Patch: FYI: libgcj_bc library

Tom Tromey tromey@redhat.com
Thu Aug 17 01:09:00 GMT 2006


I'm checking this in on the trunk.  I'll be pulling it over to the
gcj-eclipse branch shortly as well; Andrew needs it there for the next
round of changes.

This is a port from a patch on the RH 4.1 branch.  I'm not sure any
more who wrote what, but I know Bryce and Jakub worked on it, so I put
their names on the ChangeLog entry.

The idea behind this patch is to have a 'libgcj_bc' shared library
against which BC ABI shared libraries are linked.  This library's
soname will only change when there is an incompatible change to the BC
ABI.

This makes it somewhat simpler to update libgcj itself, or to have
multiple versions of libgcj installed at the same time.

This new library is only enabled on Linux.  Enabling it where
appropriate for other platforms should not be excessively difficult.

Tom

Index: gcc/java/ChangeLog
from  Jakub Jelinek  <jakub@redhat.com>
	Bryce McKinlay  <bryce@mckinlay.net.nz>

	* jvspec.c (lang_specific_driver): Add -s-bc-abi when needed.

Index: libjava/ChangeLog
from  Jakub Jelinek  <jakub@redhat.com>
	Bryce McKinlay  <bryce@mckinlay.net.nz>

	* configure, Makefile.in: Rebuilt.
	* Makefile.am (toolexeclib_LTLIBRARIES): Add libgcj_bc.la.
	(libgcj_bc_la_SOURCES): New variable.
	(libgcj_bc_la_LDFLAGS): Likewise.
	(libgcj_bc_la_LIBADD): Likewise.
	(libgcj_bc_la_DEPENDENCIES): Likewise.
	(libgcj_bc_la_LINK): Likewise.
	(libgcj_bc_dummy_LINK): Likewise.
	(libgcj_bc.la): New target.
	(install-exec-hook): Likewise.
	* libgcj.spec.in (*lib): Use LIBGCJ_SPEC.
	* libgcj_bc.c: New file.
	* configure.ac (LIBGCJ_SPEC): New subst.
	* configure.host (use_libgcj_bc): New variable.

Index: gcc/java/jvspec.c
===================================================================
--- gcc/java/jvspec.c	(revision 116140)
+++ gcc/java/jvspec.c	(working copy)
@@ -243,6 +243,9 @@
   /* The argument we use to specify the spec file.  */
   char *spec_file = NULL;
 
+  /* If linking, nonzero if the BC-ABI is in use.  */
+  int link_for_bc_abi = 0;
+
   argc = *in_argc;
   argv = *in_argv;
   added_libraries = *in_added_libraries;
@@ -365,6 +368,11 @@
           else if (strcmp (argv[i], "-static-libgcc") == 0
                    || strcmp (argv[i], "-static") == 0)
 	    shared_libgcc = 0;
+	  else if (strcmp (argv[i], "-findirect-dispatch") == 0
+		   || strcmp (argv[i], "--indirect-dispatch") == 0)
+	    {
+	      link_for_bc_abi = 1;
+	    }
 	  else
 	    /* Pass other options through.  */
 	    continue;
@@ -490,6 +498,8 @@
   
   num_args += shared_libgcc;
 
+  num_args += link_for_bc_abi;
+
   arglist = XNEWVEC (const char *, num_args + 1);
   j = 0;
 
@@ -599,6 +609,9 @@
   if (shared_libgcc)
     arglist[j++] = "-shared-libgcc";
 
+  if (link_for_bc_abi)
+    arglist[j++] = "-s-bc-abi";
+
   arglist[j] = NULL;
 
   *in_argc = j;
Index: libjava/configure.host
===================================================================
--- libjava/configure.host	(revision 116169)
+++ libjava/configure.host	(working copy)
@@ -31,6 +31,8 @@
 #   fallback_backtrace_h  Header to use for fallback backtrace implementation
 #			  (only for targets that don't support DWARF2 unwind)
 #   descriptor_h	Header to use for looking past function descriptors
+#   use_libgcj_bc	Whether to build a "libgcj-bc" library for BC-ABI
+#			binaries to link against.
 
 libgcj_flags=
 libgcj_cflags=
@@ -317,6 +319,15 @@
 	;;
 esac
 
+case "${host}" in
+  *linux*)
+    use_libgcj_bc=yes
+  ;;
+  *)
+    use_libgcj_bc=no
+  ;;
+esac    
+
 libgcj_cflags="${libgcj_cflags} ${libgcj_flags}"
 libgcj_cxxflags="${libgcj_cxxflags} ${libgcj_flags}"
 libgcj_javaflags="${libgcj_javaflags} ${libgcj_flags}"
Index: libjava/configure.ac
===================================================================
--- libjava/configure.ac	(revision 116169)
+++ libjava/configure.ac	(working copy)
@@ -881,12 +881,19 @@
 AM_CONDITIONAL(USING_POSIX_THREADS, test "$THREADS" = posix)
 AM_CONDITIONAL(USING_WIN32_THREADS, test "$THREADS" = win32)
 AM_CONDITIONAL(USING_NO_THREADS, test "$THREADS" = none)
+AM_CONDITIONAL(USE_LIBGCJ_BC, test "$use_libgcj_bc" = yes)
 
 if test -d sysdep; then true; else mkdir sysdep; fi
 AC_CONFIG_LINKS(sysdep/locks.h:sysdep/$sysdeps_dir/locks.h)
 AC_CONFIG_LINKS(sysdep/backtrace.h:$fallback_backtrace_h)
 AC_CONFIG_LINKS(sysdep/descriptor.h:$descriptor_h)
 
+LIBGCJ_SPEC="%{s-bc-abi:} -lgcj"
+if test "$use_libgcj_bc" = yes; then
+  LIBGCJ_SPEC="%{s-bc-abi:-lgcj_bc;:-lgcj}"
+fi
+AC_SUBST(LIBGCJ_SPEC)
+
 HASH_SYNC_SPEC=
 # Hash synchronization is only useful with posix threads right now.
 if test "$enable_hash_synchronization" = yes && test "$THREADS" != "none"; then
Index: libjava/libgcj_bc.c
===================================================================
--- libjava/libgcj_bc.c	(revision 0)
+++ libjava/libgcj_bc.c	(revision 0)
@@ -0,0 +1,94 @@
+/* libgcj_bc.c  */
+
+/* Copyright (C) 2006 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.  */
+
+/* This file is used to build libgcj_bc.so, a 'fake' library that is
+   used at link time only. It ensures that binaries built with the
+   BC-ABI link against a constant SONAME. This way, BC-ABI binaries
+   continue to work if the SONAME underlying libgcj.so changes.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+static void print_wrong_lib_msg ()
+{
+  fprintf (stderr, "libgcj error: \
+This is libgcj_bc.so, a fake library used only for linking.\n\
+Please create a symlink from libgcj_bc.so.1 to the real libgcj.so.\n");
+  exit (1);
+}
+
+/* Functions called from code generated by gcj.  */
+
+void __gcj_personality_v0 () {}
+void _Jv_AllocObject () {}
+void _Jv_AllocObjectNoFinalizer () {}
+void _Jv_InitClass () {}
+void _Jv_ResolvePoolEntry () {}
+void _Jv_Throw () {}
+void _Jv_MonitorEnter () {}
+void _Jv_NewPrimArray () {}
+void _Jv_NewObjectArray () {}
+void _Jv_NewMultiArray () {}
+void _Jv_ThrowBadArrayIndex () {}
+void _Jv_ThrowNullPointerException () {}
+void _Jv_ThrowAbstractMethodError () {}
+void _Jv_ThrowNoSuchFieldError () {}
+void _Jv_CheckCast () {}
+void _Jv_IsInstanceOf () {}
+void _Jv_CheckArrayStore () {}
+void _Jv_LookupInterfaceMethodIdx () {}
+
+void _Jv_RegisterClasses () 
+{
+  print_wrong_lib_msg ();
+}
+
+void _Jv_RegisterNewClasses () 
+{
+  print_wrong_lib_msg ();
+}
+
+/* Symbols used by jvgenmain (-fmain).  */
+
+void JvRunMain () {}
+const char **_Jv_Compiler_Properties;
+
+/* Functions used by -fjni.  */
+
+void _Jv_LookupJNIMethod () {}
+void _Jv_GetJNIEnvNewFrame () {}
+void _Jv_UnwrapJNIweakReference () {}
+
+
+/* Checked divide (-fuse-divide-subroutine).  */
+
+void _Jv_divI () {}
+void _Jv_remI () {}
+void _Jv_divJ () {}
+void _Jv_remJ () {}
+
+
+/* CNI Functions.  */
+
+void _Jv_AllocBytes () {}
+void _Jv_AllocString () {}
+void _Jv_NewString () {}
+void _Jv_NewStringLatin1 () {}
+void _Jv_GetStringChars () {}
+void _Jv_GetStringUTFLength () {}
+void _Jv_GetStringUTFRegion () {}
+void _Jv_NewStringUTF () {}
+void _Jv_Malloc () {}
+void _Jv_Realloc () {}
+void _Jv_Free () {}
+void _Jv_CreateJavaVM () {}
+void _Jv_AttachCurrentThread () {}
+void _Jv_AttachCurrentThreadAsDaemon () {}
+void _Jv_DetachCurrentThread () {}
Index: libjava/libgcj.spec.in
===================================================================
--- libjava/libgcj.spec.in	(revision 116169)
+++ libjava/libgcj.spec.in	(working copy)
@@ -7,6 +7,6 @@
 *startfile: @THREADSTARTFILESPEC@ %(startfileorig)
 
 %rename lib liborig
-*lib: @LD_START_STATIC_SPEC@ -lgcj @LD_FINISH_STATIC_SPEC@ -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
+*lib: @LD_START_STATIC_SPEC@ @LIBGCJ_SPEC@ @LD_FINISH_STATIC_SPEC@ -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
 
 *jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ -fkeep-inline-functions
Index: libjava/Makefile.am
===================================================================
--- libjava/Makefile.am	(revision 116169)
+++ libjava/Makefile.am	(working copy)
@@ -36,6 +36,10 @@
 toolexeclib_LTLIBRARIES = libgcj.la libgij.la libgcj-tools.la
 toolexecmainlib_DATA = libgcj.spec
 
+if USE_LIBGCJ_BC
+toolexeclib_LTLIBRARIES += libgcj_bc.la
+endif
+
 if XLIB_AWT
 toolexeclib_LTLIBRARIES += lib-gnu-awt-xlib.la
 endif
@@ -277,6 +281,31 @@
         -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC)
 lib_gnu_awt_xlib_la_LINK = $(LIBLINK)
 
+## Support for libgcj_bc: dummy shared library.
+##
+## This lets us have one soname in BC objects and another in C++ ABI objects.
+libgcj_bc_la_SOURCES = libgcj_bc.c
+libgcj_bc_la_LDFLAGS = -rpath $(toolexeclibdir) -no-static -version-info 1:0:0
+libgcj_bc_la_LIBADD = libgcj.la
+libgcj_bc_la_DEPENDENCIES = libgcj.la
+libgcj_bc_la_LINK = $(LIBLINK)
+## This is specific to Linux/{Free,Net,Open}BSD/Hurd and perhaps few others.
+## USE_LIBGCJ_BC shouldn't be set on other targets.
+libgcj_bc_dummy_LINK = $(CC) -L$(here)/.libs $(CFLAGS) $(LDFLAGS) -shared \
+	-fPIC -nostdlib
+
+## This rule creates the libgcj_bc dummy library in the .libs directory, for use
+## when testing.
+libgcj_bc.la: $(libgcj_bc_la_OBJECTS) $(libgcj_bc_la_DEPENDENCIES)
+	$(libgcj_bc_la_LINK) $(am_libgcj_bc_la_rpath) $(libgcj_bc_la_LDFLAGS) \
+	$(libgcj_bc_la_OBJECTS) $(libgcj_bc_la_LIBADD) $(LIBS) || exit; \
+	rm .libs/libgcj_bc.so; \
+	mv .libs/libgcj_bc.so.1.0.0 .libs/libgcj_bc.so; \
+	$(libgcj_bc_dummy_LINK) -xc /dev/null -Wl,-soname,libgcj_bc.so.1 \
+	-o .libs/libgcj_bc.so.1.0.0 -lgcj || exit; \
+	rm .libs/libgcj_bc.so.1; \
+	$(LN_S) libgcj_bc.so.1.0.0 .libs/libgcj_bc.so.1
+
 ## Note that property_files is defined in sources.am.
 propertyo_files = $(patsubst classpath/resource/%,%,$(addsuffix .lo,$(property_files)))
 
@@ -507,6 +536,22 @@
 $(extra_headers) $(srcdir)/java/lang/Object.h $(srcdir)/java/lang/Class.h:
 	@:
 
+## Support for libgcj_bc: dummy shared library used only at link-time.
+if USE_LIBGCJ_BC
+## Install libgcj_bc dummy lib in the target directory. We also need to delete
+## libtool's .la file, this prevents libtool resetting the lib again 
+## later.
+install-exec-hook: install-toolexeclibLTLIBRARIES
+	@echo Installing dummy lib libgcj_bc.so.1.0.0; \
+	rm $(toolexeclibdir)/libgcj_bc.so; \
+	mv $(toolexeclibdir)/libgcj_bc.so.1.0.0 $(toolexeclibdir)/libgcj_bc.so; \
+	$(libgcj_bc_dummy_LINK) -xc /dev/null -Wl,-soname,libgcj_bc.so.1 \
+	-o $(toolexeclibdir)/libgcj_bc.so.1.0.0 -lgcj || exit; \
+	rm $(toolexeclibdir)/libgcj_bc.so.1; \
+	$(LN_S) libgcj_bc.so.1.0.0 $(toolexeclibdir)/libgcj_bc.so.1; \
+	rm $(toolexeclibdir)/libgcj_bc.la;
+endif
+
 ## Install the headers.  It is fairly ugly that we have to do this by
 ## hand.
 install-data-local:



More information about the Gcc-patches mailing list