OSDN Git Service

2002-03-25 Andrew Haley <aph@cambridge.redhat.com>, Hans Boehm <Hans_Boehm@hp.com>
[pf3gnuchains/gcc-fork.git] / libjava / include / dwarf2-signal.h
1 // dwarf2-signal.h - Catch runtime signals and turn them into exceptions.
2
3 /* Copyright (C) 2000, 2001  Free Software Foundation
4
5    This file is part of libgcj.
6
7    Use this file for a target for which the dwarf2 unwinder in libgcc
8    can unwind through signal handlers.
9
10 This software is copyrighted work licensed under the terms of the
11 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
12 details.  */
13
14 #ifndef JAVA_SIGNAL_H
15 #define JAVA_SIGNAL_H 1
16
17 #include <signal.h>
18 #include <sys/syscall.h>
19
20 #define HANDLE_SEGV 1
21 #undef HANDLE_FPE
22
23 #define SIGNAL_HANDLER(_name)   \
24 static void _Jv_##_name (int, siginfo_t *, void *_p)
25
26 class java::lang::Throwable;
27
28 // Unwind the stack to the point at which the signal was generated and
29 // then throw an exception.  With the dwarf2 unwinder we don't usually
30 // need to do anything, with some minor exceptions.
31
32 #ifdef __alpha__
33 #define MAKE_THROW_FRAME(_exception)                                    \
34 do                                                                      \
35 {                                                                       \
36   /* Alpha either leaves PC pointing at a faulting instruction or the   \
37    following instruction, depending on the signal.  SEGV always does    \
38    the former, so we adjust the saved PC to point to the following      \
39    instruction; this is what the handler in libgcc expects.  */         \
40   struct sigcontext *_sc = (struct sigcontext *)_p;                     \
41   _sc->sc_pc += 4;                                                      \
42 }                                                                       \
43 while (0)
44
45 #elif defined(__ia64__)
46
47 #define MAKE_THROW_FRAME(_exception)                                    \
48 do                                                                      \
49 {                                                                       \
50   /* IA-64 either leaves PC pointing at a faulting instruction or the   \
51    following instruction, depending on the signal.  SEGV always does    \
52    the former, so we adjust the saved PC to point to the following      \
53    instruction; this is what the handler in libgcc expects.  */         \
54   /* Note that we are lying to the unwinder here, which expects the     \
55    faulting pc, not pc+1.  But we claim the unwind information can't    \
56    be changed by such a ld or st instruction, so it doesn't matter. */  \
57   struct sigcontext *_sc = (struct sigcontext *)_p;                     \
58   _sc->sc_ip++;                                                         \
59 }                                                                       \
60 while (0)
61 #else
62 #define MAKE_THROW_FRAME(_exception)            \
63 do                                              \
64 {                                               \
65   (void)_p;                                     \
66 }                                               \
67 while (0)
68 #endif
69
70 #ifndef __ia64__
71 #define INIT_SEGV                                               \
72 do                                                              \
73   {                                                             \
74     nullp = new java::lang::NullPointerException ();            \
75     struct sigaction act;                                       \
76     act.sa_sigaction = _Jv_catch_segv;                          \
77     sigemptyset (&act.sa_mask);                                 \
78     act.sa_flags = SA_SIGINFO;                                  \
79     syscall (SYS_sigaction, SIGSEGV, &act, NULL);               \
80   }                                                             \
81 while (0)  
82
83 #define INIT_FPE                                                \
84 do                                                              \
85   {                                                             \
86     arithexception = new java::lang::ArithmeticException        \
87       (JvNewStringLatin1 ("/ by zero"));                        \
88     struct sigaction act;                                       \
89     act.sa_sigaction = _Jv_catch_fpe;                           \
90     sigemptyset (&act.sa_mask);                                 \
91     act.sa_flags = SA_SIGINFO;                                  \
92     syscall (SYS_sigaction, SIGFPE, &act, NULL);                \
93   }                                                             \
94 while (0)  
95
96 /* We use syscall(SYS_sigaction) in INIT_SEGV and INIT_FPE instead of
97  * sigaction() because on some systems the pthreads wrappers for
98  * signal handlers are not compiled with unwind information, so it's
99  * not possible to unwind through them.  This is a problem that will
100  * go away once all systems have pthreads libraries that are
101  * compiled with full unwind info.  */
102
103 #else  /* __ia64__ */
104
105 // FIXME: We shouldn't be using libc_sigaction here, since it should
106 // be glibc private.  But using syscall here would mean translating to
107 // the kernel's struct sigaction and argument sequence, which we
108 // shouldn't either.  The right solution is to call sigaction and to
109 // make sure that we can unwind correctly through the pthread signal
110 // wrapper.
111 extern "C" int __libc_sigaction (int __sig, 
112                       __const struct sigaction *__restrict __act,
113                       struct sigaction *__restrict __oact) throw ();
114
115 #define INIT_SEGV                                               \
116 do                                                              \
117   {                                                             \
118     nullp = new java::lang::NullPointerException ();            \
119     struct sigaction act;                                       \
120     act.sa_sigaction = _Jv_catch_segv;                          \
121     sigemptyset (&act.sa_mask);                                 \
122     act.sa_flags = SA_SIGINFO;                                  \
123     __libc_sigaction (SIGSEGV, &act, NULL);                     \
124   }                                                             \
125 while (0)  
126
127 #define INIT_FPE                                                \
128 do                                                              \
129   {                                                             \
130     arithexception = new java::lang::ArithmeticException        \
131       (JvNewStringLatin1 ("/ by zero"));                        \
132     struct sigaction act;                                       \
133     act.sa_sigaction = _Jv_catch_fpe;                           \
134     sigemptyset (&act.sa_mask);                                 \
135     act.sa_flags = SA_SIGINFO;                                  \
136     __libc_sigaction (SIGFPE, &act, NULL);                      \
137   }                                                             \
138 while (0)  
139 #endif /* __ia64__ */
140 #endif /* JAVA_SIGNAL_H */