This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
DL_DEBUG_UNUSED buggy, especially with vdso
- From: David Miller <davem at davemloft dot net>
- To: libc-alpha at sourceware dot org
- Date: Tue, 03 Apr 2012 23:59:32 -0400 (EDT)
- Subject: DL_DEBUG_UNUSED buggy, especially with vdso
tst-unused-dep fails on sparc and I just figured out why it
passes on x86-64 and i386.
The loop in elf/rtld.c that verifies all the deps are used has this
comment above it:
/* This loop depends on the dependencies of the executable to
correspond in number and order to the DT_NEEDED entries. */
and this is absolutely not true when there is a VDSO map.
In this case, for elf/testobj1.so, the DT_NEEDED list is [libc.so.6,
libdl.so.2] but the list of objects hung off of main_map is
[linux-vdso.so.1, libc.so.6, libdl.so.2]
Since there are two DT_NEEDED entries, it stops after looking at
libc.so.6 and during the loop we're off by one.
So it never notices that in fact libdl.so.s'2 map has l_used set to
zero.
On sparc, without a VDSO, this test fails because it does properly
execute this loop since the DT_NEEDED entries and the link map list
match up perfectly.
And if the list matched up, it would fail on x86-64 and i386 too.
The reason libdl.so.2's l_used is set to zero is because the only
symbol reference testobj1.so has to libdl.so.2 is to 'dlsym' via the
PLT, and since we're doing lazy binding we won't do a lookup on
'dlsym' and thus be able to set the link map l_used to one.
This is a complete and utter rats nest, nobody has seriously looked at
this code at all.
So we have two issues to resolve:
1) Skipping the VDSO in the link map while walking the DT_NEEDED
entries
2) Dealing with the PLT lazy eval issue. We can't just pretend
LD_BIND_NOW is set because in this test case testobj1.so also
references a symbol 'foo' via the PLT which will be undefined