diff --git a/aarch64-Make-elf_machine_-load_address-dynamic-robus.patch b/aarch64-Make-elf_machine_-load_address-dynamic-robus.patch new file mode 100644 index 0000000000000000000000000000000000000000..b17849954135668bd06c9ba120438c24be25200a --- /dev/null +++ b/aarch64-Make-elf_machine_-load_address-dynamic-robus.patch @@ -0,0 +1,72 @@ +From 43d06ed218fc8be58987bdfd00e21e5720f0b862 Mon Sep 17 00:00:00 2001 +From: Fangrui Song +Date: Wed, 11 Aug 2021 09:00:37 -0700 +Subject: [PATCH] aarch64: Make elf_machine_{load_address,dynamic} robust [BZ + #28203] + +The AArch64 ABI is largely platform agnostic and does not specify +_GLOBAL_OFFSET_TABLE_[0] ([1]). glibc ld.so turns out to be probably the +only user of _GLOBAL_OFFSET_TABLE_[0] and GNU ld defines the value +to the link-time address _DYNAMIC. [2] + +In 2012, __ehdr_start was implemented in GNU ld and gold in binutils +2.23. Using adrp+add / (-mcmodel=tiny) adr to access +__ehdr_start/_DYNAMIC gives us a robust way to get the load address and +the link-time address of _DYNAMIC. + +[1]: From a psABI maintainer, https://bugs.llvm.org/show_bug.cgi?id=49672#c2 +[2]: LLD's aarch64 port does not set _GLOBAL_OFFSET_TABLE_[0] to the +link-time address _DYNAMIC. +LLD is widely used on aarch64 Android and ChromeOS devices. Software +just works without the need for _GLOBAL_OFFSET_TABLE_[0]. + +Reviewed-by: Szabolcs Nagy +--- + sysdeps/aarch64/dl-machine.h | 24 +++++++++--------------- + 1 file changed, 9 insertions(+), 15 deletions(-) + +diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h +index d29d827..3e10cb4 100644 +--- a/sysdeps/aarch64/dl-machine.h ++++ b/sysdeps/aarch64/dl-machine.h +@@ -37,28 +37,22 @@ elf_machine_matches_host (const ElfW(Ehdr) *ehdr) + return ehdr->e_machine == EM_AARCH64; + } + +-/* Return the link-time address of _DYNAMIC. Conveniently, this is the +- first element of the GOT. */ +-static inline ElfW(Addr) __attribute__ ((unused)) +-elf_machine_dynamic (void) +-{ +- extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden; +- return _GLOBAL_OFFSET_TABLE_[0]; +-} +- + /* Return the run-time load address of the shared object. */ + + static inline ElfW(Addr) __attribute__ ((unused)) + elf_machine_load_address (void) + { +- /* To figure out the load address we use the definition that for any symbol: +- dynamic_addr(symbol) = static_addr(symbol) + load_addr ++ extern const ElfW(Ehdr) __ehdr_start attribute_hidden; ++ return (ElfW(Addr)) &__ehdr_start; ++} + +- _DYNAMIC sysmbol is used here as its link-time address stored in +- the special unrelocated first GOT entry. */ ++/* Return the link-time address of _DYNAMIC. */ + +- extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; +- return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic (); ++static inline ElfW(Addr) __attribute__ ((unused)) ++elf_machine_dynamic (void) ++{ ++ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; ++ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address (); + } + + /* Set up the loaded object described by L so its unrelocated PLT +-- +1.8.3.1 + diff --git a/elf-Unconditionally-use-__ehdr_start.patch b/elf-Unconditionally-use-__ehdr_start.patch new file mode 100644 index 0000000000000000000000000000000000000000..b30438db5358b87abf931dd3cdb9e939bd65808b --- /dev/null +++ b/elf-Unconditionally-use-__ehdr_start.patch @@ -0,0 +1,177 @@ +From 302247c89121e8d4c7629e589edbb4974fff6edb Mon Sep 17 00:00:00 2001 +From: Fangrui Song +Date: Tue, 10 Aug 2021 11:04:56 -0700 +Subject: [PATCH] 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 +--- + config.h.in | 3 --- + configure | 52 ---------------------------------------------------- + configure.ac | 34 ---------------------------------- + elf/rtld.c | 13 ++++--------- + 4 files changed, 4 insertions(+), 98 deletions(-) + +diff --git a/config.h.in b/config.h.in +index 8b45a3a..0d92504 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -198,9 +198,6 @@ + /* Define if CC supports attribute 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 + multiple symbol versions for one symbol. */ + #define SYMVER_NEEDS_ALIAS 0 +diff --git a/configure b/configure +index 9619c10..7272fbf 100755 +--- a/configure ++++ b/configure +@@ -6636,58 +6636,6 @@ if test $libc_cv_predef_fortify_source = yes; then + 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_n "checking whether the assembler requires one version per symbol... " >&6; } + if ${libc_cv_symver_needs_alias+:} false; then : +diff --git a/configure.ac b/configure.ac +index 34ecbba..af47cd5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1662,40 +1662,6 @@ if test $libc_cv_predef_fortify_source = yes; then + fi + 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 to one symbol (PR 23840). + AC_CACHE_CHECK(whether the assembler requires one version per symbol, +diff --git a/elf/rtld.c b/elf/rtld.c +index d733359..878e648 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -1684,21 +1684,16 @@ dl_main (const ElfW(Phdr) *phdr, + if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2) + 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 + __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 ++ ++ /* 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 = &__ehdr_start; + assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); + assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); + +-- +1.8.3.1 + diff --git a/glibc.spec b/glibc.spec index 2e68546d62de2971a86de41d820cdffd655de359..a4c162565d0ab2b41a944213d3e7c7b44357da9d 100644 --- a/glibc.spec +++ b/glibc.spec @@ -63,7 +63,7 @@ ############################################################################## Name: glibc Version: 2.34 -Release: 5 +Release: 6 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -95,6 +95,8 @@ Patch14: 2-5-AArch64-Improve-A64FX-memset-for-large-sizes.patch Patch15: 3-5-AArch64-Improve-A64FX-memset-for-remaining-bytes.patch Patch16: 4-5-AArch64-Improve-A64FX-memset-by-removing-unroll3.patch Patch17: 5-5-AArch64-Improve-A64FX-memset-medium-loops.patch +Patch18: elf-Unconditionally-use-__ehdr_start.patch +Patch19: aarch64-Make-elf_machine_-load_address-dynamic-robus.patch #Patch9000: turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch @@ -1186,6 +1188,11 @@ fi %doc hesiod/README.hesiod %changelog +* Sun Sep 26 2021 Qingqing Li - 2.34-6 +- elf: Unconditionally use __ehdr_start. +- aarch64: Make elf_machine_{load_addr,dynamic} robust [BZ #28203]. + upstream link: https://sourceware.org/bugzilla/show_bug.cgi?id=28203 + * Fri Sep 17 2021 Qingqing Li - 2.34-5 - aarch64: optimize memset performance.