[Gd-chatter] r11460 - trunk/fundev/sources/lib/run-time/pentium-freebsd

housel at gwydiondylan.org housel at gwydiondylan.org
Thu Sep 27 14:56:10 CEST 2007


Author: housel
Date: Thu Sep 27 14:56:09 2007
New Revision: 11460

Modified:
   trunk/fundev/sources/lib/run-time/pentium-freebsd/x86-linux-exceptions.c
Log:
Bug: 7150 7297
Fix SIGFPE handling under FreeBSD.

* sources/lib/run-time/pentium-freebsd/x86-linux-exceptions.c
  (EXCEPTION_PREAMBLE): Remove unnecessary local functions doFPEHandler()
  and doSEGVHandler().
  (EstablishDylanExceptionHandlers): Establish signal handlers using
  POSIX sigaction() calling conventions.
  (DylanFPEHandler): Branch to the exception-signalling trampoline
  functions by placing their addresses in the returning ucontext.


Modified: trunk/fundev/sources/lib/run-time/pentium-freebsd/x86-linux-exceptions.c
==============================================================================
--- trunk/fundev/sources/lib/run-time/pentium-freebsd/x86-linux-exceptions.c	(original)
+++ trunk/fundev/sources/lib/run-time/pentium-freebsd/x86-linux-exceptions.c	Thu Sep 27 14:56:09 2007
@@ -25,19 +25,13 @@
 /* ---*** TODO: Find out how to trap stack overflows and add an appropriate handler */
 
 #include <sys/signal.h>
+#include <ucontext.h>
 #include <ieeefp.h>
+#include <fenv.h>
 
 #define EXCEPTION_PREAMBLE() \
   struct sigaction oldFPEHandler; \
   struct sigaction oldSEGVHandler; \
-  void doFPEHandler (int signum, siginfo_t *info, void * sc) { \
-    DylanFPEHandler(signum, info, sc);	\
-  } \
-  void doSEGVHandler (int signum, siginfo_t *info, void * sc) { \
-    DylanSEGVHandler(signum, info, sc); \
-  } \
-  oldFPEHandler.sa_sigaction = doFPEHandler; \
-  oldSEGVHandler.sa_sigaction = doSEGVHandler; \
   EstablishDylanExceptionHandlers(&oldFPEHandler, &oldSEGVHandler); \
   {
 
@@ -45,8 +39,6 @@
   } \
   RemoveDylanExceptionHandlers(&oldFPEHandler, &oldSEGVHandler);
 
-typedef void (* SIG_SIGCONTEXT)(int, struct sigcontext);
-
 static void DylanFPEHandler (int sig, siginfo_t *info, void *sc);
 static void DylanSEGVHandler (int sig, siginfo_t *info, void *sc);
 
@@ -58,16 +50,16 @@
 
   sigset_t set, oldset;
 
-  newFPEHandler.sa_handler = oldFPEHandler->sa_handler;
-  sigemptyset(&newFPEHandler.sa_mask);
-  newFPEHandler.sa_flags = 0;
+  sigfillset(&newFPEHandler.sa_mask);
+  newFPEHandler.sa_sigaction = DylanFPEHandler;
+  newFPEHandler.sa_flags = SA_SIGINFO;
   sigaction(SIGFPE, &newFPEHandler, oldFPEHandler);
 
 #if 0
-  newSEGVHandler.sa_handler = oldSEGVHandler->sa_handler;
-  sigemptyset(&newSEGVHandler.sa_mask);
-  newSEGVHandler.sa_flags = 0;
-  sigaction(SIGSEGV, &newSEGVHandler, oldSEGVHandler);
+  sigfillset(&newFPEHandler.sa_mask);
+  newSEGVHandler.sa_sigaction = DylanFSEGVandler;
+  newSEGVHandler.sa_flags = SA_SIGINFO;
+  sigaction(SIGFPE, &newSEGVHandler, oldSEGVHandler);
 #endif
 
   sigemptyset(&set);
@@ -84,25 +76,6 @@
 #endif
 }
 
-
-/* ---*** NOTE: There doesn't appear to be an include file that defines these constants! */
-
-#define TRAP_INTEGER_DIVZERO   0
-#define TRAP_INTEGER_OVERFLOW  4
-#define TRAP_FLOAT_EXCEPTION  16
-
-#define FS_INVALID_OP          1
-#define FS_DENORMAL_OPERAND    2
-#define FS_DIVZERO             4
-#define FS_OVERFLOW            8
-#define FS_UNDERFLOW          16
-#define FS_INEXACT            32
-#define FS_FSTACK_OVERFLOW    64
-#define FS_ALL_EXCEPTIONS \
-  (FS_INVALID_OP | FS_DENORMAL_OPERAND | FS_DIVZERO | FS_OVERFLOW | FS_UNDERFLOW \
-   | FS_INEXACT | FS_FSTACK_OVERFLOW)
-
-#include <fenv.h>
 __inline
 void RestoreFPState ()
 {
@@ -111,47 +84,43 @@
   return;
 }
 
-static void DylanFPEHandler (int sig, siginfo_t *info, void *sc)
+static void DylanFPEHandler (int sig, siginfo_t *info, void *uap)
 {
   if (inside_dylan_ffi_barrier() == 0) { }
 
   else {
+    ucontext_t *uc = (ucontext_t *) uap;
+
     switch (info->si_code) {
     case FPE_INTDIV:
       RestoreFPState();
-      dylan_integer_divide_0_handler();
-      break;                                    /* Should never get here ... */              
+      uc->uc_mcontext.mc_eip = (long) dylan_integer_divide_0_handler;
+      break;
+      
     case FPE_INTOVF:
       RestoreFPState();
-      dylan_integer_overflow_handler();
-      break;                                    /* Should never get here ... */              
+      uc->uc_mcontext.mc_eip = (long) dylan_integer_overflow_handler;
+      break;
+      
     case FPE_FLTDIV:
       RestoreFPState();
-      dylan_float_divide_0_handler();       /* Should never return ... */
+      uc->uc_mcontext.mc_eip = (long) dylan_float_divide_0_handler;
       break;
+      
     case FPE_FLTOVF:
       RestoreFPState();
-      dylan_float_overflow_handler();       /* Should never return ... */
+      uc->uc_mcontext.mc_eip = (long) dylan_float_overflow_handler;
       break;
+
     case FPE_FLTUND:
       RestoreFPState();
-      dylan_float_underflow_handler();      /* Should never return ... */
+      uc->uc_mcontext.mc_eip = (long) dylan_float_underflow_handler;
       break;
+      
     default:
       break;
     }
   }
-
-  /*  // Here iff we should invoke the previous handler ...
-  if (oldHandler == SIG_DFL) {
-    signal(signum, SIG_DFL);
-    raise(signum);
-  }
-  else
-    // ---*** NOTE: What if the old handler isn't expecting this calling sequence?
-    (*(SIG_SIGCONTEXT)oldHandler)(signum, sc);
-  */
-  return;
 }
 
 



More information about the chatter mailing list