diff --git a/SOURCES/glibc-RHEL-22226.patch b/SOURCES/glibc-RHEL-22226.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3d09f70e4719005634fc69493cbfd909dd1423e3
--- /dev/null
+++ b/SOURCES/glibc-RHEL-22226.patch
@@ -0,0 +1,121 @@
+commit 5361ad3910c257bc327567be76fde532ed238e42
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Apr 19 14:38:17 2024 +0200
+
+    login: Use unsigned 32-bit types for seconds-since-epoch
+    
+    These fields store timestamps when the system was running.  No Linux
+    systems existed before 1970, so these values are unused.  Switching
+    to unsigned types allows continued use of the existing struct layouts
+    beyond the year 2038.
+    
+    The intent is to give distributions more time to switch to improved
+    interfaces that also avoid locking/data corruption issues.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/bits/utmp.h b/bits/utmp.h
+index f2d1c13d8cd205b2..27cb536800c46d67 100644
+--- a/bits/utmp.h
++++ b/bits/utmp.h
+@@ -36,7 +36,7 @@
+ struct lastlog
+   {
+ #if __WORDSIZE_TIME64_COMPAT32
+-    int32_t ll_time;
++    __uint32_t ll_time;
+ #else
+     __time_t ll_time;
+ #endif
+@@ -76,7 +76,7 @@ struct utmp
+   int32_t ut_session;		/* Session ID, used for windowing.  */
+   struct
+   {
+-    int32_t tv_sec;		/* Seconds.  */
++    __uint32_t tv_sec;		/* Seconds.  */
+     int32_t tv_usec;		/* Microseconds.  */
+   } ut_tv;			/* Time entry was made.  */
+ #else
+diff --git a/login/Makefile b/login/Makefile
+index f91190e3dcd1e6c6..84563230ef665f9c 100644
+--- a/login/Makefile
++++ b/login/Makefile
+@@ -44,9 +44,11 @@ subdir-dirs = programs
+ vpath %.c programs
+ 
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
+-  tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64
++  tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64 \
++  tst-utmp-unsigned tst-utmp-unsigned-64
+ 
+ CFLAGS-tst-utmp-size-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
++CFLAGS-tst-utmp-unsigned-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
+ 
+ # Empty compatibility library for old binaries.
+ extra-libs      := libutil
+diff --git a/login/tst-utmp-unsigned-64.c b/login/tst-utmp-unsigned-64.c
+new file mode 100644
+index 0000000000000000..940e7654f8dc5fd6
+--- /dev/null
++++ b/login/tst-utmp-unsigned-64.c
+@@ -0,0 +1 @@
++#include "tst-utmp-unsigned.c"
+diff --git a/login/tst-utmp-unsigned.c b/login/tst-utmp-unsigned.c
+new file mode 100644
+index 0000000000000000..27ad03a7d608e83d
+--- /dev/null
++++ b/login/tst-utmp-unsigned.c
+@@ -0,0 +1,40 @@
++/* Check that struct utmp, struct utmpx, struct lastlog use unsigned epoch.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <utmp.h>
++#include <utmpx.h>
++#include <utmp-size.h>
++
++/* Undefined.  Used to check that the conditions below are optimized away.  */
++void link_failure_utmp (void);
++void link_failure_utmpx (void);
++void link_failure_lastlog (void);
++
++static int
++do_test (void)
++{
++  if ((struct utmp) { .ut_tv = { 0x80000000U, }, }.ut_tv.tv_sec <= 0)
++    link_failure_utmp ();
++  if ((struct utmpx) { .ut_tv = { 0x80000000U, }, }.ut_tv.tv_sec <= 0)
++    link_failure_utmpx ();
++  if ((struct lastlog) { .ll_time = 0x80000000U, }.ll_time <= 0)
++    link_failure_lastlog ();
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h
+index 34b4afbc6ac25968..ed0df9bd8141d4e6 100644
+--- a/sysdeps/gnu/bits/utmpx.h
++++ b/sysdeps/gnu/bits/utmpx.h
+@@ -74,7 +74,7 @@ struct utmpx
+   __int32_t ut_session;		/* Session ID, used for windowing.  */
+   struct
+   {
+-    __int32_t tv_sec;		/* Seconds.  */
++    __uint32_t tv_sec;		/* Seconds.  */
+     __int32_t tv_usec;		/* Microseconds.  */
+   } ut_tv;			/* Time entry was made.  */
+ #else
diff --git a/SOURCES/glibc-upstream-2.39-22.patch b/SOURCES/glibc-upstream-2.39-22.patch
new file mode 100644
index 0000000000000000000000000000000000000000..fb7281f84a0801f71d033e5a847ed1a74f639171
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-22.patch
@@ -0,0 +1,32 @@
+commit 31c7d69af59da0da80caa74b2ec6ae149013384d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Feb 16 07:40:37 2024 +0100
+
+    i386: Use generic memrchr in libc (bug 31316)
+    
+    Before this change, we incorrectly used the SSE2 variant in the
+    implementation, without checking that the system actually supports
+    SSE2.
+    
+    Tested-by: Sam James <sam@gentoo.org>
+    (cherry picked from commit 0d9166c2245cad4ac520b337dee40c9a583872b6)
+
+diff --git a/sysdeps/i386/i686/multiarch/memrchr-c.c b/sysdeps/i386/i686/multiarch/memrchr-c.c
+index ef7bbbe792afc78e..20bfdf3af35b66e4 100644
+--- a/sysdeps/i386/i686/multiarch/memrchr-c.c
++++ b/sysdeps/i386/i686/multiarch/memrchr-c.c
+@@ -5,3 +5,4 @@ extern void *__memrchr_ia32 (const void *, int, size_t);
+ #endif
+ 
+ #include "string/memrchr.c"
++strong_alias (__memrchr_ia32, __GI___memrchr)
+diff --git a/sysdeps/i386/i686/multiarch/memrchr-sse2.S b/sysdeps/i386/i686/multiarch/memrchr-sse2.S
+index d9dae04171bfedff..e123f87435b3c6a6 100644
+--- a/sysdeps/i386/i686/multiarch/memrchr-sse2.S
++++ b/sysdeps/i386/i686/multiarch/memrchr-sse2.S
+@@ -720,5 +720,4 @@ L(ret_null):
+ 	ret
+ 
+ END (__memrchr_sse2)
+-strong_alias (__memrchr_sse2, __GI___memrchr)
+ #endif
diff --git a/SOURCES/glibc-upstream-2.39-23.patch b/SOURCES/glibc-upstream-2.39-23.patch
new file mode 100644
index 0000000000000000000000000000000000000000..11773cf6970d2400574eff94554b00390a3f31a4
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-23.patch
@@ -0,0 +1,669 @@
+commit b0e0a07018098c2c5927796be5681a298c312626
+Author: Joe Ramsay <Joe.Ramsay@arm.com>
+Date:   Tue Feb 20 16:44:13 2024 +0000
+
+    aarch64/fpu: Sync libmvec routines from 2.39 and before with AOR
+    
+    This includes a fix for big-endian in AdvSIMD log, some cosmetic
+    changes, and numerous small optimisations mainly around inlining and
+    using indexed variants of MLA intrinsics.
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    
+    (cherry picked from commit e302e1021391d13a9611ba3a910df128830bd19e)
+
+diff --git a/sysdeps/aarch64/fpu/acos_advsimd.c b/sysdeps/aarch64/fpu/acos_advsimd.c
+index a8eabb5e7155360f..0a86c9823a279766 100644
+--- a/sysdeps/aarch64/fpu/acos_advsimd.c
++++ b/sysdeps/aarch64/fpu/acos_advsimd.c
+@@ -40,8 +40,8 @@ static const struct data
+ };
+ 
+ #define AllMask v_u64 (0xffffffffffffffff)
+-#define Oneu (0x3ff0000000000000)
+-#define Small (0x3e50000000000000) /* 2^-53.  */
++#define Oneu 0x3ff0000000000000
++#define Small 0x3e50000000000000 /* 2^-53.  */
+ 
+ #if WANT_SIMD_EXCEPT
+ static float64x2_t VPCS_ATTR NOINLINE
+diff --git a/sysdeps/aarch64/fpu/asin_advsimd.c b/sysdeps/aarch64/fpu/asin_advsimd.c
+index 141646e954aa8ba1..2de6eff40782bc79 100644
+--- a/sysdeps/aarch64/fpu/asin_advsimd.c
++++ b/sysdeps/aarch64/fpu/asin_advsimd.c
+@@ -39,8 +39,8 @@ static const struct data
+ };
+ 
+ #define AllMask v_u64 (0xffffffffffffffff)
+-#define One (0x3ff0000000000000)
+-#define Small (0x3e50000000000000) /* 2^-12.  */
++#define One 0x3ff0000000000000
++#define Small 0x3e50000000000000 /* 2^-12.  */
+ 
+ #if WANT_SIMD_EXCEPT
+ static float64x2_t VPCS_ATTR NOINLINE
+diff --git a/sysdeps/aarch64/fpu/atan2_sve.c b/sysdeps/aarch64/fpu/atan2_sve.c
+index 09a4c559b8afbe95..04fa71fa37c3de29 100644
+--- a/sysdeps/aarch64/fpu/atan2_sve.c
++++ b/sysdeps/aarch64/fpu/atan2_sve.c
+@@ -37,9 +37,6 @@ static const struct data
+   .pi_over_2 = 0x1.921fb54442d18p+0,
+ };
+ 
+-/* Useful constants.  */
+-#define SignMask sv_u64 (0x8000000000000000)
+-
+ /* Special cases i.e. 0, infinity, nan (fall back to scalar calls).  */
+ static svfloat64_t NOINLINE
+ special_case (svfloat64_t y, svfloat64_t x, svfloat64_t ret,
+@@ -72,14 +69,15 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg)
+   svbool_t cmp_y = zeroinfnan (iy, pg);
+   svbool_t cmp_xy = svorr_z (pg, cmp_x, cmp_y);
+ 
+-  svuint64_t sign_x = svand_x (pg, ix, SignMask);
+-  svuint64_t sign_y = svand_x (pg, iy, SignMask);
+-  svuint64_t sign_xy = sveor_x (pg, sign_x, sign_y);
+-
+   svfloat64_t ax = svabs_x (pg, x);
+   svfloat64_t ay = svabs_x (pg, y);
++  svuint64_t iax = svreinterpret_u64 (ax);
++  svuint64_t iay = svreinterpret_u64 (ay);
++
++  svuint64_t sign_x = sveor_x (pg, ix, iax);
++  svuint64_t sign_y = sveor_x (pg, iy, iay);
++  svuint64_t sign_xy = sveor_x (pg, sign_x, sign_y);
+ 
+-  svbool_t pred_xlt0 = svcmplt (pg, x, 0.0);
+   svbool_t pred_aygtax = svcmpgt (pg, ay, ax);
+ 
+   /* Set up z for call to atan.  */
+@@ -88,8 +86,9 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg)
+   svfloat64_t z = svdiv_x (pg, n, d);
+ 
+   /* Work out the correct shift.  */
+-  svfloat64_t shift = svsel (pred_xlt0, sv_f64 (-2.0), sv_f64 (0.0));
+-  shift = svsel (pred_aygtax, svadd_x (pg, shift, 1.0), shift);
++  svfloat64_t shift = svreinterpret_f64 (svlsr_x (pg, sign_x, 1));
++  shift = svsel (pred_aygtax, sv_f64 (1.0), shift);
++  shift = svreinterpret_f64 (svorr_x (pg, sign_x, svreinterpret_u64 (shift)));
+   shift = svmul_x (pg, shift, data_ptr->pi_over_2);
+ 
+   /* Use split Estrin scheme for P(z^2) with deg(P)=19.  */
+@@ -109,10 +108,10 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg)
+   ret = svadd_m (pg, ret, shift);
+ 
+   /* Account for the sign of x and y.  */
+-  ret = svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy));
+-
+   if (__glibc_unlikely (svptest_any (pg, cmp_xy)))
+-    return special_case (y, x, ret, cmp_xy);
+-
+-  return ret;
++    return special_case (
++	y, x,
++	svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy)),
++	cmp_xy);
++  return svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy));
+ }
+diff --git a/sysdeps/aarch64/fpu/atan2f_sve.c b/sysdeps/aarch64/fpu/atan2f_sve.c
+index b92f83cdea4fb2da..9ea197147ccca0ac 100644
+--- a/sysdeps/aarch64/fpu/atan2f_sve.c
++++ b/sysdeps/aarch64/fpu/atan2f_sve.c
+@@ -32,10 +32,8 @@ static const struct data
+   .pi_over_2 = 0x1.921fb6p+0f,
+ };
+ 
+-#define SignMask sv_u32 (0x80000000)
+-
+ /* Special cases i.e. 0, infinity, nan (fall back to scalar calls).  */
+-static inline svfloat32_t
++static svfloat32_t NOINLINE
+ special_case (svfloat32_t y, svfloat32_t x, svfloat32_t ret,
+ 	      const svbool_t cmp)
+ {
+@@ -67,14 +65,15 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg)
+   svbool_t cmp_y = zeroinfnan (iy, pg);
+   svbool_t cmp_xy = svorr_z (pg, cmp_x, cmp_y);
+ 
+-  svuint32_t sign_x = svand_x (pg, ix, SignMask);
+-  svuint32_t sign_y = svand_x (pg, iy, SignMask);
+-  svuint32_t sign_xy = sveor_x (pg, sign_x, sign_y);
+-
+   svfloat32_t ax = svabs_x (pg, x);
+   svfloat32_t ay = svabs_x (pg, y);
++  svuint32_t iax = svreinterpret_u32 (ax);
++  svuint32_t iay = svreinterpret_u32 (ay);
++
++  svuint32_t sign_x = sveor_x (pg, ix, iax);
++  svuint32_t sign_y = sveor_x (pg, iy, iay);
++  svuint32_t sign_xy = sveor_x (pg, sign_x, sign_y);
+ 
+-  svbool_t pred_xlt0 = svcmplt (pg, x, 0.0);
+   svbool_t pred_aygtax = svcmpgt (pg, ay, ax);
+ 
+   /* Set up z for call to atan.  */
+@@ -83,11 +82,12 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg)
+   svfloat32_t z = svdiv_x (pg, n, d);
+ 
+   /* Work out the correct shift.  */
+-  svfloat32_t shift = svsel (pred_xlt0, sv_f32 (-2.0), sv_f32 (0.0));
+-  shift = svsel (pred_aygtax, svadd_x (pg, shift, 1.0), shift);
++  svfloat32_t shift = svreinterpret_f32 (svlsr_x (pg, sign_x, 1));
++  shift = svsel (pred_aygtax, sv_f32 (1.0), shift);
++  shift = svreinterpret_f32 (svorr_x (pg, sign_x, svreinterpret_u32 (shift)));
+   shift = svmul_x (pg, shift, sv_f32 (data_ptr->pi_over_2));
+ 
+-  /* Use split Estrin scheme for P(z^2) with deg(P)=7.  */
++  /* Use pure Estrin scheme for P(z^2) with deg(P)=7.  */
+   svfloat32_t z2 = svmul_x (pg, z, z);
+   svfloat32_t z4 = svmul_x (pg, z2, z2);
+   svfloat32_t z8 = svmul_x (pg, z4, z4);
+@@ -101,10 +101,12 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg)
+   ret = svadd_m (pg, ret, shift);
+ 
+   /* Account for the sign of x and y.  */
+-  ret = svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy));
+ 
+   if (__glibc_unlikely (svptest_any (pg, cmp_xy)))
+-    return special_case (y, x, ret, cmp_xy);
++    return special_case (
++	y, x,
++	svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy)),
++	cmp_xy);
+ 
+-  return ret;
++  return svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy));
+ }
+diff --git a/sysdeps/aarch64/fpu/cos_advsimd.c b/sysdeps/aarch64/fpu/cos_advsimd.c
+index 2897e8b909bbcb66..3924c9ce44c30d4d 100644
+--- a/sysdeps/aarch64/fpu/cos_advsimd.c
++++ b/sysdeps/aarch64/fpu/cos_advsimd.c
+@@ -63,8 +63,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (cos) (float64x2_t x)
+        special-case handler later.  */
+     r = vbslq_f64 (cmp, v_f64 (1.0), r);
+ #else
+-  cmp = vcageq_f64 (d->range_val, x);
+-  cmp = vceqzq_u64 (cmp); /* cmp = ~cmp.  */
++  cmp = vcageq_f64 (x, d->range_val);
+   r = x;
+ #endif
+ 
+diff --git a/sysdeps/aarch64/fpu/cosf_advsimd.c b/sysdeps/aarch64/fpu/cosf_advsimd.c
+index 60abc8dfcfff9ed4..d0c285b03a8bfe22 100644
+--- a/sysdeps/aarch64/fpu/cosf_advsimd.c
++++ b/sysdeps/aarch64/fpu/cosf_advsimd.c
+@@ -64,8 +64,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (cos) (float32x4_t x)
+        special-case handler later.  */
+     r = vbslq_f32 (cmp, v_f32 (1.0f), r);
+ #else
+-  cmp = vcageq_f32 (d->range_val, x);
+-  cmp = vceqzq_u32 (cmp); /* cmp = ~cmp.  */
++  cmp = vcageq_f32 (x, d->range_val);
+   r = x;
+ #endif
+ 
+diff --git a/sysdeps/aarch64/fpu/exp10_advsimd.c b/sysdeps/aarch64/fpu/exp10_advsimd.c
+index fe7149b19176da21..eeb31ca839c1f671 100644
+--- a/sysdeps/aarch64/fpu/exp10_advsimd.c
++++ b/sysdeps/aarch64/fpu/exp10_advsimd.c
+@@ -57,7 +57,7 @@ const static struct data
+ # define BigBound v_u64 (0x4070000000000000)  /* asuint64 (0x1p8).  */
+ # define Thres v_u64 (0x2070000000000000)     /* BigBound - TinyBound.  */
+ 
+-static inline float64x2_t VPCS_ATTR
++static float64x2_t VPCS_ATTR NOINLINE
+ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
+ {
+   /* If fenv exceptions are to be triggered correctly, fall back to the scalar
+@@ -72,7 +72,7 @@ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
+ # define SpecialBias1 v_u64 (0x7000000000000000)  /* 0x1p769.  */
+ # define SpecialBias2 v_u64 (0x3010000000000000)  /* 0x1p-254.  */
+ 
+-static float64x2_t VPCS_ATTR NOINLINE
++static inline float64x2_t VPCS_ATTR
+ special_case (float64x2_t s, float64x2_t y, float64x2_t n,
+ 	      const struct data *d)
+ {
+diff --git a/sysdeps/aarch64/fpu/exp10f_advsimd.c b/sysdeps/aarch64/fpu/exp10f_advsimd.c
+index 7ee0c909487c32b7..ab117b69da23e5f3 100644
+--- a/sysdeps/aarch64/fpu/exp10f_advsimd.c
++++ b/sysdeps/aarch64/fpu/exp10f_advsimd.c
+@@ -25,7 +25,8 @@
+ static const struct data
+ {
+   float32x4_t poly[5];
+-  float32x4_t shift, log10_2, log2_10_hi, log2_10_lo;
++  float32x4_t log10_2_and_inv, shift;
++
+ #if !WANT_SIMD_EXCEPT
+   float32x4_t scale_thresh;
+ #endif
+@@ -38,9 +39,9 @@ static const struct data
+   .poly = { V4 (0x1.26bb16p+1f), V4 (0x1.5350d2p+1f), V4 (0x1.04744ap+1f),
+ 	    V4 (0x1.2d8176p+0f), V4 (0x1.12b41ap-1f) },
+   .shift = V4 (0x1.8p23f),
+-  .log10_2 = V4 (0x1.a934fp+1),
+-  .log2_10_hi = V4 (0x1.344136p-2),
+-  .log2_10_lo = V4 (-0x1.ec10cp-27),
++
++  /* Stores constants 1/log10(2), log10(2)_high, log10(2)_low, 0.  */
++  .log10_2_and_inv = { 0x1.a934fp+1, 0x1.344136p-2, -0x1.ec10cp-27, 0 },
+ #if !WANT_SIMD_EXCEPT
+   .scale_thresh = V4 (ScaleBound)
+ #endif
+@@ -98,24 +99,22 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (exp10) (float32x4_t x)
+ #if WANT_SIMD_EXCEPT
+   /* asuint(x) - TinyBound >= BigBound - TinyBound.  */
+   uint32x4_t cmp = vcgeq_u32 (
+-      vsubq_u32 (vandq_u32 (vreinterpretq_u32_f32 (x), v_u32 (0x7fffffff)),
+-		 TinyBound),
+-      Thres);
++      vsubq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (x)), TinyBound), Thres);
+   float32x4_t xm = x;
+   /* If any lanes are special, mask them with 1 and retain a copy of x to allow
+      special case handler to fix special lanes later. This is only necessary if
+      fenv exceptions are to be triggered correctly.  */
+   if (__glibc_unlikely (v_any_u32 (cmp)))
+-    x = vbslq_f32 (cmp, v_f32 (1), x);
++    x = v_zerofy_f32 (x, cmp);
+ #endif
+ 
+   /* exp10(x) = 2^n * 10^r = 2^n * (1 + poly (r)),
+      with poly(r) in [1/sqrt(2), sqrt(2)] and
+      x = r + n * log10 (2), with r in [-log10(2)/2, log10(2)/2].  */
+-  float32x4_t z = vfmaq_f32 (d->shift, x, d->log10_2);
++  float32x4_t z = vfmaq_laneq_f32 (d->shift, x, d->log10_2_and_inv, 0);
+   float32x4_t n = vsubq_f32 (z, d->shift);
+-  float32x4_t r = vfmsq_f32 (x, n, d->log2_10_hi);
+-  r = vfmsq_f32 (r, n, d->log2_10_lo);
++  float32x4_t r = vfmsq_laneq_f32 (x, n, d->log10_2_and_inv, 1);
++  r = vfmsq_laneq_f32 (r, n, d->log10_2_and_inv, 2);
+   uint32x4_t e = vshlq_n_u32 (vreinterpretq_u32_f32 (z), 23);
+ 
+   float32x4_t scale = vreinterpretq_f32_u32 (vaddq_u32 (e, ExponentBias));
+diff --git a/sysdeps/aarch64/fpu/exp2_advsimd.c b/sysdeps/aarch64/fpu/exp2_advsimd.c
+index 391a93180c93427d..ae1e63d5030633d5 100644
+--- a/sysdeps/aarch64/fpu/exp2_advsimd.c
++++ b/sysdeps/aarch64/fpu/exp2_advsimd.c
+@@ -24,6 +24,7 @@
+ #define IndexMask (N - 1)
+ #define BigBound 1022.0
+ #define UOFlowBound 1280.0
++#define TinyBound 0x2000000000000000 /* asuint64(0x1p-511).  */
+ 
+ static const struct data
+ {
+@@ -48,14 +49,13 @@ lookup_sbits (uint64x2_t i)
+ 
+ #if WANT_SIMD_EXCEPT
+ 
+-# define TinyBound 0x2000000000000000 /* asuint64(0x1p-511).  */
+ # define Thres 0x2080000000000000     /* asuint64(512.0) - TinyBound.  */
+ 
+ /* Call scalar exp2 as a fallback.  */
+ static float64x2_t VPCS_ATTR NOINLINE
+-special_case (float64x2_t x)
++special_case (float64x2_t x, float64x2_t y, uint64x2_t is_special)
+ {
+-  return v_call_f64 (exp2, x, x, v_u64 (0xffffffffffffffff));
++  return v_call_f64 (exp2, x, y, is_special);
+ }
+ 
+ #else
+@@ -65,7 +65,7 @@ special_case (float64x2_t x)
+ # define SpecialBias1 0x7000000000000000 /* 0x1p769.  */
+ # define SpecialBias2 0x3010000000000000 /* 0x1p-254.  */
+ 
+-static float64x2_t VPCS_ATTR
++static inline float64x2_t VPCS_ATTR
+ special_case (float64x2_t s, float64x2_t y, float64x2_t n,
+ 	      const struct data *d)
+ {
+@@ -94,10 +94,10 @@ float64x2_t V_NAME_D1 (exp2) (float64x2_t x)
+ #if WANT_SIMD_EXCEPT
+   uint64x2_t ia = vreinterpretq_u64_f64 (vabsq_f64 (x));
+   cmp = vcgeq_u64 (vsubq_u64 (ia, v_u64 (TinyBound)), v_u64 (Thres));
+-  /* If any special case (inf, nan, small and large x) is detected,
+-     fall back to scalar for all lanes.  */
+-  if (__glibc_unlikely (v_any_u64 (cmp)))
+-    return special_case (x);
++  /* Mask special lanes and retain a copy of x for passing to special-case
++     handler.  */
++  float64x2_t xc = x;
++  x = v_zerofy_f64 (x, cmp);
+ #else
+   cmp = vcagtq_f64 (x, d->scale_big_bound);
+ #endif
+@@ -120,9 +120,11 @@ float64x2_t V_NAME_D1 (exp2) (float64x2_t x)
+   float64x2_t y = v_pairwise_poly_3_f64 (r, r2, d->poly);
+   y = vmulq_f64 (r, y);
+ 
+-#if !WANT_SIMD_EXCEPT
+   if (__glibc_unlikely (v_any_u64 (cmp)))
++#if !WANT_SIMD_EXCEPT
+     return special_case (s, y, n, d);
++#else
++    return special_case (xc, vfmaq_f64 (s, s, y), cmp);
+ #endif
+   return vfmaq_f64 (s, s, y);
+ }
+diff --git a/sysdeps/aarch64/fpu/exp2f_sve.c b/sysdeps/aarch64/fpu/exp2f_sve.c
+index 9a5a523a10280d1d..8a686e3e054cb7f5 100644
+--- a/sysdeps/aarch64/fpu/exp2f_sve.c
++++ b/sysdeps/aarch64/fpu/exp2f_sve.c
+@@ -20,6 +20,8 @@
+ #include "sv_math.h"
+ #include "poly_sve_f32.h"
+ 
++#define Thres 0x1.5d5e2ap+6f
++
+ static const struct data
+ {
+   float poly[5];
+@@ -33,7 +35,7 @@ static const struct data
+   .shift = 0x1.903f8p17f,
+   /* Roughly 87.3. For x < -Thres, the result is subnormal and not handled
+      correctly by FEXPA.  */
+-  .thres = 0x1.5d5e2ap+6f,
++  .thres = Thres,
+ };
+ 
+ static svfloat32_t NOINLINE
+diff --git a/sysdeps/aarch64/fpu/exp_advsimd.c b/sysdeps/aarch64/fpu/exp_advsimd.c
+index fd215f1d2c5e9eea..5e3a9a0d44a43656 100644
+--- a/sysdeps/aarch64/fpu/exp_advsimd.c
++++ b/sysdeps/aarch64/fpu/exp_advsimd.c
+@@ -54,7 +54,7 @@ const static volatile struct
+ # define BigBound v_u64 (0x4080000000000000) /* asuint64 (0x1p9).  */
+ # define SpecialBound v_u64 (0x2080000000000000) /* BigBound - TinyBound.  */
+ 
+-static inline float64x2_t VPCS_ATTR
++static float64x2_t VPCS_ATTR NOINLINE
+ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
+ {
+   /* If fenv exceptions are to be triggered correctly, fall back to the scalar
+@@ -69,7 +69,7 @@ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
+ # define SpecialBias1 v_u64 (0x7000000000000000) /* 0x1p769.  */
+ # define SpecialBias2 v_u64 (0x3010000000000000) /* 0x1p-254.  */
+ 
+-static float64x2_t VPCS_ATTR NOINLINE
++static inline float64x2_t VPCS_ATTR
+ special_case (float64x2_t s, float64x2_t y, float64x2_t n)
+ {
+   /* 2^(n/N) may overflow, break it up into s1*s2.  */
+diff --git a/sysdeps/aarch64/fpu/expm1_advsimd.c b/sysdeps/aarch64/fpu/expm1_advsimd.c
+index 0b85bd06f3c10068..3628398674468131 100644
+--- a/sysdeps/aarch64/fpu/expm1_advsimd.c
++++ b/sysdeps/aarch64/fpu/expm1_advsimd.c
+@@ -23,7 +23,7 @@
+ static const struct data
+ {
+   float64x2_t poly[11];
+-  float64x2_t invln2, ln2_lo, ln2_hi, shift;
++  float64x2_t invln2, ln2, shift;
+   int64x2_t exponent_bias;
+ #if WANT_SIMD_EXCEPT
+   uint64x2_t thresh, tiny_bound;
+@@ -38,8 +38,7 @@ static const struct data
+ 	    V2 (0x1.71ddf82db5bb4p-19), V2 (0x1.27e517fc0d54bp-22),
+ 	    V2 (0x1.af5eedae67435p-26), V2 (0x1.1f143d060a28ap-29) },
+   .invln2 = V2 (0x1.71547652b82fep0),
+-  .ln2_hi = V2 (0x1.62e42fefa39efp-1),
+-  .ln2_lo = V2 (0x1.abc9e3b39803fp-56),
++  .ln2 = { 0x1.62e42fefa39efp-1, 0x1.abc9e3b39803fp-56 },
+   .shift = V2 (0x1.8p52),
+   .exponent_bias = V2 (0x3ff0000000000000),
+ #if WANT_SIMD_EXCEPT
+@@ -83,7 +82,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (expm1) (float64x2_t x)
+     x = v_zerofy_f64 (x, special);
+ #else
+   /* Large input, NaNs and Infs.  */
+-  uint64x2_t special = vceqzq_u64 (vcaltq_f64 (x, d->oflow_bound));
++  uint64x2_t special = vcageq_f64 (x, d->oflow_bound);
+ #endif
+ 
+   /* Reduce argument to smaller range:
+@@ -93,8 +92,8 @@ float64x2_t VPCS_ATTR V_NAME_D1 (expm1) (float64x2_t x)
+      where 2^i is exact because i is an integer.  */
+   float64x2_t n = vsubq_f64 (vfmaq_f64 (d->shift, d->invln2, x), d->shift);
+   int64x2_t i = vcvtq_s64_f64 (n);
+-  float64x2_t f = vfmsq_f64 (x, n, d->ln2_hi);
+-  f = vfmsq_f64 (f, n, d->ln2_lo);
++  float64x2_t f = vfmsq_laneq_f64 (x, n, d->ln2, 0);
++  f = vfmsq_laneq_f64 (f, n, d->ln2, 1);
+ 
+   /* Approximate expm1(f) using polynomial.
+      Taylor expansion for expm1(x) has the form:
+diff --git a/sysdeps/aarch64/fpu/expm1f_advsimd.c b/sysdeps/aarch64/fpu/expm1f_advsimd.c
+index 8d4c9a21936d31dd..93db200f618379be 100644
+--- a/sysdeps/aarch64/fpu/expm1f_advsimd.c
++++ b/sysdeps/aarch64/fpu/expm1f_advsimd.c
+@@ -23,7 +23,8 @@
+ static const struct data
+ {
+   float32x4_t poly[5];
+-  float32x4_t invln2, ln2_lo, ln2_hi, shift;
++  float32x4_t invln2_and_ln2;
++  float32x4_t shift;
+   int32x4_t exponent_bias;
+ #if WANT_SIMD_EXCEPT
+   uint32x4_t thresh;
+@@ -34,9 +35,8 @@ static const struct data
+   /* Generated using fpminimax with degree=5 in [-log(2)/2, log(2)/2].  */
+   .poly = { V4 (0x1.fffffep-2), V4 (0x1.5554aep-3), V4 (0x1.555736p-5),
+ 	    V4 (0x1.12287cp-7), V4 (0x1.6b55a2p-10) },
+-  .invln2 = V4 (0x1.715476p+0f),
+-  .ln2_hi = V4 (0x1.62e4p-1f),
+-  .ln2_lo = V4 (0x1.7f7d1cp-20f),
++  /* Stores constants: invln2, ln2_hi, ln2_lo, 0.  */
++  .invln2_and_ln2 = { 0x1.715476p+0f, 0x1.62e4p-1f, 0x1.7f7d1cp-20f, 0 },
+   .shift = V4 (0x1.8p23f),
+   .exponent_bias = V4 (0x3f800000),
+ #if !WANT_SIMD_EXCEPT
+@@ -80,7 +80,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (expm1) (float32x4_t x)
+     x = v_zerofy_f32 (x, special);
+ #else
+   /* Handles very large values (+ve and -ve), +/-NaN, +/-Inf.  */
+-  uint32x4_t special = vceqzq_u32 (vcaltq_f32 (x, d->oflow_bound));
++  uint32x4_t special = vcagtq_f32 (x, d->oflow_bound);
+ #endif
+ 
+   /* Reduce argument to smaller range:
+@@ -88,10 +88,11 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (expm1) (float32x4_t x)
+      and f = x - i * ln2, then f is in [-ln2/2, ln2/2].
+      exp(x) - 1 = 2^i * (expm1(f) + 1) - 1
+      where 2^i is exact because i is an integer.  */
+-  float32x4_t j = vsubq_f32 (vfmaq_f32 (d->shift, d->invln2, x), d->shift);
++  float32x4_t j = vsubq_f32 (
++      vfmaq_laneq_f32 (d->shift, x, d->invln2_and_ln2, 0), d->shift);
+   int32x4_t i = vcvtq_s32_f32 (j);
+-  float32x4_t f = vfmsq_f32 (x, j, d->ln2_hi);
+-  f = vfmsq_f32 (f, j, d->ln2_lo);
++  float32x4_t f = vfmsq_laneq_f32 (x, j, d->invln2_and_ln2, 1);
++  f = vfmsq_laneq_f32 (f, j, d->invln2_and_ln2, 2);
+ 
+   /* Approximate expm1(f) using polynomial.
+      Taylor expansion for expm1(x) has the form:
+diff --git a/sysdeps/aarch64/fpu/log_advsimd.c b/sysdeps/aarch64/fpu/log_advsimd.c
+index 067ae7961300c66b..21df61728ca87374 100644
+--- a/sysdeps/aarch64/fpu/log_advsimd.c
++++ b/sysdeps/aarch64/fpu/log_advsimd.c
+@@ -58,8 +58,13 @@ lookup (uint64x2_t i)
+   uint64_t i1 = (i[1] >> (52 - V_LOG_TABLE_BITS)) & IndexMask;
+   float64x2_t e0 = vld1q_f64 (&__v_log_data.table[i0].invc);
+   float64x2_t e1 = vld1q_f64 (&__v_log_data.table[i1].invc);
++#if __BYTE_ORDER == __LITTLE_ENDIAN
+   e.invc = vuzp1q_f64 (e0, e1);
+   e.logc = vuzp2q_f64 (e0, e1);
++#else
++  e.invc = vuzp1q_f64 (e1, e0);
++  e.logc = vuzp2q_f64 (e1, e0);
++#endif
+   return e;
+ }
+ 
+diff --git a/sysdeps/aarch64/fpu/sin_advsimd.c b/sysdeps/aarch64/fpu/sin_advsimd.c
+index efce183e86e319f1..a0d9d3b81965db76 100644
+--- a/sysdeps/aarch64/fpu/sin_advsimd.c
++++ b/sysdeps/aarch64/fpu/sin_advsimd.c
+@@ -75,8 +75,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (sin) (float64x2_t x)
+   r = vbslq_f64 (cmp, vreinterpretq_f64_u64 (cmp), x);
+ #else
+   r = x;
+-  cmp = vcageq_f64 (d->range_val, x);
+-  cmp = vceqzq_u64 (cmp); /* cmp = ~cmp.  */
++  cmp = vcageq_f64 (x, d->range_val);
+ #endif
+ 
+   /* n = rint(|x|/pi).  */
+diff --git a/sysdeps/aarch64/fpu/sinf_advsimd.c b/sysdeps/aarch64/fpu/sinf_advsimd.c
+index 60cf3f2ca102619c..375dfc3331fa6a9c 100644
+--- a/sysdeps/aarch64/fpu/sinf_advsimd.c
++++ b/sysdeps/aarch64/fpu/sinf_advsimd.c
+@@ -67,8 +67,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (sin) (float32x4_t x)
+   r = vbslq_f32 (cmp, vreinterpretq_f32_u32 (cmp), x);
+ #else
+   r = x;
+-  cmp = vcageq_f32 (d->range_val, x);
+-  cmp = vceqzq_u32 (cmp); /* cmp = ~cmp.  */
++  cmp = vcageq_f32 (x, d->range_val);
+ #endif
+ 
+   /* n = rint(|x|/pi) */
+diff --git a/sysdeps/aarch64/fpu/tan_advsimd.c b/sysdeps/aarch64/fpu/tan_advsimd.c
+index d7e5ba7b1ab941e8..0459821ab25487a8 100644
+--- a/sysdeps/aarch64/fpu/tan_advsimd.c
++++ b/sysdeps/aarch64/fpu/tan_advsimd.c
+@@ -23,7 +23,7 @@
+ static const struct data
+ {
+   float64x2_t poly[9];
+-  float64x2_t half_pi_hi, half_pi_lo, two_over_pi, shift;
++  float64x2_t half_pi, two_over_pi, shift;
+ #if !WANT_SIMD_EXCEPT
+   float64x2_t range_val;
+ #endif
+@@ -34,8 +34,7 @@ static const struct data
+ 	    V2 (0x1.226e5e5ecdfa3p-7), V2 (0x1.d6c7ddbf87047p-9),
+ 	    V2 (0x1.7ea75d05b583ep-10), V2 (0x1.289f22964a03cp-11),
+ 	    V2 (0x1.4e4fd14147622p-12) },
+-  .half_pi_hi = V2 (0x1.921fb54442d18p0),
+-  .half_pi_lo = V2 (0x1.1a62633145c07p-54),
++  .half_pi = { 0x1.921fb54442d18p0, 0x1.1a62633145c07p-54 },
+   .two_over_pi = V2 (0x1.45f306dc9c883p-1),
+   .shift = V2 (0x1.8p52),
+ #if !WANT_SIMD_EXCEPT
+@@ -56,15 +55,15 @@ special_case (float64x2_t x)
+ 
+ /* Vector approximation for double-precision tan.
+    Maximum measured error is 3.48 ULP:
+-   __v_tan(0x1.4457047ef78d8p+20) got -0x1.f6ccd8ecf7dedp+37
+-				 want -0x1.f6ccd8ecf7deap+37.   */
++   _ZGVnN2v_tan(0x1.4457047ef78d8p+20) got -0x1.f6ccd8ecf7dedp+37
++				      want -0x1.f6ccd8ecf7deap+37.  */
+ float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x)
+ {
+   const struct data *dat = ptr_barrier (&data);
+-  /* Our argument reduction cannot calculate q with sufficient accuracy for very
+-     large inputs. Fall back to scalar routine for all lanes if any are too
+-     large, or Inf/NaN. If fenv exceptions are expected, also fall back for tiny
+-     input to avoid underflow.  */
++  /* Our argument reduction cannot calculate q with sufficient accuracy for
++     very large inputs. Fall back to scalar routine for all lanes if any are
++     too large, or Inf/NaN. If fenv exceptions are expected, also fall back for
++     tiny input to avoid underflow.  */
+ #if WANT_SIMD_EXCEPT
+   uint64x2_t iax = vreinterpretq_u64_f64 (vabsq_f64 (x));
+   /* iax - tiny_bound > range_val - tiny_bound.  */
+@@ -82,8 +81,8 @@ float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x)
+   /* Use q to reduce x to r in [-pi/4, pi/4], by:
+      r = x - q * pi/2, in extended precision.  */
+   float64x2_t r = x;
+-  r = vfmsq_f64 (r, q, dat->half_pi_hi);
+-  r = vfmsq_f64 (r, q, dat->half_pi_lo);
++  r = vfmsq_laneq_f64 (r, q, dat->half_pi, 0);
++  r = vfmsq_laneq_f64 (r, q, dat->half_pi, 1);
+   /* Further reduce r to [-pi/8, pi/8], to be reconstructed using double angle
+      formula.  */
+   r = vmulq_n_f64 (r, 0.5);
+@@ -106,14 +105,15 @@ float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x)
+      and reciprocity around pi/2:
+      tan(x) = 1 / (tan(pi/2 - x))
+      to assemble result using change-of-sign and conditional selection of
+-     numerator/denominator, dependent on odd/even-ness of q (hence quadrant). */
++     numerator/denominator, dependent on odd/even-ness of q (hence quadrant).
++   */
+   float64x2_t n = vfmaq_f64 (v_f64 (-1), p, p);
+   float64x2_t d = vaddq_f64 (p, p);
+ 
+   uint64x2_t no_recip = vtstq_u64 (vreinterpretq_u64_s64 (qi), v_u64 (1));
+ 
+ #if !WANT_SIMD_EXCEPT
+-  uint64x2_t special = vceqzq_u64 (vcaleq_f64 (x, dat->range_val));
++  uint64x2_t special = vcageq_f64 (x, dat->range_val);
+   if (__glibc_unlikely (v_any_u64 (special)))
+     return special_case (x);
+ #endif
+diff --git a/sysdeps/aarch64/fpu/tanf_advsimd.c b/sysdeps/aarch64/fpu/tanf_advsimd.c
+index 1f16103f8a7668f8..5a7489390a9692c6 100644
+--- a/sysdeps/aarch64/fpu/tanf_advsimd.c
++++ b/sysdeps/aarch64/fpu/tanf_advsimd.c
+@@ -23,7 +23,8 @@
+ static const struct data
+ {
+   float32x4_t poly[6];
+-  float32x4_t neg_half_pi_1, neg_half_pi_2, neg_half_pi_3, two_over_pi, shift;
++  float32x4_t pi_consts;
++  float32x4_t shift;
+ #if !WANT_SIMD_EXCEPT
+   float32x4_t range_val;
+ #endif
+@@ -31,10 +32,9 @@ static const struct data
+   /* Coefficients generated using FPMinimax.  */
+   .poly = { V4 (0x1.55555p-2f), V4 (0x1.11166p-3f), V4 (0x1.b88a78p-5f),
+ 	    V4 (0x1.7b5756p-6f), V4 (0x1.4ef4cep-8f), V4 (0x1.0e1e74p-7f) },
+-  .neg_half_pi_1 = V4 (-0x1.921fb6p+0f),
+-  .neg_half_pi_2 = V4 (0x1.777a5cp-25f),
+-  .neg_half_pi_3 = V4 (0x1.ee59dap-50f),
+-  .two_over_pi = V4 (0x1.45f306p-1f),
++  /* Stores constants: (-pi/2)_high, (-pi/2)_mid, (-pi/2)_low, and 2/pi.  */
++  .pi_consts
++  = { -0x1.921fb6p+0f, 0x1.777a5cp-25f, 0x1.ee59dap-50f, 0x1.45f306p-1f },
+   .shift = V4 (0x1.8p+23f),
+ #if !WANT_SIMD_EXCEPT
+   .range_val = V4 (0x1p15f),
+@@ -58,10 +58,11 @@ eval_poly (float32x4_t z, const struct data *d)
+ {
+   float32x4_t z2 = vmulq_f32 (z, z);
+ #if WANT_SIMD_EXCEPT
+-  /* Tiny z (<= 0x1p-31) will underflow when calculating z^4. If fp exceptions
+-     are to be triggered correctly, sidestep this by fixing such lanes to 0.  */
++  /* Tiny z (<= 0x1p-31) will underflow when calculating z^4.
++     If fp exceptions are to be triggered correctly,
++     sidestep this by fixing such lanes to 0.  */
+   uint32x4_t will_uflow
+-    = vcleq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (z)), TinyBound);
++      = vcleq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (z)), TinyBound);
+   if (__glibc_unlikely (v_any_u32 (will_uflow)))
+     z2 = vbslq_f32 (will_uflow, v_f32 (0), z2);
+ #endif
+@@ -94,16 +95,16 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (tan) (float32x4_t x)
+ #endif
+ 
+   /* n = rint(x/(pi/2)).  */
+-  float32x4_t q = vfmaq_f32 (d->shift, d->two_over_pi, x);
++  float32x4_t q = vfmaq_laneq_f32 (d->shift, x, d->pi_consts, 3);
+   float32x4_t n = vsubq_f32 (q, d->shift);
+   /* Determine if x lives in an interval, where |tan(x)| grows to infinity.  */
+   uint32x4_t pred_alt = vtstq_u32 (vreinterpretq_u32_f32 (q), v_u32 (1));
+ 
+   /* r = x - n * (pi/2)  (range reduction into -pi./4 .. pi/4).  */
+   float32x4_t r;
+-  r = vfmaq_f32 (x, d->neg_half_pi_1, n);
+-  r = vfmaq_f32 (r, d->neg_half_pi_2, n);
+-  r = vfmaq_f32 (r, d->neg_half_pi_3, n);
++  r = vfmaq_laneq_f32 (x, n, d->pi_consts, 0);
++  r = vfmaq_laneq_f32 (r, n, d->pi_consts, 1);
++  r = vfmaq_laneq_f32 (r, n, d->pi_consts, 2);
+ 
+   /* If x lives in an interval, where |tan(x)|
+      - is finite, then use a polynomial approximation of the form
diff --git a/SOURCES/glibc-upstream-2.39-24.patch b/SOURCES/glibc-upstream-2.39-24.patch
new file mode 100644
index 0000000000000000000000000000000000000000..61d3f48bd41938386cf06d619b61cec226a3ef3a
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-24.patch
@@ -0,0 +1,54 @@
+commit 395a89f61e19fa916ae4cc93fc10d81a28ce3039
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Mar 13 14:34:14 2024 +0000
+
+    aarch64: fix check for SVE support in assembler
+    
+    Due to GCC bug 110901 -mcpu can override -march setting when compiling
+    asm code and thus a compiler targetting a specific cpu can fail the
+    configure check even when binutils gas supports SVE.
+    
+    The workaround is that explicit .arch directive overrides both -mcpu
+    and -march, and since that's what the actual SVE memcpy uses the
+    configure check should use that too even if the GCC issue is fixed
+    independently.
+    
+    Reviewed-by: Florian Weimer <fweimer@redhat.com>
+    (cherry picked from commit 73c26018ed0ecd9c807bb363cc2c2ab4aca66a82)
+
+diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
+old mode 100644
+new mode 100755
+index ca57edce472e4507..9606137e8ddae545
+--- a/sysdeps/aarch64/configure
++++ b/sysdeps/aarch64/configure
+@@ -325,9 +325,10 @@ then :
+   printf %s "(cached) " >&6
+ else $as_nop
+   cat > conftest.s <<\EOF
+-        ptrue p0.b
++	.arch armv8.2-a+sve
++	ptrue p0.b
+ EOF
+-if { ac_try='${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&5'
++if { ac_try='${CC-cc} -c conftest.s 1>&5'
+   { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
+index 27874eceb44911e4..56d12d661d726892 100644
+--- a/sysdeps/aarch64/configure.ac
++++ b/sysdeps/aarch64/configure.ac
+@@ -90,9 +90,10 @@ 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_aarch64_sve_asm], [dnl
+ cat > conftest.s <<\EOF
+-        ptrue p0.b
++	.arch armv8.2-a+sve
++	ptrue p0.b
+ EOF
+-if AC_TRY_COMMAND(${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&AS_MESSAGE_LOG_FD); then
++if AC_TRY_COMMAND(${CC-cc} -c conftest.s 1>&AS_MESSAGE_LOG_FD); then
+   libc_cv_aarch64_sve_asm=yes
+ else
+   libc_cv_aarch64_sve_asm=no
diff --git a/SOURCES/glibc-upstream-2.39-25.patch b/SOURCES/glibc-upstream-2.39-25.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f168f15d5fa9d7b392024f9d79de43e9f755a80d
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-25.patch
@@ -0,0 +1,144 @@
+commit 9d92452c70805a2e2dbbdb2b1ffc34bd86e1c8df
+Author: Wilco Dijkstra <wilco.dijkstra@arm.com>
+Date:   Thu Mar 21 16:48:33 2024 +0000
+
+    AArch64: Check kernel version for SVE ifuncs
+    
+    Old Linux kernels disable SVE after every system call.  Calling the
+    SVE-optimized memcpy afterwards will then cause a trap to reenable SVE.
+    As a result, applications with a high use of syscalls may run slower with
+    the SVE memcpy.  This is true for kernels between 4.15.0 and before 6.2.0,
+    except for 5.14.0 which was patched.  Avoid this by checking the kernel
+    version and selecting the SVE ifunc on modern kernels.
+    
+    Parse the kernel version reported by uname() into a 24-bit kernel.major.minor
+    value without calling any library functions.  If uname() is not supported or
+    if the version format is not recognized, assume the kernel is modern.
+    
+    Tested-by: Florian Weimer <fweimer@redhat.com>
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+    (cherry picked from commit 2e94e2f5d2bf2de124c8ad7da85463355e54ccb2)
+
+diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
+index 77a782422af1b6e4..5f2da91ebbd0adaf 100644
+--- a/sysdeps/aarch64/cpu-features.h
++++ b/sysdeps/aarch64/cpu-features.h
+@@ -71,6 +71,7 @@ struct cpu_features
+   /* Currently, the GLIBC memory tagging tunable only defines 8 bits.  */
+   uint8_t mte_state;
+   bool sve;
++  bool prefer_sve_ifuncs;
+   bool mops;
+ };
+ 
+diff --git a/sysdeps/aarch64/multiarch/init-arch.h b/sysdeps/aarch64/multiarch/init-arch.h
+index c52860efb22d70eb..61dc40088f4d9e5e 100644
+--- a/sysdeps/aarch64/multiarch/init-arch.h
++++ b/sysdeps/aarch64/multiarch/init-arch.h
+@@ -36,5 +36,7 @@
+     MTE_ENABLED ();							      \
+   bool __attribute__((unused)) sve =					      \
+     GLRO(dl_aarch64_cpu_features).sve;					      \
++  bool __attribute__((unused)) prefer_sve_ifuncs =			      \
++    GLRO(dl_aarch64_cpu_features).prefer_sve_ifuncs;			      \
+   bool __attribute__((unused)) mops =					      \
+     GLRO(dl_aarch64_cpu_features).mops;
+diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
+index d12eccfca51f4bcf..ce53567dab33c2f0 100644
+--- a/sysdeps/aarch64/multiarch/memcpy.c
++++ b/sysdeps/aarch64/multiarch/memcpy.c
+@@ -47,7 +47,7 @@ select_memcpy_ifunc (void)
+     {
+       if (IS_A64FX (midr))
+ 	return __memcpy_a64fx;
+-      return __memcpy_sve;
++      return prefer_sve_ifuncs ? __memcpy_sve : __memcpy_generic;
+     }
+ 
+   if (IS_THUNDERX (midr))
+diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
+index 2081eeb4d40e0240..fe95037be391896c 100644
+--- a/sysdeps/aarch64/multiarch/memmove.c
++++ b/sysdeps/aarch64/multiarch/memmove.c
+@@ -47,7 +47,7 @@ select_memmove_ifunc (void)
+     {
+       if (IS_A64FX (midr))
+ 	return __memmove_a64fx;
+-      return __memmove_sve;
++      return prefer_sve_ifuncs ? __memmove_sve : __memmove_generic;
+     }
+ 
+   if (IS_THUNDERX (midr))
+diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+index b1a3f673f067280b..c0b047bc0dbeae42 100644
+--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
++++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+@@ -21,6 +21,7 @@
+ #include <sys/auxv.h>
+ #include <elf/dl-hwcaps.h>
+ #include <sys/prctl.h>
++#include <sys/utsname.h>
+ #include <dl-tunables-parse.h>
+ 
+ #define DCZID_DZP_MASK (1 << 4)
+@@ -62,6 +63,46 @@ get_midr_from_mcpu (const struct tunable_str_t *mcpu)
+   return UINT64_MAX;
+ }
+ 
++#if __LINUX_KERNEL_VERSION < 0x060200
++
++/* Return true if we prefer using SVE in string ifuncs.  Old kernels disable
++   SVE after every system call which results in unnecessary traps if memcpy
++   uses SVE.  This is true for kernels between 4.15.0 and before 6.2.0, except
++   for 5.14.0 which was patched.  For these versions return false to avoid using
++   SVE ifuncs.
++   Parse the kernel version into a 24-bit kernel.major.minor value without
++   calling any library functions.  If uname() is not supported or if the version
++   format is not recognized, assume the kernel is modern and return true.  */
++
++static inline bool
++prefer_sve_ifuncs (void)
++{
++  struct utsname buf;
++  const char *p = &buf.release[0];
++  int kernel = 0;
++  int val;
++
++  if (__uname (&buf) < 0)
++    return true;
++
++  for (int shift = 16; shift >= 0; shift -= 8)
++    {
++      for (val = 0; *p >= '0' && *p <= '9'; p++)
++	val = val * 10 + *p - '0';
++      kernel |= (val & 255) << shift;
++      if (*p++ != '.')
++	break;
++    }
++
++  if (kernel >= 0x060200 || kernel == 0x050e00)
++    return true;
++  if (kernel >= 0x040f00)
++    return false;
++  return true;
++}
++
++#endif
++
+ static inline void
+ init_cpu_features (struct cpu_features *cpu_features)
+ {
+@@ -126,6 +167,13 @@ init_cpu_features (struct cpu_features *cpu_features)
+   /* Check if SVE is supported.  */
+   cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;
+ 
++  cpu_features->prefer_sve_ifuncs = cpu_features->sve;
++
++#if __LINUX_KERNEL_VERSION < 0x060200
++  if (cpu_features->sve)
++    cpu_features->prefer_sve_ifuncs = prefer_sve_ifuncs ();
++#endif
++
+   /* Check if MOPS is supported.  */
+   cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS;
+ }
diff --git a/SOURCES/glibc-upstream-2.39-26.patch b/SOURCES/glibc-upstream-2.39-26.patch
new file mode 100644
index 0000000000000000000000000000000000000000..278d238e8f7a2a0f670ea41b1ad139c3fcd72693
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-26.patch
@@ -0,0 +1,108 @@
+commit 9883f4304cfb1558d0f1e6d9f48c4ab0a35355fe
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Feb 28 09:51:14 2024 -0800
+
+    x86-64: Don't use SSE resolvers for ISA level 3 or above
+    
+    When glibc is built with ISA level 3 or above enabled, SSE resolvers
+    aren't available and glibc fails to build:
+    
+    ld: .../elf/librtld.os: in function `init_cpu_features':
+    .../elf/../sysdeps/x86/cpu-features.c:1200:(.text+0x1445f): undefined reference to `_dl_runtime_resolve_fxsave'
+    ld: .../elf/librtld.os: relocation R_X86_64_PC32 against undefined hidden symbol `_dl_runtime_resolve_fxsave' can not be used when making a shared object
+    /usr/local/bin/ld: final link failed: bad value
+    
+    For ISA level 3 or above, don't use _dl_runtime_resolve_fxsave nor
+    _dl_tlsdesc_dynamic_fxsave.
+    
+    This fixes BZ #31429.
+    Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
+    
+    (cherry picked from commit befe2d3c4dec8be2cdd01a47132e47bdb7020922)
+
+diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
+index 6fe1b728c607f39e..b8abe733abe54fc4 100644
+--- a/sysdeps/x86/cpu-features.c
++++ b/sysdeps/x86/cpu-features.c
+@@ -18,6 +18,7 @@
+ 
+ #include <dl-hwcap.h>
+ #include <libc-pointer-arith.h>
++#include <isa-level.h>
+ #include <get-isa-level.h>
+ #include <cacheinfo.h>
+ #include <dl-cacheinfo.h>
+@@ -1198,7 +1199,9 @@ no_cpuid:
+ 	       TUNABLE_CALLBACK (set_x86_shstk));
+ #endif
+ 
++#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
+   if (GLRO(dl_x86_cpu_features).xsave_state_size != 0)
++#endif
+     {
+       if (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC))
+ 	{
+@@ -1219,22 +1222,24 @@ no_cpuid:
+ #endif
+ 	}
+     }
++#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
+   else
+     {
+-#ifdef __x86_64__
++# ifdef __x86_64__
+       GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_fxsave;
+-# ifdef SHARED
++#  ifdef SHARED
+       GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave;
+-# endif
+-#else
+-# ifdef SHARED
++#  endif
++# else
++#  ifdef SHARED
+       if (CPU_FEATURE_USABLE_P (cpu_features, FXSR))
+ 	GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave;
+       else
+ 	GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fnsave;
++#  endif
+ # endif
+-#endif
+     }
++#endif
+ 
+ #ifdef SHARED
+ # ifdef __x86_64__
+diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
+index ea69f5223a77e0c0..057a10862afd6208 100644
+--- a/sysdeps/x86_64/dl-tlsdesc.S
++++ b/sysdeps/x86_64/dl-tlsdesc.S
+@@ -20,6 +20,7 @@
+ #include <tls.h>
+ #include <cpu-features-offsets.h>
+ #include <features-offsets.h>
++#include <isa-level.h>
+ #include "tlsdesc.h"
+ #include "dl-trampoline-save.h"
+ 
+@@ -79,12 +80,14 @@ _dl_tlsdesc_undefweak:
+ 	.size	_dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
+ 
+ #ifdef SHARED
+-# define USE_FXSAVE
+-# define STATE_SAVE_ALIGNMENT	16
+-# define _dl_tlsdesc_dynamic	_dl_tlsdesc_dynamic_fxsave
+-# include "dl-tlsdesc-dynamic.h"
+-# undef _dl_tlsdesc_dynamic
+-# undef USE_FXSAVE
++# if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
++#  define USE_FXSAVE
++#  define STATE_SAVE_ALIGNMENT	16
++#  define _dl_tlsdesc_dynamic	_dl_tlsdesc_dynamic_fxsave
++#  include "dl-tlsdesc-dynamic.h"
++#  undef _dl_tlsdesc_dynamic
++#  undef USE_FXSAVE
++# endif
+ 
+ # define USE_XSAVE
+ # define STATE_SAVE_ALIGNMENT	64
diff --git a/SOURCES/glibc-upstream-2.39-27.patch b/SOURCES/glibc-upstream-2.39-27.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8f136ce0c644d6f970d425a76115ddca88f06aa4
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-27.patch
@@ -0,0 +1,61 @@
+commit 7b92f46f04c6cbce19d19ae1099628431858996c
+Author: Sunil K Pandey <skpgkp2@gmail.com>
+Date:   Thu Feb 29 17:57:02 2024 -0800
+
+    x86-64: Simplify minimum ISA check ifdef conditional with if
+    
+    Replace minimum ISA check ifdef conditional with if.  Since
+    MINIMUM_X86_ISA_LEVEL and AVX_X86_ISA_LEVEL are compile time constants,
+    compiler will perform constant folding optimization, getting same
+    results.
+    
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    (cherry picked from commit b6e3898194bbae78910bbe9cd086937014961e45)
+
+diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
+index b8abe733abe54fc4..3d7c2819d7cc6643 100644
+--- a/sysdeps/x86/cpu-features.c
++++ b/sysdeps/x86/cpu-features.c
+@@ -1199,9 +1199,8 @@ no_cpuid:
+ 	       TUNABLE_CALLBACK (set_x86_shstk));
+ #endif
+ 
+-#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
+-  if (GLRO(dl_x86_cpu_features).xsave_state_size != 0)
+-#endif
++  if (MINIMUM_X86_ISA_LEVEL >= AVX_X86_ISA_LEVEL
++      || (GLRO(dl_x86_cpu_features).xsave_state_size != 0))
+     {
+       if (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC))
+ 	{
+@@ -1222,24 +1221,22 @@ no_cpuid:
+ #endif
+ 	}
+     }
+-#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
+   else
+     {
+-# ifdef __x86_64__
++#ifdef __x86_64__
+       GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_fxsave;
+-#  ifdef SHARED
++# ifdef SHARED
+       GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave;
+-#  endif
+-# else
+-#  ifdef SHARED
++# endif
++#else
++# ifdef SHARED
+       if (CPU_FEATURE_USABLE_P (cpu_features, FXSR))
+ 	GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave;
+       else
+ 	GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fnsave;
+-#  endif
+ # endif
+-    }
+ #endif
++    }
+ 
+ #ifdef SHARED
+ # ifdef __x86_64__
diff --git a/SOURCES/glibc-upstream-2.39-28.patch b/SOURCES/glibc-upstream-2.39-28.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b5546e0112b658bb7f5dfd65564d5a2d81e2e3b1
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-28.patch
@@ -0,0 +1,50 @@
+commit edb9a76e3008725e9dc035d38a58e849a3bde0f1
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Sun Apr 14 08:24:51 2024 +0200
+
+    powerpc: Fix ld.so address determination for PCREL mode (bug 31640)
+    
+    This seems to have stopped working with some GCC 14 versions,
+    which clobber r2.  With other compilers, the kernel-provided
+    r2 value is still available at this point.
+    
+    Reviewed-by: Peter Bergner <bergner@linux.ibm.com>
+    (cherry picked from commit 14e56bd4ce15ac2d1cc43f762eb2e6b83fec1afe)
+
+diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
+index c6682f3445615636..2b6f5d2b08cb10b8 100644
+--- a/sysdeps/powerpc/powerpc64/dl-machine.h
++++ b/sysdeps/powerpc/powerpc64/dl-machine.h
+@@ -78,6 +78,7 @@ elf_host_tolerates_class (const Elf64_Ehdr *ehdr)
+ static inline Elf64_Addr
+ elf_machine_load_address (void) __attribute__ ((const));
+ 
++#ifndef __PCREL__
+ static inline Elf64_Addr
+ elf_machine_load_address (void)
+ {
+@@ -105,6 +106,24 @@ elf_machine_dynamic (void)
+   /* Then subtract off the load address offset.  */
+   return runtime_dynamic - elf_machine_load_address() ;
+ }
++#else /* __PCREL__ */
++/* In PCREL mode, r2 may have been clobbered.  Rely on relative
++   relocations instead.  */
++
++static inline ElfW(Addr)
++elf_machine_load_address (void)
++{
++  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
++  return (ElfW(Addr)) &__ehdr_start;
++}
++
++static inline ElfW(Addr)
++elf_machine_dynamic (void)
++{
++  extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
++  return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
++}
++#endif /* __PCREL__ */
+ 
+ /* The PLT uses Elf64_Rela relocs.  */
+ #define elf_machine_relplt elf_machine_rela
diff --git a/SOURCES/glibc-upstream-2.39-29.patch b/SOURCES/glibc-upstream-2.39-29.patch
new file mode 100644
index 0000000000000000000000000000000000000000..41a85b1c7f497ed44e59dfd2d2b487241bfeeaab
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-29.patch
@@ -0,0 +1,246 @@
+commit 04df8652eb1919da18d54b3dcd6db1675993d45d
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Feb 15 11:19:56 2024 -0800
+
+    Apply the Makefile sorting fix
+    
+    Apply the Makefile sorting fix generated by sort-makefile-lines.py.
+    
+    (cherry picked from commit ef7f4b1fef67430a8f3cfc77fa6aada2add851d7)
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
+index fe863e1ba411cc4b..01762ef526854d54 100644
+--- a/sysdeps/loongarch/lp64/multiarch/Makefile
++++ b/sysdeps/loongarch/lp64/multiarch/Makefile
+@@ -1,52 +1,52 @@
+ ifeq ($(subdir),string)
+ sysdep_routines += \
+-  strlen-aligned \
+-  strlen-lsx \
+-  strlen-lasx \
+-  strnlen-aligned \
+-  strnlen-lsx \
+-  strnlen-lasx \
++  memchr-aligned \
++  memchr-lasx \
++  memchr-lsx \
++  memcmp-aligned \
++  memcmp-lasx \
++  memcmp-lsx \
++  memcpy-aligned \
++  memcpy-unaligned \
++  memmove-lasx \
++  memmove-lsx \
++  memmove-unaligned \
++  memrchr-generic \
++  memrchr-lasx \
++  memrchr-lsx \
++  memset-aligned \
++  memset-lasx \
++  memset-lsx \
++  memset-unaligned \
++  rawmemchr-aligned \
++  rawmemchr-lasx \
++  rawmemchr-lsx \
++  stpcpy-aligned \
++  stpcpy-lasx \
++  stpcpy-lsx \
++  stpcpy-unaligned \
+   strchr-aligned \
+-  strchr-lsx \
+   strchr-lasx \
+-  strrchr-aligned \
+-  strrchr-lsx \
+-  strrchr-lasx \
++  strchr-lsx \
+   strchrnul-aligned \
+-  strchrnul-lsx \
+   strchrnul-lasx \
++  strchrnul-lsx \
+   strcmp-aligned \
+   strcmp-lsx \
+-  strncmp-aligned \
+-  strncmp-lsx \
+   strcpy-aligned \
+-  strcpy-unaligned \
+-  strcpy-lsx \
+   strcpy-lasx \
+-  stpcpy-aligned \
+-  stpcpy-unaligned \
+-  stpcpy-lsx \
+-  stpcpy-lasx \
+-  memcpy-aligned \
+-  memcpy-unaligned \
+-  memmove-unaligned \
+-  memmove-lsx \
+-  memmove-lasx \
+-  rawmemchr-aligned \
+-  rawmemchr-lsx \
+-  rawmemchr-lasx \
+-  memchr-aligned \
+-  memchr-lsx \
+-  memchr-lasx \
+-  memrchr-generic \
+-  memrchr-lsx \
+-  memrchr-lasx \
+-  memset-aligned \
+-  memset-unaligned \
+-  memset-lsx \
+-  memset-lasx \
+-  memcmp-aligned \
+-  memcmp-lsx \
+-  memcmp-lasx \
++  strcpy-lsx \
++  strcpy-unaligned \
++  strlen-aligned \
++  strlen-lasx \
++  strlen-lsx \
++  strncmp-aligned \
++  strncmp-lsx \
++  strnlen-aligned \
++  strnlen-lasx \
++  strnlen-lsx \
++  strrchr-aligned \
++  strrchr-lasx \
++  strrchr-lsx \
+ # sysdep_routines
+ endif
+diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
+index 992aabe43ec60abf..5311b594aff62f7c 100644
+--- a/sysdeps/x86/Makefile
++++ b/sysdeps/x86/Makefile
+@@ -15,18 +15,18 @@ CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags)
+ CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector)
+ 
+ tests += \
+-  tst-get-cpu-features \
+-  tst-get-cpu-features-static \
+   tst-cpu-features-cpuinfo \
+   tst-cpu-features-cpuinfo-static \
+   tst-cpu-features-supports \
+   tst-cpu-features-supports-static \
++  tst-get-cpu-features \
++  tst-get-cpu-features-static \
+   tst-hwcap-tunables \
+ # tests
+ tests-static += \
+-  tst-get-cpu-features-static \
+   tst-cpu-features-cpuinfo-static \
+   tst-cpu-features-supports-static \
++  tst-get-cpu-features-static \
+ # tests-static
+ ifeq (yes,$(have-ifunc))
+ ifeq (yes,$(have-gcc-ifunc))
+diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
+index 9d374a329916fc45..0ede447405d549b5 100644
+--- a/sysdeps/x86_64/Makefile
++++ b/sysdeps/x86_64/Makefile
+@@ -252,6 +252,10 @@ sysdep-dl-routines += dl-cet
+ 
+ tests += \
+   tst-cet-legacy-1 \
++  tst-cet-legacy-10 \
++  tst-cet-legacy-10-static \
++  tst-cet-legacy-10a \
++  tst-cet-legacy-10a-static \
+   tst-cet-legacy-1a \
+   tst-cet-legacy-2 \
+   tst-cet-legacy-2a \
+@@ -263,15 +267,11 @@ tests += \
+   tst-cet-legacy-8 \
+   tst-cet-legacy-9 \
+   tst-cet-legacy-9-static \
+-  tst-cet-legacy-10 \
+-  tst-cet-legacy-10-static \
+-  tst-cet-legacy-10a \
+-  tst-cet-legacy-10a-static \
+ # tests
+ tests-static += \
+-  tst-cet-legacy-9-static \
+   tst-cet-legacy-10-static \
+   tst-cet-legacy-10a-static \
++  tst-cet-legacy-9-static \
+ # tests-static
+ tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd)
+ 
+diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
+index ea81753b708fcb8d..e1a490dd98b4be07 100644
+--- a/sysdeps/x86_64/fpu/multiarch/Makefile
++++ b/sysdeps/x86_64/fpu/multiarch/Makefile
+@@ -4,10 +4,10 @@ libm-sysdep_routines += \
+   s_ceilf-c \
+   s_floor-c \
+   s_floorf-c \
+-  s_rint-c \
+-  s_rintf-c \
+   s_nearbyint-c \
+   s_nearbyintf-c \
++  s_rint-c \
++  s_rintf-c \
+   s_roundeven-c \
+   s_roundevenf-c \
+   s_trunc-c \
+@@ -21,10 +21,10 @@ libm-sysdep_routines += \
+   s_floorf-sse4_1 \
+   s_nearbyint-sse4_1 \
+   s_nearbyintf-sse4_1 \
+-  s_roundeven-sse4_1 \
+-  s_roundevenf-sse4_1 \
+   s_rint-sse4_1 \
+   s_rintf-sse4_1 \
++  s_roundeven-sse4_1 \
++  s_roundevenf-sse4_1 \
+   s_trunc-sse4_1 \
+   s_truncf-sse4_1 \
+ # libm-sysdep_routines
+@@ -84,12 +84,12 @@ CFLAGS-s_cosf-fma.c = -mfma -mavx2
+ CFLAGS-s_sincosf-fma.c = -mfma -mavx2
+ 
+ libm-sysdep_routines += \
++  e_asin-fma4 \
++  e_atan2-fma4 \
+   e_exp-fma4 \
+   e_log-fma4 \
+   e_pow-fma4 \
+-  e_asin-fma4 \
+   s_atan-fma4 \
+-  e_atan2-fma4 \
+   s_sin-fma4 \
+   s_sincos-fma4 \
+   s_tan-fma4 \
+@@ -106,10 +106,10 @@ CFLAGS-s_tan-fma4.c = -mfma4
+ CFLAGS-s_sincos-fma4.c = -mfma4
+ 
+ libm-sysdep_routines += \
++  e_atan2-avx \
+   e_exp-avx \
+   e_log-avx \
+   s_atan-avx \
+-  e_atan2-avx \
+   s_sin-avx \
+   s_sincos-avx \
+   s_tan-avx \
+diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile
+index e1e894c963afb8b1..d3d2270394bd635d 100644
+--- a/sysdeps/x86_64/multiarch/Makefile
++++ b/sysdeps/x86_64/multiarch/Makefile
+@@ -4,8 +4,8 @@ sysdep_routines += \
+   memchr-avx2 \
+   memchr-avx2-rtm \
+   memchr-evex \
+-  memchr-evex512 \
+   memchr-evex-rtm \
++  memchr-evex512 \
+   memchr-sse2 \
+   memcmp-avx2-movbe \
+   memcmp-avx2-movbe-rtm \
+@@ -37,8 +37,8 @@ sysdep_routines += \
+   rawmemchr-avx2 \
+   rawmemchr-avx2-rtm \
+   rawmemchr-evex \
+-  rawmemchr-evex512 \
+   rawmemchr-evex-rtm \
++  rawmemchr-evex512 \
+   rawmemchr-sse2 \
+   stpcpy-avx2 \
+   stpcpy-avx2-rtm \
diff --git a/SOURCES/glibc-upstream-2.39-30.patch b/SOURCES/glibc-upstream-2.39-30.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3796da6834a54de58b1557d4cd08a8b607909db7
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-30.patch
@@ -0,0 +1,2143 @@
+commit 423099a03264ea28298f47355d7811b8efe03c97
+Author: Sunil K Pandey <skpgkp2@gmail.com>
+Date:   Tue Feb 13 12:23:14 2024 -0800
+
+    x86_64: Exclude SSE, AVX and FMA4 variants in libm multiarch
+    
+    When glibc is built with ISA level 3 or higher by default, the resulting
+    glibc binaries won't run on SSE or FMA4 processors.  Exclude SSE, AVX and
+    FMA4 variants in libm multiarch when ISA level 3 or higher is enabled by
+    default.
+    
+    When glibc is built with ISA level 2 enabled by default, only keep SSE4.1
+    variant.
+    
+    Fixes BZ 31335.
+    
+    NB: elf/tst-valgrind-smoke test fails with ISA level 4, because valgrind
+    doesn't support AVX512 instructions:
+    
+    https://bugs.kde.org/show_bug.cgi?id=383010
+    
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    (cherry picked from commit 9f78a7c1d0963282608da836b840f0d5ae1c478e)
+
+diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
+index 1f4c2d67fd2693ed..2a5421bb31e9efe4 100644
+--- a/sysdeps/x86/configure
++++ b/sysdeps/x86/configure
+@@ -98,6 +98,7 @@ printf "%s\n" "$libc_cv_have_x86_lahf_sahf" >&6; }
+   if test $libc_cv_have_x86_lahf_sahf = yes; then
+     printf "%s\n" "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
+ 
++    ISAFLAG="-DHAVE_X86_LAHF_SAHF"
+   fi
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MOVBE instruction support" >&5
+ printf %s "checking for MOVBE instruction support... " >&6; }
+@@ -120,9 +121,41 @@ printf "%s\n" "$libc_cv_have_x86_movbe" >&6; }
+   if test $libc_cv_have_x86_movbe = yes; then
+     printf "%s\n" "#define HAVE_X86_MOVBE 1" >>confdefs.h
+ 
++    ISAFLAG="$ISAFLAG -DHAVE_X86_MOVBE"
+   fi
++
++  # Check for ISA level support.
++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ISA level support" >&5
++printf %s "checking for ISA level support... " >&6; }
++if test ${libc_cv_have_x86_isa_level+y}
++then :
++  printf %s "(cached) " >&6
++else $as_nop
++  cat > conftest.c <<EOF
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL >= 4
++libc_cv_have_x86_isa_level=4
++#elif MINIMUM_X86_ISA_LEVEL == 3
++libc_cv_have_x86_isa_level=3
++#elif MINIMUM_X86_ISA_LEVEL == 2
++libc_cv_have_x86_isa_level=2
++#else
++libc_cv_have_x86_isa_level=baseline
++#endif
++EOF
++		 eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level`
++		 rm -rf conftest*
++fi
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_isa_level" >&5
++printf "%s\n" "$libc_cv_have_x86_isa_level" >&6; }
++else
++  libc_cv_have_x86_isa_level=baseline
+ fi
+ config_vars="$config_vars
++have-x86-isa-level = $libc_cv_have_x86_isa_level"
++config_vars="$config_vars
++x86-isa-level-3-or-above = 3 4"
++config_vars="$config_vars
+ enable-x86-isa-level = $libc_cv_include_x86_isa_level"
+ 
+ printf "%s\n" "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
+diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
+index 437a50623b35163a..78ff7c8f41c552bc 100644
+--- a/sysdeps/x86/configure.ac
++++ b/sysdeps/x86/configure.ac
+@@ -72,6 +72,7 @@ if test $libc_cv_include_x86_isa_level = yes; then
+     fi])
+   if test $libc_cv_have_x86_lahf_sahf = yes; then
+     AC_DEFINE(HAVE_X86_LAHF_SAHF)
++    ISAFLAG="-DHAVE_X86_LAHF_SAHF"
+   fi
+   AC_CACHE_CHECK([for MOVBE instruction support],
+ 		 libc_cv_have_x86_movbe, [dnl
+@@ -81,8 +82,31 @@ if test $libc_cv_include_x86_isa_level = yes; then
+     fi])
+   if test $libc_cv_have_x86_movbe = yes; then
+     AC_DEFINE(HAVE_X86_MOVBE)
++    ISAFLAG="$ISAFLAG -DHAVE_X86_MOVBE"
+   fi
++
++  # Check for ISA level support.
++  AC_CACHE_CHECK([for ISA level support],
++		 libc_cv_have_x86_isa_level, [dnl
++cat > conftest.c <<EOF
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL >= 4
++libc_cv_have_x86_isa_level=4
++#elif MINIMUM_X86_ISA_LEVEL == 3
++libc_cv_have_x86_isa_level=3
++#elif MINIMUM_X86_ISA_LEVEL == 2
++libc_cv_have_x86_isa_level=2
++#else
++libc_cv_have_x86_isa_level=baseline
++#endif
++EOF
++		 eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level`
++		 rm -rf conftest*])
++else
++  libc_cv_have_x86_isa_level=baseline
+ fi
++LIBC_CONFIG_VAR([have-x86-isa-level], [$libc_cv_have_x86_isa_level])
++LIBC_CONFIG_VAR([x86-isa-level-3-or-above], [3 4])
+ LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
+ 
+ dnl Static PIE is supported.
+diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
+index e1a490dd98b4be07..6ddd50240ce33d22 100644
+--- a/sysdeps/x86_64/fpu/multiarch/Makefile
++++ b/sysdeps/x86_64/fpu/multiarch/Makefile
+@@ -1,49 +1,4 @@
+ ifeq ($(subdir),math)
+-libm-sysdep_routines += \
+-  s_ceil-c \
+-  s_ceilf-c \
+-  s_floor-c \
+-  s_floorf-c \
+-  s_nearbyint-c \
+-  s_nearbyintf-c \
+-  s_rint-c \
+-  s_rintf-c \
+-  s_roundeven-c \
+-  s_roundevenf-c \
+-  s_trunc-c \
+-  s_truncf-c \
+-# libm-sysdep_routines
+-
+-libm-sysdep_routines += \
+-  s_ceil-sse4_1 \
+-  s_ceilf-sse4_1 \
+-  s_floor-sse4_1 \
+-  s_floorf-sse4_1 \
+-  s_nearbyint-sse4_1 \
+-  s_nearbyintf-sse4_1 \
+-  s_rint-sse4_1 \
+-  s_rintf-sse4_1 \
+-  s_roundeven-sse4_1 \
+-  s_roundevenf-sse4_1 \
+-  s_trunc-sse4_1 \
+-  s_truncf-sse4_1 \
+-# libm-sysdep_routines
+-
+-libm-sysdep_routines += \
+-  e_asin-fma \
+-  e_atan2-fma \
+-  e_exp-fma \
+-  e_log-fma \
+-  e_log2-fma \
+-  e_pow-fma \
+-  s_atan-fma \
+-  s_expm1-fma \
+-  s_log1p-fma \
+-  s_sin-fma \
+-  s_sincos-fma \
+-  s_tan-fma \
+-# libm-sysdep_routines
+-
+ CFLAGS-e_asin-fma.c = -mfma -mavx2
+ CFLAGS-e_atan2-fma.c = -mfma -mavx2
+ CFLAGS-e_exp-fma.c = -mfma -mavx2
+@@ -57,23 +12,6 @@ CFLAGS-s_sin-fma.c = -mfma -mavx2
+ CFLAGS-s_tan-fma.c = -mfma -mavx2
+ CFLAGS-s_sincos-fma.c = -mfma -mavx2
+ 
+-libm-sysdep_routines += \
+-  s_cosf-sse2 \
+-  s_sincosf-sse2 \
+-  s_sinf-sse2 \
+-# libm-sysdep_routines
+-
+-libm-sysdep_routines += \
+-  e_exp2f-fma \
+-  e_expf-fma \
+-  e_log2f-fma \
+-  e_logf-fma \
+-  e_powf-fma \
+-  s_cosf-fma \
+-  s_sincosf-fma \
+-  s_sinf-fma \
+-# libm-sysdep_routines
+-
+ CFLAGS-e_exp2f-fma.c = -mfma -mavx2
+ CFLAGS-e_expf-fma.c = -mfma -mavx2
+ CFLAGS-e_log2f-fma.c = -mfma -mavx2
+@@ -83,17 +21,93 @@ CFLAGS-s_sinf-fma.c = -mfma -mavx2
+ CFLAGS-s_cosf-fma.c = -mfma -mavx2
+ CFLAGS-s_sincosf-fma.c = -mfma -mavx2
+ 
++# Check if ISA level is 3 or above.
++ifneq (,$(filter $(have-x86-isa-level),$(x86-isa-level-3-or-above)))
+ libm-sysdep_routines += \
++  s_ceil-avx \
++  s_ceilf-avx \
++  s_floor-avx \
++  s_floorf-avx \
++  s_nearbyint-avx \
++  s_nearbyintf-avx \
++  s_rint-avx \
++  s_rintf-avx \
++  s_roundeven-avx \
++  s_roundevenf-avx \
++  s_trunc-avx \
++  s_truncf-avx \
++# libm-sysdep_routines
++else
++libm-sysdep_routines += \
++  e_asin-fma \
+   e_asin-fma4 \
++  e_atan2-avx \
++  e_atan2-fma \
+   e_atan2-fma4 \
++  e_exp-avx \
++  e_exp-fma \
+   e_exp-fma4 \
++  e_exp2f-fma \
++  e_expf-fma \
++  e_log-avx \
++  e_log-fma \
+   e_log-fma4 \
++  e_log2-fma \
++  e_log2f-fma \
++  e_logf-fma \
++  e_pow-fma \
+   e_pow-fma4 \
++  e_powf-fma \
++  s_atan-avx \
++  s_atan-fma \
+   s_atan-fma4 \
++  s_ceil-sse4_1 \
++  s_ceilf-sse4_1 \
++  s_cosf-fma \
++  s_cosf-sse2 \
++  s_expm1-fma \
++  s_floor-sse4_1 \
++  s_floorf-sse4_1 \
++  s_log1p-fma \
++  s_nearbyint-sse4_1 \
++  s_nearbyintf-sse4_1 \
++  s_rint-sse4_1 \
++  s_rintf-sse4_1 \
++  s_roundeven-sse4_1 \
++  s_roundevenf-sse4_1 \
++  s_sin-avx \
++  s_sin-fma \
+   s_sin-fma4 \
++  s_sincos-avx \
++  s_sincos-fma \
+   s_sincos-fma4 \
++  s_sincosf-fma \
++  s_sincosf-sse2 \
++  s_sinf-fma \
++  s_sinf-sse2 \
++  s_tan-avx \
++  s_tan-fma \
+   s_tan-fma4 \
++  s_trunc-sse4_1 \
++  s_truncf-sse4_1 \
+ # libm-sysdep_routines
++ifeq ($(have-x86-isa-level),baseline)
++libm-sysdep_routines += \
++  s_ceil-c \
++  s_ceilf-c \
++  s_floor-c \
++  s_floorf-c \
++  s_nearbyint-c \
++  s_nearbyintf-c \
++  s_rint-c \
++  s_rintf-c \
++  s_roundeven-c \
++  s_roundevenf-c \
++  s_trunc-c \
++  s_truncf-c \
++# libm-sysdep_routines
++endif
++endif
+ 
+ CFLAGS-e_asin-fma4.c = -mfma4
+ CFLAGS-e_atan2-fma4.c = -mfma4
+@@ -105,16 +119,6 @@ CFLAGS-s_sin-fma4.c = -mfma4
+ CFLAGS-s_tan-fma4.c = -mfma4
+ CFLAGS-s_sincos-fma4.c = -mfma4
+ 
+-libm-sysdep_routines += \
+-  e_atan2-avx \
+-  e_exp-avx \
+-  e_log-avx \
+-  s_atan-avx \
+-  s_sin-avx \
+-  s_sincos-avx \
+-  s_tan-avx \
+-# libm-sysdep_routines
+-
+ CFLAGS-e_atan2-avx.c = -msse2avx -DSSE2AVX
+ CFLAGS-e_exp-avx.c = -msse2avx -DSSE2AVX
+ CFLAGS-e_log-avx.c = -msse2avx -DSSE2AVX
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_asin.c b/sysdeps/x86_64/fpu/multiarch/e_asin.c
+index 2eaa6c2c0490d8fc..d64fca2586d43f03 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_asin.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_asin.c
+@@ -16,26 +16,29 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-finite.h>
+ 
+ extern double __redirect_ieee754_asin (double);
+ extern double __redirect_ieee754_acos (double);
+ 
+-#define SYMBOL_NAME ieee754_asin
+-#include "ifunc-fma4.h"
++# define SYMBOL_NAME ieee754_asin
++# include "ifunc-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_ieee754_asin, __ieee754_asin,
+ 		       IFUNC_SELECTOR ());
+ libm_alias_finite (__ieee754_asin, __asin)
+ 
+-#undef SYMBOL_NAME
+-#define SYMBOL_NAME ieee754_acos
+-#include "ifunc-fma4.h"
++# undef SYMBOL_NAME
++# define SYMBOL_NAME ieee754_acos
++# include "ifunc-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_ieee754_acos, __ieee754_acos,
+ 		       IFUNC_SELECTOR ());
+ libm_alias_finite (__ieee754_acos, __acos)
+ 
+-#define __ieee754_acos __ieee754_acos_sse2
+-#define __ieee754_asin __ieee754_asin_sse2
++# define __ieee754_acos __ieee754_acos_sse2
++# define __ieee754_asin __ieee754_asin_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/e_asin.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_atan2.c b/sysdeps/x86_64/fpu/multiarch/e_atan2.c
+index 17ee4f3c366b57c4..8a86c14ded1784dd 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_atan2.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_atan2.c
+@@ -16,16 +16,19 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-finite.h>
+ 
+ extern double __redirect_ieee754_atan2 (double, double);
+ 
+-#define SYMBOL_NAME ieee754_atan2
+-#include "ifunc-avx-fma4.h"
++# define SYMBOL_NAME ieee754_atan2
++# include "ifunc-avx-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_ieee754_atan2,
+ 		       __ieee754_atan2, IFUNC_SELECTOR ());
+ libm_alias_finite (__ieee754_atan2, __atan2)
+ 
+-#define __ieee754_atan2 __ieee754_atan2_sse2
++# define __ieee754_atan2 __ieee754_atan2_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/e_atan2.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_exp.c b/sysdeps/x86_64/fpu/multiarch/e_exp.c
+index 406b7ebd44d8eba1..d56329291a204ecf 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_exp.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_exp.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <math.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <math.h>
++# include <libm-alias-finite.h>
+ 
+ extern double __redirect_ieee754_exp (double);
+ 
+-#define SYMBOL_NAME ieee754_exp
+-#include "ifunc-avx-fma4.h"
++# define SYMBOL_NAME ieee754_exp
++# include "ifunc-avx-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_ieee754_exp, __ieee754_exp,
+ 		       IFUNC_SELECTOR ());
+ libm_alias_finite (__ieee754_exp, __exp)
+ 
+-#define __exp __ieee754_exp_sse2
++# define __exp __ieee754_exp_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/e_exp.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_exp2f.c b/sysdeps/x86_64/fpu/multiarch/e_exp2f.c
+index 804fd6be850926b3..06fe5028d6e72122 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_exp2f.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_exp2f.c
+@@ -16,25 +16,28 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# include <libm-alias-finite.h>
+ 
+ extern float __redirect_exp2f (float);
+ 
+-#define SYMBOL_NAME exp2f
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME exp2f
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_exp2f, __exp2f, IFUNC_SELECTOR ());
+ 
+-#ifdef SHARED
++# ifdef SHARED
+ versioned_symbol (libm, __ieee754_exp2f, exp2f, GLIBC_2_27);
+ libm_alias_float_other (__exp2, exp2)
+-#else
++# else
+ libm_alias_float (__exp2, exp2)
+-#endif
++# endif
+ 
+ strong_alias (__exp2f, __ieee754_exp2f)
+ libm_alias_finite (__exp2f, __exp2f)
+ 
+-#define __exp2f __exp2f_sse2
++# define __exp2f __exp2f_sse2
++#endif
+ #include <sysdeps/ieee754/flt-32/e_exp2f.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_expf.c b/sysdeps/x86_64/fpu/multiarch/e_expf.c
+index 4a7e2a5bce697d60..19d767f636126c8d 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_expf.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_expf.c
+@@ -16,28 +16,31 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# include <libm-alias-finite.h>
+ 
+ extern float __redirect_expf (float);
+ 
+-#define SYMBOL_NAME expf
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME expf
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_expf, __expf, IFUNC_SELECTOR ());
+ 
+-#ifdef SHARED
++# ifdef SHARED
+ __hidden_ver1 (__expf, __GI___expf, __redirect_expf)
+   __attribute__ ((visibility ("hidden")));
+ 
+ versioned_symbol (libm, __ieee754_expf, expf, GLIBC_2_27);
+ libm_alias_float_other (__exp, exp)
+-#else
++# else
+ libm_alias_float (__exp, exp)
+-#endif
++# endif
+ 
+ strong_alias (__expf, __ieee754_expf)
+ libm_alias_finite (__expf, __expf)
+ 
+-#define __expf __expf_sse2
++# define __expf __expf_sse2
++#endif
+ #include <sysdeps/ieee754/flt-32/e_expf.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_log.c b/sysdeps/x86_64/fpu/multiarch/e_log.c
+index 067fbf58c3f8e0f5..d80c1b1463954af8 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_log.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_log.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <math.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <math.h>
++# include <libm-alias-finite.h>
+ 
+ extern double __redirect_ieee754_log (double);
+ 
+-#define SYMBOL_NAME ieee754_log
+-#include "ifunc-avx-fma4.h"
++# define SYMBOL_NAME ieee754_log
++# include "ifunc-avx-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_ieee754_log, __ieee754_log,
+ 		       IFUNC_SELECTOR ());
+ libm_alias_finite (__ieee754_log, __log)
+ 
+-#define __log __ieee754_log_sse2
++# define __log __ieee754_log_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/e_log.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_log2.c b/sysdeps/x86_64/fpu/multiarch/e_log2.c
+index 9c57a2f6ccfcbdfd..9686782c09b1f343 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_log2.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_log2.c
+@@ -16,28 +16,31 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-double.h>
++# include <libm-alias-finite.h>
+ 
+ extern double __redirect_log2 (double);
+ 
+-#define SYMBOL_NAME log2
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME log2
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_log2, __log2, IFUNC_SELECTOR ());
+ 
+-#ifdef SHARED
++# ifdef SHARED
+ __hidden_ver1 (__log2, __GI___log2, __redirect_log2)
+   __attribute__ ((visibility ("hidden")));
+ 
+ versioned_symbol (libm, __ieee754_log2, log2, GLIBC_2_29);
+ libm_alias_double_other (__log2, log2)
+-#else
++# else
+ libm_alias_double (__log2, log2)
+-#endif
++# endif
+ 
+ strong_alias (__log2, __ieee754_log2)
+ libm_alias_finite (__log2, __log2)
+ 
+-#define __log2 __log2_sse2
++# define __log2 __log2_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/e_log2.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_log2f.c b/sysdeps/x86_64/fpu/multiarch/e_log2f.c
+index 2b45c87f38afea62..8ada46e11e62726c 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_log2f.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_log2f.c
+@@ -16,28 +16,31 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# include <libm-alias-finite.h>
+ 
+ extern float __redirect_log2f (float);
+ 
+-#define SYMBOL_NAME log2f
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME log2f
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_log2f, __log2f, IFUNC_SELECTOR ());
+ 
+-#ifdef SHARED
++# ifdef SHARED
+ __hidden_ver1 (__log2f, __GI___log2f, __redirect_log2f)
+   __attribute__ ((visibility ("hidden")));
+ 
+ versioned_symbol (libm, __ieee754_log2f, log2f, GLIBC_2_27);
+ libm_alias_float_other (__log2, log2)
+-#else
++# else
+ libm_alias_float (__log2, log2)
+-#endif
++# endif
+ 
+ strong_alias (__log2f, __ieee754_log2f)
+ libm_alias_finite (__log2f, __log2f)
+ 
+-#define __log2f __log2f_sse2
++# define __log2f __log2f_sse2
++#endif
+ #include <sysdeps/ieee754/flt-32/e_log2f.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_logf.c b/sysdeps/x86_64/fpu/multiarch/e_logf.c
+index 97e23c8fea39f37e..a3978d9a8e40c588 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_logf.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_logf.c
+@@ -16,28 +16,31 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# include <libm-alias-finite.h>
+ 
+ extern float __redirect_logf (float);
+ 
+-#define SYMBOL_NAME logf
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME logf
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_logf, __logf, IFUNC_SELECTOR ());
+ 
+-#ifdef SHARED
++# ifdef SHARED
+ __hidden_ver1 (__logf, __GI___logf, __redirect_logf)
+   __attribute__ ((visibility ("hidden")));
+ 
+ versioned_symbol (libm, __ieee754_logf, logf, GLIBC_2_27);
+ libm_alias_float_other (__log, log)
+-#else
++# else
+ libm_alias_float (__log, log)
+-#endif
++# endif
+ 
+ strong_alias (__logf, __ieee754_logf)
+ libm_alias_finite (__logf, __logf)
+ 
+-#define __logf __logf_sse2
++# define __logf __logf_sse2
++#endif
+ #include <sysdeps/ieee754/flt-32/e_logf.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_pow.c b/sysdeps/x86_64/fpu/multiarch/e_pow.c
+index 42618e7112fac769..f8f17aff9ffb9bf2 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_pow.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_pow.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <math.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <math.h>
++# include <libm-alias-finite.h>
+ 
+ extern double __redirect_ieee754_pow (double, double);
+ 
+-#define SYMBOL_NAME ieee754_pow
+-#include "ifunc-fma4.h"
++# define SYMBOL_NAME ieee754_pow
++# include "ifunc-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_ieee754_pow,
+ 		       __ieee754_pow, IFUNC_SELECTOR ());
+ libm_alias_finite (__ieee754_pow, __pow)
+ 
+-#define __pow __ieee754_pow_sse2
++# define __pow __ieee754_pow_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/e_pow.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/e_powf.c b/sysdeps/x86_64/fpu/multiarch/e_powf.c
+index 8e6ce13cc1a2470b..8b1a4c7d047115f5 100644
+--- a/sysdeps/x86_64/fpu/multiarch/e_powf.c
++++ b/sysdeps/x86_64/fpu/multiarch/e_powf.c
+@@ -16,31 +16,34 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
+-#include <libm-alias-finite.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# include <libm-alias-finite.h>
+ 
+-#define powf __redirect_powf
+-#define __DECL_SIMD___redirect_powf
+-#include <math.h>
+-#undef powf
++# define powf __redirect_powf
++# define __DECL_SIMD___redirect_powf
++# include <math.h>
++# undef powf
+ 
+-#define SYMBOL_NAME powf
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME powf
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_powf, __powf, IFUNC_SELECTOR ());
+ 
+-#ifdef SHARED
++# ifdef SHARED
+ __hidden_ver1 (__powf, __GI___powf, __redirect_powf)
+   __attribute__ ((visibility ("hidden")));
+ 
+ versioned_symbol (libm, __ieee754_powf, powf, GLIBC_2_27);
+ libm_alias_float_other (__pow, pow)
+-#else
++# else
+ libm_alias_float (__pow, pow)
+-#endif
++# endif
+ 
+ strong_alias (__powf, __ieee754_powf)
+ libm_alias_finite (__powf, __powf)
+ 
+-#define __powf __powf_sse2
++# define __powf __powf_sse2
++#endif
+ #include <sysdeps/ieee754/flt-32/e_powf.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_atan.c b/sysdeps/x86_64/fpu/multiarch/s_atan.c
+index 71bad096a9da60fe..4d2c6ce0060b6d8f 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_atan.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_atan.c
+@@ -16,15 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+ extern double __redirect_atan (double);
+ 
+-#define SYMBOL_NAME atan
+-#include "ifunc-avx-fma4.h"
++# define SYMBOL_NAME atan
++# include "ifunc-avx-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_atan, __atan, IFUNC_SELECTOR ());
+ libm_alias_double (__atan, atan)
+ 
+-#define __atan __atan_sse2
++# define __atan __atan_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/s_atan.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S b/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S
+new file mode 100644
+index 0000000000000000..e6c1106753f29600
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of ceil function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-double.h>
++
++	.text
++ENTRY(__ceil)
++	vroundsd $10, %xmm0, %xmm0, %xmm0
++	ret
++END(__ceil)
++
++libm_alias_double (__ceil, ceil)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
+index 64119011add00832..dba756c38f47b871 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
++# define __ceil_sse41 __ceil
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__ceil_sse41)
+ 	roundsd	$10, %xmm0, %xmm0
+ 	ret
+ END(__ceil_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_double (__ceil, ceil)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil.c b/sysdeps/x86_64/fpu/multiarch/s_ceil.c
+index cc028addee82f19c..46c8e91e199311db 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_ceil.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_ceil.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-double.h>
+ 
+-#define ceil __redirect_ceil
+-#define __ceil __redirect___ceil
+-#include <math.h>
+-#undef ceil
+-#undef __ceil
++# define ceil __redirect_ceil
++# define __ceil __redirect___ceil
++# include <math.h>
++# undef ceil
++# undef __ceil
+ 
+-#define SYMBOL_NAME ceil
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME ceil
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_ceil, __ceil, IFUNC_SELECTOR ());
+ libm_alias_double (__ceil, ceil)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S
+new file mode 100644
+index 0000000000000000..b4d8ac045569900c
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of ceilf function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-float.h>
++
++	.text
++ENTRY(__ceilf)
++	vroundss $10, %xmm0, %xmm0, %xmm0
++	ret
++END(__ceilf)
++
++libm_alias_float (__ceil, ceil)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
+index dd9a9f6b71449fc4..9abc87b91afafcbb 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# define __ceilf_sse41 __ceilf
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__ceilf_sse41)
+ 	roundss	$10, %xmm0, %xmm0
+ 	ret
+ END(__ceilf_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_float (__ceil, ceil)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf.c b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
+index 97a0ca7d19a0d8dd..bb53108f73c00fd0 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-float.h>
+ 
+-#define ceilf __redirect_ceilf
+-#define __ceilf __redirect___ceilf
+-#include <math.h>
+-#undef ceilf
+-#undef __ceilf
++# define ceilf __redirect_ceilf
++# define __ceilf __redirect___ceilf
++# include <math.h>
++# undef ceilf
++# undef __ceilf
+ 
+-#define SYMBOL_NAME ceilf
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME ceilf
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_ceilf, __ceilf, IFUNC_SELECTOR ());
+ libm_alias_float (__ceil, ceil)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_cosf.c b/sysdeps/x86_64/fpu/multiarch/s_cosf.c
+index 2703c576dfa715ce..8a02e04538841602 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_cosf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_cosf.c
+@@ -16,13 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
+ 
+ extern float __redirect_cosf (float);
+ 
+-#define SYMBOL_NAME cosf
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME cosf
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_cosf, __cosf, IFUNC_SELECTOR ());
+ 
+ libm_alias_float (__cos, cos)
++#else
++# include <sysdeps/ieee754/flt-32/s_cosf.c>
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_expm1.c b/sysdeps/x86_64/fpu/multiarch/s_expm1.c
+index 8a2d69f9b28fb03d..d58ef3d8f5e7933f 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_expm1.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_expm1.c
+@@ -16,21 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+ extern double __redirect_expm1 (double);
+ 
+-#define SYMBOL_NAME expm1
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME expm1
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_expm1, __expm1, IFUNC_SELECTOR ());
+ libm_alias_double (__expm1, expm1)
+ 
+-#define __expm1 __expm1_sse2
++# define __expm1 __expm1_sse2
+ 
+ /* NB: __expm1 may be expanded to __expm1_sse2 in the following
+    prototypes.  */
+ extern long double __expm1l (long double);
+ extern long double __expm1f128 (long double);
+ 
++#endif
+ #include <sysdeps/ieee754/dbl-64/s_expm1.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S b/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S
+new file mode 100644
+index 0000000000000000..ff74b5a8bfe69423
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of floor function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-double.h>
++
++	.text
++ENTRY(__floor)
++	vroundsd $9, %xmm0, %xmm0, %xmm0
++	ret
++END(__floor)
++
++libm_alias_double (__floor, floor)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
+index 2f7521f39f5e1c63..c9b9b0639bd24182 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
++# define __floor_sse41 __floor
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__floor_sse41)
+ 	roundsd	$9, %xmm0, %xmm0
+ 	ret
+ END(__floor_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_double (__floor, floor)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor.c b/sysdeps/x86_64/fpu/multiarch/s_floor.c
+index 8cebd48e1008af6e..2c87dd0056419492 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_floor.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_floor.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-double.h>
+ 
+-#define floor __redirect_floor
+-#define __floor __redirect___floor
+-#include <math.h>
+-#undef floor
+-#undef __floor
++# define floor __redirect_floor
++# define __floor __redirect___floor
++# include <math.h>
++# undef floor
++# undef __floor
+ 
+-#define SYMBOL_NAME floor
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME floor
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_floor, __floor, IFUNC_SELECTOR ());
+ libm_alias_double (__floor, floor)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S
+new file mode 100644
+index 0000000000000000..c378baae8e9c7ac7
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of floorf function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-float.h>
++
++	.text
++ENTRY(__floorf)
++	vroundss $9, %xmm0, %xmm0, %xmm0
++	ret
++END(__floorf)
++
++libm_alias_float (__floor, floor)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
+index 5f6020d27daceb80..c2216899db7b71a3 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# define __floorf_sse41 __floorf
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__floorf_sse41)
+ 	roundss	$9, %xmm0, %xmm0
+ 	ret
+ END(__floorf_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_float (__floor, floor)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf.c b/sysdeps/x86_64/fpu/multiarch/s_floorf.c
+index a14e18b03c1a1dc9..a277802b6ddc1dfd 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_floorf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_floorf.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-float.h>
+ 
+-#define floorf __redirect_floorf
+-#define __floorf __redirect___floorf
+-#include <math.h>
+-#undef floorf
+-#undef __floorf
++# define floorf __redirect_floorf
++# define __floorf __redirect___floorf
++# include <math.h>
++# undef floorf
++# undef __floorf
+ 
+-#define SYMBOL_NAME floorf
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME floorf
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_floorf, __floorf, IFUNC_SELECTOR ());
+ libm_alias_float (__floor, floor)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_log1p.c b/sysdeps/x86_64/fpu/multiarch/s_log1p.c
+index a8e1a3f21b17236c..3fa1185d81af33e7 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_log1p.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_log1p.c
+@@ -16,14 +16,17 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+ extern double __redirect_log1p (double);
+ 
+-#define SYMBOL_NAME log1p
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME log1p
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_log1p, __log1p, IFUNC_SELECTOR ());
+ 
+-#define __log1p __log1p_sse2
++# define __log1p __log1p_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/s_log1p.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S
+new file mode 100644
+index 0000000000000000..5bfdf73c28b34350
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of nearbyint function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-double.h>
++
++	.text
++ENTRY(__nearbyint)
++	vroundsd $0xc, %xmm0, %xmm0, %xmm0
++	ret
++END(__nearbyint)
++
++libm_alias_double (__nearbyint, nearbyint)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
+index 674f7eb40abb33d9..9d84410a1f347b7a 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
++# define __nearbyint_sse41 __nearbyint
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__nearbyint_sse41)
+ 	roundsd	$0xc, %xmm0, %xmm0
+ 	ret
+ END(__nearbyint_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_double (__nearbyint, nearbyint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
+index 693e42dd4edffcc1..057a7ca60f0853cf 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+-#define nearbyint __redirect_nearbyint
+-#define __nearbyint __redirect___nearbyint
+-#include <math.h>
+-#undef nearbyint
+-#undef __nearbyint
++# define nearbyint __redirect_nearbyint
++# define __nearbyint __redirect___nearbyint
++# include <math.h>
++# undef nearbyint
++# undef __nearbyint
+ 
+-#define SYMBOL_NAME nearbyint
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME nearbyint
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_nearbyint, __nearbyint,
+ 		       IFUNC_SELECTOR ());
+ libm_alias_double (__nearbyint, nearbyint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S
+new file mode 100644
+index 0000000000000000..1dbaed0324daa024
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implmentation of nearbyintf function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-float.h>
++
++	.text
++ENTRY(__nearbyintf)
++	vroundss $0xc, %xmm0, %xmm0, %xmm0
++	ret
++END(__nearbyintf)
++
++libm_alias_float (__nearbyint, nearbyint)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
+index 5892bd756366f076..3cf35f92d6a0ea9b 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# define __nearbyintf_sse41 __nearbyintf
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__nearbyintf_sse41)
+ 	roundss	$0xc, %xmm0, %xmm0
+ 	ret
+ END(__nearbyintf_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_float (__nearbyint, nearbyint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
+index a0ac009f4bd43baa..41f374ba72902bcf 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
+ 
+-#define nearbyintf __redirect_nearbyintf
+-#define __nearbyintf __redirect___nearbyintf
+-#include <math.h>
+-#undef nearbyintf
+-#undef __nearbyintf
++# define nearbyintf __redirect_nearbyintf
++# define __nearbyintf __redirect___nearbyintf
++# include <math.h>
++# undef nearbyintf
++# undef __nearbyintf
+ 
+-#define SYMBOL_NAME nearbyintf
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME nearbyintf
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_nearbyintf, __nearbyintf,
+ 		       IFUNC_SELECTOR ());
+ libm_alias_float (__nearbyint, nearbyint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S b/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S
+new file mode 100644
+index 0000000000000000..2b403b331f145221
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of rint function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-double.h>
++
++	.text
++ENTRY(__rint)
++	vroundsd $4, %xmm0, %xmm0, %xmm0
++	ret
++END(__rint)
++
++libm_alias_double (__rint, rint)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
+index 405372991bfac3d0..8cd9cf759f3ac70c 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
++# define __rint_sse41 __rint
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__rint_sse41)
+ 	roundsd	$4, %xmm0, %xmm0
+ 	ret
+ END(__rint_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_double (__rint, rint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint.c b/sysdeps/x86_64/fpu/multiarch/s_rint.c
+index 754c87e004f4b006..18623b7d99d1a26e 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_rint.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_rint.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-double.h>
+ 
+-#define rint __redirect_rint
+-#define __rint __redirect___rint
+-#include <math.h>
+-#undef rint
+-#undef __rint
++# define rint __redirect_rint
++# define __rint __redirect___rint
++# include <math.h>
++# undef rint
++# undef __rint
+ 
+-#define SYMBOL_NAME rint
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME rint
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_rint, __rint, IFUNC_SELECTOR ());
+ libm_alias_double (__rint, rint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S
+new file mode 100644
+index 0000000000000000..171c2867f4ab4e3c
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of rintf function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-float.h>
++
++	.text
++ENTRY(__rintf)
++	vroundss $4, %xmm0, %xmm0, %xmm0
++	ret
++END(__rintf)
++
++libm_alias_float (__rint, rint)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
+index 8ac67ce7673d2aca..fc1e70f0c9a068e4 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# define __rintf_sse41 __rintf
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__rintf_sse41)
+ 	roundss	$4, %xmm0, %xmm0
+ 	ret
+ END(__rintf_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_float (__rint, rint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf.c b/sysdeps/x86_64/fpu/multiarch/s_rintf.c
+index e9d6b7a5f2080b8b..e275368decba8359 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_rintf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_rintf.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-float.h>
+ 
+-#define rintf __redirect_rintf
+-#define __rintf __redirect___rintf
+-#include <math.h>
+-#undef rintf
+-#undef __rintf
++# define rintf __redirect_rintf
++# define __rintf __redirect___rintf
++# include <math.h>
++# undef rintf
++# undef __rintf
+ 
+-#define SYMBOL_NAME rintf
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME rintf
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_rintf, __rintf, IFUNC_SELECTOR ());
+ libm_alias_float (__rint, rint)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S
+new file mode 100644
+index 0000000000000000..576790355c6b493f
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of roundeven function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-double.h>
++
++	.text
++ENTRY(__roundeven)
++	vroundsd $8, %xmm0, %xmm0, %xmm0
++	ret
++END(__roundeven)
++
++libm_alias_double (__roundeven, roundeven)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
+index 5ef102336bfa9e2b..f00be56c592a614d 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
++# define __roundeven_sse41 __roundeven
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__roundeven_sse41)
+ 	roundsd	$8, %xmm0, %xmm0
+ 	ret
+ END(__roundeven_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_double (__roundeven, roundeven)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
+index 8737b32e2604290a..139aad088f59c957 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
+@@ -16,16 +16,19 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+-#define roundeven __redirect_roundeven
+-#define __roundeven __redirect___roundeven
+-#include <math.h>
+-#undef roundeven
+-#undef __roundeven
++# define roundeven __redirect_roundeven
++# define __roundeven __redirect___roundeven
++# include <math.h>
++# undef roundeven
++# undef __roundeven
+ 
+-#define SYMBOL_NAME roundeven
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME roundeven
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_roundeven, __roundeven, IFUNC_SELECTOR ());
+ libm_alias_double (__roundeven, roundeven)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S
+new file mode 100644
+index 0000000000000000..42c359f4cd04fc56
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of roundevenf function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-float.h>
++
++	.text
++ENTRY(__roundevenf)
++	vroundss $8, %xmm0, %xmm0, %xmm0
++	ret
++END(__roundevenf)
++
++libm_alias_float (__roundeven, roundeven)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
+index 792c90ba07a3f985..6b148e435316816f 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
+@@ -17,8 +17,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# define __roundevenf_sse41 __roundevenf
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__roundevenf_sse41)
+ 	roundss	$8, %xmm0, %xmm0
+ 	ret
+ END(__roundevenf_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_float (__roundeven, roundeven)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
+index e96016a4d5ba7b39..2fb090075d328ae8 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
+@@ -16,16 +16,19 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
+ 
+-#define roundevenf __redirect_roundevenf
+-#define __roundevenf __redirect___roundevenf
+-#include <math.h>
+-#undef roundevenf
+-#undef __roundevenf
++# define roundevenf __redirect_roundevenf
++# define __roundevenf __redirect___roundevenf
++# include <math.h>
++# undef roundevenf
++# undef __roundevenf
+ 
+-#define SYMBOL_NAME roundevenf
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME roundevenf
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_roundevenf, __roundevenf, IFUNC_SELECTOR ());
+ libm_alias_float (__roundeven, roundeven)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_sin.c b/sysdeps/x86_64/fpu/multiarch/s_sin.c
+index 355cc0092eda46a6..21e77943a3662cd6 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_sin.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_sin.c
+@@ -16,24 +16,27 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+ extern double __redirect_sin (double);
+ extern double __redirect_cos (double);
+ 
+-#define SYMBOL_NAME sin
+-#include "ifunc-avx-fma4.h"
++# define SYMBOL_NAME sin
++# include "ifunc-avx-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_sin, __sin, IFUNC_SELECTOR ());
+ libm_alias_double (__sin, sin)
+ 
+-#undef SYMBOL_NAME
+-#define SYMBOL_NAME cos
+-#include "ifunc-avx-fma4.h"
++# undef SYMBOL_NAME
++# define SYMBOL_NAME cos
++# include "ifunc-avx-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_cos, __cos, IFUNC_SELECTOR ());
+ libm_alias_double (__cos, cos)
+ 
+-#define __cos __cos_sse2
+-#define __sin __sin_sse2
++# define __cos __cos_sse2
++# define __sin __sin_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/s_sin.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_sincos.c b/sysdeps/x86_64/fpu/multiarch/s_sincos.c
+index 70107e999c39da91..b35757f8de4f9d2d 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_sincos.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_sincos.c
+@@ -16,15 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+ extern void __redirect_sincos (double, double *, double *);
+ 
+-#define SYMBOL_NAME sincos
+-#include "ifunc-fma4.h"
++# define SYMBOL_NAME sincos
++# include "ifunc-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_sincos, __sincos, IFUNC_SELECTOR ());
+ libm_alias_double (__sincos, sincos)
+ 
+-#define __sincos __sincos_sse2
++# define __sincos __sincos_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/s_sincos.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_sincosf.c b/sysdeps/x86_64/fpu/multiarch/s_sincosf.c
+index 80bc028451e5153c..0ea9b40e844a2b22 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_sincosf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_sincosf.c
+@@ -16,13 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
+ 
+ extern void __redirect_sincosf (float, float *, float *);
+ 
+-#define SYMBOL_NAME sincosf
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME sincosf
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_sincosf, __sincosf, IFUNC_SELECTOR ());
+ 
+ libm_alias_float (__sincos, sincos)
++#else
++# include <sysdeps/ieee754/flt-32/s_sincosf.c>
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_sinf.c b/sysdeps/x86_64/fpu/multiarch/s_sinf.c
+index a32b9e955052c296..c61624e3eed441dd 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_sinf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_sinf.c
+@@ -16,13 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-float.h>
+ 
+ extern float __redirect_sinf (float);
+ 
+-#define SYMBOL_NAME sinf
+-#include "ifunc-fma.h"
++# define SYMBOL_NAME sinf
++# include "ifunc-fma.h"
+ 
+ libc_ifunc_redirected (__redirect_sinf, __sinf, IFUNC_SELECTOR ());
+ 
+ libm_alias_float (__sin, sin)
++#else
++# include <sysdeps/ieee754/flt-32/s_sinf.c>
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_tan.c b/sysdeps/x86_64/fpu/multiarch/s_tan.c
+index f9a2474a139b0807..125d992ba1fb01ea 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_tan.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_tan.c
+@@ -16,15 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
++# include <libm-alias-double.h>
+ 
+ extern double __redirect_tan (double);
+ 
+-#define SYMBOL_NAME tan
+-#include "ifunc-avx-fma4.h"
++# define SYMBOL_NAME tan
++# include "ifunc-avx-fma4.h"
+ 
+ libc_ifunc_redirected (__redirect_tan, __tan, IFUNC_SELECTOR ());
+ libm_alias_double (__tan, tan)
+ 
+-#define __tan __tan_sse2
++# define __tan __tan_sse2
++#endif
+ #include <sysdeps/ieee754/dbl-64/s_tan.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S b/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S
+new file mode 100644
+index 0000000000000000..b3e87e96068e5404
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of trunc function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-double.h>
++
++	.text
++ENTRY(__trunc)
++	vroundsd $11, %xmm0, %xmm0, %xmm0
++	ret
++END(__trunc)
++
++libm_alias_double (__trunc, trunc)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S
+index b496a6ef49ac5d1c..2b79174eeda798f8 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S
+@@ -18,8 +18,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-double.h>
++# define __trunc_sse41 __trunc
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__trunc_sse41)
+ 	roundsd	$11, %xmm0, %xmm0
+ 	ret
+ END(__trunc_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_double (__trunc, trunc)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc.c b/sysdeps/x86_64/fpu/multiarch/s_trunc.c
+index 9bc9df8744dd56b0..ea89c4f85d9c9dbd 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_trunc.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_trunc.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-double.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-double.h>
+ 
+-#define trunc __redirect_trunc
+-#define __trunc __redirect___trunc
+-#include <math.h>
+-#undef trunc
+-#undef __trunc
++# define trunc __redirect_trunc
++# define __trunc __redirect___trunc
++# include <math.h>
++# undef trunc
++# undef __trunc
+ 
+-#define SYMBOL_NAME trunc
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME trunc
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_trunc, __trunc, IFUNC_SELECTOR ());
+ libm_alias_double (__trunc, trunc)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S
+new file mode 100644
+index 0000000000000000..f31ac7d7f7980f2e
+--- /dev/null
++++ b/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S
+@@ -0,0 +1,28 @@
++/* AVX implementation of truncf function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++#include <libm-alias-float.h>
++
++	.text
++ENTRY(__truncf)
++	vroundss $11, %xmm0, %xmm0, %xmm0
++	ret
++END(__truncf)
++
++libm_alias_float (__trunc, trunc)
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S
+index 22e9a8330746da2f..60498b2cb21a97fa 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S
++++ b/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S
+@@ -18,8 +18,20 @@
+ 
+ #include <sysdep.h>
+ 
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++# include <libm-alias-float.h>
++# define __truncf_sse41 __truncf
++	.text
++#else
+ 	.section .text.sse4.1,"ax",@progbits
++#endif
++
+ ENTRY(__truncf_sse41)
+ 	roundss	$11, %xmm0, %xmm0
+ 	ret
+ END(__truncf_sse41)
++
++#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
++libm_alias_float (__trunc, trunc)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf.c b/sysdeps/x86_64/fpu/multiarch/s_truncf.c
+index dae01d166a0dfa13..92435ce39dbd7cca 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_truncf.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_truncf.c
+@@ -16,17 +16,20 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#define NO_MATH_REDIRECT
+-#include <libm-alias-float.h>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
++# define NO_MATH_REDIRECT
++# include <libm-alias-float.h>
+ 
+-#define truncf __redirect_truncf
+-#define __truncf __redirect___truncf
+-#include <math.h>
+-#undef truncf
+-#undef __truncf
++# define truncf __redirect_truncf
++# define __truncf __redirect___truncf
++# include <math.h>
++# undef truncf
++# undef __truncf
+ 
+-#define SYMBOL_NAME truncf
+-#include "ifunc-sse4_1.h"
++# define SYMBOL_NAME truncf
++# include "ifunc-sse4_1.h"
+ 
+ libc_ifunc_redirected (__redirect_truncf, __truncf, IFUNC_SELECTOR ());
+ libm_alias_float (__trunc, trunc)
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/w_exp.c b/sysdeps/x86_64/fpu/multiarch/w_exp.c
+index 27eee98a0a3e16f0..3584187e0e223195 100644
+--- a/sysdeps/x86_64/fpu/multiarch/w_exp.c
++++ b/sysdeps/x86_64/fpu/multiarch/w_exp.c
+@@ -1 +1,6 @@
+-#include <sysdeps/../math/w_exp.c>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL
++# include <sysdeps/ieee754/dbl-64/w_exp.c>
++#else
++# include <sysdeps/../math/w_exp.c>
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/w_log.c b/sysdeps/x86_64/fpu/multiarch/w_log.c
+index 9b2b0187116bc48e..414ca3ca3ddf530a 100644
+--- a/sysdeps/x86_64/fpu/multiarch/w_log.c
++++ b/sysdeps/x86_64/fpu/multiarch/w_log.c
+@@ -1 +1,6 @@
+-#include <sysdeps/../math/w_log.c>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL
++# include <sysdeps/ieee754/dbl-64/w_log.c>
++#else
++# include <sysdeps/../math/w_log.c>
++#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/w_pow.c b/sysdeps/x86_64/fpu/multiarch/w_pow.c
+index b50c1988de597731..d5fcc4f871bd7eea 100644
+--- a/sysdeps/x86_64/fpu/multiarch/w_pow.c
++++ b/sysdeps/x86_64/fpu/multiarch/w_pow.c
+@@ -1 +1,6 @@
+-#include <sysdeps/../math/w_pow.c>
++#include <sysdeps/x86/isa-level.h>
++#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL
++# include <sysdeps/ieee754/dbl-64/w_pow.c>
++#else
++# include <sysdeps/../math/w_pow.c>
++#endif
diff --git a/SOURCES/glibc-upstream-2.39-31.patch b/SOURCES/glibc-upstream-2.39-31.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bf21203d18fe6a2ad13de7ec0d70421b90c16aa1
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-31.patch
@@ -0,0 +1,207 @@
+commit 31da30f23cddd36db29d5b6a1c7619361b271fb4
+Author: Charles Fol <folcharles@gmail.com>
+Date:   Thu Mar 28 12:25:38 2024 -0300
+
+    iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961)
+    
+    ISO-2022-CN-EXT uses escape sequences to indicate character set changes
+    (as specified by RFC 1922).  While the SOdesignation has the expected
+    bounds checks, neither SS2designation nor SS3designation have its;
+    allowing a write overflow of 1, 2, or 3 bytes with fixed values:
+    '$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'.
+    
+    Checked on aarch64-linux-gnu.
+    
+    Co-authored-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    Tested-by: Carlos O'Donell <carlos@redhat.com>
+    
+    (cherry picked from commit f9dc609e06b1136bb0408be9605ce7973a767ada)
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index ea019ce5c0e67e98..7196a8744bb66e8c 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -75,7 +75,8 @@ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+ 	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
+ 	bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \
+-	bug-iconv13 bug-iconv14 bug-iconv15
++	bug-iconv13 bug-iconv14 bug-iconv15 \
++	tst-iconv-iso-2022-cn-ext
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -330,6 +331,8 @@ $(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)tst-iconv-iso-2022-cn-ext.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/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
+index b34c8a36f4564c11..cce29b19692263d6 100644
+--- a/iconvdata/iso-2022-cn-ext.c
++++ b/iconvdata/iso-2022-cn-ext.c
+@@ -574,6 +574,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+ 	      {								      \
+ 		const char *escseq;					      \
+ 									      \
++		if (outptr + 4 > outend)				      \
++		  {							      \
++		    result = __GCONV_FULL_OUTPUT;			      \
++		    break;						      \
++		  }							      \
++									      \
+ 		assert (used == CNS11643_2_set); /* XXX */		      \
+ 		escseq = "*H";						      \
+ 		*outptr++ = ESC;					      \
+@@ -587,6 +593,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+ 	      {								      \
+ 		const char *escseq;					      \
+ 									      \
++		if (outptr + 4 > outend)				      \
++		  {							      \
++		    result = __GCONV_FULL_OUTPUT;			      \
++		    break;						      \
++		  }							      \
++									      \
+ 		assert ((used >> 5) >= 3 && (used >> 5) <= 7);		      \
+ 		escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2;		      \
+ 		*outptr++ = ESC;					      \
+diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c
+new file mode 100644
+index 0000000000000000..96a8765fd5369681
+--- /dev/null
++++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c
+@@ -0,0 +1,128 @@
++/* Verify ISO-2022-CN-EXT does not write out of the bounds.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <string.h>
++
++#include <errno.h>
++#include <iconv.h>
++#include <sys/mman.h>
++
++#include <support/xunistd.h>
++#include <support/check.h>
++#include <support/support.h>
++
++/* The test sets up a two memory page buffer with the second page marked
++   PROT_NONE to trigger a fault if the conversion writes beyond the exact
++   expected amount.  Then we carry out various conversions and precisely
++   place the start of the output buffer in order to trigger a SIGSEGV if the
++   process writes anywhere between 1 and page sized bytes more (only one
++   PROT_NONE page is setup as a canary) than expected.  These tests exercise
++   all three of the cases in ISO-2022-CN-EXT where the converter must switch
++   character sets and may run out of buffer space while doing the
++   operation.  */
++
++static int
++do_test (void)
++{
++  iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8");
++  TEST_VERIFY_EXIT (cd != (iconv_t) -1);
++
++  char *ntf;
++  size_t ntfsize;
++  char *outbufbase;
++  {
++    int pgz = getpagesize ();
++    TEST_VERIFY_EXIT (pgz > 0);
++    ntfsize = 2 * pgz;
++
++    ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE
++		 | MAP_ANONYMOUS, -1);
++    xmprotect (ntf + pgz, pgz, PROT_NONE);
++
++    outbufbase = ntf + pgz;
++  }
++
++  /* Check if SOdesignation escape sequence does not trigger an OOB write.  */
++  {
++    char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2";
++
++    for (int i = 0; i < 9; i++)
++      {
++	char *inp = inbuf;
++	size_t inleft = sizeof (inbuf) - 1;
++
++	char *outp = outbufbase - i;
++	size_t outleft = i;
++
++	TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
++			  == (size_t) -1);
++	TEST_COMPARE (errno, E2BIG);
++
++	TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
++      }
++  }
++
++  /* Same as before for SS2designation.  */
++  {
++    char inbuf[] = "ã´½ \xe3\xb4\xbd";
++
++    for (int i = 0; i < 14; i++)
++      {
++	char *inp = inbuf;
++	size_t inleft = sizeof (inbuf) - 1;
++
++	char *outp = outbufbase - i;
++	size_t outleft = i;
++
++	TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
++			  == (size_t) -1);
++	TEST_COMPARE (errno, E2BIG);
++
++	TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
++      }
++  }
++
++  /* Same as before for SS3designation.  */
++  {
++    char inbuf[] = "劄 \xe5\x8a\x84";
++
++    for (int i = 0; i < 14; i++)
++      {
++	char *inp = inbuf;
++	size_t inleft = sizeof (inbuf) - 1;
++
++	char *outp = outbufbase - i;
++	size_t outleft = i;
++
++	TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
++			  == (size_t) -1);
++	TEST_COMPARE (errno, E2BIG);
++
++	TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
++      }
++  }
++
++  TEST_VERIFY_EXIT (iconv_close (cd) != -1);
++
++  xmunmap (ntf, ntfsize);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.39-32.patch b/SOURCES/glibc-upstream-2.39-32.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f5cf970df2e524b055f0f271820cf411b773b579
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-32.patch
@@ -0,0 +1,49 @@
+commit e828914cf9f2fc2caa5bced0fc6a03cb78324979
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Apr 23 21:16:32 2024 +0200
+
+    nptl: Fix tst-cancel30 on kernels without ppoll_time64 support
+    
+    Fall back to ppoll if ppoll_time64 fails with ENOSYS.
+    Fixes commit 370da8a121c3ba9eeb2f13da15fc0f21f4136b25 ("nptl: Fix
+    tst-cancel30 on sparc64").
+    
+    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+    (cherry picked from commit f4724843ada64a51d66f65d3199fe431f9d4c254)
+
+diff --git a/sysdeps/pthread/tst-cancel30.c b/sysdeps/pthread/tst-cancel30.c
+index 3030660e5fd93e2c..94ad6281bcf080f4 100644
+--- a/sysdeps/pthread/tst-cancel30.c
++++ b/sysdeps/pthread/tst-cancel30.c
+@@ -18,6 +18,7 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
++#include <errno.h>
+ #include <support/check.h>
+ #include <support/xstdio.h>
+ #include <support/xthread.h>
+@@ -46,13 +47,19 @@ tf (void *arg)
+ 
+   /* Wait indefinitely for cancellation, which only works if asynchronous
+      cancellation is enabled.  */
+-#if defined SYS_ppoll || defined SYS_ppoll_time64
+-# ifndef SYS_ppoll_time64
+-#  define SYS_ppoll_time64 SYS_ppoll
++#ifdef SYS_ppoll_time64
++  long int ret = syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL);
++  (void) ret;
++# ifdef SYS_ppoll
++  if (ret == -1 && errno == ENOSYS)
++    syscall (SYS_ppoll, NULL, 0, NULL, NULL);
+ # endif
+-  syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL);
+ #else
++# ifdef SYS_ppoll
++  syscall (SYS_ppoll, NULL, 0, NULL, NULL);
++# else
+   for (;;);
++# endif
+ #endif
+ 
+   return 0;
diff --git a/SOURCES/glibc-upstream-2.39-33.patch b/SOURCES/glibc-upstream-2.39-33.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a13dbfa219de8f15ba08d8f62737b39769028dd0
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-33.patch
@@ -0,0 +1,20 @@
+commit e701c7d761f6e5c48d8e9dd5da88cbe2e94943f4
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 12:56:48 2024 +0200
+
+    i386: ulp update for SSE2 --disable-multi-arch configurations
+    
+    (cherry picked from commit 3a3a4497421422aa854c855cbe5110ca7d598ffc)
+
+diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
+index 84e6686eba5fe79a..f2139fc172ceef7b 100644
+--- a/sysdeps/i386/fpu/libm-test-ulps
++++ b/sysdeps/i386/fpu/libm-test-ulps
+@@ -1232,6 +1232,7 @@ ldouble: 6
+ 
+ Function: "hypot":
+ double: 1
++float: 1
+ float128: 1
+ ldouble: 1
+ 
diff --git a/SOURCES/glibc-upstream-2.39-34.patch b/SOURCES/glibc-upstream-2.39-34.patch
new file mode 100644
index 0000000000000000000000000000000000000000..961feddae648cb1935e15f452a2fd53525f0278d
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-34.patch
@@ -0,0 +1,89 @@
+commit 2f8f157eb0cc7f1d8d9a3fcaa8c55bed53b092a8
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Tue Apr 23 13:59:50 2024 -0700
+
+    x86: Define MINIMUM_X86_ISA_LEVEL in config.h [BZ #31676]
+    
+    Define MINIMUM_X86_ISA_LEVEL at configure time to avoid
+    
+    /usr/bin/ld: …/build/elf/librtld.os: in function `init_cpu_features':
+    …/git/elf/../sysdeps/x86/cpu-features.c:1202: undefined reference to `_dl_runtime_resolve_fxsave'
+    /usr/bin/ld: …/build/elf/librtld.os: relocation R_X86_64_PC32 against undefined hidden symbol `_dl_runtime_resolve_fxsave' can not be used when making a shared object
+    /usr/bin/ld: final link failed: bad value
+    collect2: error: ld returned 1 exit status
+    
+    when glibc is built with -march=x86-64-v3 and configured with
+    --with-rtld-early-cflags=-march=x86-64, which is used to allow ld.so to
+    print an error message on unsupported CPUs:
+    
+    Fatal glibc error: CPU does not support x86-64-v3
+    
+    This fixes BZ #31676.
+    Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
+    
+    (cherry picked from commit 46c999741340ea559784c20a45077955b50aca43)
+
+diff --git a/config.h.in b/config.h.in
+index 4d33c63a841d3d6d..1e647de58580bc2d 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -286,6 +286,9 @@
+ /* Define if x86 ISA level should be included in shared libraries.  */
+ #undef INCLUDE_X86_ISA_LEVEL
+ 
++/* The x86 ISA level.  1 for baseline.  Undefined on non-x86.  */
++#undef MINIMUM_X86_ISA_LEVEL
++
+ /* Define if -msahf is enabled by default on x86.  */
+ #undef HAVE_X86_LAHF_SAHF
+ 
+diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
+index 2a5421bb31e9efe4..d28d9bcb296c6380 100644
+--- a/sysdeps/x86/configure
++++ b/sysdeps/x86/configure
+@@ -151,6 +151,13 @@ printf "%s\n" "$libc_cv_have_x86_isa_level" >&6; }
+ else
+   libc_cv_have_x86_isa_level=baseline
+ fi
++if test $libc_cv_have_x86_isa_level = baseline; then
++  printf "%s\n" "#define MINIMUM_X86_ISA_LEVEL 1" >>confdefs.h
++
++else
++  printf "%s\n" "#define MINIMUM_X86_ISA_LEVEL $libc_cv_have_x86_isa_level" >>confdefs.h
++
++fi
+ config_vars="$config_vars
+ have-x86-isa-level = $libc_cv_have_x86_isa_level"
+ config_vars="$config_vars
+diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
+index 78ff7c8f41c552bc..5b0acd03d2a30c9b 100644
+--- a/sysdeps/x86/configure.ac
++++ b/sysdeps/x86/configure.ac
+@@ -105,6 +105,11 @@ EOF
+ else
+   libc_cv_have_x86_isa_level=baseline
+ fi
++if test $libc_cv_have_x86_isa_level = baseline; then
++  AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, 1)
++else
++  AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, $libc_cv_have_x86_isa_level)
++fi
+ LIBC_CONFIG_VAR([have-x86-isa-level], [$libc_cv_have_x86_isa_level])
+ LIBC_CONFIG_VAR([x86-isa-level-3-or-above], [3 4])
+ LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
+diff --git a/sysdeps/x86/isa-level.h b/sysdeps/x86/isa-level.h
+index 11fe1ca90c5bfedf..2c7f74212b9a27e5 100644
+--- a/sysdeps/x86/isa-level.h
++++ b/sysdeps/x86/isa-level.h
+@@ -61,8 +61,10 @@
+ # define __X86_ISA_V4 0
+ #endif
+ 
+-#define MINIMUM_X86_ISA_LEVEL                                                 \
++#ifndef MINIMUM_X86_ISA_LEVEL
++# define MINIMUM_X86_ISA_LEVEL                                                 \
+   (__X86_ISA_V1 + __X86_ISA_V2 + __X86_ISA_V3 + __X86_ISA_V4)
++#endif
+ 
+ /* Depending on the minimum ISA level, a feature check result can be a
+    compile-time constant.. */
diff --git a/SOURCES/glibc-upstream-2.39-35.patch b/SOURCES/glibc-upstream-2.39-35.patch
new file mode 100644
index 0000000000000000000000000000000000000000..41555b4b95d5a4724a6b8dff401fecd937106b5c
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-35.patch
@@ -0,0 +1,32 @@
+commit 1263d583d2e28afb8be53f8d6922f0842036f35d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 15:00:45 2024 +0200
+
+    CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677)
+    
+    Using alloca matches what other caches do.  The request length is
+    bounded by MAXKEYLEN.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 87801a8fd06db1d654eea3e4f7626ff476a9bdaa)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 0c6e46f15c5d7139..f227dc7fa2856e38 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -502,12 +502,13 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+       = (struct indataset *) mempool_alloc (db,
+ 					    sizeof (*dataset) + req->key_len,
+ 					    1);
+-  struct indataset dataset_mem;
+   bool cacheable = true;
+   if (__glibc_unlikely (dataset == NULL))
+     {
+       cacheable = false;
+-      dataset = &dataset_mem;
++      /* The alloca is safe because nscd_run_worker verfies that
++	 key_len is not larger than MAXKEYLEN.  */
++      dataset = alloca (sizeof (*dataset) + req->key_len);
+     }
+ 
+   datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
diff --git a/SOURCES/glibc-upstream-2.39-36.patch b/SOURCES/glibc-upstream-2.39-36.patch
new file mode 100644
index 0000000000000000000000000000000000000000..28518451e5a216430b926394a6e09a2c6bbf4db4
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-36.patch
@@ -0,0 +1,53 @@
+commit 5a508e0b508c8ad53bd0d2fb48fd71b242626341
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 15:01:07 2024 +0200
+
+    CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX (bug 31678)
+    
+    If we failed to add a not-found response to the cache, the dataset
+    point can be null, resulting in a null pointer dereference.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 7835b00dbce53c3c87bbbb1754a95fb5e58187aa)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index f227dc7fa2856e38..c18fe111f37496d7 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -147,7 +147,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+       /* No such service.  */
+       cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ 			       &key_copy);
+-      goto writeout;
++      goto maybe_cache_add;
+     }
+ 
+   memset (&data, '\0', sizeof (data));
+@@ -348,7 +348,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+     {
+       cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ 			       &key_copy);
+-      goto writeout;
++      goto maybe_cache_add;
+     }
+ 
+   total = buffilled;
+@@ -410,14 +410,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+   }
+ 
+   if (he == NULL && fd != -1)
+-    {
+-      /* We write the dataset before inserting it to the database
+-	 since while inserting this thread might block and so would
+-	 unnecessarily let the receiver wait.  */
+-    writeout:
++    /* We write the dataset before inserting it to the database since
++       while inserting this thread might block and so would
++       unnecessarily let the receiver wait.  */
+       writeall (fd, &dataset->resp, dataset->head.recsize);
+-    }
+ 
++ maybe_cache_add:
+   if (cacheable)
+     {
+       /* If necessary, we also propagate the data to disk.  */
diff --git a/SOURCES/glibc-upstream-2.39-37.patch b/SOURCES/glibc-upstream-2.39-37.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b0a31a8c4db6604887b1516dac24abbf8409cf13
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-37.patch
@@ -0,0 +1,54 @@
+commit c99f886de54446cd4447db6b44be93dabbdc2f8b
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 15:01:07 2024 +0200
+
+    CVE-2024-33600: nscd: Avoid null pointer crashes after notfound response (bug 31678)
+    
+    The addgetnetgrentX call in addinnetgrX may have failed to produce
+    a result, so the result variable in addinnetgrX can be NULL.
+    Use db->negtimeout as the fallback value if there is no result data;
+    the timeout is also overwritten below.
+    
+    Also avoid sending a second not-found response.  (The client
+    disconnects after receiving the first response, so the data stream did
+    not go out of sync even without this fix.)  It is still beneficial to
+    add the negative response to the mapping, so that the client can get
+    it from there in the future, instead of going through the socket.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit b048a482f088e53144d26a61c390bed0210f49f2)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index c18fe111f37496d7..e22ffa5884e36260 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -511,14 +511,15 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ 
+   datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
+ 		     sizeof (innetgroup_response_header),
+-		     he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
++		     he == NULL ? 0 : dh->nreloads + 1,
++		     result == NULL ? db->negtimeout : result->head.ttl);
+   /* Set the notfound status and timeout based on the result from
+      getnetgrent.  */
+-  dataset->head.notfound = result->head.notfound;
++  dataset->head.notfound = result == NULL || result->head.notfound;
+   dataset->head.timeout = timeout;
+ 
+   dataset->resp.version = NSCD_VERSION;
+-  dataset->resp.found = result->resp.found;
++  dataset->resp.found = result != NULL && result->resp.found;
+   /* Until we find a matching entry the result is 0.  */
+   dataset->resp.result = 0;
+ 
+@@ -566,7 +567,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+       goto out;
+     }
+ 
+-  if (he == NULL)
++  /* addgetnetgrentX may have already sent a notfound response.  Do
++     not send another one.  */
++  if (he == NULL && dataset->resp.found)
+     {
+       /* We write the dataset before inserting it to the database
+ 	 since while inserting this thread might block and so would
diff --git a/SOURCES/glibc-upstream-2.39-38.patch b/SOURCES/glibc-upstream-2.39-38.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5bda08bec4460e176ff103b1feaecd555b27402c
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-38.patch
@@ -0,0 +1,384 @@
+commit a9a8d3eebb145779a18d90e3966009a1daa63cd8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 15:01:07 2024 +0200
+
+    CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX (bug 31680)
+    
+    This avoids potential memory corruption when the underlying NSS
+    callback function does not use the buffer space to store all strings
+    (e.g., for constant strings).
+    
+    Instead of custom buffer management, two scratch buffers are used.
+    This increases stack usage somewhat.
+    
+    Scratch buffer allocation failure is handled by return -1
+    (an invalid timeout value) instead of terminating the process.
+    This fixes bug 31679.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit c04a21e050d64a1193a6daab872bca2528bda44b)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index e22ffa5884e36260..e8fe041846b75cb9 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/mman.h>
++#include <scratch_buffer.h>
+ 
+ #include "../nss/netgroup.h"
+ #include "nscd.h"
+@@ -65,6 +66,16 @@ struct dataset
+   char strdata[0];
+ };
+ 
++/* Send a notfound response to FD.  Always returns -1 to indicate an
++   ephemeral error.  */
++static time_t
++send_notfound (int fd)
++{
++  if (fd != -1)
++    TEMP_FAILURE_RETRY (send (fd, &notfound, sizeof (notfound), MSG_NOSIGNAL));
++  return -1;
++}
++
+ /* Sends a notfound message and prepares a notfound dataset to write to the
+    cache.  Returns true if there was enough memory to allocate the dataset and
+    returns the dataset in DATASETP, total bytes to write in TOTALP and the
+@@ -83,8 +94,7 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
+   total = sizeof (notfound);
+   timeout = time (NULL) + db->negtimeout;
+ 
+-  if (fd != -1)
+-    TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
++  send_notfound (fd);
+ 
+   dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
+   /* If we cannot permanently store the result, so be it.  */
+@@ -109,11 +119,78 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
+   return cacheable;
+ }
+ 
++struct addgetnetgrentX_scratch
++{
++  /* This is the result that the caller should use.  It can be NULL,
++     point into buffer, or it can be in the cache.  */
++  struct dataset *dataset;
++
++  struct scratch_buffer buffer;
++
++  /* Used internally in addgetnetgrentX as a staging area.  */
++  struct scratch_buffer tmp;
++
++  /* Number of bytes in buffer that are actually used.  */
++  size_t buffer_used;
++};
++
++static void
++addgetnetgrentX_scratch_init (struct addgetnetgrentX_scratch *scratch)
++{
++  scratch->dataset = NULL;
++  scratch_buffer_init (&scratch->buffer);
++  scratch_buffer_init (&scratch->tmp);
++
++  /* Reserve space for the header.  */
++  scratch->buffer_used = sizeof (struct dataset);
++  static_assert (sizeof (struct dataset) < sizeof (scratch->tmp.__space),
++		 "initial buffer space");
++  memset (scratch->tmp.data, 0, sizeof (struct dataset));
++}
++
++static void
++addgetnetgrentX_scratch_free (struct addgetnetgrentX_scratch *scratch)
++{
++  scratch_buffer_free (&scratch->buffer);
++  scratch_buffer_free (&scratch->tmp);
++}
++
++/* Copy LENGTH bytes from S into SCRATCH.  Returns NULL if SCRATCH
++   could not be resized, otherwise a pointer to the copy.  */
++static char *
++addgetnetgrentX_append_n (struct addgetnetgrentX_scratch *scratch,
++			  const char *s, size_t length)
++{
++  while (true)
++    {
++      size_t remaining = scratch->buffer.length - scratch->buffer_used;
++      if (remaining >= length)
++	break;
++      if (!scratch_buffer_grow_preserve (&scratch->buffer))
++	return NULL;
++    }
++  char *copy = scratch->buffer.data + scratch->buffer_used;
++  memcpy (copy, s, length);
++  scratch->buffer_used += length;
++  return copy;
++}
++
++/* Copy S into SCRATCH, including its null terminator.  Returns false
++   if SCRATCH could not be resized.  */
++static bool
++addgetnetgrentX_append (struct addgetnetgrentX_scratch *scratch, const char *s)
++{
++  if (s == NULL)
++    s = "";
++  return addgetnetgrentX_append_n (scratch, s, strlen (s) + 1) != NULL;
++}
++
++/* Caller must initialize and free *SCRATCH.  If the return value is
++   negative, this function has sent a notfound response.  */
+ static time_t
+ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 		 const char *key, uid_t uid, struct hashentry *he,
+-		 struct datahead *dh, struct dataset **resultp,
+-		 void **tofreep)
++		 struct datahead *dh, struct addgetnetgrentX_scratch *scratch)
+ {
+   if (__glibc_unlikely (debug_level > 0))
+     {
+@@ -132,14 +209,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 
+   char *key_copy = NULL;
+   struct __netgrent data;
+-  size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
+-  size_t buffilled = sizeof (*dataset);
+-  char *buffer = NULL;
+   size_t nentries = 0;
+   size_t group_len = strlen (key) + 1;
+   struct name_list *first_needed
+     = alloca (sizeof (struct name_list) + group_len);
+-  *tofreep = NULL;
+ 
+   if (netgroup_database == NULL
+       && !__nss_database_get (nss_database_netgroup, &netgroup_database))
+@@ -151,8 +224,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+     }
+ 
+   memset (&data, '\0', sizeof (data));
+-  buffer = xmalloc (buflen);
+-  *tofreep = buffer;
+   first_needed->next = first_needed;
+   memcpy (first_needed->name, key, group_len);
+   data.needed_groups = first_needed;
+@@ -195,8 +266,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 		while (1)
+ 		  {
+ 		    int e;
+-		    status = getfct.f (&data, buffer + buffilled,
+-				       buflen - buffilled - req->key_len, &e);
++		    status = getfct.f (&data, scratch->tmp.data,
++				       scratch->tmp.length, &e);
+ 		    if (status == NSS_STATUS_SUCCESS)
+ 		      {
+ 			if (data.type == triple_val)
+@@ -204,68 +275,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 			    const char *nhost = data.val.triple.host;
+ 			    const char *nuser = data.val.triple.user;
+ 			    const char *ndomain = data.val.triple.domain;
+-
+-			    size_t hostlen = strlen (nhost ?: "") + 1;
+-			    size_t userlen = strlen (nuser ?: "") + 1;
+-			    size_t domainlen = strlen (ndomain ?: "") + 1;
+-
+-			    if (nhost == NULL || nuser == NULL || ndomain == NULL
+-				|| nhost > nuser || nuser > ndomain)
+-			      {
+-				const char *last = nhost;
+-				if (last == NULL
+-				    || (nuser != NULL && nuser > last))
+-				  last = nuser;
+-				if (last == NULL
+-				    || (ndomain != NULL && ndomain > last))
+-				  last = ndomain;
+-
+-				size_t bufused
+-				  = (last == NULL
+-				     ? buffilled
+-				     : last + strlen (last) + 1 - buffer);
+-
+-				/* We have to make temporary copies.  */
+-				size_t needed = hostlen + userlen + domainlen;
+-
+-				if (buflen - req->key_len - bufused < needed)
+-				  {
+-				    buflen += MAX (buflen, 2 * needed);
+-				    /* Save offset in the old buffer.  We don't
+-				       bother with the NULL check here since
+-				       we'll do that later anyway.  */
+-				    size_t nhostdiff = nhost - buffer;
+-				    size_t nuserdiff = nuser - buffer;
+-				    size_t ndomaindiff = ndomain - buffer;
+-
+-				    char *newbuf = xrealloc (buffer, buflen);
+-				    /* Fix up the triplet pointers into the new
+-				       buffer.  */
+-				    nhost = (nhost ? newbuf + nhostdiff
+-					     : NULL);
+-				    nuser = (nuser ? newbuf + nuserdiff
+-					     : NULL);
+-				    ndomain = (ndomain ? newbuf + ndomaindiff
+-					       : NULL);
+-				    *tofreep = buffer = newbuf;
+-				  }
+-
+-				nhost = memcpy (buffer + bufused,
+-						nhost ?: "", hostlen);
+-				nuser = memcpy ((char *) nhost + hostlen,
+-						nuser ?: "", userlen);
+-				ndomain = memcpy ((char *) nuser + userlen,
+-						  ndomain ?: "", domainlen);
+-			      }
+-
+-			    char *wp = buffer + buffilled;
+-			    wp = memmove (wp, nhost ?: "", hostlen);
+-			    wp += hostlen;
+-			    wp = memmove (wp, nuser ?: "", userlen);
+-			    wp += userlen;
+-			    wp = memmove (wp, ndomain ?: "", domainlen);
+-			    wp += domainlen;
+-			    buffilled = wp - buffer;
++			    if (!(addgetnetgrentX_append (scratch, nhost)
++				  && addgetnetgrentX_append (scratch, nuser)
++				  && addgetnetgrentX_append (scratch, ndomain)))
++			      return send_notfound (fd);
+ 			    ++nentries;
+ 			  }
+ 			else
+@@ -317,8 +330,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 		      }
+ 		    else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
+ 		      {
+-			buflen *= 2;
+-			*tofreep = buffer = xrealloc (buffer, buflen);
++			if (!scratch_buffer_grow (&scratch->tmp))
++			  return send_notfound (fd);
+ 		      }
+ 		    else if (status == NSS_STATUS_RETURN
+ 			     || status == NSS_STATUS_NOTFOUND
+@@ -351,10 +364,17 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+       goto maybe_cache_add;
+     }
+ 
+-  total = buffilled;
++  /* Capture the result size without the key appended.   */
++  total = scratch->buffer_used;
++
++  /* Make a copy of the key.  The scratch buffer must not move after
++     this point.  */
++  key_copy = addgetnetgrentX_append_n (scratch, key, req->key_len);
++  if (key_copy == NULL)
++    return send_notfound (fd);
+ 
+   /* Fill in the dataset.  */
+-  dataset = (struct dataset *) buffer;
++  dataset = scratch->buffer.data;
+   timeout = datahead_init_pos (&dataset->head, total + req->key_len,
+ 			       total - offsetof (struct dataset, resp),
+ 			       he == NULL ? 0 : dh->nreloads + 1,
+@@ -363,11 +383,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+   dataset->resp.version = NSCD_VERSION;
+   dataset->resp.found = 1;
+   dataset->resp.nresults = nentries;
+-  dataset->resp.result_len = buffilled - sizeof (*dataset);
+-
+-  assert (buflen - buffilled >= req->key_len);
+-  key_copy = memcpy (buffer + buffilled, key, req->key_len);
+-  buffilled += req->key_len;
++  dataset->resp.result_len = total - sizeof (*dataset);
+ 
+   /* Now we can determine whether on refill we have to create a new
+      record or not.  */
+@@ -398,7 +414,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+     if (__glibc_likely (newp != NULL))
+       {
+ 	/* Adjust pointer into the memory block.  */
+-	key_copy = (char *) newp + (key_copy - buffer);
++	key_copy = (char *) newp + (key_copy - (char *) dataset);
+ 
+ 	dataset = memcpy (newp, dataset, total + req->key_len);
+ 	cacheable = true;
+@@ -439,7 +455,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+     }
+ 
+  out:
+-  *resultp = dataset;
++  scratch->dataset = dataset;
+ 
+   return timeout;
+ }
+@@ -460,6 +476,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+   if (user != NULL)
+     key = strchr (key, '\0') + 1;
+   const char *domain = *key++ ? key : NULL;
++  struct addgetnetgrentX_scratch scratch;
++
++  addgetnetgrentX_scratch_init (&scratch);
+ 
+   if (__glibc_unlikely (debug_level > 0))
+     {
+@@ -475,12 +494,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ 							    group, group_len,
+ 							    db, uid);
+   time_t timeout;
+-  void *tofree;
+   if (result != NULL)
+-    {
+-      timeout = result->head.timeout;
+-      tofree = NULL;
+-    }
++    timeout = result->head.timeout;
+   else
+     {
+       request_header req_get =
+@@ -489,7 +504,10 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ 	  .key_len = group_len
+ 	};
+       timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
+-				 &result, &tofree);
++				 &scratch);
++      result = scratch.dataset;
++      if (timeout < 0)
++	goto out;
+     }
+ 
+   struct indataset
+@@ -603,7 +621,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+     }
+ 
+  out:
+-  free (tofree);
++  addgetnetgrentX_scratch_free (&scratch);
+   return timeout;
+ }
+ 
+@@ -613,11 +631,12 @@ addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
+ 			const char *key, uid_t uid, struct hashentry *he,
+ 			struct datahead *dh)
+ {
+-  struct dataset *ignore;
+-  void *tofree;
+-  time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
+-				    &ignore, &tofree);
+-  free (tofree);
++  struct addgetnetgrentX_scratch scratch;
++  addgetnetgrentX_scratch_init (&scratch);
++  time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, &scratch);
++  addgetnetgrentX_scratch_free (&scratch);
++  if (timeout < 0)
++    timeout = 0;
+   return timeout;
+ }
+ 
+@@ -661,5 +680,9 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
+       .key_len = he->len
+     };
+ 
+-  return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh);
++  int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
++			     he, dh);
++  if (timeout < 0)
++    timeout = 0;
++  return timeout;
+ }
diff --git a/SOURCES/glibc-upstream-2.39-39.patch b/SOURCES/glibc-upstream-2.39-39.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4dee6eafe921fe10b061abce2c6dd4b2b54118a5
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-39.patch
@@ -0,0 +1,49 @@
+commit fd658f026f25cf59e8db243bc3b3e09cd5a20ba0
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Apr 25 08:06:52 2024 -0700
+
+    elf: Also compile dl-misc.os with $(rtld-early-cflags)
+    
+    Also compile dl-misc.os with $(rtld-early-cflags) to avoid
+    
+    Program received signal SIGILL, Illegal instruction.
+    0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2",
+        endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156
+    156       bool positive = true;
+    (gdb) bt
+     #0  0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2",
+        endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156
+     #1  0x00007ffff7fdb1a9 in tunable_initialize (
+        cur=cur@entry=0x7ffff7ffbc00 <tunable_list+2176>,
+        strval=strval@entry=0x7fffffffe2c9 "2", len=len@entry=1)
+        at dl-tunables.c:131
+     #2  0x00007ffff7fdb3a2 in parse_tunables (valstring=<optimized out>)
+        at dl-tunables.c:258
+     #3  0x00007ffff7fdb5d9 in __GI___tunables_init (envp=0x7fffffffdd58)
+        at dl-tunables.c:288
+     #4  0x00007ffff7fe44c3 in _dl_sysdep_start (
+        start_argptr=start_argptr@entry=0x7fffffffdcb0,
+        dl_main=dl_main@entry=0x7ffff7fe5f80 <dl_main>)
+        at ../sysdeps/unix/sysv/linux/dl-sysdep.c:110
+     #5  0x00007ffff7fe5cae in _dl_start_final (arg=0x7fffffffdcb0) at rtld.c:494
+     #6  _dl_start (arg=0x7fffffffdcb0) at rtld.c:581
+     #7  0x00007ffff7fe4b38 in _start ()
+    (gdb)
+    
+    when setting GLIBC_TUNABLES in glibc compiled with APX.
+    Reviewed-by: Florian Weimer <fweimer@redhat.com>
+    
+    (cherry picked from commit 049b7684c912dd32b67b1b15b0f43bf07d5f512e)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 69aa423c4b90127d..a50a988e7362cf3b 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -170,6 +170,7 @@ CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os))
+ CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))
+ 
+ # Add the requested compiler flags to the early startup code.
++CFLAGS-dl-misc.os += $(rtld-early-cflags)
+ CFLAGS-dl-printf.os += $(rtld-early-cflags)
+ CFLAGS-dl-setup_hash.os += $(rtld-early-cflags)
+ CFLAGS-dl-sysdep.os += $(rtld-early-cflags)
diff --git a/SOURCES/glibc-upstream-2.39-40.patch b/SOURCES/glibc-upstream-2.39-40.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c3070ada98ea2748a07f18e7e034320fee0689d3
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-40.patch
@@ -0,0 +1,209 @@
+commit 9831f98c266a8d56d1bf729b709c08e40375540c
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Apr 19 14:38:17 2024 +0200
+
+    login: Check default sizes of structs utmp, utmpx, lastlog
+    
+    The default <utmp-size.h> is for ports with a 64-bit time_t.
+    Ports with a 32-bit time_t or with __WORDSIZE_TIME64_COMPAT32=1
+    need to override it.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    (cherry picked from commit 4d4da5aab936504b2d3eca3146e109630d9093c4)
+
+diff --git a/login/Makefile b/login/Makefile
+index 1e22008a61e99083..b26ac42bfceadf89 100644
+--- a/login/Makefile
++++ b/login/Makefile
+@@ -44,7 +44,7 @@ subdir-dirs = programs
+ vpath %.c programs
+ 
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
+-  tst-pututxline-lockfail tst-pututxline-cache
++  tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size
+ 
+ # Empty compatibility library for old binaries.
+ extra-libs      := libutil
+diff --git a/login/tst-utmp-size.c b/login/tst-utmp-size.c
+new file mode 100644
+index 0000000000000000..1b7f7ff04224efb5
+--- /dev/null
++++ b/login/tst-utmp-size.c
+@@ -0,0 +1,33 @@
++/* Check expected sizes of struct utmp, struct utmpx, struct lastlog.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <utmp.h>
++#include <utmpx.h>
++#include <utmp-size.h>
++
++static int
++do_test (void)
++{
++  _Static_assert (sizeof (struct utmp) == UTMP_SIZE, "struct utmp size");
++  _Static_assert (sizeof (struct utmpx) == UTMP_SIZE, "struct utmpx size");
++  _Static_assert (sizeof (struct lastlog) == LASTLOG_SIZE,
++                  "struct lastlog size");
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/arc/utmp-size.h b/sysdeps/arc/utmp-size.h
+new file mode 100644
+index 0000000000000000..a247fcd3dab15f81
+--- /dev/null
++++ b/sysdeps/arc/utmp-size.h
+@@ -0,0 +1,3 @@
++/* arc has less padding than other architectures with 64-bit time_t.  */
++#define UTMP_SIZE 392
++#define LASTLOG_SIZE 296
+diff --git a/sysdeps/arm/utmp-size.h b/sysdeps/arm/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/arm/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/csky/utmp-size.h b/sysdeps/csky/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/csky/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/generic/utmp-size.h b/sysdeps/generic/utmp-size.h
+new file mode 100644
+index 0000000000000000..89dbe878b02301e9
+--- /dev/null
++++ b/sysdeps/generic/utmp-size.h
+@@ -0,0 +1,23 @@
++/* Expected sizes of utmp-related structures stored in files.  64-bit version.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++/* Expected size, in bytes, of struct utmp and struct utmpx.  */
++#define UTMP_SIZE 400
++
++/* Expected size, in bytes, of struct lastlog.  */
++#define LASTLOG_SIZE 296
+diff --git a/sysdeps/hppa/utmp-size.h b/sysdeps/hppa/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/hppa/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/m68k/utmp-size.h b/sysdeps/m68k/utmp-size.h
+new file mode 100644
+index 0000000000000000..5946685819d60289
+--- /dev/null
++++ b/sysdeps/m68k/utmp-size.h
+@@ -0,0 +1,3 @@
++/* m68k has 2-byte alignment.  */
++#define UTMP_SIZE 382
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/microblaze/utmp-size.h b/sysdeps/microblaze/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/microblaze/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/mips/utmp-size.h b/sysdeps/mips/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/mips/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/nios2/utmp-size.h b/sysdeps/nios2/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/nios2/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/or1k/utmp-size.h b/sysdeps/or1k/utmp-size.h
+new file mode 100644
+index 0000000000000000..6b3653aa4dccd59d
+--- /dev/null
++++ b/sysdeps/or1k/utmp-size.h
+@@ -0,0 +1,3 @@
++/* or1k has less padding than other architectures with 64-bit time_t.  */
++#define UTMP_SIZE 392
++#define LASTLOG_SIZE 296
+diff --git a/sysdeps/powerpc/utmp-size.h b/sysdeps/powerpc/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/powerpc/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/riscv/utmp-size.h b/sysdeps/riscv/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/riscv/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/sh/utmp-size.h b/sysdeps/sh/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/sh/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/sparc/utmp-size.h b/sysdeps/sparc/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/sparc/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
+diff --git a/sysdeps/x86/utmp-size.h b/sysdeps/x86/utmp-size.h
+new file mode 100644
+index 0000000000000000..8f21ebe1b6c26ea1
+--- /dev/null
++++ b/sysdeps/x86/utmp-size.h
+@@ -0,0 +1,2 @@
++#define UTMP_SIZE 384
++#define LASTLOG_SIZE 292
diff --git a/SOURCES/glibc-upstream-2.39-41.patch b/SOURCES/glibc-upstream-2.39-41.patch
new file mode 100644
index 0000000000000000000000000000000000000000..659acb3f6738395bcc4cca146b2585d8a4a393cd
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-41.patch
@@ -0,0 +1,368 @@
+commit 836d43b98973e0845b739ff5d3aad3af09dc7d0f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Apr 19 14:38:17 2024 +0200
+
+    login: structs utmp, utmpx, lastlog _TIME_BITS independence (bug 30701)
+    
+    These structs describe file formats under /var/log, and should not
+    depend on the definition of _TIME_BITS.  This is achieved by
+    defining __WORDSIZE_TIME64_COMPAT32 to 1 on 32-bit ports that
+    support 32-bit time_t values (where __time_t is 32 bits).
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    (cherry picked from commit 9abdae94c7454c45e02e97e4ed1eb1b1915d13d8)
+
+diff --git a/bits/wordsize.h b/bits/wordsize.h
+index 14edae3a11d01c97..53013a9275c7c81e 100644
+--- a/bits/wordsize.h
++++ b/bits/wordsize.h
+@@ -21,7 +21,9 @@
+ #define __WORDSIZE32_PTRDIFF_LONG
+ 
+ /* Set to 1 in order to force time types to be 32 bits instead of 64 bits in
+-   struct lastlog and struct utmp{,x} on 64-bit ports.  This may be done in
++   struct lastlog and struct utmp{,x}.  This may be done in
+    order to make 64-bit ports compatible with 32-bit ports.  Set to 0 for
+-   64-bit ports where the time types are 64-bits or for any 32-bit ports.  */
++   64-bit ports where the time types are 64-bits and new 32-bit ports
++   where time_t is 64 bits, and there is no companion architecture with
++   32-bit time_t.  */
+ #define __WORDSIZE_TIME64_COMPAT32
+diff --git a/login/Makefile b/login/Makefile
+index b26ac42bfceadf89..f91190e3dcd1e6c6 100644
+--- a/login/Makefile
++++ b/login/Makefile
+@@ -44,7 +44,9 @@ subdir-dirs = programs
+ vpath %.c programs
+ 
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
+-  tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size
++  tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64
++
++CFLAGS-tst-utmp-size-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
+ 
+ # Empty compatibility library for old binaries.
+ extra-libs      := libutil
+diff --git a/login/tst-utmp-size-64.c b/login/tst-utmp-size-64.c
+new file mode 100644
+index 0000000000000000..7a581a4c1254644a
+--- /dev/null
++++ b/login/tst-utmp-size-64.c
+@@ -0,0 +1,2 @@
++/* The on-disk layout must not change in time64 mode.  */
++#include "tst-utmp-size.c"
+diff --git a/sysdeps/arm/bits/wordsize.h b/sysdeps/arm/bits/wordsize.h
+new file mode 100644
+index 0000000000000000..6ecbfe7c863f3a17
+--- /dev/null
++++ b/sysdeps/arm/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#define __WORDSIZE			32
++#define __WORDSIZE_TIME64_COMPAT32	1
++#define __WORDSIZE32_SIZE_ULONG		0
++#define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/csky/bits/wordsize.h b/sysdeps/csky/bits/wordsize.h
+new file mode 100644
+index 0000000000000000..6ecbfe7c863f3a17
+--- /dev/null
++++ b/sysdeps/csky/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#define __WORDSIZE			32
++#define __WORDSIZE_TIME64_COMPAT32	1
++#define __WORDSIZE32_SIZE_ULONG		0
++#define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/m68k/bits/wordsize.h b/sysdeps/m68k/bits/wordsize.h
+new file mode 100644
+index 0000000000000000..6ecbfe7c863f3a17
+--- /dev/null
++++ b/sysdeps/m68k/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#define __WORDSIZE			32
++#define __WORDSIZE_TIME64_COMPAT32	1
++#define __WORDSIZE32_SIZE_ULONG		0
++#define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/microblaze/bits/wordsize.h b/sysdeps/microblaze/bits/wordsize.h
+new file mode 100644
+index 0000000000000000..6ecbfe7c863f3a17
+--- /dev/null
++++ b/sysdeps/microblaze/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#define __WORDSIZE			32
++#define __WORDSIZE_TIME64_COMPAT32	1
++#define __WORDSIZE32_SIZE_ULONG		0
++#define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/mips/bits/wordsize.h b/sysdeps/mips/bits/wordsize.h
+index 57f0f2a22f81745c..30dd3fd85db1f966 100644
+--- a/sysdeps/mips/bits/wordsize.h
++++ b/sysdeps/mips/bits/wordsize.h
+@@ -19,11 +19,7 @@
+ 
+ #define __WORDSIZE			_MIPS_SZPTR
+ 
+-#if _MIPS_SIM == _ABI64
+-# define __WORDSIZE_TIME64_COMPAT32	1
+-#else
+-# define __WORDSIZE_TIME64_COMPAT32	0
+-#endif
++#define __WORDSIZE_TIME64_COMPAT32	1
+ 
+ #if __WORDSIZE == 32
+ #define __WORDSIZE32_SIZE_ULONG		0
+diff --git a/sysdeps/nios2/bits/wordsize.h b/sysdeps/nios2/bits/wordsize.h
+new file mode 100644
+index 0000000000000000..6ecbfe7c863f3a17
+--- /dev/null
++++ b/sysdeps/nios2/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#define __WORDSIZE			32
++#define __WORDSIZE_TIME64_COMPAT32	1
++#define __WORDSIZE32_SIZE_ULONG		0
++#define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/powerpc/powerpc32/bits/wordsize.h b/sysdeps/powerpc/powerpc32/bits/wordsize.h
+index 04ca9debf00d7ee9..6993fb6b29ea3f74 100644
+--- a/sysdeps/powerpc/powerpc32/bits/wordsize.h
++++ b/sysdeps/powerpc/powerpc32/bits/wordsize.h
+@@ -2,10 +2,9 @@
+ 
+ #if defined __powerpc64__
+ # define __WORDSIZE	64
+-# define __WORDSIZE_TIME64_COMPAT32	1
+ #else
+ # define __WORDSIZE	32
+-# define __WORDSIZE_TIME64_COMPAT32	0
+ # define __WORDSIZE32_SIZE_ULONG	0
+ # define __WORDSIZE32_PTRDIFF_LONG	0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32	1
+diff --git a/sysdeps/powerpc/powerpc64/bits/wordsize.h b/sysdeps/powerpc/powerpc64/bits/wordsize.h
+index 04ca9debf00d7ee9..6993fb6b29ea3f74 100644
+--- a/sysdeps/powerpc/powerpc64/bits/wordsize.h
++++ b/sysdeps/powerpc/powerpc64/bits/wordsize.h
+@@ -2,10 +2,9 @@
+ 
+ #if defined __powerpc64__
+ # define __WORDSIZE	64
+-# define __WORDSIZE_TIME64_COMPAT32	1
+ #else
+ # define __WORDSIZE	32
+-# define __WORDSIZE_TIME64_COMPAT32	0
+ # define __WORDSIZE32_SIZE_ULONG	0
+ # define __WORDSIZE32_PTRDIFF_LONG	0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32	1
+diff --git a/sysdeps/sh/bits/wordsize.h b/sysdeps/sh/bits/wordsize.h
+new file mode 100644
+index 0000000000000000..6ecbfe7c863f3a17
+--- /dev/null
++++ b/sysdeps/sh/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#define __WORDSIZE			32
++#define __WORDSIZE_TIME64_COMPAT32	1
++#define __WORDSIZE32_SIZE_ULONG		0
++#define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/sparc/sparc32/bits/wordsize.h b/sysdeps/sparc/sparc32/bits/wordsize.h
+index 4bbd2e63b49bb2e2..a2e79e0fa9dc41d9 100644
+--- a/sysdeps/sparc/sparc32/bits/wordsize.h
++++ b/sysdeps/sparc/sparc32/bits/wordsize.h
+@@ -1,6 +1,6 @@
+ /* Determine the wordsize from the preprocessor defines.  */
+ 
+ #define __WORDSIZE	32
+-#define __WORDSIZE_TIME64_COMPAT32	0
++#define __WORDSIZE_TIME64_COMPAT32	1
+ #define __WORDSIZE32_SIZE_ULONG	0
+ #define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/sparc/sparc64/bits/wordsize.h b/sysdeps/sparc/sparc64/bits/wordsize.h
+index 2f66f10d7206731a..ea103e5970829abc 100644
+--- a/sysdeps/sparc/sparc64/bits/wordsize.h
++++ b/sysdeps/sparc/sparc64/bits/wordsize.h
+@@ -2,10 +2,9 @@
+ 
+ #if defined __arch64__ || defined __sparcv9
+ # define __WORDSIZE	64
+-# define __WORDSIZE_TIME64_COMPAT32	1
+ #else
+ # define __WORDSIZE	32
+-# define __WORDSIZE_TIME64_COMPAT32	0
+ # define __WORDSIZE32_SIZE_ULONG	0
+ # define __WORDSIZE32_PTRDIFF_LONG	0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32	1
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h
+new file mode 100644
+index 0000000000000000..6ecbfe7c863f3a17
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h
+@@ -0,0 +1,21 @@
++/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#define __WORDSIZE			32
++#define __WORDSIZE_TIME64_COMPAT32	1
++#define __WORDSIZE32_SIZE_ULONG		0
++#define __WORDSIZE32_PTRDIFF_LONG	0
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
+index 04ca9debf00d7ee9..6993fb6b29ea3f74 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
+@@ -2,10 +2,9 @@
+ 
+ #if defined __powerpc64__
+ # define __WORDSIZE	64
+-# define __WORDSIZE_TIME64_COMPAT32	1
+ #else
+ # define __WORDSIZE	32
+-# define __WORDSIZE_TIME64_COMPAT32	0
+ # define __WORDSIZE32_SIZE_ULONG	0
+ # define __WORDSIZE32_PTRDIFF_LONG	0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32	1
+diff --git a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
+index 7562875ee23ba8c5..ea103e5970829abc 100644
+--- a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
+@@ -2,10 +2,9 @@
+ 
+ #if defined __arch64__ || defined __sparcv9
+ # define __WORDSIZE	64
+-# define __WORDSIZE_TIME64_COMPAT32	1
+ #else
+ # define __WORDSIZE	32
+ # define __WORDSIZE32_SIZE_ULONG	0
+ # define __WORDSIZE32_PTRDIFF_LONG	0
+-# define __WORDSIZE_TIME64_COMPAT32	0
+ #endif
++#define __WORDSIZE_TIME64_COMPAT32	1
+diff --git a/sysdeps/x86/bits/wordsize.h b/sysdeps/x86/bits/wordsize.h
+index 70f652bca14d65c1..3f40aa76f99c75e5 100644
+--- a/sysdeps/x86/bits/wordsize.h
++++ b/sysdeps/x86/bits/wordsize.h
+@@ -8,10 +8,9 @@
+ #define __WORDSIZE32_PTRDIFF_LONG	0
+ #endif
+ 
++#define __WORDSIZE_TIME64_COMPAT32 1
++
+ #ifdef __x86_64__
+-# define __WORDSIZE_TIME64_COMPAT32	1
+ /* Both x86-64 and x32 use the 64-bit system call interface.  */
+ # define __SYSCALL_WORDSIZE		64
+-#else
+-# define __WORDSIZE_TIME64_COMPAT32	0
+ #endif
diff --git a/SOURCES/glibc-upstream-2.39-42.patch b/SOURCES/glibc-upstream-2.39-42.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6be162f72cc38fda824febe2c037f3e50f89020f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-42.patch
@@ -0,0 +1,31 @@
+commit acc56074b0a5127631a64640aef1b7c5c103ebd8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu May 2 17:06:19 2024 +0200
+
+    nscd: Use time_t for return type of addgetnetgrentX
+    
+    Using int may give false results for future dates (timeouts after the
+    year 2028).
+    
+    Fixes commit 04a21e050d64a1193a6daab872bca2528bda44b ("CVE-2024-33601,
+    CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX
+    (bug 31680)").
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 4bbca1a44691a6e9adcee5c6798a707b626bc331)
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index e8fe041846b75cb9..01d554af9c407739 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -680,8 +680,8 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
+       .key_len = he->len
+     };
+ 
+-  int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
+-			     he, dh);
++  time_t timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
++				he, dh);
+   if (timeout < 0)
+     timeout = 0;
+   return timeout;
diff --git a/SOURCES/glibc-upstream-2.39-43.patch b/SOURCES/glibc-upstream-2.39-43.patch
new file mode 100644
index 0000000000000000000000000000000000000000..093670f2c9156a56ee33032aeee2c4111502ea68
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-43.patch
@@ -0,0 +1,73 @@
+commit 273a835fe7c685cc54266bb8b502787bad5e9bae
+Author: Carlos O'Donell <carlos@redhat.com>
+Date:   Tue Apr 23 13:30:37 2024 -0400
+
+    time: Allow later version licensing.
+    
+    The FSF's Licensing and Compliance Lab noted a discrepancy in the
+    licensing of several files in the glibc package.
+    
+    When timespect_get.c was impelemented the license did not include
+    the standard ", or (at your option) any later version." text.
+    
+    Change the license in timespec_get.c and all copied files to match
+    the expected license.
+    
+    This change was previously approved in principle by the FSF in
+    RT ticket #1316403. And a similar instance was fixed in
+    commit 46703efa02f6ddebce5ee54c92f7c32598de0de6.
+    
+    (cherry picked from commit 91695ee4598b39d181ab8df579b888a8863c4cab)
+
+diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c
+index c6e5e6628928523b..778d1e33548d2369 100644
+--- a/sysdeps/unix/sysv/linux/timespec_get.c
++++ b/sysdeps/unix/sysv/linux/timespec_get.c
+@@ -5,7 +5,7 @@
+    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.
++   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
+diff --git a/sysdeps/unix/sysv/linux/timespec_getres.c b/sysdeps/unix/sysv/linux/timespec_getres.c
+index 5acebe2a2cb99ccf..2eef9e512c6f650e 100644
+--- a/sysdeps/unix/sysv/linux/timespec_getres.c
++++ b/sysdeps/unix/sysv/linux/timespec_getres.c
+@@ -5,7 +5,7 @@
+    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.
++   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
+diff --git a/time/timespec_get.c b/time/timespec_get.c
+index b031e42ca20c1eea..26a044bca6e7f9fe 100644
+--- a/time/timespec_get.c
++++ b/time/timespec_get.c
+@@ -4,7 +4,7 @@
+    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.
++   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
+diff --git a/time/timespec_getres.c b/time/timespec_getres.c
+index edb397507cdfc2fa..2e18b8bcacfec498 100644
+--- a/time/timespec_getres.c
++++ b/time/timespec_getres.c
+@@ -5,7 +5,7 @@
+    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.
++   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
diff --git a/SOURCES/glibc-upstream-2.39-44.patch b/SOURCES/glibc-upstream-2.39-44.patch
new file mode 100644
index 0000000000000000000000000000000000000000..92b587aa5e1e1a0ffdedcfe4106b41a80d86d3f7
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-44.patch
@@ -0,0 +1,34 @@
+commit 3148714ab61ad61281bae5a30f530d637034ac3b
+Author: Gabi Falk <gabifalk@gmx.com>
+Date:   Tue Apr 30 20:05:02 2024 +0000
+
+    i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk
+    
+    /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy_chk.o): in function `__memcpy_chk':
+    /home/bmg/src/glibc/debug/../sysdeps/i386/memcpy_chk.S:29: multiple definition of `__memcpy_chk';/home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy_chk.o): in function `__mempcpy_chk': /home/bmg/src/glibc/debug/../sysdeps/i386/mempcpy_chk.S:28: multiple definition of `__mempcpy_chk'; /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here
+    
+    After this change, the static library built for i586, regardless of PIC
+    options, contains implementations of these functions respectively from
+    sysdeps/i386/memcpy_chk.S and sysdeps/i386/mempcpy_chk.S.  This ensures
+    that memcpy and mempcpy won't pull in __chk_fail and the routines it
+    calls.
+    
+    Reported-by: Florian Weimer <fweimer@redhat.com>
+    Signed-off-by: Gabi Falk <gabifalk@gmx.com>
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
+    (cherry picked from commit 789894a2f554d4503ecb2f13b2b4e93e43414f33)
+
+diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S
+index 3e26f112d685e148..79856d498af90f66 100644
+--- a/sysdeps/i386/i586/memcpy.S
++++ b/sysdeps/i386/i586/memcpy.S
+@@ -26,7 +26,7 @@
+ #define LEN	SRC+4
+ 
+         .text
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY (__memcpy_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
diff --git a/SOURCES/glibc-upstream-2.39-45.patch b/SOURCES/glibc-upstream-2.39-45.patch
new file mode 100644
index 0000000000000000000000000000000000000000..208555ef8e5569ba070098af4307476fee3223e3
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-45.patch
@@ -0,0 +1,57 @@
+commit ad92c483a4bd34db1cfb3eb625212ea64848244f
+Author: Gabi Falk <gabifalk@gmx.com>
+Date:   Tue Apr 30 20:05:03 2024 +0000
+
+    i686: Fix multiple definitions of __memmove_chk and __memset_chk
+    
+    Commit c73c96a4a1af1326df7f96eec58209e1e04066d8 updated memcpy.S and
+    mempcpy.S, but omitted memmove.S and memset.S.  As a result, the static
+    library built as PIC, whether with or without multiarch support,
+    contains two definitions for each of the __memmove_chk and __memset_chk
+    symbols.
+    
+    /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../i686-pc-linux-gnu/bin/ld: /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset-ia32.o): in function `__memset_chk':
+    /var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/string/../sysdeps/i386/i686/memset.S:32: multiple definition of `__memset_chk'; /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset_chk.o):/var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/debug/../sysdeps/i386/i686/multiarch/memset_chk.c:24: first defined here
+    
+    After this change, regardless of PIC options, the static library, built
+    for i686 with multiarch contains implementations of these functions
+    respectively from debug/memmove_chk.c and debug/memset_chk.c, and
+    without multiarch contains implementations of these functions
+    respectively from sysdeps/i386/memmove_chk.S and
+    sysdeps/i386/memset_chk.S.  This ensures that memmove and memset won't
+    pull in __chk_fail and the routines it calls.
+    
+    Reported-by: Sam James <sam@gentoo.org>
+    Tested-by: Sam James <sam@gentoo.org>
+    Fixes: c73c96a4a1 ("i686: Fix build with --disable-multiarch")
+    Signed-off-by: Gabi Falk <gabifalk@gmx.com>
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
+    (cherry picked from commit 5a2cf833f5772d6c37c7adac388dd9af9cc1c4b9)
+
+diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S
+index f230359ad62b2443..effd958120082b04 100644
+--- a/sysdeps/i386/i686/memmove.S
++++ b/sysdeps/i386/i686/memmove.S
+@@ -29,7 +29,7 @@
+ #define SRC	DEST+4
+ #define LEN	SRC+4
+ 
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY_CHK (__memmove_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
+diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
+index f02f5a6df763d4e9..ab06771ea0ca071f 100644
+--- a/sysdeps/i386/i686/memset.S
++++ b/sysdeps/i386/i686/memset.S
+@@ -27,7 +27,7 @@
+ #define LEN	CHR+4
+ 
+         .text
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY_CHK (__memset_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
diff --git a/SOURCES/glibc-upstream-2.39-46.patch b/SOURCES/glibc-upstream-2.39-46.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d2f28d5341e63f9858f6c0d3512c7a628dce4b81
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-46.patch
@@ -0,0 +1,34 @@
+commit ff110b2591f0bdeccd121c3726af19c62d6fb184
+Author: Gabi Falk <gabifalk@gmx.com>
+Date:   Tue Apr 30 20:05:04 2024 +0000
+
+    Add a test to check for duplicate definitions in the static library
+    
+    This change follows two previous fixes addressing multiple definitions
+    of __memcpy_chk and __mempcpy_chk functions on i586, and __memmove_chk
+    and __memset_chk functions on i686.  The test is intended to prevent
+    such issues from occurring in the future.
+    
+    Signed-off-by: Gabi Falk <gabifalk@gmx.com>
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
+    (cherry picked from commit ded2e0753e9c46debeb2e0d26c5e560d2581d314)
+
+diff --git a/Makefile b/Makefile
+index f7e4eb9ff2cc464c..37bf70aa4ad4403f 100644
+--- a/Makefile
++++ b/Makefile
+@@ -577,6 +577,13 @@ $(objpfx)lint-makefiles.out: scripts/lint-makefiles.sh
+ 	$(SHELL) $< "$(PYTHON)" `pwd` > $@ ; \
+ 	$(evaluate-test)
+ 
++# Link libc.a as a whole to verify that it does not contain multiple
++# definitions of any symbols.
++tests-special += $(objpfx)link-static-libc.out
++$(objpfx)link-static-libc.out:
++	$(LINK.o) $(whole-archive) -r $(objpfx)libc.a -o /dev/null > $@ 2>&1; \
++	$(evaluate-test)
++
+ # Print test summary for tests in $1 .sum file;
+ # $2 is optional test identifier.
+ # Fail if there are unexpected failures in the test results.
diff --git a/SOURCES/glibc-upstream-2.39-47.patch b/SOURCES/glibc-upstream-2.39-47.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0ab4156241dc1a6681479944e336cf951fa1d71a
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-47.patch
@@ -0,0 +1,32 @@
+commit fa616ea3730cb42046d19f28d611be0bc390af7c
+Author: Sam James <sam@gentoo.org>
+Date:   Sat May 4 13:28:13 2024 +0100
+
+    Revert "Add a test to check for duplicate definitions in the static library"
+    
+    This reverts commit ff110b2591f0bdeccd121c3726af19c62d6fb184.
+    
+    I had the wrong cherry-pick reference (the commit content is right; it's
+    just referring to a base that isn't upstream), but let's revert and reapply
+    for clarity.
+    
+    Signed-off-by: Sam James <sam@gentoo.org>
+
+diff --git a/Makefile b/Makefile
+index 37bf70aa4ad4403f..f7e4eb9ff2cc464c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -577,13 +577,6 @@ $(objpfx)lint-makefiles.out: scripts/lint-makefiles.sh
+ 	$(SHELL) $< "$(PYTHON)" `pwd` > $@ ; \
+ 	$(evaluate-test)
+ 
+-# Link libc.a as a whole to verify that it does not contain multiple
+-# definitions of any symbols.
+-tests-special += $(objpfx)link-static-libc.out
+-$(objpfx)link-static-libc.out:
+-	$(LINK.o) $(whole-archive) -r $(objpfx)libc.a -o /dev/null > $@ 2>&1; \
+-	$(evaluate-test)
+-
+ # Print test summary for tests in $1 .sum file;
+ # $2 is optional test identifier.
+ # Fail if there are unexpected failures in the test results.
diff --git a/SOURCES/glibc-upstream-2.39-48.patch b/SOURCES/glibc-upstream-2.39-48.patch
new file mode 100644
index 0000000000000000000000000000000000000000..133d6a0b7487e291ecc57f5612990b6bd813c6b4
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-48.patch
@@ -0,0 +1,40 @@
+commit c16871e662cd0f3370173d916864b19e69f1bc9a
+Author: Sam James <sam@gentoo.org>
+Date:   Sat May 4 13:28:51 2024 +0100
+
+    Revert "i686: Fix multiple definitions of __memmove_chk and __memset_chk"
+    
+    This reverts commit ad92c483a4bd34db1cfb3eb625212ea64848244f.
+    
+    I had the wrong cherry-pick reference (the commit content is right; it's
+    just referring to a base that isn't upstream), but let's revert and reapply
+    for clarity.
+    
+    Signed-off-by: Sam James <sam@gentoo.org>
+
+diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S
+index effd958120082b04..f230359ad62b2443 100644
+--- a/sysdeps/i386/i686/memmove.S
++++ b/sysdeps/i386/i686/memmove.S
+@@ -29,7 +29,7 @@
+ #define SRC	DEST+4
+ #define LEN	SRC+4
+ 
+-#if defined SHARED && IS_IN (libc)
++#if defined PIC && IS_IN (libc)
+ ENTRY_CHK (__memmove_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
+diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
+index ab06771ea0ca071f..f02f5a6df763d4e9 100644
+--- a/sysdeps/i386/i686/memset.S
++++ b/sysdeps/i386/i686/memset.S
+@@ -27,7 +27,7 @@
+ #define LEN	CHR+4
+ 
+         .text
+-#if defined SHARED && IS_IN (libc)
++#if defined PIC && IS_IN (libc)
+ ENTRY_CHK (__memset_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
diff --git a/SOURCES/glibc-upstream-2.39-49.patch b/SOURCES/glibc-upstream-2.39-49.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a3c6b8863c4f7eef23e46f2b517adc5d2c86acc3
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-49.patch
@@ -0,0 +1,27 @@
+commit 5141d4d83c17406f0eaea3e345ef2b52e10f386e
+Author: Sam James <sam@gentoo.org>
+Date:   Sat May 4 13:28:54 2024 +0100
+
+    Revert "i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk"
+    
+    This reverts commit 3148714ab61ad61281bae5a30f530d637034ac3b.
+    
+    I had the wrong cherry-pick reference (the commit content is right; it's
+    just referring to a base that isn't upstream), but let's revert and reapply
+    for clarity.
+    
+    Signed-off-by: Sam James <sam@gentoo.org>
+
+diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S
+index 79856d498af90f66..3e26f112d685e148 100644
+--- a/sysdeps/i386/i586/memcpy.S
++++ b/sysdeps/i386/i586/memcpy.S
+@@ -26,7 +26,7 @@
+ #define LEN	SRC+4
+ 
+         .text
+-#if defined SHARED && IS_IN (libc)
++#if defined PIC && IS_IN (libc)
+ ENTRY (__memcpy_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
diff --git a/SOURCES/glibc-upstream-2.39-50.patch b/SOURCES/glibc-upstream-2.39-50.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d79e2dbc9dca188712f608edf684a9bd39878048
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-50.patch
@@ -0,0 +1,34 @@
+commit 8323a83abd73446dc434aceff66219712c09140b
+Author: Gabi Falk <gabifalk@gmx.com>
+Date:   Tue Apr 30 20:05:02 2024 +0000
+
+    i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk
+    
+    /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy_chk.o): in function `__memcpy_chk':
+    /home/bmg/src/glibc/debug/../sysdeps/i386/memcpy_chk.S:29: multiple definition of `__memcpy_chk';/home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(memcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here /home/bmg/install/compilers/x86_64-linux-gnu/lib/gcc/x86_64-glibc-linux-gnu/13.2.1/../../../../x86_64-glibc-linux-gnu/bin/ld: /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy_chk.o): in function `__mempcpy_chk': /home/bmg/src/glibc/debug/../sysdeps/i386/mempcpy_chk.S:28: multiple definition of `__mempcpy_chk'; /home/bmg/build/glibcs/i586-linux-gnu/glibc/libc.a(mempcpy.o):/home/bmg/src/glibc/string/../sysdeps/i386/i586/memcpy.S:31: first defined here
+    
+    After this change, the static library built for i586, regardless of PIC
+    options, contains implementations of these functions respectively from
+    sysdeps/i386/memcpy_chk.S and sysdeps/i386/mempcpy_chk.S.  This ensures
+    that memcpy and mempcpy won't pull in __chk_fail and the routines it
+    calls.
+    
+    Reported-by: Florian Weimer <fweimer@redhat.com>
+    Signed-off-by: Gabi Falk <gabifalk@gmx.com>
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
+    (cherry picked from commit 0fdf4ba48ccce5abf567340b0ab8fa8ed8a9bc6e)
+
+diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S
+index 3e26f112d685e148..79856d498af90f66 100644
+--- a/sysdeps/i386/i586/memcpy.S
++++ b/sysdeps/i386/i586/memcpy.S
+@@ -26,7 +26,7 @@
+ #define LEN	SRC+4
+ 
+         .text
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY (__memcpy_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
diff --git a/SOURCES/glibc-upstream-2.39-51.patch b/SOURCES/glibc-upstream-2.39-51.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4c9718c12a36203aa15e46ac39b6533b8e6c1e33
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-51.patch
@@ -0,0 +1,57 @@
+commit 8b005d7869debac4d5cd67f65e49a0fad89da9ad
+Author: Gabi Falk <gabifalk@gmx.com>
+Date:   Tue Apr 30 20:05:03 2024 +0000
+
+    i686: Fix multiple definitions of __memmove_chk and __memset_chk
+    
+    Commit c73c96a4a1af1326df7f96eec58209e1e04066d8 updated memcpy.S and
+    mempcpy.S, but omitted memmove.S and memset.S.  As a result, the static
+    library built as PIC, whether with or without multiarch support,
+    contains two definitions for each of the __memmove_chk and __memset_chk
+    symbols.
+    
+    /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../i686-pc-linux-gnu/bin/ld: /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset-ia32.o): in function `__memset_chk':
+    /var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/string/../sysdeps/i386/i686/memset.S:32: multiple definition of `__memset_chk'; /usr/lib/gcc/i686-pc-linux-gnu/14/../../../../lib/libc.a(memset_chk.o):/var/tmp/portage/sys-libs/glibc-2.39-r3/work/glibc-2.39/debug/../sysdeps/i386/i686/multiarch/memset_chk.c:24: first defined here
+    
+    After this change, regardless of PIC options, the static library, built
+    for i686 with multiarch contains implementations of these functions
+    respectively from debug/memmove_chk.c and debug/memset_chk.c, and
+    without multiarch contains implementations of these functions
+    respectively from sysdeps/i386/memmove_chk.S and
+    sysdeps/i386/memset_chk.S.  This ensures that memmove and memset won't
+    pull in __chk_fail and the routines it calls.
+    
+    Reported-by: Sam James <sam@gentoo.org>
+    Tested-by: Sam James <sam@gentoo.org>
+    Fixes: c73c96a4a1 ("i686: Fix build with --disable-multiarch")
+    Signed-off-by: Gabi Falk <gabifalk@gmx.com>
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
+    (cherry picked from commit 5a2cf833f5772d6c37c7adac388dd9af9cc1c4b9)
+
+diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S
+index f230359ad62b2443..effd958120082b04 100644
+--- a/sysdeps/i386/i686/memmove.S
++++ b/sysdeps/i386/i686/memmove.S
+@@ -29,7 +29,7 @@
+ #define SRC	DEST+4
+ #define LEN	SRC+4
+ 
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY_CHK (__memmove_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
+diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
+index f02f5a6df763d4e9..ab06771ea0ca071f 100644
+--- a/sysdeps/i386/i686/memset.S
++++ b/sysdeps/i386/i686/memset.S
+@@ -27,7 +27,7 @@
+ #define LEN	CHR+4
+ 
+         .text
+-#if defined PIC && IS_IN (libc)
++#if defined SHARED && IS_IN (libc)
+ ENTRY_CHK (__memset_chk)
+ 	movl	12(%esp), %eax
+ 	cmpl	%eax, 16(%esp)
diff --git a/SOURCES/glibc-upstream-2.39-52.patch b/SOURCES/glibc-upstream-2.39-52.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c03d7cc41793c0ae9ae46fb5c6cd3ffa4b64848b
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-52.patch
@@ -0,0 +1,34 @@
+commit f8e462342189525e4605cf233b8f798d1c7f398d
+Author: Gabi Falk <gabifalk@gmx.com>
+Date:   Tue Apr 30 20:05:04 2024 +0000
+
+    Add a test to check for duplicate definitions in the static library
+    
+    This change follows two previous fixes addressing multiple definitions
+    of __memcpy_chk and __mempcpy_chk functions on i586, and __memmove_chk
+    and __memset_chk functions on i686.  The test is intended to prevent
+    such issues from occurring in the future.
+    
+    Signed-off-by: Gabi Falk <gabifalk@gmx.com>
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
+    (cherry picked from commit ded2e0753e9c46debeb2e0d26c5e560d2581d314)
+
+diff --git a/Makefile b/Makefile
+index f7e4eb9ff2cc464c..37bf70aa4ad4403f 100644
+--- a/Makefile
++++ b/Makefile
+@@ -577,6 +577,13 @@ $(objpfx)lint-makefiles.out: scripts/lint-makefiles.sh
+ 	$(SHELL) $< "$(PYTHON)" `pwd` > $@ ; \
+ 	$(evaluate-test)
+ 
++# Link libc.a as a whole to verify that it does not contain multiple
++# definitions of any symbols.
++tests-special += $(objpfx)link-static-libc.out
++$(objpfx)link-static-libc.out:
++	$(LINK.o) $(whole-archive) -r $(objpfx)libc.a -o /dev/null > $@ 2>&1; \
++	$(evaluate-test)
++
+ # Print test summary for tests in $1 .sum file;
+ # $2 is optional test identifier.
+ # Fail if there are unexpected failures in the test results.
diff --git a/SOURCES/glibc-upstream-2.39-53.patch b/SOURCES/glibc-upstream-2.39-53.patch
new file mode 100644
index 0000000000000000000000000000000000000000..94ec6624cced282ca78c1b0498aa7f8d828fc673
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-53.patch
@@ -0,0 +1,207 @@
+commit 71149c2a2e85a8233631cc816030d449f021bb2a
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Mon May 6 13:18:45 2024 -0300
+
+    elf: Only process multiple tunable once (BZ 31686)
+    
+    The 680c597e9c3 commit made loader reject ill-formatted strings by
+    first tracking all set tunables and then applying them. However, it does
+    not take into consideration if the same tunable is set multiple times,
+    where parse_tunables_string appends the found tunable without checking
+    if it was already in the list. It leads to a stack-based buffer overflow
+    if the tunable is specified more than the total number of tunables.  For
+    instance:
+    
+      GLIBC_TUNABLES=glibc.malloc.check=2:... (repeat over the number of
+      total support for different tunable).
+    
+    Instead, use the index of the tunable list to get the expected tunable
+    entry.  Since now the initial list is zero-initialized, the compiler
+    might emit an extra memset and this requires some minor adjustment
+    on some ports.
+    
+    Checked on x86_64-linux-gnu and aarch64-linux-gnu.
+    
+    Reported-by: Yuto Maeda <maeda@cyberdefense.jp>
+    Reported-by: Yutaro Shimizu <shimizu@cyberdefense.jp>
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit bcae44ea8536b30a7119c0986ff5692bddacb672)
+
+diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
+index 03e1a68675d65224..614ac9c0471c5963 100644
+--- a/elf/dl-tunables.c
++++ b/elf/dl-tunables.c
+@@ -32,6 +32,7 @@
+ #include <ldsodefs.h>
+ #include <array_length.h>
+ #include <dl-minimal-malloc.h>
++#include <dl-symbol-redir-ifunc.h>
+ 
+ #define TUNABLES_INTERNAL 1
+ #include "dl-tunables.h"
+@@ -223,6 +224,7 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables)
+ 	    {
+ 	      tunables[ntunables++] =
+ 		(struct tunable_toset_t) { cur, value, p - value };
++
+ 	      break;
+ 	    }
+ 	}
+@@ -234,23 +236,27 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables)
+ static void
+ parse_tunables (const char *valstring)
+ {
+-  struct tunable_toset_t tunables[tunables_list_size];
+-  int ntunables = parse_tunables_string (valstring, tunables);
+-  if (ntunables == -1)
++  struct tunable_toset_t tunables[tunables_list_size] = { 0 };
++  if (parse_tunables_string (valstring, tunables) == -1)
+     {
+       _dl_error_printf (
+         "WARNING: ld.so: invalid GLIBC_TUNABLES `%s': ignored.\n", valstring);
+       return;
+     }
+ 
+-  for (int i = 0; i < ntunables; i++)
+-    if (!tunable_initialize (tunables[i].t, tunables[i].value,
+-			     tunables[i].len))
+-      _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' "
+-		       "for option `%s': ignored.\n",
+-		       (int) tunables[i].len,
+-		       tunables[i].value,
+-		       tunables[i].t->name);
++  for (int i = 0; i < tunables_list_size; i++)
++    {
++      if (tunables[i].t == NULL)
++	continue;
++
++      if (!tunable_initialize (tunables[i].t, tunables[i].value,
++			       tunables[i].len))
++	_dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' "
++			  "for option `%s': ignored.\n",
++			  (int) tunables[i].len,
++			  tunables[i].value,
++			  tunables[i].t->name);
++    }
+ }
+ 
+ /* Initialize the tunables list from the environment.  For now we only use the
+diff --git a/elf/tst-tunables.c b/elf/tst-tunables.c
+index 095b5c81d95c8760..dff34ed748b4ae83 100644
+--- a/elf/tst-tunables.c
++++ b/elf/tst-tunables.c
+@@ -17,6 +17,10 @@
+    <https://www.gnu.org/licenses/>.  */
+ 
+ #include <array_length.h>
++/* The test uses the tunable_list size, which is only exported for
++   ld.so.  This will result in a copy of tunable_list, which is ununsed by
++   the test itself.  */
++#define TUNABLES_INTERNAL 1
+ #include <dl-tunables.h>
+ #include <getopt.h>
+ #include <intprops.h>
+@@ -24,12 +28,13 @@
+ #include <stdlib.h>
+ #include <support/capture_subprocess.h>
+ #include <support/check.h>
++#include <support/support.h>
+ 
+ static int restart;
+ #define CMDLINE_OPTIONS \
+   { "restart", no_argument, &restart, 1 },
+ 
+-static const struct test_t
++static struct test_t
+ {
+   const char *name;
+   const char *value;
+@@ -284,6 +289,29 @@ static const struct test_t
+     0,
+     0,
+   },
++  /* Also check for repeated tunables with a count larger than the total number
++     of tunables.  */
++  {
++    "GLIBC_TUNABLES",
++    NULL,
++    2,
++    0,
++    0,
++  },
++  {
++    "GLIBC_TUNABLES",
++    NULL,
++    1,
++    0,
++    0,
++  },
++  {
++    "GLIBC_TUNABLES",
++    NULL,
++    0,
++    0,
++    0,
++  },
+ };
+ 
+ static int
+@@ -327,6 +355,37 @@ do_test (int argc, char *argv[])
+     spargv[i] = NULL;
+   }
+ 
++  /* Create a tunable line with the duplicate values with a total number
++     larger than the different number of tunables.  */
++  {
++    enum { tunables_list_size = array_length (tunable_list) };
++    const char *value = "";
++    for (int i = 0; i < tunables_list_size; i++)
++      value = xasprintf ("%sglibc.malloc.check=2%c",
++			 value,
++			 i == (tunables_list_size - 1) ? '\0' : ':');
++    tests[33].value = value;
++  }
++  /* Same as before, but the last tunable values is differen than the
++     rest.  */
++  {
++    enum { tunables_list_size = array_length (tunable_list) };
++    const char *value = "";
++    for (int i = 0; i < tunables_list_size - 1; i++)
++      value = xasprintf ("%sglibc.malloc.check=2:", value);
++    value = xasprintf ("%sglibc.malloc.check=1", value);
++    tests[34].value = value;
++  }
++  /* Same as before, but with an invalid last entry.  */
++  {
++    enum { tunables_list_size = array_length (tunable_list) };
++    const char *value = "";
++    for (int i = 0; i < tunables_list_size - 1; i++)
++      value = xasprintf ("%sglibc.malloc.check=2:", value);
++    value = xasprintf ("%sglibc.malloc.check=1=1", value);
++    tests[35].value = value;
++  }
++
+   for (int i = 0; i < array_length (tests); i++)
+     {
+       snprintf (nteststr, sizeof nteststr, "%d", i);
+diff --git a/sysdeps/aarch64/multiarch/memset_generic.S b/sysdeps/aarch64/multiarch/memset_generic.S
+index 81748bdbce53e636..e125a5ed853301e1 100644
+--- a/sysdeps/aarch64/multiarch/memset_generic.S
++++ b/sysdeps/aarch64/multiarch/memset_generic.S
+@@ -33,3 +33,7 @@
+ #endif
+ 
+ #include <../memset.S>
++
++#if IS_IN (rtld)
++strong_alias (memset, __memset_generic)
++#endif
+diff --git a/sysdeps/sparc/sparc64/rtld-memset.c b/sysdeps/sparc/sparc64/rtld-memset.c
+index 55f38357902933b5..a19202a620fb8f7d 100644
+--- a/sysdeps/sparc/sparc64/rtld-memset.c
++++ b/sysdeps/sparc/sparc64/rtld-memset.c
+@@ -1 +1,4 @@
+ #include <string/memset.c>
++#if IS_IN(rtld)
++strong_alias (memset, __memset_ultra1)
++#endif
diff --git a/SOURCES/glibc-upstream-2.39-54.patch b/SOURCES/glibc-upstream-2.39-54.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7ed1911f6ffc57af659df5d4c22f2cc066ecd3e5
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-54.patch
@@ -0,0 +1,45 @@
+commit 97bb89668d7171164975f3dc895e38343a2f3a95
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu May 9 20:07:01 2024 -0700
+
+    Force DT_RPATH for --enable-hardcoded-path-in-tests
+    
+    On Fedora 40/x86-64, linker enables --enable-new-dtags by default which
+    generates DT_RUNPATH instead of DT_RPATH.  Unlike DT_RPATH, DT_RUNPATH
+    only applies to DT_NEEDED entries in the executable and doesn't applies
+    to DT_NEEDED entries in shared libraries which are loaded via DT_NEEDED
+    entries in the executable.  Some glibc tests have libstdc++.so.6 in
+    DT_NEEDED, which has libm.so.6 in DT_NEEDED.  When DT_RUNPATH is generated,
+    /lib64/libm.so.6 is loaded for such tests.  If the newly built glibc is
+    older than glibc 2.36, these tests fail with
+    
+    assert/tst-assert-c++: /export/build/gnu/tools-build/glibc-gitlab-release/build-x86_64-linux/libc.so.6: version `GLIBC_2.36' not found (required by /lib64/libm.so.6)
+    assert/tst-assert-c++: /export/build/gnu/tools-build/glibc-gitlab-release/build-x86_64-linux/libc.so.6: version `GLIBC_ABI_DT_RELR' not found (required by /lib64/libm.so.6)
+    
+    Pass -Wl,--disable-new-dtags to linker when building glibc tests with
+    --enable-hardcoded-path-in-tests.  This fixes BZ #31719.
+    
+    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
+    (cherry picked from commit 2dcaf70643710e22f92a351e36e3cff8b48c60dc)
+
+diff --git a/Makeconfig b/Makeconfig
+index 85e00cef94e9deb4..522182abdc426e70 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -586,10 +586,13 @@ link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link)
+ # before the expansion of LDLIBS-* variables).
+ 
+ # Tests use -Wl,-rpath instead of -Wl,-rpath-link for
+-# build-hardcoded-path-in-tests.
++# build-hardcoded-path-in-tests.  Add -Wl,--disable-new-dtags to force
++# DT_RPATH instead of DT_RUNPATH which only applies to DT_NEEDED entries
++# in the executable and doesn't applies to DT_NEEDED entries in shared
++# libraries which are loaded via DT_NEEDED entries in the executable.
+ ifeq (yes,$(build-hardcoded-path-in-tests))
+-link-libc-tests-rpath-link = $(link-libc-rpath)
+-link-test-modules-rpath-link = $(link-libc-rpath)
++link-libc-tests-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags
++link-test-modules-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags
+ else
+ link-libc-tests-rpath-link = $(link-libc-rpath-link)
+ link-test-modules-rpath-link =
diff --git a/SOURCES/glibc-upstream-2.39-55.patch b/SOURCES/glibc-upstream-2.39-55.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0bb52db55473c7f2163bb34f3e6e84e7cb76bbc9
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-55.patch
@@ -0,0 +1,38 @@
+commit ab4ef4421f85ea7afeb482ded51003658b08de7e
+Author: Gabi Falk <gabifalk@gmx.com>
+Date:   Tue May 7 18:25:00 2024 +0000
+
+    x86_64: Fix missing wcsncat function definition without multiarch (x86-64-v4)
+    
+    This code expects the WCSCAT preprocessor macro to be predefined in case
+    the evex implementation of the function should be defined with a name
+    different from __wcsncat_evex.  However, when glibc is built for
+    x86-64-v4 without multiarch support, sysdeps/x86_64/wcsncat.S defines
+    WCSNCAT variable instead of WCSCAT to build it as wcsncat.  Rename the
+    variable to WCSNCAT, as it is actually a better naming choice for the
+    variable in this case.
+    
+    Reported-by: Kenton Groombridge
+    Link: https://bugs.gentoo.org/921945
+    Fixes: 64b8b6516b ("x86: Add evex optimized functions for the wchar_t strcpy family")
+    Signed-off-by: Gabi Falk <gabifalk@gmx.com>
+    Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
+    (cherry picked from commit dd5f891c1ad9f1b43b9db93afe2a55cbb7a6194e)
+
+diff --git a/sysdeps/x86_64/multiarch/wcsncat-evex.S b/sysdeps/x86_64/multiarch/wcsncat-evex.S
+index 392215950afd56be..10bfb0a5314130cf 100644
+--- a/sysdeps/x86_64/multiarch/wcsncat-evex.S
++++ b/sysdeps/x86_64/multiarch/wcsncat-evex.S
+@@ -1,9 +1,9 @@
+-#ifndef WCSCAT
+-# define WCSCAT	__wcsncat_evex
++#ifndef WCSNCAT
++# define WCSNCAT	__wcsncat_evex
+ #endif
+ 
+ #define USE_AS_WCSCPY
+ #define USE_AS_STRCAT
+ 
+-#define STRNCAT	WCSCAT
++#define STRNCAT	WCSNCAT
+ #include "strncat-evex.S"
diff --git a/SOURCES/glibc-upstream-2.39-56.patch b/SOURCES/glibc-upstream-2.39-56.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1acf9528697df2f566f30b881ee50704a6d6aa2d
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-56.patch
@@ -0,0 +1,71 @@
+commit 2db79c96baa1256b8fc2656596143da92fabd074
+Author: Sergey Kolosov <skolosov@redhat.com>
+Date:   Wed Apr 10 17:58:04 2024 +0200
+
+    libsupport: Add xgetpeername
+    
+    The patch adds redirections for getpeername.
+    
+    Reviewed-by: Arjun Shankar <arjun@redhat.com>
+    (cherry picked from commit 6687a6e3f962759536a8019d31c68c1009ccd6eb)
+
+diff --git a/support/Makefile b/support/Makefile
+index 362a51f882787f2b..aa57207bdccc852d 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -131,6 +131,7 @@ libsupport-routines = \
+   xfreopen \
+   xftruncate \
+   xgetline \
++  xgetpeername \
+   xgetsockname \
+   xlisten \
+   xlseek \
+diff --git a/support/xgetpeername.c b/support/xgetpeername.c
+new file mode 100644
+index 0000000000000000..6f448e456a1d9e1e
+--- /dev/null
++++ b/support/xgetpeername.c
+@@ -0,0 +1,30 @@
++/* getpeername with error checking.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <support/xsocket.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <support/check.h>
++
++void
++xgetpeername (int fd, struct sockaddr *sa, socklen_t *plen)
++{
++  if (getpeername (fd, sa, plen) != 0)
++    FAIL_EXIT1 ("getpeername (%d): %m", fd);
++}
+diff --git a/support/xsocket.h b/support/xsocket.h
+index 3e4410354676cb2a..4ac0e1f5ffe35dc2 100644
+--- a/support/xsocket.h
++++ b/support/xsocket.h
+@@ -26,6 +26,7 @@
+ int xsocket (int, int, int);
+ void xsetsockopt (int, int, int, const void *, socklen_t);
+ void xgetsockname (int, struct sockaddr *, socklen_t *);
++void xgetpeername (int, struct sockaddr *, socklen_t *);
+ void xconnect (int, const struct sockaddr *, socklen_t);
+ void xbind (int, const struct sockaddr *, socklen_t);
+ void xlisten (int, int);
diff --git a/SOURCES/glibc-upstream-2.39-57.patch b/SOURCES/glibc-upstream-2.39-57.patch
new file mode 100644
index 0000000000000000000000000000000000000000..aee72fa6de229a68c50aed222e4201fb729ba6d3
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-57.patch
@@ -0,0 +1,143 @@
+commit 32969a2b36b8cc74343182b768b3babe6f81c3aa
+Author: Sergey Kolosov <skolosov@redhat.com>
+Date:   Wed Apr 10 17:58:05 2024 +0200
+
+    socket: Add new test for connect
+    
+    This commit adds a simple bind/accept/connect test for an IPv4 TCP
+    connection to a local process via the loopback interface.
+    
+    Reviewed-by: Arjun Shankar <arjun@redhat.com>
+    (cherry picked from commit 3a83f79024cc023a74c3892a1673542e8e972485)
+
+diff --git a/socket/Makefile b/socket/Makefile
+index 74ca5b8452cd15d3..fc1bd0a2608f04bc 100644
+--- a/socket/Makefile
++++ b/socket/Makefile
+@@ -70,6 +70,7 @@ tests := \
+   tst-accept4 \
+   tst-cmsg_cloexec \
+   tst-cmsghdr \
++  tst-connect \
+   tst-sockopt \
+   # tests
+ 
+diff --git a/socket/tst-connect.c b/socket/tst-connect.c
+new file mode 100644
+index 0000000000000000..ec2fdd92c0a6f1be
+--- /dev/null
++++ b/socket/tst-connect.c
+@@ -0,0 +1,113 @@
++/* Test the connect function.
++   Copyright (C) 2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <arpa/inet.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <signal.h>
++#include <stdbool.h>
++#include <support/check.h>
++#include <support/xsocket.h>
++#include <support/xunistd.h>
++#include <sys/socket.h>
++#include <stdio.h>
++
++static struct sockaddr_in server_address;
++
++int
++open_socket_inet_tcp (void)
++{
++  int fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
++  if (fd < 0)
++    {
++      if (errno == EAFNOSUPPORT)
++        FAIL_UNSUPPORTED ("The host does not support IPv4");
++      else
++        FAIL_EXIT1 ("socket (AF_INET, SOCK_STREAM, IPPROTO_TCP): %m\n");
++    }
++  return fd;
++}
++
++static pid_t
++start_server (void)
++{
++  server_address.sin_family = AF_INET;
++  server_address.sin_port = 0;
++  server_address.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
++
++  int server_sock = open_socket_inet_tcp ();
++
++  xbind (server_sock, (struct sockaddr *) &server_address,
++         sizeof (server_address));
++
++  socklen_t sa_len = sizeof (server_address);
++  xgetsockname (server_sock, (struct sockaddr *) &server_address, &sa_len);
++  xlisten (server_sock, 5);
++
++  pid_t my_pid = xfork ();
++  if (my_pid > 0)
++    {
++      xclose (server_sock);
++      return my_pid;
++    }
++
++  struct sockaddr_in client_address;
++  socklen_t ca_len = sizeof (server_address);
++  int client_sock = xaccept (server_sock, (struct sockaddr *) &client_address,
++                             &ca_len);
++  printf ("socket accepted %d\n", client_sock);
++
++  _exit (0);
++}
++
++static int
++do_test (void)
++{
++  pid_t serv_pid;
++  struct sockaddr_in peer;
++  socklen_t peer_len;
++
++  serv_pid = start_server ();
++  int client_sock = open_socket_inet_tcp ();
++  xconnect (client_sock, (const struct sockaddr *) &server_address,
++            sizeof (server_address));
++
++  /* A second connect with same arguments should fail with EISCONN.  */
++  int result = connect (client_sock,
++                        (const struct sockaddr *) &server_address,
++                        sizeof (server_address));
++  if (result == 0 || errno != EISCONN)
++    FAIL_EXIT1 ("Second connect (%d), should fail with EISCONN: %m",
++                client_sock);
++
++  peer_len = sizeof (peer);
++  xgetpeername (client_sock, (struct sockaddr *) &peer, &peer_len);
++  TEST_COMPARE (peer_len, sizeof (peer));
++  TEST_COMPARE (peer.sin_port, server_address.sin_port);
++  TEST_COMPARE_BLOB (&peer.sin_addr, sizeof (peer.sin_addr),
++                     &server_address.sin_addr,
++                     sizeof (server_address.sin_addr));
++
++  int status;
++  xwaitpid (serv_pid, &status, 0);
++  TEST_COMPARE (status, 0);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.39-58.patch b/SOURCES/glibc-upstream-2.39-58.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cbe201a9097afd8e62ca62110a1d58704cd8c035
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-58.patch
@@ -0,0 +1,23 @@
+commit c7c3f5bf80ae86b34501f473f1a9fc545c911b7f
+Author: caiyinyu <caiyinyu@loongson.cn>
+Date:   Sat May 11 10:25:54 2024 +0800
+
+    LoongArch: Fix undefined `__memset_aligned` reference in ld.so linking.
+    
+    This patch from 095067efdf68c8061d6f99a21a0300841bede999 (LoongArch: Add
+    glibc.cpu.hwcap support.)
+
+diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
+index cb640d77b7695b93..a73390b12f67a3fc 100644
+--- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
++++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
+@@ -19,6 +19,9 @@
+ #ifndef _DL_IFUNC_GENERIC_H
+ #define _DL_IFUNC_GENERIC_H
+ 
++#ifndef SHARED
+ asm ("memset = __memset_aligned");
++asm ("memcmp = __memcmp_aligned");
++#endif
+ 
+ #endif
diff --git a/SOURCES/glibc-upstream-2.39-59.patch b/SOURCES/glibc-upstream-2.39-59.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0f4fb1c80c56e62d15701d3ce2b32bf4d4b189fb
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-59.patch
@@ -0,0 +1,40 @@
+commit 9f2b100d6705b9bbb25206b53e80d7759644e06e
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Sat May 25 05:13:41 2024 -0700
+
+    parse_fdinfo: Don't advance pointer twice [BZ #31798]
+    
+    pidfd_getpid.c has
+    
+          /* Ignore invalid large values.  */
+          if (INT_MULTIPLY_WRAPV (10, n, &n)
+              || INT_ADD_WRAPV (n, *l++ - '0', &n))
+            return -1;
+    
+    For GCC older than GCC 7, INT_ADD_WRAPV(a, b, r) is defined as
+    
+       _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
+    
+    and *l++ - '0' is evaluated twice.  Fix BZ #31798 by moving "l++" out of
+    the if statement.  Tested with GCC 6.4 and GCC 14.1.
+    
+    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    (cherry picked from commit f981bf6b9db87e0732b46bfe92fdad4d363225e8)
+
+diff --git a/sysdeps/unix/sysv/linux/pidfd_getpid.c b/sysdeps/unix/sysv/linux/pidfd_getpid.c
+index 8567b413dd2c210b..30025e5863f7b956 100644
+--- a/sysdeps/unix/sysv/linux/pidfd_getpid.c
++++ b/sysdeps/unix/sysv/linux/pidfd_getpid.c
+@@ -74,8 +74,10 @@ parse_fdinfo (const char *l, void *arg)
+ 
+       /* Ignore invalid large values.  */
+       if (INT_MULTIPLY_WRAPV (10, n, &n)
+-          || INT_ADD_WRAPV (n, *l++ - '0', &n))
++          || INT_ADD_WRAPV (n, *l - '0', &n))
+         return -1;
++
++      l++;
+     }
+ 
+   /* -1 indicates that the process is terminated.  */
diff --git a/SOURCES/glibc-upstream-2.39-60.patch b/SOURCES/glibc-upstream-2.39-60.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8765056a3f671b26fd7327a58dad6308af942ea4
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-60.patch
@@ -0,0 +1,195 @@
+commit 26e7005728f0eea2972474e6be2905c467661237
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Sat May 18 09:33:19 2024 +0200
+
+    socket: Use may_alias on sockaddr structs (bug 19622)
+    
+    This supports common coding patterns.  The GCC C front end before
+    version 7 rejects the may_alias attribute on a struct definition
+    if it was not present in a previous forward declaration, so this
+    attribute can only be conditionally applied.
+    
+    This implements the spirit of the change in Austin Group issue 1641.
+    
+    Suggested-by: Marek Polacek <polacek@redhat.com>
+    Suggested-by: Jakub Jelinek <jakub@redhat.com>
+    Reviewed-by: Sam James <sam@gentoo.org>
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 8d7b6b4cb27d4dec1dd5f7960298c1699275f962)
+
+diff --git a/bits/socket.h b/bits/socket.h
+index 13de124bac67c217..772074d52ab957df 100644
+--- a/bits/socket.h
++++ b/bits/socket.h
+@@ -149,7 +149,7 @@ enum __socket_type
+ #include <bits/sockaddr.h>
+ 
+ /* Structure describing a generic socket address.  */
+-struct sockaddr
++struct __attribute_struct_may_alias__ sockaddr
+   {
+     __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
+     char sa_data[14];		/* Address data.  */
+@@ -166,7 +166,7 @@ struct sockaddr
+ #define _SS_PADSIZE \
+   (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype))
+ 
+-struct sockaddr_storage
++struct __attribute_struct_may_alias__ sockaddr_storage
+   {
+     __SOCKADDR_COMMON (ss_);	/* Address family, etc.  */
+     char __ss_padding[_SS_PADSIZE];
+diff --git a/inet/netinet/in.h b/inet/netinet/in.h
+index fa57b6107908590c..f684be5beb26fc62 100644
+--- a/inet/netinet/in.h
++++ b/inet/netinet/in.h
+@@ -244,7 +244,7 @@ extern const struct in6_addr in6addr_loopback;   /* ::1 */
+ 
+ 
+ /* Structure describing an Internet socket address.  */
+-struct sockaddr_in
++struct __attribute_struct_may_alias__ sockaddr_in
+   {
+     __SOCKADDR_COMMON (sin_);
+     in_port_t sin_port;			/* Port number.  */
+@@ -257,9 +257,11 @@ struct sockaddr_in
+ 			   - sizeof (struct in_addr)];
+   };
+ 
+-#if !__USE_KERNEL_IPV6_DEFS
++#if __USE_KERNEL_IPV6_DEFS
++struct __attribute_struct_may_alias__ sockaddr_in6;
++#else
+ /* Ditto, for IPv6.  */
+-struct sockaddr_in6
++struct __attribute_struct_may_alias__ sockaddr_in6
+   {
+     __SOCKADDR_COMMON (sin6_);
+     in_port_t sin6_port;	/* Transport layer port # */
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index 520231dbea3a4e24..399ee7d24cae9446 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -720,4 +720,13 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf
+ # define __attribute_returns_twice__ /* Ignore.  */
+ #endif
+ 
++/* Mark struct types as aliasable.  Restricted to compilers that
++   support forward declarations of structs in the presence of the
++   attribute.  */
++#if __GNUC_PREREQ (7, 1) || defined __clang__
++# define __attribute_struct_may_alias__ __attribute__ ((__may_alias__))
++#else
++# define __attribute_struct_may_alias__
++#endif
++
+ #endif	 /* sys/cdefs.h */
+diff --git a/socket/sys/un.h b/socket/sys/un.h
+index bf03b7d6ce959065..ff9cbd6efa7693d5 100644
+--- a/socket/sys/un.h
++++ b/socket/sys/un.h
+@@ -26,7 +26,7 @@
+ __BEGIN_DECLS
+ 
+ /* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket.  */
+-struct sockaddr_un
++struct __attribute_struct_may_alias__ sockaddr_un
+   {
+     __SOCKADDR_COMMON (sun_);
+     char sun_path[108];		/* Path name.  */
+diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h
+index 3e72f9fa93add888..b5eeac373111e694 100644
+--- a/sysdeps/mach/hurd/bits/socket.h
++++ b/sysdeps/mach/hurd/bits/socket.h
+@@ -153,7 +153,7 @@ enum __socket_type
+ #include <bits/sockaddr.h>
+ 
+ /* Structure describing a generic socket address.  */
+-struct sockaddr
++struct __attribute_struct_may_alias__ sockaddr
+   {
+     __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
+     char sa_data[14];		/* Address data.  */
+@@ -170,7 +170,7 @@ struct sockaddr
+ #define _SS_PADSIZE \
+   (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype))
+ 
+-struct sockaddr_storage
++struct __attribute_struct_may_alias__ sockaddr_storage
+   {
+     __SOCKADDR_COMMON (ss_);	/* Address family, etc.  */
+     char __ss_padding[_SS_PADSIZE];
+diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
+index 0d86feb4cadc13e3..6dab283a2ebeaed1 100644
+--- a/sysdeps/unix/sysv/linux/bits/socket.h
++++ b/sysdeps/unix/sysv/linux/bits/socket.h
+@@ -180,7 +180,7 @@ typedef __socklen_t socklen_t;
+ #include <bits/sockaddr.h>
+ 
+ /* Structure describing a generic socket address.  */
+-struct sockaddr
++struct __attribute_struct_may_alias__ sockaddr
+   {
+     __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
+     char sa_data[14];		/* Address data.  */
+@@ -193,7 +193,7 @@ struct sockaddr
+ #define _SS_PADSIZE \
+   (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype))
+ 
+-struct sockaddr_storage
++struct __attribute_struct_may_alias__ sockaddr_storage
+   {
+     __SOCKADDR_COMMON (ss_);	/* Address family, etc.  */
+     char __ss_padding[_SS_PADSIZE];
+diff --git a/sysdeps/unix/sysv/linux/net/if_packet.h b/sysdeps/unix/sysv/linux/net/if_packet.h
+index 9ffb69b508cc8ca7..c17e1c23c5cf9169 100644
+--- a/sysdeps/unix/sysv/linux/net/if_packet.h
++++ b/sysdeps/unix/sysv/linux/net/if_packet.h
+@@ -26,7 +26,7 @@
+    From Linux 2.1 the AF_PACKET interface is preferred and you should
+    consider using it in place of this one.  */
+ 
+-struct sockaddr_pkt
++struct __attribute_struct_may_alias__ sockaddr_pkt
+   {
+     __SOCKADDR_COMMON (spkt_);
+     unsigned char spkt_device[14];
+diff --git a/sysdeps/unix/sysv/linux/netash/ash.h b/sysdeps/unix/sysv/linux/netash/ash.h
+index 7d885d17cc9ec313..7a6ff50b17b370c4 100644
+--- a/sysdeps/unix/sysv/linux/netash/ash.h
++++ b/sysdeps/unix/sysv/linux/netash/ash.h
+@@ -22,7 +22,7 @@
+ #include <features.h>
+ #include <bits/sockaddr.h>
+ 
+-struct sockaddr_ash
++struct __attribute_struct_may_alias__ sockaddr_ash
+   {
+     __SOCKADDR_COMMON (sash_);		/* Common data: address family etc.  */
+     int sash_ifindex;			/* Interface to use.  */
+diff --git a/sysdeps/unix/sysv/linux/neteconet/ec.h b/sysdeps/unix/sysv/linux/neteconet/ec.h
+index b07a10796196e28e..f3132f06ff9f8dee 100644
+--- a/sysdeps/unix/sysv/linux/neteconet/ec.h
++++ b/sysdeps/unix/sysv/linux/neteconet/ec.h
+@@ -28,7 +28,7 @@ struct ec_addr
+     unsigned char net;			/* Network number.  */
+   };
+ 
+-struct sockaddr_ec
++struct __attribute_struct_may_alias__ sockaddr_ec
+   {
+     __SOCKADDR_COMMON (sec_);
+     unsigned char port;			/* Port number.  */
+diff --git a/sysdeps/unix/sysv/linux/netiucv/iucv.h b/sysdeps/unix/sysv/linux/netiucv/iucv.h
+index f5fad817513f3c46..27151e8bbe1e7fa2 100644
+--- a/sysdeps/unix/sysv/linux/netiucv/iucv.h
++++ b/sysdeps/unix/sysv/linux/netiucv/iucv.h
+@@ -23,7 +23,7 @@
+ 
+ __BEGIN_DECLS
+ 
+-struct sockaddr_iucv
++struct __attribute_struct_may_alias__ sockaddr_iucv
+   {
+     __SOCKADDR_COMMON (siucv_);
+     unsigned short	siucv_port;		/* Reserved */
diff --git a/SOURCES/glibc-upstream-2.39-61.patch b/SOURCES/glibc-upstream-2.39-61.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8c4aa9819d0634ca8217c4cc259c6df57295160f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-61.patch
@@ -0,0 +1,1824 @@
+commit dd535f4f19ef2b5c367a362af445ecadcf45401e
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Thu Jan 18 10:18:01 2024 -0300
+
+    Always define __USE_TIME_BITS64 when 64 bit time_t is used
+    
+    It was raised on libc-help [1] that some Linux kernel interfaces expect
+    the libc to define __USE_TIME_BITS64 to indicate the time_t size for the
+    kABI.  Different than defined by the initial y2038 design document [2],
+    the __USE_TIME_BITS64 is only defined for ABIs that support more than
+    one time_t size (by defining the _TIME_BITS for each module).
+    
+    The 64 bit time_t redirects are now enabled using a different internal
+    define (__USE_TIME64_REDIRECTS). There is no expected change in semantic
+    or code generation.
+    
+    Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, and
+    arm-linux-gnueabi
+    
+    [1] https://sourceware.org/pipermail/libc-help/2024-January/006557.html
+    [2] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+    (cherry picked from commit a4ed0471d71739928a0d0fa3258b3ff3b158e9b9)
+
+diff --git a/io/bits/poll2.h b/io/bits/poll2.h
+index 6152a8c5e4536d68..efc8b85403e91ba2 100644
+--- a/io/bits/poll2.h
++++ b/io/bits/poll2.h
+@@ -43,7 +43,7 @@ poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
+ 
+ 
+ #ifdef __USE_GNU
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ extern int __REDIRECT (__ppoll64_alias, (struct pollfd *__fds, nfds_t __nfds,
+ 				       const struct timespec *__timeout,
+ 				       const __sigset_t *__ss), __ppoll64);
+diff --git a/io/fcntl.h b/io/fcntl.h
+index 9cee0b5900cb4f7c..666b7e5eb616b950 100644
+--- a/io/fcntl.h
++++ b/io/fcntl.h
+@@ -172,7 +172,7 @@ typedef __pid_t pid_t;
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ # ifndef __USE_FILE_OFFSET64
+ extern int fcntl (int __fd, int __cmd, ...);
+ # else
+@@ -185,7 +185,7 @@ extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64);
+ # ifdef __USE_LARGEFILE64
+ extern int fcntl64 (int __fd, int __cmd, ...);
+ # endif
+-#else /* __USE_TIME_BITS64 */
++#else /* __USE_TIME64_REDIRECTS */
+ # ifdef __REDIRECT
+ extern int __REDIRECT_NTH (fcntl, (int __fd, int __request, ...),
+ 			   __fcntl_time64);
+diff --git a/io/fts.h b/io/fts.h
+index 61f95bb4415f77e2..97a031ebbd040080 100644
+--- a/io/fts.h
++++ b/io/fts.h
+@@ -187,7 +187,7 @@ FTSENT	*fts_read (FTS *);
+ int	 fts_set (FTS *, FTSENT *, int) __THROW;
+ #else
+ # ifdef __REDIRECT
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ FTSENT	*__REDIRECT (fts_children, (FTS *, int), fts64_children);
+ int	 __REDIRECT (fts_close, (FTS *), fts64_close);
+ FTS	*__REDIRECT (fts_open, (char * const *, int,
+@@ -206,7 +206,7 @@ int	 __REDIRECT_NTH (fts_set, (FTS *, FTSENT *, int),
+ 			 __fts64_set_time64);
+ #  endif
+ # else
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ #   define fts_children fts64_children
+ #   define fts_close fts64_close
+ #   define fts_open fts64_open
+@@ -217,7 +217,7 @@ int	 __REDIRECT_NTH (fts_set, (FTS *, FTSENT *, int),
+ # endif
+ #endif
+ #ifdef __USE_LARGEFILE64
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ FTSENT64 *fts64_children (FTS64 *, int);
+ int	  fts64_close (FTS64 *);
+ FTS64	 *fts64_open (char * const *, int,
+diff --git a/io/ftw.h b/io/ftw.h
+index e4d1b84d53550d26..39cf595b277a0049 100644
+--- a/io/ftw.h
++++ b/io/ftw.h
+@@ -137,7 +137,7 @@ extern int ftw (const char *__dir, __ftw_func_t __func, int __descriptors)
+      __nonnull ((1, 2));
+ #else
+ # ifdef __REDIRECT
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func,
+ 			     int __descriptors), ftw64) __nonnull ((1, 2));
+ #  else
+@@ -146,7 +146,7 @@ extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func,
+      __nonnull ((1, 2));
+ #  endif
+ # else
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ #   define ftw ftw64
+ #  else
+ #   define ftw __ftw64_time64
+@@ -154,7 +154,7 @@ extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func,
+ # endif
+ #endif
+ #ifdef __USE_LARGEFILE64
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int ftw64 (const char *__dir, __ftw64_func_t __func,
+ 		  int __descriptors) __nonnull ((1, 2));
+ # else
+@@ -180,7 +180,7 @@ extern int nftw (const char *__dir, __nftw_func_t __func, int __descriptors,
+ 		 int __flag) __nonnull ((1, 2));
+ # else
+ #  ifdef __REDIRECT
+-#   ifndef __USE_TIME_BITS64
++#   ifndef __USE_TIME64_REDIRECTS
+ extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func,
+ 			      int __descriptors, int __flag), nftw64)
+      __nonnull ((1, 2));
+@@ -190,7 +190,7 @@ extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func,
+      __nonnull ((1, 2));
+ #   endif
+ #  else
+-#   ifndef __USE_TIME_BITS64
++#   ifndef __USE_TIME64_REDIRECTS
+ #    define nftw nftw64
+ #   else
+ #    define nftw __nftw64_time64
+@@ -198,7 +198,7 @@ extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func,
+ #  endif
+ # endif
+ # ifdef __USE_LARGEFILE64
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int nftw64 (const char *__dir, __nftw64_func_t __func,
+ 		   int __descriptors, int __flag) __nonnull ((1, 2));
+ #  else
+diff --git a/io/sys/poll.h b/io/sys/poll.h
+index 7858fad6b9b53725..c324ff5dad0d5a81 100644
+--- a/io/sys/poll.h
++++ b/io/sys/poll.h
+@@ -66,7 +66,7 @@ extern int ppoll (struct pollfd *__fds, nfds_t __nfds,
+ 		  const __sigset_t *__ss)
+     __fortified_attr_access (__write_only__, 1, 2);
+ 
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  ifdef __REDIRECT
+ extern int __REDIRECT (ppoll, (struct pollfd *__fds, nfds_t __nfds,
+                                const struct timespec *__timeout,
+diff --git a/io/sys/stat.h b/io/sys/stat.h
+index 1fa6d6e62ecb2e4b..3b4ba80132d0b703 100644
+--- a/io/sys/stat.h
++++ b/io/sys/stat.h
+@@ -209,7 +209,7 @@ extern int stat (const char *__restrict __file,
+    that file descriptor FD is open on and put them in BUF.  */
+ extern int fstat (int __fd, struct stat *__buf) __THROW __nonnull ((2));
+ #else
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  ifdef __REDIRECT_NTH
+ extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
+ 				  struct stat *__restrict __buf),
+@@ -236,7 +236,7 @@ extern int __REDIRECT_NTH (fstat, (int __fd, struct stat *__buf), fstat64)
+ # endif
+ #endif
+ #ifdef __USE_LARGEFILE64
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int stat64 (const char *__restrict __file,
+ 		   struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2));
+ extern int fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2));
+@@ -265,7 +265,7 @@ extern int fstatat (int __fd, const char *__restrict __file,
+ 		    struct stat *__restrict __buf, int __flag)
+      __THROW __nonnull ((2, 3));
+ # else
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ #   ifdef __REDIRECT_NTH
+ extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file,
+ 				     struct stat *__restrict __buf,
+@@ -287,7 +287,7 @@ extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file,
+ # endif
+ 
+ # ifdef __USE_LARGEFILE64
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int fstatat64 (int __fd, const char *__restrict __file,
+ 		      struct stat64 *__restrict __buf, int __flag)
+      __THROW __nonnull ((2, 3));
+@@ -313,7 +313,7 @@ extern int __REDIRECT_NTH (fstatat64, (int __fd,
+ extern int lstat (const char *__restrict __file,
+ 		  struct stat *__restrict __buf) __THROW __nonnull ((1, 2));
+ # else
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ #   ifdef __REDIRECT_NTH
+ extern int __REDIRECT_NTH (lstat,
+ 			   (const char *__restrict __file,
+@@ -334,7 +334,7 @@ extern int __REDIRECT_NTH (lstat,
+ #  endif
+ # endif
+ # ifdef __USE_LARGEFILE64
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int lstat64 (const char *__restrict __file,
+ 		    struct stat64 *__restrict __buf)
+      __THROW __nonnull ((1, 2));
+@@ -427,7 +427,7 @@ extern int mkfifoat (int __fd, const char *__path, __mode_t __mode)
+ #endif
+ 
+ #ifdef __USE_ATFILE
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Set file access and modification times relative to directory file
+    descriptor.  */
+ extern int utimensat (int __fd, const char *__path,
+@@ -447,7 +447,7 @@ extern int __REDIRECT_NTH (utimensat, (int fd, const char *__path,
+ #endif
+ 
+ #ifdef __USE_XOPEN2K8
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Set file access and modification times of the file associated with FD.  */
+ extern int futimens (int __fd, const struct timespec __times[2]) __THROW;
+ 
+diff --git a/io/utime.h b/io/utime.h
+index c5eacedd6a7c9925..1c7587d9c1475348 100644
+--- a/io/utime.h
++++ b/io/utime.h
+@@ -35,7 +35,7 @@ __BEGIN_DECLS
+ /* Structure describing file times.  */
+ struct utimbuf
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+     __time64_t actime;		/* Access time.  */
+     __time64_t modtime;		/* Modification time.  */
+ #else
+@@ -46,7 +46,7 @@ struct utimbuf
+ 
+ /* Set the access and modification times of FILE to those given in
+    *FILE_TIMES.  If FILE_TIMES is NULL, set them to the current time.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int utime (const char *__file,
+ 		  const struct utimbuf *__file_times)
+      __THROW __nonnull ((1));
+diff --git a/manual/creature.texi b/manual/creature.texi
+index fa5dd9d6ad9081f6..8d19e9dd73560607 100644
+--- a/manual/creature.texi
++++ b/manual/creature.texi
+@@ -192,6 +192,12 @@ Linux kernel version on which the system is running. For Linux kernel
+ version above @b{5.1} syscalls supporting 64-bit time are used. Otherwise,
+ a fallback code is used with legacy (i.e. 32-bit) syscalls.
+ 
++On such platforms, @theglibc{} will also define @code{__USE_TIME64_REDIRECTS}
++to indicate whether the declarations are expanded to different ones
++(either by redefiniding the symbol name or using symbol aliais).
++For instance, if the symbol @code{clock_gettime} expands to
++@code{__glock_gettime64}.
++
+ @item
+ If @code{_TIME_BITS} is defined to be 32, @code{time_t} is defined to
+ be a 32-bit integer where that is supported.  This is not recommended,
+diff --git a/manual/maint.texi b/manual/maint.texi
+index 89da704f45912ecb..04faa222e2bd2fc4 100644
+--- a/manual/maint.texi
++++ b/manual/maint.texi
+@@ -491,6 +491,10 @@ derived as in the dual-time configuration case, and which expands to
+ the symbol's name.  For instance, the macro @code{__clock_gettime64}
+ expands to @code{clock_gettime}.
+ 
++When @code{__TIMESIZE} is set to 64, @theglibc{} will also define
++the@code{__USE_TIME_BITS64} macro.  It is used by the Linux kernel ABI
++to set the expected @code{time_t} size used on some syscalls.
++
+ These macros are purely internal to @theglibc{} and exist only so that
+ a single definition of the 64-bit time functions can be used on both
+ single-time and dual-time configurations, and so that glibc code can
+diff --git a/misc/sys/ioctl.h b/misc/sys/ioctl.h
+index 3f2338ddd32ee2c5..ea6583e12251266d 100644
+--- a/misc/sys/ioctl.h
++++ b/misc/sys/ioctl.h
+@@ -38,7 +38,7 @@ __BEGIN_DECLS
+ /* Perform the I/O control operation specified by REQUEST on FD.
+    One argument may follow; its presence and type depend on REQUEST.
+    Return value depends on REQUEST.  Usually -1 indicates error.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;
+ #else
+ # ifdef __REDIRECT
+diff --git a/misc/sys/select.h b/misc/sys/select.h
+index e6a0c1b8b278ec22..2e45e94bc19b932e 100644
+--- a/misc/sys/select.h
++++ b/misc/sys/select.h
+@@ -98,7 +98,7 @@ __BEGIN_DECLS
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int select (int __nfds, fd_set *__restrict __readfds,
+ 		   fd_set *__restrict __writefds,
+ 		   fd_set *__restrict __exceptfds,
+@@ -123,7 +123,7 @@ extern int __REDIRECT (select,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int pselect (int __nfds, fd_set *__restrict __readfds,
+ 		    fd_set *__restrict __writefds,
+ 		    fd_set *__restrict __exceptfds,
+diff --git a/posix/glob.h b/posix/glob.h
+index 3406662840997c68..b6bba0fbcd0ecce8 100644
+--- a/posix/glob.h
++++ b/posix/glob.h
+@@ -150,7 +150,7 @@ extern int glob (const char *__restrict __pattern, int __flags,
+ /* Free storage allocated in PGLOB by a previous `glob' call.  */
+ extern void globfree (glob_t *__pglob) __THROW;
+ #else
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ extern int __REDIRECT_NTHNL (glob, (const char *__restrict __pattern,
+ 				    int __flags,
+ 				    int (*__errfunc) (const char *, int),
+@@ -170,7 +170,7 @@ extern void __REDIRECT_NTH (globfree, (glob_t *__pglob), globfree64);
+ #endif
+ 
+ #ifdef __USE_LARGEFILE64
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ extern int __REDIRECT_NTHNL (glob64, (const char *__restrict __pattern,
+ 				      int __flags,
+ 				      int (*__errfunc) (const char *, int),
+diff --git a/posix/sched.h b/posix/sched.h
+index 3eac206f359090e9..49f504a488a08727 100644
+--- a/posix/sched.h
++++ b/posix/sched.h
+@@ -74,7 +74,7 @@ extern int sched_get_priority_max (int __algorithm) __THROW;
+ extern int sched_get_priority_min (int __algorithm) __THROW;
+ 
+ /* Get the SCHED_RR interval for the named process.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) __THROW;
+ #else
+ # ifdef __REDIRECT_NTH
+diff --git a/posix/sys/wait.h b/posix/sys/wait.h
+index edbb7b43920dffe7..1f44ee114566b9c9 100644
+--- a/posix/sys/wait.h
++++ b/posix/sys/wait.h
+@@ -139,7 +139,7 @@ struct rusage;
+    nil, store information about the child's resource usage there.  If the
+    WUNTRACED bit is set in OPTIONS, return status for stopped children;
+    otherwise don't.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern __pid_t wait3 (int *__stat_loc, int __options,
+ 		      struct rusage * __usage) __THROWNL;
+ # else
+@@ -154,7 +154,7 @@ extern __pid_t __REDIRECT_NTHNL (wait3, (int *__stat_loc, int __options,
+ #endif
+ 
+ #ifdef __USE_MISC
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* PID is like waitpid.  Other args are like wait3.  */
+ extern __pid_t wait4 (__pid_t __pid, int *__stat_loc, int __options,
+ 		      struct rusage *__usage) __THROWNL;
+diff --git a/resolv/netdb.h b/resolv/netdb.h
+index 14228b0d952664ea..b7f473fafe801b02 100644
+--- a/resolv/netdb.h
++++ b/resolv/netdb.h
+@@ -701,7 +701,7 @@ extern int getaddrinfo_a (int __mode, struct gaicb *__list[__restrict_arr],
+ extern int gai_suspend (const struct gaicb *const __list[], int __ent,
+ 			const struct timespec *__timeout);
+ 
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  if defined(__REDIRECT)
+ extern int __REDIRECT (gai_suspend, (const struct gaicb *const __list[],
+                                      int __ent,
+diff --git a/resource/sys/resource.h b/resource/sys/resource.h
+index a5634ba7153c069c..b0bf751e929af810 100644
+--- a/resource/sys/resource.h
++++ b/resource/sys/resource.h
+@@ -88,7 +88,7 @@ extern int setrlimit64 (__rlimit_resource_t __resource,
+    and put it in *USAGE.  Returns 0 for success, -1 for failure.  */
+ extern int getrusage (__rusage_who_t __who, struct rusage *__usage) __THROW;
+ 
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # if defined(__REDIRECT_NTH)
+ extern int __REDIRECT_NTH (getrusage, (__rusage_who_t __who,
+                                        struct rusage *__usage),
+diff --git a/rt/aio.h b/rt/aio.h
+index 37d19abf16ee98e3..e71435733f988f85 100644
+--- a/rt/aio.h
++++ b/rt/aio.h
+@@ -193,7 +193,7 @@ extern __ssize_t __REDIRECT_NTH (aio_return, (struct aiocb *__aiocbp),
+ extern int __REDIRECT_NTH (aio_cancel,
+ 			   (int __fildes, struct aiocb *__aiocbp),
+ 			   aio_cancel64);
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ extern int __REDIRECT_NTH (aio_suspend,
+ 			   (const struct aiocb *const __list[], int __nent,
+ 			    const struct timespec *__restrict __timeout),
+@@ -215,7 +215,7 @@ extern int __REDIRECT_NTH (aio_fsync,
+ #  define aio_error aio_error64
+ #  define aio_return aio_return64
+ #  define aio_cancel aio_cancel64
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ #   define aio_suspend __aio_suspend_time64
+ #  else
+ #   define aio_suspend aio_suspend64
+diff --git a/rt/mqueue.h b/rt/mqueue.h
+index 787cc36df2eaf9e8..fd6fff4bb2326717 100644
+--- a/rt/mqueue.h
++++ b/rt/mqueue.h
+@@ -71,7 +71,7 @@ extern int mq_send (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len,
+ 		    unsigned int __msg_prio) __nonnull ((2));
+ 
+ #ifdef __USE_XOPEN2K
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Receive the oldest from highest priority messages in message queue
+    MQDES, stop waiting if ABS_TIMEOUT expires.  */
+ extern ssize_t mq_timedreceive (mqd_t __mqdes, char *__restrict __msg_ptr,
+diff --git a/signal/signal.h b/signal/signal.h
+index f37499ce607b998a..8e07b041b1c07fa9 100644
+--- a/signal/signal.h
++++ b/signal/signal.h
+@@ -269,7 +269,7 @@ extern int sigwaitinfo (const sigset_t *__restrict __set,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int sigtimedwait (const sigset_t *__restrict __set,
+ 			 siginfo_t *__restrict __info,
+ 			 const struct timespec *__restrict __timeout)
+diff --git a/socket/sys/socket.h b/socket/sys/socket.h
+index 366eaab845a6f326..463cf3291b714427 100644
+--- a/socket/sys/socket.h
++++ b/socket/sys/socket.h
+@@ -170,7 +170,7 @@ extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern ssize_t sendmsg (int __fd, const struct msghdr *__message,
+ 			int __flags);
+ #else
+@@ -191,7 +191,7 @@ extern ssize_t __sendmsg64 (int __fd, const struct msghdr *__message,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int sendmmsg (int __fd, struct mmsghdr *__vmessages,
+ 		     unsigned int __vlen, int __flags);
+ # else
+@@ -204,7 +204,7 @@ extern int __sendmmsg64 (int __fd, struct mmsghdr *__vmessages,
+ 			 unsigned int __vlen, int __flags);
+ #   define sendmmsg __sendmmsg64
+ #  endif
+-# endif	 /* __USE_TIME_BITS64 */
++# endif	 /* __USE_TIME64_REDIRECTS */
+ #endif /* __USE_GNU */
+ 
+ /* Receive a message as described by MESSAGE from socket FD.
+@@ -212,7 +212,7 @@ extern int __sendmmsg64 (int __fd, struct mmsghdr *__vmessages,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags);
+ #else
+ # ifdef __REDIRECT
+@@ -231,7 +231,7 @@ extern ssize_t __recvmsg64 (int __fd, struct msghdr *__message, int __flags);
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
+ 		     unsigned int __vlen, int __flags,
+ 		     struct timespec *__tmo);
+@@ -251,7 +251,7 @@ extern int __REDIRECT (recvmmsg, (int __fd, struct mmsghdr *__vmessages,
+ /* Put the current value for socket FD's option OPTNAME at protocol level LEVEL
+    into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's
+    actual length.  Returns 0 on success, -1 for errors.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int getsockopt (int __fd, int __level, int __optname,
+ 		       void *__restrict __optval,
+ 		       socklen_t *__restrict __optlen) __THROW;
+@@ -273,7 +273,7 @@ extern int __getsockopt64 (int __fd, int __level, int __optname,
+ /* Set socket FD's option OPTNAME at protocol level LEVEL
+    to *OPTVAL (which is OPTLEN bytes long).
+    Returns 0 on success, -1 for errors.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int setsockopt (int __fd, int __level, int __optname,
+ 		       const void *__optval, socklen_t __optlen) __THROW;
+ #else
+diff --git a/support/timespec.h b/support/timespec.h
+index 42f32bcc2c30eaac..5ccc7163a50198a5 100644
+--- a/support/timespec.h
++++ b/support/timespec.h
+@@ -35,7 +35,7 @@ make_timespec (time_t s, long int ns)
+ 
+ enum { TIMESPEC_HZ = 1000000000 };
+ 
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ struct timespec timespec_add (struct timespec, struct timespec)
+   __attribute__((const));
+ struct timespec timespec_sub (struct timespec, struct timespec)
+diff --git a/support/xtime.h b/support/xtime.h
+index 5200eef2e017d380..9961899634e47a1b 100644
+--- a/support/xtime.h
++++ b/support/xtime.h
+@@ -30,7 +30,7 @@ __BEGIN_DECLS
+ /* The following functions call the corresponding libc functions and
+    terminate the process on error.  */
+ 
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ void xclock_gettime (clockid_t clock, struct timespec *ts);
+ void xclock_settime (clockid_t clock, const struct timespec *ts);
+ #else
+diff --git a/support/xunistd.h b/support/xunistd.h
+index b5e8c2f420021c42..13be9a46a3e6b07b 100644
+--- a/support/xunistd.h
++++ b/support/xunistd.h
+@@ -36,7 +36,7 @@ pid_t xwaitpid (pid_t, int *status, int flags);
+ void xpipe (int[2]);
+ void xdup2 (int, int);
+ int xopen (const char *path, int flags, mode_t);
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ # ifdef __USE_FILE_OFFSET64
+ void xstat (const char *path, struct stat *);
+ void xlstat (const char *path, struct stat *);
+diff --git a/sysdeps/generic/features-time64.h b/sysdeps/generic/features-time64.h
+deleted file mode 100644
+index 4d38b8ba766b34f5..0000000000000000
+--- a/sysdeps/generic/features-time64.h
++++ /dev/null
+@@ -1,19 +0,0 @@
+-/* Features part to handle 64-bit time_t support.  Generic version.
+-   Copyright (C) 2021-2024 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <https://www.gnu.org/licenses/>.  */
+-
+-/* The generic configuration only support _TIME_BITS=32.  */
+diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
+index 1607fdf29a5ed964..3d4f4a756c66750d 100644
+--- a/sysdeps/nptl/pthread.h
++++ b/sysdeps/nptl/pthread.h
+@@ -223,7 +223,7 @@ extern int pthread_join (pthread_t __th, void **__thread_return);
+    the thread in *THREAD_RETURN, if THREAD_RETURN is not NULL.  */
+ extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW;
+ 
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Make calling thread wait for termination of the thread TH, but only
+    until TIMEOUT.  The exit status of the thread is stored in
+    *THREAD_RETURN, if THREAD_RETURN is not NULL.
+@@ -796,7 +796,7 @@ extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
+ 
+ #ifdef __USE_XOPEN2K
+ /* Wait until lock becomes available, or specified time passes. */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
+ 				    const struct timespec *__restrict
+ 				    __abstime) __THROWNL __nonnull ((1, 2));
+@@ -813,7 +813,7 @@ extern int __REDIRECT_NTHNL (pthread_mutex_timedlock,
+ #endif
+ 
+ #ifdef __USE_GNU
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_mutex_clocklock (pthread_mutex_t *__restrict __mutex,
+ 				    clockid_t __clockid,
+ 				    const struct timespec *__restrict
+@@ -982,7 +982,7 @@ extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
+ 
+ # ifdef __USE_XOPEN2K
+ /* Try to acquire read lock for RWLOCK or return after specified time.  */
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
+ 				       const struct timespec *__restrict
+ 				       __abstime) __THROWNL __nonnull ((1, 2));
+@@ -1000,7 +1000,7 @@ extern int __REDIRECT_NTHNL (pthread_rwlock_timedrdlock,
+ # endif
+ 
+ # ifdef __USE_GNU
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_rwlock_clockrdlock (pthread_rwlock_t *__restrict __rwlock,
+ 				       clockid_t __clockid,
+ 				       const struct timespec *__restrict
+@@ -1029,7 +1029,7 @@ extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
+ 
+ # ifdef __USE_XOPEN2K
+ /* Try to acquire write lock for RWLOCK or return after specified time.  */
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
+ 				       const struct timespec *__restrict
+ 				       __abstime) __THROWNL __nonnull ((1, 2));
+@@ -1047,7 +1047,7 @@ extern int __REDIRECT_NTHNL (pthread_rwlock_timedwrlock,
+ # endif
+ 
+ # ifdef __USE_GNU
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_rwlock_clockwrlock (pthread_rwlock_t *__restrict __rwlock,
+ 				       clockid_t __clockid,
+ 				       const struct timespec *__restrict
+@@ -1141,7 +1141,7 @@ extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
+ 				   pthread_mutex_t *__restrict __mutex,
+ 				   const struct timespec *__restrict __abstime)
+@@ -1167,7 +1167,7 @@ extern int __REDIRECT (pthread_cond_timedwait,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW. */
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int pthread_cond_clockwait (pthread_cond_t *__restrict __cond,
+ 				   pthread_mutex_t *__restrict __mutex,
+ 				   __clockid_t __clock_id,
+diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h
+index c75ca4ce6d12e081..8a096336991730a8 100644
+--- a/sysdeps/pthread/semaphore.h
++++ b/sysdeps/pthread/semaphore.h
+@@ -59,7 +59,7 @@ extern int sem_wait (sem_t *__sem) __nonnull ((1));
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int sem_timedwait (sem_t *__restrict __sem,
+ 			  const struct timespec *__restrict __abstime)
+   __nonnull ((1, 2));
+@@ -77,7 +77,7 @@ extern int __REDIRECT (sem_timedwait,
+ #endif
+ 
+ #ifdef __USE_GNU
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int sem_clockwait (sem_t *__restrict __sem,
+ 			  clockid_t clock,
+ 			  const struct timespec *__restrict __abstime)
+diff --git a/sysdeps/pthread/threads.h b/sysdeps/pthread/threads.h
+index c5410b5c3af84883..7cade24e1f4b9e7a 100644
+--- a/sysdeps/pthread/threads.h
++++ b/sysdeps/pthread/threads.h
+@@ -90,7 +90,7 @@ extern thrd_t thrd_current (void);
+    __TIME_POINT.  The current thread may resume if receives a signal.  In
+    that case, if __REMAINING is not NULL, the remaining time is stored in
+    the object pointed by it.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int thrd_sleep (const struct timespec *__time_point,
+ 		       struct timespec *__remaining);
+ #else
+@@ -143,7 +143,7 @@ extern int mtx_lock (mtx_t *__mutex);
+ /* Block the current thread until the mutex pointed by __MUTEX is unlocked
+    or time pointed by __TIME_POINT is reached.  In case the mutex is unlock,
+    the current thread will not be blocked.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int mtx_timedlock (mtx_t *__restrict __mutex,
+ 			  const struct timespec *__restrict __time_point);
+ #else
+@@ -194,7 +194,7 @@ extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex);
+ /* Block current thread on the condition variable until condition variable
+    pointed by __COND is signaled or time pointed by __TIME_POINT is
+    reached.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int cnd_timedwait (cnd_t *__restrict __cond,
+ 			  mtx_t *__restrict __mutex,
+ 			  const struct timespec *__restrict __time_point);
+diff --git a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
+index 255feaa8cbf048b5..89534fea85100202 100644
+--- a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
+@@ -28,7 +28,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;			/* Device.  */
+@@ -83,13 +83,13 @@ struct stat
+ # else
+     __ino64_t st_ino;			/* File serial number.	*/
+ # endif
+-#endif /* __USE_TIME_BITS64  */
++#endif /* __USE_TIME64_REDIRECTS  */
+   };
+ 
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;			/* Device.  */
+@@ -125,7 +125,7 @@ struct stat64
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+ #  endif
+     __ino64_t st_ino;			/* File serial number.		*/
+-# endif /* __USE_TIME_BITS64  */
++# endif /* __USE_TIME64_REDIRECTS  */
+   };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/bits/socket-constants.h b/sysdeps/unix/sysv/linux/bits/socket-constants.h
+index d997dbf5943aa90f..b2102d3abfe5a386 100644
+--- a/sysdeps/unix/sysv/linux/bits/socket-constants.h
++++ b/sysdeps/unix/sysv/linux/bits/socket-constants.h
+@@ -64,7 +64,7 @@
+ #  define SO_TIMESTAMPNS_NEW 64
+ #  define SO_TIMESTAMPING_NEW 65
+ 
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ #   define SO_RCVTIMEO SO_RCVTIMEO_NEW
+ #   define SO_SNDTIMEO SO_SNDTIMEO_NEW
+ #   define SO_TIMESTAMP SO_TIMESTAMP_NEW
+diff --git a/sysdeps/unix/sysv/linux/bits/time.h b/sysdeps/unix/sysv/linux/bits/time.h
+index b70ba58a7dd58f72..cab405797130387d 100644
+--- a/sysdeps/unix/sysv/linux/bits/time.h
++++ b/sysdeps/unix/sysv/linux/bits/time.h
+@@ -77,7 +77,7 @@ __BEGIN_DECLS
+ /* Tune a POSIX clock.  */
+ extern int clock_adjtime (__clockid_t __clock_id, struct timex *__utx) __THROW __nonnull((2));
+ 
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # if defined(__REDIRECT_NTH)
+ extern int __REDIRECT_NTH (clock_adjtime, (__clockid_t __clock_id,
+                                            struct timex *__utx),
+diff --git a/sysdeps/unix/sysv/linux/bits/timex.h b/sysdeps/unix/sysv/linux/bits/timex.h
+index 398d8094f23f0b5d..03ccde6d0a0d086c 100644
+--- a/sysdeps/unix/sysv/linux/bits/timex.h
++++ b/sysdeps/unix/sysv/linux/bits/timex.h
+@@ -25,7 +25,7 @@
+ 
+ struct timex
+ {
+-# if defined __USE_TIME_BITS64 || (__TIMESIZE == 64 && __WORDSIZE == 32)
++# if defined __USE_TIME64_REDIRECTS || (__TIMESIZE == 64 && __WORDSIZE == 32)
+   unsigned int modes;          /* mode selector */
+   int :32;                     /* pad */
+   long long offset;            /* time offset (usec) */
+diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
+index fae50281c7fccdfc..86296ca92299c114 100644
+--- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
++++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
+@@ -26,7 +26,7 @@
+    The type `struct msg' is opaque.  */
+ struct msqid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_msqid64_ds_helper.h>
+ #else
+   struct ipc_perm msg_perm;	/* structure describing operation permission */
+diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
+index 3c277ed1d8a3a956..2ac89b3ce456fd39 100644
+--- a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
++++ b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a set of semaphores.  */
+ struct semid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_semid64_ds_helper.h>
+ #else
+   struct ipc_perm sem_perm;        /* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
+index 09de0b4e3a587c52..1012ed031702df04 100644
+--- a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
++++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a shared memory segment.  */
+ struct shmid_ds
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_shmid64_ds_helper.h>
+ #else
+     struct ipc_perm shm_perm;		/* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
+index 4b4822d6d0c00081..47a9f0aaff8fce00 100644
+--- a/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
+@@ -43,7 +43,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;		/* Device.  */
+@@ -88,7 +88,7 @@ struct stat
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;		/* Device.  */
+diff --git a/sysdeps/unix/sysv/linux/features-time64.h b/sysdeps/unix/sysv/linux/features-time64.h
+index dd3442c2eab58cbe..8d573cd23e48c0f7 100644
+--- a/sysdeps/unix/sysv/linux/features-time64.h
++++ b/sysdeps/unix/sysv/linux/features-time64.h
+@@ -24,9 +24,8 @@
+ # if _TIME_BITS == 64
+ #  if ! defined (_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
+ #   error "_TIME_BITS=64 is allowed only with _FILE_OFFSET_BITS=64"
+-#  elif __TIMESIZE == 32
+-#   define __USE_TIME_BITS64	1
+ #  endif
++#  define __USE_TIME_BITS64	1
+ # elif _TIME_BITS == 32
+ #  if __TIMESIZE > 32
+ #   error "_TIME_BITS=32 is not compatible with __TIMESIZE > 32"
+@@ -34,4 +33,10 @@
+ # else
+ #  error Invalid _TIME_BITS value (can only be 32 or 64-bit)
+ # endif
++#elif __TIMESIZE == 64
++# define __USE_TIME_BITS64      1
++#endif
++
++#if defined __USE_TIME_BITS64 && __TIMESIZE == 32
++# define __USE_TIME64_REDIRECTS 1
+ #endif
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
+index 58b523d03a234a76..80a76a17dc0d75c9 100644
+--- a/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/socket-constants.h
+@@ -54,7 +54,7 @@
+ # define SO_TIMESTAMPNS_NEW 0x4039
+ # define SO_TIMESTAMPING_NEW 0x403A
+ 
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  define SO_RCVTIMEO SO_RCVTIMEO_NEW
+ #  define SO_SNDTIMEO SO_SNDTIMEO_NEW
+ #  define SO_TIMESTAMP SO_TIMESTAMP_NEW
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
+index 069efdbc5579bfde..09ea40054bcd12da 100644
+--- a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
+@@ -28,7 +28,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;			/* Device.  */
+@@ -83,13 +83,13 @@ struct stat
+ # else
+     __ino64_t st_ino;			/* File serial number.	*/
+ # endif
+-#endif /* __USE_TIME_BITS64  */
++#endif /* __USE_TIME64_REDIRECTS  */
+   };
+ 
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;			/* Device.  */
+@@ -125,7 +125,7 @@ struct stat64
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+ #  endif
+     __ino64_t st_ino;			/* File serial number.		*/
+-# endif /* __USE_TIME_BITS64  */
++# endif /* __USE_TIME64_REDIRECTS  */
+   };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
+index 2bc7cac06da36e27..4995e0a4a5017f1a 100644
+--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
+@@ -26,7 +26,7 @@
+    The type `struct msg' is opaque.  */
+ struct msqid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_msqid64_ds_helper.h>
+ #else
+   struct ipc_perm msg_perm;	/* structure describing operation permission */
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
+index dd8fbebcf48891f9..df88949dc20c9821 100644
+--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a set of semaphores.  */
+ struct semid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_semid64_ds_helper.h>
+ #else
+   struct ipc_perm sem_perm;   /* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
+index 58ac572b6e9b13f9..cb3b0303aa28d192 100644
+--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a shared memory segment.  */
+ struct shmid_ds
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_shmid64_ds_helper.h>
+ #else
+     struct ipc_perm shm_perm;		/* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
+index 3b1db157bc0a76a7..b7f20189b1600585 100644
+--- a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
+@@ -25,7 +25,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;			/* Device.  */
+@@ -80,13 +80,13 @@ struct stat
+ # else
+     __ino64_t st_ino;			/* File serial number.	*/
+ # endif
+-#endif /* __USE_TIME_BITS64  */
++#endif /* __USE_TIME64_REDIRECTS  */
+   };
+ 
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;			/* Device.  */
+@@ -122,7 +122,7 @@ struct stat64
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+ #  endif
+     __ino64_t st_ino;			/* File serial number.		*/
+-# endif /* __USE_TIME_BITS64 */
++# endif /* __USE_TIME64_REDIRECTS */
+   };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
+index 0f4693fb1fa6750e..ff1e269f1461a50e 100644
+--- a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
+@@ -26,7 +26,7 @@
+ #ifndef __USE_FILE_OFFSET64
+ struct stat
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+         __dev_t         st_dev;     /* Device.  */
+@@ -64,7 +64,7 @@ struct stat
+ # endif
+         unsigned int            __glibc_reserved4;
+         unsigned int            __glibc_reserved5;
+-#endif /* __USE_TIME_BITS64  */
++#endif /* __USE_TIME64_REDIRECTS  */
+ };
+ #else /* __USE_FILE_OFFSET64 */
+ /* MS: If __USE_FILE_OFFSET64 is setup then struct stat should match stat64
+@@ -74,7 +74,7 @@ struct stat
+  * create one ifdef to separate stats structures.  */
+ struct stat
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+         unsigned long long      st_dev;     /* Device.  */
+@@ -112,14 +112,14 @@ struct stat
+ # endif
+         unsigned int            __glibc_reserved4;
+         unsigned int            __glibc_reserved5;
+-# endif /* __USE_TIME_BITS64 */
++# endif /* __USE_TIME64_REDIRECTS */
+ };
+ #endif /* __USE_FILE_OFFSET64 */
+ 
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+ {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+         unsigned long long      st_dev;     /* Device.  */
+@@ -157,7 +157,7 @@ struct stat64
+ #  endif
+         unsigned int            __glibc_reserved4;
+         unsigned int            __glibc_reserved5;
+-# endif /* __USE_TIME_BITS64 */
++# endif /* __USE_TIME64_REDIRECTS */
+ };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
+index c6908a2793db1e6f..77ffc8b890311c23 100644
+--- a/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/socket-constants.h
+@@ -54,7 +54,7 @@
+ # define SO_TIMESTAMPNS_NEW 64
+ # define SO_TIMESTAMPING_NEW 65
+ 
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  define SO_RCVTIMEO SO_RCVTIMEO_NEW
+ #  define SO_SNDTIMEO SO_SNDTIMEO_NEW
+ #  define SO_TIMESTAMP SO_TIMESTAMP_NEW
+diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
+index 277ebad9b6e66e42..50a4b367f6d8d8da 100644
+--- a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
+@@ -29,7 +29,7 @@
+ /* Structure describing file characteristics.  */
+ struct stat
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     unsigned long int st_dev;
+@@ -82,13 +82,13 @@ struct stat
+     __blkcnt64_t st_blocks;	/* Number of 512-byte blocks allocated.  */
+ #  endif
+     long int st_pad5[14];
+-# endif /* __USE_TIME_BITS64  */
++# endif /* __USE_TIME64_REDIRECTS  */
+   };
+ 
+ # ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ #   include <bits/struct_stat_time64_helper.h>
+ #  else
+     unsigned long int st_dev;
+@@ -123,7 +123,7 @@ struct stat64
+     long int st_pad3;
+     __blkcnt64_t st_blocks;	/* Number of 512-byte blocks allocated.  */
+     long int st_pad4[14];
+-#  endif /* __USE_TIME_BITS64  */
++#  endif /* __USE_TIME64_REDIRECTS  */
+   };
+ # endif /* __USE_LARGEFILE64  */
+ 
+@@ -131,7 +131,7 @@ struct stat64
+ 
+ struct stat
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;
+@@ -189,7 +189,7 @@ struct stat
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;
+@@ -224,7 +224,7 @@ struct stat64
+     unsigned int st_pad3;
+     __blkcnt64_t st_blocks;
+     int st_pad4[14];
+-# endif /* __USE_TIME_BITS64  */
++# endif /* __USE_TIME64_REDIRECTS  */
+ };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
+index 4e8bd51b0aa59929..09c53648b7451ac4 100644
+--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
+@@ -26,7 +26,7 @@
+    The type `struct msg' is opaque.  */
+ struct msqid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_msqid64_ds_helper.h>
+ #else
+   struct ipc_perm msg_perm;	/* structure describing operation permission */
+diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
+index d1a30e31645ee2a4..0746684a7d4c0dc4 100644
+--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a set of semaphores.  */
+ struct semid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_semid64_ds_helper.h>
+ #else
+   struct ipc_perm sem_perm;		/* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
+index 8771164b5762c48f..c665af187489c675 100644
+--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a shared memory segment.  */
+ struct shmid_ds
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_shmid64_ds_helper.h>
+ #else
+     struct ipc_perm shm_perm;		/* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
+index 672c7c6bb8f20314..dab466d881c94b61 100644
+--- a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
+@@ -43,7 +43,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;		/* Device.  */
+@@ -88,7 +88,7 @@ struct stat
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;		/* Device.  */
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
+index 6be5055e65ab0b88..0d3e095c5d4bb94c 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/socket-constants.h
+@@ -54,7 +54,7 @@
+ # define SO_TIMESTAMPNS_NEW 64
+ # define SO_TIMESTAMPING_NEW 65
+ 
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  define SO_RCVTIMEO SO_RCVTIMEO_NEW
+ #  define SO_SNDTIMEO SO_SNDTIMEO_NEW
+ #  define SO_TIMESTAMP SO_TIMESTAMP_NEW
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
+index f6328399cd1f2985..2cf331544a805f06 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
+@@ -28,7 +28,7 @@
+ #if __WORDSIZE == 32
+ struct stat
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;			/* Device.  */
+@@ -79,13 +79,13 @@ struct stat
+ #  endif
+     unsigned long int __glibc_reserved4;
+     unsigned long int __glibc_reserved5;
+-# endif /* __USE_TIME_BITS64 */
++# endif /* __USE_TIME64_REDIRECTS */
+   };
+ 
+ # ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ #   include <bits/struct_stat_time64_helper.h>
+ #  else
+     __dev_t st_dev;			/* Device.  */
+@@ -122,7 +122,7 @@ struct stat64
+ #   endif
+     unsigned long int __glibc_reserved4;
+     unsigned long int __glibc_reserved5;
+-#  endif /* __USE_TIME_BITS64 */
++#  endif /* __USE_TIME64_REDIRECTS */
+   };
+ # endif /* __USE_LARGEFILE64 */
+ 
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
+index 830629cd37e4fccf..44ae08265d41502c 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
+@@ -26,7 +26,7 @@
+    The type `struct msg' is opaque.  */
+ struct msqid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_msqid64_ds_helper.h>
+ #else
+   struct ipc_perm msg_perm;	/* structure describing operation permission */
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
+index 43702575570a7d54..ccee57c28bf70729 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a set of semaphores.  */
+ struct semid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_semid64_ds_helper.h>
+ #else
+   struct ipc_perm sem_perm;   /* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
+index da1b4b3c56383000..58145d0a5d2e8203 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a shared memory segment.  */
+ struct shmid_ds
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_shmid64_ds_helper.h>
+ #else
+     struct ipc_perm shm_perm;		/* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h b/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h
+index 9911c47bb268e207..e5c9024fb241fad9 100644
+--- a/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/struct_stat.h
+@@ -65,7 +65,7 @@ struct stat
+ #else
+ struct stat
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;			/* Device.  */
+@@ -166,7 +166,7 @@ struct stat64
+ # else
+ struct stat64
+   {
+-#  ifdef __USE_TIME_BITS64
++#  ifdef __USE_TIME64_REDIRECTS
+ #   include <bits/struct_stat_time64_helper.h>
+ #  else
+     __dev_t st_dev;			/* Device.  */
+diff --git a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
+index cbd4bc0f31ac0c97..d47cd7be1eeb9f17 100644
+--- a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
+@@ -28,7 +28,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;			/* Device.  */
+@@ -83,13 +83,13 @@ struct stat
+ # else
+     __ino64_t st_ino;			/* File serial number.	*/
+ # endif
+-#endif /* __USE_TIME_BITS64  */
++#endif /* __USE_TIME64_REDIRECTS  */
+   };
+ 
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;			/* Device.  */
+@@ -125,7 +125,7 @@ struct stat64
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+ #  endif
+     __ino64_t st_ino;			/* File serial number.		*/
+-# endif /* __USE_TIME_BITS64  */
++# endif /* __USE_TIME64_REDIRECTS  */
+   };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
+index 59958611c42ed1f6..e7a6b684ccc51a1e 100644
+--- a/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/socket-constants.h
+@@ -54,7 +54,7 @@
+ # define SO_TIMESTAMPNS_NEW 0x0042
+ # define SO_TIMESTAMPING_NEW 0x0043
+ 
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  define SO_RCVTIMEO SO_RCVTIMEO_NEW
+ #  define SO_SNDTIMEO SO_SNDTIMEO_NEW
+ #  define SO_TIMESTAMP SO_TIMESTAMP_NEW
+diff --git a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h
+index 4e48634edc7f16f6..fcab5f480478768b 100644
+--- a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h
+@@ -28,7 +28,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;			/* Device.  */
+@@ -79,13 +79,13 @@ struct stat
+ # endif
+     unsigned long int __glibc_reserved4;
+     unsigned long int __glibc_reserved5;
+-#endif /* __USE_TIME_BITS64  */
++#endif /* __USE_TIME64_REDIRECTS  */
+   };
+ 
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;			/* Device.  */
+@@ -126,7 +126,7 @@ struct stat64
+ #  endif
+     unsigned long int __glibc_reserved4;
+     unsigned long int __glibc_reserved5;
+-# endif /* __USE_TIME_BITS64  */
++# endif /* __USE_TIME64_REDIRECTS  */
+   };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
+index db783c28d414000f..ed8d47c9b61f182b 100644
+--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
+@@ -26,7 +26,7 @@
+    The type `struct msg' is opaque.  */
+ struct msqid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_msqid64_ds_helper.h>
+ #else
+   struct ipc_perm msg_perm;	/* structure describing operation permission */
+diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
+index 1c8a3693dbd6977f..b9e729b8b46a232e 100644
+--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a set of semaphores.  */
+ struct semid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_semid64_ds_helper.h>
+ #else
+   struct ipc_perm sem_perm;   /* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
+index 35a0cc36ab764e52..7885d2ab25d9c679 100644
+--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a shared memory segment.  */
+ struct shmid_ds
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_shmid64_ds_helper.h>
+ #else
+     struct ipc_perm shm_perm;		/* operation permission struct */
+diff --git a/sysdeps/unix/sysv/linux/sys/epoll.h b/sysdeps/unix/sysv/linux/sys/epoll.h
+index 9b51e3bd1471c25c..fc8dce45c8947a03 100644
+--- a/sysdeps/unix/sysv/linux/sys/epoll.h
++++ b/sysdeps/unix/sysv/linux/sys/epoll.h
+@@ -140,7 +140,7 @@ extern int epoll_pwait (int __epfd, struct epoll_event *__events,
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int epoll_pwait2 (int __epfd, struct epoll_event *__events,
+ 			 int __maxevents, const struct timespec *__timeout,
+ 			 const __sigset_t *__ss)
+diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h
+index b13b84626149450e..79a9b31273b33bca 100644
+--- a/sysdeps/unix/sysv/linux/sys/prctl.h
++++ b/sysdeps/unix/sysv/linux/sys/prctl.h
+@@ -38,7 +38,7 @@
+ __BEGIN_DECLS
+ 
+ /* Control process execution.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int prctl (int __option, ...) __THROW;
+ #else
+ # ifdef __REDIRECT
+diff --git a/sysdeps/unix/sysv/linux/sys/timerfd.h b/sysdeps/unix/sysv/linux/sys/timerfd.h
+index 19d0cbfae020d7a6..f66ece306ade51dd 100644
+--- a/sysdeps/unix/sysv/linux/sys/timerfd.h
++++ b/sysdeps/unix/sysv/linux/sys/timerfd.h
+@@ -47,7 +47,7 @@ extern int timerfd_settime (int __ufd, int __flags,
+ 			    const struct itimerspec *__utmr,
+ 			    struct itimerspec *__otmr) __THROW;
+ 
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # if defined(__REDIRECT_NTH)
+ extern int __REDIRECT_NTH (timerfd_settime,
+                            (int __ufd, int __flags,
+@@ -62,7 +62,7 @@ extern int __REDIRECT_NTH (timerfd_settime,
+ /* Return the next expiration time of UFD.  */
+ extern int timerfd_gettime (int __ufd, struct itimerspec *__otmr) __THROW;
+ 
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # if defined(__REDIRECT_NTH)
+ extern int __REDIRECT_NTH (timerfd_gettime, (int __ufd,
+                                              struct itimerspec *__otmr),
+diff --git a/sysdeps/unix/sysv/linux/sys/timex.h b/sysdeps/unix/sysv/linux/sys/timex.h
+index 28ce022253e057ce..568748d7679211fd 100644
+--- a/sysdeps/unix/sysv/linux/sys/timex.h
++++ b/sysdeps/unix/sysv/linux/sys/timex.h
+@@ -54,7 +54,7 @@ struct ntptimeval
+ 
+ __BEGIN_DECLS
+ 
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int adjtimex (struct timex *__ntx) __THROW __nonnull ((1));
+ extern int ntp_gettimex (struct ntptimeval *__ntv) __THROW __nonnull ((1));
+ 
+diff --git a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
+index 21aa315d8dc15681..810d6566f05683f3 100644
+--- a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
+@@ -25,7 +25,7 @@
+ 
+ struct stat
+   {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/struct_stat_time64_helper.h>
+ #else
+     __dev_t st_dev;		/* Device.  */
+@@ -95,14 +95,14 @@ struct stat
+     __ino64_t st_ino;			/* File serial number.	*/
+ #  endif
+ # endif
+-#endif /* __USE_TIME_BITS64  */
++#endif /* __USE_TIME64_REDIRECTS  */
+   };
+ 
+ #ifdef __USE_LARGEFILE64
+ /* Note stat64 has the same shape as stat for x86-64.  */
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
++# ifdef __USE_TIME64_REDIRECTS
+ #  include <bits/struct_stat_time64_helper.h>
+ # else
+     __dev_t st_dev;		/* Device.  */
+@@ -152,7 +152,7 @@ struct stat64
+ #  else
+     __ino64_t st_ino;			/* File serial number.		*/
+ #  endif
+-# endif /* __USE_TIME_BITS64  */
++# endif /* __USE_TIME64_REDIRECTS  */
+   };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
+index 9f3d170b65269927..81867c0316080913 100644
+--- a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
++++ b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
+@@ -23,7 +23,7 @@
+ /* Data structure describing a set of semaphores.  */
+ struct semid_ds
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ # include <bits/types/struct_semid64_ds_helper.h>
+ #else
+   struct ipc_perm sem_perm;   /* operation permission struct */
+diff --git a/sysvipc/sys/msg.h b/sysvipc/sys/msg.h
+index d0388b0522fb4183..4178ad99550e8b12 100644
+--- a/sysvipc/sys/msg.h
++++ b/sysvipc/sys/msg.h
+@@ -58,7 +58,7 @@ struct msgbuf
+ __BEGIN_DECLS
+ 
+ /* Message queue control operation.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) __THROW;
+ #else
+ # ifdef __REDIRECT_NTH
+diff --git a/sysvipc/sys/sem.h b/sysvipc/sys/sem.h
+index 5d9ec39296af6db9..812f1303b3d93360 100644
+--- a/sysvipc/sys/sem.h
++++ b/sysvipc/sys/sem.h
+@@ -48,7 +48,7 @@ struct sembuf
+ __BEGIN_DECLS
+ 
+ /* Semaphore control operation.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int semctl (int __semid, int __semnum, int __cmd, ...) __THROW;
+ #else
+ # ifdef __REDIRECT_NTH
+@@ -68,7 +68,7 @@ extern int semop (int __semid, struct sembuf *__sops, size_t __nsops) __THROW;
+ 
+ #ifdef __USE_GNU
+ /* Operate on semaphore with timeout.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int semtimedop (int __semid, struct sembuf *__sops, size_t __nsops,
+ 		       const struct timespec *__timeout) __THROW;
+ # else
+diff --git a/sysvipc/sys/shm.h b/sysvipc/sys/shm.h
+index 04191656d54d3c89..496e57ef4528af2e 100644
+--- a/sysvipc/sys/shm.h
++++ b/sysvipc/sys/shm.h
+@@ -46,7 +46,7 @@ __BEGIN_DECLS
+    facility.  The definition is found in XPG4.2.  */
+ 
+ /* Shared memory control operation.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) __THROW;
+ #else
+ # ifdef __REDIRECT_NTH
+diff --git a/time/bits/types/struct_timespec.h b/time/bits/types/struct_timespec.h
+index 489e81136d7f4ad5..1141015f276cb330 100644
+--- a/time/bits/types/struct_timespec.h
++++ b/time/bits/types/struct_timespec.h
+@@ -10,14 +10,14 @@
+    has nanoseconds instead of microseconds.  */
+ struct timespec
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+   __time64_t tv_sec;		/* Seconds.  */
+ #else
+   __time_t tv_sec;		/* Seconds.  */
+ #endif
+ #if __WORDSIZE == 64 \
+   || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
+-  || (__TIMESIZE == 32 && !defined __USE_TIME_BITS64)
++  || (__TIMESIZE == 32 && !defined __USE_TIME64_REDIRECTS)
+   __syscall_slong_t tv_nsec;	/* Nanoseconds.  */
+ #else
+ # if __BYTE_ORDER == __BIG_ENDIAN
+diff --git a/time/bits/types/struct_timeval.h b/time/bits/types/struct_timeval.h
+index 3466137c35fb5d0e..0c8e88c82c400d68 100644
+--- a/time/bits/types/struct_timeval.h
++++ b/time/bits/types/struct_timeval.h
+@@ -7,7 +7,7 @@
+    microsecond but also has a range of years.  */
+ struct timeval
+ {
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+   __time64_t tv_sec;		/* Seconds.  */
+   __suseconds64_t tv_usec;	/* Microseconds.  */
+ #else
+diff --git a/time/bits/types/time_t.h b/time/bits/types/time_t.h
+index 84d67f6ac346e249..00cde92c623375f3 100644
+--- a/time/bits/types/time_t.h
++++ b/time/bits/types/time_t.h
+@@ -4,7 +4,7 @@
+ #include <bits/types.h>
+ 
+ /* Returned by `time'.  */
+-#ifdef __USE_TIME_BITS64
++#ifdef __USE_TIME64_REDIRECTS
+ typedef __time64_t time_t;
+ #else
+ typedef __time_t time_t;
+diff --git a/time/sys/time.h b/time/sys/time.h
+index c8708198a5fa2e58..8c3d0c30222d15d1 100644
+--- a/time/sys/time.h
++++ b/time/sys/time.h
+@@ -63,7 +63,7 @@ struct timezone
+    use localtime etc. instead.
+    This function itself is semi-obsolete;
+    most callers should use time or clock_gettime instead. */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern int gettimeofday (struct timeval *__restrict __tv,
+ 			 void *__restrict __tz) __THROW __nonnull ((1));
+ #else
+@@ -77,7 +77,7 @@ extern int __REDIRECT_NTH (gettimeofday, (struct timeval *__restrict __tv,
+ #endif
+ 
+ #ifdef __USE_MISC
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Set the current time of day and timezone information.
+    This call is restricted to the super-user.
+    Setting the timezone in this way is obsolete, but we don't yet
+@@ -143,7 +143,7 @@ typedef enum __itimer_which __itimer_which_t;
+ typedef int __itimer_which_t;
+ #endif
+ 
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ /* Set *VALUE to the current setting of timer WHICH.
+    Return 0 on success, -1 on errors.  */
+ extern int getitimer (__itimer_which_t __which,
+@@ -184,7 +184,7 @@ extern int __REDIRECT_NTH (utimes, (const char *__file,
+ #endif
+ 
+ #ifdef __USE_MISC
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Same as `utimes', but does not follow symbolic links.  */
+ extern int lutimes (const char *__file, const struct timeval __tvp[2])
+      __THROW __nonnull ((1));
+@@ -207,7 +207,7 @@ extern int __REDIRECT_NTH (futimes, (int __fd, const struct timeval __tvp[2]),
+ #endif
+ 
+ #ifdef __USE_GNU
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Change the access time of FILE relative to FD to TVP[0] and the
+    modification time of FILE to TVP[1].  If TVP is a null pointer, use
+    the current time instead.  Returns 0 on success, -1 on errors.  */
+diff --git a/time/time.h b/time/time.h
+index 1609aaeffaac5713..3785dc608f6c6ed6 100644
+--- a/time/time.h
++++ b/time/time.h
+@@ -71,7 +71,7 @@ __BEGIN_DECLS
+    The result / CLOCKS_PER_SEC is program time in seconds.  */
+ extern clock_t clock (void) __THROW;
+ 
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ /* Return the current time and put it in *TIMER if TIMER is not NULL.  */
+ extern time_t time (time_t *__timer) __THROW;
+ 
+@@ -127,7 +127,7 @@ extern char *strptime_l (const char *__restrict __s,
+ #endif
+ 
+ 
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ /* Return the `struct tm' representation of *TIMER
+    in Universal Coordinated Time (aka Greenwich Mean Time).  */
+ extern struct tm *gmtime (const time_t *__timer) __THROW;
+@@ -149,7 +149,7 @@ extern struct tm *__REDIRECT_NTH (localtime, (const time_t *__timer),
+ 
+ 
+ #if defined __USE_POSIX || __GLIBC_USE (ISOC2X)
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Return the `struct tm' representation of *TIMER in UTC,
+    using *TP to store the result.  */
+ extern struct tm *gmtime_r (const time_t *__restrict __timer,
+@@ -180,7 +180,7 @@ extern struct tm*__REDIRECT_NTH (localtime_r, (const time_t *__restrict __t,
+ extern char *asctime (const struct tm *__tp) __THROW;
+ 
+ /* Equivalent to `asctime (localtime (timer))'.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern char *ctime (const time_t *__timer) __THROW;
+ #else
+ # ifdef __REDIRECT_NTH
+@@ -199,7 +199,7 @@ extern char *asctime_r (const struct tm *__restrict __tp,
+ 			char *__restrict __buf) __THROW;
+ 
+ /* Equivalent to `asctime_r (localtime_r (timer, *TMP*), buf)'.  */
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ extern char *ctime_r (const time_t *__restrict __timer,
+ 		      char *__restrict __buf) __THROW;
+ #else
+@@ -242,7 +242,7 @@ extern long int timezone;
+ 
+ 
+ #if defined __USE_MISC || __GLIBC_USE (ISOC2X)
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Like `mktime', but for TP represents Universal Time, not local time.  */
+ extern time_t timegm (struct tm *__tp) __THROW;
+ # else
+@@ -259,7 +259,7 @@ extern time_t __REDIRECT_NTH (timegm, (struct tm *__tp), __timegm64);
+ /* Miscellaneous functions many Unices inherited from the public domain
+    localtime package.  These are included only for compatibility.  */
+ 
+-#ifndef __USE_TIME_BITS64
++#ifndef __USE_TIME64_REDIRECTS
+ /* Another name for `mktime'.  */
+ extern time_t timelocal (struct tm *__tp) __THROW;
+ #else
+@@ -274,7 +274,7 @@ extern int dysize (int __year) __THROW  __attribute__ ((__const__));
+ 
+ 
+ #ifdef __USE_POSIX199309
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Pause execution for a number of nanoseconds.
+ 
+    This function is a cancellation point and therefore not marked with
+@@ -320,7 +320,7 @@ extern int __REDIRECT_NTH (clock_settime, (clockid_t __clock_id, const struct
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+-#  ifndef __USE_TIME_BITS64
++#  ifndef __USE_TIME64_REDIRECTS
+ extern int clock_nanosleep (clockid_t __clock_id, int __flags,
+ 			    const struct timespec *__req,
+ 			    struct timespec *__rem);
+@@ -349,7 +349,7 @@ extern int timer_create (clockid_t __clock_id,
+ extern int timer_delete (timer_t __timerid) __THROW;
+ 
+ /* Set timer TIMERID to VALUE, returning old value in OVALUE.  */
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ extern int timer_settime (timer_t __timerid, int __flags,
+ 			  const struct itimerspec *__restrict __value,
+ 			  struct itimerspec *__restrict __ovalue) __THROW;
+@@ -379,7 +379,7 @@ extern int timer_getoverrun (timer_t __timerid) __THROW;
+ 
+ 
+ #ifdef __USE_ISOC11
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Set TS to calendar time based in time base BASE.  */
+ extern int timespec_get (struct timespec *__ts, int __base)
+      __THROW __nonnull ((1));
+@@ -395,7 +395,7 @@ extern int __REDIRECT_NTH (timespec_get, (struct timespec *__ts, int __base),
+ 
+ 
+ #if __GLIBC_USE (ISOC2X)
+-# ifndef __USE_TIME_BITS64
++# ifndef __USE_TIME64_REDIRECTS
+ /* Set TS to resolution of time base BASE.  */
+ extern int timespec_getres (struct timespec *__ts, int __base)
+      __THROW;
diff --git a/SOURCES/glibc-upstream-2.39-62.patch b/SOURCES/glibc-upstream-2.39-62.patch
new file mode 100644
index 0000000000000000000000000000000000000000..e9289356e10dc861638f5bf69844dbd987dd81ee
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-62.patch
@@ -0,0 +1,38 @@
+commit aee37de299af95007a1f00f2cdf6c1452f39e682
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Apr 5 09:02:36 2024 -0300
+
+    Reinstate generic features-time64.h
+    
+    The a4ed0471d7 removed the generic version which is included by
+    features.h and used by Hurd.
+    
+    Checked by building i686-gnu and x86_64-gnu with build-many-glibc.py.
+    
+    (cherry picked from commit c27f8763cffbb7db9b3f1f5e09ef24d26cbb63f4)
+
+diff --git a/sysdeps/generic/features-time64.h b/sysdeps/generic/features-time64.h
+new file mode 100644
+index 0000000000000000..4d38b8ba766b34f5
+--- /dev/null
++++ b/sysdeps/generic/features-time64.h
+@@ -0,0 +1,19 @@
++/* Features part to handle 64-bit time_t support.  Generic version.
++   Copyright (C) 2021-2024 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++/* The generic configuration only support _TIME_BITS=32.  */
diff --git a/SOURCES/glibc-upstream-2.39-63.patch b/SOURCES/glibc-upstream-2.39-63.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4db9709bec4648b56e792afaec033c9b7a82913e
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-63.patch
@@ -0,0 +1,62 @@
+commit c9d8534406ab69b9bc1fd3fdfb9e88c9580d3f24
+Author: Sunil K Pandey <skpgkp2@gmail.com>
+Date:   Mon May 27 10:08:18 2024 -0700
+
+    i386: Disable Intel Xeon Phi tests for GCC 15 and above (BZ 31782)
+    
+    This patch disables Intel Xeon Phi tests for GCC 15 and above.
+    
+    GCC 15 removed Intel Xeon Phi ISA support.
+    commit e1a7e2c54d52d0ba374735e285b617af44841ace
+    Author: Haochen Jiang <haochen.jiang@intel.com>
+    Date:   Mon May 20 10:43:44 2024 +0800
+    
+        i386: Remove Xeon Phi ISA support
+    
+    Fixes BZ 31782.
+    
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    (cherry picked from commit 1b713c9a5349ef3cd1a8ccf9de017c7865713c67)
+
+diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c
+index 93008dac703e762f..0f43ef2b2da0d3db 100644
+--- a/sysdeps/x86/tst-cpu-features-supports.c
++++ b/sysdeps/x86/tst-cpu-features-supports.c
+@@ -65,7 +65,7 @@ do_test (int argc, char **argv)
+ #endif
+   fails += CHECK_FEATURE_ACTIVE (avx, AVX);
+   fails += CHECK_FEATURE_ACTIVE (avx2, AVX2);
+-#if __GNUC_PREREQ (7, 0)
++#if __GNUC_PREREQ (7, 0) && !__GNUC_PREREQ (15, 0)
+   fails += CHECK_FEATURE_ACTIVE (avx5124fmaps, AVX512_4FMAPS);
+   fails += CHECK_FEATURE_ACTIVE (avx5124vnniw, AVX512_4VNNIW);
+ #endif
+@@ -92,14 +92,18 @@ do_test (int argc, char **argv)
+ #if __GNUC_PREREQ (6, 0)
+   fails += CHECK_FEATURE_ACTIVE (avx512bw, AVX512BW);
+   fails += CHECK_FEATURE_ACTIVE (avx512cd, AVX512CD);
++# if !__GNUC_PREREQ (15, 0)
+   fails += CHECK_FEATURE_ACTIVE (avx512er, AVX512ER);
++# endif
+   fails += CHECK_FEATURE_ACTIVE (avx512dq, AVX512DQ);
+ #endif
+ #if __GNUC_PREREQ (5, 0)
+   fails += CHECK_FEATURE_ACTIVE (avx512f, AVX512F);
+ #endif
+ #if __GNUC_PREREQ (6, 0)
++# if !__GNUC_PREREQ (15, 0)
+   fails += CHECK_FEATURE_ACTIVE (avx512pf, AVX512PF);
++# endif
+   fails += CHECK_FEATURE_ACTIVE (avx512vl, AVX512VL);
+ #endif
+ #if __GNUC_PREREQ (5, 0)
+@@ -148,7 +152,9 @@ do_test (int argc, char **argv)
+ #endif
+   fails += CHECK_FEATURE_ACTIVE (popcnt, POPCNT);
+ #if __GNUC_PREREQ (11, 0)
++# if !__GNUC_PREREQ (15, 0)
+   fails += CHECK_FEATURE_ACTIVE (prefetchwt1, PREFETCHWT1);
++# endif
+   fails += CHECK_FEATURE_ACTIVE (ptwrite, PTWRITE);
+   fails += CHECK_FEATURE_ACTIVE (rdpid, RDPID);
+   fails += CHECK_FEATURE_ACTIVE (rdrnd, RDRAND);
diff --git a/SOURCES/glibc-upstream-2.39-64.patch b/SOURCES/glibc-upstream-2.39-64.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bbba76676d1638610e7dc2876010aeaece0d0016
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-64.patch
@@ -0,0 +1,68 @@
+commit 70f560fc22212f733647c9121c26bbb2307f2e10
+Author: Stafford Horne <shorne@gmail.com>
+Date:   Wed Apr 3 06:40:37 2024 +0100
+
+    misc: Add support for Linux uio.h RWF_NOAPPEND flag
+    
+    In Linux 6.9 a new flag is added to allow for Per-io operations to
+    disable append mode even if a file was opened with the flag O_APPEND.
+    This is done with the new RWF_NOAPPEND flag.
+    
+    This caused two test failures as these tests expected the flag 0x00000020
+    to be unused.  Adding the flag definition now fixes these tests on Linux
+    6.9 (v6.9-rc1).
+    
+      FAIL: misc/tst-preadvwritev2
+      FAIL: misc/tst-preadvwritev64v2
+    
+    This patch adds the flag, adjusts the test and adds details to
+    documentation.
+    
+    Link: https://lore.kernel.org/all/20200831153207.GO3265@brightrain.aerifal.cx/
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    (cherry picked from commit 3db9d208dd5f30b12900989c6d2214782b8e2011)
+
+diff --git a/manual/llio.texi b/manual/llio.texi
+index 0b61d491f50b763a..fae49d14332db675 100644
+--- a/manual/llio.texi
++++ b/manual/llio.texi
+@@ -1339,6 +1339,10 @@ will fail and set @code{errno} to @code{EAGAIN} if the operation would block.
+ 
+ @item RWF_APPEND
+ Per-IO synchronization as if the file was opened with @code{O_APPEND} flag.
++
++@item RWF_NOAPPEND
++This flag allows an offset to be honored, even if the file was opened with
++@code{O_APPEND} flag.
+ @end vtable
+ 
+ When the source file is compiled with @code{_FILE_OFFSET_BITS == 64} the
+diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c
+index b5f19f002cd1653e..8e04ff7282e727b6 100644
+--- a/misc/tst-preadvwritev2-common.c
++++ b/misc/tst-preadvwritev2-common.c
+@@ -34,8 +34,11 @@
+ #ifndef RWF_APPEND
+ # define RWF_APPEND 0
+ #endif
++#ifndef RWF_NOAPPEND
++# define RWF_NOAPPEND 0
++#endif
+ #define RWF_SUPPORTED	(RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \
+-			 | RWF_APPEND)
++			 | RWF_APPEND | RWF_NOAPPEND)
+ 
+ /* Generic uio_lim.h does not define IOV_MAX.  */
+ #ifndef IOV_MAX
+diff --git a/sysdeps/unix/sysv/linux/bits/uio-ext.h b/sysdeps/unix/sysv/linux/bits/uio-ext.h
+index 7854cccef3e0a618..ead7a091566aa295 100644
+--- a/sysdeps/unix/sysv/linux/bits/uio-ext.h
++++ b/sysdeps/unix/sysv/linux/bits/uio-ext.h
+@@ -47,6 +47,7 @@ extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec,
+ #define RWF_SYNC	0x00000004 /* per-IO O_SYNC.  */
+ #define RWF_NOWAIT	0x00000008 /* per-IO nonblocking mode.  */
+ #define RWF_APPEND	0x00000010 /* per-IO O_APPEND.  */
++#define RWF_NOAPPEND	0x00000020 /* per-IO negation of O_APPEND */
+ 
+ __END_DECLS
+ 
diff --git a/SOURCES/glibc-upstream-2.39-65.patch b/SOURCES/glibc-upstream-2.39-65.patch
new file mode 100644
index 0000000000000000000000000000000000000000..60b9efb241ae077001796c1dbbb7b0fed02e9e51
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.39-65.patch
@@ -0,0 +1,44 @@
+commit 6ade91c21140d8c803c289932dbfc74537f65a1f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jun 3 10:49:40 2024 +0200
+
+    elf: Avoid some free (NULL) calls in _dl_update_slotinfo
+    
+    This has been confirmed to work around some interposed mallocs.  Here
+    is a discussion of the impact test ust/libc-wrapper/test_libc-wrapper
+    in lttng-tools:
+    
+      New TLS usage in libgcc_s.so.1, compatibility impact
+      <https://inbox.sourceware.org/libc-alpha/8734v1ieke.fsf@oldenburg.str.redhat.com/>
+    
+    Reportedly, this patch also papers over a similar issue when tcmalloc
+    2.9.1 is not compiled with -ftls-model=initial-exec.  Of course the
+    goal really should be to compile mallocs with the initial-exec TLS
+    model, but this commit appears to be a useful interim workaround.
+    
+    Fixes commit d2123d68275acc0f061e73d5f86ca504e0d5a344 ("elf: Fix slow
+    tls access after dlopen [BZ #19924]").
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit afe42e935b3ee97bac9a7064157587777259c60e)
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 7b3dd9ab60e89ae9..670dbc42fc2e3334 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -819,7 +819,14 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
+ 		 dtv entry free it.  Note: this is not AS-safe.  */
+ 	      /* XXX Ideally we will at some point create a memory
+ 		 pool.  */
+-	      free (dtv[modid].pointer.to_free);
++	      /* Avoid calling free on a null pointer.  Some mallocs
++		 incorrectly use dynamic TLS, and depending on how the
++		 free function was compiled, it could call
++		 __tls_get_addr before the null pointer check in the
++		 free implementation.  Checking here papers over at
++		 least some dynamic TLS usage by interposed mallocs.  */
++	      if (dtv[modid].pointer.to_free != NULL)
++		free (dtv[modid].pointer.to_free);
+ 	      dtv[modid].pointer.val = TLS_DTV_UNALLOCATED;
+ 	      dtv[modid].pointer.to_free = NULL;
+ 
diff --git a/SOURCES/wrap-find-debuginfo.sh b/SOURCES/wrap-find-debuginfo.sh
index ba1719a90b9eeeeca501a530cfb9cbe5bea496ca..5257de7cabd090b114ce3594509cc5ac5523a13d 100644
--- a/SOURCES/wrap-find-debuginfo.sh
+++ b/SOURCES/wrap-find-debuginfo.sh
@@ -18,7 +18,13 @@ set -ex
 workdir="$(mktemp -d -t find_debuginfo.XXXXXX)"
 
 ldso_tmp="$workdir/ld.so"
-libc_tmp="$workdir/libc.so"
+libc_tmp_dir="$workdir/"
+
+# Return the path where a libc should be saved temporarily. This path is
+# based on its original path received in $1.
+libc_tmp_path() {
+    echo "$libc_tmp_dir"`dirname "$1"`"/libc.so"
+}
 
 # Prefer a separately installed debugedit over the RPM-integrated one.
 if command -v debugedit >/dev/null ; then
@@ -34,64 +40,65 @@ trap cleanup 0
 
 sysroot_path="$1"
 shift
+# Resolve symbolic link, so that the activities below only alter the
+# file it points to.
+ldso_path="$(readlink -f "$sysroot_path/$1")"
+shift
 script_path="$1"
 shift
 
-# See ldso_path setting in glibc.spec.
-ldso_path=
-for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \
-  -regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do
-    if test -z "$ldso_path" ; then
-	ldso_path="$ldso_candidate"
-    elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then
-	# x86_64 with 32-bit libc built for glibc32 as well.  Finding
-	# multiple dynamic linkers is expected, not a bug; ensure the
-	# 64-bit one is used.
-	ldso_path="$sysroot_path/lib64/ld-linux-x86-64.so.2"
-    else
-	echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate"
-	exit 1
-    fi
-done
-
 # libc.so.6 always uses this name, so it is simpler to locate.
-libc_path=
-for libc_candidate in `find "$sysroot_path" -maxdepth 2 -name libc.so.6`; do
-    if test -z "$libc_path" ; then
-	libc_path="$libc_candidate"
-    elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then
-	# x86_64 with 32-bit libc built for glibc32 as well.  The test
-	# here uses ld.so paths, not libc paths, to ensure it doesn't
-	# apply on any other architecture.
-	libc_path="$sysroot_path/lib64/libc.so.6"
-    else
-	echo "error: multiple libc.so.6 candidates: $libc_path, $libc_candidate"
-	exit 1
-    fi
-done
+# This can result in multiple paths, hence the loop below.
+libc_path=`find "$sysroot_path" -name libc.so.6`
 
 
 # Preserve the original files.
 cp "$ldso_path" "$ldso_tmp"
-cp "$libc_path" "$libc_tmp"
+for lib in $libc_path ; do
+    libtmp=`libc_tmp_path $lib`
+    mkdir -p `dirname "$libtmp"`
+    cp "$lib" "$libtmp"
+done
 
 # Run the debuginfo extraction.
 "$script_path" "$@"
 
-# libc.so.6: Extract the .gnu_debuglink section
-objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
-  -O binary "$libc_path" "$libc_tmp.debuglink"
+for lib in $libc_path ; do
+    libtmp=`libc_tmp_path "$lib"`
+    # libc.so.6: Extract the .gnu_debuglink section
+    objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
+        -O binary "$lib" "$libtmp.debuglink"
+    # Restore the original files.
+    cp "$libtmp" "$lib"
+
+    # Reduce the size of libc notes.  Primarily for annobin.
+    objcopy --merge-notes "$lib"
+
+    # libc.so.6: Restore the .gnu_debuglink section
+    objcopy --add-section .gnu_debuglink="$libtmp.debuglink" "$lib"
+
+    # libc.so.6: 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.)
+    strip -w \
+          -K '*' \
+          -K '!*.c' \
+          -K '!*.os' \
+          -K '!.annobin_*' \
+          -K '!__EI_*' \
+          -K '!__PRETTY_FUNCTION__*' \
+          "$lib"
+done
 
-# Restore the original files.
+# Restore the original ld.so.
 cp "$ldso_tmp" "$ldso_path"
-cp "$libc_tmp" "$libc_path"
 
 # Reduce the size of notes.  Primarily for annobin.
 objcopy --merge-notes "$ldso_path"
-objcopy --merge-notes "$libc_path"
-
-# libc.so.6: Restore the .gnu_debuglink section
-objcopy --add-section .gnu_debuglink="$libc_tmp.debuglink" "$libc_path"
 
 # ld.so does not have separated debuginfo and so the debuginfo file
 # generated by find-debuginfo is redundant.  Therefore, remove it.
@@ -108,22 +115,6 @@ for ldso_debug_candidate in `find "$sysroot_path" -maxdepth 2 \
 done
 rm -f "$ldso_debug"
 
-# libc.so.6: 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.)
-strip -w \
-    -K '*' \
-    -K '!*.c' \
-    -K '!*.os' \
-    -K '!.annobin_*' \
-    -K '!__EI_*' \
-    -K '!__PRETTY_FUNCTION__*' \
-    "$libc_path"
-
 # ld.so: Rewrite the source file paths to match the extracted
 # locations.  First compute the arguments for invoking debugedit.
 # See find-debuginfo.sh.
@@ -147,7 +138,7 @@ done
 debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
 $debugedit -b "$debug_base_name" -d "$debug_dest_name" -n $ldso_path
 # Remove the .annobin* symbols (and only them).
-if nm --format=just-symbols "$ldso_path" \
+if nm --format=posix "$ldso_path" | cut -d' ' -f1 \
 	| grep '^\.annobin' > "$ldso_tmp.annobin-symbols"; then
     objcopy --strip-symbols="$ldso_tmp.annobin-symbols" "$ldso_path"
 fi
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index 493b171e285805fa8fae94e28dc55fc96e75ae2f..13a57dfa99a96673fd79145de39f4224d413427f 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -61,6 +61,13 @@
 %endif
 %endif
 
+# Build the POWER10 multilib.
+%ifarch ppc64le
+%define buildpower10 1
+%else
+%define buildpower10 0
+%endif
+
 %if %{with bootstrap}
 # Disable benchtests, -Werror, docs, and valgrind if we're bootstrapping
 %undefine with_benchtests
@@ -69,16 +76,8 @@
 %undefine with_valgrind
 %endif
 
-# The annobin annotations cause binutils to produce broken ARM EABI
-# unwinding information.  Symptom is a hang/test failure for
-# malloc/tst-malloc-stats-cancellation.  See
-# <https://bugzilla.redhat.com/show_bug.cgi?id=1951492>.
-%ifarch armv7hl
-%undefine _annotated_build
-%endif
-
 # We do our own build flags management.  In particular, see
-# rpm_inherit_flags below.
+# glibc_shell_* below.
 %undefine _auto_set_build_flags
 
 ##############################################################################
@@ -171,7 +170,7 @@ Version: %{glibcversion}
 # - It allows using the Release number without the %%dist tag in the dependency
 #   generator to make the generated requires interchangeable between Rawhide
 #   and ELN (.elnYY < .fcXX).
-%global baserelease 7
+%global baserelease 15
 Release: %{baserelease}%{?dist}
 
 # Licenses:
@@ -238,6 +237,45 @@ Source11: parse-SUPPORTED.py
 # Include in the source RPM for reference.
 Source12: ChangeLog.old
 
+# glibc_ldso: ABI-specific program interpreter name.  Used for debuginfo
+# extraction (wrap-find-debuginfo.sh) and smoke testing ($run_ldso below).
+#
+# glibc_rtld_early_cflags: The ABI baseline for architectures with
+# potentially a later baseline.  The --with-rtld-early-cflags=
+# configure option is passed to the main glibc build if this macro is
+# defined.
+%ifarch %{ix86}
+%global glibc_ldso /lib/ld-linux.so.2
+%endif
+%ifarch aarch64
+%global glibc_ldso /lib/ld-linux-aarch64.so.1
+%endif
+%ifarch ppc
+%global glibc_ldso /lib/ld.so.1
+%endif
+%ifarch ppc64
+%global glibc_ldso /lib64/ld64.so.1
+%define glibc_rtld_early_cflags -mcpu=power8
+%endif
+%ifarch ppc64le
+%global glibc_ldso /lib64/ld64.so.2
+%endif
+%ifarch riscv64
+%global glibc_ldso /lib/ld-linux-riscv64-lp64d.so.1
+%endif
+%ifarch s390
+%global glibc_ldso /lib/ld.so.1
+%define glibc_rtld_early_cflags -march=z13
+%endif
+%ifarch s390x
+%global glibc_ldso /lib/ld64.so.1
+%define glibc_rtld_early_cflags -march=z13
+%endif
+%ifarch x86_64 x86_64_v2 x86_64_v3 x86_64_v4
+%global glibc_ldso /lib64/ld-linux-x86-64.so.2
+%define glibc_rtld_early_cflags -march=x86-64
+%endif
+
 ######################################################################
 # Activate the wrapper script for debuginfo generation, by rewriting
 # the definition of __debug_install_post.
@@ -249,7 +287,7 @@ local original = rpm.expand("%{macrobody:__debug_install_post}")
 -- Avoid embedded newlines that confuse the macro definition.
 original = original:match("^%s*(.-)%s*$"):gsub("\\\n", "")
 rpm.define("__debug_install_post bash " .. wrapper
-  .. " " .. sysroot .. " " .. original)
+  .. " " .. sysroot .. " %{glibc_ldso} " .. original)
 }
 
 # sysroot package support.  These contain arch-specific packages, so
@@ -270,6 +308,18 @@ rpm.define("__debug_install_post bash " .. wrapper
 %global _no_recompute_build_ids 1
 %undefine _unique_build_ids
 
+%ifarch %{ix86}
+# The memory tracing tools (like mtrace, memusage) in glibc-utils only work
+# when the corresponding memory tracing libraries are preloaded.  So we ship
+# memory allocation tracing/checking libraries in glibc-utils, except on
+# i686 where we need to ship them in glibc.i686.  This is because
+# glibc-utils.x86_64 will contain only the 64-bit version of these
+# libraries.
+%global glibc_ship_tracelibs_in_utils 0
+%else
+%global glibc_ship_tracelibs_in_utils 1
+%endif
+
 ##############################################################################
 # Patches:
 # - See each individual patch file for origin and upstream status.
@@ -302,6 +352,51 @@ Patch41: glibc-upstream-2.39-18.patch
 Patch42: glibc-upstream-2.39-19.patch
 Patch43: glibc-upstream-2.39-20.patch
 Patch44: glibc-upstream-2.39-21.patch
+Patch45: glibc-upstream-2.39-22.patch
+Patch46: glibc-upstream-2.39-23.patch
+Patch47: glibc-upstream-2.39-24.patch
+Patch48: glibc-upstream-2.39-25.patch
+Patch49: glibc-upstream-2.39-26.patch
+Patch50: glibc-upstream-2.39-27.patch
+Patch51: glibc-upstream-2.39-28.patch
+Patch52: glibc-upstream-2.39-29.patch
+Patch53: glibc-upstream-2.39-30.patch
+Patch54: glibc-upstream-2.39-31.patch
+Patch55: glibc-upstream-2.39-32.patch
+Patch56: glibc-upstream-2.39-33.patch
+Patch57: glibc-upstream-2.39-34.patch
+Patch58: glibc-upstream-2.39-35.patch
+Patch59: glibc-upstream-2.39-36.patch
+Patch60: glibc-upstream-2.39-37.patch
+Patch61: glibc-upstream-2.39-38.patch
+Patch62: glibc-upstream-2.39-39.patch
+Patch63: glibc-upstream-2.39-40.patch
+Patch64: glibc-upstream-2.39-41.patch
+Patch65: glibc-upstream-2.39-42.patch
+Patch66: glibc-upstream-2.39-43.patch
+Patch67: glibc-upstream-2.39-44.patch
+Patch68: glibc-upstream-2.39-45.patch
+Patch69: glibc-upstream-2.39-46.patch
+Patch70: glibc-upstream-2.39-47.patch
+Patch71: glibc-upstream-2.39-48.patch
+Patch72: glibc-upstream-2.39-49.patch
+Patch73: glibc-upstream-2.39-50.patch
+Patch74: glibc-upstream-2.39-51.patch
+Patch75: glibc-upstream-2.39-52.patch
+Patch76: glibc-upstream-2.39-53.patch
+Patch77: glibc-upstream-2.39-54.patch
+Patch78: glibc-RHEL-22226.patch
+Patch79: glibc-upstream-2.39-55.patch
+Patch80: glibc-upstream-2.39-56.patch
+Patch81: glibc-upstream-2.39-57.patch
+Patch82: glibc-upstream-2.39-58.patch
+Patch83: glibc-upstream-2.39-59.patch
+Patch84: glibc-upstream-2.39-60.patch
+Patch85: glibc-upstream-2.39-61.patch
+Patch86: glibc-upstream-2.39-62.patch
+Patch87: glibc-upstream-2.39-63.patch
+Patch88: glibc-upstream-2.39-64.patch
+Patch89: glibc-upstream-2.39-65.patch
 
 ##############################################################################
 # Continued list of core "glibc" package information:
@@ -371,10 +466,7 @@ BuildRequires: python3 python3-devel
 BuildRequires: gcc >= 7.2.1-6
 %global enablekernel 3.2
 Conflicts: kernel < %{enablekernel}
-%global target %{_target_cpu}-redhat-linux
-%ifarch %{arm}
-%global target %{_target_cpu}-redhat-linuxeabi
-%endif
+%define target %{_target_cpu}-redhat-linux
 %ifarch ppc64le
 %global target ppc64le-redhat-linux
 %endif
@@ -1174,78 +1266,97 @@ cat /proc/sysinfo 2>/dev/null || true
 cat /proc/meminfo
 df
 
-# We build using the native system compilers.
-GCC=gcc
-GXX=g++
-
-# Part of rpm_inherit_flags.  Is overridden below.
-rpm_append_flag ()
-{
-    BuildFlags="$BuildFlags $*"
-}
-
-# Propagates the listed flags to rpm_append_flag if supplied by
-# redhat-rpm-config.
-BuildFlags="-O2 -g"
-rpm_inherit_flags ()
-{
-	local reference=" $* "
-	local flag
-	for flag in $RPM_OPT_FLAGS $RPM_LD_FLAGS ; do
-		if echo "$reference" | grep -q -F " $flag " ; then
-			rpm_append_flag "$flag"
-		fi
-	done
-}
-
 # Propgate select compiler flags from redhat-rpm-config.  These flags
 # are target-dependent, so we use only those which are specified in
 # redhat-rpm-config.  We keep the -m32/-m32/-m64 flags to support
 # multilib builds.
-#
-# Note: For building alternative run-times, care is required to avoid
-# overriding the architecture flags which go into CC/CXX.  The flags
-# below are passed in CFLAGS.
-
-rpm_inherit_flags \
-	"-Wp,-D_GLIBCXX_ASSERTIONS" \
-	"-fasynchronous-unwind-tables" \
-	"-fstack-clash-protection" \
-	"-fno-omit-frame-pointer" \
-	"-funwind-tables" \
-	"-m31" \
-	"-m32" \
-	"-m64" \
-	"-march=armv8-a+lse" \
-	"-march=armv8.1-a" \
-	"-march=haswell" \
-	"-march=i686" \
-	"-march=x86-64" \
-	"-march=x86-64-v2" \
-	"-march=x86-64-v3" \
-	"-march=x86-64-v4" \
-	"-march=z13" \
-	"-march=z14" \
-	"-march=z15" \
-	"-march=zEC12" \
-	"-mbackchain" \
-	"-mbranch-protection=standard" \
-	"-mcpu=power10" \
-	"-mcpu=power8" \
-	"-mcpu=power9" \
-	"-mfpmath=sse" \
-	"-mno-omit-leaf-frame-pointer" \
-	"-msse2" \
-	"-mstackrealign" \
-	"-mtune=generic" \
-	"-mtune=power10" \
-	"-mtune=power8" \
-	"-mtune=power9" \
-	"-mtune=z13" \
-	"-mtune=z14" \
-	"-mtune=z15" \
-	"-mtune=zEC12" \
-	"-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1" \
+
+%{lua:
+-- Split the string argument into keys of an associate array.
+-- The values are set to true.
+local function string_to_array(s)
+    local result = {}
+    for e in string.gmatch(s, "%S+") do
+        result[e] = true
+    end
+    return result
+end
+
+local inherit_flags = {}
+
+-- These flags are put into the CC and CXX arguments to configure.
+-- Alternate builds do not use the flags listed here, only the main build does.
+inherit_flags.cc_main = string_to_array [[
+-march=armv8-a+lse
+-march=armv8.1-a
+-march=haswell
+-march=i686
+-march=x86-64
+-march=x86-64-v2
+-march=x86-64-v3
+-march=x86-64-v4
+-march=z13
+-march=z14
+-march=z15
+-march=zEC12
+-mcpu=power10
+-mcpu=power8
+-mcpu=power9
+-mtune=generic
+-mtune=power10
+-mtune=power8
+-mtune=power9
+-mtune=z13
+-mtune=z14
+-mtune=z15
+-mtune=zEC12
+]]
+
+-- Like inherit_flags_cc_main, but also used for alternate builds.
+inherit_flags.cc = string_to_array [[
+-m31
+-m32
+-m64
+]]
+
+-- These flags are passed through CFLAGS and CXXFLAGS.
+inherit_flags.cflags = string_to_array [[
+-O2
+-O3
+-Wall
+-Wp,-D_GLIBCXX_ASSERTIONS
+-fasynchronous-unwind-tables
+-fno-omit-frame-pointer
+-fstack-clash-protection
+-funwind-tables
+-g
+-mbackchain
+-mbranch-protection=standard
+-mfpmath=sse
+-mno-omit-leaf-frame-pointer
+-msse2
+-mstackrealign
+-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1
+]]
+
+-- Iterate over the build_cflags RPM variable and emit a shell
+-- variable that contains the inherited flags of the indicated variant.
+local function shell_build_flags(variant)
+    local result = {}
+    local inherit = assert(inherit_flags[variant])
+    for f in string.gmatch(rpm.expand("%build_cflags"), "%S+") do
+        if inherit[f] then
+	    result[#result + 1] = f
+	end
+    end
+    print("glibc_flags_" .. variant .. "=\"" .. table.concat(result, " ")
+          .. "\"\n")
+end
+
+shell_build_flags('cc_main') -- Set $glibc_flags_cc_main.
+shell_build_flags('cc') -- Set $glibc_flags_cc.
+shell_build_flags('cflags') -- Set $glibc_flags_cflags.
+}
 
 %if 0%{?_annotated_build} > 0
 # libc_nonshared.a cannot be built with the default hardening flags
@@ -1267,34 +1378,29 @@ BuildFlagsNonshared="-fplugin=annobin -fplugin-arg-annobin-disable -Wa,--generat
 # %%build - Generic options.
 ##############################################################################
 EnableKernel="--enable-kernel=%{enablekernel}"
-# Save the used compiler and options into the file "Gcc" for use later
-# by %%install.
-echo "$GCC" > Gcc
 
 ##############################################################################
 # build()
-#	Build glibc in `build-%{target}$1', passing the rest of the arguments
-#	as CFLAGS to the build (not the same as configure CFLAGS). Several
+#	Build glibc in the directory $1, passing the rest of the arguments
+#	as additional configure arguments.  Several
 #	global values are used to determine build flags, kernel version,
 #	system tap support, etc.
 ##############################################################################
 build()
 {
-	local builddir=build-%{target}${1:+-$1}
-	${1+shift}
+	local builddir=$1
+	shift
 	rm -rf $builddir
 	mkdir $builddir
 	pushd $builddir
-	../configure CC="$GCC" CXX="$GXX" CFLAGS="$BuildFlags $*" \
+	../configure "$@" \
 		--prefix=%{_prefix} \
 		--with-headers=%{_prefix}/include $EnableKernel \
 		--with-nonshared-cflags="$BuildFlagsNonshared" \
 		--enable-bind-now \
 		--build=%{target} \
-		${configure_host} \
 		--enable-stack-protector=strong \
 		--enable-systemtap \
-		${core_with_options} \
 %ifarch %{ix86}
 		--disable-multi-arch \
 %endif
@@ -1329,17 +1435,35 @@ build()
 
 %ifarch x86_64
 # Build for the glibc32 package.
-GCC="$GCC -m32" GXX="$GXX -m32" BuildFlags="${BuildFlags/-m64/-m32}" configure_host="--host=i686-linux-gnu" build 32
+build build-%{target}-32 \
+  CC="gcc -m32" \
+  CXX="g++ -m32" \
+  CFLAGS="${glibc_flags_cflags/-m64/-m32}" \
+  --host=i686-linux-gnu \
+#
 %endif
 
-configure_host=""
-
+# Default set of compiler options.
+build build-%{target} \
+  CC="gcc $glibc_flags_cc $glibc_flags_cc_main" \
+  CXX="g++ $glibc_flags_cc $glibc_flags_cc_main" \
+  CFLAGS="$glibc_flags_cflags" \
+  %{?glibc_rtld_early_cflags:--with-rtld-early-cflags=%glibc_rtld_early_cflags} \
 %ifarch x86_64
-configure_host="--enable-cet"
+  --enable-cet \
+%endif
+#
+
+# POWER10 build variant.
+%if %{buildpower10}
+build build-%{target}-power10 \
+  CC="gcc $glibc_flags_cc" \
+  CXX="g++ $glibc_flags_cc" \
+  CFLAGS="$glibc_flags_cflags" \
+  --with-cpu=power10 \
+#
 %endif
 
-# Default set of compiler options.
-build
 
 ##############################################################################
 # Install glibc...
@@ -1355,9 +1479,6 @@ build
 # Remove existing file lists.
 find . -type f -name '*.filelist' -exec rm -rf {} \;
 
-# Reload compiler and build options that were used during %%build.
-GCC=`cat Gcc`
-
 %ifarch riscv64
 # RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d.
 # Make these be symlinks to /lib64 or /usr/lib64 respectively.  See:
@@ -1422,23 +1543,28 @@ install_different()
 	mkdir -p "$destdir"
 	mkdir -p "$libdestdir"
 	# Walk all of the libraries we installed...
-	for lib in libc math/libm nptl/libpthread rt/librt nptl_db/libthread_db
+	for lib in libc math/libm
 	do
 		libbase=${lib#*/}
 		# Take care that `libbaseso' has a * that needs expanding so
 		# take care with quoting.
-		libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}-*.so)
+		libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*)
 		# Only install if different from default build library.
 		if cmp -s ${lib}.so ../build-%{target}/${lib}.so; then
 			ln -sf "$subdir_up"/$libbaseso $libdestdir/$libbaseso
 		else
 			cp -a ${lib}.so $libdestdir/$libbaseso
 		fi
-		dlib=$libdestdir/$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*)
-		ln -sf $libbaseso $dlib
 	done
 }
 
+%if %{buildpower10}
+pushd build-%{target}-power10
+install_different "$RPM_BUILD_ROOT/%{_libdir}/glibc-hwcaps" power10 ..
+popd
+%endif
+
+
 ##############################################################################
 # Remove the files we don't want to distribute
 ##############################################################################
@@ -1835,6 +1961,7 @@ chmod 0444 master.filelist
 #     a double negation of -v and [^i] so it removes all files in
 #     sbin *but* iconvconfig.
 # - All the libnss files (we add back the ones we want later).
+# - libc_malloc_debug.so, since it is a debugging library.
 # - All bench test binaries.
 # - The aux-cache, since it's handled specially in the files section.
 # - Extra gconv modules.  We add the required modules later.
@@ -1855,6 +1982,9 @@ cat master.filelist \
 	-e '/var/db/Makefile' \
 	-e '/libnss_.*\.so[0-9.]*$' \
 	-e '/libnsl' \
+%if %{glibc_ship_tracelibs_in_utils}
+	-e 'libc_malloc_debug\.so' \
+%endif
 	-e 'glibc-benchtests' \
 	-e 'aux-cache' \
 %ifarch x86_64
@@ -1878,7 +2008,12 @@ for module in compat files dns; do
 %endif
 	>> glibc.filelist
 done
-grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist \
+grep \
+%if ! %{glibc_ship_tracelibs_in_utils}
+	-e "libmemusage.so" \
+%endif
+	-e "libpcprofile.so" \
+	master.filelist \
 %ifarch x86_64
 %dnl Exclude 32-bit libraries built for glibc32.
 	| grep -v -e /lib/lib \
@@ -1934,6 +2069,7 @@ grep '%{_libdir}/lib.*\.a' master.filelist \
 # devel package.
 grep '%{_libdir}/.*\.o' < master.filelist >> devel.filelist
 grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist
+
 # The exceptions are:
 # - libmemusage.so and libpcprofile.so in glibc used by utils.
 # - libnss_*.so which are in nss-devel.
@@ -2053,6 +2189,13 @@ cat > utils.filelist <<EOF
 %{_prefix}/bin/xtrace
 EOF
 
+%if %{glibc_ship_tracelibs_in_utils}
+grep \
+	-e '%{_lib}/libc_malloc_debug\.so' \
+	-e '%{_lib}/libmemusage.so' \
+	< master.filelist >> utils.filelist
+%endif
+
 ###############################################################################
 # nss_db, nss_hesiod
 ###############################################################################
@@ -2170,6 +2313,16 @@ pushd build-%{target}
 run_tests
 popd
 
+%if %{buildpower10}
+# Run this test only if the server supports Power10 instructions.
+if LD_SHOW_AUXV=1 /bin/true | grep -E "AT_HWCAP2:[^$]*arch_3_1" > /dev/null; then
+  echo ====================TESTING -mcpu=power10=============
+  pushd build-%{target}-power10
+  run_tests
+  popd
+fi
+%endif
+
 echo ====================TESTING END=====================
 PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p'
 echo ====================PLT RELOCS LD.SO================
@@ -2178,19 +2331,7 @@ 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).  Use -maxdepth 2 to avoid descending into the /sys-root/
-# sub-tree.  See wrap-find-debuginfo.sh.
-%ifarch x86_64
-# Hardcode the patch to avoid picking up the 32-bit dynamic linker from
-# glibc32; both 32-bit and 64-bit dynamic linkers will be present.
-ldso_path="%{glibc_sysroot}/lib64/ld-linux-x86-64.so.2"
-%else
-ldso_path="$(find %{glibc_sysroot}/ -maxdepth 2 -regextype posix-extended \
-  -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f | LC_ALL=C sort | head -n1)"
-%endif
-run_ldso="$ldso_path --library-path %{glibc_sysroot}/%{_lib}"
+run_ldso="%{glibc_sysroot}/%{glibc_ldso} --library-path %{glibc_sysroot}/%{_lib}"
 
 # Show the auxiliary vector as seen by the new library
 # (even if we do not perform the valgrind test).
@@ -2221,13 +2362,11 @@ if rpm.vercmp(rel, required) < 0 then
   error("FATAL: kernel too old", 0)
 end
 
-%post -p <lua>
-%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
+-- all platform directories before installing a new glibc
 -- version.  RPM only deletes files removed by updates near the end
--- of the transaction.  If we did not remove the obsolete platform
+-- of the transaction.  If we did not remove all platform
 -- directories here, they may be preferred by the dynamic linker
 -- during the execution of subsequent RPM scriptlets, likely
 -- resulting in process startup failures.
@@ -2300,7 +2439,9 @@ for _, rdir in ipairs (remove_dirs) do
   end
 end
 
--- (2) Update /etc/ld.so.conf
+%post -p <lua>
+%glibc_post_funcs
+-- (1) Update /etc/ld.so.conf
 -- Next we update /etc/ld.so.conf to ensure that it starts with
 -- a literal "include ld.so.conf.d/*.conf".
 
@@ -2339,14 +2480,14 @@ if posix.access (ldsoconf) then
   end
 end
 
--- (3) Rebuild ld.so.cache early.
+-- (2) Rebuild ld.so.cache early.
 -- If the format of the cache changes then we need to rebuild
 -- the cache early to avoid any problems running binaries with
 -- the new glibc.
 
 call_ldconfig()
 
--- (4) Update gconv modules cache.
+-- (3) Update gconv modules cache.
 -- If the /usr/lib/gconv/gconv-modules.cache exists, then update it
 -- with the latest set of modules that were just installed.
 -- We assume that the cache is in _libdir/gconv and called
@@ -2354,7 +2495,7 @@ call_ldconfig()
 
 update_gconv_modules_cache()
 
--- (5) On upgrades, restart systemd if installed.  "systemctl -q" does
+-- (4) On upgrades, restart systemd if installed.  "systemctl -q" does
 -- not suppress the error message (which is common in chroots), so
 -- open-code rpm.execute with standard error suppressed.
 if tonumber(arg[2]) >= 2
@@ -2403,6 +2544,9 @@ update_gconv_modules_cache ()
 
 %files -f glibc.filelist
 %dir %{_prefix}/%{_lib}/audit
+%if %{buildpower10}
+%dir /%{_libdir}/glibc-hwcaps/power10
+%endif
 %verify(not md5 size mtime) %config(noreplace) /etc/ld.so.conf
 %verify(not md5 size mtime) %config(noreplace) /etc/rpc
 %dir /etc/ld.so.conf.d
@@ -2478,6 +2622,73 @@ update_gconv_modules_cache ()
 %endif
 
 %changelog
+* Wed Jun 05 2024 Arjun Shankar <arjun@redhat.com> - 2.39-15
+- Sync with upstream branch release/2.39/master,
+  commit 6ade91c21140d8c803c289932dbfc74537f65a1f:
+- elf: Avoid some free (NULL) calls in _dl_update_slotinfo
+- misc: Add support for Linux uio.h RWF_NOAPPEND flag
+- i386: Disable Intel Xeon Phi tests for GCC 15 and above (BZ 31782)
+- Reinstate generic features-time64.h
+- Always define __USE_TIME_BITS64 when 64 bit time_t is used
+- socket: Use may_alias on sockaddr structs (bug 19622)
+- parse_fdinfo: Don't advance pointer twice [BZ #31798]
+- LoongArch: Fix undefined `__memset_aligned` reference in ld.so linking.
+- socket: Add new test for connect
+- libsupport: Add xgetpeername
+- x86_64: Fix missing wcsncat function definition without multiarch (x86-64-v4)
+
+* Fri May 31 2024 Florian Weimer <fweimer@redhat.com> - 2.39-14
+- Enable CPU compatibility diagnostics in ld.so (#2276631, RHEL-31738)
+
+* Wed May 15 2024 Arjun Shankar <arjun@redhat.com> - 2.39-13
+- Move memory tracing libraries to glibc-utils
+
+* Fri May 10 2024 Florian Weimer <fweimer@redhat.com> - 2.39-12
+- Use unsigned types in <utmp.h>/<utmpx.h> (RHEL-22226)
+
+* Fri May 10 2024 Florian Weimer <fweimer@redhat.com> - 2.39-11
+- Sync with upstream branch release/2.39/master,
+  commit 97bb89668d7171164975f3dc895e38343a2f3a95:
+- Force DT_RPATH for --enable-hardcoded-path-in-tests
+- elf: Only process multiple tunable once (BZ 31686)
+- Add a test to check for duplicate definitions in the static library
+- i686: Fix multiple definitions of __memmove_chk and __memset_chk
+- i586: Fix multiple definitions of __memcpy_chk and __mempcpy_chk
+- time: Allow later version licensing.
+- nscd: Use time_t for return type of addgetnetgrentX
+- login: structs utmp, utmpx, lastlog _TIME_BITS independence (bug 30701)
+- login: Check default sizes of structs utmp, utmpx, lastlog
+
+* Fri May 03 2024 Florian Weimer <fweimer@redhat.com> - 2.39-10
+- Build POWER10 multilib
+
+* Fri Apr 26 2024 Florian Weimer <fweimer@redhat.com> - 2.39-9
+- nscd is currently not build, so the security fixes below are not relevant.
+- Sync with upstream branch release/2.39/master,
+  commit fd658f026f25cf59e8db243bc3b3e09cd5a20ba0:
+- elf: Also compile dl-misc.os with $(rtld-early-cflags)
+- CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX (bug 31680)
+- CVE-2024-33600: nscd: Avoid null pointer crashes after notfound response (bug 31678)
+- CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX (bug 31678)
+- CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677)
+- x86: Define MINIMUM_X86_ISA_LEVEL in config.h [BZ #31676]
+- i386: ulp update for SSE2 --disable-multi-arch configurations
+- nptl: Fix tst-cancel30 on kernels without ppoll_time64 support
+
+* Thu Apr 18 2024 Florian Weimer <fweimer@redhat.com> - 2.39-8
+- Sync with upstream branch release/2.39/master,
+  commit 31da30f23cddd36db29d5b6a1c7619361b271fb4:
+- iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961)
+- x86_64: Exclude SSE, AVX and FMA4 variants in libm multiarch
+- Apply the Makefile sorting fix
+- powerpc: Fix ld.so address determination for PCREL mode (bug 31640)
+- x86-64: Simplify minimum ISA check ifdef conditional with if
+- x86-64: Don't use SSE resolvers for ISA level 3 or above
+- AArch64: Check kernel version for SVE ifuncs
+- aarch64: fix check for SVE support in assembler
+- aarch64/fpu: Sync libmvec routines from 2.39 and before with AOR
+- i386: Use generic memrchr in libc (bug 31316)
+
 * Thu Apr 04 2024 Arjun Shankar <arjun@redhat.com> - 2.39-7
 - Sync with upstream branch release/2.39/master,
   commit 5d070d12b3a52bc44dd1b71743abc4b6243862ae: