diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 6feb54e0ff1ca269de1c85b41d52b829210b2675..2bad1d497502aff0293662a3f28b141b9ae251aa 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,10 @@
+2004-10-21  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+	* configure.ac (SIGNAL_HANDLER): Set to include/sh-signal.h
+	for all sh*-*-linux* targets.
+	* configure: Regenerate.
+	* include/sh-signal.h: New file.
+
 2004-10-21  Kazuhiro Inaoka  <inaoka.kazuhiro@renesas.com>
 
 	* java/lang/ieeefp.h: Add m32r support.
diff --git a/libjava/configure b/libjava/configure
index 050c5281a71c03bd0ed3c5310bc7405cf8d600bd..d3ce0509d0fba934dd0ce4eb1a7ccaa577829655 100755
--- a/libjava/configure
+++ b/libjava/configure
@@ -16211,8 +16211,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 --git a/libjava/configure.ac b/libjava/configure.ac
index c0282afda5bada2e32ba36e7257a526777ded04c..80775ab6219ab576223e1b3ebda73e3ac388db3b 100644
--- a/libjava/configure.ac
+++ b/libjava/configure.ac
@@ -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 --git a/libjava/include/sh-signal.h b/libjava/include/sh-signal.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c76b5716bebf1465787822ba3810faae5688ef2
--- /dev/null
+++ b/libjava/include/sh-signal.h
@@ -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 */