It takes the alpha/hppa/mips64 approach of storing the state in struct sigcontext instead of using a pointer. Using unsigned int and unsigned long long instead of uint32_t and uint64_t here to avoid having to include other headers. But I suppose I could include include <sys/_types.h> and use __uint32_t and __uint64_t if people prefer that.
This is an ABI break. Code that plays tricks with sigcontext, like copying structs around or looks at the internals will have to be recompiled. But we don't really support that, so I'm inclined to just go aead. This fixes the corruption in ksh/sh that is currently preventing snaps from being built. At least in combination with the setjmp fix I mailed out wednesday and Dale's ast fix. ok? Index: arch/arm/arm/sig_machdep.c =================================================================== RCS file: /cvs/src/sys/arch/arm/arm/sig_machdep.c,v retrieving revision 1.16 diff -u -p -r1.16 sig_machdep.c --- arch/arm/arm/sig_machdep.c 12 Apr 2018 17:13:43 -0000 1.16 +++ arch/arm/arm/sig_machdep.c 22 Jun 2018 15:07:30 -0000 @@ -51,12 +51,13 @@ #include <sys/systm.h> #include <sys/user.h> -#include <arm/armreg.h> - #include <machine/cpu.h> #include <machine/frame.h> #include <machine/pcb.h> + +#include <arm/armreg.h> #include <arm/cpufunc.h> +#include <arm/vfp.h> #include <uvm/uvm_extern.h> @@ -80,6 +81,7 @@ sendsig(sig_t catcher, int sig, int retu union sigval val) { struct proc *p = curproc; + struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tf; struct sigframe *fp, frame; struct sigacts *psp = p->p_p->ps_sigacts; @@ -130,6 +132,15 @@ sendsig(sig_t catcher, int sig, int retu /* Save signal mask. */ frame.sf_sc.sc_mask = returnmask; + /* Save FPU registers. */ + frame.sf_sc.sc_fpused = pcb->pcb_flags & PCB_FPU; + if (frame.sf_sc.sc_fpused) { + frame.sf_sc.sc_fpscr = pcb->pcb_fpstate.fp_scr; + memcpy(&frame.sf_sc.sc_fpreg, &pcb->pcb_fpstate.fp_reg, + sizeof(pcb->pcb_fpstate.fp_reg)); + pcb->pcb_flags &= ~PCB_FPU; + } + if (psp->ps_siginfo & sigmask(sig)) { frame.sf_sip = &fp->sf_si; initsiginfo(&frame.sf_si, sig, code, type, val); @@ -176,6 +187,7 @@ sys_sigreturn(struct proc *p, void *v, r syscallarg(struct sigcontext *) sigcntxp; } */ *uap = v; struct sigcontext ksc, *scp = SCARG(uap, sigcntxp); + struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tf; if (PROC_PC(p) != p->p_p->ps_sigcoderet) { @@ -227,6 +239,17 @@ sys_sigreturn(struct proc *p, void *v, r /* Restore signal mask. */ p->p_sigmask = ksc.sc_mask & ~sigcantmask; + + /* Restore FPU registers. */ + if (ksc.sc_fpused) { + if (p->p_addr->u_pcb.pcb_fpcpu != NULL) + vfp_discard(p); + + pcb->pcb_fpstate.fp_scr = ksc.sc_fpscr; + memcpy(&pcb->pcb_fpstate.fp_reg, &ksc.sc_fpreg, + sizeof(pcb->pcb_fpstate.fp_reg)); + pcb->pcb_flags |= PCB_FPU; + } return (EJUSTRETURN); } Index: arch/arm/include/signal.h =================================================================== RCS file: /cvs/src/sys/arch/arm/include/signal.h,v retrieving revision 1.9 diff -u -p -r1.9 signal.h --- arch/arm/include/signal.h 10 May 2016 18:39:43 -0000 1.9 +++ arch/arm/include/signal.h 22 Jun 2018 15:07:30 -0000 @@ -82,6 +82,10 @@ struct sigcontext { unsigned int sc_usr_lr; unsigned int sc_svc_lr; unsigned int sc_pc; + + unsigned int sc_fpused; + unsigned int sc_fpscr; + unsigned long long sc_fpreg[32]; }; #endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */ #endif /* !_LOCORE */