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

1.1     ! root        1: /*
        !             2:  *  Emulation of Linux signals
        !             3:  * 
        !             4:  *  Copyright (c) 2003 Fabrice Bellard
        !             5:  *
        !             6:  *  This program is free software; you can redistribute it and/or modify
        !             7:  *  it under the terms of the GNU General Public License as published by
        !             8:  *  the Free Software Foundation; either version 2 of the License, or
        !             9:  *  (at your option) any later version.
        !            10:  *
        !            11:  *  This program is distributed in the hope that it will be useful,
        !            12:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14:  *  GNU General Public License for more details.
        !            15:  *
        !            16:  *  You should have received a copy of the GNU General Public License
        !            17:  *  along with this program; if not, write to the Free Software
        !            18:  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            19:  */
        !            20: #include <stdlib.h>
        !            21: #include <stdio.h>
        !            22: #include <string.h>
        !            23: #include <stdarg.h>
        !            24: #include <unistd.h>
        !            25: #include <signal.h>
        !            26: #include <errno.h>
        !            27: #include <sys/ucontext.h>
        !            28: 
        !            29: #include "qemu.h"
        !            30: 
        !            31: //#define DEBUG_SIGNAL
        !            32: 
        !            33: #define MAX_SIGQUEUE_SIZE 1024
        !            34: 
        !            35: struct sigqueue {
        !            36:     struct sigqueue *next;
        !            37:     target_siginfo_t info;
        !            38: };
        !            39: 
        !            40: struct emulated_sigaction {
        !            41:     struct target_sigaction sa;
        !            42:     int pending; /* true if signal is pending */
        !            43:     struct sigqueue *first;
        !            44:     struct sigqueue info; /* in order to always have memory for the
        !            45:                              first signal, we put it here */
        !            46: };
        !            47: 
        !            48: static struct emulated_sigaction sigact_table[TARGET_NSIG];
        !            49: static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
        !            50: static struct sigqueue *first_free; /* first free siginfo queue entry */
        !            51: static int signal_pending; /* non zero if a signal may be pending */
        !            52: 
        !            53: static void host_signal_handler(int host_signum, siginfo_t *info, 
        !            54:                                 void *puc);
        !            55: 
        !            56: static uint8_t host_to_target_signal_table[65] = {
        !            57:     [SIGHUP] = TARGET_SIGHUP,
        !            58:     [SIGINT] = TARGET_SIGINT,
        !            59:     [SIGQUIT] = TARGET_SIGQUIT,
        !            60:     [SIGILL] = TARGET_SIGILL,
        !            61:     [SIGTRAP] = TARGET_SIGTRAP,
        !            62:     [SIGABRT] = TARGET_SIGABRT,
        !            63: /*    [SIGIOT] = TARGET_SIGIOT,*/
        !            64:     [SIGBUS] = TARGET_SIGBUS,
        !            65:     [SIGFPE] = TARGET_SIGFPE,
        !            66:     [SIGKILL] = TARGET_SIGKILL,
        !            67:     [SIGUSR1] = TARGET_SIGUSR1,
        !            68:     [SIGSEGV] = TARGET_SIGSEGV,
        !            69:     [SIGUSR2] = TARGET_SIGUSR2,
        !            70:     [SIGPIPE] = TARGET_SIGPIPE,
        !            71:     [SIGALRM] = TARGET_SIGALRM,
        !            72:     [SIGTERM] = TARGET_SIGTERM,
        !            73: #ifdef SIGSTKFLT
        !            74:     [SIGSTKFLT] = TARGET_SIGSTKFLT,
        !            75: #endif
        !            76:     [SIGCHLD] = TARGET_SIGCHLD,
        !            77:     [SIGCONT] = TARGET_SIGCONT,
        !            78:     [SIGSTOP] = TARGET_SIGSTOP,
        !            79:     [SIGTSTP] = TARGET_SIGTSTP,
        !            80:     [SIGTTIN] = TARGET_SIGTTIN,
        !            81:     [SIGTTOU] = TARGET_SIGTTOU,
        !            82:     [SIGURG] = TARGET_SIGURG,
        !            83:     [SIGXCPU] = TARGET_SIGXCPU,
        !            84:     [SIGXFSZ] = TARGET_SIGXFSZ,
        !            85:     [SIGVTALRM] = TARGET_SIGVTALRM,
        !            86:     [SIGPROF] = TARGET_SIGPROF,
        !            87:     [SIGWINCH] = TARGET_SIGWINCH,
        !            88:     [SIGIO] = TARGET_SIGIO,
        !            89:     [SIGPWR] = TARGET_SIGPWR,
        !            90:     [SIGSYS] = TARGET_SIGSYS,
        !            91:     /* next signals stay the same */
        !            92: };
        !            93: static uint8_t target_to_host_signal_table[65];
        !            94: 
        !            95: static inline int host_to_target_signal(int sig)
        !            96: {
        !            97:     return host_to_target_signal_table[sig];
        !            98: }
        !            99: 
        !           100: static inline int target_to_host_signal(int sig)
        !           101: {
        !           102:     return target_to_host_signal_table[sig];
        !           103: }
        !           104: 
        !           105: static void host_to_target_sigset_internal(target_sigset_t *d, 
        !           106:                                            const sigset_t *s)
        !           107: {
        !           108:     int i;
        !           109:     unsigned long sigmask;
        !           110:     uint32_t target_sigmask;
        !           111:     
        !           112:     sigmask = ((unsigned long *)s)[0];
        !           113:     target_sigmask = 0;
        !           114:     for(i = 0; i < 32; i++) {
        !           115:         if (sigmask & (1 << i)) 
        !           116:             target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1);
        !           117:     }
        !           118: #if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
        !           119:     d->sig[0] = target_sigmask;
        !           120:     for(i = 1;i < TARGET_NSIG_WORDS; i++) {
        !           121:         d->sig[i] = ((unsigned long *)s)[i];
        !           122:     }
        !           123: #elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
        !           124:     d->sig[0] = target_sigmask;
        !           125:     d->sig[1] = sigmask >> 32;
        !           126: #else
        !           127: #warning host_to_target_sigset
        !           128: #endif
        !           129: }
        !           130: 
        !           131: void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
        !           132: {
        !           133:     target_sigset_t d1;
        !           134:     int i;
        !           135: 
        !           136:     host_to_target_sigset_internal(&d1, s);
        !           137:     for(i = 0;i < TARGET_NSIG_WORDS; i++)
        !           138:         __put_user(d1.sig[i], &d->sig[i]);
        !           139: }
        !           140: 
        !           141: void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s)
        !           142: {
        !           143:     int i;
        !           144:     unsigned long sigmask;
        !           145:     target_ulong target_sigmask;
        !           146: 
        !           147:     target_sigmask = s->sig[0];
        !           148:     sigmask = 0;
        !           149:     for(i = 0; i < 32; i++) {
        !           150:         if (target_sigmask & (1 << i)) 
        !           151:             sigmask |= 1 << (target_to_host_signal(i + 1) - 1);
        !           152:     }
        !           153: #if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
        !           154:     ((unsigned long *)d)[0] = sigmask;
        !           155:     for(i = 1;i < TARGET_NSIG_WORDS; i++) {
        !           156:         ((unsigned long *)d)[i] = s->sig[i];
        !           157:     }
        !           158: #elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
        !           159:     ((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32);
        !           160: #else
        !           161: #warning target_to_host_sigset
        !           162: #endif /* TARGET_LONG_BITS */
        !           163: }
        !           164: 
        !           165: void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
        !           166: {
        !           167:     target_sigset_t s1;
        !           168:     int i;
        !           169: 
        !           170:     for(i = 0;i < TARGET_NSIG_WORDS; i++)
        !           171:         __get_user(s1.sig[i], &s->sig[i]);
        !           172:     target_to_host_sigset_internal(d, &s1);
        !           173: }
        !           174:     
        !           175: void host_to_target_old_sigset(target_ulong *old_sigset, 
        !           176:                                const sigset_t *sigset)
        !           177: {
        !           178:     target_sigset_t d;
        !           179:     host_to_target_sigset(&d, sigset);
        !           180:     *old_sigset = d.sig[0];
        !           181: }
        !           182: 
        !           183: void target_to_host_old_sigset(sigset_t *sigset, 
        !           184:                                const target_ulong *old_sigset)
        !           185: {
        !           186:     target_sigset_t d;
        !           187:     int i;
        !           188: 
        !           189:     d.sig[0] = *old_sigset;
        !           190:     for(i = 1;i < TARGET_NSIG_WORDS; i++)
        !           191:         d.sig[i] = 0;
        !           192:     target_to_host_sigset(sigset, &d);
        !           193: }
        !           194: 
        !           195: /* siginfo conversion */
        !           196: 
        !           197: static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, 
        !           198:                                                  const siginfo_t *info)
        !           199: {
        !           200:     int sig;
        !           201:     sig = host_to_target_signal(info->si_signo);
        !           202:     tinfo->si_signo = sig;
        !           203:     tinfo->si_errno = 0;
        !           204:     tinfo->si_code = 0;
        !           205:     if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || 
        !           206:         sig == SIGBUS || sig == SIGTRAP) {
        !           207:         /* should never come here, but who knows. The information for
        !           208:            the target is irrelevant */
        !           209:         tinfo->_sifields._sigfault._addr = 0;
        !           210:     } else if (sig >= TARGET_SIGRTMIN) {
        !           211:         tinfo->_sifields._rt._pid = info->si_pid;
        !           212:         tinfo->_sifields._rt._uid = info->si_uid;
        !           213:         /* XXX: potential problem if 64 bit */
        !           214:         tinfo->_sifields._rt._sigval.sival_ptr = 
        !           215:             (target_ulong)info->si_value.sival_ptr;
        !           216:     }
        !           217: }
        !           218: 
        !           219: static void tswap_siginfo(target_siginfo_t *tinfo, 
        !           220:                           const target_siginfo_t *info)
        !           221: {
        !           222:     int sig;
        !           223:     sig = info->si_signo;
        !           224:     tinfo->si_signo = tswap32(sig);
        !           225:     tinfo->si_errno = tswap32(info->si_errno);
        !           226:     tinfo->si_code = tswap32(info->si_code);
        !           227:     if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || 
        !           228:         sig == SIGBUS || sig == SIGTRAP) {
        !           229:         tinfo->_sifields._sigfault._addr = 
        !           230:             tswapl(info->_sifields._sigfault._addr);
        !           231:     } else if (sig >= TARGET_SIGRTMIN) {
        !           232:         tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
        !           233:         tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
        !           234:         tinfo->_sifields._rt._sigval.sival_ptr = 
        !           235:             tswapl(info->_sifields._rt._sigval.sival_ptr);
        !           236:     }
        !           237: }
        !           238: 
        !           239: 
        !           240: void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
        !           241: {
        !           242:     host_to_target_siginfo_noswap(tinfo, info);
        !           243:     tswap_siginfo(tinfo, tinfo);
        !           244: }
        !           245: 
        !           246: /* XXX: we support only POSIX RT signals are used. */
        !           247: /* XXX: find a solution for 64 bit (additionnal malloced data is needed) */
        !           248: void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
        !           249: {
        !           250:     info->si_signo = tswap32(tinfo->si_signo);
        !           251:     info->si_errno = tswap32(tinfo->si_errno);
        !           252:     info->si_code = tswap32(tinfo->si_code);
        !           253:     info->si_pid = tswap32(tinfo->_sifields._rt._pid);
        !           254:     info->si_uid = tswap32(tinfo->_sifields._rt._uid);
        !           255:     info->si_value.sival_ptr = 
        !           256:         (void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
        !           257: }
        !           258: 
        !           259: void signal_init(void)
        !           260: {
        !           261:     struct sigaction act;
        !           262:     int i, j;
        !           263: 
        !           264:     /* generate signal conversion tables */
        !           265:     for(i = 1; i <= 64; i++) {
        !           266:         if (host_to_target_signal_table[i] == 0)
        !           267:             host_to_target_signal_table[i] = i;
        !           268:     }
        !           269:     for(i = 1; i <= 64; i++) {
        !           270:         j = host_to_target_signal_table[i];
        !           271:         target_to_host_signal_table[j] = i;
        !           272:     }
        !           273:         
        !           274:     /* set all host signal handlers. ALL signals are blocked during
        !           275:        the handlers to serialize them. */
        !           276:     sigfillset(&act.sa_mask);
        !           277:     act.sa_flags = SA_SIGINFO;
        !           278:     act.sa_sigaction = host_signal_handler;
        !           279:     for(i = 1; i < NSIG; i++) {
        !           280:         sigaction(i, &act, NULL);
        !           281:     }
        !           282:     
        !           283:     memset(sigact_table, 0, sizeof(sigact_table));
        !           284: 
        !           285:     first_free = &sigqueue_table[0];
        !           286:     for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) 
        !           287:         sigqueue_table[i].next = &sigqueue_table[i + 1];
        !           288:     sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
        !           289: }
        !           290: 
        !           291: /* signal queue handling */
        !           292: 
        !           293: static inline struct sigqueue *alloc_sigqueue(void)
        !           294: {
        !           295:     struct sigqueue *q = first_free;
        !           296:     if (!q)
        !           297:         return NULL;
        !           298:     first_free = q->next;
        !           299:     return q;
        !           300: }
        !           301: 
        !           302: static inline void free_sigqueue(struct sigqueue *q)
        !           303: {
        !           304:     q->next = first_free;
        !           305:     first_free = q;
        !           306: }
        !           307: 
        !           308: /* abort execution with signal */
        !           309: void __attribute((noreturn)) force_sig(int sig)
        !           310: {
        !           311:     int host_sig;
        !           312:     host_sig = target_to_host_signal(sig);
        !           313:     fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n", 
        !           314:             sig, strsignal(host_sig));
        !           315: #if 1
        !           316:     _exit(-host_sig);
        !           317: #else
        !           318:     {
        !           319:         struct sigaction act;
        !           320:         sigemptyset(&act.sa_mask);
        !           321:         act.sa_flags = SA_SIGINFO;
        !           322:         act.sa_sigaction = SIG_DFL;
        !           323:         sigaction(SIGABRT, &act, NULL);
        !           324:         abort();
        !           325:     }
        !           326: #endif
        !           327: }
        !           328: 
        !           329: /* queue a signal so that it will be send to the virtual CPU as soon
        !           330:    as possible */
        !           331: int queue_signal(int sig, target_siginfo_t *info)
        !           332: {
        !           333:     struct emulated_sigaction *k;
        !           334:     struct sigqueue *q, **pq;
        !           335:     target_ulong handler;
        !           336: 
        !           337: #if defined(DEBUG_SIGNAL)
        !           338:     fprintf(stderr, "queue_signal: sig=%d\n", 
        !           339:             sig);
        !           340: #endif
        !           341:     k = &sigact_table[sig - 1];
        !           342:     handler = k->sa._sa_handler;
        !           343:     if (handler == TARGET_SIG_DFL) {
        !           344:         /* default handler : ignore some signal. The other are fatal */
        !           345:         if (sig != TARGET_SIGCHLD && 
        !           346:             sig != TARGET_SIGURG && 
        !           347:             sig != TARGET_SIGWINCH) {
        !           348:             force_sig(sig);
        !           349:         } else {
        !           350:             return 0; /* indicate ignored */
        !           351:         }
        !           352:     } else if (handler == TARGET_SIG_IGN) {
        !           353:         /* ignore signal */
        !           354:         return 0;
        !           355:     } else if (handler == TARGET_SIG_ERR) {
        !           356:         force_sig(sig);
        !           357:     } else {
        !           358:         pq = &k->first;
        !           359:         if (sig < TARGET_SIGRTMIN) {
        !           360:             /* if non real time signal, we queue exactly one signal */
        !           361:             if (!k->pending)
        !           362:                 q = &k->info;
        !           363:             else
        !           364:                 return 0;
        !           365:         } else {
        !           366:             if (!k->pending) {
        !           367:                 /* first signal */
        !           368:                 q = &k->info;
        !           369:             } else {
        !           370:                 q = alloc_sigqueue();
        !           371:                 if (!q)
        !           372:                     return -EAGAIN;
        !           373:                 while (*pq != NULL)
        !           374:                     pq = &(*pq)->next;
        !           375:             }
        !           376:         }
        !           377:         *pq = q;
        !           378:         q->info = *info;
        !           379:         q->next = NULL;
        !           380:         k->pending = 1;
        !           381:         /* signal that a new signal is pending */
        !           382:         signal_pending = 1;
        !           383:         return 1; /* indicates that the signal was queued */
        !           384:     }
        !           385: }
        !           386: 
        !           387: static void host_signal_handler(int host_signum, siginfo_t *info, 
        !           388:                                 void *puc)
        !           389: {
        !           390:     int sig;
        !           391:     target_siginfo_t tinfo;
        !           392: 
        !           393:     /* the CPU emulator uses some host signals to detect exceptions,
        !           394:        we we forward to it some signals */
        !           395:     if (host_signum == SIGSEGV || host_signum == SIGBUS 
        !           396: #if defined(TARGET_I386) && defined(USE_CODE_COPY)
        !           397:         || host_signum == SIGFPE
        !           398: #endif
        !           399:         ) {
        !           400:         if (cpu_signal_handler(host_signum, info, puc))
        !           401:             return;
        !           402:     }
        !           403: 
        !           404:     /* get target signal number */
        !           405:     sig = host_to_target_signal(host_signum);
        !           406:     if (sig < 1 || sig > TARGET_NSIG)
        !           407:         return;
        !           408: #if defined(DEBUG_SIGNAL)
        !           409:     fprintf(stderr, "qemu: got signal %d\n", sig);
        !           410: #endif
        !           411:     host_to_target_siginfo_noswap(&tinfo, info);
        !           412:     if (queue_signal(sig, &tinfo) == 1) {
        !           413:         /* interrupt the virtual CPU as soon as possible */
        !           414:         cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
        !           415:     }
        !           416: }
        !           417: 
        !           418: int do_sigaction(int sig, const struct target_sigaction *act,
        !           419:                  struct target_sigaction *oact)
        !           420: {
        !           421:     struct emulated_sigaction *k;
        !           422:     struct sigaction act1;
        !           423:     int host_sig;
        !           424: 
        !           425:     if (sig < 1 || sig > TARGET_NSIG)
        !           426:         return -EINVAL;
        !           427:     k = &sigact_table[sig - 1];
        !           428: #if defined(DEBUG_SIGNAL)
        !           429:     fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", 
        !           430:             sig, (int)act, (int)oact);
        !           431: #endif
        !           432:     if (oact) {
        !           433:         oact->_sa_handler = tswapl(k->sa._sa_handler);
        !           434:         oact->sa_flags = tswapl(k->sa.sa_flags);
        !           435:         oact->sa_restorer = tswapl(k->sa.sa_restorer);
        !           436:         oact->sa_mask = k->sa.sa_mask;
        !           437:     }
        !           438:     if (act) {
        !           439:         k->sa._sa_handler = tswapl(act->_sa_handler);
        !           440:         k->sa.sa_flags = tswapl(act->sa_flags);
        !           441:         k->sa.sa_restorer = tswapl(act->sa_restorer);
        !           442:         k->sa.sa_mask = act->sa_mask;
        !           443: 
        !           444:         /* we update the host linux signal state */
        !           445:         host_sig = target_to_host_signal(sig);
        !           446:         if (host_sig != SIGSEGV && host_sig != SIGBUS) {
        !           447:             sigfillset(&act1.sa_mask);
        !           448:             act1.sa_flags = SA_SIGINFO;
        !           449:             if (k->sa.sa_flags & TARGET_SA_RESTART)
        !           450:                 act1.sa_flags |= SA_RESTART;
        !           451:             /* NOTE: it is important to update the host kernel signal
        !           452:                ignore state to avoid getting unexpected interrupted
        !           453:                syscalls */
        !           454:             if (k->sa._sa_handler == TARGET_SIG_IGN) {
        !           455:                 act1.sa_sigaction = (void *)SIG_IGN;
        !           456:             } else if (k->sa._sa_handler == TARGET_SIG_DFL) {
        !           457:                 act1.sa_sigaction = (void *)SIG_DFL;
        !           458:             } else {
        !           459:                 act1.sa_sigaction = host_signal_handler;
        !           460:             }
        !           461:             sigaction(host_sig, &act1, NULL);
        !           462:         }
        !           463:     }
        !           464:     return 0;
        !           465: }
        !           466: 
        !           467: #ifndef offsetof
        !           468: #define offsetof(type, field) ((size_t) &((type *)0)->field)
        !           469: #endif
        !           470: 
        !           471: static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, 
        !           472:                                        const target_siginfo_t *info)
        !           473: {
        !           474:     tswap_siginfo(tinfo, info);
        !           475:     return 0;
        !           476: }
        !           477: 
        !           478: #ifdef TARGET_I386
        !           479: 
        !           480: /* from the Linux kernel */
        !           481: 
        !           482: struct target_fpreg {
        !           483:        uint16_t significand[4];
        !           484:        uint16_t exponent;
        !           485: };
        !           486: 
        !           487: struct target_fpxreg {
        !           488:        uint16_t significand[4];
        !           489:        uint16_t exponent;
        !           490:        uint16_t padding[3];
        !           491: };
        !           492: 
        !           493: struct target_xmmreg {
        !           494:        target_ulong element[4];
        !           495: };
        !           496: 
        !           497: struct target_fpstate {
        !           498:        /* Regular FPU environment */
        !           499:        target_ulong    cw;
        !           500:        target_ulong    sw;
        !           501:        target_ulong    tag;
        !           502:        target_ulong    ipoff;
        !           503:        target_ulong    cssel;
        !           504:        target_ulong    dataoff;
        !           505:        target_ulong    datasel;
        !           506:        struct target_fpreg     _st[8];
        !           507:        uint16_t        status;
        !           508:        uint16_t        magic;          /* 0xffff = regular FPU data only */
        !           509: 
        !           510:        /* FXSR FPU environment */
        !           511:        target_ulong    _fxsr_env[6];   /* FXSR FPU env is ignored */
        !           512:        target_ulong    mxcsr;
        !           513:        target_ulong    reserved;
        !           514:        struct target_fpxreg    _fxsr_st[8];    /* FXSR FPU reg data is ignored */
        !           515:        struct target_xmmreg    _xmm[8];
        !           516:        target_ulong    padding[56];
        !           517: };
        !           518: 
        !           519: #define X86_FXSR_MAGIC         0x0000
        !           520: 
        !           521: struct target_sigcontext {
        !           522:        uint16_t gs, __gsh;
        !           523:        uint16_t fs, __fsh;
        !           524:        uint16_t es, __esh;
        !           525:        uint16_t ds, __dsh;
        !           526:        target_ulong edi;
        !           527:        target_ulong esi;
        !           528:        target_ulong ebp;
        !           529:        target_ulong esp;
        !           530:        target_ulong ebx;
        !           531:        target_ulong edx;
        !           532:        target_ulong ecx;
        !           533:        target_ulong eax;
        !           534:        target_ulong trapno;
        !           535:        target_ulong err;
        !           536:        target_ulong eip;
        !           537:        uint16_t cs, __csh;
        !           538:        target_ulong eflags;
        !           539:        target_ulong esp_at_signal;
        !           540:        uint16_t ss, __ssh;
        !           541:         target_ulong fpstate; /* pointer */
        !           542:        target_ulong oldmask;
        !           543:        target_ulong cr2;
        !           544: };
        !           545: 
        !           546: typedef struct target_sigaltstack {
        !           547:        target_ulong ss_sp;
        !           548:        int ss_flags;
        !           549:        target_ulong ss_size;
        !           550: } target_stack_t;
        !           551: 
        !           552: struct target_ucontext {
        !           553:         target_ulong     tuc_flags;
        !           554:        target_ulong      tuc_link;
        !           555:        target_stack_t    tuc_stack;
        !           556:        struct target_sigcontext tuc_mcontext;
        !           557:        target_sigset_t   tuc_sigmask;  /* mask last for extensibility */
        !           558: };
        !           559: 
        !           560: struct sigframe
        !           561: {
        !           562:     target_ulong pretcode;
        !           563:     int sig;
        !           564:     struct target_sigcontext sc;
        !           565:     struct target_fpstate fpstate;
        !           566:     target_ulong extramask[TARGET_NSIG_WORDS-1];
        !           567:     char retcode[8];
        !           568: };
        !           569: 
        !           570: struct rt_sigframe
        !           571: {
        !           572:     target_ulong pretcode;
        !           573:     int sig;
        !           574:     target_ulong pinfo;
        !           575:     target_ulong puc;
        !           576:     struct target_siginfo info;
        !           577:     struct target_ucontext uc;
        !           578:     struct target_fpstate fpstate;
        !           579:     char retcode[8];
        !           580: };
        !           581: 
        !           582: /*
        !           583:  * Set up a signal frame.
        !           584:  */
        !           585: 
        !           586: /* XXX: save x87 state */
        !           587: static int
        !           588: setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
        !           589:                 CPUX86State *env, unsigned long mask)
        !           590: {
        !           591:        int err = 0;
        !           592: 
        !           593:        err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
        !           594:        err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
        !           595:        err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
        !           596:        err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
        !           597:        err |= __put_user(env->regs[R_EDI], &sc->edi);
        !           598:        err |= __put_user(env->regs[R_ESI], &sc->esi);
        !           599:        err |= __put_user(env->regs[R_EBP], &sc->ebp);
        !           600:        err |= __put_user(env->regs[R_ESP], &sc->esp);
        !           601:        err |= __put_user(env->regs[R_EBX], &sc->ebx);
        !           602:        err |= __put_user(env->regs[R_EDX], &sc->edx);
        !           603:        err |= __put_user(env->regs[R_ECX], &sc->ecx);
        !           604:        err |= __put_user(env->regs[R_EAX], &sc->eax);
        !           605:        err |= __put_user(env->exception_index, &sc->trapno);
        !           606:        err |= __put_user(env->error_code, &sc->err);
        !           607:        err |= __put_user(env->eip, &sc->eip);
        !           608:        err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
        !           609:        err |= __put_user(env->eflags, &sc->eflags);
        !           610:        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
        !           611:        err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
        !           612: 
        !           613:         cpu_x86_fsave(env, (void *)fpstate, 1);
        !           614:         fpstate->status = fpstate->sw;
        !           615:         err |= __put_user(0xffff, &fpstate->magic);
        !           616:         err |= __put_user(fpstate, &sc->fpstate);
        !           617: 
        !           618:        /* non-iBCS2 extensions.. */
        !           619:        err |= __put_user(mask, &sc->oldmask);
        !           620:        err |= __put_user(env->cr[2], &sc->cr2);
        !           621:        return err;
        !           622: }
        !           623: 
        !           624: /*
        !           625:  * Determine which stack to use..
        !           626:  */
        !           627: 
        !           628: static inline void *
        !           629: get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
        !           630: {
        !           631:        unsigned long esp;
        !           632: 
        !           633:        /* Default to using normal stack */
        !           634:        esp = env->regs[R_ESP];
        !           635: #if 0
        !           636:        /* This is the X/Open sanctioned signal stack switching.  */
        !           637:        if (ka->sa.sa_flags & SA_ONSTACK) {
        !           638:                if (sas_ss_flags(esp) == 0)
        !           639:                        esp = current->sas_ss_sp + current->sas_ss_size;
        !           640:        }
        !           641: 
        !           642:        /* This is the legacy signal stack switching. */
        !           643:        else 
        !           644: #endif
        !           645:         if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
        !           646:             !(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
        !           647:             ka->sa.sa_restorer) {
        !           648:             esp = (unsigned long) ka->sa.sa_restorer;
        !           649:        }
        !           650:         return (void *)((esp - frame_size) & -8ul);
        !           651: }
        !           652: 
        !           653: static void setup_frame(int sig, struct emulated_sigaction *ka,
        !           654:                        target_sigset_t *set, CPUX86State *env)
        !           655: {
        !           656:        struct sigframe *frame;
        !           657:        int i, err = 0;
        !           658: 
        !           659:        frame = get_sigframe(ka, env, sizeof(*frame));
        !           660: 
        !           661:        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
        !           662:                goto give_sigsegv;
        !           663:        err |= __put_user((/*current->exec_domain
        !           664:                           && current->exec_domain->signal_invmap
        !           665:                           && sig < 32
        !           666:                           ? current->exec_domain->signal_invmap[sig]
        !           667:                           : */ sig),
        !           668:                          &frame->sig);
        !           669:        if (err)
        !           670:                goto give_sigsegv;
        !           671: 
        !           672:        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
        !           673:        if (err)
        !           674:                goto give_sigsegv;
        !           675: 
        !           676:         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
        !           677:             if (__put_user(set->sig[i], &frame->extramask[i - 1]))
        !           678:                 goto give_sigsegv;
        !           679:         }
        !           680: 
        !           681:        /* Set up to return from userspace.  If provided, use a stub
        !           682:           already in userspace.  */
        !           683:        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
        !           684:                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
        !           685:        } else {
        !           686:                err |= __put_user(frame->retcode, &frame->pretcode);
        !           687:                /* This is popl %eax ; movl $,%eax ; int $0x80 */
        !           688:                err |= __put_user(0xb858, (short *)(frame->retcode+0));
        !           689:                err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
        !           690:                err |= __put_user(0x80cd, (short *)(frame->retcode+6));
        !           691:        }
        !           692: 
        !           693:        if (err)
        !           694:                goto give_sigsegv;
        !           695: 
        !           696:        /* Set up registers for signal handler */
        !           697:        env->regs[R_ESP] = (unsigned long) frame;
        !           698:        env->eip = (unsigned long) ka->sa._sa_handler;
        !           699: 
        !           700:         cpu_x86_load_seg(env, R_DS, __USER_DS);
        !           701:         cpu_x86_load_seg(env, R_ES, __USER_DS);
        !           702:         cpu_x86_load_seg(env, R_SS, __USER_DS);
        !           703:         cpu_x86_load_seg(env, R_CS, __USER_CS);
        !           704:        env->eflags &= ~TF_MASK;
        !           705: 
        !           706:        return;
        !           707: 
        !           708: give_sigsegv:
        !           709:        if (sig == TARGET_SIGSEGV)
        !           710:                ka->sa._sa_handler = TARGET_SIG_DFL;
        !           711:        force_sig(TARGET_SIGSEGV /* , current */);
        !           712: }
        !           713: 
        !           714: static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
        !           715:                            target_siginfo_t *info,
        !           716:                           target_sigset_t *set, CPUX86State *env)
        !           717: {
        !           718:        struct rt_sigframe *frame;
        !           719:        int i, err = 0;
        !           720: 
        !           721:        frame = get_sigframe(ka, env, sizeof(*frame));
        !           722: 
        !           723:        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
        !           724:                goto give_sigsegv;
        !           725: 
        !           726:        err |= __put_user((/*current->exec_domain
        !           727:                           && current->exec_domain->signal_invmap
        !           728:                           && sig < 32
        !           729:                           ? current->exec_domain->signal_invmap[sig]
        !           730:                           : */sig),
        !           731:                          &frame->sig);
        !           732:        err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
        !           733:        err |= __put_user((target_ulong)&frame->uc, &frame->puc);
        !           734:        err |= copy_siginfo_to_user(&frame->info, info);
        !           735:        if (err)
        !           736:                goto give_sigsegv;
        !           737: 
        !           738:        /* Create the ucontext.  */
        !           739:        err |= __put_user(0, &frame->uc.tuc_flags);
        !           740:        err |= __put_user(0, &frame->uc.tuc_link);
        !           741:        err |= __put_user(/*current->sas_ss_sp*/ 0,
        !           742:                          &frame->uc.tuc_stack.ss_sp);
        !           743:        err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
        !           744:                          &frame->uc.tuc_stack.ss_flags);
        !           745:        err |= __put_user(/* current->sas_ss_size */ 0,
        !           746:                          &frame->uc.tuc_stack.ss_size);
        !           747:        err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
        !           748:                                env, set->sig[0]);
        !           749:         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
        !           750:             if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
        !           751:                 goto give_sigsegv;
        !           752:         }
        !           753: 
        !           754:        /* Set up to return from userspace.  If provided, use a stub
        !           755:           already in userspace.  */
        !           756:        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
        !           757:                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
        !           758:        } else {
        !           759:                err |= __put_user(frame->retcode, &frame->pretcode);
        !           760:                /* This is movl $,%eax ; int $0x80 */
        !           761:                err |= __put_user(0xb8, (char *)(frame->retcode+0));
        !           762:                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
        !           763:                err |= __put_user(0x80cd, (short *)(frame->retcode+5));
        !           764:        }
        !           765: 
        !           766:        if (err)
        !           767:                goto give_sigsegv;
        !           768: 
        !           769:        /* Set up registers for signal handler */
        !           770:        env->regs[R_ESP] = (unsigned long) frame;
        !           771:        env->eip = (unsigned long) ka->sa._sa_handler;
        !           772: 
        !           773:         cpu_x86_load_seg(env, R_DS, __USER_DS);
        !           774:         cpu_x86_load_seg(env, R_ES, __USER_DS);
        !           775:         cpu_x86_load_seg(env, R_SS, __USER_DS);
        !           776:         cpu_x86_load_seg(env, R_CS, __USER_CS);
        !           777:        env->eflags &= ~TF_MASK;
        !           778: 
        !           779:        return;
        !           780: 
        !           781: give_sigsegv:
        !           782:        if (sig == TARGET_SIGSEGV)
        !           783:                ka->sa._sa_handler = TARGET_SIG_DFL;
        !           784:        force_sig(TARGET_SIGSEGV /* , current */);
        !           785: }
        !           786: 
        !           787: static int
        !           788: restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
        !           789: {
        !           790:        unsigned int err = 0;
        !           791: 
        !           792:         cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
        !           793:         cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
        !           794:         cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
        !           795:         cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
        !           796: 
        !           797:         env->regs[R_EDI] = ldl(&sc->edi);
        !           798:         env->regs[R_ESI] = ldl(&sc->esi);
        !           799:         env->regs[R_EBP] = ldl(&sc->ebp);
        !           800:         env->regs[R_ESP] = ldl(&sc->esp);
        !           801:         env->regs[R_EBX] = ldl(&sc->ebx);
        !           802:         env->regs[R_EDX] = ldl(&sc->edx);
        !           803:         env->regs[R_ECX] = ldl(&sc->ecx);
        !           804:         env->eip = ldl(&sc->eip);
        !           805: 
        !           806:         cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
        !           807:         cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
        !           808:        
        !           809:        {
        !           810:                unsigned int tmpflags;
        !           811:                 tmpflags = ldl(&sc->eflags);
        !           812:                env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
        !           813:                 //             regs->orig_eax = -1;            /* disable syscall checks */
        !           814:        }
        !           815: 
        !           816:        {
        !           817:                struct _fpstate * buf;
        !           818:                 buf = (void *)ldl(&sc->fpstate);
        !           819:                if (buf) {
        !           820: #if 0
        !           821:                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
        !           822:                                goto badframe;
        !           823: #endif
        !           824:                         cpu_x86_frstor(env, (void *)buf, 1);
        !           825:                }
        !           826:        }
        !           827: 
        !           828:         *peax = ldl(&sc->eax);
        !           829:        return err;
        !           830: #if 0
        !           831: badframe:
        !           832:        return 1;
        !           833: #endif
        !           834: }
        !           835: 
        !           836: long do_sigreturn(CPUX86State *env)
        !           837: {
        !           838:     struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
        !           839:     target_sigset_t target_set;
        !           840:     sigset_t set;
        !           841:     int eax, i;
        !           842: 
        !           843: #if defined(DEBUG_SIGNAL)
        !           844:     fprintf(stderr, "do_sigreturn\n");
        !           845: #endif
        !           846:     /* set blocked signals */
        !           847:     if (__get_user(target_set.sig[0], &frame->sc.oldmask))
        !           848:         goto badframe;
        !           849:     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
        !           850:         if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
        !           851:             goto badframe;
        !           852:     }
        !           853: 
        !           854:     target_to_host_sigset_internal(&set, &target_set);
        !           855:     sigprocmask(SIG_SETMASK, &set, NULL);
        !           856:     
        !           857:     /* restore registers */
        !           858:     if (restore_sigcontext(env, &frame->sc, &eax))
        !           859:         goto badframe;
        !           860:     return eax;
        !           861: 
        !           862: badframe:
        !           863:     force_sig(TARGET_SIGSEGV);
        !           864:     return 0;
        !           865: }
        !           866: 
        !           867: long do_rt_sigreturn(CPUX86State *env)
        !           868: {
        !           869:        struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
        !           870:         sigset_t set;
        !           871:         //     stack_t st;
        !           872:        int eax;
        !           873: 
        !           874: #if 0
        !           875:        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
        !           876:                goto badframe;
        !           877: #endif
        !           878:         target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
        !           879:         sigprocmask(SIG_SETMASK, &set, NULL);
        !           880:        
        !           881:        if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
        !           882:                goto badframe;
        !           883: 
        !           884: #if 0
        !           885:        if (__copy_from_user(&st, &frame->uc.tuc_stack, sizeof(st)))
        !           886:                goto badframe;
        !           887:        /* It is more difficult to avoid calling this function than to
        !           888:           call it and ignore errors.  */
        !           889:        do_sigaltstack(&st, NULL, regs->esp);
        !           890: #endif
        !           891:        return eax;
        !           892: 
        !           893: badframe:
        !           894:        force_sig(TARGET_SIGSEGV);
        !           895:        return 0;
        !           896: }
        !           897: 
        !           898: #elif defined(TARGET_ARM)
        !           899: 
        !           900: struct target_sigcontext {
        !           901:        target_ulong trap_no;
        !           902:        target_ulong error_code;
        !           903:        target_ulong oldmask;
        !           904:        target_ulong arm_r0;
        !           905:        target_ulong arm_r1;
        !           906:        target_ulong arm_r2;
        !           907:        target_ulong arm_r3;
        !           908:        target_ulong arm_r4;
        !           909:        target_ulong arm_r5;
        !           910:        target_ulong arm_r6;
        !           911:        target_ulong arm_r7;
        !           912:        target_ulong arm_r8;
        !           913:        target_ulong arm_r9;
        !           914:        target_ulong arm_r10;
        !           915:        target_ulong arm_fp;
        !           916:        target_ulong arm_ip;
        !           917:        target_ulong arm_sp;
        !           918:        target_ulong arm_lr;
        !           919:        target_ulong arm_pc;
        !           920:        target_ulong arm_cpsr;
        !           921:        target_ulong fault_address;
        !           922: };
        !           923: 
        !           924: typedef struct target_sigaltstack {
        !           925:        target_ulong ss_sp;
        !           926:        int ss_flags;
        !           927:        target_ulong ss_size;
        !           928: } target_stack_t;
        !           929: 
        !           930: struct target_ucontext {
        !           931:     target_ulong tuc_flags;
        !           932:     target_ulong tuc_link;
        !           933:     target_stack_t tuc_stack;
        !           934:     struct target_sigcontext tuc_mcontext;
        !           935:     target_sigset_t  tuc_sigmask;      /* mask last for extensibility */
        !           936: };
        !           937: 
        !           938: struct sigframe
        !           939: {
        !           940:     struct target_sigcontext sc;
        !           941:     target_ulong extramask[TARGET_NSIG_WORDS-1];
        !           942:     target_ulong retcode;
        !           943: };
        !           944: 
        !           945: struct rt_sigframe
        !           946: {
        !           947:     struct target_siginfo *pinfo;
        !           948:     void *puc;
        !           949:     struct target_siginfo info;
        !           950:     struct target_ucontext uc;
        !           951:     target_ulong retcode;
        !           952: };
        !           953: 
        !           954: #define TARGET_CONFIG_CPU_32 1
        !           955: 
        !           956: /*
        !           957:  * For ARM syscalls, we encode the syscall number into the instruction.
        !           958:  */
        !           959: #define SWI_SYS_SIGRETURN      (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
        !           960: #define SWI_SYS_RT_SIGRETURN   (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
        !           961: 
        !           962: /*
        !           963:  * For Thumb syscalls, we pass the syscall number via r7.  We therefore
        !           964:  * need two 16-bit instructions.
        !           965:  */
        !           966: #define SWI_THUMB_SIGRETURN    (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
        !           967: #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
        !           968: 
        !           969: static const target_ulong retcodes[4] = {
        !           970:        SWI_SYS_SIGRETURN,      SWI_THUMB_SIGRETURN,
        !           971:        SWI_SYS_RT_SIGRETURN,   SWI_THUMB_RT_SIGRETURN
        !           972: };
        !           973: 
        !           974: 
        !           975: #define __put_user_error(x,p,e) __put_user(x, p)
        !           976: #define __get_user_error(x,p,e) __get_user(x, p)
        !           977: 
        !           978: static inline int valid_user_regs(CPUState *regs)
        !           979: {
        !           980:     return 1;
        !           981: }
        !           982: 
        !           983: static int
        !           984: setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
        !           985:                 CPUState *env, unsigned long mask)
        !           986: {
        !           987:        int err = 0;
        !           988: 
        !           989:        __put_user_error(env->regs[0], &sc->arm_r0, err);
        !           990:        __put_user_error(env->regs[1], &sc->arm_r1, err);
        !           991:        __put_user_error(env->regs[2], &sc->arm_r2, err);
        !           992:        __put_user_error(env->regs[3], &sc->arm_r3, err);
        !           993:        __put_user_error(env->regs[4], &sc->arm_r4, err);
        !           994:        __put_user_error(env->regs[5], &sc->arm_r5, err);
        !           995:        __put_user_error(env->regs[6], &sc->arm_r6, err);
        !           996:        __put_user_error(env->regs[7], &sc->arm_r7, err);
        !           997:        __put_user_error(env->regs[8], &sc->arm_r8, err);
        !           998:        __put_user_error(env->regs[9], &sc->arm_r9, err);
        !           999:        __put_user_error(env->regs[10], &sc->arm_r10, err);
        !          1000:        __put_user_error(env->regs[11], &sc->arm_fp, err);
        !          1001:        __put_user_error(env->regs[12], &sc->arm_ip, err);
        !          1002:        __put_user_error(env->regs[13], &sc->arm_sp, err);
        !          1003:        __put_user_error(env->regs[14], &sc->arm_lr, err);
        !          1004:        __put_user_error(env->regs[15], &sc->arm_pc, err);
        !          1005: #ifdef TARGET_CONFIG_CPU_32
        !          1006:        __put_user_error(env->cpsr, &sc->arm_cpsr, err);
        !          1007: #endif
        !          1008: 
        !          1009:        __put_user_error(/* current->thread.trap_no */ 0, &sc->trap_no, err);
        !          1010:        __put_user_error(/* current->thread.error_code */ 0, &sc->error_code, err);
        !          1011:        __put_user_error(/* current->thread.address */ 0, &sc->fault_address, err);
        !          1012:        __put_user_error(mask, &sc->oldmask, err);
        !          1013: 
        !          1014:        return err;
        !          1015: }
        !          1016: 
        !          1017: static inline void *
        !          1018: get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
        !          1019: {
        !          1020:        unsigned long sp = regs->regs[13];
        !          1021: 
        !          1022: #if 0
        !          1023:        /*
        !          1024:         * This is the X/Open sanctioned signal stack switching.
        !          1025:         */
        !          1026:        if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
        !          1027:                sp = current->sas_ss_sp + current->sas_ss_size;
        !          1028: #endif
        !          1029:        /*
        !          1030:         * ATPCS B01 mandates 8-byte alignment
        !          1031:         */
        !          1032:        return (void *)((sp - framesize) & ~7);
        !          1033: }
        !          1034: 
        !          1035: static int
        !          1036: setup_return(CPUState *env, struct emulated_sigaction *ka,
        !          1037:             target_ulong *rc, void *frame, int usig)
        !          1038: {
        !          1039:        target_ulong handler = (target_ulong)ka->sa._sa_handler;
        !          1040:        target_ulong retcode;
        !          1041:        int thumb = 0;
        !          1042: #if defined(TARGET_CONFIG_CPU_32)
        !          1043:        target_ulong cpsr = env->cpsr;
        !          1044: 
        !          1045: #if 0
        !          1046:        /*
        !          1047:         * Maybe we need to deliver a 32-bit signal to a 26-bit task.
        !          1048:         */
        !          1049:        if (ka->sa.sa_flags & SA_THIRTYTWO)
        !          1050:                cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
        !          1051: 
        !          1052: #ifdef CONFIG_ARM_THUMB
        !          1053:        if (elf_hwcap & HWCAP_THUMB) {
        !          1054:                /*
        !          1055:                 * The LSB of the handler determines if we're going to
        !          1056:                 * be using THUMB or ARM mode for this signal handler.
        !          1057:                 */
        !          1058:                thumb = handler & 1;
        !          1059: 
        !          1060:                if (thumb)
        !          1061:                        cpsr |= T_BIT;
        !          1062:                else
        !          1063:                        cpsr &= ~T_BIT;
        !          1064:        }
        !          1065: #endif
        !          1066: #endif
        !          1067: #endif /* TARGET_CONFIG_CPU_32 */
        !          1068: 
        !          1069:        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
        !          1070:                retcode = (target_ulong)ka->sa.sa_restorer;
        !          1071:        } else {
        !          1072:                unsigned int idx = thumb;
        !          1073: 
        !          1074:                if (ka->sa.sa_flags & TARGET_SA_SIGINFO)
        !          1075:                        idx += 2;
        !          1076: 
        !          1077:                if (__put_user(retcodes[idx], rc))
        !          1078:                        return 1;
        !          1079: #if 0
        !          1080:                flush_icache_range((target_ulong)rc,
        !          1081:                                   (target_ulong)(rc + 1));
        !          1082: #endif
        !          1083:                retcode = ((target_ulong)rc) + thumb;
        !          1084:        }
        !          1085: 
        !          1086:        env->regs[0] = usig;
        !          1087:        env->regs[13] = (target_ulong)frame;
        !          1088:        env->regs[14] = retcode;
        !          1089:        env->regs[15] = handler & (thumb ? ~1 : ~3);
        !          1090: 
        !          1091: #ifdef TARGET_CONFIG_CPU_32
        !          1092:        env->cpsr = cpsr;
        !          1093: #endif
        !          1094: 
        !          1095:        return 0;
        !          1096: }
        !          1097: 
        !          1098: static void setup_frame(int usig, struct emulated_sigaction *ka,
        !          1099:                        target_sigset_t *set, CPUState *regs)
        !          1100: {
        !          1101:        struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
        !          1102:        int i, err = 0;
        !          1103: 
        !          1104:        err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
        !          1105: 
        !          1106:         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
        !          1107:             if (__put_user(set->sig[i], &frame->extramask[i - 1]))
        !          1108:                 return;
        !          1109:        }
        !          1110: 
        !          1111:        if (err == 0)
        !          1112:             err = setup_return(regs, ka, &frame->retcode, frame, usig);
        !          1113:         //     return err;
        !          1114: }
        !          1115: 
        !          1116: static void setup_rt_frame(int usig, struct emulated_sigaction *ka, 
        !          1117:                            target_siginfo_t *info,
        !          1118:                           target_sigset_t *set, CPUState *env)
        !          1119: {
        !          1120:        struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
        !          1121:        int i, err = 0;
        !          1122: 
        !          1123:        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
        !          1124:             return /* 1 */;
        !          1125: 
        !          1126:        __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
        !          1127:        __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
        !          1128:        err |= copy_siginfo_to_user(&frame->info, info);
        !          1129: 
        !          1130:        /* Clear all the bits of the ucontext we don't use.  */
        !          1131:        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
        !          1132: 
        !          1133:        err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
        !          1134:                                env, set->sig[0]);
        !          1135:         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
        !          1136:             if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
        !          1137:                 return;
        !          1138:         }
        !          1139: 
        !          1140:        if (err == 0)
        !          1141:                err = setup_return(env, ka, &frame->retcode, frame, usig);
        !          1142: 
        !          1143:        if (err == 0) {
        !          1144:                /*
        !          1145:                 * For realtime signals we must also set the second and third
        !          1146:                 * arguments for the signal handler.
        !          1147:                 *   -- Peter Maydell <[email protected]> 2000-12-06
        !          1148:                 */
        !          1149:             env->regs[1] = (target_ulong)frame->pinfo;
        !          1150:             env->regs[2] = (target_ulong)frame->puc;
        !          1151:        }
        !          1152: 
        !          1153:         //     return err;
        !          1154: }
        !          1155: 
        !          1156: static int
        !          1157: restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
        !          1158: {
        !          1159:        int err = 0;
        !          1160: 
        !          1161:        __get_user_error(env->regs[0], &sc->arm_r0, err);
        !          1162:        __get_user_error(env->regs[1], &sc->arm_r1, err);
        !          1163:        __get_user_error(env->regs[2], &sc->arm_r2, err);
        !          1164:        __get_user_error(env->regs[3], &sc->arm_r3, err);
        !          1165:        __get_user_error(env->regs[4], &sc->arm_r4, err);
        !          1166:        __get_user_error(env->regs[5], &sc->arm_r5, err);
        !          1167:        __get_user_error(env->regs[6], &sc->arm_r6, err);
        !          1168:        __get_user_error(env->regs[7], &sc->arm_r7, err);
        !          1169:        __get_user_error(env->regs[8], &sc->arm_r8, err);
        !          1170:        __get_user_error(env->regs[9], &sc->arm_r9, err);
        !          1171:        __get_user_error(env->regs[10], &sc->arm_r10, err);
        !          1172:        __get_user_error(env->regs[11], &sc->arm_fp, err);
        !          1173:        __get_user_error(env->regs[12], &sc->arm_ip, err);
        !          1174:        __get_user_error(env->regs[13], &sc->arm_sp, err);
        !          1175:        __get_user_error(env->regs[14], &sc->arm_lr, err);
        !          1176:        __get_user_error(env->regs[15], &sc->arm_pc, err);
        !          1177: #ifdef TARGET_CONFIG_CPU_32
        !          1178:        __get_user_error(env->cpsr, &sc->arm_cpsr, err);
        !          1179: #endif
        !          1180: 
        !          1181:        err |= !valid_user_regs(env);
        !          1182: 
        !          1183:        return err;
        !          1184: }
        !          1185: 
        !          1186: long do_sigreturn(CPUState *env)
        !          1187: {
        !          1188:        struct sigframe *frame;
        !          1189:        target_sigset_t set;
        !          1190:         sigset_t host_set;
        !          1191:         int i;
        !          1192: 
        !          1193:        /*
        !          1194:         * Since we stacked the signal on a 64-bit boundary,
        !          1195:         * then 'sp' should be word aligned here.  If it's
        !          1196:         * not, then the user is trying to mess with us.
        !          1197:         */
        !          1198:        if (env->regs[13] & 7)
        !          1199:                goto badframe;
        !          1200: 
        !          1201:        frame = (struct sigframe *)env->regs[13];
        !          1202: 
        !          1203: #if 0
        !          1204:        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
        !          1205:                goto badframe;
        !          1206: #endif
        !          1207:        if (__get_user(set.sig[0], &frame->sc.oldmask))
        !          1208:             goto badframe;
        !          1209:         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
        !          1210:             if (__get_user(set.sig[i], &frame->extramask[i - 1]))
        !          1211:                 goto badframe;
        !          1212:         }
        !          1213: 
        !          1214:         target_to_host_sigset_internal(&host_set, &set);
        !          1215:         sigprocmask(SIG_SETMASK, &host_set, NULL);
        !          1216: 
        !          1217:        if (restore_sigcontext(env, &frame->sc))
        !          1218:                goto badframe;
        !          1219: 
        !          1220: #if 0
        !          1221:        /* Send SIGTRAP if we're single-stepping */
        !          1222:        if (ptrace_cancel_bpt(current))
        !          1223:                send_sig(SIGTRAP, current, 1);
        !          1224: #endif
        !          1225:        return env->regs[0];
        !          1226: 
        !          1227: badframe:
        !          1228:         force_sig(SIGSEGV /* , current */);
        !          1229:        return 0;
        !          1230: }
        !          1231: 
        !          1232: long do_rt_sigreturn(CPUState *env)
        !          1233: {
        !          1234:        struct rt_sigframe *frame;
        !          1235:         sigset_t host_set;
        !          1236: 
        !          1237:        /*
        !          1238:         * Since we stacked the signal on a 64-bit boundary,
        !          1239:         * then 'sp' should be word aligned here.  If it's
        !          1240:         * not, then the user is trying to mess with us.
        !          1241:         */
        !          1242:        if (env->regs[13] & 7)
        !          1243:                goto badframe;
        !          1244: 
        !          1245:        frame = (struct rt_sigframe *)env->regs[13];
        !          1246: 
        !          1247: #if 0
        !          1248:        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
        !          1249:                goto badframe;
        !          1250: #endif
        !          1251:         target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
        !          1252:         sigprocmask(SIG_SETMASK, &host_set, NULL);
        !          1253: 
        !          1254:        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
        !          1255:                goto badframe;
        !          1256: 
        !          1257: #if 0
        !          1258:        /* Send SIGTRAP if we're single-stepping */
        !          1259:        if (ptrace_cancel_bpt(current))
        !          1260:                send_sig(SIGTRAP, current, 1);
        !          1261: #endif
        !          1262:        return env->regs[0];
        !          1263: 
        !          1264: badframe:
        !          1265:         force_sig(SIGSEGV /* , current */);
        !          1266:        return 0;
        !          1267: }
        !          1268: 
        !          1269: #elif defined(TARGET_SPARC)
        !          1270: 
        !          1271: #define __SUNOS_MAXWIN   31
        !          1272: 
        !          1273: /* This is what SunOS does, so shall I. */
        !          1274: struct target_sigcontext {
        !          1275:         target_ulong sigc_onstack;      /* state to restore */
        !          1276: 
        !          1277:         target_ulong sigc_mask;         /* sigmask to restore */
        !          1278:         target_ulong sigc_sp;           /* stack pointer */
        !          1279:         target_ulong sigc_pc;           /* program counter */
        !          1280:         target_ulong sigc_npc;          /* next program counter */
        !          1281:         target_ulong sigc_psr;          /* for condition codes etc */
        !          1282:         target_ulong sigc_g1;           /* User uses these two registers */
        !          1283:         target_ulong sigc_o0;           /* within the trampoline code. */
        !          1284: 
        !          1285:         /* Now comes information regarding the users window set
        !          1286:          * at the time of the signal.
        !          1287:          */
        !          1288:         target_ulong sigc_oswins;       /* outstanding windows */
        !          1289: 
        !          1290:         /* stack ptrs for each regwin buf */
        !          1291:         char *sigc_spbuf[__SUNOS_MAXWIN];
        !          1292: 
        !          1293:         /* Windows to restore after signal */
        !          1294:         struct {
        !          1295:                 target_ulong locals[8];
        !          1296:                 target_ulong ins[8];
        !          1297:         } sigc_wbuf[__SUNOS_MAXWIN];
        !          1298: };
        !          1299: /* A Sparc stack frame */
        !          1300: struct sparc_stackf {
        !          1301:         target_ulong locals[8];
        !          1302:         target_ulong ins[6];
        !          1303:         struct sparc_stackf *fp;
        !          1304:         target_ulong callers_pc;
        !          1305:         char *structptr;
        !          1306:         target_ulong xargs[6];
        !          1307:         target_ulong xxargs[1];
        !          1308: };
        !          1309: 
        !          1310: typedef struct {
        !          1311:         struct {
        !          1312:                 target_ulong psr;
        !          1313:                 target_ulong pc;
        !          1314:                 target_ulong npc;
        !          1315:                 target_ulong y;
        !          1316:                 target_ulong u_regs[16]; /* globals and ins */
        !          1317:         }               si_regs;
        !          1318:         int             si_mask;
        !          1319: } __siginfo_t;
        !          1320: 
        !          1321: typedef struct {
        !          1322:         unsigned   long si_float_regs [32];
        !          1323:         unsigned   long si_fsr;
        !          1324:         unsigned   long si_fpqdepth;
        !          1325:         struct {
        !          1326:                 unsigned long *insn_addr;
        !          1327:                 unsigned long insn;
        !          1328:         } si_fpqueue [16];
        !          1329: } __siginfo_fpu_t;
        !          1330: 
        !          1331: 
        !          1332: struct target_signal_frame {
        !          1333:        struct sparc_stackf     ss;
        !          1334:        __siginfo_t             info;
        !          1335:        __siginfo_fpu_t         *fpu_save;
        !          1336:        target_ulong            insns[2] __attribute__ ((aligned (8)));
        !          1337:        target_ulong            extramask[TARGET_NSIG_WORDS - 1];
        !          1338:        target_ulong            extra_size; /* Should be 0 */
        !          1339:        __siginfo_fpu_t         fpu_state;
        !          1340: };
        !          1341: struct target_rt_signal_frame {
        !          1342:        struct sparc_stackf     ss;
        !          1343:        siginfo_t               info;
        !          1344:        target_ulong            regs[20];
        !          1345:        sigset_t                mask;
        !          1346:        __siginfo_fpu_t         *fpu_save;
        !          1347:        unsigned int            insns[2];
        !          1348:        stack_t                 stack;
        !          1349:        unsigned int            extra_size; /* Should be 0 */
        !          1350:        __siginfo_fpu_t         fpu_state;
        !          1351: };
        !          1352: 
        !          1353: #define UREG_O0        16
        !          1354: #define UREG_O6        22
        !          1355: #define UREG_I0        0
        !          1356: #define UREG_I1        1
        !          1357: #define UREG_I2        2
        !          1358: #define UREG_I6        6
        !          1359: #define UREG_I7        7
        !          1360: #define UREG_L0               8
        !          1361: #define UREG_FP        UREG_I6
        !          1362: #define UREG_SP        UREG_O6
        !          1363: 
        !          1364: static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, unsigned long framesize)
        !          1365: {
        !          1366:        unsigned long sp;
        !          1367: 
        !          1368:        sp = env->regwptr[UREG_FP];
        !          1369: #if 0
        !          1370: 
        !          1371:        /* This is the X/Open sanctioned signal stack switching.  */
        !          1372:        if (sa->sa_flags & TARGET_SA_ONSTACK) {
        !          1373:                if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
        !          1374:                        sp = current->sas_ss_sp + current->sas_ss_size;
        !          1375:        }
        !          1376: #endif
        !          1377:        return (void *)(sp - framesize);
        !          1378: }
        !          1379: 
        !          1380: static int
        !          1381: setup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask)
        !          1382: {
        !          1383:        int err = 0, i;
        !          1384: 
        !          1385:        err |= __put_user(env->psr, &si->si_regs.psr);
        !          1386:        err |= __put_user(env->pc, &si->si_regs.pc);
        !          1387:        err |= __put_user(env->npc, &si->si_regs.npc);
        !          1388:        err |= __put_user(env->y, &si->si_regs.y);
        !          1389:        for (i=0; i < 8; i++) {
        !          1390:                err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
        !          1391:        }
        !          1392:        for (i=0; i < 8; i++) {
        !          1393:                err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
        !          1394:        }
        !          1395:        err |= __put_user(mask, &si->si_mask);
        !          1396:        return err;
        !          1397: }
        !          1398: 
        !          1399: #if 0
        !          1400: static int
        !          1401: setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
        !          1402:                 CPUState *env, unsigned long mask)
        !          1403: {
        !          1404:        int err = 0;
        !          1405: 
        !          1406:        err |= __put_user(mask, &sc->sigc_mask);
        !          1407:        err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
        !          1408:        err |= __put_user(env->pc, &sc->sigc_pc);
        !          1409:        err |= __put_user(env->npc, &sc->sigc_npc);
        !          1410:        err |= __put_user(env->psr, &sc->sigc_psr);
        !          1411:        err |= __put_user(env->gregs[1], &sc->sigc_g1);
        !          1412:        err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
        !          1413: 
        !          1414:        return err;
        !          1415: }
        !          1416: #endif
        !          1417: #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
        !          1418: 
        !          1419: static void setup_frame(int sig, struct emulated_sigaction *ka,
        !          1420:                        target_sigset_t *set, CPUState *env)
        !          1421: {
        !          1422:        struct target_signal_frame *sf;
        !          1423:        int sigframe_size, err, i;
        !          1424: 
        !          1425:        /* 1. Make sure everything is clean */
        !          1426:        //synchronize_user_stack();
        !          1427: 
        !          1428:         sigframe_size = NF_ALIGNEDSZ;
        !          1429: 
        !          1430:        sf = (struct target_signal_frame *)
        !          1431:                get_sigframe(ka, env, sigframe_size);
        !          1432: 
        !          1433:        //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
        !          1434: #if 0
        !          1435:        if (invalid_frame_pointer(sf, sigframe_size))
        !          1436:                goto sigill_and_return;
        !          1437: #endif
        !          1438:        /* 2. Save the current process state */
        !          1439:        err = setup___siginfo(&sf->info, env, set->sig[0]);
        !          1440:        err |= __put_user(0, &sf->extra_size);
        !          1441: 
        !          1442:        //err |= save_fpu_state(regs, &sf->fpu_state);
        !          1443:        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
        !          1444: 
        !          1445:        err |= __put_user(set->sig[0], &sf->info.si_mask);
        !          1446:        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
        !          1447:                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
        !          1448:        }
        !          1449: 
        !          1450:        for (i = 0; i < 8; i++) {
        !          1451:                err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
        !          1452:        }
        !          1453:        for (i = 0; i < 8; i++) {
        !          1454:                err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
        !          1455:        }
        !          1456:        if (err)
        !          1457:                goto sigsegv;
        !          1458: 
        !          1459:        /* 3. signal handler back-trampoline and parameters */
        !          1460:        env->regwptr[UREG_FP] = (target_ulong) sf;
        !          1461:        env->regwptr[UREG_I0] = sig;
        !          1462:        env->regwptr[UREG_I1] = (target_ulong) &sf->info;
        !          1463:        env->regwptr[UREG_I2] = (target_ulong) &sf->info;
        !          1464: 
        !          1465:        /* 4. signal handler */
        !          1466:        env->pc = (unsigned long) ka->sa._sa_handler;
        !          1467:        env->npc = (env->pc + 4);
        !          1468:        /* 5. return to kernel instructions */
        !          1469:        if (ka->sa.sa_restorer)
        !          1470:                env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer;
        !          1471:        else {
        !          1472:                env->regwptr[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
        !          1473: 
        !          1474:                /* mov __NR_sigreturn, %g1 */
        !          1475:                err |= __put_user(0x821020d8, &sf->insns[0]);
        !          1476: 
        !          1477:                /* t 0x10 */
        !          1478:                err |= __put_user(0x91d02010, &sf->insns[1]);
        !          1479:                if (err)
        !          1480:                        goto sigsegv;
        !          1481: 
        !          1482:                /* Flush instruction space. */
        !          1483:                //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
        !          1484:                 //             tb_flush(env);
        !          1485:        }
        !          1486:        return;
        !          1487: 
        !          1488:         //sigill_and_return:
        !          1489:        force_sig(TARGET_SIGILL);
        !          1490: sigsegv:
        !          1491:        //fprintf(stderr, "force_sig\n");
        !          1492:        force_sig(TARGET_SIGSEGV);
        !          1493: }
        !          1494: static inline int
        !          1495: restore_fpu_state(CPUState *env, __siginfo_fpu_t *fpu)
        !          1496: {
        !          1497:         int err;
        !          1498: #if 0
        !          1499: #ifdef CONFIG_SMP
        !          1500:         if (current->flags & PF_USEDFPU)
        !          1501:                 regs->psr &= ~PSR_EF;
        !          1502: #else
        !          1503:         if (current == last_task_used_math) {
        !          1504:                 last_task_used_math = 0;
        !          1505:                 regs->psr &= ~PSR_EF;
        !          1506:         }
        !          1507: #endif
        !          1508:         current->used_math = 1;
        !          1509:         current->flags &= ~PF_USEDFPU;
        !          1510: #endif
        !          1511: #if 0
        !          1512:         if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
        !          1513:                 return -EFAULT;
        !          1514: #endif
        !          1515: 
        !          1516:         err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
        !          1517:                                     (sizeof(unsigned long) * 32));
        !          1518:         err |= __get_user(env->fsr, &fpu->si_fsr);
        !          1519: #if 0
        !          1520:         err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
        !          1521:         if (current->thread.fpqdepth != 0)
        !          1522:                 err |= __copy_from_user(&current->thread.fpqueue[0],
        !          1523:                                         &fpu->si_fpqueue[0],
        !          1524:                                         ((sizeof(unsigned long) +
        !          1525:                                         (sizeof(unsigned long *)))*16));
        !          1526: #endif
        !          1527:         return err;
        !          1528: }
        !          1529: 
        !          1530: 
        !          1531: static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
        !          1532:                            target_siginfo_t *info,
        !          1533:                           target_sigset_t *set, CPUState *env)
        !          1534: {
        !          1535:     fprintf(stderr, "setup_rt_frame: not implemented\n");
        !          1536: }
        !          1537: 
        !          1538: long do_sigreturn(CPUState *env)
        !          1539: {
        !          1540:         struct target_signal_frame *sf;
        !          1541:         uint32_t up_psr, pc, npc;
        !          1542:         target_sigset_t set;
        !          1543:         sigset_t host_set;
        !          1544:         target_ulong fpu_save;
        !          1545:         int err, i;
        !          1546: 
        !          1547:         sf = (struct target_signal_frame *) env->regwptr[UREG_FP];
        !          1548: #if 0
        !          1549:        fprintf(stderr, "sigreturn\n");
        !          1550:        fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
        !          1551: #endif
        !          1552:        //cpu_dump_state(env, stderr, fprintf, 0);
        !          1553: 
        !          1554:         /* 1. Make sure we are not getting garbage from the user */
        !          1555: #if 0
        !          1556:         if (verify_area (VERIFY_READ, sf, sizeof (*sf)))
        !          1557:                 goto segv_and_exit;
        !          1558: #endif
        !          1559: 
        !          1560:         if (((uint) sf) & 3)
        !          1561:                 goto segv_and_exit;
        !          1562: 
        !          1563:         err = __get_user(pc,  &sf->info.si_regs.pc);
        !          1564:         err |= __get_user(npc, &sf->info.si_regs.npc);
        !          1565: 
        !          1566:         if ((pc | npc) & 3)
        !          1567:                 goto segv_and_exit;
        !          1568: 
        !          1569:         /* 2. Restore the state */
        !          1570:         err |= __get_user(up_psr, &sf->info.si_regs.psr);
        !          1571: 
        !          1572:         /* User can only change condition codes and FPU enabling in %psr. */
        !          1573:         env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
        !          1574:                   | (env->psr & ~(PSR_ICC /* | PSR_EF */));
        !          1575: 
        !          1576:        env->pc = pc;
        !          1577:        env->npc = npc;
        !          1578:         err |= __get_user(env->y, &sf->info.si_regs.y);
        !          1579:        for (i=0; i < 8; i++) {
        !          1580:                err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
        !          1581:        }
        !          1582:        for (i=0; i < 8; i++) {
        !          1583:                err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
        !          1584:        }
        !          1585: 
        !          1586:         err |= __get_user(fpu_save, (target_ulong *)&sf->fpu_save);
        !          1587: 
        !          1588:         //if (fpu_save)
        !          1589:         //        err |= restore_fpu_state(env, fpu_save);
        !          1590: 
        !          1591:         /* This is pretty much atomic, no amount locking would prevent
        !          1592:          * the races which exist anyways.
        !          1593:          */
        !          1594:         err |= __get_user(set.sig[0], &sf->info.si_mask);
        !          1595:         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
        !          1596:             err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
        !          1597:         }
        !          1598: 
        !          1599:         target_to_host_sigset_internal(&host_set, &set);
        !          1600:         sigprocmask(SIG_SETMASK, &host_set, NULL);
        !          1601: 
        !          1602:         if (err)
        !          1603:                 goto segv_and_exit;
        !          1604: 
        !          1605:         return env->regwptr[0];
        !          1606: 
        !          1607: segv_and_exit:
        !          1608:        force_sig(TARGET_SIGSEGV);
        !          1609: }
        !          1610: 
        !          1611: long do_rt_sigreturn(CPUState *env)
        !          1612: {
        !          1613:     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
        !          1614:     return -ENOSYS;
        !          1615: }
        !          1616: 
        !          1617: 
        !          1618: #else
        !          1619: 
        !          1620: static void setup_frame(int sig, struct emulated_sigaction *ka,
        !          1621:                        target_sigset_t *set, CPUState *env)
        !          1622: {
        !          1623:     fprintf(stderr, "setup_frame: not implemented\n");
        !          1624: }
        !          1625: 
        !          1626: static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
        !          1627:                            target_siginfo_t *info,
        !          1628:                           target_sigset_t *set, CPUState *env)
        !          1629: {
        !          1630:     fprintf(stderr, "setup_rt_frame: not implemented\n");
        !          1631: }
        !          1632: 
        !          1633: long do_sigreturn(CPUState *env)
        !          1634: {
        !          1635:     fprintf(stderr, "do_sigreturn: not implemented\n");
        !          1636:     return -ENOSYS;
        !          1637: }
        !          1638: 
        !          1639: long do_rt_sigreturn(CPUState *env)
        !          1640: {
        !          1641:     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
        !          1642:     return -ENOSYS;
        !          1643: }
        !          1644: 
        !          1645: #endif
        !          1646: 
        !          1647: void process_pending_signals(void *cpu_env)
        !          1648: {
        !          1649:     int sig;
        !          1650:     target_ulong handler;
        !          1651:     sigset_t set, old_set;
        !          1652:     target_sigset_t target_old_set;
        !          1653:     struct emulated_sigaction *k;
        !          1654:     struct sigqueue *q;
        !          1655:     
        !          1656:     if (!signal_pending)
        !          1657:         return;
        !          1658: 
        !          1659:     k = sigact_table;
        !          1660:     for(sig = 1; sig <= TARGET_NSIG; sig++) {
        !          1661:         if (k->pending)
        !          1662:             goto handle_signal;
        !          1663:         k++;
        !          1664:     }
        !          1665:     /* if no signal is pending, just return */
        !          1666:     signal_pending = 0;
        !          1667:     return;
        !          1668: 
        !          1669:  handle_signal:
        !          1670: #ifdef DEBUG_SIGNAL
        !          1671:     fprintf(stderr, "qemu: process signal %d\n", sig);
        !          1672: #endif
        !          1673:     /* dequeue signal */
        !          1674:     q = k->first;
        !          1675:     k->first = q->next;
        !          1676:     if (!k->first)
        !          1677:         k->pending = 0;
        !          1678:       
        !          1679:     sig = gdb_handlesig (cpu_env, sig);
        !          1680:     if (!sig) {
        !          1681:         fprintf (stderr, "Lost signal\n");
        !          1682:         abort();
        !          1683:     }
        !          1684: 
        !          1685:     handler = k->sa._sa_handler;
        !          1686:     if (handler == TARGET_SIG_DFL) {
        !          1687:         /* default handler : ignore some signal. The other are fatal */
        !          1688:         if (sig != TARGET_SIGCHLD && 
        !          1689:             sig != TARGET_SIGURG && 
        !          1690:             sig != TARGET_SIGWINCH) {
        !          1691:             force_sig(sig);
        !          1692:         }
        !          1693:     } else if (handler == TARGET_SIG_IGN) {
        !          1694:         /* ignore sig */
        !          1695:     } else if (handler == TARGET_SIG_ERR) {
        !          1696:         force_sig(sig);
        !          1697:     } else {
        !          1698:         /* compute the blocked signals during the handler execution */
        !          1699:         target_to_host_sigset(&set, &k->sa.sa_mask);
        !          1700:         /* SA_NODEFER indicates that the current signal should not be
        !          1701:            blocked during the handler */
        !          1702:         if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
        !          1703:             sigaddset(&set, target_to_host_signal(sig));
        !          1704:         
        !          1705:         /* block signals in the handler using Linux */
        !          1706:         sigprocmask(SIG_BLOCK, &set, &old_set);
        !          1707:         /* save the previous blocked signal state to restore it at the
        !          1708:            end of the signal execution (see do_sigreturn) */
        !          1709:         host_to_target_sigset_internal(&target_old_set, &old_set);
        !          1710: 
        !          1711:         /* if the CPU is in VM86 mode, we restore the 32 bit values */
        !          1712: #ifdef TARGET_I386
        !          1713:         {
        !          1714:             CPUX86State *env = cpu_env;
        !          1715:             if (env->eflags & VM_MASK)
        !          1716:                 save_v86_state(env);
        !          1717:         }
        !          1718: #endif
        !          1719:         /* prepare the stack frame of the virtual CPU */
        !          1720:         if (k->sa.sa_flags & TARGET_SA_SIGINFO)
        !          1721:             setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
        !          1722:         else
        !          1723:             setup_frame(sig, k, &target_old_set, cpu_env);
        !          1724:        if (k->sa.sa_flags & TARGET_SA_RESETHAND)
        !          1725:             k->sa._sa_handler = TARGET_SIG_DFL;
        !          1726:     }
        !          1727:     if (q != &k->info)
        !          1728:         free_sigqueue(q);
        !          1729: }
        !          1730: 
        !          1731: 

unix.superglobalmegacorp.com

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