summaryrefslogtreecommitdiff
path: root/libjava/include
diff options
context:
space:
mode:
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-30 21:00:22 +0000
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-30 21:00:22 +0000
commit767b093ff5f16ea04d12d99eb5a7f2a3ef6540d1 (patch)
tree27e58e5f86b39ba85e92ce58398d2dc91865e68c /libjava/include
parentca7744c6a69a868a1d2e7ae930cb394aa135bbc5 (diff)
downloadgcc-767b093ff5f16ea04d12d99eb5a7f2a3ef6540d1.tar.gz
2001-01-26 Andrew Haley <aph@redhat.com>
(INIT_FPE): Use a direct system call to set the handler. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39354 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/include')
-rw-r--r--libjava/include/i386-signal.h18
1 files changed, 16 insertions, 2 deletions
diff --git a/libjava/include/i386-signal.h b/libjava/include/i386-signal.h
index 599edc940ad..de2e39cdbc2 100644
--- a/libjava/include/i386-signal.h
+++ b/libjava/include/i386-signal.h
@@ -1,6 +1,6 @@
// i386-signal.h - Catch runtime signals and turn them into exceptions.
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001 Free Software Foundation
This file is part of libgcj.
@@ -17,6 +17,7 @@ details. */
#define JAVA_SIGNAL_H 1
#include <signal.h>
+#include <sys/syscall.h>
#define HANDLE_SEGV 1
#define HANDLE_FPE 1
@@ -140,9 +141,22 @@ do \
act.sa_handler = catch_fpe; \
sigemptyset (&act.sa_mask); \
act.sa_flags = 0; \
- __sigaction (SIGFPE, &act, NULL); \
+ syscall (SYS_sigaction, SIGFPE, &act, NULL); \
} \
while (0)
+/* You might wonder why we use syscall(SYS_sigaction) in INIT_FPE
+ * instead of the standard sigaction(). This is necessary because of
+ * the shenanigans above where we increment the PC saved in the
+ * context and then return. This trick will only work when we are
+ * called _directly_ by the kernel, because linuxthreads wraps signal
+ * handlers and its wrappers do not copy the sigcontext struct back
+ * when returning from a signal handler. If we return from our divide
+ * handler to a linuxthreads wrapper, we will lose the PC adjustment
+ * we made and return to the faulting instruction again. Using
+ * syscall(SYS_sigaction) causes our handler to be called directly by
+ * the kernel, bypassing any wrappers. This is a kludge, and a future
+ * version of this handler will do something better. */
+
#endif /* JAVA_SIGNAL_H */