Your message dated Sat, 16 May 2026 11:07:42 +0000
with message-id <[email protected]>
and subject line Released with 12.14
has caused the Debian Bug report #1135176,
regarding bookworm-pu: package glibc/2.36-9+deb12u14
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1135176: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1135176
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:glibc
User: [email protected]
Usertags: pu

[ Reason ]
The upstream stable branch received many fixes since the latest bookworm
point release, and this update pulls them into the debian package. This
includes most notably 6 security fixes.

[ Impact ]
In case the update isn't approved, systems will be left with a few
issues, including 6 security ones, and the differences with upstream
will increase.

[ Tests ]
Most of the changes come with additional upstream tests, and one
additional test has been enabled.

[ Risks ]
I believe the risks are low, as a significant part of the changes are
already in trixie since the last point release. All the other changes
are in testing for more than 3 weeks, with the exception of the fix for
CVE-2026-4046 which entered testing only a couple of days ago. 

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
The changes are summarized in the changelog, let me give you a few extra
details for some of them:

 - Fix a performance bottleneck with the Address Sanitizer (ASAN) on 32-bit
   arm.

This is https://sourceware.org/bugzilla/show_bug.cgi?id=31405 upstream

 - Fix _dl_find_object when ld.so has LOAD segment gaps, causing wrong
   backtrace unwinding. This affects at least arm64.

This is https://sourceware.org/bugzilla/show_bug.cgi?id=31943 upstream

 - Fix typo in wmemset ifunc selector that caused AVX2/AVX512 paths to be
   skipped.

This is https://sourceware.org/bugzilla/show_bug.cgi?id=33542 upstream

 - Fix POWER optimized rawmemchr function on ppc64el.

This is https://sourceware.org/bugzilla/show_bug.cgi?id=33091 upstream

 - Optimize trylock for high cache contention workloads.

This is https://sourceware.org/bugzilla/show_bug.cgi?id=33704 upstream

 - Fix a typo preventing new tst-wordexp-reuse-mem to run

There was a typo in the makefile, causing the test to be ignored. This
just fixes that.

 - Fix random failure of tst-link-map-contiguous-ldso.

This test failure appears randomly, but has significantly more chances
to happen on a 16KiB page size kernel. This is the case for instance on
the 16k kernel we ship on arm64.

 - Add GLIBC_ABI_DT_X86_64_PLT symbol version on amd64.
 * d/p/amd64/local-revert-x86-64-add-GLIBC_ABI_DT_X86_64_PLT-version.diff:
 revert addition of the GLIBC_ABI_DT_X86_64_PLT symbol version used as ABI
 flag, as the dpkg-shlibdeps version in bookworm is not able to handle it
 (see #1122107).

This is the tricky part of the of this new bookworm-pu version. A bug in
the R_X86_64_GLOB_DAT and R_X86_64_JUMP_SLOT relocation (emitted when
using -z mark-plt) has been fixed in 2.36 (so already included in
bookworm). The GLIBC_ABI_DT_X86_64_PLT symbol version is therefore
emitted by binutils to ensure that binaries built with the fixed ABI are
only executed with a glibc that has the fix. This makes possible to
backport the fix to older glibc version instead of requiring a newer
glibc.

However the dpkg-shlibdeps version in bookworm is not able to handle
symbol versions not associated with any symbol (see #1122107). Therefore
the chosen approach is to just revert the symbol version addition (see
below). I do not expect the dpkg-shlibdeps bug to be fixed in bookworm
given it starts to be old, but users needing a binary compatibility with
other distribution can upgrade.

Note that that the same approach that was done in 2.41-12+deb13u2 in the
13.4 point release (just extended to more flags).

[ Other info ]
There are still a few pending CVEs to be fixed, but no visibility when
they'll be fixed, and I believe that it's better to have an upload not
too late before the point release.
diff --git a/debian/changelog b/debian/changelog
index 87be104d..88dc4614 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,38 @@
+glibc (2.36-9+deb12u14) bookworm; urgency=medium
+
+  * debian/patches/git-updates.diff: update from upstream stable branch:
+    - Fix a performance bottleneck with the Address Sanitizer (ASAN) on 32-bit
+      arm.
+    - Fix _dl_find_object when ld.so has LOAD segment gaps, causing wrong
+      backtrace unwinding. This affects at least arm64.
+    - Add GLIBC_ABI_DT_X86_64_PLT symbol version on amd64.
+    - Fix typo in wmemset ifunc selector that caused AVX2/AVX512 paths to be
+      skipped.
+    - Fix POWER optimized rawmemchr function on ppc64el.
+    - Optimize trylock for high cache contention workloads.
+    - Fix and integer overflow in _int_memalign leading to heap corruption
+      (CVE-2026-0861).  Closes: #1125678.
+    - Fix stack contents leak in getnetbyaddr (CVE-2026-0915).  Closes:
+      #1125748.
+    - Fix bug in wordexp, which could return uninitialized memory when using
+      WRDE_REUSE together with WRDE_APPEND (CVE-2025-15281).  Closes: #1126266.
+    - Fix invalid pointer arithmetic in ANSI_X3.110 iconv module
+    - Fix a typo preventing new tst-wordexp-reuse-mem to run
+    - Fix incorrect handling of DNS responses in gethostbyaddr and
+      gethostbyaddr_r (CVE-2026-4437).  Closes: #1131435.
+    - Fix invalid DNS hostnames returned by gethostbyaddr and
+      gethostbyaddr_r (CVE-2026-4438).  Closes: #1131887.
+    - Fix random failure of tst-link-map-contiguous-ldso.
+    - Fix a possible crash due to an assertion failure when converting
+      inputs from the IBM139x character sets (CVE-2026-4046).  Closes:
+      #1132499.
+  * d/p/amd64/local-revert-x86-64-add-GLIBC_ABI_DT_X86_64_PLT-version.diff:
+    revert addition of the GLIBC_ABI_DT_X86_64_PLT symbol version used as ABI
+    flag, as the dpkg-shlibdeps version in bookworm is not able to handle it
+    (see #1122107).
+
+ -- Aurelien Jarno <[email protected]>  Mon, 27 Apr 2026 22:14:33 +0200
+
 glibc (2.36-9+deb12u13) bookworm; urgency=medium
 
   * debian/patches/git-updates.diff: update from upstream stable branch:
diff --git 
a/debian/patches/amd64/local-revert-x86-64-add-GLIBC_ABI_DT_X86_64_PLT-version.diff
 
b/debian/patches/amd64/local-revert-x86-64-add-GLIBC_ABI_DT_X86_64_PLT-version.diff
new file mode 100644
index 00000000..829c7593
--- /dev/null
+++ 
b/debian/patches/amd64/local-revert-x86-64-add-GLIBC_ABI_DT_X86_64_PLT-version.diff
@@ -0,0 +1,50 @@
+From cc8046413227196540f7f3106739e91e6e8a86d6 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <[email protected]>
+Date: Sat, 7 Mar 2026 23:26:12 +0100
+Subject: [PATCH] Revert "x86-64: Add GLIBC_ABI_DT_X86_64_PLT [BZ #33212]"
+
+This reverts commit 99338e3841dd8dcc36e35c274e1063c33b5e5e87.
+---
+ sysdeps/x86_64/Makefile | 9 ---------
+ sysdeps/x86_64/Versions | 5 -----
+ 2 files changed, 14 deletions(-)
+
+diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
+index f173c5ef4a..c19bef2dec 100644
+--- a/sysdeps/x86_64/Makefile
++++ b/sysdeps/x86_64/Makefile
+@@ -190,15 +190,6 @@ endif
+ 
+ tests-internal += tst-x86-64-tls-1
+ 
+-tests-special += $(objpfx)check-dt-x86-64-plt.out
+-
+-$(objpfx)check-dt-x86-64-plt.out: $(common-objpfx)libc.so
+-       LC_ALL=C $(READELF) -V -W $< \
+-               | sed -ne '/.gnu.version_d/, /.gnu.version_r/ p' \
+-               | grep GLIBC_ABI_DT_X86_64_PLT > $@; \
+-       $(evaluate-test)
+-generated += check-dt-x86-64-plt.out
+-
+ endif # $(subdir) == elf
+ 
+ ifeq ($(subdir),csu)
+diff --git a/sysdeps/x86_64/Versions b/sysdeps/x86_64/Versions
+index 6a989ad3b3..e94758b236 100644
+--- a/sysdeps/x86_64/Versions
++++ b/sysdeps/x86_64/Versions
+@@ -5,11 +5,6 @@ libc {
+   GLIBC_2.13 {
+     __fentry__;
+   }
+-  GLIBC_ABI_DT_X86_64_PLT {
+-    # This symbol is used only for empty version map and will be removed
+-    # by scripts/versions.awk.
+-    __placeholder_only_for_empty_version_map;
+-  }
+ }
+ libm {
+   GLIBC_2.1 {
+-- 
+2.51.0
+
diff --git a/debian/patches/git-updates.diff b/debian/patches/git-updates.diff
index 361d0520..6655f339 100644
--- a/debian/patches/git-updates.diff
+++ b/debian/patches/git-updates.diff
@@ -85,10 +85,10 @@ index d1e139d03c..09c0cf8357 100644
  else                                          # -s
  verbose       :=
 diff --git a/NEWS b/NEWS
-index f61e521fc8..60ac79f4e6 100644
+index f61e521fc8..127817782f 100644
 --- a/NEWS
 +++ b/NEWS
-@@ -5,6 +5,117 @@ See the end for copying conditions.
+@@ -5,6 +5,123 @@ See the end for copying conditions.
  Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
  using `glibc' in the "product" field.
  
@@ -138,6 +138,9 @@ index f61e521fc8..60ac79f4e6 100644
 +  information, which may lead to a buffer overflow if the message string
 +  size aligns to page size.
 +
++  GLIBC-SA-2026-0003: wordexp with WRDE_REUSE and WRDE_APPEND may return
++  uninitialized memory (CVE-2025-15281).
++
 +The following bugs are resolved with this release:
 +
 +  [12154] Do not fail DNS resolution for CNAMEs which are not host names
@@ -193,6 +196,7 @@ index f61e521fc8..60ac79f4e6 100644
 +  [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and 
_dl_tlsdesc_dynamic
 +  [31476] resolv: Track single-request fallback via _res._flags
 +  [31890] resolv: Allow short error responses to match any DNS query
++  [31943] _dl_find_object can fail if ld.so contains gaps between load 
segments
 +  [31965] rseq extension mechanism does not work as intended
 +  [31968] mremap implementation in C does not handle arguments correctly
 +  [32052] Name space violation in fortify wrappers
@@ -202,6 +206,8 @@ index f61e521fc8..60ac79f4e6 100644
 +  [32582] Fix underallocation of abort_msg_s struct (CVE-2025-0395)
 +  [32987] elf: Fix subprocess status handling for tst-dlopen-sgid
 +  [33185] Fix double-free after allocation failure in regcomp
++  [33814] glob: wordexp with WRDE_REUSE and WRDE_APPEND may return
++    uninitialized memory
 +
  Version 2.36
  
@@ -532,7 +538,7 @@ index 2696dde4b1..9b07b4e132 100644
  
  void *
 diff --git a/elf/Makefile b/elf/Makefile
-index fd77d0c7c8..3e08a8046d 100644
+index fd77d0c7c8..97befdaf02 100644
 --- a/elf/Makefile
 +++ b/elf/Makefile
 @@ -53,6 +53,7 @@ routines = \
@@ -584,7 +590,27 @@ index fd77d0c7c8..3e08a8046d 100644
    tst-relsort1 \
    tst-ro-dynamic \
    tst-rtld-run-static \
-@@ -631,6 +638,7 @@ ifeq ($(run-built-tests),yes)
+@@ -497,6 +504,8 @@ tests-internal += \
+   tst-dl_find_object \
+   tst-dl_find_object-threads \
+   tst-dlmopen2 \
++  tst-link-map-contiguous-ldso \
++  tst-link-map-contiguous-libc \
+   tst-ptrguard1 \
+   tst-stackguard1 \
+   tst-tls-surplus \
+@@ -508,6 +517,10 @@ tests-internal += \
+   unload2 \
+   # tests-internal
+ 
++ifeq ($(build-hardcoded-path-in-tests),yes)
++tests-internal += tst-link-map-contiguous-main
++endif
++
+ tests-container += \
+   tst-dlopen-self-container \
+   tst-dlopen-tlsmodid-container \
+@@ -631,6 +644,7 @@ ifeq ($(run-built-tests),yes)
  tests-special += \
    $(objpfx)noload-mem.out \
    $(objpfx)tst-ldconfig-X.out \
@@ -592,7 +618,7 @@ index fd77d0c7c8..3e08a8046d 100644
    $(objpfx)tst-leaks1-mem.out \
    $(objpfx)tst-rtld-help.out \
    # tests-special
-@@ -765,6 +773,8 @@ modules-names += \
+@@ -765,6 +779,8 @@ modules-names += \
    tst-alignmod3 \
    tst-array2dep \
    tst-array5dep \
@@ -601,7 +627,7 @@ index fd77d0c7c8..3e08a8046d 100644
    tst-audit11mod1 \
    tst-audit11mod2 \
    tst-audit12mod1 \
-@@ -798,6 +808,7 @@ modules-names += \
+@@ -798,6 +814,7 @@ modules-names += \
    tst-auditmanymod7 \
    tst-auditmanymod8 \
    tst-auditmanymod9 \
@@ -609,7 +635,7 @@ index fd77d0c7c8..3e08a8046d 100644
    tst-auditmod1 \
    tst-auditmod9a \
    tst-auditmod9b \
-@@ -834,6 +845,9 @@ modules-names += \
+@@ -834,6 +851,9 @@ modules-names += \
    tst-dlmopen1mod \
    tst-dlmopen-dlerror-mod \
    tst-dlmopen-gethostbyname-mod \
@@ -619,7 +645,7 @@ index fd77d0c7c8..3e08a8046d 100644
    tst-dlopenfaillinkmod \
    tst-dlopenfailmod1 \
    tst-dlopenfailmod2 \
-@@ -866,6 +880,23 @@ modules-names += \
+@@ -866,6 +886,23 @@ modules-names += \
    tst-null-argv-lib \
    tst-p_alignmod-base \
    tst-p_alignmod3 \
@@ -643,7 +669,7 @@ index fd77d0c7c8..3e08a8046d 100644
    tst-relsort1mod1 \
    tst-relsort1mod2 \
    tst-ro-dynamic-mod \
-@@ -990,23 +1021,8 @@ modules-names += tst-gnu2-tls1mod
+@@ -990,23 +1027,8 @@ modules-names += tst-gnu2-tls1mod
  $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
  tst-gnu2-tls1mod.so-no-z-defs = yes
  CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
@@ -668,7 +694,7 @@ index fd77d0c7c8..3e08a8046d 100644
  ifeq (yes,$(have-protected-data))
  modules-names += tst-protected1moda tst-protected1modb
  tests += tst-protected1a tst-protected1b
-@@ -2410,6 +2426,11 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh 
$(objpfx)ldconfig
+@@ -2410,6 +2432,11 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh 
$(objpfx)ldconfig
                 '$(run-program-env)' > $@; \
        $(evaluate-test)
  
@@ -680,7 +706,7 @@ index fd77d0c7c8..3e08a8046d 100644
  # Test static linking of all the libraries we can possibly link
  # together.  Note that in some configurations this may be less than the
  # complete list of libraries we build but we try to maxmimize this list.
-@@ -2967,3 +2988,35 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: 
\
+@@ -2967,3 +2994,35 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: 
\
        grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \
          && grep -q '^status: 127$$' $@; \
          $(evaluate-test)
@@ -878,7 +904,7 @@ index bcd6e206e9..ef909d8c66 100644
        if (tls_free_end == GL(dl_tls_static_used))
        GL(dl_tls_static_used) = tls_free_start;
 diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c
-index 4d5831b6f4..2e5b456c11 100644
+index 4d5831b6f4..cb8555a543 100644
 --- a/elf/dl-find_object.c
 +++ b/elf/dl-find_object.c
 @@ -46,7 +46,7 @@ _dl_find_object_slow (void *pc, struct dl_find_object 
*result)
@@ -890,6 +916,134 @@ index 4d5831b6f4..2e5b456c11 100644
          }
  
    /* Object not found.  */
+@@ -465,6 +465,37 @@ _dl_find_object (void *pc1, struct dl_find_object *result)
+ }
+ rtld_hidden_def (_dl_find_object)
+ 
++/* Subroutine of _dlfo_process_initial to split out noncontigous link
++   maps.  NODELETE is the number of used _dlfo_nodelete_mappings
++   elements.  It is incremented as needed, and the new NODELETE value
++   is returned.  */
++static size_t
++_dlfo_process_initial_noncontiguous_map (struct link_map *map,
++                                         size_t nodelete)
++{
++  struct dl_find_object_internal dlfo;
++  _dl_find_object_from_map (map, &dlfo);
++
++  /* PT_LOAD segments for a non-contiguous link map are added to the
++     non-closeable mappings.  */
++  const ElfW(Phdr) *ph = map->l_phdr;
++  const ElfW(Phdr) *ph_end = map->l_phdr + map->l_phnum;
++  for (; ph < ph_end; ++ph)
++    if (ph->p_type == PT_LOAD)
++      {
++        if (_dlfo_nodelete_mappings != NULL)
++          {
++            /* Second pass only.  */
++            _dlfo_nodelete_mappings[nodelete] = dlfo;
++            ElfW(Addr) start = ph->p_vaddr + map->l_addr;
++            _dlfo_nodelete_mappings[nodelete].map_start = start;
++            _dlfo_nodelete_mappings[nodelete].map_end = start + ph->p_memsz;
++          }
++        ++nodelete;
++      }
++  return nodelete;
++}
++
+ /* _dlfo_process_initial is called twice.  First to compute the array
+    sizes from the initial loaded mappings.  Second to fill in the
+    bases and infos arrays with the (still unsorted) data.  Returns the
+@@ -476,29 +507,8 @@ _dlfo_process_initial (void)
+ 
+   size_t nodelete = 0;
+   if (!main_map->l_contiguous)
+-    {
+-      struct dl_find_object_internal dlfo;
+-      _dl_find_object_from_map (main_map, &dlfo);
+-
+-      /* PT_LOAD segments for a non-contiguous are added to the
+-         non-closeable mappings.  */
+-      for (const ElfW(Phdr) *ph = main_map->l_phdr,
+-             *ph_end = main_map->l_phdr + main_map->l_phnum;
+-           ph < ph_end; ++ph)
+-        if (ph->p_type == PT_LOAD)
+-          {
+-            if (_dlfo_nodelete_mappings != NULL)
+-              {
+-                /* Second pass only.  */
+-                _dlfo_nodelete_mappings[nodelete] = dlfo;
+-                _dlfo_nodelete_mappings[nodelete].map_start
+-                  = ph->p_vaddr + main_map->l_addr;
+-                _dlfo_nodelete_mappings[nodelete].map_end
+-                  = _dlfo_nodelete_mappings[nodelete].map_start + ph->p_memsz;
+-              }
+-            ++nodelete;
+-          }
+-    }
++    /* Contiguous case already handled in _dl_find_object_init.  */
++    nodelete = _dlfo_process_initial_noncontiguous_map (main_map, nodelete);
+ 
+   size_t loaded = 0;
+   for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
+@@ -510,11 +520,22 @@ _dlfo_process_initial (void)
+           /* lt_library link maps are implicitly NODELETE.  */
+           if (l->l_type == lt_library || l->l_nodelete_active)
+             {
+-              if (_dlfo_nodelete_mappings != NULL)
+-                /* Second pass only.  */
+-                _dl_find_object_from_map
+-                  (l, _dlfo_nodelete_mappings + nodelete);
+-              ++nodelete;
++              /* The kernel may have loaded ld.so with gaps.   */
++              if (!l->l_contiguous
++#ifdef SHARED
++                  && l == &GL(dl_rtld_map)
++#endif
++                  )
++                nodelete
++                  = _dlfo_process_initial_noncontiguous_map (l, nodelete);
++              else
++                {
++                  if (_dlfo_nodelete_mappings != NULL)
++                    /* Second pass only.  */
++                    _dl_find_object_from_map
++                      (l, _dlfo_nodelete_mappings + nodelete);
++                  ++nodelete;
++                }
+             }
+           else if (l->l_type == lt_loaded)
+             {
+@@ -756,7 +777,6 @@ _dl_find_object_update_1 (struct link_map **loaded, size_t 
count)
+           /* Prefer newly loaded link map.  */
+           assert (loaded_index1 > 0);
+           _dl_find_object_from_map (loaded[loaded_index1 - 1], dlfo);
+-          loaded[loaded_index1 -  1]->l_find_object_processed = 1;
+           --loaded_index1;
+         }
+ 
+diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h
+index 3b49877e0e..9d13163ccd 100644
+--- a/elf/dl-find_object.h
++++ b/elf/dl-find_object.h
+@@ -87,7 +87,7 @@ _dl_find_object_to_external (struct dl_find_object_internal 
*internal,
+ }
+ 
+ /* Extract the object location data from a link map and writes it to
+-   *RESULT using relaxed MO stores.  */
++   *RESULT using relaxed MO stores.  Set L->l_find_object_processed.  */
+ static void __attribute__ ((unused))
+ _dl_find_object_from_map (struct link_map *l,
+                           struct dl_find_object_internal *result)
+@@ -100,6 +100,8 @@ _dl_find_object_from_map (struct link_map *l,
+   atomic_store_relaxed (&result->eh_dbase, (void *) l->l_info[DT_PLTGOT]);
+ #endif
+ 
++  l->l_find_object_processed = 1;
++
+   for (const ElfW(Phdr) *ph = l->l_phdr, *ph_end = l->l_phdr + l->l_phnum;
+        ph < ph_end; ++ph)
+     if (ph->p_type == DLFO_EH_SEGMENT_TYPE)
 diff --git a/elf/dl-fini.c b/elf/dl-fini.c
 index 030b1fcbcd..50ff94db16 100644
 --- a/elf/dl-fini.c
@@ -1875,7 +2029,7 @@ index ca00dd1fe2..3c5e273f2b 100644
  else                                          # -s
  verbose       :=
 diff --git a/elf/rtld.c b/elf/rtld.c
-index cbbaf4a331..6e40893e52 100644
+index cbbaf4a331..bb3fc4806a 100644
 --- a/elf/rtld.c
 +++ b/elf/rtld.c
 @@ -791,6 +791,8 @@ init_tls (size_t naudit)
@@ -1887,7 +2041,103 @@ index cbbaf4a331..6e40893e52 100644
    /* Store for detection of the special case by __tls_get_addr
       so it knows not to pass this dtv to the normal realloc.  */
    GL(dl_initial_dtv) = GET_DTV (tcbp);
-@@ -2122,6 +2124,12 @@ dl_main (const ElfW(Phdr) *phdr,
+@@ -1293,6 +1295,60 @@ rtld_setup_main_map (struct link_map *main_map)
+   return has_interp;
+ }
+ 
++/* Set up the program header information for the dynamic linker
++   itself.  It can be accessed via _r_debug and dl_iterate_phdr
++   callbacks, and it is used by _dl_find_object.  */
++static void
++rtld_setup_phdr (void)
++{
++  /* Starting from binutils-2.23, the linker will define the magic
++     symbol __ehdr_start to point to our own ELF header if it is
++     visible in a segment that also includes the phdrs.  */
++
++  const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
++  assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
++  assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));
++
++  const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff;
++
++  GL(dl_rtld_map).l_phdr = rtld_phdr;
++  GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;
++
++
++  GL(dl_rtld_map).l_contiguous = 1;
++  /* The linker may not have produced a contiguous object.  The kernel
++     will load the object with actual gaps (unlike the glibc loader
++     for shared objects, which always produces a contiguous mapping).
++     See similar logic in rtld_setup_main_map above.  */
++  {
++    ElfW(Addr) expected_load_address = 0;
++    for (const ElfW(Phdr) *ph = rtld_phdr; ph < 
&rtld_phdr[rtld_ehdr->e_phnum];
++       ++ph)
++      if (ph->p_type == PT_LOAD)
++      {
++        ElfW(Addr) mapstart = ph->p_vaddr & ~(GLRO(dl_pagesize) - 1);
++        if (GL(dl_rtld_map).l_contiguous && expected_load_address != 0
++            && expected_load_address != mapstart)
++          GL(dl_rtld_map).l_contiguous = 0;
++        ElfW(Addr) allocend = ph->p_vaddr + ph->p_memsz;
++        /* The next expected address is the page following this load
++           segment.  */
++        expected_load_address = ((allocend + GLRO(dl_pagesize) - 1)
++                                 & ~(GLRO(dl_pagesize) - 1));
++      }
++  }
++
++  /* PT_GNU_RELRO is usually the last phdr.  */
++  size_t cnt = rtld_ehdr->e_phnum;
++  while (cnt-- > 0)
++    if (rtld_phdr[cnt].p_type == PT_GNU_RELRO)
++      {
++      GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr;
++      GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz;
++      break;
++      }
++}
++
+ /* Adjusts the contents of the stack and related globals for the user
+    entry point.  The ld.so processed skip_args arguments and bumped
+    _dl_argv and _dl_argc accordingly.  Those arguments are removed from
+@@ -1762,33 +1818,7 @@ dl_main (const ElfW(Phdr) *phdr,
+   ++GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
+   ++GL(dl_load_adds);
+ 
+-  /* Starting from binutils-2.23, the linker will define the magic symbol
+-     __ehdr_start to point to our own ELF header if it is visible in a
+-     segment that also includes the phdrs.  If that's not available, we use
+-     the old method that assumes the beginning of the file is part of the
+-     lowest-addressed PT_LOAD segment.  */
+-
+-  /* Set up the program header information for the dynamic linker
+-     itself.  It is needed in the dl_iterate_phdr callbacks.  */
+-  const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
+-  assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
+-  assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));
+-
+-  const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff;
+-
+-  GL(dl_rtld_map).l_phdr = rtld_phdr;
+-  GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;
+-
+-
+-  /* PT_GNU_RELRO is usually the last phdr.  */
+-  size_t cnt = rtld_ehdr->e_phnum;
+-  while (cnt-- > 0)
+-    if (rtld_phdr[cnt].p_type == PT_GNU_RELRO)
+-      {
+-      GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr;
+-      GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz;
+-      break;
+-      }
++  rtld_setup_phdr ();
+ 
+   /* Add the dynamic linker to the TLS list if it also uses TLS.  */
+   if (GL(dl_rtld_map).l_tls_blocksize != 0)
+@@ -2122,6 +2152,12 @@ dl_main (const ElfW(Phdr) *phdr,
            if (l->l_faked)
              /* The library was not found.  */
              _dl_printf ("\t%s => not found\n",  l->l_libname->name);
@@ -2395,6 +2645,284 @@ index 0000000000..ec937bf4ec
 +esac
 +
 +exit $errors
+diff --git a/elf/tst-link-map-contiguous-ldso.c 
b/elf/tst-link-map-contiguous-ldso.c
+new file mode 100644
+index 0000000000..f0e26682f2
+--- /dev/null
++++ b/elf/tst-link-map-contiguous-ldso.c
+@@ -0,0 +1,158 @@
++/* Check that _dl_find_object behavior matches up with gaps.
++   Copyright (C) 2025 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 <dlfcn.h>
++#include <gnu/lib-names.h>
++#include <inttypes.h>
++#include <link.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/xdlfcn.h>
++#include <support/xunistd.h>
++#include <support/xstdio.h>
++#include <sys/mman.h>
++#include <unistd.h>
++
++/* Slow path in case we cannot find a gap with mmap (when the runtime has
++   mapped all the pages in the gap for some reason).  */
++static bool
++find_gap_with_proc_self_map (const struct link_map *l)
++{
++  int pagesize = getpagesize ();
++
++  support_need_proc ("Reads /proc/self/maps to find gap in ld.so mapping");
++
++  /* Parse /proc/self/maps and find all the mappings in the ld.so range
++     but not from ld.so.  */
++  FILE *f = xfopen ("/proc/self/maps", "r");
++  char *line = NULL, *path_ldso = NULL;
++  size_t len;
++  bool found = false;
++  while (xgetline (&line, &len, f))
++    {
++      uintptr_t from, to;
++      char *path = NULL;
++      int r = sscanf (line, "%" SCNxPTR "-%" SCNxPTR "%*s%*s%*s%*s%ms",
++                      &from, &to, &path);
++
++      TEST_VERIFY (r == 2 || r == 3);
++      TEST_COMPARE (from % pagesize, 0);
++      TEST_COMPARE (to % pagesize, 0);
++
++      if (path_ldso == NULL && l->l_map_start == from)
++        {
++          TEST_COMPARE (r, 3);
++          path_ldso = path;
++          continue;
++        }
++
++      if (from > l->l_map_start && to < l->l_map_end
++          && (r == 2 || (path_ldso != NULL && strcmp (path, path_ldso))))
++        {
++          if (r == 2)
++            printf ("info: anonymous mapping found at 0x%" PRIxPTR " - 0x%"
++                    PRIxPTR "\n", from, to);
++          else
++            printf ("info: object \"%s\" found at 0x%" PRIxPTR " - 0x%"
++                    PRIxPTR "\n", path, from, to);
++
++          found = true;
++        }
++
++      free (path);
++    }
++
++  free (path_ldso);
++  free (line);
++  xfclose (f);
++  return found;
++}
++
++static int
++do_test (void)
++{
++  struct link_map *l = xdlopen (LD_SO, RTLD_NOW);
++  if (!l->l_contiguous)
++    {
++      puts ("info: ld.so link map is not contiguous");
++
++      /* Try to find holes by probing with mmap.  */
++      int pagesize = getpagesize ();
++      bool gap_found = false;
++      ElfW(Addr) addr = l->l_map_start;
++      TEST_COMPARE (addr % pagesize, 0);
++      while (addr < l->l_map_end)
++        {
++          void *expected = (void *) addr;
++          void *ptr = xmmap (expected, 1, PROT_READ | PROT_WRITE,
++                             MAP_PRIVATE | MAP_ANONYMOUS, -1);
++          struct dl_find_object dlfo;
++          int dlfo_ret = _dl_find_object (expected, &dlfo);
++          if (ptr == expected)
++            {
++              if (dlfo_ret < 0)
++                {
++                  TEST_COMPARE (dlfo_ret, -1);
++                  printf ("info: hole without mapping data found at %p\n", 
ptr);
++                }
++              else
++                FAIL ("object \"%s\" found in gap at %p",
++                      dlfo.dlfo_link_map->l_name, ptr);
++              gap_found = true;
++            }
++          else if (dlfo_ret == 0)
++            {
++              if ((void *) dlfo.dlfo_link_map != (void *) l)
++                {
++                  printf ("info: object \"%s\" found at %p\n",
++                          dlfo.dlfo_link_map->l_name, expected);
++                  gap_found = true;
++                }
++            }
++          else
++            TEST_COMPARE (dlfo_ret, -1);
++
++          xmunmap (ptr, 1);
++          addr += pagesize;
++        }
++
++      if (!gap_found && !find_gap_with_proc_self_map (l))
++        FAIL ("no ld.so gap found");
++    }
++  else
++    {
++      puts ("info: ld.so link map is contiguous");
++
++      /* Assert that ld.so is truly contiguous in memory.  */
++      volatile long int *p = (volatile long int *) l->l_map_start;
++      volatile long int *end = (volatile long int *) l->l_map_end;
++      while (p < end)
++        {
++          *p;
++          ++p;
++        }
++    }
++
++  xdlclose (l);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-link-map-contiguous-libc.c 
b/elf/tst-link-map-contiguous-libc.c
+new file mode 100644
+index 0000000000..eb5728c765
+--- /dev/null
++++ b/elf/tst-link-map-contiguous-libc.c
+@@ -0,0 +1,57 @@
++/* Check that the entire libc.so program image is readable if contiguous.
++   Copyright (C) 2025 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <gnu/lib-names.h>
++#include <link.h>
++#include <support/check.h>
++#include <support/xdlfcn.h>
++#include <support/xunistd.h>
++#include <sys/mman.h>
++#include <unistd.h>
++
++static int
++do_test (void)
++{
++  struct link_map *l = xdlopen (LIBC_SO, RTLD_NOW);
++
++  /* The dynamic loader fills holes with PROT_NONE mappings.  */
++  if (!l->l_contiguous)
++    FAIL_EXIT1 ("libc.so link map is not contiguous");
++
++  /* Direct probing does not work because not everything is readable
++     due to PROT_NONE mappings.  */
++  int pagesize = getpagesize ();
++  ElfW(Addr) addr = l->l_map_start;
++  TEST_COMPARE (addr % pagesize, 0);
++  while (addr < l->l_map_end)
++    {
++      void *expected = (void *) addr;
++      void *ptr = xmmap (expected, 1, PROT_READ | PROT_WRITE,
++                         MAP_PRIVATE | MAP_ANONYMOUS, -1);
++      if (ptr == expected)
++        FAIL ("hole in libc.so memory image after %lu bytes",
++              (unsigned long int) (addr - l->l_map_start));
++      xmunmap (ptr, 1);
++      addr += pagesize;
++    }
++
++  xdlclose (l);
++
++  return 0;
++}
++#include <support/test-driver.c>
+diff --git a/elf/tst-link-map-contiguous-main.c 
b/elf/tst-link-map-contiguous-main.c
+new file mode 100644
+index 0000000000..2d1a054f0f
+--- /dev/null
++++ b/elf/tst-link-map-contiguous-main.c
+@@ -0,0 +1,45 @@
++/* Check that the entire main program image is readable if contiguous.
++   Copyright (C) 2025 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 <link.h>
++#include <support/check.h>
++#include <support/xdlfcn.h>
++
++static int
++do_test (void)
++{
++  struct link_map *l = xdlopen ("", RTLD_NOW);
++  if (!l->l_contiguous)
++    FAIL_UNSUPPORTED ("main link map is not contiguous");
++
++  /* This check only works if the kernel loaded the main program.  The
++     dynamic loader replaces gaps with PROT_NONE mappings, resulting
++     in faults.  */
++  volatile long int *p = (volatile long int *) l->l_map_start;
++  volatile long int *end = (volatile long int *) l->l_map_end;
++  while (p < end)
++    {
++      *p;
++      ++p;
++    }
++
++  xdlclose (l);
++
++  return 0;
++}
++#include <support/test-driver.c>
 diff --git a/elf/tst-recursive-tls.c b/elf/tst-recursive-tls.c
 new file mode 100644
 index 0000000000..716d1f783a
@@ -3101,7 +3629,7 @@ index debb96b322..b72933b526 100644
  
              free (conf);
 diff --git a/iconvdata/Makefile b/iconvdata/Makefile
-index f4c089ed5d..d01b3fcab6 100644
+index f4c089ed5d..1ca3a193c7 100644
 --- a/iconvdata/Makefile
 +++ b/iconvdata/Makefile
 @@ -75,7 +75,8 @@ ifeq (yes,$(build-shared))
@@ -3110,19 +3638,148 @@ index f4c089ed5d..d01b3fcab6 100644
        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
++      tst-iconv-iso-2022-cn-ext tst-bug33980
  ifeq ($(have-thread-library),yes)
  tests += bug-iconv3
  endif
-@@ -330,6 +331,8 @@ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), 
$(gconv-modules)) \
+@@ -330,6 +331,10 @@ $(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)tst-bug33980.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/ansi_x3.110.c b/iconvdata/ansi_x3.110.c
+index fa2f6b46e5..6c9e5a024e 100644
+--- a/iconvdata/ansi_x3.110.c
++++ b/iconvdata/ansi_x3.110.c
+@@ -407,7 +407,7 @@ static const char from_ucs4[][2] =
+          is also available.  */                                             \
+       uint32_t ch2;                                                         \
+                                                                             \
+-      if (inptr + 1 >= inend)                                               \
++      if (inend - inptr <= 1)                                               \
+         {                                                                   \
+           /* The second character is not available.  */                     \
+           result = __GCONV_INCOMPLETE_INPUT;                                \
+diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
+index ce3172416c..e79f98a769 100644
+--- a/iconvdata/ibm1364.c
++++ b/iconvdata/ibm1364.c
+@@ -67,12 +67,29 @@
+ 
+ /* Since this is a stateful encoding we have to provide code which resets
+    the output state to the initial state.  This has to be done during the
+-   flushing.  */
++   flushing.  For the to-internal direction (FROM_DIRECTION is true),
++   there may be a pending character that needs flushing.  */
+ #define EMIT_SHIFT_TO_INIT \
+   if ((data->__statep->__count & ~7) != sb)                                 \
+     {                                                                       \
+       if (FROM_DIRECTION)                                                   \
+-      data->__statep->__count &= 7;                                         \
++      {                                                                     \
++        uint32_t ch = data->__statep->__count >> 7;                         \
++        if (__glibc_unlikely (ch != 0))                                     \
++          {                                                                 \
++            if (__glibc_unlikely (outend - outbuf < 4))                     \
++              status = __GCONV_FULL_OUTPUT;                                 \
++            else                                                            \
++              {                                                             \
++                put32u (outbuf, ch);                                        \
++                outbuf += 4;                                                \
++                /* Clear character and db bit.  */                          \
++                data->__statep->__count &= 7;                               \
++              }                                                             \
++          }                                                                 \
++        else                                                                \
++          data->__statep->__count &= 7;                                     \
++      }                                                                     \
+       else                                                                  \
+       {                                                                     \
+         /* We are not in the initial state.  To switch back we have         \
+@@ -99,11 +116,13 @@
+     *curcsp = save_curcs
+ 
+ 
+-/* Current codeset type.  */
++/* Current codeset type.  The bit is stored in the __count variable of
++   the conversion state.  If the db bit is set, bit 7 and above store
++   a pending UCS-4 code point if non-zero.  */
+ enum
+ {
+-  sb = 0,
+-  db = 64
++  sb = 0,                     /* Single byte mode.  */
++  db = 64                     /* Double byte mode.  */
+ };
+ 
+ 
+@@ -119,21 +138,29 @@ enum
+       }                                                                       
      \
+     else                                                                    \
+       {                                                                       
      \
+-      /* This is a combined character.  Make sure we have room.  */         \
+-      if (__glibc_unlikely (outptr + 8 > outend))                           \
+-        {                                                                   \
+-          result = __GCONV_FULL_OUTPUT;                                     \
+-          break;                                                            \
+-        }                                                                   \
+-                                                                            \
+       const struct divide *cmbp                                             \
+         = &DB_TO_UCS4_COMB[ch - __TO_UCS4_COMBINED_MIN];                    \
+       assert (cmbp->res1 != 0 && cmbp->res2 != 0);                          \
+                                                                             \
+       put32 (outptr, cmbp->res1);                                           \
+       outptr += 4;                                                          \
+-      put32 (outptr, cmbp->res2);                                           \
+-      outptr += 4;                                                          \
++                                                                            \
++      /* See whether we have room for the second character.  */             \
++      if (outend - outptr >= 4)                                             \
++        {                                                                   \
++          put32 (outptr, cmbp->res2);                                       \
++          outptr += 4;                                                      \
++        }                                                                   \
++      else                                                                  \
++        {                                                                   \
++          /* Otherwise store only the first character now, and              \
++             put the second one into the queue.  */                         \
++          curcs |= cmbp->res2 << 7;                                         \
++          inptr += 2;                                                       \
++          /* Tell the caller why we terminate the loop.  */                 \
++          result = __GCONV_FULL_OUTPUT;                                     \
++          break;                                                            \
++        }                                                                   \
+       }                                                                       
      \
+   }
+ #else
+@@ -153,7 +180,20 @@ enum
+ #define LOOPFCT               FROM_LOOP
+ #define BODY \
+   {                                                                         \
+-    uint32_t ch = *inptr;                                                   \
++    uint32_t ch;                                                            \
++                                                                            \
++    ch = curcs >> 7;                                                        \
++    if (__glibc_unlikely (ch != 0))                                         \
++      {                                                                       
      \
++      put32 (outptr, ch);                                                   \
++      outptr += 4;                                                          \
++      /* Remove the pending character, but preserve state bits.  */         \
++      curcs &= (1 << 7) - 1;                                                \
++      continue;                                                             \
++      }                                                                       
      \
++                                                                            \
++    /* Otherwise read the next input byte.  */                                
      \
++    ch = *inptr;                                                            \
+                                                                             \
+     if (__builtin_expect (ch, 0) == SO)                                       
      \
+       {                                                                       
      \
 diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
 index e09f358cad..2cc478a8c6 100644
 --- a/iconvdata/iso-2022-cn-ext.c
@@ -3153,6 +3810,165 @@ index e09f358cad..2cc478a8c6 100644
                assert ((used >> 5) >= 3 && (used >> 5) <= 7);                \
                escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2;                \
                *outptr++ = ESC;                                              \
+diff --git a/iconvdata/tst-bug33980.c b/iconvdata/tst-bug33980.c
+new file mode 100644
+index 0000000000..c9693e0efe
+--- /dev/null
++++ b/iconvdata/tst-bug33980.c
+@@ -0,0 +1,153 @@
++/* Test for bug 33980: combining characters in IBM1390/IBM1399.
++   Copyright (C) 2026 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 <alloc_buffer.h>
++#include <errno.h>
++#include <iconv.h>
++#include <stdbool.h>
++#include <string.h>
++
++#include <support/check.h>
++#include <support/next_to_fault.h>
++#include <support/support.h>
++
++/* Run iconv in a loop with a small output buffer of OUTBUFSIZE bytes
++   starting at OUTBUF.  OUTBUF should be right before an unmapped page
++   so that writing past the end will fault.  Skip SHIFT bytes at the
++   start of the input and output, to exercise different buffer
++   alignment.  TRUNCATE indicates skipped bytes at the end of
++   input (0 and 1 a valid).  */
++static void
++test_one (const char *encoding, unsigned int shift, unsigned int truncate,
++          char *outbuf, size_t outbufsize)
++{
++  /* In IBM1390 and IBM1399, the DBCS code 0xECB5 expands to two
++     Unicode code points when translated.  */
++  static char input[] =
++    {
++      /* 8 letters X.  */
++      0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
++      /* SO, 0xECB5, SI: shift to DBCS, special character, shift back.  */
++      0x0e, 0xec, 0xb5, 0x0f
++    };
++
++  /* Expected output after UTF-8 conversion.  */
++  static char expected[] =
++    {
++      'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X',
++      /* U+304B (HIRAGANA LETTER KA).  */
++      0xe3, 0x81, 0x8b,
++      /* U+309A (COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK).  */
++      0xe3, 0x82, 0x9a
++    };
++
++  iconv_t cd = iconv_open ("UTF-8", encoding);
++  TEST_VERIFY_EXIT (cd != (iconv_t) -1);
++
++  char result_storage[64];
++  struct alloc_buffer result_buf
++    = alloc_buffer_create (result_storage, sizeof (result_storage));
++
++  char *inptr = &input[shift];
++  size_t inleft = sizeof (input) - shift - truncate;
++
++  while (inleft > 0)
++    {
++      char *outptr = outbuf;
++      size_t outleft = outbufsize;
++      size_t inleft_before = inleft;
++
++      size_t ret = iconv (cd, &inptr, &inleft, &outptr, &outleft);
++      size_t produced = outptr - outbuf;
++      alloc_buffer_copy_bytes (&result_buf, outbuf, produced);
++
++      if (ret == (size_t) -1 && errno == E2BIG)
++        {
++          if (produced == 0 && inleft == inleft_before)
++            {
++              /* Output buffer too small to make progress.  This is
++                 expected for very small output buffer sizes.  */
++              TEST_VERIFY_EXIT (outbufsize < 3);
++              break;
++            }
++          continue;
++        }
++      if (ret == (size_t) -1)
++        FAIL_EXIT1 ("%s (outbufsize %zu): iconv: %m", encoding, outbufsize);
++      break;
++    }
++
++  /* Flush any pending state (e.g. a buffered combined character).
++     With outbufsize < 3, we could not store the first character, so
++     the second character did not become pending, and there is nothing
++     to flush.  */
++  {
++    char *outptr = outbuf;
++    size_t outleft = outbufsize;
++
++    size_t ret = iconv (cd, NULL, NULL, &outptr, &outleft);
++    TEST_VERIFY_EXIT (ret == 0);
++    size_t produced = outptr - outbuf;
++    alloc_buffer_copy_bytes (&result_buf, outbuf, produced);
++
++    /* Second flush does not provide more data.  */
++    outptr = outbuf;
++    outleft = outbufsize;
++    ret = iconv (cd, NULL, NULL, &outptr, &outleft);
++    TEST_VERIFY_EXIT (ret == 0);
++    TEST_VERIFY (outptr == outbuf);
++  }
++
++  TEST_VERIFY_EXIT (!alloc_buffer_has_failed (&result_buf));
++  size_t result_used
++    = sizeof (result_storage) - alloc_buffer_size (&result_buf);
++
++  if (outbufsize >= 3)
++    {
++      TEST_COMPARE (inleft, 0);
++      TEST_COMPARE (result_used, sizeof (expected) - shift);
++      TEST_COMPARE_BLOB (result_storage, result_used,
++                         &expected[shift], sizeof (expected) - shift);
++    }
++  else
++    /* If the buffer is too small, only the leading X could be converted.  */
++    TEST_COMPARE (result_used, 8 - shift);
++
++  TEST_VERIFY_EXIT (iconv_close (cd) == 0);
++}
++
++static int
++do_test (void)
++{
++  struct support_next_to_fault ntf
++    = support_next_to_fault_allocate (8);
++
++  for (int shift = 0; shift <= 8; ++shift)
++    for (int truncate = 0; truncate < 2; ++truncate)
++      for (size_t outbufsize = 1; outbufsize <= 8; outbufsize++)
++        {
++          char *outbuf = ntf.buffer + ntf.length - outbufsize;
++          test_one ("IBM1390", shift, truncate, outbuf, outbufsize);
++          test_one ("IBM1399", shift, truncate, outbuf, outbufsize);
++        }
++
++  support_next_to_fault_free (&ntf);
++  return 0;
++}
++
++#include <support/test-driver.c>
 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 0000000000..96a8765fd5
@@ -4080,6 +4896,67 @@ index 0a684a720d..a1ee7928d3 100644
  
                if (n >= 1)
                  narenas_limit = NARENAS_FROM_NCORES (n);
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index bd3c76ed31..53d6e06bb0 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -4949,7 +4949,7 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
+ 
+ 
+   nb = checked_request2size (bytes);
+-  if (nb == 0)
++  if (nb == 0 || alignment > PTRDIFF_MAX)
+     {
+       __set_errno (ENOMEM);
+       return NULL;
+@@ -4960,8 +4960,10 @@ _int_memalign (mstate av, size_t alignment, size_t 
bytes)
+      request, and then possibly free the leading and trailing space.
+    */
+ 
+-  /* Call malloc with worst case padding to hit alignment. */
+-
++  /* Call malloc with worst case padding to hit alignment.  ALIGNMENT is a
++     power of 2, so it tops out at (PTRDIFF_MAX >> 1) + 1, leaving plenty of
++     space to add MINSIZE and whatever checked_request2size adds to BYTES to
++     get NB.  Consequently, total below also does not overflow.  */
+   m = (char *) (_int_malloc (av, nb + alignment + MINSIZE));
+ 
+   if (m == 0)
+diff --git a/malloc/tst-malloc-too-large.c b/malloc/tst-malloc-too-large.c
+index dac3c8086c..e7017981aa 100644
+--- a/malloc/tst-malloc-too-large.c
++++ b/malloc/tst-malloc-too-large.c
+@@ -151,7 +151,6 @@ test_large_allocations (size_t size)
+ }
+ 
+ 
+-static long pagesize;
+ 
+ /* This function tests the following aligned memory allocation functions
+    using several valid alignments and precedes each allocation test with a
+@@ -170,8 +169,8 @@ test_large_aligned_allocations (size_t size)
+ 
+   /* All aligned memory allocation functions expect an alignment that is a
+      power of 2.  Given this, we test each of them with every valid
+-     alignment from 1 thru PAGESIZE.  */
+-  for (align = 1; align <= pagesize; align *= 2)
++     alignment for the type of ALIGN, i.e. until it wraps to 0.  */
++  for (align = 1; align > 0; align <<= 1)
+     {
+       test_setup ();
+ #if __GNUC_PREREQ (7, 0)
+@@ -264,11 +263,6 @@ do_test (void)
+   DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+ #endif
+ 
+-  /* Aligned memory allocation functions need to be tested up to alignment
+-     size equivalent to page size, which should be a power of 2.  */
+-  pagesize = sysconf (_SC_PAGESIZE);
+-  TEST_VERIFY_EXIT (powerof2 (pagesize));
+-
+   /* Loop 1: Ensure that all allocations with SIZE close to SIZE_MAX, i.e.
+      in the range (SIZE_MAX - 2^14, SIZE_MAX], fail.
+ 
 diff --git a/math/test-tgmath2.c b/math/test-tgmath2.c
 index d758231a89..95897948fb 100644
 --- a/math/test-tgmath2.c
@@ -4963,6 +5840,32 @@ index 5cacb286f3..bbb26607ef 100644
  } __attribute ((aligned (TCB_ALIGNMENT)));
  
  static inline bool
+diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
+index 8a7de8e598..69aa11b0aa 100644
+--- a/nptl/pthread_mutex_trylock.c
++++ b/nptl/pthread_mutex_trylock.c
+@@ -48,7 +48,8 @@ ___pthread_mutex_trylock (pthread_mutex_t *mutex)
+         return 0;
+       }
+ 
+-      if (lll_trylock (mutex->__data.__lock) == 0)
++      if (atomic_load_relaxed (&(mutex->__data.__lock)) == 0
++        && lll_trylock (mutex->__data.__lock) == 0)
+       {
+         /* Record the ownership.  */
+         mutex->__data.__owner = id;
+@@ -71,7 +72,10 @@ ___pthread_mutex_trylock (pthread_mutex_t *mutex)
+       /*FALL THROUGH*/
+     case PTHREAD_MUTEX_ADAPTIVE_NP:
+     case PTHREAD_MUTEX_ERRORCHECK_NP:
+-      if (lll_trylock (mutex->__data.__lock) != 0)
++      /* Mutex type is already loaded, lock check overhead should
++         be minimal.  */
++      if (atomic_load_relaxed (&(mutex->__data.__lock)) != 0
++        || lll_trylock (mutex->__data.__lock) != 0)
+       break;
+ 
+       /* Record the ownership.  */
 diff --git a/nptl/tst-cancel7.c b/nptl/tst-cancel7.c
 index 903457db76..1c80457553 100644
 --- a/nptl/tst-cancel7.c
@@ -5958,18 +6861,56 @@ index fdc5bdd65b..bc32bb132a 100644
  
  static struct hostent host_table_2[] = {
 diff --git a/posix/Makefile b/posix/Makefile
-index d1df7c27cb..336bee4a4a 100644
+index d1df7c27cb..36ae315fad 100644
 --- a/posix/Makefile
 +++ b/posix/Makefile
-@@ -109,7 +109,7 @@ tests              := test-errno tstgetopt testfnm 
runtests runptests \
+@@ -109,7 +109,8 @@ tests              := test-errno tstgetopt testfnm 
runtests runptests \
                   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
                   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
                   tst-wordexp-nocmd tst-execveat tst-spawn5 \
 -                 tst-sched_getaffinity tst-spawn6
-+                 tst-sched_getaffinity tst-spawn6 tst-regcomp-bracket-free
++                 tst-sched_getaffinity tst-spawn6 tst-regcomp-bracket-free \
++                 tst-wordexp-reuse
  
  # Test for the glob symbol version that was replaced in glibc 2.27.
  ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes)
+@@ -156,11 +157,13 @@ generated += $(addprefix wordexp-test-result, 1 2 3 4 5 
6 7 8 9 10) \
+            bug-glob2.mtrace bug-glob2-mem.out tst-vfork3-mem.out \
+            tst-vfork3.mtrace getconf.speclist tst-fnmatch-mem.out \
+            tst-fnmatch.mtrace bug-regex36.mtrace \
+-           testcases.h ptestcases.h
++           testcases.h ptestcases.h tst-wordexp-reuse-mem.out \
++           tst-wordexp-reuse.mtrace
+ 
+ ifeq ($(run-built-tests),yes)
+ ifeq (yes,$(build-shared))
+-tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
++tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out \
++               $(objpfx)wordexp-tst.out
+ endif
+ endif
+ 
+@@ -174,7 +177,8 @@ tests-special += $(objpfx)bug-regex2-mem.out 
$(objpfx)bug-regex14-mem.out \
+                $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
+                $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
+                $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out \
+-               $(objpfx)tst-glob-tilde-mem.out $(objpfx)bug-ga2-mem.out
++               $(objpfx)tst-glob-tilde-mem.out $(objpfx)bug-ga2-mem.out \
++               $(objpfx)tst-wordexp-reuse-mem.out
+ endif
+ 
+ include ../Rules
+@@ -451,3 +455,10 @@ $(objpfx)posix-conf-vars-def.h: 
$(..)scripts/gen-posix-conf-vars.awk \
+       $(make-target-directory)
+       $(AWK) -f $(filter-out Makefile, $^) > [email protected]
+       mv -f [email protected] $@
++
++tst-wordexp-reuse-ENV += MALLOC_TRACE=$(objpfx)tst-wordexp-reuse.mtrace \
++                       LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
++
++$(objpfx)tst-wordexp-reuse-mem.out: $(objpfx)tst-wordexp-reuse.out
++      $(common-objpfx)malloc/mtrace $(objpfx)tst-wordexp-reuse.mtrace > $@; \
++      $(evaluate-test)
 diff --git a/posix/regcomp.c b/posix/regcomp.c
 index 84fc1cc82b..7bd0beeafe 100644
 --- a/posix/regcomp.c
@@ -6243,8 +7184,117 @@ index c8093c5473..39061ce6c5 100644
  
    return 0;
  }
+diff --git a/posix/tst-wordexp-reuse.c b/posix/tst-wordexp-reuse.c
+new file mode 100644
+index 0000000000..3926b9f557
+--- /dev/null
++++ b/posix/tst-wordexp-reuse.c
+@@ -0,0 +1,89 @@
++/* Test for wordexp with WRDE_REUSE flag.
++   Copyright (C) 2026 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 <wordexp.h>
++#include <mcheck.h>
++
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  mtrace ();
++
++  {
++    wordexp_t p = { 0 };
++    TEST_COMPARE (wordexp ("one", &p, 0), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[0], "one");
++    TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[0], "two");
++    wordfree (&p);
++  }
++
++  {
++    wordexp_t p = { .we_offs = 2 };
++    TEST_COMPARE (wordexp ("one", &p, 0), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[0], "one");
++    TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE | WRDE_DOOFFS), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "two");
++    wordfree (&p);
++  }
++
++  {
++    wordexp_t p = { 0 };
++    TEST_COMPARE (wordexp ("one", &p, 0), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[0], "one");
++    TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE | WRDE_APPEND), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[0], "two");
++    wordfree (&p);
++  }
++
++  {
++    wordexp_t p = { .we_offs = 2 };
++    TEST_COMPARE (wordexp ("one", &p, WRDE_DOOFFS), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "one");
++    TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE
++                                    | WRDE_DOOFFS), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "two");
++    wordfree (&p);
++  }
++
++  {
++    wordexp_t p = { .we_offs = 2 };
++    TEST_COMPARE (wordexp ("one", &p, WRDE_DOOFFS), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "one");
++    TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE
++                                    | WRDE_DOOFFS | WRDE_APPEND), 0);
++    TEST_COMPARE (p.we_wordc, 1);
++    TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "two");
++    wordfree (&p);
++  }
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/posix/wordexp.c b/posix/wordexp.c
+index d4cb9c734b..25f5b509a8 100644
+--- a/posix/wordexp.c
++++ b/posix/wordexp.c
+@@ -2219,7 +2219,9 @@ wordexp (const char *words, wordexp_t *pwordexp, int 
flags)
+     {
+       /* Minimal implementation of WRDE_REUSE for now */
+       wordfree (pwordexp);
++      old_word.we_wordc = 0;
+       old_word.we_wordv = NULL;
++      pwordexp->we_wordc = 0;
+     }
+ 
+   if ((flags & WRDE_APPEND) == 0)
 diff --git a/resolv/Makefile b/resolv/Makefile
-index 5b15321f9b..e5165fb34b 100644
+index 5b15321f9b..d1b22f5b64 100644
 --- a/resolv/Makefile
 +++ b/resolv/Makefile
 @@ -40,12 +40,16 @@ routines := \
@@ -6264,7 +7314,7 @@ index 5b15321f9b..e5165fb34b 100644
    ns_samename \
    nsap_addr \
    nss_dns_functions \
-@@ -89,14 +93,20 @@ tests += \
+@@ -89,21 +93,42 @@ tests += \
    tst-ns_name_pton \
    tst-res_hconf_reorder \
    tst-res_hnok \
@@ -6272,8 +7322,10 @@ index 5b15321f9b..e5165fb34b 100644
    tst-resolv-basic \
    tst-resolv-binary \
 +  tst-resolv-byaddr \
++  tst-resolv-dns-section \
    tst-resolv-edns \
 +  tst-resolv-invalid-cname \
++  tst-resolv-invalid-ptr \
    tst-resolv-network \
    tst-resolv-noaaaa \
 +  tst-resolv-noaaaa-vc \
@@ -6283,9 +7335,10 @@ index 5b15321f9b..e5165fb34b 100644
 +  tst-resolv-semi-failure \
 +  tst-resolv-short-response \
    tst-resolv-trailing \
++  # tests
  
  # This test calls __res_context_send directly, which is not exported
-@@ -104,6 +114,18 @@ tests += \
+ # from libresolv.
  tests-internal += tst-resolv-txnid-collision
  tests-static += tst-resolv-txnid-collision
  
@@ -6304,7 +7357,7 @@ index 5b15321f9b..e5165fb34b 100644
  # These tests need libdl.
  ifeq (yes,$(build-shared))
  tests += \
-@@ -258,8 +280,10 @@ $(objpfx)tst-resolv-ai_idn.out: $(gen-locales)
+@@ -258,8 +283,12 @@ $(objpfx)tst-resolv-ai_idn.out: $(gen-locales)
  $(objpfx)tst-resolv-ai_idn-latin1.out: $(gen-locales)
  $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \
    $(gen-locales) $(objpfx)tst-no-libidn2.so
@@ -6312,14 +7365,18 @@ index 5b15321f9b..e5165fb34b 100644
  $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library)
  $(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library)
 +$(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-dns-section: $(objpfx)libresolv.so \
++  $(shared-thread-library)
  $(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library)
  $(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library)
  $(objpfx)tst-resolv-res_init: $(objpfx)libresolv.so
-@@ -267,11 +291,18 @@ $(objpfx)tst-resolv-res_init-multi: 
$(objpfx)libresolv.so \
+@@ -267,11 +296,20 @@ $(objpfx)tst-resolv-res_init-multi: 
$(objpfx)libresolv.so \
    $(shared-thread-library)
  $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
    $(shared-thread-library)
 +$(objpfx)tst-resolv-invalid-cname: $(objpfx)libresolv.so \
++  $(shared-thread-library)
++$(objpfx)tst-resolv-invalid-ptr: $(objpfx)libresolv.so \
 +  $(shared-thread-library)
  $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library)
 +$(objpfx)tst-resolv-noaaaa-vc: $(objpfx)libresolv.so $(shared-thread-library)
@@ -6798,7 +7855,7 @@ index 0000000000..9a47d8e97a
 +  return *a == 0 && *b == 0;
 +}
 diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
-index 544cffbecd..227734da5c 100644
+index 544cffbecd..7053f212ae 100644
 --- a/resolv/nss_dns/dns-host.c
 +++ b/resolv/nss_dns/dns-host.c
 @@ -69,6 +69,7 @@
@@ -7522,7 +8579,7 @@ index 544cffbecd..227734da5c 100644
 +  unsigned char name_buffer[NS_MAXCDNAME];
  
 -      if (__glibc_unlikely (class != C_IN))
-+  while (ancount > 0)
++  for (; ancount > 0; --ancount)
 +    {
 +      struct ns_rr_wire rr;
 +      if (!__ns_rr_cursor_next (&c, &rr))
@@ -7647,7 +8704,7 @@ index 544cffbecd..227734da5c 100644
 +        char hname[MAXHOSTNAMELEN + 1];
 +        if (__ns_name_unpack (c.begin, c.end, rr.rdata,
 +                              name_buffer, sizeof (name_buffer)) < 0
-+            || !__res_binary_hnok (expected_name)
++            || !__res_binary_hnok (name_buffer)
 +            || __ns_name_ntop (name_buffer, hname, sizeof (hname)) < 0)
            {
 -            cp += n;
@@ -8245,6 +9302,21 @@ index 544cffbecd..227734da5c 100644
 +                                 abuf, &pat, errnop, h_errnop, ttlp, true);
    return status;
  }
+diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
+index 09cd917444..3458bd4615 100644
+--- a/resolv/nss_dns/dns-network.c
++++ b/resolv/nss_dns/dns-network.c
+@@ -207,6 +207,10 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct 
netent *result,
+       sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
+              net_bytes[1], net_bytes[0]);
+       break;
++    default:
++      /* Default network (net is originally zero).  */
++      strcpy (qbuf, "0.0.0.0.in-addr.arpa");
++      break;
+     }
+ 
+   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
 diff --git a/resolv/res-name-checking.c b/resolv/res-name-checking.c
 index 07a412d8ff..213edceaf3 100644
 --- a/resolv/res-name-checking.c
@@ -9416,6 +10488,174 @@ index 0000000000..6299e89837
 +}
 +
 +#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-dns-section.c b/resolv/tst-resolv-dns-section.c
+new file mode 100644
+index 0000000000..1171baef51
+--- /dev/null
++++ b/resolv/tst-resolv-dns-section.c
+@@ -0,0 +1,162 @@
++/* Test handling of invalid section transitions (bug 34014).
++   Copyright (C) 2022-2026 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 <array_length.h>
++#include <errno.h>
++#include <netdb.h>
++#include <resolv.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/format_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++/* Name of test, and the second section type.  */
++struct item {
++  const char *test;
++  int ns_section;
++};
++
++static const struct item test_items[] =
++  {
++    { "Test crossing from ns_s_an to ns_s_ar.", ns_s_ar },
++    { "Test crossing from ns_s_an to ns_s_an.", ns_s_ns },
++
++    { NULL, 0 },
++  };
++
++/* The response is designed to contain the following:
++   - An Answer section with one T_PTR record that is skipped.
++   - A second section with a semantically invalid T_PTR record.
++   The original defect is that the response parsing would cross
++   section boundaries and handle the additional section T_PTR
++   as if it were an answer.  A conforming implementation would
++   stop as soon as it reaches the end of the section.  */
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  TEST_COMPARE (qclass, C_IN);
++
++  /* We only test PTR.  */
++  TEST_COMPARE (qtype, T_PTR);
++
++  unsigned int count;
++  char *tail = NULL;
++
++  if (strstr (qname, "in-addr.arpa") != NULL
++      && sscanf (qname, "%u.%ms", &count, &tail) == 2)
++    TEST_COMPARE_STRING (tail, "0.168.192.in-addr.arpa");
++  else if (sscanf (qname, "%x.%ms", &count, &tail) == 2)
++    {
++    TEST_COMPARE_STRING (tail, "\
++0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa");
++    }
++  else
++    FAIL_EXIT1 ("invalid QNAME: %s\n", qname);
++  free (tail);
++
++  /* We have a bounded number of possible tests.  */
++  TEST_VERIFY (count >= 0);
++  TEST_VERIFY (count <= 15);
++
++  struct resolv_response_flags flags = {};
++  resolv_response_init (b, flags);
++  resolv_response_add_question (b, qname, qclass, qtype);
++  resolv_response_section (b, ns_s_an);
++
++  /* Actual answer record, but the wrong name (skipped).  */
++  resolv_response_open_record (b, "1.0.0.10.in-addr.arpa", qclass, qtype, 60);
++
++  /* Record the answer.  */
++  resolv_response_add_name (b, "test.ptr.example.net");
++  resolv_response_close_record (b);
++
++  /* Add a second section to test section boundary crossing.  */
++  resolv_response_section (b, test_items[count].ns_section);
++  /* Semantically incorrect, but hide a T_PTR entry.  */
++  resolv_response_open_record (b, qname, qclass, qtype, 60);
++  resolv_response_add_name (b, "wrong.ptr.example.net");
++  resolv_response_close_record (b);
++}
++
++
++/* Perform one check using a reverse lookup.  */
++static void
++check_reverse (int af, int count)
++{
++  TEST_VERIFY (af == AF_INET || af == AF_INET6);
++  TEST_VERIFY (count < array_length (test_items));
++
++  char addr[sizeof (struct in6_addr)] = { 0 };
++  socklen_t addrlen;
++  if (af == AF_INET)
++    {
++      addr[0] = (char) 192;
++      addr[1] = (char) 168;
++      addr[2] = (char) 0;
++      addr[3] = (char) count;
++      addrlen = 4;
++    }
++  else
++    {
++      addr[0] = 0x20;
++      addr[1] = 0x01;
++      addr[2] = 0x0d;
++      addr[3] = 0xb8;
++      addr[4] = addr[5] = addr[6] = addr[7] = 0x0;
++      addr[8] = addr[9] = addr[10] = addr[11] = 0x0;
++      addr[12] = 0x0;
++      addr[13] = 0x0;
++      addr[14] = 0x0;
++      addr[15] = count;
++      addrlen = 16;
++    }
++
++  h_errno = 0;
++  struct hostent *answer = gethostbyaddr (addr, addrlen, af);
++  TEST_VERIFY (answer == NULL);
++  TEST_VERIFY (h_errno == NO_RECOVERY);
++  if (answer != NULL)
++    printf ("error: unexpected success: %s\n",
++          support_format_hostent (answer));
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *obj = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response
++     });
++
++  for (int i = 0; test_items[i].test != NULL; i++)
++    {
++      check_reverse (AF_INET, i);
++      check_reverse (AF_INET6, i);
++    }
++
++  resolv_test_end (obj);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
 diff --git a/resolv/tst-resolv-invalid-cname.c 
b/resolv/tst-resolv-invalid-cname.c
 new file mode 100644
 index 0000000000..63dac90e02
@@ -9828,6 +11068,267 @@ index 0000000000..63dac90e02
 +}
 +
 +#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-invalid-ptr.c b/resolv/tst-resolv-invalid-ptr.c
+new file mode 100644
+index 0000000000..0c802ab967
+--- /dev/null
++++ b/resolv/tst-resolv-invalid-ptr.c
+@@ -0,0 +1,255 @@
++/* Test handling of invalid T_PTR results (bug 34015).
++   Copyright (C) 2022-2026 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 <array_length.h>
++#include <errno.h>
++#include <netdb.h>
++#include <resolv.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/format_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++/* Name of test, the answer, the expected error return, and if we
++   expect the call to fail.  */
++struct item {
++  const char *test;
++  const char *answer;
++  int expected;
++  bool fail;
++};
++
++static const struct item test_items[] =
++  {
++    /* Test for invalid characters.  */
++    { "Invalid use of \"|\"",
++      "test.|.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"&\"",
++      "test.&.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \";\"",
++      "test.;.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"<\"",
++      "test.<.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \">\"",
++      "test.>.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"(\"",
++      "test.(.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \")\"",
++      "test.).ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"$\"",
++      "test.$.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"`\"",
++      "test.`.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"\\\"",
++      "test.\\.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"\'\"",
++      "test.'.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"\"\"",
++      "test.\".ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \" \"",
++      "test. .ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"\\t\"",
++      "test.\t.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"\\n\"",
++      "test.\n.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"\\r\"",
++      "test.\r.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"*\"",
++      "test.*.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"?\"",
++      "test.?.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"[\"",
++      "test.[.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"]\"",
++      "test.].ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \",\"",
++      "test.,.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"~\"",
++      "test.~.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \":\"",
++      "test.:.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"!\"",
++      "test.!.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"@\"",
++      "[email protected]", NO_RECOVERY, true },
++    { "Invalid use of \"#\"",
++      "test.#.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"%\"",
++      "test.%%.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of \"^\"",
++      "test.^.ptr.example", NO_RECOVERY, true },
++
++    /* Test for invalid UTF-8 characters (2-byte, 4-byte, 6-byte).  */
++    { "Invalid use of UTF-8 (2-byte, U+00C0-U+00C2)",
++      "ÁÂÃ.test.ptr.example", NO_RECOVERY, true },
++    { "Invalid use of UTF-8 (4-byte, U+0750-U+0752)",
++      "ݐݑݒ.test.ptr.example", NO_RECOVERY, true },
++     { "Invalid use of UTF-8 (6-byte, U+0904-U+0906)",
++      "ऄअआ.test.ptr.example", NO_RECOVERY, true },
++
++    /* Test for "-" which may be valid depending on position.  */
++    { "Invalid leading \"-\"",
++      "-test.ptr.example", NO_RECOVERY, true },
++    { "Valid trailing \"-\"",
++      "test-.ptr.example", 0, false },
++    { "Valid mid-label use of \"-\"",
++      "te-st.ptr.example", 0, false },
++
++    /* Test for "_" which is always valid in any position.  */
++    { "Valid leading use of \"_\"",
++      "_test.ptr.example", 0, false },
++    { "Valid mid-label use of \"_\"",
++      "te_st.ptr.example", 0, false },
++    { "Valid trailing use of \"_\"",
++      "test_.ptr.example", 0, false },
++
++    /* Sanity test the broader set [A-Za-z0-9_-] of valid characters.  */
++    { "Valid \"[A-Z]\"",
++      "test.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ptr.example", 0, false },
++    { "Valid \"[a-z]\"",
++      "test.abcdefghijklmnopqrstuvwxyz.ptr.example", 0, false },
++    { "Valid \"[0-9]\"",
++      "test.0123456789.ptr.example", 0, false },
++    { "Valid mixed use of \"[A-Za-z0-9_-]\"",
++      "test.012abcABZ_-.ptr.example", 0, false },
++  };
++
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  TEST_COMPARE (qclass, C_IN);
++
++  /* We only test PTR.  */
++  TEST_COMPARE (qtype, T_PTR);
++
++  unsigned int count, count1;
++  char *tail = NULL;
++
++  /* The test implementation can handle up to 255 tests.  */
++  if (strstr (qname, "in-addr.arpa") != NULL
++      && sscanf (qname, "%u.%ms", &count, &tail) == 2)
++    TEST_COMPARE_STRING (tail, "0.168.192.in-addr.arpa");
++  else if (sscanf (qname, "%x.%x.%ms", &count, &count1, &tail) == 3)
++    {
++      TEST_COMPARE_STRING (tail, "\
++0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa");
++      count |= count1 << 4;
++    }
++  else
++    FAIL_EXIT1 ("invalid QNAME: %s\n", qname);
++  free (tail);
++
++  /* Cross check. Count has a fixed bound (soft limit).  */
++  TEST_VERIFY (count >= 0 && count <= 255);
++
++  /* We have a fixed number of tests (hard limit).  */
++  TEST_VERIFY_EXIT (count < array_length (test_items));
++
++  struct resolv_response_flags flags = {};
++  resolv_response_init (b, flags);
++  resolv_response_add_question (b, qname, qclass, qtype);
++  resolv_response_section (b, ns_s_an);
++
++  /* Actual answer record.  */
++  resolv_response_open_record (b, qname, qclass, qtype, 60);
++
++  /* Record the answer.  */
++  resolv_response_add_name (b, test_items[count].answer);
++  resolv_response_close_record (b);
++}
++
++/* Perform one check using a reverse lookup.  */
++static void
++check_reverse (int af, int count)
++{
++  TEST_VERIFY (af == AF_INET || af == AF_INET6);
++  TEST_VERIFY_EXIT (count < array_length (test_items));
++
++  /* Generate an address to query for each test.  */
++  char addr[sizeof (struct in6_addr)] = { 0 };
++  socklen_t addrlen;
++  if (af == AF_INET)
++    {
++      addr[0] = (char) 192;
++      addr[1] = (char) 168;
++      addr[2] = (char) 0;
++      addr[3] = (char) count;
++      addrlen = 4;
++    }
++  else
++    {
++      addr[0] = 0x20;
++      addr[1] = 0x01;
++      addr[2] = 0x0d;
++      addr[3] = 0xb8;
++      addr[4] = addr[5] = addr[6] = addr[7] = 0x0;
++      addr[8] = addr[9] = addr[10] = addr[11] = 0x0;
++      addr[12] = 0x0;
++      addr[13] = 0x0;
++      addr[14] = 0x0;
++      addr[15] = (char) count;
++      addrlen = 16;
++    }
++
++  h_errno = 0;
++  struct hostent *answer = gethostbyaddr (addr, addrlen, af);
++
++  /* Verify h_errno is as expected.  */
++  TEST_COMPARE (h_errno, test_items[count].expected);
++  if (h_errno != test_items[count].expected)
++    /* And print more information if it's not.  */
++    printf ("INFO: %s\n", test_items[count].test);
++
++  if (test_items[count].fail)
++    {
++      /* We expected a failure so verify answer is NULL.  */
++      TEST_VERIFY (answer == NULL);
++      /* If it's not NULL we should print out what we received.  */
++      if (answer != NULL)
++        printf ("error: unexpected success: %s\n",
++              support_format_hostent (answer));
++    }
++  else
++    /* We don't expect a failure so answer must be valid.  */
++    TEST_COMPARE_STRING (answer->h_name, test_items[count].answer);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *obj = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response
++     });
++
++  for (int i = 0; i < array_length (test_items); i++)
++    {
++      check_reverse (AF_INET, i);
++      check_reverse (AF_INET6, i);
++    }
++  resolv_test_end (obj);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
 diff --git a/resolv/tst-resolv-maybe_insert_sig.h 
b/resolv/tst-resolv-maybe_insert_sig.h
 new file mode 100644
 index 0000000000..05725225af
@@ -9866,6 +11367,30 @@ index 0000000000..05725225af
 +  resolv_response_add_data (b, "", 1);
 +  resolv_response_close_record (b);
 +}
+diff --git a/resolv/tst-resolv-network.c b/resolv/tst-resolv-network.c
+index 956f847db7..f1f11613ac 100644
+--- a/resolv/tst-resolv-network.c
++++ b/resolv/tst-resolv-network.c
+@@ -46,6 +46,9 @@ handle_code (const struct resolv_response_context *ctx,
+ {
+   switch (code)
+     {
++    case 0:
++      send_ptr (b, qname, qclass, qtype, "0.in-addr.arpa");
++      break;
+     case 1:
+       send_ptr (b, qname, qclass, qtype, "1.in-addr.arpa");
+       break;
+@@ -265,6 +268,9 @@ do_test (void)
+                 "error: TRY_AGAIN\n");
+ 
+   /* Lookup by address, success cases.  */
++  check_reverse (0,
++                 "name: 0.in-addr.arpa\n"
++                 "net: 0x00000000\n");
+   check_reverse (1,
+                  "name: 1.in-addr.arpa\n"
+                  "net: 0x00000001\n");
 diff --git a/resolv/tst-resolv-noaaaa-vc.c b/resolv/tst-resolv-noaaaa-vc.c
 new file mode 100644
 index 0000000000..9f5aebd99f
@@ -15420,6 +16945,81 @@ index 6a422713bd..659c6f16da 100644
        @ save the entry point in another register\n\
        mov     r6, r0\n\
        @ get the original arg count\n\
+diff --git a/sysdeps/arm/find_exidx.c b/sysdeps/arm/find_exidx.c
+index aab06d25f6..0236b1f4ca 100644
+--- a/sysdeps/arm/find_exidx.c
++++ b/sysdeps/arm/find_exidx.c
+@@ -15,65 +15,17 @@
+    License along with the GNU C Library.  If not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
++#include <ldsodefs.h>
+ #include <link.h>
+-#include <unwind.h>
+-
+-struct unw_eh_callback_data
+-{
+-  _Unwind_Ptr pc;
+-  _Unwind_Ptr exidx_start;
+-  int exidx_len;
+-};
+-
+-
+-/* Callback to determins if the PC lies within an object, and remember the
+-   location of the exception index table if it does.  */
+-
+-static int
+-find_exidx_callback (struct dl_phdr_info * info, size_t size, void * ptr)
+-{
+-  struct unw_eh_callback_data * data;
+-  const ElfW(Phdr) *phdr;
+-  int i;
+-  int match;
+-  _Unwind_Ptr load_base;
+-
+-  data = (struct unw_eh_callback_data *) ptr;
+-  load_base = info->dlpi_addr;
+-  phdr = info->dlpi_phdr;
+-
+-  match = 0;
+-  for (i = info->dlpi_phnum; i > 0; i--, phdr++)
+-    {
+-      if (phdr->p_type == PT_LOAD)
+-        {
+-          _Unwind_Ptr vaddr = phdr->p_vaddr + load_base;
+-          if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz)
+-            match = 1;
+-        }
+-      else if (phdr->p_type == PT_ARM_EXIDX)
+-      {
+-        data->exidx_start = (_Unwind_Ptr) (phdr->p_vaddr + load_base);
+-        data->exidx_len = phdr->p_memsz;
+-      }
+-    }
+-
+-  return match;
+-}
+-
+ 
+ /* Find the exception index table containing PC.  */
+ 
+ _Unwind_Ptr
+ __gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int * pcount)
+ {
+-  struct unw_eh_callback_data data;
+-
+-  data.pc = pc;
+-  data.exidx_start = 0;
+-  if (__dl_iterate_phdr (find_exidx_callback, &data) <= 0)
++  struct dl_find_object data;
++  if (GLRO(dl_find_object) ((void *) pc, &data) < 0)
+     return 0;
+-
+-  *pcount = data.exidx_len / 8;
+-  return data.exidx_start;
++  *pcount = data.dlfo_eh_count;
++  return (_Unwind_Ptr) data.dlfo_eh_frame;
+ }
 diff --git a/sysdeps/arm/utmp-size.h b/sysdeps/arm/utmp-size.h
 new file mode 100644
 index 0000000000..8f21ebe1b6
@@ -16373,6 +17973,19 @@ index bb0ccd0811..3868bcc2f7 100644
  
  /* The PLT uses Elf64_Rela relocs.  */
  #define elf_machine_relplt elf_machine_rela
+diff --git a/sysdeps/powerpc/powerpc64/le/power10/strlen.S 
b/sysdeps/powerpc/powerpc64/le/power10/strlen.S
+index 5c42f78de9..b9c7f511cf 100644
+--- a/sysdeps/powerpc/powerpc64/le/power10/strlen.S
++++ b/sysdeps/powerpc/powerpc64/le/power10/strlen.S
+@@ -31,7 +31,7 @@
+ #  define FUNCNAME RAWMEMCHR
+ # endif
+ # define MCOUNT_NARGS 2
+-# define VREG_ZERO v20
++# define VREG_ZERO v17
+ # define OFF_START_LOOP 256
+ # define RAWMEMCHR_SUBTRACT_VECTORS \
+       vsububm   v4,v4,v18;        \
 diff --git a/sysdeps/powerpc/utmp-size.h b/sysdeps/powerpc/utmp-size.h
 new file mode 100644
 index 0000000000..8f21ebe1b6
@@ -19742,6 +21355,42 @@ index 0000000000..8f21ebe1b6
 @@ -0,0 +1,2 @@
 +#define UTMP_SIZE 384
 +#define LASTLOG_SIZE 292
+diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
+index c19bef2dec..f173c5ef4a 100644
+--- a/sysdeps/x86_64/Makefile
++++ b/sysdeps/x86_64/Makefile
+@@ -190,6 +190,15 @@ endif
+ 
+ tests-internal += tst-x86-64-tls-1
+ 
++tests-special += $(objpfx)check-dt-x86-64-plt.out
++
++$(objpfx)check-dt-x86-64-plt.out: $(common-objpfx)libc.so
++       LC_ALL=C $(READELF) -V -W $< \
++               | sed -ne '/.gnu.version_d/, /.gnu.version_r/ p' \
++               | grep GLIBC_ABI_DT_X86_64_PLT > $@; \
++       $(evaluate-test)
++generated += check-dt-x86-64-plt.out
++
+ endif # $(subdir) == elf
+ 
+ ifeq ($(subdir),csu)
+diff --git a/sysdeps/x86_64/Versions b/sysdeps/x86_64/Versions
+index e94758b236..6a989ad3b3 100644
+--- a/sysdeps/x86_64/Versions
++++ b/sysdeps/x86_64/Versions
+@@ -5,6 +5,11 @@ libc {
+   GLIBC_2.13 {
+     __fentry__;
+   }
++  GLIBC_ABI_DT_X86_64_PLT {
++    # This symbol is used only for empty version map and will be removed
++    # by scripts/versions.awk.
++    __placeholder_only_for_empty_version_map;
++  }
+ }
+ libm {
+   GLIBC_2.1 {
 diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c
 index 24a6e643b0..86517573dc 100644
 --- a/sysdeps/x86_64/dl-tls.c
@@ -20409,6 +22058,19 @@ index 68646ef199..7622af259c 100644
        && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
                                      AVX_Fast_Unaligned_Load, ))
      {
+diff --git a/sysdeps/x86_64/multiarch/ifunc-wmemset.h 
b/sysdeps/x86_64/multiarch/ifunc-wmemset.h
+index 3810c719c6..9e58bc00b5 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-wmemset.h
++++ b/sysdeps/x86_64/multiarch/ifunc-wmemset.h
+@@ -35,7 +35,7 @@ IFUNC_SELECTOR (void)
+ 
+   if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+       && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+-                                    AVX_Fast_Unaligned_Load, !))
++                                    AVX_Fast_Unaligned_Load,))
+     {
+       if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL))
+       {
 diff --git a/sysdeps/x86_64/multiarch/memcmp-sse2.S 
b/sysdeps/x86_64/multiarch/memcmp-sse2.S
 index afd450d020..51bc9344f0 100644
 --- a/sysdeps/x86_64/multiarch/memcmp-sse2.S
diff --git a/debian/patches/series b/debian/patches/series
index 153a5d9d..7217d7dc 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -21,6 +21,8 @@ alpha/local-string-functions.diff
 alpha/submitted-fts64.diff
 alpha/submitted-makecontext.diff
 
+amd64/local-revert-x86-64-add-GLIBC_ABI_DT_X86_64_PLT-version.diff
+
 arm/local-sigaction.diff
 arm/unsubmitted-ldso-multilib.diff
 arm/local-arm-futex.diff

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 12.14

This update has been released as part of Debian 12.14.

--- End Message ---

Reply via email to