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 */

Reply via email to