mirror of git://sourceware.org/git/glibc.git
Use __ehdr_start, when available, for rtld to get its own headers.
This commit is contained in:
parent
041a92472e
commit
44c4e5d598
|
@ -1,3 +1,11 @@
|
||||||
|
2014-03-13 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.
|
||||||
|
|
||||||
2014-03-13 Joseph Myers <joseph@codesourcery.com>
|
2014-03-13 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* INSTALL: Regenerated.
|
* INSTALL: Regenerated.
|
||||||
|
|
|
@ -195,6 +195,9 @@
|
||||||
/* Define if linux/fanotify.h is available. */
|
/* Define if linux/fanotify.h is available. */
|
||||||
#undef HAVE_LINUX_FANOTIFY_H
|
#undef HAVE_LINUX_FANOTIFY_H
|
||||||
|
|
||||||
|
/* Define if the linker defines __ehdr_start. */
|
||||||
|
#undef HAVE_EHDR_START
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -7268,6 +7268,44 @@ if test $libc_cv_predef_stack_protector = yes; then
|
||||||
fi
|
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.
|
### End of automated tests.
|
||||||
### Now run sysdeps configure fragments.
|
### Now run sysdeps configure fragments.
|
||||||
|
|
||||||
|
|
21
configure.ac
21
configure.ac
|
@ -2069,6 +2069,27 @@ if test $libc_cv_predef_stack_protector = yes; then
|
||||||
fi
|
fi
|
||||||
AC_SUBST(libc_extra_cflags)
|
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.
|
### End of automated tests.
|
||||||
### Now run sysdeps configure fragments.
|
### Now run sysdeps configure fragments.
|
||||||
|
|
||||||
|
|
23
elf/rtld.c
23
elf/rtld.c
|
@ -1371,10 +1371,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;
|
GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0;
|
||||||
|
|
||||||
/* Set up the program header information for the dynamic linker
|
/* Set up the program header information for the dynamic linker
|
||||||
itself. It is needed in the dl_iterate_phdr() callbacks. */
|
itself. It is needed in the dl_iterate_phdr callbacks. */
|
||||||
ElfW(Ehdr) *rtld_ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start;
|
const ElfW(Ehdr) *rtld_ehdr;
|
||||||
ElfW(Phdr) *rtld_phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start
|
|
||||||
+ rtld_ehdr->e_phoff);
|
/* 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_phdr = rtld_phdr;
|
||||||
GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;
|
GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue