This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
RFA: [PATCH]: MIPS enhancements to libgcj...
- From: David Daney <ddaney at avtrex dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Tue, 21 Oct 2003 10:36:05 -0700
- Subject: RFA: [PATCH]: MIPS enhancements to libgcj...
Greetings,
Here is a much improved version of my libgcj/mips patch.
Build for and tested on mipsisa32el-linux.
For some running the test suite on our hardware is broken again, but I
have successfully run several of the key tests manually. This
includes PR218 and SyncTest.
All added features were tested. Also the gcc-3.3.1 version passes the
entire libjava testsuite (except for a couple of unrelated code
generation problems) for what ever that is worth.
The patch adds can_unwind_signal=yes and backtracing for all
mips*-linux platforms. And enable_hash_synchronization_default=yes
for (mipsel*-linux* | mipsisa32el*-linux*). I think the hash
synchronization would work for others as well, but would want someone
to test it before enabling it.
The backtrace is implemented in sysdep/dwarf2-backtrace.cc which I
think will work for all *-linux* targets. If someone wants to test
this theory, that would be great.
Since I am only an amateur MIPS expert, perhaps someone (a real MIPS
expert for example) should look at sysdeps/mips/locks.h
BTW: I now have write after approval in gcc so I can do the checkins now.
David Daney.
Index: libjava/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libjava/ChangeLog,v
retrieving revision 1.2280
diff -3 -u -p -r1.2280 ChangeLog
--- libjava/ChangeLog 20 Oct 2003 20:14:04 -0000 1.2280
+++ libjava/ChangeLog 21 Oct 2003 01:36:41 -0000
@@ -1,3 +1,27 @@
+2003-10-20 David Daney <ddaney@avtrex.com)
+
+ * include/mips-signal.h: New file.
+ * sysdep/dwarf2-backtrace.cc: New file.
+ * sysdep/mips: New directory.
+ * sysdep/mips/locks.h: New file.
+ * Makefile.am(extra_cc_files): New, to allow extra c++ files to be
+ added to libgcj.
+ (extra_cc_source_files): Ditto.
+ * configure.in: added --with-broken-dladdr, --with-libgcj-mips-xgot
+ (mips*-*-linux*): Use sysdep/dwarf2-backtrace.cc to generate
+ backtrace, and include/mips-signal.h as SIGNAL_HANDLER
+ (HAVE_DLADDR): Make it depend on setting of --with-broken-dladdr.
+ (EXTRA_CC_FILES): New, to support conditional addition of
+ sysdep/dwarf2-backtrace.cc.
+ * configure.host(mips*-*-linux*): sysdeps_dir=mips,
+ can_unwind_signal=yes, use -mxgot if --with-libgcj-mips-xgot set.
+ (mipsel*-linux* | mipsisa32el*-linux*): Enable hash synchronization.
+ * configure: Regenerated.
+ * Makefile.in: Regenerated.
+ * include/config.h.in: Regenerated.
+ * include/Makefile.in: Regenerated.
+ * testsuite/Makefile.in: Regenerated.
+
2003-10-20 Michael Koch <konqueror@gmx.de>
* java/text/RuleBasedCollator.java
Index: gcc/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.1496
diff -3 -u -p -r2.1496 ChangeLog
--- gcc/ChangeLog 20 Oct 2003 23:45:28 -0000 2.1496
+++ gcc/ChangeLog 21 Oct 2003 01:36:09 -0000
@@ -1,3 +1,8 @@
+2003-10-20 David Daney <ddaney@avtrex.com>
+
+ * doc/install.texi: Document --with-broken-dladdr and
+ --with-libgcj-mips-xgot.
+
2003-10-20 Kelley Cook <kcook@gcc.gnu.org>
* Makefile.in: Get parsedir and docobjdir from configure.
Index: gcc/doc/install.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/install.texi,v
retrieving revision 1.230
diff -3 -u -p -r1.230 install.texi
--- gcc/doc/install.texi 20 Oct 2003 23:45:51 -0000 1.230
+++ gcc/doc/install.texi 21 Oct 2003 01:36:19 -0000
@@ -1112,6 +1112,17 @@ error message.
All support for systems which have been obsoleted in one release of GCC
is removed entirely in the next major release, unless someone steps
forward to maintain the port.
+
+@item --with-broken-dladdr
+Specify that libgcj should not try to use the dladdr function. It does
+this to resolve stack trace addresses and on systems with a broken
+dladdr this can cause a SIGSEGV.
+
+@item --with-libgcj-mips-xgot
+Specify that libgcj should be built with -mxgot on MIPS systems. The
+way in which libtool does multi-stage linking on systems with short
+maximum command line lengths can cause GOT overflow errors while
+linking. This option enables a large GOT to work around the problem.
@end table
Some options which only apply to building cross compilers:
Index: libjava/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.332
diff -3 -u -p -r1.332 Makefile.am
--- libjava/Makefile.am 12 Oct 2003 13:39:06 -0000 1.332
+++ libjava/Makefile.am 21 Oct 2003 01:36:42 -0000
@@ -138,6 +138,7 @@ nat_files = $(nat_source_files:.cc=.lo)
x_nat_files = $(x_nat_source_files:.cc=.lo)
## Objects from C sources in subdirs.
c_files = $(c_source_files:.c=.lo)
+extra_cc_files = $(extra_cc_source_files:.cc=.lo)
## Objects from gtk-related C sources in subdirs.
gtk_c_files = $(gtk_c_source_files:.c=.lo)
## Objects from Java sources in subdirs.
@@ -149,13 +150,13 @@ libgcj_la_SOURCES = prims.cc jni.cc exce
resolve.cc defineclass.cc interpret.cc verify.cc \
$(nat_source_files)
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
- win32-threads.cc posix.cc win32.cc \
- $(c_source_files) $(java_source_files) $(built_java_source_files)
+ win32-threads.cc posix.cc win32.cc $(c_source_files) \
+ $(extra_cc_source_files) $(java_source_files) $(built_java_source_files)
libgcj_la_DEPENDENCIES = libgcj-@gcc_version@.jar $(javao_files) \
- $(c_files) $(GCOBJS) $(THREADOBJS) $(PLATFORMOBJS) $(LIBLTDL) \
- $(LIBFFI) $(ZLIBS) $(GCLIBS)
+ $(c_files) $(extra_cc_files) $(GCOBJS) $(THREADOBJS) \
+ $(PLATFORMOBJS) $(LIBLTDL) $(LIBFFI) $(ZLIBS) $(GCLIBS)
-libgcj_la_LIBADD = $(javao_files) $(c_files) $(GCOBJS) \
+libgcj_la_LIBADD = $(javao_files) $(c_files) $(extra_cc_files) $(GCOBJS) \
$(THREADOBJS) $(PLATFORMOBJS)
# Include THREADLIBS here to ensure that the correct version of
# certain linuxthread functions get linked:
@@ -418,6 +419,9 @@ $(nat_files) $(x_nat_files): %.lo: %.cc
$(c_files): %.lo: %.c
$(LTCOMPILE) -c -o $@ $<
+$(extra_cc_files): %.lo: %.cc
+ $(LTCXXCOMPILE) -c -o $@ $<
+
$(c_files): java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h
## FIXME: see above
@@ -2631,6 +2635,8 @@ c_source_files = \
java/lang/e_scalb.c java/lang/s_rint.c java/lang/w_sqrt.c \
java/lang/e_sqrt.c java/lang/s_scalbn.c java/lang/sf_rint.c \
java/lang/k_cos.c java/lang/s_sin.c java/lang/sf_fabs.c
+
+extra_cc_source_files = $(EXTRA_CC_FILES)
#java/awt/natToolkit.cc
Index: libjava/configure.host
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.host,v
retrieving revision 1.53
diff -3 -u -p -r1.53 configure.host
--- libjava/configure.host 10 Sep 2003 18:50:47 -0000 1.53
+++ libjava/configure.host 21 Oct 2003 01:36:53 -0000
@@ -213,6 +213,18 @@ EOF
rm -f conftest conftest.c
fi
;;
+ mips*-*-linux* )
+ sysdeps_dir=mips
+ can_unwind_signal=yes
+ if test "x${with_libgcj_mips_xgot}" = "xyes"; then
+ libgcj_flags="${libgcj_flags} -mxgot"
+ fi
+ case "${host}" in
+ mipsel*-linux* | mipsisa32el*-linux*)
+ enable_hash_synchronization_default=yes
+ ;;
+ esac
+ ;;
*-*-darwin*)
enable_hash_synchronization_default=no
slow_pthread_self=
Index: libjava/configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.in,v
retrieving revision 1.172
diff -3 -u -p -r1.172 configure.in
--- libjava/configure.in 22 Sep 2003 16:04:24 -0000 1.172
+++ libjava/configure.in 21 Oct 2003 01:36:58 -0000
@@ -19,6 +19,12 @@ AC_ARG_WITH(cross-host,
AC_ARG_WITH(newlib,
[ --with-newlib Configuring with newlib])
+AC_ARG_WITH(broken-dladdr,
+[ --with-broken-dladdr Configuring to not use dladdr because it is broken])
+
+AC_ARG_WITH(libgcj-mips-xgot,
+[ --with-libgcj-mips-xgot For MIPS builds use -Wa,-xgot to build libgcj])
+
LIBGCJ_CONFIGURE(.)
AM_CONFIG_HEADER(include/config.h gcj/libgcj-config.h)
@@ -232,6 +238,9 @@ AC_ARG_WITH(ecos,
TARGET_ECOS="$with_ecos"
)
+EXTRA_CC_FILES=
+AC_SUBST(EXTRA_CC_FILES)
+
PLATFORMOBJS=
case "$TARGET_ECOS" in
no) case "$host" in
@@ -600,6 +609,13 @@ else
ia64-*-linux*)
# Has broken backtrace()
;;
+ mips*-*-linux*)
+ # Has broken backtrace(), but we supply our own.
+ if test -d sysdep; then true; else mkdir -p sysdep; fi
+ EXTRA_CC_FILES="${EXTRA_CC_FILES} sysdep/dwarf2-backtrace.cc"
+ AC_DEFINE(HAVE_BACKTRACE, 1,
+ [Define if your platform has a working backtrace() function.])
+ ;;
*)
AC_DEFINE(HAVE_BACKTRACE, 1,
[Define if your platform has a working backtrace() function.])
@@ -616,7 +632,13 @@ else
])
AC_CHECK_LIB(dl, dladdr, [
- AC_DEFINE(HAVE_DLADDR, 1, [Define if you have dladdr()])])
+ if test "x${with_broken_dladdr}" = "xyes"; then
+ #Broken dladdr().
+ true
+ else
+ AC_DEFINE(HAVE_DLADDR, 1, [Define if you have dladdr()])
+ fi
+ ])
if test x"$build" = x"$host"; then
AC_CHECK_FILES(/proc/self/exe, [
AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])])
@@ -1106,6 +1128,9 @@ case "${host}" in
;;
*mingw*)
SIGNAL_HANDLER=include/win32-signal.h
+ ;;
+ mips*-*-linux*)
+ SIGNAL_HANDLER=include/mips-signal.h
;;
*)
SIGNAL_HANDLER=include/default-signal.h
Index: libjava/include/mips-signal.h
===================================================================
RCS file: libjava/include/mips-signal.h
diff -N libjava/include/mips-signal.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/include/mips-signal.h 21 Oct 2003 01:36:58 -0000
@@ -0,0 +1,89 @@
+// mips-signal.h - Catch runtime signals and turn them into exceptions
+// on an mips based Linux system.
+
+/* Copyright (C) 1998, 1999, 2001, 2002, 2003 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. */
+
+/* Adapted from sparc-signal.h and powerpc-signal.h
+ by David Daney <ddaney@avtrex.com> */
+
+#ifndef JAVA_SIGNAL_H
+#define JAVA_SIGNAL_H 1
+
+#include <signal.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+/* #include <asm/ucontext.h> structures we use are here but clash with
+ sys/ucontext.h included by java-signal.h from prims.cc */
+
+#define HANDLE_SEGV 1
+#undef HANDLE_FPE
+
+/* 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;
+
+/* We use kernel_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.
+ Additionally we want a proper prototype for the handler function
+ with the struct sigcontext pointer passed by the kernel as the 2nd
+ argument, which isn't there in userland headers. */
+
+struct kernel_sigaction {
+ unsigned int k_sa_flags;
+ void (*k_sa_handler) (int, siginfo_t *, sig_ucontext_t *);
+ sigset_t k_sa_mask;
+ void (*k_sa_restorer)(void);
+ int k_sa_resv[1]; /* reserved */
+};
+
+
+
+#define SIGNAL_HANDLER(_name) \
+static void _name (int _dummy, siginfo_t *_info, sig_ucontext_t *_arg)
+
+/*
+ * MIPS leaves pc pointing at the faulting instruction, but the
+ * unwinder expects it to point to the following instruction
+ */
+
+#define MAKE_THROW_FRAME(_exception) \
+do \
+{ \
+ _arg->uc_mcontext.sc_pc += 4; \
+ (void)_dummy; \
+ (void)_info; \
+} \
+while (0)
+
+/* For an explanation why we cannot simply use sigaction to
+ install the handlers, see i386-signal.h. */
+
+#define INIT_SEGV \
+do \
+ { \
+ struct kernel_sigaction kact; \
+ kact.k_sa_handler = catch_segv; \
+ kact.k_sa_flags = SA_SIGINFO | SA_NODEFER; \
+ sigemptyset (&kact.k_sa_mask); \
+ syscall (SYS_sigaction, SIGSEGV, &kact, NULL); \
+ } \
+while (0)
+
+
+#endif /* JAVA_SIGNAL_H */
+
Index: libjava/sysdep/dwarf2-backtrace.cc
===================================================================
RCS file: libjava/sysdep/dwarf2-backtrace.cc
diff -N libjava/sysdep/dwarf2-backtrace.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/sysdep/dwarf2-backtrace.cc 21 Oct 2003 01:37:00 -0000
@@ -0,0 +1,86 @@
+/* dwarf2-backtrac.cc - backtrace implementation driven by the dwarf2
+ exception unwinder. */
+
+/* Copyright (C) 2003 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. */
+
+/* Written by David Daney <ddaney@avtrex.com> */
+
+/*
+ Although this in theory could be 'C' instead of C++, saying that it
+ is C++ and including jvm.h makes it easier to insure that the proper
+ compiler options are used. There must be unwind tables for
+ backtrace because it is on the stack when _Unwind_Backtrace is
+ called. Compiling as C++ insures this.
+
+*/
+
+#include <config.h>
+
+#include <unwind.h>
+
+#include <jvm.h>
+
+
+extern "C"
+{
+ int backtrace (void **, int);
+}
+
+struct backtrace_state
+{
+ int skip_count;
+ int current_level;
+ int max_level;
+ void **locations;
+};
+
+static _Unwind_Reason_Code
+my_trace_fn (struct _Unwind_Context *uc, void *arg)
+{
+
+ struct backtrace_state *bs = (struct backtrace_state *) arg;
+
+ if (bs->skip_count)
+ {
+ bs->skip_count--;
+ return _URC_NO_REASON;
+ }
+
+ _Unwind_Ptr loc = _Unwind_GetIP (uc);
+
+ if (bs->current_level < bs->max_level)
+ bs->locations[bs->current_level++] = (void *) loc;
+
+ if (bs->current_level >= bs->max_level)
+ return _URC_END_OF_STACK;
+ else
+ return _URC_NO_REASON;
+}
+
+/*
+ * backtrace is defined in (some versions of) libc. This definition
+ * must match so that it can replace the libc version at link time.
+ *
+ * Fill the locations array with at most len back trace locations.
+ *
+ * Returns the number of locations actually filled in.
+ *
+ */
+int
+backtrace (void **locations, int len)
+{
+ struct backtrace_state bs;
+ bs.skip_count = 1; /* Don't log the call to backtrace itself. */
+ bs.current_level = 0;
+ bs.max_level = len;
+ bs.locations = locations;
+
+ _Unwind_Backtrace (my_trace_fn, &bs);
+ return bs.current_level;
+}
--- /dev/null Thu Apr 11 07:25:15 2002
+++ libjava/sysdep/mips/locks.h Fri Oct 17 09:51:34 2003
@@ -0,0 +1,87 @@
+// locks.h - Thread synchronization primitives. MIPS implementation.
+
+/* Copyright (C) 2003 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 __SYSDEP_LOCKS_H__
+#define __SYSDEP_LOCKS_H__
+
+/* Integer type big enough for object address. */
+typedef unsigned obj_addr_t __attribute__((__mode__(__pointer__)));
+
+
+// Atomically replace *addr by new_val if it was initially equal to old.
+// Return true if the comparison succeeded.
+// Assumed to have acquire semantics, i.e. later memory operations
+// cannot execute before the compare_and_swap finishes.
+inline static bool
+compare_and_swap(volatile obj_addr_t *addr,
+ obj_addr_t old,
+ obj_addr_t new_val)
+{
+ long result;
+ __asm__ __volatile__("1:\n\t"
+ ".set\tpush\n\t"
+#if _MIPS_SIM == _ABIO32
+ ".set\tmips2\n\t"
+#endif
+ "ll\t%[result],0(%[addr])\n\t"
+ "beq\t%[result],%[old],2f\n\t"
+ "move\t%[result],$0\n\t"
+ "b\t3f\n"
+ "2:\tmove\t%[result],%[new_val]\n\t"
+ "sc\t%[result],0(%[addr])\n\t"
+ "beq\t%[result],$0,1b\n\t"
+ ".set\tpop\n\t"
+ "3:"
+ : [result] "=&r" (result)
+ : [addr] "r" (addr), [new_val] "r" (new_val), [old] "r"(old)
+ : "memory");
+ return (bool) result;
+}
+
+// Set *addr to new_val with release semantics, i.e. making sure
+// that prior loads and stores complete before this
+// assignment.
+inline static void
+release_set(volatile obj_addr_t *addr, obj_addr_t new_val)
+{
+ __asm__ __volatile__("sync" : :);
+ *(addr) = new_val;
+}
+
+// Compare_and_swap with release semantics instead of acquire semantics.
+// On many architecture, the operation makes both guarantees, so the
+// implementation can be the same.
+inline static bool
+compare_and_swap_release(volatile obj_addr_t *addr,
+ obj_addr_t old,
+ obj_addr_t new_val)
+{
+ __asm__ __volatile__("sync" : :);
+ return compare_and_swap(addr, old, new_val);
+}
+
+// Ensure that subsequent instructions do not execute on stale
+// data that was loaded from memory before the barrier.
+// On X86, the hardware ensures that reads are properly ordered.
+inline static void
+read_barrier()
+{
+ __asm__ __volatile__("sync" : :);
+}
+
+// Ensure that prior stores to memory are completed with respect to other
+// processors.
+inline static void
+write_barrier()
+{
+ __asm__ __volatile__("sync" : :);
+}
+
+#endif // __SYSDEP_LOCKS_H__