diff --git a/libjava/ChangeLog b/libjava/ChangeLog index e7c780f8543..46a90850dee 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,11 @@ +2002-03-25 Andrew Haley , Hans Boehm + + * configure.in, configure: enable dwarf2-exception-style + exception handling on IA-64. + * include/dwarf2-signal.h (MAKE_THROW_FRAME): Add for IA-64. + (INIT_SEGV, INIT_FPE): Use __libc_sigaction instead of syscall. + Add FIXME comment. + 2002-03-25 Tom Tromey * Makefile.am (libgcj_la_LDFLAGS): Use THREADLDFLAGS. diff --git a/libjava/configure b/libjava/configure index 5fd51a12253..f86c865a395 100755 --- a/libjava/configure +++ b/libjava/configure @@ -6400,6 +6400,9 @@ case "${host}" in # SYSDEP_SOURCES=sysdep/ia64.c # test -d sysdep || mkdir sysdep # ;; + ia64-*-linux*) + SIGNAL_HANDLER=include/dwarf2-signal.h + ;; powerpc-*-linux*) SIGNAL_HANDLER=include/dwarf2-signal.h ;; diff --git a/libjava/configure.in b/libjava/configure.in index 4ca3930034c..ba9649535d4 100644 --- a/libjava/configure.in +++ b/libjava/configure.in @@ -852,6 +852,9 @@ case "${host}" in # SYSDEP_SOURCES=sysdep/ia64.c # test -d sysdep || mkdir sysdep # ;; + ia64-*-linux*) + SIGNAL_HANDLER=include/dwarf2-signal.h + ;; powerpc-*-linux*) SIGNAL_HANDLER=include/dwarf2-signal.h ;; diff --git a/libjava/include/dwarf2-signal.h b/libjava/include/dwarf2-signal.h index 3a662aec2d9..f1572d3e772 100644 --- a/libjava/include/dwarf2-signal.h +++ b/libjava/include/dwarf2-signal.h @@ -41,7 +41,25 @@ do \ _sc->sc_pc += 4; \ } \ while (0) + +#elif defined(__ia64__) + +#define MAKE_THROW_FRAME(_exception) \ +do \ +{ \ + /* IA-64 either leaves PC pointing at a faulting instruction or the \ + following instruction, depending on the signal. SEGV always does \ + the former, 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 sigcontext *_sc = (struct sigcontext *)_p; \ + _sc->sc_ip++; \ +} \ +while (0) #else +#error #define MAKE_THROW_FRAME(_exception) \ do \ { \ @@ -50,6 +68,16 @@ do \ while (0) #endif +// 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 (); + #define INIT_SEGV \ do \ { \ @@ -58,7 +86,7 @@ do \ act.sa_sigaction = _Jv_catch_segv; \ sigemptyset (&act.sa_mask); \ act.sa_flags = SA_SIGINFO; \ - syscall (SYS_sigaction, SIGSEGV, &act, NULL); \ + __libc_sigaction (SIGSEGV, &act, NULL); \ } \ while (0) @@ -71,7 +99,7 @@ do \ act.sa_sigaction = _Jv_catch_fpe; \ sigemptyset (&act.sa_mask); \ act.sa_flags = SA_SIGINFO; \ - syscall (SYS_sigaction, SIGFPE, &act, NULL); \ + __libc_sigaction (SIGFPE, &act, NULL); \ } \ while (0)