From mboxrd@z Thu Jan 1 00:00:00 1970 From: hjl@lucon.org (H.J. Lu) To: svivanov@pdmi.ras.ru Cc: egcs@cygnus.com, ian@cygnus.com (Ian Lance Taylor) Subject: Re: Why link C with crtstuff? [patch] Date: Tue, 28 Apr 1998 14:10:00 -0000 Message-id: References: X-SW-Source: 1998-04/msg01110.html > > Answers are reordered, the verified one first. ;-) > > > > > > A side note: dependence on gcc internals from shared libs it not only > > > a problem of compatibility between gcc versions. A library could be > > > rewritten/optimized so that it stops using a certain gcc internal > > > so that it disappears. The author would normally change only a minor > > > version, but in this case the library becomes incompatible. > > > > > > > That is why we now add -lgcc to build shared libraries. Again show me > > the problem. I will take a look. > > > > Here is an artificial case, a library libfoo.so and a program test-foo. > libfoo uses long long division internally, so it has __divdi3 defined. > test-foo is linked with -lfoo and uses __divdi3 itself. Since -lfoo > goes to the linker before -lgcc, test-foo uses __divdi3 from libfoo. > The first implementation of libfoo is inefficient, so there comes > a revision. :-) It does exactly the same but without using long long. > Then test-foo fails because libfoo does not define __divdi3 any more. > > System: i586-pc-linux-gnulibc1, egcs-1.0.2, libc-5.4.44, binutils-2.8.1.0.15. > > This is run as root, assuming there is no useful /usr/lib/libfoo.so* > --------------- > #!/bin/sh > rm /usr/lib/libfoo.so* > gcc -c foo1.c -o foo.o > gcc -shared foo.o -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 > (cp libfoo.so.1.0 /usr/lib ; cd /usr/lib ; ln -sf libfoo.so.1.0 libfoo.so) > ldconfig > gcc test-foo.c -lfoo -o test-foo > echo -n "libfoo 1.0: " > ./test-foo > gcc -c foo2.c -o foo.o > gcc -shared foo.o -Wl,-soname,libfoo.so.1 -o libfoo.so.1.1 > (cp libfoo.so.1.1 /usr/lib ; cd /usr/lib ; ln -sf libfoo.so.1.1 libfoo.so) > ldconfig > echo -n "libfoo 1.1: " > ./test-foo > -------------- > This is foo1.c > -------------- > int foo (void) > { > long long a=1, b=1; return a/b; > } > -------------- > foo2.c > -------------- > int foo (void) > { > return 1; > } > -------------- > test-foo.c > -------------- > #include > > int main() > { > long long x=1, y=1, z=x/y; > printf ("Ok\n"); > return 0; > } > ------------- > and the output > ------------- > libfoo 1.0: Ok > libfoo 1.1: ./test-foo: can't resolve symbol '__divdi3' > ------------- > > > > > > Still it is unpleasant that the binary appears dependent on these > > > symbols if linked with the library (and now with weak symbols even > > > an extra -lgcc does not help). > > > > What is the problem? Show me one. I will see what I can do. > > No it is not a severe problem. It is just something that would be better > not to have, if it's easy. Something close to "it's a problem" is the > following. I recompiled libvga and main(){} with -lvga, then replaced > libvga by a copy created with the previous patch (i.e. a library > without __register_frame_info), and the binary failed. I suppose > the same would happen if the library was rebuilt with some another > compiler. For example, gcc-2.7.2.x. (Or not rebuilt but overwritten > from a binary archive or distribution. But I did not really try this.) > > This is the same with or without the patch. The patch just makes this > difiicult to avoid. If I'm paranoid I could put -lgcc before -lvga to > prevent binding to gcc internals in libvga. But this fails for the weak > __register_frame_info. > > > > > > Maybe use different names for static and shared things? For example, > > > let some __register_frame_info__static in libgcc be a copy/alias/call to > > > __register_frame_info and let crtbegin.o have this new symbol weak extern > > > while crtbeginS.o uses __register_frame_info. > > > > Why? Can you give me an example how it is used? > > I was addressing the above (pseudo?) problem with references from a new > binary to the __register_frame_info in a shared library. Renaming weak > symbols could prevent them from being hit by ones in the shared library > and thus make the binary more self-contained w.r.t. gcc internals. > > But sorry, I don't know how to make these symbols work for different > orders of linking. They only do with the .o first, then libgcc, then > shared libraries... So it was a stupid idea. :-( > I have been thinking about it for a while now. It is a good idea to include -lgcc to build libfoo.so. But exporting the symbols in libgcc.a from libfoo.so is a different story. It may cause many problems down the road. What I'd like to see is: 1. Create a libgcc.list along with libgcc.a which lists the global symbols in libgcc.a. 2. Modify the gnu linker to take ld ... --local foo,bar,.... which will make foo, bar .. local to libfoo.so. I believe everything is almost in binutils 2.9. We just need to add the --local option to ld. 3. gcc -shared will read libgcc.list and pass those symbols to ld via --local foo,bar,.... I can work on --local for ld if it is feasible. Thanks. -- H.J. Lu (hjl@gnu.org)