diff --git a/SOURCES/SUPPORTED b/SOURCES/SUPPORTED
index 952f13d..a4bf79c 100644
--- a/SOURCES/SUPPORTED
+++ b/SOURCES/SUPPORTED
@@ -159,6 +159,7 @@ en_SG/ISO-8859-1 \
 en_US.UTF-8/UTF-8 \
 en_US/ISO-8859-1 \
 en_US.ISO-8859-15/ISO-8859-15 \
+en_US@ampm.UTF-8/UTF-8 \
 en_ZA.UTF-8/UTF-8 \
 en_ZA/ISO-8859-1 \
 en_ZM/UTF-8 \
diff --git a/SOURCES/glibc-rh1929928-1.patch b/SOURCES/glibc-rh1929928-1.patch
new file mode 100644
index 0000000..5e04ea2
--- /dev/null
+++ b/SOURCES/glibc-rh1929928-1.patch
@@ -0,0 +1,38 @@
+This patch is a downstream-only variant of this upstream commit:
+
+commit 45b1e17e9150dbd9ac2d578579063fbfa8e1b327
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Dec 17 10:03:05 2020 +0000
+
+    aarch64: use PTR_ARG and SIZE_ARG instead of DELOUSE
+    
+    DELOUSE was added to asm code to make them compatible with non-LP64
+    ABIs, but it is an unfortunate name and the code was not compatible
+    with ABIs where pointer and size_t are different. Glibc currently
+    only supports the LP64 ABI so these macros are not really needed or
+    tested, but for now the name is changed to be more meaningful instead
+    of removing them completely.
+    
+    Some DELOUSE macros were dropped: clone, strlen and strnlen used it
+    unnecessarily.
+    
+    The out of tree ILP32 patches are currently not maintained and will
+    likely need a rework to rebase them on top of the time64 changes.
+
+Keeping the DELOUSE macro avoids the need to update all string
+functions.  Lack of BTI markers and architecture variants cause many
+conflicts in a full upstream backport.
+
+diff --git a/sysdeps/aarch64/sysdep.h b/sysdeps/aarch64/sysdep.h
+index 5b30709436d3acea..1bcf15d4f18586ba 100644
+--- a/sysdeps/aarch64/sysdep.h
++++ b/sysdeps/aarch64/sysdep.h
+@@ -32,6 +32,8 @@
+ # define PTR_LOG_SIZE		2
+ # define DELOUSE(n)		mov     w##n, w##n
+ #endif
++#define PTR_ARG(n) DELOUSE(n)
++#define SIZE_ARG(n) DELOUSE(n)
+ 
+ #define PTR_SIZE	(1<<PTR_LOG_SIZE)
+ 
diff --git a/SOURCES/glibc-rh1929928-2.patch b/SOURCES/glibc-rh1929928-2.patch
new file mode 100644
index 0000000..a51310e
--- /dev/null
+++ b/SOURCES/glibc-rh1929928-2.patch
@@ -0,0 +1,88 @@
+commit 77d175e14e5f4cf24e9579c03eef5d006a286316
+Author: Naohiro Tamura <naohirot@jp.fujitsu.com>
+Date:   Wed May 12 09:26:40 2021 +0000
+
+    config: Added HAVE_AARCH64_SVE_ASM for aarch64
+    
+    This patch checks if assembler supports '-march=armv8.2-a+sve' to
+    generate SVE code or not, and then define HAVE_AARCH64_SVE_ASM macro.
+
+Conflicts:
+	config.h.in
+	  (missing PAC+BTI support downstream, missing other ports)
+
+diff --git a/config.h.in b/config.h.in
+index 8520b0fa8d4668fb..94d5ea367e10f849 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -112,6 +112,11 @@
+ /* AArch64 big endian ABI */
+ #undef HAVE_AARCH64_BE
+ 
++/* Assembler support ARMv8.2-A SVE.
++   This macro becomes obsolete when glibc increased the minimum
++   required version of GNU 'binutils' to 2.28 or later. */
++#define HAVE_AARCH64_SVE_ASM 0
++
+ /* RISC-V integer ABI for ld.so.  */
+ #undef RISCV_ABI_XLEN
+ 
+diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
+index f78a79338aba1e34..9fb713155d4ee6d8 100644
+--- a/sysdeps/aarch64/configure
++++ b/sysdeps/aarch64/configure
+@@ -212,3 +212,31 @@ fi
+ $as_echo "$libc_cv_aarch64_variant_pcs" >&6; }
+ config_vars="$config_vars
+ aarch64-variant-pcs = $libc_cv_aarch64_variant_pcs"
++
++# Check if asm support armv8.2-a+sve
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SVE support in assembler" >&5
++$as_echo_n "checking for SVE support in assembler... " >&6; }
++if ${libc_cv_asm_sve+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.s <<\EOF
++        ptrue p0.b
++EOF
++if { ac_try='${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&5'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then
++  libc_cv_aarch64_sve_asm=yes
++else
++  libc_cv_aarch64_sve_asm=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_sve" >&5
++$as_echo "$libc_cv_asm_sve" >&6; }
++if test $libc_cv_aarch64_sve_asm = yes; then
++  $as_echo "#define HAVE_AARCH64_SVE_ASM 1" >>confdefs.h
++
++fi
+diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
+index 7f13bfb93b60bfd7..0236cfcdf3c8d10d 100644
+--- a/sysdeps/aarch64/configure.ac
++++ b/sysdeps/aarch64/configure.ac
+@@ -42,3 +42,18 @@ EOF
+   fi
+   rm -rf conftest.*])
+ LIBC_CONFIG_VAR([aarch64-variant-pcs], [$libc_cv_aarch64_variant_pcs])
++
++# Check if asm support armv8.2-a+sve
++AC_CACHE_CHECK(for SVE support in assembler, libc_cv_asm_sve, [dnl
++cat > conftest.s <<\EOF
++        ptrue p0.b
++EOF
++if AC_TRY_COMMAND(${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&AS_MESSAGE_LOG_FD); then
++  libc_cv_aarch64_sve_asm=yes
++else
++  libc_cv_aarch64_sve_asm=no
++fi
++rm -f conftest*])
++if test $libc_cv_aarch64_sve_asm = yes; then
++  AC_DEFINE(HAVE_AARCH64_SVE_ASM)
++fi
diff --git a/SOURCES/glibc-rh1929928-3.patch b/SOURCES/glibc-rh1929928-3.patch
new file mode 100644
index 0000000..76ff1a2
--- /dev/null
+++ b/SOURCES/glibc-rh1929928-3.patch
@@ -0,0 +1,140 @@
+commit 38560563587ad8eafa700c56800ff844f18fbad1
+Author: Naohiro Tamura <naohirot@fujitsu.com>
+Date:   Thu May 20 07:34:37 2021 +0000
+
+    aarch64: Added Vector Length Set test helper script
+    
+    This patch is a test helper script to change Vector Length for child
+    process. This script can be used as test-wrapper for 'make check'.
+    
+    Usage examples:
+    
+    ~/build$ make check subdirs=string \
+    test-wrapper='~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 16'
+    
+    ~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 16 \
+    make test t=string/test-memcpy
+    
+    ~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 32 \
+    ./debugglibc.sh string/test-memmove
+    
+    ~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 64 \
+    ./testrun.sh string/test-memset
+
+diff --git a/INSTALL b/INSTALL
+index 065565093bd76d5b..b3a4370f592c5047 100644
+--- a/INSTALL
++++ b/INSTALL
+@@ -387,6 +387,10 @@ the same syntax as 'test-wrapper-env', the only difference in its
+ semantics being starting with an empty set of environment variables
+ rather than the ambient set.
+ 
++   For AArch64 with SVE, when testing the GNU C Library, 'test-wrapper'
++may be set to "SRCDIR/sysdeps/unix/sysv/linux/aarch64/vltest.py
++VECTOR-LENGTH" to change Vector Length.
++
+ Installing the C Library
+ ========================
+ 
+diff --git a/manual/install.texi b/manual/install.texi
+index 7e9f2be150e6f98a..c262fd56d0cef67b 100644
+--- a/manual/install.texi
++++ b/manual/install.texi
+@@ -425,6 +425,9 @@ use has the same syntax as @samp{test-wrapper-env}, the only
+ difference in its semantics being starting with an empty set of
+ environment variables rather than the ambient set.
+ 
++For AArch64 with SVE, when testing @theglibc{}, @samp{test-wrapper}
++may be set to "@var{srcdir}/sysdeps/unix/sysv/linux/aarch64/vltest.py
++@var{vector-length}" to change Vector Length.
+ 
+ @node Running make install
+ @appendixsec Installing the C Library
+diff --git a/sysdeps/unix/sysv/linux/aarch64/vltest.py b/sysdeps/unix/sysv/linux/aarch64/vltest.py
+new file mode 100755
+index 0000000000000000..bed62ad151e06868
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/aarch64/vltest.py
+@@ -0,0 +1,82 @@
++#!/usr/bin/python3
++# Set Scalable Vector Length test helper
++# 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/>.
++"""Set Scalable Vector Length test helper.
++
++Set Scalable Vector Length for child process.
++
++examples:
++
++~/build$ make check subdirs=string \
++test-wrapper='~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 16'
++
++~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 16 \
++make test t=string/test-memcpy
++
++~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 32 \
++./debugglibc.sh string/test-memmove
++
++~/build$ ~/glibc/sysdeps/unix/sysv/linux/aarch64/vltest.py 64 \
++./testrun.sh string/test-memset
++"""
++import argparse
++from ctypes import cdll, CDLL
++import os
++import sys
++
++EXIT_SUCCESS = 0
++EXIT_FAILURE = 1
++EXIT_UNSUPPORTED = 77
++
++AT_HWCAP = 16
++HWCAP_SVE = (1 << 22)
++
++PR_SVE_GET_VL = 51
++PR_SVE_SET_VL = 50
++PR_SVE_SET_VL_ONEXEC = (1 << 18)
++PR_SVE_VL_INHERIT = (1 << 17)
++PR_SVE_VL_LEN_MASK = 0xffff
++
++def main(args):
++    libc = CDLL("libc.so.6")
++    if not libc.getauxval(AT_HWCAP) & HWCAP_SVE:
++        print("CPU doesn't support SVE")
++        sys.exit(EXIT_UNSUPPORTED)
++
++    libc.prctl(PR_SVE_SET_VL,
++               args.vl[0] | PR_SVE_SET_VL_ONEXEC | PR_SVE_VL_INHERIT)
++    os.execvp(args.args[0], args.args)
++    print("exec system call failure")
++    sys.exit(EXIT_FAILURE)
++
++if __name__ == '__main__':
++    parser = argparse.ArgumentParser(description=
++            "Set Scalable Vector Length test helper",
++            formatter_class=argparse.ArgumentDefaultsHelpFormatter)
++
++    # positional argument
++    parser.add_argument("vl", nargs=1, type=int,
++                        choices=range(16, 257, 16),
++                        help=('vector length '\
++                              'which is multiples of 16 from 16 to 256'))
++    # remainDer arguments
++    parser.add_argument('args', nargs=argparse.REMAINDER,
++                        help=('args '\
++                              'which is passed to child process'))
++    args = parser.parse_args()
++    main(args)
diff --git a/SOURCES/glibc-rh1929928-4.patch b/SOURCES/glibc-rh1929928-4.patch
new file mode 100644
index 0000000..f2ec8e3
--- /dev/null
+++ b/SOURCES/glibc-rh1929928-4.patch
@@ -0,0 +1,623 @@
+commit fa527f345cbbe852ec085932fbea979956c195b5
+Author: Naohiro Tamura <naohirot@jp.fujitsu.com>
+Date:   Thu May 27 07:42:35 2021 +0000
+
+    aarch64: Added optimized memcpy and memmove for A64FX
+    
+    This patch optimizes the performance of memcpy/memmove for A64FX [1]
+    which implements ARMv8-A SVE and has L1 64KB cache per core and L2 8MB
+    cache per NUMA node.
+    
+    The performance optimization makes use of Scalable Vector Register
+    with several techniques such as loop unrolling, memory access
+    alignment, cache zero fill, and software pipelining.
+    
+    SVE assembler code for memcpy/memmove is implemented as Vector Length
+    Agnostic code so theoretically it can be run on any SOC which supports
+    ARMv8-A SVE standard.
+    
+    We confirmed that all testcases have been passed by running 'make
+    check' and 'make xcheck' not only on A64FX but also on ThunderX2.
+    
+    And also we confirmed that the SVE 512 bit vector register performance
+    is roughly 4 times better than Advanced SIMD 128 bit register and 8
+    times better than scalar 64 bit register by running 'make bench'.
+    
+    [1] https://github.com/fujitsu/A64FX
+    
+    Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
+    Reviewed-by: Szabolcs Nagy <Szabolcs.Nagy@arm.com>
+
+Conflicts:
+	manual/tunables.texi
+	sysdeps/aarch64/multiarch/Makefile
+	sysdeps/aarch64/multiarch/ifunc-impl-list.c
+	sysdeps/aarch64/multiarch/init-arch.h
+	sysdeps/aarch64/multiarch/memcpy.c
+	sysdeps/aarch64/multiarch/memmove.c
+	sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+	sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+	  (all conflicts due to missing optimizations for other CPUs)
+
+diff --git a/manual/tunables.texi b/manual/tunables.texi
+index bd737b5d57080462..07887981748bc44b 100644
+--- a/manual/tunables.texi
++++ b/manual/tunables.texi
+@@ -386,7 +386,7 @@ This tunable is specific to powerpc, powerpc64 and powerpc64le.
+ The @code{glibc.cpu.name=xxx} tunable allows the user to tell @theglibc{} to
+ assume that the CPU is @code{xxx} where xxx may have one of these values:
+ @code{generic}, @code{falkor}, @code{thunderxt88}, @code{thunderx2t99},
+-@code{thunderx2t99p1}.
++@code{thunderx2t99p1}, @code{a64fx}.
+ 
+ This tunable is specific to aarch64.
+ @end deftp
+diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
+index 57ffdf72382c0a44..5a19ba0308e80983 100644
+--- a/sysdeps/aarch64/multiarch/Makefile
++++ b/sysdeps/aarch64/multiarch/Makefile
+@@ -1,4 +1,5 @@
+ ifeq ($(subdir),string)
+ sysdep_routines += memcpy_generic memcpy_thunderx memcpy_thunderx2 \
+-		   memcpy_falkor memmove_falkor memset_generic memset_falkor
++		   memcpy_falkor memcpy_a64fx \
++		   memmove_falkor memset_generic memset_falkor
+ endif
+diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+index e55be80103b948a2..f53db12acce37877 100644
+--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+@@ -25,7 +25,7 @@
+ #include <stdio.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+-#define MAX_IFUNC	4
++#define MAX_IFUNC	7
+ 
+ size_t
+ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+@@ -42,10 +42,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_thunderx)
+ 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_thunderx2)
+ 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_falkor)
++#if HAVE_AARCH64_SVE_ASM
++	      IFUNC_IMPL_ADD (array, i, memcpy, sve, __memcpy_a64fx)
++#endif
+ 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic))
+   IFUNC_IMPL (i, name, memmove,
+ 	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_thunderx)
+ 	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_falkor)
++#if HAVE_AARCH64_SVE_ASM
++	      IFUNC_IMPL_ADD (array, i, memmove, sve, __memmove_a64fx)
++#endif
+ 	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic))
+   IFUNC_IMPL (i, name, memset,
+ 	      /* Enable this on non-falkor processors too so that other cores
+diff --git a/sysdeps/aarch64/multiarch/init-arch.h b/sysdeps/aarch64/multiarch/init-arch.h
+index d1e5703cb25fdcff..65dc8f82ff23c754 100644
+--- a/sysdeps/aarch64/multiarch/init-arch.h
++++ b/sysdeps/aarch64/multiarch/init-arch.h
+@@ -22,4 +22,6 @@
+   uint64_t __attribute__((unused)) midr =				      \
+     GLRO(dl_aarch64_cpu_features).midr_el1;				      \
+   unsigned __attribute__((unused)) zva_size =				      \
+-    GLRO(dl_aarch64_cpu_features).zva_size;
++    GLRO(dl_aarch64_cpu_features).zva_size;				      \
++  bool __attribute__((unused)) sve =					      \
++    GLRO(dl_aarch64_cpu_features).sve;
+diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
+index 4a04a63b0fe0c84b..e0313c42e82a7b86 100644
+--- a/sysdeps/aarch64/multiarch/memcpy.c
++++ b/sysdeps/aarch64/multiarch/memcpy.c
+@@ -32,6 +32,9 @@ extern __typeof (__redirect_memcpy) __memcpy_generic attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_thunderx attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_thunderx2 attribute_hidden;
+ extern __typeof (__redirect_memcpy) __memcpy_falkor attribute_hidden;
++# if HAVE_AARCH64_SVE_ASM
++extern __typeof (__redirect_memcpy) __memcpy_a64fx attribute_hidden;
++# endif
+ 
+ libc_ifunc (__libc_memcpy,
+             (IS_THUNDERX (midr)
+@@ -40,8 +43,13 @@ libc_ifunc (__libc_memcpy,
+ 		? __memcpy_falkor
+ 		: (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr)
+ 		  ? __memcpy_thunderx2
++# if HAVE_AARCH64_SVE_ASM
++		  : (IS_A64FX (midr)
++		     ? __memcpy_a64fx
++		     : __memcpy_generic)))));
++# else
+ 		  : __memcpy_generic))));
+-
++# endif
+ # undef memcpy
+ strong_alias (__libc_memcpy, memcpy);
+ #endif
+diff --git a/sysdeps/aarch64/multiarch/memcpy_a64fx.S b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
+new file mode 100644
+index 0000000000000000..65528405bb123737
+--- /dev/null
++++ b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
+@@ -0,0 +1,406 @@
++/* Optimized memcpy for Fujitsu A64FX processor.
++   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 <sysdep.h>
++
++/* Assumptions:
++ *
++ * ARMv8.2-a, AArch64, unaligned accesses, sve
++ *
++ */
++
++#define L2_SIZE		(8*1024*1024)/2	// L2 8MB/2
++#define CACHE_LINE_SIZE	256
++#define ZF_DIST		(CACHE_LINE_SIZE * 21)	// Zerofill distance
++#define dest		x0
++#define src		x1
++#define n		x2	// size
++#define tmp1		x3
++#define tmp2		x4
++#define tmp3		x5
++#define rest		x6
++#define dest_ptr	x7
++#define src_ptr		x8
++#define vector_length	x9
++#define cl_remainder	x10	// CACHE_LINE_SIZE remainder
++
++#if HAVE_AARCH64_SVE_ASM
++# if IS_IN (libc)
++#  define MEMCPY __memcpy_a64fx
++#  define MEMMOVE __memmove_a64fx
++
++	.arch armv8.2-a+sve
++
++	.macro dc_zva times
++	dc	zva, tmp1
++	add	tmp1, tmp1, CACHE_LINE_SIZE
++	.if \times-1
++	dc_zva "(\times-1)"
++	.endif
++	.endm
++
++	.macro ld1b_unroll8
++	ld1b	z0.b, p0/z, [src_ptr, #0, mul vl]
++	ld1b	z1.b, p0/z, [src_ptr, #1, mul vl]
++	ld1b	z2.b, p0/z, [src_ptr, #2, mul vl]
++	ld1b	z3.b, p0/z, [src_ptr, #3, mul vl]
++	ld1b	z4.b, p0/z, [src_ptr, #4, mul vl]
++	ld1b	z5.b, p0/z, [src_ptr, #5, mul vl]
++	ld1b	z6.b, p0/z, [src_ptr, #6, mul vl]
++	ld1b	z7.b, p0/z, [src_ptr, #7, mul vl]
++	.endm
++
++	.macro stld1b_unroll4a
++	st1b	z0.b, p0,   [dest_ptr, #0, mul vl]
++	st1b	z1.b, p0,   [dest_ptr, #1, mul vl]
++	ld1b	z0.b, p0/z, [src_ptr,  #0, mul vl]
++	ld1b	z1.b, p0/z, [src_ptr,  #1, mul vl]
++	st1b	z2.b, p0,   [dest_ptr, #2, mul vl]
++	st1b	z3.b, p0,   [dest_ptr, #3, mul vl]
++	ld1b	z2.b, p0/z, [src_ptr,  #2, mul vl]
++	ld1b	z3.b, p0/z, [src_ptr,  #3, mul vl]
++	.endm
++
++	.macro stld1b_unroll4b
++	st1b	z4.b, p0,   [dest_ptr, #4, mul vl]
++	st1b	z5.b, p0,   [dest_ptr, #5, mul vl]
++	ld1b	z4.b, p0/z, [src_ptr,  #4, mul vl]
++	ld1b	z5.b, p0/z, [src_ptr,  #5, mul vl]
++	st1b	z6.b, p0,   [dest_ptr, #6, mul vl]
++	st1b	z7.b, p0,   [dest_ptr, #7, mul vl]
++	ld1b	z6.b, p0/z, [src_ptr,  #6, mul vl]
++	ld1b	z7.b, p0/z, [src_ptr,  #7, mul vl]
++	.endm
++
++	.macro stld1b_unroll8
++	stld1b_unroll4a
++	stld1b_unroll4b
++	.endm
++
++	.macro st1b_unroll8
++	st1b	z0.b, p0, [dest_ptr, #0, mul vl]
++	st1b	z1.b, p0, [dest_ptr, #1, mul vl]
++	st1b	z2.b, p0, [dest_ptr, #2, mul vl]
++	st1b	z3.b, p0, [dest_ptr, #3, mul vl]
++	st1b	z4.b, p0, [dest_ptr, #4, mul vl]
++	st1b	z5.b, p0, [dest_ptr, #5, mul vl]
++	st1b	z6.b, p0, [dest_ptr, #6, mul vl]
++	st1b	z7.b, p0, [dest_ptr, #7, mul vl]
++	.endm
++
++	.macro shortcut_for_small_size exit
++	// if rest <= vector_length * 2
++	whilelo	p0.b, xzr, n
++	whilelo	p1.b, vector_length, n
++	b.last	1f
++	ld1b	z0.b, p0/z, [src, #0, mul vl]
++	ld1b	z1.b, p1/z, [src, #1, mul vl]
++	st1b	z0.b, p0, [dest, #0, mul vl]
++	st1b	z1.b, p1, [dest, #1, mul vl]
++	ret
++1:	// if rest > vector_length * 8
++	cmp	n, vector_length, lsl 3 // vector_length * 8
++	b.hi	\exit
++	// if rest <= vector_length * 4
++	lsl	tmp1, vector_length, 1  // vector_length * 2
++	whilelo	p2.b, tmp1, n
++	incb	tmp1
++	whilelo	p3.b, tmp1, n
++	b.last	1f
++	ld1b	z0.b, p0/z, [src, #0, mul vl]
++	ld1b	z1.b, p1/z, [src, #1, mul vl]
++	ld1b	z2.b, p2/z, [src, #2, mul vl]
++	ld1b	z3.b, p3/z, [src, #3, mul vl]
++	st1b	z0.b, p0, [dest, #0, mul vl]
++	st1b	z1.b, p1, [dest, #1, mul vl]
++	st1b	z2.b, p2, [dest, #2, mul vl]
++	st1b	z3.b, p3, [dest, #3, mul vl]
++	ret
++1:	// if rest <= vector_length * 8
++	lsl	tmp1, vector_length, 2  // vector_length * 4
++	whilelo	p4.b, tmp1, n
++	incb	tmp1
++	whilelo	p5.b, tmp1, n
++	b.last	1f
++	ld1b	z0.b, p0/z, [src, #0, mul vl]
++	ld1b	z1.b, p1/z, [src, #1, mul vl]
++	ld1b	z2.b, p2/z, [src, #2, mul vl]
++	ld1b	z3.b, p3/z, [src, #3, mul vl]
++	ld1b	z4.b, p4/z, [src, #4, mul vl]
++	ld1b	z5.b, p5/z, [src, #5, mul vl]
++	st1b	z0.b, p0, [dest, #0, mul vl]
++	st1b	z1.b, p1, [dest, #1, mul vl]
++	st1b	z2.b, p2, [dest, #2, mul vl]
++	st1b	z3.b, p3, [dest, #3, mul vl]
++	st1b	z4.b, p4, [dest, #4, mul vl]
++	st1b	z5.b, p5, [dest, #5, mul vl]
++	ret
++1:	lsl	tmp1, vector_length, 2	// vector_length * 4
++	incb	tmp1			// vector_length * 5
++	incb	tmp1			// vector_length * 6
++	whilelo	p6.b, tmp1, n
++	incb	tmp1
++	whilelo	p7.b, tmp1, n
++	ld1b	z0.b, p0/z, [src, #0, mul vl]
++	ld1b	z1.b, p1/z, [src, #1, mul vl]
++	ld1b	z2.b, p2/z, [src, #2, mul vl]
++	ld1b	z3.b, p3/z, [src, #3, mul vl]
++	ld1b	z4.b, p4/z, [src, #4, mul vl]
++	ld1b	z5.b, p5/z, [src, #5, mul vl]
++	ld1b	z6.b, p6/z, [src, #6, mul vl]
++	ld1b	z7.b, p7/z, [src, #7, mul vl]
++	st1b	z0.b, p0, [dest, #0, mul vl]
++	st1b	z1.b, p1, [dest, #1, mul vl]
++	st1b	z2.b, p2, [dest, #2, mul vl]
++	st1b	z3.b, p3, [dest, #3, mul vl]
++	st1b	z4.b, p4, [dest, #4, mul vl]
++	st1b	z5.b, p5, [dest, #5, mul vl]
++	st1b	z6.b, p6, [dest, #6, mul vl]
++	st1b	z7.b, p7, [dest, #7, mul vl]
++	ret
++	.endm
++
++ENTRY (MEMCPY)
++
++	PTR_ARG (0)
++	PTR_ARG (1)
++	SIZE_ARG (2)
++
++L(memcpy):
++	cntb	vector_length
++	// shortcut for less than vector_length * 8
++	// gives a free ptrue to p0.b for n >= vector_length
++	shortcut_for_small_size L(vl_agnostic)
++	// end of shortcut
++
++L(vl_agnostic): // VL Agnostic
++	mov	rest, n
++	mov	dest_ptr, dest
++	mov	src_ptr, src
++	// if rest >= L2_SIZE && vector_length == 64 then L(L2)
++	mov	tmp1, 64
++	cmp	rest, L2_SIZE
++	ccmp	vector_length, tmp1, 0, cs
++	b.eq	L(L2)
++
++L(unroll8): // unrolling and software pipeline
++	lsl	tmp1, vector_length, 3	// vector_length * 8
++	.p2align 3
++	cmp	 rest, tmp1
++	b.cc	L(last)
++	ld1b_unroll8
++	add	src_ptr, src_ptr, tmp1
++	sub	rest, rest, tmp1
++	cmp	rest, tmp1
++	b.cc	2f
++	.p2align 3
++1:	stld1b_unroll8
++	add	dest_ptr, dest_ptr, tmp1
++	add	src_ptr, src_ptr, tmp1
++	sub	rest, rest, tmp1
++	cmp	rest, tmp1
++	b.ge	1b
++2:	st1b_unroll8
++	add	dest_ptr, dest_ptr, tmp1
++
++	.p2align 3
++L(last):
++	whilelo	p0.b, xzr, rest
++	whilelo	p1.b, vector_length, rest
++	b.last	1f
++	ld1b	z0.b, p0/z, [src_ptr, #0, mul vl]
++	ld1b	z1.b, p1/z, [src_ptr, #1, mul vl]
++	st1b	z0.b, p0, [dest_ptr, #0, mul vl]
++	st1b	z1.b, p1, [dest_ptr, #1, mul vl]
++	ret
++1:	lsl	tmp1, vector_length, 1	// vector_length * 2
++	whilelo	p2.b, tmp1, rest
++	incb	tmp1
++	whilelo	p3.b, tmp1, rest
++	b.last	1f
++	ld1b	z0.b, p0/z, [src_ptr, #0, mul vl]
++	ld1b	z1.b, p1/z, [src_ptr, #1, mul vl]
++	ld1b	z2.b, p2/z, [src_ptr, #2, mul vl]
++	ld1b	z3.b, p3/z, [src_ptr, #3, mul vl]
++	st1b	z0.b, p0, [dest_ptr, #0, mul vl]
++	st1b	z1.b, p1, [dest_ptr, #1, mul vl]
++	st1b	z2.b, p2, [dest_ptr, #2, mul vl]
++	st1b	z3.b, p3, [dest_ptr, #3, mul vl]
++	ret
++1:	lsl	tmp1, vector_length, 2	// vector_length * 4
++	whilelo	p4.b, tmp1, rest
++	incb	tmp1
++	whilelo	p5.b, tmp1, rest
++	incb	tmp1
++	whilelo	p6.b, tmp1, rest
++	incb	tmp1
++	whilelo	p7.b, tmp1, rest
++	ld1b	z0.b, p0/z, [src_ptr, #0, mul vl]
++	ld1b	z1.b, p1/z, [src_ptr, #1, mul vl]
++	ld1b	z2.b, p2/z, [src_ptr, #2, mul vl]
++	ld1b	z3.b, p3/z, [src_ptr, #3, mul vl]
++	ld1b	z4.b, p4/z, [src_ptr, #4, mul vl]
++	ld1b	z5.b, p5/z, [src_ptr, #5, mul vl]
++	ld1b	z6.b, p6/z, [src_ptr, #6, mul vl]
++	ld1b	z7.b, p7/z, [src_ptr, #7, mul vl]
++	st1b	z0.b, p0, [dest_ptr, #0, mul vl]
++	st1b	z1.b, p1, [dest_ptr, #1, mul vl]
++	st1b	z2.b, p2, [dest_ptr, #2, mul vl]
++	st1b	z3.b, p3, [dest_ptr, #3, mul vl]
++	st1b	z4.b, p4, [dest_ptr, #4, mul vl]
++	st1b	z5.b, p5, [dest_ptr, #5, mul vl]
++	st1b	z6.b, p6, [dest_ptr, #6, mul vl]
++	st1b	z7.b, p7, [dest_ptr, #7, mul vl]
++	ret
++
++L(L2):
++	// align dest address at CACHE_LINE_SIZE byte boundary
++	mov	tmp1, CACHE_LINE_SIZE
++	ands	tmp2, dest_ptr, CACHE_LINE_SIZE - 1
++	// if cl_remainder == 0
++	b.eq	L(L2_dc_zva)
++	sub	cl_remainder, tmp1, tmp2
++	// process remainder until the first CACHE_LINE_SIZE boundary
++	whilelo	p1.b, xzr, cl_remainder	// keep p0.b all true
++	whilelo	p2.b, vector_length, cl_remainder
++	b.last	1f
++	ld1b	z1.b, p1/z, [src_ptr, #0, mul vl]
++	ld1b	z2.b, p2/z, [src_ptr, #1, mul vl]
++	st1b	z1.b, p1, [dest_ptr, #0, mul vl]
++	st1b	z2.b, p2, [dest_ptr, #1, mul vl]
++	b	2f
++1:	lsl	tmp1, vector_length, 1	// vector_length * 2
++	whilelo	p3.b, tmp1, cl_remainder
++	incb	tmp1
++	whilelo	p4.b, tmp1, cl_remainder
++	ld1b	z1.b, p1/z, [src_ptr, #0, mul vl]
++	ld1b	z2.b, p2/z, [src_ptr, #1, mul vl]
++	ld1b	z3.b, p3/z, [src_ptr, #2, mul vl]
++	ld1b	z4.b, p4/z, [src_ptr, #3, mul vl]
++	st1b	z1.b, p1, [dest_ptr, #0, mul vl]
++	st1b	z2.b, p2, [dest_ptr, #1, mul vl]
++	st1b	z3.b, p3, [dest_ptr, #2, mul vl]
++	st1b	z4.b, p4, [dest_ptr, #3, mul vl]
++2:	add	dest_ptr, dest_ptr, cl_remainder
++	add	src_ptr, src_ptr, cl_remainder
++	sub	rest, rest, cl_remainder
++
++L(L2_dc_zva):
++	// zero fill
++	and	tmp1, dest, 0xffffffffffffff
++	and	tmp2, src, 0xffffffffffffff
++	subs	tmp1, tmp1, tmp2	// diff
++	b.ge	1f
++	neg	tmp1, tmp1
++1:	mov	tmp3, ZF_DIST + CACHE_LINE_SIZE * 2
++	cmp	tmp1, tmp3
++	b.lo	L(unroll8)
++	mov	tmp1, dest_ptr
++	dc_zva	(ZF_DIST / CACHE_LINE_SIZE) - 1
++	// unroll
++	ld1b_unroll8	// this line has to be after "b.lo L(unroll8)"
++	add	 src_ptr, src_ptr, CACHE_LINE_SIZE * 2
++	sub	 rest, rest, CACHE_LINE_SIZE * 2
++	mov	 tmp1, ZF_DIST
++	.p2align 3
++1:	stld1b_unroll4a
++	add	tmp2, dest_ptr, tmp1	// dest_ptr + ZF_DIST
++	dc	zva, tmp2
++	stld1b_unroll4b
++	add	tmp2, tmp2, CACHE_LINE_SIZE
++	dc	zva, tmp2
++	add	dest_ptr, dest_ptr, CACHE_LINE_SIZE * 2
++	add	src_ptr, src_ptr, CACHE_LINE_SIZE * 2
++	sub	rest, rest, CACHE_LINE_SIZE * 2
++	cmp	rest, tmp3	// ZF_DIST + CACHE_LINE_SIZE * 2
++	b.ge	1b
++	st1b_unroll8
++	add	dest_ptr, dest_ptr, CACHE_LINE_SIZE * 2
++	b	L(unroll8)
++
++END (MEMCPY)
++libc_hidden_builtin_def (MEMCPY)
++
++
++ENTRY (MEMMOVE)
++
++	PTR_ARG (0)
++	PTR_ARG (1)
++	SIZE_ARG (2)
++
++	// remove tag address
++	// dest has to be immutable because it is the return value
++	// src has to be immutable because it is used in L(bwd_last)
++	and	tmp2, dest, 0xffffffffffffff	// save dest_notag into tmp2
++	and	tmp3, src, 0xffffffffffffff	// save src_notag intp tmp3
++	cmp	n, 0
++	ccmp	tmp2, tmp3, 4, ne
++	b.ne	1f
++	ret
++1:	cntb	vector_length
++	// shortcut for less than vector_length * 8
++	// gives a free ptrue to p0.b for n >= vector_length
++	// tmp2 and tmp3 should not be used in this macro to keep
++	// notag addresses
++	shortcut_for_small_size L(dispatch)
++	// end of shortcut
++
++L(dispatch):
++	// tmp2 = dest_notag, tmp3 = src_notag
++	// diff = dest_notag - src_notag
++	sub	tmp1, tmp2, tmp3
++	// if diff <= 0 || diff >= n then memcpy
++	cmp	tmp1, 0
++	ccmp	tmp1, n, 2, gt
++	b.cs	L(vl_agnostic)
++
++L(bwd_start):
++	mov	rest, n
++	add	dest_ptr, dest, n	// dest_end
++	add	src_ptr, src, n		// src_end
++
++L(bwd_unroll8): // unrolling and software pipeline
++	lsl	tmp1, vector_length, 3	// vector_length * 8
++	.p2align 3
++	cmp	rest, tmp1
++	b.cc	L(bwd_last)
++	sub	src_ptr, src_ptr, tmp1
++	ld1b_unroll8
++	sub	rest, rest, tmp1
++	cmp	rest, tmp1
++	b.cc	2f
++	.p2align 3
++1:	sub	src_ptr, src_ptr, tmp1
++	sub	dest_ptr, dest_ptr, tmp1
++	stld1b_unroll8
++	sub	rest, rest, tmp1
++	cmp	rest, tmp1
++	b.ge	1b
++2:	sub	dest_ptr, dest_ptr, tmp1
++	st1b_unroll8
++
++L(bwd_last):
++	mov	dest_ptr, dest
++	mov	src_ptr, src
++	b	L(last)
++
++END (MEMMOVE)
++libc_hidden_builtin_def (MEMMOVE)
++# endif /* IS_IN (libc) */
++#endif /* HAVE_AARCH64_SVE_ASM */
+diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
+index e69d8162910b938e..d96612b9cf7c3a4e 100644
+--- a/sysdeps/aarch64/multiarch/memmove.c
++++ b/sysdeps/aarch64/multiarch/memmove.c
+@@ -31,14 +31,22 @@ extern __typeof (__redirect_memmove) __libc_memmove;
+ extern __typeof (__redirect_memmove) __memmove_generic attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_thunderx attribute_hidden;
+ extern __typeof (__redirect_memmove) __memmove_falkor attribute_hidden;
++# if HAVE_AARCH64_SVE_ASM
++extern __typeof (__redirect_memmove) __memmove_a64fx attribute_hidden;
++# endif
+ 
+ libc_ifunc (__libc_memmove,
+             (IS_THUNDERX (midr)
+ 	     ? __memmove_thunderx
+ 	     : (IS_FALKOR (midr) || IS_PHECDA (midr)
+ 		? __memmove_falkor
++# if HAVE_AARCH64_SVE_ASM
++		: (IS_A64FX (midr)
++		   ? __memmove_a64fx
++		   : __memmove_generic))));
++# else
+ 		: __memmove_generic)));
+-
++# endif
+ # undef memmove
+ strong_alias (__libc_memmove, memmove);
+ #endif
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+index b4f348509eb1c6b3..71e4355c972f1ffb 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+@@ -36,6 +36,7 @@ static struct cpu_list cpu_list[] = {
+       {"thunderx2t99",   0x431F0AF0},
+       {"thunderx2t99p1", 0x420F5160},
+       {"phecda",	 0x680F0000},
++      {"a64fx",		 0x460F0010},
+       {"generic", 	 0x0}
+ };
+ 
+@@ -80,4 +81,7 @@ init_cpu_features (struct cpu_features *cpu_features)
+ 
+   if ((dczid & DCZID_DZP_MASK) == 0)
+     cpu_features->zva_size = 4 << (dczid & DCZID_BS_MASK);
++
++  /* Check if SVE is supported.  */
++  cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;
+ }
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+index eb35adfbe9d429d5..5691aea6de3cb7f4 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+@@ -20,6 +20,7 @@
+ #define _CPU_FEATURES_AARCH64_H
+ 
+ #include <stdint.h>
++#include <stdbool.h>
+ 
+ #define MIDR_PARTNUM_SHIFT	4
+ #define MIDR_PARTNUM_MASK	(0xfff << MIDR_PARTNUM_SHIFT)
+@@ -52,10 +53,14 @@
+ #define IS_PHECDA(midr) (MIDR_IMPLEMENTOR(midr) == 'h'			      \
+                         && MIDR_PARTNUM(midr) == 0x000)
+ 
++#define IS_A64FX(midr) (MIDR_IMPLEMENTOR(midr) == 'F'			      \
++			&& MIDR_PARTNUM(midr) == 0x001)
++
+ struct cpu_features
+ {
+   uint64_t midr_el1;
+   unsigned zva_size;
++  bool sve;
+ };
+ 
+ #endif /* _CPU_FEATURES_AARCH64_H  */
diff --git a/SOURCES/glibc-rh1929928-5.patch b/SOURCES/glibc-rh1929928-5.patch
new file mode 100644
index 0000000..7b5da7d
--- /dev/null
+++ b/SOURCES/glibc-rh1929928-5.patch
@@ -0,0 +1,371 @@
+commit 4f26956d5ba394eb3ade6c1c20b5c16864a00766
+Author: Naohiro Tamura <naohirot@jp.fujitsu.com>
+Date:   Thu May 27 07:44:12 2021 +0000
+
+    aarch64: Added optimized memset for A64FX
+    
+    This patch optimizes the performance of memset for A64FX [1] which
+    implements ARMv8-A SVE and has L1 64KB cache per core and L2 8MB cache
+    per NUMA node.
+    
+    The performance optimization makes use of Scalable Vector Register
+    with several techniques such as loop unrolling, memory access
+    alignment, cache zero fill and prefetch.
+    
+    SVE assembler code for memset is implemented as Vector Length Agnostic
+    code so theoretically it can be run on any SOC which supports ARMv8-A
+    SVE standard.
+    
+    We confirmed that all testcases have been passed by running 'make
+    check' and 'make xcheck' not only on A64FX but also on ThunderX2.
+    
+    And also we confirmed that the SVE 512 bit vector register performance
+    is roughly 4 times better than Advanced SIMD 128 bit register and 8
+    times better than scalar 64 bit register by running 'make bench'.
+    
+    [1] https://github.com/fujitsu/A64FX
+    
+    Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
+    Reviewed-by: Szabolcs Nagy <Szabolcs.Nagy@arm.com>
+
+Conflicts:
+	sysdeps/aarch64/multiarch/Makefile
+	sysdeps/aarch64/multiarch/ifunc-impl-list.c
+	sysdeps/aarch64/multiarch/memset.c
+	  (all conflicts due to missing other CPU implementations downstream)
+
+diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
+index 5a19ba0308e80983..5ff883a8ad8e3067 100644
+--- a/sysdeps/aarch64/multiarch/Makefile
++++ b/sysdeps/aarch64/multiarch/Makefile
+@@ -1,5 +1,6 @@
+ ifeq ($(subdir),string)
+ sysdep_routines += memcpy_generic memcpy_thunderx memcpy_thunderx2 \
+ 		   memcpy_falkor memcpy_a64fx \
+-		   memmove_falkor memset_generic memset_falkor
++		   memmove_falkor memset_generic memset_falkor \
++		   memset_a64fx
+ endif
+diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+index f53db12acce37877..53e3e162a1025e40 100644
+--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+@@ -37,7 +37,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   INIT_ARCH ();
+ 
+-  /* Support sysdeps/aarch64/multiarch/memcpy.c and memmove.c.  */
++  /* Support sysdeps/aarch64/multiarch/memcpy.c, memmove.c and memset.c.  */
+   IFUNC_IMPL (i, name, memcpy,
+ 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_thunderx)
+ 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_thunderx2)
+@@ -57,6 +57,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 	      /* Enable this on non-falkor processors too so that other cores
+ 		 can do a comparative analysis with __memset_generic.  */
+ 	      IFUNC_IMPL_ADD (array, i, memset, (zva_size == 64), __memset_falkor)
++#if HAVE_AARCH64_SVE_ASM
++	      IFUNC_IMPL_ADD (array, i, memset, sve, __memset_a64fx)
++#endif
+ 	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_generic))
+ 
+   return i;
+diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
+index d74ed3a549a54b10..2c8cc72bb0b18474 100644
+--- a/sysdeps/aarch64/multiarch/memset.c
++++ b/sysdeps/aarch64/multiarch/memset.c
+@@ -29,12 +29,21 @@
+ extern __typeof (__redirect_memset) __libc_memset;
+ 
+ extern __typeof (__redirect_memset) __memset_falkor attribute_hidden;
++# if HAVE_AARCH64_SVE_ASM
++extern __typeof (__redirect_memset) __memset_a64fx attribute_hidden;
++# endif
+ extern __typeof (__redirect_memset) __memset_generic attribute_hidden;
+ 
+ libc_ifunc (__libc_memset,
+ 	    ((IS_FALKOR (midr) || IS_PHECDA (midr)) && zva_size == 64
+ 	     ? __memset_falkor
++# if HAVE_AARCH64_SVE_ASM
++	     : (IS_A64FX (midr)
++		? __memset_a64fx
++		: __memset_generic)));
++# else
+ 	     : __memset_generic));
++# endif
+ 
+ # undef memset
+ strong_alias (__libc_memset, memset);
+diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
+new file mode 100644
+index 0000000000000000..ce54e5418b08c8bc
+--- /dev/null
++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
+@@ -0,0 +1,268 @@
++/* Optimized memset for Fujitsu A64FX processor.
++   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 <sysdep.h>
++#include <sysdeps/aarch64/memset-reg.h>
++
++/* Assumptions:
++ *
++ * ARMv8.2-a, AArch64, unaligned accesses, sve
++ *
++ */
++
++#define L1_SIZE		(64*1024)	// L1 64KB
++#define L2_SIZE         (8*1024*1024)	// L2 8MB - 1MB
++#define CACHE_LINE_SIZE	256
++#define PF_DIST_L1	(CACHE_LINE_SIZE * 16)	// Prefetch distance L1
++#define ZF_DIST		(CACHE_LINE_SIZE * 21)	// Zerofill distance
++#define rest		x8
++#define vector_length	x9
++#define vl_remainder	x10	// vector_length remainder
++#define cl_remainder	x11	// CACHE_LINE_SIZE remainder
++
++#if HAVE_AARCH64_SVE_ASM
++# if IS_IN (libc)
++#  define MEMSET __memset_a64fx
++
++	.arch armv8.2-a+sve
++
++	.macro dc_zva times
++	dc	zva, tmp1
++	add	tmp1, tmp1, CACHE_LINE_SIZE
++	.if \times-1
++	dc_zva "(\times-1)"
++	.endif
++	.endm
++
++	.macro st1b_unroll first=0, last=7
++	st1b	z0.b, p0, [dst, #\first, mul vl]
++	.if \last-\first
++	st1b_unroll "(\first+1)", \last
++	.endif
++	.endm
++
++	.macro shortcut_for_small_size exit
++	// if rest <= vector_length * 2
++	whilelo	p0.b, xzr, count
++	whilelo	p1.b, vector_length, count
++	b.last	1f
++	st1b	z0.b, p0, [dstin, #0, mul vl]
++	st1b	z0.b, p1, [dstin, #1, mul vl]
++	ret
++1:	// if rest > vector_length * 8
++	cmp	count, vector_length, lsl 3	// vector_length * 8
++	b.hi	\exit
++	// if rest <= vector_length * 4
++	lsl	tmp1, vector_length, 1	// vector_length * 2
++	whilelo	p2.b, tmp1, count
++	incb	tmp1
++	whilelo	p3.b, tmp1, count
++	b.last	1f
++	st1b	z0.b, p0, [dstin, #0, mul vl]
++	st1b	z0.b, p1, [dstin, #1, mul vl]
++	st1b	z0.b, p2, [dstin, #2, mul vl]
++	st1b	z0.b, p3, [dstin, #3, mul vl]
++	ret
++1:	// if rest <= vector_length * 8
++	lsl	tmp1, vector_length, 2	// vector_length * 4
++	whilelo	p4.b, tmp1, count
++	incb	tmp1
++	whilelo	p5.b, tmp1, count
++	b.last	1f
++	st1b	z0.b, p0, [dstin, #0, mul vl]
++	st1b	z0.b, p1, [dstin, #1, mul vl]
++	st1b	z0.b, p2, [dstin, #2, mul vl]
++	st1b	z0.b, p3, [dstin, #3, mul vl]
++	st1b	z0.b, p4, [dstin, #4, mul vl]
++	st1b	z0.b, p5, [dstin, #5, mul vl]
++	ret
++1:	lsl	tmp1, vector_length, 2	// vector_length * 4
++	incb	tmp1			// vector_length * 5
++	incb	tmp1			// vector_length * 6
++	whilelo	p6.b, tmp1, count
++	incb	tmp1
++	whilelo	p7.b, tmp1, count
++	st1b	z0.b, p0, [dstin, #0, mul vl]
++	st1b	z0.b, p1, [dstin, #1, mul vl]
++	st1b	z0.b, p2, [dstin, #2, mul vl]
++	st1b	z0.b, p3, [dstin, #3, mul vl]
++	st1b	z0.b, p4, [dstin, #4, mul vl]
++	st1b	z0.b, p5, [dstin, #5, mul vl]
++	st1b	z0.b, p6, [dstin, #6, mul vl]
++	st1b	z0.b, p7, [dstin, #7, mul vl]
++	ret
++	.endm
++
++ENTRY (MEMSET)
++
++	PTR_ARG (0)
++	SIZE_ARG (2)
++
++	cbnz	count, 1f
++	ret
++1:	dup	z0.b, valw
++	cntb	vector_length
++	// shortcut for less than vector_length * 8
++	// gives a free ptrue to p0.b for n >= vector_length
++	shortcut_for_small_size L(vl_agnostic)
++	// end of shortcut
++
++L(vl_agnostic): // VL Agnostic
++	mov	rest, count
++	mov	dst, dstin
++	add	dstend, dstin, count
++	// if rest >= L2_SIZE && vector_length == 64 then L(L2)
++	mov	tmp1, 64
++	cmp	rest, L2_SIZE
++	ccmp	vector_length, tmp1, 0, cs
++	b.eq	L(L2)
++	// if rest >= L1_SIZE && vector_length == 64 then L(L1_prefetch)
++	cmp	rest, L1_SIZE
++	ccmp	vector_length, tmp1, 0, cs
++	b.eq	L(L1_prefetch)
++
++L(unroll32):
++	lsl	tmp1, vector_length, 3	// vector_length * 8
++	lsl	tmp2, vector_length, 5	// vector_length * 32
++	.p2align 3
++1:	cmp	rest, tmp2
++	b.cc	L(unroll8)
++	st1b_unroll
++	add	dst, dst, tmp1
++	st1b_unroll
++	add	dst, dst, tmp1
++	st1b_unroll
++	add	dst, dst, tmp1
++	st1b_unroll
++	add	dst, dst, tmp1
++	sub	rest, rest, tmp2
++	b	1b
++
++L(unroll8):
++	lsl	tmp1, vector_length, 3
++	.p2align 3
++1:	cmp	rest, tmp1
++	b.cc	L(last)
++	st1b_unroll
++	add	dst, dst, tmp1
++	sub	rest, rest, tmp1
++	b	1b
++
++L(last):
++	whilelo	p0.b, xzr, rest
++	whilelo	p1.b, vector_length, rest
++	b.last	1f
++	st1b	z0.b, p0, [dst, #0, mul vl]
++	st1b	z0.b, p1, [dst, #1, mul vl]
++	ret
++1:	lsl	tmp1, vector_length, 1	// vector_length * 2
++	whilelo	p2.b, tmp1, rest
++	incb	tmp1
++	whilelo	p3.b, tmp1, rest
++	b.last	1f
++	st1b	z0.b, p0, [dst, #0, mul vl]
++	st1b	z0.b, p1, [dst, #1, mul vl]
++	st1b	z0.b, p2, [dst, #2, mul vl]
++	st1b	z0.b, p3, [dst, #3, mul vl]
++	ret
++1:	lsl	tmp1, vector_length, 2	// vector_length * 4
++	whilelo	p4.b, tmp1, rest
++	incb	tmp1
++	whilelo	p5.b, tmp1, rest
++	incb	tmp1
++	whilelo	p6.b, tmp1, rest
++	incb	tmp1
++	whilelo	p7.b, tmp1, rest
++	st1b	z0.b, p0, [dst, #0, mul vl]
++	st1b	z0.b, p1, [dst, #1, mul vl]
++	st1b	z0.b, p2, [dst, #2, mul vl]
++	st1b	z0.b, p3, [dst, #3, mul vl]
++	st1b	z0.b, p4, [dst, #4, mul vl]
++	st1b	z0.b, p5, [dst, #5, mul vl]
++	st1b	z0.b, p6, [dst, #6, mul vl]
++	st1b	z0.b, p7, [dst, #7, mul vl]
++	ret
++
++L(L1_prefetch): // if rest >= L1_SIZE
++	.p2align 3
++1:	st1b_unroll 0, 3
++	prfm	pstl1keep, [dst, PF_DIST_L1]
++	st1b_unroll 4, 7
++	prfm	pstl1keep, [dst, PF_DIST_L1 + CACHE_LINE_SIZE]
++	add	dst, dst, CACHE_LINE_SIZE * 2
++	sub	rest, rest, CACHE_LINE_SIZE * 2
++	cmp	rest, L1_SIZE
++	b.ge	1b
++	cbnz	rest, L(unroll32)
++	ret
++
++L(L2):
++	// align dst address at vector_length byte boundary
++	sub	tmp1, vector_length, 1
++	ands	tmp2, dst, tmp1
++	// if vl_remainder == 0
++	b.eq	1f
++	sub	vl_remainder, vector_length, tmp2
++	// process remainder until the first vector_length boundary
++	whilelt	p2.b, xzr, vl_remainder
++	st1b	z0.b, p2, [dst]
++	add	dst, dst, vl_remainder
++	sub	rest, rest, vl_remainder
++	// align dstin address at CACHE_LINE_SIZE byte boundary
++1:	mov	tmp1, CACHE_LINE_SIZE
++	ands	tmp2, dst, CACHE_LINE_SIZE - 1
++	// if cl_remainder == 0
++	b.eq	L(L2_dc_zva)
++	sub	cl_remainder, tmp1, tmp2
++	// process remainder until the first CACHE_LINE_SIZE boundary
++	mov	tmp1, xzr       // index
++2:	whilelt	p2.b, tmp1, cl_remainder
++	st1b	z0.b, p2, [dst, tmp1]
++	incb	tmp1
++	cmp	tmp1, cl_remainder
++	b.lo	2b
++	add	dst, dst, cl_remainder
++	sub	rest, rest, cl_remainder
++
++L(L2_dc_zva):
++	// zero fill
++	mov	tmp1, dst
++	dc_zva	(ZF_DIST / CACHE_LINE_SIZE) - 1
++	mov	zva_len, ZF_DIST
++	add	tmp1, zva_len, CACHE_LINE_SIZE * 2
++	// unroll
++	.p2align 3
++1:	st1b_unroll 0, 3
++	add	tmp2, dst, zva_len
++	dc	 zva, tmp2
++	st1b_unroll 4, 7
++	add	tmp2, tmp2, CACHE_LINE_SIZE
++	dc	zva, tmp2
++	add	dst, dst, CACHE_LINE_SIZE * 2
++	sub	rest, rest, CACHE_LINE_SIZE * 2
++	cmp	rest, tmp1	// ZF_DIST + CACHE_LINE_SIZE * 2
++	b.ge	1b
++	cbnz	rest, L(unroll8)
++	ret
++
++END (MEMSET)
++libc_hidden_builtin_def (MEMSET)
++
++#endif /* IS_IN (libc) */
++#endif /* HAVE_AARCH64_SVE_ASM */
diff --git a/SOURCES/glibc-rh1934162-1.patch b/SOURCES/glibc-rh1934162-1.patch
new file mode 100644
index 0000000..3a50009
--- /dev/null
+++ b/SOURCES/glibc-rh1934162-1.patch
@@ -0,0 +1,159 @@
+From 332421312576bd7095e70589154af99b124dd2d1 Mon Sep 17 00:00:00 2001
+From: Carlos O'Donell <carlos@redhat.com>
+Date: Fri, 12 Mar 2021 16:44:47 +0100
+Subject: elf: Always set l in _dl_init_paths (bug 23462)
+
+After d1d5471579eb0426671bf94f2d71e61dfb204c30 ("Remove dead
+DL_DST_REQ_STATIC code.") we always setup the link map l to make the
+static and shared cases the same.  The bug is that in elf/dl-load.c
+(_dl_init_paths) we conditionally set l only in the #ifdef SHARED
+case, but unconditionally use it later.  The simple solution is to
+remove the #ifdef SHARED conditional, because it's no longer needed,
+and unconditionally setup l for both the static and shared cases. A
+regression test is added to run a static binary with
+LD_LIBRARY_PATH='$ORIGIN' which crashes before the fix and runs after
+the fix.
+
+Co-Authored-By: Florian Weimer <fweimer@redhat.com>
+
+diff --git a/elf/Makefile b/elf/Makefile
+--- a/elf/Makefile	2021-11-02 16:28:14.720143774 -0400
++++ b/elf/Makefile	2021-11-02 18:42:38.763843571 -0400
+@@ -151,7 +151,8 @@ endif
+ tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
+ 	       tst-dl-iter-static \
+ 	       tst-tlsalign-static tst-tlsalign-extern-static \
+-	       tst-linkall-static tst-env-setuid tst-env-setuid-tunables
++	       tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
++	       tst-dst-static
+ tests-static-internal := tst-tls1-static tst-tls2-static \
+ 	       tst-ptrguard1-static tst-stackguard1-static \
+ 	       tst-tls1-static-non-pie tst-libc_dlvsym-static
+@@ -1811,3 +1812,5 @@ $(objpfx)tst-glibc-hwcaps-mask.out: \
+ # Generic dependency for sysdeps implementation of
+ # tst-glibc-hwcaps-cache.
+ $(objpfx)tst-glibc-hwcaps-cache.out: $(objpfx)tst-glibc-hwcaps
++
++tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN'
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 9e2089cfaa..376a2e64d6 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -758,50 +758,45 @@ _dl_init_paths (const char *llp, const char *source,
+   max_dirnamelen = SYSTEM_DIRS_MAX_LEN;
+   *aelem = NULL;
+ 
+-#ifdef SHARED
+   /* This points to the map of the main object.  */
+   l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+-  if (l != NULL)
++  assert (l->l_type != lt_loaded);
++
++  if (l->l_info[DT_RUNPATH])
++    {
++      /* Allocate room for the search path and fill in information
++	 from RUNPATH.  */
++      decompose_rpath (&l->l_runpath_dirs,
++		       (const void *) (D_PTR (l, l_info[DT_STRTAB])
++				       + l->l_info[DT_RUNPATH]->d_un.d_val),
++		       l, "RUNPATH");
++      /* During rtld init the memory is allocated by the stub malloc,
++	 prevent any attempt to free it by the normal malloc.  */
++      l->l_runpath_dirs.malloced = 0;
++
++      /* The RPATH is ignored.  */
++      l->l_rpath_dirs.dirs = (void *) -1;
++    }
++  else
+     {
+-      assert (l->l_type != lt_loaded);
++      l->l_runpath_dirs.dirs = (void *) -1;
+ 
+-      if (l->l_info[DT_RUNPATH])
++      if (l->l_info[DT_RPATH])
+ 	{
+ 	  /* Allocate room for the search path and fill in information
+-	     from RUNPATH.  */
+-	  decompose_rpath (&l->l_runpath_dirs,
++	     from RPATH.  */
++	  decompose_rpath (&l->l_rpath_dirs,
+ 			   (const void *) (D_PTR (l, l_info[DT_STRTAB])
+-					   + l->l_info[DT_RUNPATH]->d_un.d_val),
+-			   l, "RUNPATH");
+-	  /* During rtld init the memory is allocated by the stub malloc,
+-	     prevent any attempt to free it by the normal malloc.  */
+-	  l->l_runpath_dirs.malloced = 0;
+-
+-	  /* The RPATH is ignored.  */
+-	  l->l_rpath_dirs.dirs = (void *) -1;
++					   + l->l_info[DT_RPATH]->d_un.d_val),
++			   l, "RPATH");
++	  /* During rtld init the memory is allocated by the stub
++	     malloc, prevent any attempt to free it by the normal
++	     malloc.  */
++	  l->l_rpath_dirs.malloced = 0;
+ 	}
+       else
+-	{
+-	  l->l_runpath_dirs.dirs = (void *) -1;
+-
+-	  if (l->l_info[DT_RPATH])
+-	    {
+-	      /* Allocate room for the search path and fill in information
+-		 from RPATH.  */
+-	      decompose_rpath (&l->l_rpath_dirs,
+-			       (const void *) (D_PTR (l, l_info[DT_STRTAB])
+-					       + l->l_info[DT_RPATH]->d_un.d_val),
+-			       l, "RPATH");
+-	      /* During rtld init the memory is allocated by the stub
+-		 malloc, prevent any attempt to free it by the normal
+-		 malloc.  */
+-	      l->l_rpath_dirs.malloced = 0;
+-	    }
+-	  else
+-	    l->l_rpath_dirs.dirs = (void *) -1;
+-	}
++	l->l_rpath_dirs.dirs = (void *) -1;
+     }
+-#endif	/* SHARED */
+ 
+   if (llp != NULL && *llp != '\0')
+     {
+diff --git a/elf/tst-dst-static.c b/elf/tst-dst-static.c
+new file mode 100644
+index 0000000000..56eb371c96
+--- /dev/null
++++ b/elf/tst-dst-static.c
+@@ -0,0 +1,32 @@
++/* Test DST expansion for static binaries doesn't carsh.  Bug 23462.
++   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/>.  */
++
++/* The purpose of this test is to exercise the code in elf/dl-loac.c
++   (_dl_init_paths) or thereabout and ensure that static binaries
++   don't crash when expanding DSTs.
++
++   If the dynamic loader code linked into the static binary cannot
++   handle expanding the DSTs e.g. null-deref on an incomplete link
++   map, then it will crash before reaching main, so the test harness
++   is unnecessary.  */
++
++int
++main (void)
++{
++  return 0;
++}
diff --git a/SOURCES/glibc-rh1934162-2.patch b/SOURCES/glibc-rh1934162-2.patch
new file mode 100644
index 0000000..aad6dab
--- /dev/null
+++ b/SOURCES/glibc-rh1934162-2.patch
@@ -0,0 +1,74 @@
+From 4e6db99c665d3b82a70a3e218860ef087b1555b4 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 15 Mar 2021 10:33:43 +0100
+Subject: elf: ld.so --help calls _dl_init_paths without a main map [BZ #27577]
+
+In this case, use the link map of the dynamic loader itself as
+a replacement.  This is more than just a hack: if we ever support
+DT_RUNPATH/DT_RPATH for the dynamic loader, reporting it for
+ld.so --help (without further command line arguments) would be the
+right thing to do.
+
+Fixes commit 332421312576bd7095e70589154af99b124dd2d1 ("elf: Always
+set l in _dl_init_paths (bug 23462)").
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 4c9e63dac9..ba4689a7fa 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -231,7 +231,7 @@ tests += $(tests-execstack-$(have-z-execstack))
+ ifeq ($(run-built-tests),yes)
+ tests-special += $(objpfx)tst-leaks1-mem.out \
+ 		 $(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
+-		 $(objpfx)tst-ldconfig-X.out
++		 $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out
+ endif
+ tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+ tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+@@ -409,7 +409,8 @@ endif
+ ifeq (yes,$(build-shared))
+ ifeq ($(run-built-tests),yes)
+ tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \
+-		 $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out
++		 $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out \
++		 $(objpfx)tst-rtld-help.out
+ endif
+ tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \
+ 		 $(objpfx)check-wx-segment.out \
+@@ -1814,3 +1815,16 @@ $(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so
+ $(objpfx)tst-glibc-hwcaps-cache.out: $(objpfx)tst-glibc-hwcaps
+ 
+ tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN'
++
++$(objpfx)tst-rtld-help.out: $(objpfx)ld.so
++	$(test-wrapper) $(rtld-prefix) --help > $@; \
++	status=$$?; \
++	echo "info: ld.so exit status: $$status" >> $@; \
++	if ! grep -q 'Legacy HWCAP subdirectories under library search path directories' $@; then \
++	  echo "error: missing subdirectory pattern" >> $@; \
++	  if test $$status -eq 0; then \
++	    status=1; \
++	  fi; \
++	fi; \
++	(exit $$status); \
++	$(evaluate-test)
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 376a2e64d6..2f760503c5 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -758,8 +758,14 @@ _dl_init_paths (const char *llp, const char *source,
+   max_dirnamelen = SYSTEM_DIRS_MAX_LEN;
+   *aelem = NULL;
+ 
+-  /* This points to the map of the main object.  */
++  /* This points to the map of the main object.  If there is no main
++     object (e.g., under --help, use the dynamic loader itself as a
++     stand-in.  */
+   l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
++#ifdef SHARED
++  if (l == NULL)
++    l = &GL (dl_rtld_map);
++#endif
+   assert (l->l_type != lt_loaded);
+ 
+   if (l->l_info[DT_RUNPATH])
diff --git a/SOURCES/glibc-rh1937515.patch b/SOURCES/glibc-rh1937515.patch
new file mode 100644
index 0000000..1e77538
--- /dev/null
+++ b/SOURCES/glibc-rh1937515.patch
@@ -0,0 +1,90 @@
+Based on the following commit, adjusted for glibc-2.28 in RHEL-8:
+
+commit 27f74636752d0c4438cf8346cf2a76b6fcf3be16
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Fri Mar 19 06:15:37 2021 -0700
+
+    x86: Properly disable XSAVE related features [BZ #27605]
+    
+    1. Support GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVE.
+    2. Disable all features which depend on XSAVE:
+       a. If OSXSAVE is disabled by glibc tunables.  Or
+       b. If both XSAVE and XSAVEC aren't usable.
+
+diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
+index 805d00a43309fc23..910425053d9e226f 100644
+--- a/sysdeps/x86/cpu-features.c
++++ b/sysdeps/x86/cpu-features.c
+@@ -654,6 +654,60 @@ no_cpuid:
+     = TUNABLE_GET (x86_data_cache_size, long int, NULL);
+   cpu_features->shared_cache_size
+     = TUNABLE_GET (x86_shared_cache_size, long int, NULL);
++
++  bool disable_xsave_features = false;
++
++  if (!CPU_FEATURE_USABLE_P (cpu_features, OSXSAVE))
++    {
++      /* These features are usable only if OSXSAVE is usable.  */
++      CPU_FEATURE_UNSET (cpu_features, XSAVE);
++      CPU_FEATURE_UNSET (cpu_features, XSAVEOPT);
++      CPU_FEATURE_UNSET (cpu_features, XSAVEC);
++      CPU_FEATURE_UNSET (cpu_features, XGETBV_ECX_1);
++      CPU_FEATURE_UNSET (cpu_features, XFD);
++
++      disable_xsave_features = true;
++    }
++
++  if (disable_xsave_features
++      || (!CPU_FEATURE_USABLE_P (cpu_features, XSAVE)
++	  && !CPU_FEATURE_USABLE_P (cpu_features, XSAVEC)))
++    {
++      /* Clear xsave_state_size if both XSAVE and XSAVEC aren't usable.  */
++      cpu_features->xsave_state_size = 0;
++
++      CPU_FEATURE_UNSET (cpu_features, AVX);
++      CPU_FEATURE_UNSET (cpu_features, AVX2);
++      CPU_FEATURE_UNSET (cpu_features, AVX_VNNI);
++      CPU_FEATURE_UNSET (cpu_features, FMA);
++      CPU_FEATURE_UNSET (cpu_features, VAES);
++      CPU_FEATURE_UNSET (cpu_features, VPCLMULQDQ);
++      CPU_FEATURE_UNSET (cpu_features, XOP);
++      CPU_FEATURE_UNSET (cpu_features, F16C);
++      CPU_FEATURE_UNSET (cpu_features, AVX512F);
++      CPU_FEATURE_UNSET (cpu_features, AVX512CD);
++      CPU_FEATURE_UNSET (cpu_features, AVX512ER);
++      CPU_FEATURE_UNSET (cpu_features, AVX512PF);
++      CPU_FEATURE_UNSET (cpu_features, AVX512VL);
++      CPU_FEATURE_UNSET (cpu_features, AVX512DQ);
++      CPU_FEATURE_UNSET (cpu_features, AVX512BW);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_4FMAPS);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_4VNNIW);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_BITALG);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_IFMA);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_VBMI);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_VBMI2);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_VNNI);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_VPOPCNTDQ);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_VP2INTERSECT);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_BF16);
++      CPU_FEATURE_UNSET (cpu_features, AVX512_FP16);
++      CPU_FEATURE_UNSET (cpu_features, AMX_BF16);
++      CPU_FEATURE_UNSET (cpu_features, AMX_TILE);
++      CPU_FEATURE_UNSET (cpu_features, AMX_INT8);
++
++      CPU_FEATURE_UNSET (cpu_features, FMA4);
++    }
+ #endif
+ 
+   /* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86.  */
+diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
+index 0728023007a0f423..3173b2b959ca88f9 100644
+--- a/sysdeps/x86/cpu-tunables.c
++++ b/sysdeps/x86/cpu-tunables.c
+@@ -168,6 +168,7 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
+ 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, MOVBE, 5);
+ 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, SHSTK, 5);
+ 	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, SSSE3, 5);
++	      CHECK_GLIBC_IFUNC_CPU_OFF (n, cpu_features, XSAVE, 5);
+ 	    }
+ 	  break;
+ 	case 6:
diff --git a/SOURCES/glibc-rh1971664-1.patch b/SOURCES/glibc-rh1971664-1.patch
new file mode 100644
index 0000000..5a858d2
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-1.patch
@@ -0,0 +1,102 @@
+commit 0c78b0bb78d87a7de18726a033d88904f158f0fe
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Jun 7 14:22:17 2021 +0530
+
+    iconvconfig: Make file handling more general purpose
+    
+    Split out configuration file handling code from handle_dir into its
+    own function so that it can be reused for multiple configuration
+    files.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index b6fef1553cbbdd3d..2b3c587bc77cfdcd 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -644,37 +644,17 @@ add_module (char *rp, const char *directory)
+ 	      cost, need_ext);
+ }
+ 
+-
+-/* Read the config file and add the data for this directory to that.  */
+-static int
+-handle_dir (const char *dir)
++/* Read a gconv-modules configuration file.  */
++static bool
++handle_file (const char *dir, const char *infile)
+ {
+-  char *cp;
+   FILE *fp;
+   char *line = NULL;
+   size_t linelen = 0;
+-  size_t dirlen = strlen (dir);
+-
+-  if (dir[dirlen - 1] != '/')
+-    {
+-      char *newp = (char *) xmalloc (dirlen + 2);
+-      dir = memcpy (newp, dir, dirlen);
+-      newp[dirlen++] = '/';
+-      newp[dirlen] = '\0';
+-    }
+-
+-  char infile[prefix_len + dirlen + sizeof "gconv-modules"];
+-  cp = infile;
+-  if (dir[0] == '/')
+-    cp = mempcpy (cp, prefix, prefix_len);
+-  strcpy (mempcpy (cp, dir, dirlen), "gconv-modules");
+ 
+   fp = fopen (infile, "r");
+   if (fp == NULL)
+-    {
+-      error (0, errno, "cannot open `%s'", infile);
+-      return 1;
+-    }
++    return false;
+ 
+   /* No threads present.  */
+   __fsetlocking (fp, FSETLOCKING_BYCALLER);
+@@ -723,7 +703,42 @@ handle_dir (const char *dir)
+ 
+   fclose (fp);
+ 
+-  return 0;
++  return true;
++}
++
++/* Read config files and add the data for this directory to cache.  */
++static int
++handle_dir (const char *dir)
++{
++  char *cp;
++  size_t dirlen = strlen (dir);
++  bool found = false;
++
++  if (dir[dirlen - 1] != '/')
++    {
++      char *newp = (char *) xmalloc (dirlen + 2);
++      dir = memcpy (newp, dir, dirlen);
++      newp[dirlen++] = '/';
++      newp[dirlen] = '\0';
++    }
++
++  char infile[prefix_len + dirlen + sizeof "gconv-modules"];
++  cp = infile;
++  if (dir[0] == '/')
++    cp = mempcpy (cp, prefix, prefix_len);
++  strcpy (mempcpy (cp, dir, dirlen), "gconv-modules");
++
++  found |= handle_file (dir, infile);
++
++  if (!found)
++    {
++      error (0, errno, "failed to open gconv configuration file in `%s'",
++	     dir);
++      error (0, 0,
++	     "ensure that the directory contains a valid gconv-modules file.");
++    }
++
++  return found ? 0 : 1;
+ }
+ 
+ 
diff --git a/SOURCES/glibc-rh1971664-10.patch b/SOURCES/glibc-rh1971664-10.patch
new file mode 100644
index 0000000..a265910
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-10.patch
@@ -0,0 +1,188 @@
+commit eeac390eecf7de24a110dc84e77e1190f42c5305
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Thu Jun 10 14:31:57 2021 +0530
+
+    iconvconfig: Use common gconv module parsing function
+    
+    Drop local copy of gconv file parsing and use the one in
+    gconv_parseconfdir.h instead.  Now there is a single implementation of
+    configuration file parsing.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index 2f9d5f45ad3a8159..01ecf6f67d55dbbf 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -18,7 +18,6 @@
+ 
+ #include <argp.h>
+ #include <assert.h>
+-#include <dirent.h>
+ #include <error.h>
+ #include <errno.h>
+ #include <fcntl.h>
+@@ -34,10 +33,10 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/cdefs.h>
+-#include <sys/types.h>
+ #include <sys/uio.h>
+ 
+ #include "iconvconfig.h"
++#include <gconv_parseconfdir.h>
+ 
+ /* Get libc version number.  */
+ #include "../version.h"
+@@ -568,7 +567,9 @@ new_module (const char *fromname, size_t fromlen, const char *toname,
+ 
+ /* Add new module.  */
+ static void
+-add_module (char *rp, const char *directory)
++add_module (char *rp, const char *directory,
++	    size_t dirlen __attribute__ ((__unused__)),
++	    int modcount __attribute__ ((__unused__)))
+ {
+   /* We expect now
+      1. `from' name
+@@ -646,131 +647,28 @@ add_module (char *rp, const char *directory)
+ 	      cost, need_ext);
+ }
+ 
+-/* Read a gconv-modules configuration file.  */
+-static bool
+-handle_file (const char *dir, const char *infile)
+-{
+-  FILE *fp;
+-  char *line = NULL;
+-  size_t linelen = 0;
+-
+-  fp = fopen (infile, "r");
+-  if (fp == NULL)
+-    return false;
+-
+-  /* No threads present.  */
+-  __fsetlocking (fp, FSETLOCKING_BYCALLER);
+-
+-  while (!feof_unlocked (fp))
+-    {
+-      char *rp, *endp, *word;
+-      ssize_t n = __getdelim (&line, &linelen, '\n', fp);
+-
+-      if (n < 0)
+-	/* An error occurred.  */
+-	break;
+-
+-      rp = line;
+-      /* Terminate the line (excluding comments or newline) with a NUL
+-	 byte to simplify the following code.  */
+-      endp = strchr (rp, '#');
+-      if (endp != NULL)
+-	*endp = '\0';
+-      else
+-	if (rp[n - 1] == '\n')
+-	  rp[n - 1] = '\0';
+-
+-      while (isspace (*rp))
+-	++rp;
+-
+-      /* If this is an empty line go on with the next one.  */
+-      if (rp == endp)
+-	continue;
+-
+-      word = rp;
+-      while (*rp != '\0' && !isspace (*rp))
+-	++rp;
+-
+-      if (rp - word == sizeof ("alias") - 1
+-	  && memcmp (word, "alias", sizeof ("alias") - 1) == 0)
+-	add_alias (rp);
+-      else if (rp - word == sizeof ("module") - 1
+-	       && memcmp (word, "module", sizeof ("module") - 1) == 0)
+-	add_module (rp, dir);
+-      /* else */
+-	/* Otherwise ignore the line.  */
+-    }
+-
+-  free (line);
+-
+-  fclose (fp);
+-
+-  return true;
+-}
+-
+ /* Read config files and add the data for this directory to cache.  */
+ static int
+ handle_dir (const char *dir)
+ {
+-  char *cp;
+   size_t dirlen = strlen (dir);
+   bool found = false;
+ 
++  /* Add the prefix before sending it off to the parser.  */
++  char *fulldir = xmalloc (prefix_len + dirlen + 2);
++  char *cp = mempcpy (mempcpy (fulldir, prefix, prefix_len), dir, dirlen);
++
+   if (dir[dirlen - 1] != '/')
+     {
+-      char *newp = (char *) xmalloc (dirlen + 2);
+-      dir = memcpy (newp, dir, dirlen);
+-      newp[dirlen++] = '/';
+-      newp[dirlen] = '\0';
++      *cp++ = '/';
++      *cp = '\0';
++      dirlen++;
+     }
+ 
+-  /* First, look for a gconv-modules file.  */
+-  char *buf = malloc (prefix_len + dirlen + sizeof "gconv-modules.d");
+-  if (buf == NULL)
+-    goto out;
+-
+-  cp = buf;
+-  if (dir[0] == '/')
+-    cp = mempcpy (cp, prefix, prefix_len);
+-  cp = mempcpy (cp, dir, dirlen);
+-  cp = stpcpy (cp, "gconv-modules");
+-
+-  found |= handle_file (dir, buf);
+-
+-  /* Next, see if there is a gconv-modules.d directory containing configuration
+-     files and if it is non-empty.  */
+-  cp[0] = '.';
+-  cp[1] = 'd';
+-  cp[2] = '\0';
+-
+-  DIR *confdir = opendir (buf);
+-  if (confdir != NULL)
+-    {
+-      struct dirent *ent;
+-      while ((ent = readdir (confdir)) != NULL)
+-	{
+-	  if (ent->d_type != DT_REG)
+-	    continue;
+-
+-	  size_t len = strlen (ent->d_name);
+-	  const char *suffix = ".conf";
+-
+-	  if (len > strlen (suffix)
+-	      && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
+-	    {
+-	      char *conf;
+-	      if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
+-		continue;
+-	      found |= handle_file (dir, conf);
+-	      free (conf);
+-	    }
+-	}
+-      closedir (confdir);
+-    }
++  found = gconv_parseconfdir (fulldir, dirlen + prefix_len);
+ 
+-  free (buf);
++  free (fulldir);
+ 
+-out:
+   if (!found)
+     {
+       error (0, errno, "failed to open gconv configuration files in `%s'",
diff --git a/SOURCES/glibc-rh1971664-11.patch b/SOURCES/glibc-rh1971664-11.patch
new file mode 100644
index 0000000..cc5074d
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-11.patch
@@ -0,0 +1,53 @@
+Changes specific to RHEL-8:
+
+- lstat64 is a macro, so undefine it first
+
+commit f3629a4be82a393ff56646c388da2fda0101f557
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Thu Jun 10 14:56:37 2021 +0530
+
+    Handle DT_UNKNOWN in gconv-modules.d
+    
+    On filesystems that do not support dt_type, a regular file shows up as
+    DT_UNKNOWN.  Fall back to using lstat64 to read file properties in
+    such cases.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
+index 3d4d58d4be10a250..ba9b3fd36d9e30f9 100644
+--- a/iconv/gconv_parseconfdir.h
++++ b/iconv/gconv_parseconfdir.h
+@@ -32,6 +32,8 @@
+ # define readdir __readdir
+ # define closedir __closedir
+ # define mempcpy __mempcpy
++# undef lstat64
++# define lstat64 __lstat64
+ #endif
+ 
+ /* Name of the file containing the module information in the directories
+@@ -138,7 +140,7 @@ gconv_parseconfdir (const char *dir, size_t dir_len)
+       struct dirent *ent;
+       while ((ent = readdir (confdir)) != NULL)
+ 	{
+-	  if (ent->d_type != DT_REG)
++	  if (ent->d_type != DT_REG && ent->d_type != DT_UNKNOWN)
+ 	    continue;
+ 
+ 	  size_t len = strlen (ent->d_name);
+@@ -148,8 +150,14 @@ gconv_parseconfdir (const char *dir, size_t dir_len)
+ 	      && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
+ 	    {
+ 	      char *conf;
++	      struct stat64 st;
+ 	      if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
+ 		continue;
++	      if (ent->d_type == DT_UNKNOWN
++		  && (lstat64 (conf, &st) == -1
++		      || !S_ISREG (st.st_mode)))
++		continue;
++
+ 	      found |= read_conf_file (conf, dir, dir_len);
+ 	      free (conf);
+ 	    }
diff --git a/SOURCES/glibc-rh1971664-12.patch b/SOURCES/glibc-rh1971664-12.patch
new file mode 100644
index 0000000..0d375f1
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-12.patch
@@ -0,0 +1,98 @@
+commit 9429049c178b3af3d6afeb3717ff1f2214dc9572
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Jun 28 09:15:55 2021 +0530
+
+    iconvconfig: Fix multiple issues
+    
+    It was noticed on big-endian systems that msgfmt would fail with the
+    following error:
+    
+    msgfmt: gconv_builtin.c:70: __gconv_get_builtin_trans: Assertion `cnt < sizeof (map) / sizeof (map[0])' failed.
+    Aborted (core dumped)
+    
+    This is only seen on installed systems because it was due to a
+    corrupted gconv-modules.cache.  iconvconfig had the following issues
+    (it was specifically freeing fulldir that caused this issue, but other
+    cleanups are also needed) that this patch fixes.
+    
+    - Add prefix only if dir starts with '/'
+    - Use asprintf instead of mempcpy so that the directory string is NULL
+      terminated
+    - Make a copy of the directory reference in new_module so that fulldir
+      can be freed within the same scope in handle_dir.
+    
+    Reviewed-by: Florian Weimer <fweimer@redhat.com>
+
+diff --git a/iconv/Makefile b/iconv/Makefile
+index d09b8ac842731780..6df9862e748ae588 100644
+--- a/iconv/Makefile
++++ b/iconv/Makefile
+@@ -33,7 +33,7 @@ vpath %.c ../locale/programs ../intl
+ iconv_prog-modules = iconv_charmap charmap charmap-dir linereader \
+ 		     dummy-repertoire simple-hash xstrdup xmalloc \
+ 		     record-status
+-iconvconfig-modules = strtab xmalloc hash-string
++iconvconfig-modules = strtab xmalloc xasprintf xstrdup hash-string
+ extra-objs	   = $(iconv_prog-modules:=.o) $(iconvconfig-modules:=.o)
+ CFLAGS-iconv_prog.c += -I../locale/programs
+ CFLAGS-iconv_charmap.c += -I../locale/programs
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index 01ecf6f67d55dbbf..777da870d2f8e99a 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -250,6 +250,7 @@ static const char gconv_module_ext[] = MODULE_EXT;
+ 
+ 
+ #include <programs/xmalloc.h>
++#include <programs/xasprintf.h>
+ 
+ 
+ /* C string table handling.  */
+@@ -519,11 +520,12 @@ module_compare (const void *p1, const void *p2)
+ /* Create new module record.  */
+ static void
+ new_module (const char *fromname, size_t fromlen, const char *toname,
+-	    size_t tolen, const char *directory,
++	    size_t tolen, const char *dir_in,
+ 	    const char *filename, size_t filelen, int cost, size_t need_ext)
+ {
+   struct module *new_module;
+-  size_t dirlen = strlen (directory) + 1;
++  size_t dirlen = strlen (dir_in) + 1;
++  const char *directory = xstrdup (dir_in);
+   char *tmp;
+   void **inserted;
+ 
+@@ -654,20 +656,10 @@ handle_dir (const char *dir)
+   size_t dirlen = strlen (dir);
+   bool found = false;
+ 
+-  /* Add the prefix before sending it off to the parser.  */
+-  char *fulldir = xmalloc (prefix_len + dirlen + 2);
+-  char *cp = mempcpy (mempcpy (fulldir, prefix, prefix_len), dir, dirlen);
++  char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "",
++			     dir, dir[dirlen - 1] != '/' ? "/" : "");
+ 
+-  if (dir[dirlen - 1] != '/')
+-    {
+-      *cp++ = '/';
+-      *cp = '\0';
+-      dirlen++;
+-    }
+-
+-  found = gconv_parseconfdir (fulldir, dirlen + prefix_len);
+-
+-  free (fulldir);
++  found = gconv_parseconfdir (fulldir, strlen (fulldir));
+ 
+   if (!found)
+     {
+@@ -679,6 +671,8 @@ handle_dir (const char *dir)
+ 	     "configuration files with names ending in .conf.");
+     }
+ 
++  free (fulldir);
++
+   return found ? 0 : 1;
+ }
+ 
diff --git a/SOURCES/glibc-rh1971664-13.patch b/SOURCES/glibc-rh1971664-13.patch
new file mode 100644
index 0000000..23e523a
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-13.patch
@@ -0,0 +1,34 @@
+commit 7f784fabcb186ffaa082ed0aeed52a56b7d96cee
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Fri Jul 2 16:53:25 2021 +0530
+
+    iconvconfig: Use the public feof_unlocked
+    
+    Build of iconvconfig failed with CFLAGS=-Os since __feof_unlocked is
+    not a public symbol.  Replace with feof_unlocked (defined to
+    __feof_unlocked when IS_IN (libc)) to fix this.
+    
+    Reported-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
+index ba9b3fd36d9e30f9..234b85a586f1d79a 100644
+--- a/iconv/gconv_parseconfdir.h
++++ b/iconv/gconv_parseconfdir.h
+@@ -34,6 +34,7 @@
+ # define mempcpy __mempcpy
+ # undef lstat64
+ # define lstat64 __lstat64
++# define feof_unlocked __feof_unlocked
+ #endif
+ 
+ /* Name of the file containing the module information in the directories
+@@ -65,7 +66,7 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len)
+ 
+   /* Process the known entries of the file.  Comments start with `#' and
+      end with the end of the line.  Empty lines are ignored.  */
+-  while (!__feof_unlocked (fp))
++  while (!feof_unlocked (fp))
+     {
+       char *rp, *endp, *word;
+       ssize_t n = __getdelim (&line, &line_len, '\n', fp);
diff --git a/SOURCES/glibc-rh1971664-14.patch b/SOURCES/glibc-rh1971664-14.patch
new file mode 100644
index 0000000..09e3493
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-14.patch
@@ -0,0 +1,32 @@
+commit 5f9b78fe35d08739b6da1e5b356786d41116c108
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Tue Aug 3 21:10:20 2021 +0530
+
+    gconv_parseconfdir: Fix memory leak
+    
+    The allocated `conf` would leak if we have to skip over the file due
+    to the underlying filesystem not supporting dt_type.
+    
+    Reviewed-by: Arjun Shankar <arjun@redhat.com>
+
+diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
+index 915b60845ca11c03..e4c3c16d1f96ce0c 100644
+--- a/iconv/gconv_parseconfdir.h
++++ b/iconv/gconv_parseconfdir.h
+@@ -153,12 +153,11 @@ gconv_parseconfdir (const char *dir, size_t dir_len)
+ 	      struct stat64 st;
+ 	      if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
+ 		continue;
+-	      if (ent->d_type == DT_UNKNOWN
+-		  && (lstat64 (conf, &st) == -1
+-		      || !S_ISREG (st.st_mode)))
+-		continue;
+ 
+-	      found |= read_conf_file (conf, dir, dir_len);
++	      if (ent->d_type != DT_UNKNOWN
++		  || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode)))
++		found |= read_conf_file (conf, dir, dir_len);
++
+ 	      free (conf);
+ 	    }
+ 	}
diff --git a/SOURCES/glibc-rh1971664-15.patch b/SOURCES/glibc-rh1971664-15.patch
new file mode 100644
index 0000000..8029cf6
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-15.patch
@@ -0,0 +1,116 @@
+commit 43cea6d5652b6b9e61ac6ecc69419c909b504f47
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Sep 13 20:48:35 2021 +0530
+
+    iconvconfig: Fix behaviour with --prefix [BZ #28199]
+    
+    The consolidation of configuration parsing broke behaviour with
+    --prefix, where the prefix bled into the modules cache.  Accept a
+    prefix which, when non-NULL, is prepended to the path when looking for
+    configuration files but only the original directory is added to the
+    modules cache.
+    
+    This has no effect on the codegen of gconv_conf since it passes NULL.
+    
+    Reported-by: Patrick McCarty <patrick.mccarty@intel.com>
+    Reported-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
+    Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
+
+diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
+index ce64faa928dc1c52..3f5a692f1510157c 100644
+--- a/iconv/gconv_conf.c
++++ b/iconv/gconv_conf.c
+@@ -476,7 +476,7 @@ __gconv_read_conf (void)
+     __gconv_get_path ();
+ 
+   for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt)
+-    gconv_parseconfdir (__gconv_path_elem[cnt].name,
++    gconv_parseconfdir (NULL, __gconv_path_elem[cnt].name,
+ 			__gconv_path_elem[cnt].len);
+ #endif
+ 
+diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
+index e4c3c16d1f96ce0c..433aa18bab5083b0 100644
+--- a/iconv/gconv_parseconfdir.h
++++ b/iconv/gconv_parseconfdir.h
+@@ -39,7 +39,6 @@
+ /* Name of the file containing the module information in the directories
+    along the path.  */
+ static const char gconv_conf_filename[] = "gconv-modules";
+-static const char gconv_conf_dirname[] = "gconv-modules.d";
+ 
+ static void add_alias (char *);
+ static void add_module (char *, const char *, size_t, int);
+@@ -110,19 +109,28 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len)
+   return true;
+ }
+ 
++/* Prefix DIR (with length DIR_LEN) with PREFIX if the latter is non-NULL and
++   parse configuration in it.  */
++
+ static __always_inline bool
+-gconv_parseconfdir (const char *dir, size_t dir_len)
++gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
+ {
+-  /* No slash needs to be inserted between dir and gconv_conf_filename;
+-     dir already ends in a slash.  */
+-  char *buf = malloc (dir_len + sizeof (gconv_conf_dirname));
++  /* No slash needs to be inserted between dir and gconv_conf_filename; dir
++     already ends in a slash.  The additional 2 is to accommodate the ".d"
++     when looking for configuration files in gconv-modules.d.  */
++  size_t buflen = dir_len + sizeof (gconv_conf_filename) + 2;
++  char *buf = malloc (buflen + (prefix != NULL ? strlen (prefix) : 0));
++  char *cp = buf;
+   bool found = false;
+ 
+   if (buf == NULL)
+     return false;
+ 
+-  char *cp = mempcpy (mempcpy (buf, dir, dir_len), gconv_conf_filename,
+-		      sizeof (gconv_conf_filename));
++  if (prefix != NULL)
++    cp = stpcpy (cp, prefix);
++
++  cp = mempcpy (mempcpy (cp, dir, dir_len), gconv_conf_filename,
++		sizeof (gconv_conf_filename));
+ 
+   /* Read the gconv-modules configuration file first.  */
+   found = read_conf_file (buf, dir, dir_len);
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index 777da870d2f8e99a..b1fd4100b5cbc9d2 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -653,13 +653,21 @@ add_module (char *rp, const char *directory,
+ static int
+ handle_dir (const char *dir)
+ {
++  char *newp = NULL;
+   size_t dirlen = strlen (dir);
+   bool found = false;
+ 
+-  char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "",
+-			     dir, dir[dirlen - 1] != '/' ? "/" : "");
++  /* End directory path with a '/' if it doesn't already.  */
++  if (dir[dirlen - 1] != '/')
++    {
++      newp = xmalloc (dirlen + 2);
++      memcpy (newp, dir, dirlen);
++      newp[dirlen++] = '/';
++      newp[dirlen] = '\0';
++      dir = newp;
++    }
+ 
+-  found = gconv_parseconfdir (fulldir, strlen (fulldir));
++  found = gconv_parseconfdir (dir[0] == '/' ? prefix : NULL, dir, dirlen);
+ 
+   if (!found)
+     {
+@@ -671,7 +679,7 @@ handle_dir (const char *dir)
+ 	     "configuration files with names ending in .conf.");
+     }
+ 
+-  free (fulldir);
++  free (newp);
+ 
+   return found ? 0 : 1;
+ }
diff --git a/SOURCES/glibc-rh1971664-2.patch b/SOURCES/glibc-rh1971664-2.patch
new file mode 100644
index 0000000..06119e0
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-2.patch
@@ -0,0 +1,109 @@
+commit 3979c3e1bae20459d9b6d424bdb49927d9cd6fec
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Jun 7 14:22:18 2021 +0530
+
+    iconvconfig: Read configuration from gconv-modules.d subdirectory
+    
+    In addition to GCONV_PATH/gconv-modules, also read module
+    configuration from *.conf files in GCONV_PATH/gconv-modules.d.  This
+    allows a single gconv directory to have multiple sets of gconv modules
+    but at the same time, a single modules cache.
+    
+    With this feature, one could separate the glibc supported gconv
+    modules into a minimal essential set (ISO-8859-*, UTF, etc.) from the
+    remaining modules.  In future, these could be further segregated into
+    langpack-associated sets with their own
+    gconv-modules.d/someconfig.conf.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index 2b3c587bc77cfdcd..fafc686ae25fb5c1 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -18,6 +18,7 @@
+ 
+ #include <argp.h>
+ #include <assert.h>
++#include <dirent.h>
+ #include <error.h>
+ #include <errno.h>
+ #include <fcntl.h>
+@@ -33,6 +34,7 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/cdefs.h>
++#include <sys/types.h>
+ #include <sys/uio.h>
+ 
+ #include "iconvconfig.h"
+@@ -710,6 +712,7 @@ handle_file (const char *dir, const char *infile)
+ static int
+ handle_dir (const char *dir)
+ {
++#define BUF_LEN prefix_len + dirlen + sizeof "gconv-modules.d"
+   char *cp;
+   size_t dirlen = strlen (dir);
+   bool found = false;
+@@ -722,20 +725,55 @@ handle_dir (const char *dir)
+       newp[dirlen] = '\0';
+     }
+ 
+-  char infile[prefix_len + dirlen + sizeof "gconv-modules"];
+-  cp = infile;
++  /* First, look for a gconv-modules file.  */
++  char buf[BUF_LEN];
++  cp = buf;
+   if (dir[0] == '/')
+     cp = mempcpy (cp, prefix, prefix_len);
+-  strcpy (mempcpy (cp, dir, dirlen), "gconv-modules");
++  cp = mempcpy (cp, dir, dirlen);
++  cp = stpcpy (cp, "gconv-modules");
+ 
+-  found |= handle_file (dir, infile);
++  found |= handle_file (dir, buf);
++
++  /* Next, see if there is a gconv-modules.d directory containing configuration
++     files and if it is non-empty.  */
++  cp[0] = '.';
++  cp[1] = 'd';
++  cp[2] = '\0';
++
++  DIR *confdir = opendir (buf);
++  if (confdir != NULL)
++    {
++      struct dirent *ent;
++      while ((ent = readdir (confdir)) != NULL)
++	{
++	  if (ent->d_type != DT_REG)
++	    continue;
++
++	  size_t len = strlen (ent->d_name);
++	  const char *suffix = ".conf";
++
++	  if (len > strlen (suffix)
++	      && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
++	    {
++	      /* LEN <= PATH_MAX so this alloca is not unbounded.  */
++	      char *conf = alloca (BUF_LEN + len + 1);
++	      cp = stpcpy (conf, buf);
++	      sprintf (cp, "/%s", ent->d_name);
++	      found |= handle_file (dir, conf);
++	    }
++	}
++      closedir (confdir);
++    }
+ 
+   if (!found)
+     {
+-      error (0, errno, "failed to open gconv configuration file in `%s'",
++      error (0, errno, "failed to open gconv configuration files in `%s'",
+ 	     dir);
+       error (0, 0,
+-	     "ensure that the directory contains a valid gconv-modules file.");
++	     "ensure that the directory contains either a valid "
++	     "gconv-modules file or a gconv-modules.d directory with "
++	     "configuration files with names ending in .conf.");
+     }
+ 
+   return found ? 0 : 1;
diff --git a/SOURCES/glibc-rh1971664-3.patch b/SOURCES/glibc-rh1971664-3.patch
new file mode 100644
index 0000000..a8dedd1
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-3.patch
@@ -0,0 +1,99 @@
+commit b17d29b390154df9dfad9d21f1e6605422521fd2
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Jun 7 14:22:19 2021 +0530
+
+    gconv_conf: Read configuration files in gconv-modules.d
+    
+    Read configuration files with names ending in .conf in
+    GCONV_PATH/gconv-modules.d to mirror configuration flexibility in
+    iconvconfig into the iconv program and function.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
+index f173cde71b2a61d7..8eb981fca7cee36a 100644
+--- a/iconv/gconv_conf.c
++++ b/iconv/gconv_conf.c
+@@ -19,6 +19,7 @@
+ 
+ #include <assert.h>
+ #include <ctype.h>
++#include <dirent.h>
+ #include <errno.h>
+ #include <limits.h>
+ #include <locale.h>
+@@ -30,6 +31,7 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/param.h>
++#include <sys/types.h>
+ 
+ #include <libc-lock.h>
+ #include <gconv_int.h>
+@@ -50,6 +52,7 @@ static const struct path_elem empty_path_elem = { NULL, 0 };
+ /* Name of the file containing the module information in the directories
+    along the path.  */
+ static const char gconv_conf_filename[] = "gconv-modules";
++static const char gconv_conf_dirname[] = "gconv-modules.d";
+ 
+ /* Filename extension for the modules.  */
+ #ifndef MODULE_EXT
+@@ -554,18 +557,52 @@ __gconv_read_conf (void)
+ 
+   for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt)
+     {
++#define BUF_LEN elem_len + sizeof (gconv_conf_dirname)
++
+       const char *elem = __gconv_path_elem[cnt].name;
+       size_t elem_len = __gconv_path_elem[cnt].len;
+-      char *filename;
++      char *buf;
+ 
+       /* No slash needs to be inserted between elem and gconv_conf_filename;
+ 	 elem already ends in a slash.  */
+-      filename = alloca (elem_len + sizeof (gconv_conf_filename));
+-      __mempcpy (__mempcpy (filename, elem, elem_len),
+-		 gconv_conf_filename, sizeof (gconv_conf_filename));
++      buf = alloca (BUF_LEN);
++      char *cp = __mempcpy (__mempcpy (buf, elem, elem_len),
++			    gconv_conf_filename, sizeof (gconv_conf_filename));
++
++      /* Read the gconv-modules configuration file first.  */
++      read_conf_file (buf, elem, elem_len, &modules, &nmodules);
++
++      /* Next, see if there is a gconv-modules.d directory containing
++	 configuration files and if it is non-empty.  */
++      cp--;
++      cp[0] = '.';
++      cp[1] = 'd';
++      cp[2] = '\0';
++
++      DIR *confdir = __opendir (buf);
++      if (confdir != NULL)
++	{
++	  struct dirent *ent;
++	  while ((ent = __readdir (confdir)) != NULL)
++	    {
++	      if (ent->d_type != DT_REG)
++		continue;
++
++	      size_t len = strlen (ent->d_name);
++	      const char *suffix = ".conf";
+ 
+-      /* Read the next configuration file.  */
+-      read_conf_file (filename, elem, elem_len, &modules, &nmodules);
++	      if (len > strlen (suffix)
++		  && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
++		{
++		  /* LEN <= PATH_MAX so this alloca is not unbounded.  */
++		  char *conf = alloca (BUF_LEN + len + 1);
++		  cp = stpcpy (conf, buf);
++		  sprintf (cp, "/%s", ent->d_name);
++		  read_conf_file (conf, elem, elem_len, &modules, &nmodules);
++		}
++	    }
++	  __closedir (confdir);
++	}
+     }
+ #endif
+ 
diff --git a/SOURCES/glibc-rh1971664-4.patch b/SOURCES/glibc-rh1971664-4.patch
new file mode 100644
index 0000000..e6cc136
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-4.patch
@@ -0,0 +1,179 @@
+commit fc5bfade69ca12d034967dc6b929dbe3dd715172
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Jun 7 14:22:20 2021 +0530
+
+    iconvdata: Move gconv-modules configuration to gconv-modules.conf
+    
+    Move all gconv-modules configuration files to gconv-modules.conf.
+    That is, the S390 extensions now become gconv-modules-s390.conf.  Move
+    both configuration files into gconv-modules.d.
+    
+    Now GCONV_PATH/gconv-modules is read only for backward compatibility
+    for third-party gconv modules directories.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+# Conflicts:
+#	iconvdata/Makefile
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index 32656ad31d9b434b..fc403e8abe3cc11f 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -136,10 +136,13 @@ charmaps = ../localedata/charmaps
+ extra-modules-left := $(modules)
+ include extra-module.mk
+ 
++gconv-modules = gconv-modules.conf
++modpfx = $(objpfx)gconv-modules.d/
+ 
+ extra-objs	+= $(modules.so)
+ install-others	= $(addprefix $(inst_gconvdir)/, $(modules.so))	\
+-		  $(inst_gconvdir)/gconv-modules
++		  $(addprefix $(inst_gconvdir)/gconv-modules.d/, \
++			      $(gconv-modules))
+ 
+ # We can build the conversion tables for numerous charsets automatically.
+ 
+@@ -181,7 +184,7 @@ generated += $(generated-modules:=.h) $(generated-modules:=.stmp) \
+ 	     iconv-test.out iconv-rules tst-loading.mtrace	 \
+ 	     mtrace-tst-loading.out tst-tables.out iconv-test.xxx
+ ifdef objpfx
+-generated += gconv-modules
++generated += $(addprefix gconv-modules.d/,$(gconv-modules))
+ endif
+ 
+ # Rules to generate the headers.
+@@ -249,7 +252,8 @@ headers: $(addprefix $(objpfx), $(generated-modules:=.h))
+ $(addprefix $(inst_gconvdir)/, $(modules.so)): \
+     $(inst_gconvdir)/%: $(objpfx)% $(+force)
+ 	$(do-install-program)
+-$(inst_gconvdir)/gconv-modules: $(objpfx)gconv-modules $(+force)
++$(addprefix $(inst_gconvdir)/gconv-modules.d/, $(gconv-modules)): \
++    $(inst_gconvdir)/gconv-modules.d/%: $(modpfx)% $(+force)
+ 	$(do-install)
+ ifeq (no,$(cross-compiling))
+ # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
+@@ -297,29 +301,30 @@ $(objpfx)mtrace-tst-loading.out: $(objpfx)tst-loading.out
+ 	$(common-objpfx)malloc/mtrace $(objpfx)tst-loading.mtrace > $@; \
+ 	$(evaluate-test)
+ 
+-$(objpfx)bug-iconv1.out: $(objpfx)gconv-modules \
++$(objpfx)bug-iconv1.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv2.out: $(objpfx)gconv-modules \
++$(objpfx)bug-iconv2.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+ $(objpfx)bug-iconv3: $(libdl)
+-$(objpfx)bug-iconv3.out: $(objpfx)gconv-modules \
++$(objpfx)bug-iconv3.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv5.out: $(objpfx)gconv-modules \
++$(objpfx)bug-iconv5.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)tst-loading.out: $(objpfx)gconv-modules \
++$(objpfx)tst-loading.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)tst-iconv4.out: $(objpfx)gconv-modules \
++$(objpfx)tst-iconv4.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
++$(objpfx)tst-iconv7.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \
++$(objpfx)bug-iconv10.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
++$(objpfx)bug-iconv12.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \
++$(objpfx)bug-iconv14.out: $(addprefix $(modpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+ 
+-$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
++$(objpfx)iconv-test.out: run-iconv-test.sh \
++			 $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so)) \
+ 			 $(common-objdir)/iconv/iconv_prog TESTS
+ 	iconv_modules="$(modules)" \
+@@ -327,7 +332,8 @@ $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
+ 		 '$(run-program-env)' > $@; \
+ 	$(evaluate-test)
+ 
+-$(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
++$(objpfx)tst-tables.out: tst-tables.sh \
++			 $(addprefix $(modpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so)) \
+ 			 $(objpfx)tst-table-from $(objpfx)tst-table-to
+ 	$(SHELL) $< $(common-objpfx) $(common-objpfx)iconvdata/ \
+@@ -340,5 +346,8 @@ do-tests-clean common-mostlyclean: tst-tables-clean
+ tst-tables-clean:
+ 	-rm -f $(objpfx)tst-*.table $(objpfx)tst-EUC-TW.irreversible
+ 
+-$(objpfx)gconv-modules: gconv-modules
+-	cat $(sysdeps-gconv-modules) $^ > $@
++$(modpfx):
++	mkdir -p $@
++
++$(modpfx)%: % $(modpfx)
++	cp $< $@
+diff --git a/iconvdata/gconv-modules b/iconvdata/gconv-modules.conf
+similarity index 100%
+rename from iconvdata/gconv-modules
+rename to iconvdata/gconv-modules.conf
+diff --git a/localedata/Makefile b/localedata/Makefile
+index 14fcc37fed21e740..a5ca7a31f43d50c3 100644
+--- a/localedata/Makefile
++++ b/localedata/Makefile
+@@ -179,7 +179,7 @@ install-others := $(addprefix $(inst_i18ndir)/, \
+ 			      $(locales))
+ endif
+ 
+-tests: $(objdir)/iconvdata/gconv-modules
++tests: $(objdir)/iconvdata/gconv-modules.d/gconv-modules.conf
+ 
+ tests-static += tst-langinfo-newlocale-static tst-langinfo-setlocale-static
+ 
+@@ -442,5 +442,5 @@ $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
+ bug-setlocale1-ENV-only = LOCPATH=$(objpfx) LC_CTYPE=de_DE.UTF-8
+ bug-setlocale1-static-ENV-only = $(bug-setlocale1-ENV-only)
+ 
+-$(objdir)/iconvdata/gconv-modules:
++$(objdir)/iconvdata/gconv-modules.d/gconv-modules.conf:
+ 	$(MAKE) -C ../iconvdata subdir=iconvdata $@
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 8bc82e523f9049db..5c8e1170b4d799ba 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -21,13 +21,25 @@ lib := iconvdata
+ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
+ 
+ extra-objs      += $(addsuffix .so, $(s390x-iconv-modules))
+-install-others  += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules))
++install-others  += $(patsubst %, $(inst_gconvdir)/%.so, \
++				 $(s390x-iconv-modules)) \
++		   $(inst_gconvdir)/gconv-modules.d/gconv-modules-s390.conf
+ 
+ $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \
+ $(inst_gconvdir)/%.so: $(objpfx)%.so $(+force)
+ 	$(do-install-program)
+ 
+-sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules
++ifdef objpfx
++generated += gconv-modules.d/gconv-modules-s390.conf
++endif
++
++$(inst_gconvdir)/gconv-modules.d/gconv-modules-s390.conf: \
++		$(modpfx)gconv-modules-s390.conf $(+force)
++	$(do-install)
++
++$(modpfx)gconv-modules-s390.conf: ../sysdeps/s390/gconv-modules-s390.conf \
++				  $(modpfx)
++	cp $< $@
+ endif
+ 
+ ifeq ($(subdir),string)
+diff --git a/sysdeps/s390/gconv-modules b/sysdeps/s390/gconv-modules-s390.conf
+similarity index 100%
+rename from sysdeps/s390/gconv-modules
+rename to sysdeps/s390/gconv-modules-s390.conf
diff --git a/SOURCES/glibc-rh1971664-5.patch b/SOURCES/glibc-rh1971664-5.patch
new file mode 100644
index 0000000..0e6f3df
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-5.patch
@@ -0,0 +1,3825 @@
+commit 5a5b48136567de019f35a2996513bd7bbeb8175e
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Jun 7 14:22:21 2021 +0530
+
+    iconvdata: Split out non-essential gconv module configuration
+    
+    Split module configuration so that only the bare minimum charsets,
+    i.e. ANSI_X3.110, ISO8859-15, ISO8859-1, CP1252, UNICODE, UTF-16,
+    UTF-32 and UTF-7 are configured in gconv-modules.conf.  The remaining
+    module configurations are now in gconv-modules-extra.conf.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+# Conflicts:
+#	iconvdata/gconv-modules.conf
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index fc403e8abe3cc11f..d682a98b5c4a8003 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -136,7 +136,7 @@ charmaps = ../localedata/charmaps
+ extra-modules-left := $(modules)
+ include extra-module.mk
+ 
+-gconv-modules = gconv-modules.conf
++gconv-modules = gconv-modules.conf gconv-modules-extra.conf
+ modpfx = $(objpfx)gconv-modules.d/
+ 
+ extra-objs	+= $(modules.so)
+diff --git a/iconvdata/gconv-modules-extra.conf b/iconvdata/gconv-modules-extra.conf
+new file mode 100644
+index 0000000000000000..edbd4d9be4b533b9
+--- /dev/null
++++ b/iconvdata/gconv-modules-extra.conf
+@@ -0,0 +1,1889 @@
++# GNU libc iconv configuration.
++# Copyright (C) 1997-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/>.
++
++# All lines contain the following information:
++
++# If the lines start with `module'
++#  fromset:	either a name triple or a regular expression triple.
++#  toset:	a name triple or an expression with \N to get regular
++#		expression matching results.
++#  filename:	filename of the module implementing the transformation.
++#		If it is not absolute the path is made absolute by prepending
++#		the directory the configuration file is found in.
++#  cost:	optional cost of the transformation.  Default is 1.
++
++# If the lines start with `alias'
++#  alias:	alias name which is not really recognized.
++#  name:	the real name of the character set
++
++alias	ISO-IR-4//		BS_4730//
++alias	ISO646-GB//		BS_4730//
++alias	GB//			BS_4730//
++alias	UK//			BS_4730//
++alias	CSISO4UNITEDKINGDOM//	BS_4730//
++module	BS_4730//		INTERNAL		ISO646		2
++module	INTERNAL		BS_4730//		ISO646		2
++
++alias	ISO-IR-121//		CSA_Z243.4-1985-1//
++alias	ISO646-CA//		CSA_Z243.4-1985-1//
++alias	CSA7-1//		CSA_Z243.4-1985-1//
++alias	CA//			CSA_Z243.4-1985-1//
++alias	CSISO121CANADIAN1//	CSA_Z243.4-1985-1//
++alias	CSA_Z243.419851//	CSA_Z243.4-1985-1//
++module	CSA_Z243.4-1985-1//	INTERNAL		ISO646		2
++module	INTERNAL		CSA_Z243.4-1985-1//	ISO646		2
++
++alias	ISO-IR-122//		CSA_Z243.4-1985-2//
++alias	ISO646-CA2//		CSA_Z243.4-1985-2//
++alias	CSA7-2//		CSA_Z243.4-1985-2//
++alias	CSISO122CANADIAN2//	CSA_Z243.4-1985-2//
++alias	CSA_Z243.419852//	CSA_Z243.4-1985-2//
++module	CSA_Z243.4-1985-2//	INTERNAL		ISO646		2
++module	INTERNAL		CSA_Z243.4-1985-2//	ISO646		2
++
++alias	ISO-IR-21//		DIN_66003//
++alias	DE//			DIN_66003//
++alias	ISO646-DE//		DIN_66003//
++alias	CSISO21GERMAN//		DIN_66003//
++module	DIN_66003//		INTERNAL		ISO646		2
++module	INTERNAL		DIN_66003//		ISO646		2
++
++alias	DS2089//		DS_2089//
++alias	ISO646-DK//		DS_2089//
++alias	DK//			DS_2089//
++alias	CSISO646DANISH//	DS_2089//
++module	DS_2089//		INTERNAL		ISO646		2
++module	INTERNAL		DS_2089//		ISO646		2
++
++alias	ISO-IR-17//		ES//
++alias	ISO646-ES//		ES//
++alias	CSISO17SPANISH//	ES//
++module	ES//			INTERNAL		ISO646		2
++module	INTERNAL		ES//			ISO646		2
++
++alias	ISO-IR-85//		ES2//
++alias	ISO646-ES2//		ES2//
++alias	CSISO85SPANISH2//	ES2//
++module	ES2//			INTERNAL		ISO646		2
++module	INTERNAL		ES2//			ISO646		2
++
++alias	ISO-IR-57//		GB_1988-80//
++alias	CN//			GB_1988-80//
++alias	ISO646-CN//		GB_1988-80//
++alias	CSISO58GB1988//		GB_1988-80//
++alias	GB_198880//		GB_1988-80//
++module	GB_1988-80//		INTERNAL		ISO646		2
++module	INTERNAL		GB_1988-80//		ISO646		2
++
++alias	ISO-IR-15//		IT//
++alias	ISO646-IT//		IT//
++alias	CSISO15ITALIAN//	IT//
++module	IT//			INTERNAL		ISO646		2
++module	INTERNAL		IT//			ISO646		2
++
++alias	ISO-IR-14//		JIS_C6220-1969-RO//
++alias	JP//			JIS_C6220-1969-RO//
++alias	ISO646-JP//		JIS_C6220-1969-RO//
++alias	CSISO14JISC6220RO//	JIS_C6220-1969-RO//
++alias	JIS_C62201969RO//	JIS_C6220-1969-RO//
++module	JIS_C6220-1969-RO//	INTERNAL		ISO646		2
++module	INTERNAL		JIS_C6220-1969-RO//	ISO646		2
++
++alias	ISO-IR-92//		JIS_C6229-1984-B//
++alias	ISO646-JP-OCR-B//	JIS_C6229-1984-B//
++alias	JP-OCR-B//		JIS_C6229-1984-B//
++alias	CSISO92JISC62991984B//	JIS_C6229-1984-B//
++alias	JIS_C62291984B//	JIS_C6229-1984-B//
++module	JIS_C6229-1984-B//	INTERNAL		ISO646		2
++module	INTERNAL		JIS_C6229-1984-B//	ISO646		2
++
++alias	ISO-IR-141//		JUS_I.B1.002//
++alias	ISO646-YU//		JUS_I.B1.002//
++alias	JS//			JUS_I.B1.002//
++alias	YU//			JUS_I.B1.002//
++alias	CSISO141JUSIB1002//	JUS_I.B1.002//
++module	JUS_I.B1.002//		INTERNAL		ISO646		2
++module	INTERNAL		JUS_I.B1.002//		ISO646		2
++
++alias	ISO646-KR//		KSC5636//
++alias	CSKSC5636//		KSC5636//
++module	KSC5636//		INTERNAL		ISO646		2
++module	INTERNAL		KSC5636//		ISO646		2
++
++alias	ISO-IR-86//		MSZ_7795.3//
++alias	ISO646-HU//		MSZ_7795.3//
++alias	HU//			MSZ_7795.3//
++alias	CSISO86HUNGARIAN//	MSZ_7795.3//
++module	MSZ_7795.3//		INTERNAL		ISO646		2
++module	INTERNAL		MSZ_7795.3//		ISO646		2
++
++alias	CUBA//			NC_NC00-10//
++alias	NC_NC00-10:81//		NC_NC00-10//
++alias	ISO-IR-151//		NC_NC00-10//
++alias	ISO646-CU//		NC_NC00-10//
++alias	CSISO151CUBA//		NC_NC00-10//
++alias	NC_NC0010//		NC_NC00-10//
++module	NC_NC00-10//		INTERNAL		ISO646		2
++module	INTERNAL		NC_NC00-10//		ISO646		2
++
++alias	ISO-IR-69//		NF_Z_62-010//
++alias	ISO646-FR//		NF_Z_62-010//
++alias	FR//			NF_Z_62-010//
++alias	CSISO69FRENCH//		NF_Z_62-010//
++alias	NF_Z_62010//		NF_Z_62-010//
++module	NF_Z_62-010//		INTERNAL		ISO646		2
++module	INTERNAL		NF_Z_62-010//		ISO646		2
++
++alias	ISO-IR-25//		NF_Z_62-010_1973//
++alias	ISO646-FR1//		NF_Z_62-010_1973//
++alias	NF_Z_62-010_(1973)//	NF_Z_62-010_1973//
++alias	CSISO25FRENCH//		NF_Z_62-010_1973//
++alias	NF_Z_62010_1973//	NF_Z_62-010_1973//
++module	NF_Z_62-010_1973//	INTERNAL		ISO646		2
++module	INTERNAL		NF_Z_62-010_1973//	ISO646		2
++
++alias	ISO-IR-60//		NS_4551-1//
++alias	ISO646-NO//		NS_4551-1//
++alias	NO//			NS_4551-1//
++alias	CSISO60DANISHNORWEGIAN// NS_4551-1//
++alias	CSISO60NORWEGIAN1//	NS_4551-1//
++alias	NS_45511//		NS_4551-1//
++module	NS_4551-1//		INTERNAL		ISO646		2
++module	INTERNAL		NS_4551-1//		ISO646		2
++
++alias	ISO646-NO2//		NS_4551-2//
++alias	ISO-IR-61//		NS_4551-2//
++alias	NO2//			NS_4551-2//
++alias	CSISO61NORWEGIAN2//	NS_4551-2//
++alias	NS_45512//		NS_4551-2//
++module	NS_4551-2//		INTERNAL		ISO646		2
++module	INTERNAL		NS_4551-2//		ISO646		2
++
++alias	ISO-IR-16//		PT//
++alias	ISO646-PT//		PT//
++alias	CSISO16PORTUGESE//	PT//
++module	PT//			INTERNAL		ISO646		2
++module	INTERNAL		PT//			ISO646		2
++
++alias	ISO-IR-84//		PT2//
++alias	ISO646-PT2//		PT2//
++alias	CSISO84PORTUGUESE2//	PT2//
++module	PT2//			INTERNAL		ISO646		2
++module	INTERNAL		PT2//			ISO646		2
++
++alias	ISO-IR-10//		SEN_850200_B//
++alias	FI//			SEN_850200_B//
++alias	ISO646-FI//		SEN_850200_B//
++alias	ISO646-SE//		SEN_850200_B//
++alias	SE//			SEN_850200_B//
++alias	CSISO10SWEDISH//	SEN_850200_B//
++alias	SS636127//		SEN_850200_B//
++module	SEN_850200_B//		INTERNAL		ISO646		2
++module	INTERNAL		SEN_850200_B//		ISO646		2
++
++alias	ISO-IR-11//		SEN_850200_C//
++alias	ISO646-SE2//		SEN_850200_C//
++alias	SE2//			SEN_850200_C//
++alias	CSISO11SWEDISHFORNAMES// SEN_850200_C//
++module	SEN_850200_C//		INTERNAL		ISO646		2
++module	INTERNAL		SEN_850200_C//		ISO646		2
++
++#	from			to			module		cost
++alias	ISO-IR-101//		ISO-8859-2//
++alias	ISO_8859-2:1987//	ISO-8859-2//
++alias	ISO_8859-2//		ISO-8859-2//
++alias	ISO8859-2//		ISO-8859-2//
++alias	ISO88592//		ISO-8859-2//
++alias	LATIN2//		ISO-8859-2//
++alias	L2//			ISO-8859-2//
++alias	CSISOLATIN2//		ISO-8859-2//
++alias	8859_2//		ISO-8859-2//
++alias	OSF00010002//		ISO-8859-2//
++alias	IBM912//		ISO-8859-2//
++alias	CP912//			ISO-8859-2//
++module	ISO-8859-2//		INTERNAL		ISO8859-2	1
++module	INTERNAL		ISO-8859-2//		ISO8859-2	1
++
++#	from			to			 module		cost
++alias	ISO-IR-109//		ISO-8859-3//
++alias	ISO_8859-3:1988//	ISO-8859-3//
++alias	ISO_8859-3//		ISO-8859-3//
++alias	ISO8859-3//		ISO-8859-3//
++alias	ISO88593//		ISO-8859-3//
++alias	LATIN3//		ISO-8859-3//
++alias	L3//			ISO-8859-3//
++alias	CSISOLATIN3//		ISO-8859-3//
++alias	8859_3//		ISO-8859-3//
++alias	OSF00010003//		ISO-8859-3//
++module	ISO-8859-3//		INTERNAL		ISO8859-3	1
++module	INTERNAL		ISO-8859-3//		ISO8859-3	1
++
++#	from			to			module		cost
++alias	ISO-IR-110//		ISO-8859-4//
++alias	ISO_8859-4:1988//	ISO-8859-4//
++alias	ISO_8859-4//		ISO-8859-4//
++alias	ISO8859-4//		ISO-8859-4//
++alias	ISO88594//		ISO-8859-4//
++alias	LATIN4//		ISO-8859-4//
++alias	L4//			ISO-8859-4//
++alias	CSISOLATIN4//		ISO-8859-4//
++alias	8859_4//		ISO-8859-4//
++alias	OSF00010004//		ISO-8859-4//
++module	ISO-8859-4//		INTERNAL		ISO8859-4	1
++module	INTERNAL		ISO-8859-4//		ISO8859-4	1
++
++#	from			to			module		cost
++alias	ISO-IR-144//		ISO-8859-5//
++alias	ISO_8859-5:1988//	ISO-8859-5//
++alias	ISO_8859-5//		ISO-8859-5//
++alias	ISO8859-5//		ISO-8859-5//
++alias	ISO88595//		ISO-8859-5//
++alias	CYRILLIC//		ISO-8859-5//
++alias	CSISOLATINCYRILLIC//	ISO-8859-5//
++alias	8859_5//		ISO-8859-5//
++alias	OSF00010005//		ISO-8859-5//
++alias	IBM915//		ISO-8859-5//
++alias	CP915//			ISO-8859-5//
++module	ISO-8859-5//		INTERNAL		ISO8859-5	1
++module	INTERNAL		ISO-8859-5//		ISO8859-5	1
++
++#	from			to			module		cost
++alias	ISO-IR-127//		ISO-8859-6//
++alias	ISO_8859-6:1987//	ISO-8859-6//
++alias	ISO_8859-6//		ISO-8859-6//
++alias	ISO8859-6//		ISO-8859-6//
++alias	ISO88596//		ISO-8859-6//
++alias	ECMA-114//		ISO-8859-6//
++alias	ASMO-708//		ISO-8859-6//
++alias	ARABIC//		ISO-8859-6//
++alias	CSISOLATINARABIC//	ISO-8859-6//
++alias	8859_6//		ISO-8859-6//
++alias	OSF00010006//		ISO-8859-6//
++alias	IBM1089//		ISO-8859-6//
++alias	CP1089//		ISO-8859-6//
++module	ISO-8859-6//		INTERNAL		ISO8859-6	1
++module	INTERNAL		ISO-8859-6//		ISO8859-6	1
++
++#	from			to			module		cost
++alias	ISO-IR-126//		ISO-8859-7//
++alias	ISO_8859-7:2003//	ISO-8859-7//
++alias	ISO_8859-7:1987//	ISO-8859-7//
++alias	ISO_8859-7//		ISO-8859-7//
++alias	ISO8859-7//		ISO-8859-7//
++alias	ISO88597//		ISO-8859-7//
++alias	ELOT_928//		ISO-8859-7//
++alias	ECMA-118//		ISO-8859-7//
++alias	GREEK//			ISO-8859-7//
++alias	GREEK8//		ISO-8859-7//
++alias	CSISOLATINGREEK//	ISO-8859-7//
++alias	8859_7//		ISO-8859-7//
++alias	OSF00010007//		ISO-8859-7//
++alias	IBM813//		ISO-8859-7//
++alias	CP813//			ISO-8859-7//
++module	ISO-8859-7//		INTERNAL		ISO8859-7	1
++module	INTERNAL		ISO-8859-7//		ISO8859-7	1
++
++#	from			to			module		cost
++alias	ISO-IR-138//		ISO-8859-8//
++alias	ISO_8859-8:1988//	ISO-8859-8//
++alias	ISO_8859-8//		ISO-8859-8//
++alias	ISO8859-8//		ISO-8859-8//
++alias	ISO88598//		ISO-8859-8//
++alias	HEBREW//		ISO-8859-8//
++alias	CSISOLATINHEBREW//	ISO-8859-8//
++alias	8859_8//		ISO-8859-8//
++alias	OSF00010008//		ISO-8859-8//
++alias	IBM916//		ISO-8859-8//
++alias	CP916//			ISO-8859-8//
++module	ISO-8859-8//		INTERNAL		ISO8859-8	1
++module	INTERNAL		ISO-8859-8//		ISO8859-8	1
++
++#	from			to			module		cost
++alias	ISO-IR-148//		ISO-8859-9//
++alias	ISO_8859-9:1989//	ISO-8859-9//
++alias	ISO_8859-9//		ISO-8859-9//
++alias	ISO8859-9//		ISO-8859-9//
++alias	ISO88599//		ISO-8859-9//
++alias	LATIN5//		ISO-8859-9//
++alias	L5//			ISO-8859-9//
++alias	CSISOLATIN5//		ISO-8859-9//
++alias	8859_9//		ISO-8859-9//
++alias	OSF00010009//		ISO-8859-9//
++alias	IBM920//		ISO-8859-9//
++alias	CP920//			ISO-8859-9//
++alias	TS-5881//		ISO-8859-9//
++alias	ECMA-128//		ISO-8859-9//
++module	ISO-8859-9//		INTERNAL		ISO8859-9	1
++module	INTERNAL		ISO-8859-9//		ISO8859-9	1
++
++#	from			to			module		cost
++alias	ISO-IR-157//		ISO-8859-10//
++alias	ISO_8859-10:1992//	ISO-8859-10//
++alias	ISO_8859-10//		ISO-8859-10//
++alias	ISO8859-10//		ISO-8859-10//
++alias	ISO885910//		ISO-8859-10//
++alias	LATIN6//		ISO-8859-10//
++alias	L6//			ISO-8859-10//
++alias	CSISOLATIN6//		ISO-8859-10//
++alias	OSF0001000A//		ISO-8859-10//
++module	ISO-8859-10//		INTERNAL		ISO8859-10	1
++module	INTERNAL		ISO-8859-10//		ISO8859-10	1
++
++#	from			to			module		cost
++alias	ISO8859-11//		ISO-8859-11//
++alias	ISO885911//		ISO-8859-11//
++module	ISO-8859-11//		INTERNAL		ISO8859-11	1
++module	INTERNAL		ISO-8859-11//		ISO8859-11	1
++
++#	from			to			module		cost
++alias	ISO8859-13//		ISO-8859-13//
++alias	ISO885913//		ISO-8859-13//
++alias	ISO-IR-179//		ISO-8859-13//
++alias	LATIN7//		ISO-8859-13//
++alias	L7//			ISO-8859-13//
++alias	BALTIC//		ISO-8859-13//
++module	ISO-8859-13//		INTERNAL		ISO8859-13	1
++module	INTERNAL		ISO-8859-13//		ISO8859-13	1
++
++#	from			to			module		cost
++alias	ISO8859-14//		ISO-8859-14//
++alias	ISO885914//		ISO-8859-14//
++alias	ISO-IR-199//		ISO-8859-14//
++alias	LATIN8//		ISO-8859-14//
++alias	L8//			ISO-8859-14//
++alias	ISO_8859-14:1998//	ISO-8859-14//
++alias	ISO_8859-14//		ISO-8859-14//
++alias	ISO-CELTIC//		ISO-8859-14//
++module	ISO-8859-14//		INTERNAL		ISO8859-14	1
++module	INTERNAL		ISO-8859-14//		ISO8859-14	1
++
++#	from			to			module		cost
++alias	ISO8859-16//		ISO-8859-16//
++alias	ISO885916//		ISO-8859-16//
++alias	ISO-IR-226//		ISO-8859-16//
++alias	LATIN10//		ISO-8859-16//
++alias	L10//			ISO-8859-16//
++alias	ISO_8859-16:2001//	ISO-8859-16//
++alias	ISO_8859-16//		ISO-8859-16//
++module	ISO-8859-16//		INTERNAL		ISO8859-16	1
++module	INTERNAL		ISO-8859-16//		ISO8859-16	1
++
++#	from			to			module		cost
++alias	T.61//			T.61-8BIT//
++alias	ISO-IR-103//		T.61-8BIT//
++alias	CSISO103T618BIT//	T.61-8BIT//
++alias	T.618BIT//		T.61-8BIT//
++module	T.61-8BIT//		INTERNAL		T.61		1
++module	INTERNAL		T.61-8BIT//		T.61		1
++
++#	from			to			module		cost
++alias	ISO-IR-156//		ISO_6937//
++alias	ISO_6937:1992//		ISO_6937//
++alias	ISO6937//		ISO_6937//
++module	ISO_6937//		INTERNAL		ISO_6937	1
++module	INTERNAL		ISO_6937//		ISO_6937	1
++
++
++#	from			to			module		cost
++alias	ISO-IR-90//		ISO_6937-2//
++alias	ISO_6937-2:1983//	ISO_6937-2//
++alias	CSISO90//		ISO_6937-2//
++alias	ISO_69372//		ISO_6937-2//
++module	ISO_6937-2//		INTERNAL		ISO_6937-2	1
++module	INTERNAL		ISO_6937-2//		ISO_6937-2	1
++
++#	from			to			module		cost
++alias	SHIFT-JIS//		SJIS//
++alias	SHIFT_JIS//		SJIS//
++alias	MS_KANJI//		SJIS//
++alias	CSSHIFTJIS//		SJIS//
++module	SJIS//			INTERNAL		SJIS		1
++module	INTERNAL		SJIS//			SJIS		1
++
++#	from			to			module		cost
++alias	WINDOWS-31J//		CP932//
++alias	MS932//			CP932//
++alias	SJIS-OPEN//		CP932//
++alias	SJIS-WIN//		CP932//
++alias	CSWINDOWS31J//		CP932//
++module	CP932//			INTERNAL		CP932		1
++module	INTERNAL		CP932//			CP932		1
++
++#	from			to			module		cost
++alias	KOI8//			KOI-8//
++module	KOI-8//			INTERNAL		KOI-8		1
++module	INTERNAL		KOI-8//			KOI-8		1
++
++#	from			to			module		cost
++alias	CSKOI8R//		KOI8-R//
++alias	KOI8R//			KOI8-R//
++module	KOI8-R//		INTERNAL		KOI8-R		1
++module	INTERNAL		KOI8-R//		KOI8-R		1
++
++#	from			to			module		cost
++alias	ISO-IR-19//		LATIN-GREEK//
++alias	CSISO19LATINGREEK//	LATIN-GREEK//
++alias	LATINGREEK//		LATIN-GREEK//
++module	LATIN-GREEK//		INTERNAL		LATIN-GREEK	1
++module	INTERNAL		LATIN-GREEK//		LATIN-GREEK	1
++
++#	from			to			module		cost
++alias	ISO-IR-27//		LATIN-GREEK-1//
++alias	CSISO27LATINGREEK1//	LATIN-GREEK-1//
++alias	LATINGREEK1//		LATIN-GREEK-1//
++module	LATIN-GREEK-1//		INTERNAL		LATIN-GREEK-1	1
++module	INTERNAL		LATIN-GREEK-1//		LATIN-GREEK-1	1
++
++#	from			to			module		cost
++alias	ROMAN8//		HP-ROMAN8//
++alias	R8//			HP-ROMAN8//
++alias	CSHPROMAN8//		HP-ROMAN8//
++alias	OSF10010001//		HP-ROMAN8//
++alias	HPROMAN8//		HP-ROMAN8//
++module	HP-ROMAN8//		INTERNAL		HP-ROMAN8	1
++module	INTERNAL		HP-ROMAN8//		HP-ROMAN8	1
++
++#	from			to			module		cost
++alias	CSEBCDICATDE//		EBCDIC-AT-DE//
++alias	EBCDICATDE//		EBCDIC-AT-DE//
++module	EBCDIC-AT-DE//		INTERNAL		EBCDIC-AT-DE	1
++module	INTERNAL		EBCDIC-AT-DE//		EBCDIC-AT-DE	1
++
++#	from			to			module		cost
++alias	CSEBCDICATDEA//		EBCDIC-AT-DE-A//
++alias	EBCDICATDEA//		EBCDIC-AT-DE-A//
++module	EBCDIC-AT-DE-A//	INTERNAL		EBCDIC-AT-DE-A	1
++module	INTERNAL		EBCDIC-AT-DE-A//	EBCDIC-AT-DE-A	1
++
++#	from			to			module		cost
++alias	CSEBCDICCAFR//		EBCDIC-CA-FR//
++alias	EBCDICCAFR//		EBCDIC-CA-FR//
++module	EBCDIC-CA-FR//		INTERNAL		EBCDIC-CA-FR	1
++module	INTERNAL		EBCDIC-CA-FR//		EBCDIC-CA-FR	1
++
++#	from			to			module		cost
++alias	CSEBCDICDKNO//		EBCDIC-DK-NO//
++alias	EBCDICDKNO//		EBCDIC-DK-NO//
++module	EBCDIC-DK-NO//		INTERNAL		EBCDIC-DK-NO	1
++module	INTERNAL		EBCDIC-DK-NO//		EBCDIC-DK-NO	1
++
++#	from			to			module		cost
++alias	CSEBCDICDKNOA//		EBCDIC-DK-NO-A//
++alias	EBCDICDKNOA//		EBCDIC-DK-NO-A//
++module	EBCDIC-DK-NO-A//	INTERNAL		EBCDIC-DK-NO-A	1
++module	INTERNAL		EBCDIC-DK-NO-A//	EBCDIC-DK-NO-A	1
++
++#	from			to			module		cost
++alias	CSEBCDICES//		EBCDIC-ES//
++alias	EBCDICES//		EBCDIC-ES//
++module	EBCDIC-ES//		INTERNAL		EBCDIC-ES	1
++module	INTERNAL		EBCDIC-ES//		EBCDIC-ES	1
++
++#	from			to			module		cost
++alias	CSEBCDICESA//		EBCDIC-ES-A//
++alias	EBCDICESA//		EBCDIC-ES-A//
++module	EBCDIC-ES-A//		INTERNAL		EBCDIC-ES-A	1
++module	INTERNAL		EBCDIC-ES-A//		EBCDIC-ES-A	1
++
++#	from			to			module		cost
++alias	CSEBCDICESS//		EBCDIC-ES-S//
++alias	EBCDICESS//		EBCDIC-ES-S//
++module	EBCDIC-ES-S//		INTERNAL		EBCDIC-ES-S	1
++module	INTERNAL		EBCDIC-ES-S//		EBCDIC-ES-S	1
++
++#	from			to			module		cost
++alias	CSEBCDICFISE//		EBCDIC-FI-SE//
++alias	EBCDICFISE//		EBCDIC-FI-SE//
++module	EBCDIC-FI-SE//		INTERNAL		EBCDIC-FI-SE	1
++module	INTERNAL		EBCDIC-FI-SE//		EBCDIC-FI-SE	1
++
++#	from			to			module		cost
++alias	CSEBCDICFISEA//		EBCDIC-FI-SE-A//
++alias	EBCDICFISEA//		EBCDIC-FI-SE-A//
++module	EBCDIC-FI-SE-A//	INTERNAL		EBCDIC-FI-SE-A	1
++module	INTERNAL		EBCDIC-FI-SE-A//	EBCDIC-FI-SE-A	1
++
++#	from			to			module		cost
++alias	CSEBCDICFR//		EBCDIC-FR//
++alias	EBCDICFR//		EBCDIC-FR//
++module	EBCDIC-FR//		INTERNAL		EBCDIC-FR	1
++module	INTERNAL		EBCDIC-FR//		EBCDIC-FR	1
++
++#	from			to			module		cost
++alias	EBCDICISFRISS//		EBCDIC-IS-FRISS//
++module	EBCDIC-IS-FRISS//	INTERNAL		EBCDIC-IS-FRISS	1
++module	INTERNAL		EBCDIC-IS-FRISS//	EBCDIC-IS-FRISS	1
++
++#	from			to			module		cost
++alias	CSEBCDICIT//		EBCDIC-IT//
++alias	EBCDICIT//		EBCDIC-IT//
++module	EBCDIC-IT//		INTERNAL		EBCDIC-IT	1
++module	INTERNAL		EBCDIC-IT//		EBCDIC-IT	1
++
++#	from			to			module		cost
++alias	CSEBCDICPT//		EBCDIC-PT//
++alias	EBCDICPT//		EBCDIC-PT//
++module	EBCDIC-PT//		INTERNAL		EBCDIC-PT	1
++module	INTERNAL		EBCDIC-PT//		EBCDIC-PT	1
++
++#	from			to			module		cost
++alias	CSEBCDICUK//		EBCDIC-UK//
++alias	EBCDICUK//		EBCDIC-UK//
++module	EBCDIC-UK//		INTERNAL		EBCDIC-UK	1
++module	INTERNAL		EBCDIC-UK//		EBCDIC-UK	1
++
++#	from			to			module		cost
++alias	CSEBCDICUS//		EBCDIC-US//
++alias	EBCDICUS//		EBCDIC-US//
++module	EBCDIC-US//		INTERNAL		EBCDIC-US	1
++module	INTERNAL		EBCDIC-US//		EBCDIC-US	1
++
++#	from			to			module		cost
++alias	CP037//			IBM037//
++alias	EBCDIC-CP-US//		IBM037//
++alias	EBCDIC-CP-CA//		IBM037//
++alias	EBCDIC-CP-WT//		IBM037//
++alias	EBCDIC-CP-NL//		IBM037//
++alias	CSIBM037//		IBM037//
++alias	OSF10020025//		IBM037//
++alias	CP1070//		IBM037//
++alias	CP282//			IBM037//
++module	IBM037//		INTERNAL		IBM037		1
++module	INTERNAL		IBM037//		IBM037		1
++
++#	from			to			module		cost
++alias	EBCDIC-INT//		IBM038//
++alias	CP038//			IBM038//
++alias	CSIBM038//		IBM038//
++module	IBM038//		INTERNAL		IBM038		1
++module	INTERNAL		IBM038//		IBM038		1
++
++#	from			to			module		cost
++alias	EBCDIC-INT1//		IBM256//
++module	IBM256//		INTERNAL		IBM256		1
++module	INTERNAL		IBM256//		IBM256		1
++
++#	from			to			module		cost
++alias	CP273//			IBM273//
++alias	CSIBM273//		IBM273//
++alias	OSF10020111//		IBM273//
++module	IBM273//		INTERNAL		IBM273		1
++module	INTERNAL		IBM273//		IBM273		1
++
++#	from			to			module		cost
++alias	EBCDIC-BE//		IBM274//
++alias	CP274//			IBM274//
++alias	CSIBM274//		IBM274//
++module	IBM274//		INTERNAL		IBM274		1
++module	INTERNAL		IBM274//		IBM274		1
++
++#	from			to			module		cost
++alias	EBCDIC-BR//		IBM275//
++alias	CP275//			IBM275//
++alias	CSIBM275//		IBM275//
++module	IBM275//		INTERNAL		IBM275		1
++module	INTERNAL		IBM275//		IBM275		1
++
++#	from			to			module		cost
++alias	EBCDIC-CP-DK//		IBM277//
++alias	EBCDIC-CP-NO//		IBM277//
++alias	CSIBM277//		IBM277//
++alias	OSF10020115//		IBM277//
++module	IBM277//		INTERNAL		IBM277		1
++module	INTERNAL		IBM277//		IBM277		1
++
++#	from			to			module		cost
++alias	CP278//			IBM278//
++alias	EBCDIC-CP-FI//		IBM278//
++alias	EBCDIC-CP-SE//		IBM278//
++alias	CSIBM278//		IBM278//
++alias	OSF10020116//		IBM278//
++module	IBM278//		INTERNAL		IBM278		1
++module	INTERNAL		IBM278//		IBM278		1
++
++#	from			to			module		cost
++alias	CP280//			IBM280//
++alias	EBCDIC-CP-IT//		IBM280//
++alias	CSIBM280//		IBM280//
++alias	OSF10020118//		IBM280//
++module	IBM280//		INTERNAL		IBM280		1
++module	INTERNAL		IBM280//		IBM280		1
++
++#	from			to			module		cost
++alias	EBCDIC-JP-E//		IBM281//
++alias	CP281//			IBM281//
++alias	CSIBM281//		IBM281//
++module	IBM281//		INTERNAL		IBM281		1
++module	INTERNAL		IBM281//		IBM281		1
++
++#	from			to			module		cost
++alias	CP284//			IBM284//
++alias	EBCDIC-CP-ES//		IBM284//
++alias	CSIBM284//		IBM284//
++alias	OSF1002011C//		IBM284//
++alias	CP1079//		IBM284//
++module	IBM284//		INTERNAL		IBM284		1
++module	INTERNAL		IBM284//		IBM284		1
++
++#	from			to			module		cost
++alias	CP285//			IBM285//
++alias	EBCDIC-CP-GB//		IBM285//
++alias	CSIBM285//		IBM285//
++alias	OSF1002011D//		IBM285//
++module	IBM285//		INTERNAL		IBM285		1
++module	INTERNAL		IBM285//		IBM285		1
++
++#	from			to			module		cost
++alias	CP290//			IBM290//
++alias	EBCDIC-JP-KANA//	IBM290//
++alias	CSIBM290//		IBM290//
++alias	OSF10020122//		IBM290//
++module	IBM290//		INTERNAL		IBM290		1
++module	INTERNAL		IBM290//		IBM290		1
++
++#	from			to			module		cost
++alias	CP297//			IBM297//
++alias	EBCDIC-CP-FR//		IBM297//
++alias	CSIBM297//		IBM297//
++alias	OSF10020129//		IBM297//
++alias	CP1081//		IBM297//
++module	IBM297//		INTERNAL		IBM297		1
++module	INTERNAL		IBM297//		IBM297		1
++
++#	from			to			module		cost
++alias	CP420//			IBM420//
++alias	EBCDIC-CP-AR1//		IBM420//
++alias	CSIBM420//		IBM420//
++alias	OSF100201A4//		IBM420//
++module	IBM420//		INTERNAL		IBM420		1
++module	INTERNAL		IBM420//		IBM420		1
++
++#	from			to			module		cost
++alias	CP423//			IBM423//
++alias	EBCDIC-CP-GR//		IBM423//
++alias	CSIBM423//		IBM423//
++module	IBM423//		INTERNAL		IBM423		1
++module	INTERNAL		IBM423//		IBM423		1
++
++#	from			to			module		cost
++alias	CP424//			IBM424//
++alias	EBCDIC-CP-HE//		IBM424//
++alias	CSIBM424//		IBM424//
++alias	OSF100201A8//		IBM424//
++module	IBM424//		INTERNAL		IBM424		1
++module	INTERNAL		IBM424//		IBM424		1
++
++#	from			to			module		cost
++alias	CP437//			IBM437//
++alias	437//			IBM437//
++alias	CSPC8CODEPAGE437//	IBM437//
++alias	OSF100201B5//		IBM437//
++module	IBM437//		INTERNAL		IBM437		1
++module	INTERNAL		IBM437//		IBM437		1
++
++#	from			to			module		cost
++alias	CP500//			IBM500//
++alias	500//			IBM500//
++alias	500V1//			IBM500//
++alias	EBCDIC-CP-BE//		IBM500//
++alias	EBCDIC-CP-CH//		IBM500//
++alias	CSIBM500//		IBM500//
++alias	OSF100201F4//		IBM500//
++alias	CP1084//		IBM500//
++module	IBM500//		INTERNAL		IBM500		1
++module	INTERNAL		IBM500//		IBM500		1
++
++#	from			to			module		cost
++alias	CP850//			IBM850//
++alias	850//			IBM850//
++alias	CSPC850MULTILINGUAL//	IBM850//
++alias	OSF10020352//		IBM850//
++module	IBM850//		INTERNAL		IBM850		1
++module	INTERNAL		IBM850//		IBM850		1
++
++#	from			to			module		cost
++alias	CP858//			IBM858//
++alias	858//			IBM858//
++alias	CSPC858MULTILINGUAL//	IBM858//
++module	IBM858//		INTERNAL		IBM858		1
++module	INTERNAL		IBM858//		IBM858		1
++
++#	from			to			module		cost
++alias	CP851//			IBM851//
++alias	851//			IBM851//
++alias	CSIBM851//		IBM851//
++module	IBM851//		INTERNAL		IBM851		1
++module	INTERNAL		IBM851//		IBM851		1
++
++#	from			to			module		cost
++alias	CP852//			IBM852//
++alias	852//			IBM852//
++alias	CSPCP852//		IBM852//
++alias	OSF10020354//		IBM852//
++module	IBM852//		INTERNAL		IBM852		1
++module	INTERNAL		IBM852//		IBM852		1
++
++#	from			to			module		cost
++alias	CP855//			IBM855//
++alias	855//			IBM855//
++alias	CSIBM855//		IBM855//
++alias	OSF10020357//		IBM855//
++module	IBM855//		INTERNAL		IBM855		1
++module	INTERNAL		IBM855//		IBM855		1
++
++#	from			to			module		cost
++alias	IBM-856//		IBM856//
++alias	CP856//			IBM856//
++alias	856//			IBM856//
++alias	CSIBM856//		IBM856//
++module	IBM856//		INTERNAL		IBM856		1
++module	INTERNAL		IBM856//		IBM856		1
++
++#	from			to			module		cost
++alias	CP857//			IBM857//
++alias	857//			IBM857//
++alias	CSIBM857//		IBM857//
++alias	OSF10020359//		IBM857//
++module	IBM857//		INTERNAL		IBM857		1
++module	INTERNAL		IBM857//		IBM857		1
++
++#	from			to			module		cost
++alias	CP860//			IBM860//
++alias	860//			IBM860//
++alias	CSIBM860//		IBM860//
++module	IBM860//		INTERNAL		IBM860		1
++module	INTERNAL		IBM860//		IBM860		1
++
++#	from			to			module		cost
++alias	CP861//			IBM861//
++alias	861//			IBM861//
++alias	CPIBM861//		IBM861//
++alias	OSF1002035D//		IBM861//
++module	IBM861//		INTERNAL		IBM861		1
++module	INTERNAL		IBM861//		IBM861		1
++
++#	from			to			module		cost
++alias	CP862//			IBM862//
++alias	862//			IBM862//
++alias	CSPC862LATINHEBREW//	IBM862//
++alias	OSF1002035E//		IBM862//
++module	IBM862//		INTERNAL		IBM862		1
++module	INTERNAL		IBM862//		IBM862		1
++
++#	from			to			module		cost
++alias	CP863//			IBM863//
++alias	863//			IBM863//
++alias	CSIBM863//		IBM863//
++alias	OSF1002035F//		IBM863//
++module	IBM863//		INTERNAL		IBM863		1
++module	INTERNAL		IBM863//		IBM863		1
++
++#	from			to			module		cost
++alias	CP864//			IBM864//
++alias	864//			IBM864//
++alias	CSIBM864//		IBM864//
++alias	OSF10020360//		IBM864//
++module	IBM864//		INTERNAL		IBM864		1
++module	INTERNAL		IBM864//		IBM864		1
++
++#	from			to			module		cost
++alias	CP865//			IBM865//
++alias	865//			IBM865//
++alias	CSIBM865//		IBM865//
++module	IBM865//		INTERNAL		IBM865		1
++module	INTERNAL		IBM865//		IBM865		1
++
++#	from			to			module		cost
++alias	CP866//			IBM866//
++alias	866//			IBM866//
++alias	CSIBM866//		IBM866//
++module	IBM866//		INTERNAL		IBM866		1
++module	INTERNAL		IBM866//		IBM866		1
++
++#	from			to			module		cost
++alias	CP866NAV//		IBM866NAV//
++alias	866NAV//		IBM866NAV//
++module	IBM866NAV//		INTERNAL		IBM866NAV	1
++module	INTERNAL		IBM866NAV//		IBM866NAV	1
++
++#	from			to			module		cost
++alias	CP868//			IBM868//
++alias	CP-AR//			IBM868//
++alias	CSIBM868//		IBM868//
++alias	OSF10020364//		IBM868//
++module	IBM868//		INTERNAL		IBM868		1
++module	INTERNAL		IBM868//		IBM868		1
++
++#	from			to			module		cost
++alias	CP869//			IBM869//
++alias	869//			IBM869//
++alias	CP-GR//			IBM869//
++alias	CSIBM869//		IBM869//
++alias	OSF10020365//		IBM869//
++module	IBM869//		INTERNAL		IBM869		1
++module	INTERNAL		IBM869//		IBM869		1
++
++#	from			to			module		cost
++alias	CP870//			IBM870//
++alias	EBCDIC-CP-ROECE//	IBM870//
++alias	EBCDIC-CP-YU//		IBM870//
++alias	CSIBM870//		IBM870//
++alias	OSF10020366//		IBM870//
++module	IBM870//		INTERNAL		IBM870		1
++module	INTERNAL		IBM870//		IBM870		1
++
++#	from			to			module		cost
++alias	CP871//			IBM871//
++alias	EBCDIC-CP-IS//		IBM871//
++alias	CSIBM871//		IBM871//
++alias	OSF10020367//		IBM871//
++module	IBM871//		INTERNAL		IBM871		1
++module	INTERNAL		IBM871//		IBM871		1
++
++#	from			to			module		cost
++alias	CP875//			IBM875//
++alias	EBCDIC-GREEK//		IBM875//
++alias	OSF1002036B//		IBM875//
++module	IBM875//		INTERNAL		IBM875		1
++module	INTERNAL		IBM875//		IBM875		1
++
++#	from			to			module		cost
++alias	CP880//			IBM880//
++alias	EBCDIC-CYRILLIC//	IBM880//
++alias	CSIBM880//		IBM880//
++alias	OSF10020370//		IBM880//
++module	IBM880//		INTERNAL		IBM880		1
++module	INTERNAL		IBM880//		IBM880		1
++
++#	from			to			module		cost
++alias	CP891//			IBM891//
++alias	CSIBM891//		IBM891//
++alias	OSF1002037B//		IBM891//
++module	IBM891//		INTERNAL		IBM891		1
++module	INTERNAL		IBM891//		IBM891		1
++
++#	from			to			module		cost
++alias	CP903//			IBM903//
++alias	CSIBM903//		IBM903//
++alias	OSF10020387//		IBM903//
++module	IBM903//		INTERNAL		IBM903		1
++module	INTERNAL		IBM903//		IBM903		1
++
++#	from			to			module		cost
++alias	CP904//			IBM904//
++alias	904//			IBM904//
++alias	CSIBM904//		IBM904//
++alias	OSF10020388//		IBM904//
++module	IBM904//		INTERNAL		IBM904		1
++module	INTERNAL		IBM904//		IBM904		1
++
++#	from			to			module		cost
++alias	CP905//			IBM905//
++alias	EBCDIC-CP-TR//		IBM905//
++alias	CSIBM905//		IBM905//
++module	IBM905//		INTERNAL		IBM905		1
++module	INTERNAL		IBM905//		IBM905		1
++
++#	from			to			module		cost
++alias	CP918//			IBM918//
++alias	EBCDIC-CP-AR2//		IBM918//
++alias	CSIBM918//		IBM918//
++alias	OSF10020396//		IBM918//
++module	IBM918//		INTERNAL		IBM918		1
++module	INTERNAL		IBM918//		IBM918		1
++
++#	from			to			module		cost
++alias	IBM-922//		IBM922//
++alias	CP922//			IBM922//
++alias	CSIBM922//		IBM922//
++module	IBM922//		INTERNAL		IBM922		1
++module	INTERNAL		IBM922//		IBM922		1
++
++#	from			to			module		cost
++alias	IBM-930//		IBM930//
++alias	CP930//			IBM930//
++alias	CSIBM930//		IBM930//
++module	IBM930//		INTERNAL		IBM930		1
++module	INTERNAL		IBM930//		IBM930		1
++
++#	from			to			module		cost
++alias	IBM-932//		IBM932//
++alias	CSIBM932//		IBM932//
++module	IBM932//		INTERNAL		IBM932		1
++module	INTERNAL		IBM932//		IBM932		1
++
++#	from			to			module		cost
++alias	IBM-933//		IBM933//
++alias	CP933//			IBM933//
++alias	CSIBM933//		IBM933//
++module	IBM933//		INTERNAL		IBM933		1
++module	INTERNAL		IBM933//		IBM933		1
++
++#	from			to			module		cost
++alias	IBM-935//		IBM935//
++alias	CP935//			IBM935//
++alias	CSIBM935//		IBM935//
++module	IBM935//		INTERNAL		IBM935		1
++module	INTERNAL		IBM935//		IBM935		1
++
++#	from			to			module		cost
++alias	IBM-937//		IBM937//
++alias	CP937//			IBM937//
++alias	CSIBM937//		IBM937//
++module	IBM937//		INTERNAL		IBM937		1
++module	INTERNAL		IBM937//		IBM937		1
++
++#	from			to			module		cost
++alias	IBM-939//		IBM939//
++alias	CP939//			IBM939//
++alias	CSIBM939//		IBM939//
++module	IBM939//		INTERNAL		IBM939		1
++module	INTERNAL		IBM939//		IBM939		1
++
++#	from			to			module		cost
++alias	IBM-943//		IBM943//
++alias	CSIBM943//		IBM943//
++module	IBM943//		INTERNAL		IBM943		1
++module	INTERNAL		IBM943//		IBM943		1
++
++#	from			to			module		cost
++alias	CP1004//		IBM1004//
++alias	OS2LATIN1//		IBM1004//
++module	IBM1004//		INTERNAL		IBM1004		1
++module	INTERNAL		IBM1004//		IBM1004		1
++
++#	from			to			module		cost
++alias	CP1026//		IBM1026//
++alias	1026//			IBM1026//
++alias	CSIBM1026//		IBM1026//
++alias	OSF10020402//		IBM1026//
++module	IBM1026//		INTERNAL		IBM1026		1
++module	INTERNAL		IBM1026//		IBM1026		1
++
++#	from			to			module		cost
++alias	IBM-1046//		IBM1046//
++alias	CP1046//		IBM1046//
++alias	1046//			IBM1046//
++module	IBM1046//		INTERNAL		IBM1046		1
++module	INTERNAL		IBM1046//		IBM1046		1
++
++#	from			to			module		cost
++alias	IBM-1047//		IBM1047//
++alias	CP1047//		IBM1047//
++alias	1047//			IBM1047//
++alias	OSF10020417//		IBM1047//
++module	IBM1047//		INTERNAL		IBM1047		1
++module	INTERNAL		IBM1047//		IBM1047		1
++
++#	from			to			module		cost
++alias	IBM-1124//		IBM1124//
++alias	CP1124//		IBM1124//
++alias	CSIBM1124//		IBM1124//
++module	IBM1124//		INTERNAL		IBM1124		1
++module	INTERNAL		IBM1124//		IBM1124		1
++
++#	from			to			module		cost
++alias	IBM-1129//		IBM1129//
++alias	CP1129//		IBM1129//
++alias	CSIBM1129//		IBM1129//
++module	IBM1129//		INTERNAL		IBM1129		1
++module	INTERNAL		IBM1129//		IBM1129		1
++
++#	from			to			module		cost
++alias	IBM-1160//		IBM1160//
++alias	CP1160//		IBM1160//
++alias	CSIBM1160//		IBM1160//
++module	IBM1160//		INTERNAL		IBM1160		1
++module	INTERNAL		IBM1160//		IBM1160		1
++
++#	from			to			module		cost
++alias	IBM-1161//		IBM1161//
++alias	CP1161//		IBM1161//
++alias	CSIBM1161//		IBM1161//
++module	IBM1161//		INTERNAL		IBM1161		1
++module	INTERNAL		IBM1161//		IBM1161		1
++
++#	from			to			module		cost
++alias	IBM-1132//		IBM1132//
++alias	CP1132//		IBM1132//
++alias	CSIBM1132//		IBM1132//
++module	IBM1132//		INTERNAL		IBM1132		1
++module	INTERNAL		IBM1132//		IBM1132		1
++
++#	from			to			module		cost
++alias	IBM-1133//		IBM1133//
++alias	CP1133//		IBM1133//
++alias	CSIBM1133//		IBM1133//
++module	IBM1133//		INTERNAL		IBM1133		1
++module	INTERNAL		IBM1133//		IBM1133		1
++
++#	from			to			module		cost
++alias	IBM-1162//		IBM1162//
++alias	CP1162//		IBM1162//
++alias	CSIBM11621162//		IBM1162//
++module	IBM1162//		INTERNAL		IBM1162		1
++module	INTERNAL		IBM1162//		IBM1162		1
++
++#	from			to			module		cost
++alias	IBM-1163//		IBM1163//
++alias	CP1163//		IBM1163//
++alias	CSIBM1163//		IBM1163//
++module	IBM1163//		INTERNAL		IBM1163		1
++module	INTERNAL		IBM1163//		IBM1163		1
++
++#	from			to			module		cost
++alias	IBM-1164//		IBM1164//
++alias	CP1164//		IBM1164//
++alias	CSIBM1164//		IBM1164//
++module	IBM1164//		INTERNAL		IBM1164		1
++module	INTERNAL		IBM1164//		IBM1164		1
++
++#	from			to			module		cost
++alias	EUCKR//			EUC-KR//
++alias	CSEUCKR//		EUC-KR//
++alias	OSF0004000a//		EUC-KR//
++module	EUC-KR//		INTERNAL		EUC-KR		1
++module	INTERNAL		EUC-KR//		EUC-KR		1
++
++#	from			to			module		cost
++alias	MSCP949//		UHC//
++alias	CP949//			UHC//
++alias	OSF100203B5//		UHC//
++module	UHC//			INTERNAL		UHC		1
++module	INTERNAL		UHC//			UHC		1
++
++#	from			to			module		cost
++alias	MSCP1361//		JOHAB//
++alias	CP1361//		JOHAB//
++module	JOHAB//			INTERNAL		JOHAB		1
++module	INTERNAL		JOHAB//			JOHAB		1
++
++#	from			to			module		cost
++alias	BIG-FIVE//		BIG5//
++alias	BIGFIVE//		BIG5//
++alias	BIG-5//			BIG5//
++alias	CN-BIG5//		BIG5//
++alias	CP950//			BIG5//
++module	BIG5//			INTERNAL		BIG5		1
++module	INTERNAL		BIG5//			BIG5		1
++
++#	from			to			module		cost
++alias	BIG5-HKSCS//		BIG5HKSCS//
++module	BIG5HKSCS//		INTERNAL		BIG5HKSCS	1
++module	INTERNAL		BIG5HKSCS//		BIG5HKSCS	1
++
++#	from			to			module		cost
++alias	EUCJP-MS//		EUC-JP-MS//
++alias	EUCJP-OPEN//		EUC-JP-MS//
++alias	EUCJP-WIN//		EUC-JP-MS//
++module	EUC-JP-MS//		INTERNAL		EUC-JP-MS	1
++module	INTERNAL		EUC-JP-MS//		EUC-JP-MS	1
++
++#	from			to			module		cost
++alias	EUCJP//			EUC-JP//
++alias	CSEUCPKDFMTJAPANESE//	EUC-JP//
++alias	OSF00030010//		EUC-JP//
++alias	UJIS//			EUC-JP//
++module	EUC-JP//		INTERNAL		EUC-JP		1
++module	INTERNAL		EUC-JP//		EUC-JP		1
++
++#	from			to			module		cost
++alias	EUCCN//			EUC-CN//
++alias	GB2312//		EUC-CN//
++alias	csGB2312//		EUC-CN//
++alias	CN-GB//			EUC-CN//
++module	EUC-CN//		INTERNAL		EUC-CN		1
++module	INTERNAL		EUC-CN//		EUC-CN		1
++
++#	from			to			module		cost
++module	EUC-CN//		BIG5//			GBBIG5		1
++module	BIG5//			EUC-CN//		GBBIG5		1
++
++#	from			to			module		cost
++alias	GB13000//		GBK//
++alias	CP936//			GBK//
++alias	MS936//			GBK//
++alias	WINDOWS-936//		GBK//
++module	GBK//			INTERNAL		GBK		1
++module	INTERNAL		GBK//			GBK		1
++
++#	from			to			module		cost
++module	GBK//			EUC-CN//		GBGBK		1
++module	EUC-CN//		GBK//			GBGBK		1
++
++#	from			to			module		cost
++alias	EUCTW//			EUC-TW//
++alias	OSF0005000a//		EUC-TW//
++module	EUC-TW//		INTERNAL		EUC-TW		1
++module	INTERNAL		EUC-TW//		EUC-TW		1
++
++#	from			to			module		cost
++alias	RUSCII//		CP1125//
++alias	IBM848//		CP1125//
++module	CP1125//		INTERNAL		CP1125		1
++module	INTERNAL		CP1125//		CP1125		1
++
++#	from			to			module		cost
++alias	MS-EE//			CP1250//
++alias	WINDOWS-1250//		CP1250//
++module	CP1250//		INTERNAL		CP1250		1
++module	INTERNAL		CP1250//		CP1250		1
++
++#	from			to			module		cost
++alias	MS-CYRL//		CP1251//
++alias	WINDOWS-1251//		CP1251//
++module	CP1251//		INTERNAL		CP1251		1
++module	INTERNAL		CP1251//		CP1251		1
++
++#	from			to			module		cost
++alias	MS-GREEK//		CP1253//
++alias	WINDOWS-1253//		CP1253//
++module	CP1253//		INTERNAL		CP1253		1
++module	INTERNAL		CP1253//		CP1253		1
++
++#	from			to			module		cost
++alias	MS-TURK//		CP1254//
++alias	WINDOWS-1254//		CP1254//
++module	CP1254//		INTERNAL		CP1254		1
++module	INTERNAL		CP1254//		CP1254		1
++
++#	from			to			module		cost
++alias	MS-HEBR//		CP1255//
++alias	WINDOWS-1255//		CP1255//
++module	CP1255//		INTERNAL		CP1255		1
++module	INTERNAL		CP1255//		CP1255		1
++
++#	from			to			module		cost
++alias	MS-ARAB//		CP1256//
++alias	WINDOWS-1256//		CP1256//
++module	CP1256//		INTERNAL		CP1256		1
++module	INTERNAL		CP1256//		CP1256		1
++
++#	from			to			module		cost
++alias	WINBALTRIM//		CP1257//
++alias	WINDOWS-1257//		CP1257//
++module	CP1257//		INTERNAL		CP1257		1
++module	INTERNAL		CP1257//		CP1257		1
++
++#	from			to			module		cost
++alias	WINDOWS-1258//		CP1258//
++module	CP1258//		INTERNAL		CP1258		1
++module	INTERNAL		CP1258//		CP1258		1
++
++#	from			to			module		cost
++alias	874//			IBM874//
++alias	CP874//			IBM874//
++alias	WINDOWS-874//		IBM874//
++module	IBM874//		INTERNAL		IBM874		1
++module	INTERNAL		IBM874//		IBM874		1
++
++#	from			to			module		cost
++module	CP737//			INTERNAL		CP737		1
++module	INTERNAL		CP737//			CP737		1
++
++#	from			to			module		cost
++module	CP770//			INTERNAL		CP770		1
++module	INTERNAL		CP770//			CP770		1
++
++#	from			to			module		cost
++module	CP771//			INTERNAL		CP771		1
++module	INTERNAL		CP771//			CP771		1
++
++#	from			to			module		cost
++module	CP772//			INTERNAL		CP772		1
++module	INTERNAL		CP772//			CP772		1
++
++#	from			to			module		cost
++module	CP773//			INTERNAL		CP773		1
++module	INTERNAL		CP773//			CP773		1
++
++#	from			to			module		cost
++module	CP774//			INTERNAL		CP774		1
++module	INTERNAL		CP774//			CP774		1
++
++#	from			to			module		cost
++alias	IBM775//		CP775//
++alias	CSPC775BALTIC//		CP775//
++module	CP775//			INTERNAL		CP775		1
++module	INTERNAL		CP775//			CP775		1
++
++#	from			to			module		cost
++alias	CSISO2022JP//		ISO-2022-JP//
++alias	ISO2022JP//		ISO-2022-JP//
++module	ISO-2022-JP//		INTERNAL		ISO-2022-JP	1
++module	INTERNAL		ISO-2022-JP//		ISO-2022-JP	1
++
++#	from			to			module		cost
++alias	CSISO2022JP2//		ISO-2022-JP-2//
++alias	ISO2022JP2//		ISO-2022-JP-2//
++module	ISO-2022-JP-2//		INTERNAL		ISO-2022-JP	1
++module	INTERNAL		ISO-2022-JP-2//		ISO-2022-JP	1
++
++#	from			to			module		cost
++module	ISO-2022-JP-3//		INTERNAL		ISO-2022-JP-3	1
++module	INTERNAL		ISO-2022-JP-3//		ISO-2022-JP-3	1
++
++#	from			to			module		cost
++alias	CSISO2022KR//		ISO-2022-KR//
++alias	ISO2022KR//		ISO-2022-KR//
++module	ISO-2022-KR//		INTERNAL		ISO-2022-KR	1
++module	INTERNAL		ISO-2022-KR//		ISO-2022-KR	1
++
++#	from			to			module		cost
++alias	CSISO2022CN//		ISO-2022-CN//
++alias	ISO2022CN//		ISO-2022-CN//
++module	ISO-2022-CN//		INTERNAL		ISO-2022-CN	1
++module	INTERNAL		ISO-2022-CN//		ISO-2022-CN	1
++
++#	from			to			module		cost
++alias	ISO2022CNEXT//		ISO-2022-CN-EXT//
++module	ISO-2022-CN-EXT//	INTERNAL		ISO-2022-CN-EXT	1
++module	INTERNAL		ISO-2022-CN-EXT//	ISO-2022-CN-EXT	1
++
++#	from			to			module		cost
++alias	MAC//			MACINTOSH//
++alias	CSMACINTOSH//		MACINTOSH//
++module	MACINTOSH//		INTERNAL		MACINTOSH	1
++module	INTERNAL		MACINTOSH//		MACINTOSH	1
++
++#	from			to			module		cost
++alias	ISO-IR-143//		IEC_P27-1//
++alias	CSISO143IECP271//	IEC_P27-1//
++alias	IEC_P271//		IEC_P27-1//
++module	IEC_P27-1//		INTERNAL		IEC_P27-1	1
++module	INTERNAL		IEC_P27-1//		IEC_P27-1	1
++
++#	from			to			module		cost
++alias	ISO_9036//		ASMO_449//
++alias	ARABIC7//		ASMO_449//
++alias	ISO-IR-89//		ASMO_449//
++alias	CSISO89ASMO449//	ASMO_449//
++module	ASMO_449//		INTERNAL		ASMO_449	1
++module	INTERNAL		ASMO_449//		ASMO_449	1
++
++#	from			to			module		cost
++alias	ISO-IR-139//		CSN_369103//
++alias	CSISO139CSN369103//	CSN_369103//
++module	CSN_369103//		INTERNAL		CSN_369103	1
++module	INTERNAL		CSN_369103//		CSN_369103	1
++
++#	from			to			module		cost
++alias	CWI-2//			CWI//
++alias	CP-HU//			CWI//
++module	CWI//			INTERNAL		CWI		1
++module	INTERNAL		CWI//			CWI		1
++
++#	from			to			module		cost
++alias	DEC//			DEC-MCS//
++alias	CSDECMCS//		DEC-MCS//
++alias	DECMCS//		DEC-MCS//
++module	DEC-MCS//		INTERNAL		DEC-MCS		1
++module	INTERNAL		DEC-MCS//		DEC-MCS		1
++
++#	from			to			module		cost
++alias	ISO-IR-111//		ECMA-CYRILLIC//
++alias	CSISO111ECMACYRILLIC//	ECMA-CYRILLIC//
++alias	ECMACYRILLIC//		ECMA-CYRILLIC//
++module	ECMA-CYRILLIC//		INTERNAL		ECMA-CYRILLIC	1
++module	INTERNAL		ECMA-CYRILLIC//		ECMA-CYRILLIC	1
++
++#	from			to			module		cost
++alias	ST_SEV_358-88//		GOST_19768-74//
++alias	GOST_19768//		GOST_19768-74//
++alias	ISO-IR-153//		GOST_19768-74//
++alias	CSISO153GOST1976874//	GOST_19768-74//
++alias	GOST_1976874//		GOST_19768-74//
++module	GOST_19768-74//		INTERNAL		GOST_19768-74	1
++module	INTERNAL		GOST_19768-74//		GOST_19768-74	1
++
++#	from			to			module		cost
++alias	ISO-IR-150//		GREEK-CCITT//
++alias	CSISO150//		GREEK-CCITT//
++alias	CSISO150GREEKCCITT//	GREEK-CCITT//
++alias	GREEKCCITT//		GREEK-CCITT//
++module	GREEK-CCITT//		INTERNAL		GREEK-CCITT	1
++module	INTERNAL		GREEK-CCITT//		GREEK-CCITT	1
++
++#	from			to			module		cost
++alias	ISO-IR-88//		GREEK7//
++alias	CSISO88GREEK7//		GREEK7//
++module	GREEK7//		INTERNAL		GREEK7		1
++module	INTERNAL		GREEK7//		GREEK7		1
++
++#	from			to			module		cost
++alias	ISO-IR-18//		GREEK7-OLD//
++alias	CSISO18GREEK7OLD//	GREEK7-OLD//
++alias	GREEK7OLD//		GREEK7-OLD//
++module	GREEK7-OLD//		INTERNAL		GREEK7-OLD	1
++module	INTERNAL		GREEK7-OLD//		GREEK7-OLD	1
++
++#	from			to			module		cost
++alias	ISO-IR-49//		INIS//
++alias	CSISO49INIS//		INIS//
++module	INIS//			INTERNAL		INIS		1
++module	INTERNAL		INIS//			INIS		1
++
++#	from			to			module		cost
++alias	ISO-IR-50//		INIS-8//
++alias	CSISO50INIS8//		INIS-8//
++alias	INIS8//			INIS-8//
++module	INIS-8//		INTERNAL		INIS-8		1
++module	INTERNAL		INIS-8//		INIS-8		1
++
++#	from			to			module		cost
++alias	ISO-IR-51//		INIS-CYRILLIC//
++alias	CSISO51INISCYRILLIC//	INIS-CYRILLIC//
++alias	INISCYRILLIC//		INIS-CYRILLIC//
++module	INIS-CYRILLIC//		INTERNAL		INIS-CYRILLIC	1
++module	INTERNAL		INIS-CYRILLIC//		INIS-CYRILLIC	1
++
++#	from			to			module		cost
++alias	ISO-IR-98//		ISO_2033//
++alias	ISO_2033-1983//		ISO_2033//
++alias	E13B//			ISO_2033//
++alias	CSISO2033//		ISO_2033//
++module	ISO_2033//		INTERNAL		ISO_2033	1
++module	INTERNAL		ISO_2033//		ISO_2033	1
++
++#	from			to			module		cost
++alias	ISO-IR-37//		ISO_5427//
++alias	KOI-7//			ISO_5427//
++alias	CSISO5427CYRILLIC//	ISO_5427//
++module	ISO_5427//		INTERNAL		ISO_5427	1
++module	INTERNAL		ISO_5427//		ISO_5427	1
++
++#	from			to			module		cost
++alias	ISO-IR-54//		ISO_5427-EXT//
++alias	ISO_5427:1981//		ISO_5427-EXT//
++alias	CSISO5427CYRILLIC1981//	ISO_5427-EXT//
++alias	ISO_5427EXT//		ISO_5427-EXT//
++module	ISO_5427-EXT//		INTERNAL		ISO_5427-EXT	1
++module	INTERNAL		ISO_5427-EXT//		ISO_5427-EXT	1
++
++#	from			to			module		cost
++alias	ISO-IR-55//		ISO_5428//
++alias	ISO_5428:1980//		ISO_5428//
++alias	CSISO5428GREEK//	ISO_5428//
++module	ISO_5428//		INTERNAL		ISO_5428	1
++module	INTERNAL		ISO_5428//		ISO_5428	1
++
++#	from			to			module		cost
++alias	ISO-IR-155//		ISO_10367-BOX//
++alias	CSISO10367BOX//		ISO_10367-BOX//
++alias	ISO_10367BOX//		ISO_10367-BOX//
++module	ISO_10367-BOX//		INTERNAL		ISO_10367-BOX	1
++module	INTERNAL		ISO_10367-BOX//		ISO_10367-BOX	1
++
++#	from			to			module		cost
++alias	MACIS//			MAC-IS//
++module	MAC-IS//		INTERNAL		MAC-IS		1
++module	INTERNAL		MAC-IS//		MAC-IS		1
++
++#	from			to			module		cost
++alias	MACUK//			MAC-UK//
++alias	MACUKRAINIAN//		MAC-UK//
++alias	MAC-CYRILLIC//		MAC-UK//
++alias	MACCYRILLIC//		MAC-UK//
++module	MAC-UK//		INTERNAL		MAC-UK		1
++module	INTERNAL		MAC-UK//		MAC-UK		1
++
++#	from			to			module		cost
++alias	MS-MAC-CYRILLIC//	CP10007//
++alias	MSMACCYRILLIC//		CP10007//
++module	CP10007//		INTERNAL		CP10007		1
++module	INTERNAL		CP10007//		CP10007		1
++
++#	from			to			module		cost
++alias	ISO-IR-9-1//		NATS-DANO//
++alias	CSNATSDANO//		NATS-DANO//
++alias	NATSDANO//		NATS-DANO//
++module	NATS-DANO//		INTERNAL		NATS-DANO	1
++module	INTERNAL		NATS-DANO//		NATS-DANO	1
++
++#	from			to			module		cost
++alias	ISO-IR-8-1//		NATS-SEFI//
++alias	CSNATSSEFI//		NATS-SEFI//
++alias	NATSSEFI//		NATS-SEFI//
++module	NATS-SEFI//		INTERNAL		NATS-SEFI	1
++module	INTERNAL		NATS-SEFI//		NATS-SEFI	1
++
++#	from			to			module		cost
++alias	WS2//			WIN-SAMI-2//
++alias	WINSAMI2//		WIN-SAMI-2//
++module	WIN-SAMI-2//		INTERNAL		SAMI-WS2	1
++module	INTERNAL		WIN-SAMI-2//		SAMI-WS2	1
++
++#	from			to			module		cost
++module	ISO-IR-197//		INTERNAL		ISO-IR-197	1
++module	INTERNAL		ISO-IR-197//		ISO-IR-197	1
++
++#	from			to			module		cost
++alias	TIS620//		TIS-620//
++alias	TIS620-0//		TIS-620//
++alias	TIS620.2529-1//		TIS-620//
++alias	TIS620.2533-0//		TIS-620//
++alias	ISO-IR-166//		TIS-620//
++module	TIS-620//		INTERNAL		TIS-620		1
++module	INTERNAL		TIS-620//		TIS-620		1
++
++#	from			to			module		cost
++alias	KOI8U//			KOI8-U//
++module	KOI8-U//		INTERNAL		KOI8-U		1
++module	INTERNAL		KOI8-U//		KOI8-U		1
++
++#	from			to			module		cost
++alias	ISIRI3342//		ISIRI-3342//
++module	ISIRI-3342//		INTERNAL		ISIRI-3342	1
++module	INTERNAL		ISIRI-3342//		ISIRI-3342	1
++
++#	from			to			module		cost
++module	GB18030//		INTERNAL		GB18030		1
++module	INTERNAL		GB18030//		GB18030		1
++
++#	from			to			module		cost
++module	VISCII//		INTERNAL		VISCII		1
++module	INTERNAL		VISCII//		VISCII		1
++
++#	from			to			module		cost
++module	KOI8-T//		INTERNAL		KOI8-T		1
++module	INTERNAL		KOI8-T//		KOI8-T		1
++
++#	from			to			module		cost
++module	GEORGIAN-PS//		INTERNAL		GEORGIAN-PS	1
++module	INTERNAL		GEORGIAN-PS//		GEORGIAN-PS	1
++
++#	from			to			module		cost
++module	GEORGIAN-ACADEMY//	INTERNAL		GEORGIAN-ACADEMY 1
++module	INTERNAL		GEORGIAN-ACADEMY//	GEORGIAN-ACADEMY 1
++
++#	from			to			module		cost
++module	ISO-IR-209//		INTERNAL		ISO-IR-209	1
++module	INTERNAL		ISO-IR-209//		ISO-IR-209	1
++
++#	from			to			module		cost
++module	MAC-SAMI//		INTERNAL		MAC-SAMI	1
++module	INTERNAL		MAC-SAMI//		MAC-SAMI	1
++
++#	from			to			module		cost
++alias	ARMSCII8//		ARMSCII-8//
++module	ARMSCII-8//		INTERNAL		ARMSCII-8	1
++module	INTERNAL		ARMSCII-8//		ARMSCII-8	1
++
++#	from			to			module		cost
++alias	TCVN//			TCVN5712-1//
++alias	TCVN-5712//		TCVN5712-1//
++alias	TCVN5712-1:1993//	TCVN5712-1//
++module	TCVN5712-1//		INTERNAL		TCVN5712-1	1
++module	INTERNAL		TCVN5712-1//		TCVN5712-1	1
++
++#	from			to			module		cost
++module	EUC-JISX0213//		INTERNAL		EUC-JISX0213	1
++module	INTERNAL		EUC-JISX0213//		EUC-JISX0213	1
++
++#	from			to			module		cost
++alias	ShiftJISX0213//		Shift_JISX0213//
++module	Shift_JISX0213//	INTERNAL		SHIFT_JISX0213	1
++module	INTERNAL		Shift_JISX0213//	SHIFT_JISX0213	1
++
++#	from			to			module		cost
++module	TSCII//			INTERNAL		TSCII		1
++module	INTERNAL		TSCII//			TSCII		1
++
++#	from			to			module		cost
++module	PT154//			INTERNAL		PT154		1
++module	INTERNAL		PT154//			PT154		1
++
++#	from			to			module		cost
++alias	STRK1048-2002//		RK1048//
++module	RK1048//		INTERNAL		RK1048		1
++module	INTERNAL		RK1048//		RK1048		1
++
++#	from			to			module		cost
++alias	IBM-1025//		IBM1025//
++alias	CP1025//		IBM1025//
++alias	CSIBM1025//		IBM1025//
++module	IBM1025//		INTERNAL		IBM1025		1
++module	INTERNAL		IBM1025//		IBM1025		1
++
++#	from			to			module		cost
++alias	IBM-1122//		IBM1122//
++alias	CP1122//		IBM1122//
++alias	CSIBM1122//		IBM1122//
++module	IBM1122//		INTERNAL		IBM1122		1
++module	INTERNAL		IBM1122//		IBM1122		1
++
++#	from			to			module		cost
++alias	IBM-1137//		IBM1137//
++alias	CP1137//		IBM1137//
++alias	CSIBM1137//		IBM1137//
++module	IBM1137//		INTERNAL		IBM1137		1
++module	INTERNAL		IBM1137//		IBM1137		1
++
++#	from			to			module		cost
++alias	IBM-1153//		IBM1153//
++alias	CP1153//		IBM1153//
++alias	CSIBM1153//		IBM1153//
++module	IBM1153//		INTERNAL		IBM1153		1
++module	INTERNAL		IBM1153//		IBM1153		1
++
++#	from			to			module		cost
++alias	IBM-1154//		IBM1154//
++alias	CP1154//		IBM1154//
++alias	CSIBM1154//		IBM1154//
++module	IBM1154//		INTERNAL		IBM1154		1
++module	INTERNAL		IBM1154//		IBM1154		1
++
++#	from			to			module		cost
++alias	IBM-1155//		IBM1155//
++alias	CP1155//		IBM1155//
++alias	CSIBM1155//		IBM1155//
++module	IBM1155//		INTERNAL		IBM1155		1
++module	INTERNAL		IBM1155//		IBM1155		1
++
++#	from			to			module		cost
++alias	IBM-1156//		IBM1156//
++alias	CP1156//		IBM1156//
++alias	CSIBM1156//		IBM1156//
++module	IBM1156//		INTERNAL		IBM1156		1
++module	INTERNAL		IBM1156//		IBM1156		1
++
++#	from			to			module		cost
++alias	IBM-1157//		IBM1157//
++alias	CP1157//		IBM1157//
++alias	CSIBM1157//		IBM1157//
++module	IBM1157//		INTERNAL		IBM1157		1
++module	INTERNAL		IBM1157//		IBM1157		1
++
++#	from			to			module		cost
++alias	IBM-1158//		IBM1158//
++alias	CP1158//		IBM1158//
++alias	CSIBM1158//		IBM1158//
++module	IBM1158//		INTERNAL		IBM1158		1
++module	INTERNAL		IBM1158//		IBM1158		1
++
++#	from			to			module		cost
++alias	IBM-803//		IBM803//
++alias	CP803//		IBM803//
++alias	CSIBM803//		IBM803//
++module	IBM803//		INTERNAL		IBM803		1
++module	INTERNAL		IBM803//		IBM803		1
++
++#	from			to			module		cost
++alias	IBM-901//		IBM901//
++alias	CP901//		IBM901//
++alias	CSIBM901//		IBM901//
++module	IBM901//		INTERNAL		IBM901		1
++module	INTERNAL		IBM901//		IBM901		1
++
++#	from			to			module		cost
++alias	IBM-902//		IBM902//
++alias	CP902//		IBM902//
++alias	CSIBM902//		IBM902//
++module	IBM902//		INTERNAL		IBM902		1
++module	INTERNAL		IBM902//		IBM902		1
++
++#	from			to			module		cost
++alias	IBM-921//		IBM921//
++alias	CP921//		IBM921//
++alias	CSIBM921//		IBM921//
++module	IBM921//		INTERNAL		IBM921		1
++module	INTERNAL		IBM921//		IBM921		1
++
++#	from			to			module		cost
++alias	IBM-1008//		IBM1008//
++alias	CP1008//		IBM1008//
++alias	CSIBM1008//		IBM1008//
++module	IBM1008//		INTERNAL		IBM1008		1
++module	INTERNAL		IBM1008//		IBM1008		1
++
++#	from			to			module		cost
++module	IBM1008//		IBM420//		IBM1008_420	1
++module	IBM420//		IBM1008//		IBM1008_420	1
++
++#	from			to			module		cost
++alias	IBM-1097//		IBM1097//
++alias	CP1097//		IBM1097//
++alias	CSIBM1097//		IBM1097//
++module	IBM1097//		INTERNAL		IBM1097		1
++module	INTERNAL		IBM1097//		IBM1097		1
++
++#	from			to			module		cost
++alias	IBM-1112//		IBM1112//
++alias	CP1112//		IBM1112//
++alias	CSIBM1112//		IBM1112//
++module	IBM1112//		INTERNAL		IBM1112		1
++module	INTERNAL		IBM1112//		IBM1112		1
++
++#	from			to			module		cost
++alias	IBM-1123//		IBM1123//
++alias	CP1123//		IBM1123//
++alias	CSIBM1123//		IBM1123//
++module	IBM1123//		INTERNAL		IBM1123		1
++module	INTERNAL		IBM1123//		IBM1123		1
++
++#	from			to			module		cost
++alias	IBM-1130//		IBM1130//
++alias	CP1130//		IBM1130//
++alias	CSIBM1130//		IBM1130//
++module	IBM1130//		INTERNAL		IBM1130		1
++module	INTERNAL		IBM1130//		IBM1130		1
++
++#	from			to			module		cost
++alias	IBM-1140//		IBM1140//
++alias	CP1140//		IBM1140//
++alias	CSIBM1140//		IBM1140//
++module	IBM1140//		INTERNAL		IBM1140		1
++module	INTERNAL		IBM1140//		IBM1140		1
++
++#	from			to			module		cost
++alias	IBM-1141//		IBM1141//
++alias	CP1141//		IBM1141//
++alias	CSIBM1141//		IBM1141//
++module	IBM1141//		INTERNAL		IBM1141		1
++module	INTERNAL		IBM1141//		IBM1141		1
++
++#	from			to			module		cost
++alias	IBM-1142//		IBM1142//
++alias	CP1142//		IBM1142//
++alias	CSIBM1142//		IBM1142//
++module	IBM1142//		INTERNAL		IBM1142		1
++module	INTERNAL		IBM1142//		IBM1142		1
++
++#	from			to			module		cost
++alias	IBM-1143//		IBM1143//
++alias	CP1143//		IBM1143//
++alias	CSIBM1143//		IBM1143//
++module	IBM1143//		INTERNAL		IBM1143		1
++module	INTERNAL		IBM1143//		IBM1143		1
++
++#	from			to			module		cost
++alias	IBM-1144//		IBM1144//
++alias	CP1144//		IBM1144//
++alias	CSIBM1144//		IBM1144//
++module	IBM1144//		INTERNAL		IBM1144		1
++module	INTERNAL		IBM1144//		IBM1144		1
++
++#	from			to			module		cost
++alias	IBM-1145//		IBM1145//
++alias	CP1145//		IBM1145//
++alias	CSIBM1145//		IBM1145//
++module	IBM1145//		INTERNAL		IBM1145		1
++module	INTERNAL		IBM1145//		IBM1145		1
++
++#	from			to			module		cost
++alias	IBM-1146//		IBM1146//
++alias	CP1146//		IBM1146//
++alias	CSIBM1146//		IBM1146//
++module	IBM1146//		INTERNAL		IBM1146		1
++module	INTERNAL		IBM1146//		IBM1146		1
++
++#	from			to			module		cost
++alias	IBM-1147//		IBM1147//
++alias	CP1147//		IBM1147//
++alias	CSIBM1147//		IBM1147//
++module	IBM1147//		INTERNAL		IBM1147		1
++module	INTERNAL		IBM1147//		IBM1147		1
++
++#	from			to			module		cost
++alias	IBM-1148//		IBM1148//
++alias	CP1148//		IBM1148//
++alias	CSIBM1148//		IBM1148//
++module	IBM1148//		INTERNAL		IBM1148		1
++module	INTERNAL		IBM1148//		IBM1148		1
++
++#	from			to			module		cost
++alias	IBM-1149//		IBM1149//
++alias	CP1149//		IBM1149//
++alias	CSIBM1149//		IBM1149//
++module	IBM1149//		INTERNAL		IBM1149		1
++module	INTERNAL		IBM1149//		IBM1149		1
++
++#	from			to			module		cost
++alias	IBM-1166//		IBM1166//
++alias	CP1166//		IBM1166//
++alias	CSIBM1166//		IBM1166//
++module	IBM1166//		INTERNAL		IBM1166		1
++module	INTERNAL		IBM1166//		IBM1166		1
++
++#	from			to			module		cost
++alias	IBM-1167//		IBM1167//
++alias	CP1167//		IBM1167//
++alias	CSIBM1167//		IBM1167//
++module	IBM1167//		INTERNAL		IBM1167		1
++module	INTERNAL		IBM1167//		IBM1167		1
++
++#	from			to			module		cost
++alias	IBM-4517//		IBM4517//
++alias	CP4517//		IBM4517//
++alias	CSIBM4517//		IBM4517//
++module	IBM4517//		INTERNAL		IBM4517		1
++module	INTERNAL		IBM4517//		IBM4517		1
++
++#	from			to			module		cost
++alias	IBM-4899//		IBM4899//
++alias	CP4899//		IBM4899//
++alias	CSIBM4899//		IBM4899//
++module	IBM4899//		INTERNAL		IBM4899		1
++module	INTERNAL		IBM4899//		IBM4899		1
++
++#	from			to			module		cost
++alias	IBM-4909//		IBM4909//
++alias	CP4909//		IBM4909//
++alias	CSIBM4909//		IBM4909//
++module	IBM4909//		INTERNAL		IBM4909		1
++module	INTERNAL		IBM4909//		IBM4909		1
++
++#	from			to			module		cost
++alias	IBM-4971//		IBM4971//
++alias	CP4971//		IBM4971//
++alias	CSIBM4971//		IBM4971//
++module	IBM4971//		INTERNAL		IBM4971		1
++module	INTERNAL		IBM4971//		IBM4971		1
++
++#	from			to			module		cost
++alias	IBM-5347//		IBM5347//
++alias	CP5347//		IBM5347//
++alias	CSIBM5347//		IBM5347//
++module	IBM5347//		INTERNAL		IBM5347		1
++module	INTERNAL		IBM5347//		IBM5347		1
++
++#	from			to			module		cost
++alias	IBM-9030//		IBM9030//
++alias	CP9030//		IBM9030//
++alias	CSIBM9030//		IBM9030//
++module	IBM9030//		INTERNAL		IBM9030		1
++module	INTERNAL		IBM9030//		IBM9030		1
++
++#	from			to			module		cost
++alias	IBM-9066//		IBM9066//
++alias	CP9066//		IBM9066//
++alias	CSIBM9066//		IBM9066//
++module	IBM9066//		INTERNAL		IBM9066		1
++module	INTERNAL		IBM9066//		IBM9066		1
++
++#	from			to			module		cost
++alias	IBM-9448//		IBM9448//
++alias	CP9448//		IBM9448//
++alias	CSIBM9448//		IBM9448//
++module	IBM9448//		INTERNAL		IBM9448		1
++module	INTERNAL		IBM9448//		IBM9448		1
++
++#	from			to			module		cost
++alias	IBM-12712//		IBM12712//
++alias	CP12712//		IBM12712//
++alias	CSIBM12712//		IBM12712//
++module	IBM12712//		INTERNAL		IBM12712		1
++module	INTERNAL		IBM12712//		IBM12712		1
++
++#	from			to			module		cost
++alias	IBM-16804//		IBM16804//
++alias	CP16804//		IBM16804//
++alias	CSIBM16804//		IBM16804//
++module	IBM16804//		INTERNAL		IBM16804		1
++module	INTERNAL		IBM16804//		IBM16804		1
++
++#	from			to			module		cost
++alias	IBM-1364//		IBM1364//
++alias	CP1364//		IBM1364//
++alias	CSIBM1364//		IBM1364//
++module	IBM1364//		INTERNAL		IBM1364		1
++module	INTERNAL		IBM1364//		IBM1364		1
++
++#	from			to			module		cost
++alias	IBM-1371//		IBM1371//
++alias	CP1371//		IBM1371//
++alias	CSIBM1371//		IBM1371//
++module	IBM1371//		INTERNAL		IBM1371		1
++module	INTERNAL		IBM1371//		IBM1371		1
++
++#	from			to			module		cost
++alias	IBM-1388//		IBM1388//
++alias	CP1388//		IBM1388//
++alias	CSIBM1388//		IBM1388//
++module	IBM1388//		INTERNAL		IBM1388		1
++module	INTERNAL		IBM1388//		IBM1388		1
++
++#	from			to			module		cost
++alias	IBM-1390//		IBM1390//
++alias	CP1390//		IBM1390//
++alias	CSIBM1390//		IBM1390//
++module	IBM1390//		INTERNAL		IBM1390		1
++module	INTERNAL		IBM1390//		IBM1390		1
++
++#	from			to			module		cost
++alias	IBM-1399//		IBM1399//
++alias	CP1399//		IBM1399//
++alias	CSIBM1399//		IBM1399//
++module	IBM1399//		INTERNAL		IBM1399		1
++module	INTERNAL		IBM1399//		IBM1399		1
++
++#	from			to			module		cost
++alias	ISO/TR_11548-1/		ISO_11548-1//
++alias	ISO11548-1//		ISO_11548-1//
++module	ISO_11548-1//		INTERNAL		ISO_11548-1	1
++module	INTERNAL		ISO_11548-1//		ISO_11548-1	1
++
++#	from			to			module		cost
++module	MIK//			INTERNAL		MIK		1
++module	INTERNAL		MIK//			MIK		1
++
++#	from			to			module		cost
++module	BRF//			INTERNAL		BRF		1
++module	INTERNAL		BRF//			BRF		1
++
++#	from			to			module		cost
++alias	CP1282//		MAC-CENTRALEUROPE//
++module	MAC-CENTRALEUROPE//	INTERNAL		MAC-CENTRALEUROPE 1
++module	INTERNAL		MAC-CENTRALEUROPE//	MAC-CENTRALEUROPE 1
++
++#	from			to			module		cost
++module	KOI8-RU//		INTERNAL		KOI8-RU		1
++module	INTERNAL		KOI8-RU//		KOI8-RU		1
++
++#	from			to			module		cost
++alias	ISO_8859-9E//		ISO-8859-9E//
++alias	ISO8859-9E//		ISO-8859-9E//
++alias	ISO88599E//		ISO-8859-9E//
++module	ISO-8859-9E//		INTERNAL		ISO8859-9E	1
++module	INTERNAL		ISO-8859-9E//		ISO8859-9E	1
++
++#	from			to			module		cost
++alias	ROMAN9//		HP-ROMAN9//
++alias	R9//			HP-ROMAN9//
++alias	HPROMAN9//		HP-ROMAN9//
++module	HP-ROMAN9//		INTERNAL		HP-ROMAN9	1
++module	INTERNAL		HP-ROMAN9//		HP-ROMAN9	1
++
++#	from			to			module		cost
++alias	TURKISH8//		HP-TURKISH8//
++alias	HPTURKISH8//		HP-TURKISH8//
++alias	OSF10010006//		HP-TURKISH8//
++module	HP-TURKISH8//		INTERNAL		HP-TURKISH8	1
++module	INTERNAL		HP-TURKISH8//		HP-TURKISH8	1
++
++#	from			to			module		cost
++alias	THAI8//			HP-THAI8//
++alias	HPTHAI8//		HP-THAI8//
++module	HP-THAI8//		INTERNAL		HP-THAI8	1
++module	INTERNAL		HP-THAI8//		HP-THAI8	1
++
++#	from			to			module		cost
++alias	HPGREEK8//		HP-GREEK8//
++alias	OSF10010004//		HP-GREEK8//
++module	HP-GREEK8//		INTERNAL		HP-GREEK8	1
++module	INTERNAL		HP-GREEK8//		HP-GREEK8	1
+diff --git a/iconvdata/gconv-modules.conf b/iconvdata/gconv-modules.conf
+index e12b0aa2ed41a234..e63dda673d749001 100644
+--- a/iconvdata/gconv-modules.conf
++++ b/iconvdata/gconv-modules.conf
+@@ -31,178 +31,6 @@
+ #  alias:	alias name which is not really recognized.
+ #  name:	the real name of the character set
+ 
+-alias	ISO-IR-4//		BS_4730//
+-alias	ISO646-GB//		BS_4730//
+-alias	GB//			BS_4730//
+-alias	UK//			BS_4730//
+-alias	CSISO4UNITEDKINGDOM//	BS_4730//
+-module	BS_4730//		INTERNAL		ISO646		2
+-module	INTERNAL		BS_4730//		ISO646		2
+-
+-alias	ISO-IR-121//		CSA_Z243.4-1985-1//
+-alias	ISO646-CA//		CSA_Z243.4-1985-1//
+-alias	CSA7-1//		CSA_Z243.4-1985-1//
+-alias	CA//			CSA_Z243.4-1985-1//
+-alias	CSISO121CANADIAN1//	CSA_Z243.4-1985-1//
+-alias	CSA_Z243.419851//	CSA_Z243.4-1985-1//
+-module	CSA_Z243.4-1985-1//	INTERNAL		ISO646		2
+-module	INTERNAL		CSA_Z243.4-1985-1//	ISO646		2
+-
+-alias	ISO-IR-122//		CSA_Z243.4-1985-2//
+-alias	ISO646-CA2//		CSA_Z243.4-1985-2//
+-alias	CSA7-2//		CSA_Z243.4-1985-2//
+-alias	CSISO122CANADIAN2//	CSA_Z243.4-1985-2//
+-alias	CSA_Z243.419852//	CSA_Z243.4-1985-2//
+-module	CSA_Z243.4-1985-2//	INTERNAL		ISO646		2
+-module	INTERNAL		CSA_Z243.4-1985-2//	ISO646		2
+-
+-alias	ISO-IR-21//		DIN_66003//
+-alias	DE//			DIN_66003//
+-alias	ISO646-DE//		DIN_66003//
+-alias	CSISO21GERMAN//		DIN_66003//
+-module	DIN_66003//		INTERNAL		ISO646		2
+-module	INTERNAL		DIN_66003//		ISO646		2
+-
+-alias	DS2089//		DS_2089//
+-alias	ISO646-DK//		DS_2089//
+-alias	DK//			DS_2089//
+-alias	CSISO646DANISH//	DS_2089//
+-module	DS_2089//		INTERNAL		ISO646		2
+-module	INTERNAL		DS_2089//		ISO646		2
+-
+-alias	ISO-IR-17//		ES//
+-alias	ISO646-ES//		ES//
+-alias	CSISO17SPANISH//	ES//
+-module	ES//			INTERNAL		ISO646		2
+-module	INTERNAL		ES//			ISO646		2
+-
+-alias	ISO-IR-85//		ES2//
+-alias	ISO646-ES2//		ES2//
+-alias	CSISO85SPANISH2//	ES2//
+-module	ES2//			INTERNAL		ISO646		2
+-module	INTERNAL		ES2//			ISO646		2
+-
+-alias	ISO-IR-57//		GB_1988-80//
+-alias	CN//			GB_1988-80//
+-alias	ISO646-CN//		GB_1988-80//
+-alias	CSISO58GB1988//		GB_1988-80//
+-alias	GB_198880//		GB_1988-80//
+-module	GB_1988-80//		INTERNAL		ISO646		2
+-module	INTERNAL		GB_1988-80//		ISO646		2
+-
+-alias	ISO-IR-15//		IT//
+-alias	ISO646-IT//		IT//
+-alias	CSISO15ITALIAN//	IT//
+-module	IT//			INTERNAL		ISO646		2
+-module	INTERNAL		IT//			ISO646		2
+-
+-alias	ISO-IR-14//		JIS_C6220-1969-RO//
+-alias	JP//			JIS_C6220-1969-RO//
+-alias	ISO646-JP//		JIS_C6220-1969-RO//
+-alias	CSISO14JISC6220RO//	JIS_C6220-1969-RO//
+-alias	JIS_C62201969RO//	JIS_C6220-1969-RO//
+-module	JIS_C6220-1969-RO//	INTERNAL		ISO646		2
+-module	INTERNAL		JIS_C6220-1969-RO//	ISO646		2
+-
+-alias	ISO-IR-92//		JIS_C6229-1984-B//
+-alias	ISO646-JP-OCR-B//	JIS_C6229-1984-B//
+-alias	JP-OCR-B//		JIS_C6229-1984-B//
+-alias	CSISO92JISC62991984B//	JIS_C6229-1984-B//
+-alias	JIS_C62291984B//	JIS_C6229-1984-B//
+-module	JIS_C6229-1984-B//	INTERNAL		ISO646		2
+-module	INTERNAL		JIS_C6229-1984-B//	ISO646		2
+-
+-alias	ISO-IR-141//		JUS_I.B1.002//
+-alias	ISO646-YU//		JUS_I.B1.002//
+-alias	JS//			JUS_I.B1.002//
+-alias	YU//			JUS_I.B1.002//
+-alias	CSISO141JUSIB1002//	JUS_I.B1.002//
+-module	JUS_I.B1.002//		INTERNAL		ISO646		2
+-module	INTERNAL		JUS_I.B1.002//		ISO646		2
+-
+-alias	ISO646-KR//		KSC5636//
+-alias	CSKSC5636//		KSC5636//
+-module	KSC5636//		INTERNAL		ISO646		2
+-module	INTERNAL		KSC5636//		ISO646		2
+-
+-alias	ISO-IR-86//		MSZ_7795.3//
+-alias	ISO646-HU//		MSZ_7795.3//
+-alias	HU//			MSZ_7795.3//
+-alias	CSISO86HUNGARIAN//	MSZ_7795.3//
+-module	MSZ_7795.3//		INTERNAL		ISO646		2
+-module	INTERNAL		MSZ_7795.3//		ISO646		2
+-
+-alias	CUBA//			NC_NC00-10//
+-alias	NC_NC00-10:81//		NC_NC00-10//
+-alias	ISO-IR-151//		NC_NC00-10//
+-alias	ISO646-CU//		NC_NC00-10//
+-alias	CSISO151CUBA//		NC_NC00-10//
+-alias	NC_NC0010//		NC_NC00-10//
+-module	NC_NC00-10//		INTERNAL		ISO646		2
+-module	INTERNAL		NC_NC00-10//		ISO646		2
+-
+-alias	ISO-IR-69//		NF_Z_62-010//
+-alias	ISO646-FR//		NF_Z_62-010//
+-alias	FR//			NF_Z_62-010//
+-alias	CSISO69FRENCH//		NF_Z_62-010//
+-alias	NF_Z_62010//		NF_Z_62-010//
+-module	NF_Z_62-010//		INTERNAL		ISO646		2
+-module	INTERNAL		NF_Z_62-010//		ISO646		2
+-
+-alias	ISO-IR-25//		NF_Z_62-010_1973//
+-alias	ISO646-FR1//		NF_Z_62-010_1973//
+-alias	NF_Z_62-010_(1973)//	NF_Z_62-010_1973//
+-alias	CSISO25FRENCH//		NF_Z_62-010_1973//
+-alias	NF_Z_62010_1973//	NF_Z_62-010_1973//
+-module	NF_Z_62-010_1973//	INTERNAL		ISO646		2
+-module	INTERNAL		NF_Z_62-010_1973//	ISO646		2
+-
+-alias	ISO-IR-60//		NS_4551-1//
+-alias	ISO646-NO//		NS_4551-1//
+-alias	NO//			NS_4551-1//
+-alias	CSISO60DANISHNORWEGIAN// NS_4551-1//
+-alias	CSISO60NORWEGIAN1//	NS_4551-1//
+-alias	NS_45511//		NS_4551-1//
+-module	NS_4551-1//		INTERNAL		ISO646		2
+-module	INTERNAL		NS_4551-1//		ISO646		2
+-
+-alias	ISO646-NO2//		NS_4551-2//
+-alias	ISO-IR-61//		NS_4551-2//
+-alias	NO2//			NS_4551-2//
+-alias	CSISO61NORWEGIAN2//	NS_4551-2//
+-alias	NS_45512//		NS_4551-2//
+-module	NS_4551-2//		INTERNAL		ISO646		2
+-module	INTERNAL		NS_4551-2//		ISO646		2
+-
+-alias	ISO-IR-16//		PT//
+-alias	ISO646-PT//		PT//
+-alias	CSISO16PORTUGESE//	PT//
+-module	PT//			INTERNAL		ISO646		2
+-module	INTERNAL		PT//			ISO646		2
+-
+-alias	ISO-IR-84//		PT2//
+-alias	ISO646-PT2//		PT2//
+-alias	CSISO84PORTUGUESE2//	PT2//
+-module	PT2//			INTERNAL		ISO646		2
+-module	INTERNAL		PT2//			ISO646		2
+-
+-alias	ISO-IR-10//		SEN_850200_B//
+-alias	FI//			SEN_850200_B//
+-alias	ISO646-FI//		SEN_850200_B//
+-alias	ISO646-SE//		SEN_850200_B//
+-alias	SE//			SEN_850200_B//
+-alias	CSISO10SWEDISH//	SEN_850200_B//
+-alias	SS636127//		SEN_850200_B//
+-module	SEN_850200_B//		INTERNAL		ISO646		2
+-module	INTERNAL		SEN_850200_B//		ISO646		2
+-
+-alias	ISO-IR-11//		SEN_850200_C//
+-alias	ISO646-SE2//		SEN_850200_C//
+-alias	SE2//			SEN_850200_C//
+-alias	CSISO11SWEDISHFORNAMES// SEN_850200_C//
+-module	SEN_850200_C//		INTERNAL		ISO646		2
+-module	INTERNAL		SEN_850200_C//		ISO646		2
+-
+ #	from			to			module		cost
+ alias	ISO-IR-100//		ISO-8859-1//
+ alias	ISO_8859-1:1987//	ISO-8859-1//
+@@ -219,175 +47,6 @@ alias	OSF00010001//		ISO-8859-1//
+ module	ISO-8859-1//		INTERNAL		ISO8859-1	1
+ module	INTERNAL		ISO-8859-1//		ISO8859-1	1
+ 
+-#	from			to			module		cost
+-alias	ISO-IR-101//		ISO-8859-2//
+-alias	ISO_8859-2:1987//	ISO-8859-2//
+-alias	ISO_8859-2//		ISO-8859-2//
+-alias	ISO8859-2//		ISO-8859-2//
+-alias	ISO88592//		ISO-8859-2//
+-alias	LATIN2//		ISO-8859-2//
+-alias	L2//			ISO-8859-2//
+-alias	CSISOLATIN2//		ISO-8859-2//
+-alias	8859_2//		ISO-8859-2//
+-alias	OSF00010002//		ISO-8859-2//
+-alias	IBM912//		ISO-8859-2//
+-alias	CP912//			ISO-8859-2//
+-module	ISO-8859-2//		INTERNAL		ISO8859-2	1
+-module	INTERNAL		ISO-8859-2//		ISO8859-2	1
+-
+-#	from			to			 module		cost
+-alias	ISO-IR-109//		ISO-8859-3//
+-alias	ISO_8859-3:1988//	ISO-8859-3//
+-alias	ISO_8859-3//		ISO-8859-3//
+-alias	ISO8859-3//		ISO-8859-3//
+-alias	ISO88593//		ISO-8859-3//
+-alias	LATIN3//		ISO-8859-3//
+-alias	L3//			ISO-8859-3//
+-alias	CSISOLATIN3//		ISO-8859-3//
+-alias	8859_3//		ISO-8859-3//
+-alias	OSF00010003//		ISO-8859-3//
+-module	ISO-8859-3//		INTERNAL		ISO8859-3	1
+-module	INTERNAL		ISO-8859-3//		ISO8859-3	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-110//		ISO-8859-4//
+-alias	ISO_8859-4:1988//	ISO-8859-4//
+-alias	ISO_8859-4//		ISO-8859-4//
+-alias	ISO8859-4//		ISO-8859-4//
+-alias	ISO88594//		ISO-8859-4//
+-alias	LATIN4//		ISO-8859-4//
+-alias	L4//			ISO-8859-4//
+-alias	CSISOLATIN4//		ISO-8859-4//
+-alias	8859_4//		ISO-8859-4//
+-alias	OSF00010004//		ISO-8859-4//
+-module	ISO-8859-4//		INTERNAL		ISO8859-4	1
+-module	INTERNAL		ISO-8859-4//		ISO8859-4	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-144//		ISO-8859-5//
+-alias	ISO_8859-5:1988//	ISO-8859-5//
+-alias	ISO_8859-5//		ISO-8859-5//
+-alias	ISO8859-5//		ISO-8859-5//
+-alias	ISO88595//		ISO-8859-5//
+-alias	CYRILLIC//		ISO-8859-5//
+-alias	CSISOLATINCYRILLIC//	ISO-8859-5//
+-alias	8859_5//		ISO-8859-5//
+-alias	OSF00010005//		ISO-8859-5//
+-alias	IBM915//		ISO-8859-5//
+-alias	CP915//			ISO-8859-5//
+-module	ISO-8859-5//		INTERNAL		ISO8859-5	1
+-module	INTERNAL		ISO-8859-5//		ISO8859-5	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-127//		ISO-8859-6//
+-alias	ISO_8859-6:1987//	ISO-8859-6//
+-alias	ISO_8859-6//		ISO-8859-6//
+-alias	ISO8859-6//		ISO-8859-6//
+-alias	ISO88596//		ISO-8859-6//
+-alias	ECMA-114//		ISO-8859-6//
+-alias	ASMO-708//		ISO-8859-6//
+-alias	ARABIC//		ISO-8859-6//
+-alias	CSISOLATINARABIC//	ISO-8859-6//
+-alias	8859_6//		ISO-8859-6//
+-alias	OSF00010006//		ISO-8859-6//
+-alias	IBM1089//		ISO-8859-6//
+-alias	CP1089//		ISO-8859-6//
+-module	ISO-8859-6//		INTERNAL		ISO8859-6	1
+-module	INTERNAL		ISO-8859-6//		ISO8859-6	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-126//		ISO-8859-7//
+-alias	ISO_8859-7:2003//	ISO-8859-7//
+-alias	ISO_8859-7:1987//	ISO-8859-7//
+-alias	ISO_8859-7//		ISO-8859-7//
+-alias	ISO8859-7//		ISO-8859-7//
+-alias	ISO88597//		ISO-8859-7//
+-alias	ELOT_928//		ISO-8859-7//
+-alias	ECMA-118//		ISO-8859-7//
+-alias	GREEK//			ISO-8859-7//
+-alias	GREEK8//		ISO-8859-7//
+-alias	CSISOLATINGREEK//	ISO-8859-7//
+-alias	8859_7//		ISO-8859-7//
+-alias	OSF00010007//		ISO-8859-7//
+-alias	IBM813//		ISO-8859-7//
+-alias	CP813//			ISO-8859-7//
+-module	ISO-8859-7//		INTERNAL		ISO8859-7	1
+-module	INTERNAL		ISO-8859-7//		ISO8859-7	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-138//		ISO-8859-8//
+-alias	ISO_8859-8:1988//	ISO-8859-8//
+-alias	ISO_8859-8//		ISO-8859-8//
+-alias	ISO8859-8//		ISO-8859-8//
+-alias	ISO88598//		ISO-8859-8//
+-alias	HEBREW//		ISO-8859-8//
+-alias	CSISOLATINHEBREW//	ISO-8859-8//
+-alias	8859_8//		ISO-8859-8//
+-alias	OSF00010008//		ISO-8859-8//
+-alias	IBM916//		ISO-8859-8//
+-alias	CP916//			ISO-8859-8//
+-module	ISO-8859-8//		INTERNAL		ISO8859-8	1
+-module	INTERNAL		ISO-8859-8//		ISO8859-8	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-148//		ISO-8859-9//
+-alias	ISO_8859-9:1989//	ISO-8859-9//
+-alias	ISO_8859-9//		ISO-8859-9//
+-alias	ISO8859-9//		ISO-8859-9//
+-alias	ISO88599//		ISO-8859-9//
+-alias	LATIN5//		ISO-8859-9//
+-alias	L5//			ISO-8859-9//
+-alias	CSISOLATIN5//		ISO-8859-9//
+-alias	8859_9//		ISO-8859-9//
+-alias	OSF00010009//		ISO-8859-9//
+-alias	IBM920//		ISO-8859-9//
+-alias	CP920//			ISO-8859-9//
+-alias	TS-5881//		ISO-8859-9//
+-alias	ECMA-128//		ISO-8859-9//
+-module	ISO-8859-9//		INTERNAL		ISO8859-9	1
+-module	INTERNAL		ISO-8859-9//		ISO8859-9	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-157//		ISO-8859-10//
+-alias	ISO_8859-10:1992//	ISO-8859-10//
+-alias	ISO_8859-10//		ISO-8859-10//
+-alias	ISO8859-10//		ISO-8859-10//
+-alias	ISO885910//		ISO-8859-10//
+-alias	LATIN6//		ISO-8859-10//
+-alias	L6//			ISO-8859-10//
+-alias	CSISOLATIN6//		ISO-8859-10//
+-alias	OSF0001000A//		ISO-8859-10//
+-module	ISO-8859-10//		INTERNAL		ISO8859-10	1
+-module	INTERNAL		ISO-8859-10//		ISO8859-10	1
+-
+-#	from			to			module		cost
+-alias	ISO8859-11//		ISO-8859-11//
+-alias	ISO885911//		ISO-8859-11//
+-module	ISO-8859-11//		INTERNAL		ISO8859-11	1
+-module	INTERNAL		ISO-8859-11//		ISO8859-11	1
+-
+-#	from			to			module		cost
+-alias	ISO8859-13//		ISO-8859-13//
+-alias	ISO885913//		ISO-8859-13//
+-alias	ISO-IR-179//		ISO-8859-13//
+-alias	LATIN7//		ISO-8859-13//
+-alias	L7//			ISO-8859-13//
+-alias	BALTIC//		ISO-8859-13//
+-module	ISO-8859-13//		INTERNAL		ISO8859-13	1
+-module	INTERNAL		ISO-8859-13//		ISO8859-13	1
+-
+-#	from			to			module		cost
+-alias	ISO8859-14//		ISO-8859-14//
+-alias	ISO885914//		ISO-8859-14//
+-alias	ISO-IR-199//		ISO-8859-14//
+-alias	LATIN8//		ISO-8859-14//
+-alias	L8//			ISO-8859-14//
+-alias	ISO_8859-14:1998//	ISO-8859-14//
+-alias	ISO_8859-14//		ISO-8859-14//
+-alias	ISO-CELTIC//		ISO-8859-14//
+-module	ISO-8859-14//		INTERNAL		ISO8859-14	1
+-module	INTERNAL		ISO-8859-14//		ISO8859-14	1
+-
+ #	from			to			module		cost
+ alias	ISO8859-15//		ISO-8859-15//
+ alias	ISO885915//		ISO-8859-15//
+@@ -399,916 +58,12 @@ alias	ISO_8859-15:1998//	ISO-8859-15//
+ module	ISO-8859-15//		INTERNAL		ISO8859-15	1
+ module	INTERNAL		ISO-8859-15//		ISO8859-15	1
+ 
+-#	from			to			module		cost
+-alias	ISO8859-16//		ISO-8859-16//
+-alias	ISO885916//		ISO-8859-16//
+-alias	ISO-IR-226//		ISO-8859-16//
+-alias	LATIN10//		ISO-8859-16//
+-alias	L10//			ISO-8859-16//
+-alias	ISO_8859-16:2001//	ISO-8859-16//
+-alias	ISO_8859-16//		ISO-8859-16//
+-module	ISO-8859-16//		INTERNAL		ISO8859-16	1
+-module	INTERNAL		ISO-8859-16//		ISO8859-16	1
+-
+-#	from			to			module		cost
+-alias	T.61//			T.61-8BIT//
+-alias	ISO-IR-103//		T.61-8BIT//
+-alias	CSISO103T618BIT//	T.61-8BIT//
+-alias	T.618BIT//		T.61-8BIT//
+-module	T.61-8BIT//		INTERNAL		T.61		1
+-module	INTERNAL		T.61-8BIT//		T.61		1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-156//		ISO_6937//
+-alias	ISO_6937:1992//		ISO_6937//
+-alias	ISO6937//		ISO_6937//
+-module	ISO_6937//		INTERNAL		ISO_6937	1
+-module	INTERNAL		ISO_6937//		ISO_6937	1
+-
+-
+-#	from			to			module		cost
+-alias	ISO-IR-90//		ISO_6937-2//
+-alias	ISO_6937-2:1983//	ISO_6937-2//
+-alias	CSISO90//		ISO_6937-2//
+-alias	ISO_69372//		ISO_6937-2//
+-module	ISO_6937-2//		INTERNAL		ISO_6937-2	1
+-module	INTERNAL		ISO_6937-2//		ISO_6937-2	1
+-
+-#	from			to			module		cost
+-alias	SHIFT-JIS//		SJIS//
+-alias	SHIFT_JIS//		SJIS//
+-alias	MS_KANJI//		SJIS//
+-alias	CSSHIFTJIS//		SJIS//
+-module	SJIS//			INTERNAL		SJIS		1
+-module	INTERNAL		SJIS//			SJIS		1
+-
+-#	from			to			module		cost
+-alias	WINDOWS-31J//		CP932//
+-alias	MS932//			CP932//
+-alias	SJIS-OPEN//		CP932//
+-alias	SJIS-WIN//		CP932//
+-alias	CSWINDOWS31J//		CP932//
+-module	CP932//			INTERNAL		CP932		1
+-module	INTERNAL		CP932//			CP932		1
+-
+-#	from			to			module		cost
+-alias	KOI8//			KOI-8//
+-module	KOI-8//			INTERNAL		KOI-8		1
+-module	INTERNAL		KOI-8//			KOI-8		1
+-
+-#	from			to			module		cost
+-alias	CSKOI8R//		KOI8-R//
+-alias	KOI8R//			KOI8-R//
+-module	KOI8-R//		INTERNAL		KOI8-R		1
+-module	INTERNAL		KOI8-R//		KOI8-R		1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-19//		LATIN-GREEK//
+-alias	CSISO19LATINGREEK//	LATIN-GREEK//
+-alias	LATINGREEK//		LATIN-GREEK//
+-module	LATIN-GREEK//		INTERNAL		LATIN-GREEK	1
+-module	INTERNAL		LATIN-GREEK//		LATIN-GREEK	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-27//		LATIN-GREEK-1//
+-alias	CSISO27LATINGREEK1//	LATIN-GREEK-1//
+-alias	LATINGREEK1//		LATIN-GREEK-1//
+-module	LATIN-GREEK-1//		INTERNAL		LATIN-GREEK-1	1
+-module	INTERNAL		LATIN-GREEK-1//		LATIN-GREEK-1	1
+-
+-#	from			to			module		cost
+-alias	ROMAN8//		HP-ROMAN8//
+-alias	R8//			HP-ROMAN8//
+-alias	CSHPROMAN8//		HP-ROMAN8//
+-alias	OSF10010001//		HP-ROMAN8//
+-alias	HPROMAN8//		HP-ROMAN8//
+-module	HP-ROMAN8//		INTERNAL		HP-ROMAN8	1
+-module	INTERNAL		HP-ROMAN8//		HP-ROMAN8	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICATDE//		EBCDIC-AT-DE//
+-alias	EBCDICATDE//		EBCDIC-AT-DE//
+-module	EBCDIC-AT-DE//		INTERNAL		EBCDIC-AT-DE	1
+-module	INTERNAL		EBCDIC-AT-DE//		EBCDIC-AT-DE	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICATDEA//		EBCDIC-AT-DE-A//
+-alias	EBCDICATDEA//		EBCDIC-AT-DE-A//
+-module	EBCDIC-AT-DE-A//	INTERNAL		EBCDIC-AT-DE-A	1
+-module	INTERNAL		EBCDIC-AT-DE-A//	EBCDIC-AT-DE-A	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICCAFR//		EBCDIC-CA-FR//
+-alias	EBCDICCAFR//		EBCDIC-CA-FR//
+-module	EBCDIC-CA-FR//		INTERNAL		EBCDIC-CA-FR	1
+-module	INTERNAL		EBCDIC-CA-FR//		EBCDIC-CA-FR	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICDKNO//		EBCDIC-DK-NO//
+-alias	EBCDICDKNO//		EBCDIC-DK-NO//
+-module	EBCDIC-DK-NO//		INTERNAL		EBCDIC-DK-NO	1
+-module	INTERNAL		EBCDIC-DK-NO//		EBCDIC-DK-NO	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICDKNOA//		EBCDIC-DK-NO-A//
+-alias	EBCDICDKNOA//		EBCDIC-DK-NO-A//
+-module	EBCDIC-DK-NO-A//	INTERNAL		EBCDIC-DK-NO-A	1
+-module	INTERNAL		EBCDIC-DK-NO-A//	EBCDIC-DK-NO-A	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICES//		EBCDIC-ES//
+-alias	EBCDICES//		EBCDIC-ES//
+-module	EBCDIC-ES//		INTERNAL		EBCDIC-ES	1
+-module	INTERNAL		EBCDIC-ES//		EBCDIC-ES	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICESA//		EBCDIC-ES-A//
+-alias	EBCDICESA//		EBCDIC-ES-A//
+-module	EBCDIC-ES-A//		INTERNAL		EBCDIC-ES-A	1
+-module	INTERNAL		EBCDIC-ES-A//		EBCDIC-ES-A	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICESS//		EBCDIC-ES-S//
+-alias	EBCDICESS//		EBCDIC-ES-S//
+-module	EBCDIC-ES-S//		INTERNAL		EBCDIC-ES-S	1
+-module	INTERNAL		EBCDIC-ES-S//		EBCDIC-ES-S	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICFISE//		EBCDIC-FI-SE//
+-alias	EBCDICFISE//		EBCDIC-FI-SE//
+-module	EBCDIC-FI-SE//		INTERNAL		EBCDIC-FI-SE	1
+-module	INTERNAL		EBCDIC-FI-SE//		EBCDIC-FI-SE	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICFISEA//		EBCDIC-FI-SE-A//
+-alias	EBCDICFISEA//		EBCDIC-FI-SE-A//
+-module	EBCDIC-FI-SE-A//	INTERNAL		EBCDIC-FI-SE-A	1
+-module	INTERNAL		EBCDIC-FI-SE-A//	EBCDIC-FI-SE-A	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICFR//		EBCDIC-FR//
+-alias	EBCDICFR//		EBCDIC-FR//
+-module	EBCDIC-FR//		INTERNAL		EBCDIC-FR	1
+-module	INTERNAL		EBCDIC-FR//		EBCDIC-FR	1
+-
+-#	from			to			module		cost
+-alias	EBCDICISFRISS//		EBCDIC-IS-FRISS//
+-module	EBCDIC-IS-FRISS//	INTERNAL		EBCDIC-IS-FRISS	1
+-module	INTERNAL		EBCDIC-IS-FRISS//	EBCDIC-IS-FRISS	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICIT//		EBCDIC-IT//
+-alias	EBCDICIT//		EBCDIC-IT//
+-module	EBCDIC-IT//		INTERNAL		EBCDIC-IT	1
+-module	INTERNAL		EBCDIC-IT//		EBCDIC-IT	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICPT//		EBCDIC-PT//
+-alias	EBCDICPT//		EBCDIC-PT//
+-module	EBCDIC-PT//		INTERNAL		EBCDIC-PT	1
+-module	INTERNAL		EBCDIC-PT//		EBCDIC-PT	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICUK//		EBCDIC-UK//
+-alias	EBCDICUK//		EBCDIC-UK//
+-module	EBCDIC-UK//		INTERNAL		EBCDIC-UK	1
+-module	INTERNAL		EBCDIC-UK//		EBCDIC-UK	1
+-
+-#	from			to			module		cost
+-alias	CSEBCDICUS//		EBCDIC-US//
+-alias	EBCDICUS//		EBCDIC-US//
+-module	EBCDIC-US//		INTERNAL		EBCDIC-US	1
+-module	INTERNAL		EBCDIC-US//		EBCDIC-US	1
+-
+-#	from			to			module		cost
+-alias	CP037//			IBM037//
+-alias	EBCDIC-CP-US//		IBM037//
+-alias	EBCDIC-CP-CA//		IBM037//
+-alias	EBCDIC-CP-WT//		IBM037//
+-alias	EBCDIC-CP-NL//		IBM037//
+-alias	CSIBM037//		IBM037//
+-alias	OSF10020025//		IBM037//
+-alias	CP1070//		IBM037//
+-alias	CP282//			IBM037//
+-module	IBM037//		INTERNAL		IBM037		1
+-module	INTERNAL		IBM037//		IBM037		1
+-
+-#	from			to			module		cost
+-alias	EBCDIC-INT//		IBM038//
+-alias	CP038//			IBM038//
+-alias	CSIBM038//		IBM038//
+-module	IBM038//		INTERNAL		IBM038		1
+-module	INTERNAL		IBM038//		IBM038		1
+-
+-#	from			to			module		cost
+-alias	EBCDIC-INT1//		IBM256//
+-module	IBM256//		INTERNAL		IBM256		1
+-module	INTERNAL		IBM256//		IBM256		1
+-
+-#	from			to			module		cost
+-alias	CP273//			IBM273//
+-alias	CSIBM273//		IBM273//
+-alias	OSF10020111//		IBM273//
+-module	IBM273//		INTERNAL		IBM273		1
+-module	INTERNAL		IBM273//		IBM273		1
+-
+-#	from			to			module		cost
+-alias	EBCDIC-BE//		IBM274//
+-alias	CP274//			IBM274//
+-alias	CSIBM274//		IBM274//
+-module	IBM274//		INTERNAL		IBM274		1
+-module	INTERNAL		IBM274//		IBM274		1
+-
+-#	from			to			module		cost
+-alias	EBCDIC-BR//		IBM275//
+-alias	CP275//			IBM275//
+-alias	CSIBM275//		IBM275//
+-module	IBM275//		INTERNAL		IBM275		1
+-module	INTERNAL		IBM275//		IBM275		1
+-
+-#	from			to			module		cost
+-alias	EBCDIC-CP-DK//		IBM277//
+-alias	EBCDIC-CP-NO//		IBM277//
+-alias	CSIBM277//		IBM277//
+-alias	OSF10020115//		IBM277//
+-module	IBM277//		INTERNAL		IBM277		1
+-module	INTERNAL		IBM277//		IBM277		1
+-
+-#	from			to			module		cost
+-alias	CP278//			IBM278//
+-alias	EBCDIC-CP-FI//		IBM278//
+-alias	EBCDIC-CP-SE//		IBM278//
+-alias	CSIBM278//		IBM278//
+-alias	OSF10020116//		IBM278//
+-module	IBM278//		INTERNAL		IBM278		1
+-module	INTERNAL		IBM278//		IBM278		1
+-
+-#	from			to			module		cost
+-alias	CP280//			IBM280//
+-alias	EBCDIC-CP-IT//		IBM280//
+-alias	CSIBM280//		IBM280//
+-alias	OSF10020118//		IBM280//
+-module	IBM280//		INTERNAL		IBM280		1
+-module	INTERNAL		IBM280//		IBM280		1
+-
+-#	from			to			module		cost
+-alias	EBCDIC-JP-E//		IBM281//
+-alias	CP281//			IBM281//
+-alias	CSIBM281//		IBM281//
+-module	IBM281//		INTERNAL		IBM281		1
+-module	INTERNAL		IBM281//		IBM281		1
+-
+-#	from			to			module		cost
+-alias	CP284//			IBM284//
+-alias	EBCDIC-CP-ES//		IBM284//
+-alias	CSIBM284//		IBM284//
+-alias	OSF1002011C//		IBM284//
+-alias	CP1079//		IBM284//
+-module	IBM284//		INTERNAL		IBM284		1
+-module	INTERNAL		IBM284//		IBM284		1
+-
+-#	from			to			module		cost
+-alias	CP285//			IBM285//
+-alias	EBCDIC-CP-GB//		IBM285//
+-alias	CSIBM285//		IBM285//
+-alias	OSF1002011D//		IBM285//
+-module	IBM285//		INTERNAL		IBM285		1
+-module	INTERNAL		IBM285//		IBM285		1
+-
+-#	from			to			module		cost
+-alias	CP290//			IBM290//
+-alias	EBCDIC-JP-KANA//	IBM290//
+-alias	CSIBM290//		IBM290//
+-alias	OSF10020122//		IBM290//
+-module	IBM290//		INTERNAL		IBM290		1
+-module	INTERNAL		IBM290//		IBM290		1
+-
+-#	from			to			module		cost
+-alias	CP297//			IBM297//
+-alias	EBCDIC-CP-FR//		IBM297//
+-alias	CSIBM297//		IBM297//
+-alias	OSF10020129//		IBM297//
+-alias	CP1081//		IBM297//
+-module	IBM297//		INTERNAL		IBM297		1
+-module	INTERNAL		IBM297//		IBM297		1
+-
+-#	from			to			module		cost
+-alias	CP420//			IBM420//
+-alias	EBCDIC-CP-AR1//		IBM420//
+-alias	CSIBM420//		IBM420//
+-alias	OSF100201A4//		IBM420//
+-module	IBM420//		INTERNAL		IBM420		1
+-module	INTERNAL		IBM420//		IBM420		1
+-
+-#	from			to			module		cost
+-alias	CP423//			IBM423//
+-alias	EBCDIC-CP-GR//		IBM423//
+-alias	CSIBM423//		IBM423//
+-module	IBM423//		INTERNAL		IBM423		1
+-module	INTERNAL		IBM423//		IBM423		1
+-
+-#	from			to			module		cost
+-alias	CP424//			IBM424//
+-alias	EBCDIC-CP-HE//		IBM424//
+-alias	CSIBM424//		IBM424//
+-alias	OSF100201A8//		IBM424//
+-module	IBM424//		INTERNAL		IBM424		1
+-module	INTERNAL		IBM424//		IBM424		1
+-
+-#	from			to			module		cost
+-alias	CP437//			IBM437//
+-alias	437//			IBM437//
+-alias	CSPC8CODEPAGE437//	IBM437//
+-alias	OSF100201B5//		IBM437//
+-module	IBM437//		INTERNAL		IBM437		1
+-module	INTERNAL		IBM437//		IBM437		1
+-
+-#	from			to			module		cost
+-alias	CP500//			IBM500//
+-alias	500//			IBM500//
+-alias	500V1//			IBM500//
+-alias	EBCDIC-CP-BE//		IBM500//
+-alias	EBCDIC-CP-CH//		IBM500//
+-alias	CSIBM500//		IBM500//
+-alias	OSF100201F4//		IBM500//
+-alias	CP1084//		IBM500//
+-module	IBM500//		INTERNAL		IBM500		1
+-module	INTERNAL		IBM500//		IBM500		1
+-
+-#	from			to			module		cost
+-alias	CP850//			IBM850//
+-alias	850//			IBM850//
+-alias	CSPC850MULTILINGUAL//	IBM850//
+-alias	OSF10020352//		IBM850//
+-module	IBM850//		INTERNAL		IBM850		1
+-module	INTERNAL		IBM850//		IBM850		1
+-
+-#	from			to			module		cost
+-alias	CP858//			IBM858//
+-alias	858//			IBM858//
+-alias	CSPC858MULTILINGUAL//	IBM858//
+-module	IBM858//		INTERNAL		IBM858		1
+-module	INTERNAL		IBM858//		IBM858		1
+-
+-#	from			to			module		cost
+-alias	CP851//			IBM851//
+-alias	851//			IBM851//
+-alias	CSIBM851//		IBM851//
+-module	IBM851//		INTERNAL		IBM851		1
+-module	INTERNAL		IBM851//		IBM851		1
+-
+-#	from			to			module		cost
+-alias	CP852//			IBM852//
+-alias	852//			IBM852//
+-alias	CSPCP852//		IBM852//
+-alias	OSF10020354//		IBM852//
+-module	IBM852//		INTERNAL		IBM852		1
+-module	INTERNAL		IBM852//		IBM852		1
+-
+-#	from			to			module		cost
+-alias	CP855//			IBM855//
+-alias	855//			IBM855//
+-alias	CSIBM855//		IBM855//
+-alias	OSF10020357//		IBM855//
+-module	IBM855//		INTERNAL		IBM855		1
+-module	INTERNAL		IBM855//		IBM855		1
+-
+-#	from			to			module		cost
+-alias	IBM-856//		IBM856//
+-alias	CP856//			IBM856//
+-alias	856//			IBM856//
+-alias	CSIBM856//		IBM856//
+-module	IBM856//		INTERNAL		IBM856		1
+-module	INTERNAL		IBM856//		IBM856		1
+-
+-#	from			to			module		cost
+-alias	CP857//			IBM857//
+-alias	857//			IBM857//
+-alias	CSIBM857//		IBM857//
+-alias	OSF10020359//		IBM857//
+-module	IBM857//		INTERNAL		IBM857		1
+-module	INTERNAL		IBM857//		IBM857		1
+-
+-#	from			to			module		cost
+-alias	CP860//			IBM860//
+-alias	860//			IBM860//
+-alias	CSIBM860//		IBM860//
+-module	IBM860//		INTERNAL		IBM860		1
+-module	INTERNAL		IBM860//		IBM860		1
+-
+-#	from			to			module		cost
+-alias	CP861//			IBM861//
+-alias	861//			IBM861//
+-alias	CPIBM861//		IBM861//
+-alias	OSF1002035D//		IBM861//
+-module	IBM861//		INTERNAL		IBM861		1
+-module	INTERNAL		IBM861//		IBM861		1
+-
+-#	from			to			module		cost
+-alias	CP862//			IBM862//
+-alias	862//			IBM862//
+-alias	CSPC862LATINHEBREW//	IBM862//
+-alias	OSF1002035E//		IBM862//
+-module	IBM862//		INTERNAL		IBM862		1
+-module	INTERNAL		IBM862//		IBM862		1
+-
+-#	from			to			module		cost
+-alias	CP863//			IBM863//
+-alias	863//			IBM863//
+-alias	CSIBM863//		IBM863//
+-alias	OSF1002035F//		IBM863//
+-module	IBM863//		INTERNAL		IBM863		1
+-module	INTERNAL		IBM863//		IBM863		1
+-
+-#	from			to			module		cost
+-alias	CP864//			IBM864//
+-alias	864//			IBM864//
+-alias	CSIBM864//		IBM864//
+-alias	OSF10020360//		IBM864//
+-module	IBM864//		INTERNAL		IBM864		1
+-module	INTERNAL		IBM864//		IBM864		1
+-
+-#	from			to			module		cost
+-alias	CP865//			IBM865//
+-alias	865//			IBM865//
+-alias	CSIBM865//		IBM865//
+-module	IBM865//		INTERNAL		IBM865		1
+-module	INTERNAL		IBM865//		IBM865		1
+-
+-#	from			to			module		cost
+-alias	CP866//			IBM866//
+-alias	866//			IBM866//
+-alias	CSIBM866//		IBM866//
+-module	IBM866//		INTERNAL		IBM866		1
+-module	INTERNAL		IBM866//		IBM866		1
+-
+-#	from			to			module		cost
+-alias	CP866NAV//		IBM866NAV//
+-alias	866NAV//		IBM866NAV//
+-module	IBM866NAV//		INTERNAL		IBM866NAV	1
+-module	INTERNAL		IBM866NAV//		IBM866NAV	1
+-
+-#	from			to			module		cost
+-alias	CP868//			IBM868//
+-alias	CP-AR//			IBM868//
+-alias	CSIBM868//		IBM868//
+-alias	OSF10020364//		IBM868//
+-module	IBM868//		INTERNAL		IBM868		1
+-module	INTERNAL		IBM868//		IBM868		1
+-
+-#	from			to			module		cost
+-alias	CP869//			IBM869//
+-alias	869//			IBM869//
+-alias	CP-GR//			IBM869//
+-alias	CSIBM869//		IBM869//
+-alias	OSF10020365//		IBM869//
+-module	IBM869//		INTERNAL		IBM869		1
+-module	INTERNAL		IBM869//		IBM869		1
+-
+-#	from			to			module		cost
+-alias	CP870//			IBM870//
+-alias	EBCDIC-CP-ROECE//	IBM870//
+-alias	EBCDIC-CP-YU//		IBM870//
+-alias	CSIBM870//		IBM870//
+-alias	OSF10020366//		IBM870//
+-module	IBM870//		INTERNAL		IBM870		1
+-module	INTERNAL		IBM870//		IBM870		1
+-
+-#	from			to			module		cost
+-alias	CP871//			IBM871//
+-alias	EBCDIC-CP-IS//		IBM871//
+-alias	CSIBM871//		IBM871//
+-alias	OSF10020367//		IBM871//
+-module	IBM871//		INTERNAL		IBM871		1
+-module	INTERNAL		IBM871//		IBM871		1
+-
+-#	from			to			module		cost
+-alias	CP875//			IBM875//
+-alias	EBCDIC-GREEK//		IBM875//
+-alias	OSF1002036B//		IBM875//
+-module	IBM875//		INTERNAL		IBM875		1
+-module	INTERNAL		IBM875//		IBM875		1
+-
+-#	from			to			module		cost
+-alias	CP880//			IBM880//
+-alias	EBCDIC-CYRILLIC//	IBM880//
+-alias	CSIBM880//		IBM880//
+-alias	OSF10020370//		IBM880//
+-module	IBM880//		INTERNAL		IBM880		1
+-module	INTERNAL		IBM880//		IBM880		1
+-
+-#	from			to			module		cost
+-alias	CP891//			IBM891//
+-alias	CSIBM891//		IBM891//
+-alias	OSF1002037B//		IBM891//
+-module	IBM891//		INTERNAL		IBM891		1
+-module	INTERNAL		IBM891//		IBM891		1
+-
+-#	from			to			module		cost
+-alias	CP903//			IBM903//
+-alias	CSIBM903//		IBM903//
+-alias	OSF10020387//		IBM903//
+-module	IBM903//		INTERNAL		IBM903		1
+-module	INTERNAL		IBM903//		IBM903		1
+-
+-#	from			to			module		cost
+-alias	CP904//			IBM904//
+-alias	904//			IBM904//
+-alias	CSIBM904//		IBM904//
+-alias	OSF10020388//		IBM904//
+-module	IBM904//		INTERNAL		IBM904		1
+-module	INTERNAL		IBM904//		IBM904		1
+-
+-#	from			to			module		cost
+-alias	CP905//			IBM905//
+-alias	EBCDIC-CP-TR//		IBM905//
+-alias	CSIBM905//		IBM905//
+-module	IBM905//		INTERNAL		IBM905		1
+-module	INTERNAL		IBM905//		IBM905		1
+-
+-#	from			to			module		cost
+-alias	CP918//			IBM918//
+-alias	EBCDIC-CP-AR2//		IBM918//
+-alias	CSIBM918//		IBM918//
+-alias	OSF10020396//		IBM918//
+-module	IBM918//		INTERNAL		IBM918		1
+-module	INTERNAL		IBM918//		IBM918		1
+-
+-#	from			to			module		cost
+-alias	IBM-922//		IBM922//
+-alias	CP922//			IBM922//
+-alias	CSIBM922//		IBM922//
+-module	IBM922//		INTERNAL		IBM922		1
+-module	INTERNAL		IBM922//		IBM922		1
+-
+-#	from			to			module		cost
+-alias	IBM-930//		IBM930//
+-alias	CP930//			IBM930//
+-alias	CSIBM930//		IBM930//
+-module	IBM930//		INTERNAL		IBM930		1
+-module	INTERNAL		IBM930//		IBM930		1
+-
+-#	from			to			module		cost
+-alias	IBM-932//		IBM932//
+-alias	CSIBM932//		IBM932//
+-module	IBM932//		INTERNAL		IBM932		1
+-module	INTERNAL		IBM932//		IBM932		1
+-
+-#	from			to			module		cost
+-alias	IBM-933//		IBM933//
+-alias	CP933//			IBM933//
+-alias	CSIBM933//		IBM933//
+-module	IBM933//		INTERNAL		IBM933		1
+-module	INTERNAL		IBM933//		IBM933		1
+-
+-#	from			to			module		cost
+-alias	IBM-935//		IBM935//
+-alias	CP935//			IBM935//
+-alias	CSIBM935//		IBM935//
+-module	IBM935//		INTERNAL		IBM935		1
+-module	INTERNAL		IBM935//		IBM935		1
+-
+-#	from			to			module		cost
+-alias	IBM-937//		IBM937//
+-alias	CP937//			IBM937//
+-alias	CSIBM937//		IBM937//
+-module	IBM937//		INTERNAL		IBM937		1
+-module	INTERNAL		IBM937//		IBM937		1
+-
+-#	from			to			module		cost
+-alias	IBM-939//		IBM939//
+-alias	CP939//			IBM939//
+-alias	CSIBM939//		IBM939//
+-module	IBM939//		INTERNAL		IBM939		1
+-module	INTERNAL		IBM939//		IBM939		1
+-
+-#	from			to			module		cost
+-alias	IBM-943//		IBM943//
+-alias	CSIBM943//		IBM943//
+-module	IBM943//		INTERNAL		IBM943		1
+-module	INTERNAL		IBM943//		IBM943		1
+-
+-#	from			to			module		cost
+-alias	CP1004//		IBM1004//
+-alias	OS2LATIN1//		IBM1004//
+-module	IBM1004//		INTERNAL		IBM1004		1
+-module	INTERNAL		IBM1004//		IBM1004		1
+-
+-#	from			to			module		cost
+-alias	CP1026//		IBM1026//
+-alias	1026//			IBM1026//
+-alias	CSIBM1026//		IBM1026//
+-alias	OSF10020402//		IBM1026//
+-module	IBM1026//		INTERNAL		IBM1026		1
+-module	INTERNAL		IBM1026//		IBM1026		1
+-
+-#	from			to			module		cost
+-alias	IBM-1046//		IBM1046//
+-alias	CP1046//		IBM1046//
+-alias	1046//			IBM1046//
+-module	IBM1046//		INTERNAL		IBM1046		1
+-module	INTERNAL		IBM1046//		IBM1046		1
+-
+-#	from			to			module		cost
+-alias	IBM-1047//		IBM1047//
+-alias	CP1047//		IBM1047//
+-alias	1047//			IBM1047//
+-alias	OSF10020417//		IBM1047//
+-module	IBM1047//		INTERNAL		IBM1047		1
+-module	INTERNAL		IBM1047//		IBM1047		1
+-
+-#	from			to			module		cost
+-alias	IBM-1124//		IBM1124//
+-alias	CP1124//		IBM1124//
+-alias	CSIBM1124//		IBM1124//
+-module	IBM1124//		INTERNAL		IBM1124		1
+-module	INTERNAL		IBM1124//		IBM1124		1
+-
+-#	from			to			module		cost
+-alias	IBM-1129//		IBM1129//
+-alias	CP1129//		IBM1129//
+-alias	CSIBM1129//		IBM1129//
+-module	IBM1129//		INTERNAL		IBM1129		1
+-module	INTERNAL		IBM1129//		IBM1129		1
+-
+-#	from			to			module		cost
+-alias	IBM-1160//		IBM1160//
+-alias	CP1160//		IBM1160//
+-alias	CSIBM1160//		IBM1160//
+-module	IBM1160//		INTERNAL		IBM1160		1
+-module	INTERNAL		IBM1160//		IBM1160		1
+-
+-#	from			to			module		cost
+-alias	IBM-1161//		IBM1161//
+-alias	CP1161//		IBM1161//
+-alias	CSIBM1161//		IBM1161//
+-module	IBM1161//		INTERNAL		IBM1161		1
+-module	INTERNAL		IBM1161//		IBM1161		1
+-
+-#	from			to			module		cost
+-alias	IBM-1132//		IBM1132//
+-alias	CP1132//		IBM1132//
+-alias	CSIBM1132//		IBM1132//
+-module	IBM1132//		INTERNAL		IBM1132		1
+-module	INTERNAL		IBM1132//		IBM1132		1
+-
+-#	from			to			module		cost
+-alias	IBM-1133//		IBM1133//
+-alias	CP1133//		IBM1133//
+-alias	CSIBM1133//		IBM1133//
+-module	IBM1133//		INTERNAL		IBM1133		1
+-module	INTERNAL		IBM1133//		IBM1133		1
+-
+-#	from			to			module		cost
+-alias	IBM-1162//		IBM1162//
+-alias	CP1162//		IBM1162//
+-alias	CSIBM11621162//		IBM1162//
+-module	IBM1162//		INTERNAL		IBM1162		1
+-module	INTERNAL		IBM1162//		IBM1162		1
+-
+-#	from			to			module		cost
+-alias	IBM-1163//		IBM1163//
+-alias	CP1163//		IBM1163//
+-alias	CSIBM1163//		IBM1163//
+-module	IBM1163//		INTERNAL		IBM1163		1
+-module	INTERNAL		IBM1163//		IBM1163		1
+-
+-#	from			to			module		cost
+-alias	IBM-1164//		IBM1164//
+-alias	CP1164//		IBM1164//
+-alias	CSIBM1164//		IBM1164//
+-module	IBM1164//		INTERNAL		IBM1164		1
+-module	INTERNAL		IBM1164//		IBM1164		1
+-
+-#	from			to			module		cost
+-alias	EUCKR//			EUC-KR//
+-alias	CSEUCKR//		EUC-KR//
+-alias	OSF0004000a//		EUC-KR//
+-module	EUC-KR//		INTERNAL		EUC-KR		1
+-module	INTERNAL		EUC-KR//		EUC-KR		1
+-
+-#	from			to			module		cost
+-alias	MSCP949//		UHC//
+-alias	CP949//			UHC//
+-alias	OSF100203B5//		UHC//
+-module	UHC//			INTERNAL		UHC		1
+-module	INTERNAL		UHC//			UHC		1
+-
+-#	from			to			module		cost
+-alias	MSCP1361//		JOHAB//
+-alias	CP1361//		JOHAB//
+-module	JOHAB//			INTERNAL		JOHAB		1
+-module	INTERNAL		JOHAB//			JOHAB		1
+-
+-#	from			to			module		cost
+-alias	BIG-FIVE//		BIG5//
+-alias	BIGFIVE//		BIG5//
+-alias	BIG-5//			BIG5//
+-alias	CN-BIG5//		BIG5//
+-alias	CP950//			BIG5//
+-module	BIG5//			INTERNAL		BIG5		1
+-module	INTERNAL		BIG5//			BIG5		1
+-
+-#	from			to			module		cost
+-alias	BIG5-HKSCS//		BIG5HKSCS//
+-module	BIG5HKSCS//		INTERNAL		BIG5HKSCS	1
+-module	INTERNAL		BIG5HKSCS//		BIG5HKSCS	1
+-
+-#	from			to			module		cost
+-alias	EUCJP-MS//		EUC-JP-MS//
+-alias	EUCJP-OPEN//		EUC-JP-MS//
+-alias	EUCJP-WIN//		EUC-JP-MS//
+-module	EUC-JP-MS//		INTERNAL		EUC-JP-MS	1
+-module	INTERNAL		EUC-JP-MS//		EUC-JP-MS	1
+-
+-#	from			to			module		cost
+-alias	EUCJP//			EUC-JP//
+-alias	CSEUCPKDFMTJAPANESE//	EUC-JP//
+-alias	OSF00030010//		EUC-JP//
+-alias	UJIS//			EUC-JP//
+-module	EUC-JP//		INTERNAL		EUC-JP		1
+-module	INTERNAL		EUC-JP//		EUC-JP		1
+-
+-#	from			to			module		cost
+-alias	EUCCN//			EUC-CN//
+-alias	GB2312//		EUC-CN//
+-alias	csGB2312//		EUC-CN//
+-alias	CN-GB//			EUC-CN//
+-module	EUC-CN//		INTERNAL		EUC-CN		1
+-module	INTERNAL		EUC-CN//		EUC-CN		1
+-
+-#	from			to			module		cost
+-module	EUC-CN//		BIG5//			GBBIG5		1
+-module	BIG5//			EUC-CN//		GBBIG5		1
+-
+-#	from			to			module		cost
+-alias	GB13000//		GBK//
+-alias	CP936//			GBK//
+-alias	MS936//			GBK//
+-alias	WINDOWS-936//		GBK//
+-module	GBK//			INTERNAL		GBK		1
+-module	INTERNAL		GBK//			GBK		1
+-
+-#	from			to			module		cost
+-module	GBK//			EUC-CN//		GBGBK		1
+-module	EUC-CN//		GBK//			GBGBK		1
+-
+-#	from			to			module		cost
+-alias	EUCTW//			EUC-TW//
+-alias	OSF0005000a//		EUC-TW//
+-module	EUC-TW//		INTERNAL		EUC-TW		1
+-module	INTERNAL		EUC-TW//		EUC-TW		1
+-
+-#	from			to			module		cost
+-alias	RUSCII//		CP1125//
+-alias	IBM848//		CP1125//
+-module	CP1125//		INTERNAL		CP1125		1
+-module	INTERNAL		CP1125//		CP1125		1
+-
+-#	from			to			module		cost
+-alias	MS-EE//			CP1250//
+-alias	WINDOWS-1250//		CP1250//
+-module	CP1250//		INTERNAL		CP1250		1
+-module	INTERNAL		CP1250//		CP1250		1
+-
+-#	from			to			module		cost
+-alias	MS-CYRL//		CP1251//
+-alias	WINDOWS-1251//		CP1251//
+-module	CP1251//		INTERNAL		CP1251		1
+-module	INTERNAL		CP1251//		CP1251		1
+-
+ #	from			to			module		cost
+ alias	MS-ANSI//		CP1252//
+ alias	WINDOWS-1252//		CP1252//
+ module	CP1252//		INTERNAL		CP1252		1
+ module	INTERNAL		CP1252//		CP1252		1
+ 
+-#	from			to			module		cost
+-alias	MS-GREEK//		CP1253//
+-alias	WINDOWS-1253//		CP1253//
+-module	CP1253//		INTERNAL		CP1253		1
+-module	INTERNAL		CP1253//		CP1253		1
+-
+-#	from			to			module		cost
+-alias	MS-TURK//		CP1254//
+-alias	WINDOWS-1254//		CP1254//
+-module	CP1254//		INTERNAL		CP1254		1
+-module	INTERNAL		CP1254//		CP1254		1
+-
+-#	from			to			module		cost
+-alias	MS-HEBR//		CP1255//
+-alias	WINDOWS-1255//		CP1255//
+-module	CP1255//		INTERNAL		CP1255		1
+-module	INTERNAL		CP1255//		CP1255		1
+-
+-#	from			to			module		cost
+-alias	MS-ARAB//		CP1256//
+-alias	WINDOWS-1256//		CP1256//
+-module	CP1256//		INTERNAL		CP1256		1
+-module	INTERNAL		CP1256//		CP1256		1
+-
+-#	from			to			module		cost
+-alias	WINBALTRIM//		CP1257//
+-alias	WINDOWS-1257//		CP1257//
+-module	CP1257//		INTERNAL		CP1257		1
+-module	INTERNAL		CP1257//		CP1257		1
+-
+-#	from			to			module		cost
+-alias	WINDOWS-1258//		CP1258//
+-module	CP1258//		INTERNAL		CP1258		1
+-module	INTERNAL		CP1258//		CP1258		1
+-
+-#	from			to			module		cost
+-alias	874//			IBM874//
+-alias	CP874//			IBM874//
+-alias	WINDOWS-874//		IBM874//
+-module	IBM874//		INTERNAL		IBM874		1
+-module	INTERNAL		IBM874//		IBM874		1
+-
+-#	from			to			module		cost
+-module	CP737//			INTERNAL		CP737		1
+-module	INTERNAL		CP737//			CP737		1
+-
+-#	from			to			module		cost
+-module	CP770//			INTERNAL		CP770		1
+-module	INTERNAL		CP770//			CP770		1
+-
+-#	from			to			module		cost
+-module	CP771//			INTERNAL		CP771		1
+-module	INTERNAL		CP771//			CP771		1
+-
+-#	from			to			module		cost
+-module	CP772//			INTERNAL		CP772		1
+-module	INTERNAL		CP772//			CP772		1
+-
+-#	from			to			module		cost
+-module	CP773//			INTERNAL		CP773		1
+-module	INTERNAL		CP773//			CP773		1
+-
+-#	from			to			module		cost
+-module	CP774//			INTERNAL		CP774		1
+-module	INTERNAL		CP774//			CP774		1
+-
+-#	from			to			module		cost
+-alias	IBM775//		CP775//
+-alias	CSPC775BALTIC//		CP775//
+-module	CP775//			INTERNAL		CP775		1
+-module	INTERNAL		CP775//			CP775		1
+-
+-#	from			to			module		cost
+-alias	CSISO2022JP//		ISO-2022-JP//
+-alias	ISO2022JP//		ISO-2022-JP//
+-module	ISO-2022-JP//		INTERNAL		ISO-2022-JP	1
+-module	INTERNAL		ISO-2022-JP//		ISO-2022-JP	1
+-
+-#	from			to			module		cost
+-alias	CSISO2022JP2//		ISO-2022-JP-2//
+-alias	ISO2022JP2//		ISO-2022-JP-2//
+-module	ISO-2022-JP-2//		INTERNAL		ISO-2022-JP	1
+-module	INTERNAL		ISO-2022-JP-2//		ISO-2022-JP	1
+-
+-#	from			to			module		cost
+-module	ISO-2022-JP-3//		INTERNAL		ISO-2022-JP-3	1
+-module	INTERNAL		ISO-2022-JP-3//		ISO-2022-JP-3	1
+-
+-#	from			to			module		cost
+-alias	CSISO2022KR//		ISO-2022-KR//
+-alias	ISO2022KR//		ISO-2022-KR//
+-module	ISO-2022-KR//		INTERNAL		ISO-2022-KR	1
+-module	INTERNAL		ISO-2022-KR//		ISO-2022-KR	1
+-
+-#	from			to			module		cost
+-alias	CSISO2022CN//		ISO-2022-CN//
+-alias	ISO2022CN//		ISO-2022-CN//
+-module	ISO-2022-CN//		INTERNAL		ISO-2022-CN	1
+-module	INTERNAL		ISO-2022-CN//		ISO-2022-CN	1
+-
+-#	from			to			module		cost
+-alias	ISO2022CNEXT//		ISO-2022-CN-EXT//
+-module	ISO-2022-CN-EXT//	INTERNAL		ISO-2022-CN-EXT	1
+-module	INTERNAL		ISO-2022-CN-EXT//	ISO-2022-CN-EXT	1
+-
+-#	from			to			module		cost
+-alias	MAC//			MACINTOSH//
+-alias	CSMACINTOSH//		MACINTOSH//
+-module	MACINTOSH//		INTERNAL		MACINTOSH	1
+-module	INTERNAL		MACINTOSH//		MACINTOSH	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-143//		IEC_P27-1//
+-alias	CSISO143IECP271//	IEC_P27-1//
+-alias	IEC_P271//		IEC_P27-1//
+-module	IEC_P27-1//		INTERNAL		IEC_P27-1	1
+-module	INTERNAL		IEC_P27-1//		IEC_P27-1	1
+-
+-#	from			to			module		cost
+-alias	ISO_9036//		ASMO_449//
+-alias	ARABIC7//		ASMO_449//
+-alias	ISO-IR-89//		ASMO_449//
+-alias	CSISO89ASMO449//	ASMO_449//
+-module	ASMO_449//		INTERNAL		ASMO_449	1
+-module	INTERNAL		ASMO_449//		ASMO_449	1
+-
+ #	from			to			module		cost
+ alias	ANSI_X3.110-1983//	ANSI_X3.110//
+ alias	ISO-IR-99//		ANSI_X3.110//
+@@ -1319,181 +74,6 @@ alias	CSISO99NAPLPS//		ANSI_X3.110//
+ module	ANSI_X3.110//		INTERNAL		ANSI_X3.110	1
+ module	INTERNAL		ANSI_X3.110//		ANSI_X3.110	1
+ 
+-#	from			to			module		cost
+-alias	ISO-IR-139//		CSN_369103//
+-alias	CSISO139CSN369103//	CSN_369103//
+-module	CSN_369103//		INTERNAL		CSN_369103	1
+-module	INTERNAL		CSN_369103//		CSN_369103	1
+-
+-#	from			to			module		cost
+-alias	CWI-2//			CWI//
+-alias	CP-HU//			CWI//
+-module	CWI//			INTERNAL		CWI		1
+-module	INTERNAL		CWI//			CWI		1
+-
+-#	from			to			module		cost
+-alias	DEC//			DEC-MCS//
+-alias	CSDECMCS//		DEC-MCS//
+-alias	DECMCS//		DEC-MCS//
+-module	DEC-MCS//		INTERNAL		DEC-MCS		1
+-module	INTERNAL		DEC-MCS//		DEC-MCS		1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-111//		ECMA-CYRILLIC//
+-alias	CSISO111ECMACYRILLIC//	ECMA-CYRILLIC//
+-alias	ECMACYRILLIC//		ECMA-CYRILLIC//
+-module	ECMA-CYRILLIC//		INTERNAL		ECMA-CYRILLIC	1
+-module	INTERNAL		ECMA-CYRILLIC//		ECMA-CYRILLIC	1
+-
+-#	from			to			module		cost
+-alias	ST_SEV_358-88//		GOST_19768-74//
+-alias	GOST_19768//		GOST_19768-74//
+-alias	ISO-IR-153//		GOST_19768-74//
+-alias	CSISO153GOST1976874//	GOST_19768-74//
+-alias	GOST_1976874//		GOST_19768-74//
+-module	GOST_19768-74//		INTERNAL		GOST_19768-74	1
+-module	INTERNAL		GOST_19768-74//		GOST_19768-74	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-150//		GREEK-CCITT//
+-alias	CSISO150//		GREEK-CCITT//
+-alias	CSISO150GREEKCCITT//	GREEK-CCITT//
+-alias	GREEKCCITT//		GREEK-CCITT//
+-module	GREEK-CCITT//		INTERNAL		GREEK-CCITT	1
+-module	INTERNAL		GREEK-CCITT//		GREEK-CCITT	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-88//		GREEK7//
+-alias	CSISO88GREEK7//		GREEK7//
+-module	GREEK7//		INTERNAL		GREEK7		1
+-module	INTERNAL		GREEK7//		GREEK7		1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-18//		GREEK7-OLD//
+-alias	CSISO18GREEK7OLD//	GREEK7-OLD//
+-alias	GREEK7OLD//		GREEK7-OLD//
+-module	GREEK7-OLD//		INTERNAL		GREEK7-OLD	1
+-module	INTERNAL		GREEK7-OLD//		GREEK7-OLD	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-49//		INIS//
+-alias	CSISO49INIS//		INIS//
+-module	INIS//			INTERNAL		INIS		1
+-module	INTERNAL		INIS//			INIS		1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-50//		INIS-8//
+-alias	CSISO50INIS8//		INIS-8//
+-alias	INIS8//			INIS-8//
+-module	INIS-8//		INTERNAL		INIS-8		1
+-module	INTERNAL		INIS-8//		INIS-8		1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-51//		INIS-CYRILLIC//
+-alias	CSISO51INISCYRILLIC//	INIS-CYRILLIC//
+-alias	INISCYRILLIC//		INIS-CYRILLIC//
+-module	INIS-CYRILLIC//		INTERNAL		INIS-CYRILLIC	1
+-module	INTERNAL		INIS-CYRILLIC//		INIS-CYRILLIC	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-98//		ISO_2033//
+-alias	ISO_2033-1983//		ISO_2033//
+-alias	E13B//			ISO_2033//
+-alias	CSISO2033//		ISO_2033//
+-module	ISO_2033//		INTERNAL		ISO_2033	1
+-module	INTERNAL		ISO_2033//		ISO_2033	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-37//		ISO_5427//
+-alias	KOI-7//			ISO_5427//
+-alias	CSISO5427CYRILLIC//	ISO_5427//
+-module	ISO_5427//		INTERNAL		ISO_5427	1
+-module	INTERNAL		ISO_5427//		ISO_5427	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-54//		ISO_5427-EXT//
+-alias	ISO_5427:1981//		ISO_5427-EXT//
+-alias	CSISO5427CYRILLIC1981//	ISO_5427-EXT//
+-alias	ISO_5427EXT//		ISO_5427-EXT//
+-module	ISO_5427-EXT//		INTERNAL		ISO_5427-EXT	1
+-module	INTERNAL		ISO_5427-EXT//		ISO_5427-EXT	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-55//		ISO_5428//
+-alias	ISO_5428:1980//		ISO_5428//
+-alias	CSISO5428GREEK//	ISO_5428//
+-module	ISO_5428//		INTERNAL		ISO_5428	1
+-module	INTERNAL		ISO_5428//		ISO_5428	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-155//		ISO_10367-BOX//
+-alias	CSISO10367BOX//		ISO_10367-BOX//
+-alias	ISO_10367BOX//		ISO_10367-BOX//
+-module	ISO_10367-BOX//		INTERNAL		ISO_10367-BOX	1
+-module	INTERNAL		ISO_10367-BOX//		ISO_10367-BOX	1
+-
+-#	from			to			module		cost
+-alias	MACIS//			MAC-IS//
+-module	MAC-IS//		INTERNAL		MAC-IS		1
+-module	INTERNAL		MAC-IS//		MAC-IS		1
+-
+-#	from			to			module		cost
+-alias	MACUK//			MAC-UK//
+-alias	MACUKRAINIAN//		MAC-UK//
+-alias	MAC-CYRILLIC//		MAC-UK//
+-alias	MACCYRILLIC//		MAC-UK//
+-module	MAC-UK//		INTERNAL		MAC-UK		1
+-module	INTERNAL		MAC-UK//		MAC-UK		1
+-
+-#	from			to			module		cost
+-alias	MS-MAC-CYRILLIC//	CP10007//
+-alias	MSMACCYRILLIC//		CP10007//
+-module	CP10007//		INTERNAL		CP10007		1
+-module	INTERNAL		CP10007//		CP10007		1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-9-1//		NATS-DANO//
+-alias	CSNATSDANO//		NATS-DANO//
+-alias	NATSDANO//		NATS-DANO//
+-module	NATS-DANO//		INTERNAL		NATS-DANO	1
+-module	INTERNAL		NATS-DANO//		NATS-DANO	1
+-
+-#	from			to			module		cost
+-alias	ISO-IR-8-1//		NATS-SEFI//
+-alias	CSNATSSEFI//		NATS-SEFI//
+-alias	NATSSEFI//		NATS-SEFI//
+-module	NATS-SEFI//		INTERNAL		NATS-SEFI	1
+-module	INTERNAL		NATS-SEFI//		NATS-SEFI	1
+-
+-#	from			to			module		cost
+-alias	WS2//			WIN-SAMI-2//
+-alias	WINSAMI2//		WIN-SAMI-2//
+-module	WIN-SAMI-2//		INTERNAL		SAMI-WS2	1
+-module	INTERNAL		WIN-SAMI-2//		SAMI-WS2	1
+-
+-#	from			to			module		cost
+-module	ISO-IR-197//		INTERNAL		ISO-IR-197	1
+-module	INTERNAL		ISO-IR-197//		ISO-IR-197	1
+-
+-#	from			to			module		cost
+-alias	TIS620//		TIS-620//
+-alias	TIS620-0//		TIS-620//
+-alias	TIS620.2529-1//		TIS-620//
+-alias	TIS620.2533-0//		TIS-620//
+-alias	ISO-IR-166//		TIS-620//
+-module	TIS-620//		INTERNAL		TIS-620		1
+-module	INTERNAL		TIS-620//		TIS-620		1
+-
+-#	from			to			module		cost
+-alias	KOI8U//			KOI8-U//
+-module	KOI8-U//		INTERNAL		KOI8-U		1
+-module	INTERNAL		KOI8-U//		KOI8-U		1
+-
+-#	from			to			module		cost
+-alias	ISIRI3342//		ISIRI-3342//
+-module	ISIRI-3342//		INTERNAL		ISIRI-3342	1
+-module	INTERNAL		ISIRI-3342//		ISIRI-3342	1
+-
+ #	from			to			module		cost
+ alias	UTF16//			UTF-16//
+ module	UTF-16//		INTERNAL		UTF-16		1
+@@ -1534,442 +114,5 @@ alias	UTF7//			UTF-7//
+ module	UTF-7//			INTERNAL		UTF-7		1
+ module	INTERNAL		UTF-7//			UTF-7		1
+ 
+-#	from			to			module		cost
+-module	GB18030//		INTERNAL		GB18030		1
+-module	INTERNAL		GB18030//		GB18030		1
+-
+-#	from			to			module		cost
+-module	VISCII//		INTERNAL		VISCII		1
+-module	INTERNAL		VISCII//		VISCII		1
+-
+-#	from			to			module		cost
+-module	KOI8-T//		INTERNAL		KOI8-T		1
+-module	INTERNAL		KOI8-T//		KOI8-T		1
+-
+-#	from			to			module		cost
+-module	GEORGIAN-PS//		INTERNAL		GEORGIAN-PS	1
+-module	INTERNAL		GEORGIAN-PS//		GEORGIAN-PS	1
+-
+-#	from			to			module		cost
+-module	GEORGIAN-ACADEMY//	INTERNAL		GEORGIAN-ACADEMY 1
+-module	INTERNAL		GEORGIAN-ACADEMY//	GEORGIAN-ACADEMY 1
+-
+-#	from			to			module		cost
+-module	ISO-IR-209//		INTERNAL		ISO-IR-209	1
+-module	INTERNAL		ISO-IR-209//		ISO-IR-209	1
+-
+-#	from			to			module		cost
+-module	MAC-SAMI//		INTERNAL		MAC-SAMI	1
+-module	INTERNAL		MAC-SAMI//		MAC-SAMI	1
+-
+-#	from			to			module		cost
+-alias	ARMSCII8//		ARMSCII-8//
+-module	ARMSCII-8//		INTERNAL		ARMSCII-8	1
+-module	INTERNAL		ARMSCII-8//		ARMSCII-8	1
+-
+-#	from			to			module		cost
+-alias	TCVN//			TCVN5712-1//
+-alias	TCVN-5712//		TCVN5712-1//
+-alias	TCVN5712-1:1993//	TCVN5712-1//
+-module	TCVN5712-1//		INTERNAL		TCVN5712-1	1
+-module	INTERNAL		TCVN5712-1//		TCVN5712-1	1
+-
+-#	from			to			module		cost
+-module	EUC-JISX0213//		INTERNAL		EUC-JISX0213	1
+-module	INTERNAL		EUC-JISX0213//		EUC-JISX0213	1
+-
+-#	from			to			module		cost
+-alias	ShiftJISX0213//		Shift_JISX0213//
+-module	Shift_JISX0213//	INTERNAL		SHIFT_JISX0213	1
+-module	INTERNAL		Shift_JISX0213//	SHIFT_JISX0213	1
+-
+-#	from			to			module		cost
+-module	TSCII//			INTERNAL		TSCII		1
+-module	INTERNAL		TSCII//			TSCII		1
+-
+-#	from			to			module		cost
+-module	PT154//			INTERNAL		PT154		1
+-module	INTERNAL		PT154//			PT154		1
+-
+-#	from			to			module		cost
+-alias	STRK1048-2002//		RK1048//
+-module	RK1048//		INTERNAL		RK1048		1
+-module	INTERNAL		RK1048//		RK1048		1
+-
+-#	from			to			module		cost
+-alias	IBM-1025//		IBM1025//
+-alias	CP1025//		IBM1025//
+-alias	CSIBM1025//		IBM1025//
+-module	IBM1025//		INTERNAL		IBM1025		1
+-module	INTERNAL		IBM1025//		IBM1025		1
+-
+-#	from			to			module		cost
+-alias	IBM-1122//		IBM1122//
+-alias	CP1122//		IBM1122//
+-alias	CSIBM1122//		IBM1122//
+-module	IBM1122//		INTERNAL		IBM1122		1
+-module	INTERNAL		IBM1122//		IBM1122		1
+-
+-#	from			to			module		cost
+-alias	IBM-1137//		IBM1137//
+-alias	CP1137//		IBM1137//
+-alias	CSIBM1137//		IBM1137//
+-module	IBM1137//		INTERNAL		IBM1137		1
+-module	INTERNAL		IBM1137//		IBM1137		1
+-
+-#	from			to			module		cost
+-alias	IBM-1153//		IBM1153//
+-alias	CP1153//		IBM1153//
+-alias	CSIBM1153//		IBM1153//
+-module	IBM1153//		INTERNAL		IBM1153		1
+-module	INTERNAL		IBM1153//		IBM1153		1
+-
+-#	from			to			module		cost
+-alias	IBM-1154//		IBM1154//
+-alias	CP1154//		IBM1154//
+-alias	CSIBM1154//		IBM1154//
+-module	IBM1154//		INTERNAL		IBM1154		1
+-module	INTERNAL		IBM1154//		IBM1154		1
+-
+-#	from			to			module		cost
+-alias	IBM-1155//		IBM1155//
+-alias	CP1155//		IBM1155//
+-alias	CSIBM1155//		IBM1155//
+-module	IBM1155//		INTERNAL		IBM1155		1
+-module	INTERNAL		IBM1155//		IBM1155		1
+-
+-#	from			to			module		cost
+-alias	IBM-1156//		IBM1156//
+-alias	CP1156//		IBM1156//
+-alias	CSIBM1156//		IBM1156//
+-module	IBM1156//		INTERNAL		IBM1156		1
+-module	INTERNAL		IBM1156//		IBM1156		1
+-
+-#	from			to			module		cost
+-alias	IBM-1157//		IBM1157//
+-alias	CP1157//		IBM1157//
+-alias	CSIBM1157//		IBM1157//
+-module	IBM1157//		INTERNAL		IBM1157		1
+-module	INTERNAL		IBM1157//		IBM1157		1
+-
+-#	from			to			module		cost
+-alias	IBM-1158//		IBM1158//
+-alias	CP1158//		IBM1158//
+-alias	CSIBM1158//		IBM1158//
+-module	IBM1158//		INTERNAL		IBM1158		1
+-module	INTERNAL		IBM1158//		IBM1158		1
+-
+-#	from			to			module		cost
+-alias	IBM-803//		IBM803//
+-alias	CP803//		IBM803//
+-alias	CSIBM803//		IBM803//
+-module	IBM803//		INTERNAL		IBM803		1
+-module	INTERNAL		IBM803//		IBM803		1
+-
+-#	from			to			module		cost
+-alias	IBM-901//		IBM901//
+-alias	CP901//		IBM901//
+-alias	CSIBM901//		IBM901//
+-module	IBM901//		INTERNAL		IBM901		1
+-module	INTERNAL		IBM901//		IBM901		1
+-
+-#	from			to			module		cost
+-alias	IBM-902//		IBM902//
+-alias	CP902//		IBM902//
+-alias	CSIBM902//		IBM902//
+-module	IBM902//		INTERNAL		IBM902		1
+-module	INTERNAL		IBM902//		IBM902		1
+-
+-#	from			to			module		cost
+-alias	IBM-921//		IBM921//
+-alias	CP921//		IBM921//
+-alias	CSIBM921//		IBM921//
+-module	IBM921//		INTERNAL		IBM921		1
+-module	INTERNAL		IBM921//		IBM921		1
+-
+-#	from			to			module		cost
+-alias	IBM-1008//		IBM1008//
+-alias	CP1008//		IBM1008//
+-alias	CSIBM1008//		IBM1008//
+-module	IBM1008//		INTERNAL		IBM1008		1
+-module	INTERNAL		IBM1008//		IBM1008		1
+-
+-#	from			to			module		cost
+-module	IBM1008//		IBM420//		IBM1008_420	1
+-module	IBM420//		IBM1008//		IBM1008_420	1
+-
+-#	from			to			module		cost
+-alias	IBM-1097//		IBM1097//
+-alias	CP1097//		IBM1097//
+-alias	CSIBM1097//		IBM1097//
+-module	IBM1097//		INTERNAL		IBM1097		1
+-module	INTERNAL		IBM1097//		IBM1097		1
+-
+-#	from			to			module		cost
+-alias	IBM-1112//		IBM1112//
+-alias	CP1112//		IBM1112//
+-alias	CSIBM1112//		IBM1112//
+-module	IBM1112//		INTERNAL		IBM1112		1
+-module	INTERNAL		IBM1112//		IBM1112		1
+-
+-#	from			to			module		cost
+-alias	IBM-1123//		IBM1123//
+-alias	CP1123//		IBM1123//
+-alias	CSIBM1123//		IBM1123//
+-module	IBM1123//		INTERNAL		IBM1123		1
+-module	INTERNAL		IBM1123//		IBM1123		1
+-
+-#	from			to			module		cost
+-alias	IBM-1130//		IBM1130//
+-alias	CP1130//		IBM1130//
+-alias	CSIBM1130//		IBM1130//
+-module	IBM1130//		INTERNAL		IBM1130		1
+-module	INTERNAL		IBM1130//		IBM1130		1
+-
+-#	from			to			module		cost
+-alias	IBM-1140//		IBM1140//
+-alias	CP1140//		IBM1140//
+-alias	CSIBM1140//		IBM1140//
+-module	IBM1140//		INTERNAL		IBM1140		1
+-module	INTERNAL		IBM1140//		IBM1140		1
+-
+-#	from			to			module		cost
+-alias	IBM-1141//		IBM1141//
+-alias	CP1141//		IBM1141//
+-alias	CSIBM1141//		IBM1141//
+-module	IBM1141//		INTERNAL		IBM1141		1
+-module	INTERNAL		IBM1141//		IBM1141		1
+-
+-#	from			to			module		cost
+-alias	IBM-1142//		IBM1142//
+-alias	CP1142//		IBM1142//
+-alias	CSIBM1142//		IBM1142//
+-module	IBM1142//		INTERNAL		IBM1142		1
+-module	INTERNAL		IBM1142//		IBM1142		1
+-
+-#	from			to			module		cost
+-alias	IBM-1143//		IBM1143//
+-alias	CP1143//		IBM1143//
+-alias	CSIBM1143//		IBM1143//
+-module	IBM1143//		INTERNAL		IBM1143		1
+-module	INTERNAL		IBM1143//		IBM1143		1
+-
+-#	from			to			module		cost
+-alias	IBM-1144//		IBM1144//
+-alias	CP1144//		IBM1144//
+-alias	CSIBM1144//		IBM1144//
+-module	IBM1144//		INTERNAL		IBM1144		1
+-module	INTERNAL		IBM1144//		IBM1144		1
+-
+-#	from			to			module		cost
+-alias	IBM-1145//		IBM1145//
+-alias	CP1145//		IBM1145//
+-alias	CSIBM1145//		IBM1145//
+-module	IBM1145//		INTERNAL		IBM1145		1
+-module	INTERNAL		IBM1145//		IBM1145		1
+-
+-#	from			to			module		cost
+-alias	IBM-1146//		IBM1146//
+-alias	CP1146//		IBM1146//
+-alias	CSIBM1146//		IBM1146//
+-module	IBM1146//		INTERNAL		IBM1146		1
+-module	INTERNAL		IBM1146//		IBM1146		1
+-
+-#	from			to			module		cost
+-alias	IBM-1147//		IBM1147//
+-alias	CP1147//		IBM1147//
+-alias	CSIBM1147//		IBM1147//
+-module	IBM1147//		INTERNAL		IBM1147		1
+-module	INTERNAL		IBM1147//		IBM1147		1
+-
+-#	from			to			module		cost
+-alias	IBM-1148//		IBM1148//
+-alias	CP1148//		IBM1148//
+-alias	CSIBM1148//		IBM1148//
+-module	IBM1148//		INTERNAL		IBM1148		1
+-module	INTERNAL		IBM1148//		IBM1148		1
+-
+-#	from			to			module		cost
+-alias	IBM-1149//		IBM1149//
+-alias	CP1149//		IBM1149//
+-alias	CSIBM1149//		IBM1149//
+-module	IBM1149//		INTERNAL		IBM1149		1
+-module	INTERNAL		IBM1149//		IBM1149		1
+-
+-#	from			to			module		cost
+-alias	IBM-1166//		IBM1166//
+-alias	CP1166//		IBM1166//
+-alias	CSIBM1166//		IBM1166//
+-module	IBM1166//		INTERNAL		IBM1166		1
+-module	INTERNAL		IBM1166//		IBM1166		1
+-
+-#	from			to			module		cost
+-alias	IBM-1167//		IBM1167//
+-alias	CP1167//		IBM1167//
+-alias	CSIBM1167//		IBM1167//
+-module	IBM1167//		INTERNAL		IBM1167		1
+-module	INTERNAL		IBM1167//		IBM1167		1
+-
+-#	from			to			module		cost
+-alias	IBM-4517//		IBM4517//
+-alias	CP4517//		IBM4517//
+-alias	CSIBM4517//		IBM4517//
+-module	IBM4517//		INTERNAL		IBM4517		1
+-module	INTERNAL		IBM4517//		IBM4517		1
+-
+-#	from			to			module		cost
+-alias	IBM-4899//		IBM4899//
+-alias	CP4899//		IBM4899//
+-alias	CSIBM4899//		IBM4899//
+-module	IBM4899//		INTERNAL		IBM4899		1
+-module	INTERNAL		IBM4899//		IBM4899		1
+-
+-#	from			to			module		cost
+-alias	IBM-4909//		IBM4909//
+-alias	CP4909//		IBM4909//
+-alias	CSIBM4909//		IBM4909//
+-module	IBM4909//		INTERNAL		IBM4909		1
+-module	INTERNAL		IBM4909//		IBM4909		1
+-
+-#	from			to			module		cost
+-alias	IBM-4971//		IBM4971//
+-alias	CP4971//		IBM4971//
+-alias	CSIBM4971//		IBM4971//
+-module	IBM4971//		INTERNAL		IBM4971		1
+-module	INTERNAL		IBM4971//		IBM4971		1
+-
+-#	from			to			module		cost
+-alias	IBM-5347//		IBM5347//
+-alias	CP5347//		IBM5347//
+-alias	CSIBM5347//		IBM5347//
+-module	IBM5347//		INTERNAL		IBM5347		1
+-module	INTERNAL		IBM5347//		IBM5347		1
+-
+-#	from			to			module		cost
+-alias	IBM-9030//		IBM9030//
+-alias	CP9030//		IBM9030//
+-alias	CSIBM9030//		IBM9030//
+-module	IBM9030//		INTERNAL		IBM9030		1
+-module	INTERNAL		IBM9030//		IBM9030		1
+-
+-#	from			to			module		cost
+-alias	IBM-9066//		IBM9066//
+-alias	CP9066//		IBM9066//
+-alias	CSIBM9066//		IBM9066//
+-module	IBM9066//		INTERNAL		IBM9066		1
+-module	INTERNAL		IBM9066//		IBM9066		1
+-
+-#	from			to			module		cost
+-alias	IBM-9448//		IBM9448//
+-alias	CP9448//		IBM9448//
+-alias	CSIBM9448//		IBM9448//
+-module	IBM9448//		INTERNAL		IBM9448		1
+-module	INTERNAL		IBM9448//		IBM9448		1
+-
+-#	from			to			module		cost
+-alias	IBM-12712//		IBM12712//
+-alias	CP12712//		IBM12712//
+-alias	CSIBM12712//		IBM12712//
+-module	IBM12712//		INTERNAL		IBM12712		1
+-module	INTERNAL		IBM12712//		IBM12712		1
+-
+-#	from			to			module		cost
+-alias	IBM-16804//		IBM16804//
+-alias	CP16804//		IBM16804//
+-alias	CSIBM16804//		IBM16804//
+-module	IBM16804//		INTERNAL		IBM16804		1
+-module	INTERNAL		IBM16804//		IBM16804		1
+-
+-#	from			to			module		cost
+-alias	IBM-1364//		IBM1364//
+-alias	CP1364//		IBM1364//
+-alias	CSIBM1364//		IBM1364//
+-module	IBM1364//		INTERNAL		IBM1364		1
+-module	INTERNAL		IBM1364//		IBM1364		1
+-
+-#	from			to			module		cost
+-alias	IBM-1371//		IBM1371//
+-alias	CP1371//		IBM1371//
+-alias	CSIBM1371//		IBM1371//
+-module	IBM1371//		INTERNAL		IBM1371		1
+-module	INTERNAL		IBM1371//		IBM1371		1
+-
+-#	from			to			module		cost
+-alias	IBM-1388//		IBM1388//
+-alias	CP1388//		IBM1388//
+-alias	CSIBM1388//		IBM1388//
+-module	IBM1388//		INTERNAL		IBM1388		1
+-module	INTERNAL		IBM1388//		IBM1388		1
+-
+-#	from			to			module		cost
+-alias	IBM-1390//		IBM1390//
+-alias	CP1390//		IBM1390//
+-alias	CSIBM1390//		IBM1390//
+-module	IBM1390//		INTERNAL		IBM1390		1
+-module	INTERNAL		IBM1390//		IBM1390		1
+-
+-#	from			to			module		cost
+-alias	IBM-1399//		IBM1399//
+-alias	CP1399//		IBM1399//
+-alias	CSIBM1399//		IBM1399//
+-module	IBM1399//		INTERNAL		IBM1399		1
+-module	INTERNAL		IBM1399//		IBM1399		1
+-
+-#	from			to			module		cost
+-alias	ISO/TR_11548-1/		ISO_11548-1//
+-alias	ISO11548-1//		ISO_11548-1//
+-module	ISO_11548-1//		INTERNAL		ISO_11548-1	1
+-module	INTERNAL		ISO_11548-1//		ISO_11548-1	1
+-
+-#	from			to			module		cost
+-module	MIK//			INTERNAL		MIK		1
+-module	INTERNAL		MIK//			MIK		1
+-
+-#	from			to			module		cost
+-module	BRF//			INTERNAL		BRF		1
+-module	INTERNAL		BRF//			BRF		1
+-
+-#	from			to			module		cost
+-alias	CP1282//		MAC-CENTRALEUROPE//
+-module	MAC-CENTRALEUROPE//	INTERNAL		MAC-CENTRALEUROPE 1
+-module	INTERNAL		MAC-CENTRALEUROPE//	MAC-CENTRALEUROPE 1
+-
+-#	from			to			module		cost
+-module	KOI8-RU//		INTERNAL		KOI8-RU		1
+-module	INTERNAL		KOI8-RU//		KOI8-RU		1
+-
+-#	from			to			module		cost
+-alias	ISO_8859-9E//		ISO-8859-9E//
+-alias	ISO8859-9E//		ISO-8859-9E//
+-alias	ISO88599E//		ISO-8859-9E//
+-module	ISO-8859-9E//		INTERNAL		ISO8859-9E	1
+-module	INTERNAL		ISO-8859-9E//		ISO8859-9E	1
+-
+-#	from			to			module		cost
+-alias	ROMAN9//		HP-ROMAN9//
+-alias	R9//			HP-ROMAN9//
+-alias	HPROMAN9//		HP-ROMAN9//
+-module	HP-ROMAN9//		INTERNAL		HP-ROMAN9	1
+-module	INTERNAL		HP-ROMAN9//		HP-ROMAN9	1
+-
+-#	from			to			module		cost
+-alias	TURKISH8//		HP-TURKISH8//
+-alias	HPTURKISH8//		HP-TURKISH8//
+-alias	OSF10010006//		HP-TURKISH8//
+-module	HP-TURKISH8//		INTERNAL		HP-TURKISH8	1
+-module	INTERNAL		HP-TURKISH8//		HP-TURKISH8	1
+-
+-#	from			to			module		cost
+-alias	THAI8//			HP-THAI8//
+-alias	HPTHAI8//		HP-THAI8//
+-module	HP-THAI8//		INTERNAL		HP-THAI8	1
+-module	INTERNAL		HP-THAI8//		HP-THAI8	1
+-
+-#	from			to			module		cost
+-alias	HPGREEK8//		HP-GREEK8//
+-alias	OSF10010004//		HP-GREEK8//
+-module	HP-GREEK8//		INTERNAL		HP-GREEK8	1
+-module	INTERNAL		HP-GREEK8//		HP-GREEK8	1
+-
+ alias	ISO-10646-UCS-2//	UNICODE//
+ alias	ISO-10646-UCS-2//	ISO-10646/UTF8/
diff --git a/SOURCES/glibc-rh1971664-6.patch b/SOURCES/glibc-rh1971664-6.patch
new file mode 100644
index 0000000..b0d40a0
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-6.patch
@@ -0,0 +1,137 @@
+commit 06a1b794073c4d6adbfb2e4b11339985a14d7a00
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Mon Jun 14 11:09:56 2021 +0530
+
+    Reinstate gconv-modules as the default configuration file
+    
+    Reinstate gconv-modules as the main file so that the configuration
+    files in gconv-modules.d/ become add-on configuration.  With this, the
+    effective user visible change is that GCONV_PATH can now have
+    supplementary configuration in GCONV_PATH/gconv-modules.d/ in addition
+    to the main GCONV_PATH/gconv-modules file.
+
+# Conflicts:
+#	iconvdata/Makefile
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index d682a98b5c4a8003..95e5fb8f722a513b 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -136,13 +136,12 @@ charmaps = ../localedata/charmaps
+ extra-modules-left := $(modules)
+ include extra-module.mk
+ 
+-gconv-modules = gconv-modules.conf gconv-modules-extra.conf
++gconv-modules = gconv-modules gconv-modules.d/gconv-modules-extra.conf
+ modpfx = $(objpfx)gconv-modules.d/
+ 
+ extra-objs	+= $(modules.so)
+ install-others	= $(addprefix $(inst_gconvdir)/, $(modules.so))	\
+-		  $(addprefix $(inst_gconvdir)/gconv-modules.d/, \
+-			      $(gconv-modules))
++		  $(addprefix $(inst_gconvdir)/, $(gconv-modules))
+ 
+ # We can build the conversion tables for numerous charsets automatically.
+ 
+@@ -184,7 +183,7 @@ generated += $(generated-modules:=.h) $(generated-modules:=.stmp) \
+ 	     iconv-test.out iconv-rules tst-loading.mtrace	 \
+ 	     mtrace-tst-loading.out tst-tables.out iconv-test.xxx
+ ifdef objpfx
+-generated += $(addprefix gconv-modules.d/,$(gconv-modules))
++generated += $(gconv-modules)
+ endif
+ 
+ # Rules to generate the headers.
+@@ -252,8 +251,8 @@ headers: $(addprefix $(objpfx), $(generated-modules:=.h))
+ $(addprefix $(inst_gconvdir)/, $(modules.so)): \
+     $(inst_gconvdir)/%: $(objpfx)% $(+force)
+ 	$(do-install-program)
+-$(addprefix $(inst_gconvdir)/gconv-modules.d/, $(gconv-modules)): \
+-    $(inst_gconvdir)/gconv-modules.d/%: $(modpfx)% $(+force)
++$(addprefix $(inst_gconvdir)/, $(gconv-modules)): \
++    $(inst_gconvdir)/%: $(objpfx)% $(+force)
+ 	$(do-install)
+ ifeq (no,$(cross-compiling))
+ # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
+@@ -301,30 +300,30 @@ $(objpfx)mtrace-tst-loading.out: $(objpfx)tst-loading.out
+ 	$(common-objpfx)malloc/mtrace $(objpfx)tst-loading.mtrace > $@; \
+ 	$(evaluate-test)
+ 
+-$(objpfx)bug-iconv1.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)bug-iconv1.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv2.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)bug-iconv2.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+ $(objpfx)bug-iconv3: $(libdl)
+-$(objpfx)bug-iconv3.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)bug-iconv3.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv5.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)bug-iconv5.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)tst-loading.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)tst-loading.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)tst-iconv4.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)tst-iconv4.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)tst-iconv7.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)tst-iconv7.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv10.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)bug-iconv10.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv12.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)bug-iconv12.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+-$(objpfx)bug-iconv14.out: $(addprefix $(modpfx), $(gconv-modules)) \
++$(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+ 
+ $(objpfx)iconv-test.out: run-iconv-test.sh \
+-			 $(addprefix $(modpfx), $(gconv-modules)) \
++			 $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so)) \
+ 			 $(common-objdir)/iconv/iconv_prog TESTS
+ 	iconv_modules="$(modules)" \
+@@ -333,7 +332,7 @@ $(objpfx)iconv-test.out: run-iconv-test.sh \
+ 	$(evaluate-test)
+ 
+ $(objpfx)tst-tables.out: tst-tables.sh \
+-			 $(addprefix $(modpfx), $(gconv-modules)) \
++			 $(addprefix $(objpfx), $(gconv-modules)) \
+ 			 $(addprefix $(objpfx),$(modules.so)) \
+ 			 $(objpfx)tst-table-from $(objpfx)tst-table-to
+ 	$(SHELL) $< $(common-objpfx) $(common-objpfx)iconvdata/ \
+@@ -351,3 +350,6 @@ $(modpfx):
+ 
+ $(modpfx)%: % $(modpfx)
+ 	cp $< $@
++
++$(objpfx)gconv-modules: gconv-modules
++	cp $^ $@
+diff --git a/iconvdata/gconv-modules.conf b/iconvdata/gconv-modules
+similarity index 100%
+rename from iconvdata/gconv-modules.conf
+rename to iconvdata/gconv-modules
+diff --git a/localedata/Makefile b/localedata/Makefile
+index a5ca7a31f43d50c3..14fcc37fed21e740 100644
+--- a/localedata/Makefile
++++ b/localedata/Makefile
+@@ -179,7 +179,7 @@ install-others := $(addprefix $(inst_i18ndir)/, \
+ 			      $(locales))
+ endif
+ 
+-tests: $(objdir)/iconvdata/gconv-modules.d/gconv-modules.conf
++tests: $(objdir)/iconvdata/gconv-modules
+ 
+ tests-static += tst-langinfo-newlocale-static tst-langinfo-setlocale-static
+ 
+@@ -442,5 +442,5 @@ $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
+ bug-setlocale1-ENV-only = LOCPATH=$(objpfx) LC_CTYPE=de_DE.UTF-8
+ bug-setlocale1-static-ENV-only = $(bug-setlocale1-ENV-only)
+ 
+-$(objdir)/iconvdata/gconv-modules.d/gconv-modules.conf:
++$(objdir)/iconvdata/gconv-modules:
+ 	$(MAKE) -C ../iconvdata subdir=iconvdata $@
diff --git a/SOURCES/glibc-rh1971664-7.patch b/SOURCES/glibc-rh1971664-7.patch
new file mode 100644
index 0000000..f7c4dd8
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-7.patch
@@ -0,0 +1,107 @@
+commit e3217c7fd9e67aa2d53700bb1da9a966e73b9684
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Thu Jun 10 00:41:35 2021 +0530
+
+    iconv: Remove alloca use in gconv-modules configuration parsing
+    
+    The alloca sizes ought to be constrained to PATH_MAX, but replace them
+    with dynamic allocation to be safe.  A static PATH_MAX array would
+    have worked too but Hurd does not have PATH_MAX and the code path is
+    not hot enough to micro-optimise this allocation.  Revisit if any of
+    those realities change.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
+index 8eb981fca7cee36a..3099bf192adce711 100644
+--- a/iconv/gconv_conf.c
++++ b/iconv/gconv_conf.c
+@@ -557,15 +557,15 @@ __gconv_read_conf (void)
+ 
+   for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt)
+     {
+-#define BUF_LEN elem_len + sizeof (gconv_conf_dirname)
+-
+       const char *elem = __gconv_path_elem[cnt].name;
+       size_t elem_len = __gconv_path_elem[cnt].len;
+-      char *buf;
+ 
+       /* No slash needs to be inserted between elem and gconv_conf_filename;
+ 	 elem already ends in a slash.  */
+-      buf = alloca (BUF_LEN);
++      char *buf = malloc (elem_len + sizeof (gconv_conf_dirname));
++      if (buf == NULL)
++	continue;
++
+       char *cp = __mempcpy (__mempcpy (buf, elem, elem_len),
+ 			    gconv_conf_filename, sizeof (gconv_conf_filename));
+ 
+@@ -594,15 +594,16 @@ __gconv_read_conf (void)
+ 	      if (len > strlen (suffix)
+ 		  && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
+ 		{
+-		  /* LEN <= PATH_MAX so this alloca is not unbounded.  */
+-		  char *conf = alloca (BUF_LEN + len + 1);
+-		  cp = stpcpy (conf, buf);
+-		  sprintf (cp, "/%s", ent->d_name);
++		  char *conf;
++		  if (__asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
++		    continue;
+ 		  read_conf_file (conf, elem, elem_len, &modules, &nmodules);
++		  free (conf);
+ 		}
+ 	    }
+ 	  __closedir (confdir);
+ 	}
++      free (buf);
+     }
+ #endif
+ 
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index fafc686ae25fb5c1..2f9d5f45ad3a8159 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -712,7 +712,6 @@ handle_file (const char *dir, const char *infile)
+ static int
+ handle_dir (const char *dir)
+ {
+-#define BUF_LEN prefix_len + dirlen + sizeof "gconv-modules.d"
+   char *cp;
+   size_t dirlen = strlen (dir);
+   bool found = false;
+@@ -726,7 +725,10 @@ handle_dir (const char *dir)
+     }
+ 
+   /* First, look for a gconv-modules file.  */
+-  char buf[BUF_LEN];
++  char *buf = malloc (prefix_len + dirlen + sizeof "gconv-modules.d");
++  if (buf == NULL)
++    goto out;
++
+   cp = buf;
+   if (dir[0] == '/')
+     cp = mempcpy (cp, prefix, prefix_len);
+@@ -756,16 +758,19 @@ handle_dir (const char *dir)
+ 	  if (len > strlen (suffix)
+ 	      && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
+ 	    {
+-	      /* LEN <= PATH_MAX so this alloca is not unbounded.  */
+-	      char *conf = alloca (BUF_LEN + len + 1);
+-	      cp = stpcpy (conf, buf);
+-	      sprintf (cp, "/%s", ent->d_name);
++	      char *conf;
++	      if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
++		continue;
+ 	      found |= handle_file (dir, conf);
++	      free (conf);
+ 	    }
+ 	}
+       closedir (confdir);
+     }
+ 
++  free (buf);
++
++out:
+   if (!found)
+     {
+       error (0, errno, "failed to open gconv configuration files in `%s'",
diff --git a/SOURCES/glibc-rh1971664-8.patch b/SOURCES/glibc-rh1971664-8.patch
new file mode 100644
index 0000000..ec11f7b
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-8.patch
@@ -0,0 +1,113 @@
+commit 23e15ea1ae80ec2120afdf643691359644cf2873
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Thu Jun 10 09:51:50 2021 +0530
+
+    gconv_conf: Remove unused variables
+    
+    The modules and nmodules parameters passed to add_modules, add_alias,
+    etc. are not used and are hence unnecessary.  Remove them so that
+    their signatures match the functions in iconvconfig.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+    Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
+
+diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
+index 3099bf192adce711..dc12ce24844474cc 100644
+--- a/iconv/gconv_conf.c
++++ b/iconv/gconv_conf.c
+@@ -125,7 +125,7 @@ detect_conflict (const char *alias)
+ 
+ /* The actual code to add aliases.  */
+ static void
+-add_alias2 (const char *from, const char *to, const char *wp, void *modules)
++add_alias2 (const char *from, const char *to, const char *wp)
+ {
+   /* Test whether this alias conflicts with any available module.  */
+   if (detect_conflict (from))
+@@ -154,7 +154,7 @@ add_alias2 (const char *from, const char *to, const char *wp, void *modules)
+ 
+ /* Add new alias.  */
+ static void
+-add_alias (char *rp, void *modules)
++add_alias (char *rp)
+ {
+   /* We now expect two more string.  The strings are normalized
+      (converted to UPPER case) and strored in the alias database.  */
+@@ -179,7 +179,7 @@ add_alias (char *rp, void *modules)
+     return;
+   *wp++ = '\0';
+ 
+-  add_alias2 (from, to, wp, modules);
++  add_alias2 (from, to, wp);
+ }
+ 
+ 
+@@ -243,8 +243,7 @@ insert_module (struct gconv_module *newp, int tobefreed)
+ 
+ /* Add new module.  */
+ static void
+-add_module (char *rp, const char *directory, size_t dir_len, void **modules,
+-	    size_t *nmodules, int modcounter)
++add_module (char *rp, const char *directory, size_t dir_len, int modcounter)
+ {
+   /* We expect now
+      1. `from' name
+@@ -357,8 +356,7 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
+ 
+ /* Read the next configuration file.  */
+ static void
+-read_conf_file (const char *filename, const char *directory, size_t dir_len,
+-		void **modules, size_t *nmodules)
++read_conf_file (const char *filename, const char *directory, size_t dir_len)
+ {
+   /* Note the file is opened with cancellation in the I/O functions
+      disabled.  */
+@@ -408,10 +406,10 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
+ 
+       if (rp - word == sizeof ("alias") - 1
+ 	  && memcmp (word, "alias", sizeof ("alias") - 1) == 0)
+-	add_alias (rp, *modules);
++	add_alias (rp);
+       else if (rp - word == sizeof ("module") - 1
+ 	       && memcmp (word, "module", sizeof ("module") - 1) == 0)
+-	add_module (rp, directory, dir_len, modules, nmodules, modcounter++);
++	add_module (rp, directory, dir_len, modcounter++);
+       /* else */
+ 	/* Otherwise ignore the line.  */
+     }
+@@ -537,8 +535,6 @@ void
+ attribute_hidden
+ __gconv_read_conf (void)
+ {
+-  void *modules = NULL;
+-  size_t nmodules = 0;
+   int save_errno = errno;
+   size_t cnt;
+ 
+@@ -570,7 +566,7 @@ __gconv_read_conf (void)
+ 			    gconv_conf_filename, sizeof (gconv_conf_filename));
+ 
+       /* Read the gconv-modules configuration file first.  */
+-      read_conf_file (buf, elem, elem_len, &modules, &nmodules);
++      read_conf_file (buf, elem, elem_len);
+ 
+       /* Next, see if there is a gconv-modules.d directory containing
+ 	 configuration files and if it is non-empty.  */
+@@ -597,7 +593,7 @@ __gconv_read_conf (void)
+ 		  char *conf;
+ 		  if (__asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
+ 		    continue;
+-		  read_conf_file (conf, elem, elem_len, &modules, &nmodules);
++		  read_conf_file (conf, elem, elem_len);
+ 		  free (conf);
+ 		}
+ 	    }
+@@ -631,7 +627,7 @@ __gconv_read_conf (void)
+       const char *to = __rawmemchr (from, '\0') + 1;
+       cp = __rawmemchr (to, '\0') + 1;
+ 
+-      add_alias2 (from, to, cp, modules);
++      add_alias2 (from, to, cp);
+     }
+   while (*cp != '\0');
+ 
diff --git a/SOURCES/glibc-rh1971664-9.patch b/SOURCES/glibc-rh1971664-9.patch
new file mode 100644
index 0000000..c1c1369
--- /dev/null
+++ b/SOURCES/glibc-rh1971664-9.patch
@@ -0,0 +1,360 @@
+commit d8e8097f3be5b3c49fc741fa19e1da0b0431384c
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Thu Jun 10 14:07:27 2021 +0530
+
+    gconv_conf: Split out configuration file processing
+    
+    Split configuration file processing into a separate header file and
+    include it.  Macroize all calls that need to go through internal
+    interfaces so that iconvconfig can also use them.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+# Conflicts:
+#	iconv/gconv_conf.c
+
+diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
+index dc12ce24844474cc..ce64faa928dc1c52 100644
+--- a/iconv/gconv_conf.c
++++ b/iconv/gconv_conf.c
+@@ -19,7 +19,6 @@
+ 
+ #include <assert.h>
+ #include <ctype.h>
+-#include <dirent.h>
+ #include <errno.h>
+ #include <limits.h>
+ #include <locale.h>
+@@ -31,11 +30,10 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/param.h>
+-#include <sys/types.h>
+ 
+ #include <libc-lock.h>
+ #include <gconv_int.h>
+-
++#include <gconv_parseconfdir.h>
+ 
+ /* This is the default path where we look for module lists.  */
+ static const char default_gconv_path[] = GCONV_PATH;
+@@ -49,11 +47,6 @@ size_t __gconv_max_path_elem_len;
+ /* We use the following struct if we couldn't allocate memory.  */
+ static const struct path_elem empty_path_elem = { NULL, 0 };
+ 
+-/* Name of the file containing the module information in the directories
+-   along the path.  */
+-static const char gconv_conf_filename[] = "gconv-modules";
+-static const char gconv_conf_dirname[] = "gconv-modules.d";
+-
+ /* Filename extension for the modules.  */
+ #ifndef MODULE_EXT
+ # define MODULE_EXT ".so"
+@@ -92,9 +85,6 @@ static const char builtin_aliases[] =
+ #undef BUILTIN_ALIAS
+ };
+ 
+-#include <libio/libioP.h>
+-#define __getdelim(line, len, c, fp) _IO_getdelim (line, len, c, fp)
+-
+ 
+ /* Value of the GCONV_PATH environment variable.  */
+ const char *__gconv_path_envvar;
+@@ -354,72 +344,6 @@ add_module (char *rp, const char *directory, size_t dir_len, int modcounter)
+ }
+ 
+ 
+-/* Read the next configuration file.  */
+-static void
+-read_conf_file (const char *filename, const char *directory, size_t dir_len)
+-{
+-  /* Note the file is opened with cancellation in the I/O functions
+-     disabled.  */
+-  FILE *fp = fopen (filename, "rce");
+-  char *line = NULL;
+-  size_t line_len = 0;
+-  static int modcounter;
+-
+-  /* Don't complain if a file is not present or readable, simply silently
+-     ignore it.  */
+-  if (fp == NULL)
+-    return;
+-
+-  /* No threads reading from this stream.  */
+-  __fsetlocking (fp, FSETLOCKING_BYCALLER);
+-
+-  /* Process the known entries of the file.  Comments start with `#' and
+-     end with the end of the line.  Empty lines are ignored.  */
+-  while (!__feof_unlocked (fp))
+-    {
+-      char *rp, *endp, *word;
+-      ssize_t n = __getdelim (&line, &line_len, '\n', fp);
+-      if (n < 0)
+-	/* An error occurred.  */
+-	break;
+-
+-      rp = line;
+-      /* Terminate the line (excluding comments or newline) by an NUL byte
+-	 to simplify the following code.  */
+-      endp = strchr (rp, '#');
+-      if (endp != NULL)
+-	*endp = '\0';
+-      else
+-	if (rp[n - 1] == '\n')
+-	  rp[n - 1] = '\0';
+-
+-      while (__isspace_l (*rp, _nl_C_locobj_ptr))
+-	++rp;
+-
+-      /* If this is an empty line go on with the next one.  */
+-      if (rp == endp)
+-	continue;
+-
+-      word = rp;
+-      while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
+-	++rp;
+-
+-      if (rp - word == sizeof ("alias") - 1
+-	  && memcmp (word, "alias", sizeof ("alias") - 1) == 0)
+-	add_alias (rp);
+-      else if (rp - word == sizeof ("module") - 1
+-	       && memcmp (word, "module", sizeof ("module") - 1) == 0)
+-	add_module (rp, directory, dir_len, modcounter++);
+-      /* else */
+-	/* Otherwise ignore the line.  */
+-    }
+-
+-  free (line);
+-
+-  fclose (fp);
+-}
+-
+-
+ /* Determine the directories we are looking for data in.  */
+ void
+ __gconv_get_path (void)
+@@ -552,55 +476,8 @@ __gconv_read_conf (void)
+     __gconv_get_path ();
+ 
+   for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt)
+-    {
+-      const char *elem = __gconv_path_elem[cnt].name;
+-      size_t elem_len = __gconv_path_elem[cnt].len;
+-
+-      /* No slash needs to be inserted between elem and gconv_conf_filename;
+-	 elem already ends in a slash.  */
+-      char *buf = malloc (elem_len + sizeof (gconv_conf_dirname));
+-      if (buf == NULL)
+-	continue;
+-
+-      char *cp = __mempcpy (__mempcpy (buf, elem, elem_len),
+-			    gconv_conf_filename, sizeof (gconv_conf_filename));
+-
+-      /* Read the gconv-modules configuration file first.  */
+-      read_conf_file (buf, elem, elem_len);
+-
+-      /* Next, see if there is a gconv-modules.d directory containing
+-	 configuration files and if it is non-empty.  */
+-      cp--;
+-      cp[0] = '.';
+-      cp[1] = 'd';
+-      cp[2] = '\0';
+-
+-      DIR *confdir = __opendir (buf);
+-      if (confdir != NULL)
+-	{
+-	  struct dirent *ent;
+-	  while ((ent = __readdir (confdir)) != NULL)
+-	    {
+-	      if (ent->d_type != DT_REG)
+-		continue;
+-
+-	      size_t len = strlen (ent->d_name);
+-	      const char *suffix = ".conf";
+-
+-	      if (len > strlen (suffix)
+-		  && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
+-		{
+-		  char *conf;
+-		  if (__asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
+-		    continue;
+-		  read_conf_file (conf, elem, elem_len);
+-		  free (conf);
+-		}
+-	    }
+-	  __closedir (confdir);
+-	}
+-      free (buf);
+-    }
++    gconv_parseconfdir (__gconv_path_elem[cnt].name,
++			__gconv_path_elem[cnt].len);
+ #endif
+ 
+   /* Add the internal modules.  */
+diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
+new file mode 100644
+index 0000000000000000..3d4d58d4be10a250
+--- /dev/null
++++ b/iconv/gconv_parseconfdir.h
+@@ -0,0 +1,161 @@
++/* Handle configuration data.
++   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 <dirent.h>
++#include <libc-symbols.h>
++#include <locale.h>
++#include <sys/types.h>
++
++#if IS_IN (libc)
++# include <libio/libioP.h>
++# define __getdelim(line, len, c, fp) _IO_getdelim (line, len, c, fp)
++
++# undef isspace
++# define isspace(__c) __isspace_l ((__c), _nl_C_locobj_ptr)
++# define asprintf __asprintf
++# define opendir __opendir
++# define readdir __readdir
++# define closedir __closedir
++# define mempcpy __mempcpy
++#endif
++
++/* Name of the file containing the module information in the directories
++   along the path.  */
++static const char gconv_conf_filename[] = "gconv-modules";
++static const char gconv_conf_dirname[] = "gconv-modules.d";
++
++static void add_alias (char *);
++static void add_module (char *, const char *, size_t, int);
++
++/* Read the next configuration file.  */
++static bool
++read_conf_file (const char *filename, const char *directory, size_t dir_len)
++{
++  /* Note the file is opened with cancellation in the I/O functions
++     disabled.  */
++  FILE *fp = fopen (filename, "rce");
++  char *line = NULL;
++  size_t line_len = 0;
++  static int modcounter;
++
++  /* Don't complain if a file is not present or readable, simply silently
++     ignore it.  */
++  if (fp == NULL)
++    return false;
++
++  /* No threads reading from this stream.  */
++  __fsetlocking (fp, FSETLOCKING_BYCALLER);
++
++  /* Process the known entries of the file.  Comments start with `#' and
++     end with the end of the line.  Empty lines are ignored.  */
++  while (!__feof_unlocked (fp))
++    {
++      char *rp, *endp, *word;
++      ssize_t n = __getdelim (&line, &line_len, '\n', fp);
++      if (n < 0)
++	/* An error occurred.  */
++	break;
++
++      rp = line;
++      /* Terminate the line (excluding comments or newline) by an NUL byte
++	 to simplify the following code.  */
++      endp = strchr (rp, '#');
++      if (endp != NULL)
++	*endp = '\0';
++      else
++	if (rp[n - 1] == '\n')
++	  rp[n - 1] = '\0';
++
++      while (isspace (*rp))
++	++rp;
++
++      /* If this is an empty line go on with the next one.  */
++      if (rp == endp)
++	continue;
++
++      word = rp;
++      while (*rp != '\0' && !isspace (*rp))
++	++rp;
++
++      if (rp - word == sizeof ("alias") - 1
++	  && memcmp (word, "alias", sizeof ("alias") - 1) == 0)
++	add_alias (rp);
++      else if (rp - word == sizeof ("module") - 1
++	       && memcmp (word, "module", sizeof ("module") - 1) == 0)
++	add_module (rp, directory, dir_len, modcounter++);
++      /* else */
++	/* Otherwise ignore the line.  */
++    }
++
++  free (line);
++
++  fclose (fp);
++  return true;
++}
++
++static __always_inline bool
++gconv_parseconfdir (const char *dir, size_t dir_len)
++{
++  /* No slash needs to be inserted between dir and gconv_conf_filename;
++     dir already ends in a slash.  */
++  char *buf = malloc (dir_len + sizeof (gconv_conf_dirname));
++  bool found = false;
++
++  if (buf == NULL)
++    return false;
++
++  char *cp = mempcpy (mempcpy (buf, dir, dir_len), gconv_conf_filename,
++		      sizeof (gconv_conf_filename));
++
++  /* Read the gconv-modules configuration file first.  */
++  found = read_conf_file (buf, dir, dir_len);
++
++  /* Next, see if there is a gconv-modules.d directory containing
++     configuration files and if it is non-empty.  */
++  cp--;
++  cp[0] = '.';
++  cp[1] = 'd';
++  cp[2] = '\0';
++
++  DIR *confdir = opendir (buf);
++  if (confdir != NULL)
++    {
++      struct dirent *ent;
++      while ((ent = readdir (confdir)) != NULL)
++	{
++	  if (ent->d_type != DT_REG)
++	    continue;
++
++	  size_t len = strlen (ent->d_name);
++	  const char *suffix = ".conf";
++
++	  if (len > strlen (suffix)
++	      && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
++	    {
++	      char *conf;
++	      if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
++		continue;
++	      found |= read_conf_file (conf, dir, dir_len);
++	      free (conf);
++	    }
++	}
++      closedir (confdir);
++    }
++  free (buf);
++  return found;
++}
diff --git a/SOURCES/glibc-rh1977614.patch b/SOURCES/glibc-rh1977614.patch
new file mode 100644
index 0000000..078dc68
--- /dev/null
+++ b/SOURCES/glibc-rh1977614.patch
@@ -0,0 +1,33 @@
+commit dfec225ee1972488bb48a8b67a2c4a13010c334a
+Author: JeffyChen <jeffy.chen@rock-chips.com>
+Date:   Fri Jul 2 17:39:24 2021 +0200
+
+    malloc: Initiate tcache shutdown even without allocations [BZ #28028]
+    
+    After commit 1e26d35193efbb29239c710a4c46a64708643320 ("malloc: Fix
+    tcache leak after thread destruction [BZ #22111]"),
+    tcache_shutting_down is still not early enough.  When we detach a
+    thread with no tcache allocated, tcache_shutting_down would still be
+    false.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 00a37f218c0ab3b2..61f7bdc76064c340 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -2960,12 +2960,13 @@ tcache_thread_shutdown (void)
+   int i;
+   tcache_perthread_struct *tcache_tmp = tcache;
+ 
++  tcache_shutting_down = true;
++
+   if (!tcache)
+     return;
+ 
+   /* Disable the tcache and prevent it from being reinitialized.  */
+   tcache = NULL;
+-  tcache_shutting_down = true;
+ 
+   /* Free all of the entries and the tcache itself back to the arena
+      heap for coalescing.  */
diff --git a/SOURCES/glibc-rh1983203-1.patch b/SOURCES/glibc-rh1983203-1.patch
new file mode 100644
index 0000000..07e1431
--- /dev/null
+++ b/SOURCES/glibc-rh1983203-1.patch
@@ -0,0 +1,306 @@
+commit a55e2da2702e235fa0ae66a116d304d1bffc060a
+Author: Lucas A. M. Magalhaes <lamm@linux.ibm.com>
+Date:   Thu May 6 17:01:52 2021 -0300
+
+    powerpc: Optimized memcmp for power10
+    
+    This patch was based on the __memcmp_power8 and the recent
+    __strlen_power10.
+    
+    Improvements from __memcmp_power8:
+    
+    1. Don't need alignment code.
+    
+       On POWER10 lxvp and lxvl do not generate alignment interrupts, so
+    they are safe for use on caching-inhibited memory.  Notice that the
+    comparison on the main loop will wait for both VSR to be ready.
+    Therefore aligning one of the input address does not improve
+    performance.  In order to align both registers a vperm is necessary
+    which add too much overhead.
+    
+    2. Uses new POWER10 instructions
+    
+       This code uses lxvp to decrease contention on load by loading 32 bytes
+    per instruction.
+       The vextractbm is used to have a smaller tail code for calculating the
+    return value.
+    
+    3. Performance improvement
+    
+       This version has around 35% better performance on average. I saw no
+    performance regressions for any length or alignment.
+    
+    Thanks Matheus for helping me out with some details.
+    
+    Co-authored-by: Matheus Castanho <msc@linux.ibm.com>
+    Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/powerpc64/le/power10/memcmp.S b/sysdeps/powerpc/powerpc64/le/power10/memcmp.S
+new file mode 100644
+index 0000000000000000..52f244e7e77cbdf9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/le/power10/memcmp.S
+@@ -0,0 +1,179 @@
++/* Optimized memcmp implementation for POWER10.
++   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 <sysdep.h>
++
++/* TODO: Replace macros by the actual instructions when minimum binutils becomes
++   >= 2.35.  This is used to keep compatibility with older versions.  */
++#define VEXTRACTBM(rt,vrb)	 \
++	.long(((4)<<(32-6))	 \
++	      | ((rt)<<(32-11))  \
++	      | ((8)<<(32-16))	 \
++	      | ((vrb)<<(32-21)) \
++	      | 1602)
++
++#define LXVP(xtp,dq,ra)			   \
++	.long(((6)<<(32-6))		   \
++	      | ((((xtp)-32)>>1)<<(32-10)) \
++	      | ((1)<<(32-11))		   \
++	      | ((ra)<<(32-16))		   \
++	      | dq)
++
++/* Compare 32 bytes.  */
++#define COMPARE_32(vr1,vr2,offset,tail_1,tail_2)\
++	LXVP(32+vr1,offset,r3);		\
++	LXVP(32+vr2,offset,r4);		\
++	vcmpneb.  v5,vr1+1,vr2+1;	\
++	bne	  cr6,L(tail_2);	\
++	vcmpneb.  v4,vr1,vr2;		\
++	bne	  cr6,L(tail_1);	\
++
++#define TAIL(v_res,s1,s2)	\
++	vctzlsbb  r7,v_res;	\
++	vextubrx  r8,r7,s1;	\
++	vextubrx  r9,r7,s2;	\
++	subf	  r3,r9,r8;	\
++	blr;			\
++
++/* int [r3] memcmp (const char *s1 [r3], const char *s2 [r4],
++					size_t size [r5])  */
++
++#ifndef MEMCMP
++# define MEMCMP memcmp
++#endif
++	.machine  power9
++ENTRY_TOCLESS (MEMCMP, 4)
++	CALL_MCOUNT 3
++
++	cmpldi	cr6,r5,64
++	bgt	cr6,L(loop_head)
++
++/* Compare 64 bytes. This section is used for lengths <= 64 and for the last
++   bytes for larger lengths.  */
++L(last_compare):
++	li	r8,16
++
++	sldi	r9,r5,56
++	sldi	r8,r8,56
++	addi	r6,r3,16
++	addi	r7,r4,16
++
++	/* Align up to 16 bytes.  */
++	lxvl	32+v0,r3,r9
++	lxvl	32+v2,r4,r9
++
++	/* The sub. and vcmpneb. results are concatenated by the crnand in order
++	   to do a single branch. It's doing a NOT(CR0.GT AND CR6.EQ) then
++	   loading to CR0.LT.  That means r9 is not bigger than 0 and v4 is not
++	   all equal to 0.  */
++	sub.	  r9,r9,r8
++	vcmpneb.  v4,v0,v2
++	crnand	  4*cr0+lt,4*cr0+gt,4*cr6+eq
++	bt	  4*cr0+lt,L(tail1)
++
++	addi	  r3,r3,32
++	addi	  r4,r4,32
++
++	lxvl	  32+v1,r6,r9
++	lxvl	  32+v3,r7,r9
++	sub.	  r9,r9,r8
++	vcmpneb.  v5,v1,v3
++	crnand	  4*cr0+lt,4*cr0+gt,4*cr6+eq
++	bt	  4*cr0+lt,L(tail2)
++
++	addi	  r6,r3,16
++	addi	  r7,r4,16
++
++	lxvl	  32+v6,r3,r9
++	lxvl	  32+v8,r4,r9
++	sub.	  r9,r9,r8
++	vcmpneb.  v4,v6,v8
++	crnand	  4*cr0+lt,4*cr0+gt,4*cr6+eq
++	bt	  4*cr0+lt,L(tail3)
++
++	lxvl	  32+v7,r6,r9
++	lxvl	  32+v9,r7,r9
++	vcmpneb.  v5,v7,v9
++	bne	  cr6,L(tail4)
++
++L(finish):
++	/* The contents are equal.  */
++	li	r3,0
++	blr
++
++L(loop_head):
++	/* Calculate how many loops to run.  */
++	srdi.	r8,r5,7
++	beq	L(loop_tail)
++	mtctr	r8
++
++/* Main loop.  Compares 128 bytes each loop.  */
++	.p2align 5
++L(loop_128):
++	COMPARE_32(v0,v2,0,tail1,tail2)
++	COMPARE_32(v6,v8,32,tail3,tail4)
++	COMPARE_32(v10,v12,64,tail5,tail6)
++	COMPARE_32(v14,v16,96,tail7,tail8)
++
++	addi	r3,r3,128
++	addi	r4,r4,128
++	bdnz	L(loop_128)
++
++	/* Account loop comparisons.  */
++	clrldi.  r5,r5,57
++	beq	 L(finish)
++
++/* Compares 64 bytes if length is still bigger than 64 bytes.  */
++	.p2align 5
++L(loop_tail):
++	cmpldi	r5,64
++	ble	L(last_compare)
++	COMPARE_32(v0,v2,0,tail1,tail2)
++	COMPARE_32(v6,v8,32,tail3,tail4)
++	addi	r3,r3,64
++	addi	r4,r4,64
++	subi	r5,r5,64
++	b	L(last_compare)
++
++L(tail1):
++	TAIL(v4,v0,v2)
++
++L(tail2):
++	TAIL(v5,v1,v3)
++
++L(tail3):
++	TAIL(v4,v6,v8)
++
++L(tail4):
++	TAIL(v5,v7,v9)
++
++L(tail5):
++	TAIL(v4,v10,v12)
++
++L(tail6):
++	TAIL(v5,v11,v13)
++
++L(tail7):
++	TAIL(v4,v14,v16)
++
++L(tail8):
++	TAIL(v5,v15,v17)
++
++END (MEMCMP)
++libc_hidden_builtin_def (memcmp)
++weak_alias (memcmp, bcmp)
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index ac2446aca62cc4ab..ee98417f4a383356 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -32,7 +32,7 @@ sysdep_routines += memcpy-power8-cached memcpy-power7 memcpy-a2 memcpy-power6 \
+ 		   strncase-power8
+ 
+ ifneq (,$(filter %le,$(config-machine)))
+-sysdep_routines += memcpy-power10 memmove-power10 memset-power10 \
++sysdep_routines += memcmp-power10 memcpy-power10 memmove-power10 memset-power10 \
+ 		   rawmemchr-power9 rawmemchr-power10 \
+ 		   strcmp-power9 strncmp-power9 strcpy-power9 stpcpy-power9 \
+ 		   strlen-power9 strncpy-power9 stpncpy-power9 strlen-power10
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 127af84b32a8196f..5213abdf87c79c88 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -184,6 +184,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c.  */
+   IFUNC_IMPL (i, name, memcmp,
++#ifdef __LITTLE_ENDIAN__
++	      IFUNC_IMPL_ADD (array, i, memcmp,
++            hwcap2 & PPC_FEATURE2_ARCH_3_1
++            && hwcap & PPC_FEATURE_HAS_VSX,
++			      __memcmp_power10)
++#endif
+ 	      IFUNC_IMPL_ADD (array, i, memcmp, hwcap2 & PPC_FEATURE2_ARCH_2_07,
+ 			      __memcmp_power8)
+ 	      IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_HAS_VSX,
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power10.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power10.S
+new file mode 100644
+index 0000000000000000..73a0debd4a811d8e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power10.S
+@@ -0,0 +1,26 @@
++/* Optimized memcmp implementation for POWER10.
++   Copyright (C) 2017-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/>.  */
++
++#define MEMCMP __memcmp_power10
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++#undef weak_alias
++#define weak_alias(name,alias)
++
++#include <sysdeps/powerpc/powerpc64/le/power10/memcmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
+index 2c7a083a6560f920..0b8c0c1d8aa3f90a 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
+@@ -27,11 +27,17 @@ extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
+ extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
+ extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
+ extern __typeof (memcmp) __memcmp_power8 attribute_hidden;
++extern __typeof (memcmp) __memcmp_power10 attribute_hidden;
+ # undef memcmp
+ 
+ /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+    ifunc symbol properly.  */
+ libc_ifunc_redirected (__redirect_memcmp, memcmp,
++#ifdef __LITTLE_ENDIAN__
++				(hwcap2 & PPC_FEATURE2_ARCH_3_1
++				 && hwcap & PPC_FEATURE_HAS_VSX)
++				 ? __memcmp_power10 :
++#endif
+ 		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+ 		       ? __memcmp_power8 :
+ 		       (hwcap & PPC_FEATURE_HAS_VSX)
diff --git a/SOURCES/glibc-rh1983203-2.patch b/SOURCES/glibc-rh1983203-2.patch
new file mode 100644
index 0000000..eb06d39
--- /dev/null
+++ b/SOURCES/glibc-rh1983203-2.patch
@@ -0,0 +1,278 @@
+commit 813c6ec808556553be9d39e900a3fc97ceb32330
+Author: Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
+Date:   Wed Jun 30 12:36:07 2021 -0300
+
+    powerpc: optimize strcpy/stpcpy for POWER9/10
+    
+    This patch modifies the current POWER9 implementation of strcpy and
+    stpcpy to optimize it for POWER9/10.
+    
+    Since no new POWER10 instructions are used, the original POWER9 strcpy is
+    modified instead of creating a new implementation for POWER10.  This
+    implementation is based on both the original POWER9 implementation of
+    strcpy and the preamble of the new POWER10 implementation of strlen.
+    
+    The changes also affect stpcpy, which uses the same implementation with
+    some additional code before returning.
+    
+    On POWER9, averaging improvements across the benchmark
+    inputs (length/source alignment/destination alignment), for an
+    experiment that ran the benchmark five times, bench-strcpy showed an
+    improvement of 5.23%, and bench-stpcpy showed an improvement of 6.59%.
+    
+    On POWER10, bench-strcpy showed 13.16%, and bench-stpcpy showed 13.59%.
+    
+    The changes are:
+    
+    1. Removed the null string optimization.
+    
+       Although this results in a few extra cycles for the null string, in
+       combination with the second change, this resulted in improvements for
+       for other cases.
+    
+    2. Adapted the preamble from strlen for POWER10.
+    
+       This is the part of the function that handles up to the first 16 bytes
+       of the string.
+    
+    3. Increased number of unrolled iterations in the main loop to 6.
+    
+    Reviewed-by: Matheus Castanho <msc@linux.ibm.com>
+    Tested-by: Matheus Castanho <msc@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/powerpc64/le/power9/strcpy.S b/sysdeps/powerpc/powerpc64/le/power9/strcpy.S
+index ce8f50329177fd06..9845a1d4cf0e1e5d 100644
+--- a/sysdeps/powerpc/powerpc64/le/power9/strcpy.S
++++ b/sysdeps/powerpc/powerpc64/le/power9/strcpy.S
+@@ -45,91 +45,78 @@
+    The implementation can load bytes past a null terminator, but only
+    up to the next 16B boundary, so it never crosses a page.  */
+ 
++/* Load quadword at addr+offset to vreg, check for null bytes,
++   and branch to label if any are found.  */
++#define CHECK16(vreg,offset,addr,label) \
++	lxv	vreg+32,offset(addr);	\
++	vcmpequb. v6,vreg,v18;	\
++	bne	cr6,L(label);
++
+ .machine power9
+ ENTRY_TOCLESS (FUNC_NAME, 4)
+ 	CALL_MCOUNT 2
+ 
+-	/* NULL string optimisation  */
+-	lbz	r0,0(r4)
+-	stb	r0,0(r3)
+-	cmpwi	r0,0
+-	beqlr
+-
+-	addi	r4,r4,1
+-	addi	r11,r3,1
+-
+ 	vspltisb v18,0		/* Zeroes in v18  */
++	vspltisb v19,-1 	/* 0xFF bytes in v19  */
+ 
+-	neg	r5,r4
+-	rldicl	r9,r5,0,60	/* How many bytes to get source 16B aligned?  */
++	/* Next 16B-aligned address. Prepare address for L(loop).  */
++	addi	r5,r4,16
++	clrrdi	r5,r5,4
++	subf	r8,r4,r5
++	add	r11,r3,r8
+ 
+-	/* Get source 16B aligned  */
++	/* Align data and fill bytes not loaded with non matching char.  */
+ 	lvx	v0,0,r4
+ 	lvsr	v1,0,r4
+-	vperm	v0,v18,v0,v1
+-
+-	vcmpequb v6,v0,v18	/* 0xff if byte is NULL, 0x00 otherwise  */
+-	vctzlsbb r7,v6		/* Number of trailing zeroes  */
+-	addi	r8,r7,1		/* Add null terminator  */
++	vperm	v0,v19,v0,v1
+ 
+-	/* r8 = bytes including null
+-	   r9 = bytes to get source 16B aligned
+-	   if r8 > r9
+-	      no null, copy r9 bytes
+-	   else
+-	      there is a null, copy r8 bytes and return.  */
+-	cmpd	r8,r9
+-	bgt	L(no_null)
++	vcmpequb. v6,v0,v18	/* 0xff if byte is NULL, 0x00 otherwise  */
++	beq	cr6,L(no_null)
+ 
+-	sldi	r10,r8,56	/* stxvl wants size in top 8 bits  */
+-	stxvl	32+v0,r11,r10	/* Partial store  */
++	/* There's a null byte.  */
++	vctzlsbb r8,v6		/* Number of trailing zeroes  */
++	addi	r9,r8,1 	/* Add null byte.  */
++	sldi	r10,r9,56	/* stxvl wants size in top 8 bits.  */
++	stxvl	32+v0,r3,r10	/* Partial store  */
+ 
+ #ifdef USE_AS_STPCPY
+ 	/* stpcpy returns the dest address plus the size not counting the
+ 	   final '\0'.  */
+-	add	r3,r11,r7
++	add	r3,r3,r8
+ #endif
+ 	blr
+ 
+ L(no_null):
+-	sldi	r10,r9,56	/* stxvl wants size in top 8 bits  */
+-	stxvl	32+v0,r11,r10	/* Partial store  */
+-
+-	add	r4,r4,r9
+-	add	r11,r11,r9
++	sldi	r10,r8,56	/* stxvl wants size in top 8 bits  */
++	stxvl	32+v0,r3,r10	/* Partial store  */
+ 
++	.p2align 4
+ L(loop):
+-	lxv	32+v0,0(r4)
+-	vcmpequb. v6,v0,v18	/* Any zero bytes?  */
+-	bne	cr6,L(tail1)
+-
+-	lxv	32+v1,16(r4)
+-	vcmpequb. v6,v1,v18	/* Any zero bytes?  */
+-	bne	cr6,L(tail2)
+-
+-	lxv	32+v2,32(r4)
+-	vcmpequb. v6,v2,v18	/* Any zero bytes?  */
+-	bne	cr6,L(tail3)
+-
+-	lxv	32+v3,48(r4)
+-	vcmpequb. v6,v3,v18	/* Any zero bytes?  */
+-	bne	cr6,L(tail4)
++	CHECK16(v0,0,r5,tail1)
++	CHECK16(v1,16,r5,tail2)
++	CHECK16(v2,32,r5,tail3)
++	CHECK16(v3,48,r5,tail4)
++	CHECK16(v4,64,r5,tail5)
++	CHECK16(v5,80,r5,tail6)
+ 
+ 	stxv	32+v0,0(r11)
+ 	stxv	32+v1,16(r11)
+ 	stxv	32+v2,32(r11)
+ 	stxv	32+v3,48(r11)
++	stxv	32+v4,64(r11)
++	stxv	32+v5,80(r11)
+ 
+-	addi	r4,r4,64
+-	addi	r11,r11,64
++	addi	r5,r5,96
++	addi	r11,r11,96
+ 
+ 	b	L(loop)
+ 
++	.p2align 4
+ L(tail1):
+-	vctzlsbb r8,v6
+-	addi	r9,r8,1
++	vctzlsbb r8,v6		/* Number of trailing zeroes  */
++	addi	r9,r8,1		/* Add null terminator  */
+ 	sldi	r9,r9,56	/* stxvl wants size in top 8 bits  */
+-	stxvl	32+v0,r11,r9
++	stxvl	32+v0,r11,r9	/* Partial store  */
+ #ifdef USE_AS_STPCPY
+ 	/* stpcpy returns the dest address plus the size not counting the
+ 	   final '\0'.  */
+@@ -137,50 +124,81 @@ L(tail1):
+ #endif
+ 	blr
+ 
++	.p2align 4
+ L(tail2):
+ 	stxv	32+v0,0(r11)
+-	vctzlsbb r8,v6		/* Number of trailing zeroes  */
+-	addi	r9,r8,1		/* Add null terminator  */
+-	sldi	r10,r9,56	/* stxvl wants size in top 8 bits  */
++	vctzlsbb r8,v6
++	addi	r9,r8,1
++	sldi	r9,r9,56
+ 	addi	r11,r11,16
+-	stxvl	32+v1,r11,r10	/* Partial store  */
++	stxvl	32+v1,r11,r9
+ #ifdef USE_AS_STPCPY
+-	/* stpcpy returns the dest address plus the size not counting the
+-	   final '\0'.  */
+ 	add	r3,r11,r8
+ #endif
+ 	blr
+ 
++	.p2align 4
+ L(tail3):
+ 	stxv	32+v0,0(r11)
+ 	stxv	32+v1,16(r11)
+-	vctzlsbb r8,v6		/* Number of trailing zeroes  */
+-	addi	r9,r8,1		/* Add null terminator  */
+-	sldi	r10,r9,56	/* stxvl wants size in top 8 bits  */
++	vctzlsbb r8,v6
++	addi	r9,r8,1
++	sldi	r9,r9,56
+ 	addi	r11,r11,32
+-	stxvl	32+v2,r11,r10	/* Partial store  */
++	stxvl	32+v2,r11,r9
+ #ifdef USE_AS_STPCPY
+-	/* stpcpy returns the dest address plus the size not counting the
+-	   final '\0'.  */
+ 	add	r3,r11,r8
+ #endif
+ 	blr
+ 
++	.p2align 4
+ L(tail4):
+ 	stxv	32+v0,0(r11)
+ 	stxv	32+v1,16(r11)
+ 	stxv	32+v2,32(r11)
+-	vctzlsbb r8,v6		/* Number of trailing zeroes  */
+-	addi	r9,r8,1		/* Add null terminator  */
+-	sldi	r10,r9,56	/* stxvl wants size in top 8 bits  */
++	vctzlsbb r8,v6
++	addi	r9,r8,1
++	sldi	r9,r9,56
+ 	addi	r11,r11,48
+-	stxvl	32+v3,r11,r10	/* Partial store  */
++	stxvl	32+v3,r11,r9
+ #ifdef USE_AS_STPCPY
+-	/* stpcpy returns the dest address plus the size not counting the
+-	   final '\0'.  */
+ 	add	r3,r11,r8
+ #endif
+ 	blr
++
++	.p2align 4
++L(tail5):
++	stxv	32+v0,0(r11)
++	stxv	32+v1,16(r11)
++	stxv	32+v2,32(r11)
++	stxv	32+v3,48(r11)
++	vctzlsbb r8,v6
++	addi	r9,r8,1
++	sldi	r9,r9,56
++	addi	r11,r11,64
++	stxvl	32+v4,r11,r9
++#ifdef USE_AS_STPCPY
++	add	r3,r11,r8
++#endif
++	blr
++
++	.p2align 4
++L(tail6):
++	stxv	32+v0,0(r11)
++	stxv	32+v1,16(r11)
++	stxv	32+v2,32(r11)
++	stxv	32+v3,48(r11)
++	stxv	32+v4,64(r11)
++	vctzlsbb r8,v6
++	addi	r9,r8,1
++	sldi	r9,r9,56
++	addi	r11,r11,80
++	stxvl	32+v5,r11,r9
++#ifdef USE_AS_STPCPY
++	add	r3,r11,r8
++#endif
++	blr
++
+ END (FUNC_NAME)
+ #ifndef USE_AS_STPCPY
+ libc_hidden_builtin_def (strcpy)
diff --git a/SOURCES/glibc-rh1984802-1.patch b/SOURCES/glibc-rh1984802-1.patch
new file mode 100644
index 0000000..47fcc60
--- /dev/null
+++ b/SOURCES/glibc-rh1984802-1.patch
@@ -0,0 +1,50 @@
+From 756c306502498f999fdd494477b9cea1b45e4faf Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Fri, 21 Aug 2020 11:23:17 +0200
+Subject: [PATCH] S390: Sync HWCAP names with kernel by adding aliases [BZ
+ #25971]
+
+Unfortunately some HWCAP names like HWCAP_S390_VX differs between
+kernel (see <kernel>/arch/s390/include/asm/elf.h) and glibc.
+
+Therefore, those HWCAP names from kernel are now introduced as alias
+---
+ sysdeps/s390/dl-procinfo.h                | 3 +++
+ sysdeps/unix/sysv/linux/s390/bits/hwcap.h | 3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
+index 0db4bc39c7..08eee109f7 100644
+--- a/sysdeps/s390/dl-procinfo.h
++++ b/sysdeps/s390/dl-procinfo.h
+@@ -51,8 +51,11 @@ enum
+   HWCAP_S390_HIGH_GPRS = 1 << 9,
+   HWCAP_S390_TE = 1 << 10,
+   HWCAP_S390_VX = 1 << 11,
++  HWCAP_S390_VXRS = HWCAP_S390_VX,
+   HWCAP_S390_VXD = 1 << 12,
++  HWCAP_S390_VXRS_BCD = HWCAP_S390_VXD,
+   HWCAP_S390_VXE = 1 << 13,
++  HWCAP_S390_VXRS_EXT = HWCAP_S390_VXE,
+   HWCAP_S390_GS = 1 << 14,
+   HWCAP_S390_VXRS_EXT2 = 1 << 15,
+   HWCAP_S390_VXRS_PDE = 1 << 16,
+diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+index 6adbec018b..f2998ff131 100644
+--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+@@ -36,8 +36,11 @@
+ #define HWCAP_S390_HIGH_GPRS    512
+ #define HWCAP_S390_TE           1024
+ #define HWCAP_S390_VX           2048
++#define HWCAP_S390_VXRS         HWCAP_S390_VX
+ #define HWCAP_S390_VXD          4096
++#define HWCAP_S390_VXRS_BCD     HWCAP_S390_VXD
+ #define HWCAP_S390_VXE          8192
++#define HWCAP_S390_VXRS_EXT     HWCAP_S390_VXE
+ #define HWCAP_S390_GS           16384
+ #define HWCAP_S390_VXRS_EXT2    32768
+ #define HWCAP_S390_VXRS_PDE     65536
+-- 
+2.31.1
+
diff --git a/SOURCES/glibc-rh1984802-2.patch b/SOURCES/glibc-rh1984802-2.patch
new file mode 100644
index 0000000..4d7d4b5
--- /dev/null
+++ b/SOURCES/glibc-rh1984802-2.patch
@@ -0,0 +1,67 @@
+From 25251c0707fe34f30a27381a5fabc35435a96621 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Tue, 16 Feb 2021 16:18:56 +0100
+Subject: [PATCH] S390: Add new hwcap values.
+
+The new hwcap values indicate support for arch14 architecture.
+---
+ sysdeps/s390/dl-procinfo.c                | 5 +++--
+ sysdeps/s390/dl-procinfo.h                | 4 +++-
+ sysdeps/unix/sysv/linux/s390/bits/hwcap.h | 2 ++
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
+index 0c334a2551..c174e27b35 100644
+--- a/sysdeps/s390/dl-procinfo.c
++++ b/sysdeps/s390/dl-procinfo.c
+@@ -46,12 +46,13 @@
+ #if !defined PROCINFO_DECL && defined SHARED
+   ._dl_s390_cap_flags
+ #else
+-PROCINFO_CLASS const char _dl_s390_cap_flags[19][9]
++PROCINFO_CLASS const char _dl_s390_cap_flags[21][9]
+ #endif
+ #ifndef PROCINFO_DECL
+ = {
+      "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh",
+-     "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt"
++     "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt",
++     "vxp2", "nnpa"
+   }
+ #endif
+ #if !defined SHARED || defined PROCINFO_DECL
+diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
+index 9e1a8c7ba9..2d9c305808 100644
+--- a/sysdeps/s390/dl-procinfo.h
++++ b/sysdeps/s390/dl-procinfo.h
+@@ -21,7 +21,7 @@
+ #define _DL_PROCINFO_H	1
+ #include <ldsodefs.h>
+ 
+-#define _DL_HWCAP_COUNT 19
++#define _DL_HWCAP_COUNT 21
+ 
+ #define _DL_PLATFORMS_COUNT	10
+ 
+@@ -61,6 +61,8 @@ enum
+   HWCAP_S390_VXRS_PDE = 1 << 16,
+   HWCAP_S390_SORT = 1 << 17,
+   HWCAP_S390_DFLT = 1 << 18,
++  HWCAP_S390_VXRS_PDE2 = 1 << 19,
++  HWCAP_S390_NNPA = 1 << 20,
+ };
+ 
+ #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
+diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+index 696616e779..e9bd3684db 100644
+--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+@@ -46,3 +46,5 @@
+ #define HWCAP_S390_VXRS_PDE     65536
+ #define HWCAP_S390_SORT         131072
+ #define HWCAP_S390_DFLT         262144
++#define HWCAP_S390_VXRS_PDE2    524288
++#define HWCAP_S390_NNPA         1048576
+-- 
+2.31.1
+
diff --git a/SOURCES/glibc-rh1984802-3.patch b/SOURCES/glibc-rh1984802-3.patch
new file mode 100644
index 0000000..c0412b4
--- /dev/null
+++ b/SOURCES/glibc-rh1984802-3.patch
@@ -0,0 +1,88 @@
+From f2e06656d04a9fcb0603802a4f8ce7aa3a1f055e Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Tue, 5 Oct 2021 16:14:10 +0200
+Subject: [PATCH] S390: Add PCI_MIO and SIE HWCAPs
+
+Both new HWCAPs were introduced in these kernel commits:
+- 7e8403ecaf884f307b627f3c371475913dd29292
+  "s390: add HWCAP_S390_PCI_MIO to ELF hwcaps"
+- 7e82523f2583e9813e4109df3656707162541297
+  "s390/hwcaps: make sie capability regular hwcap"
+
+Also note that the kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e
+"s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros
+from "HWCAP_S390_" to "HWCAP_".  For compatibility reasons, we do not
+change the prefix in public glibc header file.
+---
+ sysdeps/s390/dl-procinfo.c                | 4 ++--
+ sysdeps/s390/dl-procinfo.h                | 4 +++-
+ sysdeps/unix/sysv/linux/s390/bits/hwcap.h | 7 +++++++
+ 3 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
+index 7314c31b15..97be34fe9d 100644
+--- a/sysdeps/s390/dl-procinfo.c
++++ b/sysdeps/s390/dl-procinfo.c
+@@ -45,13 +45,13 @@
+ #if !defined PROCINFO_DECL && defined SHARED
+   ._dl_s390_cap_flags
+ #else
+-PROCINFO_CLASS const char _dl_s390_cap_flags[21][9]
++PROCINFO_CLASS const char _dl_s390_cap_flags[23][9]
+ #endif
+ #ifndef PROCINFO_DECL
+ = {
+      "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh",
+      "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt",
+-     "vxp2", "nnpa"
++     "vxp2", "nnpa", "pcimio", "sie"
+   }
+ #endif
+ #if !defined SHARED || defined PROCINFO_DECL
+diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
+index 2502dd2604..d9a3b264ff 100644
+--- a/sysdeps/s390/dl-procinfo.h
++++ b/sysdeps/s390/dl-procinfo.h
+@@ -20,7 +20,7 @@
+ #define _DL_PROCINFO_H	1
+ #include <ldsodefs.h>
+ 
+-#define _DL_HWCAP_COUNT 21
++#define _DL_HWCAP_COUNT 23
+ 
+ #define _DL_PLATFORMS_COUNT	10
+ 
+@@ -62,6 +62,8 @@ enum
+   HWCAP_S390_DFLT = 1 << 18,
+   HWCAP_S390_VXRS_PDE2 = 1 << 19,
+   HWCAP_S390_NNPA = 1 << 20,
++  HWCAP_S390_PCI_MIO = 1 << 21,
++  HWCAP_S390_SIE = 1 << 22,
+ };
+ 
+ #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
+diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+index e9bd3684db..00e73a3e3b 100644
+--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+@@ -22,6 +22,11 @@
+ 
+ /*
+  * The following must match the kernels asm/elf.h.
++ * Note: The kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e
++ * "s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros
++ * from "HWCAP_S390_" to "HWCAP_".  For compatibility reasons, we do not
++ * change the prefix in public glibc header file.
++ *
+  * Note that these are *not* the same as the STORE FACILITY LIST bits.
+  */
+ #define HWCAP_S390_ESAN3        1
+@@ -48,3 +53,5 @@
+ #define HWCAP_S390_DFLT         262144
+ #define HWCAP_S390_VXRS_PDE2    524288
+ #define HWCAP_S390_NNPA         1048576
++#define HWCAP_S390_PCI_MIO      2097152
++#define HWCAP_S390_SIE          4194304
+-- 
+2.31.1
+
diff --git a/SOURCES/glibc-rh1991001-1.patch b/SOURCES/glibc-rh1991001-1.patch
new file mode 100644
index 0000000..6d09fa0
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-1.patch
@@ -0,0 +1,30 @@
+commit ad78d702757a189b1fa552d607e8aaa22252a45f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue May 12 19:06:18 2020 +0200
+
+    elf: Remove redundant add_to_global_resize_failure  call from dl_open_args
+    
+    The second call does not do anything because the data structures have
+    already been resized by the call that comes before the demarcation
+    point.  Fixes commit a509eb117fac1d764b15eba64993f4bdb63d7f3c
+    ("Avoid late dlopen failure due to scope, TLS slotinfo updates
+    [BZ #25112]").
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index 3d49a84596e99bf6..b052bb0bc2cd17aa 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -769,11 +769,6 @@ dl_open_worker (void *a)
+   DL_STATIC_INIT (new);
+ #endif
+ 
+-  /* Perform the necessary allocations for adding new global objects
+-     to the global scope below, via add_to_global_update.  */
+-  if (mode & RTLD_GLOBAL)
+-    add_to_global_resize (new);
+-
+   /* Run the initializer functions of new objects.  Temporarily
+      disable the exception handler, so that lazy binding failures are
+      fatal.  */
diff --git a/SOURCES/glibc-rh1991001-10.patch b/SOURCES/glibc-rh1991001-10.patch
new file mode 100644
index 0000000..7263cc7
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-10.patch
@@ -0,0 +1,23 @@
+commit 52290d8c04569615fb011ee286d52dc5147afbd7
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Apr 15 09:57:10 2021 +0100
+
+    elf: Fix missing include in test case [BZ #27136]
+    
+    Broken test was introduced in
+    
+      commit 8f85075a2e9c26ff7486d4bbaf358999807d215c
+      elf: Add a DTV setup test [BZ #27136]
+
+diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c
+index ac5f8c8d39b66dd6..9977ec803208b9c8 100644
+--- a/elf/tst-tls20.c
++++ b/elf/tst-tls20.c
+@@ -21,6 +21,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <support/check.h>
++#include <support/support.h>
+ #include <support/xdlfcn.h>
+ #include <support/xthread.h>
+ 
diff --git a/SOURCES/glibc-rh1991001-11.patch b/SOURCES/glibc-rh1991001-11.patch
new file mode 100644
index 0000000..a704d26
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-11.patch
@@ -0,0 +1,160 @@
+commit 2208066603a136f95cfb815ca9281262e6465784
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Feb 11 13:24:47 2021 +0000
+
+    elf: Remove lazy tlsdesc relocation related code
+    
+    Remove generic tlsdesc code related to lazy tlsdesc processing since
+    lazy tlsdesc relocation is no longer supported.  This includes removing
+    GL(dl_load_lock) from _dl_make_tlsdesc_dynamic which is only called at
+    load time when that lock is already held.
+    
+    Added a documentation comment too.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/tlsdeschtab.h b/elf/tlsdeschtab.h
+index fea9eefe72edcd6b..c20857e5b4264f00 100644
+--- a/elf/tlsdeschtab.h
++++ b/elf/tlsdeschtab.h
+@@ -78,6 +78,10 @@ map_generation (struct link_map *map)
+   return GL(dl_tls_generation) + 1;
+ }
+ 
++/* Returns the data pointer for a given map and tls offset that is used
++   to fill in one of the GOT entries referenced by a TLSDESC relocation
++   when using dynamic TLS.  This requires allocation, returns NULL on
++   allocation failure.  */
+ void *
+ _dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset)
+ {
+@@ -85,18 +89,12 @@ _dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset)
+   void **entry;
+   struct tlsdesc_dynamic_arg *td, test;
+ 
+-  /* FIXME: We could use a per-map lock here, but is it worth it?  */
+-  __rtld_lock_lock_recursive (GL(dl_load_lock));
+-
+   ht = map->l_mach.tlsdesc_table;
+   if (! ht)
+     {
+       ht = htab_create ();
+       if (! ht)
+-	{
+-	  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-	  return 0;
+-	}
++	return 0;
+       map->l_mach.tlsdesc_table = ht;
+     }
+ 
+@@ -104,15 +102,11 @@ _dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset)
+   test.tlsinfo.ti_offset = ti_offset;
+   entry = htab_find_slot (ht, &test, 1, hash_tlsdesc, eq_tlsdesc);
+   if (! entry)
+-    {
+-      __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-      return 0;
+-    }
++    return 0;
+ 
+   if (*entry)
+     {
+       td = *entry;
+-      __rtld_lock_unlock_recursive (GL(dl_load_lock));
+       return td;
+     }
+ 
+@@ -122,44 +116,9 @@ _dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset)
+      thread.  */
+   td->gen_count = map_generation (map);
+   td->tlsinfo = test.tlsinfo;
+-
+-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+   return td;
+ }
+ 
+ # endif /* SHARED */
+ 
+-/* The idea of the following two functions is to stop multiple threads
+-   from attempting to resolve the same TLS descriptor without busy
+-   waiting.  Ideally, we should be able to release the lock right
+-   after changing td->entry, and then using say a condition variable
+-   or a futex wake to wake up any waiting threads, but let's try to
+-   avoid introducing such dependencies.  */
+-
+-static int
+-__attribute__ ((unused))
+-_dl_tlsdesc_resolve_early_return_p (struct tlsdesc volatile *td, void *caller)
+-{
+-  if (caller != atomic_load_relaxed (&td->entry))
+-    return 1;
+-
+-  __rtld_lock_lock_recursive (GL(dl_load_lock));
+-  if (caller != atomic_load_relaxed (&td->entry))
+-    {
+-      __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-      return 1;
+-    }
+-
+-  atomic_store_relaxed (&td->entry, _dl_tlsdesc_resolve_hold);
+-
+-  return 0;
+-}
+-
+-static void
+-__attribute__ ((unused))
+-_dl_tlsdesc_wake_up_held_fixups (void)
+-{
+-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-}
+-
+ #endif
+diff --git a/sysdeps/aarch64/tlsdesc.c b/sysdeps/aarch64/tlsdesc.c
+index 357465f23d76e2bd..1ead73ab8250e29c 100644
+--- a/sysdeps/aarch64/tlsdesc.c
++++ b/sysdeps/aarch64/tlsdesc.c
+@@ -22,7 +22,6 @@
+ #include <tls.h>
+ #include <dl-tlsdesc.h>
+ #include <dl-unmap-segments.h>
+-#define _dl_tlsdesc_resolve_hold 0
+ #include <tlsdeschtab.h>
+ 
+ /* Unmap the dynamic object, but also release its TLS descriptor table
+diff --git a/sysdeps/arm/tlsdesc.c b/sysdeps/arm/tlsdesc.c
+index d142d7a2c91e9adb..b78e3f65785bf587 100644
+--- a/sysdeps/arm/tlsdesc.c
++++ b/sysdeps/arm/tlsdesc.c
+@@ -20,7 +20,6 @@
+ #include <tls.h>
+ #include <dl-tlsdesc.h>
+ #include <dl-unmap-segments.h>
+-#define _dl_tlsdesc_resolve_hold 0
+ #include <tlsdeschtab.h>
+ 
+ /* Unmap the dynamic object, but also release its TLS descriptor table
+diff --git a/sysdeps/i386/tlsdesc.c b/sysdeps/i386/tlsdesc.c
+index 1b4227c8381e1b3d..c242ffce726d50e4 100644
+--- a/sysdeps/i386/tlsdesc.c
++++ b/sysdeps/i386/tlsdesc.c
+@@ -20,7 +20,6 @@
+ #include <tls.h>
+ #include <dl-tlsdesc.h>
+ #include <dl-unmap-segments.h>
+-#define _dl_tlsdesc_resolve_hold 0
+ #include <tlsdeschtab.h>
+ 
+ /* Unmap the dynamic object, but also release its TLS descriptor table
+diff --git a/sysdeps/x86_64/tlsdesc.c b/sysdeps/x86_64/tlsdesc.c
+index 61a19ae26944c84f..a9325827d0e5e31b 100644
+--- a/sysdeps/x86_64/tlsdesc.c
++++ b/sysdeps/x86_64/tlsdesc.c
+@@ -20,7 +20,6 @@
+ #include <tls.h>
+ #include <dl-tlsdesc.h>
+ #include <dl-unmap-segments.h>
+-#define _dl_tlsdesc_resolve_hold 0
+ #include <tlsdeschtab.h>
+ 
+ /* Unmap the dynamic object, but also release its TLS descriptor table
diff --git a/SOURCES/glibc-rh1991001-12.patch b/SOURCES/glibc-rh1991001-12.patch
new file mode 100644
index 0000000..67f9bab
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-12.patch
@@ -0,0 +1,182 @@
+commit 1387ad6225c2222f027790e3f460e31aa5dd2c54
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Dec 30 19:19:37 2020 +0000
+
+    elf: Fix data races in pthread_create and TLS access [BZ #19329]
+    
+    DTV setup at thread creation (_dl_allocate_tls_init) is changed
+    to take the dlopen lock, GL(dl_load_lock).  Avoiding data races
+    here without locks would require design changes: the map that is
+    accessed for static TLS initialization here may be concurrently
+    freed by dlclose.  That use after free may be solved by only
+    locking around static TLS setup or by ensuring dlclose does not
+    free modules with static TLS, however currently every link map
+    with TLS has to be accessed at least to see if it needs static
+    TLS.  And even if that's solved, still a lot of atomics would be
+    needed to synchronize DTV related globals without a lock. So fix
+    both bug 19329 and bug 27111 with a lock that prevents DTV setup
+    running concurrently with dlopen or dlclose.
+    
+    _dl_update_slotinfo at TLS access still does not use any locks
+    so CONCURRENCY NOTES are added to explain the synchronization.
+    The early exit from the slotinfo walk when max_modid is reached
+    is not strictly necessary, but does not hurt either.
+    
+    An incorrect acquire load was removed from _dl_resize_dtv: it
+    did not synchronize with any release store or fence and
+    synchronization is now handled separately at thread creation
+    and TLS access time.
+    
+    There are still a number of racy read accesses to globals that
+    will be changed to relaxed MO atomics in a followup patch. This
+    should not introduce regressions compared to existing behaviour
+    and avoid cluttering the main part of the fix.
+    
+    Not all TLS access related data races got fixed here: there are
+    additional races at lazy tlsdesc relocations see bug 27137.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 15ed01d795a8627a..da83cd6ae2ee6504 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -471,14 +471,11 @@ extern dtv_t _dl_static_dtv[];
+ #endif
+ 
+ static dtv_t *
+-_dl_resize_dtv (dtv_t *dtv)
++_dl_resize_dtv (dtv_t *dtv, size_t max_modid)
+ {
+   /* Resize the dtv.  */
+   dtv_t *newp;
+-  /* Load GL(dl_tls_max_dtv_idx) atomically since it may be written to by
+-     other threads concurrently.  */
+-  size_t newsize
+-    = atomic_load_acquire (&GL(dl_tls_max_dtv_idx)) + DTV_SURPLUS;
++  size_t newsize = max_modid + DTV_SURPLUS;
+   size_t oldsize = dtv[-1].counter;
+ 
+   if (dtv == GL(dl_initial_dtv))
+@@ -524,11 +521,14 @@ _dl_allocate_tls_init (void *result)
+   size_t total = 0;
+   size_t maxgen = 0;
+ 
++  /* Protects global dynamic TLS related state.  */
++  __rtld_lock_lock_recursive (GL(dl_load_lock));
++
+   /* Check if the current dtv is big enough.   */
+   if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
+     {
+       /* Resize the dtv.  */
+-      dtv = _dl_resize_dtv (dtv);
++      dtv = _dl_resize_dtv (dtv, GL(dl_tls_max_dtv_idx));
+ 
+       /* Install this new dtv in the thread data structures.  */
+       INSTALL_DTV (result, &dtv[-1]);
+@@ -596,6 +596,7 @@ _dl_allocate_tls_init (void *result)
+       listp = listp->next;
+       assert (listp != NULL);
+     }
++  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+ 
+   /* The DTV version is up-to-date now.  */
+   dtv[0].counter = maxgen;
+@@ -730,12 +731,29 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 
+   if (dtv[0].counter < listp->slotinfo[idx].gen)
+     {
+-      /* The generation counter for the slot is higher than what the
+-	 current dtv implements.  We have to update the whole dtv but
+-	 only those entries with a generation counter <= the one for
+-	 the entry we need.  */
++      /* CONCURRENCY NOTES:
++
++	 Here the dtv needs to be updated to new_gen generation count.
++
++	 This code may be called during TLS access when GL(dl_load_lock)
++	 is not held.  In that case the user code has to synchronize with
++	 dlopen and dlclose calls of relevant modules.  A module m is
++	 relevant if the generation of m <= new_gen and dlclose of m is
++	 synchronized: a memory access here happens after the dlopen and
++	 before the dlclose of relevant modules.  The dtv entries for
++	 relevant modules need to be updated, other entries can be
++	 arbitrary.
++
++	 This e.g. means that the first part of the slotinfo list can be
++	 accessed race free, but the tail may be concurrently extended.
++	 Similarly relevant slotinfo entries can be read race free, but
++	 other entries are racy.  However updating a non-relevant dtv
++	 entry does not affect correctness.  For a relevant module m,
++	 max_modid >= modid of m.  */
+       size_t new_gen = listp->slotinfo[idx].gen;
+       size_t total = 0;
++      size_t max_modid  = atomic_load_relaxed (&GL(dl_tls_max_dtv_idx));
++      assert (max_modid >= req_modid);
+ 
+       /* We have to look through the entire dtv slotinfo list.  */
+       listp =  GL(dl_tls_dtv_slotinfo_list);
+@@ -745,12 +763,14 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 	    {
+ 	      size_t modid = total + cnt;
+ 
++	      /* Later entries are not relevant.  */
++	      if (modid > max_modid)
++		break;
++
+ 	      size_t gen = listp->slotinfo[cnt].gen;
+ 
+ 	      if (gen > new_gen)
+-		/* This is a slot for a generation younger than the
+-		   one we are handling now.  It might be incompletely
+-		   set up so ignore it.  */
++		/* Not relevant.  */
+ 		continue;
+ 
+ 	      /* If the entry is older than the current dtv layout we
+@@ -767,7 +787,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 		    continue;
+ 
+ 		  /* Resize the dtv.  */
+-		  dtv = _dl_resize_dtv (dtv);
++		  dtv = _dl_resize_dtv (dtv, max_modid);
+ 
+ 		  assert (modid <= dtv[-1].counter);
+ 
+@@ -789,8 +809,17 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 	    }
+ 
+ 	  total += listp->len;
++	  if (total > max_modid)
++	    break;
++
++	  /* Synchronize with _dl_add_to_slotinfo.  Ideally this would
++	     be consume MO since we only need to order the accesses to
++	     the next node after the read of the address and on most
++	     hardware (other than alpha) a normal load would do that
++	     because of the address dependency.  */
++	  listp = atomic_load_acquire (&listp->next);
+ 	}
+-      while ((listp = listp->next) != NULL);
++      while (listp != NULL);
+ 
+       /* This will be the new maximum generation counter.  */
+       dtv[0].counter = new_gen;
+@@ -982,7 +1011,7 @@ _dl_add_to_slotinfo (struct link_map *l, bool do_add)
+ 	 the first slot.  */
+       assert (idx == 0);
+ 
+-      listp = prevp->next = (struct dtv_slotinfo_list *)
++      listp = (struct dtv_slotinfo_list *)
+ 	malloc (sizeof (struct dtv_slotinfo_list)
+ 		+ TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
+       if (listp == NULL)
+@@ -996,6 +1025,8 @@ cannot create TLS data structures"));
+       listp->next = NULL;
+       memset (listp->slotinfo, '\0',
+ 	      TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
++      /* Synchronize with _dl_update_slotinfo.  */
++      atomic_store_release (&prevp->next, listp);
+     }
+ 
+   /* Add the information into the slotinfo data structure.  */
diff --git a/SOURCES/glibc-rh1991001-13.patch b/SOURCES/glibc-rh1991001-13.patch
new file mode 100644
index 0000000..524eb3c
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-13.patch
@@ -0,0 +1,193 @@
+commit f4f8f4d4e0f92488431b268c8cd9555730b9afe9
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Dec 30 19:19:37 2020 +0000
+
+    elf: Use relaxed atomics for racy accesses [BZ #19329]
+    
+    This is a follow up patch to the fix for bug 19329.  This adds relaxed
+    MO atomics to accesses that were previously data races but are now
+    race conditions, and where relaxed MO is sufficient.
+    
+    The race conditions all follow the pattern that the write is behind the
+    dlopen lock, but a read can happen concurrently (e.g. during tls access)
+    without holding the lock.  For slotinfo entries the read value only
+    matters if it reads from a synchronized write in dlopen or dlclose,
+    otherwise the related dtv entry is not valid to access so it is fine
+    to leave it in an inconsistent state.  The same applies for
+    GL(dl_tls_max_dtv_idx) and GL(dl_tls_generation), but there the
+    algorithm relies on the fact that the read of the last synchronized
+    write is an increasing value.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index 1ece0ae1dd062d1e..7d2dc2272cd643f5 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -79,9 +79,10 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
+ 	{
+ 	  assert (old_map->l_tls_modid == idx);
+ 
+-	  /* Mark the entry as unused. */
+-	  listp->slotinfo[idx - disp].gen = GL(dl_tls_generation) + 1;
+-	  listp->slotinfo[idx - disp].map = NULL;
++	  /* Mark the entry as unused.  These can be read concurrently.  */
++	  atomic_store_relaxed (&listp->slotinfo[idx - disp].gen,
++				GL(dl_tls_generation) + 1);
++	  atomic_store_relaxed (&listp->slotinfo[idx - disp].map, NULL);
+ 	}
+ 
+       /* If this is not the last currently used entry no need to look
+@@ -96,8 +97,8 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
+ 
+       if (listp->slotinfo[idx - disp].map != NULL)
+ 	{
+-	  /* Found a new last used index.  */
+-	  GL(dl_tls_max_dtv_idx) = idx;
++	  /* Found a new last used index.  This can be read concurrently.  */
++	  atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), idx);
+ 	  return true;
+ 	}
+     }
+@@ -571,7 +572,9 @@ _dl_close_worker (struct link_map *map, bool force)
+ 					GL(dl_tls_dtv_slotinfo_list), 0,
+ 					imap->l_init_called))
+ 		/* All dynamically loaded modules with TLS are unloaded.  */
+-		GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
++		/* Can be read concurrently.  */
++		atomic_store_relaxed (&GL(dl_tls_max_dtv_idx),
++				      GL(dl_tls_static_nelem));
+ 
+ 	      if (imap->l_tls_offset != NO_TLS_OFFSET
+ 		  && imap->l_tls_offset != FORCED_DYNAMIC_TLS_OFFSET)
+@@ -769,8 +772,11 @@ _dl_close_worker (struct link_map *map, bool force)
+   /* If we removed any object which uses TLS bump the generation counter.  */
+   if (any_tls)
+     {
+-      if (__glibc_unlikely (++GL(dl_tls_generation) == 0))
++      size_t newgen = GL(dl_tls_generation) + 1;
++      if (__glibc_unlikely (newgen == 0))
+ 	_dl_fatal_printf ("TLS generation counter wrapped!  Please report as described in "REPORT_BUGS_TO".\n");
++      /* Can be read concurrently.  */
++      atomic_store_relaxed (&GL(dl_tls_generation), newgen);
+ 
+       if (tls_free_end == GL(dl_tls_static_used))
+ 	GL(dl_tls_static_used) = tls_free_start;
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index b052bb0bc2cd17aa..a67fb3aee40860e1 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -395,9 +395,12 @@ update_tls_slotinfo (struct link_map *new)
+ 	}
+     }
+ 
+-  if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
++  size_t newgen = GL(dl_tls_generation) + 1;
++  if (__glibc_unlikely (newgen == 0))
+     _dl_fatal_printf (N_("\
+ TLS generation counter wrapped!  Please report this."));
++  /* Can be read concurrently.  */
++  atomic_store_relaxed (&GL(dl_tls_generation), newgen);
+ 
+   /* We need a second pass for static tls data, because
+      _dl_update_slotinfo must not be run while calls to
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index da83cd6ae2ee6504..801eafad3961573c 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -175,7 +175,9 @@ _dl_next_tls_modid (void)
+       /* No gaps, allocate a new entry.  */
+     nogaps:
+ 
+-      result = ++GL(dl_tls_max_dtv_idx);
++      result = GL(dl_tls_max_dtv_idx) + 1;
++      /* Can be read concurrently.  */
++      atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), result);
+     }
+ 
+   return result;
+@@ -359,10 +361,12 @@ allocate_dtv (void *result)
+   dtv_t *dtv;
+   size_t dtv_length;
+ 
++  /* Relaxed MO, because the dtv size is later rechecked, not relied on.  */
++  size_t max_modid = atomic_load_relaxed (&GL(dl_tls_max_dtv_idx));
+   /* We allocate a few more elements in the dtv than are needed for the
+      initial set of modules.  This should avoid in most cases expansions
+      of the dtv.  */
+-  dtv_length = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
++  dtv_length = max_modid + DTV_SURPLUS;
+   dtv = calloc (dtv_length + 2, sizeof (dtv_t));
+   if (dtv != NULL)
+     {
+@@ -767,7 +771,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 	      if (modid > max_modid)
+ 		break;
+ 
+-	      size_t gen = listp->slotinfo[cnt].gen;
++	      size_t gen = atomic_load_relaxed (&listp->slotinfo[cnt].gen);
+ 
+ 	      if (gen > new_gen)
+ 		/* Not relevant.  */
+@@ -779,7 +783,8 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 		continue;
+ 
+ 	      /* If there is no map this means the entry is empty.  */
+-	      struct link_map *map = listp->slotinfo[cnt].map;
++	      struct link_map *map
++		= atomic_load_relaxed (&listp->slotinfo[cnt].map);
+ 	      /* Check whether the current dtv array is large enough.  */
+ 	      if (dtv[-1].counter < modid)
+ 		{
+@@ -923,7 +928,12 @@ __tls_get_addr (GET_ADDR_ARGS)
+ {
+   dtv_t *dtv = THREAD_DTV ();
+ 
+-  if (__glibc_unlikely (dtv[0].counter != GL(dl_tls_generation)))
++  /* Update is needed if dtv[0].counter < the generation of the accessed
++     module.  The global generation counter is used here as it is easier
++     to check.  Synchronization for the relaxed MO access is guaranteed
++     by user code, see CONCURRENCY NOTES in _dl_update_slotinfo.  */
++  size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
++  if (__glibc_unlikely (dtv[0].counter != gen))
+     return update_get_addr (GET_ADDR_PARAM);
+ 
+   void *p = dtv[GET_ADDR_MODULE].pointer.val;
+@@ -946,7 +956,10 @@ _dl_tls_get_addr_soft (struct link_map *l)
+     return NULL;
+ 
+   dtv_t *dtv = THREAD_DTV ();
+-  if (__glibc_unlikely (dtv[0].counter != GL(dl_tls_generation)))
++  /* This may be called without holding the GL(dl_load_lock).  Reading
++     arbitrary gen value is fine since this is best effort code.  */
++  size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
++  if (__glibc_unlikely (dtv[0].counter != gen))
+     {
+       /* This thread's DTV is not completely current,
+ 	 but it might already cover this module.  */
+@@ -1032,7 +1045,9 @@ cannot create TLS data structures"));
+   /* Add the information into the slotinfo data structure.  */
+   if (do_add)
+     {
+-      listp->slotinfo[idx].map = l;
+-      listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
++      /* Can be read concurrently.  See _dl_update_slotinfo.  */
++      atomic_store_relaxed (&listp->slotinfo[idx].map, l);
++      atomic_store_relaxed (&listp->slotinfo[idx].gen,
++			    GL(dl_tls_generation) + 1);
+     }
+ }
+diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c
+index 533ee2b3a6e85ad8..bc543dcc264ea361 100644
+--- a/sysdeps/x86_64/dl-tls.c
++++ b/sysdeps/x86_64/dl-tls.c
+@@ -40,7 +40,8 @@ __tls_get_addr_slow (GET_ADDR_ARGS)
+ {
+   dtv_t *dtv = THREAD_DTV ();
+ 
+-  if (__glibc_unlikely (dtv[0].counter != GL(dl_tls_generation)))
++  size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
++  if (__glibc_unlikely (dtv[0].counter != gen))
+     return update_get_addr (GET_ADDR_PARAM);
+ 
+   return tls_get_addr_tail (GET_ADDR_PARAM, dtv, NULL);
diff --git a/SOURCES/glibc-rh1991001-14.patch b/SOURCES/glibc-rh1991001-14.patch
new file mode 100644
index 0000000..3467532
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-14.patch
@@ -0,0 +1,133 @@
+commit 9d0e30329c23b5ad736fda3f174208c25970dbce
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Tue Dec 13 12:28:41 2016 +0000
+
+    elf: Add test case for [BZ #19329]
+    
+    Test concurrent dlopen and pthread_create when the loaded modules have
+    TLS.  This triggers dl-tls assertion failures more reliably than the
+    nptl/tst-stack4 test.
+    
+    The dlopened module has 100 DT_NEEDED dependencies with TLS, they were
+    reused from an existing TLS test. The number of created threads during
+    dlopen depends on filesystem speed and hardware, but at most 3 threads
+    are alive at a time to limit resource usage.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+Conflicts:
+	elf/Makefile
+	  (usual testing differences)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 0995d810b57d0dda..be40e3761cf91c4a 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -210,7 +210,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 tst-tls-ie tst-tls-ie-dlmopen \
+ 	 argv0test \
+ 	 tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
+-	 tst-tls20
++	 tst-tls20 tst-tls21
+ #	 reldep9
+ tests-internal += loadtest unload unload2 circleload1 \
+ 	 neededtest neededtest2 neededtest3 neededtest4 \
+@@ -333,7 +333,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		libmarkermod2-1 libmarkermod2-2 \
+ 		libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \
+ 		libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
+-		tst-tls20mod-bad
++		tst-tls20mod-bad tst-tls21mod \
+ 
+ # Most modules build with _ISOMAC defined, but those filtered out
+ # depend on internal headers.
+@@ -1836,3 +1836,8 @@ tst-tls20mod-bad.so-no-z-defs = yes
+ $(objpfx)tst-tls20: $(libdl) $(shared-thread-library)
+ $(objpfx)tst-tls20.out: $(objpfx)tst-tls20mod-bad.so \
+ 			$(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
++
++# Reuses tst-tls-many-dynamic-modules
++$(objpfx)tst-tls21: $(libdl) $(shared-thread-library)
++$(objpfx)tst-tls21.out: $(objpfx)tst-tls21mod.so
++$(objpfx)tst-tls21mod.so: $(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
+diff --git a/elf/tst-tls21.c b/elf/tst-tls21.c
+new file mode 100644
+index 0000000000000000..560bf5813a746417
+--- /dev/null
++++ b/elf/tst-tls21.c
+@@ -0,0 +1,68 @@
++/* Test concurrent dlopen and pthread_create: BZ 19329.
++   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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <dlfcn.h>
++#include <pthread.h>
++#include <stdio.h>
++#include <stdatomic.h>
++#include <support/xdlfcn.h>
++#include <support/xthread.h>
++
++#define THREADS 10000
++
++static atomic_int done;
++
++static void *
++start (void *a)
++{
++  /* Load a module with many dependencies that each have TLS.  */
++  xdlopen ("tst-tls21mod.so", RTLD_LAZY);
++  atomic_store_explicit (&done, 1, memory_order_release);
++  return 0;
++}
++
++static void *
++nop (void *a)
++{
++  return 0;
++}
++
++static int
++do_test (void)
++{
++  pthread_t t1, t2;
++  int i;
++
++  /* Load a module with lots of dependencies and TLS.  */
++  t1 = xpthread_create (0, start, 0);
++
++  /* Concurrently create lots of threads until dlopen is observably done.  */
++  for (i = 0; i < THREADS; i++)
++    {
++      if (atomic_load_explicit (&done, memory_order_acquire) != 0)
++	break;
++      t2 = xpthread_create (0, nop, 0);
++      xpthread_join (t2);
++    }
++
++  xpthread_join (t1);
++  printf ("threads created during dlopen: %d\n", i);
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-tls21mod.c b/elf/tst-tls21mod.c
+new file mode 100644
+index 0000000000000000..206ece4fb34622a9
+--- /dev/null
++++ b/elf/tst-tls21mod.c
+@@ -0,0 +1 @@
++int __thread x;
diff --git a/SOURCES/glibc-rh1991001-15.patch b/SOURCES/glibc-rh1991001-15.patch
new file mode 100644
index 0000000..553ecfb
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-15.patch
@@ -0,0 +1,81 @@
+commit 572bd547d57a39b6cf0ea072545dc4048921f4c3
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Dec 31 13:59:38 2020 +0000
+
+    elf: Fix DTV gap reuse logic [BZ #27135]
+    
+    For some reason only dlopen failure caused dtv gaps to be reused.
+    
+    It is possible that the intent was to never reuse modids for a
+    different module, but after dlopen failure all gaps are reused
+    not just the ones caused by the unfinished dlopened.
+    
+    So the code has to handle reused modids already which seems to
+    work, however the data races at thread creation and tls access
+    (see bug 19329 and bug 27111) may be more severe if slots are
+    reused so this is scheduled after those fixes. I think fixing
+    the races are not simpler if reuse is disallowed and reuse has
+    other benefits, so set GL(dl_tls_dtv_gaps) whenever entries are
+    removed from the middle of the slotinfo list. The value does
+    not have to be correct: incorrect true value causes the next
+    modid query to do a slotinfo walk, incorrect false will leave
+    gaps and new entries are added at the end.
+    
+    Fixes bug 27135.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index 7d2dc2272cd643f5..41cb6c58491c364b 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -88,7 +88,11 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
+       /* If this is not the last currently used entry no need to look
+ 	 further.  */
+       if (idx != GL(dl_tls_max_dtv_idx))
+-	return true;
++	{
++	  /* There is an unused dtv entry in the middle.  */
++	  GL(dl_tls_dtv_gaps) = true;
++	  return true;
++	}
+     }
+ 
+   while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0))
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index a67fb3aee40860e1..54727402750f4c0c 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -896,16 +896,6 @@ no more namespaces available for dlmopen()"));
+ 	 state if relocation failed, for example.  */
+       if (args.map)
+ 	{
+-	  /* Maybe some of the modules which were loaded use TLS.
+-	     Since it will be removed in the following _dl_close call
+-	     we have to mark the dtv array as having gaps to fill the
+-	     holes.  This is a pessimistic assumption which won't hurt
+-	     if not true.  There is no need to do this when we are
+-	     loading the auditing DSOs since TLS has not yet been set
+-	     up.  */
+-	  if ((mode & __RTLD_AUDIT) == 0)
+-	    GL(dl_tls_dtv_gaps) = true;
+-
+ 	  _dl_close_worker (args.map, true);
+ 
+ 	  /* All l_nodelete_pending objects should have been deleted
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 801eafad3961573c..bacb4101e2e2c4e5 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -187,10 +187,7 @@ _dl_next_tls_modid (void)
+ size_t
+ _dl_count_modids (void)
+ {
+-  /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where
+-     we fail to load a module and unload it leaving a gap.  If we don't
+-     have gaps then the number of modids is the current maximum so
+-     return that.  */
++  /* The count is the max unless dlclose or failed dlopen created gaps.  */
+   if (__glibc_likely (!GL(dl_tls_dtv_gaps)))
+     return GL(dl_tls_max_dtv_idx);
+ 
diff --git a/SOURCES/glibc-rh1991001-16.patch b/SOURCES/glibc-rh1991001-16.patch
new file mode 100644
index 0000000..d1902a7
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-16.patch
@@ -0,0 +1,71 @@
+commit 40ebfd016ad284872f434bdd76dbe9c708db4d6b
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Jun 25 08:09:08 2021 +0200
+
+    elf: Disable most of TLS modid gaps processing [BZ #27135]
+    
+    Revert "elf: Fix DTV gap reuse logic [BZ #27135]"
+    
+    This reverts commit 572bd547d57a39b6cf0ea072545dc4048921f4c3.
+    
+    It turns out that the _dl_next_tls_modid in _dl_map_object_from_fd keeps
+    returning the same modid over and over again if there is a gap and
+    more than TLS-using module is loaded in one dlopen call.  This corrupts
+    TLS data structures.  The bug is still present after a revert, but
+    empirically it is much more difficult to trigger (because it involves a
+    dlopen failure).
+
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index 41cb6c58491c364b..7d2dc2272cd643f5 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -88,11 +88,7 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
+       /* If this is not the last currently used entry no need to look
+ 	 further.  */
+       if (idx != GL(dl_tls_max_dtv_idx))
+-	{
+-	  /* There is an unused dtv entry in the middle.  */
+-	  GL(dl_tls_dtv_gaps) = true;
+-	  return true;
+-	}
++	return true;
+     }
+ 
+   while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0))
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index 54727402750f4c0c..a67fb3aee40860e1 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -896,6 +896,16 @@ no more namespaces available for dlmopen()"));
+ 	 state if relocation failed, for example.  */
+       if (args.map)
+ 	{
++	  /* Maybe some of the modules which were loaded use TLS.
++	     Since it will be removed in the following _dl_close call
++	     we have to mark the dtv array as having gaps to fill the
++	     holes.  This is a pessimistic assumption which won't hurt
++	     if not true.  There is no need to do this when we are
++	     loading the auditing DSOs since TLS has not yet been set
++	     up.  */
++	  if ((mode & __RTLD_AUDIT) == 0)
++	    GL(dl_tls_dtv_gaps) = true;
++
+ 	  _dl_close_worker (args.map, true);
+ 
+ 	  /* All l_nodelete_pending objects should have been deleted
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index bacb4101e2e2c4e5..801eafad3961573c 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -187,7 +187,10 @@ _dl_next_tls_modid (void)
+ size_t
+ _dl_count_modids (void)
+ {
+-  /* The count is the max unless dlclose or failed dlopen created gaps.  */
++  /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where
++     we fail to load a module and unload it leaving a gap.  If we don't
++     have gaps then the number of modids is the current maximum so
++     return that.  */
+   if (__glibc_likely (!GL(dl_tls_dtv_gaps)))
+     return GL(dl_tls_max_dtv_idx);
+ 
diff --git a/SOURCES/glibc-rh1991001-17.patch b/SOURCES/glibc-rh1991001-17.patch
new file mode 100644
index 0000000..cb1a041
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-17.patch
@@ -0,0 +1,585 @@
+commit ba33937be210da5d07f7f01709323743f66011ce
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Jun 25 10:54:12 2021 -0300
+
+    elf: Fix DTV gap reuse logic (BZ #27135)
+    
+    This is updated version of the 572bd547d57a (reverted by 40ebfd016ad2)
+    that fixes the _dl_next_tls_modid issues.
+    
+    This issue with 572bd547d57a patch is the DTV entry will be only
+    update on dl_open_worker() with the update_tls_slotinfo() call after
+    all dependencies are being processed by _dl_map_object_deps().  However
+    _dl_map_object_deps() itself might call _dl_next_tls_modid(), and since
+    the _dl_tls_dtv_slotinfo_list::map is not yet set the entry will be
+    wrongly reused.
+    
+    This patch fixes by renaming the _dl_next_tls_modid() function to
+    _dl_assign_tls_modid() and by passing the link_map so it can set
+    the slotinfo value so a subsequente _dl_next_tls_modid() call will
+    see the entry as allocated.
+    
+    The intermediary value is cleared up on remove_slotinfo() for the case
+    a library fails to load with RTLD_NOW.
+    
+    This patch fixes BZ #27135.
+    
+    Checked on x86_64-linux-gnu.
+    
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+Conflicts:
+	elf/Makefile
+	  (testing differences; libdl removal upstream)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index be40e3761cf91c4a..3e71939d3234c4c3 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -242,6 +242,13 @@ one-hundred = $(foreach x,0 1 2 3 4 5 6 7 8 9, \
+   0$x 1$x 2$x 3$x 4$x 5$x 6$x 7$x 8$x 9$x)
+ tst-tls-many-dynamic-modules := \
+   $(foreach n,$(one-hundred),tst-tls-manydynamic$(n)mod)
++tst-tls-many-dynamic-modules-dep-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 \
++					    14 15 16 17 18 19
++tst-tls-many-dynamic-modules-dep = \
++  $(foreach n,$(tst-tls-many-dynamic-modules-dep-suffixes),tst-tls-manydynamic$(n)mod-dep)
++tst-tls-many-dynamic-modules-dep-bad-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
++tst-tls-many-dynamic-modules-dep-bad = \
++  $(foreach n,$(tst-tls-many-dynamic-modules-dep-bad-suffixes),tst-tls-manydynamic$(n)mod-dep-bad)
+ extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \
+ 		   tst-tlsalign-vars.o
+ test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars
+@@ -314,6 +321,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
+ 		tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
+ 		tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
++		$(tst-tls-many-dynamic-modules-dep) \
++		$(tst-tls-many-dynamic-modules-dep-bad) \
+ 		tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
+ 		tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \
+ 		tst-absolute-zero-lib tst-big-note-lib \
+@@ -1832,10 +1841,63 @@ $(objpfx)tst-rtld-help.out: $(objpfx)ld.so
+ 	$(evaluate-test)
+ 
+ # Reuses tst-tls-many-dynamic-modules
++$(patsubst %,$(objpfx)%.os,$(tst-tls-many-dynamic-modules-dep)): \
++  $(objpfx)tst-tls-manydynamic%mod-dep.os : tst-tls-manydynamicmod.c
++	$(compile-command.c) \
++	  -DNAME=tls_global_$* -DSETTER=set_value_$* -DGETTER=get_value_$*
++$(patsubst %,$(objpfx)%.os,$(tst-tls-many-dynamic-modules-dep-bad)): \
++  $(objpfx)tst-tls-manydynamic%mod-dep-bad.os : tst-tls-manydynamicmod.c
++	$(compile-command.c) \
++	  -DNAME=tls_global_$* -DSETTER=set_value_$* -DGETTER=get_value_$*
+ tst-tls20mod-bad.so-no-z-defs = yes
++# Single dependency.
++$(objpfx)tst-tls-manydynamic0mod-dep.so: $(objpfx)tst-tls-manydynamic1mod-dep.so
++# Double dependencies.
++$(objpfx)tst-tls-manydynamic2mod-dep.so: $(objpfx)tst-tls-manydynamic3mod-dep.so \
++					 $(objpfx)tst-tls-manydynamic4mod-dep.so
++# Double dependencies with each dependency depent of another module.
++$(objpfx)tst-tls-manydynamic5mod-dep.so: $(objpfx)tst-tls-manydynamic6mod-dep.so \
++					 $(objpfx)tst-tls-manydynamic7mod-dep.so
++$(objpfx)tst-tls-manydynamic6mod-dep.so: $(objpfx)tst-tls-manydynamic8mod-dep.so
++$(objpfx)tst-tls-manydynamic7mod-dep.so: $(objpfx)tst-tls-manydynamic8mod-dep.so
++# Long chain with one double dependency in the middle
++$(objpfx)tst-tls-manydynamic9mod-dep.so: $(objpfx)tst-tls-manydynamic10mod-dep.so \
++					 $(objpfx)tst-tls-manydynamic11mod-dep.so
++$(objpfx)tst-tls-manydynamic10mod-dep.so: $(objpfx)tst-tls-manydynamic12mod-dep.so
++$(objpfx)tst-tls-manydynamic12mod-dep.so: $(objpfx)tst-tls-manydynamic13mod-dep.so
++# Long chain with two double depedencies in the middle
++$(objpfx)tst-tls-manydynamic14mod-dep.so: $(objpfx)tst-tls-manydynamic15mod-dep.so
++$(objpfx)tst-tls-manydynamic15mod-dep.so: $(objpfx)tst-tls-manydynamic16mod-dep.so \
++					  $(objpfx)tst-tls-manydynamic17mod-dep.so
++$(objpfx)tst-tls-manydynamic16mod-dep.so: $(objpfx)tst-tls-manydynamic18mod-dep.so \
++					  $(objpfx)tst-tls-manydynamic19mod-dep.so
++# Same but with an invalid module.
++# Single dependency.
++$(objpfx)tst-tls-manydynamic0mod-dep-bad.so: $(objpfx)tst-tls20mod-bad.so
++# Double dependencies.
++$(objpfx)tst-tls-manydynamic1mod-dep-bad.so: $(objpfx)tst-tls-manydynamic2mod-dep-bad.so \
++					     $(objpfx)tst-tls20mod-bad.so
++# Double dependencies with each dependency depent of another module.
++$(objpfx)tst-tls-manydynamic3mod-dep-bad.so: $(objpfx)tst-tls-manydynamic4mod-dep-bad.so \
++					     $(objpfx)tst-tls-manydynamic5mod-dep-bad.so
++$(objpfx)tst-tls-manydynamic4mod-dep-bad.so: $(objpfx)tst-tls20mod-bad.so
++$(objpfx)tst-tls-manydynamic5mod-dep-bad.so: $(objpfx)tst-tls20mod-bad.so
++# Long chain with one double dependency in the middle
++$(objpfx)tst-tls-manydynamic6mod-dep-bad.so: $(objpfx)tst-tls-manydynamic7mod-dep-bad.so \
++					     $(objpfx)tst-tls-manydynamic8mod-dep-bad.so
++$(objpfx)tst-tls-manydynamic7mod-dep-bad.so: $(objpfx)tst-tls-manydynamic9mod-dep-bad.so
++$(objpfx)tst-tls-manydynamic9mod-dep-bad.so: $(objpfx)tst-tls20mod-bad.so
++# Long chain with two double depedencies in the middle
++$(objpfx)tst-tls-manydynamic10mod-dep-bad.so: $(objpfx)tst-tls-manydynamic11mod-dep-bad.so
++$(objpfx)tst-tls-manydynamic11mod-dep-bad.so: $(objpfx)tst-tls-manydynamic12mod-dep-bad.so \
++					      $(objpfx)tst-tls-manydynamic13mod-dep-bad.so
++$(objpfx)tst-tls-manydynamic12mod-dep-bad.so: $(objpfx)tst-tls-manydynamic14mod-dep-bad.so \
++					      $(objpfx)tst-tls20mod-bad.so
+ $(objpfx)tst-tls20: $(libdl) $(shared-thread-library)
+ $(objpfx)tst-tls20.out: $(objpfx)tst-tls20mod-bad.so \
+-			$(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
++			$(tst-tls-many-dynamic-modules:%=$(objpfx)%.so) \
++			$(tst-tls-many-dynamic-modules-dep:%=$(objpfx)%.so) \
++			$(tst-tls-many-dynamic-modules-dep-bad:%=$(objpfx)%.so) \
+ 
+ # Reuses tst-tls-many-dynamic-modules
+ $(objpfx)tst-tls21: $(libdl) $(shared-thread-library)
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index 7d2dc2272cd643f5..18227fe992029364 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -77,8 +77,6 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
+ 	 object that wasn't fully set up.  */
+       if (__glibc_likely (old_map != NULL))
+ 	{
+-	  assert (old_map->l_tls_modid == idx);
+-
+ 	  /* Mark the entry as unused.  These can be read concurrently.  */
+ 	  atomic_store_relaxed (&listp->slotinfo[idx - disp].gen,
+ 				GL(dl_tls_generation) + 1);
+@@ -88,7 +86,11 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
+       /* If this is not the last currently used entry no need to look
+ 	 further.  */
+       if (idx != GL(dl_tls_max_dtv_idx))
+-	return true;
++	{
++	  /* There is an unused dtv entry in the middle.  */
++	  GL(dl_tls_dtv_gaps) = true;
++	  return true;
++	}
+     }
+ 
+   while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0))
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 80fc38041a936c3c..cdb5d4b5b67f1ca1 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1419,7 +1419,7 @@ cannot enable executable stack as shared object requires");
+ 	     not set up TLS data structures, so don't use them now.  */
+ 	  || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL)))
+     /* Assign the next available module ID.  */
+-    l->l_tls_modid = _dl_next_tls_modid ();
++    _dl_assign_tls_modid (l);
+ 
+ #ifdef DL_AFTER_LOAD
+   DL_AFTER_LOAD (l);
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index a67fb3aee40860e1..54727402750f4c0c 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -896,16 +896,6 @@ no more namespaces available for dlmopen()"));
+ 	 state if relocation failed, for example.  */
+       if (args.map)
+ 	{
+-	  /* Maybe some of the modules which were loaded use TLS.
+-	     Since it will be removed in the following _dl_close call
+-	     we have to mark the dtv array as having gaps to fill the
+-	     holes.  This is a pessimistic assumption which won't hurt
+-	     if not true.  There is no need to do this when we are
+-	     loading the auditing DSOs since TLS has not yet been set
+-	     up.  */
+-	  if ((mode & __RTLD_AUDIT) == 0)
+-	    GL(dl_tls_dtv_gaps) = true;
+-
+ 	  _dl_close_worker (args.map, true);
+ 
+ 	  /* All l_nodelete_pending objects should have been deleted
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 801eafad3961573c..8c0f9e972d7a0eac 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -122,8 +122,8 @@ oom (void)
+ }
+ 
+ 
+-size_t
+-_dl_next_tls_modid (void)
++void
++_dl_assign_tls_modid (struct link_map *l)
+ {
+   size_t result;
+ 
+@@ -153,7 +153,11 @@ _dl_next_tls_modid (void)
+ 	      }
+ 
+ 	    if (result - disp < runp->len)
+-	      break;
++	      {
++		/* Mark the entry as used, so any dependency see it.  */
++		atomic_store_relaxed (&runp->slotinfo[result - disp].map, l);
++		break;
++	      }
+ 
+ 	    disp += runp->len;
+ 	  }
+@@ -180,17 +184,14 @@ _dl_next_tls_modid (void)
+       atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), result);
+     }
+ 
+-  return result;
++  l->l_tls_modid = result;
+ }
+ 
+ 
+ size_t
+ _dl_count_modids (void)
+ {
+-  /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where
+-     we fail to load a module and unload it leaving a gap.  If we don't
+-     have gaps then the number of modids is the current maximum so
+-     return that.  */
++  /* The count is the max unless dlclose or failed dlopen created gaps.  */
+   if (__glibc_likely (!GL(dl_tls_dtv_gaps)))
+     return GL(dl_tls_max_dtv_idx);
+ 
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 992f825ba00762a7..118c454a2329573f 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -1693,7 +1693,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
+   /* Add the dynamic linker to the TLS list if it also uses TLS.  */
+   if (GL(dl_rtld_map).l_tls_blocksize != 0)
+     /* Assign a module ID.  Do this before loading any audit modules.  */
+-    GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
++    _dl_assign_tls_modid (&GL(dl_rtld_map));
+ 
+   audit_list_add_dynamic_tag (&state.audit_list, main_map, DT_AUDIT);
+   audit_list_add_dynamic_tag (&state.audit_list, main_map, DT_DEPAUDIT);
+diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c
+index 9977ec803208b9c8..d8d04fe574597f35 100644
+--- a/elf/tst-tls20.c
++++ b/elf/tst-tls20.c
+@@ -16,12 +16,14 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <array_length.h>
+ #include <dlfcn.h>
+ #include <pthread.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <support/check.h>
+ #include <support/support.h>
++#include <support/test-driver.h>
+ #include <support/xdlfcn.h>
+ #include <support/xthread.h>
+ 
+@@ -59,28 +61,75 @@ access (int i)
+   char *buf = xasprintf ("tls_global_%02d", i);
+   dlerror ();
+   int *p = dlsym (mod[i], buf);
+-  printf ("mod[%d]: &tls = %p\n", i, p);
++  if (test_verbose)
++    printf ("mod[%d]: &tls = %p\n", i, p);
+   if (p == NULL)
+     FAIL_EXIT1 ("dlsym failed: %s\n", dlerror ());
++  TEST_COMPARE (*p, 0);
+   ++*p;
+   free (buf);
+ }
+ 
++static void
++access_mod (const char *modname, void *mod, int i)
++{
++  char *modsym = xasprintf ("tls_global_%d", i);
++  dlerror ();
++  int *p = dlsym (mod, modsym);
++  if (test_verbose)
++    printf ("%s: &tls = %p\n", modname, p);
++  if (p == NULL)
++    FAIL_EXIT1 ("dlsym failed: %s\n", dlerror ());
++  TEST_COMPARE (*p, 0);
++  ++*p;
++  free (modsym);
++}
++
++static void
++access_dep (int i)
++{
++  char *modname = xasprintf ("tst-tls-manydynamic%dmod-dep.so", i);
++  void *moddep = xdlopen (modname, RTLD_LAZY);
++  access_mod (modname, moddep, i);
++  free (modname);
++  xdlclose (moddep);
++}
++
++struct start_args
++{
++  const char *modname;
++  void *mod;
++  int modi;
++  int ndeps;
++  const int *deps;
++};
++
+ static void *
+ start (void *a)
+ {
++  struct start_args *args = a;
++
+   for (int i = 0; i < NMOD; i++)
+     if (mod[i] != NULL)
+       access (i);
++
++  if (args != NULL)
++    {
++      access_mod (args->modname, args->mod, args->modi);
++      for (int n = 0; n < args->ndeps; n++)
++	access_dep (args->deps[n]);
++    }
++
+   return 0;
+ }
+ 
+-static int
+-do_test (void)
++/* This test gaps with shared libraries with dynamic TLS that has no
++   dependencies.  The DTV gap is set with by trying to load an invalid
++   module, the entry should be used on the dlopen.  */
++static void
++do_test_no_depedency (void)
+ {
+-  int i;
+-
+-  for (i = 0; i < NMOD; i++)
++  for (int i = 0; i < NMOD; i++)
+     {
+       load_mod (i);
+       /* Bump the generation of mod[0] without using new dtv slot.  */
+@@ -91,8 +140,220 @@ do_test (void)
+       pthread_t t = xpthread_create (0, start, 0);
+       xpthread_join (t);
+     }
+-  for (i = 0; i < NMOD; i++)
++  for (int i = 0; i < NMOD; i++)
+     unload_mod (i);
++}
++
++/* The following test check DTV gaps handling with shared libraries that has
++   dependencies.  It defines 5 different sets:
++
++   1. Single dependency:
++      mod0 -> mod1
++   2. Double dependency:
++      mod2 -> [mod3,mod4]
++   3. Double dependency with each dependency depent of another module:
++      mod5 -> [mod6,mod7] -> mod8
++   4. Long chain with one double dependency in the middle:
++      mod9 -> [mod10, mod11] -> mod12 -> mod13
++   5. Long chain with two double depedencies in the middle:
++      mod14 -> mod15 -> [mod16, mod17]
++      mod15 -> [mod18, mod19]
++
++   This does not cover all the possible gaps and configuration, but it
++   should check if different dynamic shared sets are placed correctly in
++   different gaps configurations.  */
++
++static int
++nmodules (uint32_t v)
++{
++  unsigned int r = 0;
++  while (v >>= 1)
++    r++;
++  return r + 1;
++}
++
++static inline bool
++is_mod_set (uint32_t g, uint32_t n)
++{
++  return (1U << (n - 1)) & g;
++}
++
++static void
++print_gap (uint32_t g)
++{
++  if (!test_verbose)
++    return;
++  printf ("gap: ");
++  int nmods = nmodules (g);
++  for (int n = 1; n <= nmods; n++)
++    printf ("%c", ((1 << (n - 1)) & g) == 0 ? 'G' : 'M');
++  printf ("\n");
++}
++
++static void
++do_test_dependency (void)
++{
++  /* Maps the module and its dependencies, use thread to access the TLS on
++     each loaded module.  */
++  static const int tlsmanydeps0[] = { 1 };
++  static const int tlsmanydeps1[] = { 3, 4 };
++  static const int tlsmanydeps2[] = { 6, 7, 8 };
++  static const int tlsmanydeps3[] = { 10, 11, 12 };
++  static const int tlsmanydeps4[] = { 15, 16, 17, 18, 19 };
++  static const struct tlsmanydeps_t
++  {
++    int modi;
++    int ndeps;
++    const int *deps;
++  } tlsmanydeps[] =
++  {
++    {  0, array_length (tlsmanydeps0), tlsmanydeps0 },
++    {  2, array_length (tlsmanydeps1), tlsmanydeps1 },
++    {  5, array_length (tlsmanydeps2), tlsmanydeps2 },
++    {  9, array_length (tlsmanydeps3), tlsmanydeps3 },
++    { 14, array_length (tlsmanydeps4), tlsmanydeps4 },
++  };
++
++  /* The gap configuration is defined as a bitmap: the bit set represents a
++     loaded module prior the tests execution, while a bit unsed is a module
++     unloaded.  Not all permtation will show gaps, but it is simpler than
++     define each one independently.  */
++  for (uint32_t g = 0; g < 64; g++)
++    {
++      print_gap (g);
++      int nmods = nmodules (g);
++
++      int mods[nmods];
++      /* We use '0' as indication for a gap, to avoid the dlclose on iteration
++	 cleanup.  */
++      for (int n = 1; n <= nmods; n++)
++	{
++	  load_mod (n);
++	   mods[n] = n;
++	}
++      for (int n = 1; n <= nmods; n++)
++	{
++	  if (!is_mod_set (g, n))
++	    {
++	      unload_mod (n);
++	      mods[n] = 0;
++	    }
++	}
++
++      for (int t = 0; t < array_length (tlsmanydeps); t++)
++	{
++	  char *moddepname = xasprintf ("tst-tls-manydynamic%dmod-dep.so",
++					tlsmanydeps[t].modi);
++	  void *moddep = xdlopen (moddepname, RTLD_LAZY);
++
++	  /* Access TLS in all loaded modules.  */
++	  struct start_args args =
++	    {
++	      moddepname,
++	      moddep,
++	      tlsmanydeps[t].modi,
++	      tlsmanydeps[t].ndeps,
++	      tlsmanydeps[t].deps
++	    };
++	  pthread_t t = xpthread_create (0, start, &args);
++	  xpthread_join (t);
++
++	  free (moddepname);
++	  xdlclose (moddep);
++	}
++
++      for (int n = 1; n <= nmods; n++)
++	if (mods[n] != 0)
++	  unload_mod (n);
++    }
++}
++
++/* The following test check DTV gaps handling with shared libraries that has
++   invalid dependencies.  It defines 5 different sets:
++
++   1. Single dependency:
++      mod0 -> invalid
++   2. Double dependency:
++      mod1 -> [mod2,invalid]
++   3. Double dependency with each dependency depent of another module:
++      mod3 -> [mod4,mod5] -> invalid
++   4. Long chain with one double dependency in the middle:
++      mod6 -> [mod7, mod8] -> mod12 -> invalid
++   5. Long chain with two double depedencies in the middle:
++      mod10 -> mod11 -> [mod12, mod13]
++      mod12 -> [mod14, invalid]
++
++   This does not cover all the possible gaps and configuration, but it
++   should check if different dynamic shared sets are placed correctly in
++   different gaps configurations.  */
++
++static void
++do_test_invalid_dependency (bool bind_now)
++{
++  static const int tlsmanydeps[] = { 0, 1, 3, 6, 10 };
++
++  /* The gap configuration is defined as a bitmap: the bit set represents a
++     loaded module prior the tests execution, while a bit unsed is a module
++     unloaded.  Not all permtation will show gaps, but it is simpler than
++     define each one independently.  */
++  for (uint32_t g = 0; g < 64; g++)
++    {
++      print_gap (g);
++      int nmods = nmodules (g);
++
++      int mods[nmods];
++      /* We use '0' as indication for a gap, to avoid the dlclose on iteration
++	 cleanup.  */
++      for (int n = 1; n <= nmods; n++)
++	{
++	  load_mod (n);
++	   mods[n] = n;
++	}
++      for (int n = 1; n <= nmods; n++)
++	{
++	  if (!is_mod_set (g, n))
++	    {
++	      unload_mod (n);
++	      mods[n] = 0;
++	    }
++	}
++
++      for (int t = 0; t < array_length (tlsmanydeps); t++)
++	{
++	  char *moddepname = xasprintf ("tst-tls-manydynamic%dmod-dep-bad.so",
++					tlsmanydeps[t]);
++	  void *moddep;
++	  if (bind_now)
++	    {
++	      moddep = dlopen (moddepname, RTLD_NOW);
++	      TEST_VERIFY (moddep == 0);
++	    }
++	  else
++	    moddep = dlopen (moddepname, RTLD_LAZY);
++
++	  /* Access TLS in all loaded modules.  */
++	  pthread_t t = xpthread_create (0, start, NULL);
++	  xpthread_join (t);
++
++	  free (moddepname);
++	  if (!bind_now)
++	    xdlclose (moddep);
++	}
++
++      for (int n = 1; n <= nmods; n++)
++	if (mods[n] != 0)
++	  unload_mod (n);
++    }
++}
++
++static int
++do_test (void)
++{
++  do_test_no_depedency ();
++  do_test_dependency ();
++  do_test_invalid_dependency (true);
++  do_test_invalid_dependency (false);
++
+   return 0;
+ }
+ 
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index 6cbbaa808a596f77..0138353ccb41c5f1 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -1111,8 +1111,8 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
+ extern void _dl_sysdep_start_cleanup (void) attribute_hidden;
+ 
+ 
+-/* Determine next available module ID.  */
+-extern size_t _dl_next_tls_modid (void) attribute_hidden;
++/* Determine next available module ID and set the L l_tls_modid.  */
++extern void _dl_assign_tls_modid (struct link_map *l) attribute_hidden;
+ 
+ /* Count the modules with TLS segments.  */
+ extern size_t _dl_count_modids (void) attribute_hidden;
diff --git a/SOURCES/glibc-rh1991001-18.patch b/SOURCES/glibc-rh1991001-18.patch
new file mode 100644
index 0000000..340b345
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-18.patch
@@ -0,0 +1,42 @@
+commit 881b68e45c3a518319dcf5a3c4a2b3ec59e1c1e5
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Jul 16 08:32:05 2021 -0300
+
+    elf: Fix a wrong array access on tst-tls20
+    
+    Check on x86_64-linux-gnu with --enable-stack-protector=all.
+
+diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c
+index d8d04fe574597f35..831c3336c914790d 100644
+--- a/elf/tst-tls20.c
++++ b/elf/tst-tls20.c
+@@ -226,12 +226,12 @@ do_test_dependency (void)
+       int mods[nmods];
+       /* We use '0' as indication for a gap, to avoid the dlclose on iteration
+ 	 cleanup.  */
+-      for (int n = 1; n <= nmods; n++)
++      for (int n = 1; n < nmods; n++)
+ 	{
+ 	  load_mod (n);
+ 	   mods[n] = n;
+ 	}
+-      for (int n = 1; n <= nmods; n++)
++      for (int n = 1; n < nmods; n++)
+ 	{
+ 	  if (!is_mod_set (g, n))
+ 	    {
+@@ -304,12 +304,12 @@ do_test_invalid_dependency (bool bind_now)
+       int mods[nmods];
+       /* We use '0' as indication for a gap, to avoid the dlclose on iteration
+ 	 cleanup.  */
+-      for (int n = 1; n <= nmods; n++)
++      for (int n = 1; n < nmods; n++)
+ 	{
+ 	  load_mod (n);
+ 	   mods[n] = n;
+ 	}
+-      for (int n = 1; n <= nmods; n++)
++      for (int n = 1; n < nmods; n++)
+ 	{
+ 	  if (!is_mod_set (g, n))
+ 	    {
diff --git a/SOURCES/glibc-rh1991001-19.patch b/SOURCES/glibc-rh1991001-19.patch
new file mode 100644
index 0000000..48995ad
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-19.patch
@@ -0,0 +1,468 @@
+commit 83b5323261bb72313bffcf37476c1b8f0847c736
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Sep 15 15:16:19 2021 +0100
+
+    elf: Avoid deadlock between pthread_create and ctors [BZ #28357]
+
+    The fix for bug 19329 caused a regression such that pthread_create can
+    deadlock when concurrent ctors from dlopen are waiting for it to finish.
+    Use a new GL(dl_load_tls_lock) in pthread_create that is not taken
+    around ctors in dlopen.
+
+    The new lock is also used in __tls_get_addr instead of GL(dl_load_lock).
+
+    The new lock is held in _dl_open_worker and _dl_close_worker around
+    most of the logic before/after the init/fini routines.  When init/fini
+    routines are running then TLS is in a consistent, usable state.
+    In _dl_open_worker the new lock requires catching and reraising dlopen
+    failures that happen in the critical section.
+
+    The new lock is reinitialized in a fork child, to keep the existing
+    behaviour and it is kept recursive in case malloc interposition or TLS
+    access from signal handlers can retake it.  It is not obvious if this
+    is necessary or helps, but avoids changing the preexisting behaviour.
+
+    The new lock may be more appropriate for dl_iterate_phdr too than
+    GL(dl_load_write_lock), since TLS state of an incompletely loaded
+    module may be accessed.  If the new lock can replace the old one,
+    that can be a separate change.
+
+    Fixes bug 28357.
+
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+Conflicts:
+	posix/fork.c
+	  (reworked due to file rename upstream and libpthread integration)
+	sysdeps/pthread/Makefile
+	  (htl testing support was missing downstream, reconstituted here;
+	  added $(libdl) required downstream)
+
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index 18227fe992029364..7fe91bdd9aaf694e 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -549,6 +549,9 @@ _dl_close_worker (struct link_map *map, bool force)
+   size_t tls_free_end;
+   tls_free_start = tls_free_end = NO_TLS_OFFSET;
+ 
++  /* Protects global and module specitic TLS state.  */
++  __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
++
+   /* We modify the list of loaded objects.  */
+   __rtld_lock_lock_recursive (GL(dl_load_write_lock));
+ 
+@@ -784,6 +787,9 @@ _dl_close_worker (struct link_map *map, bool force)
+ 	GL(dl_tls_static_used) = tls_free_start;
+     }
+ 
++  /* TLS is cleaned up for the unloaded modules.  */
++  __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
++
+ #ifdef SHARED
+   /* Auditing checkpoint: we have deleted all objects.  */
+   if (__glibc_unlikely (do_audit))
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index 54727402750f4c0c..736df62ce6e46d34 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -65,6 +65,9 @@ struct dl_open_args
+      libc_map value in the namespace in case of a dlopen failure.  */
+   bool libc_already_loaded;
+ 
++  /* Set to true if the end of dl_open_worker_begin was reached.  */
++  bool worker_continue;
++
+   /* Original parameters to the program and the current environment.  */
+   int argc;
+   char **argv;
+@@ -481,7 +484,7 @@ call_dl_init (void *closure)
+ }
+ 
+ static void
+-dl_open_worker (void *a)
++dl_open_worker_begin (void *a)
+ {
+   struct dl_open_args *args = a;
+   const char *file = args->file;
+@@ -772,6 +775,36 @@ dl_open_worker (void *a)
+   DL_STATIC_INIT (new);
+ #endif
+ 
++  args->worker_continue = true;
++}
++
++static void
++dl_open_worker (void *a)
++{
++  struct dl_open_args *args = a;
++
++  args->worker_continue = false;
++
++  {
++    /* Protects global and module specific TLS state.  */
++    __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
++
++    struct dl_exception ex;
++    int err = _dl_catch_exception (&ex, dl_open_worker_begin, args);
++
++    __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
++
++    if (__glibc_unlikely (ex.errstring != NULL))
++      /* Reraise the error.  */
++      _dl_signal_exception (err, &ex, NULL);
++  }
++
++  if (!args->worker_continue)
++    return;
++
++  int mode = args->mode;
++  struct link_map *new = args->map;
++
+   /* Run the initializer functions of new objects.  Temporarily
+      disable the exception handler, so that lazy binding failures are
+      fatal.  */
+diff --git a/elf/dl-support.c b/elf/dl-support.c
+index 34be8e5babfb6af3..3e5531138eaa18f8 100644
+--- a/elf/dl-support.c
++++ b/elf/dl-support.c
+@@ -212,6 +212,13 @@ __rtld_lock_define_initialized_recursive (, _dl_load_lock)
+    list of loaded objects while an object is added to or removed from
+    that list.  */
+ __rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
++  /* This lock protects global and module specific TLS related data.
++     E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
++     GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
++     accessed and when TLS related relocations are processed for a
++     module.  It was introduced to keep pthread_create accessing TLS
++     state that is being set up.  */
++__rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
+ 
+ 
+ #ifdef HAVE_AUX_VECTOR
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 8c0f9e972d7a0eac..7865fc390c3f3f0a 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -527,7 +527,7 @@ _dl_allocate_tls_init (void *result)
+   size_t maxgen = 0;
+ 
+   /* Protects global dynamic TLS related state.  */
+-  __rtld_lock_lock_recursive (GL(dl_load_lock));
++  __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
+ 
+   /* Check if the current dtv is big enough.   */
+   if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
+@@ -601,7 +601,7 @@ _dl_allocate_tls_init (void *result)
+       listp = listp->next;
+       assert (listp != NULL);
+     }
+-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
++  __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
+ 
+   /* The DTV version is up-to-date now.  */
+   dtv[0].counter = maxgen;
+@@ -740,7 +740,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 
+ 	 Here the dtv needs to be updated to new_gen generation count.
+ 
+-	 This code may be called during TLS access when GL(dl_load_lock)
++	 This code may be called during TLS access when GL(dl_load_tls_lock)
+ 	 is not held.  In that case the user code has to synchronize with
+ 	 dlopen and dlclose calls of relevant modules.  A module m is
+ 	 relevant if the generation of m <= new_gen and dlclose of m is
+@@ -862,11 +862,11 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
+   if (__glibc_unlikely (the_map->l_tls_offset
+ 			!= FORCED_DYNAMIC_TLS_OFFSET))
+     {
+-      __rtld_lock_lock_recursive (GL(dl_load_lock));
++      __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
+       if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
+ 	{
+ 	  the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
+-	  __rtld_lock_unlock_recursive (GL(dl_load_lock));
++	  __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
+ 	}
+       else if (__glibc_likely (the_map->l_tls_offset
+ 			       != FORCED_DYNAMIC_TLS_OFFSET))
+@@ -878,7 +878,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
+ #else
+ # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+ #endif
+-	  __rtld_lock_unlock_recursive (GL(dl_load_lock));
++	  __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
+ 
+ 	  dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
+ 	  dtv[GET_ADDR_MODULE].pointer.val = p;
+@@ -886,7 +886,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
+ 	  return (char *) p + GET_ADDR_OFFSET;
+ 	}
+       else
+-	__rtld_lock_unlock_recursive (GL(dl_load_lock));
++	__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
+     }
+   struct dtv_pointer result = allocate_and_init (the_map);
+   dtv[GET_ADDR_MODULE].pointer = result;
+@@ -957,7 +957,7 @@ _dl_tls_get_addr_soft (struct link_map *l)
+     return NULL;
+ 
+   dtv_t *dtv = THREAD_DTV ();
+-  /* This may be called without holding the GL(dl_load_lock).  Reading
++  /* This may be called without holding the GL(dl_load_tls_lock).  Reading
+      arbitrary gen value is fine since this is best effort code.  */
+   size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
+   if (__glibc_unlikely (dtv[0].counter != gen))
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 118c454a2329573f..9e09896da078274d 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -317,6 +317,7 @@ struct rtld_global _rtld_global =
+ #ifdef _LIBC_REENTRANT
+     ._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
+     ._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
++    ._dl_load_tls_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
+ #endif
+     ._dl_nns = 1,
+     ._dl_ns =
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index 0138353ccb41c5f1..7b0a667629ddc06a 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -373,6 +373,13 @@ struct rtld_global
+      list of loaded objects while an object is added to or removed
+      from that list.  */
+   __rtld_lock_define_recursive (EXTERN, _dl_load_write_lock)
++  /* This lock protects global and module specific TLS related data.
++     E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
++     GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
++     accessed and when TLS related relocations are processed for a
++     module.  It was introduced to keep pthread_create accessing TLS
++     state that is being set up.  */
++  __rtld_lock_define_recursive (EXTERN, _dl_load_tls_lock)
+ 
+   /* Incremented whenever something may have been added to dl_loaded.  */
+   EXTERN unsigned long long _dl_load_adds;
+@@ -1192,7 +1199,7 @@ extern int _dl_scope_free (void *) attribute_hidden;
+ 
+ /* Add module to slot information data.  If DO_ADD is false, only the
+    required memory is allocated.  Must be called with GL
+-   (dl_load_lock) acquired.  If the function has already been called
++   (dl_load_tls_lock) acquired.  If the function has already been called
+    for the link map L with !do_add, then this function will not raise
+    an exception, otherwise it is possible that it encounters a memory
+    allocation failure.  */
+diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
+index 37db30f3d1e846b6..b4d20fa652f4ba3b 100644
+--- a/sysdeps/nptl/fork.c
++++ b/sysdeps/nptl/fork.c
+@@ -125,6 +125,9 @@ __libc_fork (void)
+       /* Reset the lock the dynamic loader uses to protect its data.  */
+       __rtld_lock_initialize (GL(dl_load_lock));
+ 
++      /* Reset the lock protecting dynamic TLS related data.  */
++      __rtld_lock_initialize (GL(dl_load_tls_lock));
++
+       /* Run the handlers registered for the child.  */
+       __run_fork_handlers (atfork_run_child, multiple_threads);
+     }
+diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
+index ea4f8894891b2636..98a92f8d6bb119ba 100644
+--- a/sysdeps/pthread/Makefile
++++ b/sysdeps/pthread/Makefile
+@@ -25,3 +25,24 @@ $(objpfx)tst-timer: $(objpfx)librt.a $(static-thread-library)
+ endif
+ 
+ endif
++
++ifneq (,$(filter $(subdir),htl nptl))
++ifeq ($(build-shared),yes)
++tests += tst-create1
++endif
++
++tst-create1mod.so-no-z-defs = yes
++
++ifeq ($(build-shared),yes)
++# Build all the modules even when not actually running test programs.
++tests: $(test-modules)
++endif
++
++modules-names += tst-create1mod
++test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
++
++LDFLAGS-tst-create1 = -Wl,-export-dynamic
++$(objpfx)tst-create1: $(libdl) $(shared-thread-library)
++$(objpfx)tst-create1.out: $(objpfx)tst-create1mod.so
++
++endif
+diff --git a/sysdeps/pthread/tst-create1.c b/sysdeps/pthread/tst-create1.c
+new file mode 100644
+index 0000000000000000..932586c30990d1d4
+--- /dev/null
++++ b/sysdeps/pthread/tst-create1.c
+@@ -0,0 +1,119 @@
++/* Verify that pthread_create does not deadlock when ctors take locks.
++   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 <stdio.h>
++#include <support/xdlfcn.h>
++#include <support/xthread.h>
++
++/*
++Check if ctor and pthread_create deadlocks in
++
++thread 1: dlopen -> ctor -> lock(user_lock)
++thread 2: lock(user_lock) -> pthread_create
++
++or in
++
++thread 1: dlclose -> dtor -> lock(user_lock)
++thread 2: lock(user_lock) -> pthread_create
++*/
++
++static pthread_barrier_t bar_ctor;
++static pthread_barrier_t bar_dtor;
++static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER;
++
++void
++ctor (void)
++{
++  xpthread_barrier_wait (&bar_ctor);
++  dprintf (1, "thread 1: in ctor: started.\n");
++  xpthread_mutex_lock (&user_lock);
++  dprintf (1, "thread 1: in ctor: locked user_lock.\n");
++  xpthread_mutex_unlock (&user_lock);
++  dprintf (1, "thread 1: in ctor: unlocked user_lock.\n");
++  dprintf (1, "thread 1: in ctor: done.\n");
++}
++
++void
++dtor (void)
++{
++  xpthread_barrier_wait (&bar_dtor);
++  dprintf (1, "thread 1: in dtor: started.\n");
++  xpthread_mutex_lock (&user_lock);
++  dprintf (1, "thread 1: in dtor: locked user_lock.\n");
++  xpthread_mutex_unlock (&user_lock);
++  dprintf (1, "thread 1: in dtor: unlocked user_lock.\n");
++  dprintf (1, "thread 1: in dtor: done.\n");
++}
++
++static void *
++thread3 (void *a)
++{
++  dprintf (1, "thread 3: started.\n");
++  dprintf (1, "thread 3: done.\n");
++  return 0;
++}
++
++static void *
++thread2 (void *a)
++{
++  pthread_t t3;
++  dprintf (1, "thread 2: started.\n");
++
++  xpthread_mutex_lock (&user_lock);
++  dprintf (1, "thread 2: locked user_lock.\n");
++  xpthread_barrier_wait (&bar_ctor);
++  t3 = xpthread_create (0, thread3, 0);
++  xpthread_mutex_unlock (&user_lock);
++  dprintf (1, "thread 2: unlocked user_lock.\n");
++  xpthread_join (t3);
++
++  xpthread_mutex_lock (&user_lock);
++  dprintf (1, "thread 2: locked user_lock.\n");
++  xpthread_barrier_wait (&bar_dtor);
++  t3 = xpthread_create (0, thread3, 0);
++  xpthread_mutex_unlock (&user_lock);
++  dprintf (1, "thread 2: unlocked user_lock.\n");
++  xpthread_join (t3);
++
++  dprintf (1, "thread 2: done.\n");
++  return 0;
++}
++
++static void
++thread1 (void)
++{
++  dprintf (1, "thread 1: started.\n");
++  xpthread_barrier_init (&bar_ctor, NULL, 2);
++  xpthread_barrier_init (&bar_dtor, NULL, 2);
++  pthread_t t2 = xpthread_create (0, thread2, 0);
++  void *p = xdlopen ("tst-create1mod.so", RTLD_NOW | RTLD_GLOBAL);
++  dprintf (1, "thread 1: dlopen done.\n");
++  xdlclose (p);
++  dprintf (1, "thread 1: dlclose done.\n");
++  xpthread_join (t2);
++  dprintf (1, "thread 1: done.\n");
++}
++
++static int
++do_test (void)
++{
++  thread1 ();
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/pthread/tst-create1mod.c b/sysdeps/pthread/tst-create1mod.c
+new file mode 100644
+index 0000000000000000..62c9006961683177
+--- /dev/null
++++ b/sysdeps/pthread/tst-create1mod.c
+@@ -0,0 +1,41 @@
++/* Verify that pthread_create does not deadlock when ctors take locks.
++   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 <stdio.h>
++
++/* Require TLS setup for the module.  */
++__thread int tlsvar;
++
++void ctor (void);
++void dtor (void);
++
++static void __attribute__ ((constructor))
++do_init (void)
++{
++  dprintf (1, "constructor started: %d.\n", tlsvar++);
++  ctor ();
++  dprintf (1, "constructor done: %d.\n", tlsvar++);
++}
++
++static void __attribute__ ((destructor))
++do_end (void)
++{
++  dprintf (1, "destructor started: %d.\n", tlsvar++);
++  dtor ();
++  dprintf (1, "destructor done: %d.\n", tlsvar++);
++}
diff --git a/SOURCES/glibc-rh1991001-2.patch b/SOURCES/glibc-rh1991001-2.patch
new file mode 100644
index 0000000..468fc03
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-2.patch
@@ -0,0 +1,28 @@
+commit d2b997c7172e9a00895a9deb379f8782fbd2e36f
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Dec 30 23:40:14 2020 +0000
+
+    elf: Fix a DTV setup issue [BZ #27136]
+    
+    The max modid is a valid index in the dtv, it should not be skipped.
+    
+    The bug is observable if the last module has modid == 64 and its
+    generation is same or less than the max generation of the previous
+    modules.  Then dtv[0].counter implies dtv[64] is initialized but
+    it isn't. Fixes bug 27136.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index cccf74b33481b866..0b96b1dceed99d58 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -590,7 +590,7 @@ _dl_allocate_tls_init (void *result)
+ 	}
+ 
+       total += cnt;
+-      if (total >= GL(dl_tls_max_dtv_idx))
++      if (total > GL(dl_tls_max_dtv_idx))
+ 	break;
+ 
+       listp = listp->next;
diff --git a/SOURCES/glibc-rh1991001-20.patch b/SOURCES/glibc-rh1991001-20.patch
new file mode 100644
index 0000000..d8aedcc
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-20.patch
@@ -0,0 +1,20 @@
+commit 3c7c5117826816021f9d3f352f49e0dd0236cbad
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Nov 30 14:35:54 2021 +0100
+
+    elf: Include <stdint.h> in tst-tls20.c
+    
+    The test uses standard integer types.
+
+diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c
+index 831c3336c914790d..18067e6b0a6093f9 100644
+--- a/elf/tst-tls20.c
++++ b/elf/tst-tls20.c
+@@ -19,6 +19,7 @@
+ #include <array_length.h>
+ #include <dlfcn.h>
+ #include <pthread.h>
++#include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <support/check.h>
diff --git a/SOURCES/glibc-rh1991001-21.patch b/SOURCES/glibc-rh1991001-21.patch
new file mode 100644
index 0000000..c4e1316
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-21.patch
@@ -0,0 +1,20 @@
+commit df4cb2280e32187380520f71bd27ab32252cbc85
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Nov 30 15:39:17 2021 +0100
+
+    elf: Include <stdbool.h> in tst-tls20.c
+    
+    The test uses the bool type.
+
+diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c
+index 18067e6b0a6093f9..200dacb748af21a8 100644
+--- a/elf/tst-tls20.c
++++ b/elf/tst-tls20.c
+@@ -19,6 +19,7 @@
+ #include <array_length.h>
+ #include <dlfcn.h>
+ #include <pthread.h>
++#include <stdbool.h>
+ #include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
diff --git a/SOURCES/glibc-rh1991001-22.patch b/SOURCES/glibc-rh1991001-22.patch
new file mode 100644
index 0000000..490e909
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-22.patch
@@ -0,0 +1,62 @@
+commit 5cc338565479a620244c2f8ff35956629c4dbf81
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Dec 10 05:14:24 2021 +0100
+
+    nptl: Add one more barrier to nptl/tst-create1
+    
+    Without the bar_ctor_finish barrier, it was possible that thread2
+    re-locked user_lock before ctor had a chance to lock it.  ctor then
+    blocked in its locking operation, xdlopen from the main thread
+    did not return, and thread2 was stuck waiting in bar_dtor:
+    
+    thread 1: started.
+    thread 2: started.
+    thread 2: locked user_lock.
+    constructor started: 0.
+    thread 1: in ctor: started.
+    thread 3: started.
+    thread 3: done.
+    thread 2: unlocked user_lock.
+    thread 2: locked user_lock.
+    
+    Fixes the test in commit 83b5323261bb72313bffcf37476c1b8f0847c736
+    ("elf: Avoid deadlock between pthread_create and ctors [BZ #28357]").
+    
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+diff --git a/sysdeps/pthread/tst-create1.c b/sysdeps/pthread/tst-create1.c
+index 932586c30990d1d4..763ded8d7956f943 100644
+--- a/sysdeps/pthread/tst-create1.c
++++ b/sysdeps/pthread/tst-create1.c
+@@ -33,6 +33,7 @@ thread 2: lock(user_lock) -> pthread_create
+ */
+ 
+ static pthread_barrier_t bar_ctor;
++static pthread_barrier_t bar_ctor_finish;
+ static pthread_barrier_t bar_dtor;
+ static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER;
+ 
+@@ -46,6 +47,7 @@ ctor (void)
+   xpthread_mutex_unlock (&user_lock);
+   dprintf (1, "thread 1: in ctor: unlocked user_lock.\n");
+   dprintf (1, "thread 1: in ctor: done.\n");
++  xpthread_barrier_wait (&bar_ctor_finish);
+ }
+ 
+ void
+@@ -81,6 +83,7 @@ thread2 (void *a)
+   xpthread_mutex_unlock (&user_lock);
+   dprintf (1, "thread 2: unlocked user_lock.\n");
+   xpthread_join (t3);
++  xpthread_barrier_wait (&bar_ctor_finish);
+ 
+   xpthread_mutex_lock (&user_lock);
+   dprintf (1, "thread 2: locked user_lock.\n");
+@@ -99,6 +102,7 @@ thread1 (void)
+ {
+   dprintf (1, "thread 1: started.\n");
+   xpthread_barrier_init (&bar_ctor, NULL, 2);
++  xpthread_barrier_init (&bar_ctor_finish, NULL, 2);
+   xpthread_barrier_init (&bar_dtor, NULL, 2);
+   pthread_t t2 = xpthread_create (0, thread2, 0);
+   void *p = xdlopen ("tst-create1mod.so", RTLD_NOW | RTLD_GLOBAL);
diff --git a/SOURCES/glibc-rh1991001-3.patch b/SOURCES/glibc-rh1991001-3.patch
new file mode 100644
index 0000000..85a9cd7
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-3.patch
@@ -0,0 +1,163 @@
+commit 8f85075a2e9c26ff7486d4bbaf358999807d215c
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Dec 31 12:24:38 2020 +0000
+
+    elf: Add a DTV setup test [BZ #27136]
+    
+    The test dlopens a large number of modules with TLS, they are reused
+    from an existing test.
+    
+    The test relies on the reuse of slotinfo entries after dlclose, without
+    bug 27135 fixed this needs a failing dlopen. With a slotinfo list that
+    has non-monotone increasing generation counters, bug 27136 can trigger.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+Conflicts:
+	elf/Makefile
+	  (usual test differences)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 82fb019a634caf81..0995d810b57d0dda 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -209,7 +209,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 tst-audit14 tst-audit15 tst-audit16 \
+ 	 tst-tls-ie tst-tls-ie-dlmopen \
+ 	 argv0test \
+-	 tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask
++	 tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
++	 tst-tls20
+ #	 reldep9
+ tests-internal += loadtest unload unload2 circleload1 \
+ 	 neededtest neededtest2 neededtest3 neededtest4 \
+@@ -332,6 +333,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		libmarkermod2-1 libmarkermod2-2 \
+ 		libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \
+ 		libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
++		tst-tls20mod-bad
+ 
+ # Most modules build with _ISOMAC defined, but those filtered out
+ # depend on internal headers.
+@@ -1828,3 +1830,9 @@ $(objpfx)tst-rtld-help.out: $(objpfx)ld.so
+ 	fi; \
+ 	(exit $$status); \
+ 	$(evaluate-test)
++
++# Reuses tst-tls-many-dynamic-modules
++tst-tls20mod-bad.so-no-z-defs = yes
++$(objpfx)tst-tls20: $(libdl) $(shared-thread-library)
++$(objpfx)tst-tls20.out: $(objpfx)tst-tls20mod-bad.so \
++			$(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
+diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c
+new file mode 100644
+index 0000000000000000..ac5f8c8d39b66dd6
+--- /dev/null
++++ b/elf/tst-tls20.c
+@@ -0,0 +1,98 @@
++/* Test dtv setup if entries don't have monotone increasing generation.
++   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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <dlfcn.h>
++#include <pthread.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <support/check.h>
++#include <support/xdlfcn.h>
++#include <support/xthread.h>
++
++#define NMOD 100
++static void *mod[NMOD];
++
++static void
++load_fail (void)
++{
++  /* Expected to fail because of a missing symbol.  */
++  void *m = dlopen ("tst-tls20mod-bad.so", RTLD_NOW);
++  if (m != NULL)
++    FAIL_EXIT1 ("dlopen of tst-tls20mod-bad.so succeeded\n");
++}
++
++static void
++load_mod (int i)
++{
++  char *buf = xasprintf ("tst-tls-manydynamic%02dmod.so", i);
++  mod[i] = xdlopen (buf, RTLD_LAZY);
++  free (buf);
++}
++
++static void
++unload_mod (int i)
++{
++  if (mod[i] != NULL)
++    xdlclose (mod[i]);
++  mod[i] = NULL;
++}
++
++static void
++access (int i)
++{
++  char *buf = xasprintf ("tls_global_%02d", i);
++  dlerror ();
++  int *p = dlsym (mod[i], buf);
++  printf ("mod[%d]: &tls = %p\n", i, p);
++  if (p == NULL)
++    FAIL_EXIT1 ("dlsym failed: %s\n", dlerror ());
++  ++*p;
++  free (buf);
++}
++
++static void *
++start (void *a)
++{
++  for (int i = 0; i < NMOD; i++)
++    if (mod[i] != NULL)
++      access (i);
++  return 0;
++}
++
++static int
++do_test (void)
++{
++  int i;
++
++  for (i = 0; i < NMOD; i++)
++    {
++      load_mod (i);
++      /* Bump the generation of mod[0] without using new dtv slot.  */
++      unload_mod (0);
++      load_fail (); /* Ensure GL(dl_tls_dtv_gaps) is true: see bug 27135.  */
++      load_mod (0);
++      /* Access TLS in all loaded modules.  */
++      pthread_t t = xpthread_create (0, start, 0);
++      xpthread_join (t);
++    }
++  for (i = 0; i < NMOD; i++)
++    unload_mod (i);
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-tls20mod-bad.c b/elf/tst-tls20mod-bad.c
+new file mode 100644
+index 0000000000000000..c1aed8ea7deffd22
+--- /dev/null
++++ b/elf/tst-tls20mod-bad.c
+@@ -0,0 +1,2 @@
++void missing_symbol (void);
++void f (void) {missing_symbol ();}
diff --git a/SOURCES/glibc-rh1991001-4.patch b/SOURCES/glibc-rh1991001-4.patch
new file mode 100644
index 0000000..c8650bb
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-4.patch
@@ -0,0 +1,41 @@
+commit c489c35054c39d7f2437ca61b369e3ede448f022
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Nov 30 11:44:25 2016 +0000
+
+    elf: Fix comments and logic in _dl_add_to_slotinfo
+    
+    Since
+    
+      commit a509eb117fac1d764b15eba64993f4bdb63d7f3c
+      Avoid late dlopen failure due to scope, TLS slotinfo updates [BZ #25112]
+    
+    the generation counter update is not needed in the failure path.
+    That commit ensures allocation in _dl_add_to_slotinfo happens before
+    the demarcation point in dlopen (it is called twice, first time is for
+    allocation only where dlopen can still be reverted on failure, then
+    second time actual dtv updates are done which then cannot fail).
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 0b96b1dceed99d58..9375650a3ab5247d 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -998,16 +998,7 @@ _dl_add_to_slotinfo (struct link_map *l, bool do_add)
+ 		+ TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
+       if (listp == NULL)
+ 	{
+-	  /* We ran out of memory.  We will simply fail this
+-	     call but don't undo anything we did so far.  The
+-	     application will crash or be terminated anyway very
+-	     soon.  */
+-
+-	  /* We have to do this since some entries in the dtv
+-	     slotinfo array might already point to this
+-	     generation.  */
+-	  ++GL(dl_tls_generation);
+-
++	  /* We ran out of memory while resizing the dtv slotinfo list.  */
+ 	  _dl_signal_error (ENOMEM, "dlopen", NULL, N_("\
+ cannot create TLS data structures"));
+ 	}
diff --git a/SOURCES/glibc-rh1991001-5.patch b/SOURCES/glibc-rh1991001-5.patch
new file mode 100644
index 0000000..735e348
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-5.patch
@@ -0,0 +1,58 @@
+commit c0669ae1a629e16b536bf11cdd0865e0dbcf4bee
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Dec 30 21:52:38 2020 +0000
+
+    elf: Refactor _dl_update_slotinfo to avoid use after free
+    
+    map is not valid to access here because it can be freed by a concurrent
+    dlclose: during tls access (via __tls_get_addr) _dl_update_slotinfo is
+    called without holding dlopen locks. So don't check the modid of map.
+    
+    The map == 0 and map != 0 code paths can be shared (avoiding the dtv
+    resize in case of map == 0 is just an optimization: larger dtv than
+    necessary would be fine too).
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 9375650a3ab5247d..15ed01d795a8627a 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -743,6 +743,8 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 	{
+ 	  for (size_t cnt = total == 0 ? 1 : 0; cnt < listp->len; ++cnt)
+ 	    {
++	      size_t modid = total + cnt;
++
+ 	      size_t gen = listp->slotinfo[cnt].gen;
+ 
+ 	      if (gen > new_gen)
+@@ -758,25 +760,12 @@ _dl_update_slotinfo (unsigned long int req_modid)
+ 
+ 	      /* If there is no map this means the entry is empty.  */
+ 	      struct link_map *map = listp->slotinfo[cnt].map;
+-	      if (map == NULL)
+-		{
+-		  if (dtv[-1].counter >= total + cnt)
+-		    {
+-		      /* If this modid was used at some point the memory
+-			 might still be allocated.  */
+-		      free (dtv[total + cnt].pointer.to_free);
+-		      dtv[total + cnt].pointer.val = TLS_DTV_UNALLOCATED;
+-		      dtv[total + cnt].pointer.to_free = NULL;
+-		    }
+-
+-		  continue;
+-		}
+-
+ 	      /* Check whether the current dtv array is large enough.  */
+-	      size_t modid = map->l_tls_modid;
+-	      assert (total + cnt == modid);
+ 	      if (dtv[-1].counter < modid)
+ 		{
++		  if (map == NULL)
++		    continue;
++
+ 		  /* Resize the dtv.  */
+ 		  dtv = _dl_resize_dtv (dtv);
+ 
diff --git a/SOURCES/glibc-rh1991001-6.patch b/SOURCES/glibc-rh1991001-6.patch
new file mode 100644
index 0000000..03505b0
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-6.patch
@@ -0,0 +1,48 @@
+commit 8f7e09f4dbdb5c815a18b8285fbc5d5d7bc17d86
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Feb 11 11:29:23 2021 +0000
+
+    x86_64: Avoid lazy relocation of tlsdesc [BZ #27137]
+    
+    Lazy tlsdesc relocation is racy because the static tls optimization and
+    tlsdesc management operations are done without holding the dlopen lock.
+    
+    This similar to the commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67
+    for aarch64, but it fixes a different race: bug 27137.
+    
+    Another issue is that ld auditing ignores DT_BIND_NOW and thus tries to
+    relocate tlsdesc lazily, but that does not work in a BIND_NOW module
+    due to missing DT_TLSDESC_PLT. Unconditionally relocating tlsdesc at
+    load time fixes this bug 27721 too.
+
+diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
+index e308b662d245cc63..ef5740ba281c7282 100644
+--- a/sysdeps/x86_64/dl-machine.h
++++ b/sysdeps/x86_64/dl-machine.h
+@@ -563,12 +563,21 @@ elf_machine_lazy_rel (struct link_map *map,
+     }
+   else if (__glibc_likely (r_type == R_X86_64_TLSDESC))
+     {
+-      struct tlsdesc volatile * __attribute__((__unused__)) td =
+-	(struct tlsdesc volatile *)reloc_addr;
++      const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
++      const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]);
++      const ElfW (Sym) *sym = &symtab[symndx];
++      const struct r_found_version *version = NULL;
+ 
+-      td->arg = (void*)reloc;
+-      td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
+-			  + map->l_addr);
++      if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
++	{
++	  const ElfW (Half) *vernum =
++	    (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
++	  version = &map->l_versions[vernum[symndx] & 0x7fff];
++	}
++
++      /* Always initialize TLS descriptors completely at load time, in
++	 case static TLS is allocated for it that requires locking.  */
++      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
+     }
+   else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE))
+     {
diff --git a/SOURCES/glibc-rh1991001-7.patch b/SOURCES/glibc-rh1991001-7.patch
new file mode 100644
index 0000000..0d7da7f
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-7.patch
@@ -0,0 +1,116 @@
+commit ddcacd91cc10ff92d6201eda87047d029c14158d
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Feb 11 11:40:11 2021 +0000
+
+    i386: Avoid lazy relocation of tlsdesc [BZ #27137]
+    
+    Lazy tlsdesc relocation is racy because the static tls optimization and
+    tlsdesc management operations are done without holding the dlopen lock.
+    
+    This similar to the commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67
+    for aarch64, but it fixes a different race: bug 27137.
+    
+    On i386 the code is a bit more complicated than on x86_64 because both
+    rel and rela relocs are supported.
+
+diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
+index e5776ef7bc8ad749..3a30671591284d79 100644
+--- a/sysdeps/i386/dl-machine.h
++++ b/sysdeps/i386/dl-machine.h
+@@ -679,50 +679,32 @@ elf_machine_lazy_rel (struct link_map *map,
+     }
+   else if (__glibc_likely (r_type == R_386_TLS_DESC))
+     {
+-      struct tlsdesc volatile * __attribute__((__unused__)) td =
+-	(struct tlsdesc volatile *)reloc_addr;
+-
+-      /* Handle relocations that reference the local *ABS* in a simple
+-	 way, so as to preserve a potential addend.  */
+-      if (ELF32_R_SYM (reloc->r_info) == 0)
+-	td->entry = _dl_tlsdesc_resolve_abs_plus_addend;
+-      /* Given a known-zero addend, we can store a pointer to the
+-	 reloc in the arg position.  */
+-      else if (td->arg == 0)
+-	{
+-	  td->arg = (void*)reloc;
+-	  td->entry = _dl_tlsdesc_resolve_rel;
+-	}
+-      else
+-	{
+-	  /* We could handle non-*ABS* relocations with non-zero addends
+-	     by allocating dynamically an arg to hold a pointer to the
+-	     reloc, but that sounds pointless.  */
+-	  const Elf32_Rel *const r = reloc;
+-	  /* The code below was borrowed from elf_dynamic_do_rel().  */
+-	  const ElfW(Sym) *const symtab =
+-	    (const void *) D_PTR (map, l_info[DT_SYMTAB]);
++      const Elf32_Rel *const r = reloc;
++      /* The code below was borrowed from elf_dynamic_do_rel().  */
++      const ElfW(Sym) *const symtab =
++	(const void *) D_PTR (map, l_info[DT_SYMTAB]);
+ 
++      /* Always initialize TLS descriptors completely at load time, in
++	 case static TLS is allocated for it that requires locking.  */
+ # ifdef RTLD_BOOTSTRAP
+-	  /* The dynamic linker always uses versioning.  */
+-	  assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL);
++      /* The dynamic linker always uses versioning.  */
++      assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL);
+ # else
+-	  if (map->l_info[VERSYMIDX (DT_VERSYM)])
++      if (map->l_info[VERSYMIDX (DT_VERSYM)])
+ # endif
+-	    {
+-	      const ElfW(Half) *const version =
+-		(const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
+-	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
+-	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
+-			       &map->l_versions[ndx],
+-			       (void *) (l_addr + r->r_offset), skip_ifunc);
+-	    }
++	{
++	  const ElfW(Half) *const version =
++	    (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
++	  ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
++	  elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
++			   &map->l_versions[ndx],
++			   (void *) (l_addr + r->r_offset), skip_ifunc);
++	}
+ # ifndef RTLD_BOOTSTRAP
+-	  else
+-	    elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
+-			     (void *) (l_addr + r->r_offset), skip_ifunc);
++      else
++	elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
++			 (void *) (l_addr + r->r_offset), skip_ifunc);
+ # endif
+-	}
+     }
+   else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
+     {
+@@ -749,11 +731,21 @@ elf_machine_lazy_rela (struct link_map *map,
+     ;
+   else if (__glibc_likely (r_type == R_386_TLS_DESC))
+     {
+-      struct tlsdesc volatile * __attribute__((__unused__)) td =
+-	(struct tlsdesc volatile *)reloc_addr;
++      const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
++      const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]);
++      const ElfW (Sym) *sym = &symtab[symndx];
++      const struct r_found_version *version = NULL;
++
++      if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
++	{
++	  const ElfW (Half) *vernum =
++	    (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
++	  version = &map->l_versions[vernum[symndx] & 0x7fff];
++	}
+ 
+-      td->arg = (void*)reloc;
+-      td->entry = _dl_tlsdesc_resolve_rela;
++      /* Always initialize TLS descriptors completely at load time, in
++	 case static TLS is allocated for it that requires locking.  */
++      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
+     }
+   else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
+     {
diff --git a/SOURCES/glibc-rh1991001-8.patch b/SOURCES/glibc-rh1991001-8.patch
new file mode 100644
index 0000000..3a1b147
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-8.patch
@@ -0,0 +1,277 @@
+commit 55c9f3238080e9aba733bc0902779c46cfa16446
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Feb 11 11:52:24 2021 +0000
+
+    x86_64: Remove lazy tlsdesc relocation related code
+    
+    _dl_tlsdesc_resolve_rela and _dl_tlsdesc_resolve_hold are only used for
+    lazy tlsdesc relocation processing which is no longer supported.
+
+diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
+index ef5740ba281c7282..b94d3b39ec1dca64 100644
+--- a/sysdeps/x86_64/dl-machine.h
++++ b/sysdeps/x86_64/dl-machine.h
+@@ -127,10 +127,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+ 	}
+     }
+ 
+-  if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy)
+-    *(ElfW(Addr)*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) + l->l_addr)
+-      = (ElfW(Addr)) &_dl_tlsdesc_resolve_rela;
+-
+   return lazy;
+ }
+ 
+diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
+index 80d771cd887dd626..77e78cf0a6d8babc 100644
+--- a/sysdeps/x86_64/dl-tlsdesc.S
++++ b/sysdeps/x86_64/dl-tlsdesc.S
+@@ -148,107 +148,3 @@ _dl_tlsdesc_dynamic:
+ 	cfi_endproc
+ 	.size	_dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
+ #endif /* SHARED */
+-
+-     /* This function is a wrapper for a lazy resolver for TLS_DESC
+-	RELA relocations.  The incoming 0(%rsp) points to the caller's
+-	link map, pushed by the dynamic object's internal lazy TLS
+-	resolver front-end before tail-calling us.  We need to pop it
+-	ourselves.  %rax points to a TLS descriptor, such that 0(%rax)
+-	holds the address of the internal resolver front-end (unless
+-	some other thread beat us to resolving it) and 8(%rax) holds a
+-	pointer to the relocation.
+-
+-	When the actual resolver returns, it will have adjusted the
+-	TLS descriptor such that we can tail-call it for it to return
+-	the TP offset of the symbol.  */
+-
+-	.hidden _dl_tlsdesc_resolve_rela
+-	.global	_dl_tlsdesc_resolve_rela
+-	.type	_dl_tlsdesc_resolve_rela,@function
+-	cfi_startproc
+-	.align 16
+-	/* The PLT entry will have pushed the link_map pointer.  */
+-_dl_tlsdesc_resolve_rela:
+-	_CET_ENDBR
+-	cfi_adjust_cfa_offset (8)
+-	/* Save all call-clobbered registers.  Add 8 bytes for push in
+-	   the PLT entry to align the stack.  */
+-	subq	$80, %rsp
+-	cfi_adjust_cfa_offset (80)
+-	movq	%rax, (%rsp)
+-	movq	%rdi, 8(%rsp)
+-	movq	%rax, %rdi	/* Pass tlsdesc* in %rdi.  */
+-	movq	%rsi, 16(%rsp)
+-	movq	80(%rsp), %rsi	/* Pass link_map* in %rsi.  */
+-	movq	%r8, 24(%rsp)
+-	movq	%r9, 32(%rsp)
+-	movq	%r10, 40(%rsp)
+-	movq	%r11, 48(%rsp)
+-	movq	%rdx, 56(%rsp)
+-	movq	%rcx, 64(%rsp)
+-	call	_dl_tlsdesc_resolve_rela_fixup
+-	movq	(%rsp), %rax
+-	movq	8(%rsp), %rdi
+-	movq	16(%rsp), %rsi
+-	movq	24(%rsp), %r8
+-	movq	32(%rsp), %r9
+-	movq	40(%rsp), %r10
+-	movq	48(%rsp), %r11
+-	movq	56(%rsp), %rdx
+-	movq	64(%rsp), %rcx
+-	addq	$88, %rsp
+-	cfi_adjust_cfa_offset (-88)
+-	jmp	*(%rax)
+-	cfi_endproc
+-	.size	_dl_tlsdesc_resolve_rela, .-_dl_tlsdesc_resolve_rela
+-
+-     /* This function is a placeholder for lazy resolving of TLS
+-	relocations.  Once some thread starts resolving a TLS
+-	relocation, it sets up the TLS descriptor to use this
+-	resolver, such that other threads that would attempt to
+-	resolve it concurrently may skip the call to the original lazy
+-	resolver and go straight to a condition wait.
+-
+-	When the actual resolver returns, it will have adjusted the
+-	TLS descriptor such that we can tail-call it for it to return
+-	the TP offset of the symbol.  */
+-
+-	.hidden _dl_tlsdesc_resolve_hold
+-	.global	_dl_tlsdesc_resolve_hold
+-	.type	_dl_tlsdesc_resolve_hold,@function
+-	cfi_startproc
+-	.align 16
+-_dl_tlsdesc_resolve_hold:
+-0:
+-	_CET_ENDBR
+-	/* Save all call-clobbered registers.  */
+-	subq	$72, %rsp
+-	cfi_adjust_cfa_offset (72)
+-	movq	%rax, (%rsp)
+-	movq	%rdi, 8(%rsp)
+-	movq	%rax, %rdi	/* Pass tlsdesc* in %rdi.  */
+-	movq	%rsi, 16(%rsp)
+-	/* Pass _dl_tlsdesc_resolve_hold's address in %rsi.  */
+-	leaq	. - _dl_tlsdesc_resolve_hold(%rip), %rsi
+-	movq	%r8, 24(%rsp)
+-	movq	%r9, 32(%rsp)
+-	movq	%r10, 40(%rsp)
+-	movq	%r11, 48(%rsp)
+-	movq	%rdx, 56(%rsp)
+-	movq	%rcx, 64(%rsp)
+-	call	_dl_tlsdesc_resolve_hold_fixup
+-1:
+-	movq	(%rsp), %rax
+-	movq	8(%rsp), %rdi
+-	movq	16(%rsp), %rsi
+-	movq	24(%rsp), %r8
+-	movq	32(%rsp), %r9
+-	movq	40(%rsp), %r10
+-	movq	48(%rsp), %r11
+-	movq	56(%rsp), %rdx
+-	movq	64(%rsp), %rcx
+-	addq	$72, %rsp
+-	cfi_adjust_cfa_offset (-72)
+-	jmp	*(%rax)
+-	cfi_endproc
+-	.size	_dl_tlsdesc_resolve_hold, .-_dl_tlsdesc_resolve_hold
+diff --git a/sysdeps/x86_64/dl-tlsdesc.h b/sysdeps/x86_64/dl-tlsdesc.h
+index 66e659bb5c7ede74..1cde1ee9664f4908 100644
+--- a/sysdeps/x86_64/dl-tlsdesc.h
++++ b/sysdeps/x86_64/dl-tlsdesc.h
+@@ -55,9 +55,7 @@ struct tlsdesc_dynamic_arg
+ 
+ extern ptrdiff_t attribute_hidden
+   _dl_tlsdesc_return(struct tlsdesc *on_rax),
+-  _dl_tlsdesc_undefweak(struct tlsdesc *on_rax),
+-  _dl_tlsdesc_resolve_rela(struct tlsdesc *on_rax),
+-  _dl_tlsdesc_resolve_hold(struct tlsdesc *on_rax);
++  _dl_tlsdesc_undefweak(struct tlsdesc *on_rax);
+ 
+ # ifdef SHARED
+ extern void *_dl_make_tlsdesc_dynamic (struct link_map *map,
+diff --git a/sysdeps/x86_64/tlsdesc.c b/sysdeps/x86_64/tlsdesc.c
+index 302d097dbb0c4f1e..61a19ae26944c84f 100644
+--- a/sysdeps/x86_64/tlsdesc.c
++++ b/sysdeps/x86_64/tlsdesc.c
+@@ -16,120 +16,13 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <link.h>
+ #include <ldsodefs.h>
+-#include <elf/dynamic-link.h>
+ #include <tls.h>
+ #include <dl-tlsdesc.h>
+ #include <dl-unmap-segments.h>
++#define _dl_tlsdesc_resolve_hold 0
+ #include <tlsdeschtab.h>
+ 
+-/* The following 2 functions take a caller argument, that contains the
+-   address expected to be in the TLS descriptor.  If it's changed, we
+-   want to return immediately.  */
+-
+-/* This function is used to lazily resolve TLS_DESC RELA relocations.
+-   The argument location is used to hold a pointer to the relocation.  */
+-
+-void
+-attribute_hidden
+-_dl_tlsdesc_resolve_rela_fixup (struct tlsdesc volatile *td,
+-				struct link_map *l)
+-{
+-  const ElfW(Rela) *reloc = td->arg;
+-
+-  if (_dl_tlsdesc_resolve_early_return_p
+-      (td, (void*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_PLT)]) + l->l_addr)))
+-    return;
+-
+-  /* The code below was borrowed from _dl_fixup().  */
+-  const ElfW(Sym) *const symtab
+-    = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
+-  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
+-  const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+-  lookup_t result;
+-
+-   /* Look up the target symbol.  If the normal lookup rules are not
+-      used don't look in the global scope.  */
+-  if (ELFW(ST_BIND) (sym->st_info) != STB_LOCAL
+-      && __builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
+-    {
+-      const struct r_found_version *version = NULL;
+-
+-      if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+-	{
+-	  const ElfW(Half) *vernum =
+-	    (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
+-	  ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
+-	  version = &l->l_versions[ndx];
+-	  if (version->hash == 0)
+-	    version = NULL;
+-	}
+-
+-      result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
+-				    l->l_scope, version, ELF_RTYPE_CLASS_PLT,
+-				    DL_LOOKUP_ADD_DEPENDENCY, NULL);
+-    }
+-  else
+-    {
+-      /* We already found the symbol.  The module (and therefore its load
+-	 address) is also known.  */
+-      result = l;
+-    }
+-
+-  if (! sym)
+-    {
+-      td->arg = (void*)reloc->r_addend;
+-      td->entry = _dl_tlsdesc_undefweak;
+-    }
+-  else
+-    {
+-#  ifndef SHARED
+-      CHECK_STATIC_TLS (l, result);
+-#  else
+-      if (!TRY_STATIC_TLS (l, result))
+-	{
+-	  td->arg = _dl_make_tlsdesc_dynamic (result, sym->st_value
+-					      + reloc->r_addend);
+-	  td->entry = _dl_tlsdesc_dynamic;
+-	}
+-      else
+-#  endif
+-	{
+-	  td->arg = (void*)(sym->st_value - result->l_tls_offset
+-			    + reloc->r_addend);
+-	  td->entry = _dl_tlsdesc_return;
+-	}
+-    }
+-
+-  _dl_tlsdesc_wake_up_held_fixups ();
+-}
+-
+-/* This function is used to avoid busy waiting for other threads to
+-   complete the lazy relocation.  Once another thread wins the race to
+-   relocate a TLS descriptor, it sets the descriptor up such that this
+-   function is called to wait until the resolver releases the
+-   lock.  */
+-
+-void
+-attribute_hidden
+-_dl_tlsdesc_resolve_hold_fixup (struct tlsdesc volatile *td,
+-				void *caller)
+-{
+-  /* Maybe we're lucky and can return early.  */
+-  if (caller != td->entry)
+-    return;
+-
+-  /* Locking here will stop execution until the running resolver runs
+-     _dl_tlsdesc_wake_up_held_fixups(), releasing the lock.
+-
+-     FIXME: We'd be better off waiting on a condition variable, such
+-     that we didn't have to hold the lock throughout the relocation
+-     processing.  */
+-  __rtld_lock_lock_recursive (GL(dl_load_lock));
+-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-}
+-
+ /* Unmap the dynamic object, but also release its TLS descriptor table
+    if there is one.  */
+ 
diff --git a/SOURCES/glibc-rh1991001-9.patch b/SOURCES/glibc-rh1991001-9.patch
new file mode 100644
index 0000000..116739a
--- /dev/null
+++ b/SOURCES/glibc-rh1991001-9.patch
@@ -0,0 +1,443 @@
+commit a75a02a696f9f869d77b17b99964823aa8833a8b
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Thu Feb 11 11:58:20 2021 +0000
+
+    i386: Remove lazy tlsdesc relocation related code
+    
+    Like in commit e75711ebfa976d5468ec292282566a18b07e4d67 for x86_64,
+    remove unused lazy tlsdesc relocation processing code:
+    
+      _dl_tlsdesc_resolve_abs_plus_addend
+      _dl_tlsdesc_resolve_rel
+      _dl_tlsdesc_resolve_rela
+      _dl_tlsdesc_resolve_hold
+
+diff --git a/sysdeps/i386/dl-tlsdesc.S b/sysdeps/i386/dl-tlsdesc.S
+index 128f0af3188f46bb..22ecb2c6adc6cc6e 100644
+--- a/sysdeps/i386/dl-tlsdesc.S
++++ b/sysdeps/i386/dl-tlsdesc.S
+@@ -138,159 +138,3 @@ _dl_tlsdesc_dynamic:
+ 	cfi_endproc
+ 	.size	_dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
+ #endif /* SHARED */
+-
+-     /* This function is a wrapper for a lazy resolver for TLS_DESC
+-	REL relocations that reference the *ABS* segment in their own
+-	link maps.  %ebx points to the caller's GOT.  %eax points to a
+-	TLS descriptor, such that 0(%eax) holds the address of the
+-	resolver wrapper itself (unless some other thread beat us to
+-	it) and 4(%eax) holds the addend in the relocation.
+-
+-	When the actual resolver returns, it will have adjusted the
+-	TLS descriptor such that we can tail-call it for it to return
+-	the TP offset of the symbol.  */
+-
+-	.hidden _dl_tlsdesc_resolve_abs_plus_addend
+-	.global	_dl_tlsdesc_resolve_abs_plus_addend
+-	.type	_dl_tlsdesc_resolve_abs_plus_addend,@function
+-	cfi_startproc
+-	.align 16
+-_dl_tlsdesc_resolve_abs_plus_addend:
+-0:
+-	_CET_ENDBR
+-	pushl	%eax
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%ecx
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%edx
+-	cfi_adjust_cfa_offset (4)
+-	movl	$1f - 0b, %ecx
+-	movl	4(%ebx), %edx
+-	call	_dl_tlsdesc_resolve_abs_plus_addend_fixup
+-1:
+-	popl	%edx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%ecx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%eax
+-	cfi_adjust_cfa_offset (-4)
+-	jmp	*(%eax)
+-	cfi_endproc
+-	.size	_dl_tlsdesc_resolve_abs_plus_addend, .-_dl_tlsdesc_resolve_abs_plus_addend
+-
+-     /* This function is a wrapper for a lazy resolver for TLS_DESC
+-	REL relocations that had zero addends.  %ebx points to the
+-	caller's GOT.  %eax points to a TLS descriptor, such that
+-	0(%eax) holds the address of the resolver wrapper itself
+-	(unless some other thread beat us to it) and 4(%eax) holds a
+-	pointer to the relocation.
+-
+-	When the actual resolver returns, it will have adjusted the
+-	TLS descriptor such that we can tail-call it for it to return
+-	the TP offset of the symbol.  */
+-
+-	.hidden _dl_tlsdesc_resolve_rel
+-	.global	_dl_tlsdesc_resolve_rel
+-	.type	_dl_tlsdesc_resolve_rel,@function
+-	cfi_startproc
+-	.align 16
+-_dl_tlsdesc_resolve_rel:
+-0:
+-	_CET_ENDBR
+-	pushl	%eax
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%ecx
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%edx
+-	cfi_adjust_cfa_offset (4)
+-	movl	$1f - 0b, %ecx
+-	movl	4(%ebx), %edx
+-	call	_dl_tlsdesc_resolve_rel_fixup
+-1:
+-	popl	%edx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%ecx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%eax
+-	cfi_adjust_cfa_offset (-4)
+-	jmp	*(%eax)
+-	cfi_endproc
+-	.size	_dl_tlsdesc_resolve_rel, .-_dl_tlsdesc_resolve_rel
+-
+-     /* This function is a wrapper for a lazy resolver for TLS_DESC
+-	RELA relocations.  %ebx points to the caller's GOT.  %eax
+-	points to a TLS descriptor, such that 0(%eax) holds the
+-	address of the resolver wrapper itself (unless some other
+-	thread beat us to it) and 4(%eax) holds a pointer to the
+-	relocation.
+-
+-	When the actual resolver returns, it will have adjusted the
+-	TLS descriptor such that we can tail-call it for it to return
+-	the TP offset of the symbol.  */
+-
+-	.hidden _dl_tlsdesc_resolve_rela
+-	.global	_dl_tlsdesc_resolve_rela
+-	.type	_dl_tlsdesc_resolve_rela,@function
+-	cfi_startproc
+-	.align 16
+-_dl_tlsdesc_resolve_rela:
+-0:
+-	_CET_ENDBR
+-	pushl	%eax
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%ecx
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%edx
+-	cfi_adjust_cfa_offset (4)
+-	movl	$1f - 0b, %ecx
+-	movl	4(%ebx), %edx
+-	call	_dl_tlsdesc_resolve_rela_fixup
+-1:
+-	popl	%edx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%ecx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%eax
+-	cfi_adjust_cfa_offset (-4)
+-	jmp	*(%eax)
+-	cfi_endproc
+-	.size	_dl_tlsdesc_resolve_rela, .-_dl_tlsdesc_resolve_rela
+-
+-     /* This function is a placeholder for lazy resolving of TLS
+-	relocations.  Once some thread starts resolving a TLS
+-	relocation, it sets up the TLS descriptor to use this
+-	resolver, such that other threads that would attempt to
+-	resolve it concurrently may skip the call to the original lazy
+-	resolver and go straight to a condition wait.
+-
+-	When the actual resolver returns, it will have adjusted the
+-	TLS descriptor such that we can tail-call it for it to return
+-	the TP offset of the symbol.  */
+-
+-	.hidden _dl_tlsdesc_resolve_hold
+-	.global	_dl_tlsdesc_resolve_hold
+-	.type	_dl_tlsdesc_resolve_hold,@function
+-	cfi_startproc
+-	.align 16
+-_dl_tlsdesc_resolve_hold:
+-0:
+-	_CET_ENDBR
+-	pushl	%eax
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%ecx
+-	cfi_adjust_cfa_offset (4)
+-	pushl	%edx
+-	cfi_adjust_cfa_offset (4)
+-	movl	$1f - 0b, %ecx
+-	movl	4(%ebx), %edx
+-	call	_dl_tlsdesc_resolve_hold_fixup
+-1:
+-	popl	%edx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%ecx
+-	cfi_adjust_cfa_offset (-4)
+-	popl	%eax
+-	cfi_adjust_cfa_offset (-4)
+-	jmp	*(%eax)
+-	cfi_endproc
+-	.size	_dl_tlsdesc_resolve_hold, .-_dl_tlsdesc_resolve_hold
+diff --git a/sysdeps/i386/dl-tlsdesc.h b/sysdeps/i386/dl-tlsdesc.h
+index c8a1e056150dc418..1a1a22c303baf85b 100644
+--- a/sysdeps/i386/dl-tlsdesc.h
++++ b/sysdeps/i386/dl-tlsdesc.h
+@@ -43,11 +43,7 @@ struct tlsdesc_dynamic_arg
+ 
+ extern ptrdiff_t attribute_hidden __attribute__ ((regparm (1)))
+   _dl_tlsdesc_return (struct tlsdesc *),
+-  _dl_tlsdesc_undefweak (struct tlsdesc *),
+-  _dl_tlsdesc_resolve_abs_plus_addend (struct tlsdesc *),
+-  _dl_tlsdesc_resolve_rel (struct tlsdesc *),
+-  _dl_tlsdesc_resolve_rela (struct tlsdesc *),
+-  _dl_tlsdesc_resolve_hold (struct tlsdesc *);
++  _dl_tlsdesc_undefweak (struct tlsdesc *);
+ 
+ # ifdef SHARED
+ extern void *_dl_make_tlsdesc_dynamic (struct link_map *map,
+diff --git a/sysdeps/i386/tlsdesc.c b/sysdeps/i386/tlsdesc.c
+index 82fa8a1d35fd1912..1b4227c8381e1b3d 100644
+--- a/sysdeps/i386/tlsdesc.c
++++ b/sysdeps/i386/tlsdesc.c
+@@ -16,242 +16,13 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <link.h>
+ #include <ldsodefs.h>
+-#include <elf/dynamic-link.h>
+ #include <tls.h>
+ #include <dl-tlsdesc.h>
+ #include <dl-unmap-segments.h>
++#define _dl_tlsdesc_resolve_hold 0
+ #include <tlsdeschtab.h>
+ 
+-/* The following 4 functions take an entry_check_offset argument.
+-   It's computed by the caller as an offset between its entry point
+-   and the call site, such that by adding the built-in return address
+-   that is implicitly passed to the function with this offset, we can
+-   easily obtain the caller's entry point to compare with the entry
+-   point given in the TLS descriptor.  If it's changed, we want to
+-   return immediately.  */
+-
+-/* This function is used to lazily resolve TLS_DESC REL relocations
+-   that reference the *ABS* segment in their own link maps.  The
+-   argument is the addend originally stored there.  */
+-
+-void
+-__attribute__ ((regparm (3))) attribute_hidden
+-_dl_tlsdesc_resolve_abs_plus_addend_fixup (struct tlsdesc volatile *td,
+-					   struct link_map *l,
+-					   ptrdiff_t entry_check_offset)
+-{
+-  ptrdiff_t addend = (ptrdiff_t) td->arg;
+-
+-  if (_dl_tlsdesc_resolve_early_return_p (td, __builtin_return_address (0)
+-					  - entry_check_offset))
+-    return;
+-
+-#ifndef SHARED
+-  CHECK_STATIC_TLS (l, l);
+-#else
+-  if (!TRY_STATIC_TLS (l, l))
+-    {
+-      td->arg = _dl_make_tlsdesc_dynamic (l, addend);
+-      td->entry = _dl_tlsdesc_dynamic;
+-    }
+-  else
+-#endif
+-    {
+-      td->arg = (void*) (addend - l->l_tls_offset);
+-      td->entry = _dl_tlsdesc_return;
+-    }
+-
+-  _dl_tlsdesc_wake_up_held_fixups ();
+-}
+-
+-/* This function is used to lazily resolve TLS_DESC REL relocations
+-   that originally had zero addends.  The argument location, that
+-   originally held the addend, is used to hold a pointer to the
+-   relocation, but it has to be restored before we call the function
+-   that applies relocations.  */
+-
+-void
+-__attribute__ ((regparm (3))) attribute_hidden
+-_dl_tlsdesc_resolve_rel_fixup (struct tlsdesc volatile *td,
+-			       struct link_map *l,
+-			       ptrdiff_t entry_check_offset)
+-{
+-  const ElfW(Rel) *reloc = td->arg;
+-
+-  if (_dl_tlsdesc_resolve_early_return_p (td, __builtin_return_address (0)
+-					  - entry_check_offset))
+-    return;
+-
+-  /* The code below was borrowed from _dl_fixup(),
+-     except for checking for STB_LOCAL.  */
+-  const ElfW(Sym) *const symtab
+-    = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
+-  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
+-  const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+-  lookup_t result;
+-
+-   /* Look up the target symbol.  If the normal lookup rules are not
+-      used don't look in the global scope.  */
+-  if (ELFW(ST_BIND) (sym->st_info) != STB_LOCAL
+-      && __builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
+-    {
+-      const struct r_found_version *version = NULL;
+-
+-      if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+-	{
+-	  const ElfW(Half) *vernum =
+-	    (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
+-	  ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
+-	  version = &l->l_versions[ndx];
+-	  if (version->hash == 0)
+-	    version = NULL;
+-	}
+-
+-      result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
+-				    l->l_scope, version, ELF_RTYPE_CLASS_PLT,
+-				    DL_LOOKUP_ADD_DEPENDENCY, NULL);
+-    }
+-  else
+-    {
+-      /* We already found the symbol.  The module (and therefore its load
+-	 address) is also known.  */
+-      result = l;
+-    }
+-
+-  if (!sym)
+-    {
+-      td->arg = 0;
+-      td->entry = _dl_tlsdesc_undefweak;
+-    }
+-  else
+-    {
+-#  ifndef SHARED
+-      CHECK_STATIC_TLS (l, result);
+-#  else
+-      if (!TRY_STATIC_TLS (l, result))
+-	{
+-	  td->arg = _dl_make_tlsdesc_dynamic (result, sym->st_value);
+-	  td->entry = _dl_tlsdesc_dynamic;
+-	}
+-      else
+-#  endif
+-	{
+-	  td->arg = (void*)(sym->st_value - result->l_tls_offset);
+-	  td->entry = _dl_tlsdesc_return;
+-	}
+-    }
+-
+-  _dl_tlsdesc_wake_up_held_fixups ();
+-}
+-
+-/* This function is used to lazily resolve TLS_DESC RELA relocations.
+-   The argument location is used to hold a pointer to the relocation.  */
+-
+-void
+-__attribute__ ((regparm (3))) attribute_hidden
+-_dl_tlsdesc_resolve_rela_fixup (struct tlsdesc volatile *td,
+-				struct link_map *l,
+-				ptrdiff_t entry_check_offset)
+-{
+-  const ElfW(Rela) *reloc = td->arg;
+-
+-  if (_dl_tlsdesc_resolve_early_return_p (td, __builtin_return_address (0)
+-					  - entry_check_offset))
+-    return;
+-
+-  /* The code below was borrowed from _dl_fixup(),
+-     except for checking for STB_LOCAL.  */
+-  const ElfW(Sym) *const symtab
+-    = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
+-  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
+-  const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+-  lookup_t result;
+-
+-   /* Look up the target symbol.  If the normal lookup rules are not
+-      used don't look in the global scope.  */
+-  if (ELFW(ST_BIND) (sym->st_info) != STB_LOCAL
+-      && __builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
+-    {
+-      const struct r_found_version *version = NULL;
+-
+-      if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+-	{
+-	  const ElfW(Half) *vernum =
+-	    (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
+-	  ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
+-	  version = &l->l_versions[ndx];
+-	  if (version->hash == 0)
+-	    version = NULL;
+-	}
+-
+-      result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
+-				    l->l_scope, version, ELF_RTYPE_CLASS_PLT,
+-				    DL_LOOKUP_ADD_DEPENDENCY, NULL);
+-    }
+-  else
+-    {
+-      /* We already found the symbol.  The module (and therefore its load
+-	 address) is also known.  */
+-      result = l;
+-    }
+-
+-  if (!sym)
+-    {
+-      td->arg = (void*) reloc->r_addend;
+-      td->entry = _dl_tlsdesc_undefweak;
+-    }
+-  else
+-    {
+-#  ifndef SHARED
+-      CHECK_STATIC_TLS (l, result);
+-#  else
+-      if (!TRY_STATIC_TLS (l, result))
+-	{
+-	  td->arg = _dl_make_tlsdesc_dynamic (result, sym->st_value
+-					      + reloc->r_addend);
+-	  td->entry = _dl_tlsdesc_dynamic;
+-	}
+-      else
+-#  endif
+-	{
+-	  td->arg = (void*) (sym->st_value - result->l_tls_offset
+-			     + reloc->r_addend);
+-	  td->entry = _dl_tlsdesc_return;
+-	}
+-    }
+-
+-  _dl_tlsdesc_wake_up_held_fixups ();
+-}
+-
+-/* This function is used to avoid busy waiting for other threads to
+-   complete the lazy relocation.  Once another thread wins the race to
+-   relocate a TLS descriptor, it sets the descriptor up such that this
+-   function is called to wait until the resolver releases the
+-   lock.  */
+-
+-void
+-__attribute__ ((regparm (3))) attribute_hidden
+-_dl_tlsdesc_resolve_hold_fixup (struct tlsdesc volatile *td,
+-				struct link_map *l __attribute__((__unused__)),
+-				ptrdiff_t entry_check_offset)
+-{
+-  /* Maybe we're lucky and can return early.  */
+-  if (__builtin_return_address (0) - entry_check_offset != td->entry)
+-    return;
+-
+-  /* Locking here will stop execution until the running resolver runs
+-     _dl_tlsdesc_wake_up_held_fixups(), releasing the lock.
+-
+-     FIXME: We'd be better off waiting on a condition variable, such
+-     that we didn't have to hold the lock throughout the relocation
+-     processing.  */
+-  __rtld_lock_lock_recursive (GL(dl_load_lock));
+-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-}
+-
+-
+ /* Unmap the dynamic object, but also release its TLS descriptor table
+    if there is one.  */
+ 
diff --git a/SOURCES/glibc-rh2000374.patch b/SOURCES/glibc-rh2000374.patch
new file mode 100644
index 0000000..1d510ae
--- /dev/null
+++ b/SOURCES/glibc-rh2000374.patch
@@ -0,0 +1,205 @@
+Bug RHEL #2000374
+Bugs Upstream #24046, #25923
+
+This patch provides 12-hour time for the English language UTF-8 locale as a
+new locale en_US@ampm.UTF-8.
+
+Two upstream commits were applied to en_US to create the new file en_US@ampm:
+  Upstream commit: 7395f3a0efad9fc51bb54fa383ef6524702e0c49
+  Upstream commit: 8cde977077b3568310c743b21a905ca9ab286724
+
+en_US remains unchanged and the new file en_US@ampm is now supported.
+
+
+diff -Nrup a/localedata/locales/en_US@ampm b/localedata/locales/en_US@ampm
+--- a/localedata/locales/en_US@ampm	1969-12-31 19:00:00.000000000 -0500
++++ b/localedata/locales/en_US@ampm	2021-11-17 17:19:15.338720307 -0500
+@@ -0,0 +1,177 @@
++comment_char %
++escape_char /
++
++% This file is part of the GNU C Library and contains locale data.
++% The Free Software Foundation does not claim any copyright interest
++% in the locale data contained in this file.  The foregoing does not
++% affect the license of the GNU C Library as a whole.  It does not
++% exempt you from the conditions of the license if your use would
++% otherwise be governed by that license.
++
++% Locale for English locale in the USA
++% Contributed by Ulrich Drepper <drepper@redhat.com>, 2000
++
++LC_IDENTIFICATION
++title      "English locale for the USA"
++source     "Free Software Foundation, Inc."
++address    "http:////www.gnu.org//software//libc//"
++contact    ""
++email      "bug-glibc-locales@gnu.org"
++tel        ""
++fax        ""
++language   "American English"
++territory  "United States"
++revision   "1.0"
++date       "2000-06-24"
++
++category "i18n:2012";LC_IDENTIFICATION
++category "i18n:2012";LC_CTYPE
++category "i18n:2012";LC_COLLATE
++category "i18n:2012";LC_TIME
++category "i18n:2012";LC_NUMERIC
++category "i18n:2012";LC_MONETARY
++category "i18n:2012";LC_MESSAGES
++category "i18n:2012";LC_PAPER
++category "i18n:2012";LC_NAME
++category "i18n:2012";LC_ADDRESS
++category "i18n:2012";LC_TELEPHONE
++category "i18n:2012";LC_MEASUREMENT
++END LC_IDENTIFICATION
++
++LC_CTYPE
++copy "en_GB"
++END LC_CTYPE
++
++LC_COLLATE
++
++% Copy the template from ISO/IEC 14651
++copy "iso14651_t1"
++
++END LC_COLLATE
++
++LC_MONETARY
++int_curr_symbol     "USD "
++currency_symbol     "$"
++mon_decimal_point   "."
++mon_thousands_sep   ","
++mon_grouping        3;3
++positive_sign       ""
++negative_sign       "-"
++int_frac_digits     2
++frac_digits         2
++p_cs_precedes       1
++int_p_sep_by_space  1
++p_sep_by_space      0
++n_cs_precedes       1
++int_n_sep_by_space  1
++n_sep_by_space      0
++p_sign_posn         1
++n_sign_posn         1
++%
++END LC_MONETARY
++
++LC_NUMERIC
++decimal_point   "."
++thousands_sep   ","
++grouping        3;3
++END LC_NUMERIC
++
++LC_TIME
++abday	"Sun";"Mon";"Tue";"Wed";"Thu";"Fri";"Sat"
++day	"Sunday";/
++	"Monday";/
++	"Tuesday";/
++	"Wednesday";/
++	"Thursday";/
++	"Friday";/
++	"Saturday"
++
++week 7;19971130;1
++abmon	"Jan";"Feb";/
++	"Mar";"Apr";/
++	"May";"Jun";/
++	"Jul";"Aug";/
++	"Sep";"Oct";/
++	"Nov";"Dec"
++mon	"January";/
++	"February";/
++	"March";/
++	"April";/
++	"May";/
++	"June";/
++	"July";/
++	"August";/
++	"September";/
++	"October";/
++	"November";/
++	"December"
++% Appropriate date and time representation (%c)
++d_t_fmt "%a %d %b %Y %r %Z"
++%
++% Appropriate date representation (%x)
++d_fmt   "%m//%d//%Y"
++%
++% Appropriate time representation (%X)
++t_fmt   "%r"
++%
++% Appropriate AM/PM time representation (%r)
++t_fmt_ampm "%I:%M:%S %p"
++%
++% Appropriate date and time representation for date(1).  This is
++% different from d_t_fmt for historical reasons and has been different
++% since 2000 when date_fmt was added as a GNU extension.  At the end
++% of 2018 it was adjusted to use 12H time (bug 24046) instead of 24H.
++date_fmt "%a %b %e %r %Z %Y"
++%
++% Strings for AM/PM
++%
++am_pm	"AM";"PM"
++END LC_TIME
++
++LC_MESSAGES
++yesexpr "^[+1yY]"
++noexpr  "^[-0nN]"
++yesstr  "yes"
++nostr   "no"
++END LC_MESSAGES
++
++LC_PAPER
++height   279
++width    216
++END LC_PAPER
++
++LC_NAME
++name_fmt    "%d%t%g%t%m%t%f"
++name_miss   "Miss."
++name_mr     "Mr."
++name_mrs    "Mrs."
++name_ms     "Ms."
++END LC_NAME
++
++
++LC_ADDRESS
++postal_fmt    "%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N"
++country_name "United States"
++country_post  "USA"
++country_ab2   "US"
++country_ab3   "USA"
++country_num   840
++country_car   "USA"
++country_isbn  0
++lang_name     "English"
++lang_ab      "en"
++lang_term    "eng"
++lang_lib    "eng"
++END LC_ADDRESS
++
++LC_TELEPHONE
++tel_int_fmt    "+%c (%a) %l"
++tel_dom_fmt    "(%a) %l"
++int_select     "11"
++int_prefix     "1"
++END LC_TELEPHONE
++
++LC_MEASUREMENT
++% US customary units.
++measurement 2
++END LC_MEASUREMENT
+diff -Nrup a/localedata/SUPPORTED b/localedata/SUPPORTED
+--- a/localedata/SUPPORTED	2021-11-17 17:14:33.831631483 -0500
++++ b/localedata/SUPPORTED	2021-11-17 17:21:16.418188595 -0500
+@@ -159,6 +159,7 @@ en_SG/ISO-8859-1 \
+ en_US.UTF-8/UTF-8 \
+ en_US/ISO-8859-1 \
+ en_US.ISO-8859-15/ISO-8859-15 \
++en_US@ampm.UTF-8/UTF-8 \
+ en_ZA.UTF-8/UTF-8 \
+ en_ZA/ISO-8859-1 \
+ en_ZM/UTF-8 \
diff --git a/SOURCES/glibc-rh2007327-1.patch b/SOURCES/glibc-rh2007327-1.patch
new file mode 100644
index 0000000..2c6379e
--- /dev/null
+++ b/SOURCES/glibc-rh2007327-1.patch
@@ -0,0 +1,92 @@
+commit 28c30a6232aa9a54783c146590498a061fc0112a
+Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Date:   Sun Feb 9 19:50:21 2020 +0000
+
+    pthread: Move most once tests from nptl to sysdeps/pthread
+    
+    So they can be checked with htl too.
+
+# Conflicts:
+#	sysdeps/pthread/Makefile
+#	(Moved only the tests in this commit which subsequently
+#	 needed for the pthread_once fix)
+
+diff --git a/nptl/Makefile b/nptl/Makefile
+index b14de3ffb330c10b..dcf3868869767015 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -260,7 +260,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
+ 	tst-rwlock4 tst-rwlock5 tst-rwlock6 tst-rwlock7 tst-rwlock8 \
+ 	tst-rwlock9 tst-rwlock10 tst-rwlock11 tst-rwlock12 tst-rwlock13 \
+ 	tst-rwlock14 tst-rwlock15 tst-rwlock16 tst-rwlock17 tst-rwlock18 \
+-	tst-once1 tst-once2 tst-once3 tst-once4 tst-once5 \
++	tst-once5 \
+ 	tst-key1 tst-key2 tst-key3 tst-key4 \
+ 	tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
+ 	tst-sem8 tst-sem9 tst-sem10 tst-sem14 \
+@@ -384,8 +384,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
+ 	 tst-cancelx6 tst-cancelx7 tst-cancelx8 tst-cancelx9 tst-cancelx10 \
+ 	 tst-cancelx11 tst-cancelx12 tst-cancelx13 tst-cancelx14 tst-cancelx15 \
+ 	 tst-cancelx16 tst-cancelx17 tst-cancelx18 tst-cancelx20 tst-cancelx21 \
+-	 tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \
+-	 tst-oncex3 tst-oncex4
++	 tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4
+ ifeq ($(build-shared),yes)
+ tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \
+ 	 tst-audit-threads
+@@ -525,8 +524,6 @@ CFLAGS-tst-cleanupx2.c += -fexceptions
+ CFLAGS-tst-cleanupx3.c += -fexceptions
+ CFLAGS-tst-cleanupx4.c += -fexceptions
+ CFLAGS-tst-cleanupx4aux.c += -fexceptions
+-CFLAGS-tst-oncex3.c += -fexceptions
+-CFLAGS-tst-oncex4.c += -fexceptions
+ CFLAGS-tst-align.c += $(stack-align-test-flags)
+ CFLAGS-tst-align3.c += $(stack-align-test-flags)
+ CFLAGS-tst-initializers1.c += -W -Wall -Werror
+diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
+index 98a92f8d6bb119ba..14ef04247cb84ad3 100644
+--- a/sysdeps/pthread/Makefile
++++ b/sysdeps/pthread/Makefile
+@@ -33,11 +33,18 @@ endif
+ 
+ tst-create1mod.so-no-z-defs = yes
+ 
++tests += tst-once1 tst-once2 tst-once3 tst-once4
++
++tests += tst-oncex3 tst-oncex4
++
+ ifeq ($(build-shared),yes)
+ # Build all the modules even when not actually running test programs.
+ tests: $(test-modules)
+ endif
+ 
++CFLAGS-tst-oncex3.c += -fexceptions
++CFLAGS-tst-oncex4.c += -fexceptions
++
+ modules-names += tst-create1mod
+ test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
+ 
+diff --git a/nptl/tst-once1.c b/sysdeps/pthread/tst-once1.c
+similarity index 100%
+rename from nptl/tst-once1.c
+rename to sysdeps/pthread/tst-once1.c
+diff --git a/nptl/tst-once2.c b/sysdeps/pthread/tst-once2.c
+similarity index 100%
+rename from nptl/tst-once2.c
+rename to sysdeps/pthread/tst-once2.c
+diff --git a/nptl/tst-once3.c b/sysdeps/pthread/tst-once3.c
+similarity index 100%
+rename from nptl/tst-once3.c
+rename to sysdeps/pthread/tst-once3.c
+diff --git a/nptl/tst-once4.c b/sysdeps/pthread/tst-once4.c
+similarity index 100%
+rename from nptl/tst-once4.c
+rename to sysdeps/pthread/tst-once4.c
+diff --git a/nptl/tst-oncex3.c b/sysdeps/pthread/tst-oncex3.c
+similarity index 100%
+rename from nptl/tst-oncex3.c
+rename to sysdeps/pthread/tst-oncex3.c
+diff --git a/nptl/tst-oncex4.c b/sysdeps/pthread/tst-oncex4.c
+similarity index 100%
+rename from nptl/tst-oncex4.c
+rename to sysdeps/pthread/tst-oncex4.c
diff --git a/SOURCES/glibc-rh2007327-2.patch b/SOURCES/glibc-rh2007327-2.patch
new file mode 100644
index 0000000..29e67f9
--- /dev/null
+++ b/SOURCES/glibc-rh2007327-2.patch
@@ -0,0 +1,200 @@
+commit f0419e6a10740a672b28e112c409ae24f5e890ab
+Author: Jakub Jelinek <jakub@redhat.com>
+Date:   Thu Mar 4 15:15:33 2021 +0100
+
+    [PATCH] pthread_once hangs when init routine throws an exception [BZ #18435]
+    
+    This is another attempt at making pthread_once handle throwing exceptions
+    from the init routine callback.  As the new testcases show, just switching
+    to the cleanup attribute based cleanup does fix the tst-once5 test, but
+    breaks the new tst-oncey3 test.  That is because when throwing exceptions,
+    only the unwind info registered cleanups (i.e. C++ destructors or cleanup
+    attribute), when cancelling threads and there has been unwind info from the
+    cancellation point up to whatever needs cleanup both unwind info registered
+    cleanups and THREAD_SETMEM (self, cleanup, ...) registered cleanups are
+    invoked, but once we hit some frame with no unwind info, only the
+    THREAD_SETMEM (self, cleanup, ...) registered cleanups are invoked.
+    So, to stay fully backwards compatible (allow init routines without
+    unwind info which encounter cancellation points) and handle exception throwing
+    we actually need to register the pthread_once cleanups in both unwind info
+    and in the THREAD_SETMEM (self, cleanup, ...) way.
+    If an exception is thrown, only the former will happen and we in that case
+    need to also unregister the THREAD_SETMEM (self, cleanup, ...) registered
+    handler, because otherwise after catching the exception the user code could
+    call deeper into the stack some cancellation point, get cancelled and then
+    a stale cleanup handler would clobber stack and probably crash.
+    If a thread calling init routine is cancelled and unwind info ends before
+    the pthread_once frame, it will be cleaned up through self->cleanup as
+    before.  And if unwind info is present, unwind_stop first calls the
+    self->cleanup registered handler for the frame, then it will call the
+    unwind info registered handler but that will already see __do_it == 0
+    and do nothing.
+
+# Conflicts:
+#	nptl/Makefile
+#	(The usual cleanups because they don't match.)
+#	sysdeps/pthread/Makefile
+#	(The usual cleanups because all the other tests aren't moved.)
+
+diff --git a/nptl/Makefile b/nptl/Makefile
+index dcf3868869767015..70a3be23ecfcd9c9 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -334,10 +334,6 @@ xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
+ 	tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
+ test-srcs = tst-oddstacklimit
+ 
+-# Test expected to fail on most targets (except x86_64) due to bug
+-# 18435 - pthread_once hangs when init routine throws an exception.
+-test-xfail-tst-once5 = yes
+-
+ # Files which must not be linked with libpthread.
+ tests-nolibpthread = tst-unload
+ 
+diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
+index a2d48b2015cd385c..7ddc166cf32414c4 100644
+--- a/nptl/pthreadP.h
++++ b/nptl/pthreadP.h
+@@ -571,6 +571,67 @@ extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
+ # undef pthread_cleanup_pop
+ # define pthread_cleanup_pop(execute)                   \
+   __pthread_cleanup_pop (&_buffer, (execute)); }
++
++# if defined __EXCEPTIONS && !defined __cplusplus
++/* Structure to hold the cleanup handler information.  */
++struct __pthread_cleanup_combined_frame
++{
++  void (*__cancel_routine) (void *);
++  void *__cancel_arg;
++  int __do_it;
++  struct _pthread_cleanup_buffer __buffer;
++};
++
++/* Special cleanup macros which register cleanup both using
++   __pthread_cleanup_{push,pop} and using cleanup attribute.  This is needed
++   for pthread_once, so that it supports both throwing exceptions from the
++   pthread_once callback (only cleanup attribute works there) and cancellation
++   of the thread running the callback if the callback or some routines it
++   calls don't have unwind information.  */
++
++static __always_inline void
++__pthread_cleanup_combined_routine (struct __pthread_cleanup_combined_frame
++				    *__frame)
++{
++  if (__frame->__do_it)
++    {
++      __frame->__cancel_routine (__frame->__cancel_arg);
++      __frame->__do_it = 0;
++      __pthread_cleanup_pop (&__frame->__buffer, 0);
++    }
++}
++
++static inline void
++__pthread_cleanup_combined_routine_voidptr (void *__arg)
++{
++  struct __pthread_cleanup_combined_frame *__frame
++    = (struct __pthread_cleanup_combined_frame *) __arg;
++  if (__frame->__do_it)
++    {
++      __frame->__cancel_routine (__frame->__cancel_arg);
++      __frame->__do_it = 0;
++    }
++}
++
++#  define pthread_cleanup_combined_push(routine, arg) \
++  do {									      \
++    void (*__cancel_routine) (void *) = (routine);			      \
++    struct __pthread_cleanup_combined_frame __clframe			      \
++      __attribute__ ((__cleanup__ (__pthread_cleanup_combined_routine)))      \
++      = { .__cancel_routine = __cancel_routine, .__cancel_arg = (arg),	      \
++	  .__do_it = 1 };						      \
++    __pthread_cleanup_push (&__clframe.__buffer,			      \
++			    __pthread_cleanup_combined_routine_voidptr,	      \
++			    &__clframe);
++
++#  define pthread_cleanup_combined_pop(execute) \
++    __pthread_cleanup_pop (&__clframe.__buffer, 0);			      \
++    __clframe.__do_it = 0;						      \
++    if (execute)							      \
++      __cancel_routine (__clframe.__cancel_arg);			      \
++  } while (0)
++
++# endif
+ #endif
+ 
+ extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
+diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
+index 1653226286dc3539..45e965e8743d9412 100644
+--- a/nptl/pthread_once.c
++++ b/nptl/pthread_once.c
+@@ -111,11 +111,11 @@ __pthread_once_slow (pthread_once_t *once_control, void (*init_routine) (void))
+       /* This thread is the first here.  Do the initialization.
+ 	 Register a cleanup handler so that in case the thread gets
+ 	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
++      pthread_cleanup_combined_push (clear_once_control, once_control);
+ 
+       init_routine ();
+ 
+-      pthread_cleanup_pop (0);
++      pthread_cleanup_combined_pop (0);
+ 
+ 
+       /* Mark *once_control as having finished the initialization.  We need
+diff --git a/nptl/tst-once5.cc b/nptl/tst-once5.cc
+index d232266c3ace89d9..dda18e610c9114bc 100644
+--- a/nptl/tst-once5.cc
++++ b/nptl/tst-once5.cc
+@@ -59,7 +59,7 @@ do_test (void)
+                " throwing an exception", stderr);
+     }
+     catch (OnceException) {
+-      if (1 < niter)
++      if (niter > 1)
+         fputs ("pthread_once unexpectedly threw", stderr);
+       result = 0;
+     }
+@@ -75,7 +75,5 @@ do_test (void)
+   return result;
+ }
+ 
+-// The test currently hangs and is XFAILed.  Reduce the timeout.
+-#define TIMEOUT 1
+ #define TEST_FUNCTION do_test ()
+ #include "../test-skeleton.c"
+diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
+index 14ef04247cb84ad3..80a71f3f9f0e72ae 100644
+--- a/sysdeps/pthread/Makefile
++++ b/sysdeps/pthread/Makefile
+@@ -35,7 +35,7 @@ tst-create1mod.so-no-z-defs = yes
+ 
+ tests += tst-once1 tst-once2 tst-once3 tst-once4
+ 
+-tests += tst-oncex3 tst-oncex4
++tests += tst-oncex3 tst-oncex4 tst-oncey3 tst-oncey4
+ 
+ ifeq ($(build-shared),yes)
+ # Build all the modules even when not actually running test programs.
+@@ -44,6 +44,8 @@ endif
+ 
+ CFLAGS-tst-oncex3.c += -fexceptions
+ CFLAGS-tst-oncex4.c += -fexceptions
++CFLAGS-tst-oncey3.c += -fno-exceptions -fno-asynchronous-unwind-tables
++CFLAGS-tst-oncey4.c += -fno-exceptions -fno-asynchronous-unwind-tables
+ 
+ modules-names += tst-create1mod
+ test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
+diff --git a/sysdeps/pthread/tst-oncey3.c b/sysdeps/pthread/tst-oncey3.c
+new file mode 100644
+index 0000000000000000..08225b88dc06b979
+--- /dev/null
++++ b/sysdeps/pthread/tst-oncey3.c
+@@ -0,0 +1 @@
++#include "tst-once3.c"
+diff --git a/sysdeps/pthread/tst-oncey4.c b/sysdeps/pthread/tst-oncey4.c
+new file mode 100644
+index 0000000000000000..9b4d98f3f13c265a
+--- /dev/null
++++ b/sysdeps/pthread/tst-oncey4.c
+@@ -0,0 +1 @@
++#include "tst-once4.c"
diff --git a/SOURCES/glibc-rh2021452.patch b/SOURCES/glibc-rh2021452.patch
new file mode 100644
index 0000000..3dad2df
--- /dev/null
+++ b/SOURCES/glibc-rh2021452.patch
@@ -0,0 +1,40 @@
+commit 98966749f2b418825ff2ea496a0ee89fe63d2cc8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Nov 10 15:21:37 2021 +0100
+
+    s390: Use long branches across object boundaries (jgh instead of jh)
+    
+    Depending on the layout chosen by the linker, the 16-bit displacement
+    of the jh instruction is insufficient to reach the target label.
+    
+    Analysis of the linker failure was carried out by Nick Clifton.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    Reviewed-by: Stefan Liebler <stli@linux.ibm.com>
+
+diff --git a/sysdeps/s390/memmem-arch13.S b/sysdeps/s390/memmem-arch13.S
+index b59d60acf0f6aaa0..4faede0cd2f942e3 100644
+--- a/sysdeps/s390/memmem-arch13.S
++++ b/sysdeps/s390/memmem-arch13.S
+@@ -41,7 +41,7 @@ ENTRY(MEMMEM_ARCH13)
+ #  error The arch13 variant of memmem needs the z13 variant of memmem!
+ # endif
+ 	clgfi	%r5,9
+-	jh	MEMMEM_Z13
++	jgh	MEMMEM_Z13
+ 
+ 	aghik	%r0,%r5,-1		/* vll needs highest index.  */
+ 	bc	4,0(%r14)		/* cc==1: return if needle-len == 0.  */
+diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S
+index faa969849e09c2e1..ffc34c2523ce635a 100644
+--- a/sysdeps/s390/strstr-arch13.S
++++ b/sysdeps/s390/strstr-arch13.S
+@@ -49,7 +49,7 @@ ENTRY(STRSTR_ARCH13)
+ #  error The arch13 variant of strstr needs the z13 variant of strstr!
+ # endif
+ 	clgfi	%r4,9
+-	jh	STRSTR_Z13
++	jgh	STRSTR_Z13
+ 
+ 	/* In case of a partial match, the vstrs instruction returns the index
+ 	   of the partial match in a vector-register.  Then we have to
diff --git a/SOURCES/glibc-rh2023420-1.patch b/SOURCES/glibc-rh2023420-1.patch
new file mode 100644
index 0000000..3b8d299
--- /dev/null
+++ b/SOURCES/glibc-rh2023420-1.patch
@@ -0,0 +1,304 @@
+commit 86f65dffc2396d408beb628f1cad2b8f63e197bd
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Sun Jul 12 06:04:53 2020 -0700
+
+    ld.so: Add --list-tunables to print tunable values
+    
+    Pass --list-tunables to ld.so to print tunables with min and max values.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+Conflicts:
+	elf/Makefile
+	  (different backporting order)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 3e71939d3234c4c3..aa65ec59f143bccf 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -44,6 +44,10 @@ dl-routines += dl-tunables
+ tunables-type = $(addprefix TUNABLES_FRONTEND_,$(have-tunables))
+ CPPFLAGS-dl-tunables.c += -DTUNABLES_FRONTEND=$(tunables-type)
+ 
++ifeq (yesyes,$(build-shared)$(run-built-tests))
++tests-special += $(objpfx)list-tunables.out
++endif
++
+ # Make sure that the compiler does not insert any library calls in tunables
+ # code paths.
+ ifeq (yes,$(have-loop-to-function))
+@@ -1825,6 +1829,13 @@ $(objpfx)tst-glibc-hwcaps-mask.out: \
+ # tst-glibc-hwcaps-cache.
+ $(objpfx)tst-glibc-hwcaps-cache.out: $(objpfx)tst-glibc-hwcaps
+ 
++$(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so
++	$(SHELL) $< $(objpfx)ld.so '$(test-wrapper-env)' \
++	    '$(run_program_env)' > $(objpfx)/tst-rtld-list-tunables.out
++	cmp tst-rtld-list-tunables.exp \
++	    $(objpfx)/tst-rtld-list-tunables.out > $@; \
++	$(evaluate-test)
++
+ tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN'
+ 
+ $(objpfx)tst-rtld-help.out: $(objpfx)ld.so
+diff --git a/elf/dl-main.h b/elf/dl-main.h
+index 566713a0d10cfdb7..9e7b51d8f010e904 100644
+--- a/elf/dl-main.h
++++ b/elf/dl-main.h
+@@ -63,7 +63,7 @@ struct audit_list
+ enum rtld_mode
+   {
+     rtld_mode_normal, rtld_mode_list, rtld_mode_verify, rtld_mode_trace,
+-    rtld_mode_help,
++    rtld_mode_list_tunables, rtld_mode_help,
+   };
+ 
+ /* Aggregated state information extracted from environment variables
+diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
+index bbc3679e3564a766..3c84809d44381241 100644
+--- a/elf/dl-tunables.c
++++ b/elf/dl-tunables.c
+@@ -26,6 +26,7 @@
+ #include <sysdep.h>
+ #include <fcntl.h>
+ #include <ldsodefs.h>
++#include <array_length.h>
+ 
+ #define TUNABLES_INTERNAL 1
+ #include "dl-tunables.h"
+@@ -359,6 +360,48 @@ __tunables_init (char **envp)
+     }
+ }
+ 
++void
++__tunables_print (void)
++{
++  for (int i = 0; i < array_length (tunable_list); i++)
++    {
++      const tunable_t *cur = &tunable_list[i];
++      if (cur->type.type_code == TUNABLE_TYPE_STRING
++	  && cur->val.strval == NULL)
++	_dl_printf ("%s:\n", cur->name);
++      else
++	{
++	  _dl_printf ("%s: ", cur->name);
++	  switch (cur->type.type_code)
++	    {
++	    case TUNABLE_TYPE_INT_32:
++	      _dl_printf ("%d (min: %d, max: %d)\n",
++			  (int) cur->val.numval,
++			  (int) cur->type.min,
++			  (int) cur->type.max);
++	      break;
++	    case TUNABLE_TYPE_UINT_64:
++	      _dl_printf ("0x%lx (min: 0x%lx, max: 0x%lx)\n",
++			  (long int) cur->val.numval,
++			  (long int) cur->type.min,
++			  (long int) cur->type.max);
++	      break;
++	    case TUNABLE_TYPE_SIZE_T:
++	      _dl_printf ("0x%Zx (min: 0x%Zx, max: 0x%Zx)\n",
++			  (size_t) cur->val.numval,
++			  (size_t) cur->type.min,
++			  (size_t) cur->type.max);
++	      break;
++	    case TUNABLE_TYPE_STRING:
++	      _dl_printf ("%s\n", cur->val.strval);
++	      break;
++	    default:
++	      __builtin_unreachable ();
++	    }
++	}
++    }
++}
++
+ /* Set the tunable value.  This is called by the module that the tunable exists
+    in. */
+ void
+diff --git a/elf/dl-tunables.h b/elf/dl-tunables.h
+index 7f181f3316cd9fc1..f4f2cfaeb9828599 100644
+--- a/elf/dl-tunables.h
++++ b/elf/dl-tunables.h
+@@ -69,9 +69,11 @@ typedef struct _tunable tunable_t;
+ # include "dl-tunable-list.h"
+ 
+ extern void __tunables_init (char **);
++extern void __tunables_print (void);
+ extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
+ extern void __tunable_set_val (tunable_id_t, void *);
+ rtld_hidden_proto (__tunables_init)
++rtld_hidden_proto (__tunables_print)
+ rtld_hidden_proto (__tunable_get_val)
+ 
+ /* Define TUNABLE_GET and TUNABLE_SET in short form if TOP_NAMESPACE and
+diff --git a/elf/dl-usage.c b/elf/dl-usage.c
+index e22a9c39427187d1..908b4894b3014b2d 100644
+--- a/elf/dl-usage.c
++++ b/elf/dl-usage.c
+@@ -255,7 +255,12 @@ setting environment variables (which would be inherited by subprocesses).\n\
+                         in LIST\n\
+   --audit LIST          use objects named in LIST as auditors\n\
+   --preload LIST        preload objects named in LIST\n\
+-  --argv0 STRING        set argv[0] to STRING before running\n\
++  --argv0 STRING        set argv[0] to STRING before running\n"
++#if HAVE_TUNABLES
++"\
++  --list-tunables       list all tunables with minimum and maximum values\n"
++#endif
++"\
+   --help                display this help and exit\n\
+   --version             output version information and exit\n\
+ \n\
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 9e09896da078274d..54b621ec5ca014fa 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -47,6 +47,7 @@
+ #include <libc-early-init.h>
+ #include <dl-main.h>
+ #include <gnu/lib-names.h>
++#include <dl-tunables.h>
+ 
+ #include <assert.h>
+ 
+@@ -1262,6 +1263,16 @@ dl_main (const ElfW(Phdr) *phdr,
+ 	    _dl_argc -= 2;
+ 	    _dl_argv += 2;
+ 	  }
++#if HAVE_TUNABLES
++	else if (! strcmp (_dl_argv[1], "--list-tunables"))
++	  {
++	    state.mode = rtld_mode_list_tunables;
++
++	    ++_dl_skip_args;
++	    --_dl_argc;
++	    ++_dl_argv;
++	  }
++#endif
+ 	else if (strcmp (_dl_argv[1], "--help") == 0)
+ 	  {
+ 	    state.mode = rtld_mode_help;
+@@ -1282,6 +1293,14 @@ dl_main (const ElfW(Phdr) *phdr,
+ 	else
+ 	  break;
+ 
++#if HAVE_TUNABLES
++      if (__glibc_unlikely (state.mode == rtld_mode_list_tunables))
++	{
++	  __tunables_print ();
++	  _exit (0);
++	}
++#endif
++
+       /* If we have no further argument the program was called incorrectly.
+ 	 Grant the user some education.  */
+       if (_dl_argc < 2)
+diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
+new file mode 100644
+index 0000000000000000..4f3f7ee4e30a2b42
+--- /dev/null
++++ b/elf/tst-rtld-list-tunables.exp
+@@ -0,0 +1,14 @@
++glibc.malloc.arena_max: 0x0 (min: 0x1, max: 0x[f]+)
++glibc.malloc.arena_test: 0x0 (min: 0x1, max: 0x[f]+)
++glibc.malloc.check: 0 (min: 0, max: 3)
++glibc.malloc.mmap_max: 0 (min: -2147483648, max: 2147483647)
++glibc.malloc.mmap_threshold: 0x0 (min: 0x0, max: 0x[f]+)
++glibc.malloc.mxfast: 0x0 (min: 0x0, max: 0x[f]+)
++glibc.malloc.perturb: 0 (min: 0, max: 255)
++glibc.malloc.tcache_count: 0x0 (min: 0x0, max: 0x[f]+)
++glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
++glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
++glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+)
++glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
++glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
++glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
+diff --git a/elf/tst-rtld-list-tunables.sh b/elf/tst-rtld-list-tunables.sh
+new file mode 100755
+index 0000000000000000..e7bbdde94952b872
+--- /dev/null
++++ b/elf/tst-rtld-list-tunables.sh
+@@ -0,0 +1,34 @@
++#!/bin/sh
++# Test for --list-tunables option ld.so.
++# 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/>.
++
++set -e
++
++rtld=$1
++test_wrapper_env=$2
++run_program_env=$3
++
++LC_ALL=C
++export LC_ALL
++
++${test_wrapper_env} \
++${run_program_env} \
++$rtld --list-tunables \
++| sort -u \
++| egrep "(rtld|malloc)" \
++| sed -e "s/0xf\+/0x[f]+/"
+diff --git a/manual/tunables.texi b/manual/tunables.texi
+index 07887981748bc44b..43272cf885d1e3e6 100644
+--- a/manual/tunables.texi
++++ b/manual/tunables.texi
+@@ -28,6 +28,44 @@ Finally, the set of tunables available may vary between distributions as
+ the tunables feature allows distributions to add their own tunables under
+ their own namespace.
+ 
++Passing @option{--list-tunables} to the dynamic loader to print all
++tunables with minimum and maximum values:
++
++@example
++$ /lib64/ld-linux-x86-64.so.2 --list-tunables
++glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
++glibc.elision.skip_lock_after_retries: 3 (min: -2147483648, max: 2147483647)
++glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0xffffffffffffffff)
++glibc.malloc.perturb: 0 (min: 0, max: 255)
++glibc.cpu.x86_shared_cache_size: 0x100000 (min: 0x0, max: 0xffffffffffffffff)
++glibc.mem.tagging: 0 (min: 0, max: 255)
++glibc.elision.tries: 3 (min: -2147483648, max: 2147483647)
++glibc.elision.enable: 0 (min: 0, max: 1)
++glibc.cpu.x86_rep_movsb_threshold: 0x1000 (min: 0x100, max: 0xffffffffffffffff)
++glibc.malloc.mxfast: 0x0 (min: 0x0, max: 0xffffffffffffffff)
++glibc.elision.skip_lock_busy: 3 (min: -2147483648, max: 2147483647)
++glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0xffffffffffffffff)
++glibc.cpu.x86_rep_stosb_threshold: 0x800 (min: 0x1, max: 0xffffffffffffffff)
++glibc.cpu.x86_non_temporal_threshold: 0xc0000 (min: 0x0, max: 0xffffffffffffffff)
++glibc.cpu.x86_shstk:
++glibc.cpu.hwcap_mask: 0x6 (min: 0x0, max: 0xffffffffffffffff)
++glibc.malloc.mmap_max: 0 (min: -2147483648, max: 2147483647)
++glibc.elision.skip_trylock_internal_abort: 3 (min: -2147483648, max: 2147483647)
++glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0xffffffffffffffff)
++glibc.cpu.x86_ibt:
++glibc.cpu.hwcaps:
++glibc.elision.skip_lock_internal_abort: 3 (min: -2147483648, max: 2147483647)
++glibc.malloc.arena_max: 0x0 (min: 0x1, max: 0xffffffffffffffff)
++glibc.malloc.mmap_threshold: 0x0 (min: 0x0, max: 0xffffffffffffffff)
++glibc.cpu.x86_data_cache_size: 0x8000 (min: 0x0, max: 0xffffffffffffffff)
++glibc.malloc.tcache_count: 0x0 (min: 0x0, max: 0xffffffffffffffff)
++glibc.malloc.arena_test: 0x0 (min: 0x1, max: 0xffffffffffffffff)
++glibc.pthread.mutex_spin_count: 100 (min: 0, max: 32767)
++glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0xffffffffffffffff)
++glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0xffffffffffffffff)
++glibc.malloc.check: 0 (min: 0, max: 3)
++@end example
++
+ @menu
+ * Tunable names::  The structure of a tunable name
+ * Memory Allocation Tunables::  Tunables in the memory allocation subsystem
diff --git a/SOURCES/glibc-rh2023420-2.patch b/SOURCES/glibc-rh2023420-2.patch
new file mode 100644
index 0000000..23e3da5
--- /dev/null
+++ b/SOURCES/glibc-rh2023420-2.patch
@@ -0,0 +1,30 @@
+commit d2d12c7a988a9a04aec23b5e4af549db61b0a005
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Tue Feb 2 09:31:56 2021 -0800
+
+    tst-rtld-list-tunables.sh: Unset glibc tunables
+    
+    Unset glibc tunables and their aliases for --list-tunables test.
+
+diff --git a/elf/tst-rtld-list-tunables.sh b/elf/tst-rtld-list-tunables.sh
+index e7bbdde94952b872..78f4ed2ebbd3db2c 100755
+--- a/elf/tst-rtld-list-tunables.sh
++++ b/elf/tst-rtld-list-tunables.sh
+@@ -26,6 +26,17 @@ run_program_env=$3
+ LC_ALL=C
+ export LC_ALL
+ 
++# Unset tunables and their aliases.
++GLIBC_TUNABLES=
++MALLOC_ARENA_MAX=
++MALLOC_ARENA_TEST=
++MALLOC_CHECK_=
++MALLOC_MMAP_MAX_=
++MALLOC_MMAP_THRESHOLD_=
++MALLOC_PERTURB_=
++MALLOC_TOP_PAD_=
++MALLOC_TRIM_THRESHOLD_=
++
+ ${test_wrapper_env} \
+ ${run_program_env} \
+ $rtld --list-tunables \
diff --git a/SOURCES/glibc-rh2023420-3.patch b/SOURCES/glibc-rh2023420-3.patch
new file mode 100644
index 0000000..1e8307c
--- /dev/null
+++ b/SOURCES/glibc-rh2023420-3.patch
@@ -0,0 +1,578 @@
+commit 851f32cf7bf7067f73b991610778915edd57d7b4
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Mar 2 14:38:42 2021 +0100
+
+    ld.so: Implement the --list-diagnostics option
+
+diff --git a/elf/Makefile b/elf/Makefile
+index aa65ec59f143bccf..d246f1c0d9e019fd 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -64,7 +64,7 @@ elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
+ # interpreter and operating independent of libc.
+ rtld-routines	= rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \
+   dl-error-minimal dl-conflict dl-hwcaps dl-hwcaps_split dl-hwcaps-subdirs \
+-  dl-usage
++  dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu
+ all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
+ 
+ CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables
+@@ -672,6 +672,9 @@ CFLAGS-cache.c += $(SYSCONF-FLAGS)
+ CFLAGS-rtld.c += $(SYSCONF-FLAGS)
+ CFLAGS-dl-usage.c += $(SYSCONF-FLAGS) \
+   -D'RTLD="$(rtlddir)/$(rtld-installed-name)"'
++CFLAGS-dl-diagnostics.c += $(SYSCONF-FLAGS) \
++  -D'PREFIX="$(prefix)"' \
++  -D'RTLD="$(rtlddir)/$(rtld-installed-name)"'
+ 
+ cpp-srcs-left := $(all-rtld-routines:=.os)
+ lib := rtld
+diff --git a/elf/dl-diagnostics-cpu.c b/elf/dl-diagnostics-cpu.c
+new file mode 100644
+index 0000000000000000..f7d149764bcb35a1
+--- /dev/null
++++ b/elf/dl-diagnostics-cpu.c
+@@ -0,0 +1,24 @@
++/* Print CPU diagnostics data in ld.so.  Stub version.
++   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 <dl-diagnostics.h>
++
++void
++_dl_diagnostics_cpu (void)
++{
++}
+diff --git a/elf/dl-diagnostics-kernel.c b/elf/dl-diagnostics-kernel.c
+new file mode 100644
+index 0000000000000000..831c358f1463cbf4
+--- /dev/null
++++ b/elf/dl-diagnostics-kernel.c
+@@ -0,0 +1,24 @@
++/* Print kernel diagnostics data in ld.so.  Stub version.
++   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 <dl-diagnostics.h>
++
++void
++_dl_diagnostics_kernel (void)
++{
++}
+diff --git a/elf/dl-diagnostics.c b/elf/dl-diagnostics.c
+new file mode 100644
+index 0000000000000000..bef224b36cbf5fc3
+--- /dev/null
++++ b/elf/dl-diagnostics.c
+@@ -0,0 +1,265 @@
++/* Print diagnostics data in ld.so.
++   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 <gnu/lib-names.h>
++#include <stdbool.h>
++#include <stddef.h>
++#include <unistd.h>
++
++#include <dl-diagnostics.h>
++#include <dl-hwcaps.h>
++#include <dl-main.h>
++#include <dl-procinfo.h>
++#include <dl-sysdep.h>
++#include <ldsodefs.h>
++#include "trusted-dirs.h"
++#include "version.h"
++
++/* Write CH to standard output.  */
++static void
++_dl_putc (char ch)
++{
++  _dl_write (STDOUT_FILENO, &ch, 1);
++}
++
++/* Print CH to standard output, quoting it if necessary.  */
++static void
++print_quoted_char (char ch)
++{
++  if (ch < ' ' || ch > '~')
++    {
++      char buf[4];
++      buf[0] = '\\';
++      buf[1] = '0' + ((ch >> 6) & 7);
++      buf[2] = '0' + ((ch >> 6) & 7);
++      buf[3] = '0' + (ch & 7);
++      _dl_write (STDOUT_FILENO, buf, 4);
++    }
++  else
++    {
++      if (ch == '\\' || ch == '"')
++        _dl_putc ('\\');
++      _dl_putc (ch);
++    }
++}
++
++/* Print S of LEN bytes to standard output, quoting characters as
++   needed.  */
++static void
++print_string_length (const char *s, size_t len)
++{
++  _dl_putc ('"');
++  for (size_t i = 0; i < len; ++i)
++    print_quoted_char (s[i]);
++  _dl_putc ('"');
++}
++
++void
++_dl_diagnostics_print_string (const char *s)
++{
++  if (s == NULL)
++    {
++      _dl_printf ("0x0");
++      return;
++    }
++
++  _dl_putc ('"');
++  while (*s != '\0')
++    {
++      print_quoted_char (*s);
++      ++s;
++    }
++  _dl_putc ('"');
++}
++
++void
++_dl_diagnostics_print_labeled_string (const char *label, const char *s)
++{
++  _dl_printf ("%s=", label);
++  _dl_diagnostics_print_string (s);
++  _dl_putc ('\n');
++}
++
++void
++_dl_diagnostics_print_labeled_value (const char *label, uint64_t value)
++{
++  if (sizeof (value) == sizeof (unsigned long int))
++    /* _dl_printf can print 64-bit values directly.  */
++    _dl_printf ("%s=0x%lx\n", label, (unsigned long int) value);
++  else
++    {
++      uint32_t high = value >> 32;
++      uint32_t low = value;
++      if (high == 0)
++        _dl_printf ("%s=0x%x\n", label, low);
++      else
++        _dl_printf ("%s=0x%x%08x\n", label, high, low);
++    }
++}
++
++/* Return true if ENV is an unfiltered environment variable.  */
++static bool
++unfiltered_envvar (const char *env, size_t *name_length)
++{
++  char *env_equal = strchr (env, '=');
++  if (env_equal == NULL)
++    {
++      /* Always dump malformed entries.  */
++      *name_length = strlen (env);
++      return true;
++    }
++  size_t envname_length = env_equal - env;
++  *name_length = envname_length;
++
++  /* LC_ and LD_ variables.  */
++  if (env[0] == 'L' && (env[1] == 'C' || env[1] == 'D')
++      && env[2] == '_')
++    return true;
++
++  /* MALLOC_ variables.  */
++  if (strncmp (env, "MALLOC_", strlen ("MALLOC_")) == 0)
++    return true;
++
++  static const char unfiltered[] =
++    "DATEMSK\0"
++    "GCONV_PATH\0"
++    "GETCONF_DIR\0"
++    "GETCONF_DIR\0"
++    "GLIBC_TUNABLES\0"
++    "GMON_OUTPUT_PREFIX\0"
++    "HESIOD_CONFIG\0"
++    "HES_DOMAIN\0"
++    "HOSTALIASES\0"
++    "I18NPATH\0"
++    "IFS\0"
++    "LANG\0"
++    "LOCALDOMAIN\0"
++    "LOCPATH\0"
++    "MSGVERB\0"
++    "NIS_DEFAULTS\0"
++    "NIS_GROUP\0"
++    "NIS_PATH\0"
++    "NLSPATH\0"
++    "PATH\0"
++    "POSIXLY_CORRECT\0"
++    "RESOLV_HOST_CONF\0"
++    "RES_OPTIONS\0"
++    "SEV_LEVEL\0"
++    "TMPDIR\0"
++    "TZ\0"
++    "TZDIR\0"
++    /* Two null bytes at the end to mark the end of the list via an
++       empty substring.  */
++    ;
++  for (const char *candidate = unfiltered; *candidate != '\0'; )
++    {
++      size_t candidate_length = strlen (candidate);
++      if (candidate_length == envname_length
++          && memcmp (candidate, env, candidate_length) == 0)
++        return true;
++      candidate += candidate_length + 1;
++    }
++
++  return false;
++}
++
++/* Dump the process environment.  */
++static void
++print_environ (char **environ)
++{
++  unsigned int index = 0;
++  for (char **envp = environ; *envp != NULL; ++envp)
++    {
++      char *env = *envp;
++      size_t name_length;
++      bool unfiltered = unfiltered_envvar (env, &name_length);
++      _dl_printf ("env%s[0x%x]=",
++                  unfiltered ? "" : "_filtered", index);
++      if (unfiltered)
++        _dl_diagnostics_print_string (env);
++      else
++        print_string_length (env, name_length);
++      _dl_putc ('\n');
++      ++index;
++    }
++}
++
++/* Print configured paths and the built-in search path.  */
++static void
++print_paths (void)
++{
++  _dl_diagnostics_print_labeled_string ("path.prefix", PREFIX);
++  _dl_diagnostics_print_labeled_string ("path.rtld", RTLD);
++  _dl_diagnostics_print_labeled_string ("path.sysconfdir", SYSCONFDIR);
++
++  unsigned int index = 0;
++  static const char *system_dirs = SYSTEM_DIRS "\0";
++  for (const char *e = system_dirs; *e != '\0'; )
++    {
++      size_t len = strlen (e);
++      _dl_printf ("path.system_dirs[0x%x]=", index);
++      print_string_length (e, len);
++      _dl_putc ('\n');
++      ++index;
++      e += len + 1;
++    }
++}
++
++/* Print information about the glibc version.  */
++static void
++print_version (void)
++{
++  _dl_diagnostics_print_labeled_string ("version.release", RELEASE);
++  _dl_diagnostics_print_labeled_string ("version.version", VERSION);
++}
++
++void
++_dl_print_diagnostics (char **environ)
++{
++#ifdef HAVE_DL_DISCOVER_OSVERSION
++  _dl_diagnostics_print_labeled_value
++    ("dl_discover_osversion", _dl_discover_osversion ());
++#endif
++  _dl_diagnostics_print_labeled_string ("dl_dst_lib", DL_DST_LIB);
++  _dl_diagnostics_print_labeled_value ("dl_hwcap", GLRO (dl_hwcap));
++  _dl_diagnostics_print_labeled_value ("dl_hwcap_important", HWCAP_IMPORTANT);
++  _dl_diagnostics_print_labeled_value ("dl_hwcap2", GLRO (dl_hwcap2));
++  _dl_diagnostics_print_labeled_string
++    ("dl_hwcaps_subdirs", _dl_hwcaps_subdirs);
++  _dl_diagnostics_print_labeled_value
++    ("dl_hwcaps_subdirs_active", _dl_hwcaps_subdirs_active ());
++  _dl_diagnostics_print_labeled_value ("dl_osversion", GLRO (dl_osversion));
++  _dl_diagnostics_print_labeled_value ("dl_pagesize", GLRO (dl_pagesize));
++  _dl_diagnostics_print_labeled_string ("dl_platform", GLRO (dl_platform));
++  _dl_diagnostics_print_labeled_string
++    ("dl_profile_output", GLRO (dl_profile_output));
++  _dl_diagnostics_print_labeled_value
++    ("dl_string_platform", _dl_string_platform ( GLRO (dl_platform)));
++
++  _dl_diagnostics_print_labeled_string ("dso.ld", LD_SO);
++  _dl_diagnostics_print_labeled_string ("dso.libc", LIBC_SO);
++
++  print_environ (environ);
++  print_paths ();
++  print_version ();
++
++  _dl_diagnostics_kernel ();
++  _dl_diagnostics_cpu ();
++
++  _exit (EXIT_SUCCESS);
++}
+diff --git a/elf/dl-diagnostics.h b/elf/dl-diagnostics.h
+new file mode 100644
+index 0000000000000000..27dcb12bca12e5b6
+--- /dev/null
++++ b/elf/dl-diagnostics.h
+@@ -0,0 +1,46 @@
++/* Interfaces for printing diagnostics in ld.so.
++   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/>.  */
++
++#ifndef _DL_DIAGNOSTICS_H
++#define _DL_DIAGNOSTICS_H
++
++#include <stdint.h>
++
++/* Write the null-terminated string to standard output, surrounded in
++   quotation marks.  */
++void _dl_diagnostics_print_string (const char *s) attribute_hidden;
++
++/* Like _dl_diagnostics_print_string, but add a LABEL= prefix, and a
++   newline character as a suffix.  */
++void _dl_diagnostics_print_labeled_string (const char *label, const char *s)
++  attribute_hidden;
++
++/* Print LABEL=VALUE to standard output, followed by a newline
++   character.  */
++void _dl_diagnostics_print_labeled_value (const char *label, uint64_t value)
++  attribute_hidden;
++
++/* Print diagnostics data for the kernel.  Called from
++   _dl_print_diagnostics.  */
++void _dl_diagnostics_kernel (void) attribute_hidden;
++
++/* Print diagnostics data for the CPU(s).  Called from
++   _dl_print_diagnostics.  */
++void _dl_diagnostics_cpu (void) attribute_hidden;
++
++#endif /* _DL_DIAGNOSTICS_H */
+diff --git a/elf/dl-main.h b/elf/dl-main.h
+index 9e7b51d8f010e904..9fbbdb0fac09adf3 100644
+--- a/elf/dl-main.h
++++ b/elf/dl-main.h
+@@ -63,7 +63,7 @@ struct audit_list
+ enum rtld_mode
+   {
+     rtld_mode_normal, rtld_mode_list, rtld_mode_verify, rtld_mode_trace,
+-    rtld_mode_list_tunables, rtld_mode_help,
++    rtld_mode_list_tunables, rtld_mode_list_diagnostics, rtld_mode_help,
+   };
+ 
+ /* Aggregated state information extracted from environment variables
+@@ -121,4 +121,7 @@ _Noreturn void _dl_version (void) attribute_hidden;
+ _Noreturn void _dl_help (const char *argv0, struct dl_main_state *state)
+   attribute_hidden;
+ 
++/* Print a diagnostics dump.  */
++_Noreturn void _dl_print_diagnostics (char **environ) attribute_hidden;
++
+ #endif /* _DL_MAIN */
+diff --git a/elf/dl-usage.c b/elf/dl-usage.c
+index 908b4894b3014b2d..e19e1791d9169da2 100644
+--- a/elf/dl-usage.c
++++ b/elf/dl-usage.c
+@@ -261,6 +261,7 @@ setting environment variables (which would be inherited by subprocesses).\n\
+   --list-tunables       list all tunables with minimum and maximum values\n"
+ #endif
+ "\
++  --list-diagnostics    list diagnostics information\n\
+   --help                display this help and exit\n\
+   --version             output version information and exit\n\
+ \n\
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 54b621ec5ca014fa..d14c388f548d6d51 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -138,6 +138,7 @@ static void dl_main_state_init (struct dl_main_state *state);
+ /* Process all environments variables the dynamic linker must recognize.
+    Since all of them start with `LD_' we are a bit smarter while finding
+    all the entries.  */
++extern char **_environ attribute_hidden;
+ static void process_envvars (struct dl_main_state *state);
+ 
+ #ifdef DL_ARGV_NOT_RELRO
+@@ -1273,6 +1274,14 @@ dl_main (const ElfW(Phdr) *phdr,
+ 	    ++_dl_argv;
+ 	  }
+ #endif
++	else if (! strcmp (_dl_argv[1], "--list-diagnostics"))
++	  {
++	    state.mode = rtld_mode_list_diagnostics;
++
++	    ++_dl_skip_args;
++	    --_dl_argc;
++	    ++_dl_argv;
++	  }
+ 	else if (strcmp (_dl_argv[1], "--help") == 0)
+ 	  {
+ 	    state.mode = rtld_mode_help;
+@@ -1301,6 +1310,9 @@ dl_main (const ElfW(Phdr) *phdr,
+ 	}
+ #endif
+ 
++      if (state.mode == rtld_mode_list_diagnostics)
++	_dl_print_diagnostics (_environ);
++
+       /* If we have no further argument the program was called incorrectly.
+ 	 Grant the user some education.  */
+       if (_dl_argc < 2)
+@@ -2623,12 +2635,6 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
+     }
+ }
+ 
+-/* Process all environments variables the dynamic linker must recognize.
+-   Since all of them start with `LD_' we are a bit smarter while finding
+-   all the entries.  */
+-extern char **_environ attribute_hidden;
+-
+-
+ static void
+ process_envvars (struct dl_main_state *state)
+ {
+diff --git a/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c b/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c
+new file mode 100644
+index 0000000000000000..59f6402c547ba590
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c
+@@ -0,0 +1,77 @@
++/* Print kernel diagnostics data in ld.so.  Linux version.
++   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 <dl-diagnostics.h>
++#include <ldsodefs.h>
++#include <sys/utsname.h>
++
++/* Dump the auxiliary vector to standard output.  */
++static void
++print_auxv (void)
++{
++  /* See _dl_show_auxv.  The code below follows the general output
++     format for diagnostic dumps.  */
++  unsigned int index = 0;
++  for (ElfW(auxv_t) *av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av)
++    {
++      _dl_printf ("auxv[0x%x].a_type=0x%lx\n"
++                  "auxv[0x%x].a_val=",
++                  index, (unsigned long int) av->a_type, index);
++      if (av->a_type == AT_EXECFN
++          || av->a_type == AT_PLATFORM
++          || av->a_type == AT_BASE_PLATFORM)
++        /* The address of the strings is not useful at all, so print
++           the strings themselvs.  */
++        _dl_diagnostics_print_string ((const char *) av->a_un.a_val);
++      else
++        _dl_printf ("0x%lx", (unsigned long int) av->a_un.a_val);
++      _dl_printf ("\n");
++      ++index;
++    }
++}
++
++/* Print one uname entry.  */
++static void
++print_utsname_entry (const char *field, const char *value)
++{
++  _dl_printf ("uname.");
++  _dl_diagnostics_print_labeled_string (field, value);
++}
++
++/* Print information from uname, including the kernel version.  */
++static void
++print_uname (void)
++{
++  struct utsname uts;
++  if (__uname (&uts) == 0)
++    {
++      print_utsname_entry ("sysname", uts.sysname);
++      print_utsname_entry ("nodename", uts.nodename);
++      print_utsname_entry ("release", uts.release);
++      print_utsname_entry ("version", uts.version);
++      print_utsname_entry ("machine", uts.machine);
++      print_utsname_entry ("domainname", uts.domainname);
++    }
++}
++
++void
++_dl_diagnostics_kernel (void)
++{
++  print_auxv ();
++  print_uname ();
++}
diff --git a/SOURCES/glibc-rh2023420-4.patch b/SOURCES/glibc-rh2023420-4.patch
new file mode 100644
index 0000000..bf1a407
--- /dev/null
+++ b/SOURCES/glibc-rh2023420-4.patch
@@ -0,0 +1,117 @@
+commit e4933c8a92ea08eecdf3ab45e7f76c95dc3d20ac
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Mar 2 14:58:05 2021 +0100
+
+    x86: Automate generation of PREFERRED_FEATURE_INDEX_1 bitfield
+
+    Use a .def file to define the bitfield layout, so that it is possible
+    to iterate over field members using the preprocessor.
+
+Conflicts:
+	sysdeps/x86/include/cpu-features.h
+	  (re-did the change from scratch)
+	sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
+	  (adjusted to the downstream bits)
+
+diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
+new file mode 100644
+index 0000000000000000..17a5cc428c1dabea
+--- /dev/null
++++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
+@@ -0,0 +1,34 @@
++/* Bits in the PREFERRED_FEATURE_INDEX_1 bitfield of <cpu-features.h>.
++   Copyright (C) 2020-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/>.  */
++
++BIT (I586)
++BIT (I686)
++BIT (Fast_Rep_String)
++BIT (Fast_Copy_Backward)
++BIT (Fast_Unaligned_Load)
++BIT (Fast_Unaligned_Copy)
++BIT (Slow_BSF)
++BIT (Slow_SSE4_2)
++BIT (AVX_Fast_Unaligned_Load)
++BIT (Prefer_MAP_32BIT_EXEC)
++BIT (Prefer_PMINUB_for_stringop)
++BIT (Prefer_No_VZEROUPPER)
++BIT (Prefer_ERMS)
++BIT (Prefer_FSRM)
++BIT (Prefer_No_AVX512)
++BIT (MathVec_Prefer_No_AVX512)
+diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
+index f62be0b9b3746675..f43e22f677b249a9 100644
+--- a/sysdeps/x86/include/cpu-features.h
++++ b/sysdeps/x86/include/cpu-features.h
+@@ -80,40 +80,23 @@ enum
+ # define HAS_ARCH_FEATURE(name) \
+   CPU_FEATURE_PREFERRED (name)
+ 
+-/* PREFERRED_FEATURE_INDEX_1.  */
+-# define bit_arch_I586				(1u << 0)
+-# define bit_arch_I686				(1u << 1)
+-# define bit_arch_Fast_Rep_String		(1u << 2)
+-# define bit_arch_Fast_Copy_Backward		(1u << 3)
+-# define bit_arch_Fast_Unaligned_Load		(1u << 4)
+-# define bit_arch_Fast_Unaligned_Copy		(1u << 5)
+-# define bit_arch_Slow_BSF			(1u << 6)
+-# define bit_arch_Slow_SSE4_2			(1u << 7)
+-# define bit_arch_AVX_Fast_Unaligned_Load	(1u << 8)
+-# define bit_arch_Prefer_MAP_32BIT_EXEC		(1u << 9)
+-# define bit_arch_Prefer_PMINUB_for_stringop	(1u << 10)
+-# define bit_arch_Prefer_No_VZEROUPPER		(1u << 11)
+-# define bit_arch_Prefer_ERMS			(1u << 12)
+-# define bit_arch_Prefer_FSRM			(1u << 13)
+-# define bit_arch_Prefer_No_AVX512		(1u << 14)
+-# define bit_arch_MathVec_Prefer_No_AVX512	(1u << 15)
+-
+-# define index_arch_Fast_Rep_String		PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Fast_Copy_Backward		PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Slow_BSF			PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Fast_Unaligned_Load		PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Prefer_PMINUB_for_stringop 	PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Fast_Unaligned_Copy		PREFERRED_FEATURE_INDEX_1
+-# define index_arch_I586			PREFERRED_FEATURE_INDEX_1
+-# define index_arch_I686			PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Slow_SSE4_2			PREFERRED_FEATURE_INDEX_1
+-# define index_arch_AVX_Fast_Unaligned_Load	PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Prefer_MAP_32BIT_EXEC	PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Prefer_No_VZEROUPPER	PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Prefer_ERMS			PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Prefer_No_AVX512		PREFERRED_FEATURE_INDEX_1
+-# define index_arch_MathVec_Prefer_No_AVX512	PREFERRED_FEATURE_INDEX_1
+-# define index_arch_Prefer_FSRM			PREFERRED_FEATURE_INDEX_1
++/* PREFERRED_FEATURE_INDEX_1.  First define the bitindex values
++   sequentially, then define the bit_arch* and index_arch_* lookup
++   constants.  */
++enum
++  {
++#define BIT(x) _bitindex_arch_##x ,
++#include "cpu-features-preferred_feature_index_1.def"
++#undef BIT
++  };
++enum
++  {
++#define BIT(x)                                 \
++    bit_arch_##x = 1u << _bitindex_arch_##x ,  \
++    index_arch_##x = PREFERRED_FEATURE_INDEX_1,
++#include "cpu-features-preferred_feature_index_1.def"
++#undef BIT
++  };
+ 
+ /* XCR0 Feature flags.  */
+ # define bit_XMM_state		(1u << 1)
diff --git a/SOURCES/glibc-rh2023420-5.patch b/SOURCES/glibc-rh2023420-5.patch
new file mode 100644
index 0000000..0d3ca97
--- /dev/null
+++ b/SOURCES/glibc-rh2023420-5.patch
@@ -0,0 +1,131 @@
+commit 01a5746b6c8a44dc29d33e056b63485075a6a3cc
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Feb 24 13:12:04 2021 +0100
+
+    x86: Add CPU-specific diagnostics to ld.so --list-diagnostics
+
+Conflicts:
+	sysdeps/x86/dl-diagnostics-cpu.c
+	  (reworked due to struct differences, different knobs
+	  downstream)
+
+diff --git a/sysdeps/x86/dl-diagnostics-cpu.c b/sysdeps/x86/dl-diagnostics-cpu.c
+new file mode 100644
+index 0000000000000000..0ba286a828b69937
+--- /dev/null
++++ b/sysdeps/x86/dl-diagnostics-cpu.c
+@@ -0,0 +1,101 @@
++/* Print CPU diagnostics data in ld.so.  x86 version.
++   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 <dl-diagnostics.h>
++#include <ldsodefs.h>
++
++static void
++print_cpu_features_value (const char *label, uint64_t value)
++{
++  _dl_printf ("x86.cpu_features.");
++  _dl_diagnostics_print_labeled_value (label, value);
++}
++
++static void
++print_cpu_feature_internal (unsigned int index, const char *kind,
++                            unsigned int reg, uint32_t value)
++{
++  _dl_printf ("x86.cpu_features.features[0x%x].%s[0x%x]=0x%x\n",
++              index, kind, reg, value);
++}
++
++static void
++print_cpu_feature_preferred (const char *label, unsigned int flag)
++{
++  _dl_printf("x86.cpu_features.preferred.%s=0x%x\n", label, flag);
++}
++
++void
++_dl_diagnostics_cpu (void)
++{
++  const struct cpu_features *cpu_features = __get_cpu_features ();
++
++  print_cpu_features_value ("basic.kind", cpu_features->basic.kind);
++  print_cpu_features_value ("basic.max_cpuid", cpu_features->basic.max_cpuid);
++  print_cpu_features_value ("basic.family", cpu_features->basic.family);
++  print_cpu_features_value ("basic.model", cpu_features->basic.model);
++  print_cpu_features_value ("basic.stepping", cpu_features->basic.stepping);
++
++  for (unsigned int index = 0; index < COMMON_CPUID_INDEX_MAX; ++index)
++    {
++      /* Downstream, these constants are not part of the ABI yet, so
++         analysis needs to take the precise glibc version into
++         account.  */
++      print_cpu_feature_internal
++        (index, "cpuid", 0, cpu_features->features[index].cpuid.eax);
++      print_cpu_feature_internal
++        (index, "cpuid", 1, cpu_features->features[index].cpuid.ebx);
++      print_cpu_feature_internal
++        (index, "cpuid", 2, cpu_features->features[index].cpuid.ecx);
++      print_cpu_feature_internal
++        (index, "cpuid", 3, cpu_features->features[index].cpuid.edx);
++      print_cpu_feature_internal
++        (index, "usable", 0, cpu_features->features[index].usable.eax);
++      print_cpu_feature_internal
++        (index, "usable", 1, cpu_features->features[index].usable.ebx);
++      print_cpu_feature_internal
++        (index, "usable", 2, cpu_features->features[index].usable.ecx);
++      print_cpu_feature_internal
++        (index, "usable", 3, cpu_features->features[index].usable.edx);
++    }
++
++  /* The preferred indicators are not part of the ABI and need to be
++     translated.  */
++#define BIT(x) \
++  print_cpu_feature_preferred (#x, CPU_FEATURE_PREFERRED_P (cpu_features, x));
++#include "cpu-features-preferred_feature_index_1.def"
++#undef BIT
++
++  print_cpu_features_value ("xsave_state_size",
++                            cpu_features->xsave_state_size);
++  print_cpu_features_value ("xsave_state_full_size",
++                            cpu_features->xsave_state_full_size);
++  print_cpu_features_value ("data_cache_size", cpu_features->data_cache_size);
++  print_cpu_features_value ("shared_cache_size",
++                            cpu_features->shared_cache_size);
++  print_cpu_features_value ("non_temporal_threshold",
++                            cpu_features->non_temporal_threshold);
++  print_cpu_features_value ("rep_movsb_threshold",
++                            cpu_features->rep_movsb_threshold);
++  print_cpu_features_value ("rep_stosb_threshold",
++                            cpu_features->rep_stosb_threshold);
++  _Static_assert (offsetof (struct cpu_features, rep_stosb_threshold)
++                  + sizeof (cpu_features->rep_stosb_threshold)
++                  == sizeof (*cpu_features),
++                  "last cpu_features field has been printed");
++}
+diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
+index f43e22f677b249a9..536643b209425198 100644
+--- a/sysdeps/x86/include/cpu-features.h
++++ b/sysdeps/x86/include/cpu-features.h
+@@ -107,6 +107,8 @@ enum
+ # define bit_XTILECFG_state	(1u << 17)
+ # define bit_XTILEDATA_state	(1u << 18)
+ 
++/* NB: When adding new fields, update sysdeps/x86/dl-diagnostics-cpu.c
++   to print them.  */
+ struct cpu_features
+ {
+   struct cpu_features_basic basic;
diff --git a/SOURCES/glibc-rh2023420-6.patch b/SOURCES/glibc-rh2023420-6.patch
new file mode 100644
index 0000000..a05a690
--- /dev/null
+++ b/SOURCES/glibc-rh2023420-6.patch
@@ -0,0 +1,255 @@
+commit c1cb2deeca1a85c6fc5bd41b90816d48a95bc434
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Sun Dec 5 11:28:34 2021 +0100
+
+    elf: execve statically linked programs instead of crashing [BZ #28648]
+
+    Programs without dynamic dependencies and without a program
+    interpreter are now run via execve.
+
+    Previously, the dynamic linker either crashed while attempting to
+    read a non-existing dynamic segment (looking for DT_AUDIT/DT_DEPAUDIT
+    data), or the self-relocated in the static PIE executable crashed
+    because the outer dynamic linker had already applied RELRO protection.
+
+    <dl-execve.h> is needed because execve is not available in the
+    dynamic loader on Hurd.
+
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+
+Conflicts:
+	elf/Makefile
+	  (some missing backports)
+	elf/rtld.c
+	  (missing rework of ld.so self-relocation downstream,
+	  always print error as a number due to missing
+	  sterrorname_np, also fix errcode/errno glitch)
+	sysdeps/unix/sysv/linux/dl-execve.h
+	  (missing INTERNAL_SYSCALL_CALL refactoring to Linux-like
+	  calling convention)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index d246f1c0d9e019fd..b3e8ab2792608de7 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -214,7 +214,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 tst-tls-ie tst-tls-ie-dlmopen \
+ 	 argv0test \
+ 	 tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
+-	 tst-tls20 tst-tls21
++	 tst-tls20 tst-tls21 \
++	 tst-rtld-run-static \
+ #	 reldep9
+ tests-internal += loadtest unload unload2 circleload1 \
+ 	 neededtest neededtest2 neededtest3 neededtest4 \
+@@ -1917,3 +1918,5 @@ $(objpfx)tst-tls20.out: $(objpfx)tst-tls20mod-bad.so \
+ $(objpfx)tst-tls21: $(libdl) $(shared-thread-library)
+ $(objpfx)tst-tls21.out: $(objpfx)tst-tls21mod.so
+ $(objpfx)tst-tls21mod.so: $(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
++
++$(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig
+diff --git a/elf/rtld.c b/elf/rtld.c
+index d14c388f548d6d51..461d8c114a875a9b 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -48,6 +48,7 @@
+ #include <dl-main.h>
+ #include <gnu/lib-names.h>
+ #include <dl-tunables.h>
++#include <dl-execve.h>
+ 
+ #include <assert.h>
+ 
+@@ -1114,6 +1115,40 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
+     }
+ }
+ 
++/* Check if the executable is not actualy dynamically linked, and
++   invoke it directly in that case.  */
++static void
++rtld_chain_load (struct link_map *main_map, char *argv0)
++{
++  /* The dynamic loader run against itself.  */
++  const char *rtld_soname
++    = ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
++       + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val);
++  if (main_map->l_info[DT_SONAME] != NULL
++      && strcmp (rtld_soname,
++		 ((const char *) D_PTR (main_map, l_info[DT_STRTAB])
++		  + main_map->l_info[DT_SONAME]->d_un.d_val)) == 0)
++    _dl_fatal_printf ("%s: loader cannot load itself\n", rtld_soname);
++
++  /* With DT_NEEDED dependencies, the executable is dynamically
++     linked.  */
++  if (__glibc_unlikely (main_map->l_info[DT_NEEDED] != NULL))
++    return;
++
++  /* If the executable has program interpreter, it is dynamically
++     linked.  */
++  for (size_t i = 0; i < main_map->l_phnum; ++i)
++    if (main_map->l_phdr[i].p_type == PT_INTERP)
++      return;
++
++  const char *pathname = _dl_argv[0];
++  if (argv0 != NULL)
++    _dl_argv[0] = argv0;
++  int errcode = __rtld_execve (pathname, _dl_argv, _environ);
++  _dl_fatal_printf("%s: cannot execute %s: %d\n",
++		   rtld_soname, pathname, errcode);
++}
++
+ static void
+ dl_main (const ElfW(Phdr) *phdr,
+ 	 ElfW(Word) phnum,
+@@ -1384,14 +1419,8 @@ dl_main (const ElfW(Phdr) *phdr,
+       /* Now the map for the main executable is available.  */
+       main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+ 
+-      if (__glibc_likely (state.mode == rtld_mode_normal)
+-	  && GL(dl_rtld_map).l_info[DT_SONAME] != NULL
+-	  && main_map->l_info[DT_SONAME] != NULL
+-	  && strcmp ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
+-		     + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val,
+-		     (const char *) D_PTR (main_map, l_info[DT_STRTAB])
+-		     + main_map->l_info[DT_SONAME]->d_un.d_val) == 0)
+-	_dl_fatal_printf ("loader cannot load itself\n");
++      if (__glibc_likely (state.mode == rtld_mode_normal))
++	rtld_chain_load (main_map, argv0);
+ 
+       phdr = main_map->l_phdr;
+       phnum = main_map->l_phnum;
+diff --git a/elf/tst-rtld-run-static.c b/elf/tst-rtld-run-static.c
+new file mode 100644
+index 0000000000000000..7281093504b675c4
+--- /dev/null
++++ b/elf/tst-rtld-run-static.c
+@@ -0,0 +1,62 @@
++/* Test running statically linked programs using ld.so.
++   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 <support/check.h>
++#include <support/support.h>
++#include <support/capture_subprocess.h>
++#include <string.h>
++#include <stdlib.h>
++
++static int
++do_test (void)
++{
++  char *ldconfig_path = xasprintf ("%s/elf/ldconfig", support_objdir_root);
++
++  {
++    char *argv[] = { (char *) "ld.so", ldconfig_path, (char *) "--help", NULL };
++    struct support_capture_subprocess cap
++      = support_capture_subprogram (support_objdir_elf_ldso, argv);
++    support_capture_subprocess_check (&cap, "no --argv0", 0, sc_allow_stdout);
++    puts ("info: output without --argv0:");
++    puts (cap.out.buffer);
++    TEST_VERIFY (strstr (cap.out.buffer, "Usage: ldconfig [OPTION...]\n")
++                 == cap.out.buffer);
++    support_capture_subprocess_free (&cap);
++  }
++
++  {
++    char *argv[] =
++      {
++        (char *) "ld.so", (char *) "--argv0", (char *) "ldconfig-argv0",
++        ldconfig_path, (char *) "--help", NULL
++      };
++    struct support_capture_subprocess cap
++      = support_capture_subprogram (support_objdir_elf_ldso, argv);
++    support_capture_subprocess_check (&cap, "with --argv0", 0, sc_allow_stdout);
++    puts ("info: output with --argv0:");
++    puts (cap.out.buffer);
++    TEST_VERIFY (strstr (cap.out.buffer, "Usage: ldconfig-argv0 [OPTION...]\n")
++                 == cap.out.buffer);
++    support_capture_subprocess_free (&cap);
++  }
++
++  free (ldconfig_path);
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/generic/dl-execve.h b/sysdeps/generic/dl-execve.h
+new file mode 100644
+index 0000000000000000..5fd097df69e1770c
+--- /dev/null
++++ b/sysdeps/generic/dl-execve.h
+@@ -0,0 +1,25 @@
++/* execve for the dynamic linker.  Generic stub version.
++   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 <errno.h>
++
++static int
++__rtld_execve (const char *path, char *const *argv, char *const *envp)
++{
++  return ENOSYS;
++}
+diff --git a/sysdeps/unix/sysv/linux/dl-execve.h b/sysdeps/unix/sysv/linux/dl-execve.h
+new file mode 100644
+index 0000000000000000..9ec6539286bb0589
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/dl-execve.h
+@@ -0,0 +1,30 @@
++/* execve for the dynamic linker.  Linux version.
++   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 <errno.h>
++
++static inline int
++__rtld_execve (const char *path, char *const *argv, char *const *envp)
++{
++  INTERNAL_SYSCALL_DECL (err);
++  long int r = INTERNAL_SYSCALL_CALL (execve, err, path, argv, envp);
++  if (INTERNAL_SYSCALL_ERROR_P (r, err))
++    return INTERNAL_SYSCALL_ERRNO (r, err);
++  else
++    return 0;
++}
diff --git a/SOURCES/glibc-rh2023420-7.patch b/SOURCES/glibc-rh2023420-7.patch
new file mode 100644
index 0000000..c14031c
--- /dev/null
+++ b/SOURCES/glibc-rh2023420-7.patch
@@ -0,0 +1,41 @@
+commit 2e75604f8337fa4332977f72a8f6726309679edf
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Dec 10 16:06:36 2021 +0100
+
+    elf: Install a symbolic link to ld.so as /usr/bin/ld.so
+    
+    This makes ld.so features such as --preload, --audit,
+    and --list-diagnostics more accessible to end users because they
+    do not need to know the ABI name of the dynamic loader.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+ Conflicts:
+	elf/Makefile
+	  (versioned shared objects downstream)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index b3e8ab2792608de7..c552aff350c2faac 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -99,7 +99,7 @@ endif
+ ifeq (yes,$(build-shared))
+ extra-objs	= $(all-rtld-routines:%=%.os) soinit.os sofini.os interp.os
+ generated	+= librtld.os dl-allobjs.os ld.so ldd
+-install-others	= $(inst_rtlddir)/$(rtld-installed-name)
++install-others	= $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so
+ install-bin-script = ldd
+ endif
+ 
+@@ -622,6 +622,11 @@ $(inst_rtlddir)/$(rtld-installed-name): \
+ 	$(make-target-directory)
+ 	$(make-shlib-link)
+ 
++# Creates the relative /usr/bin/ld.so symbolic link.
++$(inst_bindir)/ld.so: $(inst_rtlddir)/$(rtld-installed-name)
++	$(make-target-directory)
++	$(make-link)
++
+ # Special target called by parent to install just the dynamic linker.
+ .PHONY: ldso_install
+ ldso_install: $(inst_rtlddir)/$(rtld-installed-name)
diff --git a/SOURCES/glibc-rh2032280-1.patch b/SOURCES/glibc-rh2032280-1.patch
deleted file mode 100644
index 6308350..0000000
--- a/SOURCES/glibc-rh2032280-1.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-commit a7e9dbb7742954814643a8562dcad09abb0b0e5d
-Author: Alexandra Hájková <ahajkova@redhat.com>
-Date:   Sat Dec 26 18:45:13 2020 +0100
-
-    Add xchdir to libsupport.
-
-diff --git a/support/Makefile b/support/Makefile
-index dcf3c4baa2a31070..fb95a69ed9158e78 100644
---- a/support/Makefile
-+++ b/support/Makefile
-@@ -82,6 +82,7 @@ libsupport-routines = \
-   xasprintf \
-   xbind \
-   xcalloc \
-+  xchdir \
-   xchroot \
-   xclose \
-   xconnect \
-diff --git a/support/xchdir.c b/support/xchdir.c
-new file mode 100644
-index 0000000000000000..beb4feff72832065
---- /dev/null
-+++ b/support/xchdir.c
-@@ -0,0 +1,28 @@
-+/* chdir with error checking.
-+   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 <support/check.h>
-+#include <support/xunistd.h>
-+#include <unistd.h>
-+
-+void
-+xchdir (const char *path)
-+{
-+  if (chdir (path) != 0)
-+    FAIL_EXIT1 ("chdir (\"%s\"): %m", path);
-+}
-diff --git a/support/xunistd.h b/support/xunistd.h
-index f99f362cb4763c5b..74fd2771d12c36fe 100644
---- a/support/xunistd.h
-+++ b/support/xunistd.h
-@@ -44,6 +44,7 @@ long xsysconf (int name);
- long long xlseek (int fd, long long offset, int whence);
- void xftruncate (int fd, long long length);
- void xsymlink (const char *target, const char *linkpath);
-+void xchdir (const char *path);
- 
- /* Equivalent of "mkdir -p".  */
- void xmkdirp (const char *, mode_t);
diff --git a/SOURCES/glibc-rh2032280-2.patch b/SOURCES/glibc-rh2032280-2.patch
deleted file mode 100644
index 56edb3d..0000000
--- a/SOURCES/glibc-rh2032280-2.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-commit 60854f40ea2d420867ed2f0f052ee7fca661dbff
-Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-Date:   Thu Oct 15 15:14:22 2020 -0300
-
-    support: Add create_temp_file_in_dir
-    
-    It allows created a temporary file in a specified directory.
-
-diff --git a/support/support.h b/support/support.h
-index f50f8cc1496d657d..96833bd4e992e6d3 100644
---- a/support/support.h
-+++ b/support/support.h
-@@ -23,6 +23,7 @@
- #ifndef SUPPORT_H
- #define SUPPORT_H
- 
-+#include <stdbool.h>
- #include <stddef.h>
- #include <sys/cdefs.h>
- /* For mode_t.  */
-diff --git a/support/temp_file.c b/support/temp_file.c
-index 0bbc7f997264f758..5a2728c94a9c32ae 100644
---- a/support/temp_file.c
-+++ b/support/temp_file.c
-@@ -60,14 +60,12 @@ add_temp_file (const char *name)
- }
- 
- int
--create_temp_file (const char *base, char **filename)
-+create_temp_file_in_dir (const char *base, const char *dir, char **filename)
- {
-   char *fname;
-   int fd;
- 
--  fname = (char *) xmalloc (strlen (test_dir) + 1 + strlen (base)
--			    + sizeof ("XXXXXX"));
--  strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");
-+  fname = xasprintf ("%s/%sXXXXXX", dir, base);
- 
-   fd = mkstemp (fname);
-   if (fd == -1)
-@@ -86,6 +84,12 @@ create_temp_file (const char *base, char **filename)
-   return fd;
- }
- 
-+int
-+create_temp_file (const char *base, char **filename)
-+{
-+  return create_temp_file_in_dir (base, test_dir, filename);
-+}
-+
- char *
- support_create_temp_directory (const char *base)
- {
-diff --git a/support/temp_file.h b/support/temp_file.h
-index c7795cc577ca22a9..d64563f41f1f50cd 100644
---- a/support/temp_file.h
-+++ b/support/temp_file.h
-@@ -32,6 +32,13 @@ void add_temp_file (const char *name);
-    *FILENAME.  */
- int create_temp_file (const char *base, char **filename);
- 
-+/* Create a temporary file in directory DIR.  Return the opened file
-+   descriptor on success, or -1 on failure.  Write the file name to
-+   *FILENAME if FILENAME is not NULL.  In this case, the caller is
-+   expected to free *FILENAME.  */
-+int create_temp_file_in_dir (const char *base, const char *dir,
-+			     char **filename);
-+
- /* Create a temporary directory and schedule it for deletion.  BASE is
-    used as a prefix for the unique directory name, which the function
-    returns.  The caller should free this string.  */
diff --git a/SOURCES/glibc-rh2032280-3.patch b/SOURCES/glibc-rh2032280-3.patch
deleted file mode 100644
index 7cb306d..0000000
--- a/SOURCES/glibc-rh2032280-3.patch
+++ /dev/null
@@ -1,278 +0,0 @@
-commit fb7bff12e81c677a6622f724edd4d4987dd9d971
-Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
-Date:   Tue Jan 18 13:29:36 2022 +0530
-
-    support: Add helpers to create paths longer than PATH_MAX
-    
-    Add new helpers support_create_and_chdir_toolong_temp_directory and
-    support_chdir_toolong_temp_directory to create and descend into
-    directory trees longer than PATH_MAX.
-    
-    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
-    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-
-# Conflicts:
-#	support/temp_file.c
-
-diff --git a/support/temp_file.c b/support/temp_file.c
-index 5a2728c94a9c32ae..661c86bad5c0121f 100644
---- a/support/temp_file.c
-+++ b/support/temp_file.c
-@@ -1,5 +1,6 @@
- /* Temporary file handling for tests.
--   Copyright (C) 1998-2018 Free Software Foundation, Inc.
-+   Copyright (C) 1998-2022 Free Software Foundation, Inc.
-+   Copyright The GNU Tools Authors.
-    This file is part of the GNU C Library.
- 
-    The GNU C Library is free software; you can redistribute it and/or
-@@ -20,15 +21,17 @@
-    some 32-bit platforms. */
- #define _FILE_OFFSET_BITS 64
- 
-+#include <support/check.h>
- #include <support/temp_file.h>
- #include <support/temp_file-internal.h>
- #include <support/support.h>
- 
-+#include <errno.h>
- #include <paths.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
--#include <unistd.h>
-+#include <xunistd.h>
- 
- /* List of temporary files.  */
- static struct temp_name_list
-@@ -36,14 +39,20 @@ static struct temp_name_list
-   struct temp_name_list *next;
-   char *name;
-   pid_t owner;
-+  bool toolong;
- } *temp_name_list;
- 
- /* Location of the temporary files.  Set by the test skeleton via
-    support_set_test_dir.  The string is not be freed.  */
- static const char *test_dir = _PATH_TMP;
- 
--void
--add_temp_file (const char *name)
-+/* Name of subdirectories in a too long temporary directory tree.  */
-+static char toolong_subdir[NAME_MAX + 1];
-+static bool toolong_initialized;
-+static size_t toolong_path_max;
-+
-+static void
-+add_temp_file_internal (const char *name, bool toolong)
- {
-   struct temp_name_list *newp
-     = (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
-@@ -53,12 +62,19 @@ add_temp_file (const char *name)
-       newp->name = newname;
-       newp->next = temp_name_list;
-       newp->owner = getpid ();
-+      newp->toolong = toolong;
-       temp_name_list = newp;
-     }
-   else
-     free (newp);
- }
- 
-+void
-+add_temp_file (const char *name)
-+{
-+  add_temp_file_internal (name, false);
-+}
-+
- int
- create_temp_file_in_dir (const char *base, const char *dir, char **filename)
- {
-@@ -90,8 +106,8 @@ create_temp_file (const char *base, char **filename)
-   return create_temp_file_in_dir (base, test_dir, filename);
- }
- 
--char *
--support_create_temp_directory (const char *base)
-+static char *
-+create_temp_directory_internal (const char *base, bool toolong)
- {
-   char *path = xasprintf ("%s/%sXXXXXX", test_dir, base);
-   if (mkdtemp (path) == NULL)
-@@ -99,16 +115,132 @@ support_create_temp_directory (const char *base)
-       printf ("error: mkdtemp (\"%s\"): %m", path);
-       exit (1);
-     }
--  add_temp_file (path);
-+  add_temp_file_internal (path, toolong);
-   return path;
- }
- 
--/* Helper functions called by the test skeleton follow.  */
-+char *
-+support_create_temp_directory (const char *base)
-+{
-+  return create_temp_directory_internal (base, false);
-+}
-+
-+static void
-+ensure_toolong_initialized (void)
-+{
-+  if (!toolong_initialized)
-+    FAIL_EXIT1 ("uninitialized toolong directory tree\n");
-+}
-+
-+static void
-+initialize_toolong (const char *base)
-+{
-+  long name_max = pathconf (base, _PC_NAME_MAX);
-+  name_max = (name_max < 0 ? 64
-+	      : (name_max < sizeof (toolong_subdir) ? name_max
-+		 : sizeof (toolong_subdir) - 1));
-+
-+  long path_max = pathconf (base, _PC_PATH_MAX);
-+  path_max = (path_max < 0 ? 1024
-+	      : path_max <= PTRDIFF_MAX ? path_max : PTRDIFF_MAX);
-+
-+  /* Sanity check to ensure that the test does not create temporary directories
-+     in different filesystems because this API doesn't support it.  */
-+  if (toolong_initialized)
-+    {
-+      if (name_max != strlen (toolong_subdir))
-+	FAIL_UNSUPPORTED ("name_max: Temporary directories in different"
-+			  " filesystems not supported yet\n");
-+      if (path_max != toolong_path_max)
-+	FAIL_UNSUPPORTED ("path_max: Temporary directories in different"
-+			  " filesystems not supported yet\n");
-+      return;
-+    }
-+
-+  toolong_path_max = path_max;
-+
-+  size_t len = name_max;
-+  memset (toolong_subdir, 'X', len);
-+  toolong_initialized = true;
-+}
-+
-+char *
-+support_create_and_chdir_toolong_temp_directory (const char *basename)
-+{
-+  char *base = create_temp_directory_internal (basename, true);
-+  xchdir (base);
-+
-+  initialize_toolong (base);
-+
-+  size_t sz = strlen (toolong_subdir);
-+
-+  /* Create directories and descend into them so that the final path is larger
-+     than PATH_MAX.  */
-+  for (size_t i = 0; i <= toolong_path_max / sz; i++)
-+    {
-+      int ret = mkdir (toolong_subdir, S_IRWXU);
-+      if (ret != 0 && errno == ENAMETOOLONG)
-+	FAIL_UNSUPPORTED ("Filesystem does not support creating too long "
-+			  "directory trees\n");
-+      else if (ret != 0)
-+	FAIL_EXIT1 ("Failed to create directory tree: %m\n");
-+      xchdir (toolong_subdir);
-+    }
-+  return base;
-+}
- 
- void
--support_set_test_dir (const char *path)
-+support_chdir_toolong_temp_directory (const char *base)
- {
--  test_dir = path;
-+  ensure_toolong_initialized ();
-+
-+  xchdir (base);
-+
-+  size_t sz = strlen (toolong_subdir);
-+  for (size_t i = 0; i <= toolong_path_max / sz; i++)
-+    xchdir (toolong_subdir);
-+}
-+
-+/* Helper functions called by the test skeleton follow.  */
-+
-+static void
-+remove_toolong_subdirs (const char *base)
-+{
-+  ensure_toolong_initialized ();
-+
-+  if (chdir (base) != 0)
-+    {
-+      printf ("warning: toolong cleanup base failed: chdir (\"%s\"): %m\n",
-+	      base);
-+      return;
-+    }
-+
-+  /* Descend.  */
-+  int levels = 0;
-+  size_t sz = strlen (toolong_subdir);
-+  for (levels = 0; levels <= toolong_path_max / sz; levels++)
-+    if (chdir (toolong_subdir) != 0)
-+      {
-+	printf ("warning: toolong cleanup failed: chdir (\"%s\"): %m\n",
-+		toolong_subdir);
-+	break;
-+      }
-+
-+  /* Ascend and remove.  */
-+  while (--levels >= 0)
-+    {
-+      if (chdir ("..") != 0)
-+	{
-+	  printf ("warning: toolong cleanup failed: chdir (\"..\"): %m\n");
-+	  return;
-+	}
-+      if (remove (toolong_subdir) != 0)
-+	{
-+	  printf ("warning: could not remove subdirectory: %s: %m\n",
-+		  toolong_subdir);
-+	  return;
-+	}
-+    }
- }
- 
- void
-@@ -123,6 +255,9 @@ support_delete_temp_files (void)
- 	 around, to prevent PID reuse.)  */
-       if (temp_name_list->owner == pid)
- 	{
-+	  if (temp_name_list->toolong)
-+	    remove_toolong_subdirs (temp_name_list->name);
-+
- 	  if (remove (temp_name_list->name) != 0)
- 	    printf ("warning: could not remove temporary file: %s: %m\n",
- 		    temp_name_list->name);
-@@ -147,3 +282,9 @@ support_print_temp_files (FILE *f)
-       fprintf (f, ")\n");
-     }
- }
-+
-+void
-+support_set_test_dir (const char *path)
-+{
-+  test_dir = path;
-+}
-diff --git a/support/temp_file.h b/support/temp_file.h
-index d64563f41f1f50cd..055e31dcfb843ba6 100644
---- a/support/temp_file.h
-+++ b/support/temp_file.h
-@@ -44,6 +44,15 @@ int create_temp_file_in_dir (const char *base, const char *dir,
-    returns.  The caller should free this string.  */
- char *support_create_temp_directory (const char *base);
- 
-+/* Create a temporary directory tree that is longer than PATH_MAX and schedule
-+   it for deletion.  BASENAME is used as a prefix for the unique directory
-+   name, which the function returns.  The caller should free this string.  */
-+char *support_create_and_chdir_toolong_temp_directory (const char *basename);
-+
-+/* Change into the innermost directory of the directory tree BASE, which was
-+   created using support_create_and_chdir_toolong_temp_directory.  */
-+void support_chdir_toolong_temp_directory (const char *base);
-+
- __END_DECLS
- 
- #endif /* SUPPORT_TEMP_FILE_H */
diff --git a/SOURCES/glibc-rh2032280-4.patch b/SOURCES/glibc-rh2032280-4.patch
deleted file mode 100644
index 65ba651..0000000
--- a/SOURCES/glibc-rh2032280-4.patch
+++ /dev/null
@@ -1,331 +0,0 @@
-commit 23e0e8f5f1fb5ed150253d986ecccdc90c2dcd5e
-Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
-Date:   Fri Jan 21 23:32:56 2022 +0530
-
-    getcwd: Set errno to ERANGE for size == 1 (CVE-2021-3999)
-    
-    No valid path returned by getcwd would fit into 1 byte, so reject the
-    size early and return NULL with errno set to ERANGE.  This change is
-    prompted by CVE-2021-3999, which describes a single byte buffer
-    underflow and overflow when all of the following conditions are met:
-    
-    - The buffer size (i.e. the second argument of getcwd) is 1 byte
-    - The current working directory is too long
-    - '/' is also mounted on the current working directory
-    
-    Sequence of events:
-    
-    - In sysdeps/unix/sysv/linux/getcwd.c, the syscall returns ENAMETOOLONG
-      because the linux kernel checks for name length before it checks
-      buffer size
-    
-    - The code falls back to the generic getcwd in sysdeps/posix
-    
-    - In the generic func, the buf[0] is set to '\0' on line 250
-    
-    - this while loop on line 262 is bypassed:
-    
-        while (!(thisdev == rootdev && thisino == rootino))
-    
-      since the rootfs (/) is bind mounted onto the directory and the flow
-      goes on to line 449, where it puts a '/' in the byte before the
-      buffer.
-    
-    - Finally on line 458, it moves 2 bytes (the underflowed byte and the
-      '\0') to the buf[0] and buf[1], resulting in a 1 byte buffer overflow.
-    
-    - buf is returned on line 469 and errno is not set.
-    
-    This resolves BZ #28769.
-    
-    Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
-    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
-    Signed-off-by: Qualys Security Advisory <qsa@qualys.com>
-    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-
-# Conflicts:
-#	sysdeps/posix/getcwd.c
-#	sysdeps/unix/sysv/linux/Makefile
-
-diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
-index b53433a2dc77fafa..fcd7aaea79c6477b 100644
---- a/sysdeps/posix/getcwd.c
-+++ b/sysdeps/posix/getcwd.c
-@@ -238,6 +238,13 @@ __getcwd (char *buf, size_t size)
-   bool fd_needs_closing = false;
-   int fd = AT_FDCWD;
- 
-+  /* A size of 1 byte is never useful.  */
-+  if (size == 1)
-+    {
-+      __set_errno (ERANGE);
-+      return NULL;
-+    }
-+
-   char *path;
- #ifndef NO_ALLOCATION
-   size_t allocated = size;
-diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
-index 688cf9fa9dea23a6..bb055f9d6b841ff5 100644
---- a/sysdeps/unix/sysv/linux/Makefile
-+++ b/sysdeps/unix/sysv/linux/Makefile
-@@ -180,7 +180,11 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
- 
- sysdep_headers += bits/fcntl-linux.h
- 
--tests += tst-fallocate tst-fallocate64
-+tests += \
-+  tst-fallocate \
-+  tst-fallocate64 \
-+  tst-getcwd-smallbuff \
-+# tests
- endif
- 
- ifeq ($(subdir),elf)
-diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
-new file mode 100644
-index 0000000000000000..d460d6e7662dc5e4
---- /dev/null
-+++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
-@@ -0,0 +1,241 @@
-+/* Verify that getcwd returns ERANGE for size 1 byte and does not underflow
-+   buffer when the CWD is too long and is also a mount target of /.  See bug
-+   #28769 or CVE-2021-3999 for more context.
-+   Copyright The GNU Toolchain Authors.
-+   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 <fcntl.h>
-+#include <intprops.h>
-+#include <limits.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/mount.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+#include <support/check.h>
-+#include <support/temp_file.h>
-+#include <support/xsched.h>
-+#include <support/xunistd.h>
-+
-+static char *base;
-+#define BASENAME "tst-getcwd-smallbuff"
-+#define MOUNT_NAME "mpoint"
-+static int sockfd[2];
-+
-+static void
-+do_cleanup (void)
-+{
-+  support_chdir_toolong_temp_directory (base);
-+  TEST_VERIFY_EXIT (rmdir (MOUNT_NAME) == 0);
-+  free (base);
-+}
-+
-+static void
-+send_fd (const int sock, const int fd)
-+{
-+  struct msghdr msg = {0};
-+  union
-+    {
-+      struct cmsghdr hdr;
-+      char buf[CMSG_SPACE (sizeof (int))];
-+    } cmsgbuf = {0};
-+  struct cmsghdr *cmsg;
-+  struct iovec vec;
-+  char ch = 'A';
-+  ssize_t n;
-+
-+  msg.msg_control = &cmsgbuf.buf;
-+  msg.msg_controllen = sizeof (cmsgbuf.buf);
-+
-+  cmsg = CMSG_FIRSTHDR (&msg);
-+  cmsg->cmsg_len = CMSG_LEN (sizeof (int));
-+  cmsg->cmsg_level = SOL_SOCKET;
-+  cmsg->cmsg_type = SCM_RIGHTS;
-+  memcpy (CMSG_DATA (cmsg), &fd, sizeof (fd));
-+
-+  vec.iov_base = &ch;
-+  vec.iov_len = 1;
-+  msg.msg_iov = &vec;
-+  msg.msg_iovlen = 1;
-+
-+  while ((n = sendmsg (sock, &msg, 0)) == -1 && errno == EINTR);
-+
-+  TEST_VERIFY_EXIT (n == 1);
-+}
-+
-+static int
-+recv_fd (const int sock)
-+{
-+  struct msghdr msg = {0};
-+  union
-+    {
-+      struct cmsghdr hdr;
-+      char buf[CMSG_SPACE(sizeof(int))];
-+    } cmsgbuf = {0};
-+  struct cmsghdr *cmsg;
-+  struct iovec vec;
-+  ssize_t n;
-+  char ch = '\0';
-+  int fd = -1;
-+
-+  vec.iov_base = &ch;
-+  vec.iov_len = 1;
-+  msg.msg_iov = &vec;
-+  msg.msg_iovlen = 1;
-+
-+  msg.msg_control = &cmsgbuf.buf;
-+  msg.msg_controllen = sizeof (cmsgbuf.buf);
-+
-+  while ((n = recvmsg (sock, &msg, 0)) == -1 && errno == EINTR);
-+  if (n != 1 || ch != 'A')
-+    return -1;
-+
-+  cmsg = CMSG_FIRSTHDR (&msg);
-+  if (cmsg == NULL)
-+    return -1;
-+  if (cmsg->cmsg_type != SCM_RIGHTS)
-+    return -1;
-+  memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd));
-+  if (fd < 0)
-+    return -1;
-+  return fd;
-+}
-+
-+static int
-+child_func (void * const arg)
-+{
-+  xclose (sockfd[0]);
-+  const int sock = sockfd[1];
-+  char ch;
-+
-+  TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1);
-+  TEST_VERIFY_EXIT (ch == '1');
-+
-+  if (mount ("/", MOUNT_NAME, NULL, MS_BIND | MS_REC, NULL))
-+    FAIL_EXIT1 ("mount failed: %m\n");
-+  const int fd = xopen ("mpoint",
-+			O_RDONLY | O_PATH | O_DIRECTORY | O_NOFOLLOW, 0);
-+
-+  send_fd (sock, fd);
-+  xclose (fd);
-+
-+  TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1);
-+  TEST_VERIFY_EXIT (ch == 'a');
-+
-+  xclose (sock);
-+  return 0;
-+}
-+
-+static void
-+update_map (char * const mapping, const char * const map_file)
-+{
-+  const size_t map_len = strlen (mapping);
-+
-+  const int fd = xopen (map_file, O_WRONLY, 0);
-+  xwrite (fd, mapping, map_len);
-+  xclose (fd);
-+}
-+
-+static void
-+proc_setgroups_write (const long child_pid, const char * const str)
-+{
-+  const size_t str_len = strlen(str);
-+
-+  char setgroups_path[sizeof ("/proc//setgroups") + INT_STRLEN_BOUND (long)];
-+
-+  snprintf (setgroups_path, sizeof (setgroups_path),
-+	    "/proc/%ld/setgroups", child_pid);
-+
-+  const int fd = open (setgroups_path, O_WRONLY);
-+
-+  if (fd < 0)
-+    {
-+      TEST_VERIFY_EXIT (errno == ENOENT);
-+      FAIL_UNSUPPORTED ("/proc/%ld/setgroups not found\n", child_pid);
-+    }
-+
-+  xwrite (fd, str, str_len);
-+  xclose(fd);
-+}
-+
-+static char child_stack[1024 * 1024];
-+
-+int
-+do_test (void)
-+{
-+  base = support_create_and_chdir_toolong_temp_directory (BASENAME);
-+
-+  xmkdir (MOUNT_NAME, S_IRWXU);
-+  atexit (do_cleanup);
-+
-+  TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0);
-+  pid_t child_pid = xclone (child_func, NULL, child_stack,
-+			    sizeof (child_stack),
-+			    CLONE_NEWUSER | CLONE_NEWNS | SIGCHLD);
-+
-+  xclose (sockfd[1]);
-+  const int sock = sockfd[0];
-+
-+  char map_path[sizeof ("/proc//uid_map") + INT_STRLEN_BOUND (long)];
-+  char map_buf[sizeof ("0  1") + INT_STRLEN_BOUND (long)];
-+
-+  snprintf (map_path, sizeof (map_path), "/proc/%ld/uid_map",
-+	    (long) child_pid);
-+  snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getuid());
-+  update_map (map_buf, map_path);
-+
-+  proc_setgroups_write ((long) child_pid, "deny");
-+  snprintf (map_path, sizeof (map_path), "/proc/%ld/gid_map",
-+	    (long) child_pid);
-+  snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getgid());
-+  update_map (map_buf, map_path);
-+
-+  TEST_VERIFY_EXIT (send (sock, "1", 1, MSG_NOSIGNAL) == 1);
-+  const int fd = recv_fd (sock);
-+  TEST_VERIFY_EXIT (fd >= 0);
-+  TEST_VERIFY_EXIT (fchdir (fd) == 0);
-+
-+  static char buf[2 * 10 + 1];
-+  memset (buf, 'A', sizeof (buf));
-+
-+  /* Finally, call getcwd and check if it resulted in a buffer underflow.  */
-+  char * cwd = getcwd (buf + sizeof (buf) / 2, 1);
-+  TEST_VERIFY (cwd == NULL);
-+  TEST_VERIFY (errno == ERANGE);
-+
-+  for (int i = 0; i < sizeof (buf); i++)
-+    if (buf[i] != 'A')
-+      {
-+	printf ("buf[%d] = %02x\n", i, (unsigned int) buf[i]);
-+	support_record_failure ();
-+      }
-+
-+  TEST_VERIFY_EXIT (send (sock, "a", 1, MSG_NOSIGNAL) == 1);
-+  xclose (sock);
-+  TEST_VERIFY_EXIT (xwaitpid (child_pid, NULL, 0) == child_pid);
-+
-+  return 0;
-+}
-+
-+#define CLEANUP_HANDLER do_cleanup
-+#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2032280-5.patch b/SOURCES/glibc-rh2032280-5.patch
deleted file mode 100644
index f761b9d..0000000
--- a/SOURCES/glibc-rh2032280-5.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-commit de8995a2a04163617c1a233b4b81356ef9f9741f
-Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-Date:   Wed Mar 10 12:26:30 2021 -0300
-
-    support: Add xclone
-    
-    It is a wrapper for Linux clone syscall, to simplify the call to the
-    use only the most common arguments and remove architecture specific
-    handling (such as ia64 different name and signature).
-
-# Conflicts:
-#	support/Makefile
-
-diff --git a/support/Makefile b/support/Makefile
-index fb95a69ed9158e78..d2b95539403e416c 100644
---- a/support/Makefile
-+++ b/support/Makefile
-@@ -84,6 +84,7 @@ libsupport-routines = \
-   xcalloc \
-   xchdir \
-   xchroot \
-+  xclone \
-   xclose \
-   xconnect \
-   xcopy_file_range \
-diff --git a/support/xclone.c b/support/xclone.c
-new file mode 100644
-index 0000000000000000..924d2b875402a819
---- /dev/null
-+++ b/support/xclone.c
-@@ -0,0 +1,50 @@
-+/* Auxiliary functions to issue the clone syscall.
-+   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/>.  */
-+
-+#ifdef __linux__
-+# include <support/check.h>
-+# include <stackinfo.h>  /* For _STACK_GROWS_{UP,DOWN}.  */
-+# include <xsched.h>
-+
-+pid_t
-+xclone (int (*fn) (void *arg), void *arg, void *stack, size_t stack_size,
-+	int flags)
-+{
-+  pid_t r = -1;
-+
-+# ifdef __ia64__
-+  extern int __clone2 (int (*fn) (void *arg), void *stack, size_t stack_size,
-+		       int flags, void *arg, ...);
-+  r = __clone2 (f, stack, stack_size, flags, arg, /* ptid */ NULL,
-+		/* tls */ NULL, /* ctid  */ ctid);
-+# else
-+#  if _STACK_GROWS_DOWN
-+  r = clone (fn, stack + stack_size, flags, arg, /* ptid */ NULL,
-+	     /* tls */ NULL, /* ctid */  NULL);
-+#  elif _STACK_GROWS_UP
-+  r = clone (fn, stack, flags, arg, /* ptid */ NULL, /* tls */ NULL,
-+	     &ctid);
-+#  endif
-+# endif
-+
-+  if (r < 0)
-+    FAIL_EXIT1 ("clone: %m");
-+
-+  return r;
-+}
-+#endif
-diff --git a/support/xsched.h b/support/xsched.h
-new file mode 100644
-index 0000000000000000..eefd731940187b39
---- /dev/null
-+++ b/support/xsched.h
-@@ -0,0 +1,34 @@
-+/* Wrapper for sched.h functions.
-+   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/>.  */
-+
-+#ifndef SUPPORT_XSCHED_H
-+#define SUPPORT_XSCHED_H
-+
-+__BEGIN_DECLS
-+
-+#include <sched.h>
-+#include <sys/types.h>
-+
-+#ifdef __linux__
-+pid_t xclone (int (*fn) (void *arg), void *arg, void *stack,
-+	      size_t stack_size, int flags);
-+#endif
-+
-+__END_DECLS
-+
-+#endif
diff --git a/SOURCES/glibc-rh2032280-6.patch b/SOURCES/glibc-rh2032280-6.patch
deleted file mode 100644
index a8bc55b..0000000
--- a/SOURCES/glibc-rh2032280-6.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-commit 5b8e7980c5dabd9aaefeba4f0208baa8cf7653ee
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Mon Jan 24 18:14:24 2022 +0100
-
-    Linux: Detect user namespace support in io/tst-getcwd-smallbuff
-    
-    Otherwise the test fails with certain container runtimes.
-    
-    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-
-diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
-index d460d6e7662dc5e4..55362f6060a2b3be 100644
---- a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
-+++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
-@@ -34,6 +34,7 @@
- #include <sys/un.h>
- #include <support/check.h>
- #include <support/temp_file.h>
-+#include <support/test-driver.h>
- #include <support/xsched.h>
- #include <support/xunistd.h>
- 
-@@ -188,6 +189,23 @@ do_test (void)
-   xmkdir (MOUNT_NAME, S_IRWXU);
-   atexit (do_cleanup);
- 
-+  /* Check whether user namespaces are supported.  */
-+  {
-+    pid_t pid = xfork ();
-+    if (pid == 0)
-+      {
-+	if (unshare (CLONE_NEWUSER | CLONE_NEWNS) != 0)
-+	  _exit (EXIT_UNSUPPORTED);
-+	else
-+	  _exit (0);
-+      }
-+    int status;
-+    xwaitpid (pid, &status, 0);
-+    TEST_VERIFY_EXIT (WIFEXITED (status));
-+    if (WEXITSTATUS (status) != 0)
-+      return WEXITSTATUS (status);
-+  }
-+
-   TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0);
-   pid_t child_pid = xclone (child_func, NULL, child_stack,
- 			    sizeof (child_stack),
diff --git a/SOURCES/glibc-rh2032280-7.patch b/SOURCES/glibc-rh2032280-7.patch
deleted file mode 100644
index 60ea205..0000000
--- a/SOURCES/glibc-rh2032280-7.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-commit 3842ba494963b1d76ad5f68b8d1e5c2279160e31
-Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
-Date:   Tue Jun 1 09:23:40 2021 +0100
-
-    aarch64: align stack in clone [BZ #27939]
-    
-    The AArch64 PCS requires 16 byte aligned stack.  Previously if the
-    caller passed an unaligned stack to clone then the child crashed.
-    
-    Fixes bug 27939.
-
-diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S
-index e0653048259dd9a3..4a1a999447ee5cf1 100644
---- a/sysdeps/unix/sysv/linux/aarch64/clone.S
-+++ b/sysdeps/unix/sysv/linux/aarch64/clone.S
-@@ -48,6 +48,8 @@ ENTRY(__clone)
- 	/* Sanity check args.  */
- 	mov	x0, #-EINVAL
- 	cbz	x10, .Lsyscall_error
-+	/* Align sp.  */
-+	and	x1, x1, -16
- 	cbz	x1, .Lsyscall_error
- 
- 	/* Do the system call.  */
diff --git a/SOURCES/glibc-rh2032281-1.patch b/SOURCES/glibc-rh2032281-1.patch
new file mode 100644
index 0000000..6308350
--- /dev/null
+++ b/SOURCES/glibc-rh2032281-1.patch
@@ -0,0 +1,64 @@
+commit a7e9dbb7742954814643a8562dcad09abb0b0e5d
+Author: Alexandra Hájková <ahajkova@redhat.com>
+Date:   Sat Dec 26 18:45:13 2020 +0100
+
+    Add xchdir to libsupport.
+
+diff --git a/support/Makefile b/support/Makefile
+index dcf3c4baa2a31070..fb95a69ed9158e78 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -82,6 +82,7 @@ libsupport-routines = \
+   xasprintf \
+   xbind \
+   xcalloc \
++  xchdir \
+   xchroot \
+   xclose \
+   xconnect \
+diff --git a/support/xchdir.c b/support/xchdir.c
+new file mode 100644
+index 0000000000000000..beb4feff72832065
+--- /dev/null
++++ b/support/xchdir.c
+@@ -0,0 +1,28 @@
++/* chdir with error checking.
++   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 <support/check.h>
++#include <support/xunistd.h>
++#include <unistd.h>
++
++void
++xchdir (const char *path)
++{
++  if (chdir (path) != 0)
++    FAIL_EXIT1 ("chdir (\"%s\"): %m", path);
++}
+diff --git a/support/xunistd.h b/support/xunistd.h
+index f99f362cb4763c5b..74fd2771d12c36fe 100644
+--- a/support/xunistd.h
++++ b/support/xunistd.h
+@@ -44,6 +44,7 @@ long xsysconf (int name);
+ long long xlseek (int fd, long long offset, int whence);
+ void xftruncate (int fd, long long length);
+ void xsymlink (const char *target, const char *linkpath);
++void xchdir (const char *path);
+ 
+ /* Equivalent of "mkdir -p".  */
+ void xmkdirp (const char *, mode_t);
diff --git a/SOURCES/glibc-rh2032281-2.patch b/SOURCES/glibc-rh2032281-2.patch
new file mode 100644
index 0000000..feac384
--- /dev/null
+++ b/SOURCES/glibc-rh2032281-2.patch
@@ -0,0 +1,74 @@
+Additionally include stdbool.h to fix issues with bool keyword usage.
+
+commit 60854f40ea2d420867ed2f0f052ee7fca661dbff
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Thu Oct 15 15:14:22 2020 -0300
+
+    support: Add create_temp_file_in_dir
+    
+    It allows created a temporary file in a specified directory.
+
+diff --git a/support/support.h b/support/support.h
+index f50f8cc1496d657d..96833bd4e992e6d3 100644
+--- a/support/support.h
++++ b/support/support.h
+@@ -23,6 +23,7 @@
+ #ifndef SUPPORT_H
+ #define SUPPORT_H
+ 
++#include <stdbool.h>
+ #include <stddef.h>
+ #include <sys/cdefs.h>
+ /* For mode_t.  */
+diff --git a/support/temp_file.c b/support/temp_file.c
+index 0bbc7f997264f758..5a2728c94a9c32ae 100644
+--- a/support/temp_file.c
++++ b/support/temp_file.c
+@@ -60,14 +60,12 @@ add_temp_file (const char *name)
+ }
+ 
+ int
+-create_temp_file (const char *base, char **filename)
++create_temp_file_in_dir (const char *base, const char *dir, char **filename)
+ {
+   char *fname;
+   int fd;
+ 
+-  fname = (char *) xmalloc (strlen (test_dir) + 1 + strlen (base)
+-			    + sizeof ("XXXXXX"));
+-  strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");
++  fname = xasprintf ("%s/%sXXXXXX", dir, base);
+ 
+   fd = mkstemp (fname);
+   if (fd == -1)
+@@ -86,6 +84,12 @@ create_temp_file (const char *base, char **filename)
+   return fd;
+ }
+ 
++int
++create_temp_file (const char *base, char **filename)
++{
++  return create_temp_file_in_dir (base, test_dir, filename);
++}
++
+ char *
+ support_create_temp_directory (const char *base)
+ {
+diff --git a/support/temp_file.h b/support/temp_file.h
+index c7795cc577ca22a9..d64563f41f1f50cd 100644
+--- a/support/temp_file.h
++++ b/support/temp_file.h
+@@ -32,6 +32,13 @@ void add_temp_file (const char *name);
+    *FILENAME.  */
+ int create_temp_file (const char *base, char **filename);
+ 
++/* Create a temporary file in directory DIR.  Return the opened file
++   descriptor on success, or -1 on failure.  Write the file name to
++   *FILENAME if FILENAME is not NULL.  In this case, the caller is
++   expected to free *FILENAME.  */
++int create_temp_file_in_dir (const char *base, const char *dir,
++			     char **filename);
++
+ /* Create a temporary directory and schedule it for deletion.  BASE is
+    used as a prefix for the unique directory name, which the function
+    returns.  The caller should free this string.  */
diff --git a/SOURCES/glibc-rh2032281-3.patch b/SOURCES/glibc-rh2032281-3.patch
new file mode 100644
index 0000000..7cb306d
--- /dev/null
+++ b/SOURCES/glibc-rh2032281-3.patch
@@ -0,0 +1,278 @@
+commit fb7bff12e81c677a6622f724edd4d4987dd9d971
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Tue Jan 18 13:29:36 2022 +0530
+
+    support: Add helpers to create paths longer than PATH_MAX
+    
+    Add new helpers support_create_and_chdir_toolong_temp_directory and
+    support_chdir_toolong_temp_directory to create and descend into
+    directory trees longer than PATH_MAX.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+# Conflicts:
+#	support/temp_file.c
+
+diff --git a/support/temp_file.c b/support/temp_file.c
+index 5a2728c94a9c32ae..661c86bad5c0121f 100644
+--- a/support/temp_file.c
++++ b/support/temp_file.c
+@@ -1,5 +1,6 @@
+ /* Temporary file handling for tests.
+-   Copyright (C) 1998-2018 Free Software Foundation, Inc.
++   Copyright (C) 1998-2022 Free Software Foundation, Inc.
++   Copyright The GNU Tools Authors.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+@@ -20,15 +21,17 @@
+    some 32-bit platforms. */
+ #define _FILE_OFFSET_BITS 64
+ 
++#include <support/check.h>
+ #include <support/temp_file.h>
+ #include <support/temp_file-internal.h>
+ #include <support/support.h>
+ 
++#include <errno.h>
+ #include <paths.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <unistd.h>
++#include <xunistd.h>
+ 
+ /* List of temporary files.  */
+ static struct temp_name_list
+@@ -36,14 +39,20 @@ static struct temp_name_list
+   struct temp_name_list *next;
+   char *name;
+   pid_t owner;
++  bool toolong;
+ } *temp_name_list;
+ 
+ /* Location of the temporary files.  Set by the test skeleton via
+    support_set_test_dir.  The string is not be freed.  */
+ static const char *test_dir = _PATH_TMP;
+ 
+-void
+-add_temp_file (const char *name)
++/* Name of subdirectories in a too long temporary directory tree.  */
++static char toolong_subdir[NAME_MAX + 1];
++static bool toolong_initialized;
++static size_t toolong_path_max;
++
++static void
++add_temp_file_internal (const char *name, bool toolong)
+ {
+   struct temp_name_list *newp
+     = (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
+@@ -53,12 +62,19 @@ add_temp_file (const char *name)
+       newp->name = newname;
+       newp->next = temp_name_list;
+       newp->owner = getpid ();
++      newp->toolong = toolong;
+       temp_name_list = newp;
+     }
+   else
+     free (newp);
+ }
+ 
++void
++add_temp_file (const char *name)
++{
++  add_temp_file_internal (name, false);
++}
++
+ int
+ create_temp_file_in_dir (const char *base, const char *dir, char **filename)
+ {
+@@ -90,8 +106,8 @@ create_temp_file (const char *base, char **filename)
+   return create_temp_file_in_dir (base, test_dir, filename);
+ }
+ 
+-char *
+-support_create_temp_directory (const char *base)
++static char *
++create_temp_directory_internal (const char *base, bool toolong)
+ {
+   char *path = xasprintf ("%s/%sXXXXXX", test_dir, base);
+   if (mkdtemp (path) == NULL)
+@@ -99,16 +115,132 @@ support_create_temp_directory (const char *base)
+       printf ("error: mkdtemp (\"%s\"): %m", path);
+       exit (1);
+     }
+-  add_temp_file (path);
++  add_temp_file_internal (path, toolong);
+   return path;
+ }
+ 
+-/* Helper functions called by the test skeleton follow.  */
++char *
++support_create_temp_directory (const char *base)
++{
++  return create_temp_directory_internal (base, false);
++}
++
++static void
++ensure_toolong_initialized (void)
++{
++  if (!toolong_initialized)
++    FAIL_EXIT1 ("uninitialized toolong directory tree\n");
++}
++
++static void
++initialize_toolong (const char *base)
++{
++  long name_max = pathconf (base, _PC_NAME_MAX);
++  name_max = (name_max < 0 ? 64
++	      : (name_max < sizeof (toolong_subdir) ? name_max
++		 : sizeof (toolong_subdir) - 1));
++
++  long path_max = pathconf (base, _PC_PATH_MAX);
++  path_max = (path_max < 0 ? 1024
++	      : path_max <= PTRDIFF_MAX ? path_max : PTRDIFF_MAX);
++
++  /* Sanity check to ensure that the test does not create temporary directories
++     in different filesystems because this API doesn't support it.  */
++  if (toolong_initialized)
++    {
++      if (name_max != strlen (toolong_subdir))
++	FAIL_UNSUPPORTED ("name_max: Temporary directories in different"
++			  " filesystems not supported yet\n");
++      if (path_max != toolong_path_max)
++	FAIL_UNSUPPORTED ("path_max: Temporary directories in different"
++			  " filesystems not supported yet\n");
++      return;
++    }
++
++  toolong_path_max = path_max;
++
++  size_t len = name_max;
++  memset (toolong_subdir, 'X', len);
++  toolong_initialized = true;
++}
++
++char *
++support_create_and_chdir_toolong_temp_directory (const char *basename)
++{
++  char *base = create_temp_directory_internal (basename, true);
++  xchdir (base);
++
++  initialize_toolong (base);
++
++  size_t sz = strlen (toolong_subdir);
++
++  /* Create directories and descend into them so that the final path is larger
++     than PATH_MAX.  */
++  for (size_t i = 0; i <= toolong_path_max / sz; i++)
++    {
++      int ret = mkdir (toolong_subdir, S_IRWXU);
++      if (ret != 0 && errno == ENAMETOOLONG)
++	FAIL_UNSUPPORTED ("Filesystem does not support creating too long "
++			  "directory trees\n");
++      else if (ret != 0)
++	FAIL_EXIT1 ("Failed to create directory tree: %m\n");
++      xchdir (toolong_subdir);
++    }
++  return base;
++}
+ 
+ void
+-support_set_test_dir (const char *path)
++support_chdir_toolong_temp_directory (const char *base)
+ {
+-  test_dir = path;
++  ensure_toolong_initialized ();
++
++  xchdir (base);
++
++  size_t sz = strlen (toolong_subdir);
++  for (size_t i = 0; i <= toolong_path_max / sz; i++)
++    xchdir (toolong_subdir);
++}
++
++/* Helper functions called by the test skeleton follow.  */
++
++static void
++remove_toolong_subdirs (const char *base)
++{
++  ensure_toolong_initialized ();
++
++  if (chdir (base) != 0)
++    {
++      printf ("warning: toolong cleanup base failed: chdir (\"%s\"): %m\n",
++	      base);
++      return;
++    }
++
++  /* Descend.  */
++  int levels = 0;
++  size_t sz = strlen (toolong_subdir);
++  for (levels = 0; levels <= toolong_path_max / sz; levels++)
++    if (chdir (toolong_subdir) != 0)
++      {
++	printf ("warning: toolong cleanup failed: chdir (\"%s\"): %m\n",
++		toolong_subdir);
++	break;
++      }
++
++  /* Ascend and remove.  */
++  while (--levels >= 0)
++    {
++      if (chdir ("..") != 0)
++	{
++	  printf ("warning: toolong cleanup failed: chdir (\"..\"): %m\n");
++	  return;
++	}
++      if (remove (toolong_subdir) != 0)
++	{
++	  printf ("warning: could not remove subdirectory: %s: %m\n",
++		  toolong_subdir);
++	  return;
++	}
++    }
+ }
+ 
+ void
+@@ -123,6 +255,9 @@ support_delete_temp_files (void)
+ 	 around, to prevent PID reuse.)  */
+       if (temp_name_list->owner == pid)
+ 	{
++	  if (temp_name_list->toolong)
++	    remove_toolong_subdirs (temp_name_list->name);
++
+ 	  if (remove (temp_name_list->name) != 0)
+ 	    printf ("warning: could not remove temporary file: %s: %m\n",
+ 		    temp_name_list->name);
+@@ -147,3 +282,9 @@ support_print_temp_files (FILE *f)
+       fprintf (f, ")\n");
+     }
+ }
++
++void
++support_set_test_dir (const char *path)
++{
++  test_dir = path;
++}
+diff --git a/support/temp_file.h b/support/temp_file.h
+index d64563f41f1f50cd..055e31dcfb843ba6 100644
+--- a/support/temp_file.h
++++ b/support/temp_file.h
+@@ -44,6 +44,15 @@ int create_temp_file_in_dir (const char *base, const char *dir,
+    returns.  The caller should free this string.  */
+ char *support_create_temp_directory (const char *base);
+ 
++/* Create a temporary directory tree that is longer than PATH_MAX and schedule
++   it for deletion.  BASENAME is used as a prefix for the unique directory
++   name, which the function returns.  The caller should free this string.  */
++char *support_create_and_chdir_toolong_temp_directory (const char *basename);
++
++/* Change into the innermost directory of the directory tree BASE, which was
++   created using support_create_and_chdir_toolong_temp_directory.  */
++void support_chdir_toolong_temp_directory (const char *base);
++
+ __END_DECLS
+ 
+ #endif /* SUPPORT_TEMP_FILE_H */
diff --git a/SOURCES/glibc-rh2032281-4.patch b/SOURCES/glibc-rh2032281-4.patch
new file mode 100644
index 0000000..65ba651
--- /dev/null
+++ b/SOURCES/glibc-rh2032281-4.patch
@@ -0,0 +1,331 @@
+commit 23e0e8f5f1fb5ed150253d986ecccdc90c2dcd5e
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Fri Jan 21 23:32:56 2022 +0530
+
+    getcwd: Set errno to ERANGE for size == 1 (CVE-2021-3999)
+    
+    No valid path returned by getcwd would fit into 1 byte, so reject the
+    size early and return NULL with errno set to ERANGE.  This change is
+    prompted by CVE-2021-3999, which describes a single byte buffer
+    underflow and overflow when all of the following conditions are met:
+    
+    - The buffer size (i.e. the second argument of getcwd) is 1 byte
+    - The current working directory is too long
+    - '/' is also mounted on the current working directory
+    
+    Sequence of events:
+    
+    - In sysdeps/unix/sysv/linux/getcwd.c, the syscall returns ENAMETOOLONG
+      because the linux kernel checks for name length before it checks
+      buffer size
+    
+    - The code falls back to the generic getcwd in sysdeps/posix
+    
+    - In the generic func, the buf[0] is set to '\0' on line 250
+    
+    - this while loop on line 262 is bypassed:
+    
+        while (!(thisdev == rootdev && thisino == rootino))
+    
+      since the rootfs (/) is bind mounted onto the directory and the flow
+      goes on to line 449, where it puts a '/' in the byte before the
+      buffer.
+    
+    - Finally on line 458, it moves 2 bytes (the underflowed byte and the
+      '\0') to the buf[0] and buf[1], resulting in a 1 byte buffer overflow.
+    
+    - buf is returned on line 469 and errno is not set.
+    
+    This resolves BZ #28769.
+    
+    Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    Signed-off-by: Qualys Security Advisory <qsa@qualys.com>
+    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+# Conflicts:
+#	sysdeps/posix/getcwd.c
+#	sysdeps/unix/sysv/linux/Makefile
+
+diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
+index b53433a2dc77fafa..fcd7aaea79c6477b 100644
+--- a/sysdeps/posix/getcwd.c
++++ b/sysdeps/posix/getcwd.c
+@@ -238,6 +238,13 @@ __getcwd (char *buf, size_t size)
+   bool fd_needs_closing = false;
+   int fd = AT_FDCWD;
+ 
++  /* A size of 1 byte is never useful.  */
++  if (size == 1)
++    {
++      __set_errno (ERANGE);
++      return NULL;
++    }
++
+   char *path;
+ #ifndef NO_ALLOCATION
+   size_t allocated = size;
+diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
+index 688cf9fa9dea23a6..bb055f9d6b841ff5 100644
+--- a/sysdeps/unix/sysv/linux/Makefile
++++ b/sysdeps/unix/sysv/linux/Makefile
+@@ -180,7 +180,11 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
+ 
+ sysdep_headers += bits/fcntl-linux.h
+ 
+-tests += tst-fallocate tst-fallocate64
++tests += \
++  tst-fallocate \
++  tst-fallocate64 \
++  tst-getcwd-smallbuff \
++# tests
+ endif
+ 
+ ifeq ($(subdir),elf)
+diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
+new file mode 100644
+index 0000000000000000..d460d6e7662dc5e4
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
+@@ -0,0 +1,241 @@
++/* Verify that getcwd returns ERANGE for size 1 byte and does not underflow
++   buffer when the CWD is too long and is also a mount target of /.  See bug
++   #28769 or CVE-2021-3999 for more context.
++   Copyright The GNU Toolchain Authors.
++   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 <fcntl.h>
++#include <intprops.h>
++#include <limits.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/mount.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <support/check.h>
++#include <support/temp_file.h>
++#include <support/xsched.h>
++#include <support/xunistd.h>
++
++static char *base;
++#define BASENAME "tst-getcwd-smallbuff"
++#define MOUNT_NAME "mpoint"
++static int sockfd[2];
++
++static void
++do_cleanup (void)
++{
++  support_chdir_toolong_temp_directory (base);
++  TEST_VERIFY_EXIT (rmdir (MOUNT_NAME) == 0);
++  free (base);
++}
++
++static void
++send_fd (const int sock, const int fd)
++{
++  struct msghdr msg = {0};
++  union
++    {
++      struct cmsghdr hdr;
++      char buf[CMSG_SPACE (sizeof (int))];
++    } cmsgbuf = {0};
++  struct cmsghdr *cmsg;
++  struct iovec vec;
++  char ch = 'A';
++  ssize_t n;
++
++  msg.msg_control = &cmsgbuf.buf;
++  msg.msg_controllen = sizeof (cmsgbuf.buf);
++
++  cmsg = CMSG_FIRSTHDR (&msg);
++  cmsg->cmsg_len = CMSG_LEN (sizeof (int));
++  cmsg->cmsg_level = SOL_SOCKET;
++  cmsg->cmsg_type = SCM_RIGHTS;
++  memcpy (CMSG_DATA (cmsg), &fd, sizeof (fd));
++
++  vec.iov_base = &ch;
++  vec.iov_len = 1;
++  msg.msg_iov = &vec;
++  msg.msg_iovlen = 1;
++
++  while ((n = sendmsg (sock, &msg, 0)) == -1 && errno == EINTR);
++
++  TEST_VERIFY_EXIT (n == 1);
++}
++
++static int
++recv_fd (const int sock)
++{
++  struct msghdr msg = {0};
++  union
++    {
++      struct cmsghdr hdr;
++      char buf[CMSG_SPACE(sizeof(int))];
++    } cmsgbuf = {0};
++  struct cmsghdr *cmsg;
++  struct iovec vec;
++  ssize_t n;
++  char ch = '\0';
++  int fd = -1;
++
++  vec.iov_base = &ch;
++  vec.iov_len = 1;
++  msg.msg_iov = &vec;
++  msg.msg_iovlen = 1;
++
++  msg.msg_control = &cmsgbuf.buf;
++  msg.msg_controllen = sizeof (cmsgbuf.buf);
++
++  while ((n = recvmsg (sock, &msg, 0)) == -1 && errno == EINTR);
++  if (n != 1 || ch != 'A')
++    return -1;
++
++  cmsg = CMSG_FIRSTHDR (&msg);
++  if (cmsg == NULL)
++    return -1;
++  if (cmsg->cmsg_type != SCM_RIGHTS)
++    return -1;
++  memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd));
++  if (fd < 0)
++    return -1;
++  return fd;
++}
++
++static int
++child_func (void * const arg)
++{
++  xclose (sockfd[0]);
++  const int sock = sockfd[1];
++  char ch;
++
++  TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1);
++  TEST_VERIFY_EXIT (ch == '1');
++
++  if (mount ("/", MOUNT_NAME, NULL, MS_BIND | MS_REC, NULL))
++    FAIL_EXIT1 ("mount failed: %m\n");
++  const int fd = xopen ("mpoint",
++			O_RDONLY | O_PATH | O_DIRECTORY | O_NOFOLLOW, 0);
++
++  send_fd (sock, fd);
++  xclose (fd);
++
++  TEST_VERIFY_EXIT (read (sock, &ch, 1) == 1);
++  TEST_VERIFY_EXIT (ch == 'a');
++
++  xclose (sock);
++  return 0;
++}
++
++static void
++update_map (char * const mapping, const char * const map_file)
++{
++  const size_t map_len = strlen (mapping);
++
++  const int fd = xopen (map_file, O_WRONLY, 0);
++  xwrite (fd, mapping, map_len);
++  xclose (fd);
++}
++
++static void
++proc_setgroups_write (const long child_pid, const char * const str)
++{
++  const size_t str_len = strlen(str);
++
++  char setgroups_path[sizeof ("/proc//setgroups") + INT_STRLEN_BOUND (long)];
++
++  snprintf (setgroups_path, sizeof (setgroups_path),
++	    "/proc/%ld/setgroups", child_pid);
++
++  const int fd = open (setgroups_path, O_WRONLY);
++
++  if (fd < 0)
++    {
++      TEST_VERIFY_EXIT (errno == ENOENT);
++      FAIL_UNSUPPORTED ("/proc/%ld/setgroups not found\n", child_pid);
++    }
++
++  xwrite (fd, str, str_len);
++  xclose(fd);
++}
++
++static char child_stack[1024 * 1024];
++
++int
++do_test (void)
++{
++  base = support_create_and_chdir_toolong_temp_directory (BASENAME);
++
++  xmkdir (MOUNT_NAME, S_IRWXU);
++  atexit (do_cleanup);
++
++  TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0);
++  pid_t child_pid = xclone (child_func, NULL, child_stack,
++			    sizeof (child_stack),
++			    CLONE_NEWUSER | CLONE_NEWNS | SIGCHLD);
++
++  xclose (sockfd[1]);
++  const int sock = sockfd[0];
++
++  char map_path[sizeof ("/proc//uid_map") + INT_STRLEN_BOUND (long)];
++  char map_buf[sizeof ("0  1") + INT_STRLEN_BOUND (long)];
++
++  snprintf (map_path, sizeof (map_path), "/proc/%ld/uid_map",
++	    (long) child_pid);
++  snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getuid());
++  update_map (map_buf, map_path);
++
++  proc_setgroups_write ((long) child_pid, "deny");
++  snprintf (map_path, sizeof (map_path), "/proc/%ld/gid_map",
++	    (long) child_pid);
++  snprintf (map_buf, sizeof (map_buf), "0 %ld 1", (long) getgid());
++  update_map (map_buf, map_path);
++
++  TEST_VERIFY_EXIT (send (sock, "1", 1, MSG_NOSIGNAL) == 1);
++  const int fd = recv_fd (sock);
++  TEST_VERIFY_EXIT (fd >= 0);
++  TEST_VERIFY_EXIT (fchdir (fd) == 0);
++
++  static char buf[2 * 10 + 1];
++  memset (buf, 'A', sizeof (buf));
++
++  /* Finally, call getcwd and check if it resulted in a buffer underflow.  */
++  char * cwd = getcwd (buf + sizeof (buf) / 2, 1);
++  TEST_VERIFY (cwd == NULL);
++  TEST_VERIFY (errno == ERANGE);
++
++  for (int i = 0; i < sizeof (buf); i++)
++    if (buf[i] != 'A')
++      {
++	printf ("buf[%d] = %02x\n", i, (unsigned int) buf[i]);
++	support_record_failure ();
++      }
++
++  TEST_VERIFY_EXIT (send (sock, "a", 1, MSG_NOSIGNAL) == 1);
++  xclose (sock);
++  TEST_VERIFY_EXIT (xwaitpid (child_pid, NULL, 0) == child_pid);
++
++  return 0;
++}
++
++#define CLEANUP_HANDLER do_cleanup
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2032281-5.patch b/SOURCES/glibc-rh2032281-5.patch
new file mode 100644
index 0000000..f761b9d
--- /dev/null
+++ b/SOURCES/glibc-rh2032281-5.patch
@@ -0,0 +1,121 @@
+commit de8995a2a04163617c1a233b4b81356ef9f9741f
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Mar 10 12:26:30 2021 -0300
+
+    support: Add xclone
+    
+    It is a wrapper for Linux clone syscall, to simplify the call to the
+    use only the most common arguments and remove architecture specific
+    handling (such as ia64 different name and signature).
+
+# Conflicts:
+#	support/Makefile
+
+diff --git a/support/Makefile b/support/Makefile
+index fb95a69ed9158e78..d2b95539403e416c 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -84,6 +84,7 @@ libsupport-routines = \
+   xcalloc \
+   xchdir \
+   xchroot \
++  xclone \
+   xclose \
+   xconnect \
+   xcopy_file_range \
+diff --git a/support/xclone.c b/support/xclone.c
+new file mode 100644
+index 0000000000000000..924d2b875402a819
+--- /dev/null
++++ b/support/xclone.c
+@@ -0,0 +1,50 @@
++/* Auxiliary functions to issue the clone syscall.
++   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/>.  */
++
++#ifdef __linux__
++# include <support/check.h>
++# include <stackinfo.h>  /* For _STACK_GROWS_{UP,DOWN}.  */
++# include <xsched.h>
++
++pid_t
++xclone (int (*fn) (void *arg), void *arg, void *stack, size_t stack_size,
++	int flags)
++{
++  pid_t r = -1;
++
++# ifdef __ia64__
++  extern int __clone2 (int (*fn) (void *arg), void *stack, size_t stack_size,
++		       int flags, void *arg, ...);
++  r = __clone2 (f, stack, stack_size, flags, arg, /* ptid */ NULL,
++		/* tls */ NULL, /* ctid  */ ctid);
++# else
++#  if _STACK_GROWS_DOWN
++  r = clone (fn, stack + stack_size, flags, arg, /* ptid */ NULL,
++	     /* tls */ NULL, /* ctid */  NULL);
++#  elif _STACK_GROWS_UP
++  r = clone (fn, stack, flags, arg, /* ptid */ NULL, /* tls */ NULL,
++	     &ctid);
++#  endif
++# endif
++
++  if (r < 0)
++    FAIL_EXIT1 ("clone: %m");
++
++  return r;
++}
++#endif
+diff --git a/support/xsched.h b/support/xsched.h
+new file mode 100644
+index 0000000000000000..eefd731940187b39
+--- /dev/null
++++ b/support/xsched.h
+@@ -0,0 +1,34 @@
++/* Wrapper for sched.h functions.
++   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/>.  */
++
++#ifndef SUPPORT_XSCHED_H
++#define SUPPORT_XSCHED_H
++
++__BEGIN_DECLS
++
++#include <sched.h>
++#include <sys/types.h>
++
++#ifdef __linux__
++pid_t xclone (int (*fn) (void *arg), void *arg, void *stack,
++	      size_t stack_size, int flags);
++#endif
++
++__END_DECLS
++
++#endif
diff --git a/SOURCES/glibc-rh2032281-6.patch b/SOURCES/glibc-rh2032281-6.patch
new file mode 100644
index 0000000..a8bc55b
--- /dev/null
+++ b/SOURCES/glibc-rh2032281-6.patch
@@ -0,0 +1,46 @@
+commit 5b8e7980c5dabd9aaefeba4f0208baa8cf7653ee
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 24 18:14:24 2022 +0100
+
+    Linux: Detect user namespace support in io/tst-getcwd-smallbuff
+    
+    Otherwise the test fails with certain container runtimes.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
+index d460d6e7662dc5e4..55362f6060a2b3be 100644
+--- a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
++++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c
+@@ -34,6 +34,7 @@
+ #include <sys/un.h>
+ #include <support/check.h>
+ #include <support/temp_file.h>
++#include <support/test-driver.h>
+ #include <support/xsched.h>
+ #include <support/xunistd.h>
+ 
+@@ -188,6 +189,23 @@ do_test (void)
+   xmkdir (MOUNT_NAME, S_IRWXU);
+   atexit (do_cleanup);
+ 
++  /* Check whether user namespaces are supported.  */
++  {
++    pid_t pid = xfork ();
++    if (pid == 0)
++      {
++	if (unshare (CLONE_NEWUSER | CLONE_NEWNS) != 0)
++	  _exit (EXIT_UNSUPPORTED);
++	else
++	  _exit (0);
++      }
++    int status;
++    xwaitpid (pid, &status, 0);
++    TEST_VERIFY_EXIT (WIFEXITED (status));
++    if (WEXITSTATUS (status) != 0)
++      return WEXITSTATUS (status);
++  }
++
+   TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0);
+   pid_t child_pid = xclone (child_func, NULL, child_stack,
+ 			    sizeof (child_stack),
diff --git a/SOURCES/glibc-rh2032281-7.patch b/SOURCES/glibc-rh2032281-7.patch
new file mode 100644
index 0000000..60ea205
--- /dev/null
+++ b/SOURCES/glibc-rh2032281-7.patch
@@ -0,0 +1,24 @@
+commit 3842ba494963b1d76ad5f68b8d1e5c2279160e31
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Tue Jun 1 09:23:40 2021 +0100
+
+    aarch64: align stack in clone [BZ #27939]
+    
+    The AArch64 PCS requires 16 byte aligned stack.  Previously if the
+    caller passed an unaligned stack to clone then the child crashed.
+    
+    Fixes bug 27939.
+
+diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S
+index e0653048259dd9a3..4a1a999447ee5cf1 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/clone.S
++++ b/sysdeps/unix/sysv/linux/aarch64/clone.S
+@@ -48,6 +48,8 @@ ENTRY(__clone)
+ 	/* Sanity check args.  */
+ 	mov	x0, #-EINVAL
+ 	cbz	x10, .Lsyscall_error
++	/* Align sp.  */
++	and	x1, x1, -16
+ 	cbz	x1, .Lsyscall_error
+ 
+ 	/* Do the system call.  */
diff --git a/SOURCES/glibc-rh2033648-1.patch b/SOURCES/glibc-rh2033648-1.patch
new file mode 100644
index 0000000..8717167
--- /dev/null
+++ b/SOURCES/glibc-rh2033648-1.patch
@@ -0,0 +1,51 @@
+commit c36f64aa6dff13b12a1e03a185e75a50fa9f6a4c
+Author: Hans-Peter Nilsson <hp@axis.com>
+Date:   Fri Dec 17 21:38:00 2021 +0100
+
+    timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707)
+    
+    When using a timezone file with a truncated starting time,
+    generated by the zic in IANA tzcode-2021d a.k.a. tzlib-2021d
+    (also in tzlib-2021e; current as of this writing), glibc
+    asserts in __tzfile_read (on e.g. tzset() for this file) and
+    you may find lines matching "tzfile.c:435: __tzfile_read:
+    Assertion `num_types == 1' failed" in your syslog.
+    
+    One example of such a file is the tzfile for Asuncion
+    generated by tzlib-2021e as follows, using the tzlib-2021e zic:
+    "zic -d DEST -r @1546300800 -L /dev/null -b slim
+    SOURCE/southamerica".  Note that in its type 2 header, it has
+    two entries in its "time-types" array (types), but only one
+    entry in its "transition types" array (type_idxs).
+    
+    This is valid and expected already in the published RFC8536, and
+    not even frowned upon: "Local time for timestamps before the
+    first transition is specified by the first time type (time type
+    0)" ... "every nonzero local time type index SHOULD appear at
+    least once in the transition type array".  Note the "nonzero ...
+    index".  Until the 2021d zic, index 0 has been shared by the
+    first valid transition but with 2021d it's separate, set apart
+    as a placeholder and only "implicitly" indexed.  (A draft update
+    of the RFC mandates that the entry at index 0 is a placeholder
+    in this case, hence can no longer be shared.)
+    
+            * time/tzfile.c (__tzfile_read): Don't assert when no transitions
+            are found.
+    
+    Co-authored-by: Christopher Wong <Christopher.Wong@axis.com>
+
+diff --git a/time/tzfile.c b/time/tzfile.c
+index 190a777152..8668392ad3 100644
+--- a/time/tzfile.c
++++ b/time/tzfile.c
+@@ -431,8 +431,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
+   if (__tzname[0] == NULL)
+     {
+       /* This should only happen if there are no transition rules.
+-	 In this case there should be only one single type.  */
+-      assert (num_types == 1);
++	 In this case there's usually only one single type, unless
++	 e.g. the data file has a truncated time-range.  */
+       __tzname[0] = __tzstring (zone_names);
+     }
+   if (__tzname[1] == NULL)
diff --git a/SOURCES/glibc-rh2033648-2.patch b/SOURCES/glibc-rh2033648-2.patch
new file mode 100644
index 0000000..1a8c41a
--- /dev/null
+++ b/SOURCES/glibc-rh2033648-2.patch
@@ -0,0 +1,126 @@
+commit ebe899af0dc3215159a9c896ac6f35b72a18cb6e
+Author: Hans-Peter Nilsson <hp@axis.com>
+Date:   Fri Dec 17 21:45:54 2021 +0100
+
+    timezone: test-case for BZ #28707
+
+    This test-case is the tzfile for Asuncion generated by
+    tzlib-2021e as follows, using the tzlib-2021e zic: "zic -d
+    DEST -r @1546300800 -L /dev/null -b slim
+    SOURCE/southamerica".  Note that in its type 2 header, it
+    has two entries in its "time-types" array (types), but only
+    one entry in its "transition types" array (type_idxs).
+  
+            * timezone/Makefile, timezone/tst-pr28707.c,
+            timezone/testdata/gen-XT5.sh: New test.
+    
+    Co-authored-by: Christopher Wong <Christopher.Wong@axis.com>
+
+    Reworked due to timezone/Makefile difference.
+
+diff -Nrup a/timezone/Makefile b/timezone/Makefile
+--- a/timezone/Makefile	2021-07-06 15:04:00.000000000 -0400
++++ b/timezone/Makefile	2022-01-05 15:03:57.433756574 -0500
+@@ -23,7 +23,7 @@ subdir	:= timezone
+ include ../Makeconfig
+ 
+ others	:= zdump zic
+-tests	:= test-tz tst-timezone tst-tzset
++tests	:= test-tz tst-timezone tst-tzset tst-bz28707
+ 
+ generated-dirs += testdata
+ 
+@@ -85,10 +85,12 @@ $(objpfx)tst-timezone.out: $(addprefix $
+ 				       America/Sao_Paulo Asia/Tokyo \
+ 				       Europe/London)
+ $(objpfx)tst-tzset.out: $(addprefix $(testdata)/XT, 1 2 3 4)
++$(objpfx)tst-bz28707.out: $(testdata)/XT5
+ 
+ test-tz-ENV = TZDIR=$(testdata)
+ tst-timezone-ENV = TZDIR=$(testdata)
+ tst-tzset-ENV = TZDIR=$(testdata)
++tst-bz28707-ENV = TZDIR=$(testdata)
+ 
+ # Note this must come second in the deps list for $(built-program-cmd) to work.
+ zic-deps = $(objpfx)zic $(leapseconds) yearistype
+@@ -122,6 +124,10 @@ $(testdata)/XT%: testdata/XT%
+ 	$(make-target-directory)
+ 	cp $< $@
+ 
++$(testdata)/XT%: testdata/gen-XT%.sh
++	$(SHELL) $< > $@.tmp
++	mv $@.tmp $@
++
+ $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
+ 	sed -e 's|/bin/bash|$(BASH)|' \
+ 	    -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
+diff -Nrup a/timezone/testdata/gen-XT5.sh b/timezone/testdata/gen-XT5.sh
+--- a/timezone/testdata/gen-XT5.sh	1969-12-31 19:00:00.000000000 -0500
++++ b/timezone/testdata/gen-XT5.sh	2022-01-05 12:50:01.666972313 -0500
+@@ -0,0 +1,16 @@
++#! /bin/sh
++
++# This test-case is the tzfile for America/Asuncion
++# generated by tzlib-2021e as follows, using the tzlib-2021e
++# zic: "zic -d DEST -r @1546300800 -L /dev/null -b slim
++# SOURCE/southamerica".  Note that in its type 2 header, it
++# has two entries in its "time-types" array (types), but
++# only one entry in its "transition types" array
++# (type_idxs).
++
++printf \
++'TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'\
++'\0\0\0\0\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0TZif2\0\0\0\0\0\0\0\0'\
++'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\2\0\0\0\b\0'\
++'\0\0\0\*\255\200\1\0\0\0\0\0\0\377\377\325\320\1\4-00\0-03\0\n'\
++'<-04>4<-03>,M10.1.0/0,M3.4.0/0\n'
+diff -Nrup a/timezone/tst-bz28707.c b/timezone/tst-bz28707.c
+--- a/timezone/tst-bz28707.c	1969-12-31 19:00:00.000000000 -0500
++++ b/timezone/tst-bz28707.c	2022-01-05 12:50:01.666972313 -0500
+@@ -0,0 +1,46 @@
++/* 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 <time.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++/* Test that we can use a truncated timezone-file, where the time-type
++   at index 0 is not indexed by the transition-types array (and the
++   transition-types array does not contain at least both one DST and one
++   normal time members).  */
++
++static int
++do_test (void)
++{
++  if (setenv ("TZ", "XT5", 1))
++    {
++      puts ("setenv failed.");
++      return 1;
++    }
++
++  tzset ();
++
++  return
++    /* Sanity-check that we got the right timezone-name for DST.  For
++       normal time, we're likely to get "-00" (the "unspecified" marker),
++       even though the POSIX timezone string says "-04".  Let's not test
++       that.  */
++    !(strcmp (tzname[1], "-03") == 0);
++}
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2033655.patch b/SOURCES/glibc-rh2033655.patch
new file mode 100644
index 0000000..96a3488
--- /dev/null
+++ b/SOURCES/glibc-rh2033655.patch
@@ -0,0 +1,185 @@
+commit ff012870b2c02a62598c04daa1e54632e020fd7d
+Author: Nikita Popov <npv1310@gmail.com>
+Date:   Tue Nov 2 13:21:42 2021 +0500
+
+    gconv: Do not emit spurious NUL character in ISO-2022-JP-3 (bug 28524)
+    
+    Bugfix 27256 has introduced another issue:
+    In conversion from ISO-2022-JP-3 encoding, it is possible
+    to force iconv to emit extra NUL character on internal state reset.
+    To do this, it is sufficient to feed iconv with escape sequence
+    which switches active character set.
+    The simplified check 'data->__statep->__count != ASCII_set'
+    introduced by the aforementioned bugfix picks that case and
+    behaves as if '\0' character has been queued thus emitting it.
+    
+    To eliminate this issue, these steps are taken:
+    * Restore original condition
+    '(data->__statep->__count & ~7) != ASCII_set'.
+    It is necessary since bits 0-2 may contain
+    number of buffered input characters.
+    * Check that queued character is not NUL.
+    Similar step is taken for main conversion loop.
+    
+    Bundled test case follows following logic:
+    * Try to convert ISO-2022-JP-3 escape sequence
+    switching active character set
+    * Reset internal state by providing NULL as input buffer
+    * Ensure that nothing has been converted.
+    
+    Signed-off-by: Nikita Popov <npv1310@gmail.com>
+
+Conflicts:
+	iconvdata/Makefile
+	  (Copyright header.  Usual test backporting differences.)
+	iconvdata/iso-2022-jp-3.c
+	  (Copyright header.)
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index 95e5fb8f722a513b..646e2ccd11478646 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -1,4 +1,5 @@
+-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
++# Copyright (C) 1997-2021 Free Software Foundation, Inc.
++# Copyright (C) The GNU Toolchain Authors.
+ # This file is part of the GNU C Library.
+ 
+ # The GNU C Library is free software; you can redistribute it and/or
+@@ -73,7 +74,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 bug-iconv13 bug-iconv14
++	bug-iconv10 bug-iconv11 bug-iconv12 bug-iconv13 bug-iconv14 \
++	bug-iconv15
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -321,6 +323,8 @@ $(objpfx)bug-iconv12.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
+ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ 			  $(addprefix $(objpfx),$(modules.so))
++$(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \
++			  $(addprefix $(objpfx),$(modules.so))
+ 
+ $(objpfx)iconv-test.out: run-iconv-test.sh \
+ 			 $(addprefix $(objpfx), $(gconv-modules)) \
+diff --git a/iconvdata/bug-iconv15.c b/iconvdata/bug-iconv15.c
+new file mode 100644
+index 0000000000000000..cc04bd0313a68786
+--- /dev/null
++++ b/iconvdata/bug-iconv15.c
+@@ -0,0 +1,60 @@
++/* Bug 28524: Conversion from ISO-2022-JP-3 with iconv
++   may emit spurious NUL character on state reset.
++   Copyright (C) The GNU Toolchain Authors.
++   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 <stddef.h>
++#include <iconv.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  char in[] = "\x1b(I";
++  char *inbuf = in;
++  size_t inleft = sizeof (in) - 1;
++  char out[1];
++  char *outbuf = out;
++  size_t outleft = sizeof (out);
++  iconv_t cd;
++
++  cd = iconv_open ("UTF8", "ISO-2022-JP-3");
++  TEST_VERIFY_EXIT (cd != (iconv_t) -1);
++
++  /* First call to iconv should alter internal state.
++     Now, JISX0201_Kana_set is selected and
++     state value != ASCII_set.  */
++  TEST_VERIFY (iconv (cd, &inbuf, &inleft, &outbuf, &outleft) != (size_t) -1);
++
++  /* No bytes should have been added to
++     the output buffer at this point.  */
++  TEST_VERIFY (outbuf == out);
++  TEST_VERIFY (outleft == sizeof (out));
++
++  /* Second call shall emit spurious NUL character in unpatched glibc.  */
++  TEST_VERIFY (iconv (cd, NULL, NULL, &outbuf, &outleft) != (size_t) -1);
++
++  /* No characters are expected to be produced.  */
++  TEST_VERIFY (outbuf == out);
++  TEST_VERIFY (outleft == sizeof (out));
++
++  TEST_VERIFY_EXIT (iconv_close (cd) != -1);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/iconvdata/iso-2022-jp-3.c b/iconvdata/iso-2022-jp-3.c
+index 047fab8e8dfbde7e..a2b33b171e56392a 100644
+--- a/iconvdata/iso-2022-jp-3.c
++++ b/iconvdata/iso-2022-jp-3.c
+@@ -1,5 +1,6 @@
+ /* Conversion module for ISO-2022-JP-3.
+-   Copyright (C) 1998-2018 Free Software Foundation, Inc.
++   Copyright (C) 1998-2021 Free Software Foundation, Inc.
++   Copyright (C) The GNU Toolchain Authors.
+    This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998,
+    and Bruno Haible <bruno@clisp.org>, 2002.
+@@ -81,20 +82,31 @@ enum
+    the output state to the initial state.  This has to be done during the
+    flushing.  */
+ #define EMIT_SHIFT_TO_INIT \
+-  if (data->__statep->__count != ASCII_set)			      \
++  if ((data->__statep->__count & ~7) != ASCII_set)			      \
+     {									      \
+       if (FROM_DIRECTION)						      \
+ 	{								      \
+-	  if (__glibc_likely (outbuf + 4 <= outend))			      \
++	  uint32_t ch = data->__statep->__count >> 6;			      \
++									      \
++	  if (__glibc_unlikely (ch != 0))				      \
+ 	    {								      \
+-	      /* Write out the last character.  */			      \
+-	      *((uint32_t *) outbuf) = data->__statep->__count >> 6;	      \
+-	      outbuf += sizeof (uint32_t);				      \
+-	      data->__statep->__count = ASCII_set;			\
++	      if (__glibc_likely (outbuf + 4 <= outend))		      \
++		{							      \
++		  /* Write out the last character.  */			      \
++		  put32u (outbuf, ch);					      \
++		  outbuf += 4;						      \
++		  data->__statep->__count &= 7;				      \
++		  data->__statep->__count |= ASCII_set;			      \
++		}							      \
++	      else							      \
++		/* We don't have enough room in the output buffer.  */	      \
++		status = __GCONV_FULL_OUTPUT;				      \
+ 	    }								      \
+ 	  else								      \
+-	    /* We don't have enough room in the output buffer.  */	      \
+-	    status = __GCONV_FULL_OUTPUT;				      \
++	    {								      \
++	      data->__statep->__count &= 7;				      \
++	      data->__statep->__count |= ASCII_set;			      \
++	    }								      \
+ 	}								      \
+       else								      \
+ 	{								      \
diff --git a/SOURCES/glibc-rh2036955.patch b/SOURCES/glibc-rh2036955.patch
new file mode 100644
index 0000000..48b0f4a
--- /dev/null
+++ b/SOURCES/glibc-rh2036955.patch
@@ -0,0 +1,54 @@
+commit e5fa62b8db546f8792ec9e5c61e6419f4f8e3f4d
+Author: Wilco Dijkstra <wdijkstr@arm.com>
+Date:   Thu Jan 6 14:36:28 2022 +0000
+
+    AArch64: Check for SVE in ifuncs [BZ #28744]
+    
+    Add a check for SVE in the A64FX ifuncs for memcpy, memset and memmove.
+    This fixes BZ #28744.
+
+Conflicts:
+	sysdeps/aarch64/multiarch/memcpy.c
+	sysdeps/aarch64/multiarch/memmove.c
+	sysdeps/aarch64/multiarch/memset.c
+	  (IFUNC resolver differences in the backport.)
+
+diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
+index e0313c42e82a7b86..a6ebeb06d3bda00f 100644
+--- a/sysdeps/aarch64/multiarch/memcpy.c
++++ b/sysdeps/aarch64/multiarch/memcpy.c
+@@ -44,7 +44,7 @@ libc_ifunc (__libc_memcpy,
+ 		: (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr)
+ 		  ? __memcpy_thunderx2
+ # if HAVE_AARCH64_SVE_ASM
+-		  : (IS_A64FX (midr)
++		  : (IS_A64FX (midr) && sve
+ 		     ? __memcpy_a64fx
+ 		     : __memcpy_generic)))));
+ # else
+diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
+index d96612b9cf7c3a4e..bea72b3eddde54c0 100644
+--- a/sysdeps/aarch64/multiarch/memmove.c
++++ b/sysdeps/aarch64/multiarch/memmove.c
+@@ -41,7 +41,7 @@ libc_ifunc (__libc_memmove,
+ 	     : (IS_FALKOR (midr) || IS_PHECDA (midr)
+ 		? __memmove_falkor
+ # if HAVE_AARCH64_SVE_ASM
+-		: (IS_A64FX (midr)
++		: (IS_A64FX (midr) && sve
+ 		   ? __memmove_a64fx
+ 		   : __memmove_generic))));
+ # else
+diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
+index 2c8cc72bb0b18474..e7bd412377533f18 100644
+--- a/sysdeps/aarch64/multiarch/memset.c
++++ b/sysdeps/aarch64/multiarch/memset.c
+@@ -38,7 +38,7 @@ libc_ifunc (__libc_memset,
+ 	    ((IS_FALKOR (midr) || IS_PHECDA (midr)) && zva_size == 64
+ 	     ? __memset_falkor
+ # if HAVE_AARCH64_SVE_ASM
+-	     : (IS_A64FX (midr)
++	     : (IS_A64FX (midr) && sve
+ 		? __memset_a64fx
+ 		: __memset_generic)));
+ # else
diff --git a/SOURCES/glibc-rh2045062-1.patch b/SOURCES/glibc-rh2045062-1.patch
deleted file mode 100644
index 2885e3f..0000000
--- a/SOURCES/glibc-rh2045062-1.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-commit e368b12f6c16b6888dda99ba641e999b9c9643c8
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Mon Jan 17 10:21:34 2022 +0100
-
-    socket: Add the __sockaddr_un_set function
-    
-    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-
-# Conflicts:
-#	socket/Makefile
-
-diff --git a/include/sys/un.h b/include/sys/un.h
-index bdbee999806930f4..152afd9fc7426d8b 100644
---- a/include/sys/un.h
-+++ b/include/sys/un.h
-@@ -1 +1,13 @@
- #include <socket/sys/un.h>
-+
-+#ifndef _ISOMAC
-+
-+/* Set ADDR->sun_family to AF_UNIX and ADDR->sun_path to PATHNAME.
-+   Return 0 on success or -1 on failure (due to overlong PATHNAME).
-+   The caller should always use sizeof (struct sockaddr_un) as the
-+   socket address length, disregaring the length of PATHNAME.
-+   Only concrete (non-abstract) pathnames are supported.  */
-+int __sockaddr_un_set (struct sockaddr_un *addr, const char *pathname)
-+  attribute_hidden;
-+
-+#endif /* _ISOMAC */
-diff --git a/socket/Makefile b/socket/Makefile
-index b41eb071507a6271..8975a65c2aabbfbc 100644
---- a/socket/Makefile
-+++ b/socket/Makefile
-@@ -29,10 +29,14 @@ headers	:= sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \
- routines := accept bind connect getpeername getsockname getsockopt	\
- 	    listen recv recvfrom recvmsg send sendmsg sendto		\
- 	    setsockopt shutdown socket socketpair isfdtype opensock	\
--	    sockatmark accept4 recvmmsg sendmmsg
-+	    sockatmark accept4 recvmmsg sendmmsg sockaddr_un_set
- 
- tests := tst-accept4
- 
-+tests-internal := \
-+  tst-sockaddr_un_set \
-+  # tests-internal
-+
- aux	 := sa_len
- 
- include ../Rules
-diff --git a/socket/sockaddr_un_set.c b/socket/sockaddr_un_set.c
-new file mode 100644
-index 0000000000000000..0bd40dc34e3d7efc
---- /dev/null
-+++ b/socket/sockaddr_un_set.c
-@@ -0,0 +1,41 @@
-+/* Set the sun_path member of struct sockaddr_un.
-+   Copyright (C) 2022 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 <string.h>
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+
-+int
-+__sockaddr_un_set (struct sockaddr_un *addr, const char *pathname)
-+{
-+  size_t name_length = strlen (pathname);
-+
-+  /* The kernel supports names of exactly sizeof (addr->sun_path)
-+     bytes, without a null terminator, but userspace does not; see the
-+     SUN_LEN macro.  */
-+  if (name_length >= sizeof (addr->sun_path))
-+    {
-+      __set_errno (EINVAL);     /* Error code used by the kernel.  */
-+      return -1;
-+    }
-+
-+  addr->sun_family = AF_UNIX;
-+  memcpy (addr->sun_path, pathname, name_length + 1);
-+  return 0;
-+}
-diff --git a/socket/tst-sockaddr_un_set.c b/socket/tst-sockaddr_un_set.c
-new file mode 100644
-index 0000000000000000..29c2a81afda81b5e
---- /dev/null
-+++ b/socket/tst-sockaddr_un_set.c
-@@ -0,0 +1,62 @@
-+/* Test the __sockaddr_un_set function.
-+   Copyright (C) 2022 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/>.  */
-+
-+/* Re-compile the function because the version in libc is not
-+   exported.  */
-+#include "sockaddr_un_set.c"
-+
-+#include <support/check.h>
-+
-+static int
-+do_test (void)
-+{
-+  struct sockaddr_un sun;
-+
-+  memset (&sun, 0xcc, sizeof (sun));
-+  __sockaddr_un_set (&sun, "");
-+  TEST_COMPARE (sun.sun_family, AF_UNIX);
-+  TEST_COMPARE (__sockaddr_un_set (&sun, ""), 0);
-+
-+  memset (&sun, 0xcc, sizeof (sun));
-+  TEST_COMPARE (__sockaddr_un_set (&sun, "/example"), 0);
-+  TEST_COMPARE_STRING (sun.sun_path, "/example");
-+
-+  {
-+    char pathname[108];         /* Length of sun_path (ABI constant).  */
-+    memset (pathname, 'x', sizeof (pathname));
-+    pathname[sizeof (pathname) - 1] = '\0';
-+    memset (&sun, 0xcc, sizeof (sun));
-+    TEST_COMPARE (__sockaddr_un_set (&sun, pathname), 0);
-+    TEST_COMPARE (sun.sun_family, AF_UNIX);
-+    TEST_COMPARE_STRING (sun.sun_path, pathname);
-+  }
-+
-+  {
-+    char pathname[109];
-+    memset (pathname, 'x', sizeof (pathname));
-+    pathname[sizeof (pathname) - 1] = '\0';
-+    memset (&sun, 0xcc, sizeof (sun));
-+    errno = 0;
-+    TEST_COMPARE (__sockaddr_un_set (&sun, pathname), -1);
-+    TEST_COMPARE (errno, EINVAL);
-+  }
-+
-+  return 0;
-+}
-+
-+#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2045062-2.patch b/SOURCES/glibc-rh2045062-2.patch
deleted file mode 100644
index 9e74607..0000000
--- a/SOURCES/glibc-rh2045062-2.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-commit 226b46770c82899b555986583294b049c6ec9b40
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Mon Jan 17 10:21:34 2022 +0100
-
-    CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542)
-    
-    Processing an overlong pathname in the sunrpc clnt_create function
-    results in a stack-based buffer overflow.
-    
-    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-
-diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c
-index 13ced8994e49d4ee..b44357cd88e60599 100644
---- a/sunrpc/clnt_gen.c
-+++ b/sunrpc/clnt_gen.c
-@@ -57,9 +57,13 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
- 
-   if (strcmp (proto, "unix") == 0)
-     {
--      memset ((char *)&sun, 0, sizeof (sun));
--      sun.sun_family = AF_UNIX;
--      strcpy (sun.sun_path, hostname);
-+      if (__sockaddr_un_set (&sun, hostname) < 0)
-+	{
-+	  struct rpc_createerr *ce = &get_rpc_createerr ();
-+	  ce->cf_stat = RPC_SYSTEMERROR;
-+	  ce->cf_error.re_errno = errno;
-+	  return NULL;
-+	}
-       sock = RPC_ANYSOCK;
-       client = clntunix_create (&sun, prog, vers, &sock, 0, 0);
-       if (client == NULL)
diff --git a/SOURCES/glibc-rh2045062-3.patch b/SOURCES/glibc-rh2045062-3.patch
deleted file mode 100644
index cd1e55d..0000000
--- a/SOURCES/glibc-rh2045062-3.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-commit ef972a4c50014a16132b5c75571cfb6b30bef136
-Author: Martin Sebor <msebor@redhat.com>
-Date:   Mon Jan 17 10:21:34 2022 +0100
-
-    sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542)
-    
-    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-
-# Conflicts:
-#	sunrpc/Makefile
-
-diff --git a/sunrpc/Makefile b/sunrpc/Makefile
-index 85b0b3356aaf81a3..2f8f0597c99e117f 100644
---- a/sunrpc/Makefile
-+++ b/sunrpc/Makefile
-@@ -95,7 +95,8 @@ others += rpcgen
- endif
- 
- tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \
--  tst-udp-nonblocking
-+  tst-udp-nonblocking tst-bug22542
-+
- xtests := tst-getmyaddr
- 
- ifeq ($(have-thread-library),yes)
-@@ -246,3 +247,4 @@ $(objpfx)tst-udp-timeout: $(common-objpfx)linkobj/libc.so
- $(objpfx)tst-udp-nonblocking: $(common-objpfx)linkobj/libc.so
- $(objpfx)tst-udp-garbage: \
-   $(common-objpfx)linkobj/libc.so $(shared-thread-library)
-+$(objpfx)tst-bug22542: $(common-objpfx)linkobj/libc.so
-diff --git a/sunrpc/tst-bug22542.c b/sunrpc/tst-bug22542.c
-new file mode 100644
-index 0000000000000000..d6cd79787bdef21d
---- /dev/null
-+++ b/sunrpc/tst-bug22542.c
-@@ -0,0 +1,44 @@
-+/* Test to verify that overlong hostname is rejected by clnt_create
-+   and doesn't cause a buffer overflow (bug  22542).
-+
-+   Copyright (C) 2022 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
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include <errno.h>
-+#include <rpc/clnt.h>
-+#include <string.h>
-+#include <support/check.h>
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+
-+static int
-+do_test (void)
-+{
-+  /* Create an arbitrary hostname that's longer than fits in sun_path.  */
-+  char name [sizeof ((struct sockaddr_un*)0)->sun_path * 2];
-+  memset (name, 'x', sizeof name - 1);
-+  name [sizeof name - 1] = '\0';
-+
-+  errno = 0;
-+  CLIENT *clnt = clnt_create (name, 0, 0, "unix");
-+
-+  TEST_VERIFY (clnt == NULL);
-+  TEST_COMPARE (errno, EINVAL);
-+  return 0;
-+}
-+
-+#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2045062-4.patch b/SOURCES/glibc-rh2045062-4.patch
deleted file mode 100644
index 489c315..0000000
--- a/SOURCES/glibc-rh2045062-4.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-commit f545ad4928fa1f27a3075265182b38a4f939a5f7
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Mon Jan 17 10:21:34 2022 +0100
-
-    CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768)
-    
-    The sunrpc function svcunix_create suffers from a stack-based buffer
-    overflow with overlong pathname arguments.
-    
-    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-
-diff --git a/sunrpc/Makefile b/sunrpc/Makefile
-index 2f8f0597c99e117f..5f7087aee494cc2e 100644
---- a/sunrpc/Makefile
-+++ b/sunrpc/Makefile
-@@ -95,7 +95,7 @@ others += rpcgen
- endif
- 
- tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \
--  tst-udp-nonblocking tst-bug22542
-+  tst-udp-nonblocking tst-bug22542 tst-bug28768
- 
- xtests := tst-getmyaddr
- 
-diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c
-index c2c076aa87f0a2ad..8fac2b35da1d38a5 100644
---- a/sunrpc/svc_unix.c
-+++ b/sunrpc/svc_unix.c
-@@ -154,7 +154,10 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
-   SVCXPRT *xprt;
-   struct unix_rendezvous *r;
-   struct sockaddr_un addr;
--  socklen_t len = sizeof (struct sockaddr_in);
-+  socklen_t len = sizeof (addr);
-+
-+  if (__sockaddr_un_set (&addr, path) < 0)
-+    return NULL;
- 
-   if (sock == RPC_ANYSOCK)
-     {
-@@ -165,12 +168,6 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
- 	}
-       madesock = TRUE;
-     }
--  memset (&addr, '\0', sizeof (addr));
--  addr.sun_family = AF_UNIX;
--  len = strlen (path) + 1;
--  memcpy (addr.sun_path, path, len);
--  len += sizeof (addr.sun_family);
--
-   __bind (sock, (struct sockaddr *) &addr, len);
- 
-   if (__getsockname (sock, (struct sockaddr *) &addr, &len) != 0
-diff --git a/sunrpc/tst-bug28768.c b/sunrpc/tst-bug28768.c
-new file mode 100644
-index 0000000000000000..35a4b7b0b3d34350
---- /dev/null
-+++ b/sunrpc/tst-bug28768.c
-@@ -0,0 +1,42 @@
-+/* Test to verify that long path is rejected by svcunix_create (bug 28768).
-+   Copyright (C) 2022 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
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include <errno.h>
-+#include <rpc/svc.h>
-+#include <shlib-compat.h>
-+#include <string.h>
-+#include <support/check.h>
-+
-+/* svcunix_create does not have a default version in linkobj/libc.so.  */
-+compat_symbol_reference (libc, svcunix_create, svcunix_create, GLIBC_2_1);
-+
-+static int
-+do_test (void)
-+{
-+  char pathname[109];
-+  memset (pathname, 'x', sizeof (pathname));
-+  pathname[sizeof (pathname) - 1] = '\0';
-+
-+  errno = 0;
-+  TEST_VERIFY (svcunix_create (RPC_ANYSOCK, 4096, 4096, pathname) == NULL);
-+  TEST_COMPARE (errno, EINVAL);
-+
-+  return 0;
-+}
-+
-+#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2045062-5.patch b/SOURCES/glibc-rh2045062-5.patch
deleted file mode 100644
index 3d7b71e..0000000
--- a/SOURCES/glibc-rh2045062-5.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-commit 36f6e408845c8c539128f3fb9cb132bf1845a2c8
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Tue Mar 9 21:07:24 2021 +0100
-
-    <shlib-compat.h>: Support compat_symbol_reference for _ISOMAC
-    
-    This is helpful for testing compat symbols in cases where _ISOMAC
-    is activated implicitly due to -DMODULE_NAME=testsuite and cannot
-    be disabled easily.
-
-diff --git a/include/libc-symbols.h b/include/libc-symbols.h
-index 41436050d060b89f..44e12b63d40cc572 100644
---- a/include/libc-symbols.h
-+++ b/include/libc-symbols.h
-@@ -59,6 +59,19 @@
- # define IN_MODULE (-1)
- #endif
- 
-+/* Use symbol_version_reference to specify the version a symbol
-+   reference should link to.  Use symbol_version or
-+   default_symbol_version for the definition of a versioned symbol.
-+   The difference is that the latter is a no-op in non-shared
-+   builds.  */
-+#ifdef __ASSEMBLER__
-+# define symbol_version_reference(real, name, version) \
-+     .symver real, name##@##version
-+#else  /* !__ASSEMBLER__ */
-+# define symbol_version_reference(real, name, version) \
-+  __asm__ (".symver " #real "," #name "@" #version)
-+#endif
-+
- #ifndef _ISOMAC
- 
- /* This is defined for the compilation of all C library code.  features.h
-@@ -388,19 +401,6 @@ for linking")
-    past the last element in SET.  */
- #define symbol_set_end_p(set, ptr) ((ptr) >= (void *const *) &__stop_##set)
- 
--/* Use symbol_version_reference to specify the version a symbol
--   reference should link to.  Use symbol_version or
--   default_symbol_version for the definition of a versioned symbol.
--   The difference is that the latter is a no-op in non-shared
--   builds.  */
--#ifdef __ASSEMBLER__
--# define symbol_version_reference(real, name, version) \
--     .symver real, name##@##version
--#else  /* !__ASSEMBLER__ */
--# define symbol_version_reference(real, name, version) \
--  __asm__ (".symver " #real "," #name "@" #version)
--#endif
--
- #ifdef SHARED
- # define symbol_version(real, name, version) \
-   symbol_version_reference(real, name, version)
diff --git a/SOURCES/glibc-rh2045063-1.patch b/SOURCES/glibc-rh2045063-1.patch
new file mode 100644
index 0000000..2885e3f
--- /dev/null
+++ b/SOURCES/glibc-rh2045063-1.patch
@@ -0,0 +1,164 @@
+commit e368b12f6c16b6888dda99ba641e999b9c9643c8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 17 10:21:34 2022 +0100
+
+    socket: Add the __sockaddr_un_set function
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+# Conflicts:
+#	socket/Makefile
+
+diff --git a/include/sys/un.h b/include/sys/un.h
+index bdbee999806930f4..152afd9fc7426d8b 100644
+--- a/include/sys/un.h
++++ b/include/sys/un.h
+@@ -1 +1,13 @@
+ #include <socket/sys/un.h>
++
++#ifndef _ISOMAC
++
++/* Set ADDR->sun_family to AF_UNIX and ADDR->sun_path to PATHNAME.
++   Return 0 on success or -1 on failure (due to overlong PATHNAME).
++   The caller should always use sizeof (struct sockaddr_un) as the
++   socket address length, disregaring the length of PATHNAME.
++   Only concrete (non-abstract) pathnames are supported.  */
++int __sockaddr_un_set (struct sockaddr_un *addr, const char *pathname)
++  attribute_hidden;
++
++#endif /* _ISOMAC */
+diff --git a/socket/Makefile b/socket/Makefile
+index b41eb071507a6271..8975a65c2aabbfbc 100644
+--- a/socket/Makefile
++++ b/socket/Makefile
+@@ -29,10 +29,14 @@ headers	:= sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \
+ routines := accept bind connect getpeername getsockname getsockopt	\
+ 	    listen recv recvfrom recvmsg send sendmsg sendto		\
+ 	    setsockopt shutdown socket socketpair isfdtype opensock	\
+-	    sockatmark accept4 recvmmsg sendmmsg
++	    sockatmark accept4 recvmmsg sendmmsg sockaddr_un_set
+ 
+ tests := tst-accept4
+ 
++tests-internal := \
++  tst-sockaddr_un_set \
++  # tests-internal
++
+ aux	 := sa_len
+ 
+ include ../Rules
+diff --git a/socket/sockaddr_un_set.c b/socket/sockaddr_un_set.c
+new file mode 100644
+index 0000000000000000..0bd40dc34e3d7efc
+--- /dev/null
++++ b/socket/sockaddr_un_set.c
+@@ -0,0 +1,41 @@
++/* Set the sun_path member of struct sockaddr_un.
++   Copyright (C) 2022 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 <string.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++
++int
++__sockaddr_un_set (struct sockaddr_un *addr, const char *pathname)
++{
++  size_t name_length = strlen (pathname);
++
++  /* The kernel supports names of exactly sizeof (addr->sun_path)
++     bytes, without a null terminator, but userspace does not; see the
++     SUN_LEN macro.  */
++  if (name_length >= sizeof (addr->sun_path))
++    {
++      __set_errno (EINVAL);     /* Error code used by the kernel.  */
++      return -1;
++    }
++
++  addr->sun_family = AF_UNIX;
++  memcpy (addr->sun_path, pathname, name_length + 1);
++  return 0;
++}
+diff --git a/socket/tst-sockaddr_un_set.c b/socket/tst-sockaddr_un_set.c
+new file mode 100644
+index 0000000000000000..29c2a81afda81b5e
+--- /dev/null
++++ b/socket/tst-sockaddr_un_set.c
+@@ -0,0 +1,62 @@
++/* Test the __sockaddr_un_set function.
++   Copyright (C) 2022 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/>.  */
++
++/* Re-compile the function because the version in libc is not
++   exported.  */
++#include "sockaddr_un_set.c"
++
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  struct sockaddr_un sun;
++
++  memset (&sun, 0xcc, sizeof (sun));
++  __sockaddr_un_set (&sun, "");
++  TEST_COMPARE (sun.sun_family, AF_UNIX);
++  TEST_COMPARE (__sockaddr_un_set (&sun, ""), 0);
++
++  memset (&sun, 0xcc, sizeof (sun));
++  TEST_COMPARE (__sockaddr_un_set (&sun, "/example"), 0);
++  TEST_COMPARE_STRING (sun.sun_path, "/example");
++
++  {
++    char pathname[108];         /* Length of sun_path (ABI constant).  */
++    memset (pathname, 'x', sizeof (pathname));
++    pathname[sizeof (pathname) - 1] = '\0';
++    memset (&sun, 0xcc, sizeof (sun));
++    TEST_COMPARE (__sockaddr_un_set (&sun, pathname), 0);
++    TEST_COMPARE (sun.sun_family, AF_UNIX);
++    TEST_COMPARE_STRING (sun.sun_path, pathname);
++  }
++
++  {
++    char pathname[109];
++    memset (pathname, 'x', sizeof (pathname));
++    pathname[sizeof (pathname) - 1] = '\0';
++    memset (&sun, 0xcc, sizeof (sun));
++    errno = 0;
++    TEST_COMPARE (__sockaddr_un_set (&sun, pathname), -1);
++    TEST_COMPARE (errno, EINVAL);
++  }
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2045063-2.patch b/SOURCES/glibc-rh2045063-2.patch
new file mode 100644
index 0000000..9e74607
--- /dev/null
+++ b/SOURCES/glibc-rh2045063-2.patch
@@ -0,0 +1,32 @@
+commit 226b46770c82899b555986583294b049c6ec9b40
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 17 10:21:34 2022 +0100
+
+    CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542)
+    
+    Processing an overlong pathname in the sunrpc clnt_create function
+    results in a stack-based buffer overflow.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c
+index 13ced8994e49d4ee..b44357cd88e60599 100644
+--- a/sunrpc/clnt_gen.c
++++ b/sunrpc/clnt_gen.c
+@@ -57,9 +57,13 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
+ 
+   if (strcmp (proto, "unix") == 0)
+     {
+-      memset ((char *)&sun, 0, sizeof (sun));
+-      sun.sun_family = AF_UNIX;
+-      strcpy (sun.sun_path, hostname);
++      if (__sockaddr_un_set (&sun, hostname) < 0)
++	{
++	  struct rpc_createerr *ce = &get_rpc_createerr ();
++	  ce->cf_stat = RPC_SYSTEMERROR;
++	  ce->cf_error.re_errno = errno;
++	  return NULL;
++	}
+       sock = RPC_ANYSOCK;
+       client = clntunix_create (&sun, prog, vers, &sock, 0, 0);
+       if (client == NULL)
diff --git a/SOURCES/glibc-rh2045063-3.patch b/SOURCES/glibc-rh2045063-3.patch
new file mode 100644
index 0000000..cd1e55d
--- /dev/null
+++ b/SOURCES/glibc-rh2045063-3.patch
@@ -0,0 +1,80 @@
+commit ef972a4c50014a16132b5c75571cfb6b30bef136
+Author: Martin Sebor <msebor@redhat.com>
+Date:   Mon Jan 17 10:21:34 2022 +0100
+
+    sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542)
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+# Conflicts:
+#	sunrpc/Makefile
+
+diff --git a/sunrpc/Makefile b/sunrpc/Makefile
+index 85b0b3356aaf81a3..2f8f0597c99e117f 100644
+--- a/sunrpc/Makefile
++++ b/sunrpc/Makefile
+@@ -95,7 +95,8 @@ others += rpcgen
+ endif
+ 
+ tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \
+-  tst-udp-nonblocking
++  tst-udp-nonblocking tst-bug22542
++
+ xtests := tst-getmyaddr
+ 
+ ifeq ($(have-thread-library),yes)
+@@ -246,3 +247,4 @@ $(objpfx)tst-udp-timeout: $(common-objpfx)linkobj/libc.so
+ $(objpfx)tst-udp-nonblocking: $(common-objpfx)linkobj/libc.so
+ $(objpfx)tst-udp-garbage: \
+   $(common-objpfx)linkobj/libc.so $(shared-thread-library)
++$(objpfx)tst-bug22542: $(common-objpfx)linkobj/libc.so
+diff --git a/sunrpc/tst-bug22542.c b/sunrpc/tst-bug22542.c
+new file mode 100644
+index 0000000000000000..d6cd79787bdef21d
+--- /dev/null
++++ b/sunrpc/tst-bug22542.c
+@@ -0,0 +1,44 @@
++/* Test to verify that overlong hostname is rejected by clnt_create
++   and doesn't cause a buffer overflow (bug  22542).
++
++   Copyright (C) 2022 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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <rpc/clnt.h>
++#include <string.h>
++#include <support/check.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++
++static int
++do_test (void)
++{
++  /* Create an arbitrary hostname that's longer than fits in sun_path.  */
++  char name [sizeof ((struct sockaddr_un*)0)->sun_path * 2];
++  memset (name, 'x', sizeof name - 1);
++  name [sizeof name - 1] = '\0';
++
++  errno = 0;
++  CLIENT *clnt = clnt_create (name, 0, 0, "unix");
++
++  TEST_VERIFY (clnt == NULL);
++  TEST_COMPARE (errno, EINVAL);
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2045063-4.patch b/SOURCES/glibc-rh2045063-4.patch
new file mode 100644
index 0000000..489c315
--- /dev/null
+++ b/SOURCES/glibc-rh2045063-4.patch
@@ -0,0 +1,101 @@
+commit f545ad4928fa1f27a3075265182b38a4f939a5f7
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 17 10:21:34 2022 +0100
+
+    CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768)
+    
+    The sunrpc function svcunix_create suffers from a stack-based buffer
+    overflow with overlong pathname arguments.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+diff --git a/sunrpc/Makefile b/sunrpc/Makefile
+index 2f8f0597c99e117f..5f7087aee494cc2e 100644
+--- a/sunrpc/Makefile
++++ b/sunrpc/Makefile
+@@ -95,7 +95,7 @@ others += rpcgen
+ endif
+ 
+ tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-udp-error tst-udp-timeout \
+-  tst-udp-nonblocking tst-bug22542
++  tst-udp-nonblocking tst-bug22542 tst-bug28768
+ 
+ xtests := tst-getmyaddr
+ 
+diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c
+index c2c076aa87f0a2ad..8fac2b35da1d38a5 100644
+--- a/sunrpc/svc_unix.c
++++ b/sunrpc/svc_unix.c
+@@ -154,7 +154,10 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
+   SVCXPRT *xprt;
+   struct unix_rendezvous *r;
+   struct sockaddr_un addr;
+-  socklen_t len = sizeof (struct sockaddr_in);
++  socklen_t len = sizeof (addr);
++
++  if (__sockaddr_un_set (&addr, path) < 0)
++    return NULL;
+ 
+   if (sock == RPC_ANYSOCK)
+     {
+@@ -165,12 +168,6 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
+ 	}
+       madesock = TRUE;
+     }
+-  memset (&addr, '\0', sizeof (addr));
+-  addr.sun_family = AF_UNIX;
+-  len = strlen (path) + 1;
+-  memcpy (addr.sun_path, path, len);
+-  len += sizeof (addr.sun_family);
+-
+   __bind (sock, (struct sockaddr *) &addr, len);
+ 
+   if (__getsockname (sock, (struct sockaddr *) &addr, &len) != 0
+diff --git a/sunrpc/tst-bug28768.c b/sunrpc/tst-bug28768.c
+new file mode 100644
+index 0000000000000000..35a4b7b0b3d34350
+--- /dev/null
++++ b/sunrpc/tst-bug28768.c
+@@ -0,0 +1,42 @@
++/* Test to verify that long path is rejected by svcunix_create (bug 28768).
++   Copyright (C) 2022 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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <rpc/svc.h>
++#include <shlib-compat.h>
++#include <string.h>
++#include <support/check.h>
++
++/* svcunix_create does not have a default version in linkobj/libc.so.  */
++compat_symbol_reference (libc, svcunix_create, svcunix_create, GLIBC_2_1);
++
++static int
++do_test (void)
++{
++  char pathname[109];
++  memset (pathname, 'x', sizeof (pathname));
++  pathname[sizeof (pathname) - 1] = '\0';
++
++  errno = 0;
++  TEST_VERIFY (svcunix_create (RPC_ANYSOCK, 4096, 4096, pathname) == NULL);
++  TEST_COMPARE (errno, EINVAL);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh2045063-5.patch b/SOURCES/glibc-rh2045063-5.patch
new file mode 100644
index 0000000..3d7b71e
--- /dev/null
+++ b/SOURCES/glibc-rh2045063-5.patch
@@ -0,0 +1,54 @@
+commit 36f6e408845c8c539128f3fb9cb132bf1845a2c8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Mar 9 21:07:24 2021 +0100
+
+    <shlib-compat.h>: Support compat_symbol_reference for _ISOMAC
+    
+    This is helpful for testing compat symbols in cases where _ISOMAC
+    is activated implicitly due to -DMODULE_NAME=testsuite and cannot
+    be disabled easily.
+
+diff --git a/include/libc-symbols.h b/include/libc-symbols.h
+index 41436050d060b89f..44e12b63d40cc572 100644
+--- a/include/libc-symbols.h
++++ b/include/libc-symbols.h
+@@ -59,6 +59,19 @@
+ # define IN_MODULE (-1)
+ #endif
+ 
++/* Use symbol_version_reference to specify the version a symbol
++   reference should link to.  Use symbol_version or
++   default_symbol_version for the definition of a versioned symbol.
++   The difference is that the latter is a no-op in non-shared
++   builds.  */
++#ifdef __ASSEMBLER__
++# define symbol_version_reference(real, name, version) \
++     .symver real, name##@##version
++#else  /* !__ASSEMBLER__ */
++# define symbol_version_reference(real, name, version) \
++  __asm__ (".symver " #real "," #name "@" #version)
++#endif
++
+ #ifndef _ISOMAC
+ 
+ /* This is defined for the compilation of all C library code.  features.h
+@@ -388,19 +401,6 @@ for linking")
+    past the last element in SET.  */
+ #define symbol_set_end_p(set, ptr) ((ptr) >= (void *const *) &__stop_##set)
+ 
+-/* Use symbol_version_reference to specify the version a symbol
+-   reference should link to.  Use symbol_version or
+-   default_symbol_version for the definition of a versioned symbol.
+-   The difference is that the latter is a no-op in non-shared
+-   builds.  */
+-#ifdef __ASSEMBLER__
+-# define symbol_version_reference(real, name, version) \
+-     .symver real, name##@##version
+-#else  /* !__ASSEMBLER__ */
+-# define symbol_version_reference(real, name, version) \
+-  __asm__ (".symver " #real "," #name "@" #version)
+-#endif
+-
+ #ifdef SHARED
+ # define symbol_version(real, name, version) \
+   symbol_version_reference(real, name, version)
diff --git a/SOURCES/glibc-rh2061727.patch b/SOURCES/glibc-rh2061727.patch
new file mode 100644
index 0000000..b66fce4
--- /dev/null
+++ b/SOURCES/glibc-rh2061727.patch
@@ -0,0 +1,208 @@
+This is a downstream rework of this upstream patch:
+
+  [PATCH v2 2/2] nss: Protect against errno changes in function lookup (bug 28953)
+  <https://sourceware.org/pipermail/libc-alpha/2022-March/137015.html>
+
+The NSS module loading code has been rewritten upstream, which is why
+only the test can be reused.  NSS_DECLARE_MODULE_FUNCTIONS does not yet
+exist downstream, so this part had to be skipped.
+
+diff --git a/nss/Makefile b/nss/Makefile
+index d5c28a6b5ed3661c..e8a7d9c7b3cefcdf 100644
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -59,7 +59,8 @@ tests			= test-netdb test-digits-dots tst-nss-getpwent bug17079 \
+ 			  tst-nss-test2 \
+ 			  tst-nss-test3 \
+ 			  tst-nss-test4 \
+-			  tst-nss-test5
++			  tst-nss-test5 \
++			  tst-nss-test_errno
+ xtests			= bug-erange
+ 
+ tests-container = \
+@@ -130,7 +131,7 @@ routines                += $(libnss_files-routines)
+ static-only-routines    += $(libnss_files-routines)
+ tests-static		+= tst-nss-static
+ endif
+-extra-test-objs		+= nss_test1.os nss_test2.os
++extra-test-objs		+= nss_test1.os nss_test2.os nss_test_errno.os
+ 
+ include ../Rules
+ 
+@@ -166,10 +167,13 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
+ 
+ libof-nss_test1 = extramodules
+ libof-nss_test2 = extramodules
++libof-nss_test_errno = extramodules
+ $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
+ 	$(build-module)
+ $(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps)
+ 	$(build-module)
++$(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps)
++	$(build-module)
+ $(objpfx)nss_test2.os : nss_test1.c
+ ifdef libnss_test1.so-version
+ $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
+@@ -179,9 +183,13 @@ ifdef libnss_test2.so-version
+ $(objpfx)/libnss_test2.so$(libnss_test2.so-version): $(objpfx)/libnss_test2.so
+ 	$(make-link)
+ endif
++$(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \
++  $(objpfx)/libnss_test_errno.so
++	$(make-link)
+ $(patsubst %,$(objpfx)%.out,$(tests)) : \
+ 	$(objpfx)/libnss_test1.so$(libnss_test1.so-version) \
+-	$(objpfx)/libnss_test2.so$(libnss_test2.so-version)
++	$(objpfx)/libnss_test2.so$(libnss_test2.so-version) \
++	$(objpfx)/libnss_test_errno.so$(libnss_files.so-version)
+ 
+ ifeq (yes,$(have-thread-library))
+ $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
+diff --git a/nss/nss_test_errno.c b/nss/nss_test_errno.c
+new file mode 100644
+index 0000000000000000..ca75c890aa057869
+--- /dev/null
++++ b/nss/nss_test_errno.c
+@@ -0,0 +1,53 @@
++/* NSS service provider with errno clobber.
++   Copyright (C) 2022 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 <nss.h>
++#include <pwd.h>
++#include <stdlib.h>
++
++static void __attribute__ ((constructor))
++init (void)
++{
++  /* An arbitrary error code which is otherwise not used.  */
++  errno = ELIBBAD;
++}
++
++/* Lookup functions for pwd follow that do not return any data.  */
++
++enum nss_status
++_nss_test_errno_setpwent (int stayopen)
++{
++  setenv ("_nss_test_errno_setpwent", "yes", 1);
++  return NSS_STATUS_SUCCESS;
++}
++
++enum nss_status
++_nss_test_errno_getpwent_r (struct passwd *result,
++                            char *buffer, size_t size, int *errnop)
++{
++  setenv ("_nss_test_errno_getpwent_r", "yes", 1);
++  return NSS_STATUS_NOTFOUND;
++}
++
++enum nss_status
++_nss_test_errno_endpwent (void)
++{
++  setenv ("_nss_test_errno_endpwent", "yes", 1);
++  return NSS_STATUS_SUCCESS;
++}
+diff --git a/nss/nsswitch.c b/nss/nsswitch.c
+index 17adf1ef03f93d60..e59ab674e0426b26 100644
+--- a/nss/nsswitch.c
++++ b/nss/nsswitch.c
+@@ -401,6 +401,7 @@ void *
+ __nss_lookup_function (service_user *ni, const char *fct_name)
+ {
+   void **found, *result;
++  int saved_errno = errno;
+ 
+   /* We now modify global data.  Protect it.  */
+   __libc_lock_lock (lock);
+@@ -523,6 +524,8 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
+   /* Remove the lock.  */
+   __libc_lock_unlock (lock);
+ 
++  __set_errno (saved_errno);
++
+   return result;
+ }
+ libc_hidden_def (__nss_lookup_function)
+diff --git a/nss/tst-nss-test_errno.c b/nss/tst-nss-test_errno.c
+new file mode 100644
+index 0000000000000000..d2c42dd363a38b0e
+--- /dev/null
++++ b/nss/tst-nss-test_errno.c
+@@ -0,0 +1,61 @@
++/* getpwent failure when dlopen clobbers errno (bug 28953).
++   Copyright (C) 2022 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 <nss.h>
++#include <support/check.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <stdbool.h>
++#include <pwd.h>
++#include <string.h>
++
++static int
++do_test (void)
++{
++  __nss_configure_lookup ("passwd", "files test_errno");
++
++  errno = 0;
++  setpwent ();
++  TEST_COMPARE (errno, 0);
++
++  bool root_seen = false;
++  while (true)
++    {
++      errno = 0;
++      struct passwd *e = getpwent ();
++      if (e == NULL)
++        break;
++      if (strcmp (e->pw_name, "root"))
++        root_seen = true;
++    }
++
++  TEST_COMPARE (errno, 0);
++  TEST_VERIFY (root_seen);
++
++  errno = 0;
++  endpwent ();
++  TEST_COMPARE (errno, 0);
++
++  TEST_COMPARE_STRING (getenv ("_nss_test_errno_setpwent"), "yes");
++  TEST_COMPARE_STRING (getenv ("_nss_test_errno_getpwent_r"), "yes");
++  TEST_COMPARE_STRING (getenv ("_nss_test_errno_endpwent"), "yes");
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/wrap-find-debuginfo.sh b/SOURCES/wrap-find-debuginfo.sh
new file mode 100755
index 0000000..6eeb802
--- /dev/null
+++ b/SOURCES/wrap-find-debuginfo.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+# Wrapper script for find-debuginfo.sh
+#
+# Usage:
+#  wrap-find-debuginfo.sh SYSROOT-PATH SCRIPT-PATH SCRIPT-ARGS...
+#
+# The wrapper saves the original version of ld.so found in SYSROOT-PATH,
+# invokes SCRIPT-PATH with SCRIPT-ARGS, and then restores the
+# LDSO-PATH file, followed by note merging and DWZ compression.
+# As a result, ld.so has (mostly) unchanged debuginfo even
+# after debuginfo extraction.
+#
+# For libc.so.6 and other shared objects, a set of strategic symbols
+# is preserved in .symtab that are frequently used in valgrind
+# suppressions and elsewhere.
+
+set -evx
+
+tar_tmp="$(mktemp)"
+
+# Prefer a separately installed debugedit over the RPM-integrated one.
+if command -v debugedit >/dev/null ; then
+    debugedit=debugedit
+else
+    debugedit=/usr/lib/rpm/debugedit
+fi
+
+cleanup () {
+    rm -f "$tar_tmp"
+}
+trap cleanup 0
+
+sysroot_path="$1"
+shift
+script_path="$1"
+shift
+
+# See run_ldso setting in glibc.spec.
+ldso_list=`cd "$sysroot_path"; find . -name 'ld-*.so' -type f`
+libc_list=`cd "$sysroot_path"; find . -name 'libc-*.so' -type f`
+libdl_list=`cd "$sysroot_path"; find . -name 'libdl-*.so' -type f`
+libpthread_list=`cd "$sysroot_path"; find . -name 'libpthread-*.so' -type f`
+librt_list=`cd "$sysroot_path"; find . -name 'librt-*.so' -type f`
+
+full_list="$ldso_list $libc_list $libdl_list $libpthread_list $librt_list"
+
+# Preserve the original files.
+(cd "$sysroot_path"; ls -l $full_list)
+(cd "$sysroot_path"; tar cvf "$tar_tmp" $full_list)
+
+# Run the debuginfo extraction.
+"$script_path" "$@"
+
+# Restore the original files.
+(cd "$sysroot_path"; tar xf "$tar_tmp")
+(cd "$sysroot_path"; ls -l $full_list)
+
+# Reduce the size of notes.  Primarily for annobin.
+for p in $full_list
+do
+    objcopy --merge-notes "$sysroot_path/$p"
+done
+
+# libc.so.6 and other shared objects: Reduce to valuable symbols.
+# Eliminate file symbols, annobin symbols, and symbols used by the
+# glibc build to implement hidden aliases (__EI_*).  We would also
+# like to remove __GI_* symbols, but even listing them explicitly (as
+# in -K __GI_strlen) still causes strip to remove them, so there is no
+# filtering of __GI_* here.  (Debuginfo is gone after this, so no need
+# to optimize it.)
+for p in $libc_list $libdl_list $libpthread_list $librt_list ; do
+    strip -w \
+	  -K '*' \
+	  -K '!*.c' \
+	  -K '!*.os' \
+	  -K '!.annobin_*' \
+	  -K '!__EI_*' \
+	  -K '!__PRETTY_FUNCTION__*' \
+	  "$sysroot_path/$p"
+done
+
+# ld.so: Rewrite the source file paths to match the extracted
+# locations.  First compute the arguments for invoking debugedit.
+# See find-debuginfo.sh.
+debug_dest_name="/usr/src/debug"
+last_arg=
+while true ; do
+    arg="$1"
+    shift || break
+    case "$arg" in
+	(--unique-debug-src-base)
+	    debug_dest_name="/usr/src/debug/$1"
+	    shift
+	    ;;
+	(-*)
+	    ;;
+	(*)
+	    last_arg="$arg"
+	    ;;
+    esac
+done
+debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
+for p in $ldso_list
+do
+    $debugedit -b "$debug_base_name" -d "$debug_dest_name" -n "$sysroot_path/$p"
+done
+
+# Apply single-file DWARF optimization.
+for ldso in $ldso_list
+do
+    dwz "$sysroot_path/$p"
+done
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index 3bc5fb3..c5dfc74 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -1,6 +1,6 @@
 %define glibcsrcdir glibc-2.28
 %define glibcversion 2.28
-%define glibcrelease 164%{?dist}.3
+%define glibcrelease 189.1%{?dist}
 # Pre-release tarballs are pulled in from git using a command that is
 # effectively:
 #
@@ -85,6 +85,47 @@
 # here. If the arch is not listed here then a single core debuginfo package
 # will be created for the architecture.
 %define debuginfocommonarches %{biarcharches} alpha alphaev6
+
+##############################################################################
+# Utility functions for pre/post scripts.  Stick them at the beginning of
+# any lua %pre, %post, %postun, etc. sections to have them expand into
+# those scripts.  It only works in lua sections and not anywhere else.
+%define glibc_post_funcs() \
+-- We use lua posix.exec because there may be no shell that we can \
+-- run during glibc upgrade.  We used to implement much of %%post as a \
+-- C program, but from an overall maintenance perspective the lua in \
+-- the spec file was simpler and safer given the operations required. \
+-- All lua code will be ignored by rpm-ostree; see: \
+-- https://github.com/projectatomic/rpm-ostree/pull/1869 \
+-- If we add new lua actions to the %%post code we should coordinate \
+-- with rpm-ostree and ensure that their glibc install is functional. \
+function post_exec (program, ...) \
+  local pid = posix.fork () \
+  if pid == 0 then \
+    posix.exec (program, ...) \
+    assert (nil) \
+  elseif pid > 0 then \
+    posix.wait (pid) \
+  end \
+end \
+\
+function update_gconv_modules_cache () \
+  local iconv_dir = "%{_libdir}/gconv" \
+  local iconv_cache = iconv_dir .. "/gconv-modules.cache" \
+  local iconv_modules = iconv_dir .. "/gconv-modules" \
+  if (posix.utime (iconv_modules) == 0) then \
+    if (posix.utime (iconv_cache) == 0) then \
+      post_exec ("%{_prefix}/sbin/iconvconfig", \
+		 "-o", iconv_cache, \
+		 "--nostdlib", \
+		 iconv_dir) \
+    else \
+      io.stdout:write ("Error: Missing " .. iconv_cache .. " file.\n") \
+    end \
+  end \
+end \
+%{nil}
+
 ##############################################################################
 # %%package glibc - The GNU C Library (glibc) core package.
 ##############################################################################
@@ -135,6 +176,23 @@ Source11: SUPPORTED
 # Include in the source RPM for reference.
 Source12: ChangeLog.old
 
+Source13: wrap-find-debuginfo.sh
+
+######################################################################
+# Activate the wrapper script for debuginfo generation, by rewriting
+# the definition of __debug_install_post.
+%{lua:
+local wrapper = rpm.expand("%{SOURCE13}")
+local sysroot = rpm.expand("%{glibc_sysroot}")
+local original = rpm.expand("%{__find_debuginfo}")
+rpm.define("__find_debuginfo  " .. wrapper .. " " .. sysroot .. " " .. original)
+}
+
+# The wrapper script relies on the fact that debugedit does not change
+# build IDs.
+%define _no_recompute_build_ids 1
+%undefine _unique_build_ids
+
 ##############################################################################
 # Patches:
 # - See each individual patch file for origin and upstream status.
@@ -719,18 +777,85 @@ Patch582: glibc-rh1966472-1.patch
 Patch583: glibc-rh1966472-2.patch
 Patch584: glibc-rh1966472-3.patch
 Patch585: glibc-rh1966472-4.patch
-Patch586: glibc-rh2032280-1.patch
-Patch587: glibc-rh2032280-2.patch
-Patch588: glibc-rh2032280-3.patch
-Patch589: glibc-rh2032280-4.patch
-Patch590: glibc-rh2032280-5.patch
-Patch591: glibc-rh2032280-6.patch
-Patch592: glibc-rh2032280-7.patch
-Patch593: glibc-rh2045062-1.patch
-Patch594: glibc-rh2045062-2.patch
-Patch595: glibc-rh2045062-3.patch
-Patch596: glibc-rh2045062-4.patch
-Patch597: glibc-rh2045062-5.patch
+Patch586: glibc-rh1971664-1.patch
+Patch587: glibc-rh1971664-2.patch
+Patch588: glibc-rh1971664-3.patch
+Patch589: glibc-rh1971664-4.patch
+Patch590: glibc-rh1971664-5.patch
+Patch591: glibc-rh1971664-6.patch
+Patch592: glibc-rh1971664-7.patch
+Patch593: glibc-rh1971664-8.patch
+Patch594: glibc-rh1971664-9.patch
+Patch595: glibc-rh1971664-10.patch
+Patch596: glibc-rh1971664-11.patch
+Patch597: glibc-rh1971664-12.patch
+Patch598: glibc-rh1971664-13.patch
+Patch599: glibc-rh1971664-14.patch
+Patch600: glibc-rh1971664-15.patch
+Patch601: glibc-rh1977614.patch
+Patch602: glibc-rh1983203-1.patch
+Patch603: glibc-rh1983203-2.patch
+Patch604: glibc-rh2021452.patch
+Patch605: glibc-rh1937515.patch
+Patch606: glibc-rh1934162-1.patch
+Patch607: glibc-rh1934162-2.patch
+Patch608: glibc-rh2000374.patch
+Patch609: glibc-rh1991001-1.patch
+Patch610: glibc-rh1991001-2.patch
+Patch611: glibc-rh1991001-3.patch
+Patch612: glibc-rh1991001-4.patch
+Patch613: glibc-rh1991001-5.patch
+Patch614: glibc-rh1991001-6.patch
+Patch615: glibc-rh1991001-7.patch
+Patch616: glibc-rh1991001-8.patch
+Patch617: glibc-rh1991001-9.patch
+Patch618: glibc-rh1991001-10.patch
+Patch619: glibc-rh1991001-11.patch
+Patch620: glibc-rh1991001-12.patch
+Patch621: glibc-rh1991001-13.patch
+Patch622: glibc-rh1991001-14.patch
+Patch623: glibc-rh1991001-15.patch
+Patch624: glibc-rh1991001-16.patch
+Patch625: glibc-rh1991001-17.patch
+Patch626: glibc-rh1991001-18.patch
+Patch627: glibc-rh1991001-19.patch
+Patch628: glibc-rh1991001-20.patch
+Patch629: glibc-rh1991001-21.patch
+Patch630: glibc-rh1991001-22.patch
+Patch631: glibc-rh1929928-1.patch
+Patch632: glibc-rh1929928-2.patch
+Patch633: glibc-rh1929928-3.patch
+Patch634: glibc-rh1929928-4.patch
+Patch635: glibc-rh1929928-5.patch
+Patch636: glibc-rh1984802-1.patch
+Patch637: glibc-rh1984802-2.patch
+Patch638: glibc-rh1984802-3.patch
+Patch639: glibc-rh2023420-1.patch
+Patch640: glibc-rh2023420-2.patch
+Patch641: glibc-rh2023420-3.patch
+Patch642: glibc-rh2023420-4.patch
+Patch643: glibc-rh2023420-5.patch
+Patch644: glibc-rh2023420-6.patch
+Patch645: glibc-rh2023420-7.patch
+Patch646: glibc-rh2033648-1.patch
+Patch647: glibc-rh2033648-2.patch
+Patch648: glibc-rh2036955.patch
+Patch649: glibc-rh2033655.patch
+Patch650: glibc-rh2007327-1.patch
+Patch651: glibc-rh2007327-2.patch
+Patch652: glibc-rh2032281-1.patch
+Patch653: glibc-rh2032281-2.patch
+Patch654: glibc-rh2032281-3.patch
+Patch655: glibc-rh2032281-4.patch
+Patch656: glibc-rh2032281-5.patch
+Patch657: glibc-rh2032281-6.patch
+Patch658: glibc-rh2032281-7.patch
+Patch659: glibc-rh2045063-1.patch
+Patch660: glibc-rh2045063-2.patch
+Patch661: glibc-rh2045063-3.patch
+Patch662: glibc-rh2045063-4.patch
+Patch663: glibc-rh2045063-5.patch
+Patch664: glibc-rh2061727.patch
 
 ##############################################################################
 # Continued list of core "glibc" package information:
@@ -760,11 +885,6 @@ Recommends: (nss_db(x86-32) if nss_db(x86-64))
 BuildRequires: gd-devel libpng-devel zlib-devel
 %endif
 %if %{with docs}
-# Removing texinfo will cause check-safety.sh test to fail because it seems to
-# trigger documentation generation based on dependencies.  We need to fix this
-# upstream in some way that doesn't depend on generating docs to validate the
-# texinfo.  I expect it's simply the wrong dependency for that target.
-BuildRequires: texinfo >= 5.0
 %endif
 %if %{without bootstrap}
 BuildRequires: libselinux-devel >= 1.33.4-3
@@ -825,7 +945,8 @@ Conflicts: prelink < 0.4.2
 
 %if 0%{?_enable_debug_packages}
 BuildRequires: elfutils >= 0.72
-BuildRequires: rpm >= 4.2-0.56
+# -20 adds __find_debuginfo macro
+BuildRequires: rpm >= 4.14.3-20
 %endif
 
 %if %{without bootstrap}
@@ -861,6 +982,10 @@ BuildRequires: libidn2
 Requires: glibc-langpack = %{version}-%{release}
 Suggests: glibc-all-langpacks = %{version}-%{release}
 
+# Suggest extra gconv modules so that they are installed by default but can be
+# removed if needed to build a minimal OS image.
+Recommends: glibc-gconv-extra%{_isa} = %{version}-%{release}
+
 %description
 The glibc package contains standard libraries which are used by
 multiple programs on the system. In order to save disk space and
@@ -909,6 +1034,26 @@ Install glibc-devel if you are going to develop programs which will
 use the standard C libraries.
 
 ##############################################################################
+# glibc "doc" sub-package
+##############################################################################
+%if %{with docs}
+%package doc
+Summary: Documentation for GNU libc
+BuildArch: noarch
+Requires: %{name} = %{version}-%{release}
+
+# Removing texinfo will cause check-safety.sh test to fail because it seems to
+# trigger documentation generation based on dependencies.  We need to fix this
+# upstream in some way that doesn't depend on generating docs to validate the
+# texinfo.  I expect it's simply the wrong dependency for that target.
+BuildRequires: texinfo >= 5.0
+
+%description doc
+The glibc-doc package contains The GNU C Library Reference Manual in info
+format.  Additional package documentation is also provided.
+%endif
+
+##############################################################################
 # glibc "static" sub-package
 ##############################################################################
 %package static
@@ -1110,6 +1255,15 @@ nothing else. It is designed for assembling a minimal system.
 %files minimal-langpack
 %endif
 
+# Infrequently used iconv converter modules.
+%package gconv-extra
+Summary: All iconv converter modules for %{name}.
+Requires: %{name}%{_isa} = %{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
+
+%description gconv-extra
+This package contains all iconv converter modules built in %{name}.
+
 ##############################################################################
 # glibc "nscd" sub-package
 ##############################################################################
@@ -1192,62 +1346,6 @@ which can be helpful during program debugging.
 
 If unsure if you need this, don't install this package.
 
-##############################################################################
-# glibc core "debuginfo" sub-package
-##############################################################################
-%if 0%{?_enable_debug_packages}
-%define debug_package %{nil}
-%define __debug_install_post %{nil}
-%global __debug_package 1
-# Disable thew new features that glibc packages don't use.
-%undefine _debugsource_packages
-%undefine _debuginfo_subpackages
-%undefine _unique_debug_names
-%undefine _unique_debug_srcs
-
-%package debuginfo
-Summary: Debug information for package %{name}
-AutoReqProv: no
-%ifarch %{debuginfocommonarches}
-Requires: glibc-debuginfo-common = %{version}-%{release}
-%else
-%ifarch %{ix86} %{sparc}
-Obsoletes: glibc-debuginfo-common
-%endif
-%endif
-
-%description debuginfo
-This package provides debug information for package %{name}.
-Debug information is useful when developing applications that use this
-package or when debugging this package.
-
-This package also contains static standard C libraries with
-debugging information.  You need this only if you want to step into
-C library routines during debugging programs statically linked against
-one or more of the standard C libraries.
-To use this debugging information, you need to link binaries
-with -static -L%{_prefix}/lib/debug%{_libdir} compiler options.
-
-##############################################################################
-# glibc common "debuginfo-common" sub-package
-##############################################################################
-%ifarch %{debuginfocommonarches}
-
-%package debuginfo-common
-Summary: Debug information for package %{name}
-AutoReqProv: no
-
-%description debuginfo-common
-This package provides debug information for package %{name}.
-Debug information is useful when developing applications that use this
-package or when debugging this package.
-
-%comment Matches: %ifarch %{debuginfocommonarches}
-%endif
-
-%comment Matches: %if 0%{?_enable_debug_packages}
-%endif
-
 %if %{with benchtests}
 %package benchtests
 Summary: Benchmarking binaries and scripts for %{name}
@@ -1614,6 +1712,9 @@ fi
 # Compress all of the info files.
 gzip -9nvf %{glibc_sysroot}%{_infodir}/libc*
 
+# Copy the debugger interface documentation over to the right location
+mkdir -p %{glibc_sysroot}%{_docdir}/glibc
+cp elf/rtld-debugger-interface.txt %{glibc_sysroot}%{_docdir}/glibc
 %else
 rm -f %{glibc_sysroot}%{_infodir}/dir
 rm -f %{glibc_sysroot}%{_infodir}/libc.info*
@@ -1705,15 +1806,6 @@ chmod 644 %{glibc_sysroot}%{_libdir}/gconv/gconv-modules.cache
 #   archives we might have added.
 ##############################################################################
 
-# If we are building a debug package then copy all of the static archives
-# into the debug directory to keep them as unstripped copies.
-%if 0%{?_enable_debug_packages}
-mkdir -p %{glibc_sysroot}%{_prefix}/lib/debug%{_libdir}
-cp -a %{glibc_sysroot}%{_libdir}/*.a \
-	%{glibc_sysroot}%{_prefix}/lib/debug%{_libdir}/
-rm -f %{glibc_sysroot}%{_prefix}/lib/debug%{_libdir}/*_p.a
-%endif
-
 # Remove any zoneinfo files; they are maintained by tzdata.
 rm -rf %{glibc_sysroot}%{_prefix}/share/zoneinfo
 
@@ -1727,7 +1819,14 @@ touch -r %{SOURCE0} %{glibc_sysroot}/etc/ld.so.conf
 touch -r sunrpc/etc.rpc %{glibc_sysroot}/etc/rpc
 
 pushd build-%{target}
-$GCC -Os -g -static -o build-locale-archive %{SOURCE1} \
+$GCC -Os -g \
+%ifarch %{pie_arches}
+	-fPIE \
+	-static-pie \
+%else
+	-static \
+%endif
+	 -o build-locale-archive %{SOURCE1} \
 	../build-%{target}/locale/locarchive.o \
 	../build-%{target}/locale/md5.o \
 	../build-%{target}/locale/record-status.o \
@@ -1737,12 +1836,6 @@ $GCC -Os -g -static -o build-locale-archive %{SOURCE1} \
 install -m 700 build-locale-archive %{glibc_sysroot}%{_prefix}/sbin/build-locale-archive
 popd
 
-# Lastly copy some additional documentation for the packages.
-rm -rf documentation
-mkdir documentation
-cp timezone/README documentation/README.timezone
-cp posix/gai.conf documentation/
-
 %ifarch s390x
 # Compatibility symlink
 mkdir -p %{glibc_sysroot}/lib
@@ -1767,6 +1860,7 @@ cp benchtests/scripts/benchout.schema.json %{glibc_sysroot}%{_prefix}/libexec/gl
 cp benchtests/scripts/compare_bench.py %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/
 cp benchtests/scripts/import_bench.py %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/
 cp benchtests/scripts/validate_benchout.py %{glibc_sysroot}%{_prefix}/libexec/glibc-benchtests/
+%endif
 
 %if 0%{?_enable_debug_packages}
 # The #line directives gperf generates do not give the proper
@@ -1777,6 +1871,7 @@ popd
 pushd iconv
 ln -s ../locale/programs/charmap-kw.gperf .
 popd
+%endif
 
 %if %{with docs}
 # Remove the `dir' info-heirarchy file which will be maintained
@@ -1861,6 +1956,8 @@ ar cr %{glibc_sysroot}%{_prefix}/%{_lib}/libpthread_nonshared.a
 #	- Files for the nscd subpackage.
 # * devel.filelist
 #	- Files for the devel subpackage.
+# * doc.filelist
+#	- Files for the documentation subpackage.
 # * headers.filelist
 #	- Files for the headers subpackage.
 # * static.filelist
@@ -1874,11 +1971,6 @@ ar cr %{glibc_sysroot}%{_prefix}/%{_lib}/libpthread_nonshared.a
 #       - File list with the .so symbolic links for NSS packages.
 # * compat-libpthread-nonshared.filelist.
 #	- File list for compat-libpthread-nonshared subpackage.
-# * debuginfo.filelist
-#	- Files for the glibc debuginfo package.
-# * debuginfocommon.filelist
-#	- Files for the glibc common debuginfo package.
-#
 
 # Create the main file lists. This way we can append to any one of them later
 # wihtout having to create it. Note these are removed at the start of the
@@ -1887,8 +1979,10 @@ touch master.filelist
 touch glibc.filelist
 touch common.filelist
 touch utils.filelist
+touch gconv.filelist
 touch nscd.filelist
 touch devel.filelist
+touch doc.filelist
 touch headers.filelist
 touch static.filelist
 touch libnsl.filelist
@@ -1896,8 +1990,6 @@ touch nss_db.filelist
 touch nss_hesiod.filelist
 touch nss-devel.filelist
 touch compat-libpthread-nonshared.filelist
-touch debuginfo.filelist
-touch debuginfocommon.filelist
 
 ###############################################################################
 # Master file list, excluding a few things.
@@ -1909,10 +2001,10 @@ touch debuginfocommon.filelist
   find %{glibc_sysroot} \( -type f -o -type l \) \
        \( \
 	 -name etc -printf "%%%%config " -o \
-	 -name gconv-modules \
-	 -printf "%%%%verify(not md5 size mtime) %%%%config(noreplace) " -o \
-	 -name gconv-modules.cache \
-	 -printf "%%%%verify(not md5 size mtime) " \
+         -name gconv-modules.cache \
+         -printf "%%%%verify(not md5 size mtime) " -o \
+         -name gconv-modules* \
+         -printf "%%%%verify(not md5 size mtime) %%%%config(noreplace) " \
 	 , \
 	 ! -path "*/lib/debug/*" -printf "/%%P\n" \)
   # List all directories with a %%dir prefix.  We omit the info directory and
@@ -1964,6 +2056,7 @@ chmod 0444 master.filelist
 # - All bench test binaries.
 # - The aux-cache, since it's handled specially in the files section.
 # - The build-locale-archive binary since it's in the common package.
+# - Extra gconv modules.  We add the required modules later.
 cat master.filelist \
 	| grep -v \
 	-e '%{_infodir}' \
@@ -1972,6 +2065,8 @@ cat master.filelist \
 	-e '%{_libdir}/lib.*\.a' \
         -e '%{_libdir}/.*\.o' \
 	-e '%{_libdir}/lib.*\.so' \
+	-e '%{_libdir}/gconv/.*\.so$' \
+	-e '%{_libdir}/gconv/gconv-modules.d/gconv-modules-extra\.conf$' \
 	-e 'nscd' \
 	-e '%{_prefix}/bin' \
 	-e '%{_prefix}/lib/locale' \
@@ -1997,18 +2092,41 @@ done
 grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist >> glibc.filelist
 
 ###############################################################################
-# glibc-devel
+# glibc-gconv-extra
 ###############################################################################
 
-%if %{with docs}
-# Put the info files into the devel file list, but exclude the generated dir.
-grep '%{_infodir}' master.filelist | grep -v '%{_infodir}/dir' > devel.filelist
+grep -e "gconv-modules-extra.conf" master.filelist > gconv.filelist
+
+# Put the essential gconv modules into the main package.
+GconvBaseModules="ANSI_X3.110 ISO8859-15 ISO8859-1 CP1252"
+GconvBaseModules="$GconvBaseModules UNICODE UTF-16 UTF-32 UTF-7"
+%ifarch s390 s390x
+GconvBaseModules="$GconvBaseModules ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9"
+GconvBaseModules="$GconvBaseModules UTF16_UTF32_Z9 UTF8_UTF32_Z9"
 %endif
+GconvAllModules=$(cat master.filelist |
+                 sed -n 's|%{_libdir}/gconv/\(.*\)\.so|\1|p')
+
+# Put the base modules into glibc and the rest into glibc-gconv-extra
+for conv in $GconvAllModules; do
+    if echo $GconvBaseModules | grep -q $conv; then
+        grep -E -e "%{_libdir}/gconv/$conv.so$" \
+            master.filelist >> glibc.filelist
+    else
+        grep -E -e "%{_libdir}/gconv/$conv.so$" \
+            master.filelist >> gconv.filelist
+    fi
+done
+
+
+###############################################################################
+# glibc-devel
+###############################################################################
 
 # Put some static files into the devel package.
 grep '%{_libdir}/lib.*\.a' master.filelist \
   | grep '/lib\(\(c\|pthread\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\)\.a$' \
-  >> devel.filelist
+  > devel.filelist
 
 # Put all of the object files and *.so (not the versioned ones) into the
 # devel package.
@@ -2023,6 +2141,16 @@ sed -i -e '\,libmemusage.so,d' \
 	devel.filelist
 
 ###############################################################################
+# glibc-doc
+###############################################################################
+
+%if %{with docs}
+# Put the info files into the doc file list, but exclude the generated dir.
+grep '%{_infodir}' master.filelist | grep -v '%{_infodir}/dir' > doc.filelist
+grep '%{_docdir}' master.filelist >> doc.filelist
+%endif
+
+###############################################################################
 # glibc-headers
 ###############################################################################
 
@@ -2064,12 +2192,14 @@ grep '%{_prefix}/sbin' master.filelist \
 # multilib-independent.
 # Exceptions:
 # - The actual share directory, not owned by us.
-# - The info files which go in devel, and the info directory.
+# - The info files which go into doc, and the info directory.
+# - All documentation files, which go into doc.
 grep '%{_prefix}/share' master.filelist \
 	| grep -v \
 	-e '%{_prefix}/share/info/libc.info.*' \
 	-e '%%dir %{prefix}/share/info' \
 	-e '%%dir %{prefix}/share' \
+	-e '%{_docdir}' \
 	>> common.filelist
 
 # Add the binary to build locales to the common subpackage.
@@ -2091,8 +2221,8 @@ cat > utils.filelist <<EOF
 %if %{without bootstrap}
 %{_prefix}/bin/memusage
 %{_prefix}/bin/memusagestat
-%endif
 %{_prefix}/bin/mtrace
+%endif
 %{_prefix}/bin/pcprofiledump
 %{_prefix}/bin/xtrace
 EOF
@@ -2124,6 +2254,7 @@ grep '/libnss_[a-z]*\.so$' master.filelist > nss-devel.filelist
 grep '/libnsl-[0-9.]*.so$' master.filelist > libnsl.filelist
 test $(wc -l < libnsl.filelist) -eq 1
 
+%if %{with benchtests}
 ###############################################################################
 # glibc-benchtests
 ###############################################################################
@@ -2148,101 +2279,6 @@ echo "%{_prefix}/libexec/glibc-benchtests/validate_benchout.py*" >> benchtests.f
 ###############################################################################
 echo "%{_libdir}/libpthread_nonshared.a" >> compat-libpthread-nonshared.filelist
 
-###############################################################################
-# glibc-debuginfocommon, and glibc-debuginfo
-###############################################################################
-
-find_debuginfo_args='--strict-build-id -g -i'
-%ifarch %{debuginfocommonarches}
-find_debuginfo_args="$find_debuginfo_args \
-	-l common.filelist \
-	-l utils.filelist \
-	-l nscd.filelist \
-	-p '.*/(sbin|libexec)/.*' \
-	-o debuginfocommon.filelist \
-	-l nss_db.filelist -l nss_hesiod.filelist \
-	-l libnsl.filelist -l glibc.filelist \
-%if %{with benchtests}
-	-l benchtests.filelist
-%endif
-	"
-%endif
-
-/usr/lib/rpm/find-debuginfo.sh $find_debuginfo_args -o debuginfo.filelist
-
-# List all of the *.a archives in the debug directory.
-list_debug_archives()
-{
-	local dir=%{_prefix}/lib/debug%{_libdir}
-	find %{glibc_sysroot}$dir -name "*.a" -printf "$dir/%%P\n"
-}
-
-%ifarch %{debuginfocommonarches}
-
-# Remove the source files from the common package debuginfo.
-sed -i '\#^%{glibc_sysroot}%{_prefix}/src/debug/#d' debuginfocommon.filelist
-
-# Create a list of all of the source files we copied to the debug directory.
-find %{glibc_sysroot}%{_prefix}/src/debug \
-     \( -type d -printf '%%%%dir ' \) , \
-     -printf '%{_prefix}/src/debug/%%P\n' > debuginfocommon.sources
-
-%ifarch %{biarcharches}
-
-# Add the source files to the core debuginfo package.
-cat debuginfocommon.sources >> debuginfo.filelist
-
-%else
-
-%ifarch %{ix86}
-%define basearch i686
-%endif
-%ifarch sparc sparcv9
-%define basearch sparc
-%endif
-
-# The auxarches get only these few source files.
-auxarches_debugsources=\
-'/(generic|linux|%{basearch}|nptl(_db)?)/|/%{glibcsrcdir}/build|/dl-osinfo\.h'
-
-# Place the source files into the core debuginfo pakcage.
-egrep "$auxarches_debugsources" debuginfocommon.sources >> debuginfo.filelist
-
-# Remove the source files from the common debuginfo package.
-egrep -v "$auxarches_debugsources" \
-  debuginfocommon.sources >> debuginfocommon.filelist
-
-%comment Matches: %ifarch %{biarcharches}
-%endif
-
-# Add the list of *.a archives in the debug directory to
-# the common debuginfo package.
-list_debug_archives >> debuginfocommon.filelist
-
-%comment Matches: %ifarch %{debuginfocommonarches}
-%endif
-
-# Remove some common directories from the common package debuginfo so that we
-# don't end up owning them.
-exclude_common_dirs()
-{
-	exclude_dirs="%{_prefix}/src/debug"
-	exclude_dirs="$exclude_dirs $(echo %{_prefix}/lib/debug{,/%{_lib},/bin,/sbin})"
-	exclude_dirs="$exclude_dirs $(echo %{_prefix}/lib/debug%{_prefix}{,/%{_lib},/libexec,/bin,/sbin})"
-
-	for d in $(echo $exclude_dirs | sed 's/ /\n/g'); do
-		sed -i "\|^%%dir $d/\?$|d" $1
-	done
-}
-
-%ifarch %{debuginfocommonarches}
-exclude_common_dirs debuginfocommon.filelist
-%endif
-exclude_common_dirs debuginfo.filelist
-
-%comment Matches: %if 0%{?_enable_debug_packages}
-%endif
-
 ##############################################################################
 # Delete files that we do not intended to ship with the auxarch.
 # This is the only place where we touch the installed files after generating
@@ -2332,6 +2368,15 @@ echo ====================PLT RELOCS LIBC.SO==============
 readelf -Wr %{glibc_sysroot}/%{_lib}/libc-*.so | sed -n -e "$PLTCMD"
 echo ====================PLT RELOCS END==================
 
+# Obtain a way to run the dynamic loader.  Avoid matching the symbolic
+# link and then pick the first loader (although there should be only
+# one).
+run_ldso="$(find %{glibc_sysroot}/%{_lib}/ld-*.so -type f | LC_ALL=C sort | head -n1) --library-path %{glibc_sysroot}/%{_lib}"
+
+# Show the auxiliary vector as seen by the new library
+# (even if we do not perform the valgrind test).
+LD_SHOW_AUXV=1 $run_ldso /bin/true
+
 # Finally, check if valgrind runs with the new glibc.
 # We want to fail building if valgrind is not able to run with this glibc so
 # that we can then coordinate with valgrind to get it fixed before we update
@@ -2340,16 +2385,15 @@ pushd build-%{target}
 
 # Show the auxiliary vector as seen by the new library
 # (even if we do not perform the valgrind test).
-LD_SHOW_AUXV=1 elf/ld.so --library-path .:elf:nptl:dlfcn /bin/true
+LD_SHOW_AUXV=1 $run_ldso /bin/true
 
 %if %{with valgrind}
-elf/ld.so --library-path .:elf:nptl:dlfcn \
-	/usr/bin/valgrind --error-exitcode=1 \
-	elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/true
+$run_ldso /usr/bin/valgrind --error-exitcode=1 \
+	$run_ldso /usr/bin/true
 %endif
 popd
 
-%comment Matches: %if %{run_glibc_tests}
+%comment Matches: %if %{with testsuite}
 %endif
 
 
@@ -2362,17 +2406,7 @@ if rpm.vercmp(rel, required) < 0 then
 end
 
 %post -p <lua>
--- We use lua's posix.exec because there may be no shell that we can
--- run during glibc upgrade.
-function post_exec (program, ...)
-  local pid = posix.fork ()
-  if pid == 0 then
-    assert (posix.exec (program, ...))
-  elseif pid > 0 then
-    posix.wait (pid)
-  end
-end
-
+%glibc_post_funcs
 -- (1) Remove multilib libraries from previous installs.
 -- In order to support in-place upgrades, we must immediately remove
 -- obsolete platform directories after installing a new glibc
@@ -2481,16 +2515,7 @@ post_exec ("%{_prefix}/sbin/ldconfig")
 -- We assume that the cache is in _libdir/gconv and called
 -- "gconv-modules.cache".
 
-local iconv_dir = "%{_libdir}/gconv"
-local iconv_cache = iconv_dir .. "/gconv-modules.cache"
-if (posix.utime (iconv_cache) == 0) then
-  post_exec ("%{_prefix}/sbin/iconvconfig",
-	     "-o", iconv_cache,
-	     "--nostdlib",
-	     iconv_dir)
-else
-  io.stdout:write ("Error: Missing " .. iconv_cache .. " file.\n")
-end
+update_gconv_modules_cache()
 
 %posttrans all-langpacks -e -p <lua>
 -- If at the end of the transaction we are still installed
@@ -2531,6 +2556,14 @@ if [ "$1" = 0 ]; then
 fi
 %endif
 
+%post gconv-extra -p <lua>
+%glibc_post_funcs
+update_gconv_modules_cache ()
+
+%postun gconv-extra -p <lua>
+%glibc_post_funcs
+update_gconv_modules_cache ()
+
 %pre -n nscd
 getent group nscd >/dev/null || /usr/sbin/groupadd -g 28 -r nscd
 getent passwd nscd >/dev/null ||
@@ -2563,11 +2596,11 @@ fi
 %dir /etc/ld.so.conf.d
 %dir %{_prefix}/libexec/getconf
 %dir %{_libdir}/gconv
+%dir %{_libdir}/gconv/gconv-modules.d
 %dir %attr(0700,root,root) /var/cache/ldconfig
 %attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/cache/ldconfig/aux-cache
 %attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/ld.so.cache
 %attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/gai.conf
-%doc README NEWS INSTALL elf/rtld-debugger-interface.txt
 # If rpm doesn't support %license, then use %doc instead.
 %{!?_licensedir:%global license %%doc}
 %license COPYING COPYING.LIB LICENSES
@@ -2577,8 +2610,6 @@ fi
 %dir %{_prefix}/lib/locale
 %dir %{_prefix}/lib/locale/C.utf8
 %{_prefix}/lib/locale/C.utf8/*
-%doc documentation/README.timezone
-%doc documentation/gai.conf
 
 %files all-langpacks
 %attr(0644,root,root) %verify(not md5 size mtime) %{_prefix}/lib/locale/locale-archive.tmpl
@@ -2592,12 +2623,18 @@ fi
 
 %files -f devel.filelist devel
 
+%if %{with docs}
+%files -f doc.filelist doc
+%endif
+
 %files -f static.filelist static
 
 %files -f headers.filelist headers
 
 %files -f utils.filelist utils
 
+%files -f gconv.filelist gconv-extra
+
 %files -f nscd.filelist -n nscd
 %config(noreplace) /etc/nscd.conf
 %dir %attr(0755,root,root) /var/run/nscd
@@ -2627,15 +2664,6 @@ fi
 %files -f libnsl.filelist -n libnsl
 /%{_lib}/libnsl.so.1
 
-%if 0%{?_enable_debug_packages}
-%files debuginfo -f debuginfo.filelist
-%ifarch %{debuginfocommonarches}
-%ifnarch %{auxarches}
-%files debuginfo-common -f debuginfocommon.filelist
-%endif
-%endif
-%endif
-
 %if %{with benchtests}
 %files benchtests -f benchtests.filelist
 %endif
@@ -2643,16 +2671,91 @@ fi
 %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
 
 %changelog
-* Thu Jan 27 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-164.3
+* Thu Mar 10 2022 Florian Weimer <fweimer@redhat.com> - 2.28-189.1
+- nss: Avoid clobbering errno in get*ent via dlopen (#2061727)
+
+* Thu Jan 27 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-189
 - CVE-2021-3999: getcwd: align stack on clone in aarch64 and fix a memory leak
-  (#2032280)
+  (#2032281)
 
-* Wed Jan 26 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-164.2
+* Tue Jan 25 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-188
 - CVE-2022-23218, CVE-2022-23219: Fix buffer overflows in sunrpc clnt_create
-  for "unix" and svcunix_create (#2045062).
+  for "unix" and svcunix_create (#2045063).
+
+* Mon Jan 24 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-187
+- CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1 (#2032281)
+
+* Fri Jan 21 2022 Carlos O'Donell <carlos@redhat.com> - 2.28-186
+- Fix pthread_once regression with C++ exceptions (#2007327)
+
+* Thu Jan 20 2022 DJ Delorie <dj@redhat.com> - 2.28-185
+- Adjust to rpm's find-debuginfo.sh changes, to keep stripping binaries (#1661513)
+
+* Fri Jan  7 2022 Florian Weimer <fweimer@redhat.com> - 2.28-184
+- Conversion from ISO-2022-JP-3 may emit spurious NUL character (#2033655)
+
+* Fri Jan  7 2022 Florian Weimer <fweimer@redhat.com> - 2.28-183
+- aarch64: A64FX optimizations break "sve=off" guest mode (#2036955)
+
+* Fri Jan  7 2022 Patsy Griffin <patsy@redhat.com> - 2.28-182
+- Handle truncated timezones from tzcode-2021d and later. (#2033648)
+
+* Tue Jan  4 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-181
+- Weaken dependency of glibc on glibc-gconv-extra (#2015768)
+
+* Mon Dec 13 2021 Florian Weimer <fweimer@redhat.com> - 2.28-180
+- Do not install /usr/lib/debug/usr/bin/ld.so.debug (#2023420)
+
+* Fri Dec 10 2021 Florian Weimer <fweimer@redhat.com> - 2.28-179
+- Add /usr/bin/ld.so --list-diagnostics (#2023420)
+
+* Fri Dec 10 2021 Carlos O'Donell <carlos@redhat.com> - 2.28-178
+- Preliminary support for new IBM zSeries hardware (#1984802)
+
+* Fri Dec 10 2021 Carlos O'Donell <carlos@redhat.com> - 2.28-177
+- Fix --with and --without builds for benchtests and bootstrap (#2020989)
+
+* Wed Dec  1 2021 Florian Weimer <fweimer@redhat.com> - 2.28-176
+- A64FX memcpy/memmove/memset optimizations (#1929928)
+
+* Tue Nov 30 2021 Florian Weimer <fweimer@redhat.com> - 2.28-175
+- Fix dl-tls.c assert failure with pthread_create & dlopen (#1991001)
+- Fix x86_64 TLS lazy binding with auditors (#1950056)
+
+* Thu Nov 25 2021 Arjun Shankar <arjun@redhat.com> - 2.28-174
+- Introduce new glibc-doc.noarch subpackage (#2021671)
+- Move the reference manual info pages from glibc-devel to glibc-doc
+- Move debugger interface documentation from glibc to glibc-doc
+- Remove unnecessary README, INSTALL, NEWS files from glibc
+- Remove unnecessary README.timezone and gai.conf files from glibc-common
+
+* Wed Nov 17 2021 Patsy Griffin <patsy@redhat.com> - 2.28-173
+- Add new English-language 12 hour time locale en_US@ampm.UTF-8 (#2000374)
+
+* Tue Nov 16 2021 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-172
+- Build build-locale-archive with -static-pie when supported (#1965377)
+
+* Wed Nov  10 2021 DJ Delorie <dj@redhat.com> - 2.28-171
+- elf: Always set link map in _dl_init_paths (#1934162)
+
+* Wed Nov 10 2021 Arjun Shankar <arjun@redhat.com> - 2.28-170
+- x86: Properly disable XSAVE related features when its use is disabled via
+  tunables (#1937515)
+
+* Wed Nov 10 2021 Arjun Shankar <arjun@redhat.com> - 2.28-169
+- s390: Use long branches across object boundaries (#2021452)
+
+* Fri Oct 29 2021 Arjun Shankar <arjun@redhat.com> - 2.28-168
+- Optimize memcmp, strcpy, and stpcpy for IBM POWER10 (#1983203)
+
+* Wed Oct 13 2021 Arjun Shankar <arjun@redhat.com> - 2.28-167
+- malloc: Initiate tcache shutdown even without allocations (#1977614)
+
+* Wed Oct 13 2021 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-166
+- Fix debuginfo location for gconv-extra and make glibc Require it (#1971664).
 
-* Mon Jan 24 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-164.1
-- CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1 (#2032280)
+* Wed Oct  6 2021 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-165
+- Split extra gconv modules into a separate package (#1971664).
 
 * Mon Aug  9 2021 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-164
 - librt: fix NULL pointer dereference (#1966472).