diff mbox series

[v2,2/2] misc: Add <sys/cstack.h> and the cstack_* family of functions

Message ID 9abea57b88df1181ba27a00db6f462ad3fe92f1d.1621600453.git.fweimer@redhat.com
State Changes Requested
Headers show
Series Convenience function for allocating (alternate signal) stacks | expand

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Florian Weimer May 21, 2021, 12:37 p.m. UTC
These functions are expected to be used with sigaltstack and
coroutines.  Allocation takes architecture requirements into
account.
---
 NEWS                                          |   4 +
 include/sys/cstack.h                          |  39 ++++
 manual/memory.texi                            |  99 ++++++++++
 manual/signal.texi                            |   3 +
 misc/Makefile                                 |   8 +-
 misc/Versions                                 |   5 +
 misc/cstack_allocate.c                        | 121 ++++++++++++
 misc/cstack_free.c                            |  35 ++++
 misc/cstack_get.c                             |  27 +++
 misc/sys/cstack.h                             |  53 ++++++
 misc/tst-cstack.c                             | 176 ++++++++++++++++++
 sysdeps/mach/hurd/i386/libc.abilist           |   3 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   3 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist    |   3 +
 sysdeps/unix/sysv/linux/arc/libc.abilist      |   3 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/csky/libc.abilist     |   3 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   3 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   3 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist     |   3 +
 .../sysv/linux/m68k/coldfire/libc.abilist     |   3 +
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   3 +
 .../sysv/linux/microblaze/be/libc.abilist     |   3 +
 .../sysv/linux/microblaze/le/libc.abilist     |   3 +
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |   3 +
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |   3 +
 .../sysv/linux/mips/mips64/n32/libc.abilist   |   3 +
 .../sysv/linux/mips/mips64/n64/libc.abilist   |   3 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist    |   3 +
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |   3 +
 .../powerpc/powerpc32/nofpu/libc.abilist      |   3 +
 .../linux/powerpc/powerpc64/be/libc.abilist   |   3 +
 .../linux/powerpc/powerpc64/le/libc.abilist   |   3 +
 .../unix/sysv/linux/riscv/rv32/libc.abilist   |   3 +
 .../unix/sysv/linux/riscv/rv64/libc.abilist   |   3 +
 .../unix/sysv/linux/s390/s390-32/libc.abilist |   3 +
 .../unix/sysv/linux/s390/s390-64/libc.abilist |   3 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   3 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   3 +
 .../sysv/linux/sparc/sparc32/libc.abilist     |   3 +
 .../sysv/linux/sparc/sparc64/libc.abilist     |   3 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   3 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   3 +
 44 files changed, 666 insertions(+), 3 deletions(-)
 create mode 100644 include/sys/cstack.h
 create mode 100644 misc/cstack_allocate.c
 create mode 100644 misc/cstack_free.c
 create mode 100644 misc/cstack_get.c
 create mode 100644 misc/sys/cstack.h
 create mode 100644 misc/tst-cstack.c
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index 266837bf2d..245534d020 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@  Major new features:
   constant on Linux.  MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ)
   and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ).
 
+* The <sys/cstack.h> header file, the type cstack_t, and the functions
+  cstack_allocate, stack_free, stack_get have been added.  It provides
+  the facilities for stack allocation.
+
 * The dynamic linker implements the --list-diagnostics option, printing
   a dump of information related to IFUNC resolver operation and
   glibc-hwcaps subdirectory selection.
diff --git a/include/sys/cstack.h b/include/sys/cstack.h
new file mode 100644
index 0000000000..6ae798fe5e
--- /dev/null
+++ b/include/sys/cstack.h
@@ -0,0 +1,39 @@ 
+/* Allocating call stacks.  Wrapper header.
+   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 <misc/sys/cstack.h>
+
+#ifndef _ISOMAC
+struct __cstack
+{
+  /* This describes the region of the entire stack, including guard
+     areas.  */
+  char *entire_region_start;
+  size_t entire_region_size;
+
+  /* Returned by cstack_get.  */
+  stack_t stack;
+};
+
+extern __typeof (cstack_allocate) __cstack_allocate;
+libc_hidden_proto (__cstack_allocate)
+extern __typeof (cstack_free) __cstack_free;
+libc_hidden_proto (__cstack_free)
+extern __typeof (cstack_get) __cstack_get;
+libc_hidden_proto (__cstack_get)
+#endif
diff --git a/manual/memory.texi b/manual/memory.texi
index 28ec2e4e63..4fb4c2fda4 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -19,6 +19,7 @@  and allocation of real memory.
 * Resizing the Data Segment::   @code{brk}, @code{sbrk}
 * Memory Protection::           Controlling access to memory regions.
 * Locking Pages::               Preventing page faults
+* Allocating Stacks::           Interfaces for allocating stacks.
 @end menu
 
 Memory mapped I/O is not discussed in this chapter.  @xref{Memory-mapped I/O}.
@@ -3771,8 +3772,106 @@  calls can fail, so there are no specific @code{errno} values.
 
 @end deftypefun
 
+@node Allocating Stacks
+@section Allocating Stacks
+
+With the @code{cstack_} family of functions, @theglibc{} provides
+functions for allocating @dfn{call stacks} or @dfn{C stacks}.  Such
+stacks can be used to implement cooperative (non-preemptive)
+multi-threading or coroutines.  They are also useful as alternate
+signal stacks.  @xref{Signal Stack}
+
+These stacks do not come with their own thread control block and
+therefore need to be scheduled on an existing thread.  On most
+targets, resuming a pending computation with its own stack on a
+different thread than the one it was suspended on is undefined because
+active stack frames are typically tied to one particlar thread control
+block.
+
+By default, allocated stacks are bracketed by guard regions.
+Applications that would otherwise run into the map limit can
+optionally disable these guard pages.  For targets which fully support
+the GCC @option{-fstack-clash-protection} option, the guard region at
+the top of the stack is sized so that it can reliable detect stack
+overflow (exhaustion).
+
+Allocated stacks are not explicitly allocated with executable memory
+even if the current process image uses an executable stack.  The
+stacks can still be executable for other reasons, e.g., lack of
+hardware support for non-executable stacks.
+
+@deftp {Data Type} cstack_t
+Values of this type are handles for allocated stacks.  Handles become
+invalid when freed by the @code{cstack_free} function, and further use
+of them is invalid.
+
+The value @code{NULL} is not a valid stack handle and is used to
+indicate errors.
+@end deftp
+
+@deftypefun cstack_t cstack_allocate (size_t @var{size}, uint64_t @var{flags})
+@standards{GNU, sys/cstack.h}
+@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+This function allocates a stack memory area and returns its handle.
+The @var{size} argument indicates the number of bytes on the stack
+that are available for use by the application.  @Theglibc{} ensures
+that in addition to the requested space, there is enough memory
+available to deliver one signal to code running on this stack, plus
+some extra reservation for the signal handler itself.
+
+If the specified stack size is zero, the function picks a reasonable
+stack size that provides enough space for delivering one (non-nested)
+signal and invoking most functions provided by @theglibc{}.
+
+The @var{flags} argument is the bitwise-or of a set of flag constants.
+The following flags are defined
+
+@vtable @code
+@item CSTACK_ALLOCATE_NOBOTTOMGUARD
+@standards{GNU, sys/cstack.h}
+This flags requests that @code{cstack_allocate} does not allocate a
+guard region at the bottom of the stack (below the first activation
+frame).  This guard region can sometimes catch stack-based buffer
+overflows and turn them into a segmentation fault.
+
+@item CSTACK_ALLOCATE_NOTOPGUARD
+This flags requests that no guard region is allocated at the top end
+of the stack.  This guard region can be used to detect stack overflow
+(exahustion) and generate a segmentation fault in such sitations.
+@end vtable
+
+If allocating the stack fails, @code{cstack_allocate} returns
+@code{NULL} to indicate an error.  The following errors are specific
+to this function:
 
+@table @code
+@item ENOMEM
+Insufficient memory is available to allocate the stack, or @var{size}
+is too large.
 
+@item EINVAL
+The @var{flags} argument contains unsupported flags.
+@end table
+@end deftypefun
+
+@deftypefun void cstack_free (cstack_t @var{stack})
+@standards{GNU, sys/cstack.h}
+@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+This functions deallocations the stack handle @var{stack} and
+deallocates the associated memory.
+@end deftypefun
+
+@deftypefun void cstack_get (cstack_t @var{stack}, stack_t *@var{altstack})
+@standards{GNU, sys/cstack.h}
+@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+This function obtains the usable stack region of @var{stack}
+(excluding any guard regions) and writes it to @var{altstack}.  The
+resulting structure is suitable for use with the @code{sigaltstack}
+function.
+
+The @code{ss_flags} member of the @code{stack_t} result is currently
+set to zero.
+@end deftypefun
 
 @ignore
 @c This was never actually implemented.  -zw
diff --git a/manual/signal.texi b/manual/signal.texi
index 8a12baf044..79265335d7 100644
--- a/manual/signal.texi
+++ b/manual/signal.texi
@@ -3124,6 +3124,9 @@  BSD.  The @code{sigaltstack} interface has the advantage that it does
 not require your program to know which direction the stack grows, which
 depends on the specific machine and operating system.
 
+Memory for signal stacks can be allocated using @code{cstack_allocate}.
+@xref{Allocating Stacks}
+
 @deftp {Data Type} stack_t
 @standards{XPG, signal.h}
 This structure describes a signal stack.  It contains the following members:
diff --git a/misc/Makefile b/misc/Makefile
index 38dad737f2..67b15aaf49 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -38,7 +38,7 @@  headers	:= sys/uio.h bits/uio-ext.h bits/uio_lim.h \
 	   bits/select2.h bits/hwcap.h sys/auxv.h \
 	   sys/sysmacros.h bits/sysmacros.h bits/types/struct_iovec.h \
 	   bits/err-ldbl.h bits/error-ldbl.h \
-	   sys/single_threaded.h
+	   sys/single_threaded.h sys/cstack.h
 
 routines := brk sbrk sstk ioctl \
 	    readv writev preadv preadv64 pwritev pwritev64 \
@@ -73,7 +73,8 @@  routines := brk sbrk sstk ioctl \
 	    fgetxattr flistxattr fremovexattr fsetxattr getxattr \
 	    listxattr lgetxattr llistxattr lremovexattr lsetxattr \
 	    removexattr setxattr getauxval ifunc-impl-list makedev \
-	    allocate_once fd_to_filename single_threaded unwind-link
+	    allocate_once fd_to_filename single_threaded unwind-link \
+	    cstack_allocate cstack_free cstack_get
 
 generated += tst-error1.mtrace tst-error1-mem.out \
   tst-allocate_once.mtrace tst-allocate_once-mem.out
@@ -88,7 +89,8 @@  tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
 	 tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
 	 tst-preadvwritev2 tst-preadvwritev64v2 tst-warn-wide \
 	 tst-ldbl-warn tst-ldbl-error tst-dbl-efgcvt tst-ldbl-efgcvt \
-	 tst-mntent-autofs tst-syscalls tst-mntent-escape tst-select
+	 tst-mntent-autofs tst-syscalls tst-mntent-escape tst-select \
+	 tst-cstack
 
 # Tests which need libdl.
 ifeq (yes,$(build-shared))
diff --git a/misc/Versions b/misc/Versions
index d5b348e83a..04bb8a89f5 100644
--- a/misc/Versions
+++ b/misc/Versions
@@ -164,6 +164,11 @@  libc {
   GLIBC_2.32 {
     __libc_single_threaded;
   }
+  GLIBC_2.34 {
+    cstack_allocate;
+    cstack_free;
+    cstack_get;
+  }
   GLIBC_PRIVATE {
     __madvise;
     __mktemp;
diff --git a/misc/cstack_allocate.c b/misc/cstack_allocate.c
new file mode 100644
index 0000000000..575236f0c3
--- /dev/null
+++ b/misc/cstack_allocate.c
@@ -0,0 +1,121 @@ 
+/* Allocating a call stack.
+   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 <assert.h>
+#include <errno.h>
+#include <ldsodefs.h>
+#include <stdlib.h>
+#include <sys/cstack.h>
+#include <sys/mman.h>
+#include <sysconf-sigstksz.h>
+
+cstack_t
+__cstack_allocate (size_t size, uint64_t flags)
+{
+  if (flags & ~(uint64_t) (CSTACK_ALLOCATE_NOBOTTOMGUARD
+                           | CSTACK_ALLOCATE_NOTOPGUARD))
+    {
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
+  size_t pagesize = GLRO (dl_pagesize);
+
+  /* Buffer overflow guard.  */
+  size_t bottom_guard_size;
+  if (flags & CSTACK_ALLOCATE_NOBOTTOMGUARD)
+    bottom_guard_size = 0;
+  else
+    bottom_guard_size = pagesize;
+
+  /* -fstack-clash-protection guard.  */
+  size_t top_guard_size;
+  if (flags & CSTACK_ALLOCATE_NOTOPGUARD)
+    top_guard_size = 0;
+  else
+    {
+      if (ARCH_MIN_GUARD_SIZE != 0)
+        bottom_guard_size = roundup (ARCH_MIN_GUARD_SIZE, pagesize);
+      else
+        bottom_guard_size = pagesize;
+    }
+
+  if (size == 0)
+    /* Use SIGSTKSZ by default.  */
+    size = sysconf_sigstksz ();
+  else
+    {
+      /* Otherwise add MINSIGSTKSZ to the user-requested size.  */
+      if (__builtin_add_overflow (size, GLRO (dl_minsigstacksize), &size))
+        {
+          __set_errno (ENOMEM);
+          return NULL;
+        }
+  }
+
+  size_t rounded_size = roundup (size, pagesize);
+  size_t total_size;
+  if (rounded_size < size
+      || __builtin_add_overflow (rounded_size, bottom_guard_size, &total_size)
+      || __builtin_add_overflow (total_size, top_guard_size, &total_size))
+    {
+      __set_errno (ENOMEM);
+      return NULL;
+    }
+  assert ((total_size & (pagesize - 1)) == 0);
+
+  cstack_t result = malloc (sizeof (*result));
+  if (result == NULL)
+    return result;
+
+  int map_flags = MAP_PRIVATE | MAP_ANON;
+#ifdef MAP_STACK
+  map_flags |= MAP_STACK;
+#endif
+  result->entire_region_start = __mmap (NULL, total_size,
+                                        PROT_NONE, map_flags, -1, 0);
+  if (result->entire_region_start == MAP_FAILED)
+    {
+      free (result);
+      return NULL;
+    }
+  result->entire_region_size = total_size;
+
+#if _STACK_GROWS_DOWN
+  char *sp = result->entire_region_start + top_guard_size;
+#endif
+#if _STACK_GROWS_UP
+  char *sp = result->entire_region_start + bottom_guard_size;
+#endif
+
+  if (__mprotect (sp, rounded_size, PROT_READ | PROT_WRITE) != 0)
+    {
+      __cstack_free (result);
+      return NULL;
+    }
+
+  result->stack = (stack_t)
+    {
+      .ss_sp = sp,
+      .ss_size = rounded_size,
+    };
+
+  return result;
+}
+libc_hidden_def (__cstack_allocate)
+weak_alias (__cstack_allocate, cstack_allocate)
diff --git a/misc/cstack_free.c b/misc/cstack_free.c
new file mode 100644
index 0000000000..f5a2dfde74
--- /dev/null
+++ b/misc/cstack_free.c
@@ -0,0 +1,35 @@ 
+/* Deallocating a call stack.
+   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 <stdlib.h>
+#include <sys/cstack.h>
+#include <sys/mman.h>
+
+void
+__cstack_free (cstack_t stack)
+{
+  int saved_errno = errno;
+  /* This may leak the mapping if it causes the map count to be
+     exceeded (and clobber errno).  */
+  __munmap (stack->entire_region_start, stack->entire_region_size);
+  free (stack);
+  __set_errno (saved_errno);
+}
+libc_hidden_def (__cstack_free)
+weak_alias (__cstack_free, cstack_free)
diff --git a/misc/cstack_get.c b/misc/cstack_get.c
new file mode 100644
index 0000000000..835a261922
--- /dev/null
+++ b/misc/cstack_get.c
@@ -0,0 +1,27 @@ 
+/* Obtaining the stack region of a call stack.
+   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 <sys/cstack.h>
+
+void
+__cstack_get (cstack_t stack, stack_t *result)
+{
+  *result = stack->stack;
+}
+libc_hidden_def (__cstack_get)
+weak_alias (__cstack_get, cstack_get)
diff --git a/misc/sys/cstack.h b/misc/sys/cstack.h
new file mode 100644
index 0000000000..c973a49ab8
--- /dev/null
+++ b/misc/sys/cstack.h
@@ -0,0 +1,53 @@ 
+/* Allocating call stacks.
+   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 _SYS_CSTACK_H
+#define _SYS_CSTACK_H
+
+#include <bits/types/stack_t.h>
+#include <features.h>
+#include <stddef.h>
+#include <stdint.h>
+
+struct __cstack;
+
+/* Call stack handles returned by cstack_allocate.  */
+typedef struct __cstack *cstack_t;
+
+/* Allocate guard region below the first activation frame.  */
+#define CSTACK_ALLOCATE_NOBOTTOMGUARD 1
+
+/* Do not add a guard region to detect stack overflow/exhaustion.   */
+#define CSTACK_ALLOCATE_NOTOPGUARD 2
+
+__BEGIN_DECLS
+
+/* Allocates a handle for a new call stack of the requested SIZE.
+   Flags should be a combination of CSTACK_ALLOCATE_* constants.
+   Returns NULL and sets errno on error.  */
+extern cstack_t cstack_allocate (size_t __size, uint64_t __flags) __THROW;
+
+/* Deallocates STACK.  */
+extern void cstack_free (cstack_t __stack) __THROW;
+
+/* Obtains the usable stack region of STACK and writes it to *RESULT.  */
+extern void cstack_get (cstack_t __stack, stack_t *result) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_CSTACK_H */
diff --git a/misc/tst-cstack.c b/misc/tst-cstack.c
new file mode 100644
index 0000000000..4bc786e8a8
--- /dev/null
+++ b/misc/tst-cstack.c
@@ -0,0 +1,176 @@ 
+/* Tests for allocating call stacks.
+   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 <sys/cstack.h>
+
+#include <signal.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xsignal.h>
+
+static stack_t expected_stack;
+static volatile bool test_ran;
+
+void __attribute__ ((weak)) /* Compiler barrier.  */
+check_on_stack (void *ptr)
+{
+  TEST_VERIFY (expected_stack.ss_sp != 0);
+  TEST_VERIFY (expected_stack.ss_size > 0);
+  TEST_VERIFY (ptr >= expected_stack.ss_sp);
+  TEST_VERIFY (ptr - expected_stack.ss_sp < expected_stack.ss_size);
+}
+
+/* Used for testing an on-stack buffer with a non-default stack
+   size.  */
+enum { large_buffer_size = 8 * 1024 * 1024 };
+
+static void
+default_stack_test (int ignored)
+{
+  /* The default stack allocation should be large enough to accomodate
+     a small buffer.  */
+  char buf[512];
+  TEST_VERIFY (expected_stack.ss_size < large_buffer_size);
+  explicit_bzero (buf, sizeof (buf));
+  check_on_stack (buf);
+  check_on_stack (buf + sizeof (buf));
+  test_ran = true;
+}
+
+static void
+large_stack_test (int ignored)
+{
+  /* This needs a stack allocation with a non-default buffer size.  */
+  char buf[large_buffer_size];
+  explicit_bzero (buf, sizeof (buf));
+  check_on_stack (buf);
+  check_on_stack (buf + sizeof (buf));
+  test_ran = true;
+}
+
+static void
+run_test_on_stack (cstack_t stack, void (*test) (int))
+{
+  cstack_get (stack, &expected_stack);
+  stack_t savestk;
+  TEST_COMPARE (sigaltstack (&expected_stack, &savestk), 0);
+
+  struct sigaction saveact;
+  const struct sigaction sigact =
+    {
+      .sa_handler = test,
+      .sa_flags = SA_ONSTACK,
+    };
+  xsigaction (SIGUSR1, &sigact, &saveact);
+
+  test_ran = false;
+  xraise (SIGUSR1);
+  TEST_VERIFY (test_ran);
+
+  xsigaction (SIGUSR1, &saveact, NULL);
+  TEST_COMPARE (sigaltstack (&savestk, NULL), 0);
+}
+
+static jmp_buf fault_jmp;
+static volatile void *volatile fault_address;
+static volatile bool fault_handler_ran;
+
+static void
+fault_handler (int signum, siginfo_t *info, void *ctx)
+{
+  fault_address = info->si_addr;
+  fault_handler_ran = true;
+  siglongjmp (fault_jmp, 1);
+}
+
+static void
+check_for_fault (const stack_t *stack, volatile char *address)
+{
+  struct sigaction saveact;
+  const struct sigaction sigact =
+    {
+      .sa_sigaction = fault_handler,
+      .sa_flags = SA_SIGINFO,
+    };
+  xsigaction (SIGSEGV, &sigact, &saveact);
+
+  fault_address = NULL;
+  fault_handler_ran = false;
+  if (sigsetjmp (fault_jmp, 1) != 0)
+    {
+      TEST_VERIFY (fault_handler_ran);
+      TEST_VERIFY (address == fault_address);
+      xsigaction (SIGSEGV,  &saveact, NULL);
+      return;
+    }
+
+  *address = 1;
+  FAIL_EXIT1 ("write to %p did not trap (stack: %p, %zu)",
+              address, stack->ss_sp, stack->ss_size);
+}
+
+/* Check that right below and above the stack area, there is a
+   fault.  */
+static void
+check_for_faults (size_t size)
+{
+    cstack_t stack = cstack_allocate (0, 0);
+    TEST_VERIFY_EXIT (stack != NULL);
+    stack_t st;
+    cstack_get (stack, &st);
+    check_for_fault (&st, st.ss_sp - 1);
+    check_for_fault (&st, st.ss_sp + st.ss_size);
+    cstack_free (stack);
+}
+
+static int
+do_test (void)
+{
+  for (int do_nobottomguard = 0; do_nobottomguard < 2; ++do_nobottomguard)
+    for (int do_notopguard = 0; do_notopguard < 2; ++do_notopguard)
+      {
+        uint64_t flags = 0;
+        if (do_nobottomguard)
+          flags |= CSTACK_ALLOCATE_NOBOTTOMGUARD;
+        if (do_notopguard)
+          flags |= CSTACK_ALLOCATE_NOTOPGUARD;
+
+        {
+          cstack_t stack = cstack_allocate (0, flags);
+          TEST_VERIFY_EXIT (stack != NULL);
+          run_test_on_stack (stack, default_stack_test);
+          cstack_free (stack);
+        }
+
+        {
+          cstack_t stack = cstack_allocate (large_buffer_size + 1024, flags);
+          TEST_VERIFY_EXIT (stack != NULL);
+          run_test_on_stack (stack, large_stack_test);
+          cstack_free (stack);
+        }
+      }
+
+  check_for_faults (0);
+  check_for_faults (large_buffer_size);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 49aa809366..8e6453c328 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2207,6 +2207,9 @@  GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 _hurd_libc_proc_init F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 timespec_getres F
 GLIBC_2.4 __confstr_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index bc051ba9f5..a749e4459e 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2340,6 +2340,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 3bea473d00..9dbe5546dd 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2431,6 +2431,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 3461527c5a..8ae2089d49 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2099,6 +2099,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 7c3029a7e5..86c2e1036f 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -206,6 +206,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 24f5b202e8..d83bea234b 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -203,6 +203,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 85851c5fca..d45960f3e2 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2283,6 +2283,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index ede69c7ed5..8213c73c7c 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2236,6 +2236,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index c883dc08bc..319c4af267 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2419,6 +2419,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 38fb02e32b..432e302d93 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2272,6 +2272,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 8ee9648828..eda08d8138 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -207,6 +207,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 1c51cb41ec..fd46408199 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2362,6 +2362,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index f8b67cd170..8d02a49f0c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2334,6 +2334,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index edac4a1bb4..f822077a0a 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2331,6 +2331,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index db900c89ab..b1cb134dac 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2327,6 +2327,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 4e15f48b6c..407dd476ea 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2325,6 +2325,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 616a6076f1..b067a2dffc 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2333,6 +2333,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 59a353d306..01e70901b2 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2327,6 +2327,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 0fc42897aa..5ffd80e7ef 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2373,6 +2373,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 553ecdabc9..3fbc5ff981 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2389,6 +2389,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 7ec438f7b4..5fded4799f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2422,6 +2422,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index f382e3e296..1c611d6c35 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2237,6 +2237,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 97ff951418..31614d879e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2536,6 +2536,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 5bde5bb508..a4d7cf4b07 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2101,6 +2101,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 42f6d52e13..4a563101c1 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2301,6 +2301,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 2274342208..dc18facc8e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2387,6 +2387,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 14d1c5e7f8..ca13fa877d 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2274,6 +2274,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 97942ff01a..bd4745d0a5 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2243,6 +2243,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 617b673620..f506c94c2f 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2240,6 +2240,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 3c6559bb4f..86572409f0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2380,6 +2380,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 77f54bb23b..53ff5acea9 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2293,6 +2293,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 4035841a1e..da3eff2b8e 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2252,6 +2252,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 61ac187db9..2e814d4ff3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2355,6 +2355,9 @@  GLIBC_2.34 cnd_init F
 GLIBC_2.34 cnd_signal F
 GLIBC_2.34 cnd_timedwait F
 GLIBC_2.34 cnd_wait F
+GLIBC_2.34 cstack_allocate F
+GLIBC_2.34 cstack_free F
+GLIBC_2.34 cstack_get F
 GLIBC_2.34 execveat F
 GLIBC_2.34 mtx_destroy F
 GLIBC_2.34 mtx_init F