From: Roland McGrath Date: Thu, 28 Mar 2013 23:15:48 +0000 (-0700) Subject: Use __ehdr_start, if available, as fallback for AT_PHDR. X-Git-Tag: upstream/2.30~9273 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=288f7d79fe2dcc8e62c539f57b25d7662a2cd5ff;p=external%2Fglibc.git Use __ehdr_start, if available, as fallback for AT_PHDR. --- diff --git a/ChangeLog b/ChangeLog index de20ebb..876b577 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2013-03-28 Roland McGrath + * csu/libc-start.c (__libc_start_main) [!SHARED]: If _dl_aux_init + didn't do it already, then set _dl_phdr and _dl_phnum based on the + magic __ehdr_start linker symbol if it's defined. + * sysdeps/mach/hurd/i386/init-first.c (init1) [!SHARED]: Don't set + them up here if it was already done. + * elf/dl-support.c (_dl_phdr): Make pointer to const. (_dl_aux_init): Use const in cast when setting it. * sysdeps/mach/hurd/i386/init-first.c (init1): Remove superfluous cast. diff --git a/csu/libc-start.c b/csu/libc-start.c index 9c4c01d..fa9085c 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 . */ +#include #include #include #include @@ -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) { diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c index 59253db..fc3330c 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/i386/init-first.c @@ -117,14 +117,20 @@ init1 (int argc, char *arg0, ...) if ((void *) d == argv[0]) { #ifndef SHARED - /* We may need to see our own phdrs, e.g. for TLS setup. - Try the usual kludge to find the headers without help from - the exec server. */ - extern const void _start; - const ElfW(Ehdr) *const ehdr = &_start; - _dl_phdr = (const void *) ehdr + ehdr->e_phoff; - _dl_phnum = ehdr->e_phnum; - assert (ehdr->e_phentsize == sizeof (ElfW(Phdr))); + /* With a new enough linker (binutils-2.23 or better), + the magic __ehdr_start symbol will be available and + __libc_start_main will have done this that way already. */ + if (_dl_phdr == NULL) + { + /* We may need to see our own phdrs, e.g. for TLS setup. + Try the usual kludge to find the headers without help from + the exec server. */ + extern const void _start; + const ElfW(Ehdr) *const ehdr = &_start; + _dl_phdr = (const void *) ehdr + ehdr->e_phoff; + _dl_phnum = ehdr->e_phnum; + assert (ehdr->e_phentsize == sizeof (ElfW(Phdr))); + } #endif return; }