1 // i386-signal.h - Catch runtime signals and turn them into exceptions.
3 /* Copyright (C) 1998, 1999 Cygnus Solutions
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
11 /* This technique should work for all i386 based Unices which conform
12 * to iBCS2. This includes all versions of Linux more recent than 1.3
17 #define JAVA_SIGNAL_H 1
24 #define SIGNAL_HANDLER(_name) \
25 static void _name (int _dummy)
27 #define MAKE_THROW_FRAME \
30 void **_p = (void **)&_dummy; \
31 struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
33 register unsigned long _ebp = _regs->ebp; \
34 register unsigned char *_eip = (unsigned char *)_regs->eip; \
36 asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)" \
37 : : "r"(_ebp), "r"(_eip)); \
41 #define HANDLE_DIVIDE_OVERFLOW \
44 void **_p = (void **)&_dummy; \
45 struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
47 register unsigned long *_ebp = (unsigned long *)_regs->ebp; \
48 register unsigned char *_eip = (unsigned char *)_regs->eip; \
50 /* According to the JVM spec, "if the dividend is the negative \
51 * integer of the smallest magnitude and the divisor is -1, then \
52 * overflow occurs and the result is equal to the dividend. Despite \
53 * the overflow, no exception occurs". \
55 * We handle this by inspecting the instruction which generated the \
56 * signal and advancing eip to point to the following instruction. \
57 * As the instructions are variable length it is necessary to do a \
58 * little calculation to figure out where the following instruction \
63 if (_eip[0] == 0xf7) \
65 unsigned char _modrm = _eip[1]; \
67 if (_regs->eax == 0x80000000 \
68 && ((_modrm >> 3) & 7) == 7) /* Signed divide */ \
70 _regs->edx = 0; /* the remainder is zero */ \
71 switch (_modrm >> 6) \
74 if ((_modrm & 7) == 5) \
87 _regs->eip = (unsigned long)_eip; \
90 else if (((_modrm >> 3) & 7) == 6) /* Unsigned divide */ \
92 /* We assume that unsigned divisions are in library code, so \
93 * we throw one level down the stack, which was hopefully \
94 * the place that called the library routine. This will \
95 * break if the library is ever compiled with \
96 * -fomit-frame-pointer, but at least this way we've got a \
97 * good chance of finding the exception handler. */ \
99 _eip = (unsigned char *)_ebp[1]; \
100 _ebp = (unsigned long *)_ebp[0]; \
104 asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)" \
105 : : "r"(_ebp), "r"(_eip)); \
112 nullp = new java::lang::NullPointerException (); \
113 struct sigaction act; \
114 act.sa_handler = catch_segv; \
115 sigemptyset (&act.sa_mask); \
117 sigaction (SIGSEGV, &act, NULL); \
124 arithexception = new java::lang::ArithmeticException \
125 (JvNewStringLatin1 ("/ by zero")); \
126 struct sigaction act; \
127 act.sa_handler = catch_fpe; \
128 sigemptyset (&act.sa_mask); \
130 sigaction (SIGFPE, &act, NULL); \
134 #endif /* JAVA_SIGNAL_H */