[forwarded from http://bugs.debian.org/712081] Compiling a trivial int a() {return 17;} file with g++ -v -Wl,--as-needed t.c --shared -o libt${n}.so With binutils 2.23.52.20130612-1: $ readelf -d /tmp/libt3.so | grep NEEDED $ objdump -T libt3.so | grep _cxa_fin 0000000000000000 w D *UND* 0000000000000000 __cxa_finalize While with binutils 2.22-8 and 2.23.2: $ readelf -d libt2.so | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] $ objdump -T libt2.so | grep _cxa_fin 0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize i.e. the dependency on libc.so.6 is missing and what is worse: the libc6 symbol is not properly versioned, which might mean that that library might cause programs segfault with future libc versions. g++ says it does: COLLECT_GCC_OPTIONS='-v' '-shared' '-o' 'libt3.so' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/4.7/collect2 --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -shared -o libt3.so /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../.. --as-needed /tmp/cc8CjUQJ.o -lstdc++ -lm -lgcc_s -lc -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o with the need for symbol __cxa_finalize coming from crtbeginS.o: $ objdump -t /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o | grep _cxa_fi 0000000000000000 w *UND* 0000000000000000 __cxa_finalize gcc unlike g++ is not affected because it puts a --no-as-needed before -lc
Zack Weinberg commented in the Debian report: I think the linker is doing exactly what it's supposed to in this case -- weak symbols *shouldn't* provoke NEEDED entries all by themselves. A standard use case, for instance, is to take weak references to pthread_mutex_(un)lock and then call them only if the function addresses are non-NULL at runtime -- if that by itself dragged in libpthread it would vitiate the optimization. If you do the exact same test with a shared object that explicitly calls something in libc (say, 'puts') that's a strong reference and you will get a NEEDED entry. As for the lack of version tagging on the weak reference, I can't say whether this is a problem in general, but in the case of __cxa_finalize, I'm pretty sure it isn't: a GLIBC_2.2.5 version indicates a function that has not changed since the introduction of symbol versioning in libc.so.6, and the spec governing __cxa_finalize's behavior hasn't changed since 2003ish.
The Debian bug is closed based on Alan Modra's reply here: https://sourceware.org/ml/binutils/2013-07/msg00001.html So closing this bug too.