Red Hat Bugzilla – Bug 78937
dl_iterate_phdr belongs in ld-linux.so.2, not in libc.so.6
Last modified: 2016-11-24 10:12:03 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020529
Description of problem:
The routine dl_iterate_phdr() which is declared in <link.h> should be
implemented in the runtime loader ld-linux.so.2 (instead of in libc.so.6) so
that programs and modules that do not use libc, or that are invoked before libc
is loaded and initialized, can still perform introspection on the Phdrs of
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. cd /lib
2. nm -Dgop ld-linux.so.2 libc.so.6 | grep dl_iterate_phdr
Actual Results: libc.so.6:0010c650 W dl_iterate_phdr
which shows that dl_iterate_phdr is in libc.so.6 and not in ld-linux.so.2
Expected Results: ld-linux.so.2:XXXXXXXX T dl_iterate_phdr
showing that dl_iterate_phdr is in ld-linux.so.2
Because <link.h> hides all but a prefix of struct link_map, then access routines
such as dl_iterate_phdr() must be provided by the runtime loader itself.
I wonder why programs which don't use libc need libc dynamic linker and don't
roll their own...
If a program uses libc, then at the time DSO constructors are run libc.so
is already loaded and thus dl_iterate_phdr can be called.
dl_iterate_phdr cannot be really moved out of libc.so because of symbol versioning
(which records the containing DSO).
Well, without libc/libdl you cannot use dlopen (because most of the _dl_*
routines are GLIBC_PRIVATE) either.
Please reconsider. The current setup does not provide adequate capability for
introspection of the loaded modules. This is independent of libc/libdl in
general, and never needs dlopen in particular.
For instance, suppose that some code is auditing the loading and relocation of
modules, using r_debug.r_brk or similar. Then it is reasonably necessary to be
able to run dl_iterate_phdr at any invocation of r_brk, regardless of whether
libc.so.6 is involved, and especially if libc.so.6 is _not_ involved. The only
module that knows the layout of struct link_map, and is guaranteed to be
involved, is ld-linux.so.2 itself. ld-linux.so.2 provides no clues about the
layout of struct link_map (except the first 5 members, which are insufficient to
run dl_iterate_phdr); dl_iterate_phdr is supposed to be the way to find out.
[Even so, it is still impossible to find the address of the Elf32_Ehdr, or the
value of .e_entry, .e_machine, .e_version, .e_ident, etc.]
Because it has no need for stateful storage, dl_iterate_phdr could go into both
ld-linux.so.2 and libc.so.6.
"... symbol versioning (which records the containing DSO)" is not true [except
perhaps for pre-linking?] Only the symbol name and the version are recorded;
the containing DSO at link time has no necessary connection with the resolving
DSO at runtime. Otherwise LD_PRELOAD would not work, the organization of DSOs
could not be refactored after an application was linked, etc.
There is a Solaris like ld.so auditing API planned, so really this won't be
And as for versioning, you're wrong.
SHT_GNU_verneed section really records what file which symbol was found during
linking (together with SHT_GNU_verdef). Of course you can interpose symbols,
but if a symbol from a versioned library simply disappears, then ld.so will