diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 47856455f099..92915b6a116d 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -157,6 +157,9 @@ ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler)); ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc)); #endif ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); +#ifdef COMPAT_FREEBSD4 +ASSYM(SIGF_UC4, offsetof(struct sigframe4, sf_uc)); +#endif #ifdef COMPAT_43 ASSYM(SC_PS, offsetof(struct osigcontext, sc_ps)); ASSYM(SC_FS, offsetof(struct osigcontext, sc_fs)); diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S index 8f1d801268b3..19a6ac7117c1 100644 --- a/sys/amd64/amd64/locore.S +++ b/sys/amd64/amd64/locore.S @@ -394,32 +394,36 @@ begin: * Signal trampoline, copied to top of user stack */ NON_GPROF_ENTRY(sigcode) - call *SIGF_HANDLER(%esp) /* call signal handler */ - lea SIGF_UC(%esp),%eax /* get ucontext_t */ + calll *SIGF_HANDLER(%esp) + leal SIGF_UC(%esp),%eax /* get ucontext */ pushl %eax testl $PSL_VM,UC_EFLAGS(%eax) - jne 9f + jne 1f movl UC_GS(%eax),%gs /* restore %gs */ -9: +1: movl $SYS_sigreturn,%eax pushl %eax /* junk to fake return addr. */ int $0x80 /* enter kernel with args */ -0: jmp 0b + /* on stack */ +1: + jmp 1b #ifdef COMPAT_FREEBSD4 ALIGN_TEXT freebsd4_sigcode: - call *SIGF_HANDLER(%esp) /* call signal handler */ - lea SIGF_UC(%esp),%eax /* get ucontext_t */ + calll *SIGF_HANDLER(%esp) + leal SIGF_UC4(%esp),%eax /* get ucontext */ pushl %eax testl $PSL_VM,UC4_EFLAGS(%eax) - jne 9f + jne 1f movl UC4_GS(%eax),%gs /* restore %gs */ -9: +1: movl $344,%eax /* 4.x SYS_sigreturn */ pushl %eax /* junk to fake return addr. */ int $0x80 /* enter kernel with args */ -0: jmp 0b + /* on stack */ +1: + jmp 1b #endif #ifdef COMPAT_43 diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s index 8f1d801268b3..19a6ac7117c1 100644 --- a/sys/amd64/amd64/locore.s +++ b/sys/amd64/amd64/locore.s @@ -394,32 +394,36 @@ begin: * Signal trampoline, copied to top of user stack */ NON_GPROF_ENTRY(sigcode) - call *SIGF_HANDLER(%esp) /* call signal handler */ - lea SIGF_UC(%esp),%eax /* get ucontext_t */ + calll *SIGF_HANDLER(%esp) + leal SIGF_UC(%esp),%eax /* get ucontext */ pushl %eax testl $PSL_VM,UC_EFLAGS(%eax) - jne 9f + jne 1f movl UC_GS(%eax),%gs /* restore %gs */ -9: +1: movl $SYS_sigreturn,%eax pushl %eax /* junk to fake return addr. */ int $0x80 /* enter kernel with args */ -0: jmp 0b + /* on stack */ +1: + jmp 1b #ifdef COMPAT_FREEBSD4 ALIGN_TEXT freebsd4_sigcode: - call *SIGF_HANDLER(%esp) /* call signal handler */ - lea SIGF_UC(%esp),%eax /* get ucontext_t */ + calll *SIGF_HANDLER(%esp) + leal SIGF_UC4(%esp),%eax /* get ucontext */ pushl %eax testl $PSL_VM,UC4_EFLAGS(%eax) - jne 9f + jne 1f movl UC4_GS(%eax),%gs /* restore %gs */ -9: +1: movl $344,%eax /* 4.x SYS_sigreturn */ pushl %eax /* junk to fake return addr. */ int $0x80 /* enter kernel with args */ -0: jmp 0b + /* on stack */ +1: + jmp 1b #endif #ifdef COMPAT_43 diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 1aedc3db1f25..27b3bcac7b5e 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -506,6 +506,7 @@ sendsig(catcher, sig, mask, code) struct proc *p; struct thread *td; struct sigacts *psp; + char *sp; struct trapframe *regs; int oonstack; @@ -544,13 +545,15 @@ sendsig(catcher, sig, mask, code) /* Allocate space for the signal handler context. */ if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { - sfp = (struct sigframe *)(p->p_sigstk.ss_sp + - p->p_sigstk.ss_size - sizeof(struct sigframe)); + sp = p->p_sigstk.ss_sp + + p->p_sigstk.ss_size - sizeof(struct sigframe); #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_sigstk.ss_flags |= SS_ONSTACK; #endif } else - sfp = (struct sigframe *)regs->tf_esp - 1; + sp = (char *)regs->tf_esp - sizeof(struct sigframe); + /* Align to 16 bytes. */ + sfp = (struct sigframe *)((unsigned int)sp & ~0xF); PROC_UNLOCK(p); /* Translate the signal if appropriate. */ diff --git a/sys/amd64/include/signal.h b/sys/amd64/include/signal.h index efc7ef045888..fb2d82c4d489 100644 --- a/sys/amd64/include/signal.h +++ b/sys/amd64/include/signal.h @@ -100,7 +100,7 @@ struct osigcontext { struct sigcontext { struct __sigset sc_mask; /* signal mask to restore */ int sc_onstack; /* sigstack state to restore */ - int sc_gs; /* machine state (struct trapframe): */ + int sc_gs; /* machine state (struct trapframe) */ int sc_fs; int sc_es; int sc_ds; @@ -127,7 +127,7 @@ struct sigcontext { int sc_fpformat; int sc_ownedfp; int sc_spare1[1]; - int sc_fpstate[128]; + int sc_fpstate[128] __aligned(16); int sc_spare2[8]; }; diff --git a/sys/amd64/include/ucontext.h b/sys/amd64/include/ucontext.h index ea6f0b6b1b8f..ec3e0eefaea2 100644 --- a/sys/amd64/include/ucontext.h +++ b/sys/amd64/include/ucontext.h @@ -38,7 +38,7 @@ typedef struct __mcontext { * and ucontext_t at the same time. */ int mc_onstack; /* XXX - sigcontext compat. */ - int mc_gs; /* machine state (trapframe) */ + int mc_gs; /* machine state (struct trapframe) */ int mc_fs; int mc_es; int mc_ds; @@ -68,15 +68,17 @@ typedef struct __mcontext { #define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */ int mc_ownedfp; int mc_spare1[1]; /* align next field to 16 bytes */ - int mc_fpstate[128]; /* must be multiple of 16 bytes */ + /* + * See for the internals of mc_fpstate[]. + */ + int mc_fpstate[128] __aligned(16); int mc_spare2[8]; } mcontext_t; #if defined(_KERNEL) && defined(COMPAT_FREEBSD4) -/* For 4.x binaries */ struct mcontext4 { int mc_onstack; /* XXX - sigcontext compat. */ - int mc_gs; + int mc_gs; /* machine state (struct trapframe) */ int mc_fs; int mc_es; int mc_ds; diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index 47856455f099..92915b6a116d 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -157,6 +157,9 @@ ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler)); ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc)); #endif ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); +#ifdef COMPAT_FREEBSD4 +ASSYM(SIGF_UC4, offsetof(struct sigframe4, sf_uc)); +#endif #ifdef COMPAT_43 ASSYM(SC_PS, offsetof(struct osigcontext, sc_ps)); ASSYM(SC_FS, offsetof(struct osigcontext, sc_fs)); diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s index 8f1d801268b3..19a6ac7117c1 100644 --- a/sys/i386/i386/locore.s +++ b/sys/i386/i386/locore.s @@ -394,32 +394,36 @@ begin: * Signal trampoline, copied to top of user stack */ NON_GPROF_ENTRY(sigcode) - call *SIGF_HANDLER(%esp) /* call signal handler */ - lea SIGF_UC(%esp),%eax /* get ucontext_t */ + calll *SIGF_HANDLER(%esp) + leal SIGF_UC(%esp),%eax /* get ucontext */ pushl %eax testl $PSL_VM,UC_EFLAGS(%eax) - jne 9f + jne 1f movl UC_GS(%eax),%gs /* restore %gs */ -9: +1: movl $SYS_sigreturn,%eax pushl %eax /* junk to fake return addr. */ int $0x80 /* enter kernel with args */ -0: jmp 0b + /* on stack */ +1: + jmp 1b #ifdef COMPAT_FREEBSD4 ALIGN_TEXT freebsd4_sigcode: - call *SIGF_HANDLER(%esp) /* call signal handler */ - lea SIGF_UC(%esp),%eax /* get ucontext_t */ + calll *SIGF_HANDLER(%esp) + leal SIGF_UC4(%esp),%eax /* get ucontext */ pushl %eax testl $PSL_VM,UC4_EFLAGS(%eax) - jne 9f + jne 1f movl UC4_GS(%eax),%gs /* restore %gs */ -9: +1: movl $344,%eax /* 4.x SYS_sigreturn */ pushl %eax /* junk to fake return addr. */ int $0x80 /* enter kernel with args */ -0: jmp 0b + /* on stack */ +1: + jmp 1b #endif #ifdef COMPAT_43 diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 1aedc3db1f25..27b3bcac7b5e 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -506,6 +506,7 @@ sendsig(catcher, sig, mask, code) struct proc *p; struct thread *td; struct sigacts *psp; + char *sp; struct trapframe *regs; int oonstack; @@ -544,13 +545,15 @@ sendsig(catcher, sig, mask, code) /* Allocate space for the signal handler context. */ if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { - sfp = (struct sigframe *)(p->p_sigstk.ss_sp + - p->p_sigstk.ss_size - sizeof(struct sigframe)); + sp = p->p_sigstk.ss_sp + + p->p_sigstk.ss_size - sizeof(struct sigframe); #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_sigstk.ss_flags |= SS_ONSTACK; #endif } else - sfp = (struct sigframe *)regs->tf_esp - 1; + sp = (char *)regs->tf_esp - sizeof(struct sigframe); + /* Align to 16 bytes. */ + sfp = (struct sigframe *)((unsigned int)sp & ~0xF); PROC_UNLOCK(p); /* Translate the signal if appropriate. */ diff --git a/sys/i386/include/signal.h b/sys/i386/include/signal.h index efc7ef045888..fb2d82c4d489 100644 --- a/sys/i386/include/signal.h +++ b/sys/i386/include/signal.h @@ -100,7 +100,7 @@ struct osigcontext { struct sigcontext { struct __sigset sc_mask; /* signal mask to restore */ int sc_onstack; /* sigstack state to restore */ - int sc_gs; /* machine state (struct trapframe): */ + int sc_gs; /* machine state (struct trapframe) */ int sc_fs; int sc_es; int sc_ds; @@ -127,7 +127,7 @@ struct sigcontext { int sc_fpformat; int sc_ownedfp; int sc_spare1[1]; - int sc_fpstate[128]; + int sc_fpstate[128] __aligned(16); int sc_spare2[8]; }; diff --git a/sys/i386/include/ucontext.h b/sys/i386/include/ucontext.h index ea6f0b6b1b8f..ec3e0eefaea2 100644 --- a/sys/i386/include/ucontext.h +++ b/sys/i386/include/ucontext.h @@ -38,7 +38,7 @@ typedef struct __mcontext { * and ucontext_t at the same time. */ int mc_onstack; /* XXX - sigcontext compat. */ - int mc_gs; /* machine state (trapframe) */ + int mc_gs; /* machine state (struct trapframe) */ int mc_fs; int mc_es; int mc_ds; @@ -68,15 +68,17 @@ typedef struct __mcontext { #define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */ int mc_ownedfp; int mc_spare1[1]; /* align next field to 16 bytes */ - int mc_fpstate[128]; /* must be multiple of 16 bytes */ + /* + * See for the internals of mc_fpstate[]. + */ + int mc_fpstate[128] __aligned(16); int mc_spare2[8]; } mcontext_t; #if defined(_KERNEL) && defined(COMPAT_FREEBSD4) -/* For 4.x binaries */ struct mcontext4 { int mc_onstack; /* XXX - sigcontext compat. */ - int mc_gs; + int mc_gs; /* machine state (struct trapframe) */ int mc_fs; int mc_es; int mc_ds;