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

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
1.1.1.4   root       17:  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: #include <stdlib.h>
                     20: #include <stdio.h>
                     21: #include <string.h>
                     22: #include <stdarg.h>
                     23: #include <unistd.h>
                     24: #include <errno.h>
                     25: #include <sys/ucontext.h>
                     26: 
                     27: #ifdef __ia64__
                     28: #undef uc_mcontext
                     29: #undef uc_sigmask
                     30: #undef uc_stack
                     31: #undef uc_link
                     32: #endif
                     33: 
                     34: #include "qemu.h"
1.1.1.3   root       35: #include "qemu-common.h"
1.1       root       36: 
                     37: #define DEBUG_SIGNAL
                     38: 
                     39: #define MAX_SIGQUEUE_SIZE 1024
                     40: 
                     41: struct sigqueue {
                     42:     struct sigqueue *next;
                     43:     target_siginfo_t info;
                     44: };
                     45: 
                     46: struct emulated_sigaction {
                     47:     struct target_sigaction sa;
                     48:     int pending; /* true if signal is pending */
                     49:     struct sigqueue *first;
                     50:     struct sigqueue info; /* in order to always have memory for the
                     51:                              first signal, we put it here */
                     52: };
                     53: 
1.1.1.3   root       54: static struct sigaltstack target_sigaltstack_used = {
1.1       root       55:     0, 0, SA_DISABLE
                     56: };
                     57: 
                     58: static struct emulated_sigaction sigact_table[NSIG];
                     59: static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
                     60: static struct sigqueue *first_free; /* first free siginfo queue entry */
                     61: static int signal_pending; /* non zero if a signal may be pending */
                     62: 
                     63: static void host_signal_handler(int host_signum, siginfo_t *info,
                     64:                                 void *puc);
                     65: 
                     66: 
                     67: static inline int host_to_target_signal(int sig)
                     68: {
                     69:     return sig;
                     70: }
                     71: 
                     72: static inline int target_to_host_signal(int sig)
                     73: {
                     74:     return sig;
                     75: }
                     76: 
                     77: /* siginfo conversion */
                     78: 
                     79: 
                     80: 
                     81: void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
                     82: {
                     83: 
                     84: }
                     85: 
                     86: void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
                     87: {
                     88: 
                     89: }
                     90: 
                     91: void signal_init(void)
                     92: {
                     93:     struct sigaction act;
                     94:     int i;
                     95: 
                     96:     /* set all host signal handlers. ALL signals are blocked during
                     97:        the handlers to serialize them. */
                     98:     sigfillset(&act.sa_mask);
                     99:     act.sa_flags = SA_SIGINFO;
                    100:     act.sa_sigaction = host_signal_handler;
                    101:     for(i = 1; i < NSIG; i++) {
                    102:         sigaction(i, &act, NULL);
                    103:     }
                    104: 
                    105:     memset(sigact_table, 0, sizeof(sigact_table));
                    106: 
                    107:     first_free = &sigqueue_table[0];
                    108:     for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
                    109:         sigqueue_table[i].next = &sigqueue_table[i + 1];
                    110:     sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
                    111: }
                    112: 
                    113: /* signal queue handling */
                    114: 
                    115: static inline struct sigqueue *alloc_sigqueue(void)
                    116: {
                    117:     struct sigqueue *q = first_free;
                    118:     if (!q)
                    119:         return NULL;
                    120:     first_free = q->next;
                    121:     return q;
                    122: }
                    123: 
                    124: static inline void free_sigqueue(struct sigqueue *q)
                    125: {
                    126:     q->next = first_free;
                    127:     first_free = q;
                    128: }
                    129: 
                    130: /* abort execution with signal */
1.1.1.3   root      131: void QEMU_NORETURN force_sig(int sig)
1.1       root      132: {
                    133:     int host_sig;
                    134:     host_sig = target_to_host_signal(sig);
                    135:     fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
                    136:             sig, strsignal(host_sig));
                    137:     _exit(-host_sig);
                    138: }
                    139: 
                    140: /* queue a signal so that it will be send to the virtual CPU as soon
                    141:    as possible */
                    142: int queue_signal(int sig, target_siginfo_t *info)
                    143: {
                    144:     struct emulated_sigaction *k;
                    145:     struct sigqueue *q, **pq;
                    146:     target_ulong handler;
                    147: 
                    148: #if defined(DEBUG_SIGNAL)
                    149:     fprintf(stderr, "queue_signal: sig=%d\n",
                    150:             sig);
                    151: #endif
                    152:     k = &sigact_table[sig - 1];
                    153:     handler = (target_ulong)k->sa.sa_handler;
                    154:     if (handler == SIG_DFL) {
                    155:         /* default handler : ignore some signal. The other are fatal */
                    156:         if (sig != SIGCHLD &&
                    157:             sig != SIGURG &&
                    158:             sig != SIGWINCH) {
                    159:             force_sig(sig);
                    160:         } else {
                    161:             return 0; /* indicate ignored */
                    162:         }
                    163:     } else if (handler == host_to_target_signal(SIG_IGN)) {
                    164:         /* ignore signal */
                    165:         return 0;
                    166:     } else if (handler == host_to_target_signal(SIG_ERR)) {
                    167:         force_sig(sig);
                    168:     } else {
                    169:         pq = &k->first;
                    170:         if (!k->pending) {
                    171:             /* first signal */
                    172:             q = &k->info;
                    173:         } else {
                    174:             q = alloc_sigqueue();
                    175:             if (!q)
                    176:                 return -EAGAIN;
                    177:             while (*pq != NULL)
                    178:                 pq = &(*pq)->next;
                    179:         }
                    180:         *pq = q;
                    181:         q->info = *info;
                    182:         q->next = NULL;
                    183:         k->pending = 1;
                    184:         /* signal that a new signal is pending */
                    185:         signal_pending = 1;
                    186:         return 1; /* indicates that the signal was queued */
                    187:     }
                    188: }
                    189: 
                    190: static void host_signal_handler(int host_signum, siginfo_t *info,
                    191:                                 void *puc)
                    192: {
                    193:     int sig;
                    194:     target_siginfo_t tinfo;
                    195: 
                    196:     /* the CPU emulator uses some host signals to detect exceptions,
                    197:        we we forward to it some signals */
1.1.1.2   root      198:     if (host_signum == SIGSEGV || host_signum == SIGBUS) {
1.1       root      199:         if (cpu_signal_handler(host_signum, (void*)info, puc))
                    200:             return;
                    201:     }
                    202: 
                    203:     /* get target signal number */
                    204:     sig = host_to_target_signal(host_signum);
                    205:     if (sig < 1 || sig > NSIG)
                    206:         return;
                    207: 
                    208: #if defined(DEBUG_SIGNAL)
                    209:        fprintf(stderr, "qemu: got signal %d\n", sig);
                    210: #endif
                    211:     if (queue_signal(sig, &tinfo) == 1) {
                    212:         /* interrupt the virtual CPU as soon as possible */
1.1.1.4   root      213:         cpu_exit(global_env);
1.1       root      214:     }
                    215: }
                    216: 
                    217: int do_sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss)
                    218: {
                    219:     /* XXX: test errors */
                    220:     if(oss)
                    221:     {
                    222:         oss->ss_sp = tswap32(target_sigaltstack_used.ss_sp);
                    223:         oss->ss_size = tswap32(target_sigaltstack_used.ss_size);
                    224:         oss->ss_flags = tswap32(target_sigaltstack_used.ss_flags);
                    225:     }
                    226:     if(ss)
                    227:     {
                    228:         target_sigaltstack_used.ss_sp = tswap32(ss->ss_sp);
                    229:         target_sigaltstack_used.ss_size = tswap32(ss->ss_size);
                    230:         target_sigaltstack_used.ss_flags = tswap32(ss->ss_flags);
                    231:     }
                    232:     return 0;
                    233: }
                    234: 
                    235: int do_sigaction(int sig, const struct sigaction *act,
                    236:                  struct sigaction *oact)
                    237: {
                    238:     struct emulated_sigaction *k;
                    239:     struct sigaction act1;
                    240:     int host_sig;
                    241: 
                    242:     if (sig < 1 || sig > NSIG)
                    243:         return -EINVAL;
                    244: 
                    245:     k = &sigact_table[sig - 1];
                    246: #if defined(DEBUG_SIGNAL)
                    247:     fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
                    248:             sig, (int)act, (int)oact);
                    249: #endif
                    250:     if (oact) {
                    251: #if defined(DEBUG_SIGNAL)
                    252:     fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
                    253:             sig, (int)act, (int)oact);
                    254: #endif
                    255: 
                    256:         oact->sa_handler = tswapl(k->sa.sa_handler);
                    257:         oact->sa_flags = tswapl(k->sa.sa_flags);
                    258:         oact->sa_mask = tswapl(k->sa.sa_mask);
                    259:     }
                    260:     if (act) {
                    261: #if defined(DEBUG_SIGNAL)
                    262:     fprintf(stderr, "sigaction handler 0x%x flag 0x%x mask 0x%x\n",
                    263:             act->sa_handler, act->sa_flags, act->sa_mask);
                    264: #endif
                    265: 
                    266:         k->sa.sa_handler = tswapl(act->sa_handler);
                    267:         k->sa.sa_flags = tswapl(act->sa_flags);
                    268:         k->sa.sa_mask = tswapl(act->sa_mask);
                    269:         /* we update the host signal state */
                    270:         host_sig = target_to_host_signal(sig);
                    271:         if (host_sig != SIGSEGV && host_sig != SIGBUS) {
                    272: #if defined(DEBUG_SIGNAL)
                    273:     fprintf(stderr, "sigaction handler going to call sigaction\n",
                    274:             act->sa_handler, act->sa_flags, act->sa_mask);
                    275: #endif
                    276: 
                    277:             sigfillset(&act1.sa_mask);
                    278:             act1.sa_flags = SA_SIGINFO;
                    279:             if (k->sa.sa_flags & SA_RESTART)
                    280:                 act1.sa_flags |= SA_RESTART;
                    281:             /* NOTE: it is important to update the host kernel signal
                    282:                ignore state to avoid getting unexpected interrupted
                    283:                syscalls */
                    284:             if (k->sa.sa_handler == SIG_IGN) {
                    285:                 act1.sa_sigaction = (void *)SIG_IGN;
                    286:             } else if (k->sa.sa_handler == SIG_DFL) {
                    287:                 act1.sa_sigaction = (void *)SIG_DFL;
                    288:             } else {
                    289:                 act1.sa_sigaction = host_signal_handler;
                    290:             }
                    291:             sigaction(host_sig, &act1, NULL);
                    292:         }
                    293:     }
                    294:     return 0;
                    295: }
                    296: 
                    297: 
                    298: #ifdef TARGET_I386
                    299: 
                    300: static inline void *
                    301: get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
                    302: {
                    303:     /* XXX Fix that */
                    304:     if(target_sigaltstack_used.ss_flags & SA_DISABLE)
                    305:     {
                    306:         int esp;
                    307:         /* Default to using normal stack */
                    308:         esp = env->regs[R_ESP];
                    309: 
                    310:         return (void *)((esp - frame_size) & -8ul);
                    311:     }
                    312:     else
                    313:     {
                    314:         return target_sigaltstack_used.ss_sp;
                    315:     }
                    316: }
                    317: 
                    318: static void setup_frame(int sig, struct emulated_sigaction *ka,
                    319:                        void *set, CPUState *env)
                    320: {
                    321:        void *frame;
                    322: 
                    323:     fprintf(stderr, "setup_frame %d\n", sig);
                    324:        frame = get_sigframe(ka, env, sizeof(*frame));
                    325: 
                    326:        /* Set up registers for signal handler */
                    327:        env->regs[R_ESP] = (unsigned long) frame;
                    328:        env->eip = (unsigned long) ka->sa.sa_handler;
                    329: 
                    330:        env->eflags &= ~TF_MASK;
                    331: 
                    332:        return;
                    333: 
                    334: give_sigsegv:
                    335:        if (sig == SIGSEGV)
                    336:                ka->sa.sa_handler = SIG_DFL;
                    337:        force_sig(SIGSEGV /* , current */);
                    338: }
                    339: 
                    340: long do_sigreturn(CPUState *env, int num)
                    341: {
                    342:     int i = 0;
                    343:     struct target_sigcontext *scp = get_int_arg(&i, env);
                    344:     /* XXX Get current signal number */
                    345:     /* XXX Adjust accordin to sc_onstack, sc_mask */
                    346:     if(tswapl(scp->sc_onstack) & 0x1)
                    347:         target_sigaltstack_used.ss_flags |= ~SA_DISABLE;
                    348:     else
                    349:         target_sigaltstack_used.ss_flags &=  SA_DISABLE;
                    350:     int set = tswapl(scp->sc_eax);
                    351:     sigprocmask(SIG_SETMASK, &set, NULL);
                    352: 
                    353:     fprintf(stderr, "do_sigreturn: partially implemented %x EAX:%x EBX:%x\n", scp->sc_mask, tswapl(scp->sc_eax), tswapl(scp->sc_ebx));
                    354:     fprintf(stderr, "ECX:%x EDX:%x EDI:%x\n", scp->sc_ecx, tswapl(scp->sc_edx), tswapl(scp->sc_edi));
                    355:     fprintf(stderr, "EIP:%x\n", tswapl(scp->sc_eip));
                    356: 
                    357:     env->regs[R_EAX] = tswapl(scp->sc_eax);
                    358:     env->regs[R_EBX] = tswapl(scp->sc_ebx);
                    359:     env->regs[R_ECX] = tswapl(scp->sc_ecx);
                    360:     env->regs[R_EDX] = tswapl(scp->sc_edx);
                    361:     env->regs[R_EDI] = tswapl(scp->sc_edi);
                    362:     env->regs[R_ESI] = tswapl(scp->sc_esi);
                    363:     env->regs[R_EBP] = tswapl(scp->sc_ebp);
                    364:     env->regs[R_ESP] = tswapl(scp->sc_esp);
                    365:     env->segs[R_SS].selector = (void*)tswapl(scp->sc_ss);
                    366:     env->eflags = tswapl(scp->sc_eflags);
                    367:     env->eip = tswapl(scp->sc_eip);
                    368:     env->segs[R_CS].selector = (void*)tswapl(scp->sc_cs);
                    369:     env->segs[R_DS].selector = (void*)tswapl(scp->sc_ds);
                    370:     env->segs[R_ES].selector = (void*)tswapl(scp->sc_es);
                    371:     env->segs[R_FS].selector = (void*)tswapl(scp->sc_fs);
                    372:     env->segs[R_GS].selector = (void*)tswapl(scp->sc_gs);
                    373: 
                    374:     /* Again, because our caller's caller will reset EAX */
                    375:     return env->regs[R_EAX];
                    376: }
                    377: 
                    378: #else
                    379: 
                    380: static void setup_frame(int sig, struct emulated_sigaction *ka,
                    381:                        void *set, CPUState *env)
                    382: {
                    383:     fprintf(stderr, "setup_frame: not implemented\n");
                    384: }
                    385: 
                    386: long do_sigreturn(CPUState *env, int num)
                    387: {
                    388:     int i = 0;
                    389:     struct target_sigcontext *scp = get_int_arg(&i, env);
                    390:     fprintf(stderr, "do_sigreturn: not implemented\n");
                    391:     return -ENOSYS;
                    392: }
                    393: 
                    394: #endif
                    395: 
                    396: void process_pending_signals(void *cpu_env)
                    397: {
                    398:     struct emulated_sigaction *k;
                    399:     struct sigqueue *q;
                    400:     target_ulong handler;
                    401:     int sig;
                    402: 
                    403:     if (!signal_pending)
                    404:         return;
                    405: 
                    406:     k = sigact_table;
                    407: 
                    408:     for(sig = 1; sig <= NSIG; sig++) {
                    409:         if (k->pending)
                    410:             goto handle_signal;
                    411:         k++;
                    412:     }
                    413: 
                    414:     /* if no signal is pending, just return */
                    415:     signal_pending = 0;
                    416:     return;
                    417: handle_signal:
                    418:     #ifdef DEBUG_SIGNAL
                    419:     fprintf(stderr, "qemu: process signal %d\n", sig);
                    420:     #endif
                    421:     /* dequeue signal */
                    422:     q = k->first;
                    423:     k->first = q->next;
                    424:     if (!k->first)
                    425:         k->pending = 0;
                    426: 
                    427:     sig = gdb_handlesig (cpu_env, sig);
                    428:     if (!sig) {
                    429:         fprintf (stderr, "Lost signal\n");
                    430:         abort();
                    431:     }
                    432: 
                    433:     handler = k->sa.sa_handler;
                    434:     if (handler == SIG_DFL) {
                    435:         /* default handler : ignore some signal. The other are fatal */
                    436:         if (sig != SIGCHLD &&
                    437:             sig != SIGURG &&
                    438:             sig != SIGWINCH) {
                    439:             force_sig(sig);
                    440:         }
                    441:     } else if (handler == SIG_IGN) {
                    442:         /* ignore sig */
                    443:     } else if (handler == SIG_ERR) {
                    444:         force_sig(sig);
                    445:     } else {
                    446: 
                    447:         setup_frame(sig, k, 0, cpu_env);
                    448:        if (k->sa.sa_flags & SA_RESETHAND)
                    449:             k->sa.sa_handler = SIG_DFL;
                    450:     }
                    451:     if (q != &k->info)
                    452:         free_sigqueue(q);
                    453: }

unix.superglobalmegacorp.com

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