aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/gen
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2021-12-09 21:17:54 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2021-12-09 21:23:05 +0000
commit8bcdb144ebe391ce243c71caf06cf417d96ce335 (patch)
tree7c4635643764b7489032ee111e52fce54225f484 /lib/libc/gen
parent75395023ff1edaf4832389716338b1ba12121ffe (diff)
downloadsrc-8bcdb144ebe391ce243c71caf06cf417d96ce335.tar.gz
src-8bcdb144ebe391ce243c71caf06cf417d96ce335.zip
TLS: Use <machine/tls.h> for libc and rtld.
- Include <machine/tls.h> in MD rtld_machdep.h headers. - Remove local definitions of TLS_* constants from rtld_machdep.h headers and libc using the values from <machine/tls.h> instead. - Use _tcb_set() instead of inlined versions in MD allocate_initial_tls() routines in rtld. The one exception is amd64 whose _tcb_set() invokes the amd64_set_fsbase ifunc. rtld cannot use ifuncs, so amd64 inlines the logic to optionally write to fsbase directly. - Use _tcb_set() instead of _set_tp() in libc. - Use '&_tcb_get()->tcb_dtv' instead of _get_tp() in both rtld and libc. This permits removing _get_tp.c from rtld. - Use TLS_TCB_SIZE and TLS_TCB_ALIGN with allocate_tls() in MD allocate_initial_tls() routines in rtld. Reviewed by: kib, jrtc27 (earlier version) Differential Revision: https://reviews.freebsd.org/D33353
Diffstat (limited to 'lib/libc/gen')
-rw-r--r--lib/libc/gen/tls.c25
1 files changed, 5 insertions, 20 deletions
diff --git a/lib/libc/gen/tls.c b/lib/libc/gen/tls.c
index 5995cf605ed3..d75b883b68db 100644
--- a/lib/libc/gen/tls.c
+++ b/lib/libc/gen/tls.c
@@ -72,18 +72,6 @@ void _rtld_free_tls(void *tls, size_t tcbsize, size_t tcbalign);
void *__libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign);
void __libc_free_tls(void *tls, size_t tcbsize, size_t tcbalign);
-#if defined(__amd64__) || defined(__aarch64__) || defined(__riscv)
-#define TLS_TCB_ALIGN 16
-#elif defined(__arm__) || defined(__mips__)
-#define TLS_TCB_ALIGN 8
-#elif defined(__powerpc__)
-#define TLS_TCB_ALIGN TLS_TCB_SIZE
-#elif defined(__i386__)
-#define TLS_TCB_ALIGN 4
-#else
-#error TLS_TCB_ALIGN undefined for target architecture
-#endif
-
#ifndef PIC
static size_t libc_tls_static_space;
@@ -95,11 +83,10 @@ static void *libc_tls_init;
void *
__libc_tls_get_addr(void *vti)
{
- Elf_Addr **dtvp, *dtv;
+ uintptr_t *dtv;
tls_index *ti;
- dtvp = _get_tp();
- dtv = *dtvp;
+ dtv = _tcb_get()->tcb_dtv;
ti = vti;
return ((char *)(dtv[ti->ti_module + 1] + ti->ti_offset) +
TLS_DTV_OFFSET);
@@ -165,7 +152,7 @@ libc_free_aligned(void *ptr)
* described in [3] where TP points (with bias) to TLS and TCB immediately
* precedes TLS without any alignment gap[4]. Only TLS should be aligned.
* The TCB[0] points to DTV vector and DTV values are biased by constant
- * value (0x8000) from real addresses[5].
+ * value (TLS_DTV_OFFSET) from real addresses[5].
*
* [1] Ulrich Drepper: ELF Handling for Thread-Local Storage
* www.akkadia.org/drepper/tls.pdf
@@ -178,7 +165,7 @@ libc_free_aligned(void *ptr)
* https://members.openpowerfoundation.org/document/dl/576
*
* [4] Its unclear if "without any alignment gap" is hard ABI requirement,
- * but we must follow this rule due to suboptimal _set_tp()
+ * but we must follow this rule due to suboptimal _tcb_set()
* (aka <ARCH>_SET_TP) implementation. This function doesn't expect TP but
* TCB as argument.
*
@@ -310,8 +297,6 @@ __libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign)
#ifdef TLS_VARIANT_II
-#define TLS_TCB_SIZE (3 * sizeof(Elf_Addr))
-
/*
* Free Static TLS using the Variant II method.
*/
@@ -465,6 +450,6 @@ _init_tls(void)
}
tls = _rtld_allocate_tls(NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN);
- _set_tp(tls);
+ _tcb_set(tls);
#endif
}