cvs commit: src/lib/libc/i386/gen _setjmp.S setjmp.S

Bruce Evans brde at optusnet.com.au
Sun Jun 29 01:42:16 UTC 2008


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


More information about the cvs-all mailing list