This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: [RFC PATCH] make libgcj_bc prims symbol sizes correct
Nix wrote:
> On 15 Aug 2009, Andrew Haley told this:
>> BC-compiled executables are being linked against libgcj as well as libgcj_bc.
>
> Um:
>
> spindle 1388 /usr/src/gcc/x86_64-spindle/x86_64-pc-linux-gnu/libjava/testsuite% eu-readelf -a Array_1.exe| grep NEEDED
> NEEDED Shared library: [libgcj_bc.so.1]
> NEEDED Shared library: [libc.so.6]
>
> Looks like libgcj_bc.so.1 only to me, and libgcj_bc.so.1 is, as
> intended, a nearly-empty wrapper DT_NEEDing libgcj.so.10. ldd looks like:
>
> spindle 1391 /usr/src/gcc/x86_64-spindle/x86_64-pc-linux-gnu/libjava/testsuite% LD_LIBRARY_PATH=.:/usr/src/gcc/x86_64-spindle/x86_64-pc-linux-gnu/./libjava/.libs:/usr/src/gcc/x86_64-spindle/gcc:/usr/src/gcc/x86_64-spindle/gcc/32:/usr/src/gcc/x86_64-spindle/gcc/32/geode:.:/usr/src/gcc/x86_64-spindle/x86_64-pc-linux-gnu/./libjava/.libs:/usr/src/gcc/x86_64-spindle/gcc:/usr/src/gcc/x86_64-spindle/gcc/32:/usr/src/gcc/x86_64-spindle/gcc/32/geode ldd ./Array_1.exe
> linux-vdso.so.1 => (0x00007fffa595b000)
> libgcj_bc.so.1 => /usr/src/gcc/x86_64-spindle/x86_64-pc-linux-gnu/libjava/.libs/libgcj_bc.so.1 (0x00007f14c84cf000)
> libc.so.6 => /lib/libc.so.6 (0x00007f14c817d000)
> libgcj.so.10 => /usr/src/gcc/x86_64-spindle/x86_64-pc-linux-gnu/libjava/.libs/libgcj.so.10 (0x00007f14c508e000)
> /lib64/ld-linux-x86-64.so.2 (0x00007f14c86d0000)
> libpthread.so.0 => /lib/libpthread.so.0 (0x00007f14c4e73000)
> librt.so.1 => /lib/librt.so.1 (0x00007f14c4c6b000)
> libdl.so.2 => /lib/libdl.so.2 (0x00007f14c4a67000)
> libz.so.1 => /usr/lib/libz.so.1 (0x00007f14c4852000)
> libgcc_s.so.1 => /usr/src/gcc/x86_64-spindle/gcc/libgcc_s.so.1 (0x00007f14c463e000)
>
> which looks right to me.
>
> Just teaching my grandfather to suck eggs here for a minute: the problem
> is that the reference to the symbol burnt by ld into *Array_1.exe
> itself* includes a size, and that size is derived from libgcj_bc.so,
> thus is too small:
>
> _Jv_intClass |0000000000601660|GLOBAL|OBJECT | 4| |.bss
>
> ... versus, in libgcj.so.10:
>
> _Jv_intClass |000000000307bcb8|GLOBAL|OBJECT | 118| prims.cc:824|.bss
>
> It is this mismatch that ld.so is complaining about (during copy
> relocation processing, as it happens: see
> sysdeps/{x86_64,i386}/dl-machine.h).
>
> It happens to only complain if the reference's size is smaller than the
> size of the symbol itself, so we could probably kludge around it by
> making the reference in libgcj_bc be to a 64K long array or something
> like that. But *that* is even uglier than what I proposed, and if glibc
> chooses to become more paranoid (as well it might) then it'll just break
> again.
It's weirder than that.
The problem is due to copy relocs, which are not really compatible with
the BC abi.
On my system, libgcj_bc is linked against libgcj, and the _Jv_intClass in
its .bss is unified with the _Jv_intClass in libgcj.
If you generate a linker map when linking libgcj_bc you should see
Allocating common symbols
Common symbol size file
_Jv_doubleClass 0x118 ./.libs/libgcj.so
_Jv_floatClass 0x118 ./.libs/libgcj.so
_Jv_byteClass 0x118 ./.libs/libgcj.so
_Jv_shortClass 0x118 ./.libs/libgcj.so
_Jv_voidClass 0x118 ./.libs/libgcj.so
_Jv_intClass 0x118 ./.libs/libgcj.so
... etc
So, I get
$ nm --demangle -f sysv .libs/libgcj_bc.so|grep intClass
_Jv_intClass |0000000000202860| B | OBJECT|0000000000000118| |.bss
The question, then, is why the linker on your system doesn't unify these .bss symbols.
I think this may be a bug in the linker you're using.
I did the experiment of removing the -lgcj from the link of libgcj_bc: IMO this
link against libgcj shouldn't be done. And, I got exactly the same failure that
you did:
.../Array_1.exe: Symbol `_Jv_intClass' has different size in shared object, consider re-linking
Aborted
Compiling Array_1 as position-independent code fixes it:
$ /home/aph/gcc/trunk/obj-x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/libjava/testsuite/Array_1.exe
true
false
true
class java.lang.Object
happy:libjava $ nm --demangle -f sysv testsuite/Array_1.exe | grep intClass
_Jv_intClass | | U | OBJECT| | |*UND*
I think the right fix is to cause BC-compiled executables to be compiled PIC.
The worry I have with that is that there might be some platforms which can
work with BC-compiled code in some way but barf if the compiler sees =-fPIC".
something like
Index: libjava/libgcj.spec.in
===================================================================
--- libjava/libgcj.spec.in (revision 150702)
+++ libjava/libgcj.spec.in (working copy)
@@ -9,4 +9,4 @@
%rename lib liborig
*lib: @LD_START_STATIC_SPEC@ @LIBGCJ_SPEC@ @LD_FINISH_STATIC_SPEC@ -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) @LIBSTDCXXSPEC@ %(liborig)
-*jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ @ATOMICSPEC@ -fkeep-inline-functions
+*jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ @ATOMICSPEC@ -fkeep-inline-functions %{findirect-dispatch:-fPIC}
Index: libjava/Makefile.am
===================================================================
--- libjava/Makefile.am (revision 150701)
+++ libjava/Makefile.am (working copy)
@@ -361,8 +361,8 @@
libgcj_bc_la_SOURCES = libgcj_bc.c
libgcj_bc_la_LDFLAGS = -rpath $(toolexeclibdir) -no-static -version-info 1:0:0 \
$(LIBGCJ_LD_SYMBOLIC_FUNCTIONS)
-libgcj_bc_la_LIBADD = libgcj.la
-libgcj_bc_la_DEPENDENCIES = libgcj.la
+libgcj_bc_la_LIBADD =
+libgcj_bc_la_DEPENDENCIES =
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.
I'll have a look at using autoconf to check for "-fPIC" when compiling an
executable.
Andrew.