Why link C with crtstuff? [patch]

H.J. Lu hjl@lucon.org
Tue Apr 28 14:10:00 GMT 1998


> 
> 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 <stdio.h>
> 
> 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)



More information about the Gcc mailing list