static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp = regs->sp; int onsigstack = on_sig_stack(sp); /* */ sp -= STACK_FRAME_OVERHEAD; /* */ if ((ka->sa.sa_flags & SA_ONSTACK) && !onsigstack) { if (current->sas_ss_size) sp = current->sas_ss_sp + current->sas_ss_size; } sp = align_sigframe(sp - frame_size); /* */ if (onsigstack && !likely(on_sig_stack(sp))) return (void __user *)-1L; return (void __user *)sp; }
/* * Determine which stack to use.. */ static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) { unsigned long sp; /* Default to using normal stack */ sp = regs->gprs[15]; /* Overflow on alternate signal stack gives SIGSEGV. */ if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL)) return (void __user *) -1UL; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (! sas_ss_flags(sp)) sp = current->sas_ss_sp + current->sas_ss_size; } /* This is the legacy signal stack switching. */ else if (!user_mode(regs) && !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer) { sp = (unsigned long) ka->sa.sa_restorer; } return (void __user *)((sp - frame_size) & -8ul); }
static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; /* * 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 (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack * alignment. Second, if we took this signal because the stack * is not aligned properly, we'd like to take the signal cleanly * and report that. */ sp &= ~15UL; return (void __user *) sp; }
/* * Determine which stack to use.. */ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp; /* Default to using normal stack */ sp = regs->sp; /* * 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 (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) return (void __user __force *)-1UL; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= frame_size; /* * Align the stack pointer according to the TILE ABI, * i.e. so that on function entry (sp & 15) == 0. */ sp &= -16UL; return (void __user *) sp; }
static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize) { unsigned long sp; /* Default to using normal stack */ sp = regs->sp; /* * 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 (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) return (void __user __force *)(-1UL); /* This is the X/Open sanctioned signal stack switching. */ sp = (sigsp(sp, ksig) - framesize); /* * nds32 mandates 8-byte alignment */ sp &= ~0x7UL; return (void __user *)sp; }
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 math_size = 0; unsigned long sp = regs->sp; unsigned long buf_fx = 0; int onsigstack = on_sig_stack(sp); /* redzone */ if (config_enabled(CONFIG_X86_64)) sp -= 128; 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 if (config_enabled(CONFIG_X86_32) && (regs->ss & 0xffff) != __USER_DS && #ifdef CONFIG_KERNEL_MODE_LINUX (regs->sp > TASK_SIZE) && #endif !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer) { /* This is the legacy signal stack switching. */ sp = (unsigned long) ka->sa.sa_restorer; } } if (used_math()) { sp = alloc_mathframe(sp, config_enabled(CONFIG_X86_32), &buf_fx, &math_size); *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 and extended state */ if (used_math() && save_xstate_sig(*fpstate, (void __user *)buf_fx, math_size) < 0) return (void __user *)-1L; return (void __user *)sp; }
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; }
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; }
/* * This does just the minimum required setup of sigcontext. * Specifically, it only installs data that is either not knowable at * the user-level or that gets modified before execution in the * trampoline starts. Everything else is done at the user-level. */ static long setup_sigcontext (struct sigcontext __user *sc, sigset_t *mask, struct sigscratch *scr) { unsigned long flags = 0, ifs, cfm, nat; long err; ifs = scr->pt.cr_ifs; if (on_sig_stack((unsigned long) sc)) flags |= IA64_SC_FLAG_ONSTACK; if ((ifs & (1UL << 63)) == 0) /* if cr_ifs doesn't have the valid bit set, we got here through a syscall */ flags |= IA64_SC_FLAG_IN_SYSCALL; cfm = ifs & ((1UL << 38) - 1); ia64_flush_fph(current); if ((current->thread.flags & IA64_THREAD_FPH_VALID)) { flags |= IA64_SC_FLAG_FPH_VALID; __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16); } nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat); err = __put_user(flags, &sc->sc_flags); err |= __put_user(nat, &sc->sc_nat); err |= PUT_SIGSET(mask, &sc->sc_mask); err |= __put_user(cfm, &sc->sc_cfm); err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um); err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); err |= __put_user(scr->pt.ar_unat, &sc->sc_ar_unat); /* ar.unat */ err |= __put_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); /* ar.fpsr */ err |= __put_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); err |= __put_user(scr->pt.pr, &sc->sc_pr); /* predicates */ err |= __put_user(scr->pt.b0, &sc->sc_br[0]); /* b0 (rp) */ err |= __put_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */ err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 8); /* r1 */ err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8); /* r8-r11 */ err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 2*8); /* r12-r13 */ err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8); /* r15 */ err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip); if (flags & IA64_SC_FLAG_IN_SYSCALL) { /* Clear scratch registers if the signal interrupted a system call. */ err |= __put_user(0, &sc->sc_ar_ccv); /* ar.ccv */ err |= __put_user(0, &sc->sc_br[7]); /* b7 */ err |= __put_user(0, &sc->sc_gr[14]); /* r14 */ err |= __clear_user(&sc->sc_ar25, 2*8); /* ar.csd & ar.ssd */ err |= __clear_user(&sc->sc_gr[2], 2*8); /* r2-r3 */ err |= __clear_user(&sc->sc_gr[16], 16*8); /* r16-r31 */ } else { /* Copy scratch regs to sigcontext if the signal didn't interrupt a syscall. */ err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); /* ar.ccv */ err |= __put_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */ err |= __put_user(scr->pt.r14, &sc->sc_gr[14]); /* r14 */ err |= __copy_to_user(&sc->sc_ar25, &scr->pt.ar_csd, 2*8); /* ar.csd & ar.ssd */ err |= __copy_to_user(&sc->sc_gr[2], &scr->pt.r2, 2*8); /* r2-r3 */ err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8); /* r16-r31 */ } return err; }
static inline void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) { if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void __user *)((sp - frame_size) & -32ul); }
/* * Set up the sigcontext structure for this process. * This is not an easy task if the kernel is 64-bit, it will require * that we examine the process personality to determine if we need to * truncate for a 32-bit userspace. */ long setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, struct pt_regs *regs, int in_syscall) { compat_int_t flags = 0; long err = 0; compat_uint_t compat_reg; compat_uint_t compat_regb; int regn; if (on_sig_stack((unsigned long) sc)) flags |= PARISC_SC_FLAG_ONSTACK; if (in_syscall) { DBG(1,"setup_sigcontext32: in_syscall\n"); flags |= PARISC_SC_FLAG_IN_SYSCALL; /* Truncate gr31 */ compat_reg = (compat_uint_t)(regs->gr[31]); /* regs->iaoq is undefined in the syscall return path */ err |= __put_user(compat_reg, &sc->sc_iaoq[0]); DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n", &sc->sc_iaoq[0], compat_reg); /* Store upper half */ compat_reg = (compat_uint_t)(regs->gr[31] >> 32); err |= __put_user(compat_reg, &rf->rf_iaoq[0]); DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg); compat_reg = (compat_uint_t)(regs->gr[31]+4); err |= __put_user(compat_reg, &sc->sc_iaoq[1]); DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n", &sc->sc_iaoq[1], compat_reg); /* Store upper half */ compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32); err |= __put_user(compat_reg, &rf->rf_iaoq[1]); DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg); /* Truncate sr3 */ compat_reg = (compat_uint_t)(regs->sr[3]); err |= __put_user(compat_reg, &sc->sc_iasq[0]); err |= __put_user(compat_reg, &sc->sc_iasq[1]); /* Store upper half */ compat_reg = (compat_uint_t)(regs->sr[3] >> 32); err |= __put_user(compat_reg, &rf->rf_iasq[0]); err |= __put_user(compat_reg, &rf->rf_iasq[1]); DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg); DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg); DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n", regs->gr[31], regs->gr[31]+4); } else {
static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, unsigned long sp) { struct switch_stack *sw = (struct switch_stack *)regs - 1; long i, err = 0; err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack); err |= __put_user(mask, &sc->sc_mask); err |= __put_user(regs->pc, &sc->sc_pc); err |= __put_user(8, &sc->sc_ps); err |= __put_user(regs->r0 , sc->sc_regs+0); err |= __put_user(regs->r1 , sc->sc_regs+1); err |= __put_user(regs->r2 , sc->sc_regs+2); err |= __put_user(regs->r3 , sc->sc_regs+3); err |= __put_user(regs->r4 , sc->sc_regs+4); err |= __put_user(regs->r5 , sc->sc_regs+5); err |= __put_user(regs->r6 , sc->sc_regs+6); err |= __put_user(regs->r7 , sc->sc_regs+7); err |= __put_user(regs->r8 , sc->sc_regs+8); err |= __put_user(sw->r9 , sc->sc_regs+9); err |= __put_user(sw->r10 , sc->sc_regs+10); err |= __put_user(sw->r11 , sc->sc_regs+11); err |= __put_user(sw->r12 , sc->sc_regs+12); err |= __put_user(sw->r13 , sc->sc_regs+13); err |= __put_user(sw->r14 , sc->sc_regs+14); err |= __put_user(sw->r15 , sc->sc_regs+15); err |= __put_user(regs->r16, sc->sc_regs+16); err |= __put_user(regs->r17, sc->sc_regs+17); err |= __put_user(regs->r18, sc->sc_regs+18); err |= __put_user(regs->r19, sc->sc_regs+19); err |= __put_user(regs->r20, sc->sc_regs+20); err |= __put_user(regs->r21, sc->sc_regs+21); err |= __put_user(regs->r22, sc->sc_regs+22); err |= __put_user(regs->r23, sc->sc_regs+23); err |= __put_user(regs->r24, sc->sc_regs+24); err |= __put_user(regs->r25, sc->sc_regs+25); err |= __put_user(regs->r26, sc->sc_regs+26); err |= __put_user(regs->r27, sc->sc_regs+27); err |= __put_user(regs->r28, sc->sc_regs+28); err |= __put_user(regs->gp , sc->sc_regs+29); err |= __put_user(sp, sc->sc_regs+30); err |= __put_user(0, sc->sc_regs+31); for (i = 0; i < 31; i++) err |= __put_user(sw->fp[i], sc->sc_fpregs+i); err |= __put_user(0, sc->sc_fpregs+31); err |= __put_user(sw->fp[31], &sc->sc_fpcr); err |= __put_user(regs->trap_a0, &sc->sc_traparg_a0); err |= __put_user(regs->trap_a1, &sc->sc_traparg_a1); err |= __put_user(regs->trap_a2, &sc->sc_traparg_a2); return err; }
static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) return (void __user *) -1L; if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; sp &= ~15UL; return (void __user *) sp; }
/* * Determine which stack to use.. */ static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, void **fpstate) { unsigned long sp; /* Default to using normal stack */ sp = regs->sp; /* * 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 (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } else { /* 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; } if (used_math()) { sp = sp - sig_xstate_size; *fpstate = (struct _fpstate *) sp; } sp -= frame_size; /* * Align the stack pointer according to the i386 ABI, * i.e. so that on function entry ((sp + 4) & 15) == 0. */ sp = ((sp + 4) & -16ul) - 4; return (void __user *) sp; }
/* * This does just the minimum required setup of sigcontext. * Specifically, it only installs data that is either not knowable at * the user-level or that gets modified before execution in the * trampoline starts. Everything else is done at the user-level. */ static long setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct sigscratch *scr) { unsigned long flags = 0, ifs, cfm, nat; long err; ifs = scr->pt.cr_ifs; if (on_sig_stack((unsigned long) sc)) flags |= IA64_SC_FLAG_ONSTACK; if ((ifs & (1UL << 63)) == 0) { /* if cr_ifs isn't valid, we got here through a syscall */ flags |= IA64_SC_FLAG_IN_SYSCALL; cfm = scr->pad & ((1UL << 38) - 1); } else cfm = ifs & ((1UL << 38) - 1); ia64_flush_fph(current); if ((current->thread.flags & IA64_THREAD_FPH_VALID)) { flags |= IA64_SC_FLAG_FPH_VALID; __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16); } /* * Note: sw->ar_unat is UNDEFINED unless the process is being * PTRACED. However, this is OK because the NaT bits of the * preserved registers (r4-r7) are never being looked at by * the signal handler (registers r4-r7 are used instead). */ nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat); err = __put_user(flags, &sc->sc_flags); err |= __put_user(nat, &sc->sc_nat); err |= PUT_SIGSET(mask, &sc->sc_mask); err |= __put_user(cfm, &sc->sc_cfm); err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um); err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); err |= __put_user(scr->pt.ar_unat, &sc->sc_ar_unat); /* ar.unat */ err |= __put_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); /* ar.fpsr */ err |= __put_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); err |= __put_user(scr->pt.pr, &sc->sc_pr); /* predicates */ err |= __put_user(scr->pt.b0, &sc->sc_br[0]); /* b0 (rp) */ err |= __put_user(scr->pt.b6, &sc->sc_br[6]); /* b6 */ err |= __put_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */ err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 3*8); /* r1-r3 */ err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8); /* r8-r11 */ err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 4*8); /* r12-r15 */ err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8); /* r16-r31 */ err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip); return err; }
/* * Determine which stack to use.. */ static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { /* Default to using normal stack */ unsigned long sp = regs->gpr[GPR_SP]; if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void *)((sp - frame_size) & -8UL); }
static inline void __user *compat_get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp; sp = (unsigned long)compat_ptr(regs->sp); if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) return (void __user __force *)-1UL; if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= frame_size; sp &= -16UL; return (void __user *) sp; }
static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { unsigned long sp; sp = regs->u_regs[UREG_FP] + STACK_BIAS; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) sp = current->sas_ss_sp + current->sas_ss_size; } return (void __user *)(sp - framesize); }
static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long usp; /* Default to using normal stack. */ usp = rdusp(); /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (!on_sig_stack(usp)) usp = current->sas_ss_sp + current->sas_ss_size; } return (void *)((usp - frame_size) & -8UL); }
asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr, unsigned long sp) { int ret = -EFAULT; /* First see if old state is wanted. */ if (ossptr) { if (put_user(current->sas_ss_sp + current->sas_ss_size, &ossptr->the_stack) || __put_user(on_sig_stack(sp), &ossptr->cur_status)) goto out; } /* Now see if we want to update the new state. */ if (ssptr) { char *ss_sp; if (get_user(ss_sp, &ssptr->the_stack)) goto out; /* If the current stack was set with sigaltstack, don't swap stacks while we are on it. */ ret = -EPERM; if (current->sas_ss_sp && on_sig_stack(sp)) goto out; /* Since we don't know the extent of the stack, and we don't track onstack-ness, but rather calculate it, we must presume a size. Ho hum this interface is lossy. */ current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ; current->sas_ss_size = SIGSTKSZ; } ret = 0; out: return ret; }
/* * Allocate space for the signal frame */ static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long newsp; /* Default to using normal stack */ newsp = regs->gpr[1]; if (ka->sa.sa_flags & SA_ONSTACK) { if (! on_sig_stack(regs->gpr[1])) newsp = (current->sas_ss_sp + current->sas_ss_size); } return (void __user *)((newsp - frame_size) & -16ul); }
static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp = rdusp(); /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; } /* make sure the frame is dword-aligned */ sp &= ~3; return (void __user*)(sp - frame_size); }
/* * Determine which stack to use.. */ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp; /* Default to using normal stack */ sp = regs->sp; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; } return (void __user *) ((sp - frame_size) & ~7UL); } /* end get_sigframe() */
/* * Allocate space for the signal frame */ static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long newsp; /* Default to using normal stack */ newsp = regs->gpr[1]; if (ka->sa.sa_flags & SA_ONSTACK) { if (! on_sig_stack(regs->gpr[1])) newsp = (current->sas_ss_sp + current->sas_ss_size); } /* The ABI requires quadword alignment for the stack. */ return (void *)((newsp - frame_size) & -16ul); }
static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp = rdusp(); if (ka->sa.sa_flags & SA_ONSTACK) { if (! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; } sp &= ~3; return (void __user*)(sp - frame_size); }
static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->ARM_sp; /* * This is the X/Open sanctioned signal stack switching. */ if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; /* * No matter what happens, 'sp' must be word * aligned otherwise nasty things could happen */ sp &= ~3; return (void *)(sp - framesize); }
/* * Determine which stack to use.. */ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp; /* Default to using normal stack */ sp = regs->regs[29]; /* * FPU emulator may have it's own trampoline active just * above the user stack, 16-bytes before the next lowest * 16 byte boundary. Try to avoid trashing it. */ sp -= 32; /* This is the X/Open sanctioned signal stack switching. */ if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void *)((sp - frame_size) & ALMASK); }
/* * Allocate space for the signal frame */ void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long oldsp, newsp; /* Default to using normal stack */ oldsp = regs->gpr[1]; /* Check for alt stack */ if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size && !on_sig_stack(oldsp)) oldsp = (current->sas_ss_sp + current->sas_ss_size); /* Get aligned frame */ newsp = (oldsp - frame_size) & ~0xFUL; /* Check access */ if (!access_ok(VERIFY_WRITE, (void __user *)newsp, oldsp - newsp)) return NULL; return (void __user *)newsp; }
void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, int is_32) { unsigned long oldsp, newsp; oldsp = get_clean_sp(regs, is_32); if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size && !on_sig_stack(oldsp)) oldsp = (current->sas_ss_sp + current->sas_ss_size); newsp = (oldsp - frame_size) & ~0xFUL; if (!access_ok(VERIFY_WRITE, (void __user *)newsp, oldsp - newsp)) return NULL; return (void __user *)newsp; }
/* * 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. */ int do_signal(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; struct k_sigaction ka; unsigned long frame, newsp; int signr, ret; if (!oldset) oldset = ¤t->blocked; newsp = frame = 0; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (TRAP(regs) == 0x0C00 /* System Call! */ && regs->ccr & 0x10000000 /* error signalled */ && ((ret = regs->gpr[3]) == ERESTARTSYS || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR || ret == ERESTART_RESTARTBLOCK)) { if (signr > 0 && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK || (ret == ERESTARTSYS && !(ka.sa.sa_flags & SA_RESTART)))) { /* make the system call return an EINTR error */ regs->result = -EINTR; regs->gpr[3] = EINTR; /* note that the cr0.SO bit is already set */ } else { regs->nip -= 4; /* Back up & retry system call */ regs->result = 0; regs->trap = 0; if (ret == ERESTART_RESTARTBLOCK) regs->gpr[0] = __NR_restart_syscall; else regs->gpr[3] = regs->orig_gpr3; } } if (signr == 0) return 0; /* no signals delivered */ if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size && !on_sig_stack(regs->gpr[1])) newsp = current->sas_ss_sp + current->sas_ss_size; else newsp = regs->gpr[1]; newsp &= ~0xfUL; /* Whee! Actually deliver the signal. */ if (ka.sa.sa_flags & SA_SIGINFO) handle_rt_signal(signr, &ka, &info, oldset, regs, newsp); else handle_signal(signr, &ka, &info, oldset, regs, newsp); if (!(ka.sa.sa_flags & SA_NODEFER)) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka.sa.sa_mask); sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } return 1; }