(linenum→info "unix/slp.c:2238")

qemu/0.9.1/darwin-user/signal.c

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