diff options
Diffstat (limited to 'elf')
| -rw-r--r-- | elf/Makefile | 1 | ||||
| -rw-r--r-- | elf/tst-tls_tp_offset.c | 57 |
2 files changed, 58 insertions, 0 deletions
diff --git a/elf/Makefile b/elf/Makefile index 048878d602..4b1d0d8741 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -322,6 +322,7 @@ tests := \ tests-internal := \ $(tests-static-internal) \ tst-tls1 \ + tst-tls_tp_offset \ # tests-internal tests-static := $(tests-static-normal) $(tests-static-internal) diff --git a/elf/tst-tls_tp_offset.c b/elf/tst-tls_tp_offset.c new file mode 100644 index 0000000000..e7c50663aa --- /dev/null +++ b/elf/tst-tls_tp_offset.c @@ -0,0 +1,57 @@ +/* Check compile-time definition of TLS_TP_OFFSET against run-time value. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <thread_pointer.h> + +#include <dl-tls.h> +#include <link.h> +#include <pthread.h> +#include <stdint.h> +#include <stdio.h> +#include <support/check.h> + +static __thread char thread_var __attribute__ ((tls_model ("initial-exec"))); + +static int +do_test (void) +{ + printf ("thread variable address: %p\n", &thread_var); + printf ("thread pointer address: %p\n", __thread_pointer ()); + printf ("pthread_self address: %p\n", (void *) pthread_self ()); + ptrdiff_t block_offset = ((struct link_map *) _r_debug.r_map)->l_tls_offset; + printf ("main program TLS block offset: %td\n", block_offset); + + if ((uintptr_t) &thread_var < (uintptr_t) pthread_self ()) + { + puts("TLS variables are located before struct pthread."); + TEST_COMPARE (((intptr_t) __thread_pointer () - block_offset) + - (intptr_t) &thread_var, + TLS_TP_OFFSET); + } + else + { + puts("TLS variables are located after struct pthread."); + TEST_COMPARE (((intptr_t) __thread_pointer () + block_offset) + - (intptr_t) &thread_var, + TLS_TP_OFFSET); + } + return 0; +} + +#include <support/test-driver.c> |
