This is the mail archive of the
mailing list for the glibc project.
Re: PATCH: Implement static dl_iterate_phdr
- From: Roland McGrath <roland at redhat dot com>
- To: "H. J. Lu" <hjl at lucon dot org>
- Cc: GNU C Library <libc-alpha at sources dot redhat dot com>
- Date: Wed, 15 Oct 2003 19:48:35 -0700
- Subject: Re: PATCH: Implement static dl_iterate_phdr
> I may need the information on executable provided by dl_iterate_phdr.
> If it returns -1, I have to find another way to get what I need.
You still haven't said exactly what information it is that you need.
Usually necessary information from the static binary is statically linked
in, e.g. &_start, &etext, &edata, &end tell you what looking at the PT_LOAD
phdrs would tell you.
> Why bother with it at all if it doesn't work with static executable?
This is so obvious it really doesn't merit response. But anyway, static
linking is the rare exception and it's perfectly sensible to have things
that work better under dynamic linking. Moreover, no static binary really
needs such things because it can perfectly well already be aware of its own
contents at link time.
> Also it makes my code less portable. In this case, it is useless for me.
You are exaggerating. You have said nothing to suggest you have looked for
other solutions to whatever your real issue is. Nonetheless, as a pure
issue of completeness I see no reason dl_iterate_phdr shouldn't work in
static binaries since it is trivial to make it work. Kludges like what
your version does are not required; nor is the ia64 implementation's
kludge, though that one is at least really guaranteed to work (assuming the
executable didn't use a nonstandard linker script).
The pointer is available from the kernel via AT_PHDR and static binaries
already store this where it is trivial to retrieve. Unless there are
strong objections, I will commit the following patch.
2003-10-15 Roland McGrath <firstname.lastname@example.org>
* elf/dl-iteratephdr.c [! SHARED] (dl_iterate_phdr): New function.
Fake an entry for the main executable and then call __dl_iterate_phdr.
* elf/Makefile (routines): Remove dl-iteratephdr-static.
(CFLAGS-dl-iterate-phdr-static.c): Variable removed.
* sysdeps/generic/dl-iteratephdr-static.c: File removed.
* sysdeps/unix/sysv/linux/ia64/dl-iteratephdr-static.c: File removed.
RCS file: /cvs/glibc/libc/elf/Makefile,v
retrieving revision 1.276
diff -p -u -r1.276 Makefile
--- elf/Makefile 24 Sep 2003 01:55:51 -0000 1.276
+++ elf/Makefile 16 Oct 2003 01:45:55 -0000
@@ -22,7 +22,7 @@ subdir := elf
headers = elf.h bits/elfclass.h link.h
routines = $(dl-routines) dl-open dl-close dl-support dl-iteratephdr \
- dl-iteratephdr-static dl-addr enbl-secure dl-profstub \
+ dl-addr enbl-secure dl-profstub \
dl-origin dl-libc dl-sym dl-tsd
# The core dynamic linking functions are in libc for the static and
@@ -33,8 +33,7 @@ dl-routines = $(addprefix dl-,load cache
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
# But they are absent from the shared libc, because that code is in ld.so.
-elide-routines.os = $(all-dl-routines) dl-support enbl-secure \
- dl-iteratephdr-static dl-origin
+elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin
# ld.so uses those routines, plus some special stuff for being the program
# interpreter and operating independent of libc.
@@ -87,7 +86,6 @@ distribute := rtld-Rules \
CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-dl-iterate-phdr.c = $(uses-callbacks)
-CFLAGS-dl-iterate-phdr-static.c = $(uses-callbacks)
RCS file: /cvs/glibc/libc/elf/dl-iteratephdr.c,v
retrieving revision 1.8
diff -p -u -r1.8 dl-iteratephdr.c
--- elf/dl-iteratephdr.c 16 Sep 2003 05:47:50 -0000 1.8
+++ elf/dl-iteratephdr.c 16 Oct 2003 01:45:55 -0000
@@ -29,6 +29,7 @@ cancel_handler (void *arg __attribute__(
__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
size_t size, void *data), void *data)
@@ -58,7 +59,38 @@ __dl_iterate_phdr (int (*callback) (stru
weak_alias (__dl_iterate_phdr, dl_iterate_phdr);
+/* dl-support.c defines these and initializes them early on. */
+extern ElfW(Phdr) *_dl_phdr;
+extern size_t _dl_phnum;
+dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
+ size_t size, void *data), void *data)
+ if (_dl_phnum != 0)
+ /* This entry describes this statically-linked program itself. */
+ struct dl_phdr_info info;
+ int ret;
+ info.dlpi_addr = 0;
+ info.dlpi_name = "";
+ info.dlpi_phdr = _dl_phdr;
+ info.dlpi_phnum = _dl_phnum;
+ ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
+ if (ret)
+ return ret;
+ return __dl_iterate_phdr (callback, data);