[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] fegetenv/getcontext
From: |
Ed Connell |
Subject: |
[PATCH] fegetenv/getcontext |
Date: |
Mon, 19 May 2003 17:00:48 -0400 |
Hello,
I previously reported the x86 instruction 'fnstenv' (used in
getcontext()) was resetting floating point mask info improperly.
http://sources.redhat.com/ml/bug-glibc/2002-12/msg00047.html
I now have a patch and a testcase. I was only able to test this
on 2.2.93 but I see no reason the behavior should be different.
Someone involved with x86-64 should see if they need a similar
patch.
Cheers
Ed
2003-05-19 Ed Connell <address@hidden>
* sysdeps/unix/sysv/linux/i386/getcontext.S (getcontext):
Retain floating point mask
* sysdeps/i386/fpu/fegetenv.c (fegetenv): Likewise.
--- glibc-2.3.2/sysdeps/i386/fpu/fegetenv.c 2001-07-07 15:21:23.000000000
-0400
+++ glibc-2.3.2/sysdeps/i386/fpu/fegetenv.c.edconn 2003-05-19
16:27:16.000000000 -0400
@@ -25,6 +25,7 @@
__fegetenv (fenv_t *envp)
{
__asm__ ("fnstenv %0" : "=m" (*envp));
+ __asm__ ("fldenv %0" : "=m" (*envp));
/* Success. */
return 0;
--- glibc-2.3.2/sysdeps/unix/sysv/linux/i386/getcontext.S 2002-12-19
22:56:27.000000000 -0500
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/i386/getcontext.S.edconn
2003-05-19 15:12:12.000000000 -0400
@@ -56,6 +56,7 @@
movl %ecx, oFPREGS(%eax)
/* Save the floating-point context. */
fnstenv (%ecx)
+ fldenv (%ecx)
/* Save the current signal mask. */
pushl %ebx
Testcase
gcc -o setjmp_fpmask_test setjmp_fpmask_test.c -lm
gcc -o setjmp_fpmask_test setjmp_fpmask_test.c -lm -DDO_GETCONTEXT
gcc -o setjmp_fpmask_test setjmp_fpmask_test.c -lm -DDO_FEGETENV
Pass: "Correct: got floating point exception."
Fail: "Error: missed floating point exception."
setjmp_fpmask_test.c
********************
#define _GNU_SOURCE
#include <setjmp.h>
#include <fenv.h>
#include <signal.h>
#include <stddef.h>
#include <ucontext.h>
void fpe_hand(int signum, siginfo_t *p1, void *p2)
{
printf("Correct: got floating point exception.\n");
exit(1);
}
int main()
{
struct sigaction act;
double d = 0.0;
ucontext_t uc;
fenv_t fenv;
act.sa_sigaction = fpe_hand;
act.sa_flags = SA_SIGINFO;
memset(&act.sa_mask,0,sizeof(act.sa_mask));
sigaction(SIGFPE, &act, NULL);
feenableexcept(FE_ALL_EXCEPT);
#if defined(DO_GETCONTEXT)
getcontext(&uc);
#elif defined(DO_FEGETENV)
fegetenv(&fenv);
#endif
d = 1.0 / d;
printf("Error: missed floating point exception.\n");
}
********************
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] fegetenv/getcontext,
Ed Connell <=