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

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++)
1.1.1.3 ! root      138:         d->sig[i] = tswapl(d1.sig[i]);
1.1       root      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++)
1.1.1.3 ! root      171:         s1.sig[i] = tswapl(s->sig[i]);
1.1       root      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:        }
1.1.1.3 ! root      650:         return g2h((esp - frame_size) & -8ul);
1.1       root      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 */
1.1.1.3 ! root      697:        env->regs[R_ESP] = h2g(frame);
1.1       root      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: {
1.1.1.3 ! root      838:     struct sigframe *frame = (struct sigframe *)g2h(env->regs[R_ESP] - 8);
1.1       root      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: {
1.1.1.3 ! root      869:        struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);
1.1       root      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
1.1.1.2   root     1006:        __put_user_error(cpsr_read(env), &sc->arm_cpsr, err);
1.1       root     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:         */
1.1.1.3 ! root     1032:        return g2h((sp - framesize) & ~7);
1.1       root     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)
1.1.1.2   root     1043: #if 0
1.1       root     1044:        target_ulong cpsr = env->cpsr;
                   1045: 
                   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;
1.1.1.3 ! root     1087:        env->regs[13] = h2g(frame);
1.1       root     1088:        env->regs[14] = retcode;
                   1089:        env->regs[15] = handler & (thumb ? ~1 : ~3);
                   1090: 
1.1.1.2   root     1091: #if 0
1.1       root     1092: #ifdef TARGET_CONFIG_CPU_32
                   1093:        env->cpsr = cpsr;
                   1094: #endif
1.1.1.2   root     1095: #endif
1.1       root     1096: 
                   1097:        return 0;
                   1098: }
                   1099: 
                   1100: static void setup_frame(int usig, struct emulated_sigaction *ka,
                   1101:                        target_sigset_t *set, CPUState *regs)
                   1102: {
                   1103:        struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
                   1104:        int i, err = 0;
                   1105: 
                   1106:        err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
                   1107: 
                   1108:         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
                   1109:             if (__put_user(set->sig[i], &frame->extramask[i - 1]))
                   1110:                 return;
                   1111:        }
                   1112: 
                   1113:        if (err == 0)
                   1114:             err = setup_return(regs, ka, &frame->retcode, frame, usig);
                   1115:         //     return err;
                   1116: }
                   1117: 
                   1118: static void setup_rt_frame(int usig, struct emulated_sigaction *ka, 
                   1119:                            target_siginfo_t *info,
                   1120:                           target_sigset_t *set, CPUState *env)
                   1121: {
                   1122:        struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
                   1123:        int i, err = 0;
                   1124: 
                   1125:        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                   1126:             return /* 1 */;
                   1127: 
                   1128:        __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
                   1129:        __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
                   1130:        err |= copy_siginfo_to_user(&frame->info, info);
                   1131: 
                   1132:        /* Clear all the bits of the ucontext we don't use.  */
1.1.1.3 ! root     1133:        memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext));
1.1       root     1134: 
                   1135:        err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
                   1136:                                env, set->sig[0]);
                   1137:         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
                   1138:             if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
                   1139:                 return;
                   1140:         }
                   1141: 
                   1142:        if (err == 0)
                   1143:                err = setup_return(env, ka, &frame->retcode, frame, usig);
                   1144: 
                   1145:        if (err == 0) {
                   1146:                /*
                   1147:                 * For realtime signals we must also set the second and third
                   1148:                 * arguments for the signal handler.
                   1149:                 *   -- Peter Maydell <[email protected]> 2000-12-06
                   1150:                 */
                   1151:             env->regs[1] = (target_ulong)frame->pinfo;
                   1152:             env->regs[2] = (target_ulong)frame->puc;
                   1153:        }
                   1154: 
                   1155:         //     return err;
                   1156: }
                   1157: 
                   1158: static int
                   1159: restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
                   1160: {
                   1161:        int err = 0;
1.1.1.2   root     1162:         uint32_t cpsr;
1.1       root     1163: 
                   1164:        __get_user_error(env->regs[0], &sc->arm_r0, err);
                   1165:        __get_user_error(env->regs[1], &sc->arm_r1, err);
                   1166:        __get_user_error(env->regs[2], &sc->arm_r2, err);
                   1167:        __get_user_error(env->regs[3], &sc->arm_r3, err);
                   1168:        __get_user_error(env->regs[4], &sc->arm_r4, err);
                   1169:        __get_user_error(env->regs[5], &sc->arm_r5, err);
                   1170:        __get_user_error(env->regs[6], &sc->arm_r6, err);
                   1171:        __get_user_error(env->regs[7], &sc->arm_r7, err);
                   1172:        __get_user_error(env->regs[8], &sc->arm_r8, err);
                   1173:        __get_user_error(env->regs[9], &sc->arm_r9, err);
                   1174:        __get_user_error(env->regs[10], &sc->arm_r10, err);
                   1175:        __get_user_error(env->regs[11], &sc->arm_fp, err);
                   1176:        __get_user_error(env->regs[12], &sc->arm_ip, err);
                   1177:        __get_user_error(env->regs[13], &sc->arm_sp, err);
                   1178:        __get_user_error(env->regs[14], &sc->arm_lr, err);
                   1179:        __get_user_error(env->regs[15], &sc->arm_pc, err);
                   1180: #ifdef TARGET_CONFIG_CPU_32
1.1.1.2   root     1181:        __get_user_error(cpsr, &sc->arm_cpsr, err);
                   1182:         cpsr_write(env, cpsr, 0xffffffff);
1.1       root     1183: #endif
                   1184: 
                   1185:        err |= !valid_user_regs(env);
                   1186: 
                   1187:        return err;
                   1188: }
                   1189: 
                   1190: long do_sigreturn(CPUState *env)
                   1191: {
                   1192:        struct sigframe *frame;
                   1193:        target_sigset_t set;
                   1194:         sigset_t host_set;
                   1195:         int i;
                   1196: 
                   1197:        /*
                   1198:         * Since we stacked the signal on a 64-bit boundary,
                   1199:         * then 'sp' should be word aligned here.  If it's
                   1200:         * not, then the user is trying to mess with us.
                   1201:         */
                   1202:        if (env->regs[13] & 7)
                   1203:                goto badframe;
                   1204: 
1.1.1.3 ! root     1205:        frame = (struct sigframe *)g2h(env->regs[13]);
1.1       root     1206: 
                   1207: #if 0
                   1208:        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
                   1209:                goto badframe;
                   1210: #endif
                   1211:        if (__get_user(set.sig[0], &frame->sc.oldmask))
                   1212:             goto badframe;
                   1213:         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
                   1214:             if (__get_user(set.sig[i], &frame->extramask[i - 1]))
                   1215:                 goto badframe;
                   1216:         }
                   1217: 
                   1218:         target_to_host_sigset_internal(&host_set, &set);
                   1219:         sigprocmask(SIG_SETMASK, &host_set, NULL);
                   1220: 
                   1221:        if (restore_sigcontext(env, &frame->sc))
                   1222:                goto badframe;
                   1223: 
                   1224: #if 0
                   1225:        /* Send SIGTRAP if we're single-stepping */
                   1226:        if (ptrace_cancel_bpt(current))
                   1227:                send_sig(SIGTRAP, current, 1);
                   1228: #endif
                   1229:        return env->regs[0];
                   1230: 
                   1231: badframe:
                   1232:         force_sig(SIGSEGV /* , current */);
                   1233:        return 0;
                   1234: }
                   1235: 
                   1236: long do_rt_sigreturn(CPUState *env)
                   1237: {
                   1238:        struct rt_sigframe *frame;
                   1239:         sigset_t host_set;
                   1240: 
                   1241:        /*
                   1242:         * Since we stacked the signal on a 64-bit boundary,
                   1243:         * then 'sp' should be word aligned here.  If it's
                   1244:         * not, then the user is trying to mess with us.
                   1245:         */
                   1246:        if (env->regs[13] & 7)
                   1247:                goto badframe;
                   1248: 
                   1249:        frame = (struct rt_sigframe *)env->regs[13];
                   1250: 
                   1251: #if 0
                   1252:        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
                   1253:                goto badframe;
                   1254: #endif
                   1255:         target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
                   1256:         sigprocmask(SIG_SETMASK, &host_set, NULL);
                   1257: 
                   1258:        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
                   1259:                goto badframe;
                   1260: 
                   1261: #if 0
                   1262:        /* Send SIGTRAP if we're single-stepping */
                   1263:        if (ptrace_cancel_bpt(current))
                   1264:                send_sig(SIGTRAP, current, 1);
                   1265: #endif
                   1266:        return env->regs[0];
                   1267: 
                   1268: badframe:
                   1269:         force_sig(SIGSEGV /* , current */);
                   1270:        return 0;
                   1271: }
                   1272: 
                   1273: #elif defined(TARGET_SPARC)
                   1274: 
                   1275: #define __SUNOS_MAXWIN   31
                   1276: 
                   1277: /* This is what SunOS does, so shall I. */
                   1278: struct target_sigcontext {
                   1279:         target_ulong sigc_onstack;      /* state to restore */
                   1280: 
                   1281:         target_ulong sigc_mask;         /* sigmask to restore */
                   1282:         target_ulong sigc_sp;           /* stack pointer */
                   1283:         target_ulong sigc_pc;           /* program counter */
                   1284:         target_ulong sigc_npc;          /* next program counter */
                   1285:         target_ulong sigc_psr;          /* for condition codes etc */
                   1286:         target_ulong sigc_g1;           /* User uses these two registers */
                   1287:         target_ulong sigc_o0;           /* within the trampoline code. */
                   1288: 
                   1289:         /* Now comes information regarding the users window set
                   1290:          * at the time of the signal.
                   1291:          */
                   1292:         target_ulong sigc_oswins;       /* outstanding windows */
                   1293: 
                   1294:         /* stack ptrs for each regwin buf */
                   1295:         char *sigc_spbuf[__SUNOS_MAXWIN];
                   1296: 
                   1297:         /* Windows to restore after signal */
                   1298:         struct {
                   1299:                 target_ulong locals[8];
                   1300:                 target_ulong ins[8];
                   1301:         } sigc_wbuf[__SUNOS_MAXWIN];
                   1302: };
                   1303: /* A Sparc stack frame */
                   1304: struct sparc_stackf {
                   1305:         target_ulong locals[8];
                   1306:         target_ulong ins[6];
                   1307:         struct sparc_stackf *fp;
                   1308:         target_ulong callers_pc;
                   1309:         char *structptr;
                   1310:         target_ulong xargs[6];
                   1311:         target_ulong xxargs[1];
                   1312: };
                   1313: 
                   1314: typedef struct {
                   1315:         struct {
                   1316:                 target_ulong psr;
                   1317:                 target_ulong pc;
                   1318:                 target_ulong npc;
                   1319:                 target_ulong y;
                   1320:                 target_ulong u_regs[16]; /* globals and ins */
                   1321:         }               si_regs;
                   1322:         int             si_mask;
                   1323: } __siginfo_t;
                   1324: 
                   1325: typedef struct {
                   1326:         unsigned   long si_float_regs [32];
                   1327:         unsigned   long si_fsr;
                   1328:         unsigned   long si_fpqdepth;
                   1329:         struct {
                   1330:                 unsigned long *insn_addr;
                   1331:                 unsigned long insn;
                   1332:         } si_fpqueue [16];
                   1333: } __siginfo_fpu_t;
                   1334: 
                   1335: 
                   1336: struct target_signal_frame {
                   1337:        struct sparc_stackf     ss;
                   1338:        __siginfo_t             info;
                   1339:        __siginfo_fpu_t         *fpu_save;
                   1340:        target_ulong            insns[2] __attribute__ ((aligned (8)));
                   1341:        target_ulong            extramask[TARGET_NSIG_WORDS - 1];
                   1342:        target_ulong            extra_size; /* Should be 0 */
                   1343:        __siginfo_fpu_t         fpu_state;
                   1344: };
                   1345: struct target_rt_signal_frame {
                   1346:        struct sparc_stackf     ss;
                   1347:        siginfo_t               info;
                   1348:        target_ulong            regs[20];
                   1349:        sigset_t                mask;
                   1350:        __siginfo_fpu_t         *fpu_save;
                   1351:        unsigned int            insns[2];
                   1352:        stack_t                 stack;
                   1353:        unsigned int            extra_size; /* Should be 0 */
                   1354:        __siginfo_fpu_t         fpu_state;
                   1355: };
                   1356: 
                   1357: #define UREG_O0        16
                   1358: #define UREG_O6        22
                   1359: #define UREG_I0        0
                   1360: #define UREG_I1        1
                   1361: #define UREG_I2        2
                   1362: #define UREG_I6        6
                   1363: #define UREG_I7        7
                   1364: #define UREG_L0               8
                   1365: #define UREG_FP        UREG_I6
                   1366: #define UREG_SP        UREG_O6
                   1367: 
                   1368: static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, unsigned long framesize)
                   1369: {
                   1370:        unsigned long sp;
                   1371: 
                   1372:        sp = env->regwptr[UREG_FP];
                   1373: #if 0
                   1374: 
                   1375:        /* This is the X/Open sanctioned signal stack switching.  */
                   1376:        if (sa->sa_flags & TARGET_SA_ONSTACK) {
                   1377:                if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
                   1378:                        sp = current->sas_ss_sp + current->sas_ss_size;
                   1379:        }
                   1380: #endif
1.1.1.3 ! root     1381:        return g2h(sp - framesize);
1.1       root     1382: }
                   1383: 
                   1384: static int
                   1385: setup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask)
                   1386: {
                   1387:        int err = 0, i;
                   1388: 
                   1389:        err |= __put_user(env->psr, &si->si_regs.psr);
                   1390:        err |= __put_user(env->pc, &si->si_regs.pc);
                   1391:        err |= __put_user(env->npc, &si->si_regs.npc);
                   1392:        err |= __put_user(env->y, &si->si_regs.y);
                   1393:        for (i=0; i < 8; i++) {
                   1394:                err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
                   1395:        }
                   1396:        for (i=0; i < 8; i++) {
                   1397:                err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
                   1398:        }
                   1399:        err |= __put_user(mask, &si->si_mask);
                   1400:        return err;
                   1401: }
                   1402: 
                   1403: #if 0
                   1404: static int
                   1405: setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
                   1406:                 CPUState *env, unsigned long mask)
                   1407: {
                   1408:        int err = 0;
                   1409: 
                   1410:        err |= __put_user(mask, &sc->sigc_mask);
                   1411:        err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
                   1412:        err |= __put_user(env->pc, &sc->sigc_pc);
                   1413:        err |= __put_user(env->npc, &sc->sigc_npc);
                   1414:        err |= __put_user(env->psr, &sc->sigc_psr);
                   1415:        err |= __put_user(env->gregs[1], &sc->sigc_g1);
                   1416:        err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
                   1417: 
                   1418:        return err;
                   1419: }
                   1420: #endif
                   1421: #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
                   1422: 
                   1423: static void setup_frame(int sig, struct emulated_sigaction *ka,
                   1424:                        target_sigset_t *set, CPUState *env)
                   1425: {
                   1426:        struct target_signal_frame *sf;
                   1427:        int sigframe_size, err, i;
                   1428: 
                   1429:        /* 1. Make sure everything is clean */
                   1430:        //synchronize_user_stack();
                   1431: 
                   1432:         sigframe_size = NF_ALIGNEDSZ;
                   1433: 
                   1434:        sf = (struct target_signal_frame *)
                   1435:                get_sigframe(ka, env, sigframe_size);
                   1436: 
                   1437:        //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
                   1438: #if 0
                   1439:        if (invalid_frame_pointer(sf, sigframe_size))
                   1440:                goto sigill_and_return;
                   1441: #endif
                   1442:        /* 2. Save the current process state */
                   1443:        err = setup___siginfo(&sf->info, env, set->sig[0]);
                   1444:        err |= __put_user(0, &sf->extra_size);
                   1445: 
                   1446:        //err |= save_fpu_state(regs, &sf->fpu_state);
                   1447:        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
                   1448: 
                   1449:        err |= __put_user(set->sig[0], &sf->info.si_mask);
                   1450:        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
                   1451:                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
                   1452:        }
                   1453: 
                   1454:        for (i = 0; i < 8; i++) {
                   1455:                err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
                   1456:        }
                   1457:        for (i = 0; i < 8; i++) {
                   1458:                err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
                   1459:        }
                   1460:        if (err)
                   1461:                goto sigsegv;
                   1462: 
                   1463:        /* 3. signal handler back-trampoline and parameters */
1.1.1.3 ! root     1464:        env->regwptr[UREG_FP] = h2g(sf);
1.1       root     1465:        env->regwptr[UREG_I0] = sig;
1.1.1.3 ! root     1466:        env->regwptr[UREG_I1] = h2g(&sf->info);
        !          1467:        env->regwptr[UREG_I2] = h2g(&sf->info);
1.1       root     1468: 
                   1469:        /* 4. signal handler */
                   1470:        env->pc = (unsigned long) ka->sa._sa_handler;
                   1471:        env->npc = (env->pc + 4);
                   1472:        /* 5. return to kernel instructions */
                   1473:        if (ka->sa.sa_restorer)
                   1474:                env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer;
                   1475:        else {
1.1.1.3 ! root     1476:                env->regwptr[UREG_I7] = h2g(&(sf->insns[0]) - 2);
1.1       root     1477: 
                   1478:                /* mov __NR_sigreturn, %g1 */
                   1479:                err |= __put_user(0x821020d8, &sf->insns[0]);
                   1480: 
                   1481:                /* t 0x10 */
                   1482:                err |= __put_user(0x91d02010, &sf->insns[1]);
                   1483:                if (err)
                   1484:                        goto sigsegv;
                   1485: 
                   1486:                /* Flush instruction space. */
                   1487:                //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
                   1488:                 //             tb_flush(env);
                   1489:        }
                   1490:        return;
                   1491: 
                   1492:         //sigill_and_return:
                   1493:        force_sig(TARGET_SIGILL);
                   1494: sigsegv:
                   1495:        //fprintf(stderr, "force_sig\n");
                   1496:        force_sig(TARGET_SIGSEGV);
                   1497: }
                   1498: static inline int
                   1499: restore_fpu_state(CPUState *env, __siginfo_fpu_t *fpu)
                   1500: {
                   1501:         int err;
                   1502: #if 0
                   1503: #ifdef CONFIG_SMP
                   1504:         if (current->flags & PF_USEDFPU)
                   1505:                 regs->psr &= ~PSR_EF;
                   1506: #else
                   1507:         if (current == last_task_used_math) {
                   1508:                 last_task_used_math = 0;
                   1509:                 regs->psr &= ~PSR_EF;
                   1510:         }
                   1511: #endif
                   1512:         current->used_math = 1;
                   1513:         current->flags &= ~PF_USEDFPU;
                   1514: #endif
                   1515: #if 0
                   1516:         if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
                   1517:                 return -EFAULT;
                   1518: #endif
                   1519: 
                   1520:         err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
                   1521:                                     (sizeof(unsigned long) * 32));
                   1522:         err |= __get_user(env->fsr, &fpu->si_fsr);
                   1523: #if 0
                   1524:         err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
                   1525:         if (current->thread.fpqdepth != 0)
                   1526:                 err |= __copy_from_user(&current->thread.fpqueue[0],
                   1527:                                         &fpu->si_fpqueue[0],
                   1528:                                         ((sizeof(unsigned long) +
                   1529:                                         (sizeof(unsigned long *)))*16));
                   1530: #endif
                   1531:         return err;
                   1532: }
                   1533: 
                   1534: 
                   1535: static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
                   1536:                            target_siginfo_t *info,
                   1537:                           target_sigset_t *set, CPUState *env)
                   1538: {
                   1539:     fprintf(stderr, "setup_rt_frame: not implemented\n");
                   1540: }
                   1541: 
                   1542: long do_sigreturn(CPUState *env)
                   1543: {
                   1544:         struct target_signal_frame *sf;
                   1545:         uint32_t up_psr, pc, npc;
                   1546:         target_sigset_t set;
                   1547:         sigset_t host_set;
                   1548:         target_ulong fpu_save;
                   1549:         int err, i;
                   1550: 
1.1.1.3 ! root     1551:         sf = (struct target_signal_frame *)g2h(env->regwptr[UREG_FP]);
1.1       root     1552: #if 0
                   1553:        fprintf(stderr, "sigreturn\n");
                   1554:        fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
                   1555: #endif
                   1556:        //cpu_dump_state(env, stderr, fprintf, 0);
                   1557: 
                   1558:         /* 1. Make sure we are not getting garbage from the user */
                   1559: #if 0
                   1560:         if (verify_area (VERIFY_READ, sf, sizeof (*sf)))
                   1561:                 goto segv_and_exit;
                   1562: #endif
                   1563: 
                   1564:         if (((uint) sf) & 3)
                   1565:                 goto segv_and_exit;
                   1566: 
                   1567:         err = __get_user(pc,  &sf->info.si_regs.pc);
                   1568:         err |= __get_user(npc, &sf->info.si_regs.npc);
                   1569: 
                   1570:         if ((pc | npc) & 3)
                   1571:                 goto segv_and_exit;
                   1572: 
                   1573:         /* 2. Restore the state */
                   1574:         err |= __get_user(up_psr, &sf->info.si_regs.psr);
                   1575: 
                   1576:         /* User can only change condition codes and FPU enabling in %psr. */
                   1577:         env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
                   1578:                   | (env->psr & ~(PSR_ICC /* | PSR_EF */));
                   1579: 
                   1580:        env->pc = pc;
                   1581:        env->npc = npc;
                   1582:         err |= __get_user(env->y, &sf->info.si_regs.y);
                   1583:        for (i=0; i < 8; i++) {
                   1584:                err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
                   1585:        }
                   1586:        for (i=0; i < 8; i++) {
                   1587:                err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
                   1588:        }
                   1589: 
                   1590:         err |= __get_user(fpu_save, (target_ulong *)&sf->fpu_save);
                   1591: 
                   1592:         //if (fpu_save)
                   1593:         //        err |= restore_fpu_state(env, fpu_save);
                   1594: 
                   1595:         /* This is pretty much atomic, no amount locking would prevent
                   1596:          * the races which exist anyways.
                   1597:          */
                   1598:         err |= __get_user(set.sig[0], &sf->info.si_mask);
                   1599:         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
                   1600:             err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
                   1601:         }
                   1602: 
                   1603:         target_to_host_sigset_internal(&host_set, &set);
                   1604:         sigprocmask(SIG_SETMASK, &host_set, NULL);
                   1605: 
                   1606:         if (err)
                   1607:                 goto segv_and_exit;
                   1608: 
                   1609:         return env->regwptr[0];
                   1610: 
                   1611: segv_and_exit:
                   1612:        force_sig(TARGET_SIGSEGV);
                   1613: }
                   1614: 
                   1615: long do_rt_sigreturn(CPUState *env)
                   1616: {
                   1617:     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
                   1618:     return -ENOSYS;
                   1619: }
                   1620: 
                   1621: 
                   1622: #else
                   1623: 
                   1624: static void setup_frame(int sig, struct emulated_sigaction *ka,
                   1625:                        target_sigset_t *set, CPUState *env)
                   1626: {
                   1627:     fprintf(stderr, "setup_frame: not implemented\n");
                   1628: }
                   1629: 
                   1630: static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
                   1631:                            target_siginfo_t *info,
                   1632:                           target_sigset_t *set, CPUState *env)
                   1633: {
                   1634:     fprintf(stderr, "setup_rt_frame: not implemented\n");
                   1635: }
                   1636: 
                   1637: long do_sigreturn(CPUState *env)
                   1638: {
                   1639:     fprintf(stderr, "do_sigreturn: not implemented\n");
                   1640:     return -ENOSYS;
                   1641: }
                   1642: 
                   1643: long do_rt_sigreturn(CPUState *env)
                   1644: {
                   1645:     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
                   1646:     return -ENOSYS;
                   1647: }
                   1648: 
                   1649: #endif
                   1650: 
                   1651: void process_pending_signals(void *cpu_env)
                   1652: {
                   1653:     int sig;
                   1654:     target_ulong handler;
                   1655:     sigset_t set, old_set;
                   1656:     target_sigset_t target_old_set;
                   1657:     struct emulated_sigaction *k;
                   1658:     struct sigqueue *q;
                   1659:     
                   1660:     if (!signal_pending)
                   1661:         return;
                   1662: 
                   1663:     k = sigact_table;
                   1664:     for(sig = 1; sig <= TARGET_NSIG; sig++) {
                   1665:         if (k->pending)
                   1666:             goto handle_signal;
                   1667:         k++;
                   1668:     }
                   1669:     /* if no signal is pending, just return */
                   1670:     signal_pending = 0;
                   1671:     return;
                   1672: 
                   1673:  handle_signal:
                   1674: #ifdef DEBUG_SIGNAL
                   1675:     fprintf(stderr, "qemu: process signal %d\n", sig);
                   1676: #endif
                   1677:     /* dequeue signal */
                   1678:     q = k->first;
                   1679:     k->first = q->next;
                   1680:     if (!k->first)
                   1681:         k->pending = 0;
                   1682:       
                   1683:     sig = gdb_handlesig (cpu_env, sig);
                   1684:     if (!sig) {
                   1685:         fprintf (stderr, "Lost signal\n");
                   1686:         abort();
                   1687:     }
                   1688: 
                   1689:     handler = k->sa._sa_handler;
                   1690:     if (handler == TARGET_SIG_DFL) {
                   1691:         /* default handler : ignore some signal. The other are fatal */
                   1692:         if (sig != TARGET_SIGCHLD && 
                   1693:             sig != TARGET_SIGURG && 
                   1694:             sig != TARGET_SIGWINCH) {
                   1695:             force_sig(sig);
                   1696:         }
                   1697:     } else if (handler == TARGET_SIG_IGN) {
                   1698:         /* ignore sig */
                   1699:     } else if (handler == TARGET_SIG_ERR) {
                   1700:         force_sig(sig);
                   1701:     } else {
                   1702:         /* compute the blocked signals during the handler execution */
                   1703:         target_to_host_sigset(&set, &k->sa.sa_mask);
                   1704:         /* SA_NODEFER indicates that the current signal should not be
                   1705:            blocked during the handler */
                   1706:         if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
                   1707:             sigaddset(&set, target_to_host_signal(sig));
                   1708:         
                   1709:         /* block signals in the handler using Linux */
                   1710:         sigprocmask(SIG_BLOCK, &set, &old_set);
                   1711:         /* save the previous blocked signal state to restore it at the
                   1712:            end of the signal execution (see do_sigreturn) */
                   1713:         host_to_target_sigset_internal(&target_old_set, &old_set);
                   1714: 
                   1715:         /* if the CPU is in VM86 mode, we restore the 32 bit values */
                   1716: #ifdef TARGET_I386
                   1717:         {
                   1718:             CPUX86State *env = cpu_env;
                   1719:             if (env->eflags & VM_MASK)
                   1720:                 save_v86_state(env);
                   1721:         }
                   1722: #endif
                   1723:         /* prepare the stack frame of the virtual CPU */
                   1724:         if (k->sa.sa_flags & TARGET_SA_SIGINFO)
                   1725:             setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
                   1726:         else
                   1727:             setup_frame(sig, k, &target_old_set, cpu_env);
                   1728:        if (k->sa.sa_flags & TARGET_SA_RESETHAND)
                   1729:             k->sa._sa_handler = TARGET_SIG_DFL;
                   1730:     }
                   1731:     if (q != &k->info)
                   1732:         free_sigqueue(q);
                   1733: }
                   1734: 
                   1735: 

unix.superglobalmegacorp.com

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