1 // i386-signal.h - Catch runtime signals and turn them into exceptions.
3 /* Copyright (C) 1998, 1999 Free Software Foundation
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 /* Advance the program counter so that it is after the start of the \
37 instruction: the x86 exception handler expects \
38 the PC to point to the instruction after a call. */ \
41 asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)" \
42 : : "r"(_ebp), "r"(_eip)); \
46 #define HANDLE_DIVIDE_OVERFLOW \
49 void **_p = (void **)&_dummy; \
50 struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
52 register unsigned long *_ebp = (unsigned long *)_regs->ebp; \
53 register unsigned char *_eip = (unsigned char *)_regs->eip; \
55 /* According to the JVM spec, "if the dividend is the negative \
56 * integer of the smallest magnitude and the divisor is -1, then \
57 * overflow occurs and the result is equal to the dividend. Despite \
58 * the overflow, no exception occurs". \
60 * We handle this by inspecting the instruction which generated the \
61 * signal and advancing eip to point to the following instruction. \
62 * As the instructions are variable length it is necessary to do a \
63 * little calculation to figure out where the following instruction \
68 if (_eip[0] == 0xf7) \
70 unsigned char _modrm = _eip[1]; \
72 if (_regs->eax == 0x80000000 \
73 && ((_modrm >> 3) & 7) == 7) /* Signed divide */ \
75 _regs->edx = 0; /* the remainder is zero */ \
76 switch (_modrm >> 6) \
79 if ((_modrm & 7) == 5) \
92 _regs->eip = (unsigned long)_eip; \
95 else if (((_modrm >> 3) & 7) == 6) /* Unsigned divide */ \
97 /* We assume that unsigned divisions are in library code, so \
98 * we throw one level down the stack, which was hopefully \
99 * the place that called the library routine. This will \
100 * break if the library is ever compiled with \
101 * -fomit-frame-pointer, but at least this way we've got a \
102 * good chance of finding the exception handler. */ \
104 _eip = (unsigned char *)_ebp[1]; \
105 _ebp = (unsigned long *)_ebp[0]; \
109 /* Advance the program counter so that it is after the start \
110 of the instruction: this is because the x86 exception \
111 handler expects the PC to point to the instruction after a \
117 asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)" \
118 : : "r"(_ebp), "r"(_eip)); \
125 nullp = new java::lang::NullPointerException (); \
126 struct sigaction act; \
127 act.sa_handler = catch_segv; \
128 sigemptyset (&act.sa_mask); \
130 __sigaction (SIGSEGV, &act, NULL); \
137 arithexception = new java::lang::ArithmeticException \
138 (JvNewStringLatin1 ("/ by zero")); \
139 struct sigaction act; \
140 act.sa_handler = catch_fpe; \
141 sigemptyset (&act.sa_mask); \
143 __sigaction (SIGFPE, &act, NULL); \
147 #endif /* JAVA_SIGNAL_H */