Date: Sun, 29 Jun 2008 11:42:10 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: David Schultz <das@freebsd.org> Cc: cvs-src@freebsd.org, src-committers@freebsd.org, cvs-all@freebsd.org Subject: Re: cvs commit: src/lib/libc/i386/gen _setjmp.S setjmp.S Message-ID: <20080629110524.W92369@delplex.bde.org> In-Reply-To: <20080628180230.GA37313@zim.MIT.EDU> References: <200806281758.m5SHwIl2083857@repoman.freebsd.org> <20080628180230.GA37313@zim.MIT.EDU>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 28 Jun 2008, David Schultz wrote: > On Sat, Jun 28, 2008, David Schultz wrote: >> das 2008-06-28 17:58:06 UTC >> >> FreeBSD src repository >> >> Modified files: >> lib/libc/i386/gen _setjmp.S setjmp.S >> Log: >> SVN rev 180081 on 2008-06-28 17:58:06Z by das >> >> We should also save and restore the MXCSR as on amd64, but detecting >> whether the CPU supports SSE or not here is rather odious. > > Err, the first line of the commit message read: > > Don't clobber the FPU exception flags in longjmp. C99 requires them > to remain unchanged. > > ...but got cut off somehow. This is wrong. It breaks longjmp() from all COMPAT_[3-4] signal handlers (not just ones for SIGFPE). I don't like the corresponding change for amd64 either, and only approved it since amd64 doesn't support COMPAT_[3-4] signal handlers. With COMPAT_[3-4] signal handlers on i386, the entire FP environment of the interrupted context (except for the exception flags in the case of a SIGFPE for the FPU) are passed raw to the signal handler. We still restore the control word in longjmp(). Now we leave garbage in the tag and status words, (except for the exception flags in the case of a SIGFPE for the FPU -- these are clobbered (reset to 0) earlier and we have no way to recover them (except in RELENG_[1-4], they may be recovered from the saved exception status word in the pcb (probably need kmem to read this)). With !COMPAT_[3-4] signal handlers, the exception flags are (now unnecessarily) clobbered by signal handling before longjmp() from a signal handler can clobber them. longjmp() on i386 must clobber (reset to 0 or another safe state) the tag and status words (and perhaps other state like the error pointers) on i386. This is less controversial than restoring the control word and exception status words, since they are an implementation-defined part of the fenv API and ABI and resetting them has effects invisible to the API and ABI (only setting them to an unsafe state would have visible effects). Resetting these while preserving the status word would be slow; the unbroken version just used fninit to reset them together with the exception flags. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080629110524.W92369>