static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (in_syscall(regs)) { /* Avoid additional syscall restarting via ret_from_exception */ forget_syscall(regs); /* If so, check system call restarting.. */ switch (regs->a0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->a0 = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->a0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->a0 = regs->orig_a0; regs->pc -= TRAP0_SIZE; break; } } /* Set up the stack frame */ ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 0); }
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { int ret; /* Are we from a system call? */ if (regs->syscall_nr >= 0) { /* If so, check system call restarting.. */ switch (regs->r0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->r0 = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->r0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->r0 = regs->orig_r0; if (prev_insn(regs) < 0) return; } } /* Set up the stack frame */ ret = setup_rt_frame(ksig, sigmask_to_save(), regs); signal_setup_done(ret, ksig, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* * Increment event counter and perform fixup for the pre-signal * frame. */ rseq_signal_deliver(ksig, regs); /* * Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(ksig, oldset, regs); /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(regs); signal_setup_done(ret, ksig, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = ksig->sig; int ret; /* * Set up the stack frame */ if (is_compat_task()) { if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = compat_setup_rt_frame(usig, ksig, oldset, regs); else ret = compat_setup_frame(usig, ksig, oldset, regs); } else { ret = setup_rt_frame(usig, ksig, oldset, regs); } /* * Check that the resulting registers are actually sane. */ ret |= !valid_user_regs(®s->user_regs, current); /* * Fast forward the stepping logic so we step into the signal * handler. */ if (!ret) user_fastforward_single_step(tsk); signal_setup_done(ret, ksig, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { int ret; sigset_t *oldset = sigmask_to_save(); if (in_syscall(regs)) { /* Avoid additional syscall restarting via ret_slow_syscall. */ forget_syscall(regs); switch (regs->uregs[0]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->uregs[0] = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->uregs[0] = -EINTR; break; } case -ERESTARTNOINTR: regs->uregs[0] = regs->orig_r0; regs->ipc -= 4; break; } } /* * Set up the stack frame */ ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 0); }
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (regs->cause == EXC_SYSCALL) { /* If so, check system call restarting.. */ switch (regs->v[0]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->v[0] = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->v[0] = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->v[0] = regs->syscallno; regs->epc -= 0x4; break; } } /* Set up the stack frame */ ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 0); }
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 0); }
static inline void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { int ret; ret = setup_rt_frame(ksig, sigmask_to_save(), regs); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); }
static long handle_signal (struct ksignal *ksig, struct sigscratch *scr) { int ret = setup_frame(ksig, sigmask_to_save(), scr); if (!ret) signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); return ret; }
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Set up the stack frame */ ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); }
static inline void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int err; if (ksig->ka.sa.sa_flags & SA_SIGINFO) err = setup_rt_frame(ksig, regs, oldset); else err = setup_frame(ksig, regs, oldset); signal_setup_done(err, ksig, 0); }
static void handle_signal(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs) { int ret; /* Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(ksig->sig, &ksig->ka, oldset, regs); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP)); }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* are we from a system call? */ if (regs->orig_er0 >= 0) handle_restart(regs, &ksig->ka); ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 0); }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0) { sigset_t *oldset = sigmask_to_save(); int ret; /* Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); }
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; struct mips_abi *abi = current->thread.abi; #ifdef CONFIG_CPU_MICROMIPS void *vdso; unsigned long tmp = (unsigned long)current->mm->context.vdso; set_isa16_mode(tmp); vdso = (void *)tmp; #else void *vdso = current->mm->context.vdso; #endif if (regs->regs[0]) { switch(regs->regs[2]) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: regs->regs[2] = EINTR; break; case ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->regs[2] = EINTR; break; } /* fallthrough */ case ERESTARTNOINTR: regs->regs[7] = regs->regs[26]; regs->regs[2] = regs->regs[0]; regs->cp0_epc -= 4; } regs->regs[0] = 0; /* Don't deal with this again. */ } if (sig_uses_siginfo(&ksig->ka)) ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, ksig, regs, oldset); else ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig, regs, oldset); signal_setup_done(ret, ksig, 0); }
static inline void handle_signal(int canrestart, struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (canrestart) { /* If so, check system call restarting.. */ switch (regs->r10) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: /* ERESTARTNOHAND means that the syscall should * only be restarted if there was no handler for * the signal, and since we only get here if there * is a handler, we don't restart */ regs->r10 = -EINTR; break; case -ERESTARTSYS: /* ERESTARTSYS means to restart the syscall if * there is no handler or the handler was * registered with SA_RESTART */ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->r10 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: /* ERESTARTNOINTR means that the syscall should * be called again after the signal handler returns. */ RESTART_CRIS_SYS(regs); } } /* Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, 0); }
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (regs->faultnum == INT_SWINT_1) { /* If so, check system call restarting.. */ switch (regs->regs[0]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->regs[0] = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->regs[0] = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: /* Reload caller-saves to restore r0..r5 and r10. */ regs->flags |= PT_FLAGS_CALLER_SAVES; regs->regs[0] = regs->orig_r0; regs->pc -= 8; } } /* Set up the stack frame */ #ifdef CONFIG_COMPAT if (is_compat_task()) ret = compat_setup_rt_frame(ksig, oldset, regs); else #endif ret = setup_rt_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); }
/* * handle the actual delivery of a signal to userspace */ static int handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (regs->orig_d0 >= 0) { /* If so, check system call restarting.. */ switch (regs->d0) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->d0 = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->d0 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: regs->d0 = regs->orig_d0; stepback(regs); } } /* Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset, regs); else ret = setup_frame(ksig, oldset, regs); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); return 0; }
/* * OK, we're invoking a handler */ static void handle_signal(struct ksignal *ksig) { sigset_t *oldset = sigmask_to_save(); int ret; /* Are we from a system call? */ if (__frame->syscallno != -1) { /* If so, check system call restarting.. */ switch (__frame->gr8) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: __frame->gr8 = -EINTR; break; case -ERESTARTSYS: if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { __frame->gr8 = -EINTR; break; } /* fallthrough */ case -ERESTARTNOINTR: __frame->gr8 = __frame->orig_gr8; __frame->pc -= 4; } __frame->syscallno = -1; } /* Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(ksig, oldset); else ret = setup_frame(ksig, oldset); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); } /* end handle_signal() */
/* Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct ksignal ksig; int restart_syscall; bool has_handler; /* It's a lot of work and synchronization to add a new ptrace * register for GDB to save and restore in order to get * orig_i0 correct for syscall restarts when debugging. * * Although it should be the case that most of the global * registers are volatile across a system call, glibc already * depends upon that fact that we preserve them. So we can't * just use any global register to save away the orig_i0 value. * * In particular %g2, %g3, %g4, and %g5 are all assumed to be * preserved across a system call trap by various pieces of * code in glibc. * * %g7 is used as the "thread register". %g6 is not used in * any fixed manner. %g6 is used as a scratch register and * a compiler temporary, but it's value is never used across * a system call. Therefore %g6 is usable for orig_i0 storage. */ if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) regs->u_regs[UREG_G6] = orig_i0; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(struct pt_regs *); do_signal32(regs); return; } #endif has_handler = get_signal(&ksig); restart_syscall = 0; if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { restart_syscall = 1; orig_i0 = regs->u_regs[UREG_G6]; } if (has_handler) { if (restart_syscall) syscall_restart(orig_i0, regs, &ksig.ka.sa); signal_setup_done(setup_rt_frame(&ksig, regs), &ksig, 0); } else { if (restart_syscall) { switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } } restore_saved_sigmask(); } }