This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch roland/ehdr_start created. glibc-2.19-141-g673dd44


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, roland/ehdr_start has been created
        at  673dd446ab3bdd7c30569432955b10250781c13b (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=673dd446ab3bdd7c30569432955b10250781c13b

commit 673dd446ab3bdd7c30569432955b10250781c13b
Author: Roland McGrath <roland@hack.frob.com>
Date:   Tue Mar 11 15:17:02 2014 -0700

    Use __ehdr_start, when available, for rtld to get its own headers.

diff --git a/ChangeLog b/ChangeLog
index 3a589d8..cd57fbf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2014-03-11  Roland McGrath  <roland@hack.frob.com>
 
+	* configure.ac (HAVE_EHDR_START): New check.
+	* configure: Regenerated.
+	* config.h.in (HAVE_EHDR_START): New #undef.
+	* elf/rtld.c (dl_main) [HAVE_EHDR_START]: Use __ehdr_start rather than
+	assuming the lowest-addressed segment maps the start of the file.
+
 	* sysdeps/arm/setjmp.S: Use sfi_breg on stores of mangled registers.
 	* sysdeps/arm/__longjmp.S: Use sfi_breg on loads of mangled registers.
 	Move sfi_sp use from the load-multiple (that no longer sets sp) to
diff --git a/config.h.in b/config.h.in
index 40797e7..ed3c593 100644
--- a/config.h.in
+++ b/config.h.in
@@ -195,6 +195,9 @@
 /* Define if linux/fanotify.h is available.  */
 #undef HAVE_LINUX_FANOTIFY_H
 
+/* Define if the linker defines __ehdr_start.  */
+#undef HAVE_EHDR_START
+
 /*
  */
 
diff --git a/configure b/configure
index fc023d0..3ee1848 100755
--- a/configure
+++ b/configure
@@ -7268,6 +7268,44 @@ if test $libc_cv_predef_stack_protector = yes; then
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker provides __ehdr_start" >&5
+$as_echo_n "checking whether the linker provides __ehdr_start... " >&6; }
+if ${libc_cv_ehdr_start+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+old_CFLAGS="$CFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LIBS="$LIBS"
+CFLAGS="$CFLAGS -fPIC"
+LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared"
+LIBS=
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+extern const char __ehdr_start __attribute__ ((visibility ("hidden")));
+const char *ehdr (void) { return &__ehdr_start; }
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  libc_cv_ehdr_start=yes
+else
+  libc_cv_ehdr_start=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+CFLAGS="$old_CFLAGS"
+LDFLAGS="$old_LDFLAGS"
+LIBS="$old_LIBS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ehdr_start" >&5
+$as_echo "$libc_cv_ehdr_start" >&6; }
+if test $libc_cv_ehdr_start = yes; then
+  $as_echo "#define HAVE_EHDR_START 1" >>confdefs.h
+
+fi
+
 ### End of automated tests.
 ### Now run sysdeps configure fragments.
 
diff --git a/configure.ac b/configure.ac
index f3dd87d..59dbb5e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2069,6 +2069,27 @@ if test $libc_cv_predef_stack_protector = yes; then
 fi
 AC_SUBST(libc_extra_cflags)
 
+AC_CACHE_CHECK([whether the linker provides __ehdr_start],
+	       libc_cv_ehdr_start, [
+old_CFLAGS="$CFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LIBS="$LIBS"
+CFLAGS="$CFLAGS -fPIC"
+LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared"
+LIBS=
+AC_LINK_IFELSE([AC_LANG_SOURCE([
+extern const char __ehdr_start __attribute__ ((visibility ("hidden")));
+const char *ehdr (void) { return &__ehdr_start; }
+])],
+	       [libc_cv_ehdr_start=yes], [libc_cv_ehdr_start=no])
+CFLAGS="$old_CFLAGS"
+LDFLAGS="$old_LDFLAGS"
+LIBS="$old_LIBS"
+])
+if test $libc_cv_ehdr_start = yes; then
+  AC_DEFINE([HAVE_EHDR_START])
+fi
+
 ### End of automated tests.
 ### Now run sysdeps configure fragments.
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 7f1413a..ae36a7a 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1370,10 +1370,25 @@ of this helper program; chances are you did not intend to run this program.\n\
     GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0;
 
   /* Set up the program header information for the dynamic linker
-     itself.  It is needed in the dl_iterate_phdr() callbacks.  */
-  ElfW(Ehdr) *rtld_ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start;
-  ElfW(Phdr) *rtld_phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start
-					  + rtld_ehdr->e_phoff);
+     itself.  It is needed in the dl_iterate_phdr callbacks.  */
+  const ElfW(Ehdr) *rtld_ehdr;
+
+  /* Starting from binutils-2.23, the linker will define the magic symbol
+     __ehdr_start to point to our own ELF header if it is visible in a
+     segment that also includes the phdrs.  If that's not available, we use
+     the old method that assumes the beginning of the file is part of the
+     lowest-addressed PT_LOAD segment.  */
+#ifdef HAVE_EHDR_START
+  extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden")));
+  rtld_ehdr = &__ehdr_start;
+#else
+  rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start;
+#endif
+  assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
+  assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));
+
+  const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff;
+
   GL(dl_rtld_map).l_phdr = rtld_phdr;
   GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;
 

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]