elf: Unconditionally use __ehdr_start

We can consider __ehdr_start (from binutils 2.23 onwards)
unconditionally supported, since configure.ac requires binutils>=2.25.

The configure.ac check is related to an ia64 bug fixed by binutils 2.24.
See https://sourceware.org/pipermail/libc-alpha/2014-August/053503.html

Tested on x86_64-linux-gnu. Tested build-many-glibcs.py with
aarch64-linux-gnu and s390x-linux-gnu.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
This commit is contained in:
Fangrui Song 2021-08-10 11:04:56 -07:00
parent 13710e7e6a
commit 302247c891
4 changed files with 4 additions and 98 deletions

View File

@ -198,9 +198,6 @@
/* Define if CC supports attribute retain. */ /* Define if CC supports attribute retain. */
#undef HAVE_GNU_RETAIN #undef HAVE_GNU_RETAIN
/* Define if the linker defines __ehdr_start. */
#undef HAVE_EHDR_START
/* Define to 1 if the assembler needs intermediate aliases to define /* Define to 1 if the assembler needs intermediate aliases to define
multiple symbol versions for one symbol. */ multiple symbol versions for one symbol. */
#define SYMVER_NEEDS_ALIAS 0 #define SYMVER_NEEDS_ALIAS 0

52
configure vendored
View File

@ -6636,58 +6636,6 @@ if test $libc_cv_predef_fortify_source = yes; then
fi fi
# Some linkers on some architectures support __ehdr_start but with
# bugs. Make sure usage of it does not create relocations in the
# output (as the linker should resolve them all for us).
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker provides working __ehdr_start" >&5
$as_echo_n "checking whether the linker provides working __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 $no_ssp"
LIBS=
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
typedef struct {
char foo;
long val;
} Ehdr;
extern const Ehdr __ehdr_start __attribute__ ((visibility ("hidden")));
long ehdr (void) { return __ehdr_start.val; }
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if $READELF -r conftest | grep -F __ehdr_start >/dev/null; then
libc_cv_ehdr_start=broken
else
libc_cv_ehdr_start=yes
fi
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
elif test "$libc_cv_ehdr_start" = broken; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: linker is broken -- you should upgrade" >&5
$as_echo "$as_me: WARNING: linker is broken -- you should upgrade" >&2;}
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler requires one version per symbol" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler requires one version per symbol" >&5
$as_echo_n "checking whether the assembler requires one version per symbol... " >&6; } $as_echo_n "checking whether the assembler requires one version per symbol... " >&6; }
if ${libc_cv_symver_needs_alias+:} false; then : if ${libc_cv_symver_needs_alias+:} false; then :

View File

@ -1662,40 +1662,6 @@ if test $libc_cv_predef_fortify_source = yes; then
fi fi
AC_SUBST(CPPUNDEFS) AC_SUBST(CPPUNDEFS)
# Some linkers on some architectures support __ehdr_start but with
# bugs. Make sure usage of it does not create relocations in the
# output (as the linker should resolve them all for us).
AC_CACHE_CHECK([whether the linker provides working __ehdr_start],
libc_cv_ehdr_start, [
old_CFLAGS="$CFLAGS"
old_LDFLAGS="$LDFLAGS"
old_LIBS="$LIBS"
CFLAGS="$CFLAGS -fPIC"
LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared $no_ssp"
LIBS=
AC_LINK_IFELSE([AC_LANG_SOURCE([
typedef struct {
char foo;
long val;
} Ehdr;
extern const Ehdr __ehdr_start __attribute__ ((visibility ("hidden")));
long ehdr (void) { return __ehdr_start.val; }
])],
[if $READELF -r conftest | grep -F __ehdr_start >/dev/null; then
libc_cv_ehdr_start=broken
else
libc_cv_ehdr_start=yes
fi], [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])
elif test "$libc_cv_ehdr_start" = broken; then
AC_MSG_WARN([linker is broken -- you should upgrade])
fi
dnl Starting with binutils 2.35, GAS can attach multiple symbol versions dnl Starting with binutils 2.35, GAS can attach multiple symbol versions
dnl to one symbol (PR 23840). dnl to one symbol (PR 23840).
AC_CACHE_CHECK(whether the assembler requires one version per symbol, AC_CACHE_CHECK(whether the assembler requires one version per symbol,

View File

@ -1684,21 +1684,16 @@ dl_main (const ElfW(Phdr) *phdr,
if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2) if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2)
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
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 /* 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 __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 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 the old method that assumes the beginning of the file is part of the
lowest-addressed PT_LOAD segment. */ lowest-addressed PT_LOAD segment. */
#ifdef HAVE_EHDR_START
extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden"))); extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden")));
rtld_ehdr = &__ehdr_start;
#else /* Set up the program header information for the dynamic linker
rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start; itself. It is needed in the dl_iterate_phdr callbacks. */
#endif const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));