summaryrefslogtreecommitdiff
path: root/glibc-32/glibc-2.32-3.patch
diff options
context:
space:
mode:
authorJuergen Daubert <jue@jue.li>2021-03-24 15:19:36 +0100
committerJuergen Daubert <jue@jue.li>2021-03-24 15:19:36 +0100
commitbec746a7a25d08b973bca7f78177f10f82dd9769 (patch)
treedc15fb35b865f3ce348b32c13aa44d6839bcf22a /glibc-32/glibc-2.32-3.patch
parent032ac05e2df7e65e9368323e4c918a53cb60e4fe (diff)
downloadcore-bec746a7a25d08b973bca7f78177f10f82dd9769.tar.gz
core-bec746a7a25d08b973bca7f78177f10f82dd9769.tar.xz
glibc-32: sync with upstream 2.32 branch
Diffstat (limited to 'glibc-32/glibc-2.32-3.patch')
-rw-r--r--glibc-32/glibc-2.32-3.patch5055
1 files changed, 5055 insertions, 0 deletions
diff --git a/glibc-32/glibc-2.32-3.patch b/glibc-32/glibc-2.32-3.patch
new file mode 100644
index 00000000..8195ec34
--- /dev/null
+++ b/glibc-32/glibc-2.32-3.patch
@@ -0,0 +1,5055 @@
+diff --git a/NEWS b/NEWS
+index 485b8ddffa..f278041512 100644
+--- a/NEWS
++++ b/NEWS
+@@ -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
++++ b/iconv/Versions
+@@ -6,7 +6,9 @@ libc {
+ GLIBC_PRIVATE {
+ # functions shared with iconv program
+ __gconv_get_alias_db; __gconv_get_cache; __gconv_get_modules_db;
+- __gconv_open; __gconv_create_spec;
++
++ # functions used elsewhere in glibc
++ __gconv_open; __gconv_create_spec; __gconv_destroy_spec;
+
+ # function used by the gconv modules
+ __gconv_transliterate;
+diff --git a/iconv/gconv_charset.c b/iconv/gconv_charset.c
+index 6ccd0773cc..4ba0aa99f5 100644
+--- a/iconv/gconv_charset.c
++++ b/iconv/gconv_charset.c
+@@ -216,3 +216,13 @@ out:
+ return ret;
+ }
+ libc_hidden_def (__gconv_create_spec)
++
++
++void
++__gconv_destroy_spec (struct gconv_spec *conv_spec)
++{
++ free (conv_spec->fromcode);
++ free (conv_spec->tocode);
++ return;
++}
++libc_hidden_def (__gconv_destroy_spec)
+diff --git a/iconv/gconv_charset.h b/iconv/gconv_charset.h
+index b39b09aea1..e9c122cf7e 100644
+--- a/iconv/gconv_charset.h
++++ b/iconv/gconv_charset.h
+@@ -48,33 +48,6 @@
+ #define GCONV_IGNORE_ERRORS_SUFFIX "IGNORE"
+
+
+-/* This function accepts the charset names of the source and destination of the
+- conversion and populates *conv_spec with an equivalent conversion
+- specification that may later be used by __gconv_open. The charset names
+- might contain options in the form of suffixes that alter the conversion,
+- e.g. "ISO-10646/UTF-8/TRANSLIT". It processes the charset names, ignoring
+- and truncating any suffix options in fromcode, and processing and truncating
+- any suffix options in tocode. Supported suffix options ("TRANSLIT" or
+- "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
+- to be set to true. Unrecognized suffix options are silently discarded. If
+- the function succeeds, it returns conv_spec back to the caller. It returns
+- NULL upon failure. */
+-struct gconv_spec *
+-__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
+- const char *tocode);
+-libc_hidden_proto (__gconv_create_spec)
+-
+-
+-/* This function frees all heap memory allocated by __gconv_create_spec. */
+-static void __attribute__ ((unused))
+-gconv_destroy_spec (struct gconv_spec *conv_spec)
+-{
+- free (conv_spec->fromcode);
+- free (conv_spec->tocode);
+- return;
+-}
+-
+-
+ /* This function copies in-order, characters from the source 's' that are
+ either alpha-numeric or one in one of these: "_-.,:/" - into the destination
+ 'wp' while dropping all other characters. In the process, it converts all
+diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
+index e86938dae7..f721ce30ff 100644
+--- a/iconv/gconv_int.h
++++ b/iconv/gconv_int.h
+@@ -152,6 +152,27 @@ extern int __gconv_open (struct gconv_spec *conv_spec,
+ __gconv_t *handle, int flags);
+ libc_hidden_proto (__gconv_open)
+
++/* This function accepts the charset names of the source and destination of the
++ conversion and populates *conv_spec with an equivalent conversion
++ specification that may later be used by __gconv_open. The charset names
++ might contain options in the form of suffixes that alter the conversion,
++ e.g. "ISO-10646/UTF-8/TRANSLIT". It processes the charset names, ignoring
++ and truncating any suffix options in fromcode, and processing and truncating
++ any suffix options in tocode. Supported suffix options ("TRANSLIT" or
++ "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
++ to be set to true. Unrecognized suffix options are silently discarded. If
++ the function succeeds, it returns conv_spec back to the caller. It returns
++ NULL upon failure. */
++extern struct gconv_spec *
++__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
++ const char *tocode);
++libc_hidden_proto (__gconv_create_spec)
++
++/* This function frees all heap memory allocated by __gconv_create_spec. */
++extern void
++__gconv_destroy_spec (struct gconv_spec *conv_spec);
++libc_hidden_proto (__gconv_destroy_spec)
++
+ /* Free resources associated with transformation descriptor CD. */
+ extern int __gconv_close (__gconv_t cd)
+ attribute_hidden;
+diff --git a/iconv/iconv_open.c b/iconv/iconv_open.c
+index dd54bc12e0..5b30055c04 100644
+--- a/iconv/iconv_open.c
++++ b/iconv/iconv_open.c
+@@ -39,7 +39,7 @@ iconv_open (const char *tocode, const char *fromcode)
+
+ int res = __gconv_open (&conv_spec, &cd, 0);
+
+- gconv_destroy_spec (&conv_spec);
++ __gconv_destroy_spec (&conv_spec);
+
+ if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK)
+ {
+diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
+index b4334faa57..d59979759c 100644
+--- a/iconv/iconv_prog.c
++++ b/iconv/iconv_prog.c
+@@ -184,7 +184,7 @@ main (int argc, char *argv[])
+ /* Let's see whether we have these coded character sets. */
+ res = __gconv_open (&conv_spec, &cd, 0);
+
+- gconv_destroy_spec (&conv_spec);
++ __gconv_destroy_spec (&conv_spec);
+
+ 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
++++ b/intl/dcigettext.c
+@@ -1120,15 +1120,18 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
+
+ # ifdef _LIBC
+
+- struct gconv_spec conv_spec
+- = { .fromcode = norm_add_slashes (charset, ""),
+- .tocode = norm_add_slashes (outcharset, ""),
+- /* We always want to use transliteration. */
+- .translit = true,
+- .ignore = false
+- };
++ struct gconv_spec conv_spec;
++
++ __gconv_create_spec (&conv_spec, charset, outcharset);
++
++ /* We always want to use transliteration. */
++ conv_spec.translit = true;
++
+ int r = __gconv_open (&conv_spec, &convd->conv,
+ GCONV_AVOID_NOCONV);
++
++ __gconv_destroy_spec (&conv_spec);
++
+ if (__builtin_expect (r != __GCONV_OK, 0))
+ {
+ /* If the output encoding is the same there is
+diff --git a/intl/tst-codeset.c b/intl/tst-codeset.c
+index fd70432eca..e9f6e5e09f 100644
+--- a/intl/tst-codeset.c
++++ b/intl/tst-codeset.c
+@@ -22,13 +22,11 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <support/check.h>
+
+ static int
+ do_test (void)
+ {
+- char *s;
+- int result = 0;
+-
+ unsetenv ("LANGUAGE");
+ unsetenv ("OUTPUT_CHARSET");
+ setlocale (LC_ALL, "de_DE.ISO-8859-1");
+@@ -36,25 +34,21 @@ do_test (void)
+ bindtextdomain ("codeset", OBJPFX "domaindir");
+
+ /* Here we expect output in ISO-8859-1. */
+- s = gettext ("cheese");
+- if (strcmp (s, "K\344se"))
+- {
+- printf ("call 1 returned: %s\n", s);
+- result = 1;
+- }
++ TEST_COMPARE_STRING (gettext ("cheese"), "K\344se");
+
++ /* Here we expect output in UTF-8. */
+ bind_textdomain_codeset ("codeset", "UTF-8");
++ TEST_COMPARE_STRING (gettext ("cheese"), "K\303\244se");
+
+- /* Here we expect output in UTF-8. */
+- s = gettext ("cheese");
+- if (strcmp (s, "K\303\244se"))
+- {
+- printf ("call 2 returned: %s\n", s);
+- result = 1;
+- }
+-
+- return result;
++ /* `a with umlaut' is transliterated to `ae'. */
++ bind_textdomain_codeset ("codeset", "ASCII//TRANSLIT");
++ TEST_COMPARE_STRING (gettext ("cheese"), "Kaese");
++
++ /* Transliteration also works by default even if not set. */
++ bind_textdomain_codeset ("codeset", "ASCII");
++ TEST_COMPARE_STRING (gettext ("cheese"), "Kaese");
++
++ return 0;
+ }
+
+-#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
++++ b/stdio-common/Makefile
+@@ -69,7 +69,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
+ tst-printf-bz25691 \
+ tst-vfprintf-width-prec-alloc \
+ tst-printf-fp-free \
+- tst-printf-fp-leak
++ tst-printf-fp-leak \
++ test-strerr
+
+
+ test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble
+diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c
+index d15f13a22a..2ecf121674 100644
+--- a/stdio-common/errlist.c
++++ b/stdio-common/errlist.c
+@@ -20,9 +20,13 @@
+ #include <libintl.h>
+ #include <array_length.h>
+
++#ifndef ERR_MAP
++# define ERR_MAP(n) n
++#endif
++
+ const char *const _sys_errlist_internal[] =
+ {
+-#define _S(n, str) [n] = str,
++#define _S(n, str) [ERR_MAP(n)] = str,
+ #include <errlist.h>
+ #undef _S
+ };
+@@ -41,20 +45,21 @@ static const union sys_errname_t
+ {
+ #define MSGSTRFIELD1(line) str##line
+ #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
+-#define _S(n, str) char MSGSTRFIELD(__LINE__)[sizeof(str)];
++#define _S(n, str) char MSGSTRFIELD(__LINE__)[sizeof(#n)];
+ #include <errlist.h>
+ #undef _S
+ };
+ char str[0];
+ } _sys_errname = { {
+-#define _S(n, s) s,
++#define _S(n, s) #n,
+ #include <errlist.h>
+ #undef _S
+ } };
+
+ static const unsigned short _sys_errnameidx[] =
+ {
+-#define _S(n, s) [n] = offsetof(union sys_errname_t, MSGSTRFIELD(__LINE__)),
++#define _S(n, s) \
++ [ERR_MAP(n)] = offsetof(union sys_errname_t, MSGSTRFIELD(__LINE__)),
+ #include <errlist.h>
+ #undef _S
+ };
+diff --git a/stdio-common/test-strerr.c b/stdio-common/test-strerr.c
+index fded208118..d77b81d507 100644
+--- a/stdio-common/test-strerr.c
++++ b/stdio-common/test-strerr.c
+@@ -18,46 +18,672 @@
+
+ #include <string.h>
+ #include <errno.h>
+-#include <array_length.h>
+
+ #include <support/support.h>
+ #include <support/check.h>
+
+-#define N_(name) name
+-
+-static const char *const errlist[] =
+- {
+-/* This file is auto-generated from errlist.def. */
+-#include <errlist.h>
+- };
+-
+-#define MSGSTR_T errname_t
+-#define MSGSTR errname
+-#define MSGIDX errnameidx
+-#include <errlist-name.h>
+-#undef MSGSTR
+-#undef MSGIDX
+-
+ static int
+ do_test (void)
+ {
+- TEST_VERIFY (strerrordesc_np (-1) == NULL);
+- TEST_VERIFY (strerrordesc_np (array_length (errlist)) == NULL);
+- for (size_t i = 0; i < array_length (errlist); i++)
+- {
+- if (errlist[i] == NULL)
+- continue;
+- TEST_COMPARE_STRING (strerrordesc_np (i), errlist[i]);
+- }
++ TEST_COMPARE_STRING (strerrordesc_np (0), "Success");
++ TEST_COMPARE_STRING (strerrorname_np (0), "0");
+
+- TEST_VERIFY (strerrorname_np (-1) == NULL);
+- TEST_VERIFY (strerrorname_np (array_length (errlist)) == NULL);
+- for (size_t i = 0; i < array_length (errlist); i++)
+- {
+- if (errlist[i] == NULL)
+- continue;
+- TEST_COMPARE_STRING (strerrorname_np (i), errname.str + errnameidx[i]);
+- }
++#ifdef EPERM
++ TEST_COMPARE_STRING (strerrordesc_np (EPERM), "Operation not permitted");
++ TEST_COMPARE_STRING (strerrorname_np (EPERM), "EPERM");
++#endif
++#ifdef ENOENT
++ TEST_COMPARE_STRING (strerrordesc_np (ENOENT),
++ "No such file or directory");
++ TEST_COMPARE_STRING (strerrorname_np (ENOENT), "ENOENT");
++#endif
++#ifdef ESRCH
++ TEST_COMPARE_STRING (strerrordesc_np (ESRCH), "No such process");
++ TEST_COMPARE_STRING (strerrorname_np (ESRCH), "ESRCH");
++#endif
++#ifdef EINTR
++ TEST_COMPARE_STRING (strerrordesc_np (EINTR), "Interrupted system call");
++ TEST_COMPARE_STRING (strerrorname_np (EINTR), "EINTR");
++#endif
++#ifdef EIO
++ TEST_COMPARE_STRING (strerrordesc_np (EIO), "Input/output error");
++ TEST_COMPARE_STRING (strerrorname_np (EIO), "EIO");
++#endif
++#ifdef ENXIO
++ TEST_COMPARE_STRING (strerrordesc_np (ENXIO), "No such device or address");
++ TEST_COMPARE_STRING (strerrorname_np (ENXIO), "ENXIO");
++#endif
++#ifdef E2BIG
++ TEST_COMPARE_STRING (strerrordesc_np (E2BIG), "Argument list too long");
++ TEST_COMPARE_STRING (strerrorname_np (E2BIG), "E2BIG");
++#endif
++#ifdef ENOEXEC
++ TEST_COMPARE_STRING (strerrordesc_np (ENOEXEC), "Exec format error");
++ TEST_COMPARE_STRING (strerrorname_np (ENOEXEC), "ENOEXEC");
++#endif
++#ifdef EBADF
++ TEST_COMPARE_STRING (strerrordesc_np (EBADF), "Bad file descriptor");
++ TEST_COMPARE_STRING (strerrorname_np (EBADF), "EBADF");
++#endif
++#ifdef ECHILD
++ TEST_COMPARE_STRING (strerrordesc_np (ECHILD), "No child processes");
++ TEST_COMPARE_STRING (strerrorname_np (ECHILD), "ECHILD");
++#endif
++#ifdef EDEADLK
++ TEST_COMPARE_STRING (strerrordesc_np (EDEADLK),
++ "Resource deadlock avoided");
++ TEST_COMPARE_STRING (strerrorname_np (EDEADLK), "EDEADLK");
++#endif
++#ifdef ENOMEM
++ TEST_COMPARE_STRING (strerrordesc_np (ENOMEM), "Cannot allocate memory");
++ TEST_COMPARE_STRING (strerrorname_np (ENOMEM), "ENOMEM");
++#endif
++#ifdef EACCES
++ TEST_COMPARE_STRING (strerrordesc_np (EACCES), "Permission denied");
++ TEST_COMPARE_STRING (strerrorname_np (EACCES), "EACCES");
++#endif
++#ifdef EFAULT
++ TEST_COMPARE_STRING (strerrordesc_np (EFAULT), "Bad address");
++ TEST_COMPARE_STRING (strerrorname_np (EFAULT), "EFAULT");
++#endif
++#ifdef ENOTBLK
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTBLK), "Block device required");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTBLK), "ENOTBLK");
++#endif
++#ifdef EBUSY
++ TEST_COMPARE_STRING (strerrordesc_np (EBUSY), "Device or resource busy");
++ TEST_COMPARE_STRING (strerrorname_np (EBUSY), "EBUSY");
++#endif
++#ifdef EEXIST
++ TEST_COMPARE_STRING (strerrordesc_np (EEXIST), "File exists");
++ TEST_COMPARE_STRING (strerrorname_np (EEXIST), "EEXIST");
++#endif
++#ifdef EXDEV
++ TEST_COMPARE_STRING (strerrordesc_np (EXDEV), "Invalid cross-device link");
++ TEST_COMPARE_STRING (strerrorname_np (EXDEV), "EXDEV");
++#endif
++#ifdef ENODEV
++ TEST_COMPARE_STRING (strerrordesc_np (ENODEV), "No such device");
++ TEST_COMPARE_STRING (strerrorname_np (ENODEV), "ENODEV");
++#endif
++#ifdef ENOTDIR
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTDIR), "Not a directory");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTDIR), "ENOTDIR");
++#endif
++#ifdef EISDIR
++ TEST_COMPARE_STRING (strerrordesc_np (EISDIR), "Is a directory");
++ TEST_COMPARE_STRING (strerrorname_np (EISDIR), "EISDIR");
++#endif
++#ifdef EINVAL
++ TEST_COMPARE_STRING (strerrordesc_np (EINVAL), "Invalid argument");
++ TEST_COMPARE_STRING (strerrorname_np (EINVAL), "EINVAL");
++#endif
++#ifdef EMFILE
++ TEST_COMPARE_STRING (strerrordesc_np (EMFILE), "Too many open files");
++ TEST_COMPARE_STRING (strerrorname_np (EMFILE), "EMFILE");
++#endif
++#ifdef ENFILE
++ TEST_COMPARE_STRING (strerrordesc_np (ENFILE),
++ "Too many open files in system");
++ TEST_COMPARE_STRING (strerrorname_np (ENFILE), "ENFILE");
++#endif
++#ifdef ENOTTY
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTTY),
++ "Inappropriate ioctl for device");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTTY), "ENOTTY");
++#endif
++#ifdef ETXTBSY
++ TEST_COMPARE_STRING (strerrordesc_np (ETXTBSY), "Text file busy");
++ TEST_COMPARE_STRING (strerrorname_np (ETXTBSY), "ETXTBSY");
++#endif
++#ifdef EFBIG
++ TEST_COMPARE_STRING (strerrordesc_np (EFBIG), "File too large");
++ TEST_COMPARE_STRING (strerrorname_np (EFBIG), "EFBIG");
++#endif
++#ifdef ENOSPC
++ TEST_COMPARE_STRING (strerrordesc_np (ENOSPC), "No space left on device");
++ TEST_COMPARE_STRING (strerrorname_np (ENOSPC), "ENOSPC");
++#endif
++#ifdef ESPIPE
++ TEST_COMPARE_STRING (strerrordesc_np (ESPIPE), "Illegal seek");
++ TEST_COMPARE_STRING (strerrorname_np (ESPIPE), "ESPIPE");
++#endif
++#ifdef EROFS
++ TEST_COMPARE_STRING (strerrordesc_np (EROFS), "Read-only file system");
++ TEST_COMPARE_STRING (strerrorname_np (EROFS), "EROFS");
++#endif
++#ifdef EMLINK
++ TEST_COMPARE_STRING (strerrordesc_np (EMLINK), "Too many links");
++ TEST_COMPARE_STRING (strerrorname_np (EMLINK), "EMLINK");
++#endif
++#ifdef EPIPE
++ TEST_COMPARE_STRING (strerrordesc_np (EPIPE), "Broken pipe");
++ TEST_COMPARE_STRING (strerrorname_np (EPIPE), "EPIPE");
++#endif
++#ifdef EDOM
++ TEST_COMPARE_STRING (strerrordesc_np (EDOM),
++ "Numerical argument out of domain");
++ TEST_COMPARE_STRING (strerrorname_np (EDOM), "EDOM");
++#endif
++#ifdef ERANGE
++ TEST_COMPARE_STRING (strerrordesc_np (ERANGE),
++ "Numerical result out of range");
++ TEST_COMPARE_STRING (strerrorname_np (ERANGE), "ERANGE");
++#endif
++#ifdef EAGAIN
++ TEST_COMPARE_STRING (strerrordesc_np (EAGAIN),
++ "Resource temporarily unavailable");
++ TEST_COMPARE_STRING (strerrorname_np (EAGAIN), "EAGAIN");
++#endif
++#ifdef EINPROGRESS
++ TEST_COMPARE_STRING (strerrordesc_np (EINPROGRESS),
++ "Operation now in progress");
++ TEST_COMPARE_STRING (strerrorname_np (EINPROGRESS), "EINPROGRESS");
++#endif
++#ifdef EALREADY
++ TEST_COMPARE_STRING (strerrordesc_np (EALREADY),
++ "Operation already in progress");
++ TEST_COMPARE_STRING (strerrorname_np (EALREADY), "EALREADY");
++#endif
++#ifdef ENOTSOCK
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTSOCK),
++ "Socket operation on non-socket");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTSOCK), "ENOTSOCK");
++#endif
++#ifdef EMSGSIZE
++ TEST_COMPARE_STRING (strerrordesc_np (EMSGSIZE), "Message too long");
++ TEST_COMPARE_STRING (strerrorname_np (EMSGSIZE), "EMSGSIZE");
++#endif
++#ifdef EPROTOTYPE
++ TEST_COMPARE_STRING (strerrordesc_np (EPROTOTYPE),
++ "Protocol wrong type for socket");
++ TEST_COMPARE_STRING (strerrorname_np (EPROTOTYPE), "EPROTOTYPE");
++#endif
++#ifdef ENOPROTOOPT
++ TEST_COMPARE_STRING (strerrordesc_np (ENOPROTOOPT),
++ "Protocol not available");
++ TEST_COMPARE_STRING (strerrorname_np (ENOPROTOOPT), "ENOPROTOOPT");
++#endif
++#ifdef EPROTONOSUPPORT
++ TEST_COMPARE_STRING (strerrordesc_np (EPROTONOSUPPORT),
++ "Protocol not supported");
++ TEST_COMPARE_STRING (strerrorname_np (EPROTONOSUPPORT), "EPROTONOSUPPORT");
++#endif
++#ifdef ESOCKTNOSUPPORT
++ TEST_COMPARE_STRING (strerrordesc_np (ESOCKTNOSUPPORT),
++ "Socket type not supported");
++ TEST_COMPARE_STRING (strerrorname_np (ESOCKTNOSUPPORT), "ESOCKTNOSUPPORT");
++#endif
++#ifdef EOPNOTSUPP
++ TEST_COMPARE_STRING (strerrordesc_np (EOPNOTSUPP),
++ "Operation not supported");
++ TEST_COMPARE_STRING (strerrorname_np (EOPNOTSUPP), "EOPNOTSUPP");
++#endif
++#ifdef EPFNOSUPPORT
++ TEST_COMPARE_STRING (strerrordesc_np (EPFNOSUPPORT),
++ "Protocol family not supported");
++ TEST_COMPARE_STRING (strerrorname_np (EPFNOSUPPORT), "EPFNOSUPPORT");
++#endif
++#ifdef EAFNOSUPPORT
++ TEST_COMPARE_STRING (strerrordesc_np (EAFNOSUPPORT),
++ "Address family not supported by protocol");
++ TEST_COMPARE_STRING (strerrorname_np (EAFNOSUPPORT), "EAFNOSUPPORT");
++#endif
++#ifdef EADDRINUSE
++ TEST_COMPARE_STRING (strerrordesc_np (EADDRINUSE),
++ "Address already in use");
++ TEST_COMPARE_STRING (strerrorname_np (EADDRINUSE), "EADDRINUSE");
++#endif
++#ifdef EADDRNOTAVAIL
++ TEST_COMPARE_STRING (strerrordesc_np (EADDRNOTAVAIL),
++ "Cannot assign requested address");
++ TEST_COMPARE_STRING (strerrorname_np (EADDRNOTAVAIL), "EADDRNOTAVAIL");
++#endif
++#ifdef ENETDOWN
++ TEST_COMPARE_STRING (strerrordesc_np (ENETDOWN), "Network is down");
++ TEST_COMPARE_STRING (strerrorname_np (ENETDOWN), "ENETDOWN");
++#endif
++#ifdef ENETUNREACH
++ TEST_COMPARE_STRING (strerrordesc_np (ENETUNREACH),
++ "Network is unreachable");
++ TEST_COMPARE_STRING (strerrorname_np (ENETUNREACH), "ENETUNREACH");
++#endif
++#ifdef ENETRESET
++ TEST_COMPARE_STRING (strerrordesc_np (ENETRESET),
++ "Network dropped connection on reset");
++ TEST_COMPARE_STRING (strerrorname_np (ENETRESET), "ENETRESET");
++#endif
++#ifdef ECONNABORTED
++ TEST_COMPARE_STRING (strerrordesc_np (ECONNABORTED),
++ "Software caused connection abort");
++ TEST_COMPARE_STRING (strerrorname_np (ECONNABORTED), "ECONNABORTED");
++#endif
++#ifdef ECONNRESET
++ TEST_COMPARE_STRING (strerrordesc_np (ECONNRESET),
++ "Connection reset by peer");
++ TEST_COMPARE_STRING (strerrorname_np (ECONNRESET), "ECONNRESET");
++#endif
++#ifdef ENOBUFS
++ TEST_COMPARE_STRING (strerrordesc_np (ENOBUFS),
++ "No buffer space available");
++ TEST_COMPARE_STRING (strerrorname_np (ENOBUFS), "ENOBUFS");
++#endif
++#ifdef EISCONN
++ TEST_COMPARE_STRING (strerrordesc_np (EISCONN),
++ "Transport endpoint is already connected");
++ TEST_COMPARE_STRING (strerrorname_np (EISCONN), "EISCONN");
++#endif
++#ifdef ENOTCONN
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTCONN),
++ "Transport endpoint is not connected");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTCONN), "ENOTCONN");
++#endif
++#ifdef EDESTADDRREQ
++ TEST_COMPARE_STRING (strerrordesc_np (EDESTADDRREQ),
++ "Destination address required");
++ TEST_COMPARE_STRING (strerrorname_np (EDESTADDRREQ), "EDESTADDRREQ");
++#endif
++#ifdef ESHUTDOWN
++ TEST_COMPARE_STRING (strerrordesc_np (ESHUTDOWN),
++ "Cannot send after transport endpoint shutdown");
++ TEST_COMPARE_STRING (strerrorname_np (ESHUTDOWN), "ESHUTDOWN");
++#endif
++#ifdef ETOOMANYREFS
++ TEST_COMPARE_STRING (strerrordesc_np (ETOOMANYREFS),
++ "Too many references: cannot splice");
++ TEST_COMPARE_STRING (strerrorname_np (ETOOMANYREFS), "ETOOMANYREFS");
++#endif
++#ifdef ETIMEDOUT
++ TEST_COMPARE_STRING (strerrordesc_np (ETIMEDOUT), "Connection timed out");
++ TEST_COMPARE_STRING (strerrorname_np (ETIMEDOUT), "ETIMEDOUT");
++#endif
++#ifdef ECONNREFUSED
++ TEST_COMPARE_STRING (strerrordesc_np (ECONNREFUSED), "Connection refused");
++ TEST_COMPARE_STRING (strerrorname_np (ECONNREFUSED), "ECONNREFUSED");
++#endif
++#ifdef ELOOP
++ TEST_COMPARE_STRING (strerrordesc_np (ELOOP),
++ "Too many levels of symbolic links");
++ TEST_COMPARE_STRING (strerrorname_np (ELOOP), "ELOOP");
++#endif
++#ifdef ENAMETOOLONG
++ TEST_COMPARE_STRING (strerrordesc_np (ENAMETOOLONG), "File name too long");
++ TEST_COMPARE_STRING (strerrorname_np (ENAMETOOLONG), "ENAMETOOLONG");
++#endif
++#ifdef EHOSTDOWN
++ TEST_COMPARE_STRING (strerrordesc_np (EHOSTDOWN), "Host is down");
++ TEST_COMPARE_STRING (strerrorname_np (EHOSTDOWN), "EHOSTDOWN");
++#endif
++#ifdef EHOSTUNREACH
++ TEST_COMPARE_STRING (strerrordesc_np (EHOSTUNREACH), "No route to host");
++ TEST_COMPARE_STRING (strerrorname_np (EHOSTUNREACH), "EHOSTUNREACH");
++#endif
++#ifdef ENOTEMPTY
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTEMPTY), "Directory not empty");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTEMPTY), "ENOTEMPTY");
++#endif
++#ifdef EUSERS
++ TEST_COMPARE_STRING (strerrordesc_np (EUSERS), "Too many users");
++ TEST_COMPARE_STRING (strerrorname_np (EUSERS), "EUSERS");
++#endif
++#ifdef EDQUOT
++ TEST_COMPARE_STRING (strerrordesc_np (EDQUOT), "Disk quota exceeded");
++ TEST_COMPARE_STRING (strerrorname_np (EDQUOT), "EDQUOT");
++#endif
++#ifdef ESTALE
++ TEST_COMPARE_STRING (strerrordesc_np (ESTALE), "Stale file handle");
++ TEST_COMPARE_STRING (strerrorname_np (ESTALE), "ESTALE");
++#endif
++#ifdef EREMOTE
++ TEST_COMPARE_STRING (strerrordesc_np (EREMOTE), "Object is remote");
++ TEST_COMPARE_STRING (strerrorname_np (EREMOTE), "EREMOTE");
++#endif
++#ifdef ENOLCK
++ TEST_COMPARE_STRING (strerrordesc_np (ENOLCK), "No locks available");
++ TEST_COMPARE_STRING (strerrorname_np (ENOLCK), "ENOLCK");
++#endif
++#ifdef ENOSYS
++ TEST_COMPARE_STRING (strerrordesc_np (ENOSYS), "Function not implemented");
++ TEST_COMPARE_STRING (strerrorname_np (ENOSYS), "ENOSYS");
++#endif
++#ifdef EILSEQ
++ TEST_COMPARE_STRING (strerrordesc_np (EILSEQ),
++ "Invalid or incomplete multibyte or wide character");
++ TEST_COMPARE_STRING (strerrorname_np (EILSEQ), "EILSEQ");
++#endif
++#ifdef EBADMSG
++ TEST_COMPARE_STRING (strerrordesc_np (EBADMSG), "Bad message");
++ TEST_COMPARE_STRING (strerrorname_np (EBADMSG), "EBADMSG");
++#endif
++#ifdef EIDRM
++ TEST_COMPARE_STRING (strerrordesc_np (EIDRM), "Identifier removed");
++ TEST_COMPARE_STRING (strerrorname_np (EIDRM), "EIDRM");
++#endif
++#ifdef EMULTIHOP
++ TEST_COMPARE_STRING (strerrordesc_np (EMULTIHOP), "Multihop attempted");
++ TEST_COMPARE_STRING (strerrorname_np (EMULTIHOP), "EMULTIHOP");
++#endif
++#ifdef ENODATA
++ TEST_COMPARE_STRING (strerrordesc_np (ENODATA), "No data available");
++ TEST_COMPARE_STRING (strerrorname_np (ENODATA), "ENODATA");
++#endif
++#ifdef ENOLINK
++ TEST_COMPARE_STRING (strerrordesc_np (ENOLINK), "Link has been severed");
++ TEST_COMPARE_STRING (strerrorname_np (ENOLINK), "ENOLINK");
++#endif
++#ifdef ENOMSG
++ TEST_COMPARE_STRING (strerrordesc_np (ENOMSG),
++ "No message of desired type");
++ TEST_COMPARE_STRING (strerrorname_np (ENOMSG), "ENOMSG");
++#endif
++#ifdef ENOSR
++ TEST_COMPARE_STRING (strerrordesc_np (ENOSR), "Out of streams resources");
++ TEST_COMPARE_STRING (strerrorname_np (ENOSR), "ENOSR");
++#endif
++#ifdef ENOSTR
++ TEST_COMPARE_STRING (strerrordesc_np (ENOSTR), "Device not a stream");
++ TEST_COMPARE_STRING (strerrorname_np (ENOSTR), "ENOSTR");
++#endif
++#ifdef EOVERFLOW
++ TEST_COMPARE_STRING (strerrordesc_np (EOVERFLOW),
++ "Value too large for defined data type");
++ TEST_COMPARE_STRING (strerrorname_np (EOVERFLOW), "EOVERFLOW");
++#endif
++#ifdef EPROTO
++ TEST_COMPARE_STRING (strerrordesc_np (EPROTO), "Protocol error");
++ TEST_COMPARE_STRING (strerrorname_np (EPROTO), "EPROTO");
++#endif
++#ifdef ETIME
++ TEST_COMPARE_STRING (strerrordesc_np (ETIME), "Timer expired");
++ TEST_COMPARE_STRING (strerrorname_np (ETIME), "ETIME");
++#endif
++#ifdef ECANCELED
++ TEST_COMPARE_STRING (strerrordesc_np (ECANCELED), "Operation canceled");
++ TEST_COMPARE_STRING (strerrorname_np (ECANCELED), "ECANCELED");
++#endif
++#ifdef EOWNERDEAD
++ TEST_COMPARE_STRING (strerrordesc_np (EOWNERDEAD), "Owner died");
++ TEST_COMPARE_STRING (strerrorname_np (EOWNERDEAD), "EOWNERDEAD");
++#endif
++#ifdef ENOTRECOVERABLE
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTRECOVERABLE),
++ "State not recoverable");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTRECOVERABLE), "ENOTRECOVERABLE");
++#endif
++#ifdef ERESTART
++ TEST_COMPARE_STRING (strerrordesc_np (ERESTART),
++ "Interrupted system call should be restarted");
++ TEST_COMPARE_STRING (strerrorname_np (ERESTART), "ERESTART");
++#endif
++#ifdef ECHRNG
++ TEST_COMPARE_STRING (strerrordesc_np (ECHRNG),
++ "Channel number out of range");
++ TEST_COMPARE_STRING (strerrorname_np (ECHRNG), "ECHRNG");
++#endif
++#ifdef EL2NSYNC
++ TEST_COMPARE_STRING (strerrordesc_np (EL2NSYNC),
++ "Level 2 not synchronized");
++ TEST_COMPARE_STRING (strerrorname_np (EL2NSYNC), "EL2NSYNC");
++#endif
++#ifdef EL3HLT
++ TEST_COMPARE_STRING (strerrordesc_np (EL3HLT), "Level 3 halted");
++ TEST_COMPARE_STRING (strerrorname_np (EL3HLT), "EL3HLT");
++#endif
++#ifdef EL3RST
++ TEST_COMPARE_STRING (strerrordesc_np (EL3RST), "Level 3 reset");
++ TEST_COMPARE_STRING (strerrorname_np (EL3RST), "EL3RST");
++#endif
++#ifdef ELNRNG
++ TEST_COMPARE_STRING (strerrordesc_np (ELNRNG), "Link number out of range");
++ TEST_COMPARE_STRING (strerrorname_np (ELNRNG), "ELNRNG");
++#endif
++#ifdef EUNATCH
++ TEST_COMPARE_STRING (strerrordesc_np (EUNATCH),
++ "Protocol driver not attached");
++ TEST_COMPARE_STRING (strerrorname_np (EUNATCH), "EUNATCH");
++#endif
++#ifdef ENOCSI
++ TEST_COMPARE_STRING (strerrordesc_np (ENOCSI),
++ "No CSI structure available");
++ TEST_COMPARE_STRING (strerrorname_np (ENOCSI), "ENOCSI");
++#endif
++#ifdef EL2HLT
++ TEST_COMPARE_STRING (strerrordesc_np (EL2HLT), "Level 2 halted");
++ TEST_COMPARE_STRING (strerrorname_np (EL2HLT), "EL2HLT");
++#endif
++#ifdef EBADE
++ TEST_COMPARE_STRING (strerrordesc_np (EBADE), "Invalid exchange");
++ TEST_COMPARE_STRING (strerrorname_np (EBADE), "EBADE");
++#endif
++#ifdef EBADR
++ TEST_COMPARE_STRING (strerrordesc_np (EBADR),
++ "Invalid request descriptor");
++ TEST_COMPARE_STRING (strerrorname_np (EBADR), "EBADR");
++#endif
++#ifdef EXFULL
++ TEST_COMPARE_STRING (strerrordesc_np (EXFULL), "Exchange full");
++ TEST_COMPARE_STRING (strerrorname_np (EXFULL), "EXFULL");
++#endif
++#ifdef ENOANO
++ TEST_COMPARE_STRING (strerrordesc_np (ENOANO), "No anode");
++ TEST_COMPARE_STRING (strerrorname_np (ENOANO), "ENOANO");
++#endif
++#ifdef EBADRQC
++ TEST_COMPARE_STRING (strerrordesc_np (EBADRQC), "Invalid request code");
++ TEST_COMPARE_STRING (strerrorname_np (EBADRQC), "EBADRQC");
++#endif
++#ifdef EBADSLT
++ TEST_COMPARE_STRING (strerrordesc_np (EBADSLT), "Invalid slot");
++ TEST_COMPARE_STRING (strerrorname_np (EBADSLT), "EBADSLT");
++#endif
++#ifdef EBFONT
++ TEST_COMPARE_STRING (strerrordesc_np (EBFONT), "Bad font file format");
++ TEST_COMPARE_STRING (strerrorname_np (EBFONT), "EBFONT");
++#endif
++#ifdef ENONET
++ TEST_COMPARE_STRING (strerrordesc_np (ENONET),
++ "Machine is not on the network");
++ TEST_COMPARE_STRING (strerrorname_np (ENONET), "ENONET");
++#endif
++#ifdef ENOPKG
++ TEST_COMPARE_STRING (strerrordesc_np (ENOPKG), "Package not installed");
++ TEST_COMPARE_STRING (strerrorname_np (ENOPKG), "ENOPKG");
++#endif
++#ifdef EADV
++ TEST_COMPARE_STRING (strerrordesc_np (EADV), "Advertise error");
++ TEST_COMPARE_STRING (strerrorname_np (EADV), "EADV");
++#endif
++#ifdef ESRMNT
++ TEST_COMPARE_STRING (strerrordesc_np (ESRMNT), "Srmount error");
++ TEST_COMPARE_STRING (strerrorname_np (ESRMNT), "ESRMNT");
++#endif
++#ifdef ECOMM
++ TEST_COMPARE_STRING (strerrordesc_np (ECOMM),
++ "Communication error on send");
++ TEST_COMPARE_STRING (strerrorname_np (ECOMM), "ECOMM");
++#endif
++#ifdef EDOTDOT
++ TEST_COMPARE_STRING (strerrordesc_np (EDOTDOT), "RFS specific error");
++ TEST_COMPARE_STRING (strerrorname_np (EDOTDOT), "EDOTDOT");
++#endif
++#ifdef ENOTUNIQ
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTUNIQ),
++ "Name not unique on network");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTUNIQ), "ENOTUNIQ");
++#endif
++#ifdef EBADFD
++ TEST_COMPARE_STRING (strerrordesc_np (EBADFD),
++ "File descriptor in bad state");
++ TEST_COMPARE_STRING (strerrorname_np (EBADFD), "EBADFD");
++#endif
++#ifdef EREMCHG
++ TEST_COMPARE_STRING (strerrordesc_np (EREMCHG), "Remote address changed");
++ TEST_COMPARE_STRING (strerrorname_np (EREMCHG), "EREMCHG");
++#endif
++#ifdef ELIBACC
++ TEST_COMPARE_STRING (strerrordesc_np (ELIBACC),
++ "Can not access a needed shared library");
++ TEST_COMPARE_STRING (strerrorname_np (ELIBACC), "ELIBACC");
++#endif
++#ifdef ELIBBAD
++ TEST_COMPARE_STRING (strerrordesc_np (ELIBBAD),
++ "Accessing a corrupted shared library");
++ TEST_COMPARE_STRING (strerrorname_np (ELIBBAD), "ELIBBAD");
++#endif
++#ifdef ELIBSCN
++ TEST_COMPARE_STRING (strerrordesc_np (ELIBSCN),
++ ".lib section in a.out corrupted");
++ TEST_COMPARE_STRING (strerrorname_np (ELIBSCN), "ELIBSCN");
++#endif
++#ifdef ELIBMAX
++ TEST_COMPARE_STRING (strerrordesc_np (ELIBMAX),
++ "Attempting to link in too many shared libraries");
++ TEST_COMPARE_STRING (strerrorname_np (ELIBMAX), "ELIBMAX");
++#endif
++#ifdef ELIBEXEC
++ TEST_COMPARE_STRING (strerrordesc_np (ELIBEXEC),
++ "Cannot exec a shared library directly");
++ TEST_COMPARE_STRING (strerrorname_np (ELIBEXEC), "ELIBEXEC");
++#endif
++#ifdef ESTRPIPE
++ TEST_COMPARE_STRING (strerrordesc_np (ESTRPIPE), "Streams pipe error");
++ TEST_COMPARE_STRING (strerrorname_np (ESTRPIPE), "ESTRPIPE");
++#endif
++#ifdef EUCLEAN
++ TEST_COMPARE_STRING (strerrordesc_np (EUCLEAN),
++ "Structure needs cleaning");
++ TEST_COMPARE_STRING (strerrorname_np (EUCLEAN), "EUCLEAN");
++#endif
++#ifdef ENOTNAM
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTNAM),
++ "Not a XENIX named type file");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTNAM), "ENOTNAM");
++#endif
++#ifdef ENAVAIL
++ TEST_COMPARE_STRING (strerrordesc_np (ENAVAIL),
++ "No XENIX semaphores available");
++ TEST_COMPARE_STRING (strerrorname_np (ENAVAIL), "ENAVAIL");
++#endif
++#ifdef EISNAM
++ TEST_COMPARE_STRING (strerrordesc_np (EISNAM), "Is a named type file");
++ TEST_COMPARE_STRING (strerrorname_np (EISNAM), "EISNAM");
++#endif
++#ifdef EREMOTEIO
++ TEST_COMPARE_STRING (strerrordesc_np (EREMOTEIO), "Remote I/O error");
++ TEST_COMPARE_STRING (strerrorname_np (EREMOTEIO), "EREMOTEIO");
++#endif
++#ifdef ENOMEDIUM
++ TEST_COMPARE_STRING (strerrordesc_np (ENOMEDIUM), "No medium found");
++ TEST_COMPARE_STRING (strerrorname_np (ENOMEDIUM), "ENOMEDIUM");
++#endif
++#ifdef EMEDIUMTYPE
++ TEST_COMPARE_STRING (strerrordesc_np (EMEDIUMTYPE), "Wrong medium type");
++ TEST_COMPARE_STRING (strerrorname_np (EMEDIUMTYPE), "EMEDIUMTYPE");
++#endif
++#ifdef ENOKEY
++ TEST_COMPARE_STRING (strerrordesc_np (ENOKEY),
++ "Required key not available");
++ TEST_COMPARE_STRING (strerrorname_np (ENOKEY), "ENOKEY");
++#endif
++#ifdef EKEYEXPIRED
++ TEST_COMPARE_STRING (strerrordesc_np (EKEYEXPIRED), "Key has expired");
++ TEST_COMPARE_STRING (strerrorname_np (EKEYEXPIRED), "EKEYEXPIRED");
++#endif
++#ifdef EKEYREVOKED
++ TEST_COMPARE_STRING (strerrordesc_np (EKEYREVOKED),
++ "Key has been revoked");
++ TEST_COMPARE_STRING (strerrorname_np (EKEYREVOKED), "EKEYREVOKED");
++#endif
++#ifdef EKEYREJECTED
++ TEST_COMPARE_STRING (strerrordesc_np (EKEYREJECTED),
++ "Key was rejected by service");
++ TEST_COMPARE_STRING (strerrorname_np (EKEYREJECTED), "EKEYREJECTED");
++#endif
++#ifdef ERFKILL
++ TEST_COMPARE_STRING (strerrordesc_np (ERFKILL),
++ "Operation not possible due to RF-kill");
++ TEST_COMPARE_STRING (strerrorname_np (ERFKILL), "ERFKILL");
++#endif
++#ifdef EHWPOISON
++ TEST_COMPARE_STRING (strerrordesc_np (EHWPOISON),
++ "Memory page has hardware error");
++ TEST_COMPARE_STRING (strerrorname_np (EHWPOISON), "EHWPOISON");
++#endif
++#ifdef EBADRPC
++ TEST_COMPARE_STRING (strerrordesc_np (EBADRPC), "RPC struct is bad");
++ TEST_COMPARE_STRING (strerrorname_np (EBADRPC), "EBADRPC");
++#endif
++#ifdef EFTYPE
++ TEST_COMPARE_STRING (strerrordesc_np (EFTYPE),
++ "Inappropriate file type or format");
++ TEST_COMPARE_STRING (strerrorname_np (EFTYPE), "EFTYPE");
++#endif
++#ifdef EPROCUNAVAIL
++ TEST_COMPARE_STRING (strerrordesc_np (EPROCUNAVAIL),
++ "RPC bad procedure for program");
++ TEST_COMPARE_STRING (strerrorname_np (EPROCUNAVAIL), "EPROCUNAVAIL");
++#endif
++#ifdef EAUTH
++ TEST_COMPARE_STRING (strerrordesc_np (EAUTH), "Authentication error");
++ TEST_COMPARE_STRING (strerrorname_np (EAUTH), "EAUTH");
++#endif
++#ifdef EDIED
++ TEST_COMPARE_STRING (strerrordesc_np (EDIED), "Translator died");
++ TEST_COMPARE_STRING (strerrorname_np (EDIED), "EDIED");
++#endif
++#ifdef ERPCMISMATCH
++ TEST_COMPARE_STRING (strerrordesc_np (ERPCMISMATCH), "RPC version wrong");
++ TEST_COMPARE_STRING (strerrorname_np (ERPCMISMATCH), "ERPCMISMATCH");
++#endif
++#ifdef EGREGIOUS
++ TEST_COMPARE_STRING (strerrordesc_np (EGREGIOUS),
++ "You really blew it this time");
++ TEST_COMPARE_STRING (strerrorname_np (EGREGIOUS), "EGREGIOUS");
++#endif
++#ifdef EPROCLIM
++ TEST_COMPARE_STRING (strerrordesc_np (EPROCLIM), "Too many processes");
++ TEST_COMPARE_STRING (strerrorname_np (EPROCLIM), "EPROCLIM");
++#endif
++#ifdef EGRATUITOUS
++ TEST_COMPARE_STRING (strerrordesc_np (EGRATUITOUS), "Gratuitous error");
++ TEST_COMPARE_STRING (strerrorname_np (EGRATUITOUS), "EGRATUITOUS");
++#endif
++#if defined (ENOTSUP) && ENOTSUP != EOPNOTSUPP
++ TEST_COMPARE_STRING (strerrordesc_np (ENOTSUP), "Not supported");
++ TEST_COMPARE_STRING (strerrorname_np (ENOTSUP), "ENOTSUP");
++#endif
++#ifdef EPROGMISMATCH
++ TEST_COMPARE_STRING (strerrordesc_np (EPROGMISMATCH),
++ "RPC program version wrong");
++ TEST_COMPARE_STRING (strerrorname_np (EPROGMISMATCH), "EPROGMISMATCH");
++#endif
++#ifdef EBACKGROUND
++ TEST_COMPARE_STRING (strerrordesc_np (EBACKGROUND),
++ "Inappropriate operation for background process");
++ TEST_COMPARE_STRING (strerrorname_np (EBACKGROUND), "EBACKGROUND");
++#endif
++#ifdef EIEIO
++ TEST_COMPARE_STRING (strerrordesc_np (EIEIO), "Computer bought the farm");
++ TEST_COMPARE_STRING (strerrorname_np (EIEIO), "EIEIO");
++#endif
++#if defined (EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
++ TEST_COMPARE_STRING (strerrordesc_np (EWOULDBLOCK),
++ "Operation would block");
++ TEST_COMPARE_STRING (strerrorname_np (EWOULDBLOCK), "EWOULDBLOCK");
++#endif
++#ifdef ENEEDAUTH
++ TEST_COMPARE_STRING (strerrordesc_np (ENEEDAUTH), "Need authenticator");
++ TEST_COMPARE_STRING (strerrorname_np (ENEEDAUTH), "ENEEDAUTH");
++#endif
++#ifdef ED
++ TEST_COMPARE_STRING (strerrordesc_np (ED), "?");
++ TEST_COMPARE_STRING (strerrorname_np (ED), "ED");
++#endif
++#ifdef EPROGUNAVAIL
++ TEST_COMPARE_STRING (strerrordesc_np (EPROGUNAVAIL),
++ "RPC program not available");
++ TEST_COMPARE_STRING (strerrorname_np (EPROGUNAVAIL), "EPROGUNAVAIL");
++#endif
+
+ 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
++++ b/sysdeps/aarch64/multiarch/memcpy.c
+@@ -41,7 +41,8 @@ libc_ifunc (__libc_memcpy,
+ ? __memcpy_falkor
+ : (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr)
+ ? __memcpy_thunderx2
+- : (IS_NEOVERSE_N1 (midr)
++ : (IS_NEOVERSE_N1 (midr) || IS_NEOVERSE_N2 (midr)
++ || IS_NEOVERSE_V1 (midr)
+ ? __memcpy_simd
+ : __memcpy_generic)))));
+
+diff --git a/sysdeps/aarch64/multiarch/memcpy_advsimd.S b/sysdeps/aarch64/multiarch/memcpy_advsimd.S
+index d4ba747777..48bb6d7ca4 100644
+--- a/sysdeps/aarch64/multiarch/memcpy_advsimd.S
++++ b/sysdeps/aarch64/multiarch/memcpy_advsimd.S
+@@ -223,12 +223,13 @@ L(copy_long_backwards):
+ b.ls L(copy64_from_start)
+
+ L(loop64_backwards):
+- stp A_q, B_q, [dstend, -32]
++ str B_q, [dstend, -16]
++ str A_q, [dstend, -32]
+ ldp A_q, B_q, [srcend, -96]
+- stp C_q, D_q, [dstend, -64]
++ str D_q, [dstend, -48]
++ str C_q, [dstend, -64]!
+ ldp C_q, D_q, [srcend, -128]
+ sub srcend, srcend, 64
+- sub dstend, dstend, 64
+ subs count, count, 64
+ b.hi L(loop64_backwards)
+
+diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
+index ad10aa8ac6..46a4cb3a54 100644
+--- a/sysdeps/aarch64/multiarch/memmove.c
++++ b/sysdeps/aarch64/multiarch/memmove.c
+@@ -41,7 +41,8 @@ libc_ifunc (__libc_memmove,
+ ? __memmove_falkor
+ : (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr)
+ ? __memmove_thunderx2
+- : (IS_NEOVERSE_N1 (midr)
++ : (IS_NEOVERSE_N1 (midr) || IS_NEOVERSE_N2 (midr)
++ || IS_NEOVERSE_V1 (midr)
+ ? __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
++++ b/sysdeps/gnu/errlist.h
+@@ -1,24 +1,21 @@
+-#ifndef ERR_MAP
+-#define ERR_MAP(value) value
+-#endif
+-_S(ERR_MAP(0), N_("Success"))
++_S(0, N_("Success"))
+ #ifdef EPERM
+ /*
+ TRANS Only the owner of the file (or other resource)
+ TRANS or processes with special privileges can perform the operation. */
+-_S(ERR_MAP(EPERM), N_("Operation not permitted"))
++_S(EPERM, N_("Operation not permitted"))
+ #endif
+ #ifdef ENOENT
+ /*
+ TRANS This is a ``file doesn't exist'' error
+ TRANS for ordinary files that are referenced in contexts where they are
+ TRANS expected to already exist. */
+-_S(ERR_MAP(ENOENT), N_("No such file or directory"))
++_S(ENOENT, N_("No such file or directory"))
+ #endif
+ #ifdef ESRCH
+ /*
+ TRANS No process matches the specified process ID. */
+-_S(ERR_MAP(ESRCH), N_("No such process"))
++_S(ESRCH, N_("No such process"))
+ #endif
+ #ifdef EINTR
+ /*
+@@ -29,12 +26,12 @@ TRANS
+ TRANS You can choose to have functions resume after a signal that is handled,
+ TRANS rather than failing with @code{EINTR}; see @ref{Interrupted
+ TRANS Primitives}. */
+-_S(ERR_MAP(EINTR), N_("Interrupted system call"))
++_S(EINTR, N_("Interrupted system call"))
+ #endif
+ #ifdef EIO
+ /*
+ TRANS Usually used for physical read or write errors. */
+-_S(ERR_MAP(EIO), N_("Input/output error"))
++_S(EIO, N_("Input/output error"))
+ #endif
+ #ifdef ENXIO
+ /*
+@@ -43,7 +40,7 @@ TRANS represented by a file you specified, and it couldn't find the device.
+ TRANS This can mean that the device file was installed incorrectly, or that
+ TRANS the physical device is missing or not correctly attached to the
+ TRANS computer. */
+-_S(ERR_MAP(ENXIO), N_("No such device or address"))
++_S(ENXIO, N_("No such device or address"))
+ #endif
+ #ifdef E2BIG
+ /*
+@@ -51,27 +48,27 @@ TRANS Used when the arguments passed to a new program
+ TRANS being executed with one of the @code{exec} functions (@pxref{Executing a
+ TRANS File}) occupy too much memory space. This condition never arises on
+ TRANS @gnuhurdsystems{}. */
+-_S(ERR_MAP(E2BIG), N_("Argument list too long"))
++_S(E2BIG, N_("Argument list too long"))
+ #endif
+ #ifdef ENOEXEC
+ /*
+ TRANS Invalid executable file format. This condition is detected by the
+ TRANS @code{exec} functions; see @ref{Executing a File}. */
+-_S(ERR_MAP(ENOEXEC), N_("Exec format error"))
++_S(ENOEXEC, N_("Exec format error"))
+ #endif
+ #ifdef EBADF
+ /*
+ TRANS For example, I/O on a descriptor that has been
+ TRANS closed or reading from a descriptor open only for writing (or vice
+ TRANS versa). */
+-_S(ERR_MAP(EBADF), N_("Bad file descriptor"))
++_S(EBADF, N_("Bad file descriptor"))
+ #endif
+ #ifdef ECHILD
+ /*
+ TRANS This error happens on operations that are
+ TRANS supposed to manipulate child processes, when there aren't any processes
+ TRANS to manipulate. */
+-_S(ERR_MAP(ECHILD), N_("No child processes"))
++_S(ECHILD, N_("No child processes"))
+ #endif
+ #ifdef EDEADLK
+ /*
+@@ -79,74 +76,74 @@ TRANS Allocating a system resource would have resulted in a
+ TRANS deadlock situation. The system does not guarantee that it will notice
+ TRANS all such situations. This error means you got lucky and the system
+ TRANS noticed; it might just hang. @xref{File Locks}, for an example. */
+-_S(ERR_MAP(EDEADLK), N_("Resource deadlock avoided"))
++_S(EDEADLK, N_("Resource deadlock avoided"))
+ #endif
+ #ifdef ENOMEM
+ /*
+ TRANS The system cannot allocate more virtual memory
+ TRANS because its capacity is full. */
+-_S(ERR_MAP(ENOMEM), N_("Cannot allocate memory"))
++_S(ENOMEM, N_("Cannot allocate memory"))
+ #endif
+ #ifdef EACCES
+ /*
+ TRANS The file permissions do not allow the attempted operation. */
+-_S(ERR_MAP(EACCES), N_("Permission denied"))
++_S(EACCES, N_("Permission denied"))
+ #endif
+ #ifdef EFAULT
+ /*
+ TRANS An invalid pointer was detected.
+ TRANS On @gnuhurdsystems{}, this error never happens; you get a signal instead. */
+-_S(ERR_MAP(EFAULT), N_("Bad address"))
++_S(EFAULT, N_("Bad address"))
+ #endif
+ #ifdef ENOTBLK
+ /*
+ TRANS A file that isn't a block special file was given in a situation that
+ TRANS requires one. For example, trying to mount an ordinary file as a file
+ TRANS system in Unix gives this error. */
+-_S(ERR_MAP(ENOTBLK), N_("Block device required"))
++_S(ENOTBLK, N_("Block device required"))
+ #endif
+ #ifdef EBUSY
+ /*
+ TRANS A system resource that can't be shared is already in use.
+ TRANS For example, if you try to delete a file that is the root of a currently
+ TRANS mounted filesystem, you get this error. */
+-_S(ERR_MAP(EBUSY), N_("Device or resource busy"))
++_S(EBUSY, N_("Device or resource busy"))
+ #endif
+ #ifdef EEXIST
+ /*
+ TRANS An existing file was specified in a context where it only
+ TRANS makes sense to specify a new file. */
+-_S(ERR_MAP(EEXIST), N_("File exists"))
++_S(EEXIST, N_("File exists"))
+ #endif
+ #ifdef EXDEV
+ /*
+ TRANS An attempt to make an improper link across file systems was detected.
+ TRANS This happens not only when you use @code{link} (@pxref{Hard Links}) but
+ TRANS also when you rename a file with @code{rename} (@pxref{Renaming Files}). */
+-_S(ERR_MAP(EXDEV), N_("Invalid cross-device link"))
++_S(EXDEV, N_("Invalid cross-device link"))
+ #endif
+ #ifdef ENODEV
+ /*
+ TRANS The wrong type of device was given to a function that expects a
+ TRANS particular sort of device. */
+-_S(ERR_MAP(ENODEV), N_("No such device"))
++_S(ENODEV, N_("No such device"))
+ #endif
+ #ifdef ENOTDIR
+ /*
+ TRANS A file that isn't a directory was specified when a directory is required. */
+-_S(ERR_MAP(ENOTDIR), N_("Not a directory"))
++_S(ENOTDIR, N_("Not a directory"))
+ #endif
+ #ifdef EISDIR
+ /*
+ TRANS You cannot open a directory for writing,
+ TRANS or create or remove hard links to it. */
+-_S(ERR_MAP(EISDIR), N_("Is a directory"))
++_S(EISDIR, N_("Is a directory"))
+ #endif
+ #ifdef EINVAL
+ /*
+ TRANS This is used to indicate various kinds of problems
+ TRANS with passing the wrong argument to a library function. */
+-_S(ERR_MAP(EINVAL), N_("Invalid argument"))
++_S(EINVAL, N_("Invalid argument"))
+ #endif
+ #ifdef EMFILE
+ /*
+@@ -157,20 +154,20 @@ TRANS In BSD and GNU, the number of open files is controlled by a resource
+ TRANS limit that can usually be increased. If you get this error, you might
+ TRANS want to increase the @code{RLIMIT_NOFILE} limit or make it unlimited;
+ TRANS @pxref{Limits on Resources}. */
+-_S(ERR_MAP(EMFILE), N_("Too many open files"))
++_S(EMFILE, N_("Too many open files"))
+ #endif
+ #ifdef ENFILE
+ /*
+ TRANS There are too many distinct file openings in the entire system. Note
+ TRANS that any number of linked channels count as just one file opening; see
+ TRANS @ref{Linked Channels}. This error never occurs on @gnuhurdsystems{}. */
+-_S(ERR_MAP(ENFILE), N_("Too many open files in system"))
++_S(ENFILE, N_("Too many open files in system"))
+ #endif
+ #ifdef ENOTTY
+ /*
+ TRANS Inappropriate I/O control operation, such as trying to set terminal
+ TRANS modes on an ordinary file. */
+-_S(ERR_MAP(ENOTTY), N_("Inappropriate ioctl for device"))
++_S(ENOTTY, N_("Inappropriate ioctl for device"))
+ #endif
+ #ifdef ETXTBSY
+ /*
+@@ -179,35 +176,35 @@ TRANS write to a file that is currently being executed. Often using a
+ TRANS debugger to run a program is considered having it open for writing and
+ TRANS will cause this error. (The name stands for ``text file busy''.) This
+ TRANS is not an error on @gnuhurdsystems{}; the text is copied as necessary. */
+-_S(ERR_MAP(ETXTBSY), N_("Text file busy"))
++_S(ETXTBSY, N_("Text file busy"))
+ #endif
+ #ifdef EFBIG
+ /*
+ TRANS The size of a file would be larger than allowed by the system. */
+-_S(ERR_MAP(EFBIG), N_("File too large"))
++_S(EFBIG, N_("File too large"))
+ #endif
+ #ifdef ENOSPC
+ /*
+ TRANS Write operation on a file failed because the
+ TRANS disk is full. */
+-_S(ERR_MAP(ENOSPC), N_("No space left on device"))
++_S(ENOSPC, N_("No space left on device"))
+ #endif
+ #ifdef ESPIPE
+ /*
+ TRANS Invalid seek operation (such as on a pipe). */
+-_S(ERR_MAP(ESPIPE), N_("Illegal seek"))
++_S(ESPIPE, N_("Illegal seek"))
+ #endif
+ #ifdef EROFS
+ /*
+ TRANS An attempt was made to modify something on a read-only file system. */
+-_S(ERR_MAP(EROFS), N_("Read-only file system"))
++_S(EROFS, N_("Read-only file system"))
+ #endif
+ #ifdef EMLINK
+ /*
+ TRANS The link count of a single file would become too large.
+ TRANS @code{rename} can cause this error if the file being renamed already has
+ TRANS as many links as it can take (@pxref{Renaming Files}). */
+-_S(ERR_MAP(EMLINK), N_("Too many links"))
++_S(EMLINK, N_("Too many links"))
+ #endif
+ #ifdef EPIPE
+ /*
+@@ -216,19 +213,19 @@ TRANS Every library function that returns this error code also generates a
+ TRANS @code{SIGPIPE} signal; this signal terminates the program if not handled
+ TRANS or blocked. Thus, your program will never actually see @code{EPIPE}
+ TRANS unless it has handled or blocked @code{SIGPIPE}. */
+-_S(ERR_MAP(EPIPE), N_("Broken pipe"))
++_S(EPIPE, N_("Broken pipe"))
+ #endif
+ #ifdef EDOM
+ /*
+ TRANS Used by mathematical functions when an argument value does
+ TRANS not fall into the domain over which the function is defined. */
+-_S(ERR_MAP(EDOM), N_("Numerical argument out of domain"))
++_S(EDOM, N_("Numerical argument out of domain"))
+ #endif
+ #ifdef ERANGE
+ /*
+ TRANS Used by mathematical functions when the result value is
+ TRANS not representable because of overflow or underflow. */
+-_S(ERR_MAP(ERANGE), N_("Numerical result out of range"))
++_S(ERANGE, N_("Numerical result out of range"))
+ #endif
+ #ifdef EAGAIN
+ /*
+@@ -261,7 +258,7 @@ TRANS Such shortages are usually fairly serious and affect the whole system,
+ TRANS so usually an interactive program should report the error to the user
+ TRANS and return to its command loop.
+ TRANS @end itemize */
+-_S(ERR_MAP(EAGAIN), N_("Resource temporarily unavailable"))
++_S(EAGAIN, N_("Resource temporarily unavailable"))
+ #endif
+ #ifdef EINPROGRESS
+ /*
+@@ -273,47 +270,47 @@ TRANS the operation has begun and will take some time. Attempts to manipulate
+ TRANS the object before the call completes return @code{EALREADY}. You can
+ TRANS use the @code{select} function to find out when the pending operation
+ TRANS has completed; @pxref{Waiting for I/O}. */
+-_S(ERR_MAP(EINPROGRESS), N_("Operation now in progress"))
++_S(EINPROGRESS, N_("Operation now in progress"))
+ #endif
+ #ifdef EALREADY
+ /*
+ TRANS An operation is already in progress on an object that has non-blocking
+ TRANS mode selected. */
+-_S(ERR_MAP(EALREADY), N_("Operation already in progress"))
++_S(EALREADY, N_("Operation already in progress"))
+ #endif
+ #ifdef ENOTSOCK
+ /*
+ TRANS A file that isn't a socket was specified when a socket is required. */
+-_S(ERR_MAP(ENOTSOCK), N_("Socket operation on non-socket"))
++_S(ENOTSOCK, N_("Socket operation on non-socket"))
+ #endif
+ #ifdef EMSGSIZE
+ /*
+ TRANS The size of a message sent on a socket was larger than the supported
+ TRANS maximum size. */
+-_S(ERR_MAP(EMSGSIZE), N_("Message too long"))
++_S(EMSGSIZE, N_("Message too long"))
+ #endif
+ #ifdef EPROTOTYPE
+ /*
+ TRANS The socket type does not support the requested communications protocol. */
+-_S(ERR_MAP(EPROTOTYPE), N_("Protocol wrong type for socket"))
++_S(EPROTOTYPE, N_("Protocol wrong type for socket"))
+ #endif
+ #ifdef ENOPROTOOPT
+ /*
+ TRANS You specified a socket option that doesn't make sense for the
+ TRANS particular protocol being used by the socket. @xref{Socket Options}. */
+-_S(ERR_MAP(ENOPROTOOPT), N_("Protocol not available"))
++_S(ENOPROTOOPT, N_("Protocol not available"))
+ #endif
+ #ifdef EPROTONOSUPPORT
+ /*
+ TRANS The socket domain does not support the requested communications protocol
+ TRANS (perhaps because the requested protocol is completely invalid).
+ TRANS @xref{Creating a Socket}. */
+-_S(ERR_MAP(EPROTONOSUPPORT), N_("Protocol not supported"))
++_S(EPROTONOSUPPORT, N_("Protocol not supported"))
+ #endif
+ #ifdef ESOCKTNOSUPPORT
+ /*
+ TRANS The socket type is not supported. */
+-_S(ERR_MAP(ESOCKTNOSUPPORT), N_("Socket type not supported"))
++_S(ESOCKTNOSUPPORT, N_("Socket type not supported"))
+ #endif
+ #ifdef EOPNOTSUPP
+ /*
+@@ -323,71 +320,71 @@ TRANS implemented for all communications protocols. On @gnuhurdsystems{}, this
+ TRANS error can happen for many calls when the object does not support the
+ TRANS particular operation; it is a generic indication that the server knows
+ TRANS nothing to do for that call. */
+-_S(ERR_MAP(EOPNOTSUPP), N_("Operation not supported"))
++_S(EOPNOTSUPP, N_("Operation not supported"))
+ #endif
+ #ifdef EPFNOSUPPORT
+ /*
+ TRANS The socket communications protocol family you requested is not supported. */
+-_S(ERR_MAP(EPFNOSUPPORT), N_("Protocol family not supported"))
++_S(EPFNOSUPPORT, N_("Protocol family not supported"))
+ #endif
+ #ifdef EAFNOSUPPORT
+ /*
+ TRANS The address family specified for a socket is not supported; it is
+ TRANS inconsistent with the protocol being used on the socket. @xref{Sockets}. */
+-_S(ERR_MAP(EAFNOSUPPORT), N_("Address family not supported by protocol"))
++_S(EAFNOSUPPORT, N_("Address family not supported by protocol"))
+ #endif
+ #ifdef EADDRINUSE
+ /*
+ TRANS The requested socket address is already in use. @xref{Socket Addresses}. */
+-_S(ERR_MAP(EADDRINUSE), N_("Address already in use"))
++_S(EADDRINUSE, N_("Address already in use"))
+ #endif
+ #ifdef EADDRNOTAVAIL
+ /*
+ TRANS The requested socket address is not available; for example, you tried
+ TRANS to give a socket a name that doesn't match the local host name.
+ TRANS @xref{Socket Addresses}. */
+-_S(ERR_MAP(EADDRNOTAVAIL), N_("Cannot assign requested address"))
++_S(EADDRNOTAVAIL, N_("Cannot assign requested address"))
+ #endif
+ #ifdef ENETDOWN
+ /*
+ TRANS A socket operation failed because the network was down. */
+-_S(ERR_MAP(ENETDOWN), N_("Network is down"))
++_S(ENETDOWN, N_("Network is down"))
+ #endif
+ #ifdef ENETUNREACH
+ /*
+ TRANS A socket operation failed because the subnet containing the remote host
+ TRANS was unreachable. */
+-_S(ERR_MAP(ENETUNREACH), N_("Network is unreachable"))
++_S(ENETUNREACH, N_("Network is unreachable"))
+ #endif
+ #ifdef ENETRESET
+ /*
+ TRANS A network connection was reset because the remote host crashed. */
+-_S(ERR_MAP(ENETRESET), N_("Network dropped connection on reset"))
++_S(ENETRESET, N_("Network dropped connection on reset"))
+ #endif
+ #ifdef ECONNABORTED
+ /*
+ TRANS A network connection was aborted locally. */
+-_S(ERR_MAP(ECONNABORTED), N_("Software caused connection abort"))
++_S(ECONNABORTED, N_("Software caused connection abort"))
+ #endif
+ #ifdef ECONNRESET
+ /*
+ TRANS A network connection was closed for reasons outside the control of the
+ TRANS local host, such as by the remote machine rebooting or an unrecoverable
+ TRANS protocol violation. */
+-_S(ERR_MAP(ECONNRESET), N_("Connection reset by peer"))
++_S(ECONNRESET, N_("Connection reset by peer"))
+ #endif
+ #ifdef ENOBUFS
+ /*
+ TRANS The kernel's buffers for I/O operations are all in use. In GNU, this
+ TRANS error is always synonymous with @code{ENOMEM}; you may get one or the
+ TRANS other from network operations. */
+-_S(ERR_MAP(ENOBUFS), N_("No buffer space available"))
++_S(ENOBUFS, N_("No buffer space available"))
+ #endif
+ #ifdef EISCONN
+ /*
+ TRANS You tried to connect a socket that is already connected.
+ TRANS @xref{Connecting}. */
+-_S(ERR_MAP(EISCONN), N_("Transport endpoint is already connected"))
++_S(EISCONN, N_("Transport endpoint is already connected"))
+ #endif
+ #ifdef ENOTCONN
+ /*
+@@ -395,74 +392,74 @@ TRANS The socket is not connected to anything. You get this error when you
+ TRANS try to transmit data over a socket, without first specifying a
+ TRANS destination for the data. For a connectionless socket (for datagram
+ TRANS protocols, such as UDP), you get @code{EDESTADDRREQ} instead. */
+-_S(ERR_MAP(ENOTCONN), N_("Transport endpoint is not connected"))
++_S(ENOTCONN, N_("Transport endpoint is not connected"))
+ #endif
+ #ifdef EDESTADDRREQ
+ /*
+ TRANS No default destination address was set for the socket. You get this
+ TRANS error when you try to transmit data over a connectionless socket,
+ TRANS without first specifying a destination for the data with @code{connect}. */
+-_S(ERR_MAP(EDESTADDRREQ), N_("Destination address required"))
++_S(EDESTADDRREQ, N_("Destination address required"))
+ #endif
+ #ifdef ESHUTDOWN
+ /*
+ TRANS The socket has already been shut down. */
+-_S(ERR_MAP(ESHUTDOWN), N_("Cannot send after transport endpoint shutdown"))
++_S(ESHUTDOWN, N_("Cannot send after transport endpoint shutdown"))
+ #endif
+ #ifdef ETOOMANYREFS
+-_S(ERR_MAP(ETOOMANYREFS), N_("Too many references: cannot splice"))
++_S(ETOOMANYREFS, N_("Too many references: cannot splice"))
+ #endif
+ #ifdef ETIMEDOUT
+ /*
+ TRANS A socket operation with a specified timeout received no response during
+ TRANS the timeout period. */
+-_S(ERR_MAP(ETIMEDOUT), N_("Connection timed out"))
++_S(ETIMEDOUT, N_("Connection timed out"))
+ #endif
+ #ifdef ECONNREFUSED
+ /*
+ TRANS A remote host refused to allow the network connection (typically because
+ TRANS it is not running the requested service). */
+-_S(ERR_MAP(ECONNREFUSED), N_("Connection refused"))
++_S(ECONNREFUSED, N_("Connection refused"))
+ #endif
+ #ifdef ELOOP
+ /*
+ TRANS Too many levels of symbolic links were encountered in looking up a file name.
+ TRANS This often indicates a cycle of symbolic links. */
+-_S(ERR_MAP(ELOOP), N_("Too many levels of symbolic links"))
++_S(ELOOP, N_("Too many levels of symbolic links"))
+ #endif
+ #ifdef ENAMETOOLONG
+ /*
+ TRANS Filename too long (longer than @code{PATH_MAX}; @pxref{Limits for
+ TRANS Files}) or host name too long (in @code{gethostname} or
+ TRANS @code{sethostname}; @pxref{Host Identification}). */
+-_S(ERR_MAP(ENAMETOOLONG), N_("File name too long"))
++_S(ENAMETOOLONG, N_("File name too long"))
+ #endif
+ #ifdef EHOSTDOWN
+ /*
+ TRANS The remote host for a requested network connection is down. */
+-_S(ERR_MAP(EHOSTDOWN), N_("Host is down"))
++_S(EHOSTDOWN, N_("Host is down"))
+ #endif
+ /*
+ TRANS The remote host for a requested network connection is not reachable. */
+ #ifdef EHOSTUNREACH
+-_S(ERR_MAP(EHOSTUNREACH), N_("No route to host"))
++_S(EHOSTUNREACH, N_("No route to host"))
+ #endif
+ #ifdef ENOTEMPTY
+ /*
+ TRANS Directory not empty, where an empty directory was expected. Typically,
+ TRANS this error occurs when you are trying to delete a directory. */
+-_S(ERR_MAP(ENOTEMPTY), N_("Directory not empty"))
++_S(ENOTEMPTY, N_("Directory not empty"))
+ #endif
+ #ifdef EUSERS
+ /*
+ TRANS The file quota system is confused because there are too many users.
+ TRANS @c This can probably happen in a GNU system when using NFS. */
+-_S(ERR_MAP(EUSERS), N_("Too many users"))
++_S(EUSERS, N_("Too many users"))
+ #endif
+ #ifdef EDQUOT
+ /*
+ TRANS The user's disk quota was exceeded. */
+-_S(ERR_MAP(EDQUOT), N_("Disk quota exceeded"))
++_S(EDQUOT, N_("Disk quota exceeded"))
+ #endif
+ #ifdef ESTALE
+ /*
+@@ -471,7 +468,7 @@ TRANS file system which is due to file system rearrangements on the server host
+ TRANS for NFS file systems or corruption in other file systems.
+ TRANS Repairing this condition usually requires unmounting, possibly repairing
+ TRANS and remounting the file system. */
+-_S(ERR_MAP(ESTALE), N_("Stale file handle"))
++_S(ESTALE, N_("Stale file handle"))
+ #endif
+ #ifdef EREMOTE
+ /*
+@@ -479,7 +476,7 @@ TRANS An attempt was made to NFS-mount a remote file system with a file name tha
+ TRANS already specifies an NFS-mounted file.
+ TRANS (This is an error on some operating systems, but we expect it to work
+ TRANS properly on @gnuhurdsystems{}, making this error code impossible.) */
+-_S(ERR_MAP(EREMOTE), N_("Object is remote"))
++_S(EREMOTE, N_("Object is remote"))
+ #endif
+ #ifdef ENOLCK
+ /*
+@@ -487,7 +484,7 @@ TRANS This is used by the file locking facilities; see
+ TRANS @ref{File Locks}. This error is never generated by @gnuhurdsystems{}, but
+ TRANS it can result from an operation to an NFS server running another
+ TRANS operating system. */
+-_S(ERR_MAP(ENOLCK), N_("No locks available"))
++_S(ENOLCK, N_("No locks available"))
+ #endif
+ #ifdef ENOSYS
+ /*
+@@ -496,46 +493,46 @@ TRANS not implemented at all, either in the C library itself or in the
+ TRANS operating system. When you get this error, you can be sure that this
+ TRANS particular function will always fail with @code{ENOSYS} unless you
+ TRANS install a new version of the C library or the operating system. */
+-_S(ERR_MAP(ENOSYS), N_("Function not implemented"))
++_S(ENOSYS, N_("Function not implemented"))
+ #endif
+ #ifdef EILSEQ
+ /*
+ TRANS While decoding a multibyte character the function came along an invalid
+ TRANS or an incomplete sequence of bytes or the given wide character is invalid. */
+-_S(ERR_MAP(EILSEQ), N_("Invalid or incomplete multibyte or wide character"))
++_S(EILSEQ, N_("Invalid or incomplete multibyte or wide character"))
+ #endif
+ #ifdef EBADMSG
+-_S(ERR_MAP(EBADMSG), N_("Bad message"))
++_S(EBADMSG, N_("Bad message"))
+ #endif
+ #ifdef EIDRM
+-_S(ERR_MAP(EIDRM), N_("Identifier removed"))
++_S(EIDRM, N_("Identifier removed"))
+ #endif
+ #ifdef EMULTIHOP
+-_S(ERR_MAP(EMULTIHOP), N_("Multihop attempted"))
++_S(EMULTIHOP, N_("Multihop attempted"))
+ #endif
+ #ifdef ENODATA
+-_S(ERR_MAP(ENODATA), N_("No data available"))
++_S(ENODATA, N_("No data available"))
+ #endif
+ #ifdef ENOLINK
+-_S(ERR_MAP(ENOLINK), N_("Link has been severed"))
++_S(ENOLINK, N_("Link has been severed"))
+ #endif
+ #ifdef ENOMSG
+-_S(ERR_MAP(ENOMSG), N_("No message of desired type"))
++_S(ENOMSG, N_("No message of desired type"))
+ #endif
+ #ifdef ENOSR
+-_S(ERR_MAP(ENOSR), N_("Out of streams resources"))
++_S(ENOSR, N_("Out of streams resources"))
+ #endif
+ #ifdef ENOSTR
+-_S(ERR_MAP(ENOSTR), N_("Device not a stream"))
++_S(ENOSTR, N_("Device not a stream"))
+ #endif
+ #ifdef EOVERFLOW
+-_S(ERR_MAP(EOVERFLOW), N_("Value too large for defined data type"))
++_S(EOVERFLOW, N_("Value too large for defined data type"))
+ #endif
+ #ifdef EPROTO
+-_S(ERR_MAP(EPROTO), N_("Protocol error"))
++_S(EPROTO, N_("Protocol error"))
+ #endif
+ #ifdef ETIME
+-_S(ERR_MAP(ETIME), N_("Timer expired"))
++_S(ETIME, N_("Timer expired"))
+ #endif
+ #ifdef ECANCELED
+ /*
+@@ -543,148 +540,148 @@ TRANS An asynchronous operation was canceled before it
+ TRANS completed. @xref{Asynchronous I/O}. When you call @code{aio_cancel},
+ TRANS the normal result is for the operations affected to complete with this
+ TRANS error; @pxref{Cancel AIO Operations}. */
+-_S(ERR_MAP(ECANCELED), N_("Operation canceled"))
++_S(ECANCELED, N_("Operation canceled"))
+ #endif
+ #ifdef EOWNERDEAD
+-_S(ERR_MAP(EOWNERDEAD), N_("Owner died"))
++_S(EOWNERDEAD, N_("Owner died"))
+ #endif
+ #ifdef ENOTRECOVERABLE
+-_S(ERR_MAP(ENOTRECOVERABLE), N_("State not recoverable"))
++_S(ENOTRECOVERABLE, N_("State not recoverable"))
+ #endif
+ #ifdef ERESTART
+-_S(ERR_MAP(ERESTART), N_("Interrupted system call should be restarted"))
++_S(ERESTART, N_("Interrupted system call should be restarted"))
+ #endif
+ #ifdef ECHRNG
+-_S(ERR_MAP(ECHRNG), N_("Channel number out of range"))
++_S(ECHRNG, N_("Channel number out of range"))
+ #endif
+ #ifdef EL2NSYNC
+-_S(ERR_MAP(EL2NSYNC), N_("Level 2 not synchronized"))
++_S(EL2NSYNC, N_("Level 2 not synchronized"))
+ #endif
+ #ifdef EL3HLT
+-_S(ERR_MAP(EL3HLT), N_("Level 3 halted"))
++_S(EL3HLT, N_("Level 3 halted"))
+ #endif
+ #ifdef EL3RST
+-_S(ERR_MAP(EL3RST), N_("Level 3 reset"))
++_S(EL3RST, N_("Level 3 reset"))
+ #endif
+ #ifdef ELNRNG
+-_S(ERR_MAP(ELNRNG), N_("Link number out of range"))
++_S(ELNRNG, N_("Link number out of range"))
+ #endif
+ #ifdef EUNATCH
+-_S(ERR_MAP(EUNATCH), N_("Protocol driver not attached"))
++_S(EUNATCH, N_("Protocol driver not attached"))
+ #endif
+ #ifdef ENOCSI
+-_S(ERR_MAP(ENOCSI), N_("No CSI structure available"))
++_S(ENOCSI, N_("No CSI structure available"))
+ #endif
+ #ifdef EL2HLT
+-_S(ERR_MAP(EL2HLT), N_("Level 2 halted"))
++_S(EL2HLT, N_("Level 2 halted"))
+ #endif
+ #ifdef EBADE
+-_S(ERR_MAP(EBADE), N_("Invalid exchange"))
++_S(EBADE, N_("Invalid exchange"))
+ #endif
+ #ifdef EBADR
+-_S(ERR_MAP(EBADR), N_("Invalid request descriptor"))
++_S(EBADR, N_("Invalid request descriptor"))
+ #endif
+ #ifdef EXFULL
+-_S(ERR_MAP(EXFULL), N_("Exchange full"))
++_S(EXFULL, N_("Exchange full"))
+ #endif
+ #ifdef ENOANO
+-_S(ERR_MAP(ENOANO), N_("No anode"))
++_S(ENOANO, N_("No anode"))
+ #endif
+ #ifdef EBADRQC
+-_S(ERR_MAP(EBADRQC), N_("Invalid request code"))
++_S(EBADRQC, N_("Invalid request code"))
+ #endif
+ #ifdef EBADSLT
+-_S(ERR_MAP(EBADSLT), N_("Invalid slot"))
++_S(EBADSLT, N_("Invalid slot"))
+ #endif
+ #ifdef EBFONT
+-_S(ERR_MAP(EBFONT), N_("Bad font file format"))
++_S(EBFONT, N_("Bad font file format"))
+ #endif
+ #ifdef ENONET
+-_S(ERR_MAP(ENONET), N_("Machine is not on the network"))
++_S(ENONET, N_("Machine is not on the network"))
+ #endif
+ #ifdef ENOPKG
+-_S(ERR_MAP(ENOPKG), N_("Package not installed"))
++_S(ENOPKG, N_("Package not installed"))
+ #endif
+ #ifdef EADV
+-_S(ERR_MAP(EADV), N_("Advertise error"))
++_S(EADV, N_("Advertise error"))
+ #endif
+ #ifdef ESRMNT
+-_S(ERR_MAP(ESRMNT), N_("Srmount error"))
++_S(ESRMNT, N_("Srmount error"))
+ #endif
+ #ifdef ECOMM
+-_S(ERR_MAP(ECOMM), N_("Communication error on send"))
++_S(ECOMM, N_("Communication error on send"))
+ #endif
+ #ifdef EDOTDOT
+-_S(ERR_MAP(EDOTDOT), N_("RFS specific error"))
++_S(EDOTDOT, N_("RFS specific error"))
+ #endif
+ #ifdef ENOTUNIQ
+-_S(ERR_MAP(ENOTUNIQ), N_("Name not unique on network"))
++_S(ENOTUNIQ, N_("Name not unique on network"))
+ #endif
+ #ifdef EBADFD
+-_S(ERR_MAP(EBADFD), N_("File descriptor in bad state"))
++_S(EBADFD, N_("File descriptor in bad state"))
+ #endif
+ #ifdef EREMCHG
+-_S(ERR_MAP(EREMCHG), N_("Remote address changed"))
++_S(EREMCHG, N_("Remote address changed"))
+ #endif
+ #ifdef ELIBACC
+-_S(ERR_MAP(ELIBACC), N_("Can not access a needed shared library"))
++_S(ELIBACC, N_("Can not access a needed shared library"))
+ #endif
+ #ifdef ELIBBAD
+-_S(ERR_MAP(ELIBBAD), N_("Accessing a corrupted shared library"))
++_S(ELIBBAD, N_("Accessing a corrupted shared library"))
+ #endif
+ #ifdef ELIBSCN
+-_S(ERR_MAP(ELIBSCN), N_(".lib section in a.out corrupted"))
++_S(ELIBSCN, N_(".lib section in a.out corrupted"))
+ #endif
+ #ifdef ELIBMAX
+-_S(ERR_MAP(ELIBMAX), N_("Attempting to link in too many shared libraries"))
++_S(ELIBMAX, N_("Attempting to link in too many shared libraries"))
+ #endif
+ #ifdef ELIBEXEC
+-_S(ERR_MAP(ELIBEXEC), N_("Cannot exec a shared library directly"))
++_S(ELIBEXEC, N_("Cannot exec a shared library directly"))
+ #endif
+ #ifdef ESTRPIPE
+-_S(ERR_MAP(ESTRPIPE), N_("Streams pipe error"))
++_S(ESTRPIPE, N_("Streams pipe error"))
+ #endif
+ #ifdef EUCLEAN
+-_S(ERR_MAP(EUCLEAN), N_("Structure needs cleaning"))
++_S(EUCLEAN, N_("Structure needs cleaning"))
+ #endif
+ #ifdef ENOTNAM
+-_S(ERR_MAP(ENOTNAM), N_("Not a XENIX named type file"))
++_S(ENOTNAM, N_("Not a XENIX named type file"))
+ #endif
+ #ifdef ENAVAIL
+-_S(ERR_MAP(ENAVAIL), N_("No XENIX semaphores available"))
++_S(ENAVAIL, N_("No XENIX semaphores available"))
+ #endif
+ #ifdef EISNAM
+-_S(ERR_MAP(EISNAM), N_("Is a named type file"))
++_S(EISNAM, N_("Is a named type file"))
+ #endif
+ #ifdef EREMOTEIO
+-_S(ERR_MAP(EREMOTEIO), N_("Remote I/O error"))
++_S(EREMOTEIO, N_("Remote I/O error"))
+ #endif
+ #ifdef ENOMEDIUM
+-_S(ERR_MAP(ENOMEDIUM), N_("No medium found"))
++_S(ENOMEDIUM, N_("No medium found"))
+ #endif
+ #ifdef EMEDIUMTYPE
+-_S(ERR_MAP(EMEDIUMTYPE), N_("Wrong medium type"))
++_S(EMEDIUMTYPE, N_("Wrong medium type"))
+ #endif
+ #ifdef ENOKEY
+-_S(ERR_MAP(ENOKEY), N_("Required key not available"))
++_S(ENOKEY, N_("Required key not available"))
+ #endif
+ #ifdef EKEYEXPIRED
+-_S(ERR_MAP(EKEYEXPIRED), N_("Key has expired"))
++_S(EKEYEXPIRED, N_("Key has expired"))
+ #endif
+ #ifdef EKEYREVOKED
+-_S(ERR_MAP(EKEYREVOKED), N_("Key has been revoked"))
++_S(EKEYREVOKED, N_("Key has been revoked"))
+ #endif
+ #ifdef EKEYREJECTED
+-_S(ERR_MAP(EKEYREJECTED), N_("Key was rejected by service"))
++_S(EKEYREJECTED, N_("Key was rejected by service"))
+ #endif
+ #ifdef ERFKILL
+-_S(ERR_MAP(ERFKILL), N_("Operation not possible due to RF-kill"))
++_S(ERFKILL, N_("Operation not possible due to RF-kill"))
+ #endif
+ #ifdef EHWPOISON
+-_S(ERR_MAP(EHWPOISON), N_("Memory page has hardware error"))
++_S(EHWPOISON, N_("Memory page has hardware error"))
+ #endif
+ #ifdef EBADRPC
+-_S(ERR_MAP(EBADRPC), N_("RPC struct is bad"))
++_S(EBADRPC, N_("RPC struct is bad"))
+ #endif
+ #ifdef EFTYPE
+ /*
+@@ -693,40 +690,40 @@ TRANS operation, or a data file had the wrong format.
+ TRANS
+ TRANS On some systems @code{chmod} returns this error if you try to set the
+ TRANS sticky bit on a non-directory file; @pxref{Setting Permissions}. */
+-_S(ERR_MAP(EFTYPE), N_("Inappropriate file type or format"))
++_S(EFTYPE, N_("Inappropriate file type or format"))
+ #endif
+ #ifdef EPROCUNAVAIL
+-_S(ERR_MAP(EPROCUNAVAIL), N_("RPC bad procedure for program"))
++_S(EPROCUNAVAIL, N_("RPC bad procedure for program"))
+ #endif
+ #ifdef EAUTH
+-_S(ERR_MAP(EAUTH), N_("Authentication error"))
++_S(EAUTH, N_("Authentication error"))
+ #endif
+ #ifdef EDIED
+ /*
+ TRANS On @gnuhurdsystems{}, opening a file returns this error when the file is
+ TRANS translated by a program and the translator program dies while starting
+ TRANS up, before it has connected to the file. */
+-_S(ERR_MAP(EDIED), N_("Translator died"))
++_S(EDIED, N_("Translator died"))
+ #endif
+ #ifdef ERPCMISMATCH
+-_S(ERR_MAP(ERPCMISMATCH), N_("RPC version wrong"))
++_S(ERPCMISMATCH, N_("RPC version wrong"))
+ #endif
+ #ifdef EGREGIOUS
+ /*
+ TRANS You did @strong{what}? */
+-_S(ERR_MAP(EGREGIOUS), N_("You really blew it this time"))
++_S(EGREGIOUS, N_("You really blew it this time"))
+ #endif
+ #ifdef EPROCLIM
+ /*
+ TRANS This means that the per-user limit on new process would be exceeded by
+ TRANS an attempted @code{fork}. @xref{Limits on Resources}, for details on
+ TRANS the @code{RLIMIT_NPROC} limit. */
+-_S(ERR_MAP(EPROCLIM), N_("Too many processes"))
++_S(EPROCLIM, N_("Too many processes"))
+ #endif
+ #ifdef EGRATUITOUS
+ /*
+ TRANS This error code has no purpose. */
+-_S(ERR_MAP(EGRATUITOUS), N_("Gratuitous error"))
++_S(EGRATUITOUS, N_("Gratuitous error"))
+ #endif
+ #if defined (ENOTSUP) && ENOTSUP != EOPNOTSUPP
+ /*
+@@ -742,10 +739,10 @@ TRANS values.
+ TRANS
+ TRANS If the entire function is not available at all in the implementation,
+ TRANS it returns @code{ENOSYS} instead. */
+-_S(ERR_MAP(ENOTSUP), N_("Not supported"))
++_S(ENOTSUP, N_("Not supported"))
+ #endif
+ #ifdef EPROGMISMATCH
+-_S(ERR_MAP(EPROGMISMATCH), N_("RPC program version wrong"))
++_S(EPROGMISMATCH, N_("RPC program version wrong"))
+ #endif
+ #ifdef EBACKGROUND
+ /*
+@@ -755,7 +752,7 @@ TRANS foreground process group of the terminal. Users do not usually see this
+ TRANS error because functions such as @code{read} and @code{write} translate
+ TRANS it into a @code{SIGTTIN} or @code{SIGTTOU} signal. @xref{Job Control},
+ TRANS for information on process groups and these signals. */
+-_S(ERR_MAP(EBACKGROUND), N_("Inappropriate operation for background process"))
++_S(EBACKGROUND, N_("Inappropriate operation for background process"))
+ #endif
+ #ifdef EIEIO
+ /*
+@@ -773,7 +770,7 @@ TRANS @c "bought the farm" means "died". -jtobey
+ TRANS @c
+ TRANS @c Translators, please do not translate this litteraly, translate it into
+ TRANS @c an idiomatic funny way of saying that the computer died. */
+-_S(ERR_MAP(EIEIO), N_("Computer bought the farm"))
++_S(EIEIO, N_("Computer bought the farm"))
+ #endif
+ #if defined (EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ /*
+@@ -782,18 +779,18 @@ TRANS The values are always the same, on every operating system.
+ TRANS
+ TRANS C libraries in many older Unix systems have @code{EWOULDBLOCK} as a
+ TRANS separate error code. */
+-_S(ERR_MAP(EWOULDBLOCK), N_("Operation would block"))
++_S(EWOULDBLOCK, N_("Operation would block"))
+ #endif
+ #ifdef ENEEDAUTH
+-_S(ERR_MAP(ENEEDAUTH), N_("Need authenticator"))
++_S(ENEEDAUTH, N_("Need authenticator"))
+ #endif
+ #ifdef ED
+ /*
+ TRANS The experienced user will know what is wrong.
+ TRANS @c This error code is a joke. Its perror text is part of the joke.
+ TRANS @c Don't change it. */
+-_S(ERR_MAP(ED), N_("?"))
++_S(ED, N_("?"))
+ #endif
+ #ifdef EPROGUNAVAIL
+-_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
++++ b/sysdeps/unix/sysv/linux/Makefile
+@@ -100,7 +100,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
+ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
+ test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
+ tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
+- tst-tgkill
++ tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux tst-sysvshm-linux
+ 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/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
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+@@ -54,6 +54,10 @@
+ && MIDR_PARTNUM(midr) == 0x000)
+ #define IS_NEOVERSE_N1(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
+ && MIDR_PARTNUM(midr) == 0xd0c)
++#define IS_NEOVERSE_N2(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
++ && MIDR_PARTNUM(midr) == 0xd49)
++#define IS_NEOVERSE_V1(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
++ && MIDR_PARTNUM(midr) == 0xd40)
+
+ #define IS_EMAG(midr) (MIDR_IMPLEMENTOR(midr) == 'P' \
+ && MIDR_PARTNUM(midr) == 0x000)
+diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
+index 0776472d5e..a1f24ab242 100644
+--- a/sysdeps/unix/sysv/linux/msgctl.c
++++ b/sysdeps/unix/sysv/linux/msgctl.c
+@@ -90,8 +90,15 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
+ struct kernel_msqid64_ds ksemid, *arg = NULL;
+ if (buf != NULL)
+ {
+- msqid64_to_kmsqid64 (buf, &ksemid);
+- arg = &ksemid;
++ /* This is a Linux extension where kernel returns a 'struct msginfo'
++ instead. */
++ if (cmd == IPC_INFO || cmd == MSG_INFO)
++ arg = (struct kernel_msqid64_ds *) buf;
++ else
++ {
++ msqid64_to_kmsqid64 (buf, &ksemid);
++ arg = &ksemid;
++ }
+ }
+ # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+ if (cmd == IPC_SET)
+@@ -169,8 +176,15 @@ __msgctl (int msqid, int cmd, struct msqid_ds *buf)
+ struct __msqid64_ds msqid64, *buf64 = NULL;
+ if (buf != NULL)
+ {
+- msqid_to_msqid64 (&msqid64, buf);
+- buf64 = &msqid64;
++ /* This is a Linux extension where kernel returns a 'struct msginfo'
++ instead. */
++ if (cmd == IPC_INFO || cmd == MSG_INFO)
++ buf64 = (struct __msqid64_ds *) buf;
++ else
++ {
++ msqid_to_msqid64 (&msqid64, buf);
++ buf64 = &msqid64;
++ }
+ }
+
+ int ret = __msgctl64 (msqid, cmd, buf64);
+diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
+index f131a26fc7..1cdabde8f2 100644
+--- a/sysdeps/unix/sysv/linux/semctl.c
++++ b/sysdeps/unix/sysv/linux/semctl.c
+@@ -102,6 +102,7 @@ semun64_to_ksemun64 (int cmd, union semun64 semun64,
+ r.array = semun64.array;
+ break;
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_STAT:
+ case IPC_SET:
+ r.buf = buf;
+@@ -150,6 +151,7 @@ __semctl64 (int semid, int semnum, int cmd, ...)
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+@@ -238,6 +240,7 @@ semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
+ r.array = semun.array;
+ break;
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_STAT:
+ case IPC_SET:
+ r.buf = semid64;
+@@ -267,6 +270,7 @@ __semctl (int semid, int semnum, int cmd, ...)
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+@@ -321,6 +325,7 @@ __semctl_mode16 (int semid, int semnum, int cmd, ...)
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+@@ -354,6 +359,7 @@ __old_semctl (int semid, int semnum, int cmd, ...)
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ 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
++++ b/sysdeps/unix/sysv/linux/shmctl.c
+@@ -90,8 +90,15 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
+ struct kernel_shmid64_ds kshmid, *arg = NULL;
+ if (buf != NULL)
+ {
+- shmid64_to_kshmid64 (buf, &kshmid);
+- arg = &kshmid;
++ /* This is a Linux extension where kernel expects either a
++ 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO). */
++ if (cmd == IPC_INFO || cmd == SHM_INFO)
++ arg = (struct kernel_shmid64_ds *) buf;
++ else
++ {
++ shmid64_to_kshmid64 (buf, &kshmid);
++ arg = &kshmid;
++ }
+ }
+ # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+ if (cmd == IPC_SET)
+@@ -107,7 +114,6 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
+
+ switch (cmd)
+ {
+- case IPC_INFO:
+ case IPC_STAT:
+ case SHM_STAT:
+ case SHM_STAT_ANY:
+@@ -168,8 +174,15 @@ __shmctl (int shmid, int cmd, struct shmid_ds *buf)
+ struct __shmid64_ds shmid64, *buf64 = NULL;
+ if (buf != NULL)
+ {
+- shmid_to_shmid64 (&shmid64, buf);
+- buf64 = &shmid64;
++ /* This is a Linux extension where kernel expects either a
++ 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO). */
++ if (cmd == IPC_INFO || cmd == SHM_INFO)
++ buf64 = (struct __shmid64_ds *) buf;
++ else
++ {
++ shmid_to_shmid64 (&shmid64, buf);
++ buf64 = &shmid64;
++ }
+ }
+
+ int ret = __shmctl64 (shmid, cmd, buf64);
+@@ -178,7 +191,6 @@ __shmctl (int shmid, int cmd, struct shmid_ds *buf)
+
+ switch (cmd)
+ {
+- case IPC_INFO:
+ case IPC_STAT:
+ case SHM_STAT:
+ case SHM_STAT_ANY:
+diff --git a/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c b/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c
+new file mode 100644
+index 0000000000..630f4f792c
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c
+@@ -0,0 +1,177 @@
++/* Basic tests for Linux SYSV message queue extensions.
++ 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 <sys/ipc.h>
++#include <sys/msg.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <stdbool.h>
++#include <stdio.h>
++
++#include <support/check.h>
++#include <support/temp_file.h>
++
++#define MSGQ_MODE 0644
++
++/* These are for the temporary file we generate. */
++static char *name;
++static int msqid;
++
++static void
++remove_msq (void)
++{
++ /* Enforce message queue removal in case of early test failure.
++ Ignore error since the msg may already have being removed. */
++ msgctl (msqid, IPC_RMID, NULL);
++}
++
++static void
++do_prepare (int argc, char *argv[])
++{
++ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvmsg.", &name) != -1);
++}
++
++#define PREPARE do_prepare
++
++struct test_msginfo
++{
++ int msgmax;
++ int msgmnb;
++ int msgmni;
++};
++
++/* It tries to obtain some system-wide SysV messsage queue information from
++ /proc to check against IPC_INFO/MSG_INFO. The /proc only returns the
++ tunables value of MSGMAX, MSGMNB, and MSGMNI.
++
++ The kernel also returns constant value for MSGSSZ, MSGSEG and also MSGMAP,
++ MSGPOOL, and MSGTQL (for IPC_INFO). The issue to check them is they might
++ change over kernel releases. */
++
++static int
++read_proc_file (const char *file)
++{
++ FILE *f = fopen (file, "r");
++ if (f == NULL)
++ FAIL_UNSUPPORTED ("/proc is not mounted or %s is not available", file);
++
++ int v;
++ int r = fscanf (f, "%d", & v);
++ TEST_VERIFY_EXIT (r == 1);
++
++ fclose (f);
++ return v;
++}
++
++
++/* Check if the message queue with IDX (index into the kernel's internal
++ array) matches the one with KEY. The CMD is either MSG_STAT or
++ MSG_STAT_ANY. */
++
++static bool
++check_msginfo (int idx, key_t key, int cmd)
++{
++ struct msqid_ds msginfo;
++ int mid = msgctl (idx, cmd, &msginfo);
++ /* Ignore unused array slot returned by the kernel or information from
++ unknown message queue. */
++ if ((mid == -1 && errno == EINVAL) || mid != msqid)
++ return false;
++
++ if (mid == -1)
++ FAIL_EXIT1 ("msgctl with %s failed: %m",
++ cmd == MSG_STAT ? "MSG_STAT" : "MSG_STAT_ANY");
++
++ TEST_COMPARE (msginfo.msg_perm.__key, key);
++ TEST_COMPARE (msginfo.msg_perm.mode, MSGQ_MODE);
++ TEST_COMPARE (msginfo.msg_qnum, 0);
++
++ return true;
++}
++
++static int
++do_test (void)
++{
++ atexit (remove_msq);
++
++ key_t key = ftok (name, 'G');
++ if (key == -1)
++ FAIL_EXIT1 ("ftok failed: %m");
++
++ msqid = msgget (key, MSGQ_MODE | IPC_CREAT);
++ if (msqid == -1)
++ FAIL_EXIT1 ("msgget failed: %m");
++
++ struct test_msginfo tipcinfo;
++ tipcinfo.msgmax = read_proc_file ("/proc/sys/kernel/msgmax");
++ tipcinfo.msgmnb = read_proc_file ("/proc/sys/kernel/msgmnb");
++ tipcinfo.msgmni = read_proc_file ("/proc/sys/kernel/msgmni");
++
++ int msqidx;
++
++ {
++ struct msginfo ipcinfo;
++ msqidx = msgctl (msqid, IPC_INFO, (struct msqid_ds *) &ipcinfo);
++ if (msqidx == -1)
++ FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m");
++
++ TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax);
++ TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb);
++ TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni);
++ }
++
++ /* Same as before but with MSG_INFO. */
++ {
++ struct msginfo ipcinfo;
++ msqidx = msgctl (msqid, MSG_INFO, (struct msqid_ds *) &ipcinfo);
++ if (msqidx == -1)
++ FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m");
++
++ TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax);
++ TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb);
++ TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni);
++ }
++
++ /* We check if the created message queue shows in global list. */
++ bool found = false;
++ for (int i = 0; i <= msqidx; i++)
++ {
++ /* We can't tell apart if MSG_STAT_ANY is not supported (kernel older
++ than 4.17) or if the index used is invalid. So it just check if the
++ value returned from a valid call matches the created message
++ queue. */
++ check_msginfo (i, key, MSG_STAT_ANY);
++
++ if (check_msginfo (i, key, MSG_STAT))
++ {
++ found = true;
++ break;
++ }
++ }
++
++ if (!found)
++ FAIL_EXIT1 ("msgctl with MSG_STAT/MSG_STAT_ANY could not find the "
++ "created message queue");
++
++ if (msgctl (msqid, IPC_RMID, NULL) == -1)
++ FAIL_EXIT1 ("msgctl failed");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c b/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c
+new file mode 100644
+index 0000000000..45f19e2d37
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c
+@@ -0,0 +1,184 @@
++/* Basic tests for Linux SYSV semaphore extensions.
++ 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 <sys/ipc.h>
++#include <sys/sem.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <stdbool.h>
++#include <stdio.h>
++
++#include <support/check.h>
++#include <support/temp_file.h>
++
++/* These are for the temporary file we generate. */
++static char *name;
++static int semid;
++
++static void
++remove_sem (void)
++{
++ /* Enforce message queue removal in case of early test failure.
++ Ignore error since the sem may already have being removed. */
++ semctl (semid, 0, IPC_RMID, 0);
++}
++
++static void
++do_prepare (int argc, char *argv[])
++{
++ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvsem.", &name) != -1);
++}
++
++#define PREPARE do_prepare
++
++#define SEM_MODE 0644
++
++union semun
++{
++ int val;
++ struct semid_ds *buf;
++ unsigned short *array;
++ struct seminfo *__buf;
++};
++
++struct test_seminfo
++{
++ int semmsl;
++ int semmns;
++ int semopm;
++ int semmni;
++};
++
++/* It tries to obtain some system-wide SysV semaphore information from /proc
++ to check against IPC_INFO/SEM_INFO. The /proc only returns the tunables
++ value of SEMMSL, SEMMNS, SEMOPM, and SEMMNI.
++
++ The kernel also returns constant value for SEMVMX, SEMMNU, SEMMAP, SEMUME,
++ and also SEMUSZ and SEMAEM (for IPC_INFO). The issue to check them is they
++ might change over kernel releases. */
++
++static void
++read_sem_stat (struct test_seminfo *tseminfo)
++{
++ FILE *f = fopen ("/proc/sys/kernel/sem", "r");
++ if (f == NULL)
++ FAIL_UNSUPPORTED ("/proc is not mounted or /proc/sys/kernel/sem is not "
++ "available");
++
++ int r = fscanf (f, "%d %d %d %d",
++ &tseminfo->semmsl, &tseminfo->semmns, &tseminfo->semopm,
++ &tseminfo->semmni);
++ TEST_VERIFY_EXIT (r == 4);
++
++ fclose (f);
++}
++
++
++/* Check if the semaphore with IDX (index into the kernel's internal array)
++ matches the one with KEY. The CMD is either SEM_STAT or SEM_STAT_ANY. */
++
++static bool
++check_seminfo (int idx, key_t key, int cmd)
++{
++ struct semid_ds seminfo;
++ int sid = semctl (idx, 0, cmd, (union semun) { .buf = &seminfo });
++ /* Ignore unused array slot returned by the kernel or information from
++ unknown semaphores. */
++ if ((sid == -1 && errno == EINVAL) || sid != semid)
++ return false;
++
++ if (sid == -1)
++ FAIL_EXIT1 ("semctl with SEM_STAT failed (errno=%d)", errno);
++
++ TEST_COMPARE (seminfo.sem_perm.__key, key);
++ TEST_COMPARE (seminfo.sem_perm.mode, SEM_MODE);
++ TEST_COMPARE (seminfo.sem_nsems, 1);
++
++ return true;
++}
++
++static int
++do_test (void)
++{
++ atexit (remove_sem);
++
++ key_t key = ftok (name, 'G');
++ if (key == -1)
++ FAIL_EXIT1 ("ftok failed: %m");
++
++ semid = semget (key, 1, IPC_CREAT | IPC_EXCL | SEM_MODE);
++ if (semid == -1)
++ FAIL_EXIT1 ("semget failed: %m");
++
++ struct test_seminfo tipcinfo;
++ read_sem_stat (&tipcinfo);
++
++ int semidx;
++
++ {
++ struct seminfo ipcinfo;
++ semidx = semctl (semid, 0, IPC_INFO, (union semun) { .__buf = &ipcinfo });
++ if (semidx == -1)
++ FAIL_EXIT1 ("semctl with IPC_INFO failed: %m");
++
++ TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl);
++ TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns);
++ TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm);
++ TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni);
++ }
++
++ /* Same as before but with SEM_INFO. */
++ {
++ struct seminfo ipcinfo;
++ semidx = semctl (semid, 0, SEM_INFO, (union semun) { .__buf = &ipcinfo });
++ if (semidx == -1)
++ FAIL_EXIT1 ("semctl with IPC_INFO failed: %m");
++
++ TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl);
++ TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns);
++ TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm);
++ TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni);
++ }
++
++ /* We check if the created semaphore shows in the system-wide status. */
++ bool found = false;
++ for (int i = 0; i <= semidx; i++)
++ {
++ /* We can't tell apart if SEM_STAT_ANY is not supported (kernel older
++ than 4.17) or if the index used is invalid. So it just check if
++ value returned from a valid call matches the created semaphore. */
++ check_seminfo (i, key, SEM_STAT_ANY);
++
++ if (check_seminfo (i, key, SEM_STAT))
++ {
++ found = true;
++ break;
++ }
++ }
++
++ if (!found)
++ FAIL_EXIT1 ("semctl with SEM_STAT/SEM_STAT_ANY could not find the "
++ "created semaphore");
++
++ if (semctl (semid, 0, IPC_RMID, 0) == -1)
++ FAIL_EXIT1 ("semctl failed: %m");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
+new file mode 100644
+index 0000000000..7128ae2e14
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
+@@ -0,0 +1,185 @@
++/* Basic tests for Linux SYSV shared memory extensions.
++ 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 <sys/ipc.h>
++#include <sys/shm.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <unistd.h>
++#include <inttypes.h>
++#include <limits.h>
++
++#include <support/check.h>
++#include <support/temp_file.h>
++
++#define SHM_MODE 0644
++
++/* These are for the temporary file we generate. */
++static char *name;
++static int shmid;
++static long int pgsz;
++
++static void
++remove_shm (void)
++{
++ /* Enforce message queue removal in case of early test failure.
++ Ignore error since the shm may already have being removed. */
++ shmctl (shmid, IPC_RMID, NULL);
++}
++
++static void
++do_prepare (int argc, char *argv[])
++{
++ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvshm.", &name) != -1);
++}
++
++#define PREPARE do_prepare
++
++struct test_shminfo
++{
++ unsigned long int shmall;
++ unsigned long int shmmax;
++ unsigned long int shmmni;
++};
++
++/* It tries to obtain some system-wide SysV shared memory information from
++ /proc to check against IPC_INFO/SHM_INFO. The /proc only returns the
++ tunables value of SHMALL, SHMMAX, and SHMMNI. */
++
++static uint64_t
++read_proc_file (const char *file)
++{
++ FILE *f = fopen (file, "r");
++ if (f == NULL)
++ FAIL_UNSUPPORTED ("/proc is not mounted or %s is not available", file);
++
++ /* Handle 32-bit binaries running on 64-bit kernels. */
++ uint64_t v;
++ int r = fscanf (f, "%" SCNu64, &v);
++ TEST_VERIFY_EXIT (r == 1);
++
++ fclose (f);
++ return v;
++}
++
++
++/* Check if the message queue with IDX (index into the kernel's internal
++ array) matches the one with KEY. The CMD is either SHM_STAT or
++ SHM_STAT_ANY. */
++
++static bool
++check_shminfo (int idx, key_t key, int cmd)
++{
++ struct shmid_ds shminfo;
++ int sid = shmctl (idx, cmd, &shminfo);
++ /* Ignore unused array slot returned by the kernel or information from
++ unknown message queue. */
++ if ((sid == -1 && errno == EINVAL) || sid != shmid)
++ return false;
++
++ if (sid == -1)
++ FAIL_EXIT1 ("shmctl with %s failed: %m",
++ cmd == SHM_STAT ? "SHM_STAT" : "SHM_STAT_ANY");
++
++ TEST_COMPARE (shminfo.shm_perm.__key, key);
++ TEST_COMPARE (shminfo.shm_perm.mode, SHM_MODE);
++ TEST_COMPARE (shminfo.shm_segsz, pgsz);
++
++ return true;
++}
++
++static int
++do_test (void)
++{
++ atexit (remove_shm);
++
++ pgsz = sysconf (_SC_PAGESIZE);
++ if (pgsz == -1)
++ FAIL_EXIT1 ("sysconf (_SC_PAGESIZE) failed: %m");
++
++ key_t key = ftok (name, 'G');
++ if (key == -1)
++ FAIL_EXIT1 ("ftok failed: %m");
++
++ shmid = shmget (key, pgsz, IPC_CREAT | IPC_EXCL | SHM_MODE);
++ if (shmid == -1)
++ FAIL_EXIT1 ("shmget failed: %m");
++
++ struct test_shminfo tipcinfo;
++ {
++ uint64_t v = read_proc_file ("/proc/sys/kernel/shmmax");
++#if LONG_MAX == INT_MAX
++ /* Kernel explicit clamp the value for shmmax on compat symbol (32-bit
++ binaries running on 64-bit kernels). */
++ if (v > INT_MAX)
++ v = INT_MAX;
++#endif
++ tipcinfo.shmmax = v;
++ }
++ tipcinfo.shmall = read_proc_file ("/proc/sys/kernel/shmall");
++ tipcinfo.shmmni = read_proc_file ("/proc/sys/kernel/shmmni");
++
++ int shmidx;
++
++ /* Note: SHM_INFO does not return a shminfo, but rather a 'struct shm_info'.
++ It is tricky to verify its values since the syscall returns system wide
++ resources consumed by shared memory. The shmctl implementation handles
++ SHM_INFO as IPC_INFO, so the IPC_INFO test should validate SHM_INFO as
++ well. */
++
++ {
++ struct shminfo ipcinfo;
++ shmidx = shmctl (shmid, IPC_INFO, (struct shmid_ds *) &ipcinfo);
++ if (shmidx == -1)
++ FAIL_EXIT1 ("shmctl with IPC_INFO failed: %m");
++
++ TEST_COMPARE (ipcinfo.shmall, tipcinfo.shmall);
++ TEST_COMPARE (ipcinfo.shmmax, tipcinfo.shmmax);
++ TEST_COMPARE (ipcinfo.shmmni, tipcinfo.shmmni);
++ }
++
++ /* We check if the created shared memory shows in the global list. */
++ bool found = false;
++ for (int i = 0; i <= shmidx; i++)
++ {
++ /* We can't tell apart if SHM_STAT_ANY is not supported (kernel older
++ than 4.17) or if the index used is invalid. So it just check if
++ value returned from a valid call matches the created message
++ queue. */
++ check_shminfo (i, key, SHM_STAT_ANY);
++
++ if (check_shminfo (i, key, SHM_STAT))
++ {
++ found = true;
++ break;
++ }
++ }
++
++ if (!found)
++ FAIL_EXIT1 ("shmctl with SHM_STAT/SHM_STAT_ANY could not find the "
++ "created shared memory");
++
++ if (shmctl (shmid, IPC_RMID, NULL) == -1)
++ FAIL_EXIT1 ("shmctl failed");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+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
+
+ 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
++++ b/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h
+@@ -32,7 +32,7 @@ IFUNC_SELECTOR (void)
+ && CPU_FEATURE_USABLE_P (cpu_features, AVX2))
+ return OPTIMIZE (fma);
+
+- if (CPU_FEATURE_USABLE_P (cpu_features, FMA))
++ if (CPU_FEATURE_USABLE_P (cpu_features, FMA4))
+ 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
++++ b/sysvipc/test-sysvsem.c
+@@ -20,6 +20,7 @@
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <string.h>
++#include <stdbool.h>
+ #include <sys/types.h>
+ #include <sys/ipc.h>
+ #include <sys/sem.h>
+diff --git a/version.h b/version.h
+index 83cd196798..e6ca7a8857 100644
+--- a/version.h
++++ b/version.h
+@@ -1,4 +1,4 @@
+ /* This file just defines the current version number of libc. */
+
+-#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 },

Generated by cgit