nptl: Add pthread_getstack_np

It returns the stack bounds of a thread following the same convention
as pthread_attr_getstack applied to the result of pthread_getattr_np.

Unlike pthread_getattr_np, it does not acquire the thread descriptor
lock nor allocates memory, which make the function async-signal-safe.

The function reports the stack set up by the kernel or by
pthread_create, the alternate signal stack is not reflected in the
result (it can be queried with sigaltstack, which is also
async-signal-safe), and stacks switched by user code, such as with
makecontext or coroutine libraries, are not tracked.

Similar interfaces are provided by Solaris (stack_getbounds), OpenBSD
(pthread_stackseg_np), and LLVM libc (pthread_getstack_np).

Checked on x86_64-linux-gnu.
This commit is contained in:
Adhemerval Zanella
2026-09-11 16:33:47 -03:00
parent ce8dfd08d8
commit 7f91cbdeda
41 changed files with 431 additions and 1 deletions
+3 -1
View File
@@ -9,7 +9,9 @@ Version 2.45
Major new features:
[Add new features here]
* The function pthread_getstack_np has been added. It returns the stack
bounds of a thread, like pthread_attr_getstack applied to the result of
pthread_getattr_np, in a async-signal-safe manner.
Deprecated and removed features, and other changes affecting compatibility:
+32
View File
@@ -1148,6 +1148,7 @@ the standard.
* Thread CPU Affinity:: Limiting which CPUs can run a thread.
* Joining Threads:: Wait for a thread to terminate.
* Thread Names:: Changing the name of a thread.
* Thread Stack Bounds:: Determining the stack of a thread.
* Single-Threaded:: Detecting single-threaded execution.
* Restartable Sequences:: Linux-specific restartable sequences
integration.
@@ -1352,6 +1353,37 @@ Retrieves the name of thread @var{th}.
@manpagefunctionstub{pthread_getname_np, 3}
@end deftypefun
@node Thread Stack Bounds
@subsubsection Thread Stack Bounds
@deftypefun int pthread_getstack_np (pthread_t @var{th}, void **@var{stackaddr}, size_t *@var{stacksize})
@standards{GNU, pthread.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
Store the lowest usable address of the stack of thread @var{th} in
@code{*@var{stackaddr}} and the number of bytes usable from that
address in @code{*@var{stacksize}}, following the same convention as
@code{pthread_attr_getstack}. The reported size does not include the
guard area.
For the initial thread the bounds are computed from the current
@code{RLIMIT_STACK} resource limit and the process memory map, so the
result may change if the limit is adjusted. On failure an error code
is returned, for instance @code{ENOENT} when the stack bounds cannot
be determined.
Unlike @code{pthread_getattr_np}, this function does not acquire any
lock nor allocate memory, and it is async-signal-safe.
The function reports the stack set up by the kernel or by
@code{pthread_create}. The alternate signal stack is not reflected in
the result, and a handler running on it still gets the bounds of the
thread stack. The alternate stack can be queried with @code{sigaltstack}
(@pxref{Signal Stack}), which is also async-signal-safe.
Stacks switched by user code, such as with @code{makecontext} or coroutine
libraries, are not tracked by @theglibc{} and are not reported either.
@end deftypefun
@node Single-Threaded
@subsubsection Detecting Single-Threaded Execution
+2
View File
@@ -118,6 +118,7 @@ routines = \
pthread_getname \
pthread_getschedparam \
pthread_getspecific \
pthread_getstack_np \
pthread_gettid_np \
pthread_join \
pthread_join_common \
@@ -328,6 +329,7 @@ tests = \
tst-pthread-timedlock-lockloop \
tst-pthread_exit-nothreads \
tst-pthread_exit-nothreads-static \
tst-pthread_getstack_np \
tst-pthread_gettid_np \
tst-robust-fork \
tst-robust12 \
+3
View File
@@ -383,6 +383,9 @@ libc {
}
GLIBC_2.43 {
}
GLIBC_2.45 {
pthread_getstack_np;
}
GLIBC_PRIVATE {
__libc_alloca_cutoff;
__lll_lock_wake_private;
+53
View File
@@ -0,0 +1,53 @@
/* Get the stack bounds of a thread.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <pthreadP.h>
int
pthread_getstack_np (pthread_t threadid, void **stackaddr, size_t *stacksize)
{
struct pthread *thread = (struct pthread *) threadid;
if (__glibc_likely (thread->stackblock != NULL))
{
/* As per pthread_attr_getstack, the returned size does not include the
guard area. */
*stacksize = thread->stackblock_size - thread->guardsize;
#if _STACK_GROWS_DOWN
*stackaddr = (char *) thread->stackblock + thread->guardsize;
#else
*stackaddr = thread->stackblock;
#endif
return 0;
}
/* The initial thread stack is set up by the kernel. */
void *addr;
size_t size;
int ret = __pthread_main_stack (&addr, &size);
if (ret != 0)
return ret;
#if _STACK_GROWS_DOWN
*stackaddr = (char *) addr - size;
#else
*stackaddr = addr;
#endif
*stacksize = size;
return 0;
}
+285
View File
@@ -0,0 +1,285 @@
/* Test pthread_getstack_np.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <unistd.h>
#include <support/check.h>
#include <support/namespace.h>
#include <support/support.h>
#include <support/xsignal.h>
#include <support/xthread.h>
#include <support/xunistd.h>
/* The result must match what pthread_getattr_np plus pthread_attr_getstack
return. */
static void
check_against_getattr_np (pthread_t thr)
{
void *stackaddr;
size_t stacksize;
TEST_COMPARE (pthread_getstack_np (thr, &stackaddr, &stacksize), 0);
pthread_attr_t attr;
TEST_COMPARE (pthread_getattr_np (thr, &attr), 0);
void *attr_stackaddr;
size_t attr_stacksize;
TEST_COMPARE (pthread_attr_getstack (&attr, &attr_stackaddr,
&attr_stacksize), 0);
TEST_COMPARE (pthread_attr_destroy (&attr), 0);
TEST_VERIFY (stackaddr == attr_stackaddr);
TEST_COMPARE (stacksize, attr_stacksize);
}
/* A local variable of the calling thread lies within the reported bounds. */
static void
check_contains_local (void)
{
void *stackaddr;
size_t stacksize;
TEST_COMPARE (pthread_getstack_np (pthread_self (), &stackaddr,
&stacksize), 0);
char here;
TEST_VERIFY ((uintptr_t) &here >= (uintptr_t) stackaddr);
TEST_VERIFY ((uintptr_t) &here < (uintptr_t) stackaddr + stacksize);
}
static void *
thread_func (void *arg)
{
check_against_getattr_np (pthread_self ());
check_contains_local ();
return NULL;
}
static void *main_stackaddr;
static size_t main_stacksize;
/* Runs on the alternate signal stack, the reported bounds are still the ones
of the thread stack. */
static void
signal_handler (int sig)
{
void *stackaddr;
size_t stacksize;
TEST_COMPARE (pthread_getstack_np (pthread_self (), &stackaddr, &stacksize),
0);
TEST_VERIFY (stackaddr == main_stackaddr);
TEST_COMPARE (stacksize, main_stacksize);
}
/* Mount /proc so that /proc/self/maps cannot be opened, which forces the
AT_EXECFN fallback for the initial thread. */
static void
check_proc_fallback (void *closure)
{
if (!support_become_root ())
{
puts ("info: cannot become root, skipping /proc fallback check");
return;
}
if (!support_enter_mount_namespace ())
{
puts ("info: cannot enter mount namespace, skipping /proc fallback"
" check");
return;
}
if (mount ("none", "/proc", "tmpfs", 0, NULL) != 0)
{
printf ("info: cannot mount tmpfs on /proc (%m), skipping /proc"
" fallback check\n");
return;
}
/* The maps reader must now fail, so the fallback is exercised. */
TEST_VERIFY (open64 ("/proc/self/maps", O_RDONLY) < 0);
void *stackaddr;
size_t stacksize;
int ret = pthread_getstack_np (pthread_self (), &stackaddr, &stacksize);
pthread_attr_t attr;
int gret = pthread_getattr_np (pthread_self (), &attr);
TEST_COMPARE (ret, gret);
if (ret == 0)
{
/* The fallback (downward-growing stack) reproduces the value
computed from the maps, captured in the parent before the fork. */
void *attr_stackaddr;
size_t attr_stacksize;
TEST_COMPARE (pthread_attr_getstack (&attr, &attr_stackaddr,
&attr_stacksize), 0);
TEST_COMPARE (pthread_attr_destroy (&attr), 0);
TEST_VERIFY (stackaddr == attr_stackaddr);
TEST_COMPARE (stacksize, attr_stacksize);
TEST_VERIFY (stackaddr == main_stackaddr);
TEST_COMPARE (stacksize, main_stacksize);
char here;
TEST_VERIFY ((uintptr_t) &here >= (uintptr_t) stackaddr);
TEST_VERIFY ((uintptr_t) &here < (uintptr_t) stackaddr + stacksize);
}
else
{
/* Configurations without the fallback (e.g. an upward-growing
stack) report the failure instead of a stack. */
printf ("info: no /proc fallback in this configuration (ret %d)\n",
ret);
TEST_COMPARE (ret, ENOENT);
}
}
/* Read the current [stack] vma from /proc/self/maps. */
static bool
stack_vma (uintptr_t *lo, uintptr_t *hi)
{
FILE *f = fopen ("/proc/self/maps", "r");
if (f == NULL)
return false;
bool found = false;
char line[512];
while (fgets (line, sizeof line, f) != NULL)
if (strstr (line, "[stack]") != NULL
&& sscanf (line, "%" SCNxPTR "-%" SCNxPTR, lo, hi) == 2)
{
found = true;
break;
}
fclose (f);
return found;
}
static __attribute__ ((noinline)) bool
stack_grows_down_1 (uintptr_t outer)
{
char inner;
return (uintptr_t) &inner < outer;
}
static bool
stack_grows_down (void)
{
char outer;
return stack_grows_down_1 ((uintptr_t) &outer);
}
/* The kernel does not grow the stack into the guard gap above the mapping
below it. With a mapping planted within that distance below the current
vma the stack can not grow at all, so the reported lowest address must be
the current vma bottom rather than the end of the planted mapping. This
must be the last check, since afterwards the stack can not grow. */
static void
check_stack_guard_gap (void)
{
if (!stack_grows_down ())
{
puts ("info: stack grows up, skipping guard gap check");
return;
}
uintptr_t lo, hi;
if (!stack_vma (&lo, &hi))
{
puts ("info: no [stack] in /proc/self/maps, skipping guard gap check");
return;
}
long pagesz = sysconf (_SC_PAGESIZE);
uintptr_t planted = (lo - 100 * 1024) & -(uintptr_t) pagesz;
void *m = mmap ((void *) planted, pagesz, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0);
if (m == MAP_FAILED)
{
printf ("info: cannot map below the stack (%m), skipping guard gap"
" check\n");
return;
}
TEST_VERIFY ((uintptr_t) m == planted);
void *stackaddr;
size_t stacksize;
TEST_COMPARE (pthread_getstack_np (pthread_self (), &stackaddr, &stacksize),
0);
/* The vma may only have grown down since it was read. */
uintptr_t lo2, hi2;
TEST_VERIFY (stack_vma (&lo2, &hi2));
TEST_VERIFY (lo2 <= (uintptr_t) stackaddr && (uintptr_t) stackaddr <= lo);
TEST_VERIFY ((uintptr_t) stackaddr > planted + pagesz);
check_against_getattr_np (pthread_self ());
}
static int
do_test (void)
{
check_against_getattr_np (pthread_self ());
check_contains_local ();
TEST_COMPARE (pthread_getstack_np (pthread_self (), &main_stackaddr,
&main_stacksize), 0);
/* A thread with the default stack size, queried both by itself and
by another thread. */
{
pthread_t thr = xpthread_create (NULL, thread_func, NULL);
check_against_getattr_np (thr);
xpthread_join (thr);
}
/* A thread with a non-default stack size. */
{
pthread_attr_t attr;
xpthread_attr_init (&attr);
xpthread_attr_setstacksize (&attr, 256 * 1024);
xpthread_join (xpthread_create (&attr, thread_func, NULL));
xpthread_attr_destroy (&attr);
}
/* From a signal handler running on the alternate signal stack. */
{
struct support_stack altstack = support_stack_alloc (SIGSTKSZ);
stack_t ss = { .ss_sp = altstack.stack, .ss_size = altstack.size };
TEST_COMPARE (sigaltstack (&ss, NULL), 0);
xsigaction (SIGUSR1,
&(struct sigaction) {
.sa_handler = signal_handler,
.sa_flags = SA_ONSTACK },
NULL);
xraise (SIGUSR1);
support_stack_free (&altstack);
}
/* The initial thread fallback when /proc is not accessible. */
support_isolate_in_subprocess (check_proc_fallback, NULL);
check_stack_guard_gap ();
return 0;
}
#include <support/test-driver.c>
+6
View File
@@ -1320,6 +1320,12 @@ extern int pthread_getcpuclockid (pthread_t __thread_id,
#ifdef __USE_GNU
/* Return the Linux TID for THREAD_ID. Returns -1 on failure. */
extern pid_t pthread_gettid_np (pthread_t __thread_id);
/* Store the lowest usable address of the stack of THREAD_ID in *STACKADDR and
the number of usable bytes from that address in *STACKSIZE. */
extern int pthread_getstack_np (pthread_t __thread_id,
void **__stackaddr, size_t *__stacksize)
__THROW __nonnull ((2, 3));
#endif
+2
View File
@@ -563,6 +563,8 @@ sysdep_routines += \
spawnattr_setcgroup_np \
# sysdep_routines
CFLAGS-procutils.c += -fexceptions -fasynchronous-unwind-tables
tests += \
tst-affinity \
tst-affinity-pid \
@@ -2775,3 +2775,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -3122,6 +3122,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
+1
View File
@@ -2536,3 +2536,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -2828,6 +2828,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2825,6 +2825,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2812,3 +2812,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -2849,6 +2849,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -3032,6 +3032,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2287,3 +2287,4 @@ GLIBC_2.44 wprintf F
GLIBC_2.44 write F
GLIBC_2.44 writev F
GLIBC_2.44 wscanf F
GLIBC_2.45 pthread_getstack_np F
@@ -2296,3 +2296,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -2808,6 +2808,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2975,6 +2975,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2861,3 +2861,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -2858,3 +2858,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -2938,6 +2938,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2936,6 +2936,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2944,6 +2944,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2846,6 +2846,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2286,3 +2286,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -3165,6 +3165,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -3210,6 +3210,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2919,6 +2919,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2995,3 +2995,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
+13
View File
@@ -16,6 +16,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <libc-lock.h>
#include <not-cancel.h>
#include <procutils.h>
#include <stdbool.h>
@@ -109,6 +110,12 @@ next_line (struct line_reader *lr, char **r)
}
}
static void
close_handler (void *arg)
{
__close_nocancel_nostatus (*(int *) arg);
}
enum procutils_read_result_t
__libc_procutils_read_file (const char *filename, char *buffer,
size_t buffer_size, procutils_closure_t closure,
@@ -127,7 +134,11 @@ __libc_procutils_read_file (const char *filename, char *buffer,
if (lr.fd == -1)
return procutils_read_error;
/* The cleanup handler is required to avoid leaking the descriptor if
the thread is asynchronously canceled. */
enum next_line_result_t r;
__libc_cleanup_push (close_handler, &lr.fd);
char *line;
while ((r = next_line (&lr, &line)) == next_line_ok)
if (closure (line, arg) != 0)
@@ -135,6 +146,8 @@ __libc_procutils_read_file (const char *filename, char *buffer,
__close_nocancel_nostatus (lr.fd);
__libc_cleanup_pop (0);
if (r == next_line_error)
return procutils_read_error;
return r == next_line_ok ? procutils_read_stop : procutils_read_eof;
@@ -2539,3 +2539,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -2739,3 +2739,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
@@ -2956,6 +2956,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2855,6 +2855,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2852,6 +2852,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -3186,6 +3186,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2822,6 +2822,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2771,6 +2771,7 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2790,3 +2790,4 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
GLIBC_2.45 pthread_getstack_np F