This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/RFA] SH custom java-signal.h


Hi,

The appended patch fixes a long standing failure for Array_3 test on
sh4-unknown-linux-gnu with an sh custom java-signal.h.  It bootstraps
on mainline without new regressions for sh4-unknown-linux-gnu.
The compiler part is purely sh-linux specific.
Is the java part ok for mainline?

Regards,
	kaz
--
2004-10-16  Kaz Kojima  <kkojima@gcc.gnu.org>

[gcc]
	* config/sh/linux-unwind.h (sh_fallback_frame_state): Don't
	fixup pc here.

[libjava]
	* configure.ac (SIGNAL_HANDLER): Set to include/sh-signal.h
	for all sh*-*-linux* targets.
	* configure: Regenerate.
	* include/sh-signal.h: New file.

diff -urpN ORIG/gcc/gcc/config/sh/linux-unwind.h gcc/gcc/config/sh/linux-unwind.h
--- ORIG/gcc/gcc/config/sh/linux-unwind.h	Wed Sep  8 09:17:18 2004
+++ gcc/gcc/config/sh/linux-unwind.h	Fri Oct  8 08:55:13 2004
@@ -154,10 +154,6 @@ sh_fallback_frame_state (struct _Unwind_
     = (long)&(sc->sc_fpscr) - new_cfa;
 #endif
 
-  /* The unwinder expects the PC to point to the following insn,
-     whereas the kernel returns the address of the actual
-     faulting insn.  */
-  sc->sc_pc += 2;
   fs->regs.reg[SH_DWARF_FRAME_PC].how = REG_SAVED_OFFSET;
   fs->regs.reg[SH_DWARF_FRAME_PC].loc.offset
     = (long)&(sc->sc_pc) - new_cfa;
diff -urpN ORIG/gcc/libjava/configure.ac gcc/libjava/configure.ac
--- ORIG/gcc/libjava/configure.ac	Fri Oct  8 08:18:27 2004
+++ gcc/libjava/configure.ac	Fri Oct  8 08:55:13 2004
@@ -1310,8 +1310,8 @@ case "${host}" in
  sparc*-*-linux*)
     SIGNAL_HANDLER=include/dwarf2-signal.h
     ;;
- sh-*-linux* | sh[[34]]*-*-linux*)
-    SIGNAL_HANDLER=include/dwarf2-signal.h
+ sh*-*-linux*)
+    SIGNAL_HANDLER=include/sh-signal.h
     ;;
  *mingw*)
     SIGNAL_HANDLER=include/win32-signal.h
diff -urpN ORIG/gcc/libjava/include/sh-signal.h gcc/libjava/include/sh-signal.h
--- ORIG/gcc/libjava/include/sh-signal.h	Thu Jan  1 09:00:00 1970
+++ gcc/libjava/include/sh-signal.h	Fri Oct  8 08:55:13 2004
@@ -0,0 +1,96 @@
+// sh-signal.h - Catch runtime signals and turn them into exceptions
+// on a SuperH based Linux system.
+
+/* Copyright (C) 2004  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+
+#ifndef JAVA_SIGNAL_H
+#define JAVA_SIGNAL_H 1
+
+#include <signal.h>
+#include <sys/syscall.h>
+
+#define HANDLE_SEGV 1
+#define HANDLE_FPE 1
+
+/* The third parameter to the signal handler points to something with
+ * this structure defined in asm/ucontext.h, but the name clashes with
+ * struct ucontext from sys/ucontext.h so this private copy is used.  */
+typedef struct _sig_ucontext {
+  unsigned long uc_flags;
+  struct _sig_ucontext *uc_link;
+  stack_t uc_stack;
+  struct sigcontext uc_mcontext;
+  sigset_t uc_sigmask;
+} sig_ucontext_t;
+
+#define SIGNAL_HANDLER(_name)						\
+  static void _name (int , siginfo_t *, sig_ucontext_t *_uc)
+
+/* SH 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.  */
+
+#ifdef __SH5__
+#define MAKE_THROW_FRAME(_exception)					\
+do									\
+  {									\
+    volatile struct sigcontext *_sc = &_uc->uc_mcontext;		\ 
+    _sc->sc_pc += 4;							\
+  }									\
+while (0)
+#else
+#define MAKE_THROW_FRAME(_exception)					\
+do									\
+  {									\
+    volatile struct sigcontext *_sc = &_uc->uc_mcontext;		\ 
+    _sc->sc_pc += 2;							\
+  }									\
+while (0)
+#endif
+
+/* For an explanation why we cannot simply use sigaction to
+   install the handlers, see i386-signal.h.  */
+
+/* We use kernel_old_sigaction here because we're calling the kernel
+   directly rather than via glibc.  The sigaction structure that the
+   syscall uses is a different shape from the one in userland and not
+   visible to us in a header file so we define it here.  */
+
+struct kernel_old_sigaction {
+  void (*k_sa_handler) (int, siginfo_t *, sig_ucontext_t *);
+  unsigned long k_sa_mask;
+  unsigned long k_sa_flags;
+  void (*k_sa_restorer) (void);
+};
+
+#define INIT_SEGV							\
+do									\
+  {									\
+    struct kernel_old_sigaction kact;					\
+    kact.k_sa_handler = catch_segv;					\
+    kact.k_sa_mask = 0;							\
+    kact.k_sa_flags = SA_SIGINFO | SA_NODEFER;				\
+    syscall (SYS_sigaction, SIGSEGV, &kact, NULL);			\
+  }									\
+while (0)  
+
+#define INIT_FPE							\
+do									\
+  {									\
+    struct kernel_old_sigaction kact;					\
+    kact.k_sa_handler = catch_fpe;					\
+    kact.k_sa_mask = 0;							\
+    kact.k_sa_flags = SA_SIGINFO | SA_NODEFER;				\
+    syscall (SYS_sigaction, SIGFPE, &kact, NULL);			\
+  }									\
+while (0)
+
+#endif /* JAVA_SIGNAL_H */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]