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; }
static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size) { unsigned long sp = regs->sp; /* redzone */ sp -= STACK_FRAME_OVERHEAD; sp = sigsp(sp, ksig); sp = align_sigframe(sp - frame_size); 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; }