OSDN Git Service

* ada/acats/run_acats (which): New function.
[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, 2009  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 *_sip, 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
62 #else
63 #define MAKE_THROW_FRAME(_exception)            \
64 do                                              \
65 {                                               \
66   (void)_p;                                     \
67 }                                               \
68 while (0)
69 #endif
70
71 #if defined(__sparc__)
72 #if defined(__arch64__)
73 extern "C" {
74     static void __rt_sigreturn_stub(void)
75     {
76       __asm__("mov %0, %%g1\n\t"
77               "ta  0x6d\n\t"
78               : /* no outputs */
79               : "i" (__NR_rt_sigreturn));
80     }
81     struct kernel_sigaction
82     {
83       void (*k_sa_sigaction)(int,siginfo_t *,void *);
84       unsigned long k_sa_flags;
85       void (*k_sa_restorer)(void);
86       sigset_t k_sa_mask;
87     };
88 }
89 #define INIT_SEGV                                               \
90 do                                                              \
91   {                                                             \
92     struct kernel_sigaction act;                                \
93     unsigned long stub = ((unsigned long)&__rt_sigreturn_stub); \
94     act.k_sa_sigaction = _Jv_catch_segv;                        \
95     sigemptyset (&act.k_sa_mask);                               \
96     act.k_sa_flags = SA_SIGINFO;                                \
97     act.k_sa_restorer = NULL;                                   \
98     syscall (SYS_rt_sigaction, SIGSEGV, &act, NULL,             \
99              stub - 8, _NSIG / 8);                              \
100   }                                                             \
101 while (0)  
102
103 #define INIT_FPE                                                \
104 do                                                              \
105   {                                                             \
106     struct kernel_sigaction act;                                \
107     unsigned long stub = ((unsigned long)&__rt_sigreturn_stub); \
108     act.k_sa_sigaction = _Jv_catch_fpe;                         \
109     sigemptyset (&act.k_sa_mask);                               \
110     act.k_sa_flags = SA_SIGINFO;                                \
111     act.k_sa_restorer = NULL;                                   \
112     syscall (SYS_rt_sigaction, SIGFPE, &act, NULL,              \
113              stub - 8, _NSIG / 8);                              \
114   }                                                             \
115 while (0)  
116 #else /* __arch64__ */
117
118 extern "C" {
119     struct kernel_sigaction
120     {
121       void (*k_sa_sigaction)(int,siginfo_t *,void *);
122       unsigned long k_sa_mask, k_sa_flags;
123       void (*k_sa_restorer)(void);
124     };
125 }
126
127 #define INIT_SEGV                                               \
128 do                                                              \
129   {                                                             \
130     struct kernel_sigaction act;                                \
131     act.k_sa_sigaction = _Jv_catch_segv;                        \
132     act.k_sa_mask = 0;                                          \
133     act.k_sa_flags = SA_SIGINFO;                                \
134     act.k_sa_restorer = NULL;                                   \
135     syscall (SYS_sigaction, -SIGSEGV, &act, NULL);              \
136   }                                                             \
137 while (0)  
138
139 #define INIT_FPE                                                \
140 do                                                              \
141   {                                                             \
142     struct kernel_sigaction act;                                \
143     act.k_sa_sigaction = _Jv_catch_fpe;                         \
144     act.k_sa_mask = 0;                                          \
145     act.k_sa_flags = SA_SIGINFO;                                \
146     act.k_sa_restorer = NULL;                                   \
147     syscall (SYS_sigaction, -SIGFPE, &act, NULL);               \
148   }                                                             \
149 while (0)  
150 #endif
151 #elif !defined(__ia64__)
152 #define INIT_SEGV                                               \
153 do                                                              \
154   {                                                             \
155     struct sigaction act;                                       \
156     act.sa_sigaction = _Jv_catch_segv;                          \
157     sigemptyset (&act.sa_mask);                                 \
158     act.sa_flags = SA_SIGINFO;                                  \
159     syscall (SYS_sigaction, SIGSEGV, &act, NULL);               \
160   }                                                             \
161 while (0)  
162
163 #define INIT_FPE                                                \
164 do                                                              \
165   {                                                             \
166     struct sigaction act;                                       \
167     act.sa_sigaction = _Jv_catch_fpe;                           \
168     sigemptyset (&act.sa_mask);                                 \
169     act.sa_flags = SA_SIGINFO;                                  \
170     syscall (SYS_sigaction, SIGFPE, &act, NULL);                \
171   }                                                             \
172 while (0)  
173
174 /* We use syscall(SYS_sigaction) in INIT_SEGV and INIT_FPE instead of
175  * sigaction() because on some systems the pthreads wrappers for
176  * signal handlers are not compiled with unwind information, so it's
177  * not possible to unwind through them.  This is a problem that will
178  * go away once all systems have pthreads libraries that are
179  * compiled with full unwind info.  */
180
181 #else  /* __ia64__ */
182
183 // On IA64, unwind information is mandatory, so we can unwind
184 // correctly through glibc frames.  Thus we call the ordinary
185 // sigaction.
186
187 #define INIT_SEGV                                               \
188 do                                                              \
189   {                                                             \
190     struct sigaction act;                                       \
191     act.sa_sigaction = _Jv_catch_segv;                          \
192     sigemptyset (&act.sa_mask);                                 \
193     act.sa_flags = SA_SIGINFO;                                  \
194     sigaction (SIGSEGV, &act, NULL);                            \
195   }                                                             \
196 while (0)  
197
198 #define INIT_FPE                                                \
199 do                                                              \
200   {                                                             \
201     struct sigaction act;                                       \
202     act.sa_sigaction = _Jv_catch_fpe;                           \
203     sigemptyset (&act.sa_mask);                                 \
204     act.sa_flags = SA_SIGINFO;                                  \
205     sigaction (SIGFPE, &act, NULL);                             \
206   }                                                             \
207 while (0)  
208 #endif /* __ia64__ || __sparc__ */
209 #endif /* JAVA_SIGNAL_H */