diff options
author | Florian Weimer <fweimer@redhat.com> | 2025-01-09 19:30:44 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2025-01-09 19:30:44 +0100 |
commit | d1da011118ad8e35002034128458355a2de570ef (patch) | |
tree | 697fb370500477b36b8b061f945bd413b86e4539 | |
parent | 9b71570c465a38cc19c3362526048c7dcfc999e6 (diff) | |
download | glibc-d1da011118ad8e35002034128458355a2de570ef.zip glibc-d1da011118ad8e35002034128458355a2de570ef.tar.gz glibc-d1da011118ad8e35002034128458355a2de570ef.tar.bz2 |
elf: Always define TLS_TP_OFFSET
This will be needed to compute __rseq_offset outside of the TLS
relocation machinery.
Reviewed-by: Michael Jeanson <mjeanson@efficios.com>
-rw-r--r-- | elf/Makefile | 1 | ||||
-rw-r--r-- | elf/tst-tls_tp_offset.c | 57 | ||||
-rw-r--r-- | sysdeps/generic/dl-tls.h | 3 | ||||
-rw-r--r-- | sysdeps/i386/dl-tls.h | 3 | ||||
-rw-r--r-- | sysdeps/s390/dl-tls.h | 3 | ||||
-rw-r--r-- | sysdeps/x86_64/x32/dl-tls.h | 3 |
6 files changed, 70 insertions, 0 deletions
diff --git a/elf/Makefile b/elf/Makefile index 048878d..4b1d0d8 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 0000000..e7c5066 --- /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> diff --git a/sysdeps/generic/dl-tls.h b/sysdeps/generic/dl-tls.h index 8aff4b6..e9480f1 100644 --- a/sysdeps/generic/dl-tls.h +++ b/sysdeps/generic/dl-tls.h @@ -33,4 +33,7 @@ extern void *__tls_get_addr (tls_index *ti); TLS block. */ #define TLS_DTV_OFFSET 0 +/* Static TLS offsets are relative to the unadjusted thread pointer. */ +#define TLS_TP_OFFSET 0 + #endif /* _DL_TLS_H */ diff --git a/sysdeps/i386/dl-tls.h b/sysdeps/i386/dl-tls.h index eed1832..2dac81b 100644 --- a/sysdeps/i386/dl-tls.h +++ b/sysdeps/i386/dl-tls.h @@ -28,6 +28,9 @@ typedef struct dl_tls_index TLS block. */ #define TLS_DTV_OFFSET 0 +/* Static TLS offsets are relative to the unadjusted thread pointer. */ +#define TLS_TP_OFFSET 0 + #ifdef SHARED /* This is the prototype for the GNU version. */ extern void *___tls_get_addr (tls_index *ti) diff --git a/sysdeps/s390/dl-tls.h b/sysdeps/s390/dl-tls.h index 74756dd..53fd362 100644 --- a/sysdeps/s390/dl-tls.h +++ b/sysdeps/s390/dl-tls.h @@ -28,6 +28,9 @@ typedef struct TP-relative addresses. */ #define TLS_DTV_OFFSET (-(unsigned long int) __builtin_thread_pointer ()) +/* Static TLS offsets are relative to the unadjusted thread pointer. */ +#define TLS_TP_OFFSET 0 + #ifdef SHARED extern unsigned long __tls_get_offset (unsigned long got_offset); diff --git a/sysdeps/x86_64/x32/dl-tls.h b/sysdeps/x86_64/x32/dl-tls.h index 4b736a4..04ac0fe 100644 --- a/sysdeps/x86_64/x32/dl-tls.h +++ b/sysdeps/x86_64/x32/dl-tls.h @@ -35,4 +35,7 @@ extern void *__tls_get_addr (tls_index *ti); TLS block. */ #define TLS_DTV_OFFSET 0 +/* Static TLS offsets are relative to the unadjusted thread pointer. */ +#define TLS_TP_OFFSET 0 + #endif /* _X86_64_DL_TLS_H */ |