/** * save signal, return to _native_sig_leave_tramp if possible */ void native_isr_entry(int sig, siginfo_t *info, void *context) { (void) info; /* unused at the moment */ //printf("\n\033[33m\n\t\tnative_isr_entry(%i)\n\n\033[0m", sig); /* save the signal */ if (real_write(_sig_pipefd[1], &sig, sizeof(int)) == -1) { err(EXIT_FAILURE, "native_isr_entry(): real_write()"); } _native_sigpend++; //real_write(STDOUT_FILENO, "sigpend\n", 8); if (context == NULL) { errx(EXIT_FAILURE, "native_isr_entry: context is null - unhandled"); } if (sched_active_thread == NULL) { _native_in_isr++; warnx("native_isr_entry: sched_active_thread is null - unhandled"); _native_in_isr--; return; } /* XXX: Workaround safety check - whenever this happens it really * indicates a bug in disableIRQ */ if (native_interrupts_enabled == 0) { //printf("interrupts are off, but I caught a signal.\n"); return; } if (_native_in_isr != 0) { //real_write(STDOUT_FILENO, "interrupts in ISR!!\n", 20); return; } if (_native_in_syscall != 0) { DEBUG("\n\n\t\treturn to syscall\n\n"); return; } native_isr_context.uc_stack.ss_sp = __isr_stack; native_isr_context.uc_stack.ss_size = SIGSTKSZ; native_isr_context.uc_stack.ss_flags = 0; makecontext(&native_isr_context, native_irq_handler, 0); _native_cur_ctx = (ucontext_t *)sched_active_thread->sp; DEBUG("\n\n\t\treturn to _native_sig_leave_tramp\n\n"); /* disable interrupts in context */ isr_set_sigmask((ucontext_t *)context); _native_in_isr = 1; #ifdef __MACH__ _native_saved_eip = ((ucontext_t *)context)->uc_mcontext->__ss.__eip; ((ucontext_t *)context)->uc_mcontext->__ss.__eip = (unsigned int)&_native_sig_leave_tramp; #elif defined(__FreeBSD__) _native_saved_eip = ((struct sigcontext *)context)->sc_eip; ((struct sigcontext *)context)->sc_eip = (unsigned int)&_native_sig_leave_tramp; #else //printf("\n\033[31mEIP:\t%p\ngo switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]); _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]; ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp; #endif }
/** * save signal, return to _native_sig_leave_tramp if possible */ void native_isr_entry(int sig, siginfo_t *info, void *context) { (void) info; /* unused at the moment */ //printf("\n\033[33m\n\t\tnative_isr_entry(%i)\n\n\033[0m", sig); /* save the signal */ if (real_write(_sig_pipefd[1], &sig, sizeof(int)) == -1) { err(EXIT_FAILURE, "native_isr_entry: real_write()"); } _native_sigpend++; //real_write(STDOUT_FILENO, "sigpend\n", 8); if (context == NULL) { errx(EXIT_FAILURE, "native_isr_entry: context is null - unhandled"); } if (sched_active_thread == NULL) { _native_in_isr++; warnx("native_isr_entry: sched_active_thread is null - unhandled"); _native_in_isr--; return; } /* XXX: Workaround safety check - whenever this happens it really * indicates a bug in irq_disable */ if (native_interrupts_enabled == 0) { //printf("interrupts are off, but I caught a signal.\n"); return; } if (_native_in_isr != 0) { //real_write(STDOUT_FILENO, "interrupts in ISR!!\n", 20); return; } if (_native_in_syscall != 0) { DEBUG("\n\n\t\tnative_isr_entry: return to syscall\n\n"); return; } native_isr_context.uc_stack.ss_sp = __isr_stack; native_isr_context.uc_stack.ss_size = sizeof(__isr_stack); native_isr_context.uc_stack.ss_flags = 0; makecontext(&native_isr_context, native_irq_handler, 0); _native_cur_ctx = (ucontext_t *)sched_active_thread->sp; DEBUG("\n\n\t\tnative_isr_entry: return to _native_sig_leave_tramp\n\n"); /* disable interrupts in context */ isr_set_sigmask((ucontext_t *)context); _native_in_isr = 1; /* * For register access on new platforms see: * http://google-glog.googlecode.com/svn/trunk/m4/pc_from_ucontext.m4 * (URL added on Fri Aug 29 17:17:45 CEST 2014) */ #ifdef __MACH__ _native_saved_eip = ((ucontext_t *)context)->uc_mcontext->__ss.__eip; ((ucontext_t *)context)->uc_mcontext->__ss.__eip = (unsigned int)&_native_sig_leave_tramp; #elif defined(__FreeBSD__) _native_saved_eip = ((struct sigcontext *)context)->sc_eip; ((struct sigcontext *)context)->sc_eip = (unsigned int)&_native_sig_leave_tramp; #else /* Linux */ #if defined(__arm__) _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.arm_pc; ((ucontext_t *)context)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_tramp; #else /* Linux/x86 */ //printf("\n\033[31mEIP:\t%p\ngo switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]); _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]; ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp; #endif #endif }