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 +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< +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 +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 ++# . ++"""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 +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 + Reviewed-by: Szabolcs Nagy + +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 + + /* 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 ++ . */ ++ ++#include ++ ++/* 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 ++#include + + #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 +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 + Reviewed-by: Szabolcs Nagy + +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 ++ . */ ++ ++#include ++#include ++ ++/* 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 +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 + +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 ++ . */ ++ ++/* 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 +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 +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 +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 + +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 +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 + +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 + #include +-#include + #include + #include + #include +@@ -34,10 +33,10 @@ + #include + #include + #include +-#include + #include + + #include "iconvconfig.h" ++#include + + /* 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 +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 + +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 +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 + +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 ++#include + + + /* 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 +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 + Reviewed-by: Szabolcs Nagy + +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 +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 + +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 +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 + Reported-by: Michael Hudson-Doyle + Reviewed-by: Andreas Schwab + +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 +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 + +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 + #include ++#include + #include + #include + #include +@@ -33,6 +34,7 @@ + #include + #include + #include ++#include + #include + + #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 +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 + +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 + #include ++#include + #include + #include + #include +@@ -30,6 +31,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -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 +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 + +# 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 +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 + +# 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 ++# . ++ ++# 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 +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 +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 + +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 +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 + Reviewed-by: Andreas Schwab + +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 +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 + +# 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 + #include +-#include + #include + #include + #include +@@ -31,11 +30,10 @@ + #include + #include + #include +-#include + + #include + #include +- ++#include + + /* 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 +-#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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#if IS_IN (libc) ++# include ++# 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 +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 + +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 +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 + Reviewed-by: Raphael M Zinsly + +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 ++ . */ ++ ++#include ++ ++/* 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 ++ . */ ++ ++#define MEMCMP __memcmp_power10 ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++#undef weak_alias ++#define weak_alias(name,alias) ++ ++#include +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 +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 + Tested-by: Matheus Castanho + +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 +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 /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 +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 + +-#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 +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 + +-#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 +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 + +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 +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 + #include + #include ++#include + #include + #include + 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 +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 + +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 + #include + #include +-#define _dl_tlsdesc_resolve_hold 0 + #include + + /* 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 + #include + #include +-#define _dl_tlsdesc_resolve_hold 0 + #include + + /* 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 + #include + #include +-#define _dl_tlsdesc_resolve_hold 0 + #include + + /* 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 + #include + #include +-#define _dl_tlsdesc_resolve_hold 0 + #include + + /* 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 +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 + +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 +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 + +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 +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 + +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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 +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 +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 + +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 +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 +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 + +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 + . */ + ++#include + #include + #include + #include + #include + #include + #include ++#include + #include + #include + +@@ -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 +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 +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 + +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 ++ . */ ++ ++#include ++#include ++#include ++ ++/* ++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 +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 ++ . */ ++ ++#include ++ ++/* 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 +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 + +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 +Date: Tue Nov 30 14:35:54 2021 +0100 + + elf: Include 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 + #include + #include ++#include + #include + #include + #include 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 +Date: Tue Nov 30 15:39:17 2021 +0100 + + elf: Include 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 + #include + #include ++#include + #include + #include + #include 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 +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 + +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 +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 + +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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 +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 +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 + +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 +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 + +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 +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 +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 +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 + . */ + +-#include + #include +-#include + #include + #include + #include ++#define _dl_tlsdesc_resolve_hold 0 + #include + +-/* 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 +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 + . */ + +-#include + #include +-#include + #include + #include + #include ++#define _dl_tlsdesc_resolve_hold 0 + #include + +-/* 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 , 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 +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 +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 +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 + Reviewed-by: Stefan Liebler + +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 +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 + +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 + #include + #include ++#include + + #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 + #include + #include ++#include + + #include + +@@ -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 ++# . ++ ++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 +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 +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 ++ . */ ++ ++#include ++ ++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 ++ . */ ++ ++#include ++ ++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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#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 ++ . */ ++ ++#ifndef _DL_DIAGNOSTICS_H ++#define _DL_DIAGNOSTICS_H ++ ++#include ++ ++/* 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 ++ . */ ++ ++#include ++#include ++#include ++ ++/* 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 +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 . ++ 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 ++ . */ ++ ++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 +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 ++ . */ ++ ++#include ++#include ++ ++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 +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. + + is needed because execve is not available in the + dynamic loader on Hurd. + + Reviewed-by: H.J. Lu + +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 + #include + #include ++#include + + #include + +@@ -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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++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 +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 ++ . */ ++ ++#include ++ ++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 ++ . */ ++ ++#include ++ ++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 +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 + + 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á -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 -+ . */ -+ -+#include -+#include -+#include -+ -+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 -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 - #include - #include - /* 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 -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 - Signed-off-by: Siddhesh Poyarekar - -# 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 - #include - #include - #include - -+#include - #include - #include - #include - #include --#include -+#include - - /* 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 -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 - Reviewed-by: Adhemerval Zanella - Signed-off-by: Qualys Security Advisory - Signed-off-by: Siddhesh Poyarekar - -# 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 -+ . */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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 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 -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 -+ . */ -+ -+#ifdef __linux__ -+# include -+# include /* For _STACK_GROWS_{UP,DOWN}. */ -+# include -+ -+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 -+ . */ -+ -+#ifndef SUPPORT_XSCHED_H -+#define SUPPORT_XSCHED_H -+ -+__BEGIN_DECLS -+ -+#include -+#include -+ -+#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 -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 - -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 - #include - #include -+#include - #include - #include - -@@ -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 -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á +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 ++ . */ ++ ++#include ++#include ++#include ++ ++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 +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 + #include + #include + /* 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 +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 + Signed-off-by: Siddhesh Poyarekar + +# 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 + #include + #include + #include + ++#include + #include + #include + #include + #include +-#include ++#include + + /* 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 +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 + Reviewed-by: Adhemerval Zanella + Signed-off-by: Qualys Security Advisory + Signed-off-by: Siddhesh Poyarekar + +# 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 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 +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 ++ . */ ++ ++#ifdef __linux__ ++# include ++# include /* For _STACK_GROWS_{UP,DOWN}. */ ++# include ++ ++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 ++ . */ ++ ++#ifndef SUPPORT_XSCHED_H ++#define SUPPORT_XSCHED_H ++ ++__BEGIN_DECLS ++ ++#include ++#include ++ ++#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 +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 + +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 + #include + #include ++#include + #include + #include + +@@ -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 +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 +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 + +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 +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 + + 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* 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 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 +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 + +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 ++ . */ ++ ++#include ++#include ++#include ++ ++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 +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 , 1998, + and Bruno Haible , 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 +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 -Date: Mon Jan 17 10:21:34 2022 +0100 - - socket: Add the __sockaddr_un_set function - - Reviewed-by: Siddhesh Poyarekar - -# 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 -+ -+#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 -+ . */ -+ -+#include -+#include -+#include -+#include -+ -+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 -+ . */ -+ -+/* Re-compile the function because the version in libc is not -+ exported. */ -+#include "sockaddr_un_set.c" -+ -+#include -+ -+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 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 -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 - -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 -Date: Mon Jan 17 10:21:34 2022 +0100 - - sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542) - - Reviewed-by: Siddhesh Poyarekar - -# 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 -+ . */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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 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 -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 - -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 -+ . */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* 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 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 -Date: Tue Mar 9 21:07:24 2021 +0100 - - : 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 +Date: Mon Jan 17 10:21:34 2022 +0100 + + socket: Add the __sockaddr_un_set function + + Reviewed-by: Siddhesh Poyarekar + +# 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 ++ ++#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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++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 ++ . */ ++ ++/* Re-compile the function because the version in libc is not ++ exported. */ ++#include "sockaddr_un_set.c" ++ ++#include ++ ++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 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 +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 + +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 +Date: Mon Jan 17 10:21:34 2022 +0100 + + sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542) + + Reviewed-by: Siddhesh Poyarekar + +# 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 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 +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 + +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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 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 +Date: Tue Mar 9 21:07:24 2021 +0100 + + : 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) + + +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 ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 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 < 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 --- 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 -- 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 +%glibc_post_funcs +update_gconv_modules_cache () + +%postun gconv-extra -p +%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 - 2.28-164.3 +* Thu Mar 10 2022 Florian Weimer - 2.28-189.1 +- nss: Avoid clobbering errno in get*ent via dlopen (#2061727) + +* Thu Jan 27 2022 Siddhesh Poyarekar - 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 - 2.28-164.2 +* Tue Jan 25 2022 Siddhesh Poyarekar - 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 - 2.28-187 +- CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1 (#2032281) + +* Fri Jan 21 2022 Carlos O'Donell - 2.28-186 +- Fix pthread_once regression with C++ exceptions (#2007327) + +* Thu Jan 20 2022 DJ Delorie - 2.28-185 +- Adjust to rpm's find-debuginfo.sh changes, to keep stripping binaries (#1661513) + +* Fri Jan 7 2022 Florian Weimer - 2.28-184 +- Conversion from ISO-2022-JP-3 may emit spurious NUL character (#2033655) + +* Fri Jan 7 2022 Florian Weimer - 2.28-183 +- aarch64: A64FX optimizations break "sve=off" guest mode (#2036955) + +* Fri Jan 7 2022 Patsy Griffin - 2.28-182 +- Handle truncated timezones from tzcode-2021d and later. (#2033648) + +* Tue Jan 4 2022 Siddhesh Poyarekar - 2.28-181 +- Weaken dependency of glibc on glibc-gconv-extra (#2015768) + +* Mon Dec 13 2021 Florian Weimer - 2.28-180 +- Do not install /usr/lib/debug/usr/bin/ld.so.debug (#2023420) + +* Fri Dec 10 2021 Florian Weimer - 2.28-179 +- Add /usr/bin/ld.so --list-diagnostics (#2023420) + +* Fri Dec 10 2021 Carlos O'Donell - 2.28-178 +- Preliminary support for new IBM zSeries hardware (#1984802) + +* Fri Dec 10 2021 Carlos O'Donell - 2.28-177 +- Fix --with and --without builds for benchtests and bootstrap (#2020989) + +* Wed Dec 1 2021 Florian Weimer - 2.28-176 +- A64FX memcpy/memmove/memset optimizations (#1929928) + +* Tue Nov 30 2021 Florian Weimer - 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 - 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 - 2.28-173 +- Add new English-language 12 hour time locale en_US@ampm.UTF-8 (#2000374) + +* Tue Nov 16 2021 Siddhesh Poyarekar - 2.28-172 +- Build build-locale-archive with -static-pie when supported (#1965377) + +* Wed Nov 10 2021 DJ Delorie - 2.28-171 +- elf: Always set link map in _dl_init_paths (#1934162) + +* Wed Nov 10 2021 Arjun Shankar - 2.28-170 +- x86: Properly disable XSAVE related features when its use is disabled via + tunables (#1937515) + +* Wed Nov 10 2021 Arjun Shankar - 2.28-169 +- s390: Use long branches across object boundaries (#2021452) + +* Fri Oct 29 2021 Arjun Shankar - 2.28-168 +- Optimize memcmp, strcpy, and stpcpy for IBM POWER10 (#1983203) + +* Wed Oct 13 2021 Arjun Shankar - 2.28-167 +- malloc: Initiate tcache shutdown even without allocations (#1977614) + +* Wed Oct 13 2021 Siddhesh Poyarekar - 2.28-166 +- Fix debuginfo location for gconv-extra and make glibc Require it (#1971664). -* Mon Jan 24 2022 Siddhesh Poyarekar - 2.28-164.1 -- CVE-2021-3999: getcwd: Set errno to ERANGE for size == 1 (#2032280) +* Wed Oct 6 2021 Siddhesh Poyarekar - 2.28-165 +- Split extra gconv modules into a separate package (#1971664). * Mon Aug 9 2021 Siddhesh Poyarekar - 2.28-164 - librt: fix NULL pointer dereference (#1966472).