static void illegal_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context) { if (IS_INTERNAL_TID(get_cur_tid()) || is_internal(context)) { internal: internal_fault("Internal memory fault", arg, context); pause(); goto ret_exception; } struct shim_vma * vma = NULL; if (!(lookup_supervma((void *) arg, 0, &vma)) && !(vma->flags & VMA_INTERNAL)) { if (context) debug("illegal instruction at %p\n", context->IP); if (vma) put_vma(vma); deliver_signal(ALLOC_SIGINFO(SIGILL, si_addr, (void *) arg), context); } else { if (vma) put_vma(vma); goto internal; } ret_exception: DkExceptionReturn(event); }
static void quit_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context) { if (IS_INTERNAL_TID(get_cur_tid())) goto ret_exception; deliver_signal(ALLOC_SIGINFO(SIGTERM, si_pid, 0), NULL); ret_exception: DkExceptionReturn(event); }
static void divzero_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context) { if (IS_INTERNAL_TID(get_cur_tid()) || is_internal(context)) { internal_fault("Internal arithmetic fault", arg, context); pause(); goto ret_exception; } if (context) debug("arithmetic fault at %p\n", context->IP); deliver_signal(ALLOC_SIGINFO(SIGFPE, si_addr, (void *) arg), context); ret_exception: DkExceptionReturn(event); }
static void suspend_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context) { if (IS_INTERNAL_TID(get_cur_tid())) goto ret_exception; if (ask_for_checkpoint) { int ans = message_confirm("checkpoint execution " "(\'k\' to kill the process)", "yk"); if (ans == 'K' || ans == 'k') goto kill; if (ans != 'Y' && ans != 'y') goto ret_exception; shim_tcb_t * tcb = SHIM_GET_TLS(); assert(tcb && tcb->tp); struct shim_signal signal; __store_context(tcb, context, &signal); IDTYPE session = 0; char cpdir[20]; if (create_dir("checkpoint-", cpdir, 20, NULL) < 0) goto ret_exception; sys_printf("creating checkpoint \"%s\"...\n", cpdir); if (create_checkpoint(cpdir, &session) < 0) goto ret_exception; ipc_checkpoint_send(cpdir, session); kill_all_threads(tcb->tp, CHECKPOINT_REQUESTED, SIGINT); join_checkpoint(tcb->tp, &signal.context); goto ret_exception; } kill: deliver_signal(ALLOC_SIGINFO(SIGINT, si_pid, 0), NULL); ret_exception: DkExceptionReturn(event); }
static int parse_thread_name (const char * name, const char ** next, int * next_len, const char ** nextnext) { const char * p = name; int pid = 0; if (*p == '/') p++; if (strpartcmp_static(p, "self")) { p += static_strlen("self"); if (*p && *p != '/') return -ENOENT; pid = get_cur_tid(); } else { for ( ; *p && *p != '/' ; p++) { if (*p < '0' || *p > '9') return -ENOENT; pid = pid * 10 + *p - '0'; } } if (next) { if (*(p++) == '/' && *p) { *next = p; if (next_len || nextnext) for ( ; *p && *p != '/' ; p++); if (next_len) *next_len = p - *next; if (nextnext) *nextnext = (*(p++) == '/' && *p) ? p : NULL; } else { *next = NULL; } } return pid; }
static void resume_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context) { if (IS_INTERNAL_TID(get_cur_tid())) goto ret_exception; shim_tcb_t * tcb = SHIM_GET_TLS(); assert(tcb && tcb->tp); __disable_preempt(tcb); if ((tcb->context.preempt & ~SIGNAL_DELAYED) > 1) { tcb->context.preempt |= SIGNAL_DELAYED; __enable_preempt(tcb); goto ret_exception; } __handle_signal(tcb, 0, NULL); __enable_preempt(tcb); ret_exception: DkExceptionReturn(event); }