about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--config.make.in1
-rwxr-xr-xconfigure25
-rw-r--r--configure.ac9
-rw-r--r--elf/endswith.h33
-rw-r--r--elf/ldconfig.c12
-rw-r--r--elf/readlib.c11
-rw-r--r--libio/Makefile1
-rw-r--r--libio/genops.c3
-rw-r--r--libio/tst-closeall.c34
-rw-r--r--manual/Makefile1
-rw-r--r--manual/dynlink.texi558
-rw-r--r--manual/intro.texi17
-rw-r--r--manual/llio.texi34
-rw-r--r--manual/macros.texi7
-rw-r--r--manual/socket.texi52
-rw-r--r--manual/startup.texi22
-rw-r--r--manual/threads.texi8
-rw-r--r--po/bg.po147
-rw-r--r--socket/Makefile1
-rw-r--r--socket/tst-shutdown.c257
-rw-r--r--stdlib/arc4random.c2
-rw-r--r--sysdeps/m68k/m680x0/fpu/libm-test-ulps451
-rw-r--r--sysdeps/nptl/dl-tls_init_tp.c12
-rw-r--r--sysdeps/riscv/nofpu/libm-test-ulps20
-rw-r--r--sysdeps/unix/sysv/linux/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/dl-rseq-symbols.S64
-rw-r--r--sysdeps/unix/sysv/linux/rseq-internal.h23
-rw-r--r--sysdeps/unix/sysv/linux/tst-rseq.c10
29 files changed, 1656 insertions, 166 deletions
diff --git a/NEWS b/NEWS
index f626896aa0..3824815917 100644
--- a/NEWS
+++ b/NEWS
@@ -49,6 +49,9 @@ Deprecated and removed features, and other changes affecting compatibility:
   <utmpx.h> (except for login_tty) due to locking and session management
   problems.
 
+* __rseq_size now denotes the size of the active rseq area (20 bytes
+  initially), not the size of struct rseq (32 bytes initially).
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/config.make.in b/config.make.in
index 55e8b7563b..36096881b7 100644
--- a/config.make.in
+++ b/config.make.in
@@ -91,6 +91,7 @@ use-nscd = @use_nscd@
 build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
 build-pt-chown = @build_pt_chown@
 pthread-in-libc = @pthread_in_libc@
+man-pages-version = @man_pages_version@
 
 # Build tools.
 CC = @CC@
diff --git a/configure b/configure
index 1bae55b45b..1d543548cd 100755
--- a/configure
+++ b/configure
@@ -699,6 +699,7 @@ force_install
 bindnow
 hardcoded_path_in_tests
 enable_timezone_tools
+man_pages_version
 rtld_early_cflags
 extra_nonshared_cflags
 sysheaders
@@ -782,6 +783,7 @@ with_headers
 with_nonshared_cflags
 with_rtld_early_cflags
 with_timeoutfactor
+with_man_pages
 enable_sanity_checks
 enable_shared
 enable_profile
@@ -1508,6 +1510,8 @@ Optional Packages:
                           build early initialization with additional CFLAGS
   --with-timeoutfactor=NUM
                           specify an integer to scale the timeout
+  --with-man-pages=VERSION
+                          tie manual to a specific man-pages version
   --with-cpu=CPU          select code for CPU variant
 
 Some influential environment variables:
@@ -3868,8 +3872,9 @@ config_vars=
 if test ${enable_static_c___tests+y}
 then :
   enableval=$enable_static_c___tests; static_cxx_tests=$enableval
-else $as_nop
-  static_cxx_tests=yes
+else case e in #(
+  e) static_cxx_tests=yes ;;
+esac
 fi
 
 config_vars="$config_vars
@@ -3879,8 +3884,9 @@ static-cxx-tests = $static_cxx_tests"
 if test ${enable_static_c___link_check+y}
 then :
   enableval=$enable_static_c___link_check; static_cxx_link_check=$enableval
-else $as_nop
-  static_cxx_link_check=yes
+else case e in #(
+  e) static_cxx_link_check=yes ;;
+esac
 fi
 
 
@@ -4469,6 +4475,17 @@ fi
 printf "%s\n" "#define TIMEOUTFACTOR $timeoutfactor" >>confdefs.h
 
 
+man_pages_version=6.9.1
+
+
+# Check whether --with-man-pages was given.
+if test ${with_man_pages+y}
+then :
+  withval=$with_man_pages; man_pages_version=$withval
+fi
+
+
+
 # Check whether --enable-sanity-checks was given.
 if test ${enable_sanity_checks+y}
 then :
diff --git a/configure.ac b/configure.ac
index e48957f318..9cbc0bf68f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -183,6 +183,15 @@ AC_ARG_WITH([timeoutfactor],
 	    [timeoutfactor=1])
 AC_DEFINE_UNQUOTED(TIMEOUTFACTOR, $timeoutfactor)
 
+man_pages_version=6.9.1
+
+AC_ARG_WITH([man-pages],
+	    AS_HELP_STRING([--with-man-pages=VERSION],
+			   [tie manual to a specific man-pages version]),
+	    [man_pages_version=$withval],
+	    [])
+AC_SUBST(man_pages_version)
+
 AC_ARG_ENABLE([sanity-checks],
 	      AS_HELP_STRING([--disable-sanity-checks],
 			     [really do not use threads (should not be used except in special situations) @<:@default=yes@:>@]),
diff --git a/elf/endswith.h b/elf/endswith.h
new file mode 100644
index 0000000000..c6430c48be
--- /dev/null
+++ b/elf/endswith.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2023-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published
+   by the Free Software Foundation; version 2 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _ENDSWITH_H
+#define _ENDSWITH_H
+
+#include <string.h>
+
+/* Return true if the N bytes at NAME end with with the characters in
+   the string SUFFIX.  (NAME[N + 1] does not have to be a null byte.)
+   Expected to be called with a string literal for SUFFIX.  */
+static inline bool
+endswithn (const char *name, size_t n, const char *suffix)
+{
+  return (n >= strlen (suffix)
+	  && memcmp (name + n - strlen (suffix), suffix,
+		     strlen (suffix)) == 0);
+}
+
+#endif /* _ENDSWITH_H */
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index b64c54b53e..0f3ef707dd 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <ldconfig.h>
+#include <endswith.h>
 #include <dl-cache.h>
 #include <dl-hwcaps.h>
 #include <dl-is_dso.h>
@@ -661,17 +662,6 @@ struct dlib_entry
   struct dlib_entry *next;
 };
 
-/* Return true if the N bytes at NAME end with with the characters in
-   the string SUFFIX.  (NAME[N + 1] does not have to be a null byte.)
-   Expected to be called with a string literal for SUFFIX.  */
-static inline bool
-endswithn (const char *name, size_t n, const char *suffix)
-{
-  return (n >= strlen (suffix)
-	  && memcmp (name + n - strlen (suffix), suffix,
-		     strlen (suffix)) == 0);
-}
-
 /* Skip some temporary DSO files.  These files may be partially written
    and lead to ldconfig crashes when examined.  */
 static bool
diff --git a/elf/readlib.c b/elf/readlib.c
index 4d67c74136..f3129c4557 100644
--- a/elf/readlib.c
+++ b/elf/readlib.c
@@ -33,6 +33,7 @@
 #include <gnu/lib-names.h>
 
 #include <ldconfig.h>
+#include <endswith.h>
 
 #define Elf32_CLASS ELFCLASS32
 #define Elf64_CLASS ELFCLASS64
@@ -43,12 +44,14 @@ struct known_names
   int flag;
 };
 
-/* Check if string corresponds to a GDB Python file.  */
+/* Check if string corresponds to a GDB extension file.  */
 static bool
-is_gdb_python_file (const char *name)
+is_gdb_extension_file (const char *name)
 {
   size_t len = strlen (name);
-  return len > 7 && strcmp (name + len - 7, "-gdb.py") == 0;
+  return (endswithn (name, len, "-gdb.gdb")
+	  || endswithn (name, len, "-gdb.py")
+	  || endswithn (name, len, "-gdb.scm"));
 }
 
 /* Returns 0 if everything is ok, != 0 in case of error.  */
@@ -145,7 +148,7 @@ process_file (const char *real_file_name, const char *file_name,
       size_t len = MIN (statbuf.st_size, 512);
       if (memmem (file_contents, len, "GROUP", 5) == NULL
 	  && memmem (file_contents, len, "GNU ld script", 13) == NULL
-	  && !is_gdb_python_file (file_name))
+	  && !is_gdb_extension_file (file_name))
 	error (0, 0, _("%s is not an ELF file - it has the wrong magic bytes at the start.\n"),
 	       file_name);
       ret = 1;
diff --git a/libio/Makefile b/libio/Makefile
index 8720381fdc..6a507b67ea 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -91,6 +91,7 @@ tests = \
   tst-bz24051 \
   tst-bz24153 \
   tst-bz28828 \
+  tst-closeall \
   tst-eof \
   tst-ext \
   tst-ext2 \
diff --git a/libio/genops.c b/libio/genops.c
index 994ee9c0b1..99f5e80f20 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -119,7 +119,8 @@ _IO_link_in (struct _IO_FILE_plus *fp)
       if (_IO_vtable_offset ((FILE *) fp) == 0)
 	{
 	  fp->file._prevchain = (FILE **) &_IO_list_all;
-	  _IO_list_all->file._prevchain = &fp->file._chain;
+	  if (_IO_list_all != NULL)
+	    _IO_list_all->file._prevchain = &fp->file._chain;
 	}
       _IO_list_all = fp;
 #ifdef _IO_MTSAFE_IO
diff --git a/libio/tst-closeall.c b/libio/tst-closeall.c
new file mode 100644
index 0000000000..34f5246490
--- /dev/null
+++ b/libio/tst-closeall.c
@@ -0,0 +1,34 @@
+/* Test that opening a file when all files are closed does not crash (bug 31963)
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+#include <support/xstdio.h>
+
+static int
+do_test (void)
+{
+  xfclose (stdin);
+  xfclose (stdout);
+  xfclose (stderr);
+  FILE *f = xfopen ("/dev/null", "w");
+  fprintf (f, "final\n");
+  xfclose (f);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/manual/Makefile b/manual/Makefile
index b5fda4a7ae..a6c05db540 100644
--- a/manual/Makefile
+++ b/manual/Makefile
@@ -117,6 +117,7 @@ $(objpfx)stamp-pkgvers: $(common-objpfx)config.make
 	  echo "@set PKGVERSION_DEFAULT" >> $(objpfx)pkgvers-tmp; \
 	fi
 	echo "@set REPORT_BUGS_TO $(REPORT_BUGS_TEXI)" >> $(objpfx)pkgvers-tmp
+	echo "@set man_pages_version $(man-pages-version)" >> $(objpfx)pkgvers-tmp; \
 	echo "@end ifclear" >> $(objpfx)pkgvers-tmp
 	$(move-if-change) $(objpfx)pkgvers-tmp $(objpfx)pkgvers.texi
 	touch $@
diff --git a/manual/dynlink.texi b/manual/dynlink.texi
index d71f7a30d6..03565d4fb0 100644
--- a/manual/dynlink.texi
+++ b/manual/dynlink.texi
@@ -15,6 +15,7 @@ Dynamic linkers are sometimes called @dfn{dynamic loaders}.
 @menu
 * Dynamic Linker Invocation::   Explicit invocation of the dynamic linker.
 * Dynamic Linker Introspection::    Interfaces for querying mapping information.
+* Dynamic Linker Hardening::    Avoiding unexpected issues with dynamic linking.
 @end menu
 
 @node Dynamic Linker Invocation
@@ -535,6 +536,563 @@ information is processed.
 This function is a GNU extension.
 @end deftypefun
 
+@node Dynamic Linker Hardening
+@section Avoiding Unexpected Issues With Dynamic Linking
+
+This section details recommendations for increasing application
+robustness, by avoiding potential issues related to dynamic linking.
+The recommendations have two main aims: reduce the involvement of the
+dynamic linker in application execution after process startup, and
+restrict the application to a dynamic linker feature set whose behavior
+is more easily understood.
+
+Key aspects of limiting dynamic linker usage after startup are: no use
+of the @code{dlopen} function, disabling lazy binding, and using the
+static TLS model.  More easily understood dynamic linker behavior
+requires avoiding name conflicts (symbols and sonames) and highly
+customizable features like the audit subsystem.
+
+Note that while these steps can be considered a form of application
+hardening, they do not guard against potential harm from accidental or
+deliberate loading of untrusted or malicious code.  There is only
+limited overlap with traditional security hardening for applications
+running on GNU systems.
+
+@subsection Restricted Dynamic Linker Features
+
+Avoiding certain dynamic linker features can increase predictability of
+applications and reduce the risk of running into dynamic linker defects.
+
+@itemize @bullet
+@item
+Do not use the functions @code{dlopen}, @code{dlmopen}, or
+@code{dlclose}.  Dynamic loading and unloading of shared objects
+introduces substantial complications related to symbol and thread-local
+storage (TLS) management.
+
+@item
+Without the @code{dlopen} function, @code{dlsym} and @code{dlvsym}
+cannot be used with shared object handles.  Minimizing the use of both
+functions is recommended.  If they have to be used, only the
+@code{RTLD_DEFAULT} pseudo-handle should be used.
+
+@item
+Use the local-exec or initial-exec TLS models.  If @code{dlopen} is not
+used, there are no compatibility concerns for initial-exec TLS.  This
+TLS model avoids most of the complexity around TLS access.  In
+particular, there are no TLS-related run-time memory allocations after
+process or thread start.
+
+If shared objects are expected to be used more generally, outside the
+hardened, feature-restricted context, lack of compatibility between
+@code{dlopen} and initial-exec TLS could be a concern.  In that case,
+the second-best alternative is to use global-dynamic TLS with GNU2 TLS
+descriptors, for targets that fully implement them, including the fast
+path for access to TLS variables defined in the initially loaded set of
+objects.  Like initial-exec TLS, this avoids memory allocations after
+thread creation, but only if the @code{dlopen} function is not used.
+
+@item
+Do not use lazy binding.  Lazy binding may require run-time memory
+allocation, is not async-signal-safe, and introduces considerable
+complexity.
+
+@item
+Make dependencies on shared objects explicit.  Do not assume that
+certain libraries (such as @code{libc.so.6}) are always loaded.
+Specifically, if a main program or shared object references a symbol,
+create an ELF @code{DT_NEEDED} dependency on that shared object, or on
+another shared object that is documented (or otherwise guaranteed) to
+have the required explicit dependency.  Referencing a symbol without a
+matching link dependency results in underlinking, and underlinked
+objects cannot always be loaded correctly: Initialization of objects may
+not happen in the required order.
+
+@item
+Do not create dependency loops between shared objects (@code{libA.so.1}
+depending on @code{libB.so.1} depending on @code{libC.so.1} depending on
+@code{libA.so.1}).  @Theglibc{} has to initialize one of the objects in
+the cycle first, and the choice of that object is arbitrary and can
+change over time.  The object which is initialized first (and other
+objects involved in the cycle) may not run correctly because not all of
+its dependencies have been initialized.
+
+Underlinking (see above) can hide the presence of cycles.
+
+@item
+Limit the creation of indirect function (IFUNC) resolvers.  These
+resolvers run during relocation processing, when @theglibc{} is not in
+a fully consistent state.  If you write your own IFUNC resolvers, do
+not depend on external data or function references in those resolvers.
+
+@item
+Do not use the audit functionality (@code{LD_AUDIT}, @code{DT_AUDIT},
+@code{DT_DEPAUDIT}).  Its callback and hooking capabilities introduce a
+lot of complexity and subtly alter dynamic linker behavior in corner
+cases even if the audit module is inactive.
+
+@item
+Do not use symbol interposition.  Without symbol interposition, the
+exact order in which shared objects are searched are less relevant.
+
+Exceptions to this rule are copy relocations (see the next item), and
+vague linkage, as used by the C++ implementation (see below).
+
+@item
+One potential source of symbol interposition is a combination of static
+and dynamic linking, namely linking a static archive into multiple
+dynamic shared objects.  For such scenarios, the static library should
+be converted into its own dynamic shared object.
+
+A different approach to this situation uses hidden visibility for
+symbols in the static library, but this can cause problems if the
+library does not expect that multiple copies of its code coexist within
+the same process, with no or partial sharing of state.
+
+@item
+If you use shared objects that are linked with @option{-Wl,-Bsymbolic}
+(or equivalent) or use protected visibility, the code for the main
+program must be built as @option{-fpic} or @option{-fPIC} to avoid
+creating copy relocations (and the main program must not use copy
+relocations for other reasons).  Using @option{-fpie} or @option{-fPIE}
+is not an alternative to PIC code in this context.
+
+@item
+Be careful about explicit section annotations.  Make sure that the
+target section matches the properties of the declared entity (e.g., no
+writable objects in @code{.text}).
+
+@item
+Ensure that all assembler or object input files have the recommended
+security markup, particularly for non-executable stack.
+
+@item
+Avoid using non-default linker flags and features.  In particular, do
+not use the @code{DT_PREINIT_ARRAY} dynamic tag, and do not flag
+objects as @code{DF_1_INITFIRST}.  Do not change the default linker
+script of BFD ld.  Do not override ABI defaults, such as the dynamic
+linker path (with @option{--dynamic-linker}).
+
+@item
+Some features of @theglibc{} indirectly depend on run-time code loading
+and @code{dlopen}.  Use @code{iconv_open} with built-in converters only
+(such as @code{UTF-8}).  Do not use NSS functionality such as
+@code{getaddrinfo} or @code{getpwuid_r} unless the system is configured
+for built-in NSS service modules only (see below).
+@end itemize
+
+Several considerations apply to ELF constructors and destructors.
+
+@itemize @bullet
+@item
+The dynamic linker does not take constructor and destructor priorities
+into account when determining their execution order.  Priorities are
+only used by the link editor for ordering execution within a
+completely linked object.  If a dynamic shared object needs to be
+initialized before another object, this can be expressed with a
+@code{DT_NEEDED} dependency on the object that needs to be initialized
+earlier.
+
+@item
+The recommendations to avoid cyclic dependencies and symbol
+interposition make it less likely that ELF objects are accessed before
+their ELF constructors have run.  However, using @code{dlsym} and
+@code{dlvsym}, it is still possible to access uninitialized facilities
+even with these restrictions in place.  (Of course, access to
+uninitialized functionality is also possible within a single shared
+object or the main executable, without resorting to explicit symbol
+lookup.)  Consider using dynamic, on-demand initialization instead.  To
+deal with access after de-initialization, it may be necessary to
+implement special cases for that scenario, potentially with degraded
+functionality.
+
+@item
+Be aware that when ELF destructors are executed, it is possible to
+reference already-deconstructed shared objects.  This can happen even in
+the absence of @code{dlsym} and @code{dlvsym} function calls, for
+example if client code using a shared object has registered callbacks or
+objects with another shared object.  The ELF destructor for the client
+code is executed before the ELF destructor for the shared objects that
+it uses, based on the expected dependency order.
+
+@item
+If @code{dlopen} and @code{dlmopen} are not used, @code{DT_NEEDED}
+dependency information is complete, and lazy binding is disabled, the
+execution order of ELF destructors is expected to be the reverse of the
+ELF constructor order.  However, two separate dependency sort operations
+still occur.  Even though the listed preconditions should ensure that
+both sorts produce the same ordering, it is recommended not to depend on
+the destructor order being the reverse of the constructor order.
+@end itemize
+
+The following items provide C++-specific guidance for preparing
+applications.  If another programming language is used and it uses these
+toolchain features targeted at C++ to implement some language
+constructs, these restrictions and recommendations still apply in
+analogous ways.
+
+@itemize @bullet
+@item
+C++ inline functions, templates, and other constructs may need to be
+duplicated into multiple shared objects using vague linkage, resulting
+in symbol interposition.  This type of symbol interposition is
+unproblematic, as long as the C++ one definition rule (ODR) is followed,
+and all definitions in different translation units are equivalent
+according to the language C++ rules.
+
+@item
+Be aware that under C++ language rules, it is unspecified whether
+evaluating a string literal results in the same address for each
+evaluation.  This also applies to anonymous objects of static storage
+duration that GCC creates, for example to implement the compound
+literals C++ extension.  As a result, comparing pointers to such
+objects, or using them directly as hash table keys, may give unexpected
+results.
+
+By default, variables of block scope of static storage have consistent
+addresses across different translation units, even if defined in
+functions that use vague linkage.
+
+@item
+Special care is needed if a C++ project uses symbol visibility or
+symbol version management (for example, the GCC @samp{visibility}
+attribute, the GCC @option{-fvisibility} option, or a linker version
+script with the linker option @option{--version-script}).  It is
+necessary to ensure that the symbol management remains consistent with
+how the symbols are used.  Some C++ constructs are implemented with
+the help of ancillary symbols, which can make complicated to achieve
+consistency.  For example, an inline function that is always inlined
+into its callers has no symbol footprint for the function itself, but
+if the function contains a variable of static storage duration, this
+variable may result in the creation of one or more global symbols.
+For correctness, such symbols must be visible and bound to the same
+object in all other places where the inline function may be called.
+This requirement is not met if the symbol visibility is set to hidden,
+or if symbols are assigned a textually different symbol version
+(effectively creating two distinct symbols).
+
+Due to the complex interaction between ELF symbol management and C++
+symbol generation, it is recommended to use C++ language features for
+symbol management, in particular inline namespaces.
+
+@item
+The toolchain and dynamic linker have multiple mechanisms that bypass
+the usual symbol binding procedures.  This means that the C++ one
+definition rule (ODR) still holds even if certain symbol-based isolation
+mechanisms are used, and object addresses are not shared across
+translation units with incompatible type definitions.
+
+This does not matter if the original (language-independent) advice
+regarding symbol interposition is followed.  However, as the advice may
+be difficult to implement for C++ applications, it is recommended to
+avoid ODR violations across the entire process image.  Inline namespaces
+can be helpful in this context because they can be used to create
+distinct ELF symbols while maintaining source code compatibility at the
+C++ level.
+
+@item
+Be aware that as a special case of interposed symbols, symbols with the
+@code{STB_GNU_UNIQUE} binding type do not follow the usual ELF symbol
+namespace isolation rules: such symbols bind across @code{RTLD_LOCAL}
+boundaries.  Furthermore, symbol versioning is ignored for such symbols;
+they are bound by symbol name only.  All their definitions and uses must
+therefore be compatible.  Hidden visibility still prevents the creation
+of @code{STB_GNU_UNIQUE} symbols and can achieve isolation of
+incompatible definitions.
+
+@item
+C++ constructor priorities only affect constructor ordering within one
+shared object.  Global constructor order across shared objects is
+consistent with ELF dependency ordering if there are no ELF dependency
+cycles.
+
+@item
+C++ exception handling and run-time type information (RTTI), as
+implemented in the GNU toolchain, is not address-significant, and
+therefore is not affected by the symbol binding behaviour of the dynamic
+linker.  This means that types of the same fully-qualified name (in
+non-anonymous namespaces) are always considered the same from an
+exception-handling or RTTI perspective.  This is true even if the type
+information object or vtable has hidden symbol visibility, or the
+corresponding symbols are versioned under different symbol versions, or
+the symbols are not bound to the same objects due to the use of
+@code{RTLD_LOCAL} or @code{dlmopen}.
+
+This can cause issues in applications that contain multiple incompatible
+definitions of the same type.  Inline namespaces can be used to create
+distinct symbols at the ELF layer, avoiding this type of issue.
+
+@item
+C++ exception handling across multiple @code{dlmopen} namespaces may
+not work, particular with the unwinder in GCC versions before 12.
+Current toolchain versions are able to process unwinding tables across
+@code{dlmopen} boundaries.  However, note that type comparison is
+name-based, not address-based (see the previous item), so exception
+types may still be matched in unexpected ways.  An important special
+case of exception handling, invoking destructors for variables of block
+scope, is not impacted by this RTTI type-sharing.  Likewise, regular
+virtual member function dispatch for objects is unaffected (but still
+requires that the type definitions match in all directly involved
+translation units).
+
+Once more, inline namespaces can be used to create distinct ELF symbols
+for different types.
+
+@item
+Although the C++ standard requires that destructors for global objects
+run in the opposite order of their constructors, the Itanium C++ ABI
+requires a different destruction order in some cases.  As a result, do
+not depend on the precise destructor invocation order in applications
+that use @code{dlclose}.
+
+@item
+Registering destructors for later invocation allocates memory and may
+silently fail if insufficient memory is available.  As a result, the
+destructor is never invoked.  This applies to all forms of destructor
+registration, with the exception of thread-local variables (see the next
+item).  To avoid this issue, ensure that such objects merely have
+trivial destructors, avoiding the need for registration, and deallocate
+resources using a different mechanism (for example, from an ELF
+destructor).
+
+@item
+A similar issue exists for @code{thread_local} variables with thread
+storage duration of types that have non-trivial destructors.  However,
+in this case, memory allocation failure during registration leads to
+process termination.  If process termination is not acceptable, use
+@code{thread_local} variables with trivial destructors only.
+Functions for per-thread cleanup can be registered using
+@code{pthread_key_create} (globally for all threads) and activated
+using @code{pthread_setspecific} (on each thread).  Note that a
+@code{pthread_key_create} call may still fail (and
+@code{pthread_create} keys are a limited resource in @theglibc{}), but
+this failure can be handled without terminating the process.
+@end itemize
+
+@subsection Producing Matching Binaries
+
+This subsection recommends tools and build flags for producing
+applications that meet the recommendations of the previous subsection.
+
+@itemize @bullet
+@item
+Use BFD ld (@command{bfd.ld}) from GNU binutils to produce binaries,
+invoked through a compiler driver such as @command{gcc}.  The version
+should be not too far ahead of what was current when the version of
+@theglibc{} was first released.
+
+@item
+Do not use a binutils release that is older than the one used to build
+@theglibc{} itself.
+
+@item
+Compile with @option{-ftls-model=initial-exec} to force the initial-exec
+TLS model.
+
+@item
+Link with @option{-Wl,-z,now} to disable lazy binding.
+
+@item
+Link with @option{-Wl,-z,relro} to enable RELRO (which is the default on
+most targets).
+
+@item
+Specify all direct shared objects dependencies using @option{-l} options
+to avoid underlinking.  Rely on @code{.so} files (which can be linker
+scripts) and searching with the @option{-l} option.  Do not specify the
+file names of shared objects on the linker command line.
+
+@item
+Consider using @option{-Wl,-z,defs} to treat underlinking as an error
+condition.
+
+@item
+When creating a shared object (linked with @option{-shared}), use
+@option{-Wl,-soname,lib@dots{}} to set a soname that matches the final
+installed name of the file.
+
+@item
+Do not use the @option{-rpath} linker option.  (As explained below, all
+required shared objects should be installed into the default search
+path.)
+
+@item
+Use @option{-Wl,--error-rwx-segments} and @option{-Wl,--error-execstack} to
+instruct the link editor to fail the link if the resulting final object
+would have read-write-execute segments or an executable stack.  Such
+issues usually indicate that the input files are not marked up
+correctly.
+
+@item
+Ensure that for each @code{LOAD} segment in the ELF program header, file
+offsets, memory sizes, and load addresses are multiples of the largest
+page size supported at run time.  Similarly, the start address and size
+of the @code{GNU_RELRO} range should be multiples of the page size.
+
+Avoid creating gaps between @code{LOAD} segments.  The difference
+between the load addresses of two subsequent @code{LOAD} segments should
+be the size of the first @code{LOAD} segment.  (This may require linking
+with @option{-Wl,-z,noseparate-code}.)
+
+This may not be possible to achieve with the currently available link
+editors.
+
+@item
+If the multiple-of-page-size criterion for the @code{GNU_RELRO} region
+cannot be achieved, ensure that the process memory image right before
+the start of the region does not contain executable or writable memory.
+@c https://sourceware.org/pipermail/libc-alpha/2022-May/138638.html
+@end itemize
+
+@subsection Checking Binaries
+
+In some cases, if the previous recommendations are not followed, this
+can be determined from the produced binaries.  This section contains
+suggestions for verifying aspects of these binaries.
+
+@itemize @bullet
+@item
+To detect underlinking, examine the dynamic symbol table, for example
+using @samp{readelf -sDW}.  If the symbol is defined in a shared object
+that uses symbol versioning, it must carry a symbol version, as in
+@samp{pthread_kill@@GLIBC_2.34}.
+
+@item
+Examine the dynamic segment with @samp{readelf -dW} to check that all
+the required @code{NEEDED} entries are present.  (It is not necessary to
+list indirect dependencies if these dependencies are guaranteed to
+remain during the evolution of the explicitly listed direct
+dependencies.)
+
+@item
+The @code{NEEDED} entries should not contain full path names including
+slashes, only @code{sonames}.
+
+@item
+For a further consistency check, collect all shared objects referenced
+via @code{NEEDED} entries in dynamic segments, transitively, starting at
+the main program.  Then determine their dynamic symbol tables (using
+@samp{readelf -sDW}, for example).  Ideally, every symbol should be
+defined at most once, so that symbol interposition does not happen.
+
+If there are interposed data symbols, check if the single interposing
+definition is in the main program.  In this case, there must be a copy
+relocation for it.  (This only applies to targets with copy relocations.)
+
+Function symbols should only be interposed in C++ applications, to
+implement vague linkage.  (See the discussion in the C++ recommendations
+above.)
+
+@item
+Using the previously collected @code{NEEDED} entries, check that the
+dependency graph does not contain any cycles.
+
+@item
+The dynamic segment should also mention @code{BIND_NOW} on the
+@code{FLAGS} line or @code{NOW} on the @code{FLAGS_1} line (one is
+enough).
+
+@item
+For shared objects (not main programs), if the program header has a
+@code{PT_TLS} segment, the dynamic segment (as shown by @samp{readelf
+-dW}) should contain the @code{STATIC_TLS} flag on the @code{FLAGS}
+line.
+
+If @code{STATIC_TLS} is missing in shared objects, ensure that the
+appropriate relocations for GNU2 TLS descriptors are used (for example,
+@code{R_AARCH64_TLSDESC} or @code{R_X86_64_TLSDESC}).
+
+@item
+There should not be a reference to the symbols @code{__tls_get_addr},
+@code{__tls_get_offset}, @code{__tls_get_addr_opt} in the dynamic symbol
+table (in the @samp{readelf -sDW} output).  Thread-local storage must be
+accessed using the initial-exec (static) model, or using GNU2 TLS
+descriptors.
+
+@item
+Likewise, the functions @code{dlopen}, @code{dlmopen}, @code{dlclose}
+should not be referenced from the dynamic symbol table.
+
+@item
+For shared objects, there should be a @code{SONAME} entry that matches
+the file name (the base name, i.e., the part after the slash).  The
+@code{SONAME} string must not contain a slash @samp{/}.
+
+@item
+For all objects, the dynamic segment (as shown by @samp{readelf -dW})
+should not contain @code{RPATH} or @code{RUNPATH} entries.
+
+@item
+Likewise, the dynamic segment should not show any @code{AUDIT},
+@code{DEPAUDIT}, @code{AUXILIARY}, @code{FILTER}, or
+@code{PREINIT_ARRAY} tags.
+
+@item
+If the dynamic segment contains a (deprecated) @code{HASH} tag, it
+must also contain a @code{GNU_HASH} tag.
+
+@item
+The @code{INITFIRST} flag (undeer @code{FLAGS_1}) should not be used.
+
+@item
+The program header must not have @code{LOAD} segments that are writable
+and executable at the same time.
+
+@item
+All produced objects should have a @code{GNU_STACK} program header that
+is not marked as executable.  (However, on some newer targets, a
+non-executable stack is the default, so the @code{GNU_STACK} program
+header is not required.)
+@end itemize
+
+@subsection Run-time Considerations
+
+In addition to preparing program binaries in a recommended fashion, the
+run-time environment should be set up in such a way that problematic
+dynamic linker features are not used.
+
+@itemize @bullet
+@item
+Install shared objects using their sonames in a default search path
+directory (usually @file{/usr/lib64}).  Do not use symbolic links.
+@c This is currently not standard practice.
+
+@item
+The default search path must not contain objects with duplicate file
+names or sonames.
+
+@item
+Do not use environment variables (@code{LD_@dots{}} variables such as
+@code{LD_PRELOAD} or @code{LD_LIBRARY_PATH}, or @code{GLIBC_TUNABLES})
+to change default dynamic linker behavior.
+
+@item
+Do not install shared objects in non-default locations.  (Such locations
+are listed explicitly in the configuration file for @command{ldconfig},
+usually @file{/etc/ld.so.conf}, or in files included from there.)
+
+@item
+In relation to the previous item, do not install any objects it
+@code{glibc-hwcaps} subdirectories.
+
+@item
+Do not configure dynamically-loaded NSS service modules, to avoid
+accidental internal use of the @code{dlopen} facility.  The @code{files}
+and @code{dns} modules are built in and do not rely on @code{dlopen}.
+
+@item
+Do not truncate and overwrite files containing programs and shared
+objects in place, while they are used.  Instead, write the new version
+to a different path and use @code{rename} to replace the
+already-installed version.
+
+@item
+Be aware that during a component update procedure that involves multiple
+object files (shared objects and main programs), concurrently starting
+processes may observe an inconsistent combination of object files (some
+already updated, some still at the previous version).  For example,
+this can happen during an update of @theglibc{} itself.
+@end itemize
 
 @c FIXME these are undocumented:
 @c dladdr
diff --git a/manual/intro.texi b/manual/intro.texi
index ff43c5a7fb..879c1b38d9 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -85,6 +85,7 @@ standards each function or symbol comes from.
 * Berkeley Unix::               BSD and SunOS.
 * SVID::                        The System V Interface Description.
 * XPG::                         The X/Open Portability Guide.
+* Linux Kernel::                The Linux kernel.
 @end menu
 
 @node ISO C, POSIX,  , Standards and Portability
@@ -941,7 +942,7 @@ inter-process communication and shared memory, the @code{hsearch} and
 @code{drand48} families of functions, @code{fmtmsg} and several of the
 mathematical functions.
 
-@node XPG, , SVID, Standards and Portability
+@node XPG, Linux Kernel, SVID, Standards and Portability
 @subsection XPG (The X/Open Portability Guide)
 
 The X/Open Portability Guide, published by the X/Open Company, Ltd., is
@@ -960,6 +961,20 @@ fulfilling the XPG standard with the Unix extensions is a
 precondition for getting the Unix brand chances are good that the
 functionality is available on commercial systems.
 
+@node Linux Kernel, , XPG, Standards and Portability
+@subsection Linux (The Linux Kernel)
+
+@Theglibc{} includes by reference the Linux man-pages
+@value{man_pages_version} documentation to document the listed
+syscalls for the Linux kernel. For reference purposes only the latest
+@uref{https://www.kernel.org/doc/man-pages/,Linux man-pages Project}
+documentation can be accessed from the
+@uref{https://www.kernel.org,Linux kernel} website.  Where the syscall
+has more specific documentation in this manual that more specific
+documentation is considered authoritative.
+
+Additional details on the Linux system call interface can be found in
+@xref{System Calls}.
 
 @node Using the Library, Roadmap to the Manual, Standards and Portability, Introduction
 @section Using the Library
diff --git a/manual/llio.texi b/manual/llio.texi
index 78c7c79913..6f0a48609b 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -65,6 +65,7 @@ directly.)
 * Interrupt Input::                     Getting an asynchronous signal when
                                          input arrives.
 * IOCTLs::                              Generic I/O Control operations.
+* Other Low-Level I/O APIs::            Other low-level-I/O-related functions.
 @end menu
 
 
@@ -2324,6 +2325,8 @@ file descriptor, or until the timeout period expires.
 There is another example showing the use of @code{select} to multiplex
 input from multiple sockets in @ref{Server Example}.
 
+For an alternate interface to this functionality, see @code{poll}
+(@pxref{Other Low-Level I/O APIs}).
 
 @node Synchronizing I/O
 @section Synchronizing I/O operations
@@ -3407,7 +3410,9 @@ require additional arguments to be supplied.  These additional arguments
 and the return value and error conditions are given in the detailed
 descriptions of the individual commands.
 
-Briefly, here is a list of what the various commands are.
+Briefly, here is a list of what the various commands are.  For an
+exhaustive list of kernel-specific options, please see @xref{System
+Calls}.
 
 @vtable @code
 @item F_DUPFD
@@ -4743,5 +4748,28 @@ Most IOCTLs are OS-specific and/or only used in special system utilities,
 and are thus beyond the scope of this document.  For an example of the use
 of an IOCTL, see @ref{Out-of-Band Data}.
 
-@c FIXME this is undocumented:
-@c dup3
+@node Other Low-Level I/O APIs
+@section Other low-level-I/O-related functions
+
+@deftp {Data Type} {struct pollfd}
+@standards{POSIX.1,poll.h}
+@end deftp
+
+@deftp {Data Type} {struct epoll_event}
+@standards{Linux,sys/epoll.h}
+@end deftp
+
+@deftypefun int poll (struct pollfd *@var{fds}, nfds_t @var{nfds}, int @var{timeout})
+
+@manpagefunctionstub{poll,2}
+@end deftypefun
+
+@deftypefun int epoll_create(int @var{size})
+
+@manpagefunctionstub{epoll_create,2}
+@end deftypefun
+
+@deftypefun int epoll_wait(int @var{epfd}, struct epoll_event *@var{events}, int @var{maxevents}, int @var{timeout})
+
+@manpagefunctionstub{epoll_wait,2}
+@end deftypefun
diff --git a/manual/macros.texi b/manual/macros.texi
index 4a2e22f473..579da3fb81 100644
--- a/manual/macros.texi
+++ b/manual/macros.texi
@@ -282,4 +282,11 @@ cwd\comments\
 @macro standardsx {element, standard, header}
 @end macro
 
+@macro manpagefunctionstub {func,sec}
+This documentation is a stub.  For additional information on this
+function, consult the manual page
+@url{https://man7.org/linux/man-pages/man\sec\/\func\.\sec\.html}.
+@xref{Linux Kernel}.
+@end macro
+
 @end ifclear
diff --git a/manual/socket.texi b/manual/socket.texi
index f0e35d9e13..8708cbb07c 100644
--- a/manual/socket.texi
+++ b/manual/socket.texi
@@ -41,6 +41,7 @@ aren't documented either so far.
 			   is to make it work with Inetd.
 * Socket Options::	Miscellaneous low-level socket options.
 * Networks Database::   Accessing the database of network names.
+* Other Socket APIs::   Other socket-related functions.
 @end menu
 
 @node Socket Concepts
@@ -3134,38 +3135,8 @@ You can use plain @code{recv} (@pxref{Receiving Data}) instead of
 treat all possible senders alike).  Even @code{read} can be used if
 you don't want to specify @var{flags} (@pxref{I/O Primitives}).
 
-@ignore
-@c sendmsg and recvmsg are like readv and writev in that they
-@c use a series of buffers.  It's not clear this is worth
-@c supporting or that we support them.
-@c !!! they can do more; it is hairy
-
-@deftp {Data Type} {struct msghdr}
-@standards{BSD, sys/socket.h}
-@end deftp
-
-@deftypefun ssize_t sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags})
-@standards{BSD, sys/socket.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-This function is defined as a cancellation point in multi-threaded
-programs, so one has to be prepared for this and make sure that
-allocated resources (like memory, files descriptors, semaphores or
-whatever) are freed even if the thread is cancel.
-@c @xref{pthread_cleanup_push}, for a method how to do this.
-@end deftypefun
-
-@deftypefun ssize_t recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags})
-@standards{BSD, sys/socket.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-
-This function is defined as a cancellation point in multi-threaded
-programs, so one has to be prepared for this and make sure that
-allocated resources (like memory, files descriptors, semaphores or
-whatever) are freed even if the thread is canceled.
-@c @xref{pthread_cleanup_push}, for a method how to do this.
-@end deftypefun
-@end ignore
+If you need more flexibility and/or control over sending and receiving
+packets, see @code{sendmsg} and @code{recvmsg} (@pxref{Other Socket APIs}).
 
 @node Datagram Example
 @subsection Datagram Socket Example
@@ -3664,3 +3635,20 @@ returns a null pointer if there are no more entries.
 @c  libc_lock_unlock @aculock
 This function closes the networks database.
 @end deftypefun
+
+@node Other Socket APIs
+@section Other Socket APIs
+
+@deftp {Data Type} {struct msghdr}
+@standards{BSD, sys/socket.h}
+@end deftp
+
+@deftypefun ssize_t sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags})
+
+@manpagefunctionstub{sendmsg,2}
+@end deftypefun
+
+@deftypefun ssize_t recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags})
+
+@manpagefunctionstub{recvmsg,2}
+@end deftypefun
diff --git a/manual/startup.texi b/manual/startup.texi
index 224dd98c1e..747beed4d9 100644
--- a/manual/startup.texi
+++ b/manual/startup.texi
@@ -689,7 +689,25 @@ you don't need to know about it because you can just use @theglibc{}'s
 @code{chmod} function.
 
 @cindex kernel call
-System calls are sometimes called kernel calls.
+System calls are sometimes called syscalls or kernel calls, and this
+interface is mostly a purely mechanical translation from the kernel's
+ABI to the C ABI. For the set of syscalls where we do not guarantee
+POSIX Thread cancellation the wrappers only organize the incoming
+arguments from the C calling convention to the calling convention of
+the target kernel. For the set of syscalls where we provided POSIX
+Thread cancellation the wrappers set some internal state in the
+library to support cancellation, but this does not impact the
+behaviour of the syscall provided by the kernel.
+
+In some cases, if @theglibc{} detects that a system call has been
+superseded by a more capable one, the wrapper may map the old call to
+the new one.  For example, @code{dup2} is implemented via @code{dup3}
+by passing an additional empty flags argument, and @code{open} calls
+@code{openat} passing the additional @code{AT_FDCWD}.  Sometimes even
+more is done, such as converting between 32-bit and 64-bit time
+values.  In general, though, such processing is only to make the
+system call better match the C ABI, rather than change its
+functionality.
 
 However, there are times when you want to make a system call explicitly,
 and for that, @theglibc{} provides the @code{syscall} function.
@@ -711,6 +729,8 @@ we won't describe it here either because anyone who is coding
 library source code as a specification of the interface between them
 anyway.
 
+@code{syscall} does not provide cancellation logic, even if the system
+call you're calling is listed as cancellable above.
 
 @code{syscall} is declared in @file{unistd.h}.
 
diff --git a/manual/threads.texi b/manual/threads.texi
index e5544ff3da..25e99c9606 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -1007,8 +1007,12 @@ This variable is either zero (if restartable sequence registration
 failed or has been disabled) or the size of the restartable sequence
 registration.  This can be different from the size of @code{struct rseq}
 if the kernel has extended the size of the registration.  If
-registration is successful, @code{__rseq_size} is at least 32 (the
-initial size of @code{struct rseq}).
+registration is successful, @code{__rseq_size} is at least 20 (the
+initially active size of @code{struct rseq}).
+
+Previous versions of @theglibc{} set this to 32 even if the kernel only
+supported the initial area of 20 bytes because the value included unused
+padding at the end of the restartable sequence area.
 @end deftypevar
 
 @deftypevar {unsigned int} __rseq_flags
diff --git a/po/bg.po b/po/bg.po
index 875ea57eb6..c69a48331a 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -10,9 +10,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: libc 2.38.9000\n"
+"Project-Id-Version: libc 2.39.9000\n"
 "POT-Creation-Date: 2024-06-19 22:30+0200\n"
-"PO-Revision-Date: 2024-01-04 09:04+0300\n"
+"PO-Revision-Date: 2024-07-01 08:04+0300\n"
 "Last-Translator: Roumen Petrov <transl@roumenpetrov.info>\n"
 "Language-Team: Bulgarian <dict@ludost.net>\n"
 "Language: bg\n"
@@ -4689,7 +4689,7 @@ msgstr ""
 #: nss/makedb.c:229
 #, c-format
 msgid "cannot open database file `%s'"
-msgstr "не може да Ñе отвори файлът на базата данни: \"%s\""
+msgstr "не може да Ñе отвори файлът на базата данни: '%s'"
 
 #: nss/makedb.c:274
 #, c-format
@@ -6545,6 +6545,26 @@ msgstr "не може да Ñе забрани разрешенната подр
 msgid "can't disable SHSTK"
 msgstr "не може да Ñе забрани разрешенната подръжка на SHSTK"
 
+#: timezone/zdump.c:131
+#, c-format
+msgid "%s: size overflow\n"
+msgstr "%s: препълване на ÑтойноÑтта за размер\n"
+
+#: timezone/zdump.c:170
+#, c-format
+msgid "%s: Memory exhausted\n"
+msgstr "%s: Изчерпана памет\n"
+
+#: timezone/zdump.c:257
+#, c-format
+msgid "%s: setenv: %s\n"
+msgstr "%s: уÑтановÑване на обкръжение: %s\n"
+
+#: timezone/zdump.c:337 timezone/zdump.c:604
+#, c-format
+msgid "%s: unknown timezone '%s': %s\n"
+msgstr "%s: неизвеÑтно времева зона '%s': %s\n"
+
 #: timezone/zdump.c:402
 msgid "has characters other than ASCII alphanumerics, '-' or '+'"
 msgstr "е Ñ Ð±ÑƒÐºÐ²Ð¸ извън ASCII букви или цифри, '-' или '+'"
@@ -6599,6 +6619,16 @@ msgstr "%s: безумен -c аргумент %s\n"
 msgid "%s: wild -t argument %s\n"
 msgstr "%s: безумен -t аргумент %s\n"
 
+#: timezone/zdump.c:857
+#, c-format
+msgid " (gmtime failed)"
+msgstr " (пропадна gmtime)"
+
+#: timezone/zdump.c:867
+#, c-format
+msgid " (localtime failed)"
+msgstr " (пропадна localtime)"
+
 #: timezone/zic.c:463
 #, c-format
 msgid "%s: Memory exhausted: %s\n"
@@ -6635,11 +6665,50 @@ msgstr " (правило от \"%s\", ред %<PRIdMAX>)"
 msgid "warning: "
 msgstr "предупреждение: "
 
+#: timezone/zic.c:669
+#, c-format
+msgid ""
+"%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n"
+"\t[ -b {slim|fat} ] [ -d directory ] [ -l localtime ] [ -L leapseconds ] \\\n"
+"\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -R '@hi' ] \\\n"
+"\t[ -t localtime-link ] \\\n"
+"\t[ filename ... ]\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"%s: употребата е %s [ --version ] [ --help ] [ -v ] \\\n"
+"\t[ -b {slim|fat} ] [ -d Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ ] [ -l меÑтновреме ] [ -L виÑокоÑниÑекунди ]\\\n"
+"\t[ -p posix_правило ] [ -r '[@lo][/@hi]' ] [ -R '@hi' ] \\\n"
+"\t[ -t връзка–към–меÑтновреме ] \\\n"
+"\t[ именафайл ... ]\n"
+"\n"
+"Докладване на грешки към %s.\n"
+
 #: timezone/zic.c:695
 #, c-format
 msgid "%s: Can't chdir to %s: %s\n"
 msgstr "%s: Ðе може да Ñе Ñмени директориÑта на %s: %s\n"
 
+#: timezone/zic.c:786
+#, c-format
+msgid "\"Link %s %s\" is part of a link cycle"
+msgstr "\"Връзката %s %s\" е чаÑÑ‚ от цикъл Ñ Ð²Ñ€ÑŠÐ·ÐºÐ¸"
+
+#: timezone/zic.c:797
+#, c-format
+msgid "link %s targets itself"
+msgstr "връзката %s е към Ñебе Ñи"
+
+#: timezone/zic.c:817
+#, c-format
+msgid "link %s targeting link %s mishandled by pre-2023 zic"
+msgstr "zic, преди 2023, не Ñе ÑÐ¿Ñ€Ð°Ð²Ñ Ð´Ð¾Ð±Ñ€Ðµ при връзка %s целÑща връзка %s"
+
+#: timezone/zic.c:821
+#, c-format
+msgid "link %s targeting link %s"
+msgstr "връка %s към връзка %s"
+
 #: timezone/zic.c:992
 msgid "wild compilation-time specification of zic_t"
 msgstr "при компилирането е зададен безумен тип за zic_t"
@@ -6673,6 +6742,10 @@ msgstr "%s: Зададена е повече от една Ð¾Ð¿Ñ†Ð¸Ñ -p\n"
 msgid "%s: More than one -t option specified\n"
 msgstr "%s: Зададена е повече от една Ð¾Ð¿Ñ†Ð¸Ñ -t\n"
 
+#: timezone/zic.c:1064
+msgid "-y ignored"
+msgstr "-y пренебрегнат"
+
 #: timezone/zic.c:1071
 #, c-format
 msgid "%s: More than one -L option specified\n"
@@ -6688,10 +6761,20 @@ msgstr "%s: Зададена е повече от една Ð¾Ð¿Ñ†Ð¸Ñ -r\n"
 msgid "%s: invalid time range: %s\n"
 msgstr "%s: неправилен времеви диапазон: %s\n"
 
+#: timezone/zic.c:1098
+#, c-format
+msgid "%s: invalid time: %s\n"
+msgstr "%s: неправилно време: %s\n"
+
 #: timezone/zic.c:1104
 msgid "-s ignored"
 msgstr "-s пренебрегнат"
 
+#: timezone/zic.c:1110
+#, c-format
+msgid "%s: -R time exceeds -r cutoff\n"
+msgstr "%s: -R 'време' превишава -r 'отрÑзък'\n"
+
 #: timezone/zic.c:1171
 msgid "empty file name"
 msgstr "празно име на файл"
@@ -6731,11 +6814,21 @@ msgstr "името на файла '%s' Ñъдържа байт '\\%o'"
 msgid "%s: Can't create %s/%s: %s\n"
 msgstr "%s: Ðе може да Ñе Ñъздаде %s/%s: %s\n"
 
+#: timezone/zic.c:1388
+#, c-format
+msgid "%s: rename to %s/%s: %s\n"
+msgstr "%s: преименуване на %s/%s: %s\n"
+
 #: timezone/zic.c:1463
 #, c-format
 msgid "%s: Can't remove %s/%s: %s\n"
 msgstr "%s: Ðе може да Ñе изтрие %s/%s: %s\n"
 
+#: timezone/zic.c:1507
+#, c-format
+msgid "%s: Can't link %s/%s to %s/%s: %s\n"
+msgstr "%s: Ðе може да Ñе Ñвърже %s/%s към %s/%s: %s\n"
+
 #: timezone/zic.c:1536
 #, c-format
 msgid "symbolic link used because hard link failed: %s"
@@ -6765,6 +6858,18 @@ msgstr "едно и Ñъщо име на правило в много файло
 msgid "%s in ruleless zone"
 msgstr "%s в зона без правила"
 
+#: timezone/zic.c:1674
+msgid "input error"
+msgstr "входна грешка"
+
+#: timezone/zic.c:1679
+msgid "unterminated line"
+msgstr "незавършен ред"
+
+#: timezone/zic.c:1683
+msgid "NUL input byte"
+msgstr "NUL входÑщ байт"
+
 #: timezone/zic.c:1688
 msgid "line too long"
 msgstr "Твърде дълъг ред"
@@ -6899,6 +7004,15 @@ msgstr "многократни редове Expires"
 msgid "wrong number of fields on Link line"
 msgstr "неправилен брой полета на ред за Link"
 
+#: timezone/zic.c:2129
+msgid "blank TARGET field on Link line"
+msgstr "празно поле TARGET на ред за Link"
+
+#: timezone/zic.c:2192
+#, c-format
+msgid "FROM year \"%s\" is obsolete; treated as %d"
+msgstr "'от година' \"%s\" е отживелица, замеÑтено Ñ %d"
+
 #: timezone/zic.c:2199
 msgid "invalid starting year"
 msgstr "неправилна начална година"
@@ -6911,6 +7025,11 @@ msgstr "неправилна крайна година"
 msgid "starting year greater than ending year"
 msgstr "началната година е по-голÑма от крайната"
 
+#: timezone/zic.c:2222
+#, c-format
+msgid "year type \"%s\" is unsupported; use \"-\" instead"
+msgstr "тип на годината \"%s\" не Ñе поддържа, да Ñе използва \"-\""
+
 #: timezone/zic.c:2257
 msgid "invalid weekday name"
 msgstr "неправилно име на ден от Ñедмицата"
@@ -6924,6 +7043,16 @@ msgstr "нÑкой клиенти, Ñе ÑправÑÑ‚ зле при повечÐ
 msgid "pre-2014 clients may mishandle more than 1200 transition times"
 msgstr "клиенти преди 2014, може да не Ñе ÑправÑÑ‚ правилно при повече от 1200 прехода"
 
+#: timezone/zic.c:2480
+#, c-format
+msgid "%s: pre-2021b clients may mishandle leap second expiry"
+msgstr "%s: клиенти преди 2021b , може да не Ñе ÑправÑÑ‚ Ñ Ð¸Ð·Ñ‚Ð¸Ñ‡Ð°Ð½ÐµÑ‚Ð¾ на дългата Ñекунда"
+
+#: timezone/zic.c:2488
+#, c-format
+msgid "%s: pre-2021b clients may mishandle leap second table truncation"
+msgstr "%s: клиенти преди 2021b , може да не Ñе ÑправÑÑ‚ ÑÑŠÑ Ñъкращаването на таблицата Ñ Ð´ÑŠÐ»Ð³Ð¸ Ñекунди"
+
 #: timezone/zic.c:2537
 msgid "too many transition times"
 msgstr "твърде много типове за преход"
@@ -6933,6 +7062,10 @@ msgstr "твърде много типове за преход"
 msgid "%%z UT offset magnitude exceeds 99:59:59"
 msgstr "%%z ОтмеÑтването ÑпрÑмо универÑалноте време превишава 99:59:59"
 
+#: timezone/zic.c:3180
+msgid "no POSIX.1-2017 environment variable for zone"
+msgstr "в обкръжението, липÑва POSIX.1-2017 променлива за зона"
+
 #: timezone/zic.c:3187
 #, c-format
 msgid "%s: pre-%d clients may mishandle distant timestamps"
@@ -6958,6 +7091,10 @@ msgstr "твърде много типове за меÑтно време"
 msgid "too many leap seconds"
 msgstr "твърде много виÑокоÑни Ñекунди"
 
+#: timezone/zic.c:3535
+msgid "Rolling leap seconds not supported with -r"
+msgstr "Претълкалване на дълга Ñекунда не Ñе поддръжа Ñ -r"
+
 #: timezone/zic.c:3562
 msgid "Leap seconds too close together"
 msgstr "твърде близки виÑокоÑни Ñекунди"
@@ -6980,6 +7117,10 @@ msgstr "\"%s\" е двуÑмиÑлен за zic от преди 2017c"
 msgid "Odd number of quotation marks"
 msgstr "Ðеочакван брой кавички"
 
+#: timezone/zic.c:3750
+msgid "Too many input fields"
+msgstr "Твърде много входÑщи полета"
+
 #: timezone/zic.c:3839
 msgid "use of 2/29 in non leap-year"
 msgstr "използване на 29.2 за невиÑокоÑна година"
diff --git a/socket/Makefile b/socket/Makefile
index fc1bd0a260..df732fa9b7 100644
--- a/socket/Makefile
+++ b/socket/Makefile
@@ -71,6 +71,7 @@ tests := \
   tst-cmsg_cloexec \
   tst-cmsghdr \
   tst-connect \
+  tst-shutdown \
   tst-sockopt \
   # tests
 
diff --git a/socket/tst-shutdown.c b/socket/tst-shutdown.c
new file mode 100644
index 0000000000..a305e5e494
--- /dev/null
+++ b/socket/tst-shutdown.c
@@ -0,0 +1,257 @@
+/* Test the shutdown function.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xsocket.h>
+#include <support/xunistd.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+
+struct connection
+{
+  int sockets[2];
+};
+
+void
+establish_connection (struct connection *conn)
+{
+  if (socketpair (AF_UNIX, SOCK_STREAM, 0, conn->sockets) != 0)
+    {
+      FAIL_EXIT1 ("socketpair (AF_UNIX, SOCK_STREAM, 0): %m\n");
+    }
+}
+
+void
+close_connection (struct connection *conn)
+{
+  xclose (conn->sockets[0]);
+  xclose (conn->sockets[1]);
+}
+
+/* Open a file and check that shutdown fails with the ENOTSOCK error code.  */
+void
+do_test_enotsock (void)
+{
+  /* Open file and check that shutdown will fail with ENOTSOCK.  */
+  int fd = xopen ("/dev/null", O_RDWR, 0);
+
+  int result = shutdown (fd, SHUT_RD);
+  if (result == 0 || errno != ENOTSOCK)
+    {
+      FAIL_EXIT1 ("shutdown should fail with ENOTSOCK");
+    }
+  xclose (fd);
+}
+
+/* Test shutdown with SHUT_RD.  */
+void
+do_test_shut_rd (void)
+{
+  struct connection conn;
+  const char *str = "AAAAAAA";
+  int len = 8;
+  int ret;
+  void *s_buf = xmalloc (len);
+  bzero (s_buf, len);
+
+  establish_connection (&conn);
+  int server = conn.sockets[0];
+  int client = conn.sockets[1];
+
+  /* Call shutdown with SHUT_RD on server socket.  */
+  if (shutdown (server, SHUT_RD) != 0)
+    {
+      FAIL_EXIT1 ("shutdown with SHUT_RD on socket %d failed", server);
+    }
+
+  ret = send (server, str, len, 0);
+  if (ret <= 0)
+    {
+      FAIL_EXIT1 ("send (%d, data, %d): %m", server, len);
+    }
+
+  ret = recv (client, s_buf, len, 0);
+  if (ret <= 0)
+    {
+      FAIL_EXIT1 ("recv (%d, data, %d): %m", client, len);
+    }
+
+  TEST_COMPARE_BLOB (str, len, s_buf, len);
+
+  /* Send data should be disallowed on shutdown socket.  */
+  errno = 0;
+  ret = send (client, str, len, MSG_NOSIGNAL);
+  if (ret >= 0 || errno != EPIPE)
+    {
+      FAIL_EXIT1 ("Send on SHUT_RD socket should be disallowed: %m");
+    }
+
+  /* Recv should return zero and no error.  */
+  errno = 0;
+  ret = recv (server, s_buf, len, 0);
+  if (ret != 0 || errno != 0)
+    {
+      FAIL_EXIT1 ("recv should return 0 without error: %m");
+    }
+
+  close_connection (&conn);
+}
+
+/* Test shutdown with SHUT_WR.  */
+void
+do_test_shut_wr (void)
+{
+  struct connection conn;
+  const char *str1 = "CCCCCCC";
+  const char *str2 = "DDDDDDD";
+  const char *str3 = "EEEEEEE";
+  int len = 8;
+  int ret;
+  void *c_buf = xmalloc (len);
+  void *s_buf = xmalloc (len);
+
+  establish_connection (&conn);
+  int server = conn.sockets[0];
+  int client = conn.sockets[1];
+
+  xwrite (client, str1, len);
+
+  if (shutdown (client, SHUT_WR) != 0)
+    {
+      FAIL_EXIT1 ("shutdown with SHUT_WR on socket %d failed", client);
+    }
+
+  ret = send (client, str2, len, MSG_NOSIGNAL);
+  if (ret >= 0)
+    {
+      FAIL_EXIT1 ("send on SHUT_WR socket should fail");
+    }
+
+  /* Read data written before shutdown and check if it's correct.  */
+  xread (server, s_buf, len);
+  TEST_COMPARE_BLOB (str1, len, s_buf, len);
+
+  /* Second read should return zero without error.  */
+  errno = 0;
+  if (read (server, s_buf, len) != 0 || errno != 0)
+    {
+      FAIL_EXIT1 ("read after shutdown should return zero without error: %m");
+    }
+
+  /* Write some data to socket and check it still can be read on other side.  */
+  memcpy (s_buf, str3, len);
+  xwrite (server, s_buf, len);
+
+  xread (client, c_buf, len);
+  TEST_COMPARE_BLOB (s_buf, len, c_buf, len);
+
+  close_connection (&conn);
+}
+
+/* Test shutdown with SHUT_RDWR.  */
+void
+do_test_shut_rdwr (void)
+{
+  struct connection conn;
+  struct sockaddr peer;
+  socklen_t peer_len = sizeof (peer);
+
+  const char *str1 = "FFFFFFF";
+  const char *str2 = "GGGGGGG";
+  int len = 8;
+  int ret;
+  void *s_buf = xmalloc (len);
+  bzero (s_buf, len);
+
+  establish_connection (&conn);
+  int server = conn.sockets[0];
+  int client = conn.sockets[1];
+
+  /* Send some data to both sockets before shutdown.  */
+  xwrite (client, str1, len);
+  xwrite (server, str2, len);
+
+  /* Call shutdown with SHUT_RDWR on client socket.  */
+  if (shutdown (client, SHUT_RDWR) != 0)
+    {
+      FAIL_EXIT1 ("shutdown with SHUT_RDWR on socket %d failed", client);
+    }
+
+  /* Verify that socket is still connected.  */
+  xgetsockname (client, &peer, &peer_len);
+
+  /* Read data written before shutdown.  */
+  xread (client, s_buf, len);
+  TEST_COMPARE_BLOB (s_buf, len, str2, len);
+
+  /* Second read should return zero, but no error.  */
+  errno = 0;
+  if (read (client, s_buf, len) != 0 || errno != 0)
+    {
+      FAIL_EXIT1 ("read after shutdown should return zero without error: %m");
+    }
+
+  /* Send some data to shutdown socket and expect error.  */
+  errno = 0;
+  ret = send (server, str2, len, MSG_NOSIGNAL);
+  if (ret >= 0 || errno != EPIPE)
+    {
+      FAIL_EXIT1 ("send to RDWR shutdown socket should fail with EPIPE");
+    }
+
+  /* Read data written before shutdown.  */
+  xread (server, s_buf, len);
+  TEST_COMPARE_BLOB (s_buf, len, str1, len);
+
+  /* Second read should return zero, but no error.  */
+  errno = 0;
+  if (read (server, s_buf, len) != 0 || errno != 0)
+    {
+      FAIL_EXIT1 ("read after shutdown should return zero without error: %m");
+    }
+
+  /* Send some data to shutdown socket and expect error.  */
+  errno = 0;
+  ret = send (client, str1, len, MSG_NOSIGNAL);
+  if (ret >= 0 || errno != EPIPE)
+    {
+      FAIL_EXIT1 ("send to RDWR shutdown socket should fail with EPIPE");
+    }
+
+  close_connection (&conn);
+}
+
+static int
+do_test (void)
+{
+  do_test_enotsock ();
+  do_test_shut_rd ();
+  do_test_shut_wr ();
+  do_test_shut_rdwr ();
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/arc4random.c b/stdlib/arc4random.c
index 3ae8fc1302..7818cb9cf6 100644
--- a/stdlib/arc4random.c
+++ b/stdlib/arc4random.c
@@ -51,7 +51,7 @@ __arc4random_buf (void *p, size_t n)
 	  n -= l;
 	  continue; /* Interrupted by a signal; keep going.  */
 	}
-      else if (l == -ENOSYS)
+      else if (l < 0 && errno == ENOSYS)
 	break; /* No syscall, so fallback to /dev/urandom.  */
       arc4random_getrandom_failure ();
     }
diff --git a/sysdeps/m68k/m680x0/fpu/libm-test-ulps b/sysdeps/m68k/m680x0/fpu/libm-test-ulps
index b957e7b5d1..6eacfb6b6f 100644
--- a/sysdeps/m68k/m680x0/fpu/libm-test-ulps
+++ b/sysdeps/m68k/m680x0/fpu/libm-test-ulps
@@ -7,12 +7,12 @@ float: 1
 ldouble: 1
 
 Function: "acosh_downward":
-double: 1
+double: 2
 float: 1
 ldouble: 1
 
 Function: "acosh_towardzero":
-double: 1
+double: 2
 float: 1
 ldouble: 1
 
@@ -21,6 +21,21 @@ double: 2
 float: 1
 ldouble: 1
 
+Function: "asin":
+double: 1
+
+Function: "asin_downward":
+double: 1
+float: 1
+
+Function: "asin_towardzero":
+double: 1
+float: 1
+
+Function: "asin_upward":
+double: 1
+float: 1
+
 Function: "asinh":
 double: 1
 float: 1
@@ -42,6 +57,7 @@ float: 2
 ldouble: 3
 
 Function: "atan2":
+double: 1
 float: 1
 ldouble: 1
 
@@ -66,6 +82,7 @@ float: 1
 ldouble: 1
 
 Function: "atan_towardzero":
+double: 1
 float: 1
 ldouble: 1
 
@@ -74,6 +91,17 @@ double: 1
 float: 1
 ldouble: 1
 
+Function: "atanh":
+double: 1
+
+Function: "atanh_downward":
+double: 1
+float: 1
+
+Function: "atanh_upward":
+double: 1
+float: 1
+
 Function: "cabs":
 double: 1
 ldouble: 1
@@ -147,7 +175,7 @@ ldouble: 4
 
 Function: Imaginary part of "cacosh_downward":
 double: 2
-float: 2
+float: 3
 ldouble: 2
 
 Function: Real part of "cacosh_towardzero":
@@ -166,7 +194,7 @@ float: 5
 ldouble: 4
 
 Function: Imaginary part of "cacosh_upward":
-double: 2
+double: 3
 float: 2
 ldouble: 3
 
@@ -180,6 +208,7 @@ float: 1
 ldouble: 1
 
 Function: "carg_towardzero":
+double: 1
 float: 1
 ldouble: 1
 
@@ -199,7 +228,7 @@ float: 1
 ldouble: 2
 
 Function: Real part of "casin_downward":
-double: 2
+double: 3
 float: 2
 ldouble: 2
 
@@ -209,7 +238,7 @@ float: 3
 ldouble: 4
 
 Function: Real part of "casin_towardzero":
-double: 1
+double: 3
 float: 2
 ldouble: 2
 
@@ -224,7 +253,7 @@ float: 2
 ldouble: 2
 
 Function: Imaginary part of "casin_upward":
-double: 4
+double: 5
 float: 5
 ldouble: 4
 
@@ -244,7 +273,7 @@ float: 3
 ldouble: 4
 
 Function: Imaginary part of "casinh_downward":
-double: 2
+double: 3
 float: 2
 ldouble: 2
 
@@ -254,7 +283,7 @@ float: 3
 ldouble: 4
 
 Function: Imaginary part of "casinh_towardzero":
-double: 1
+double: 3
 float: 2
 ldouble: 2
 
@@ -269,6 +298,8 @@ float: 2
 ldouble: 2
 
 Function: Real part of "catan":
+double: 1
+float: 1
 ldouble: 1
 
 Function: Imaginary part of "catan":
@@ -283,7 +314,7 @@ ldouble: 1
 
 Function: Imaginary part of "catan_downward":
 double: 2
-float: 1
+float: 2
 ldouble: 3
 
 Function: Real part of "catan_towardzero":
@@ -312,11 +343,13 @@ float: 1
 ldouble: 1
 
 Function: Imaginary part of "catanh":
+double: 1
+float: 1
 ldouble: 1
 
 Function: Real part of "catanh_downward":
 double: 2
-float: 1
+float: 2
 ldouble: 3
 
 Function: Imaginary part of "catanh_downward":
@@ -365,60 +398,78 @@ float: 1
 ldouble: 1
 
 Function: Real part of "ccos":
+float: 1
 ldouble: 1
 
 Function: Imaginary part of "ccos":
+float: 1
 ldouble: 1
 
 Function: Real part of "ccos_downward":
 double: 1
+float: 1
 ldouble: 2
 
 Function: Imaginary part of "ccos_downward":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "ccos_towardzero":
 double: 1
+float: 1
 ldouble: 2
 
 Function: Imaginary part of "ccos_towardzero":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "ccos_upward":
 double: 1
+float: 1
 ldouble: 2
 
 Function: Imaginary part of "ccos_upward":
 double: 1
+float: 2
 ldouble: 2
 
+Function: Real part of "ccosh":
+float: 1
+
 Function: Imaginary part of "ccosh":
+float: 1
 ldouble: 1
 
 Function: Real part of "ccosh_downward":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "ccosh_downward":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "ccosh_towardzero":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "ccosh_towardzero":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "ccosh_upward":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "ccosh_upward":
 double: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "cexp":
@@ -449,15 +500,17 @@ ldouble: 3
 
 Function: Real part of "cexp_upward":
 double: 1
+float: 1
 ldouble: 2
 
 Function: Imaginary part of "cexp_upward":
 double: 1
+float: 1
 ldouble: 2
 
 Function: Real part of "clog":
 double: 3
-float: 2
+float: 3
 ldouble: 3
 
 Function: Imaginary part of "clog":
@@ -467,12 +520,12 @@ ldouble: 1
 
 Function: Real part of "clog10":
 double: 2
-float: 2
+float: 3
 ldouble: 3
 
 Function: Imaginary part of "clog10":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "clog10_downward":
@@ -482,17 +535,17 @@ ldouble: 7
 
 Function: Imaginary part of "clog10_downward":
 double: 1
-float: 2
+float: 3
 ldouble: 4
 
 Function: Real part of "clog10_towardzero":
 double: 6
-float: 4
+float: 5
 ldouble: 7
 
 Function: Imaginary part of "clog10_towardzero":
 double: 1
-float: 2
+float: 3
 ldouble: 4
 
 Function: Real part of "clog10_upward":
@@ -502,7 +555,7 @@ ldouble: 6
 
 Function: Imaginary part of "clog10_upward":
 double: 1
-float: 2
+float: 3
 ldouble: 3
 
 Function: Real part of "clog_downward":
@@ -537,6 +590,23 @@ ldouble: 2
 
 Function: "cos":
 double: 1
+float: 6
+
+Function: "cos_downward":
+float: 5
+
+Function: "cos_towardzero":
+float: 5
+
+Function: "cos_upward":
+float: 5
+
+Function: "cosh":
+double: 1
+
+Function: "cosh_upward":
+double: 1
+float: 1
 
 Function: Real part of "cpow":
 double: 1
@@ -578,11 +648,15 @@ float: 1
 ldouble: 2
 
 Function: Real part of "csin":
+float: 1
 ldouble: 1
 
+Function: Imaginary part of "csin":
+float: 1
+
 Function: Real part of "csin_downward":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "csin_downward":
@@ -592,7 +666,7 @@ ldouble: 1
 
 Function: Real part of "csin_towardzero":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "csin_towardzero":
@@ -602,7 +676,7 @@ ldouble: 1
 
 Function: Real part of "csin_upward":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "csin_upward":
@@ -611,8 +685,12 @@ float: 1
 ldouble: 1
 
 Function: Real part of "csinh":
+float: 1
 ldouble: 1
 
+Function: Imaginary part of "csinh":
+float: 1
+
 Function: Real part of "csinh_downward":
 double: 1
 float: 1
@@ -620,7 +698,7 @@ ldouble: 1
 
 Function: Imaginary part of "csinh_downward":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "csinh_towardzero":
@@ -630,7 +708,7 @@ ldouble: 1
 
 Function: Imaginary part of "csinh_towardzero":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "csinh_upward":
@@ -640,37 +718,37 @@ ldouble: 1
 
 Function: Imaginary part of "csinh_upward":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "csqrt":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "csqrt":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Real part of "csqrt_downward":
 double: 1
-float: 2
+float: 4
 ldouble: 4
 
 Function: Imaginary part of "csqrt_downward":
 double: 1
-float: 2
+float: 3
 ldouble: 3
 
 Function: Real part of "csqrt_towardzero":
 double: 1
-float: 1
+float: 3
 ldouble: 4
 
 Function: Imaginary part of "csqrt_towardzero":
 double: 1
-float: 2
+float: 3
 ldouble: 3
 
 Function: Real part of "csqrt_upward":
@@ -685,7 +763,7 @@ ldouble: 3
 
 Function: Real part of "ctan":
 double: 1
-float: 1
+float: 2
 ldouble: 2
 
 Function: Imaginary part of "ctan":
@@ -699,7 +777,7 @@ float: 2
 ldouble: 2
 
 Function: Imaginary part of "ctan_downward":
-double: 3
+double: 9
 float: 2
 ldouble: 2
 
@@ -709,7 +787,7 @@ float: 2
 ldouble: 2
 
 Function: Imaginary part of "ctan_towardzero":
-double: 3
+double: 9
 float: 2
 ldouble: 4
 
@@ -719,8 +797,8 @@ float: 3
 ldouble: 5
 
 Function: Imaginary part of "ctan_upward":
-double: 1
-float: 1
+double: 9
+float: 2
 ldouble: 7
 
 Function: Real part of "ctanh":
@@ -734,7 +812,7 @@ float: 2
 ldouble: 2
 
 Function: Real part of "ctanh_downward":
-double: 3
+double: 9
 float: 2
 ldouble: 2
 
@@ -744,7 +822,7 @@ float: 2
 ldouble: 2
 
 Function: Real part of "ctanh_towardzero":
-double: 3
+double: 9
 float: 2
 ldouble: 4
 
@@ -754,7 +832,7 @@ float: 1
 ldouble: 2
 
 Function: Real part of "ctanh_upward":
-double: 1
+double: 9
 float: 2
 ldouble: 7
 
@@ -764,31 +842,37 @@ float: 3
 ldouble: 5
 
 Function: "erf":
+double: 1
 float: 1
 ldouble: 1
 
 Function: "erf_downward":
+double: 1
 float: 1
 
 Function: "erf_towardzero":
+double: 1
+float: 1
 ldouble: 1
 
 Function: "erf_upward":
+double: 1
 float: 1
 ldouble: 1
 
 Function: "erfc":
-float: 1
+double: 1
+float: 2
 ldouble: 2
 
 Function: "erfc_downward":
 double: 1
-float: 3
+float: 4
 ldouble: 4
 
 Function: "erfc_towardzero":
 double: 1
-float: 1
+float: 4
 ldouble: 4
 
 Function: "erfc_upward":
@@ -796,26 +880,83 @@ double: 1
 float: 3
 ldouble: 3
 
+Function: "exp10m1":
+double: 1
+float: 1
+
+Function: "exp10m1_downward":
+double: 1
+float: 1
+
+Function: "exp10m1_towardzero":
+double: 1
+float: 1
+
+Function: "exp10m1_upward":
+double: 3
+float: 1
+
 Function: "exp2":
 double: 1
 
-Function: "gamma":
+Function: "exp2_downward":
+double: 1
+
+Function: "exp2_towardzero":
+double: 1
+
+Function: "exp2m1":
+double: 1
 float: 1
-ldouble: 2
 
-Function: "gamma_downward":
+Function: "exp2m1_downward":
+double: 2
+float: 1
+
+Function: "exp2m1_towardzero":
+double: 2
+float: 1
+
+Function: "exp2m1_upward":
 double: 1
 float: 1
-ldouble: 3
 
-Function: "gamma_towardzero":
+Function: "exp_upward":
+double: 1
+
+Function: "expm1":
+double: 1
+
+Function: "expm1_downward":
 double: 1
 float: 1
-ldouble: 3
 
-Function: "gamma_upward":
+Function: "expm1_towardzero":
 double: 1
 float: 1
+
+Function: "expm1_upward":
+double: 1
+float: 1
+
+Function: "gamma":
+double: 3
+float: 7
+ldouble: 2
+
+Function: "gamma_downward":
+double: 3
+float: 7
+ldouble: 3
+
+Function: "gamma_towardzero":
+double: 4
+float: 6
+ldouble: 3
+
+Function: "gamma_upward":
+double: 4
+float: 6
 ldouble: 2
 
 Function: "hypot":
@@ -835,82 +976,157 @@ double: 1
 ldouble: 1
 
 Function: "j0":
-double: 1
-float: 2
+double: 8
+float: 8
 ldouble: 2
 
 Function: "j0_downward":
-double: 4
-float: 3
+double: 7
+float: 8
 ldouble: 4
 
 Function: "j0_towardzero":
 double: 1
-float: 1
+float: 8
 ldouble: 5
 
 Function: "j0_upward":
-double: 2
-float: 3
+double: 7
+float: 9
 ldouble: 5
 
 Function: "j1":
-float: 2
+double: 3
+float: 7
 ldouble: 1
 
 Function: "j1_downward":
-double: 1
-float: 4
+double: 3
+float: 7
 ldouble: 5
 
 Function: "j1_towardzero":
-double: 1
-float: 2
+double: 9
+float: 7
 ldouble: 4
 
 Function: "j1_upward":
-double: 1
-float: 3
+double: 9
+float: 6
 ldouble: 3
 
 Function: "jn":
 double: 2
-float: 2
+float: 5
 ldouble: 4
 
 Function: "jn_downward":
 double: 2
-float: 4
+float: 6
 ldouble: 5
 
 Function: "jn_towardzero":
 double: 2
-float: 3
+float: 6
 ldouble: 5
 
 Function: "jn_upward":
 double: 2
-float: 3
+float: 5
 ldouble: 5
 
 Function: "lgamma":
-float: 1
+double: 3
+float: 7
 ldouble: 2
 
 Function: "lgamma_downward":
-double: 1
-float: 1
+double: 3
+float: 7
 ldouble: 3
 
 Function: "lgamma_towardzero":
-double: 1
-float: 1
+double: 4
+float: 6
 ldouble: 3
 
 Function: "lgamma_upward":
+double: 4
+float: 6
+ldouble: 2
+
+Function: "log10_downward":
+double: 1
+float: 1
+
+Function: "log10_towardzero":
+double: 1
+float: 1
+
+Function: "log10p1":
+double: 1
+float: 2
+
+Function: "log10p1_downward":
+double: 1
+float: 1
+
+Function: "log10p1_towardzero":
+double: 1
+float: 1
+
+Function: "log10p1_upward":
+double: 1
+float: 1
+
+Function: "log1p":
+double: 1
+
+Function: "log1p_downward":
+double: 1
+float: 1
+
+Function: "log1p_towardzero":
+double: 1
+float: 1
+
+Function: "log1p_upward":
+double: 1
+float: 1
+
+Function: "log2":
+double: 1
+
+Function: "log2p1":
+double: 1
+float: 2
+
+Function: "log2p1_downward":
+double: 1
+float: 2
+
+Function: "log2p1_towardzero":
+double: 1
+float: 2
+
+Function: "log2p1_upward":
+double: 1
+float: 2
+
+Function: "logp1":
+double: 1
+
+Function: "logp1_downward":
+double: 1
+float: 1
+
+Function: "logp1_towardzero":
+double: 1
+float: 1
+
+Function: "logp1_upward":
 double: 1
 float: 1
-ldouble: 2
 
 Function: "pow":
 double: 1
@@ -919,7 +1135,7 @@ ldouble: 9
 
 Function: "pow_downward":
 double: 1
-float: 7
+float: 9
 ldouble: 9
 
 Function: "pow_towardzero":
@@ -929,45 +1145,100 @@ ldouble: 4
 
 Function: "pow_upward":
 double: 1
-float: 2
+float: 7
 ldouble: 8
 
 Function: "sin":
 double: 1
 
-Function: "tgamma":
+Function: "sin_downward":
 double: 1
-float: 4
+float: 1
+
+Function: "sin_towardzero":
+double: 1
+float: 1
+
+Function: "sin_upward":
+double: 1
+float: 1
+
+Function: "sincos_downward":
+double: 1
+float: 1
+
+Function: "sincos_towardzero":
+double: 1
+float: 1
+
+Function: "sincos_upward":
+double: 1
+float: 1
+
+Function: "sinh_downward":
+double: 1
+float: 1
+
+Function: "sinh_upward":
+double: 1
+float: 1
+
+Function: "tan_downward":
+double: 1
+float: 1
+
+Function: "tan_upward":
+double: 1
+float: 1
+
+Function: "tanh":
+double: 1
+
+Function: "tanh_downward":
+double: 1
+float: 1
+
+Function: "tanh_towardzero":
+double: 1
+float: 1
+
+Function: "tanh_upward":
+double: 1
+float: 1
+
+Function: "tgamma":
+double: 3
+float: 9
 ldouble: 9
 
 Function: "tgamma_downward":
-double: 2
-float: 3
+double: 3
+float: 9
 ldouble: 9
 
 Function: "tgamma_towardzero":
-double: 2
-float: 4
+double: 3
+float: 9
 ldouble: 9
 
 Function: "tgamma_upward":
-double: 1
-float: 4
+double: 2
+float: 9
 ldouble: 9
 
 Function: "y0":
 double: 1
-float: 1
+float: 4
 ldouble: 1
 
 Function: "y0_downward":
 double: 1
-float: 3
+float: 4
 ldouble: 6
 
 Function: "y0_towardzero":
 double: 1
-float: 2
+float: 4
 ldouble: 5
 
 Function: "y0_upward":
@@ -977,12 +1248,12 @@ ldouble: 3
 
 Function: "y1":
 double: 1
-float: 3
+float: 4
 ldouble: 2
 
 Function: "y1_downward":
 double: 4
-float: 3
+float: 6
 ldouble: 6
 
 Function: "y1_towardzero":
@@ -992,7 +1263,7 @@ ldouble: 5
 
 Function: "y1_upward":
 double: 2
-float: 2
+float: 4
 ldouble: 7
 
 Function: "yn":
@@ -1007,12 +1278,12 @@ ldouble: 6
 
 Function: "yn_towardzero":
 double: 3
-float: 3
+float: 4
 ldouble: 5
 
 Function: "yn_upward":
 double: 3
-float: 3
+float: 4
 ldouble: 4
 
 # end of automatic generation
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
index 092c274f36..7803e19fd1 100644
--- a/sysdeps/nptl/dl-tls_init_tp.c
+++ b/sysdeps/nptl/dl-tls_init_tp.c
@@ -45,8 +45,6 @@ rtld_mutex_dummy (pthread_mutex_t *lock)
 #endif
 
 const unsigned int __rseq_flags;
-const unsigned int __rseq_size attribute_relro;
-const ptrdiff_t __rseq_offset attribute_relro;
 
 void
 __tls_pre_init_tp (void)
@@ -104,12 +102,7 @@ __tls_init_tp (void)
     bool do_rseq = true;
     do_rseq = TUNABLE_GET (rseq, int, NULL);
     if (rseq_register_current_thread (pd, do_rseq))
-      {
-        /* We need a writable view of the variables.  They are in
-           .data.relro and are not yet write-protected.  */
-        extern unsigned int size __asm__ ("__rseq_size");
-        size = sizeof (pd->rseq_area);
-      }
+      _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED;
 
 #ifdef RSEQ_SIG
     /* This should be a compile-time constant, but the current
@@ -117,8 +110,7 @@ __tls_init_tp (void)
        all targets support __thread_pointer, so set __rseq_offset only
        if the rseq registration may have happened because RSEQ_SIG is
        defined.  */
-    extern ptrdiff_t offset __asm__ ("__rseq_offset");
-    offset = (char *) &pd->rseq_area - (char *) __thread_pointer ();
+    _rseq_offset = (char *) &pd->rseq_area - (char *) __thread_pointer ();
 #endif
   }
 
diff --git a/sysdeps/riscv/nofpu/libm-test-ulps b/sysdeps/riscv/nofpu/libm-test-ulps
index d8cff3e077..9ad64d1d85 100644
--- a/sysdeps/riscv/nofpu/libm-test-ulps
+++ b/sysdeps/riscv/nofpu/libm-test-ulps
@@ -972,6 +972,11 @@ double: 2
 float: 1
 ldouble: 3
 
+Function: "exp10m1":
+double: 2
+float: 1
+ldouble: 1
+
 Function: "exp2":
 double: 1
 ldouble: 1
@@ -989,6 +994,11 @@ double: 1
 float: 1
 ldouble: 2
 
+Function: "exp2m1":
+double: 1
+float: 1
+ldouble: 1
+
 Function: "exp_downward":
 double: 1
 float: 1
@@ -1161,6 +1171,11 @@ double: 2
 float: 2
 ldouble: 1
 
+Function: "log10p1":
+double: 1
+float: 1
+ldouble: 3
+
 Function: "log1p":
 double: 1
 float: 1
@@ -1198,6 +1213,11 @@ Function: "log2_upward":
 double: 3
 ldouble: 1
 
+Function: "log2p1":
+double: 1
+float: 1
+ldouble: 3
+
 Function: "log_downward":
 ldouble: 1
 
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index ae66590e91..097b5a26fc 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -616,6 +616,10 @@ tests += \
 endif
 
 ifeq ($(subdir),elf)
+dl-routines += \
+  dl-rseq-symbols \
+  # dl-routines
+
 sysdep-rtld-routines += \
   dl-brk \
   dl-getcwd \
diff --git a/sysdeps/unix/sysv/linux/dl-rseq-symbols.S b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S
new file mode 100644
index 0000000000..b4bba06a99
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S
@@ -0,0 +1,64 @@
+/* Define symbols used by rseq.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#if __WORDSIZE == 64
+#define RSEQ_OFFSET_SIZE	8
+#else
+#define RSEQ_OFFSET_SIZE	4
+#endif
+
+/* Some targets define a macro to denote the zero register.  */
+#undef zero
+
+/* Define 2 symbols: '__rseq_size' is public const and '_rseq_size' (an
+   alias of '__rseq_size') is hidden and writable for internal use by the
+   dynamic linker which will initialize the value both symbols point to
+   before copy relocations take place. */
+
+	.globl	__rseq_size
+	.type	__rseq_size, %object
+	.size	__rseq_size, 4
+	.hidden _rseq_size
+	.globl	_rseq_size
+	.type	_rseq_size, %object
+	.size	_rseq_size, 4
+	.section .data.rel.ro
+	.balign 4
+__rseq_size:
+_rseq_size:
+	.zero	4
+
+/* Define 2 symbols: '__rseq_offset' is public const and '_rseq_offset' (an
+   alias of '__rseq_offset') is hidden and writable for internal use by the
+   dynamic linker which will initialize the value both symbols point to
+   before copy relocations take place. */
+
+	.globl	__rseq_offset
+	.type	__rseq_offset, %object
+	.size	__rseq_offset, RSEQ_OFFSET_SIZE
+	.hidden _rseq_offset
+	.globl	_rseq_offset
+	.type	_rseq_offset, %object
+	.size	_rseq_offset, RSEQ_OFFSET_SIZE
+	.section .data.rel.ro
+	.balign RSEQ_OFFSET_SIZE
+__rseq_offset:
+_rseq_offset:
+	.zero	RSEQ_OFFSET_SIZE
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
index 48eebc1e16..7ea935b4ad 100644
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
@@ -25,15 +25,34 @@
 #include <stdio.h>
 #include <sys/rseq.h>
 
+/* 32 is the initially required value for the area size.  The
+   actually used rseq size may be less (20 bytes initially).  */
+#define RSEQ_AREA_SIZE_INITIAL 32
+#define RSEQ_AREA_SIZE_INITIAL_USED 20
+
+/* The variables are in .data.relro but are not yet write-protected.  */
+extern unsigned int _rseq_size attribute_hidden;
+extern ptrdiff_t _rseq_offset attribute_hidden;
+
 #ifdef RSEQ_SIG
 static inline bool
 rseq_register_current_thread (struct pthread *self, bool do_rseq)
 {
   if (do_rseq)
     {
+      unsigned int size;
+#if IS_IN (rtld)
+      /* Use the hidden symbol in ld.so.  */
+      size = _rseq_size;
+#else
+      size = __rseq_size;
+#endif
+      if (size < RSEQ_AREA_SIZE_INITIAL)
+        /* The initial implementation used only 20 bytes out of 32,
+           but still expected size 32.  */
+        size = RSEQ_AREA_SIZE_INITIAL;
       int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area,
-                                       sizeof (self->rseq_area),
-                                       0, RSEQ_SIG);
+                                       size, 0, RSEQ_SIG);
       if (!INTERNAL_SYSCALL_ERROR_P (ret))
         return true;
     }
diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c
index 2c90409ba0..08a9533130 100644
--- a/sysdeps/unix/sysv/linux/tst-rseq.c
+++ b/sysdeps/unix/sysv/linux/tst-rseq.c
@@ -29,6 +29,7 @@
 # include <stdlib.h>
 # include <string.h>
 # include <syscall.h>
+# include <sys/auxv.h>
 # include <thread_pointer.h>
 # include <tls.h>
 # include "tst-rseq.h"
@@ -42,7 +43,8 @@ do_rseq_main_test (void)
   TEST_COMPARE (__rseq_flags, 0);
   TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset
                == (char *) &pd->rseq_area);
-  TEST_COMPARE (__rseq_size, sizeof (pd->rseq_area));
+  /* The current implementation only supports the initial size.  */
+  TEST_COMPARE (__rseq_size, 20);
 }
 
 static void
@@ -52,6 +54,12 @@ do_rseq_test (void)
     {
       FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test");
     }
+  printf ("info: __rseq_size: %u\n", __rseq_size);
+  printf ("info: __rseq_offset: %td\n", __rseq_offset);
+  printf ("info: __rseq_flags: %u\n", __rseq_flags);
+  printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n",
+          getauxval (AT_RSEQ_FEATURE_SIZE));
+  printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN));
   do_rseq_main_test ();
 }
 #else /* RSEQ_SIG */