ld ignores used libraries (especially libc) with --as-needed

Bug #1194051 reported by Matthias Klose
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro Binutils
Invalid
Undecided
Unassigned
binutils
Confirmed
Medium
binutils (Debian)
Fix Released
Unknown
binutils (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

see the debian and upstream issues

Revision history for this message
In , Matthias Klose (doko) wrote :

[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

Revision history for this message
In , Matthias Klose (doko) wrote :

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.

Changed in binutils (Debian):
status: Unknown → Confirmed
Changed in binutils:
importance: Unknown → Medium
status: Unknown → Confirmed
Changed in binutils (Debian):
status: Confirmed → Fix Released
Changed in binutils-linaro:
status: New → Invalid
Revision history for this message
Matthias Klose (doko) wrote :
Changed in binutils (Ubuntu):
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.