summaryrefslogtreecommitdiff
path: root/glibc-32
diff options
context:
space:
mode:
authorJuergen Daubert <jue@jue.li>2022-02-10 19:31:19 +0100
committerJuergen Daubert <jue@jue.li>2022-02-10 19:31:19 +0100
commitc776c651ffcaed27dcff47818b02f5a29442eac2 (patch)
treea8b3422c9d165d09b78db504d14afe4f067e202e /glibc-32
parentb09bbfd7165fbef7e82421846b122a4fdf7cdc4a (diff)
downloadcore-c776c651ffcaed27dcff47818b02f5a29442eac2.tar.gz
core-c776c651ffcaed27dcff47818b02f5a29442eac2.tar.xz
glibc-32: update to 2.35
Diffstat (limited to 'glibc-32')
-rw-r--r--glibc-32/.footprint1
-rw-r--r--glibc-32/.signature12
-rw-r--r--glibc-32/Pkgfile4
-rw-r--r--glibc-32/glibc-2.34-1.patch4419
-rw-r--r--glibc-32/glibc-2.35-1.patch230
5 files changed, 238 insertions, 4428 deletions
diff --git a/glibc-32/.footprint b/glibc-32/.footprint
index 88c87295..6f994a53 100644
--- a/glibc-32/.footprint
+++ b/glibc-32/.footprint
@@ -6,7 +6,6 @@ lrwxrwxrwx root/root lib/ld-linux.so.2 -> /lib32/ld-linux.so.2
drwxr-xr-x root/root lib32/
-rwxr-xr-x root/root lib32/ld-linux.so.2
-rwxr-xr-x root/root lib32/libBrokenLocale.so.1
--rwxr-xr-x root/root lib32/libSegFault.so
-rwxr-xr-x root/root lib32/libanl.so.1
-rwxr-xr-x root/root lib32/libc.so.6
-rwxr-xr-x root/root lib32/libc_malloc_debug.so.0
diff --git a/glibc-32/.signature b/glibc-32/.signature
index 5dcca12b..07e2119f 100644
--- a/glibc-32/.signature
+++ b/glibc-32/.signature
@@ -1,8 +1,8 @@
untrusted comment: verify with /etc/ports/core.pub
-RWRJc1FUaeVeqjMglBs29r0xnkWCM0kkBzI2ipNRYJiVx7kAKgjUOTi7W7bcnMDbNDPmm2007uR8Ap9ycVgMVNkdPHDQjMHoYwM=
-SHA256 (Pkgfile) = 1aa584a9e2fb75c2e2b1591e6bc8711ff723e7a62d5956bf05215e5720cd7cf3
-SHA256 (.footprint) = 54c55f2d06c68fe3fb88ea56cdcf13038a41794a90855c8c17e4112d8eb7cbdc
-SHA256 (glibc-2.34.tar.xz) = 44d26a1fe20b8853a48f470ead01e4279e869ac149b195dda4e44a195d981ab2
-SHA256 (linux-5.15.11.tar.xz) = c1178b7e7e12d91292e670191268e3fe9a3563faf899eef43e468577e973a1ce
-SHA256 (glibc-2.34-1.patch) = 38455bc201d53743b34335464a10d8ab2bfc456e71c49c116a58397ca48c7e2a
+RWRJc1FUaeVeqh19lKx4wk8KE2AhxflKslbkarbdSukAiOJ6+8ga9luqkksDm1m7U1Yto0Z7EXUQiCJ7p7fKnn3JpbZkkVeVIgE=
+SHA256 (Pkgfile) = fd483db30bbd4bf632ee56d2511724f33edfed5d9bad80ea070d92b53ae58a9f
+SHA256 (.footprint) = f676700a19f936a1af944e81a516dbf182723d6ac244eadabd3fd19e9a01daa5
+SHA256 (glibc-2.35.tar.xz) = 5123732f6b67ccd319305efd399971d58592122bcc2a6518a1bd2510dd0cf52e
+SHA256 (linux-5.15.21.tar.xz) = 294eeb6cd7dc9b144c3c3c8b8c7b3fca9c6b072b6ed9bf9d6c922f9deb70fbd1
+SHA256 (glibc-2.35-1.patch) = f9041b36bd2194753d43da1053320d58d75acc76cfdcc2bd13e502b247d90b4e
SHA256 (lib32.conf) = 2f174d2bcefe1c29327690514f34d6970fffdd54398320ca23a11b5f1e3c9b2d
diff --git a/glibc-32/Pkgfile b/glibc-32/Pkgfile
index 8df32af0..f7a6e182 100644
--- a/glibc-32/Pkgfile
+++ b/glibc-32/Pkgfile
@@ -3,9 +3,9 @@
# Maintainer: CRUX System Team, core-ports at crux dot nu
name=glibc-32
-version=2.34
+version=2.35
release=1
-_kernel_version=5.15.11
+_kernel_version=5.15.21
source=(https://ftp.gnu.org/gnu/glibc/glibc-$version.tar.xz
https://www.kernel.org/pub/linux/kernel/v5.x/linux-$_kernel_version.tar.xz
diff --git a/glibc-32/glibc-2.34-1.patch b/glibc-32/glibc-2.34-1.patch
deleted file mode 100644
index 19452841..00000000
--- a/glibc-32/glibc-2.34-1.patch
+++ /dev/null
@@ -1,4419 +0,0 @@
-diff --git a/NEWS b/NEWS
-index 3c610744c9..698964bb9e 100644
---- a/NEWS
-+++ b/NEWS
-@@ -4,6 +4,25 @@ See the end for copying conditions.
-
- Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
- using `glibc' in the "product" field.
-+
-+Version 2.34.1
-+
-+The following bugs are resolved with this release:
-+
-+ [12889] nptl: Fix race between pthread_kill and thread exit
-+ [19193] nptl: pthread_kill, pthread_cancel should not fail after exit
-+ [28036] Incorrect types for pthread_mutexattr_set/getrobust_np
-+ [28182] _TIME_BITS=64 in C++ has issues with fcntl, ioctl, prctl
-+ [28310] Do not use affinity mask for sysconf (_SC_NPROCESSORS_CONF)
-+ [28340] ld.so crashes while loading a DSO with a read-only dynamic section
-+ [28357] deadlock between pthread_create and ELF constructors
-+ [28361] nptl: Avoid setxid deadlock with blocked signals in thread exit
-+ [28407] pthread_kill assumes that kill and tgkill are equivalent
-+ [28524] Conversion from ISO-2022-JP-3 with iconv may emit spurious NULs
-+ [28607] Masked signals are delivered on thread exit
-+ [28532] powerpc64[le]: CFI for assembly templated syscalls is incorrect
-+ [28678] nptl/tst-create1 hangs sporadically
-+
-
- Version 2.34
-
-diff --git a/bits/stdlib-bsearch.h b/bits/stdlib-bsearch.h
-index 4132dc6af0..e2fcea6e17 100644
---- a/bits/stdlib-bsearch.h
-+++ b/bits/stdlib-bsearch.h
-@@ -29,14 +29,23 @@ bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size,
- while (__l < __u)
- {
- __idx = (__l + __u) / 2;
-- __p = (void *) (((const char *) __base) + (__idx * __size));
-+ __p = (const void *) (((const char *) __base) + (__idx * __size));
- __comparison = (*__compar) (__key, __p);
- if (__comparison < 0)
- __u = __idx;
- else if (__comparison > 0)
- __l = __idx + 1;
- else
-- return (void *) __p;
-+ {
-+#if __GNUC_PREREQ(4, 6)
-+# pragma GCC diagnostic push
-+# pragma GCC diagnostic ignored "-Wcast-qual"
-+#endif
-+ return (void *) __p;
-+#if __GNUC_PREREQ(4, 6)
-+# pragma GCC diagnostic pop
-+#endif
-+ }
- }
-
- return NULL;
-diff --git a/elf/Makefile b/elf/Makefile
-index d05f410592..118d579c42 100644
---- a/elf/Makefile
-+++ b/elf/Makefile
-@@ -224,7 +224,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
- tst-tls-ie tst-tls-ie-dlmopen argv0test \
- tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
- tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \
-- tst-dl-is_dso
-+ tst-dl-is_dso tst-ro-dynamic
- # reldep9
- tests-internal += loadtest unload unload2 circleload1 \
- neededtest neededtest2 neededtest3 neededtest4 \
-@@ -357,7 +357,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
- libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
- tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \
- tst-auxvalmod \
-- tst-dlmopen-gethostbyname-mod \
-+ tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \
-
- # Most modules build with _ISOMAC defined, but those filtered out
- # depend on internal headers.
-@@ -399,8 +399,9 @@ endif
- modules-execstack-yes = tst-execstack-mod
- extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
-
--# filtmod1.so, tst-big-note-lib.so have special rules.
--modules-names-nobuild := filtmod1 tst-big-note-lib
-+# filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
-+# rules.
-+modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod
-
- tests += $(tests-static)
-
-@@ -1906,3 +1907,10 @@ $(objpfx)tst-getauxval-static.out: $(objpfx)tst-auxvalmod.so
- tst-getauxval-static-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx)
-
- $(objpfx)tst-dlmopen-gethostbyname.out: $(objpfx)tst-dlmopen-gethostbyname-mod.so
-+
-+$(objpfx)tst-ro-dynamic: $(objpfx)tst-ro-dynamic-mod.so
-+$(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \
-+ tst-ro-dynamic-mod.map
-+ $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
-+ -Wl,--script=tst-ro-dynamic-mod.map \
-+ $(objpfx)tst-ro-dynamic-mod.os
-diff --git a/elf/dl-close.c b/elf/dl-close.c
-index f39001cab9..cd7b9c9fe8 100644
---- a/elf/dl-close.c
-+++ b/elf/dl-close.c
-@@ -549,6 +549,9 @@ _dl_close_worker (struct link_map *map, bool force)
- size_t tls_free_end;
- tls_free_start = tls_free_end = NO_TLS_OFFSET;
-
-+ /* Protects global and module specitic TLS state. */
-+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
-+
- /* We modify the list of loaded objects. */
- __rtld_lock_lock_recursive (GL(dl_load_write_lock));
-
-@@ -784,6 +787,9 @@ _dl_close_worker (struct link_map *map, bool force)
- GL(dl_tls_static_used) = tls_free_start;
- }
-
-+ /* TLS is cleaned up for the unloaded modules. */
-+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
-+
- #ifdef SHARED
- /* Auditing checkpoint: we have deleted all objects. */
- if (__glibc_unlikely (do_audit))
-diff --git a/elf/dl-load.c b/elf/dl-load.c
-index 650e4edc35..0976977fbd 100644
---- a/elf/dl-load.c
-+++ b/elf/dl-load.c
-@@ -1130,6 +1130,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
- struct loadcmd loadcmds[l->l_phnum];
- size_t nloadcmds = 0;
- bool has_holes = false;
-+ bool empty_dynamic = false;
-
- /* The struct is initialized to zero so this is not necessary:
- l->l_ld = 0;
-@@ -1142,13 +1143,16 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
- segments are mapped in. We record the addresses it says
- verbatim, and later correct for the run-time load address. */
- case PT_DYNAMIC:
-- if (ph->p_filesz)
-+ if (ph->p_filesz == 0)
-+ empty_dynamic = true; /* Usually separate debuginfo. */
-+ else
- {
- /* Debuginfo only files from "objcopy --only-keep-debug"
- contain a PT_DYNAMIC segment with p_filesz == 0. Skip
- such a segment to avoid a crash later. */
- l->l_ld = (void *) ph->p_vaddr;
- l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
-+ l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
- }
- break;
-
-@@ -1264,6 +1268,13 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
- goto lose;
- }
-
-+ /* This check recognizes most separate debuginfo files. */
-+ if (__glibc_unlikely ((l->l_ld == 0 && type == ET_DYN) || empty_dynamic))
-+ {
-+ errstring = N_("object file has no dynamic section");
-+ goto lose;
-+ }
-+
- /* Length of the sections to be loaded. */
- maplength = loadcmds[nloadcmds - 1].allocend - loadcmds[0].mapstart;
-
-@@ -1281,18 +1292,10 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
- }
- }
-
-- if (l->l_ld == 0)
-- {
-- if (__glibc_unlikely (type == ET_DYN))
-- {
-- errstring = N_("object file has no dynamic section");
-- goto lose;
-- }
-- }
-- else
-+ if (l->l_ld != 0)
- l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
-
-- elf_get_dynamic_info (l, NULL);
-+ elf_get_dynamic_info (l);
-
- /* Make sure we are not dlopen'ing an object that has the
- DF_1_NOOPEN flag set, or a PIE object. */
-diff --git a/elf/dl-open.c b/elf/dl-open.c
-index ec386626f9..bc68e2c376 100644
---- a/elf/dl-open.c
-+++ b/elf/dl-open.c
-@@ -66,6 +66,9 @@ struct dl_open_args
- libc_map value in the namespace in case of a dlopen failure. */
- bool libc_already_loaded;
-
-+ /* Set to true if the end of dl_open_worker_begin was reached. */
-+ bool worker_continue;
-+
- /* Original parameters to the program and the current environment. */
- int argc;
- char **argv;
-@@ -482,7 +485,7 @@ call_dl_init (void *closure)
- }
-
- static void
--dl_open_worker (void *a)
-+dl_open_worker_begin (void *a)
- {
- struct dl_open_args *args = a;
- const char *file = args->file;
-@@ -774,6 +777,36 @@ dl_open_worker (void *a)
- _dl_call_libc_early_init (libc_map, false);
- }
-
-+ args->worker_continue = true;
-+}
-+
-+static void
-+dl_open_worker (void *a)
-+{
-+ struct dl_open_args *args = a;
-+
-+ args->worker_continue = false;
-+
-+ {
-+ /* Protects global and module specific TLS state. */
-+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
-+
-+ struct dl_exception ex;
-+ int err = _dl_catch_exception (&ex, dl_open_worker_begin, args);
-+
-+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
-+
-+ if (__glibc_unlikely (ex.errstring != NULL))
-+ /* Reraise the error. */
-+ _dl_signal_exception (err, &ex, NULL);
-+ }
-+
-+ if (!args->worker_continue)
-+ return;
-+
-+ int mode = args->mode;
-+ struct link_map *new = args->map;
-+
- /* Run the initializer functions of new objects. Temporarily
- disable the exception handler, so that lazy binding failures are
- fatal. */
-@@ -886,7 +919,7 @@ no more namespaces available for dlmopen()"));
- /* Avoid keeping around a dangling reference to the libc.so link
- map in case it has been cached in libc_map. */
- if (!args.libc_already_loaded)
-- GL(dl_ns)[nsid].libc_map = NULL;
-+ GL(dl_ns)[args.nsid].libc_map = NULL;
-
- /* Remove the object from memory. It may be in an inconsistent
- state if relocation failed, for example. */
-diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
-index d5bd2f31e9..2fb02d7276 100644
---- a/elf/dl-reloc-static-pie.c
-+++ b/elf/dl-reloc-static-pie.c
-@@ -40,7 +40,17 @@ _dl_relocate_static_pie (void)
-
- /* Read our own dynamic section and fill in the info array. */
- main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ());
-- elf_get_dynamic_info (main_map, NULL);
-+
-+ const ElfW(Phdr) *ph, *phdr = GL(dl_phdr);
-+ size_t phnum = GL(dl_phnum);
-+ for (ph = phdr; ph < &phdr[phnum]; ++ph)
-+ if (ph->p_type == PT_DYNAMIC)
-+ {
-+ main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
-+ break;
-+ }
-+
-+ elf_get_dynamic_info (main_map);
-
- # ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
- ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info);
-diff --git a/elf/dl-support.c b/elf/dl-support.c
-index 0155718175..d8c06ba7eb 100644
---- a/elf/dl-support.c
-+++ b/elf/dl-support.c
-@@ -229,6 +229,13 @@ __rtld_lock_define_initialized_recursive (, _dl_load_lock)
- list of loaded objects while an object is added to or removed from
- that list. */
- __rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
-+ /* This lock protects global and module specific TLS related data.
-+ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
-+ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
-+ accessed and when TLS related relocations are processed for a
-+ module. It was introduced to keep pthread_create accessing TLS
-+ state that is being set up. */
-+__rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
-
-
- #ifdef HAVE_AUX_VECTOR
-diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
-index d47bef1340..2c684c2db2 100644
---- a/elf/dl-sysdep.c
-+++ b/elf/dl-sysdep.c
-@@ -317,7 +317,7 @@ _dl_show_auxv (void)
- [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex },
- [AT_RANDOM - 2] = { "RANDOM: 0x", hex },
- [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex },
-- [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ ", dec },
-+ [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec },
- [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec },
- [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex },
- [AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec },
-diff --git a/elf/dl-tls.c b/elf/dl-tls.c
-index 423e380f7c..40263cf586 100644
---- a/elf/dl-tls.c
-+++ b/elf/dl-tls.c
-@@ -532,7 +532,7 @@ _dl_allocate_tls_init (void *result)
- size_t maxgen = 0;
-
- /* Protects global dynamic TLS related state. */
-- __rtld_lock_lock_recursive (GL(dl_load_lock));
-+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
-
- /* Check if the current dtv is big enough. */
- if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
-@@ -606,7 +606,7 @@ _dl_allocate_tls_init (void *result)
- listp = listp->next;
- assert (listp != NULL);
- }
-- __rtld_lock_unlock_recursive (GL(dl_load_lock));
-+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
-
- /* The DTV version is up-to-date now. */
- dtv[0].counter = maxgen;
-@@ -745,7 +745,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
-
- Here the dtv needs to be updated to new_gen generation count.
-
-- This code may be called during TLS access when GL(dl_load_lock)
-+ This code may be called during TLS access when GL(dl_load_tls_lock)
- is not held. In that case the user code has to synchronize with
- dlopen and dlclose calls of relevant modules. A module m is
- relevant if the generation of m <= new_gen and dlclose of m is
-@@ -867,11 +867,11 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
- if (__glibc_unlikely (the_map->l_tls_offset
- != FORCED_DYNAMIC_TLS_OFFSET))
- {
-- __rtld_lock_lock_recursive (GL(dl_load_lock));
-+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
- if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
- {
- the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
-- __rtld_lock_unlock_recursive (GL(dl_load_lock));
-+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
- }
- else if (__glibc_likely (the_map->l_tls_offset
- != FORCED_DYNAMIC_TLS_OFFSET))
-@@ -883,7 +883,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
- #else
- # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
- #endif
-- __rtld_lock_unlock_recursive (GL(dl_load_lock));
-+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
-
- dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
- dtv[GET_ADDR_MODULE].pointer.val = p;
-@@ -891,7 +891,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
- return (char *) p + GET_ADDR_OFFSET;
- }
- else
-- __rtld_lock_unlock_recursive (GL(dl_load_lock));
-+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
- }
- struct dtv_pointer result = allocate_and_init (the_map);
- dtv[GET_ADDR_MODULE].pointer = result;
-@@ -962,7 +962,7 @@ _dl_tls_get_addr_soft (struct link_map *l)
- return NULL;
-
- dtv_t *dtv = THREAD_DTV ();
-- /* This may be called without holding the GL(dl_load_lock). Reading
-+ /* This may be called without holding the GL(dl_load_tls_lock). Reading
- arbitrary gen value is fine since this is best effort code. */
- size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
- if (__glibc_unlikely (dtv[0].counter != gen))
-diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
-index d8ec32377d..4aa2058abf 100644
---- a/elf/get-dynamic-info.h
-+++ b/elf/get-dynamic-info.h
-@@ -28,7 +28,7 @@ static
- auto
- #endif
- inline void __attribute__ ((unused, always_inline))
--elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
-+elf_get_dynamic_info (struct link_map *l)
- {
- #if __ELF_NATIVE_CLASS == 32
- typedef Elf32_Word d_tag_utype;
-@@ -69,28 +69,15 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
- info[i] = dyn;
- }
-
--#define DL_RO_DYN_TEMP_CNT 8
--
--#ifndef DL_RO_DYN_SECTION
- /* Don't adjust .dynamic unnecessarily. */
-- if (l->l_addr != 0)
-+ if (l->l_addr != 0 && dl_relocate_ld (l))
- {
- ElfW(Addr) l_addr = l->l_addr;
-- int cnt = 0;
-
- # define ADJUST_DYN_INFO(tag) \
- do \
- if (info[tag] != NULL) \
-- { \
-- if (temp) \
-- { \
-- temp[cnt].d_tag = info[tag]->d_tag; \
-- temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \
-- info[tag] = temp + cnt++; \
-- } \
-- else \
-- info[tag]->d_un.d_ptr += l_addr; \
-- } \
-+ info[tag]->d_un.d_ptr += l_addr; \
- while (0)
-
- ADJUST_DYN_INFO (DT_HASH);
-@@ -107,9 +94,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
- ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
- ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
- # undef ADJUST_DYN_INFO
-- assert (cnt <= DL_RO_DYN_TEMP_CNT);
- }
--#endif
- if (info[DT_PLTREL] != NULL)
- {
- #if ELF_MACHINE_NO_RELA
-diff --git a/elf/ldconfig.c b/elf/ldconfig.c
-index 1037e8d0cf..b8893637f8 100644
---- a/elf/ldconfig.c
-+++ b/elf/ldconfig.c
-@@ -503,7 +503,11 @@ add_dir_1 (const char *line, const char *from_file, int from_line)
- entry->path[--i] = '\0';
-
- if (i == 0)
-- return;
-+ {
-+ free (entry->path);
-+ free (entry);
-+ return;
-+ }
-
- char *path = entry->path;
- if (opt_chroot != NULL)
-diff --git a/elf/rtld.c b/elf/rtld.c
-index d733359eaf..d83ac1bdc4 100644
---- a/elf/rtld.c
-+++ b/elf/rtld.c
-@@ -322,6 +322,7 @@ struct rtld_global _rtld_global =
- #ifdef _LIBC_REENTRANT
- ._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
- ._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
-+ ._dl_load_tls_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
- #endif
- ._dl_nns = 1,
- ._dl_ns =
-@@ -463,6 +464,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
- #ifndef DONT_USE_BOOTSTRAP_MAP
- GL(dl_rtld_map).l_addr = info->l.l_addr;
- GL(dl_rtld_map).l_ld = info->l.l_ld;
-+ GL(dl_rtld_map).l_ld_readonly = info->l.l_ld_readonly;
- memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
- sizeof GL(dl_rtld_map).l_info);
- GL(dl_rtld_map).l_mach = info->l.l_mach;
-@@ -546,7 +548,8 @@ _dl_start (void *arg)
-
- /* Read our own dynamic section and fill in the info array. */
- bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
-- elf_get_dynamic_info (&bootstrap_map, NULL);
-+ bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
-+ elf_get_dynamic_info (&bootstrap_map);
-
- #if NO_TLS_OFFSET != 0
- bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
-@@ -1468,6 +1471,7 @@ dl_main (const ElfW(Phdr) *phdr,
- /* This tells us where to find the dynamic section,
- which tells us everything we need to do. */
- main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr;
-+ main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
- break;
- case PT_INTERP:
- /* This "interpreter segment" was used by the program loader to
-@@ -1613,7 +1617,7 @@ dl_main (const ElfW(Phdr) *phdr,
- if (! rtld_is_main)
- {
- /* Extract the contents of the dynamic section for easy access. */
-- elf_get_dynamic_info (main_map, NULL);
-+ elf_get_dynamic_info (main_map);
-
- /* If the main map is libc.so, update the base namespace to
- refer to this map. If libc.so is loaded later, this happens
-diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
-index 86c491e49c..f44748bc98 100644
---- a/elf/setup-vdso.h
-+++ b/elf/setup-vdso.h
-@@ -33,8 +33,6 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
- 0, LM_ID_BASE);
- if (__glibc_likely (l != NULL))
- {
-- static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
--
- l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
- + GLRO(dl_sysinfo_dso)->e_phoff);
- l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
-@@ -45,6 +43,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
- {
- l->l_ld = (void *) ph->p_vaddr;
- l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
-+ l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
- }
- else if (ph->p_type == PT_LOAD)
- {
-@@ -65,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
- l->l_map_end += l->l_addr;
- l->l_text_end += l->l_addr;
- l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
-- elf_get_dynamic_info (l, dyn_temp);
-+ elf_get_dynamic_info (l);
- _dl_setup_hash (l);
- l->l_relocated = 1;
-
-diff --git a/elf/tst-ro-dynamic-mod.c b/elf/tst-ro-dynamic-mod.c
-new file mode 100644
-index 0000000000..6d99925964
---- /dev/null
-+++ b/elf/tst-ro-dynamic-mod.c
-@@ -0,0 +1,19 @@
-+/* Test case for DSO with readonly dynamic section.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+int foo = -1;
-diff --git a/elf/tst-ro-dynamic-mod.map b/elf/tst-ro-dynamic-mod.map
-new file mode 100644
-index 0000000000..2fe4a2998c
---- /dev/null
-+++ b/elf/tst-ro-dynamic-mod.map
-@@ -0,0 +1,16 @@
-+SECTIONS
-+{
-+ . = SIZEOF_HEADERS;
-+ .dynamic : { *(.dynamic) } :text :dynamic
-+ .rodata : { *(.data*) *(.bss*) } :text
-+ /DISCARD/ : {
-+ *(.note.gnu.property)
-+ }
-+ .note : { *(.note.*) } :text :note
-+}
-+PHDRS
-+{
-+ text PT_LOAD FLAGS(5) FILEHDR PHDRS;
-+ dynamic PT_DYNAMIC FLAGS(4);
-+ note PT_NOTE FLAGS(4);
-+}
-diff --git a/elf/tst-ro-dynamic.c b/elf/tst-ro-dynamic.c
-new file mode 100644
-index 0000000000..3a18f8789a
---- /dev/null
-+++ b/elf/tst-ro-dynamic.c
-@@ -0,0 +1,31 @@
-+/* Test case for DSO with readonly dynamic section.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <support/check.h>
-+#include <support/test-driver.h>
-+
-+extern int foo;
-+
-+static int
-+do_test (void)
-+{
-+ TEST_COMPARE (foo, -1);
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
-index 62bee28769..cc391d8f93 100644
---- a/iconv/gconv_conf.c
-+++ b/iconv/gconv_conf.c
-@@ -478,7 +478,7 @@ __gconv_read_conf (void)
- __gconv_get_path ();
-
- for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt)
-- gconv_parseconfdir (__gconv_path_elem[cnt].name,
-+ gconv_parseconfdir (NULL, __gconv_path_elem[cnt].name,
- __gconv_path_elem[cnt].len);
- #endif
-
-diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
-index a4153e54c6..a586268abc 100644
---- a/iconv/gconv_parseconfdir.h
-+++ b/iconv/gconv_parseconfdir.h
-@@ -39,7 +39,6 @@
- /* Name of the file containing the module information in the directories
- along the path. */
- static const char gconv_conf_filename[] = "gconv-modules";
--static const char gconv_conf_dirname[] = "gconv-modules.d";
-
- static void add_alias (char *);
- static void add_module (char *, const char *, size_t, int);
-@@ -110,19 +109,28 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len)
- return true;
- }
-
-+/* Prefix DIR (with length DIR_LEN) with PREFIX if the latter is non-NULL and
-+ parse configuration in it. */
-+
- static __always_inline bool
--gconv_parseconfdir (const char *dir, size_t dir_len)
-+gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
- {
-- /* No slash needs to be inserted between dir and gconv_conf_filename;
-- dir already ends in a slash. */
-- char *buf = malloc (dir_len + sizeof (gconv_conf_dirname));
-+ /* No slash needs to be inserted between dir and gconv_conf_filename; dir
-+ already ends in a slash. The additional 2 is to accommodate the ".d"
-+ when looking for configuration files in gconv-modules.d. */
-+ size_t buflen = dir_len + sizeof (gconv_conf_filename) + 2;
-+ char *buf = malloc (buflen + (prefix != NULL ? strlen (prefix) : 0));
-+ char *cp = buf;
- bool found = false;
-
- if (buf == NULL)
- return false;
-
-- char *cp = mempcpy (mempcpy (buf, dir, dir_len), gconv_conf_filename,
-- sizeof (gconv_conf_filename));
-+ if (prefix != NULL)
-+ cp = stpcpy (cp, prefix);
-+
-+ cp = mempcpy (mempcpy (cp, dir, dir_len), gconv_conf_filename,
-+ sizeof (gconv_conf_filename));
-
- /* Read the gconv-modules configuration file first. */
- found = read_conf_file (buf, dir, dir_len);
-@@ -153,12 +161,11 @@ gconv_parseconfdir (const char *dir, size_t dir_len)
- struct stat64 st;
- if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
- continue;
-- if (ent->d_type == DT_UNKNOWN
-- && (lstat64 (conf, &st) == -1
-- || !S_ISREG (st.st_mode)))
-- continue;
-
-- found |= read_conf_file (conf, dir, dir_len);
-+ if (ent->d_type != DT_UNKNOWN
-+ || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode)))
-+ found |= read_conf_file (conf, dir, dir_len);
-+
- free (conf);
- }
- }
-diff --git a/iconv/iconv_charmap.c b/iconv/iconv_charmap.c
-index e2d53fee3c..a8b6b56124 100644
---- a/iconv/iconv_charmap.c
-+++ b/iconv/iconv_charmap.c
-@@ -234,6 +234,8 @@ charmap_conversion (const char *from_code, struct charmap_t *from_charmap,
- while (++remaining < argc);
-
- /* All done. */
-+ if (output != stdout)
-+ fclose (output);
- free_table (cvtbl);
- return status;
- }
-diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
-index 783b2bbdbb..273a71f673 100644
---- a/iconv/iconvconfig.c
-+++ b/iconv/iconvconfig.c
-@@ -653,13 +653,21 @@ add_module (char *rp, const char *directory,
- static int
- handle_dir (const char *dir)
- {
-+ char *newp = NULL;
- size_t dirlen = strlen (dir);
- bool found = false;
-
-- char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "",
-- dir, dir[dirlen - 1] != '/' ? "/" : "");
-+ /* End directory path with a '/' if it doesn't already. */
-+ if (dir[dirlen - 1] != '/')
-+ {
-+ newp = xmalloc (dirlen + 2);
-+ memcpy (newp, dir, dirlen);
-+ newp[dirlen++] = '/';
-+ newp[dirlen] = '\0';
-+ dir = newp;
-+ }
-
-- found = gconv_parseconfdir (fulldir, strlen (fulldir));
-+ found = gconv_parseconfdir (dir[0] == '/' ? prefix : NULL, dir, dirlen);
-
- if (!found)
- {
-@@ -671,7 +679,7 @@ handle_dir (const char *dir)
- "configuration files with names ending in .conf.");
- }
-
-- free (fulldir);
-+ free (newp);
-
- return found ? 0 : 1;
- }
-diff --git a/iconvdata/Makefile b/iconvdata/Makefile
-index c216f959df..d5507a048c 100644
---- a/iconvdata/Makefile
-+++ b/iconvdata/Makefile
-@@ -1,4 +1,5 @@
- # Copyright (C) 1997-2021 Free Software Foundation, Inc.
-+# Copyright (C) The GNU Toolchain Authors.
- # This file is part of the GNU C Library.
-
- # The GNU C Library is free software; you can redistribute it and/or
-@@ -74,7 +75,7 @@ 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-iconv13 bug-iconv14 bug-iconv15
- ifeq ($(have-thread-library),yes)
- tests += bug-iconv3
- endif
-@@ -327,6 +328,8 @@ $(objpfx)bug-iconv12.out: $(addprefix $(objpfx), $(gconv-modules)) \
- $(addprefix $(objpfx),$(modules.so))
- $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \
- $(addprefix $(objpfx),$(modules.so))
-+$(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \
-+ $(addprefix $(objpfx),$(modules.so))
-
- $(objpfx)iconv-test.out: run-iconv-test.sh \
- $(addprefix $(objpfx), $(gconv-modules)) \
-diff --git a/iconvdata/bug-iconv15.c b/iconvdata/bug-iconv15.c
-new file mode 100644
-index 0000000000..cc04bd0313
---- /dev/null
-+++ b/iconvdata/bug-iconv15.c
-@@ -0,0 +1,60 @@
-+/* Bug 28524: Conversion from ISO-2022-JP-3 with iconv
-+ may emit spurious NUL character on state reset.
-+ Copyright (C) The GNU Toolchain Authors.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <stddef.h>
-+#include <iconv.h>
-+#include <support/check.h>
-+
-+static int
-+do_test (void)
-+{
-+ char in[] = "\x1b(I";
-+ char *inbuf = in;
-+ size_t inleft = sizeof (in) - 1;
-+ char out[1];
-+ char *outbuf = out;
-+ size_t outleft = sizeof (out);
-+ iconv_t cd;
-+
-+ cd = iconv_open ("UTF8", "ISO-2022-JP-3");
-+ TEST_VERIFY_EXIT (cd != (iconv_t) -1);
-+
-+ /* First call to iconv should alter internal state.
-+ Now, JISX0201_Kana_set is selected and
-+ state value != ASCII_set. */
-+ TEST_VERIFY (iconv (cd, &inbuf, &inleft, &outbuf, &outleft) != (size_t) -1);
-+
-+ /* No bytes should have been added to
-+ the output buffer at this point. */
-+ TEST_VERIFY (outbuf == out);
-+ TEST_VERIFY (outleft == sizeof (out));
-+
-+ /* Second call shall emit spurious NUL character in unpatched glibc. */
-+ TEST_VERIFY (iconv (cd, NULL, NULL, &outbuf, &outleft) != (size_t) -1);
-+
-+ /* No characters are expected to be produced. */
-+ TEST_VERIFY (outbuf == out);
-+ TEST_VERIFY (outleft == sizeof (out));
-+
-+ TEST_VERIFY_EXIT (iconv_close (cd) != -1);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/iconvdata/iso-2022-jp-3.c b/iconvdata/iso-2022-jp-3.c
-index c8ba88cdc9..5fc0c0f739 100644
---- a/iconvdata/iso-2022-jp-3.c
-+++ b/iconvdata/iso-2022-jp-3.c
-@@ -1,5 +1,6 @@
- /* Conversion module for ISO-2022-JP-3.
- Copyright (C) 1998-2021 Free Software Foundation, Inc.
-+ Copyright (C) The GNU Toolchain Authors.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998,
- and Bruno Haible <bruno@clisp.org>, 2002.
-@@ -81,20 +82,31 @@ enum
- the output state to the initial state. This has to be done during the
- flushing. */
- #define EMIT_SHIFT_TO_INIT \
-- if (data->__statep->__count != ASCII_set) \
-+ if ((data->__statep->__count & ~7) != ASCII_set) \
- { \
- if (FROM_DIRECTION) \
- { \
-- if (__glibc_likely (outbuf + 4 <= outend)) \
-+ uint32_t ch = data->__statep->__count >> 6; \
-+ \
-+ if (__glibc_unlikely (ch != 0)) \
- { \
-- /* Write out the last character. */ \
-- *((uint32_t *) outbuf) = data->__statep->__count >> 6; \
-- outbuf += sizeof (uint32_t); \
-- data->__statep->__count = ASCII_set; \
-+ if (__glibc_likely (outbuf + 4 <= outend)) \
-+ { \
-+ /* Write out the last character. */ \
-+ put32u (outbuf, ch); \
-+ outbuf += 4; \
-+ data->__statep->__count &= 7; \
-+ data->__statep->__count |= ASCII_set; \
-+ } \
-+ else \
-+ /* We don't have enough room in the output buffer. */ \
-+ status = __GCONV_FULL_OUTPUT; \
- } \
- else \
-- /* We don't have enough room in the output buffer. */ \
-- status = __GCONV_FULL_OUTPUT; \
-+ { \
-+ data->__statep->__count &= 7; \
-+ data->__statep->__count |= ASCII_set; \
-+ } \
- } \
- else \
- { \
-diff --git a/include/link.h b/include/link.h
-index 4af16cb596..c46aced9f7 100644
---- a/include/link.h
-+++ b/include/link.h
-@@ -205,6 +205,7 @@ struct link_map
- unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
- freed, ie. not allocated with
- the dummy malloc in ld.so. */
-+ unsigned int l_ld_readonly:1; /* Nonzero if dynamic section is readonly. */
-
- /* NODELETE status of the map. Only valid for maps of type
- lt_loaded. Lazy binding sets l_nodelete_active directly,
-@@ -342,6 +343,8 @@ struct link_map
- unsigned long long int l_serial;
- };
-
-+#include <dl-relocate-ld.h>
-+
- /* Information used by audit modules. For most link maps, this data
- immediate follows the link map in memory. For the dynamic linker,
- it is allocated separately. See link_map_audit_state in
-diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h
-index 7388356a19..c490561581 100644
---- a/include/sys/sysinfo.h
-+++ b/include/sys/sysinfo.h
-@@ -9,10 +9,15 @@
- extern int __get_nprocs_conf (void);
- libc_hidden_proto (__get_nprocs_conf)
-
--/* Return number of available processors. */
-+/* Return number of available processors (not all of them will be
-+ available to the caller process). */
- extern int __get_nprocs (void);
- libc_hidden_proto (__get_nprocs)
-
-+/* Return the number of available processors which the process can
-+ be scheduled. */
-+extern int __get_nprocs_sched (void) attribute_hidden;
-+
- /* Return number of physical pages of memory in the system. */
- extern long int __get_phys_pages (void);
- libc_hidden_proto (__get_phys_pages)
-diff --git a/io/fcntl.h b/io/fcntl.h
-index 8917a73b42..1c96f98f4d 100644
---- a/io/fcntl.h
-+++ b/io/fcntl.h
-@@ -187,10 +187,10 @@ extern int fcntl64 (int __fd, int __cmd, ...);
- # endif
- #else /* __USE_TIME_BITS64 */
- # ifdef __REDIRECT
--extern int __REDIRECT (fcntl, (int __fd, int __request, ...),
-- __fcntl_time64) __THROW;
--extern int __REDIRECT (fcntl64, (int __fd, int __request, ...),
-- __fcntl_time64) __THROW;
-+extern int __REDIRECT_NTH (fcntl, (int __fd, int __request, ...),
-+ __fcntl_time64);
-+extern int __REDIRECT_NTH (fcntl64, (int __fd, int __request, ...),
-+ __fcntl_time64);
- # else
- extern int __fcntl_time64 (int __fd, int __request, ...) __THROW;
- # define fcntl64 __fcntl_time64
-diff --git a/io/tst-closefrom.c b/io/tst-closefrom.c
-index d4c187073c..395ec0d894 100644
---- a/io/tst-closefrom.c
-+++ b/io/tst-closefrom.c
-@@ -24,31 +24,22 @@
- #include <support/check.h>
- #include <support/descriptors.h>
- #include <support/xunistd.h>
-+#include <support/support.h>
-
- #include <array_length.h>
-
- #define NFDS 100
-
--static int
--open_multiple_temp_files (void)
--{
-- /* Check if the temporary file descriptor has no no gaps. */
-- int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
-- for (int i = 1; i <= NFDS; i++)
-- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), lowfd + i);
-- return lowfd;
--}
--
- static int
- closefrom_test (void)
- {
- struct support_descriptors *descrs = support_descriptors_list ();
-
-- int lowfd = open_multiple_temp_files ();
-+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
-
-- const int maximum_fd = lowfd + NFDS;
-+ const int maximum_fd = lowfd + NFDS - 1;
- const int half_fd = lowfd + NFDS / 2;
-- const int gap = maximum_fd / 4;
-+ const int gap = lowfd + NFDS / 4;
-
- /* Close half of the descriptors and check result. */
- closefrom (half_fd);
-@@ -58,7 +49,7 @@ closefrom_test (void)
- TEST_COMPARE (fcntl (i, F_GETFL), -1);
- TEST_COMPARE (errno, EBADF);
- }
-- for (int i = 0; i < half_fd; i++)
-+ for (int i = lowfd; i < half_fd; i++)
- TEST_VERIFY (fcntl (i, F_GETFL) > -1);
-
- /* Create some gaps, close up to a threshold, and check result. */
-@@ -74,7 +65,7 @@ closefrom_test (void)
- TEST_COMPARE (fcntl (i, F_GETFL), -1);
- TEST_COMPARE (errno, EBADF);
- }
-- for (int i = 0; i < gap; i++)
-+ for (int i = lowfd; i < gap; i++)
- TEST_VERIFY (fcntl (i, F_GETFL) > -1);
-
- /* Close the remmaining but the last one. */
-diff --git a/malloc/arena.c b/malloc/arena.c
-index 667484630e..f1f0af8648 100644
---- a/malloc/arena.c
-+++ b/malloc/arena.c
-@@ -879,7 +879,7 @@ arena_get2 (size_t size, mstate avoid_arena)
- narenas_limit = mp_.arena_max;
- else if (narenas > mp_.arena_test)
- {
-- int n = __get_nprocs ();
-+ int n = __get_nprocs_sched ();
-
- if (n >= 1)
- narenas_limit = NARENAS_FROM_NCORES (n);
-diff --git a/malloc/malloc-debug.c b/malloc/malloc-debug.c
-index 9922ef5f25..3d7e6d44fd 100644
---- a/malloc/malloc-debug.c
-+++ b/malloc/malloc-debug.c
-@@ -1,5 +1,6 @@
- /* Malloc debug DSO.
- Copyright (C) 2021 Free Software Foundation, Inc.
-+ Copyright The GNU Toolchain Authors.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
-@@ -399,17 +400,17 @@ strong_alias (__debug_calloc, calloc)
- size_t
- malloc_usable_size (void *mem)
- {
-+ if (mem == NULL)
-+ return 0;
-+
- if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
- return mcheck_usable_size (mem);
- if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
- return malloc_check_get_size (mem);
-
-- if (mem != NULL)
-- {
-- mchunkptr p = mem2chunk (mem);
-- if (DUMPED_MAIN_ARENA_CHUNK (p))
-- return chunksize (p) - SIZE_SZ;
-- }
-+ mchunkptr p = mem2chunk (mem);
-+ if (DUMPED_MAIN_ARENA_CHUNK (p))
-+ return chunksize (p) - SIZE_SZ;
-
- return musable (mem);
- }
-diff --git a/malloc/malloc.c b/malloc/malloc.c
-index e065785af7..7882c70f0a 100644
---- a/malloc/malloc.c
-+++ b/malloc/malloc.c
-@@ -1,5 +1,6 @@
- /* Malloc implementation for multiple threads without lock contention.
- Copyright (C) 1996-2021 Free Software Foundation, Inc.
-+ Copyright The GNU Toolchain Authors.
- This file is part of the GNU C Library.
- Contributed by Wolfram Gloger <wg@malloc.de>
- and Doug Lea <dl@cs.oswego.edu>, 2001.
-@@ -5009,20 +5010,13 @@ __malloc_trim (size_t s)
- static size_t
- musable (void *mem)
- {
-- mchunkptr p;
-- if (mem != 0)
-- {
-- size_t result = 0;
--
-- p = mem2chunk (mem);
-+ mchunkptr p = mem2chunk (mem);
-
-- if (chunk_is_mmapped (p))
-- result = chunksize (p) - CHUNK_HDR_SZ;
-- else if (inuse (p))
-- result = memsize (p);
-+ if (chunk_is_mmapped (p))
-+ return chunksize (p) - CHUNK_HDR_SZ;
-+ else if (inuse (p))
-+ return memsize (p);
-
-- return result;
-- }
- return 0;
- }
-
-@@ -5030,10 +5024,9 @@ musable (void *mem)
- size_t
- __malloc_usable_size (void *m)
- {
-- size_t result;
--
-- result = musable (m);
-- return result;
-+ if (m == NULL)
-+ return 0;
-+ return musable (m);
- }
- #endif
-
-diff --git a/malloc/tst-malloc-usable.c b/malloc/tst-malloc-usable.c
-index a1074b782a..b0d702be10 100644
---- a/malloc/tst-malloc-usable.c
-+++ b/malloc/tst-malloc-usable.c
-@@ -2,6 +2,7 @@
- MALLOC_CHECK_ exported to a positive value.
-
- Copyright (C) 2012-2021 Free Software Foundation, Inc.
-+ Copyright The GNU Toolchain Authors.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
-@@ -21,29 +22,24 @@
- #include <malloc.h>
- #include <string.h>
- #include <stdio.h>
-+#include <support/support.h>
-+#include <support/check.h>
-
- static int
- do_test (void)
- {
- size_t usable_size;
- void *p = malloc (7);
-- if (!p)
-- {
-- printf ("memory allocation failed\n");
-- return 1;
-- }
-
-+ TEST_VERIFY_EXIT (p != NULL);
- usable_size = malloc_usable_size (p);
-- if (usable_size != 7)
-- {
-- printf ("malloc_usable_size: expected 7 but got %zu\n", usable_size);
-- return 1;
-- }
--
-+ TEST_COMPARE (usable_size, 7);
- memset (p, 0, usable_size);
- free (p);
-+
-+ TEST_COMPARE (malloc_usable_size (NULL), 0);
-+
- return 0;
- }
-
--#define TEST_FUNCTION do_test ()
--#include "../test-skeleton.c"
-+#include "support/test-driver.c"
-diff --git a/misc/getsysstats.c b/misc/getsysstats.c
-index 0eedface6d..57d93601e2 100644
---- a/misc/getsysstats.c
-+++ b/misc/getsysstats.c
-@@ -45,6 +45,12 @@ weak_alias (__get_nprocs, get_nprocs)
- link_warning (get_nprocs, "warning: get_nprocs will always return 1")
-
-
-+int
-+__get_nprocs_sched (void)
-+{
-+ return 1;
-+}
-+
- long int
- __get_phys_pages (void)
- {
-diff --git a/misc/sys/ioctl.h b/misc/sys/ioctl.h
-index 6884d9925f..9945c1e918 100644
---- a/misc/sys/ioctl.h
-+++ b/misc/sys/ioctl.h
-@@ -42,8 +42,8 @@ __BEGIN_DECLS
- extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;
- #else
- # ifdef __REDIRECT
--extern int __REDIRECT (ioctl, (int __fd, unsigned long int __request, ...),
-- __ioctl_time64) __THROW;
-+extern int __REDIRECT_NTH (ioctl, (int __fd, unsigned long int __request, ...),
-+ __ioctl_time64);
- # else
- extern int __ioctl_time64 (int __fd, unsigned long int __request, ...) __THROW;
- # define ioctl __ioctl_time64
-diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
-index cfe37a3443..50065bc9bd 100644
---- a/nptl/allocatestack.c
-+++ b/nptl/allocatestack.c
-@@ -32,6 +32,7 @@
- #include <futex-internal.h>
- #include <kernel-features.h>
- #include <nptl-stack.h>
-+#include <libc-lock.h>
-
- /* Default alignment of stack. */
- #ifndef STACK_ALIGN
-@@ -127,6 +128,8 @@ get_cached_stack (size_t *sizep, void **memp)
- /* No pending event. */
- result->nextevent = NULL;
-
-+ result->exiting = false;
-+ __libc_lock_init (result->exit_lock);
- result->tls_state = (struct tls_internal_t) { 0 };
-
- /* Clear the DTV. */
-diff --git a/nptl/descr.h b/nptl/descr.h
-index c85778d449..4de84138fb 100644
---- a/nptl/descr.h
-+++ b/nptl/descr.h
-@@ -396,6 +396,12 @@ struct pthread
- PTHREAD_CANCEL_ASYNCHRONOUS). */
- unsigned char canceltype;
-
-+ /* Used in __pthread_kill_internal to detected a thread that has
-+ exited or is about to exit. exit_lock must only be acquired
-+ after blocking signals. */
-+ bool exiting;
-+ int exit_lock; /* A low-level lock (for use with __libc_lock_init etc). */
-+
- /* Used on strsignal. */
- struct tls_internal_t tls_state;
-
-diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
-index cc25ff21f3..9bac6e3b76 100644
---- a/nptl/pthread_cancel.c
-+++ b/nptl/pthread_cancel.c
-@@ -62,10 +62,11 @@ __pthread_cancel (pthread_t th)
- {
- volatile struct pthread *pd = (volatile struct pthread *) th;
-
-- /* Make sure the descriptor is valid. */
-- if (INVALID_TD_P (pd))
-- /* Not a valid thread handle. */
-- return ESRCH;
-+ if (pd->tid == 0)
-+ /* The thread has already exited on the kernel side. Its outcome
-+ (regular exit, other cancelation) has already been
-+ determined. */
-+ return 0;
-
- static int init_sigcancel = 0;
- if (atomic_load_relaxed (&init_sigcancel) == 0)
-diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
-index d8ec299cb1..3db0c9fdf4 100644
---- a/nptl/pthread_create.c
-+++ b/nptl/pthread_create.c
-@@ -37,6 +37,7 @@
- #include <sys/single_threaded.h>
- #include <version.h>
- #include <clone_internal.h>
-+#include <futex-internal.h>
-
- #include <shlib-compat.h>
-
-@@ -406,8 +407,6 @@ start_thread (void *arg)
- unwind_buf.priv.data.prev = NULL;
- unwind_buf.priv.data.cleanup = NULL;
-
-- __libc_signal_restore_set (&pd->sigmask);
--
- /* Allow setxid from now onwards. */
- if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0) == -2))
- futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE);
-@@ -417,6 +416,8 @@ start_thread (void *arg)
- /* Store the new cleanup handler info. */
- THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf);
-
-+ __libc_signal_restore_set (&pd->sigmask);
-+
- LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);
-
- /* Run the code the user provided. */
-@@ -485,6 +486,27 @@ start_thread (void *arg)
- /* This was the last thread. */
- exit (0);
-
-+ /* This prevents sending a signal from this thread to itself during
-+ its final stages. This must come after the exit call above
-+ because atexit handlers must not run with signals blocked.
-+
-+ Do not block SIGSETXID. The setxid handshake below expects the
-+ signal to be delivered. (SIGSETXID cannot run application code,
-+ nor does it use pthread_kill.) Reuse the pd->sigmask space for
-+ computing the signal mask, to save stack space. */
-+ __sigfillset (&pd->sigmask);
-+ __sigdelset (&pd->sigmask, SIGSETXID);
-+ INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_BLOCK, &pd->sigmask, NULL,
-+ __NSIG_BYTES);
-+
-+ /* Tell __pthread_kill_internal that this thread is about to exit.
-+ If there is a __pthread_kill_internal in progress, this delays
-+ the thread exit until the signal has been queued by the kernel
-+ (so that the TID used to send it remains valid). */
-+ __libc_lock_lock (pd->exit_lock);
-+ pd->exiting = true;
-+ __libc_lock_unlock (pd->exit_lock);
-+
- #ifndef __ASSUME_SET_ROBUST_LIST
- /* If this thread has any robust mutexes locked, handle them now. */
- # if __PTHREAD_MUTEX_HAVE_PREV
-diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c
-index f79a2b26fc..35bf1f973e 100644
---- a/nptl/pthread_kill.c
-+++ b/nptl/pthread_kill.c
-@@ -16,39 +16,66 @@
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-+#include <libc-lock.h>
- #include <unistd.h>
- #include <pthreadP.h>
- #include <shlib-compat.h>
-
--int
--__pthread_kill_internal (pthread_t threadid, int signo)
-+/* Sends SIGNO to THREADID. If the thread is about to exit or has
-+ already exited on the kernel side, return NO_TID. Otherwise return
-+ 0 or an error code. */
-+static int
-+__pthread_kill_implementation (pthread_t threadid, int signo, int no_tid)
- {
-- pid_t tid;
- struct pthread *pd = (struct pthread *) threadid;
--
- if (pd == THREAD_SELF)
-- /* It is a special case to handle raise() implementation after a vfork
-- call (which does not update the PD tid field). */
-- tid = INLINE_SYSCALL_CALL (gettid);
-- else
-- /* Force load of pd->tid into local variable or register. Otherwise
-- if a thread exits between ESRCH test and tgkill, we might return
-- EINVAL, because pd->tid would be cleared by the kernel. */
-- tid = atomic_forced_read (pd->tid);
--
-- int val;
-- if (__glibc_likely (tid > 0))
- {
-- pid_t pid = __getpid ();
--
-- val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo);
-- val = (INTERNAL_SYSCALL_ERROR_P (val)
-- ? INTERNAL_SYSCALL_ERRNO (val) : 0);
-+ /* Use the actual TID from the kernel, so that it refers to the
-+ current thread even if called after vfork. There is no
-+ signal blocking in this case, so that the signal is delivered
-+ immediately, before __pthread_kill_internal returns: a signal
-+ sent to the thread itself needs to be delivered
-+ synchronously. (It is unclear if Linux guarantees the
-+ delivery of all pending signals after unblocking in the code
-+ below. POSIX only guarantees delivery of a single signal,
-+ which may not be the right one.) */
-+ pid_t tid = INTERNAL_SYSCALL_CALL (gettid);
-+ int ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), tid, signo);
-+ return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0;
- }
-+
-+ /* Block all signals, as required by pd->exit_lock. */
-+ sigset_t old_mask;
-+ __libc_signal_block_all (&old_mask);
-+ __libc_lock_lock (pd->exit_lock);
-+
-+ int ret;
-+ if (pd->exiting)
-+ /* The thread is about to exit (or has exited). Sending the
-+ signal is either not observable (the target thread has already
-+ blocked signals at this point), or it will fail, or it might be
-+ delivered to a new, unrelated thread that has reused the TID.
-+ So do not actually send the signal. */
-+ ret = no_tid;
- else
-- val = ESRCH;
-+ {
-+ ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), pd->tid, signo);
-+ ret = INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0;
-+ }
-+
-+ __libc_lock_unlock (pd->exit_lock);
-+ __libc_signal_restore_set (&old_mask);
-
-- return val;
-+ return ret;
-+}
-+
-+int
-+__pthread_kill_internal (pthread_t threadid, int signo)
-+{
-+ /* Do not report an error in the no-tid case because the threadid
-+ argument is still valid (the thread ID lifetime has not ended),
-+ and ESRCH (for example) would be misleading. */
-+ return __pthread_kill_implementation (threadid, signo, 0);
- }
-
- int
-@@ -61,6 +88,7 @@ __pthread_kill (pthread_t threadid, int signo)
-
- return __pthread_kill_internal (threadid, signo);
- }
-+
- /* Some architectures (for instance arm) might pull raise through libgcc, so
- avoid the symbol version if it ends up being used on ld.so. */
- #if !IS_IN(rtld)
-@@ -68,6 +96,17 @@ libc_hidden_def (__pthread_kill)
- versioned_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_34);
-
- # if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34)
--compat_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_0);
-+/* Variant which returns ESRCH in the no-TID case, for backwards
-+ compatibility. */
-+int
-+attribute_compat_text_section
-+__pthread_kill_esrch (pthread_t threadid, int signo)
-+{
-+ if (__is_internal_signal (signo))
-+ return EINVAL;
-+
-+ return __pthread_kill_implementation (threadid, signo, ESRCH);
-+}
-+compat_symbol (libc, __pthread_kill_esrch, pthread_kill, GLIBC_2_0);
- # endif
- #endif
-diff --git a/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf
-new file mode 100644
-index 0000000000..5b0c6a4199
---- /dev/null
-+++ b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf
-@@ -0,0 +1 @@
-+hosts: files
-diff --git a/posix/Makefile b/posix/Makefile
-index 059efb3cd2..09460a28e8 100644
---- a/posix/Makefile
-+++ b/posix/Makefile
-@@ -107,7 +107,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \
- tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
- 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-wordexp-nocmd tst-execveat tst-spawn5 \
-+ tst-sched_getaffinity
-
- # Test for the glob symbol version that was replaced in glibc 2.27.
- ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes)
-diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
-index f0831386c7..622adeb2b2 100644
---- a/posix/bits/unistd.h
-+++ b/posix/bits/unistd.h
-@@ -199,10 +199,9 @@ __NTH (readlinkat (int __fd, const char *__restrict __path,
- #endif
-
- extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen)
-- __THROW __wur __attr_access ((__write_only__, 1, 2));
-+ __THROW __wur;
- extern char *__REDIRECT_NTH (__getcwd_alias,
-- (char *__buf, size_t __size), getcwd)
-- __wur __attr_access ((__write_only__, 1, 2));
-+ (char *__buf, size_t __size), getcwd) __wur;
- extern char *__REDIRECT_NTH (__getcwd_chk_warn,
- (char *__buf, size_t __size, size_t __buflen),
- __getcwd_chk)
-diff --git a/posix/fork.c b/posix/fork.c
-index c471f7b15f..021691b9b7 100644
---- a/posix/fork.c
-+++ b/posix/fork.c
-@@ -99,6 +99,9 @@ __libc_fork (void)
- /* Reset the lock the dynamic loader uses to protect its data. */
- __rtld_lock_initialize (GL(dl_load_lock));
-
-+ /* Reset the lock protecting dynamic TLS related data. */
-+ __rtld_lock_initialize (GL(dl_load_tls_lock));
-+
- reclaim_stacks ();
-
- /* Run the handlers registered for the child. */
-diff --git a/posix/tst-sched_getaffinity.c b/posix/tst-sched_getaffinity.c
-new file mode 100644
-index 0000000000..db9d517a96
---- /dev/null
-+++ b/posix/tst-sched_getaffinity.c
-@@ -0,0 +1,48 @@
-+/* Tests for sched_getaffinity with large buffers.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <array_length.h>
-+#include <sched.h>
-+#include <support/check.h>
-+
-+/* NB: this test may fail on system with more than 32k cpus. */
-+
-+static int
-+do_test (void)
-+{
-+ /* The values are larger than the default cpu_set_t. */
-+ const int bufsize[] = { 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, 1<<16, 1<<17 };
-+ int cpucount[array_length (bufsize)];
-+
-+ for (int i = 0; i < array_length (bufsize); i++)
-+ {
-+ cpu_set_t *cpuset = CPU_ALLOC (bufsize[i]);
-+ TEST_VERIFY (cpuset != NULL);
-+ size_t size = CPU_ALLOC_SIZE (bufsize[i]);
-+ TEST_COMPARE (sched_getaffinity (0, size, cpuset), 0);
-+ cpucount[i] = CPU_COUNT_S (size, cpuset);
-+ CPU_FREE (cpuset);
-+ }
-+
-+ for (int i = 0; i < array_length (cpucount) - 1; i++)
-+ TEST_COMPARE (cpucount[i], cpucount[i + 1]);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/posix/tst-spawn5.c b/posix/tst-spawn5.c
-index ac66738004..a95199af6b 100644
---- a/posix/tst-spawn5.c
-+++ b/posix/tst-spawn5.c
-@@ -47,17 +47,6 @@ static int initial_argv_count;
-
- #define NFDS 100
-
--static int
--open_multiple_temp_files (void)
--{
-- /* Check if the temporary file descriptor has no no gaps. */
-- int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
-- for (int i = 1; i <= NFDS; i++)
-- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600),
-- lowfd + i);
-- return lowfd;
--}
--
- static int
- parse_fd (const char *str)
- {
-@@ -185,7 +174,7 @@ spawn_closefrom_test (posix_spawn_file_actions_t *fa, int lowfd, int highfd,
- static void
- do_test_closefrom (void)
- {
-- int lowfd = open_multiple_temp_files ();
-+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
- const int half_fd = lowfd + NFDS / 2;
-
- /* Close half of the descriptors and check result. */
-diff --git a/posix/unistd.h b/posix/unistd.h
-index 3dca65732f..8224c5fbc9 100644
---- a/posix/unistd.h
-+++ b/posix/unistd.h
-@@ -528,8 +528,7 @@ extern int fchdir (int __fd) __THROW __wur;
- an array is allocated with `malloc'; the array is SIZE
- bytes long, unless SIZE == 0, in which case it is as
- big as necessary. */
--extern char *getcwd (char *__buf, size_t __size) __THROW __wur
-- __attr_access ((__write_only__, 1, 2));
-+extern char *getcwd (char *__buf, size_t __size) __THROW __wur;
-
- #ifdef __USE_GNU
- /* Return a malloc'd string containing the current directory name.
-diff --git a/rt/Makefile b/rt/Makefile
-index 113cea03a5..910e775995 100644
---- a/rt/Makefile
-+++ b/rt/Makefile
-@@ -74,6 +74,7 @@ tests := tst-shm tst-timer tst-timer2 \
- tst-aio7 tst-aio8 tst-aio9 tst-aio10 \
- tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \
- tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \
-+ tst-bz28213 \
- tst-timer3 tst-timer4 tst-timer5 \
- tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
- tst-shm-cancel \
-diff --git a/rt/tst-bz28213.c b/rt/tst-bz28213.c
-new file mode 100644
-index 0000000000..0c096b5a0a
---- /dev/null
-+++ b/rt/tst-bz28213.c
-@@ -0,0 +1,101 @@
-+/* Bug 28213: test for NULL pointer dereference in mq_notify.
-+ Copyright (C) The GNU Toolchain Authors.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <errno.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <mqueue.h>
-+#include <signal.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <support/check.h>
-+
-+static mqd_t m = -1;
-+static const char msg[] = "hello";
-+
-+static void
-+check_bz28213_cb (union sigval sv)
-+{
-+ char buf[sizeof (msg)];
-+
-+ (void) sv;
-+
-+ TEST_VERIFY_EXIT ((size_t) mq_receive (m, buf, sizeof (buf), NULL)
-+ == sizeof (buf));
-+ TEST_VERIFY_EXIT (memcmp (buf, msg, sizeof (buf)) == 0);
-+
-+ exit (0);
-+}
-+
-+static void
-+check_bz28213 (void)
-+{
-+ struct sigevent sev;
-+
-+ memset (&sev, '\0', sizeof (sev));
-+ sev.sigev_notify = SIGEV_THREAD;
-+ sev.sigev_notify_function = check_bz28213_cb;
-+
-+ /* Step 1: Register & unregister notifier.
-+ Helper thread should receive NOTIFY_REMOVED notification.
-+ In a vulnerable version of glibc, NULL pointer dereference follows. */
-+ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0);
-+ TEST_VERIFY_EXIT (mq_notify (m, NULL) == 0);
-+
-+ /* Step 2: Once again, register notification.
-+ Try to send one message.
-+ Test is considered successful, if the callback does exit (0). */
-+ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0);
-+ TEST_VERIFY_EXIT (mq_send (m, msg, sizeof (msg), 1) == 0);
-+
-+ /* Wait... */
-+ pause ();
-+}
-+
-+static int
-+do_test (void)
-+{
-+ static const char m_name[] = "/bz28213_queue";
-+ struct mq_attr m_attr;
-+
-+ memset (&m_attr, '\0', sizeof (m_attr));
-+ m_attr.mq_maxmsg = 1;
-+ m_attr.mq_msgsize = sizeof (msg);
-+
-+ m = mq_open (m_name,
-+ O_RDWR | O_CREAT | O_EXCL,
-+ 0600,
-+ &m_attr);
-+
-+ if (m < 0)
-+ {
-+ if (errno == ENOSYS)
-+ FAIL_UNSUPPORTED ("POSIX message queues are not implemented\n");
-+ FAIL_EXIT1 ("Failed to create POSIX message queue: %m\n");
-+ }
-+
-+ TEST_VERIFY_EXIT (mq_unlink (m_name) == 0);
-+
-+ check_bz28213 ();
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
-index 5a77af90a6..86537fa800 100755
---- a/scripts/build-many-glibcs.py
-+++ b/scripts/build-many-glibcs.py
-@@ -782,7 +782,7 @@ class Context(object):
- 'gcc': 'vcs-11',
- 'glibc': 'vcs-mainline',
- 'gmp': '6.2.1',
-- 'linux': '5.13',
-+ 'linux': '5.14',
- 'mpc': '1.2.1',
- 'mpfr': '4.1.0',
- 'mig': 'vcs-mainline',
-diff --git a/support/Makefile b/support/Makefile
-index a462781718..2a0731796f 100644
---- a/support/Makefile
-+++ b/support/Makefile
-@@ -66,6 +66,7 @@ libsupport-routines = \
- support_path_support_time64 \
- support_process_state \
- support_ptrace \
-+ support-open-dev-null-range \
- support_openpty \
- support_paths \
- support_quote_blob \
-@@ -82,9 +83,10 @@ libsupport-routines = \
- support_test_compare_blob \
- support_test_compare_failure \
- support_test_compare_string \
-- support_write_file_string \
- support_test_main \
- support_test_verify_impl \
-+ support_wait_for_thread_exit \
-+ support_write_file_string \
- temp_file \
- timespec \
- timespec-time64 \
-@@ -264,6 +266,7 @@ tests = \
- tst-support_capture_subprocess \
- tst-support_descriptors \
- tst-support_format_dns_packet \
-+ tst-support-open-dev-null-range \
- tst-support-process_state \
- tst-support_quote_blob \
- tst-support_quote_string \
-diff --git a/support/support-open-dev-null-range.c b/support/support-open-dev-null-range.c
-new file mode 100644
-index 0000000000..66a8504105
---- /dev/null
-+++ b/support/support-open-dev-null-range.c
-@@ -0,0 +1,134 @@
-+/* Return a range of open file descriptors.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <support/support.h>
-+#include <support/check.h>
-+#include <support/xunistd.h>
-+#include <stdlib.h>
-+#include <sys/resource.h>
-+
-+static void
-+increase_nofile (void)
-+{
-+ struct rlimit rl;
-+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1)
-+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m");
-+
-+ rl.rlim_cur += 128;
-+
-+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1)
-+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m");
-+}
-+
-+static int
-+open_dev_null (int flags, mode_t mode)
-+{
-+ int fd = open64 ("/dev/null", flags, mode);
-+ if (fd >= 0)
-+ return fd;
-+
-+ if (fd < 0 && errno != EMFILE)
-+ FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode);
-+
-+ increase_nofile ();
-+
-+ return xopen ("/dev/null", flags, mode);
-+}
-+
-+struct range
-+{
-+ int lowfd;
-+ size_t len;
-+};
-+
-+struct range_list
-+{
-+ size_t total;
-+ size_t used;
-+ struct range *ranges;
-+};
-+
-+static void
-+range_init (struct range_list *r)
-+{
-+ r->total = 8;
-+ r->used = 0;
-+ r->ranges = xmalloc (r->total * sizeof (struct range));
-+}
-+
-+static void
-+range_add (struct range_list *r, int lowfd, size_t len)
-+{
-+ if (r->used == r->total)
-+ {
-+ r->total *= 2;
-+ r->ranges = xrealloc (r->ranges, r->total * sizeof (struct range));
-+ }
-+ r->ranges[r->used].lowfd = lowfd;
-+ r->ranges[r->used].len = len;
-+ r->used++;
-+}
-+
-+static void
-+range_close (struct range_list *r)
-+{
-+ for (size_t i = 0; i < r->used; i++)
-+ {
-+ int minfd = r->ranges[i].lowfd;
-+ int maxfd = r->ranges[i].lowfd + r->ranges[i].len;
-+ for (int fd = minfd; fd < maxfd; fd++)
-+ xclose (fd);
-+ }
-+ free (r->ranges);
-+}
-+
-+int
-+support_open_dev_null_range (int num, int flags, mode_t mode)
-+{
-+ /* We keep track of the ranges that hit an already opened descriptor, so
-+ we close them after we get a working range. */
-+ struct range_list rl;
-+ range_init (&rl);
-+
-+ int lowfd = open_dev_null (flags, mode);
-+ int prevfd = lowfd;
-+ while (true)
-+ {
-+ int i = 1;
-+ for (; i < num; i++)
-+ {
-+ int fd = open_dev_null (flags, mode);
-+ if (fd != lowfd + i)
-+ {
-+ range_add (&rl, lowfd, prevfd - lowfd + 1);
-+
-+ prevfd = lowfd = fd;
-+ break;
-+ }
-+ prevfd = fd;
-+ }
-+ if (i == num)
-+ break;
-+ }
-+
-+ range_close (&rl);
-+
-+ return lowfd;
-+}
-diff --git a/support/support.h b/support/support.h
-index 834dba9097..c219e0d9d1 100644
---- a/support/support.h
-+++ b/support/support.h
-@@ -174,6 +174,10 @@ timer_t support_create_timer (uint64_t sec, long int nsec, bool repeat,
- /* Disable the timer TIMER. */
- void support_delete_timer (timer_t timer);
-
-+/* Wait until all threads except the current thread have exited (as
-+ far as the kernel is concerned). */
-+void support_wait_for_thread_exit (void);
-+
- struct support_stack
- {
- void *stack;
-@@ -193,6 +197,14 @@ struct support_stack support_stack_alloc (size_t size);
- /* Deallocate the STACK. */
- void support_stack_free (struct support_stack *stack);
-
-+
-+/* Create a range of NUM opened '/dev/null' file descriptors using FLAGS and
-+ MODE. The function takes care of restarting the open range if a file
-+ descriptor is found within the specified range and also increases
-+ RLIMIT_NOFILE if required.
-+ The returned value is the lowest file descriptor number. */
-+int support_open_dev_null_range (int num, int flags, mode_t mode);
-+
- __END_DECLS
-
- #endif /* SUPPORT_H */
-diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
-index 27bfd19c93..0bacf6dbc2 100644
---- a/support/support_capture_subprocess.c
-+++ b/support/support_capture_subprocess.c
-@@ -170,6 +170,7 @@ copy_and_spawn_sgid (char *child_id, gid_t gid)
- support_subprogram because we only want the program exit status, not the
- contents. */
- ret = 0;
-+ infd = outfd = -1;
-
- char * const args[] = {execname, child_id, NULL};
-
-diff --git a/support/support_wait_for_thread_exit.c b/support/support_wait_for_thread_exit.c
-new file mode 100644
-index 0000000000..5e3be421a7
---- /dev/null
-+++ b/support/support_wait_for_thread_exit.c
-@@ -0,0 +1,75 @@
-+/* Wait until all threads except the current thread has exited.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <dirent.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <support/check.h>
-+#include <support/support.h>
-+#include <unistd.h>
-+
-+void
-+support_wait_for_thread_exit (void)
-+{
-+#ifdef __linux__
-+ DIR *proc_self_task = opendir ("/proc/self/task");
-+ TEST_VERIFY_EXIT (proc_self_task != NULL);
-+
-+ while (true)
-+ {
-+ errno = 0;
-+ struct dirent *e = readdir (proc_self_task);
-+ if (e == NULL && errno != 0)
-+ FAIL_EXIT1 ("readdir: %m");
-+ if (e == NULL)
-+ {
-+ /* Only the main thread remains. Testing may continue. */
-+ closedir (proc_self_task);
-+ return;
-+ }
-+
-+ /* In some kernels, "0" entries denote a thread that has just
-+ exited. */
-+ if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0
-+ || strcmp (e->d_name, "0") == 0)
-+ continue;
-+
-+ int task_tid = atoi (e->d_name);
-+ if (task_tid <= 0)
-+ FAIL_EXIT1 ("Invalid /proc/self/task entry: %s", e->d_name);
-+
-+ if (task_tid == gettid ())
-+ /* The current thread. Keep scanning for other
-+ threads. */
-+ continue;
-+
-+ /* task_tid does not refer to this thread here, i.e., there is
-+ another running thread. */
-+
-+ /* Small timeout to give the thread a chance to exit. */
-+ usleep (50 * 1000);
-+
-+ /* Start scanning the directory from the start. */
-+ rewinddir (proc_self_task);
-+ }
-+#else
-+ /* Use a large timeout because we cannot verify that the thread has
-+ exited. */
-+ usleep (5 * 1000 * 1000);
-+#endif
-+}
-diff --git a/support/tst-support-open-dev-null-range.c b/support/tst-support-open-dev-null-range.c
-new file mode 100644
-index 0000000000..8e29def1ce
---- /dev/null
-+++ b/support/tst-support-open-dev-null-range.c
-@@ -0,0 +1,155 @@
-+/* Tests for support_open_dev_null_range.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <errno.h>
-+#include <dirent.h>
-+#include <fcntl.h>
-+#include <limits.h>
-+#include <support/check.h>
-+#include <support/support.h>
-+#include <support/xunistd.h>
-+#include <sys/resource.h>
-+#include <stdlib.h>
-+
-+#ifndef PATH_MAX
-+# define PATH_MAX 1024
-+#endif
-+
-+#include <stdio.h>
-+
-+static void
-+check_path (int fd)
-+{
-+ char *proc_fd_path = xasprintf ("/proc/self/fd/%d", fd);
-+ char file_path[PATH_MAX];
-+ ssize_t file_path_length
-+ = readlink (proc_fd_path, file_path, sizeof (file_path));
-+ free (proc_fd_path);
-+ if (file_path_length < 0)
-+ FAIL_EXIT1 ("readlink (%s, %p, %zu)", proc_fd_path, file_path,
-+ sizeof (file_path));
-+ file_path[file_path_length] = '\0';
-+ TEST_COMPARE_STRING (file_path, "/dev/null");
-+}
-+
-+static int
-+number_of_opened_files (void)
-+{
-+ DIR *fds = opendir ("/proc/self/fd");
-+ if (fds == NULL)
-+ FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m");
-+
-+ int r = 0;
-+ while (true)
-+ {
-+ errno = 0;
-+ struct dirent64 *e = readdir64 (fds);
-+ if (e == NULL)
-+ {
-+ if (errno != 0)
-+ FAIL_EXIT1 ("readdir: %m");
-+ break;
-+ }
-+
-+ if (e->d_name[0] == '.')
-+ continue;
-+
-+ char *endptr;
-+ long int fd = strtol (e->d_name, &endptr, 10);
-+ if (*endptr != '\0' || fd < 0 || fd > INT_MAX)
-+ FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s",
-+ e->d_name);
-+
-+ /* Skip the descriptor which is used to enumerate the
-+ descriptors. */
-+ if (fd == dirfd (fds))
-+ continue;
-+
-+ r = r + 1;
-+ }
-+
-+ closedir (fds);
-+
-+ return r;
-+}
-+
-+static int
-+do_test (void)
-+{
-+ const int nfds1 = 8;
-+ int lowfd = support_open_dev_null_range (nfds1, O_RDONLY, 0600);
-+ for (int i = 0; i < nfds1; i++)
-+ {
-+ TEST_VERIFY (fcntl (lowfd + i, F_GETFL) > -1);
-+ check_path (lowfd + i);
-+ }
-+
-+ /* create some gaps. */
-+ xclose (lowfd + 1);
-+ xclose (lowfd + 5);
-+ xclose (lowfd + 6);
-+
-+ const int nfds2 = 16;
-+ int lowfd2 = support_open_dev_null_range (nfds2, O_RDONLY, 0600);
-+ for (int i = 0; i < nfds2; i++)
-+ {
-+ TEST_VERIFY (fcntl (lowfd2 + i, F_GETFL) > -1);
-+ check_path (lowfd2 + i);
-+ }
-+
-+ /* Decrease the maximum number of files. */
-+ {
-+ struct rlimit rl;
-+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1)
-+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m");
-+
-+ rl.rlim_cur = number_of_opened_files ();
-+
-+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1)
-+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m");
-+ }
-+
-+ const int nfds3 = 16;
-+ int lowfd3 = support_open_dev_null_range (nfds3, O_RDONLY, 0600);
-+ for (int i = 0; i < nfds3; i++)
-+ {
-+ TEST_VERIFY (fcntl (lowfd3 + i, F_GETFL) > -1);
-+ check_path (lowfd3 + i);
-+ }
-+
-+ /* create a lot of gaps to trigger the range extension. */
-+ xclose (lowfd3 + 1);
-+ xclose (lowfd3 + 3);
-+ xclose (lowfd3 + 5);
-+ xclose (lowfd3 + 7);
-+ xclose (lowfd3 + 9);
-+ xclose (lowfd3 + 11);
-+ xclose (lowfd3 + 13);
-+
-+ const int nfds4 = 16;
-+ int lowfd4 = support_open_dev_null_range (nfds4, O_RDONLY, 0600);
-+ for (int i = 0; i < nfds4; i++)
-+ {
-+ TEST_VERIFY (fcntl (lowfd4 + i, F_GETFL) > -1);
-+ check_path (lowfd4 + i);
-+ }
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/generic/dl-relocate-ld.h b/sysdeps/generic/dl-relocate-ld.h
-new file mode 100644
-index 0000000000..cfb86c2d6a
---- /dev/null
-+++ b/sysdeps/generic/dl-relocate-ld.h
-@@ -0,0 +1,25 @@
-+/* Check if dynamic section should be relocated. Generic version.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#ifndef _DL_RELOCATE_LD_H
-+#define _DL_RELOCATE_LD_H
-+
-+/* The dynamic section is writable. */
-+#define DL_RO_DYN_SECTION 0
-+
-+#endif /* _DL_RELOCATE_LD_H */
-diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
-index 9c15259236..fcbbf69748 100644
---- a/sysdeps/generic/ldsodefs.h
-+++ b/sysdeps/generic/ldsodefs.h
-@@ -69,17 +69,24 @@ __BEGIN_DECLS
- `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
- #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type)
-
-+/* Return true if dynamic section in the shared library L should be
-+ relocated. */
-+
-+static inline bool
-+dl_relocate_ld (const struct link_map *l)
-+{
-+ /* Don't relocate dynamic section if it is readonly */
-+ return !(l->l_ld_readonly || DL_RO_DYN_SECTION);
-+}
-+
- /* All references to the value of l_info[DT_PLTGOT],
- l_info[DT_STRTAB], l_info[DT_SYMTAB], l_info[DT_RELA],
- l_info[DT_REL], l_info[DT_JMPREL], and l_info[VERSYMIDX (DT_VERSYM)]
- have to be accessed via the D_PTR macro. The macro is needed since for
- most architectures the entry is already relocated - but for some not
- and we need to relocate at access time. */
--#ifdef DL_RO_DYN_SECTION
--# define D_PTR(map, i) ((map)->i->d_un.d_ptr + (map)->l_addr)
--#else
--# define D_PTR(map, i) (map)->i->d_un.d_ptr
--#endif
-+#define D_PTR(map, i) \
-+ ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_addr))
-
- /* Result of the lookup functions and how to retrieve the base address. */
- typedef struct link_map *lookup_t;
-@@ -372,6 +379,13 @@ struct rtld_global
- list of loaded objects while an object is added to or removed
- from that list. */
- __rtld_lock_define_recursive (EXTERN, _dl_load_write_lock)
-+ /* This lock protects global and module specific TLS related data.
-+ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
-+ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
-+ accessed and when TLS related relocations are processed for a
-+ module. It was introduced to keep pthread_create accessing TLS
-+ state that is being set up. */
-+ __rtld_lock_define_recursive (EXTERN, _dl_load_tls_lock)
-
- /* Incremented whenever something may have been added to dl_loaded. */
- EXTERN unsigned long long _dl_load_adds;
-@@ -1261,7 +1275,7 @@ extern int _dl_scope_free (void *) attribute_hidden;
-
- /* Add module to slot information data. If DO_ADD is false, only the
- required memory is allocated. Must be called with GL
-- (dl_load_lock) acquired. If the function has already been called
-+ (dl_load_tls_lock) acquired. If the function has already been called
- for the link map L with !do_add, then this function will not raise
- an exception, otherwise it is possible that it encounters a memory
- allocation failure. */
-diff --git a/sysdeps/mach/getsysstats.c b/sysdeps/mach/getsysstats.c
-index 1267f39da2..cc8023f979 100644
---- a/sysdeps/mach/getsysstats.c
-+++ b/sysdeps/mach/getsysstats.c
-@@ -62,6 +62,12 @@ __get_nprocs (void)
- libc_hidden_def (__get_nprocs)
- weak_alias (__get_nprocs, get_nprocs)
-
-+int
-+__get_nprocs_sched (void)
-+{
-+ return __get_nprocs ();
-+}
-+
- /* Return the number of physical pages on the system. */
- long int
- __get_phys_pages (void)
-diff --git a/sysdeps/mips/dl-relocate-ld.h b/sysdeps/mips/dl-relocate-ld.h
-new file mode 100644
-index 0000000000..376ad75dd1
---- /dev/null
-+++ b/sysdeps/mips/dl-relocate-ld.h
-@@ -0,0 +1,25 @@
-+/* Check if dynamic section should be relocated. MIPS version.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#ifndef _DL_RELOCATE_LD_H
-+#define _DL_RELOCATE_LD_H
-+
-+/* The dynamic section is readonly. */
-+#define DL_RO_DYN_SECTION 1
-+
-+#endif /* _DL_RELOCATE_LD_H */
-diff --git a/sysdeps/mips/ldsodefs.h b/sysdeps/mips/ldsodefs.h
-index 4db7c60e38..36fd09a8bd 100644
---- a/sysdeps/mips/ldsodefs.h
-+++ b/sysdeps/mips/ldsodefs.h
-@@ -75,10 +75,6 @@ struct La_mips_64_retval;
- struct La_mips_64_retval *, \
- const char *);
-
--/* The MIPS ABI specifies that the dynamic section has to be read-only. */
--
--#define DL_RO_DYN_SECTION 1
--
- #include_next <ldsodefs.h>
-
- /* The 64-bit MIPS ELF ABI uses an unusual reloc format. Each
-diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
-index f1b7f2bdc6..43146e91c9 100644
---- a/sysdeps/nptl/pthread.h
-+++ b/sysdeps/nptl/pthread.h
-@@ -933,7 +933,7 @@ extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr,
- # ifdef __USE_GNU
- # ifdef __REDIRECT_NTH
- extern int __REDIRECT_NTH (pthread_mutexattr_getrobust_np,
-- (pthread_mutex_t *, int *),
-+ (pthread_mutexattr_t *, int *),
- pthread_mutexattr_getrobust) __nonnull ((1))
- __attribute_deprecated_msg__ ("\
- pthread_mutexattr_getrobust_np is deprecated, use pthread_mutexattr_getrobust");
-@@ -949,7 +949,7 @@ extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
- # ifdef __USE_GNU
- # ifdef __REDIRECT_NTH
- extern int __REDIRECT_NTH (pthread_mutexattr_setrobust_np,
-- (pthread_mutex_t *, int),
-+ (pthread_mutexattr_t *, int),
- pthread_mutexattr_setrobust) __nonnull ((1))
- __attribute_deprecated_msg__ ("\
- pthread_mutexattr_setrobust_np is deprecated, use pthread_mutexattr_setrobust");
-diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
-index 838a68f022..43dfc6739e 100644
---- a/sysdeps/posix/getaddrinfo.c
-+++ b/sysdeps/posix/getaddrinfo.c
-@@ -2008,6 +2008,7 @@ gaiconf_init (void)
- l = l->next;
- }
- free_prefixlist (labellist);
-+ labellist = NULL;
-
- /* Sort the entries so that the most specific ones are at
- the beginning. */
-@@ -2046,6 +2047,7 @@ gaiconf_init (void)
- l = l->next;
- }
- free_prefixlist (precedencelist);
-+ precedencelist = NULL;
-
- /* Sort the entries so that the most specific ones are at
- the beginning. */
-diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
-index 589f7c8d18..cfcfa69f91 100644
---- a/sysdeps/powerpc/powerpc64/sysdep.h
-+++ b/sysdeps/powerpc/powerpc64/sysdep.h
-@@ -275,12 +275,14 @@ LT_LABELSUFFIX(name,_name_end): ; \
- /* Allocate frame and save register */
- #define NVOLREG_SAVE \
- stdu r1,-SCV_FRAME_SIZE(r1); \
-+ cfi_adjust_cfa_offset(SCV_FRAME_SIZE); \
- std r31,SCV_FRAME_NVOLREG_SAVE(r1); \
-- cfi_adjust_cfa_offset(SCV_FRAME_SIZE);
-+ cfi_rel_offset(r31,SCV_FRAME_NVOLREG_SAVE);
-
- /* Restore register and destroy frame */
- #define NVOLREG_RESTORE \
- ld r31,SCV_FRAME_NVOLREG_SAVE(r1); \
-+ cfi_restore(r31); \
- addi r1,r1,SCV_FRAME_SIZE; \
- cfi_adjust_cfa_offset(-SCV_FRAME_SIZE);
-
-@@ -331,13 +333,13 @@ LT_LABELSUFFIX(name,_name_end): ; \
-
- #define DO_CALL_SCV \
- mflr r9; \
-- std r9,FRAME_LR_SAVE(r1); \
-- cfi_offset(lr,FRAME_LR_SAVE); \
-+ std r9,SCV_FRAME_SIZE+FRAME_LR_SAVE(r1); \
-+ cfi_rel_offset(lr,SCV_FRAME_SIZE+FRAME_LR_SAVE); \
- .machine "push"; \
- .machine "power9"; \
- scv 0; \
- .machine "pop"; \
-- ld r9,FRAME_LR_SAVE(r1); \
-+ ld r9,SCV_FRAME_SIZE+FRAME_LR_SAVE(r1); \
- mtlr r9; \
- cfi_restore(lr);
-
-diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
-index 42f9fc5072..c657101696 100644
---- a/sysdeps/pthread/Makefile
-+++ b/sysdeps/pthread/Makefile
-@@ -89,7 +89,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
- tst-join8 tst-join9 tst-join10 tst-join11 tst-join12 tst-join13 \
- tst-join14 tst-join15 \
- tst-key1 tst-key2 tst-key3 tst-key4 \
-- tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
-+ tst-kill1 tst-kill2 tst-kill3 tst-kill5 tst-kill6 \
- tst-locale1 tst-locale2 \
- tst-memstream \
- tst-mutex-errorcheck tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 \
-@@ -118,6 +118,14 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
- tst-unload \
- tst-unwind-thread \
- tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \
-+ tst-pthread-exit-signal \
-+ tst-pthread-setuid-loop \
-+ tst-pthread_cancel-exited \
-+ tst-pthread_cancel-select-loop \
-+ tst-pthread-raise-blocked-self \
-+ tst-pthread_kill-exited \
-+ tst-pthread_kill-exiting \
-+ # tests
-
- tests-time64 := \
- tst-abstime-time64 \
-@@ -145,15 +153,17 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx6 tst-cancelx8 tst-cancelx9 \
- tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3
-
- ifeq ($(build-shared),yes)
--tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1
-+tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1 tst-create1
- tests-nolibpthread += tst-fini1
- endif
-
- modules-names += tst-atfork2mod tst-tls4moda tst-tls4modb \
-- tst-_res1mod1 tst-_res1mod2 tst-fini1mod
-+ tst-_res1mod1 tst-_res1mod2 tst-fini1mod \
-+ tst-create1mod
- test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
-
- tst-atfork2mod.so-no-z-defs = yes
-+tst-create1mod.so-no-z-defs = yes
-
- ifeq ($(build-shared),yes)
- # Build all the modules even when not actually running test programs.
-@@ -272,4 +282,8 @@ LDFLAGS-tst-join7mod.so = -Wl,-soname,tst-join7mod.so
-
- CFLAGS-tst-unwind-thread.c += -funwind-tables
-
-+LDFLAGS-tst-create1 = -Wl,-export-dynamic
-+$(objpfx)tst-create1: $(shared-thread-library)
-+$(objpfx)tst-create1.out: $(objpfx)tst-create1mod.so
-+
- endif
-diff --git a/sysdeps/pthread/tst-create1.c b/sysdeps/pthread/tst-create1.c
-new file mode 100644
-index 0000000000..763ded8d79
---- /dev/null
-+++ b/sysdeps/pthread/tst-create1.c
-@@ -0,0 +1,123 @@
-+/* Verify that pthread_create does not deadlock when ctors take locks.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <stdio.h>
-+#include <support/xdlfcn.h>
-+#include <support/xthread.h>
-+
-+/*
-+Check if ctor and pthread_create deadlocks in
-+
-+thread 1: dlopen -> ctor -> lock(user_lock)
-+thread 2: lock(user_lock) -> pthread_create
-+
-+or in
-+
-+thread 1: dlclose -> dtor -> lock(user_lock)
-+thread 2: lock(user_lock) -> pthread_create
-+*/
-+
-+static pthread_barrier_t bar_ctor;
-+static pthread_barrier_t bar_ctor_finish;
-+static pthread_barrier_t bar_dtor;
-+static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER;
-+
-+void
-+ctor (void)
-+{
-+ xpthread_barrier_wait (&bar_ctor);
-+ dprintf (1, "thread 1: in ctor: started.\n");
-+ xpthread_mutex_lock (&user_lock);
-+ dprintf (1, "thread 1: in ctor: locked user_lock.\n");
-+ xpthread_mutex_unlock (&user_lock);
-+ dprintf (1, "thread 1: in ctor: unlocked user_lock.\n");
-+ dprintf (1, "thread 1: in ctor: done.\n");
-+ xpthread_barrier_wait (&bar_ctor_finish);
-+}
-+
-+void
-+dtor (void)
-+{
-+ xpthread_barrier_wait (&bar_dtor);
-+ dprintf (1, "thread 1: in dtor: started.\n");
-+ xpthread_mutex_lock (&user_lock);
-+ dprintf (1, "thread 1: in dtor: locked user_lock.\n");
-+ xpthread_mutex_unlock (&user_lock);
-+ dprintf (1, "thread 1: in dtor: unlocked user_lock.\n");
-+ dprintf (1, "thread 1: in dtor: done.\n");
-+}
-+
-+static void *
-+thread3 (void *a)
-+{
-+ dprintf (1, "thread 3: started.\n");
-+ dprintf (1, "thread 3: done.\n");
-+ return 0;
-+}
-+
-+static void *
-+thread2 (void *a)
-+{
-+ pthread_t t3;
-+ dprintf (1, "thread 2: started.\n");
-+
-+ xpthread_mutex_lock (&user_lock);
-+ dprintf (1, "thread 2: locked user_lock.\n");
-+ xpthread_barrier_wait (&bar_ctor);
-+ t3 = xpthread_create (0, thread3, 0);
-+ xpthread_mutex_unlock (&user_lock);
-+ dprintf (1, "thread 2: unlocked user_lock.\n");
-+ xpthread_join (t3);
-+ xpthread_barrier_wait (&bar_ctor_finish);
-+
-+ xpthread_mutex_lock (&user_lock);
-+ dprintf (1, "thread 2: locked user_lock.\n");
-+ xpthread_barrier_wait (&bar_dtor);
-+ t3 = xpthread_create (0, thread3, 0);
-+ xpthread_mutex_unlock (&user_lock);
-+ dprintf (1, "thread 2: unlocked user_lock.\n");
-+ xpthread_join (t3);
-+
-+ dprintf (1, "thread 2: done.\n");
-+ return 0;
-+}
-+
-+static void
-+thread1 (void)
-+{
-+ dprintf (1, "thread 1: started.\n");
-+ xpthread_barrier_init (&bar_ctor, NULL, 2);
-+ xpthread_barrier_init (&bar_ctor_finish, NULL, 2);
-+ xpthread_barrier_init (&bar_dtor, NULL, 2);
-+ pthread_t t2 = xpthread_create (0, thread2, 0);
-+ void *p = xdlopen ("tst-create1mod.so", RTLD_NOW | RTLD_GLOBAL);
-+ dprintf (1, "thread 1: dlopen done.\n");
-+ xdlclose (p);
-+ dprintf (1, "thread 1: dlclose done.\n");
-+ xpthread_join (t2);
-+ dprintf (1, "thread 1: done.\n");
-+}
-+
-+static int
-+do_test (void)
-+{
-+ thread1 ();
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/pthread/tst-create1mod.c b/sysdeps/pthread/tst-create1mod.c
-new file mode 100644
-index 0000000000..62c9006961
---- /dev/null
-+++ b/sysdeps/pthread/tst-create1mod.c
-@@ -0,0 +1,41 @@
-+/* Verify that pthread_create does not deadlock when ctors take locks.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <stdio.h>
-+
-+/* Require TLS setup for the module. */
-+__thread int tlsvar;
-+
-+void ctor (void);
-+void dtor (void);
-+
-+static void __attribute__ ((constructor))
-+do_init (void)
-+{
-+ dprintf (1, "constructor started: %d.\n", tlsvar++);
-+ ctor ();
-+ dprintf (1, "constructor done: %d.\n", tlsvar++);
-+}
-+
-+static void __attribute__ ((destructor))
-+do_end (void)
-+{
-+ dprintf (1, "destructor started: %d.\n", tlsvar++);
-+ dtor ();
-+ dprintf (1, "destructor done: %d.\n", tlsvar++);
-+}
-diff --git a/sysdeps/pthread/tst-kill4.c b/sysdeps/pthread/tst-kill4.c
-deleted file mode 100644
-index 9563939792..0000000000
---- a/sysdeps/pthread/tst-kill4.c
-+++ /dev/null
-@@ -1,90 +0,0 @@
--/* Copyright (C) 2003-2021 Free Software Foundation, Inc.
-- This file is part of the GNU C Library.
-- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
--
-- The GNU C Library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- The GNU C Library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with the GNU C Library; if not, see
-- <https://www.gnu.org/licenses/>. */
--
--#include <errno.h>
--#include <pthread.h>
--#include <signal.h>
--#include <stdio.h>
--#include <stdlib.h>
--#include <unistd.h>
--
--
--static void *
--tf (void *a)
--{
-- return NULL;
--}
--
--
--int
--do_test (void)
--{
-- pthread_attr_t at;
-- if (pthread_attr_init (&at) != 0)
-- {
-- puts ("attr_create failed");
-- exit (1);
-- }
--
-- /* Limit thread stack size, because if it is too large, pthread_join
-- will free it immediately rather than put it into stack cache. */
-- if (pthread_attr_setstacksize (&at, 2 * 1024 * 1024) != 0)
-- {
-- puts ("setstacksize failed");
-- exit (1);
-- }
--
-- pthread_t th;
-- if (pthread_create (&th, &at, tf, NULL) != 0)
-- {
-- puts ("create failed");
-- exit (1);
-- }
--
-- pthread_attr_destroy (&at);
--
-- if (pthread_join (th, NULL) != 0)
-- {
-- puts ("join failed");
-- exit (1);
-- }
--
-- /* The following only works because we assume here something about
-- the implementation. Namely, that the memory allocated for the
-- thread descriptor is not going away, that the TID field is
-- cleared and therefore the signal is sent to process 0, and that
-- we can savely assume there is no other process with this ID at
-- that time. */
-- int e = pthread_kill (th, 0);
-- if (e == 0)
-- {
-- puts ("pthread_kill succeeded");
-- exit (1);
-- }
-- if (e != ESRCH)
-- {
-- puts ("pthread_kill didn't return ESRCH");
-- exit (1);
-- }
--
-- return 0;
--}
--
--
--#define TEST_FUNCTION do_test ()
--#include "../test-skeleton.c"
-diff --git a/sysdeps/pthread/tst-pthread-exit-signal.c b/sysdeps/pthread/tst-pthread-exit-signal.c
-new file mode 100644
-index 0000000000..b4526fe663
---- /dev/null
-+++ b/sysdeps/pthread/tst-pthread-exit-signal.c
-@@ -0,0 +1,45 @@
-+/* Test that pending signals are not delivered on thread exit (bug 28607).
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+/* Due to bug 28607, pthread_kill (or pthread_cancel) restored the
-+ signal mask during during thread exit, triggering the delivery of a
-+ blocked pending signal (SIGUSR1 in this test). */
-+
-+#include <support/xthread.h>
-+#include <support/xsignal.h>
-+
-+static void *
-+threadfunc (void *closure)
-+{
-+ sigset_t sigmask;
-+ sigfillset (&sigmask);
-+ xpthread_sigmask (SIG_SETMASK, &sigmask, NULL);
-+ xpthread_kill (pthread_self (), SIGUSR1);
-+ pthread_exit (NULL);
-+ return NULL;
-+}
-+
-+static int
-+do_test (void)
-+{
-+ pthread_t thr = xpthread_create (NULL, threadfunc, NULL);
-+ xpthread_join (thr);
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/pthread/tst-pthread-raise-blocked-self.c b/sysdeps/pthread/tst-pthread-raise-blocked-self.c
-new file mode 100644
-index 0000000000..128e1a6071
---- /dev/null
-+++ b/sysdeps/pthread/tst-pthread-raise-blocked-self.c
-@@ -0,0 +1,92 @@
-+/* Test that raise sends signal to current thread even if blocked.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <signal.h>
-+#include <support/check.h>
-+#include <support/xsignal.h>
-+#include <support/xthread.h>
-+#include <pthread.h>
-+#include <unistd.h>
-+
-+/* Used to create a dummy thread ID distinct from all other thread
-+ IDs. */
-+static void *
-+noop (void *ignored)
-+{
-+ return NULL;
-+}
-+
-+static volatile pthread_t signal_thread;
-+
-+static void
-+signal_handler (int signo)
-+{
-+ signal_thread = pthread_self ();
-+}
-+
-+/* Used to ensure that waiting_thread has launched and can accept
-+ signals. */
-+static pthread_barrier_t barrier;
-+
-+static void *
-+waiting_thread (void *ignored)
-+{
-+ xpthread_barrier_wait (&barrier);
-+ pause ();
-+ return NULL;
-+}
-+
-+static int
-+do_test (void)
-+{
-+ xsignal (SIGUSR1, signal_handler);
-+ xpthread_barrier_init (&barrier, NULL, 2);
-+
-+ /* Distinct thread ID value to */
-+ pthread_t dummy = xpthread_create (NULL, noop, NULL);
-+ signal_thread = dummy;
-+
-+ pthread_t helper = xpthread_create (NULL, waiting_thread, NULL);
-+
-+ /* Make sure that the thread is running. */
-+ xpthread_barrier_wait (&barrier);
-+
-+ /* Block signals on this thread. */
-+ sigset_t set;
-+ sigfillset (&set);
-+ xpthread_sigmask (SIG_BLOCK, &set, NULL);
-+
-+ /* Send the signal to this thread. It must not be delivered. */
-+ raise (SIGUSR1);
-+ TEST_VERIFY (signal_thread == dummy);
-+
-+ /* Wait a bit to give a chance for signal delivery (increases
-+ chances of failure with bug 28407). */
-+ usleep (50 * 1000);
-+
-+ /* Unblocking should cause synchronous delivery of the signal. */
-+ xpthread_sigmask (SIG_UNBLOCK, &set, NULL);
-+ TEST_VERIFY (signal_thread == pthread_self ());
-+
-+ xpthread_cancel (helper);
-+ xpthread_join (helper);
-+ xpthread_join (dummy);
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/pthread/tst-pthread-setuid-loop.c b/sysdeps/pthread/tst-pthread-setuid-loop.c
-new file mode 100644
-index 0000000000..fda2a49b7f
---- /dev/null
-+++ b/sysdeps/pthread/tst-pthread-setuid-loop.c
-@@ -0,0 +1,61 @@
-+/* Test that setuid, pthread_create, thread exit do not deadlock (bug 28361).
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#include <support/check.h>
-+#include <support/xthread.h>
-+#include <unistd.h>
-+
-+/* How many threads to launch during each iteration. */
-+enum { threads = 4 };
-+
-+/* How many iterations to perform. This value seems to reproduce
-+ bug 28361 in a bout one in three runs. */
-+enum { iterations = 5000 };
-+
-+/* Cache of the real user ID used by setuid_thread. */
-+static uid_t uid;
-+
-+/* Start routine for the threads. */
-+static void *
-+setuid_thread (void *closure)
-+{
-+ TEST_COMPARE (setuid (uid), 0);
-+ return NULL;
-+}
-+
-+static int
-+do_test (void)
-+{
-+ /* The setxid machinery is still invoked even if the UID is
-+ unchanged. (The kernel might reset other credentials as part of
-+ the system call.) */
-+ uid = getuid ();
-+
-+ for (int i = 0; i < iterations; ++i)
-+ {
-+ pthread_t thread_ids[threads];
-+ for (int j = 0; j < threads; ++j)
-+ thread_ids[j] = xpthread_create (NULL, setuid_thread, NULL);
-+ for (int j = 0; j < threads; ++j)
-+ xpthread_join (thread_ids[j]);
-+ }
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/pthread/tst-pthread_cancel-exited.c b/sysdeps/pthread/tst-pthread_cancel-exited.c
-new file mode 100644
-index 0000000000..811c9bee07
---- /dev/null
-+++ b/sysdeps/pthread/tst-pthread_cancel-exited.c
-@@ -0,0 +1,45 @@
-+/* Test that pthread_kill succeeds for an exited thread.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+/* This test verifies that pthread_kill returns 0 (and not ESRCH) for
-+ a thread that has exited on the kernel side. */
-+
-+#include <stddef.h>
-+#include <support/support.h>
-+#include <support/xthread.h>
-+
-+static void *
-+noop_thread (void *closure)
-+{
-+ return NULL;
-+}
-+
-+static int
-+do_test (void)
-+{
-+ pthread_t thr = xpthread_create (NULL, noop_thread, NULL);
-+
-+ support_wait_for_thread_exit ();
-+
-+ xpthread_cancel (thr);
-+ xpthread_join (thr);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/pthread/tst-pthread_cancel-select-loop.c b/sysdeps/pthread/tst-pthread_cancel-select-loop.c
-new file mode 100644
-index 0000000000..a62087589c
---- /dev/null
-+++ b/sysdeps/pthread/tst-pthread_cancel-select-loop.c
-@@ -0,0 +1,87 @@
-+/* Test that pthread_cancel succeeds during thread exit.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+/* This test tries to trigger an internal race condition in
-+ pthread_cancel, where the cancellation signal is sent after the
-+ thread has begun the cancellation process. This can result in a
-+ spurious ESRCH error. For the original bug 12889, the window is
-+ quite small, so the bug was not reproduced in every run. */
-+
-+#include <stdbool.h>
-+#include <stddef.h>
-+#include <support/check.h>
-+#include <support/xthread.h>
-+#include <support/xunistd.h>
-+#include <sys/select.h>
-+#include <unistd.h>
-+
-+/* Set to true by timeout_thread_function when the test should
-+ terminate. */
-+static bool timeout;
-+
-+static void *
-+timeout_thread_function (void *unused)
-+{
-+ usleep (5 * 1000 * 1000);
-+ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED);
-+ return NULL;
-+}
-+
-+/* Used for blocking the select function below. */
-+static int pipe_fds[2];
-+
-+static void *
-+canceled_thread_function (void *unused)
-+{
-+ while (true)
-+ {
-+ fd_set rfs;
-+ fd_set wfs;
-+ fd_set efs;
-+ FD_ZERO (&rfs);
-+ FD_ZERO (&wfs);
-+ FD_ZERO (&efs);
-+ FD_SET (pipe_fds[0], &rfs);
-+
-+ /* If the cancellation request is recognized early, the thread
-+ begins exiting while the cancellation signal arrives. */
-+ select (FD_SETSIZE, &rfs, &wfs, &efs, NULL);
-+ }
-+ return NULL;
-+}
-+
-+static int
-+do_test (void)
-+{
-+ xpipe (pipe_fds);
-+ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL);
-+
-+ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED))
-+ {
-+ pthread_t thr = xpthread_create (NULL, canceled_thread_function, NULL);
-+ xpthread_cancel (thr);
-+ TEST_VERIFY (xpthread_join (thr) == PTHREAD_CANCELED);
-+ }
-+
-+ xpthread_join (thr_timeout);
-+ xclose (pipe_fds[0]);
-+ xclose (pipe_fds[1]);
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/pthread/tst-pthread_kill-exited.c b/sysdeps/pthread/tst-pthread_kill-exited.c
-new file mode 100644
-index 0000000000..a2fddad526
---- /dev/null
-+++ b/sysdeps/pthread/tst-pthread_kill-exited.c
-@@ -0,0 +1,63 @@
-+/* Test that pthread_kill succeeds for an exited thread.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+/* This test verifies that the default pthread_kill returns 0 (and not
-+ ESRCH) for a thread that has exited on the kernel side. */
-+
-+#include <errno.h>
-+#include <pthread.h>
-+#include <shlib-compat.h>
-+#include <signal.h>
-+#include <stddef.h>
-+#include <support/check.h>
-+#include <support/support.h>
-+#include <support/xthread.h>
-+
-+static void *
-+noop_thread (void *closure)
-+{
-+ return NULL;
-+}
-+
-+#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC
-+extern __typeof (pthread_kill) compat_pthread_kill;
-+compat_symbol_reference (libpthread, compat_pthread_kill, pthread_kill,
-+ GLIBC_2_0);
-+#endif
-+
-+static int
-+do_test (void)
-+{
-+ pthread_t thr = xpthread_create (NULL, noop_thread, NULL);
-+
-+ support_wait_for_thread_exit ();
-+
-+ /* NB: Always uses the default symbol due to separate compilation. */
-+ xpthread_kill (thr, SIGUSR1);
-+
-+#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC
-+ /* Old binaries need the non-conforming ESRCH error code. */
-+ TEST_COMPARE (compat_pthread_kill (thr, SIGUSR1), ESRCH);
-+#endif
-+
-+ xpthread_join (thr);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/pthread/tst-pthread_kill-exiting.c b/sysdeps/pthread/tst-pthread_kill-exiting.c
-new file mode 100644
-index 0000000000..f803e94f11
---- /dev/null
-+++ b/sysdeps/pthread/tst-pthread_kill-exiting.c
-@@ -0,0 +1,123 @@
-+/* Test that pthread_kill succeeds during thread exit.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+/* This test verifies that pthread_kill for a thread that is exiting
-+ succeeds (with or without actually delivering the signal). */
-+
-+#include <array_length.h>
-+#include <stdbool.h>
-+#include <stddef.h>
-+#include <support/xsignal.h>
-+#include <support/xthread.h>
-+#include <unistd.h>
-+
-+/* Set to true by timeout_thread_function when the test should
-+ terminate. */
-+static bool timeout;
-+
-+static void *
-+timeout_thread_function (void *unused)
-+{
-+ usleep (1000 * 1000);
-+ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED);
-+ return NULL;
-+}
-+
-+/* Used to synchronize the sending threads with the target thread and
-+ main thread. */
-+static pthread_barrier_t barrier_1;
-+static pthread_barrier_t barrier_2;
-+
-+/* The target thread to which signals are to be sent. */
-+static pthread_t target_thread;
-+
-+/* Set by the main thread to true after timeout has been set to
-+ true. */
-+static bool exiting;
-+
-+static void *
-+sender_thread_function (void *unused)
-+{
-+ while (true)
-+ {
-+ /* Wait until target_thread has been initialized. The target
-+ thread and main thread participate in this barrier. */
-+ xpthread_barrier_wait (&barrier_1);
-+
-+ if (exiting)
-+ break;
-+
-+ xpthread_kill (target_thread, SIGUSR1);
-+
-+ /* Communicate that the signal has been sent. The main thread
-+ participates in this barrier. */
-+ xpthread_barrier_wait (&barrier_2);
-+ }
-+ return NULL;
-+}
-+
-+static void *
-+target_thread_function (void *unused)
-+{
-+ target_thread = pthread_self ();
-+ xpthread_barrier_wait (&barrier_1);
-+ return NULL;
-+}
-+
-+static int
-+do_test (void)
-+{
-+ xsignal (SIGUSR1, SIG_IGN);
-+
-+ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL);
-+
-+ pthread_t threads[4];
-+ xpthread_barrier_init (&barrier_1, NULL, array_length (threads) + 2);
-+ xpthread_barrier_init (&barrier_2, NULL, array_length (threads) + 1);
-+
-+ for (int i = 0; i < array_length (threads); ++i)
-+ threads[i] = xpthread_create (NULL, sender_thread_function, NULL);
-+
-+ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED))
-+ {
-+ xpthread_create (NULL, target_thread_function, NULL);
-+
-+ /* Wait for the target thread to be set up and signal sending to
-+ start. */
-+ xpthread_barrier_wait (&barrier_1);
-+
-+ /* Wait for signal sending to complete. */
-+ xpthread_barrier_wait (&barrier_2);
-+
-+ xpthread_join (target_thread);
-+ }
-+
-+ exiting = true;
-+
-+ /* Signal the sending threads to exit. */
-+ xpthread_create (NULL, target_thread_function, NULL);
-+ xpthread_barrier_wait (&barrier_1);
-+
-+ for (int i = 0; i < array_length (threads); ++i)
-+ xpthread_join (threads[i]);
-+ xpthread_join (thr_timeout);
-+
-+ return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/sysdeps/riscv/dl-relocate-ld.h b/sysdeps/riscv/dl-relocate-ld.h
-new file mode 100644
-index 0000000000..2ab2b8ac6c
---- /dev/null
-+++ b/sysdeps/riscv/dl-relocate-ld.h
-@@ -0,0 +1,25 @@
-+/* Check if dynamic section should be relocated. RISC-V version.
-+ Copyright (C) 2021 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <https://www.gnu.org/licenses/>. */
-+
-+#ifndef _DL_RELOCATE_LD_H
-+#define _DL_RELOCATE_LD_H
-+
-+/* The dynamic section is readonly for ABI compatibility. */
-+#define DL_RO_DYN_SECTION 1
-+
-+#endif /* _DL_RELOCATE_LD_H */
-diff --git a/sysdeps/riscv/ldsodefs.h b/sysdeps/riscv/ldsodefs.h
-index 0c696714a7..8947ffe4b5 100644
---- a/sysdeps/riscv/ldsodefs.h
-+++ b/sysdeps/riscv/ldsodefs.h
-@@ -38,11 +38,6 @@ struct La_riscv_retval;
- struct La_riscv_retval *, \
- const char *);
-
--/* Although the RISC-V ABI does not specify that the dynamic section has
-- to be read-only, it needs to be kept for ABI compatibility. */
--
--#define DL_RO_DYN_SECTION 1
--
- #include_next <ldsodefs.h>
-
- #endif
-diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
-index c174e27b35..155f0bd99e 100644
---- a/sysdeps/s390/dl-procinfo.c
-+++ b/sysdeps/s390/dl-procinfo.c
-@@ -46,13 +46,13 @@
- #if !defined PROCINFO_DECL && defined SHARED
- ._dl_s390_cap_flags
- #else
--PROCINFO_CLASS const char _dl_s390_cap_flags[21][9]
-+PROCINFO_CLASS const char _dl_s390_cap_flags[23][9]
- #endif
- #ifndef PROCINFO_DECL
- = {
- "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh",
- "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt",
-- "vxp2", "nnpa"
-+ "vxp2", "nnpa", "pcimio", "sie"
- }
- #endif
- #if !defined SHARED || defined PROCINFO_DECL
-diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
-index 2d9c305808..e4e3e334a5 100644
---- a/sysdeps/s390/dl-procinfo.h
-+++ b/sysdeps/s390/dl-procinfo.h
-@@ -21,7 +21,7 @@
- #define _DL_PROCINFO_H 1
- #include <ldsodefs.h>
-
--#define _DL_HWCAP_COUNT 21
-+#define _DL_HWCAP_COUNT 23
-
- #define _DL_PLATFORMS_COUNT 10
-
-@@ -63,6 +63,8 @@ enum
- HWCAP_S390_DFLT = 1 << 18,
- HWCAP_S390_VXRS_PDE2 = 1 << 19,
- HWCAP_S390_NNPA = 1 << 20,
-+ HWCAP_S390_PCI_MIO = 1 << 21,
-+ HWCAP_S390_SIE = 1 << 22,
- };
-
- #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
-diff --git a/sysdeps/s390/memmem-arch13.S b/sysdeps/s390/memmem-arch13.S
-index c5c8d8c97e..58df8cdb14 100644
---- a/sysdeps/s390/memmem-arch13.S
-+++ b/sysdeps/s390/memmem-arch13.S
-@@ -41,7 +41,7 @@ ENTRY(MEMMEM_ARCH13)
- # error The arch13 variant of memmem needs the z13 variant of memmem!
- # endif
- clgfi %r5,9
-- jh MEMMEM_Z13
-+ jgh MEMMEM_Z13
-
- aghik %r0,%r5,-1 /* vll needs highest index. */
- bc 4,0(%r14) /* cc==1: return if needle-len == 0. */
-diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S
-index c7183e627c..222a6de91a 100644
---- a/sysdeps/s390/strstr-arch13.S
-+++ b/sysdeps/s390/strstr-arch13.S
-@@ -49,7 +49,7 @@ ENTRY(STRSTR_ARCH13)
- # error The arch13 variant of strstr needs the z13 variant of strstr!
- # endif
- clgfi %r4,9
-- jh STRSTR_Z13
-+ jgh STRSTR_Z13
-
- /* In case of a partial match, the vstrs instruction returns the index
- of the partial match in a vector-register. Then we have to
-diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
-index e9eb707d0a..bedab1abba 100644
---- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
-@@ -126,6 +126,7 @@
- #define __NR_mbind 235
- #define __NR_membarrier 283
- #define __NR_memfd_create 279
-+#define __NR_memfd_secret 447
- #define __NR_migrate_pages 238
- #define __NR_mincore 232
- #define __NR_mkdirat 34
-@@ -187,6 +188,7 @@
- #define __NR_pwritev 70
- #define __NR_pwritev2 287
- #define __NR_quotactl 60
-+#define __NR_quotactl_fd 443
- #define __NR_read 63
- #define __NR_readahead 213
- #define __NR_readlinkat 78
-diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
-index bd6b7d4003..91354ed9e2 100644
---- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
-@@ -337,6 +337,7 @@
- #define __NR_pwritev2 521
- #define __NR_query_module 347
- #define __NR_quotactl 148
-+#define __NR_quotactl_fd 553
- #define __NR_read 3
- #define __NR_readahead 379
- #define __NR_readlink 58
-diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
-index 10650549c1..ff5c7eb36d 100644
---- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
-@@ -190,6 +190,7 @@
- #define __NR_pwritev 70
- #define __NR_pwritev2 287
- #define __NR_quotactl 60
-+#define __NR_quotactl_fd 443
- #define __NR_read 63
- #define __NR_readahead 213
- #define __NR_readlinkat 78
-diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
-index 85c9b236ce..5772333cee 100644
---- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
-@@ -244,6 +244,7 @@
- #define __NR_pwritev 362
- #define __NR_pwritev2 393
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 225
- #define __NR_readlink 85
-diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h
-index 3b1ae418e0..31451c28d9 100644
---- a/sysdeps/unix/sysv/linux/bits/mman-linux.h
-+++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h
-@@ -89,6 +89,10 @@
- # define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK. */
- # define MADV_COLD 20 /* Deactivate these pages. */
- # define MADV_PAGEOUT 21 /* Reclaim these pages. */
-+# define MADV_POPULATE_READ 22 /* Populate (prefault) page tables
-+ readable. */
-+# define MADV_POPULATE_WRITE 23 /* Populate (prefault) page tables
-+ writable. */
- # define MADV_HWPOISON 100 /* Poison a page for testing. */
- #endif
-
-diff --git a/sysdeps/unix/sysv/linux/bits/timex.h b/sysdeps/unix/sysv/linux/bits/timex.h
-index ee37694e8f..4a5db6deca 100644
---- a/sysdeps/unix/sysv/linux/bits/timex.h
-+++ b/sysdeps/unix/sysv/linux/bits/timex.h
-@@ -25,7 +25,7 @@
-
- struct timex
- {
--# ifdef __USE_TIME_BITS64
-+# if defined __USE_TIME_BITS64 || (__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/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
-index 24b0d1f94e..4af6d6202f 100644
---- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
-@@ -199,6 +199,7 @@
- #define __NR_pwritev 70
- #define __NR_pwritev2 287
- #define __NR_quotactl 60
-+#define __NR_quotactl_fd 443
- #define __NR_read 63
- #define __NR_readahead 213
- #define __NR_readlinkat 78
-diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
-index 1391e360b8..7fc6521942 100644
---- a/sysdeps/unix/sysv/linux/getsysstats.c
-+++ b/sysdeps/unix/sysv/linux/getsysstats.c
-@@ -18,6 +18,8 @@
- <https://www.gnu.org/licenses/>. */
-
- #include <array_length.h>
-+#include <assert.h>
-+#include <ctype.h>
- #include <dirent.h>
- #include <errno.h>
- #include <ldsodefs.h>
-@@ -29,61 +31,170 @@
- #include <sys/sysinfo.h>
- #include <sysdep.h>
-
--/* Compute the population count of the entire array. */
--static int
--__get_nprocs_count (const unsigned long int *array, size_t length)
-+int
-+__get_nprocs_sched (void)
- {
-- int count = 0;
-- for (size_t i = 0; i < length; ++i)
-- if (__builtin_add_overflow (count, __builtin_popcountl (array[i]),
-- &count))
-- return INT_MAX;
-- return count;
-+ enum
-+ {
-+ max_num_cpus = 32768,
-+ cpu_bits_size = CPU_ALLOC_SIZE (32768)
-+ };
-+
-+ /* This cannot use malloc because it is used on malloc initialization. */
-+ __cpu_mask cpu_bits[cpu_bits_size / sizeof (__cpu_mask)];
-+ int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size,
-+ cpu_bits);
-+ if (r > 0)
-+ return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits);
-+ else if (r == -EINVAL)
-+ /* The input buffer is still not enough to store the number of cpus. This
-+ is an arbitrary values assuming such systems should be rare and there
-+ is no offline cpus. */
-+ return max_num_cpus;
-+ /* Some other error. 2 is conservative (not a uniprocessor system, so
-+ atomics are needed). */
-+ return 2;
-+}
-+
-+static char *
-+next_line (int fd, char *const buffer, char **cp, char **re,
-+ char *const buffer_end)
-+{
-+ char *res = *cp;
-+ char *nl = memchr (*cp, '\n', *re - *cp);
-+ if (nl == NULL)
-+ {
-+ if (*cp != buffer)
-+ {
-+ if (*re == buffer_end)
-+ {
-+ memmove (buffer, *cp, *re - *cp);
-+ *re = buffer + (*re - *cp);
-+ *cp = buffer;
-+
-+ ssize_t n = __read_nocancel (fd, *re, buffer_end - *re);
-+ if (n < 0)
-+ return NULL;
-+
-+ *re += n;
-+
-+ nl = memchr (*cp, '\n', *re - *cp);
-+ while (nl == NULL && *re == buffer_end)
-+ {
-+ /* Truncate too long lines. */
-+ *re = buffer + 3 * (buffer_end - buffer) / 4;
-+ n = __read_nocancel (fd, *re, buffer_end - *re);
-+ if (n < 0)
-+ return NULL;
-+
-+ nl = memchr (*re, '\n', n);
-+ **re = '\n';
-+ *re += n;
-+ }
-+ }
-+ else
-+ nl = memchr (*cp, '\n', *re - *cp);
-+
-+ res = *cp;
-+ }
-+
-+ if (nl == NULL)
-+ nl = *re - 1;
-+ }
-+
-+ *cp = nl + 1;
-+ assert (*cp <= *re);
-+
-+ return res == *re ? NULL : res;
- }
-
--/* __get_nprocs with a large buffer. */
- static int
--__get_nprocs_large (void)
-+get_nproc_stat (char *buffer, size_t buffer_size)
- {
-- /* This code cannot use scratch_buffer because it is used during
-- malloc initialization. */
-- size_t pagesize = GLRO (dl_pagesize);
-- unsigned long int *page = __mmap (0, pagesize, PROT_READ | PROT_WRITE,
-- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
-- if (page == MAP_FAILED)
-- return 2;
-- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, pagesize, page);
-- int count;
-- if (r > 0)
-- count = __get_nprocs_count (page, pagesize / sizeof (unsigned long int));
-- else if (r == -EINVAL)
-- /* One page is still not enough to store the bits. A more-or-less
-- arbitrary value. This assumes t hat such large systems never
-- happen in practice. */
-- count = GLRO (dl_pagesize) * CHAR_BIT;
-- else
-- count = 2;
-- __munmap (page, GLRO (dl_pagesize));
-- return count;
-+ char *buffer_end = buffer + buffer_size;
-+ char *cp = buffer_end;
-+ char *re = buffer_end;
-+
-+ /* Default to an SMP system in case we cannot obtain an accurate
-+ number. */
-+ int result = 2;
-+
-+ const int flags = O_RDONLY | O_CLOEXEC;
-+ int fd = __open_nocancel ("/proc/stat", flags);
-+ if (fd != -1)
-+ {
-+ result = 0;
-+
-+ char *l;
-+ while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
-+ /* The current format of /proc/stat has all the cpu* entries
-+ at the front. We assume here that stays this way. */
-+ if (strncmp (l, "cpu", 3) != 0)
-+ break;
-+ else if (isdigit (l[3]))
-+ ++result;
-+
-+ __close_nocancel_nostatus (fd);
-+ }
-+
-+ return result;
- }
-
- int
- __get_nprocs (void)
- {
-- /* Fast path for most systems. The kernel expects a buffer size
-- that is a multiple of 8. */
-- unsigned long int small_buffer[1024 / CHAR_BIT / sizeof (unsigned long int)];
-- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0,
-- sizeof (small_buffer), small_buffer);
-- if (r > 0)
-- return __get_nprocs_count (small_buffer, r / sizeof (unsigned long int));
-- else if (r == -EINVAL)
-- /* The kernel requests a larger buffer to store the data. */
-- return __get_nprocs_large ();
-- else
-- /* Some other error. 2 is conservative (not a uniprocessor
-- system, so atomics are needed). */
-- return 2;
-+ enum { buffer_size = 1024 };
-+ char buffer[buffer_size];
-+ char *buffer_end = buffer + buffer_size;
-+ char *cp = buffer_end;
-+ char *re = buffer_end;
-+
-+ const int flags = O_RDONLY | O_CLOEXEC;
-+ /* This file contains comma-separated ranges. */
-+ int fd = __open_nocancel ("/sys/devices/system/cpu/online", flags);
-+ char *l;
-+ int result = 0;
-+ if (fd != -1)
-+ {
-+ l = next_line (fd, buffer, &cp, &re, buffer_end);
-+ if (l != NULL)
-+ do
-+ {
-+ char *endp;
-+ unsigned long int n = strtoul (l, &endp, 10);
-+ if (l == endp)
-+ {
-+ result = 0;
-+ break;
-+ }
-+
-+ unsigned long int m = n;
-+ if (*endp == '-')
-+ {
-+ l = endp + 1;
-+ m = strtoul (l, &endp, 10);
-+ if (l == endp)
-+ {
-+ result = 0;
-+ break;
-+ }
-+ }
-+
-+ result += m - n + 1;
-+
-+ l = endp;
-+ if (l < re && *l == ',')
-+ ++l;
-+ }
-+ while (l < re && *l != '\n');
-+
-+ __close_nocancel_nostatus (fd);
-+
-+ if (result > 0)
-+ return result;
-+ }
-+
-+ return get_nproc_stat (buffer, buffer_size);
- }
- libc_hidden_def (__get_nprocs)
- weak_alias (__get_nprocs, get_nprocs)
-@@ -117,7 +228,9 @@ __get_nprocs_conf (void)
- return count;
- }
-
-- return 1;
-+ enum { buffer_size = 1024 };
-+ char buffer[buffer_size];
-+ return get_nproc_stat (buffer, buffer_size);
- }
- libc_hidden_def (__get_nprocs_conf)
- weak_alias (__get_nprocs_conf, get_nprocs_conf)
-diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
-index feb70abc3e..b07fc8549d 100644
---- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
-@@ -231,6 +231,7 @@
- #define __NR_pwritev 316
- #define __NR_pwritev2 348
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 207
- #define __NR_readlink 85
-diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
-index 3b1894a79b..6e4264698b 100644
---- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
-@@ -183,6 +183,7 @@
- #define __NR_mbind 274
- #define __NR_membarrier 375
- #define __NR_memfd_create 356
-+#define __NR_memfd_secret 447
- #define __NR_migrate_pages 294
- #define __NR_mincore 218
- #define __NR_mkdir 39
-@@ -266,6 +267,7 @@
- #define __NR_pwritev2 379
- #define __NR_query_module 167
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 225
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
-index fb388a5fa4..1ca706d721 100644
---- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
-@@ -218,6 +218,7 @@
- #define __NR_pwritev 1320
- #define __NR_pwritev2 1349
- #define __NR_quotactl 1137
-+#define __NR_quotactl_fd 1467
- #define __NR_read 1026
- #define __NR_readahead 1216
- #define __NR_readlink 1092
-diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
-index 7bc8c4af92..2f10f71f90 100644
---- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
-@@ -254,6 +254,7 @@
- #define __NR_pwritev2 378
- #define __NR_query_module 167
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 240
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
-index cf560d3af4..0607a4dfa6 100644
---- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
-@@ -266,6 +266,7 @@
- #define __NR_pwritev2 394
- #define __NR_query_module 167
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 225
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/mips/fxstat.c b/sysdeps/unix/sysv/linux/mips/fxstat.c
-index 11511d30b3..4a6016ff12 100644
---- a/sysdeps/unix/sysv/linux/mips/fxstat.c
-+++ b/sysdeps/unix/sysv/linux/mips/fxstat.c
-@@ -35,7 +35,9 @@ __fxstat (int vers, int fd, struct stat *buf)
- {
- struct kernel_stat kbuf;
- int r = INTERNAL_SYSCALL_CALL (fstat, fd, &kbuf);
-- return r ?: __xstat_conv (vers, &kbuf, buf);
-+ if (r == 0)
-+ return __xstat_conv (vers, &kbuf, buf);
-+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
- }
- }
- }
-diff --git a/sysdeps/unix/sysv/linux/mips/lxstat.c b/sysdeps/unix/sysv/linux/mips/lxstat.c
-index 871fb6c6c5..54f990a250 100644
---- a/sysdeps/unix/sysv/linux/mips/lxstat.c
-+++ b/sysdeps/unix/sysv/linux/mips/lxstat.c
-@@ -35,7 +35,9 @@ __lxstat (int vers, const char *name, struct stat *buf)
- {
- struct kernel_stat kbuf;
- int r = INTERNAL_SYSCALL_CALL (lstat, name, &kbuf);
-- return r ?: __xstat_conv (vers, &kbuf, buf);
-+ if (r == 0)
-+ return __xstat_conv (vers, &kbuf, buf);
-+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
- }
- }
- }
-diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
-index f346460f48..0055eec0b1 100644
---- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
-@@ -251,6 +251,7 @@
- #define __NR_pwritev2 4362
- #define __NR_query_module 4187
- #define __NR_quotactl 4131
-+#define __NR_quotactl_fd 4443
- #define __NR_read 4003
- #define __NR_readahead 4223
- #define __NR_readdir 4089
-diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
-index 38ed84997a..8e8e9f91cc 100644
---- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
-@@ -232,6 +232,7 @@
- #define __NR_pwritev2 6326
- #define __NR_query_module 6171
- #define __NR_quotactl 6172
-+#define __NR_quotactl_fd 6443
- #define __NR_read 6000
- #define __NR_readahead 6179
- #define __NR_readlink 6087
-diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
-index e6a10c8421..ebd1545f80 100644
---- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
-@@ -219,6 +219,7 @@
- #define __NR_pwritev2 5322
- #define __NR_query_module 5171
- #define __NR_quotactl 5172
-+#define __NR_quotactl_fd 5443
- #define __NR_read 5000
- #define __NR_readahead 5179
- #define __NR_readlink 5087
-diff --git a/sysdeps/unix/sysv/linux/mips/xstat.c b/sysdeps/unix/sysv/linux/mips/xstat.c
-index 9d810b6f65..86f4dc31a8 100644
---- a/sysdeps/unix/sysv/linux/mips/xstat.c
-+++ b/sysdeps/unix/sysv/linux/mips/xstat.c
-@@ -35,7 +35,9 @@ __xstat (int vers, const char *name, struct stat *buf)
- {
- struct kernel_stat kbuf;
- int r = INTERNAL_SYSCALL_CALL (stat, name, &kbuf);
-- return r ?: __xstat_conv (vers, &kbuf, buf);
-+ if (r == 0)
-+ return __xstat_conv (vers, &kbuf, buf);
-+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
- }
- }
- }
-diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c
-index 9799dcdaa4..eccae2e4c6 100644
---- a/sysdeps/unix/sysv/linux/mq_notify.c
-+++ b/sysdeps/unix/sysv/linux/mq_notify.c
-@@ -131,7 +131,7 @@ helper_thread (void *arg)
- to wait until it is done with it. */
- (void) __pthread_barrier_wait (&notify_barrier);
- }
-- else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED)
-+ else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED && data.attr != NULL)
- {
- /* The only state we keep is the copy of the thread attributes. */
- __pthread_attr_destroy (data.attr);
-diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
-index 5314890289..2b530b1f88 100644
---- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
-@@ -198,6 +198,7 @@
- #define __NR_pwritev 70
- #define __NR_pwritev2 287
- #define __NR_quotactl 60
-+#define __NR_quotactl_fd 443
- #define __NR_read 63
- #define __NR_readahead 213
- #define __NR_readlinkat 78
-diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
-index b5b0758532..a32984a9c1 100644
---- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
-@@ -260,6 +260,7 @@
- #define __NR_pwritev2 381
- #define __NR_query_module 166
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 191
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
-index c77435ca61..b01e464fb9 100644
---- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
-@@ -243,6 +243,7 @@
- #define __NR_pwritev2 381
- #define __NR_query_module 166
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 191
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
-index 70854bb9e3..24d0a2c455 100644
---- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
-@@ -179,6 +179,7 @@
- #define __NR_pwritev 70
- #define __NR_pwritev2 287
- #define __NR_quotactl 60
-+#define __NR_quotactl_fd 443
- #define __NR_read 63
- #define __NR_readahead 213
- #define __NR_readlinkat 78
-diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
-index 83b9f31aba..e526c89ae7 100644
---- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
-@@ -187,6 +187,7 @@
- #define __NR_pwritev 70
- #define __NR_pwritev2 287
- #define __NR_quotactl 60
-+#define __NR_quotactl_fd 443
- #define __NR_read 63
- #define __NR_readahead 213
- #define __NR_readlinkat 78
-diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
-index e9bd3684db..00e73a3e3b 100644
---- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
-+++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
-@@ -22,6 +22,11 @@
-
- /*
- * The following must match the kernels asm/elf.h.
-+ * Note: The kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e
-+ * "s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros
-+ * from "HWCAP_S390_" to "HWCAP_". For compatibility reasons, we do not
-+ * change the prefix in public glibc header file.
-+ *
- * Note that these are *not* the same as the STORE FACILITY LIST bits.
- */
- #define HWCAP_S390_ESAN3 1
-@@ -48,3 +53,5 @@
- #define HWCAP_S390_DFLT 262144
- #define HWCAP_S390_VXRS_PDE2 524288
- #define HWCAP_S390_NNPA 1048576
-+#define HWCAP_S390_PCI_MIO 2097152
-+#define HWCAP_S390_SIE 4194304
-diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
-index b224c4aad4..d4c7b101b6 100644
---- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
-@@ -251,6 +251,7 @@
- #define __NR_pwritev2 377
- #define __NR_query_module 167
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 222
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
-index 59864af125..bd8c78d705 100644
---- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
-@@ -221,6 +221,7 @@
- #define __NR_pwritev2 377
- #define __NR_query_module 167
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 222
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
-index 23612c9092..3b6ac3d084 100644
---- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
-@@ -246,6 +246,7 @@
- #define __NR_pwritev 334
- #define __NR_pwritev2 382
- #define __NR_quotactl 131
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 225
- #define __NR_readdir 89
-diff --git a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h
-index b481b4f9f8..45db6b6ffb 100644
---- a/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h
-+++ b/sysdeps/unix/sysv/linux/sparc/bits/struct_stat.h
-@@ -28,32 +28,35 @@
-
- struct stat
- {
-+#ifdef __USE_TIME_BITS64
-+# include <bits/struct_stat_time64_helper.h>
-+#else
- __dev_t st_dev; /* Device. */
--#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
-+# if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
- unsigned short int __pad1;
- __ino_t st_ino; /* File serial number. */
--#else
-+# else
- __ino64_t st_ino; /* File serial number. */
--#endif
-+# endif
- __mode_t st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
- __uid_t st_uid; /* User ID of the file's owner. */
- __gid_t st_gid; /* Group ID of the file's group.*/
- __dev_t st_rdev; /* Device number, if device. */
- unsigned short int __pad2;
--#ifndef __USE_FILE_OFFSET64
-+# ifndef __USE_FILE_OFFSET64
- __off_t st_size; /* Size of file, in bytes. */
--#else
-+# else
- __off64_t st_size; /* Size of file, in bytes. */
--#endif
-+# endif
- __blksize_t st_blksize; /* Optimal block size for I/O. */
-
--#ifndef __USE_FILE_OFFSET64
-+# ifndef __USE_FILE_OFFSET64
- __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
--#else
-+# else
- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
--#endif
--#ifdef __USE_XOPEN2K8
-+# endif
-+# ifdef __USE_XOPEN2K8
- /* Nanosecond resolution timestamps are stored in a format
- equivalent to 'struct timespec'. This is the type used
- whenever possible but the Unix namespace rules do not allow the
-@@ -63,28 +66,32 @@ struct stat
- struct timespec st_atim; /* Time of last access. */
- struct timespec st_mtim; /* Time of last modification. */
- struct timespec st_ctim; /* Time of last status change. */
--# define st_atime st_atim.tv_sec /* Backward compatibility. */
--# define st_mtime st_mtim.tv_sec
--# define st_ctime st_ctim.tv_sec
--#else
-+# define st_atime st_atim.tv_sec /* Backward compatibility. */
-+# define st_mtime st_mtim.tv_sec
-+# define st_ctime st_ctim.tv_sec
-+# else
- __time_t st_atime; /* Time of last access. */
- unsigned long int st_atimensec; /* Nscecs of last access. */
- __time_t st_mtime; /* Time of last modification. */
- unsigned long int st_mtimensec; /* Nsecs of last modification. */
- __time_t st_ctime; /* Time of last status change. */
- unsigned long int st_ctimensec; /* Nsecs of last status change. */
--#endif
-+# endif
- unsigned long int __glibc_reserved4;
- unsigned long int __glibc_reserved5;
-+#endif /* __USE_TIME_BITS64 */
- };
-
- #ifdef __USE_LARGEFILE64
- struct stat64
- {
-+# ifdef __USE_TIME_BITS64
-+# include <bits/struct_stat_time64_helper.h>
-+# else
- __dev_t st_dev; /* Device. */
--# if __WORDSIZE == 64
-+# if __WORDSIZE == 64
- unsigned short int __pad1;
--# endif
-+# endif
- __ino64_t st_ino; /* File serial number. */
- __mode_t st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
-@@ -96,7 +103,7 @@ struct stat64
- __blksize_t st_blksize; /* Optimal block size for I/O. */
-
- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
--# ifdef __USE_XOPEN2K8
-+# ifdef __USE_XOPEN2K8
- /* Nanosecond resolution timestamps are stored in a format
- equivalent to 'struct timespec'. This is the type used
- whenever possible but the Unix namespace rules do not allow the
-@@ -106,19 +113,20 @@ struct stat64
- struct timespec st_atim; /* Time of last access. */
- struct timespec st_mtim; /* Time of last modification. */
- struct timespec st_ctim; /* Time of last status change. */
--# define st_atime st_atim.tv_sec /* Backward compatibility. */
--# define st_mtime st_mtim.tv_sec
--# define st_ctime st_ctim.tv_sec
--# else
-+# define st_atime st_atim.tv_sec /* Backward compatibility. */
-+# define st_mtime st_mtim.tv_sec
-+# define st_ctime st_ctim.tv_sec
-+# else
- __time_t st_atime; /* Time of last access. */
- unsigned long int st_atimensec; /* Nscecs of last access. */
- __time_t st_mtime; /* Time of last modification. */
- unsigned long int st_mtimensec; /* Nsecs of last modification. */
- __time_t st_ctime; /* Time of last status change. */
- unsigned long int st_ctimensec; /* Nsecs of last status change. */
--# endif
-+# endif
- unsigned long int __glibc_reserved4;
- unsigned long int __glibc_reserved5;
-+# endif /* __USE_TIME_BITS64 */
- };
- #endif
-
-diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
-index 380cddb2d8..35221a707e 100644
---- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
-@@ -252,6 +252,7 @@
- #define __NR_pwritev2 359
- #define __NR_query_module 184
- #define __NR_quotactl 165
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 205
- #define __NR_readdir 204
-diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
-index 2175eeb6ed..5ba2b20509 100644
---- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
-@@ -231,6 +231,7 @@
- #define __NR_pwritev2 359
- #define __NR_query_module 184
- #define __NR_quotactl 165
-+#define __NR_quotactl_fd 443
- #define __NR_read 3
- #define __NR_readahead 205
- #define __NR_readdir 204
-diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h
-index db88938b3a..f0e0d2f27f 100644
---- a/sysdeps/unix/sysv/linux/sys/prctl.h
-+++ b/sysdeps/unix/sysv/linux/sys/prctl.h
-@@ -42,7 +42,7 @@ __BEGIN_DECLS
- extern int prctl (int __option, ...) __THROW;
- #else
- # ifdef __REDIRECT
--extern int __REDIRECT (prctl, (int __option, ...), __prctl_time64) __THROW;
-+extern int __REDIRECT_NTH (prctl, (int __option, ...), __prctl_time64);
- # else
- extern int __prctl_time64 (int __option,d ...) __THROW;
- # define ioctl __prctl_time64
-diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
-index 89c5895b9b..fd98893b0e 100644
---- a/sysdeps/unix/sysv/linux/syscall-names.list
-+++ b/sysdeps/unix/sysv/linux/syscall-names.list
-@@ -21,8 +21,8 @@
- # This file can list all potential system calls. The names are only
- # used if the installed kernel headers also provide them.
-
--# The list of system calls is current as of Linux 5.13.
--kernel 5.13
-+# The list of system calls is current as of Linux 5.14.
-+kernel 5.14
-
- FAST_atomic_update
- FAST_cmpxchg
-@@ -247,6 +247,7 @@ madvise
- mbind
- membarrier
- memfd_create
-+memfd_secret
- memory_ordering
- migrate_pages
- mincore
-@@ -452,6 +453,7 @@ pwritev
- pwritev2
- query_module
- quotactl
-+quotactl_fd
- read
- readahead
- readdir
-diff --git a/sysdeps/unix/sysv/linux/tst-close_range.c b/sysdeps/unix/sysv/linux/tst-close_range.c
-index dccb6189c5..f5069d1b8a 100644
---- a/sysdeps/unix/sysv/linux/tst-close_range.c
-+++ b/sysdeps/unix/sysv/linux/tst-close_range.c
-@@ -36,23 +36,12 @@
-
- #define NFDS 100
-
--static int
--open_multiple_temp_files (void)
--{
-- /* Check if the temporary file descriptor has no no gaps. */
-- int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
-- for (int i = 1; i <= NFDS; i++)
-- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600),
-- lowfd + i);
-- return lowfd;
--}
--
- static void
- close_range_test_max_upper_limit (void)
- {
- struct support_descriptors *descrs = support_descriptors_list ();
-
-- int lowfd = open_multiple_temp_files ();
-+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
-
- {
- int r = close_range (lowfd, ~0U, 0);
-@@ -68,7 +57,7 @@ close_range_test_max_upper_limit (void)
- static void
- close_range_test_common (int lowfd, unsigned int flags)
- {
-- const int maximum_fd = lowfd + NFDS;
-+ const int maximum_fd = lowfd + NFDS - 1;
- const int half_fd = lowfd + NFDS / 2;
- const int gap_1 = maximum_fd - 8;
-
-@@ -121,7 +110,7 @@ close_range_test (void)
- struct support_descriptors *descrs = support_descriptors_list ();
-
- /* Check if the temporary file descriptor has no no gaps. */
-- int lowfd = open_multiple_temp_files ();
-+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
-
- close_range_test_common (lowfd, 0);
-
-@@ -146,7 +135,7 @@ close_range_test_subprocess (void)
- struct support_descriptors *descrs = support_descriptors_list ();
-
- /* Check if the temporary file descriptor has no no gaps. */
-- int lowfd = open_multiple_temp_files ();
-+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
-
- struct support_stack stack = support_stack_alloc (4096);
-
-@@ -184,7 +173,7 @@ close_range_unshare_test (void)
- struct support_descriptors *descrs1 = support_descriptors_list ();
-
- /* Check if the temporary file descriptor has no no gaps. */
-- int lowfd = open_multiple_temp_files ();
-+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
-
- struct support_descriptors *descrs2 = support_descriptors_list ();
-
-@@ -200,7 +189,7 @@ close_range_unshare_test (void)
-
- support_stack_free (&stack);
-
-- for (int i = 0; i < NFDS; i++)
-+ for (int i = lowfd; i < lowfd + NFDS; i++)
- TEST_VERIFY (fcntl (i, F_GETFL) > -1);
-
- support_descriptors_check (descrs2);
-@@ -226,9 +215,9 @@ static void
- close_range_cloexec_test (void)
- {
- /* Check if the temporary file descriptor has no no gaps. */
-- const int lowfd = open_multiple_temp_files ();
-+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
-
-- const int maximum_fd = lowfd + NFDS;
-+ const int maximum_fd = lowfd + NFDS - 1;
- const int half_fd = lowfd + NFDS / 2;
- const int gap_1 = maximum_fd - 8;
-
-@@ -251,13 +240,13 @@ close_range_cloexec_test (void)
- /* Create some gaps, close up to a threshold, and check result. */
- static int gap_close[] = { 57, 78, 81, 82, 84, 90 };
- for (int i = 0; i < array_length (gap_close); i++)
-- xclose (gap_close[i]);
-+ xclose (lowfd + gap_close[i]);
-
- TEST_COMPARE (close_range (half_fd + 1, gap_1, CLOSE_RANGE_CLOEXEC), 0);
- for (int i = half_fd + 1; i < gap_1; i++)
- {
- int flags = fcntl (i, F_GETFD);
-- if (is_in_array (gap_close, array_length (gap_close), i))
-+ if (is_in_array (gap_close, array_length (gap_close), i - lowfd))
- TEST_COMPARE (flags, -1);
- else
- {
-diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py
-index ee5b13ee12..810433c238 100644
---- a/sysdeps/unix/sysv/linux/tst-mman-consts.py
-+++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py
-@@ -33,7 +33,7 @@ def main():
- help='C compiler (including options) to use')
- args = parser.parse_args()
- linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
-- linux_version_glibc = (5, 13)
-+ linux_version_glibc = (5, 14)
- sys.exit(glibcextract.compare_macro_consts(
- '#define _GNU_SOURCE 1\n'
- '#include <sys/mman.h>\n',
-diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
-index 8e028eb62b..26d6ac68a6 100644
---- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
-@@ -154,6 +154,7 @@
- #define __NR_mbind 237
- #define __NR_membarrier 324
- #define __NR_memfd_create 319
-+#define __NR_memfd_secret 447
- #define __NR_migrate_pages 256
- #define __NR_mincore 27
- #define __NR_mkdir 83
-@@ -224,6 +225,7 @@
- #define __NR_pwritev2 328
- #define __NR_query_module 178
- #define __NR_quotactl 179
-+#define __NR_quotactl_fd 443
- #define __NR_read 0
- #define __NR_readahead 187
- #define __NR_readlink 89
-diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
-index 004feb53f1..36847783f6 100644
---- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
-+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
-@@ -148,6 +148,7 @@
- #define __NR_mbind 1073742061
- #define __NR_membarrier 1073742148
- #define __NR_memfd_create 1073742143
-+#define __NR_memfd_secret 1073742271
- #define __NR_migrate_pages 1073742080
- #define __NR_mincore 1073741851
- #define __NR_mkdir 1073741907
-@@ -216,6 +217,7 @@
- #define __NR_pwritev 1073742359
- #define __NR_pwritev2 1073742371
- #define __NR_quotactl 1073742003
-+#define __NR_quotactl_fd 1073742267
- #define __NR_read 1073741824
- #define __NR_readahead 1073742011
- #define __NR_readlink 1073741913
-diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
-index 9f02624375..abde8438d4 100644
---- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
-+++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
-@@ -325,7 +325,7 @@ L(movsb):
- /* Avoid slow backward REP MOVSB. */
- jb L(more_8x_vec_backward)
- # if AVOID_SHORT_DISTANCE_REP_MOVSB
-- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
-+ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
- jz 3f
- movq %rdi, %rcx
- subq %rsi, %rcx
-@@ -333,7 +333,7 @@ L(movsb):
- # endif
- 1:
- # if AVOID_SHORT_DISTANCE_REP_MOVSB
-- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
-+ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip)
- jz 3f
- movq %rsi, %rcx
- subq %rdi, %rcx
-diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/64/configure glibc-2.32/sysdeps/unix/sysv/linux/x86_64/64/configure
---- glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/64/configure 2021-09-18 21:02:32.741186019 +1000
-+++ glibc-2.32/sysdeps/unix/sysv/linux/x86_64/64/configure 2021-09-18 21:03:05.314302356 +1000
-@@ -4,10 +4,10 @@
- test -n "$libc_cv_slibdir" ||
- case "$prefix" in
- /usr | /usr/)
-- libc_cv_slibdir='/lib64'
-- libc_cv_rtlddir='/lib64'
-+ libc_cv_slibdir='/lib'
-+ libc_cv_rtlddir='/lib'
- if test "$libdir" = '${exec_prefix}/lib'; then
-- libdir='${exec_prefix}/lib64';
-+ libdir='${exec_prefix}/lib';
- # Locale data can be shared between 32-bit and 64-bit libraries.
- libc_cv_complocaledir='${exec_prefix}/lib/locale'
- fi
-diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/ldconfig.h glibc-2.32/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
---- glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/ldconfig.h 2021-09-18 21:02:32.742186053 +1000
-+++ glibc-2.32/sysdeps/unix/sysv/linux/x86_64/ldconfig.h 2021-09-18 21:03:05.314302356 +1000
-@@ -18,9 +18,9 @@
- #include <sysdeps/generic/ldconfig.h>
-
- #define SYSDEP_KNOWN_INTERPRETER_NAMES \
-- { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
-+ { "/lib32/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
- { "/libx32/ld-linux-x32.so.2", FLAG_ELF_LIBC6 }, \
-- { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
-+ { "/lib/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
- #define SYSDEP_KNOWN_LIBRARY_NAMES \
- { "libc.so.6", FLAG_ELF_LIBC6 }, \
- { "libm.so.6", FLAG_ELF_LIBC6 },
diff --git a/glibc-32/glibc-2.35-1.patch b/glibc-32/glibc-2.35-1.patch
new file mode 100644
index 00000000..ce52a6e0
--- /dev/null
+++ b/glibc-32/glibc-2.35-1.patch
@@ -0,0 +1,230 @@
+diff --git a/NEWS b/NEWS
+index faa7ec1871..6b8db4e947 100644
+--- a/NEWS
++++ b/NEWS
+@@ -4,6 +4,17 @@ See the end for copying conditions.
+
+ Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
+ using `glibc' in the "product" field.
++
++Version 2.35.1
++
++The following bugs are resolved with this release:
++
++ [28850] linux: __get_nprocs_sched reads uninitialized memory from the stack
++ [28853] libc: tst-spawn6 changes current foreground process group
++ (breaks test isolation)
++ [28860] build: --enable-kernel=5.1.0 build fails because of missing
++ __convert_scm_timestamps
++
+
+ Version 2.35
+
+diff --git a/configure b/configure
+index 00dc638388..8e5bee775a 100755
+--- a/configure
++++ b/configure
+@@ -730,7 +730,6 @@ infodir
+ docdir
+ oldincludedir
+ includedir
+-runstatedir
+ localstatedir
+ sharedstatedir
+ sysconfdir
+@@ -845,7 +844,6 @@ datadir='${datarootdir}'
+ sysconfdir='${prefix}/etc'
+ sharedstatedir='${prefix}/com'
+ localstatedir='${prefix}/var'
+-runstatedir='${localstatedir}/run'
+ includedir='${prefix}/include'
+ oldincludedir='/usr/include'
+ docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+@@ -1098,15 +1096,6 @@ do
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+- -runstatedir | --runstatedir | --runstatedi | --runstated \
+- | --runstate | --runstat | --runsta | --runst | --runs \
+- | --run | --ru | --r)
+- ac_prev=runstatedir ;;
+- -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+- | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+- | --run=* | --ru=* | --r=*)
+- runstatedir=$ac_optarg ;;
+-
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+@@ -1244,7 +1233,7 @@ fi
+ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+- libdir localedir mandir runstatedir
++ libdir localedir mandir
+ do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+@@ -1397,7 +1386,6 @@ Fine tuning of the installation directories:
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+- --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+diff --git a/posix/tst-spawn6.c b/posix/tst-spawn6.c
+index 911e90a461..044abd8535 100644
+--- a/posix/tst-spawn6.c
++++ b/posix/tst-spawn6.c
+@@ -29,7 +29,14 @@
+ #include <support/check.h>
+ #include <support/xunistd.h>
+ #include <sys/wait.h>
++#include <sys/ioctl.h>
+ #include <stdlib.h>
++#include <termios.h>
++
++#ifndef PATH_MAX
++# define PATH_MAX 1024
++#endif
++static char ptmxpath[PATH_MAX];
+
+ static int
+ handle_restart (const char *argv1, const char *argv2)
+@@ -115,7 +122,7 @@ run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr,
+ }
+
+ static int
+-do_test (int argc, char *argv[])
++run_test (int argc, char *argv[])
+ {
+ /* We must have either:
+ - four parameters left if called initially:
+@@ -127,16 +134,7 @@ do_test (int argc, char *argv[])
+ + --setgrpr optional
+ */
+
+- if (restart)
+- return handle_restart (argv[1], argv[2]);
+-
+- int tcfd = open64 (_PATH_TTY, O_RDONLY, 0600);
+- if (tcfd == -1)
+- {
+- if (errno == ENXIO)
+- FAIL_UNSUPPORTED ("terminal not available, skipping test");
+- FAIL_EXIT1 ("open64 (\"%s\", 0x%x, 0600): %m", _PATH_TTY, O_RDONLY);
+- }
++ int tcfd = xopen (ptmxpath, O_RDONLY, 0600);
+
+ /* Check setting the controlling terminal without changing the group. */
+ {
+@@ -198,5 +196,47 @@ do_test (int argc, char *argv[])
+ return 0;
+ }
+
++static int
++do_test (int argc, char *argv[])
++{
++ if (restart)
++ return handle_restart (argv[1], argv[2]);
++
++ pid_t pid = xfork ();
++ if (pid == 0)
++ {
++ /* Create a pseudo-terminal to avoid interfering with the one using by
++ test itself, creates a new session (so there is no controlling
++ terminal), and set the pseudo-terminal as the controlling one. */
++ int ptmx = posix_openpt (0);
++ if (ptmx == -1)
++ {
++ if (errno == ENXIO)
++ FAIL_UNSUPPORTED ("terminal not available, skipping test");
++ FAIL_EXIT1 ("posix_openpt (0): %m");
++ }
++ TEST_VERIFY_EXIT (grantpt (ptmx) == 0);
++ TEST_VERIFY_EXIT (unlockpt (ptmx) == 0);
++
++ TEST_VERIFY_EXIT (setsid () != -1);
++ TEST_VERIFY_EXIT (ioctl (ptmx, TIOCSCTTY, NULL) == 0);
++ while (dup2 (ptmx, STDIN_FILENO) == -1 && errno == EBUSY)
++ ;
++ while (dup2 (ptmx, STDOUT_FILENO) == -1 && errno == EBUSY)
++ ;
++ while (dup2 (ptmx, STDERR_FILENO) == -1 && errno == EBUSY)
++ ;
++ TEST_VERIFY_EXIT (ptsname_r (ptmx, ptmxpath, sizeof ptmxpath) == 0);
++ xclose (ptmx);
++
++ run_test (argc, argv);
++ _exit (0);
++ }
++ int status;
++ xwaitpid (pid, &status, 0);
++ TEST_VERIFY (WIFEXITED (status));
++ exit (0);
++}
++
+ #define TEST_FUNCTION_ARGV do_test
+ #include <support/test-driver.c>
+diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
+index 82171bf325..dfc8c2beff 100644
+--- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
++++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c
+@@ -16,9 +16,9 @@
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+-#include <kernel-features.h>
++#include <bits/timesize.h>
+
+-#ifndef __ASSUME_TIME64_SYSCALLS
++#if __TIMESIZE != 64
+ # include <stdint.h>
+ # include <string.h>
+ # include <sys/socket.h>
+diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
+index 4798cc337e..c98c8ce3d4 100644
+--- a/sysdeps/unix/sysv/linux/getsysstats.c
++++ b/sysdeps/unix/sysv/linux/getsysstats.c
+@@ -44,7 +44,7 @@ __get_nprocs_sched (void)
+ int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size,
+ cpu_bits);
+ if (r > 0)
+- return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits);
++ return CPU_COUNT_S (r, (cpu_set_t*) cpu_bits);
+ else if (r == -EINVAL)
+ /* The input buffer is still not enough to store the number of cpus. This
+ is an arbitrary values assuming such systems should be rare and there
+diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/64/configure glibc-2.32/sysdeps/unix/sysv/linux/x86_64/64/configure
+--- glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/64/configure 2021-09-18 21:02:32.741186019 +1000
++++ glibc-2.32/sysdeps/unix/sysv/linux/x86_64/64/configure 2021-09-18 21:03:05.314302356 +1000
+@@ -4,10 +4,10 @@
+ test -n "$libc_cv_slibdir" ||
+ case "$prefix" in
+ /usr | /usr/)
+- libc_cv_slibdir='/lib64'
+- libc_cv_rtlddir='/lib64'
++ libc_cv_slibdir='/lib'
++ libc_cv_rtlddir='/lib'
+ if test "$libdir" = '${exec_prefix}/lib'; then
+- libdir='${exec_prefix}/lib64';
++ libdir='${exec_prefix}/lib';
+ # Locale data can be shared between 32-bit and 64-bit libraries.
+ libc_cv_complocaledir='${exec_prefix}/lib/locale'
+ fi
+diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/ldconfig.h glibc-2.32/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
+--- glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/ldconfig.h 2021-09-18 21:02:32.742186053 +1000
++++ glibc-2.32/sysdeps/unix/sysv/linux/x86_64/ldconfig.h 2021-09-18 21:03:05.314302356 +1000
+@@ -18,9 +18,9 @@
+ #include <sysdeps/generic/ldconfig.h>
+
+ #define SYSDEP_KNOWN_INTERPRETER_NAMES \
+- { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
++ { "/lib32/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
+ { "/libx32/ld-linux-x32.so.2", FLAG_ELF_LIBC6 }, \
+- { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
++ { "/lib/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
+ #define SYSDEP_KNOWN_LIBRARY_NAMES \
+ { "libc.so.6", FLAG_ELF_LIBC6 }, \
+ { "libm.so.6", FLAG_ELF_LIBC6 },

Generated by cgit