Exemplo n.º 1
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 (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);
}
Exemplo n.º 2
0
Arquivo: signal.c Projeto: 12zz/linux
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);
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
Arquivo: signal.c Projeto: Artox/linux
/*
 * 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(&regs->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);
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
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));
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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));
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
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));
}
Exemplo n.º 13
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;
	/* 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));
}
Exemplo n.º 15
0
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);
}
Exemplo n.º 16
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);
}
Exemplo n.º 17
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));
}
Exemplo n.º 18
0
/*
 * 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;
}
Exemplo n.º 19
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() */
Exemplo n.º 20
0
/* 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();
	}
}