Patchwork Fix linking with -findirect-dispatch

login
register
mail settings
Submitter Andreas Schwab
Date April 16, 2013, 8:35 a.m.
Message ID <mvmy5ciub3i.fsf@hawking.suse.de>
Download mbox | patch
Permalink /patch/236863/
State New
Headers show

Comments

Andreas Schwab - April 16, 2013, 8:35 a.m.
Linking with -findirect-dispatch fails with this error:

x86_64-linux-gcj -o ecjx -findirect-dispatch --main=org.eclipse.jdt.internal.compiler.batch.GCCMain ../../../gcc/libjava/../ecj.jar ecjx.o  
/usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: /tmp/ccppO92n.o: undefined reference to symbol '_Jv_MonitorExit'
/usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: note: '_Jv_MonitorExit' is defined in DSO /usr/lib64/libgcj.so.13 so try adding it to the linker command line

Andreas.

	* configure.ac (LIBGCJ_SPEC_LGCJ_BC): Append -lgcj.
	(libgcj_spec_lgcj_bc_override): Likewise.
	* configure: Regenerate.
Jakub Jelinek - April 16, 2013, 8:38 a.m.
On Tue, Apr 16, 2013 at 10:35:29AM +0200, Andreas Schwab wrote:
> Linking with -findirect-dispatch fails with this error:
> 
> x86_64-linux-gcj -o ecjx -findirect-dispatch --main=org.eclipse.jdt.internal.compiler.batch.GCCMain ../../../gcc/libjava/../ecj.jar ecjx.o  
> /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: /tmp/ccppO92n.o: undefined reference to symbol '_Jv_MonitorExit'
> /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: note: '_Jv_MonitorExit' is defined in DSO /usr/lib64/libgcj.so.13 so try adding it to the linker command line
> 
> Andreas.
> 
> 	* configure.ac (LIBGCJ_SPEC_LGCJ_BC): Append -lgcj.
> 	(libgcj_spec_lgcj_bc_override): Likewise.
> 	* configure: Regenerate.

That doesn't look right, if -findirect-dispatch now newly needs
_Jv_MonitorExit (when has that been added?), then the symbol should
be added to libgcj_bc.so.

	Jakub
Bryce McKinlay - April 16, 2013, 8:59 a.m.
On Tue, Apr 16, 2013 at 9:38 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Apr 16, 2013 at 10:35:29AM +0200, Andreas Schwab wrote:
>> Linking with -findirect-dispatch fails with this error:
>>
>> x86_64-linux-gcj -o ecjx -findirect-dispatch --main=org.eclipse.jdt.internal.compiler.batch.GCCMain ../../../gcc/libjava/../ecj.jar ecjx.o
>> /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: /tmp/ccppO92n.o: undefined reference to symbol '_Jv_MonitorExit'
>> /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: note: '_Jv_MonitorExit' is defined in DSO /usr/lib64/libgcj.so.13 so try adding it to the linker command line
>>
>> Andreas.
>>
>>       * configure.ac (LIBGCJ_SPEC_LGCJ_BC): Append -lgcj.
>>       (libgcj_spec_lgcj_bc_override): Likewise.
>>       * configure: Regenerate.
>
> That doesn't look right, if -findirect-dispatch now newly needs
> _Jv_MonitorExit (when has that been added?), then the symbol should
> be added to libgcj_bc.so.

That's right. -findirect-dispatch code should not link libgcj directly.

_Jv_MonitorExit has always been defined in libgcj_bc (see
libgcj_bc.c), so something else is going wrong here.

Bryce
Andreas Schwab - April 16, 2013, 9:13 a.m.
Jakub Jelinek <jakub@redhat.com> writes:

> That doesn't look right, if -findirect-dispatch now newly needs
> _Jv_MonitorExit (when has that been added?), then the symbol should
> be added to libgcj_bc.so.

libgcj_bc.so is just a dummy library.  You need to look at the installed
file, not the one in the build directory.

Andreas.
Jakub Jelinek - April 16, 2013, 9:19 a.m.
On Tue, Apr 16, 2013 at 11:13:35AM +0200, Andreas Schwab wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > That doesn't look right, if -findirect-dispatch now newly needs
> > _Jv_MonitorExit (when has that been added?), then the symbol should
> > be added to libgcj_bc.so.
> 
> libgcj_bc.so is just a dummy library.  You need to look at the installed
> file, not the one in the build directory.

libgcj_bc.so is a dummy library that says what symbols are allowed in
-findirect-dispatch linking at link time, and at dynamic link time it is a
dummy library with no symbols that just adds DT_NEEDED of the latest and
greatest libgcj.so.N, which provides all the symbols.

	Jakub
Andreas Schwab - April 16, 2013, 9:37 a.m.
Jakub Jelinek <jakub@redhat.com> writes:

> at dynamic link time it is a dummy library with no symbols that just
> adds DT_NEEDED of the latest and greatest libgcj.so.N, which provides
> all the symbols.

Which is exactly the problem.  --no-copy-dt-needed-entries has been the
default for a long time now.

Andreas.
Jakub Jelinek - April 16, 2013, 9:48 a.m.
On Tue, Apr 16, 2013 at 11:37:07AM +0200, Andreas Schwab wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > at dynamic link time it is a dummy library with no symbols that just
> > adds DT_NEEDED of the latest and greatest libgcj.so.N, which provides
> > all the symbols.
> 
> Which is exactly the problem.  --no-copy-dt-needed-entries has been the
> default for a long time now.

Why would that be a problem?  libgcj.so the linker sees (i.e. the dummy
library) doesn't intentionally have DT_NEEDED libgcj.so.N, programs and
shared libraries linked with -findirect-dispatch should be adding
libgcj_bc.so to DT_NEEDED, not libgcj.so.N.

If this is caused by some recent broken linker change, then that should be
better reverted.

	Jakub
Matthias Klose - April 16, 2013, 9:55 a.m.
Am 16.04.2013 11:48, schrieb Jakub Jelinek:
> On Tue, Apr 16, 2013 at 11:37:07AM +0200, Andreas Schwab wrote:
>> Jakub Jelinek <jakub@redhat.com> writes:
>>
>>> at dynamic link time it is a dummy library with no symbols that just
>>> adds DT_NEEDED of the latest and greatest libgcj.so.N, which provides
>>> all the symbols.
>>
>> Which is exactly the problem.  --no-copy-dt-needed-entries has been the
>> default for a long time now.
> 
> Why would that be a problem?  libgcj.so the linker sees (i.e. the dummy
> library) doesn't intentionally have DT_NEEDED libgcj.so.N, programs and
> shared libraries linked with -findirect-dispatch should be adding
> libgcj_bc.so to DT_NEEDED, not libgcj.so.N.
> 
> If this is caused by some recent broken linker change, then that should be
> better reverted.

I don't see this with binutils 2.23.2.
Andreas Schwab - April 16, 2013, 9:57 a.m.
Jakub Jelinek <jakub@redhat.com> writes:

> Why would that be a problem?  libgcj.so the linker sees (i.e. the dummy
> library) doesn't intentionally have DT_NEEDED libgcj.so.N, programs and
> shared libraries linked with -findirect-dispatch should be adding
> libgcj_bc.so to DT_NEEDED, not libgcj.so.N.

But the dummy libgcj_bc.so doesn't define _Jv_MonitorExit, or any other
relevant symbol.

> If this is caused by some recent broken linker change, then that should be
> better reverted.

It has been this way since almost two years.

Andreas.
Jakub Jelinek - April 16, 2013, 10:08 a.m.
On Tue, Apr 16, 2013 at 11:57:54AM +0200, Andreas Schwab wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > Why would that be a problem?  libgcj.so the linker sees (i.e. the dummy
> > library) doesn't intentionally have DT_NEEDED libgcj.so.N, programs and
> > shared libraries linked with -findirect-dispatch should be adding
> > libgcj_bc.so to DT_NEEDED, not libgcj.so.N.
> 
> But the dummy libgcj_bc.so doesn't define _Jv_MonitorExit, or any other
> relevant symbol.

That is not true.  Build from yesterday, on x86_64-linux:

$ readelf -Wa libjava/.libs/libgcj_bc.so | grep _Jv_MonitorExit; readelf -d libjava/.libs/libgcj_bc.so | grep NEEDED; echo ==; readelf -Wa libjava/.libs/libgcj_bc.so.1 | grep _Jv_MonitorExit; readelf -d libjava/.libs/libgcj_bc.so.1 | grep NEEDED
    25: 0000000000001250     2 FUNC    GLOBAL DEFAULT   10 _Jv_MonitorExit
    77: 0000000000001250     2 FUNC    GLOBAL DEFAULT   10 _Jv_MonitorExit
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
==
 0x0000000000000001 (NEEDED)             Shared library: [libgcj.so.14]

The point of -findirect-dispatch linking against -lgcj_bc rather than -lgcj
is that whenever N in libgcj.so.N is bumped, you don't need to rebuild all the
-findirect-dispatch compiled/linked programs and shared libraries, only if
you build a direct dispatch programs or shared libraries.

So, -findirect-dispatch programs and shared libraries should have:
 0x0000000000000001 (NEEDED)             Shared library: [libgcj_bc.so.1]
rather than:
 0x0000000000000001 (NEEDED)             Shared library: [libgcj.so.14]

	Jakub
Andreas Schwab - April 16, 2013, 10:11 a.m.
Jakub Jelinek <jakub@redhat.com> writes:

> $ readelf -Wa libjava/.libs/libgcj_bc.so

That's not the installed library.

Andreas.
Jakub Jelinek - April 16, 2013, 10:26 a.m.
On Tue, Apr 16, 2013 at 12:11:06PM +0200, Andreas Schwab wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > $ readelf -Wa libjava/.libs/libgcj_bc.so
> 
> That's not the installed library.

If that isn't the installed library, then the bug is that it isn't
installed.  Our spec file reshuffles libraries around heavily, so perhaps
the upstream Makefiles are buggy and the reshuffling just hides the bug,
but your patch isn't a fix.
Installed */libgcj_bc.so should be a copy of the dummy library
*/libjava/.libs/libgcj_bc.so, and */libgcj_bc.so.1.0.0 should be
a (relinked?) copy of the dummy library */libjava/.libs/libgcj_bc.so.1.0.0.

I'm pretty sure when the changes were added for gcc 4.2 it worked just fine,
but as our rpms don't use what this installs, it is possible it got broken
later on.

	Jakub
Andreas Schwab - April 16, 2013, 10:31 a.m.
Jakub Jelinek <jakub@redhat.com> writes:

> If that isn't the installed library, then the bug is that it isn't
> installed.

It's always been this way.

install-exec-hook: install-binPROGRAMS install-toolexeclibLTLIBRARIES \
	install-libexecsubPROGRAMS
## 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.
	@echo Installing dummy lib libgcj_bc.so.1.0.0; \
	rm $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so; \
	mv $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1.0.0 $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so; \
	$(libgcj_bc_dummy_LINK) -xc /dev/null -Wl,-soname,libgcj_bc.so.1 \
	-o $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1.0.0 -lgcj || exit; \
	rm $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1; \
	$(LN_S) libgcj_bc.so.1.0.0 $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1; \
	rm $(DESTDIR)$(toolexeclibdir)/libgcj_bc.la;
endif

Andreas.
Matthias Klose - April 26, 2013, 11:22 a.m.
Am 16.04.2013 11:55, schrieb Matthias Klose:
> Am 16.04.2013 11:48, schrieb Jakub Jelinek:
>> On Tue, Apr 16, 2013 at 11:37:07AM +0200, Andreas Schwab wrote:
>>> Jakub Jelinek <jakub@redhat.com> writes:
>>>
>>>> at dynamic link time it is a dummy library with no symbols that just
>>>> adds DT_NEEDED of the latest and greatest libgcj.so.N, which provides
>>>> all the symbols.
>>>
>>> Which is exactly the problem.  --no-copy-dt-needed-entries has been the
>>> default for a long time now.
>>
>> Why would that be a problem?  libgcj.so the linker sees (i.e. the dummy
>> library) doesn't intentionally have DT_NEEDED libgcj.so.N, programs and
>> shared libraries linked with -findirect-dispatch should be adding
>> libgcj_bc.so to DT_NEEDED, not libgcj.so.N.
>>
>> If this is caused by some recent broken linker change, then that should be
>> better reverted.
> 
> I don't see this with binutils 2.23.2.

I do see this now too, however the root of the problem seems to be a linker
which defaults to --as-needed (which is the case on SuSe afaik).  I can see this
without installing anything, just running the testsuite shows some hundred of
these failures.

  Matthias
Andrew Haley - April 26, 2013, 11:50 a.m.
On 04/26/2013 12:22 PM, Matthias Klose wrote:
> I do see this now too, however the root of the problem seems to be a linker
> which defaults to --as-needed (which is the case on SuSe afaik).

Is this a non-standard thing?  So SuSe has a special --configure option
which does this?  We can always patch in --no-as-needed

Andrew.

Patch

diff --git a/libjava/configure.ac b/libjava/configure.ac
index ba6b363..d378125 100644
--- a/libjava/configure.ac
+++ b/libjava/configure.ac
@@ -266,7 +266,7 @@  if test "$enable_libgcj_sublibs" = yes ; then
   # words in the string and you're relying on the ordering to
   # append the correct one.
   libgcj_spec_lgcj_override="-lgcj-noncore -lgcj"
-  libgcj_spec_lgcj_bc_override="-lgcj-noncore -lgcj_bc"
+  libgcj_spec_lgcj_bc_override="-lgcj-noncore -lgcj_bc -lgcj"
 fi
 
 
@@ -1165,7 +1165,7 @@  AC_CONFIG_LINKS(sysdep/backtrace.h:$fallback_backtrace_h)
 AC_CONFIG_LINKS(sysdep/descriptor.h:$descriptor_h)
 
 LIBGCJ_SPEC_LGCJ=-lgcj
-LIBGCJ_SPEC_LGCJ_BC=-lgcj_bc
+LIBGCJ_SPEC_LGCJ_BC="-lgcj_bc -lgcj"
 if test x"$libgcj_spec_lgcj_override" != x ; then
   LIBGCJ_SPEC_LGCJ=$libgcj_spec_lgcj_override
 fi