예제 #1
0
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
	     void __user **fpstate)
{
	/*                               */
	unsigned long sp = regs->sp;
	int onsigstack = on_sig_stack(sp);

#ifdef CONFIG_X86_64
	/*         */
	sp -= 128;
#endif /*               */

	if (!onsigstack) {
		/*                                                        */
		if (ka->sa.sa_flags & SA_ONSTACK) {
			if (current->sas_ss_size)
				sp = current->sas_ss_sp + current->sas_ss_size;
		} else {
#ifdef CONFIG_X86_32
			/*                                            */
			if ((regs->ss & 0xffff) != __USER_DS &&
				!(ka->sa.sa_flags & SA_RESTORER) &&
					ka->sa.sa_restorer)
				sp = (unsigned long) ka->sa.sa_restorer;
#endif /*               */
		}
	}

	if (used_math()) {
		sp -= sig_xstate_size;
#ifdef CONFIG_X86_64
		sp = round_down(sp, 64);
#endif /*               */
		*fpstate = (void __user *)sp;
	}

	sp = align_sigframe(sp - frame_size);

	/*
                                                                         
                                                                       
  */
	if (onsigstack && !likely(on_sig_stack(sp)))
		return (void __user *)-1L;

	/*                 */
	if (used_math() && save_i387_xstate(*fpstate) < 0)
		return (void __user *)-1L;

	return (void __user *)sp;
}
예제 #2
0
파일: signal.c 프로젝트: 3null/fastsocket
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
	     void __user **fpstate)
{
	/* Default to using normal stack */
	unsigned long sp = regs->sp;
	int onsigstack = on_sig_stack(sp);

#ifdef CONFIG_X86_64
	/* redzone */
	sp -= 128;
#endif /* CONFIG_X86_64 */

	if (!onsigstack) {
		/* This is the X/Open sanctioned signal stack switching.  */
		if (ka->sa.sa_flags & SA_ONSTACK) {
			if (current->sas_ss_size)
				sp = current->sas_ss_sp + current->sas_ss_size;
		} else {
#ifdef CONFIG_X86_32
			/* This is the legacy signal stack switching. */
			if ((regs->ss & 0xffff) != __USER_DS &&
				!(ka->sa.sa_flags & SA_RESTORER) &&
					ka->sa.sa_restorer)
				sp = (unsigned long) ka->sa.sa_restorer;
#endif /* CONFIG_X86_32 */
		}
	}

	if (used_math()) {
		sp -= sig_xstate_size;
#ifdef CONFIG_X86_64
		sp = round_down(sp, 64);
#endif /* CONFIG_X86_64 */
		*fpstate = (void __user *)sp;
	}

	sp = align_sigframe(sp - frame_size);

	/*
	 * If we are on the alternate signal stack and would overflow it, don't.
	 * Return an always-bogus address instead so we will die with SIGSEGV.
	 */
	if (onsigstack && !likely(on_sig_stack(sp)))
		return (void __user *)-1L;

	/* save i387 state */
	if (used_math() && save_i387_xstate(*fpstate) < 0)
		return (void __user *)-1L;

	return (void __user *)sp;
}
예제 #3
0
/*
 * Set up a signal frame.
 */
static int
setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
		 struct pt_regs *regs, unsigned long mask)
{
	int tmp, err = 0;

	err |= __put_user(regs->fs, (unsigned int __user *)&sc->fs);
	savesegment(gs, tmp);
	err |= __put_user(tmp, (unsigned int __user *)&sc->gs);

	err |= __put_user(regs->es, (unsigned int __user *)&sc->es);
	err |= __put_user(regs->ds, (unsigned int __user *)&sc->ds);
	err |= __put_user(regs->di, &sc->di);
	err |= __put_user(regs->si, &sc->si);
	err |= __put_user(regs->bp, &sc->bp);
	err |= __put_user(regs->sp, &sc->sp);
	err |= __put_user(regs->bx, &sc->bx);
	err |= __put_user(regs->dx, &sc->dx);
	err |= __put_user(regs->cx, &sc->cx);
	err |= __put_user(regs->ax, &sc->ax);
	err |= __put_user(current->thread.trap_no, &sc->trapno);
	err |= __put_user(current->thread.error_code, &sc->err);
	err |= __put_user(regs->ip, &sc->ip);
	err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
	err |= __put_user(regs->flags, &sc->flags);
	err |= __put_user(regs->sp, &sc->sp_at_signal);
	err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);

	tmp = save_i387_xstate(fpstate);
	if (tmp < 0)
		err = 1;
	else
		err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);

	/* non-iBCS2 extensions.. */
	err |= __put_user(mask, &sc->oldmask);
	err |= __put_user(current->thread.cr2, &sc->cr2);

	return err;
}