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 loaded modules. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: 1. cd /lib 2. nm -Dgop ld-linux.so.2 libc.so.6 | grep dl_iterate_phdr 3. 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 Additional info: 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 reconsidered. 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 complain loudly.