This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
PATCH: Implement static dl_iterate_phdr
- From: "H. J. Lu" <hjl at lucon dot org>
- To: GNU C Library <libc-alpha at sources dot redhat dot com>
- Date: Mon, 13 Oct 2003 11:32:54 -0700
- Subject: PATCH: Implement static dl_iterate_phdr
The new linker provides __executable_start. This patch implements
static dl_iterate_phdr with it.
H.J.
-----
2003-10-13 H.J. Lu <hongjiu.lu@intel.com>
* configure.in: Define HAVE_EXECUTABLE_START if linker provides
__executable_start.
* config.h.in (HAVE_EXECUTABLE_START): Add.
* sysdeps/generic/dl-iteratephdr-static.c (dl_iterate_phdr): Use
__executable_start to get ELF header if HAVE_EXECUTABLE_START
is defined.
--- libc/config.h.in.static 2003-10-13 10:57:49.000000000 -0700
+++ libc/config.h.in 2003-10-13 10:57:30.000000000 -0700
@@ -153,6 +153,9 @@
sections. */
#undef HAVE_INITFINI_ARRAY
+/* Define if the linker provides __executable_start. */
+#undef HAVE_EXECUTABLE_START
+
/* Define if the access to static and hidden variables is position independent
and does not need relocations. */
#undef PI_STATIC_AND_HIDDEN
--- libc/configure.in.static 2003-10-09 08:53:12.000000000 -0700
+++ libc/configure.in 2003-10-13 10:47:56.000000000 -0700
@@ -1266,6 +1266,26 @@ EOF
AC_DEFINE(HAVE_INITFINI_ARRAY)
fi
+ AC_CACHE_CHECK(for __executable_start support,
+ libc_cv_executable_start, [dnl
+ cat > conftest.c <<EOF
+int _start (void) { return 0; }
+int __start (void) { return 0; }
+extern void *__executable_start;
+void *executable_start = (void *) &__executable_start;
+EOF
+ if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest conftest.c
+ -static -nostartfiles -nostdlib 1>&AS_MESSAGE_LOG_FD])
+ then
+ libc_cv_executable_start=yes
+ else
+ libc_cv_executable_start=no
+ fi
+ rm -f conftest*])
+ if test $libc_cv_executable_start = yes; then
+ AC_DEFINE(HAVE_EXECUTABLE_START)
+ fi
+
AC_CACHE_CHECK(for -z nodelete option,
libc_cv_z_nodelete, [dnl
cat > conftest.c <<EOF
--- libc/sysdeps/generic/dl-iteratephdr-static.c.static 2002-08-26 15:39:51.000000000 -0700
+++ libc/sysdeps/generic/dl-iteratephdr-static.c 2003-10-13 11:25:14.000000000 -0700
@@ -1,5 +1,5 @@
/* Get static program's program headers.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
@@ -18,9 +18,50 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <link.h>
+
+#ifdef HAVE_EXECUTABLE_START
+#include <assert.h>
+#include <ldsodefs.h>
+
+#define ELF32_CLASS ELFCLASS32
+#define ELF64_CLASS ELFCLASS64
+
+extern void *__executable_start;
+
+int
+dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
+ size_t size, void *data), void *data)
+{
+ ElfW(Ehdr) *ehdr;
+ struct dl_phdr_info info;
+ int ret;
+
+ ehdr = (ElfW(Ehdr) *) &__executable_start;
+
+ assert (ehdr->e_ident[0] == 0x7f
+ && ehdr->e_ident[1] == 'E'
+ && ehdr->e_ident[2] == 'L'
+ && ehdr->e_ident[3] == 'F'
+ && ehdr->e_ident[EI_CLASS] == ELFW(CLASS)
+ && (ehdr->e_ident[EI_DATA] == ELFDATA2LSB
+ || ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+ && ehdr->e_type == ET_EXEC);
+
+ info.dlpi_addr = 0;
+ info.dlpi_name = NULL;
+ info.dlpi_phdr = (ElfW(Phdr) *) ((char *) ehdr + ehdr->e_phoff);
+ info.dlpi_phnum = ehdr->e_phnum;
+
+ ret = callback (&info, sizeof (struct dl_phdr_info), data);
+ if (ret)
+ return ret;
+
+ return __dl_iterate_phdr (callback, data);
+}
+
+#else
#include <errno.h>
-#include <elf/link.h>
-#include <stddef.h>
int
dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
@@ -29,3 +70,4 @@ dl_iterate_phdr (int (*callback) (struct
__set_errno (ENOSYS);
return -1;
}
+#endif