diff options
author | Roland McGrath <roland@hack.frob.com> | 2013-03-28 16:15:48 -0700 |
---|---|---|
committer | Roland McGrath <roland@hack.frob.com> | 2013-03-28 16:15:48 -0700 |
commit | 288f7d79fe2dcc8e62c539f57b25d7662a2cd5ff (patch) | |
tree | 01fbd48750047a5246b6bcc6d6551eb18bbdd4e3 /csu | |
parent | dc0a02638583d8e7f7e1cc72643d1b26ec6042fd (diff) | |
download | glibc-288f7d79fe2dcc8e62c539f57b25d7662a2cd5ff.tar glibc-288f7d79fe2dcc8e62c539f57b25d7662a2cd5ff.tar.gz glibc-288f7d79fe2dcc8e62c539f57b25d7662a2cd5ff.tar.bz2 glibc-288f7d79fe2dcc8e62c539f57b25d7662a2cd5ff.zip |
Use __ehdr_start, if available, as fallback for AT_PHDR.
Diffstat (limited to 'csu')
-rw-r--r-- | csu/libc-start.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/csu/libc-start.c b/csu/libc-start.c index 9c4c01d9fd..fa9085cf55 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -15,6 +15,7 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> @@ -151,7 +152,24 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), } # endif _dl_aux_init (auxvec); + if (GL(dl_phdr) == NULL) # endif + { + /* 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. + So we can set up _dl_phdr and _dl_phnum even without any + information from auxv. */ + + extern const ElfW(Ehdr) __ehdr_start __attribute__ ((weak)); + if (&__ehdr_start != NULL) + { + assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr)); + GL(dl_phdr) = (const void *) &__ehdr_start + __ehdr_start.e_phoff; + GL(dl_phnum) = __ehdr_start.e_phnum; + } + } + # ifdef DL_SYSDEP_OSCHECK if (!__libc_multiple_libcs) { |