git: 4642b638a522 - main - rtld-elf: Consistently use uintptr_t for TLS implementation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 07 May 2025 19:22:07 UTC
The branch main has been updated by jrtc27: URL: https://cgit.FreeBSD.org/src/commit/?id=4642b638a52253ae04aef699bee246b1fa7c9d1c commit 4642b638a52253ae04aef699bee246b1fa7c9d1c Author: Jessica Clarke <jrtc27@FreeBSD.org> AuthorDate: 2025-05-07 19:19:55 +0000 Commit: Jessica Clarke <jrtc27@FreeBSD.org> CommitDate: 2025-05-07 19:19:55 +0000 rtld-elf: Consistently use uintptr_t for TLS implementation Elf_Addr is the format of addresses in the ELF file with the current ABI's default class. This is normally the same as the format of an address at run time, though technically exceptions do exist outside of FreeBSD's currently-supported architectures (for example, IA-64's LP64 supports both ELFCLASS32 and ELFCLASS64 file formats; LP64 vs ILP32 is an orthogonal EF_IA_64_ABI64 flag). On traditional architectures, including all currently-supported FreeBSD architectures, addresses and pointers are synonymous, but on CHERI they are not, as pointers are capabilities that contain metadata alongside the address. In the cases here, the quantities are run-time pointers, not addresses (and definitely not ELF file addresses), so we should use pointer-ish types. Note that we already use uintptr_t in struct tcb (both Variant I and Variant II) but still use Elf_Addr in various places here (including different argument types for tls_get_addr_slow and tls_get_addr_common). Also use char * for addr rather than even uintptr_t, since most of the time we want it to be an actual pointer. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D50226 --- libexec/rtld-elf/rtld.c | 94 ++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index eb04a2f17603..4376b67aa4a9 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(Elf_Addr **, int, size_t, bool) __noinline; +static void *tls_get_addr_slow(uintptr_t **, 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); @@ -5350,9 +5350,9 @@ unref_dag(Obj_Entry *root) * Common code for MD __tls_get_addr(). */ static void * -tls_get_addr_slow(Elf_Addr **dtvp, int index, size_t offset, bool locked) +tls_get_addr_slow(uintptr_t **dtvp, int index, size_t offset, bool locked) { - Elf_Addr *newdtv, *dtv; + uintptr_t *newdtv, *dtv; RtldLockState lockstate; int to_copy; @@ -5361,11 +5361,11 @@ tls_get_addr_slow(Elf_Addr **dtvp, int index, size_t offset, bool locked) if (dtv[0] != tls_dtv_generation) { if (!locked) wlock_acquire(rtld_bind_lock, &lockstate); - newdtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); + newdtv = xcalloc(tls_max_index + 2, sizeof(uintptr_t)); to_copy = dtv[1]; if (to_copy > tls_max_index) to_copy = tls_max_index; - memcpy(&newdtv[2], &dtv[2], to_copy * sizeof(Elf_Addr)); + memcpy(&newdtv[2], &dtv[2], to_copy * sizeof(uintptr_t)); newdtv[0] = tls_dtv_generation; newdtv[1] = tls_max_index; free(dtv); @@ -5380,7 +5380,7 @@ tls_get_addr_slow(Elf_Addr **dtvp, int index, size_t offset, bool locked) if (!locked) wlock_acquire(rtld_bind_lock, &lockstate); if (!dtv[index + 1]) - dtv[index + 1] = (Elf_Addr)allocate_module_tls(index); + dtv[index + 1] = (uintptr_t)allocate_module_tls(index); if (!locked) lock_release(rtld_bind_lock, &lockstate); } @@ -5436,9 +5436,9 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) { Obj_Entry *obj; char *tls_block; - Elf_Addr *dtv, **tcb; - Elf_Addr addr; - Elf_Addr i; + uintptr_t *dtv, **tcb; + char *addr; + uintptr_t i; size_t extra_size, maxalign, post_size, pre_size, tls_block_size; size_t tls_init_align, tls_init_offset; @@ -5459,7 +5459,7 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) /* Allocate whole TLS block */ tls_block = xmalloc_aligned(tls_block_size, maxalign, 0); - tcb = (Elf_Addr **)(tls_block + pre_size + extra_size); + tcb = (uintptr_t **)(tls_block + pre_size + extra_size); if (oldtcb != NULL) { memcpy(tls_block, get_tls_block_ptr(oldtcb, tcbsize), @@ -5469,14 +5469,14 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) /* Adjust the DTV. */ dtv = tcb[0]; for (i = 0; i < dtv[1]; i++) { - if (dtv[i + 2] >= (Elf_Addr)oldtcb && - dtv[i + 2] < (Elf_Addr)oldtcb + tls_static_space) { - dtv[i + 2] = dtv[i + 2] - (Elf_Addr)oldtcb + - (Elf_Addr)tcb; + if (dtv[i + 2] >= (uintptr_t)oldtcb && + dtv[i + 2] < (uintptr_t)oldtcb + tls_static_space) { + dtv[i + 2] = dtv[i + 2] - (uintptr_t)oldtcb + + (uintptr_t)tcb; } } } else { - dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); + dtv = xcalloc(tls_max_index + 2, sizeof(uintptr_t)); tcb[0] = dtv; dtv[0] = tls_dtv_generation; dtv[1] = tls_max_index; @@ -5486,21 +5486,21 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) if (obj->tlsoffset == 0) continue; tls_init_offset = obj->tlspoffset & (obj->tlsalign - 1); - addr = (Elf_Addr)tcb + obj->tlsoffset; + addr = (char *)tcb + obj->tlsoffset; if (tls_init_offset > 0) - memset((void *)addr, 0, tls_init_offset); + memset(addr, 0, tls_init_offset); if (obj->tlsinitsize > 0) { - memcpy((void *)(addr + tls_init_offset), - obj->tlsinit, obj->tlsinitsize); + memcpy(addr + tls_init_offset, obj->tlsinit, + obj->tlsinitsize); } if (obj->tlssize > obj->tlsinitsize) { - memset((void *)(addr + tls_init_offset + - obj->tlsinitsize), + memset(addr + tls_init_offset + + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize - tls_init_offset); } - dtv[obj->tlsindex + 1] = addr; + dtv[obj->tlsindex + 1] = (uintptr_t)addr; } } @@ -5510,8 +5510,8 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) void free_tls(void *tcb, size_t tcbsize, size_t tcbalign __unused) { - Elf_Addr *dtv; - Elf_Addr tlsstart, tlsend; + uintptr_t *dtv; + uintptr_t tlsstart, tlsend; size_t post_size; size_t dtvsize, i, tls_init_align __unused; @@ -5521,10 +5521,10 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign __unused) /* Compute fragments sizes. */ post_size = calculate_tls_post_size(tls_init_align); - tlsstart = (Elf_Addr)tcb + TLS_TCB_SIZE + post_size; - tlsend = (Elf_Addr)tcb + tls_static_space; + tlsstart = (uintptr_t)tcb + TLS_TCB_SIZE + post_size; + tlsend = (uintptr_t)tcb + tls_static_space; - dtv = *(Elf_Addr **)tcb; + dtv = *(uintptr_t **)tcb; dtvsize = dtv[1]; for (i = 0; i < dtvsize; i++) { if (dtv[i + 2] != 0 && (dtv[i + 2] < tlsstart || @@ -5549,8 +5549,9 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) Obj_Entry *obj; size_t size, ralign; char *tls; - Elf_Addr *dtv, *olddtv; - Elf_Addr segbase, oldsegbase, addr; + uintptr_t *dtv, *olddtv; + uintptr_t segbase, oldsegbase; + char *addr; size_t i; ralign = tcbalign; @@ -5558,13 +5559,13 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) ralign = tls_static_max_align; size = roundup(tls_static_space, ralign) + roundup(tcbsize, ralign); - assert(tcbsize >= 2 * sizeof(Elf_Addr)); + assert(tcbsize >= 2 * sizeof(uintptr_t)); tls = xmalloc_aligned(size, ralign, 0 /* XXX */); - dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); + dtv = xcalloc(tls_max_index + 2, sizeof(uintptr_t)); - segbase = (Elf_Addr)(tls + roundup(tls_static_space, ralign)); - ((Elf_Addr *)segbase)[0] = segbase; - ((Elf_Addr *)segbase)[1] = (Elf_Addr)dtv; + segbase = (uintptr_t)(tls + roundup(tls_static_space, ralign)); + ((uintptr_t *)segbase)[0] = segbase; + ((uintptr_t *)segbase)[1] = (uintptr_t)dtv; dtv[0] = tls_dtv_generation; dtv[1] = tls_max_index; @@ -5573,7 +5574,7 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) /* * Copy the static TLS block over whole. */ - oldsegbase = (Elf_Addr)oldtls; + oldsegbase = (uintptr_t)oldtls; memcpy((void *)(segbase - tls_static_space), (const void *)(oldsegbase - tls_static_space), tls_static_space); @@ -5582,7 +5583,7 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) * If any dynamic TLS blocks have been created tls_get_addr(), * move them over. */ - olddtv = ((Elf_Addr **)oldsegbase)[1]; + olddtv = ((uintptr_t **)oldsegbase)[1]; for (i = 0; i < olddtv[1]; i++) { if (olddtv[i + 2] < oldsegbase - size || olddtv[i + 2] > oldsegbase) { @@ -5595,20 +5596,19 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) * We assume that this block was the one we created with * allocate_initial_tls(). */ - free_tls(oldtls, 2 * sizeof(Elf_Addr), sizeof(Elf_Addr)); + free_tls(oldtls, 2 * sizeof(uintptr_t), sizeof(uintptr_t)); } else { for (obj = objs; obj != NULL; obj = TAILQ_NEXT(obj, next)) { if (obj->marker || obj->tlsoffset == 0) continue; - addr = segbase - obj->tlsoffset; - memset((void *)(addr + obj->tlsinitsize), 0, - obj->tlssize - obj->tlsinitsize); + addr = (char *)segbase - obj->tlsoffset; + memset(addr + obj->tlsinitsize, 0, obj->tlssize - + obj->tlsinitsize); if (obj->tlsinit) { - memcpy((void *)addr, obj->tlsinit, - obj->tlsinitsize); + memcpy(addr, obj->tlsinit, obj->tlsinitsize); obj->static_tls_copied = true; } - dtv[obj->tlsindex + 1] = addr; + dtv[obj->tlsindex + 1] = (uintptr_t)addr; } } @@ -5618,10 +5618,10 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) void free_tls(void *tls, size_t tcbsize __unused, size_t tcbalign) { - Elf_Addr *dtv; + uintptr_t *dtv; size_t size, ralign; int dtvsize, i; - Elf_Addr tlsstart, tlsend; + uintptr_t tlsstart, tlsend; /* * Figure out the size of the initial TLS block so that we can @@ -5632,9 +5632,9 @@ free_tls(void *tls, size_t tcbsize __unused, size_t tcbalign) ralign = tls_static_max_align; size = roundup(tls_static_space, ralign); - dtv = ((Elf_Addr **)tls)[1]; + dtv = ((uintptr_t **)tls)[1]; dtvsize = dtv[1]; - tlsend = (Elf_Addr)tls; + tlsend = (uintptr_t)tls; tlsstart = tlsend - size; for (i = 0; i < dtvsize; i++) { if (dtv[i + 2] != 0 && (dtv[i + 2] < tlsstart ||