// dwarf2-signal.h - Catch runtime signals and turn them into exceptions.
-/* Copyright (C) 2000, 2001 Free Software Foundation
+/* Copyright (C) 2000, 2001, 2009 Free Software Foundation
This file is part of libgcj.
_sc->sc_ip++; \
} \
while (0)
-#elif defined(__sparc__)
-/* We could do the unwind of the signal frame quickly by hand here like
- sparc-signal.h does under Solaris, but that makes debugging unwind
- failures almost impossible. */
-#if !defined(__arch64__)
-#define MAKE_THROW_FRAME(_exception) \
-do \
-{ \
- /* Sparc-32 leaves PC pointing at a faulting instruction \
- always. So we adjust the saved PC to point to the following \
- instruction; this is what the handler in libgcc expects. */ \
- /* Note that we are lying to the unwinder here, which expects the \
- faulting pc, not pc+1. But we claim the unwind information can't \
- be changed by such a ld or st instruction, so it doesn't matter. */ \
- struct sig_regs { \
- unsigned int psr, pc, npc, y, u_regs[16]; \
- } *regp; \
- unsigned int insn; \
- __asm__ __volatile__("ld [%%i7 + 8], %0" : "=r" (insn)); \
- if (insn == 0x821020d8) \
- regp = (struct sig_regs *) _sip; \
- else \
- regp = (struct sig_regs *) (_sip + 1); \
- regp->pc = regp->npc; \
- regp->npc += 4; \
-} \
-while (0)
-#else
-#define MAKE_THROW_FRAME(_exception) \
-do \
-{ \
- /* Sparc-64 leaves PC pointing at a faulting instruction \
- always. So we adjust the saved PC to point to the following \
- instruction; this is what the handler in libgcc expects. */ \
- /* Note that we are lying to the unwinder here, which expects the \
- faulting pc, not pc+1. But we claim the unwind information can't \
- be changed by such a ld or st instruction, so it doesn't matter. */ \
- struct pt_regs { \
- unsigned long u_regs[16]; \
- unsigned long tstate, tpc, tnpc; \
- unsigned int y, fprs; \
- } *regp = (struct pt_regs *) (_sip + 1); \
- regp->tpc = regp->tnpc; \
- regp->tnpc += 4; \
-} \
-while (0)
-#endif
+
#else
#define MAKE_THROW_FRAME(_exception) \
do \
while (0)
#endif
-#if !(defined(__ia64__) || defined(__sparc__))
+#if defined(__sparc__)
+#if defined(__arch64__)
+extern "C" {
+ static void __rt_sigreturn_stub(void)
+ {
+ __asm__("mov %0, %%g1\n\t"
+ "ta 0x6d\n\t"
+ : /* no outputs */
+ : "i" (__NR_rt_sigreturn));
+ }
+ struct kernel_sigaction
+ {
+ void (*k_sa_sigaction)(int,siginfo_t *,void *);
+ unsigned long k_sa_flags;
+ void (*k_sa_restorer)(void);
+ sigset_t k_sa_mask;
+ };
+}
+#define INIT_SEGV \
+do \
+ { \
+ struct kernel_sigaction act; \
+ unsigned long stub = ((unsigned long)&__rt_sigreturn_stub); \
+ act.k_sa_sigaction = _Jv_catch_segv; \
+ sigemptyset (&act.k_sa_mask); \
+ act.k_sa_flags = SA_SIGINFO; \
+ act.k_sa_restorer = NULL; \
+ syscall (SYS_rt_sigaction, SIGSEGV, &act, NULL, \
+ stub - 8, _NSIG / 8); \
+ } \
+while (0)
+
+#define INIT_FPE \
+do \
+ { \
+ struct kernel_sigaction act; \
+ unsigned long stub = ((unsigned long)&__rt_sigreturn_stub); \
+ act.k_sa_sigaction = _Jv_catch_fpe; \
+ sigemptyset (&act.k_sa_mask); \
+ act.k_sa_flags = SA_SIGINFO; \
+ act.k_sa_restorer = NULL; \
+ syscall (SYS_rt_sigaction, SIGFPE, &act, NULL, \
+ stub - 8, _NSIG / 8); \
+ } \
+while (0)
+#else /* __arch64__ */
+
+extern "C" {
+ struct kernel_sigaction
+ {
+ void (*k_sa_sigaction)(int,siginfo_t *,void *);
+ unsigned long k_sa_mask, k_sa_flags;
+ void (*k_sa_restorer)(void);
+ };
+}
+
+#define INIT_SEGV \
+do \
+ { \
+ struct kernel_sigaction act; \
+ act.k_sa_sigaction = _Jv_catch_segv; \
+ act.k_sa_mask = 0; \
+ act.k_sa_flags = SA_SIGINFO; \
+ act.k_sa_restorer = NULL; \
+ syscall (SYS_sigaction, -SIGSEGV, &act, NULL); \
+ } \
+while (0)
+
+#define INIT_FPE \
+do \
+ { \
+ struct kernel_sigaction act; \
+ act.k_sa_sigaction = _Jv_catch_fpe; \
+ act.k_sa_mask = 0; \
+ act.k_sa_flags = SA_SIGINFO; \
+ act.k_sa_restorer = NULL; \
+ syscall (SYS_sigaction, -SIGFPE, &act, NULL); \
+ } \
+while (0)
+#endif
+#elif !defined(__ia64__)
#define INIT_SEGV \
do \
{ \
- nullp = new java::lang::NullPointerException (); \
struct sigaction act; \
act.sa_sigaction = _Jv_catch_segv; \
sigemptyset (&act.sa_mask); \
#define INIT_FPE \
do \
{ \
- arithexception = new java::lang::ArithmeticException \
- (JvNewStringLatin1 ("/ by zero")); \
struct sigaction act; \
act.sa_sigaction = _Jv_catch_fpe; \
sigemptyset (&act.sa_mask); \
* go away once all systems have pthreads libraries that are
* compiled with full unwind info. */
-#else /* __ia64__ || __sparc__ */
+#else /* __ia64__ */
-// FIXME: We shouldn't be using libc_sigaction here, since it should
-// be glibc private. But using syscall here would mean translating to
-// the kernel's struct sigaction and argument sequence, which we
-// shouldn't either. The right solution is to call sigaction and to
-// make sure that we can unwind correctly through the pthread signal
-// wrapper.
-extern "C" int __libc_sigaction (int __sig,
- __const struct sigaction *__restrict __act,
- struct sigaction *__restrict __oact) throw ();
+// On IA64, unwind information is mandatory, so we can unwind
+// correctly through glibc frames. Thus we call the ordinary
+// sigaction.
#define INIT_SEGV \
do \
{ \
- nullp = new java::lang::NullPointerException (); \
struct sigaction act; \
act.sa_sigaction = _Jv_catch_segv; \
sigemptyset (&act.sa_mask); \
act.sa_flags = SA_SIGINFO; \
- __libc_sigaction (SIGSEGV, &act, NULL); \
+ sigaction (SIGSEGV, &act, NULL); \
} \
while (0)
#define INIT_FPE \
do \
{ \
- arithexception = new java::lang::ArithmeticException \
- (JvNewStringLatin1 ("/ by zero")); \
struct sigaction act; \
act.sa_sigaction = _Jv_catch_fpe; \
sigemptyset (&act.sa_mask); \
act.sa_flags = SA_SIGINFO; \
- __libc_sigaction (SIGFPE, &act, NULL); \
+ sigaction (SIGFPE, &act, NULL); \
} \
while (0)
#endif /* __ia64__ || __sparc__ */