git: 960f40b892cf - main - rtld-elf: Pass struct tcb * around rather than struct dtv **
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 29 May 2025 16:07:28 UTC
The branch main has been updated by jrtc27: URL: https://cgit.FreeBSD.org/src/commit/?id=960f40b892cf15961f059f509990652555db7b4f commit 960f40b892cf15961f059f509990652555db7b4f Author: Jessica Clarke <jrtc27@FreeBSD.org> AuthorDate: 2025-05-29 16:06:49 +0000 Commit: Jessica Clarke <jrtc27@FreeBSD.org> CommitDate: 2025-05-29 16:06:49 +0000 rtld-elf: Pass struct tcb * around rather than struct dtv ** When this code was first written we didn't have even a struct tcb, so to make it MI a pointer to the DTV pointer in the TCB was passed around. Now that we have a struct tcb we can simplify the code by instead passing around a pointer to that, and the MI code can access the tcb_dtv member wherever it happens to be in the layout. This reduces boilerplate in all the various callers of tls_get_addr_common/slow and makes it clearer that tls_get_addr_common/slow are operating on the TCB, rather than obfuscating it slightly through the double pointer. Whilst here, clarify the comments in aarch64's TLSDESC dynamic resolver, which were using tp without clarifying what this was for (previously a pointer to the DTV pointer, now a pointer to the TCB, which happen to be the same thing for Variant I TLS, and in the case of AArch64 are what TPIDR_EL0 point to directly, with no offset/bias). Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D50591 --- libexec/rtld-elf/aarch64/reloc.c | 5 +---- libexec/rtld-elf/aarch64/rtld_start.S | 4 ++-- libexec/rtld-elf/amd64/reloc.c | 5 +---- libexec/rtld-elf/arm/reloc.c | 5 +---- libexec/rtld-elf/i386/reloc.c | 10 ++-------- libexec/rtld-elf/powerpc/reloc.c | 5 +---- libexec/rtld-elf/powerpc64/reloc.c | 5 +---- libexec/rtld-elf/riscv/reloc.c | 5 +---- libexec/rtld-elf/rtld.c | 19 ++++++++----------- libexec/rtld-elf/rtld.h | 2 +- 10 files changed, 19 insertions(+), 46 deletions(-) diff --git a/libexec/rtld-elf/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c index 8182bb428bd2..2b64b48585db 100644 --- a/libexec/rtld-elf/aarch64/reloc.c +++ b/libexec/rtld-elf/aarch64/reloc.c @@ -629,8 +629,5 @@ allocate_initial_tls(Obj_Entry *objs) void * __tls_get_addr(tls_index* ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset)); + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset)); } diff --git a/libexec/rtld-elf/aarch64/rtld_start.S b/libexec/rtld-elf/aarch64/rtld_start.S index 53a7463e2634..fdc493198676 100644 --- a/libexec/rtld-elf/aarch64/rtld_start.S +++ b/libexec/rtld-elf/aarch64/rtld_start.S @@ -189,7 +189,7 @@ ENTRY(_rtld_tlsdesc_dynamic) /* * Slow path * return( - * tls_get_addr_common(tp, tlsdesc->tls_index, tlsdesc->tls_offs)); + * tls_get_addr_common(tcb, tlsdesc->tls_index, tlsdesc->tls_offs)); * */ 1: @@ -223,7 +223,7 @@ ENTRY(_rtld_tlsdesc_dynamic) .cfi_rel_offset x18, 120 /* Find the tls offset */ - mov x0, x4 /* tp */ + mov x0, x4 /* tcb */ mov x3, x1 /* tlsdesc ptr */ ldr w1, [x3, #8] /* tlsdec->tls_index */ ldr x2, [x3, #16] /* tlsdec->tls_offs */ diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c index 95f402995836..883e3dcdff88 100644 --- a/libexec/rtld-elf/amd64/reloc.c +++ b/libexec/rtld-elf/amd64/reloc.c @@ -558,10 +558,7 @@ allocate_initial_tls(Obj_Entry *objs) void * __tls_get_addr(tls_index *ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset)); + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset)); } size_t diff --git a/libexec/rtld-elf/arm/reloc.c b/libexec/rtld-elf/arm/reloc.c index 7bb7ce83e1bd..d1c7d3e43349 100644 --- a/libexec/rtld-elf/arm/reloc.c +++ b/libexec/rtld-elf/arm/reloc.c @@ -465,8 +465,5 @@ allocate_initial_tls(Obj_Entry *objs) void * __tls_get_addr(tls_index* ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset)); + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset)); } diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c index ff4b1ebbb148..845735deac7d 100644 --- a/libexec/rtld-elf/i386/reloc.c +++ b/libexec/rtld-elf/i386/reloc.c @@ -523,20 +523,14 @@ allocate_initial_tls(Obj_Entry *objs) __attribute__((__regparm__(1))) void * ___tls_get_addr(tls_index *ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset)); + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset)); } /* Sun ABI */ void * __tls_get_addr(tls_index *ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset)); + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset)); } size_t diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c index 283a02c53511..8932c2c21278 100644 --- a/libexec/rtld-elf/powerpc/reloc.c +++ b/libexec/rtld-elf/powerpc/reloc.c @@ -837,9 +837,6 @@ allocate_initial_tls(Obj_Entry *list) void* __tls_get_addr(tls_index* ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset + + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset + TLS_DTV_OFFSET)); } diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c index b1ca871d2780..9ea14f63b5c7 100644 --- a/libexec/rtld-elf/powerpc64/reloc.c +++ b/libexec/rtld-elf/powerpc64/reloc.c @@ -734,9 +734,6 @@ allocate_initial_tls(Obj_Entry *list) void* __tls_get_addr(tls_index* ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset + + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset + TLS_DTV_OFFSET)); } diff --git a/libexec/rtld-elf/riscv/reloc.c b/libexec/rtld-elf/riscv/reloc.c index cfa474aa93b7..390e8c458c28 100644 --- a/libexec/rtld-elf/riscv/reloc.c +++ b/libexec/rtld-elf/riscv/reloc.c @@ -478,9 +478,6 @@ allocate_initial_tls(Obj_Entry *objs) void * __tls_get_addr(tls_index* ti) { - struct dtv **dtvp; - - dtvp = &_tcb_get()->tcb_dtv; - return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset + + return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset + TLS_DTV_OFFSET)); } diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 3ba6f4bb5bbe..9758fa78bc1b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -170,7 +170,7 @@ static int symlook_list(SymLook *, const Objlist *, DoneList *); static int symlook_needed(SymLook *, const Needed_Entry *, DoneList *); static int symlook_obj1_sysv(SymLook *, const Obj_Entry *); static int symlook_obj1_gnu(SymLook *, const Obj_Entry *); -static void *tls_get_addr_slow(struct dtv **, int, size_t, bool) __noinline; +static void *tls_get_addr_slow(struct tcb *, int, size_t, bool) __noinline; static void trace_loaded_objects(Obj_Entry *, bool); static void unlink_object(Obj_Entry *); static void unload_object(Obj_Entry *, RtldLockState *lockstate); @@ -4312,15 +4312,12 @@ dlinfo(void *handle, int request, void *p) static void rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info) { - struct dtv **dtvp; - phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase; phdr_info->dlpi_name = obj->path; phdr_info->dlpi_phdr = obj->phdr; phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]); phdr_info->dlpi_tls_modid = obj->tlsindex; - dtvp = &_tcb_get()->tcb_dtv; - phdr_info->dlpi_tls_data = (char *)tls_get_addr_slow(dtvp, + phdr_info->dlpi_tls_data = (char *)tls_get_addr_slow(_tcb_get(), obj->tlsindex, 0, true); phdr_info->dlpi_adds = obj_loads; phdr_info->dlpi_subs = obj_loads - obj_count; @@ -5350,13 +5347,13 @@ unref_dag(Obj_Entry *root) * Common code for MD __tls_get_addr(). */ static void * -tls_get_addr_slow(struct dtv **dtvp, int index, size_t offset, bool locked) +tls_get_addr_slow(struct tcb *tcb, int index, size_t offset, bool locked) { struct dtv *newdtv, *dtv; RtldLockState lockstate; int to_copy; - dtv = *dtvp; + dtv = tcb->tcb_dtv; /* Check dtv generation in case new modules have arrived */ if (dtv->dtv_gen != tls_dtv_generation) { if (!locked) @@ -5373,7 +5370,7 @@ tls_get_addr_slow(struct dtv **dtvp, int index, size_t offset, bool locked) free(dtv); if (!locked) lock_release(rtld_bind_lock, &lockstate); - dtv = *dtvp = newdtv; + dtv = tcb->tcb_dtv = newdtv; } /* Dynamically allocate module TLS if necessary */ @@ -5391,16 +5388,16 @@ tls_get_addr_slow(struct dtv **dtvp, int index, size_t offset, bool locked) } void * -tls_get_addr_common(struct dtv **dtvp, int index, size_t offset) +tls_get_addr_common(struct tcb *tcb, int index, size_t offset) { struct dtv *dtv; - dtv = *dtvp; + dtv = tcb->tcb_dtv; /* Check dtv generation in case new modules have arrived */ if (__predict_true(dtv->dtv_gen == tls_dtv_generation && dtv->dtv_slots[index - 1].dtvs_tls != 0)) return (dtv->dtv_slots[index - 1].dtvs_tls + offset); - return (tls_get_addr_slow(dtvp, index, offset, false)); + return (tls_get_addr_slow(tcb, index, offset, false)); } #ifdef TLS_VARIANT_I diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index a92350b9387c..378cb51d36c6 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -415,7 +415,7 @@ void _rtld_bind_start(void); void *rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def); void symlook_init(SymLook *, const char *); int symlook_obj(SymLook *, const Obj_Entry *); -void *tls_get_addr_common(struct dtv **dtvp, int index, size_t offset); +void *tls_get_addr_common(struct tcb *tcb, int index, size_t offset); void *allocate_tls(Obj_Entry *, void *, size_t, size_t); void free_tls(void *, size_t, size_t); void *allocate_module_tls(int index);