[crux-commits] ports/core (3.6): glibc-32: sync with upstream 2.32 branch

crux at crux.nu crux at crux.nu
Wed Mar 24 14:19:48 UTC 2021


commit bec746a7a25d08b973bca7f78177f10f82dd9769
Author: Juergen Daubert <jue at jue.li>
Date:   Wed Mar 24 15:19:36 2021 +0100

    glibc-32: sync with upstream 2.32 branch

diff --git a/glibc-32/.signature b/glibc-32/.signature
index 4e6b681b..f749425f 100644
--- a/glibc-32/.signature
+++ b/glibc-32/.signature
@@ -1,8 +1,8 @@
 untrusted comment: verify with /etc/ports/core.pub
-RWRJc1FUaeVeqm5CTGy3xHfvEe6BoRxt4y161ZfC8N+8sdz4AnkunQ+f0uk3DIAj37eNRkvfVA+IpTsEbYjqwS9oC1EpWb6WLgM=
-SHA256 (Pkgfile) = 146542b5d0e0dbba5e77e66bc5095b54c1e98b0aa67a69d96ce0caef054d2cd3
+RWRJc1FUaeVeqsImCrnu91cf6KEXS52UXALzInBBj8j/7tdWU6W8GeQhtQXjP2SxeFlpihMX07JTxkM9R4VuH9jYZbLwbZa+pwQ=
+SHA256 (Pkgfile) = 246974317c78736d3518e5bf328b3908d3af6e7c05527b468d5cd28ca283d74e
 SHA256 (.footprint) = 45836a310a6801080a61130aca376091caab990a0c75d9fc039fcb7ad7298642
 SHA256 (glibc-2.32.tar.xz) = 1627ea54f5a1a8467032563393e0901077626dc66f37f10ee6363bb722222836
 SHA256 (linux-5.4.72.tar.xz) = 0e24645bd56fe5b55a7a662895f5562c103d71b54d097281f0c9c71ff22c1172
-SHA256 (glibc-2.32-2.patch) = 7d0263f8683481df2af5e759f99e285a0bfeea330d4e613198c4580384fc44b0
+SHA256 (glibc-2.32-3.patch) = 6d84a6054984e89c4b139dfa1a29561ee2f146bafa479f1c465700220a6aee73
 SHA256 (lib32.conf) = 2f174d2bcefe1c29327690514f34d6970fffdd54398320ca23a11b5f1e3c9b2d
diff --git a/glibc-32/Pkgfile b/glibc-32/Pkgfile
index 7692af14..c0ceb173 100644
--- a/glibc-32/Pkgfile
+++ b/glibc-32/Pkgfile
@@ -1,13 +1,13 @@
 # Description: The C library used in the GNU system
-# URL:         http://www.gnu.org/software/libc/
-# Maintainer:  CRUX System Team, core-ports at crux dot nu
+# URL: http://www.gnu.org/software/libc/
+# Maintainer: CRUX System Team, core-ports at crux dot nu
 
 name=glibc-32
 version=2.32
-release=2
+release=3
 source=(http://ftp.gnu.org/gnu/glibc/glibc-$version.tar.xz \
 	http://www.kernel.org/pub/linux/kernel/v5.x/linux-5.4.72.tar.xz \
-	glibc-$version-2.patch lib32.conf) 
+	glibc-$version-3.patch lib32.conf) 
 
 build() {
 	# install kernel headers
@@ -17,7 +17,7 @@ build() {
 	make INSTALL_HDR_PATH=$PKG/usr headers_install
 	chown root:root $PKG/usr
 
-	patch -p1 -d $SRC/glibc-${version:0:4} -i $SRC/glibc-$version-2.patch
+	patch -p1 -d $SRC/glibc-${version:0:4} -i $SRC/glibc-$version-3.patch
 
 	mkdir $SRC/build
 	cd $SRC/build
diff --git a/glibc-32/glibc-2.32-2.patch b/glibc-32/glibc-2.32-3.patch
similarity index 54%
rename from glibc-32/glibc-2.32-2.patch
rename to glibc-32/glibc-2.32-3.patch
index 53476d29..8195ec34 100644
--- a/glibc-32/glibc-2.32-2.patch
+++ b/glibc-32/glibc-2.32-3.patch
@@ -1,25 +1,374 @@
 diff --git a/NEWS b/NEWS
-index 485b8ddffa..3030735839 100644
+index 485b8ddffa..f278041512 100644
 --- a/NEWS
 +++ b/NEWS
-@@ -5,6 +5,17 @@ See the end for copying conditions.
+@@ -5,6 +5,25 @@ See the end for copying conditions.
  Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
  using `glibc' in the "product" field.
  
 +The following bugs are resolved with this release:
 +
++  [20019] NULL pointer dereference in libc.so.6 IFUNC due to uninitialized GOT
++  [26224] iconv hangs when converting some invalid inputs from several IBM
++    character sets (CVE-2020-27618)
 +  [26534] libm.so 2.32 SIGILL in pow() due to FMA4 instruction on non-FMA4
 +    system
 +  [26555] string: strerrorname_np does not return the documented value
++  [26600] Transaction ID collisions cause slow DNS lookups in getaddrinfo
 +  [26636] libc: 32-bit shmctl(IPC_INFO) crashes when shminfo struct is
 +    at the end of a memory mapping
 +  [26637] libc: semctl SEM_STAT_ANY fails to pass the buffer specified
 +    by the caller to the kernel
 +  [26639] libc: msgctl IPC_INFO and MSG_INFO return garbage
++  [26853] aarch64: Missing unwind information in statically linked startup code
++  [26932] libc: sh: Multiple floating point functions defined as stubs only
++  [27130] "rep movsb" performance issue
++  [27177] GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on doesn't work
 +
  Version 2.32
  
  Major new features:
+@@ -185,6 +204,10 @@ Security related changes:
+   Dytrych of the Cisco Security Assessment and Penetration Team (See
+   TALOS-2020-1019).
+ 
++  CVE-2020-27618: An infinite loop has been fixed in the iconv program when
++  invoked with input containing redundant shift sequences in the IBM1364,
++  IBM1371, IBM1388, IBM1390, or IBM1399 character sets.
++
+ The following bugs are resolved with this release:
+ 
+   [9809] localedata: ckb_IQ: new Kurdish Sorani locale
+diff --git a/Rules b/Rules
+index 8b771f6095..beab969fde 100644
+--- a/Rules
++++ b/Rules
+@@ -155,6 +155,7 @@ xtests: tests $(xtests-special)
+ else
+ tests: $(tests:%=$(objpfx)%.out) $(tests-internal:%=$(objpfx)%.out) \
+        $(tests-container:%=$(objpfx)%.out) \
++       $(tests-mcheck:%=$(objpfx)%-mcheck.out) \
+        $(tests-special) $(tests-printers-out)
+ xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-special)
+ endif
+@@ -165,7 +166,7 @@ ifeq ($(run-built-tests),no)
+ tests-expected =
+ else
+ tests-expected = $(tests) $(tests-internal) $(tests-printers) \
+-	$(tests-container)
++	$(tests-container) $(tests-mcheck:%=%-mcheck)
+ endif
+ tests:
+ 	$(..)scripts/merge-test-results.sh -s $(objpfx) $(subdir) \
+@@ -191,6 +192,7 @@ else
+ binaries-pie-tests =
+ binaries-pie-notests =
+ endif
++binaries-mcheck-tests = $(tests-mcheck:%=%-mcheck)
+ else
+ binaries-all-notests =
+ binaries-all-tests = $(tests) $(tests-internal) $(xtests) $(test-srcs)
+@@ -200,6 +202,7 @@ binaries-static-tests =
+ binaries-static =
+ binaries-pie-tests =
+ binaries-pie-notests =
++binaries-mcheck-tests =
+ endif
+ 
+ binaries-pie = $(binaries-pie-tests) $(binaries-pie-notests)
+@@ -223,6 +226,14 @@ $(addprefix $(objpfx),$(binaries-shared-tests)): %: %.o \
+ 	$(+link-tests)
+ endif
+ 
++ifneq "$(strip $(binaries-mcheck-tests))" ""
++$(addprefix $(objpfx),$(binaries-mcheck-tests)): %-mcheck: %.o \
++  $(link-extra-libs-tests) \
++  $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
++  $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
++	$(+link-tests)
++endif
++
+ ifneq "$(strip $(binaries-pie-tests))" ""
+ $(addprefix $(objpfx),$(binaries-pie-tests)): %: %.o \
+   $(link-extra-libs-tests) \
+@@ -253,6 +264,12 @@ $(addprefix $(objpfx),$(binaries-static-tests)): %: %.o \
+ 	$(+link-static-tests)
+ endif
+ 
++# All mcheck tests will be run with MALLOC_CHECK_=3
++define mcheck-ENVS
++$(1)-mcheck-ENV = MALLOC_CHECK_=3
++endef
++$(foreach t,$(tests-mcheck),$(eval $(call mcheck-ENVS,$(t))))
++
+ ifneq "$(strip $(tests) $(tests-internal) $(xtests) $(test-srcs))" ""
+ # These are the implicit rules for making test outputs
+ # from the test programs and whatever input files are present.
+diff --git a/debug/Makefile b/debug/Makefile
+index 3a60d7af7a..0036edd187 100644
+--- a/debug/Makefile
++++ b/debug/Makefile
+@@ -51,7 +51,7 @@ routines  = backtrace backtracesyms backtracesymsfd noophooks \
+ 	    explicit_bzero_chk \
+ 	    stack_chk_fail fortify_fail \
+ 	    $(static-only-routines)
+-static-only-routines := warning-nop stack_chk_fail_local
++static-only-routines := stack_chk_fail_local
+ 
+ # Don't add stack_chk_fail_local.o to libc.a since __stack_chk_fail_local
+ # is an alias of __stack_chk_fail in stack_chk_fail.o.
+diff --git a/debug/warning-nop.c b/debug/warning-nop.c
+deleted file mode 100644
+index 4ab7e182b7..0000000000
+--- a/debug/warning-nop.c
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/* Dummy nop functions to elicit link-time warnings.
+-   Copyright (C) 2005-2020 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   In addition to the permissions in the GNU Lesser General Public
+-   License, the Free Software Foundation gives you unlimited
+-   permission to link the compiled version of this file with other
+-   programs, and to distribute those programs without any restriction
+-   coming from the use of this file. (The GNU Lesser General Public
+-   License restrictions do apply in other respects; for example, they
+-   cover modification of the file, and distribution when not linked
+-   into another program.)
+-
+-   Note that people who make modified versions of this file are not
+-   obligated to grant this special exception for their modified
+-   versions; it is their choice whether to do so. The GNU Lesser
+-   General Public License gives permission to release a modified
+-   version without this exception; this exception also makes it
+-   possible to release a modified version which carries forward this
+-   exception.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <https://www.gnu.org/licenses/>.  */
+-
+-#include <sys/cdefs.h>
+-
+-static void
+-__attribute__ ((used))
+-nop (void)
+-{
+-}
+-
+-/* Don't insert any other #include's before this #undef!  */
+-
+-#undef __warndecl
+-#define __warndecl(name, msg) \
+-  extern void name (void) __attribute__ ((alias ("nop"))) attribute_hidden; \
+-  link_warning (name, msg)
+-
+-#undef	__USE_FORTIFY_LEVEL
+-#define __USE_FORTIFY_LEVEL 99
+-
+-/* Following here we need an #include for each public header file
+-   that uses __warndecl.  */
+-
+-/* Define away to avoid warnings with compilers that do not have these
+-   builtins.  */
+-#define __builtin___memcpy_chk(dest, src, len, bos) NULL
+-#define __builtin___memmove_chk(dest, src, len, bos) NULL
+-#define __builtin___mempcpy_chk(dest, src, len, bos) NULL
+-#define __builtin___memset_chk(dest, ch, len, bos) NULL
+-#define __builtin___stpcpy_chk(dest, src, bos) NULL
+-#define __builtin___strcat_chk(dest, src, bos) NULL
+-#define __builtin___strcpy_chk(dest, src, bos) NULL
+-#define __builtin___strncat_chk(dest, src, len, bos) NULL
+-#define __builtin___strncpy_chk(dest, src, len, bos) NULL
+-#define __builtin_object_size(bos, level) 0
+-
+-#include <string.h>
+diff --git a/elf/Makefile b/elf/Makefile
+index 0b78721848..355e70037b 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -1381,6 +1381,8 @@ CFLAGS-ifuncmain7pie.c += $(pie-ccflag)
+ CFLAGS-ifuncmain9pie.c += $(pie-ccflag)
+ CFLAGS-tst-ifunc-textrel.c += $(pic-ccflag)
+ 
++LDFLAGS-ifuncmain6pie = -Wl,-z,lazy
++
+ $(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so
+ $(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o
+ $(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index e39980fb19..71867e7c1a 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -855,10 +855,12 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
+ 
+ /* Process PT_GNU_PROPERTY program header PH in module L after
+    PT_LOAD segments are mapped.  Only one NT_GNU_PROPERTY_TYPE_0
+-   note is handled which contains processor specific properties.  */
++   note is handled which contains processor specific properties.
++   FD is -1 for the kernel mapped main executable otherwise it is
++   the fd used for loading module L.  */
+ 
+ void
+-_dl_process_pt_gnu_property (struct link_map *l, const ElfW(Phdr) *ph)
++_dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+ {
+   const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
+   const ElfW(Addr) size = ph->p_memsz;
+@@ -905,7 +907,7 @@ _dl_process_pt_gnu_property (struct link_map *l, const ElfW(Phdr) *ph)
+ 	      last_type = type;
+ 
+ 	      /* Target specific property processing.  */
+-	      if (_dl_process_gnu_property (l, type, datasz, ptr) == 0)
++	      if (_dl_process_gnu_property (l, fd, type, datasz, ptr) == 0)
+ 		return;
+ 
+ 	      /* Check the next property item.  */
+@@ -1251,21 +1253,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
+ 				  maplength, has_holes, loader);
+     if (__glibc_unlikely (errstring != NULL))
+       goto call_lose;
+-
+-    /* Process program headers again after load segments are mapped in
+-       case processing requires accessing those segments.  Scan program
+-       headers backward so that PT_NOTE can be skipped if PT_GNU_PROPERTY
+-       exits.  */
+-    for (ph = &phdr[l->l_phnum]; ph != phdr; --ph)
+-      switch (ph[-1].p_type)
+-	{
+-	case PT_NOTE:
+-	  _dl_process_pt_note (l, &ph[-1]);
+-	  break;
+-	case PT_GNU_PROPERTY:
+-	  _dl_process_pt_gnu_property (l, &ph[-1]);
+-	  break;
+-	}
+   }
+ 
+   if (l->l_ld == 0)
+@@ -1377,6 +1364,21 @@ cannot enable executable stack as shared object requires");
+   if (l->l_tls_initimage != NULL)
+     l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr;
+ 
++  /* Process program headers again after load segments are mapped in
++     case processing requires accessing those segments.  Scan program
++     headers backward so that PT_NOTE can be skipped if PT_GNU_PROPERTY
++     exits.  */
++  for (ph = &l->l_phdr[l->l_phnum]; ph != l->l_phdr; --ph)
++    switch (ph[-1].p_type)
++      {
++      case PT_NOTE:
++	_dl_process_pt_note (l, fd, &ph[-1]);
++	break;
++      case PT_GNU_PROPERTY:
++	_dl_process_pt_gnu_property (l, fd, &ph[-1]);
++	break;
++      }
++
+   /* We are done mapping in the file.  We no longer need the descriptor.  */
+   if (__glibc_unlikely (__close_nocancel (fd) != 0))
+     {
+diff --git a/elf/ifuncmain6pie.c b/elf/ifuncmain6pie.c
+index 04faeb86ef..4a01906836 100644
+--- a/elf/ifuncmain6pie.c
++++ b/elf/ifuncmain6pie.c
+@@ -9,7 +9,6 @@
+ #include "ifunc-sel.h"
+ 
+ typedef int (*foo_p) (void);
+-extern foo_p foo_ptr;
+ 
+ static int
+ one (void)
+@@ -28,20 +27,17 @@ foo_ifunc (void)
+ }
+ 
+ extern int foo (void);
+-extern foo_p get_foo (void);
++extern int call_foo (void);
+ extern foo_p get_foo_p (void);
+ 
+-foo_p my_foo_ptr = foo;
++foo_p foo_ptr = foo;
+ 
+ int
+ main (void)
+ {
+   foo_p p;
+ 
+-  p = get_foo ();
+-  if (p != foo)
+-    abort ();
+-  if ((*p) () != -30)
++  if (call_foo () != -30)
+     abort ();
+ 
+   p = get_foo_p ();
+@@ -52,12 +48,8 @@ main (void)
+ 
+   if (foo_ptr != foo)
+     abort ();
+-  if (my_foo_ptr != foo)
+-    abort ();
+   if ((*foo_ptr) () != -30)
+     abort ();
+-  if ((*my_foo_ptr) () != -30)
+-    abort ();
+   if (foo () != -30)
+     abort ();
+ 
+diff --git a/elf/ifuncmod6.c b/elf/ifuncmod6.c
+index 2e16c1d06d..2f6d0715e6 100644
+--- a/elf/ifuncmod6.c
++++ b/elf/ifuncmod6.c
+@@ -4,7 +4,7 @@ extern int foo (void);
+ 
+ typedef int (*foo_p) (void);
+ 
+-foo_p foo_ptr = foo;
++extern foo_p foo_ptr;
+ 
+ foo_p
+ get_foo_p (void)
+@@ -12,8 +12,8 @@ get_foo_p (void)
+   return foo_ptr;
+ }
+ 
+-foo_p
+-get_foo (void)
++int
++call_foo (void)
+ {
+-  return foo;
++  return foo ();
+ }
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 5b882163fa..14a42ed00a 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -1534,10 +1534,10 @@ of this helper program; chances are you did not intend to run this program.\n\
+     switch (ph[-1].p_type)
+       {
+       case PT_NOTE:
+-	_dl_process_pt_note (main_map, &ph[-1]);
++	_dl_process_pt_note (main_map, -1, &ph[-1]);
+ 	break;
+       case PT_GNU_PROPERTY:
+-	_dl_process_pt_gnu_property (main_map, &ph[-1]);
++	_dl_process_pt_gnu_property (main_map, -1, &ph[-1]);
+ 	break;
+       }
+ 
 diff --git a/iconv/Versions b/iconv/Versions
 index 8a5f4cf780..d51af52fa3 100644
 --- a/iconv/Versions
@@ -149,6 +498,425 @@ index b4334faa57..d59979759c 100644
  
        if (res != __GCONV_OK)
  	{
+diff --git a/iconv/tst-iconv_prog.sh b/iconv/tst-iconv_prog.sh
+index 8298136b7f..d8db7b335c 100644
+--- a/iconv/tst-iconv_prog.sh
++++ b/iconv/tst-iconv_prog.sh
+@@ -102,12 +102,16 @@ hangarray=(
+ "\x00\x80;-c;IBM1161;UTF-8//TRANSLIT//IGNORE"
+ "\x00\xdb;-c;IBM1162;UTF-8//TRANSLIT//IGNORE"
+ "\x00\x70;-c;IBM12712;UTF-8//TRANSLIT//IGNORE"
+-# These are known hangs that are yet to be fixed:
+-# "\x00\x0f;-c;IBM1364;UTF-8"
+-# "\x00\x0f;-c;IBM1371;UTF-8"
+-# "\x00\x0f;-c;IBM1388;UTF-8"
+-# "\x00\x0f;-c;IBM1390;UTF-8"
+-# "\x00\x0f;-c;IBM1399;UTF-8"
++"\x00\x0f;-c;IBM1364;UTF-8"
++"\x0e\x0e;-c;IBM1364;UTF-8"
++"\x00\x0f;-c;IBM1371;UTF-8"
++"\x0e\x0e;-c;IBM1371;UTF-8"
++"\x00\x0f;-c;IBM1388;UTF-8"
++"\x0e\x0e;-c;IBM1388;UTF-8"
++"\x00\x0f;-c;IBM1390;UTF-8"
++"\x0e\x0e;-c;IBM1390;UTF-8"
++"\x00\x0f;-c;IBM1399;UTF-8"
++"\x0e\x0e;-c;IBM1399;UTF-8"
+ "\x00\x53;-c;IBM16804;UTF-8//TRANSLIT//IGNORE"
+ "\x00\x41;-c;IBM274;UTF-8//TRANSLIT//IGNORE"
+ "\x00\x41;-c;IBM275;UTF-8//TRANSLIT//IGNORE"
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index 4ec2741cdc..4eef07557e 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -73,7 +73,8 @@ modules.so := $(addsuffix .so, $(modules))
+ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+ 	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
+-	bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4
++	bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \
++	bug-iconv13 bug-iconv14
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -321,6 +322,8 @@ $(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \
+ 			  $(addprefix $(objpfx),$(modules.so))
+ $(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
+ 			  $(addprefix $(objpfx),$(modules.so))
++$(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \
++			  $(addprefix $(objpfx),$(modules.so))
+ 
+ $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
+ 			 $(addprefix $(objpfx),$(modules.so)) \
+diff --git a/iconvdata/bug-iconv13.c b/iconvdata/bug-iconv13.c
+new file mode 100644
+index 0000000000..87aaff398e
+--- /dev/null
++++ b/iconvdata/bug-iconv13.c
+@@ -0,0 +1,53 @@
++/* bug 24973: Test EUC-KR module
++   Copyright (C) 2020 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <iconv.h>
++#include <stdio.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  iconv_t cd = iconv_open ("UTF-8//IGNORE", "EUC-KR");
++  TEST_VERIFY_EXIT (cd != (iconv_t) -1);
++
++  /* 0xfe (->0x7e : row 94) and 0xc9 (->0x49 : row 41) are user-defined
++     areas, which are not allowed and should be skipped over due to
++     //IGNORE.  The trailing 0xfe also is an incomplete sequence, which
++     should be checked first.  */
++  char input[4] = { '\xc9', '\xa1', '\0', '\xfe' };
++  char *inptr = input;
++  size_t insize = sizeof (input);
++  char output[4];
++  char *outptr = output;
++  size_t outsize = sizeof (output);
++
++  /* This used to crash due to buffer overrun.  */
++  TEST_VERIFY (iconv (cd, &inptr, &insize, &outptr, &outsize) == (size_t) -1);
++  TEST_VERIFY (errno == EINVAL);
++  /* The conversion should produce one character, the converted null
++     character.  */
++  TEST_VERIFY (sizeof (output) - outsize == 1);
++
++  TEST_VERIFY_EXIT (iconv_close (cd) != -1);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/iconvdata/bug-iconv14.c b/iconvdata/bug-iconv14.c
+new file mode 100644
+index 0000000000..902f140fa9
+--- /dev/null
++++ b/iconvdata/bug-iconv14.c
+@@ -0,0 +1,127 @@
++/* Assertion in ISO-2022-JP-3 due to two-character sequence (bug 27256).
++   Copyright (C) 2021 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <iconv.h>
++#include <string.h>
++#include <errno.h>
++#include <support/check.h>
++
++/* Use an escape sequence to return to the initial state.  */
++static void
++with_escape_sequence (void)
++{
++  iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
++  TEST_VERIFY_EXIT (c != (iconv_t) -1);
++
++  char in[] = "\e$(O+D\e(B";
++  char *inbuf = in;
++  size_t inleft = strlen (in);
++  char out[3];                  /* Space for one output character.  */
++  char *outbuf;
++  size_t outleft;
++
++  outbuf = out;
++  outleft = sizeof (out);
++  TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
++  TEST_COMPARE (errno, E2BIG);
++  TEST_COMPARE (inleft, 3);
++  TEST_COMPARE (inbuf - in, strlen (in) - 3);
++  TEST_COMPARE (outleft, sizeof (out) - 2);
++  TEST_COMPARE (outbuf - out, 2);
++  TEST_COMPARE (out[0] & 0xff, 0xc3);
++  TEST_COMPARE (out[1] & 0xff, 0xa6);
++
++  /* Return to the initial shift state, producing the pending
++     character.  */
++  outbuf = out;
++  outleft = sizeof (out);
++  TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), 0);
++  TEST_COMPARE (inleft, 0);
++  TEST_COMPARE (inbuf - in, strlen (in));
++  TEST_COMPARE (outleft, sizeof (out) - 2);
++  TEST_COMPARE (outbuf - out, 2);
++  TEST_COMPARE (out[0] & 0xff, 0xcc);
++  TEST_COMPARE (out[1] & 0xff, 0x80);
++
++  /* Nothing should be flushed the second time.  */
++  outbuf = out;
++  outleft = sizeof (out);
++  TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
++  TEST_COMPARE (outleft, sizeof (out));
++  TEST_COMPARE (outbuf - out, 0);
++  TEST_COMPARE (out[0] & 0xff, 0xcc);
++  TEST_COMPARE (out[1] & 0xff, 0x80);
++
++  TEST_COMPARE (iconv_close (c), 0);
++}
++
++/* Use an explicit flush to return to the initial state.  */
++static void
++with_flush (void)
++{
++  iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
++  TEST_VERIFY_EXIT (c != (iconv_t) -1);
++
++  char in[] = "\e$(O+D";
++  char *inbuf = in;
++  size_t inleft = strlen (in);
++  char out[3];                  /* Space for one output character.  */
++  char *outbuf;
++  size_t outleft;
++
++  outbuf = out;
++  outleft = sizeof (out);
++  TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
++  TEST_COMPARE (errno, E2BIG);
++  TEST_COMPARE (inleft, 0);
++  TEST_COMPARE (inbuf - in, strlen (in));
++  TEST_COMPARE (outleft, sizeof (out) - 2);
++  TEST_COMPARE (outbuf - out, 2);
++  TEST_COMPARE (out[0] & 0xff, 0xc3);
++  TEST_COMPARE (out[1] & 0xff, 0xa6);
++
++  /* Flush the pending character.  */
++  outbuf = out;
++  outleft = sizeof (out);
++  TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
++  TEST_COMPARE (outleft, sizeof (out) - 2);
++  TEST_COMPARE (outbuf - out, 2);
++  TEST_COMPARE (out[0] & 0xff, 0xcc);
++  TEST_COMPARE (out[1] & 0xff, 0x80);
++
++  /* Nothing should be flushed the second time.  */
++  outbuf = out;
++  outleft = sizeof (out);
++  TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
++  TEST_COMPARE (outleft, sizeof (out));
++  TEST_COMPARE (outbuf - out, 0);
++  TEST_COMPARE (out[0] & 0xff, 0xcc);
++  TEST_COMPARE (out[1] & 0xff, 0x80);
++
++  TEST_COMPARE (iconv_close (c), 0);
++}
++
++static int
++do_test (void)
++{
++  with_escape_sequence ();
++  with_flush ();
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c
+index b0d56cf3ee..1045bae926 100644
+--- a/iconvdata/euc-kr.c
++++ b/iconvdata/euc-kr.c
+@@ -80,11 +80,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
+ 									      \
+     if (ch <= 0x9f)							      \
+       ++inptr;								      \
+-    /* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are		      \
+-       user-defined areas.  */						      \
+-    else if (__builtin_expect (ch == 0xa0, 0)				      \
+-	     || __builtin_expect (ch > 0xfe, 0)				      \
+-	     || __builtin_expect (ch == 0xc9, 0))			      \
++    else if (__glibc_unlikely (ch == 0xa0))				      \
+       {									      \
+ 	/* This is illegal.  */						      \
+ 	STANDARD_FROM_LOOP_ERR_HANDLER (1);				      \
+diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
+index 49e7267ab4..521f0825b7 100644
+--- a/iconvdata/ibm1364.c
++++ b/iconvdata/ibm1364.c
+@@ -158,24 +158,14 @@ enum
+ 									      \
+     if (__builtin_expect (ch, 0) == SO)					      \
+       {									      \
+-	/* Shift OUT, change to DBCS converter.  */			      \
+-	if (curcs == db)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift OUT, change to DBCS converter (redundant escape okay).  */   \
+ 	curcs = db;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+       }									      \
+     if (__builtin_expect (ch, 0) == SI)					      \
+       {									      \
+-	/* Shift IN, change to SBCS converter.  */			      \
+-	if (curcs == sb)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift IN, change to SBCS converter (redundant escape okay).  */    \
+ 	curcs = sb;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+diff --git a/iconvdata/iso-2022-jp-3.c b/iconvdata/iso-2022-jp-3.c
+index 8c3b7e627e..62cbc54a11 100644
+--- a/iconvdata/iso-2022-jp-3.c
++++ b/iconvdata/iso-2022-jp-3.c
+@@ -67,23 +67,34 @@ enum
+   CURRENT_SEL_MASK = 7 << 3
+ };
+ 
+-/* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the state
+-   also contains the last two bytes to be output, shifted by 6 bits, and a
+-   one-bit indicator whether they must be preceded by the shift sequence,
+-   in bit 22.  */
++/* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the
++   state also contains the last two bytes to be output, shifted by 6
++   bits, and a one-bit indicator whether they must be preceded by the
++   shift sequence, in bit 22.  During ISO-2022-JP-3 to UCS-4
++   conversion, COUNT may also contain a non-zero pending wide
++   character, shifted by six bits.  This happens for certain inputs in
++   JISX0213_1_2004_set and JISX0213_2_set if the second wide character
++   in a combining sequence cannot be written because the buffer is
++   full.  */
+ 
+ /* Since this is a stateful encoding we have to provide code which resets
+    the output state to the initial state.  This has to be done during the
+    flushing.  */
+ #define EMIT_SHIFT_TO_INIT \
+-  if ((data->__statep->__count & ~7) != ASCII_set)			      \
++  if (data->__statep->__count != ASCII_set)			      \
+     {									      \
+       if (FROM_DIRECTION)						      \
+ 	{								      \
+-	  /* It's easy, we don't have to emit anything, we just reset the     \
+-	     state for the input.  */					      \
+-	  data->__statep->__count &= 7;					      \
+-	  data->__statep->__count |= ASCII_set;				      \
++	  if (__glibc_likely (outbuf + 4 <= outend))			      \
++	    {								      \
++	      /* Write out the last character.  */			      \
++	      *((uint32_t *) outbuf) = data->__statep->__count >> 6;	      \
++	      outbuf += sizeof (uint32_t);				      \
++	      data->__statep->__count = ASCII_set;			\
++	    }								      \
++	  else								      \
++	    /* We don't have enough room in the output buffer.  */	      \
++	    status = __GCONV_FULL_OUTPUT;				      \
+ 	}								      \
+       else								      \
+ 	{								      \
+@@ -151,7 +162,21 @@ enum
+ #define LOOPFCT			FROM_LOOP
+ #define BODY \
+   {									      \
+-    uint32_t ch = *inptr;						      \
++    uint32_t ch;							      \
++									      \
++    /* Output any pending character.  */				      \
++    ch = set >> 6;							      \
++    if (__glibc_unlikely (ch != 0))					      \
++      {									      \
++	put32 (outptr, ch);						      \
++	outptr += 4;							      \
++	/* Remove the pending character, but preserve state bits.  */	      \
++	set &= (1 << 6) - 1;						      \
++	continue;							      \
++      }									      \
++									      \
++    /* Otherwise read the next input byte.  */				      \
++    ch = *inptr;							      \
+ 									      \
+     /* Recognize escape sequences.  */					      \
+     if (__glibc_unlikely (ch == ESC))					      \
+@@ -297,21 +322,25 @@ enum
+ 	    uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0];	      \
+ 	    uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1];	      \
+ 									      \
++	    inptr += 2;							      \
++									      \
++	    put32 (outptr, u1);						      \
++	    outptr += 4;						      \
++									      \
+ 	    /* See whether we have room for two characters.  */		      \
+-	    if (outptr + 8 <= outend)					      \
++	    if (outptr + 4 <= outend)					      \
+ 	      {								      \
+-		inptr += 2;						      \
+-		put32 (outptr, u1);					      \
+-		outptr += 4;						      \
+ 		put32 (outptr, u2);					      \
+ 		outptr += 4;						      \
+ 		continue;						      \
+ 	      }								      \
+-	    else							      \
+-	      {								      \
+-		result = __GCONV_FULL_OUTPUT;				      \
+-		break;							      \
+-	      }								      \
++									      \
++	    /* Otherwise store only the first character now, and	      \
++	       put the second one into the queue.  */			      \
++	    set |= u2 << 6;						      \
++	    /* Tell the caller why we terminate the loop.  */		      \
++	    result = __GCONV_FULL_OUTPUT;				      \
++	    break;							      \
+ 	  }								      \
+ 									      \
+ 	inptr += 2;							      \
+diff --git a/iconvdata/ksc5601.h b/iconvdata/ksc5601.h
+index d3eb3a4ff8..f5cdc72797 100644
+--- a/iconvdata/ksc5601.h
++++ b/iconvdata/ksc5601.h
+@@ -50,15 +50,15 @@ ksc5601_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset)
+   unsigned char ch2;
+   int idx;
+ 
++  if (avail < 2)
++    return 0;
++
+   /* row 94(0x7e) and row 41(0x49) are user-defined area in KS C 5601 */
+ 
+   if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) >= 0x7e
+       || (ch - offset) == 0x49)
+     return __UNKNOWN_10646_CHAR;
+ 
+-  if (avail < 2)
+-    return 0;
+-
+   ch2 = (*s)[1];
+   if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f)
+     return __UNKNOWN_10646_CHAR;
 diff --git a/intl/dcigettext.c b/intl/dcigettext.c
 index 2e7c662bc7..bd332e71da 100644
 --- a/intl/dcigettext.c
@@ -237,6 +1005,549 @@ index fd70432eca..e9f6e5e09f 100644
 -#define TEST_FUNCTION do_test ()
 -#include "../test-skeleton.c"
 +#include <support/test-driver.c>
+diff --git a/malloc/Makefile b/malloc/Makefile
+index e22cbde22d..5093e8730e 100644
+--- a/malloc/Makefile
++++ b/malloc/Makefile
+@@ -62,6 +62,16 @@ endif
+ tests += $(tests-static)
+ test-srcs = tst-mtrace
+ 
++# These tests either are run with MALLOC_CHECK_=3 by default or do not work
++# with MALLOC_CHECK_=3 because they expect a specific failure.
++tests-exclude-mcheck = tst-mcheck tst-malloc-usable \
++	tst-interpose-nothread tst-interpose-static-nothread \
++	tst-interpose-static-thread tst-malloc-too-large \
++	tst-mxfast tst-safe-linking
++
++# Run all tests with MALLOC_CHECK_=3
++tests-mcheck = $(filter-out $(tests-exclude-mcheck),$(tests))
++
+ routines = malloc morecore mcheck mtrace obstack reallocarray \
+   scratch_buffer_grow scratch_buffer_grow_preserve \
+   scratch_buffer_set_array_size \
+@@ -100,6 +110,11 @@ $(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
+ $(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
+ $(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library)
+ $(objpfx)tst-malloc-stats-cancellation: $(shared-thread-library)
++$(objpfx)tst-malloc-backtrace-mcheck: $(shared-thread-library)
++$(objpfx)tst-malloc-thread-exit-mcheck: $(shared-thread-library)
++$(objpfx)tst-malloc-thread-fail-mcheck: $(shared-thread-library)
++$(objpfx)tst-malloc-fork-deadlock-mcheck: $(shared-thread-library)
++$(objpfx)tst-malloc-stats-cancellation-mcheck: $(shared-thread-library)
+ 
+ # Export the __malloc_initialize_hook variable to libc.so.
+ LDFLAGS-tst-mallocstate = -rdynamic
+@@ -239,6 +254,8 @@ $(tests:%=$(objpfx)%.o): CPPFLAGS += -DTEST_NO_MALLOPT
+ $(objpfx)tst-interpose-nothread: $(objpfx)tst-interpose-aux-nothread.o
+ $(objpfx)tst-interpose-thread: \
+   $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library)
++$(objpfx)tst-interpose-thread-mcheck: \
++  $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library)
+ $(objpfx)tst-interpose-static-nothread: $(objpfx)tst-interpose-aux-nothread.o
+ $(objpfx)tst-interpose-static-thread: \
+   $(objpfx)tst-interpose-aux-thread.o $(static-thread-library)
+@@ -256,3 +273,6 @@ $(objpfx)tst-dynarray-fail-mem.out: $(objpfx)tst-dynarray-fail.out
+ $(objpfx)tst-malloc-tcache-leak: $(shared-thread-library)
+ $(objpfx)tst-malloc_info: $(shared-thread-library)
+ $(objpfx)tst-mallocfork2: $(shared-thread-library)
++$(objpfx)tst-malloc-tcache-leak-mcheck: $(shared-thread-library)
++$(objpfx)tst-malloc_info-mcheck: $(shared-thread-library)
++$(objpfx)tst-mallocfork2-mcheck: $(shared-thread-library)
+diff --git a/manual/tunables.texi b/manual/tunables.texi
+index 23ef0d40e7..d72d7a5ec0 100644
+--- a/manual/tunables.texi
++++ b/manual/tunables.texi
+@@ -432,7 +432,11 @@ set shared cache size in bytes for use in memory and string routines.
+ 
+ @deftp Tunable glibc.cpu.x86_non_temporal_threshold
+ The @code{glibc.cpu.x86_non_temporal_threshold} tunable allows the user
+-to set threshold in bytes for non temporal store.
++to set threshold in bytes for non temporal store. Non temporal stores
++give a hint to the hardware to move data directly to memory without
++displacing other data from the cache. This tunable is used by some
++platforms to determine when to use non temporal stores in operations
++like memmove and memcpy.
+ 
+ This tunable is specific to i386 and x86-64.
+ @end deftp
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index 19d9cc5cfe..38221d0b2a 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -124,13 +124,10 @@
+ #define __bos0(ptr) __builtin_object_size (ptr, 0)
+ 
+ #if __GNUC_PREREQ (4,3)
+-# define __warndecl(name, msg) \
+-  extern void name (void) __attribute__((__warning__ (msg)))
+ # define __warnattr(msg) __attribute__((__warning__ (msg)))
+ # define __errordecl(name, msg) \
+   extern void name (void) __attribute__((__error__ (msg)))
+ #else
+-# define __warndecl(name, msg) extern void name (void)
+ # define __warnattr(msg)
+ # define __errordecl(name, msg) extern void name (void)
+ #endif
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 88c69d1e9c..381aa721ef 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -248,7 +248,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 					     : NULL);
+ 				    ndomain = (ndomain ? newbuf + ndomaindiff
+ 					       : NULL);
+-				    buffer = newbuf;
++				    *tofreep = buffer = newbuf;
+ 				  }
+ 
+ 				nhost = memcpy (buffer + bufused,
+@@ -319,7 +319,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 		    else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
+ 		      {
+ 			buflen *= 2;
+-			buffer = xrealloc (buffer, buflen);
++			*tofreep = buffer = xrealloc (buffer, buflen);
+ 		      }
+ 		    else if (status == NSS_STATUS_RETURN
+ 			     || status == NSS_STATUS_NOTFOUND
+diff --git a/resolv/Makefile b/resolv/Makefile
+index b61c0c3e0c..dbd8f8bf4f 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -61,6 +61,11 @@ tests += \
+   tst-resolv-search \
+   tst-resolv-trailing \
+ 
++# This test calls __res_context_send directly, which is not exported
++# from libresolv.
++tests-internal += tst-resolv-txnid-collision
++tests-static += tst-resolv-txnid-collision
++
+ # These tests need libdl.
+ ifeq (yes,$(build-shared))
+ tests += \
+@@ -191,6 +196,8 @@ $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-threads: \
+   $(libdl) $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-txnid-collision: $(objpfx)libresolv.a \
++  $(static-thread-library)
+ $(objpfx)tst-resolv-canonname: \
+   $(libdl) $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-trustad: $(objpfx)libresolv.so $(shared-thread-library)
+diff --git a/resolv/res_send.c b/resolv/res_send.c
+index 7e5fec6646..70e5066031 100644
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -1342,15 +1342,6 @@ send_dg(res_state statp,
+ 			*terrno = EMSGSIZE;
+ 			return close_and_return_error (statp, resplen2);
+ 		}
+-		if ((recvresp1 || hp->id != anhp->id)
+-		    && (recvresp2 || hp2->id != anhp->id)) {
+-			/*
+-			 * response from old query, ignore it.
+-			 * XXX - potential security hazard could
+-			 *	 be detected here.
+-			 */
+-			goto wait;
+-		}
+ 
+ 		/* Paranoia check.  Due to the connected UDP socket,
+ 		   the kernel has already filtered invalid addresses
+@@ -1360,15 +1351,24 @@ send_dg(res_state statp,
+ 
+ 		/* Check for the correct header layout and a matching
+ 		   question.  */
+-		if ((recvresp1 || !res_queriesmatch(buf, buf + buflen,
+-						       *thisansp,
+-						       *thisansp
+-						       + *thisanssizp))
+-		    && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2,
+-						       *thisansp,
+-						       *thisansp
+-						       + *thisanssizp)))
+-		  goto wait;
++		int matching_query = 0; /* Default to no matching query.  */
++		if (!recvresp1
++		    && anhp->id == hp->id
++		    && res_queriesmatch (buf, buf + buflen,
++					 *thisansp, *thisansp + *thisanssizp))
++		  matching_query = 1;
++		if (!recvresp2
++		    && anhp->id == hp2->id
++		    && res_queriesmatch (buf2, buf2 + buflen2,
++					 *thisansp, *thisansp + *thisanssizp))
++		  matching_query = 2;
++		if (matching_query == 0)
++		  /* Spurious UDP packet.  Drop it and continue
++		     waiting.  */
++		  {
++		    need_recompute = 1;
++		    goto wait;
++		  }
+ 
+ 		if (anhp->rcode == SERVFAIL ||
+ 		    anhp->rcode == NOTIMP ||
+@@ -1383,7 +1383,7 @@ send_dg(res_state statp,
+ 			    /* No data from the first reply.  */
+ 			    resplen = 0;
+ 			    /* We are waiting for a possible second reply.  */
+-			    if (hp->id == anhp->id)
++			    if (matching_query == 1)
+ 			      recvresp1 = 1;
+ 			    else
+ 			      recvresp2 = 1;
+@@ -1414,7 +1414,7 @@ send_dg(res_state statp,
+ 			return (1);
+ 		}
+ 		/* Mark which reply we received.  */
+-		if (recvresp1 == 0 && hp->id == anhp->id)
++		if (matching_query == 1)
+ 			recvresp1 = 1;
+ 		else
+ 			recvresp2 = 1;
+diff --git a/resolv/tst-resolv-txnid-collision.c b/resolv/tst-resolv-txnid-collision.c
+new file mode 100644
+index 0000000000..189b76f126
+--- /dev/null
++++ b/resolv/tst-resolv-txnid-collision.c
+@@ -0,0 +1,334 @@
++/* Test parallel queries with transaction ID collisions.
++   Copyright (C) 2020 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <arpa/nameser.h>
++#include <array_length.h>
++#include <resolv-internal.h>
++#include <resolv_context.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++#include <support/test-driver.h>
++
++/* Result of parsing a DNS question name.
++
++   A question name has the form reorder-N-M-rcode-C.example.net, where
++   N and M are either 0 and 1, corresponding to the reorder member,
++   and C is a number that will be stored in the rcode field.
++
++   Also see parse_qname below.  */
++struct parsed_qname
++{
++  /* The DNS response code requested from the first server.  The
++     second server always responds with RCODE zero.  */
++  int rcode;
++
++  /* Indicates whether to perform reordering in the responses from the
++     respective server.  */
++  bool reorder[2];
++};
++
++/* Fills *PARSED based on QNAME.  */
++static void
++parse_qname (struct parsed_qname *parsed, const char *qname)
++{
++  int reorder0;
++  int reorder1;
++  int rcode;
++  char *suffix;
++  if (sscanf (qname, "reorder-%d-%d.rcode-%d.%ms",
++              &reorder0, &reorder1, &rcode, &suffix) == 4)
++    {
++      if (reorder0 != 0)
++        TEST_COMPARE (reorder0, 1);
++      if (reorder1 != 0)
++        TEST_COMPARE (reorder1, 1);
++      TEST_VERIFY (rcode >= 0 && rcode <= 15);
++      TEST_COMPARE_STRING (suffix, "example.net");
++      free (suffix);
++
++      parsed->rcode = rcode;
++      parsed->reorder[0] = reorder0;
++      parsed->reorder[1] = reorder1;
++    }
++  else
++    FAIL_EXIT1 ("unexpected query: %s", qname);
++}
++
++/* Used to construct a response. The first server responds with an
++   error, the second server succeeds.  */
++static void
++build_response (const struct resolv_response_context *ctx,
++                struct resolv_response_builder *b,
++                const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  struct parsed_qname parsed;
++  parse_qname (&parsed, qname);
++
++  switch (ctx->server_index)
++    {
++    case 0:
++      {
++        struct resolv_response_flags flags = { 0 };
++        if (parsed.rcode == 0)
++          /* Simulate a delegation in case a NODATA (RCODE zero)
++             response is requested.  */
++          flags.clear_ra = true;
++        else
++          flags.rcode = parsed.rcode;
++
++        resolv_response_init (b, flags);
++        resolv_response_add_question (b, qname, qclass, qtype);
++      }
++      break;
++
++    case 1:
++      {
++        struct resolv_response_flags flags = { 0, };
++        resolv_response_init (b, flags);
++        resolv_response_add_question (b, qname, qclass, qtype);
++
++        resolv_response_section (b, ns_s_an);
++        resolv_response_open_record (b, qname, qclass, qtype, 0);
++        if (qtype == T_A)
++          {
++            char ipv4[4] = { 192, 0, 2, 1 };
++            resolv_response_add_data (b, &ipv4, sizeof (ipv4));
++          }
++        else
++          {
++            char ipv6[16]
++              = { 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
++            resolv_response_add_data (b, &ipv6, sizeof (ipv6));
++          }
++        resolv_response_close_record (b);
++      }
++      break;
++    }
++}
++
++/* Used to reorder responses.  */
++struct resolv_response_context *previous_query;
++
++/* Used to keep track of the queries received.  */
++static int previous_server_index = -1;
++static uint16_t previous_qtype;
++
++/* For each server, buffer the first query and then send both answers
++   to the second query, reordered if requested.  */
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  TEST_VERIFY (qtype == T_A || qtype == T_AAAA);
++  if (ctx->server_index != 0)
++    TEST_COMPARE (ctx->server_index, 1);
++
++  struct parsed_qname parsed;
++  parse_qname (&parsed, qname);
++
++  if (previous_query == NULL)
++    {
++      /* No buffered query.  Record this query and do not send a
++         response.  */
++      TEST_COMPARE (previous_qtype, 0);
++      previous_query = resolv_response_context_duplicate (ctx);
++      previous_qtype = qtype;
++      resolv_response_drop (b);
++      previous_server_index = ctx->server_index;
++
++      if (test_verbose)
++        printf ("info: buffering first query for: %s\n", qname);
++    }
++  else
++    {
++      TEST_VERIFY (previous_query != 0);
++      TEST_COMPARE (ctx->server_index, previous_server_index);
++      TEST_VERIFY (previous_qtype != qtype); /* Not a duplicate.  */
++
++      /* If reordering, send a response for this query explicitly, and
++         then skip the implicit send.  */
++      if (parsed.reorder[ctx->server_index])
++        {
++          if (test_verbose)
++            printf ("info: sending reordered second response for: %s\n",
++                    qname);
++          build_response (ctx, b, qname, qclass, qtype);
++          resolv_response_send_udp (ctx, b);
++          resolv_response_drop (b);
++        }
++
++      /* Build a response for the previous query and send it, thus
++         reordering the two responses.  */
++      {
++        if (test_verbose)
++          printf ("info: sending first response for: %s\n", qname);
++        struct resolv_response_builder *btmp
++          = resolv_response_builder_allocate (previous_query->query_buffer,
++                                              previous_query->query_length);
++        build_response (ctx, btmp, qname, qclass, previous_qtype);
++        resolv_response_send_udp (ctx, btmp);
++        resolv_response_builder_free (btmp);
++      }
++
++      /* If not reordering, send the reply as usual.  */
++      if (!parsed.reorder[ctx->server_index])
++        {
++          if (test_verbose)
++            printf ("info: sending non-reordered second response for: %s\n",
++                    qname);
++          build_response (ctx, b, qname, qclass, qtype);
++        }
++
++      /* Unbuffer the response and prepare for the next query.  */
++      resolv_response_context_free (previous_query);
++      previous_query = NULL;
++      previous_qtype = 0;
++      previous_server_index = -1;
++    }
++}
++
++/* Runs a query for QNAME and checks for the expected reply.  See
++   struct parsed_qname for the expected format for QNAME.  */
++static void
++test_qname (const char *qname, int rcode)
++{
++  struct resolv_context *ctx = __resolv_context_get ();
++  TEST_VERIFY_EXIT (ctx != NULL);
++
++  unsigned char q1[512];
++  int q1len = res_mkquery (QUERY, qname, C_IN, T_A, NULL, 0, NULL,
++                           q1, sizeof (q1));
++  TEST_VERIFY_EXIT (q1len > 12);
++
++  unsigned char q2[512];
++  int q2len = res_mkquery (QUERY, qname, C_IN, T_AAAA, NULL, 0, NULL,
++                           q2, sizeof (q2));
++  TEST_VERIFY_EXIT (q2len > 12);
++
++  /* Produce a transaction ID collision.  */
++  memcpy (q2, q1, 2);
++
++  unsigned char ans1[512];
++  unsigned char *ans1p = ans1;
++  unsigned char *ans2p = NULL;
++  int nans2p = 0;
++  int resplen2 = 0;
++  int ans2p_malloced = 0;
++
++  /* Perform a parallel A/AAAA query.  */
++  int resplen1 = __res_context_send (ctx, q1, q1len, q2, q2len,
++                                     ans1, sizeof (ans1), &ans1p,
++                                     &ans2p, &nans2p,
++                                     &resplen2, &ans2p_malloced);
++
++  TEST_VERIFY (resplen1 > 12);
++  TEST_VERIFY (resplen2 > 12);
++  if (resplen1 <= 12 || resplen2 <= 12)
++    return;
++
++  if (rcode == 1 || rcode == 3)
++    {
++      /* Format Error and Name Error responses does not trigger
++         switching to the next server.  */
++      TEST_COMPARE (ans1p[3] & 0x0f, rcode);
++      TEST_COMPARE (ans2p[3] & 0x0f, rcode);
++      return;
++    }
++
++  /* The response should be successful.  */
++  TEST_COMPARE (ans1p[3] & 0x0f, 0);
++  TEST_COMPARE (ans2p[3] & 0x0f, 0);
++
++  /* Due to bug 19691, the answer may not be in the slot matching the
++     query.  Assume that the AAAA response is the longer one.  */
++  unsigned char *a_answer;
++  int a_answer_length;
++  unsigned char *aaaa_answer;
++  int aaaa_answer_length;
++  if (resplen2 > resplen1)
++    {
++      a_answer = ans1p;
++      a_answer_length = resplen1;
++      aaaa_answer = ans2p;
++      aaaa_answer_length = resplen2;
++    }
++  else
++    {
++      a_answer = ans2p;
++      a_answer_length = resplen2;
++      aaaa_answer = ans1p;
++      aaaa_answer_length = resplen1;
++    }
++
++  {
++    char *expected = xasprintf ("name: %s\n"
++                                "address: 192.0.2.1\n",
++                                qname);
++    check_dns_packet (qname, a_answer, a_answer_length, expected);
++    free (expected);
++  }
++  {
++    char *expected = xasprintf ("name: %s\n"
++                                "address: 2001:db8::1\n",
++                                qname);
++    check_dns_packet (qname, aaaa_answer, aaaa_answer_length, expected);
++    free (expected);
++  }
++
++  if (ans2p_malloced)
++    free (ans2p);
++
++  __resolv_context_put (ctx);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *aux = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response,
++
++       /* The response callback use global state (the previous_*
++          variables), and query processing must therefore be
++          serialized.  */
++       .single_thread_udp = true,
++     });
++
++  for (int rcode = 0; rcode <= 5; ++rcode)
++    for (int do_reorder_0 = 0; do_reorder_0 < 2; ++do_reorder_0)
++      for (int do_reorder_1 = 0; do_reorder_1 < 2; ++do_reorder_1)
++        {
++          char *qname = xasprintf ("reorder-%d-%d.rcode-%d.example.net",
++                                   do_reorder_0, do_reorder_1, rcode);
++          test_qname (qname, rcode);
++          free (qname);
++        }
++
++  resolv_test_end (aux);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
 diff --git a/stdio-common/Makefile b/stdio-common/Makefile
 index 8475fd1f09..eff0c98d82 100644
 --- a/stdio-common/Makefile
@@ -1002,8 +2313,609 @@ index fded208118..d77b81d507 100644
 +  TEST_COMPARE_STRING (strerrorname_np (EPROGUNAVAIL), "EPROGUNAVAIL");
 +#endif
  
-   return 0;
+   return 0;
+ }
+diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
+index 95b46dcbeb..3a323547f9 100644
+--- a/stdio-common/vfscanf-internal.c
++++ b/stdio-common/vfscanf-internal.c
+@@ -277,7 +277,7 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
+ #endif
+ {
+   va_list arg;
+-  const CHAR_T *f = format;
++  const UCHAR_T *f = (const UCHAR_T *) format;
+   UCHAR_T fc;	/* Current character of the format.  */
+   WINT_T done = 0;	/* Assignments done.  */
+   size_t read_in = 0;	/* Chars read in.  */
+@@ -415,10 +415,11 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
+ #endif
+ 
+ #ifndef COMPILE_WSCANF
+-      if (!isascii ((unsigned char) *f))
++      if (!isascii (*f))
+ 	{
+ 	  /* Non-ASCII, may be a multibyte.  */
+-	  int len = __mbrlen (f, strlen (f), &state);
++	  int len = __mbrlen ((const char *) f, strlen ((const char *) f),
++			      &state);
+ 	  if (len > 0)
+ 	    {
+ 	      do
+@@ -426,7 +427,7 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
+ 		  c = inchar ();
+ 		  if (__glibc_unlikely (c == EOF))
+ 		    input_error ();
+-		  else if (c != (unsigned char) *f++)
++		  else if (c != *f++)
+ 		    {
+ 		      ungetc_not_eof (c, s);
+ 		      conv_error ();
+@@ -484,9 +485,9 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
+       char_buffer_rewind (&charbuf);
+ 
+       /* Check for a positional parameter specification.  */
+-      if (ISDIGIT ((UCHAR_T) *f))
++      if (ISDIGIT (*f))
+ 	{
+-	  argpos = read_int ((const UCHAR_T **) &f);
++	  argpos = read_int (&f);
+ 	  if (*f == L_('$'))
+ 	    ++f;
+ 	  else
+@@ -521,8 +522,8 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
+ 
+       /* Find the maximum field width.  */
+       width = 0;
+-      if (ISDIGIT ((UCHAR_T) *f))
+-	width = read_int ((const UCHAR_T **) &f);
++      if (ISDIGIT (*f))
++	width = read_int (&f);
+     got_width:
+       if (width == 0)
+ 	width = -1;
+@@ -2522,12 +2523,11 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
+ 	    }
+ 
+ 	  while ((fc = *f++) != '\0' && fc != ']')
+-	    if (fc == '-' && *f != '\0' && *f != ']'
+-		&& (unsigned char) f[-2] <= (unsigned char) *f)
++	    if (fc == '-' && *f != '\0' && *f != ']' && f[-2] <= *f)
+ 	      {
+ 		/* Add all characters from the one before the '-'
+ 		   up to (but not including) the next format char.  */
+-		for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
++		for (fc = f[-2]; fc < *f; ++fc)
+ 		  ((char *)charbuf.scratch.data)[fc] = 1;
+ 	      }
+ 	    else
+diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
+index 309d0f39b2..c8d3051af8 100644
+--- a/string/bits/string_fortified.h
++++ b/string/bits/string_fortified.h
+@@ -22,11 +22,6 @@
+ # error "Never use <bits/string_fortified.h> directly; include <string.h> instead."
+ #endif
+ 
+-#if !__GNUC_PREREQ (5,0)
+-__warndecl (__warn_memset_zero_len,
+-	    "memset used with constant zero length parameter; this could be due to transposed parameters");
+-#endif
+-
+ __fortify_function void *
+ __NTH (memcpy (void *__restrict __dest, const void *__restrict __src,
+ 	       size_t __len))
+@@ -58,16 +53,6 @@ __NTH (mempcpy (void *__restrict __dest, const void *__restrict __src,
+ __fortify_function void *
+ __NTH (memset (void *__dest, int __ch, size_t __len))
+ {
+-  /* GCC-5.0 and newer implements these checks in the compiler, so we don't
+-     need them here.  */
+-#if !__GNUC_PREREQ (5,0)
+-  if (__builtin_constant_p (__len) && __len == 0
+-      && (!__builtin_constant_p (__ch) || __ch != 0))
+-    {
+-      __warn_memset_zero_len ();
+-      return __dest;
+-    }
+-#endif
+   return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
+ }
+ 
+diff --git a/support/Makefile b/support/Makefile
+index 93faafddf9..4154863511 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -35,6 +35,8 @@ libsupport-routines = \
+   ignore_stderr \
+   next_to_fault \
+   oom_error \
++  resolv_response_context_duplicate \
++  resolv_response_context_free \
+   resolv_test \
+   set_fortify_handler \
+   support-xfstat \
+diff --git a/support/resolv_response_context_duplicate.c b/support/resolv_response_context_duplicate.c
+new file mode 100644
+index 0000000000..f9c5c3462a
+--- /dev/null
++++ b/support/resolv_response_context_duplicate.c
+@@ -0,0 +1,37 @@
++/* Duplicate a response context used in DNS resolver tests.
++   Copyright (C) 2020 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <string.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++struct resolv_response_context *
++resolv_response_context_duplicate (const struct resolv_response_context *ctx)
++{
++  struct resolv_response_context *result = xmalloc (sizeof (*result));
++  memcpy (result, ctx, sizeof (*result));
++  if (result->client_address != NULL)
++    {
++      result->client_address = xmalloc (result->client_address_length);
++      memcpy (result->client_address, ctx->client_address,
++              result->client_address_length);
++    }
++  result->query_buffer = xmalloc (result->query_length);
++  memcpy (result->query_buffer, ctx->query_buffer, result->query_length);
++  return result;
++}
+diff --git a/support/resolv_response_context_free.c b/support/resolv_response_context_free.c
+new file mode 100644
+index 0000000000..b88c05ffd4
+--- /dev/null
++++ b/support/resolv_response_context_free.c
+@@ -0,0 +1,28 @@
++/* Free a response context used in DNS resolver tests.
++   Copyright (C) 2020 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <stdlib.h>
++#include <support/resolv_test.h>
++
++void
++resolv_response_context_free (struct resolv_response_context *ctx)
++{
++  free (ctx->query_buffer);
++  free (ctx->client_address);
++  free (ctx);
++}
+diff --git a/support/resolv_test.c b/support/resolv_test.c
+index 53b7fc41ab..9878a040a3 100644
+--- a/support/resolv_test.c
++++ b/support/resolv_test.c
+@@ -181,7 +181,9 @@ resolv_response_init (struct resolv_response_builder *b,
+   b->buffer[2] |= b->query_buffer[2] & 0x01; /* Copy the RD bit.  */
+   if (flags.tc)
+     b->buffer[2] |= 0x02;
+-  b->buffer[3] = 0x80 | flags.rcode; /* Always set RA.  */
++  b->buffer[3] = flags.rcode;
++  if (!flags.clear_ra)
++    b->buffer[3] |= 0x80;
+   if (flags.ad)
+     b->buffer[3] |= 0x20;
+ 
+@@ -434,9 +436,9 @@ resolv_response_buffer (const struct resolv_response_builder *b)
+   return result;
+ }
+ 
+-static struct resolv_response_builder *
+-response_builder_allocate
+-  (const unsigned char *query_buffer, size_t query_length)
++struct resolv_response_builder *
++resolv_response_builder_allocate (const unsigned char *query_buffer,
++                                  size_t query_length)
+ {
+   struct resolv_response_builder *b = xmalloc (sizeof (*b));
+   memset (b, 0, offsetof (struct resolv_response_builder, buffer));
+@@ -445,8 +447,8 @@ response_builder_allocate
+   return b;
+ }
+ 
+-static void
+-response_builder_free (struct resolv_response_builder *b)
++void
++resolv_response_builder_free (struct resolv_response_builder *b)
+ {
+   tdestroy (b->compression_offsets, free);
+   free (b);
+@@ -661,13 +663,17 @@ server_thread_udp_process_one (struct resolv_test *obj, int server_index)
+ 
+   struct resolv_response_context ctx =
+     {
++      .test = obj,
++      .client_address = &peer,
++      .client_address_length = peerlen,
+       .query_buffer = query,
+       .query_length = length,
+       .server_index = server_index,
+       .tcp = false,
+       .edns = qinfo.edns,
+     };
+-  struct resolv_response_builder *b = response_builder_allocate (query, length);
++  struct resolv_response_builder *b
++    = resolv_response_builder_allocate (query, length);
+   obj->config.response_callback
+     (&ctx, b, qinfo.qname, qinfo.qclass, qinfo.qtype);
+ 
+@@ -684,7 +690,7 @@ server_thread_udp_process_one (struct resolv_test *obj, int server_index)
+           if (b->offset >= 12)
+             printf ("info: UDP server %d: sending response:"
+                     " %zu bytes, RCODE %d (for %s/%u/%u)\n",
+-                    server_index, b->offset, b->buffer[3] & 0x0f,
++                    ctx.server_index, b->offset, b->buffer[3] & 0x0f,
+                     qinfo.qname, qinfo.qclass, qinfo.qtype);
+           else
+             printf ("info: UDP server %d: sending response: %zu bytes"
+@@ -694,23 +700,31 @@ server_thread_udp_process_one (struct resolv_test *obj, int server_index)
+           if (b->truncate_bytes > 0)
+             printf ("info:    truncated by %u bytes\n", b->truncate_bytes);
+         }
+-      size_t to_send = b->offset;
+-      if (to_send < b->truncate_bytes)
+-        to_send = 0;
+-      else
+-        to_send -= b->truncate_bytes;
+-
+-      /* Ignore most errors here because the other end may have closed
+-         the socket. */
+-      if (sendto (obj->servers[server_index].socket_udp,
+-                  b->buffer, to_send, 0,
+-                  (struct sockaddr *) &peer, peerlen) < 0)
+-        TEST_VERIFY_EXIT (errno != EBADF);
++      resolv_response_send_udp (&ctx, b);
+     }
+-  response_builder_free (b);
++  resolv_response_builder_free (b);
+   return true;
+ }
+ 
++void
++resolv_response_send_udp (const struct resolv_response_context *ctx,
++                          struct resolv_response_builder *b)
++{
++  TEST_VERIFY_EXIT (!ctx->tcp);
++  size_t to_send = b->offset;
++  if (to_send < b->truncate_bytes)
++    to_send = 0;
++  else
++    to_send -= b->truncate_bytes;
++
++  /* Ignore most errors here because the other end may have closed
++     the socket.  */
++  if (sendto (ctx->test->servers[ctx->server_index].socket_udp,
++              b->buffer, to_send, 0,
++              ctx->client_address, ctx->client_address_length) < 0)
++    TEST_VERIFY_EXIT (errno != EBADF);
++}
++
+ /* UDP thread_callback function.  Variant for one thread per
+    server.  */
+ static void
+@@ -897,14 +911,15 @@ server_thread_tcp_client (void *arg)
+ 
+       struct resolv_response_context ctx =
+         {
++          .test = closure->obj,
+           .query_buffer = query_buffer,
+           .query_length = query_length,
+           .server_index = closure->server_index,
+           .tcp = true,
+           .edns = qinfo.edns,
+         };
+-      struct resolv_response_builder *b = response_builder_allocate
+-        (query_buffer, query_length);
++      struct resolv_response_builder *b
++        = resolv_response_builder_allocate (query_buffer, query_length);
+       closure->obj->config.response_callback
+         (&ctx, b, qinfo.qname, qinfo.qclass, qinfo.qtype);
+ 
+@@ -936,7 +951,7 @@ server_thread_tcp_client (void *arg)
+           writev_fully (closure->client_socket, buffers, 2);
+         }
+       bool close_flag = b->close;
+-      response_builder_free (b);
++      resolv_response_builder_free (b);
+       free (query_buffer);
+       if (close_flag)
+         break;
+diff --git a/support/resolv_test.h b/support/resolv_test.h
+index 67819469a0..31a5c1c3e7 100644
+--- a/support/resolv_test.h
++++ b/support/resolv_test.h
+@@ -35,25 +35,36 @@ struct resolv_edns_info
+   uint16_t payload_size;
+ };
+ 
++/* This opaque struct collects information about the resolver testing
++   currently in progress.  */
++struct resolv_test;
++
+ /* This struct provides context information when the response callback
+    specified in struct resolv_redirect_config is invoked. */
+ struct resolv_response_context
+ {
+-  const unsigned char *query_buffer;
++  struct resolv_test *test;
++  void *client_address;
++  size_t client_address_length;
++  unsigned char *query_buffer;
+   size_t query_length;
+   int server_index;
+   bool tcp;
+   struct resolv_edns_info edns;
+ };
+ 
++/* Produces a deep copy of the context.  */
++struct resolv_response_context *
++  resolv_response_context_duplicate (const struct resolv_response_context *);
++
++/* Frees the copy.  For the context passed to the response function,
++   this happens implicitly.  */
++void resolv_response_context_free (struct resolv_response_context *);
++
+ /* This opaque struct is used to construct responses from within the
+    response callback function.  */
+ struct resolv_response_builder;
+ 
+-/* This opaque struct collects information about the resolver testing
+-   currently in progress.  */
+-struct resolv_test;
+-
+ enum
+   {
+     /* Maximum number of test servers supported by the framework.  */
+@@ -137,6 +148,10 @@ struct resolv_response_flags
+   /* If true, the AD (authenticated data) flag will be set.  */
+   bool ad;
+ 
++  /* If true, do not set the RA (recursion available) flag in the
++     response.  */
++  bool clear_ra;
++
+   /* Initial section count values.  Can be used to artificially
+      increase the counts, for malformed packet testing.*/
+   unsigned short qdcount;
+@@ -188,6 +203,22 @@ void resolv_response_close (struct resolv_response_builder *);
+ /* The size of the response packet built so far.  */
+ size_t resolv_response_length (const struct resolv_response_builder *);
+ 
++/* Allocates a response builder tied to a specific query packet,
++   starting at QUERY_BUFFER, containing QUERY_LENGTH bytes.  */
++struct resolv_response_builder *
++  resolv_response_builder_allocate (const unsigned char *query_buffer,
++                                    size_t query_length);
++
++/* Deallocates a response buffer.  */
++void resolv_response_builder_free (struct resolv_response_builder *);
++
++/* Sends a UDP response using a specific context.  This can be used to
++   reorder or duplicate responses, along with
++   resolv_response_context_duplicate and
++   response_builder_allocate.  */
++void resolv_response_send_udp (const struct resolv_response_context *,
++                               struct resolv_response_builder *);
++
+ __END_DECLS
+ 
+ #endif /* SUPPORT_RESOLV_TEST_H */
+diff --git a/sysdeps/aarch64/dl-bti.c b/sysdeps/aarch64/dl-bti.c
+index 196e462520..cf7624aaa2 100644
+--- a/sysdeps/aarch64/dl-bti.c
++++ b/sysdeps/aarch64/dl-bti.c
+@@ -19,43 +19,76 @@
+ #include <errno.h>
+ #include <libintl.h>
+ #include <ldsodefs.h>
++#include <sys/mman.h>
+ 
+-static int
+-enable_bti (struct link_map *map, const char *program)
++/* See elf/dl-load.h.  */
++#ifndef MAP_COPY
++# define MAP_COPY (MAP_PRIVATE | MAP_DENYWRITE)
++#endif
++
++/* Enable BTI protection for MAP.  */
++
++void
++_dl_bti_protect (struct link_map *map, int fd)
+ {
++  const size_t pagesz = GLRO(dl_pagesize);
+   const ElfW(Phdr) *phdr;
+-  unsigned prot;
+ 
+   for (phdr = map->l_phdr; phdr < &map->l_phdr[map->l_phnum]; ++phdr)
+     if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
+       {
+-	void *start = (void *) (phdr->p_vaddr + map->l_addr);
+-	size_t len = phdr->p_memsz;
++	size_t vstart = ALIGN_DOWN (phdr->p_vaddr, pagesz);
++	size_t vend = ALIGN_UP (phdr->p_vaddr + phdr->p_filesz, pagesz);
++	off_t off = ALIGN_DOWN (phdr->p_offset, pagesz);
++	void *start = (void *) (vstart + map->l_addr);
++	size_t len = vend - vstart;
+ 
+-	prot = PROT_EXEC | PROT_BTI;
++	unsigned prot = PROT_EXEC | PROT_BTI;
+ 	if (phdr->p_flags & PF_R)
+ 	  prot |= PROT_READ;
+ 	if (phdr->p_flags & PF_W)
+ 	  prot |= PROT_WRITE;
+ 
+-	if (__mprotect (start, len, prot) < 0)
+-	  {
+-	    if (program)
+-	      _dl_fatal_printf ("%s: mprotect failed to turn on BTI\n",
+-				map->l_name);
+-	    else
+-	      _dl_signal_error (errno, map->l_name, "dlopen",
+-				N_("mprotect failed to turn on BTI"));
+-	  }
++	if (fd == -1)
++	  /* Ignore failures for kernel mapped binaries.  */
++	  __mprotect (start, len, prot);
++	else
++	  map->l_mach.bti_fail = __mmap (start, len, prot,
++					 MAP_FIXED|MAP_COPY|MAP_FILE,
++					 fd, off) == MAP_FAILED;
+       }
+-  return 0;
+ }
+ 
+-/* Enable BTI for L if required.  */
++
++static void
++bti_failed (struct link_map *l, const char *program)
++{
++  if (program)
++    _dl_fatal_printf ("%s: %s: failed to turn on BTI protection\n",
++		      program, l->l_name);
++  else
++    /* Note: the errno value is not available any more.  */
++    _dl_signal_error (0, l->l_name, "dlopen",
++		      N_("failed to turn on BTI protection"));
++}
++
++
++/* Enable BTI for L and its dependencies.  */
+ 
+ void
+ _dl_bti_check (struct link_map *l, const char *program)
+ {
+-  if (GLRO(dl_aarch64_cpu_features).bti && l->l_mach.bti)
+-    enable_bti (l, program);
++  if (!GLRO(dl_aarch64_cpu_features).bti)
++    return;
++
++  if (l->l_mach.bti_fail)
++    bti_failed (l, program);
++
++  unsigned int i = l->l_searchlist.r_nlist;
++  while (i-- > 0)
++    {
++      struct link_map *dep = l->l_initfini[i];
++      if (dep->l_mach.bti_fail)
++	bti_failed (dep, program);
++    }
+ }
+diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
+index 70b9ed3925..fde7cfd9e2 100644
+--- a/sysdeps/aarch64/dl-machine.h
++++ b/sysdeps/aarch64/dl-machine.h
+@@ -395,13 +395,6 @@ elf_machine_lazy_rel (struct link_map *map,
+   /* Check for unexpected PLT reloc type.  */
+   if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1))
+     {
+-      if (map->l_mach.plt == 0)
+-	{
+-	  /* Prelinking.  */
+-	  *reloc_addr += l_addr;
+-	  return;
+-	}
+-
+       if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL))
+ 	{
+ 	  /* Check the symbol table for variant PCS symbols.  */
+@@ -425,7 +418,10 @@ elf_machine_lazy_rel (struct link_map *map,
+ 	    }
+ 	}
+ 
+-      *reloc_addr = map->l_mach.plt;
++      if (map->l_mach.plt == 0)
++	*reloc_addr += l_addr;
++      else
++	*reloc_addr = map->l_mach.plt;
+     }
+   else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1))
+     {
+diff --git a/sysdeps/aarch64/dl-prop.h b/sysdeps/aarch64/dl-prop.h
+index b0785bda83..e926e54984 100644
+--- a/sysdeps/aarch64/dl-prop.h
++++ b/sysdeps/aarch64/dl-prop.h
+@@ -19,6 +19,8 @@
+ #ifndef _DL_PROP_H
+ #define _DL_PROP_H
+ 
++extern void _dl_bti_protect (struct link_map *, int) attribute_hidden;
++
+ extern void _dl_bti_check (struct link_map *, const char *)
+     attribute_hidden;
+ 
+@@ -35,14 +37,18 @@ _dl_open_check (struct link_map *m)
+ }
+ 
+ static inline void __attribute__ ((always_inline))
+-_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
++_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+ {
  }
+ 
+ static inline int
+-_dl_process_gnu_property (struct link_map *l, uint32_t type, uint32_t datasz,
+-			  void *data)
++_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
++			  uint32_t datasz, void *data)
+ {
++  if (!GLRO(dl_aarch64_cpu_features).bti)
++    /* Skip note processing.  */
++    return 0;
++
+   if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
+     {
+       /* Stop if the property note is ill-formed.  */
+@@ -51,7 +57,7 @@ _dl_process_gnu_property (struct link_map *l, uint32_t type, uint32_t datasz,
+ 
+       unsigned int feature_1 = *(unsigned int *) data;
+       if (feature_1 & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
+-	l->l_mach.bti = true;
++	_dl_bti_protect (l, fd);
+ 
+       /* Stop if we processed the property note.  */
+       return 0;
+diff --git a/sysdeps/aarch64/linkmap.h b/sysdeps/aarch64/linkmap.h
+index 847a03ace2..b3f7663b07 100644
+--- a/sysdeps/aarch64/linkmap.h
++++ b/sysdeps/aarch64/linkmap.h
+@@ -22,5 +22,5 @@ struct link_map_machine
+ {
+   ElfW(Addr) plt;	  /* Address of .plt */
+   void *tlsdesc_table;	  /* Address of TLS descriptor hash table.  */
+-  bool bti;		  /* Branch Target Identification is enabled.  */
++  bool bti_fail;	  /* Failed to enable Branch Target Identification.  */
+ };
 diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
 index 7cf5f033e8..799d60c98c 100644
 --- a/sysdeps/aarch64/multiarch/memcpy.c
@@ -1053,6 +2965,109 @@ index ad10aa8ac6..46a4cb3a54 100644
  		     ? __memmove_simd
  		     : __memmove_generic)))));
  
+diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
+index 75393e1c18..1998ea95d4 100644
+--- a/sysdeps/aarch64/start.S
++++ b/sysdeps/aarch64/start.S
+@@ -43,11 +43,9 @@
+  */
+ 
+ 	.text
+-	.globl _start
+-	.type _start,#function
+-_start:
+-	BTI_C
++ENTRY(_start)
+ 	/* Create an initial frame with 0 LR and FP */
++	cfi_undefined (x30)
+ 	mov	x29, #0
+ 	mov	x30, #0
+ 
+@@ -101,8 +99,10 @@ _start:
+ 	   because crt1.o and rcrt1.o share code and the later must avoid the
+ 	   use of GOT relocations before __libc_start_main is called.  */
+ __wrap_main:
++	BTI_C
+ 	b	main
+ #endif
++END(_start)
+ 
+ 	/* Define a symbol for the first piece of initialized data.  */
+ 	.data
+diff --git a/sysdeps/generic/dl-prop.h b/sysdeps/generic/dl-prop.h
+index f1cf576fe3..df27ff8e6a 100644
+--- a/sysdeps/generic/dl-prop.h
++++ b/sysdeps/generic/dl-prop.h
+@@ -37,15 +37,15 @@ _dl_open_check (struct link_map *m)
+ }
+ 
+ static inline void __attribute__ ((always_inline))
+-_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
++_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+ {
+ }
+ 
+ /* Called for each property in the NT_GNU_PROPERTY_TYPE_0 note of L,
+    processing of the properties continues until this returns 0.  */
+ static inline int __attribute__ ((always_inline))
+-_dl_process_gnu_property (struct link_map *l, uint32_t type, uint32_t datasz,
+-			  void *data)
++_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
++			  uint32_t datasz, void *data)
+ {
+   return 0;
+ }
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index ba114ab4b1..62ac40d81b 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -919,8 +919,9 @@ extern void _dl_rtld_di_serinfo (struct link_map *loader,
+ 				 Dl_serinfo *si, bool counting);
+ 
+ /* Process PT_GNU_PROPERTY program header PH in module L after
+-   PT_LOAD segments are mapped.  */
+-void _dl_process_pt_gnu_property (struct link_map *l, const ElfW(Phdr) *ph);
++   PT_LOAD segments are mapped from file FD.  */
++void _dl_process_pt_gnu_property (struct link_map *l, int fd,
++				  const ElfW(Phdr) *ph);
+ 
+ 
+ /* Search loaded objects' symbol tables for a definition of the symbol
+diff --git a/sysdeps/generic/unwind.h b/sysdeps/generic/unwind.h
+index b667a5b652..c229603af3 100644
+--- a/sysdeps/generic/unwind.h
++++ b/sysdeps/generic/unwind.h
+@@ -75,15 +75,21 @@ typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
+ 
+ struct _Unwind_Exception
+ {
+-  _Unwind_Exception_Class exception_class;
+-  _Unwind_Exception_Cleanup_Fn exception_cleanup;
+-  _Unwind_Word private_1;
+-  _Unwind_Word private_2;
+-
+-  /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
+-     Taking that literally does not make much sense generically.  Instead we
+-     provide the maximum alignment required by any type for the machine.  */
+-} __attribute__((__aligned__));
++  union
++  {
++    struct
++    {
++      _Unwind_Exception_Class exception_class;
++      _Unwind_Exception_Cleanup_Fn exception_cleanup;
++      _Unwind_Word private_1;
++      _Unwind_Word private_2;
++    };
++
++    /* The IA-64 ABI says that this structure must be double-word aligned.  */
++    _Unwind_Word unwind_exception_align[2]
++      __attribute__ ((__aligned__ (2 * sizeof (_Unwind_Word))));
++  };
++};
+ 
+ 
+ /* The ACTIONS argument to the personality routine is a bitwise OR of one
 diff --git a/sysdeps/gnu/errlist.h b/sysdeps/gnu/errlist.h
 index 5d11ed723d..6329e5f393 100644
 --- a/sysdeps/gnu/errlist.h
@@ -1942,6 +3957,80 @@ index 5d11ed723d..6329e5f393 100644
 -_S(ERR_MAP(EPROGUNAVAIL), N_("RPC program not available"))
 +_S(EPROGUNAVAIL, N_("RPC program not available"))
  #endif
+diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
+index 0f08079e48..672d8f27ce 100644
+--- a/sysdeps/i386/dl-machine.h
++++ b/sysdeps/i386/dl-machine.h
+@@ -338,16 +338,22 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
+ 	{
+ # ifndef RTLD_BOOTSTRAP
+ 	  if (sym_map != map
+-	      && sym_map->l_type != lt_executable
+ 	      && !sym_map->l_relocated)
+ 	    {
+ 	      const char *strtab
+ 		= (const char *) D_PTR (map, l_info[DT_STRTAB]);
+-	      _dl_error_printf ("\
++	      if (sym_map->l_type == lt_executable)
++		_dl_fatal_printf ("\
++%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
++and creates an unsatisfiable circular dependency.\n",
++				  RTLD_PROGNAME, strtab + refsym->st_name,
++				  map->l_name);
++	      else
++		_dl_error_printf ("\
+ %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
+-				RTLD_PROGNAME, map->l_name,
+-				sym_map->l_name,
+-				strtab + refsym->st_name);
++				  RTLD_PROGNAME, map->l_name,
++				  sym_map->l_name,
++				  strtab + refsym->st_name);
+ 	    }
+ # endif
+ 	  value = ((Elf32_Addr (*) (void)) value) ();
+diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c
+index 8a53a1088f..362a2b713c 100644
+--- a/sysdeps/powerpc/powerpc64/backtrace.c
++++ b/sysdeps/powerpc/powerpc64/backtrace.c
+@@ -54,11 +54,22 @@ struct signal_frame_64 {
+   /* We don't care about the rest, since the IP value is at 'uc' field.  */
+ };
+ 
++/* Test if the address match to the inside the trampoline code.
++   Up to and including kernel 5.8, returning from an interrupt or syscall to a
++   signal handler starts execution directly at the handler's entry point, with
++   LR set to address of the sigreturn trampoline (the vDSO symbol).
++   Newer kernels will branch to signal handler from the trampoline instead, so
++   checking the stacktrace against the vDSO entrypoint does not work in such
++   case.
++   The vDSO branches with a 'bctrl' instruction, so checking either the
++   vDSO address itself and the next instruction should cover all kernel
++   versions.  */
+ static inline bool
+ is_sigtramp_address (void *nip)
+ {
+ #ifdef HAVE_SIGTRAMP_RT64
+-  if (nip == GLRO (dl_vdso_sigtramp_rt64))
++  if (nip == GLRO (dl_vdso_sigtramp_rt64) ||
++      nip == GLRO (dl_vdso_sigtramp_rt64) + 4)
+     return true;
+ #endif
+   return false;
+diff --git a/sysdeps/sh/be/sh4/fpu/Implies b/sysdeps/sh/be/sh4/fpu/Implies
+new file mode 100644
+index 0000000000..71b28ee1a4
+--- /dev/null
++++ b/sysdeps/sh/be/sh4/fpu/Implies
+@@ -0,0 +1 @@
++sh/sh4/fpu
+diff --git a/sysdeps/sh/le/sh4/fpu/Implies b/sysdeps/sh/le/sh4/fpu/Implies
+new file mode 100644
+index 0000000000..71b28ee1a4
+--- /dev/null
++++ b/sysdeps/sh/le/sh4/fpu/Implies
+@@ -0,0 +1 @@
++sh/sh4/fpu
 diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
 index 9b2a253032..34748ffcd1 100644
 --- a/sysdeps/unix/sysv/linux/Makefile
@@ -1955,23 +4044,6 @@ index 9b2a253032..34748ffcd1 100644
  tests-internal += tst-ofdlocks-compat tst-sigcontext-get_pc
  
  CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
-diff --git a/sysdeps/unix/sysv/linux/aarch64/configure b/sysdeps/unix/sysv/linux/aarch64/configure
-index 27d50e1d3c..290670a67a 100644
---- a/sysdeps/unix/sysv/linux/aarch64/configure
-+++ b/sysdeps/unix/sysv/linux/aarch64/configure
-@@ -6,10 +6,10 @@ arch_minimum_kernel=3.7.0
- test -n "$libc_cv_slibdir" ||
- case "$prefix" in
- /usr | /usr/)
--  libc_cv_slibdir='/lib64'
-+  libc_cv_slibdir='/lib'
-   libc_cv_rtlddir='/lib'
-   if test "$libdir" = '${exec_prefix}/lib'; then
--    libdir='${exec_prefix}/lib64';
-+    libdir='${exec_prefix}/lib';
-     # Locale data can be shared between 32-bit and 64-bit libraries.
-     libc_cv_complocaledir='${exec_prefix}/lib/locale'
-   fi
 diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
 index fc688450ee..00a4d0c8e7 100644
 --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
@@ -2079,6 +4151,20 @@ index f131a26fc7..1cdabde8f2 100644
      case IPC_INFO:      /* arg.__buf */
      case SEM_INFO:
        va_start (ap, cmd);
+diff --git a/sysdeps/unix/sysv/linux/sh/be/sh4/fpu/Implies b/sysdeps/unix/sysv/linux/sh/be/sh4/fpu/Implies
+new file mode 100644
+index 0000000000..7eeaf15a5a
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/sh/be/sh4/fpu/Implies
+@@ -0,0 +1 @@
++unix/sysv/linux/sh/sh4/fpu
+diff --git a/sysdeps/unix/sysv/linux/sh/le/sh4/fpu/Implies b/sysdeps/unix/sysv/linux/sh/le/sh4/fpu/Implies
+new file mode 100644
+index 0000000000..7eeaf15a5a
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/sh/le/sh4/fpu/Implies
+@@ -0,0 +1 @@
++unix/sysv/linux/sh/sh4/fpu
 diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
 index 76d88441f1..1d19a798b1 100644
 --- a/sysdeps/unix/sysv/linux/shmctl.c
@@ -2699,49 +4785,165 @@ index 0000000000..7128ae2e14
 +}
 +
 +#include <support/test-driver.c>
-diff --git a/sysdeps/unix/sysv/linux/x86_64/64/configure b/sysdeps/unix/sysv/linux/x86_64/64/configure
-index 9d298faba7..cef1ec842c 100644
---- a/sysdeps/unix/sysv/linux/x86_64/64/configure
-+++ b/sysdeps/unix/sysv/linux/x86_64/64/configure
-@@ -4,10 +4,10 @@
- test -n "$libc_cv_slibdir" ||
- case "$prefix" in
- /usr | /usr/)
--  libc_cv_slibdir='/lib64'
--  libc_cv_rtlddir='/lib64'
-+  libc_cv_slibdir='/lib'
-+  libc_cv_rtlddir='/lib'
-   if test "$libdir" = '${exec_prefix}/lib'; then
--    libdir='${exec_prefix}/lib64';
-+    libdir='${exec_prefix}/lib';
-     # Locale data can be shared between 32-bit and 64-bit libraries.
-     libc_cv_complocaledir='${exec_prefix}/lib/locale'
-   fi
-diff --git a/sysdeps/unix/sysv/linux/x86_64/ldconfig.h b/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
-index 062c04689d..7783757726 100644
---- a/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
-+++ b/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
-@@ -18,9 +18,9 @@
- #include <sysdeps/generic/ldconfig.h>
+diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
+index a6736aef25..9736a13e7b 100644
+--- a/sysdeps/x86/Makefile
++++ b/sysdeps/x86/Makefile
+@@ -12,6 +12,12 @@ endif
+ ifeq ($(subdir),setjmp)
+ gen-as-const-headers += jmp_buf-ssp.sym
+ sysdep_routines += __longjmp_cancel
++ifneq ($(enable-cet),no)
++ifneq ($(have-tunables),no)
++tests += tst-setjmp-cet
++tst-setjmp-cet-ENV = GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on
++endif
++endif
+ endif
  
- #define SYSDEP_KNOWN_INTERPRETER_NAMES \
--  { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
-+  { "/lib32/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
-   { "/libx32/ld-linux-x32.so.2", FLAG_ELF_LIBC6 }, \
--  { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
-+  { "/lib/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
- #define SYSDEP_KNOWN_LIBRARY_NAMES \
-   { "libc.so.6", FLAG_ELF_LIBC6 },	\
-   { "libm.so.6", FLAG_ELF_LIBC6 },
-diff --git a/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
-index 44d76e8aa1..7d6cb1e20b 100644
---- a/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
-+++ b/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
-@@ -1,3 +1,3 @@
- /LD_TRACE_LOADED_OBJECTS=1/a\
- add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
--s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[ 	]*$_\1"\2\4\6 \264\4-x86-64\6 \2x32\4-x32\6"_
-+s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[    ]*$_\1"\232\4\6 \2\4-x86-64\6 \2x32\4-x32\6"_
+ ifeq ($(subdir),string)
+diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
+index 217c21c34f..3fb4a028d8 100644
+--- a/sysdeps/x86/cacheinfo.c
++++ b/sysdeps/x86/cacheinfo.c
+@@ -808,7 +808,7 @@ init_cacheinfo (void)
+ 	      threads = 1 << ((ecx >> 12) & 0x0f);
+ 	    }
+ 
+-	  if (threads == 0)
++	  if (threads == 0 || cpu_features->basic.family >= 0x17)
+ 	    {
+ 	      /* If APIC ID width is not available, use logical
+ 		 processor count.  */
+@@ -823,8 +823,22 @@ init_cacheinfo (void)
+ 	  if (threads > 0)
+ 	    shared /= threads;
+ 
+-	  /* Account for exclusive L2 and L3 caches.  */
+-	  shared += core;
++	  /* Get shared cache per ccx for Zen architectures.  */
++	  if (cpu_features->basic.family >= 0x17)
++	    {
++	      unsigned int eax;
++
++	      /* Get number of threads share the L3 cache in CCX.  */
++	      __cpuid_count (0x8000001D, 0x3, eax, ebx, ecx, edx);
++
++	      unsigned int threads_per_ccx = ((eax >> 14) & 0xfff) + 1;
++	      shared *= threads_per_ccx;
++	    }
++	  else
++	    {
++	      /* Account for exclusive L2 and L3 caches.  */
++	      shared += core;
++            }
+ 	}
+     }
+ 
+@@ -854,14 +868,20 @@ init_cacheinfo (void)
+       __x86_shared_cache_size = shared;
+     }
+ 
+-  /* The large memcpy micro benchmark in glibc shows that 6 times of
+-     shared cache size is the approximate value above which non-temporal
+-     store becomes faster on a 8-core processor.  This is the 3/4 of the
+-     total shared cache size.  */
++  /* The default setting for the non_temporal threshold is 3/4 of one
++     thread's share of the chip's cache. For most Intel and AMD processors
++     with an initial release date between 2017 and 2020, a thread's typical
++     share of the cache is from 500 KBytes to 2 MBytes. Using the 3/4
++     threshold leaves 125 KBytes to 500 KBytes of the thread's data
++     in cache after a maximum temporal copy, which will maintain
++     in cache a reasonable portion of the thread's stack and other
++     active data. If the threshold is set higher than one thread's
++     share of the cache, it has a substantial risk of negatively
++     impacting the performance of other threads running on the chip. */
+   __x86_shared_non_temporal_threshold
+     = (cpu_features->non_temporal_threshold != 0
+        ? cpu_features->non_temporal_threshold
+-       : __x86_shared_cache_size * threads * 3 / 4);
++       : __x86_shared_cache_size * 3 / 4);
+ 
+   /* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8.  */
+   unsigned int minimum_rep_movsb_threshold;
+diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c
+index 03572f7af6..3cc54a8d53 100644
+--- a/sysdeps/x86/dl-cet.c
++++ b/sysdeps/x86/dl-cet.c
+@@ -47,7 +47,10 @@ dl_cet_check (struct link_map *m, const char *program)
+   /* No legacy object check if both IBT and SHSTK are always on.  */
+   if (enable_ibt_type == cet_always_on
+       && enable_shstk_type == cet_always_on)
+-    return;
++    {
++      THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1));
++      return;
++    }
+ 
+   /* Check if IBT is enabled by kernel.  */
+   bool ibt_enabled
+diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
+index 89911e19e2..4eb3b85a7b 100644
+--- a/sysdeps/x86/dl-prop.h
++++ b/sysdeps/x86/dl-prop.h
+@@ -145,15 +145,15 @@ _dl_process_cet_property_note (struct link_map *l,
+ }
+ 
+ static inline void __attribute__ ((unused))
+-_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
++_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
+ {
+   const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
+   _dl_process_cet_property_note (l, note, ph->p_memsz, ph->p_align);
+ }
+ 
+ static inline int __attribute__ ((always_inline))
+-_dl_process_gnu_property (struct link_map *l, uint32_t type, uint32_t datasz,
+-			  void *data)
++_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
++			  uint32_t datasz, void *data)
+ {
+   return 0;
+ }
+diff --git a/sysdeps/x86/tst-setjmp-cet.c b/sysdeps/x86/tst-setjmp-cet.c
+new file mode 100644
+index 0000000000..42c795d2a8
+--- /dev/null
++++ b/sysdeps/x86/tst-setjmp-cet.c
+@@ -0,0 +1 @@
++#include <setjmp/tst-setjmp.c>
+diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
+index ca73d8fef9..363a749cb2 100644
+--- a/sysdeps/x86_64/dl-machine.h
++++ b/sysdeps/x86_64/dl-machine.h
+@@ -315,16 +315,22 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
+ 	{
+ # ifndef RTLD_BOOTSTRAP
+ 	  if (sym_map != map
+-	      && sym_map->l_type != lt_executable
+ 	      && !sym_map->l_relocated)
+ 	    {
+ 	      const char *strtab
+ 		= (const char *) D_PTR (map, l_info[DT_STRTAB]);
+-	      _dl_error_printf ("\
++	      if (sym_map->l_type == lt_executable)
++		_dl_fatal_printf ("\
++%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
++and creates an unsatisfiable circular dependency.\n",
++				  RTLD_PROGNAME, strtab + refsym->st_name,
++				  map->l_name);
++	      else
++		_dl_error_printf ("\
+ %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
+-				RTLD_PROGNAME, map->l_name,
+-				sym_map->l_name,
+-				strtab + refsym->st_name);
++				  RTLD_PROGNAME, map->l_name,
++				  sym_map->l_name,
++				  strtab + refsym->st_name);
+ 	    }
+ # endif
+ 	  value = ((ElfW(Addr) (*) (void)) value) ();
 diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h b/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h
 index 7659758972..e5fd5ac9cb 100644
 --- a/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h
@@ -2755,6 +4957,46 @@ index 7659758972..e5fd5ac9cb 100644
      return OPTIMIZE (fma4);
  
    return OPTIMIZE (sse2);
+diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
+index bd5dc1a3f3..092f364bb6 100644
+--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
++++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
+@@ -56,6 +56,13 @@
+ # endif
+ #endif
+ 
++/* Avoid short distance rep movsb only with non-SSE vector.  */
++#ifndef AVOID_SHORT_DISTANCE_REP_MOVSB
++# define AVOID_SHORT_DISTANCE_REP_MOVSB (VEC_SIZE > 16)
++#else
++# define AVOID_SHORT_DISTANCE_REP_MOVSB 0
++#endif
++
+ #ifndef PREFETCH
+ # define PREFETCH(addr) prefetcht0 addr
+ #endif
+@@ -243,7 +250,21 @@ L(movsb):
+ 	cmpq	%r9, %rdi
+ 	/* Avoid slow backward REP MOVSB.  */
+ 	jb	L(more_8x_vec_backward)
++# if AVOID_SHORT_DISTANCE_REP_MOVSB
++	movq	%rdi, %rcx
++	subq	%rsi, %rcx
++	jmp	2f
++# endif
+ 1:
++# if AVOID_SHORT_DISTANCE_REP_MOVSB
++	movq	%rsi, %rcx
++	subq	%rdi, %rcx
++2:
++/* Avoid "rep movsb" if RCX, the distance between source and destination,
++   is N*4GB + [1..63] with N >= 0.  */
++	cmpl	$63, %ecx
++	jbe	L(more_2x_vec)	/* Avoid "rep movsb" if ECX <= 63.  */
++# endif
+ 	mov	%RDX_LP, %RCX_LP
+ 	rep movsb
+ L(nop):
 diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c
 index 01dbff343a..b7284e0b48 100644
 --- a/sysvipc/test-sysvsem.c
@@ -2777,3 +5019,37 @@ index 83cd196798..e6ca7a8857 100644
 -#define RELEASE "release"
 +#define RELEASE "stable"
  #define VERSION "2.32"
+diff --git a/sysdeps/unix/sysv/linux/x86_64/64/configure b/sysdeps/unix/sysv/linux/x86_64/64/configure
+index 9d298faba7..cef1ec842c 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/64/configure
++++ b/sysdeps/unix/sysv/linux/x86_64/64/configure
+@@ -4,10 +4,10 @@
+ test -n "$libc_cv_slibdir" ||
+ case "$prefix" in
+ /usr | /usr/)
+-  libc_cv_slibdir='/lib64'
+-  libc_cv_rtlddir='/lib64'
++  libc_cv_slibdir='/lib'
++  libc_cv_rtlddir='/lib'
+   if test "$libdir" = '${exec_prefix}/lib'; then
+-    libdir='${exec_prefix}/lib64';
++    libdir='${exec_prefix}/lib';
+     # Locale data can be shared between 32-bit and 64-bit libraries.
+     libc_cv_complocaledir='${exec_prefix}/lib/locale'
+   fi
+diff --git a/sysdeps/unix/sysv/linux/x86_64/ldconfig.h b/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
+index 062c04689d..7783757726 100644
+--- a/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
++++ b/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
+@@ -18,9 +18,9 @@
+ #include <sysdeps/generic/ldconfig.h>
+ 
+ #define SYSDEP_KNOWN_INTERPRETER_NAMES \
+-  { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
++  { "/lib32/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
+   { "/libx32/ld-linux-x32.so.2", FLAG_ELF_LIBC6 }, \
+-  { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
++  { "/lib/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
+ #define SYSDEP_KNOWN_LIBRARY_NAMES \
+   { "libc.so.6", FLAG_ELF_LIBC6 },	\
+   { "libm.so.6", FLAG_ELF_LIBC6 },


More information about the crux-commits mailing list