diff mbox

[build,libjava] Support Sun symbol versioning in libjava

Message ID yddy6dv6ve5.fsf@CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth July 1, 2010, 4:04 p.m. UTC
[Please keep me on the Cc:, I'm not subscribed to java-patches.  Thanks.]

After the precedent established by the patch to support Sun symbol
versioning in libstdc++

	PATCH: Support Sun symbol versioning in libstdc++-v3
        http://gcc.gnu.org/ml/gcc-patches/2010-02/msg01001.html

and its revision

	[build, doc, v3] Support Sun symbol versioning in libstdc++-v3, rev. 2
        http://gcc.gnu.org/ml/gcc-patches/2010-06/msg03182.html

libjava appeared relatively easy at first:

* One issue of note is that the original map file in configure.ac used
  wildcards, which Sun ld cannot handle as described, so I need to use a
  different mapfile here.

* Apart from that, I've reformatted the mapfile to make it easier to
  parse for the make_sunver.pl script.

While this worked initially, a bootstrap revealed an additional problem,
namely the use of the same mapfile for various different target
libraries.  Since for Sun ld corresponding mapfiles need to be generated
at build time and depend on the target library, I need to use different
*_version_arg variables to add to the *_la_LINK variables instead of the
common additon to extra_ldflags_libjava.  I also need per-library
variables to hold the mapfile as a dependency, which allows me to
somewhat simplify the Makefile.am, since I can set those variables even
in the unversioned case.

The main problem was that I cannot use the simple target used in the
other versioned libraries to generate the Sun mapfile, since I'd like to
avoid duplicating the same pattern over and over again.  It turned out
that the GNU make .SECONDEXPANSION: target comes in handy, since it
allows me to use automatic variables in the requisites of pattern rules.
I had to move both the .SECONDEXPANSION: target and the pattern rule to
the end of Makefile.am since otherwise filenames with $'s (which are
common inside libjava) are also expanded a second time, breaking the
build.

There's one other issue which caused me some headache: the pattern rule
I use to generate the sun version maps has a dependency on the object
files and libraries used to build the target library.  As I said,
.SECONDEXPANSION: allows me to refer to the make target with $$@ and
indirectly reference the *_la_OBJECTS and *_la_LIBADD variables.
Unfortunately, this breaks for libgcj_tools_la_LIBADD, which contains
-lm, which of course doesn't exist as a filename, breaking the build.
My solution was to move -lm (which is needed for an instance of fmod in
libgcj-tools.so) to libgcj_tools_la_LDFLAGS instead.  The Automake
manual suggests this is allowed.

Another complication that I hadn't come across with the other target
libraries was the creation of libgcj-tools.so.  It depends, via
libgcj_tools_la_LIBADD, on libgcj.la.  Before, the rules to generate the
Sun version map would look at every .o and .a file corresponding to the
.lo and .la files and add every symbol found in one of them to the
generated map.  In the case of libgcj.la, this is wrong: while libgcj.a
exists and provides tons of symbols, the actual link is against the
shared version, libgcj.so.  My solution was to just skip archive
libraries passed info the make_sunver.pl script in case a corresponding
.so file existed as well.

Again, the output of pvs -dsvo after bootstraps with Sun ld and GNU ld
on i386-pc-solaris2.11 were almost identical, with the expected

Comments

Andrew Haley July 2, 2010, 12:13 p.m. UTC | #1
On 07/01/2010 05:04 PM, Rainer Orth wrote:
> [Please keep me on the Cc:, I'm not subscribed to java-patches.  Thanks.]
> 
> After the precedent established by the patch to support Sun symbol
> versioning in libstdc++
> 
> 	PATCH: Support Sun symbol versioning in libstdc++-v3
>         http://gcc.gnu.org/ml/gcc-patches/2010-02/msg01001.html
> 
> and its revision
> 
> 	[build, doc, v3] Support Sun symbol versioning in libstdc++-v3, rev. 2
>         http://gcc.gnu.org/ml/gcc-patches/2010-06/msg03182.html
> 
> libjava appeared relatively easy at first:

To begin with, your patch was *below* the .sig delimiter.  People won't
see it there.

I have to admit I don't understand many of the issues here.  There seem
to be many changes to the Linux version, which I don't see the need for.

Did you test this on GNU/Linux ?

> Besides, there are a couple of other shared libraries installed by
> libjava, which may be internal implementation details and not usable by
> end users.  Perhaps they should be installed into $pkglibdir instead?
> Currently, this affects libgij, libgcj-tools, libjvm, lib-gnu-awt-xlib,
> and libgcj_bc.  The maintainers should be able to easily decide where
> this might apply.

A couple of these are internal, but most not.

Andrew.
Rainer Orth July 2, 2010, 12:26 p.m. UTC | #2
Andrew Haley <aph@redhat.com> writes:

> To begin with, your patch was *below* the .sig delimiter.  People won't
> see it there.

I've never heard that being a problem.

> I have to admit I don't understand many of the issues here.  There seem
> to be many changes to the Linux version, which I don't see the need for.

Actually no: I just introduce per-library variables where I need them
with Sun ld, but set them all to the same value as before for Linux.

> Did you test this on GNU/Linux ?

Not yet: no access.  Perhaps via VirtualBox or the GCC test farm.

>> Besides, there are a couple of other shared libraries installed by
>> libjava, which may be internal implementation details and not usable by
>> end users.  Perhaps they should be installed into $pkglibdir instead?
>> Currently, this affects libgij, libgcj-tools, libjvm, lib-gnu-awt-xlib,
>> and libgcj_bc.  The maintainers should be able to easily decide where
>> this might apply.
>
> A couple of these are internal, but most not.

Could you point out which of the are supposed to be used by end users
with -l<lib>?

Thanks.
	Rainer
Andrew Haley July 2, 2010, 1:09 p.m. UTC | #3
On 07/02/2010 01:26 PM, Rainer Orth wrote:
> Andrew Haley <aph@redhat.com> writes:
> 
>> To begin with, your patch was *below* the .sig delimiter.  People won't
>> see it there.
> 
> I've never heard that being a problem.

Glad to be of service.  :-)

>> I have to admit I don't understand many of the issues here.  There seem
>> to be many changes to the Linux version, which I don't see the need for.
> 
> Actually no: I just introduce per-library variables where I need them
> with Sun ld, but set them all to the same value as before for Linux.

Ah, I see now.

>> Did you test this on GNU/Linux ?
> 
> Not yet: no access.  Perhaps via VirtualBox or the GCC test farm.
> 
>>> Besides, there are a couple of other shared libraries installed by
>>> libjava, which may be internal implementation details and not usable by
>>> end users.  Perhaps they should be installed into $pkglibdir instead?
>>> Currently, this affects libgij, libgcj-tools, libjvm, lib-gnu-awt-xlib,
>>> and libgcj_bc.  The maintainers should be able to easily decide where
>>> this might apply.
>>
>> A couple of these are internal, but most not.
> 
> Could you point out which of the are supposed to be used by end users
> with -l<lib>?

lib-gnu-awt-xlib no, but that's loaded with dlopen() so has to be on the
default path AFAIK.  I'm not sure about libgij.  libgcj-tools and libjvm,
yes.  libgcj_bc, probably not.

I think Tom Tromey might be able to answer this better than me.

Andrew.
diff mbox

Patch

difference of the Solaris 2 ABI symbols bound to the base version.

During bootstrap, I get tons of warnings from Sun ld, though (with
COLLECT_NO_DEMANGLE set in the environment to make it easier to find
what's going on):

ld: warning: symbol `_ZGAN3gnu9classpath4jdwp7VMFrame8setValueEJviPNS1_5value5ValueE' has conflicting visibilities:
	(file libgcj.ver-sun visibility=D; file gnu/classpath/jdwp/.libs/natVMFrame.o visibility=H);
	gnu/classpath/jdwp/.libs/natVMFrame.o definition taken

What happens here is that the symbol, a virtual function, has been added
(with default visibility) to the generated mapfile, while in the object
file, it is marked hidden.  This cannot be detected in the nm -P output
used; one could try to run nm again without -P and detect this from
there.  I'm not sure this is worth the effort, though.  The fix would be
restricted to the make_sunver.pl script and completely transparent.  In
recent versions of Solaris 11 ld, the warning has been remove since ld
does the right thing here anyway.

Bootstrapped without regressions on Solaris 8 to 11, SPARC and x86, Sun
as and GNU as, Sun ld and GNU ld.

Ok for mainline after it becomes unfrozen again?

Besides, there are a couple of other shared libraries installed by
libjava, which may be internal implementation details and not usable by
end users.  Perhaps they should be installed into $pkglibdir instead?
Currently, this affects libgij, libgcj-tools, libjvm, lib-gnu-awt-xlib,
and libgcj_bc.  The maintainers should be able to easily decide where
this might apply.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2010-02-22  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	* configure.ac (ANONVERSCRIPT): Handle sun style.
	Define ANONVERSCRIPT_GNU, ANONVERSCRIPT_SUN automake conditionals.
	* configure: Regenerate.

	* Makefile.am [ANONVERSCRIPT]: Protect GNU section with
	ANONVERSCRIPT_GNU.
	Introduce per-library $(lib)_la_version_arg, $(lib)_la_version_dep
	variables.
	[ANONVERSCRIPT_GNU] (version_arg): Default ld arg for version map.
	(version_dep): Likewise for dependency.
	Use them to set the per-library variables.
	[!ANONVERSCRIPT]: Provide them vor the unversioned case.
	[ANONVERSCRIPT_SUN]: Handle Sun symbol versioning.
	(libgcj_la_DEPENDENCIES): Unconditionally use
	$(libgcj_la_version_dep).
	(libgcj_la_LINK): Add $(libgcj_la_version_arg).
	(libgcj_noncore_la_DEPENDENCIES): Unconditionally use
	$(libgcj_la_version_dep).
	(libgcj_tools_la_LIBADD): Move -lm ...
	(libgcj_tools_la_LDFLAGS): ... here.
	(libgcj_tools_la_DEPENDENCIES): Add
	$(libgcj_tools_la_version_dep).
	(libgcj_tools_la_LINK): Add $(libgcj_tools_la_version_arg).
	(lib_gnu_awt_xlib_la_DEPENDENCIES): Add
	$(lib_gnu_awt_xlib_la_version_dep).
	(lib_gnu_awt_xlib_la_LINK): Add
	$(lib_gnu_awt_xlib_la_version_arg).
	(libgcj_bc_la_DEPENDENCIES): Add $(libgcj_bc_la_version_dep).
	(libgcj_bc_la_LINK): $(libgcj_bc_la_version_arg).
	[ANONVERSCRIPT && ANONVERSCRIPT_SUN] (%.ver-sun): New pattern rule.
	* Makefile.in: Regenerate.

	* libgcj.ver: Reformat.

diff -r f599dd8df876 libjava/Makefile.am
--- a/libjava/Makefile.am	Thu Jun 17 23:14:16 2010 +0200
+++ b/libjava/Makefile.am	Thu Jun 17 23:15:30 2010 +0200
@@ -291,7 +291,45 @@ 
 extra_ldflags = @extra_ldflags@
 
 if ANONVERSCRIPT
-extra_ldflags_libjava += -Wl,--version-script=$(srcdir)/libgcj.ver
+if ANONVERSCRIPT_GNU
+version_arg = -Wl,--version-script=$(srcdir)/libgcj.ver
+libgcj_la_version_arg = $(version_arg)
+libgcj_tools_la_version_arg = $(version_arg)
+lib_gnu_awt_xlib_la_version_arg = $(version_arg)
+libgcj_bc_la_version_arg = $(version_arg)
+
+version_dep = $(srcdir)/libgcj.ver
+libgcj_la_version_dep = $(version_dep)
+libgcj_tools_la_version_dep = $(version_dep)
+lib_gnu_awt_xlib_la_version_dep = $(version_dep)
+libgcj_bc_la_version_dep = $(version_dep)
+endif
+if ANONVERSCRIPT_SUN
+libgcj_la_version_arg = -Wl,-M,libgcj.ver-sun
+libgcj_tools_la_version_arg = -Wl,-M,libgcj_tools.ver-sun
+lib_gnu_awt_xlib_la_version_arg = -Wl,-M,lib_gnu_awt_xlib.ver-sun
+libgcj_bc_la_version_arg = -Wl,-M,libgcj_bc.ver-sun
+
+libgcj_la_version_dep = libgcj.ver-sun
+libgcj_tools_la_version_dep = libgcj_tools.ver-sun
+lib_gnu_awt_xlib_la_version_dep = lib_gnu_awt_xlib.ver-sun
+libgcj_bc_la_version_dep = libgcj_bc.ver-sun
+
+# The pattern rule necessary to build the *.ver-sun mapfiles is at the end
+# of the file, see below.
+endif
+else
+version_arg =
+libgcj_la_version_arg = $(version_arg)
+libgcj_tools_la_version_arg = $(version_arg)
+lib_gnu_awt_xlib_la_version_arg = $(version_arg)
+libgcj_bc_la_version_arg = $(version_arg)
+
+version_dep =
+libgcj_la_version_dep = $(version_dep)
+libgcj_tools_la_version_dep = $(version_dep)
+lib_gnu_awt_xlib_la_version_dep = $(version_dep)
+libgcj_bc_la_version_dep = $(version_dep)
 endif
 
 LTLDFLAGS = $(shell $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -463,11 +501,9 @@ 
 	java/process-$(PLATFORM).lo \
 	$(ALL_PACKAGE_SOURCE_FILES_LO) \
 	$(LIBLTDL) $(libgcj_la_LIBADD) \
-	$(LIBJAVA_CORE_EXTRA)
-if ANONVERSCRIPT
-libgcj_la_DEPENDENCIES += $(srcdir)/libgcj.ver
-endif
-libgcj_la_LINK = $(LIBLINK) $(libgcj_la_LDFLAGS)
+	$(LIBJAVA_CORE_EXTRA) \
+	$(libgcj_la_version_dep)
+libgcj_la_LINK = $(LIBLINK) $(libgcj_la_LDFLAGS) $(libgcj_la_version_arg)
 
 ## A hack to make sure the various gcj-related macros, like
 ## LTGCJCOMPILE, are defined by automake.  This is never actually
@@ -490,10 +526,7 @@ 
 libgcj_noncore_la_LDFLAGS = $(libgcj_la_LDFLAGS)
 libgcj_noncore_la_LIBADD = $(libgcj_noncore_la_LIBADD_SUBOBJECTS) libgcj.la
 libgcj_noncore_la_DEPENDENCIES = libgcj-$(gcc_version).jar $(LIBLTDL) \
-		$(libgcj_noncore_la_LIBADD) libgcj.la
-if ANONVERSCRIPT
-libgcj_noncore_la_DEPENDENCIES += $(srcdir)/libgcj.ver
-endif
+		$(libgcj_noncore_la_LIBADD) libgcj.la $(libgcj_la_version_dep)
 libgcj_noncore_la_LINK = $(libgcj_la_LINK)
 
 endif	# BUILD_SUBLIBS
@@ -509,13 +542,15 @@ 
  -fsource-filename=$(here)/classpath/tools/all-classes.lst
 libgcj_tools_la_LDFLAGS = -rpath $(toolexeclibdir) \
  -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
- $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS) $(LIBJAVA_LDFLAGS_NOUNDEF)
-libgcj_tools_la_LIBADD = libgcj.la -lm
-libgcj_tools_la_DEPENDENCIES = libgcj.la libgcj.spec
+ $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS) $(LIBJAVA_LDFLAGS_NOUNDEF) -lm
+libgcj_tools_la_LIBADD = libgcj.la
+libgcj_tools_la_DEPENDENCIES = libgcj.la libgcj.spec \
+ $(libgcj_tools_la_version_dep)
 if BUILD_SUBLIBS
 libgcj_tools_la_DEPENDENCIES += libgcj-noncore.la
 endif
-libgcj_tools_la_LINK = $(LIBLINK) $(libgcj_tools_la_LDFLAGS)
+libgcj_tools_la_LINK = $(LIBLINK) $(libgcj_tools_la_LDFLAGS) \
+ $(libgcj_tools_la_version_arg)
 
 ## libjvm.so
 libjvm_la_SOURCES = jni-libjvm.cc
@@ -543,6 +578,7 @@ 
 lib_gnu_awt_xlib_la_LIBADD = gnu/awt/xlib.lo gnu/gcj/xlib.lo
 lib_gnu_awt_xlib_la_DEPENDENCIES = libgcj-$(gcc_version).jar \
 	libgcj.la libgcj.spec \
+	$(lib_gnu_awt_xlib_la_version_dep) \
 	$(lib_gnu_awt_xlib_la_LIBADD)
 if BUILD_SUBLIBS
 lib_gnu_awt_xlib_la_DEPENDENCIES += libgcj-noncore.la
@@ -558,7 +594,8 @@ 
 	@X_PRE_LIBS@ @X_LIBS@ -lX11 @X_EXTRA_LIBS@ \
         -rpath $(toolexeclibdir) $(LIBJAVA_LDFLAGS_NOUNDEF) \
         -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC)
-lib_gnu_awt_xlib_la_LINK = $(LIBLINK) $(lib_gnu_awt_xlib_la_LDFLAGS)
+lib_gnu_awt_xlib_la_LINK = $(LIBLINK) $(lib_gnu_awt_xlib_la_LDFLAGS) \
+	$(lib_gnu_awt_xlib_la_version_arg)
 
 ## Support for libgcj_bc: dummy shared library.
 ##
@@ -567,8 +604,9 @@ 
 libgcj_bc_la_SOURCES = libgcj_bc.c
 libgcj_bc_la_LDFLAGS = -rpath $(toolexeclibdir) -no-static -version-info 1:0:0 \
 	$(LIBGCJ_LD_SYMBOLIC_FUNCTIONS) $(LIBJAVA_LDFLAGS_NOUNDEF)
-libgcj_bc_la_DEPENDENCIES = libgcj.la
-libgcj_bc_la_LINK = $(LIBLINK) $(libgcj_bc_la_LDFLAGS)
+libgcj_bc_la_DEPENDENCIES = libgcj.la $(libgcj_bc_la_version_dep)
+libgcj_bc_la_LINK = $(LIBLINK) $(libgcj_bc_la_LDFLAGS) \
+	$(libgcj_bc_la_version_arg)
 ## 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 \
@@ -1574,3 +1612,22 @@ 
 	$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
 maintainer-clean-multi:
 	$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
+
+if ANONVERSCRIPT
+if ANONVERSCRIPT_SUN
+# This must be at the end of the Makefile, otherwise .SECONDEXPANSION
+# causes expansion of filenames with $ in their names, which breaks the build.
+# .SECONDEXPANSION is necessary to allow the use of automatic variables ($@
+# in this case) in the requisites of pattern rules.
+.SECONDEXPANSION:
+
+%.ver-sun : $(srcdir)/libgcj.ver \
+		$(top_srcdir)/../contrib/make_sunver.pl \
+		$$($$(basename $$@)_la_OBJECTS) $$($$(basename $$@)_la_LIBADD)
+	perl $(top_srcdir)/../contrib/make_sunver.pl \
+	  $(srcdir)/libgcj.ver \
+	 `echo $($(basename $@)_la_OBJECTS) $($(basename $@)_la_LIBADD) | \
+	    sed 's,\([^/ 	]*\)\.l\([ao]\),.libs/\1.\2,g'` \
+	 > $@ || (rm -f $@ ; exit 1)
+endif
+endif
diff -r f599dd8df876 libjava/configure.ac
--- a/libjava/configure.ac	Thu Jun 17 23:14:16 2010 +0200
+++ b/libjava/configure.ac	Thu Jun 17 23:15:30 2010 +0200
@@ -1772,13 +1772,24 @@ 
   [libjava_cv_anon_version_script],
   [save_CFLAGS="$CFLAGS"; save_LDFLAGS="$LDFLAGS"
    libjava_cv_anon_version_script=no
-   CFLAGS="$CFLAGS -fPIC"; LDFLAGS="$LDFLAGS -shared -Wl,--version-script,conftest.map"
+   CFLAGS="$CFLAGS -fPIC";
+   LDFLAGS="$LDFLAGS -shared -Wl,--version-script,conftest.map"
    echo '{ global: globalsymb*; local: *; };' > conftest.map
    AC_TRY_LINK(void globalsymbol (void) {} void localsymbol (void) {},,
-	       [libjava_cv_anon_version_script=yes], [])
+	       [libjava_cv_anon_version_script=gnu], [])
+   if test x$libjava_cv_anon_version_script = xno; then
+     LDFLAGS="$save_LDFLAGS"
+     LDFLAGS="$LDFLAGS -shared -Wl,-M,conftest.map"
+     # Sun ld doesn't understand wildcards here.
+     echo '{ global: globalsymbol; local: *; };' > conftest.map
+     AC_TRY_LINK(void globalsymbol (void) {} void localsymbol (void) {},,
+	         [libjava_cv_anon_version_script=sun], [])
+   fi
    CFLAGS="$save_CFLAGS"; LDFLAGS="$save_LDFLAGS"
   ])
-AM_CONDITIONAL(ANONVERSCRIPT, test "$libjava_cv_anon_version_script" = yes)
+AM_CONDITIONAL(ANONVERSCRIPT, test "$libjava_cv_anon_version_script" != no)
+AM_CONDITIONAL(ANONVERSCRIPT_GNU, test "$libjava_cv_anon_version_script" = gnu)
+AM_CONDITIONAL(ANONVERSCRIPT_SUN, test "$libjava_cv_anon_version_script" = sun)
 
 # Check if linker supports static linking on a per library basis
 LD_START_STATIC_SPEC=
diff -r f599dd8df876 libjava/libgcj.ver
--- a/libjava/libgcj.ver	Thu Jun 17 23:14:16 2010 +0200
+++ b/libjava/libgcj.ver	Thu Jun 17 23:15:30 2010 +0200
@@ -2,6 +2,12 @@ 
 # symbols in libgcj.so.
 
 {
-  global: Jv*; _Jv_*; __gcj_personality_v0; __gcj_personality_sj0; _Z*;
-  local: *;
+  global:
+    Jv*;
+    _Jv_*;
+    __gcj_personality_v0;
+    __gcj_personality_sj0;
+    _Z*;
+  local:
+    *;
 };