1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-07 06:43:00 +03:00

Use __ehdr_start, if available, as fallback for AT_PHDR.

This commit is contained in:
Roland McGrath
2013-03-28 16:15:48 -07:00
parent dc0a026385
commit 288f7d79fe
3 changed files with 38 additions and 8 deletions

View File

@@ -1,5 +1,11 @@
2013-03-28 Roland McGrath <roland@hack.frob.com> 2013-03-28 Roland McGrath <roland@hack.frob.com>
* 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. * elf/dl-support.c (_dl_phdr): Make pointer to const.
(_dl_aux_init): Use const in cast when setting it. (_dl_aux_init): Use const in cast when setting it.
* sysdeps/mach/hurd/i386/init-first.c (init1): Remove superfluous cast. * sysdeps/mach/hurd/i386/init-first.c (init1): Remove superfluous cast.

View File

@@ -15,6 +15,7 @@
License along with the GNU C Library; if not, see License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@@ -151,7 +152,24 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
} }
# endif # endif
_dl_aux_init (auxvec); _dl_aux_init (auxvec);
if (GL(dl_phdr) == NULL)
# endif # 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 # ifdef DL_SYSDEP_OSCHECK
if (!__libc_multiple_libcs) if (!__libc_multiple_libcs)
{ {

View File

@@ -117,6 +117,11 @@ init1 (int argc, char *arg0, ...)
if ((void *) d == argv[0]) if ((void *) d == argv[0])
{ {
#ifndef SHARED #ifndef SHARED
/* 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. /* We may need to see our own phdrs, e.g. for TLS setup.
Try the usual kludge to find the headers without help from Try the usual kludge to find the headers without help from
the exec server. */ the exec server. */
@@ -125,6 +130,7 @@ init1 (int argc, char *arg0, ...)
_dl_phdr = (const void *) ehdr + ehdr->e_phoff; _dl_phdr = (const void *) ehdr + ehdr->e_phoff;
_dl_phnum = ehdr->e_phnum; _dl_phnum = ehdr->e_phnum;
assert (ehdr->e_phentsize == sizeof (ElfW(Phdr))); assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
}
#endif #endif
return; return;
} }