git: b209947fc27c - main - rtld-elf: Use struct tcb * rather than uintptr_t ** for the tcb

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Wed, 07 May 2025 19:22:11 UTC
The branch main has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=b209947fc27ce60be866d8a16657485eedd97d55

commit b209947fc27ce60be866d8a16657485eedd97d55
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2025-05-07 19:20:15 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2025-05-07 19:20:15 +0000

    rtld-elf: Use struct tcb * rather than uintptr_t ** for the tcb
    
    This lets us access via named struct members rather than magic
    hard-coded indices.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D50229
---
 libexec/rtld-elf/rtld.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 8234efdecf53..44347e482c64 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -5436,7 +5436,8 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign)
 {
 	Obj_Entry *obj;
 	char *tls_block;
-	uintptr_t *dtv, **tcb;
+	uintptr_t *dtv;
+	struct tcb *tcb;
 	char *addr;
 	uintptr_t i;
 	size_t extra_size, maxalign, post_size, pre_size, tls_block_size;
@@ -5459,7 +5460,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 = (uintptr_t **)(tls_block + pre_size + extra_size);
+	tcb = (struct tcb *)(tls_block + pre_size + extra_size);
 
 	if (oldtcb != NULL) {
 		memcpy(tls_block, get_tls_block_ptr(oldtcb, tcbsize),
@@ -5467,7 +5468,7 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign)
 		free(get_tls_block_ptr(oldtcb, tcbsize));
 
 		/* Adjust the DTV. */
-		dtv = tcb[0];
+		dtv = tcb->tcb_dtv;
 		for (i = 0; i < dtv[1]; i++) {
 			if (dtv[i + 2] >= (uintptr_t)oldtcb &&
 			    dtv[i + 2] < (uintptr_t)oldtcb + tls_static_space) {
@@ -5477,7 +5478,7 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign)
 		}
 	} else {
 		dtv = xcalloc(tls_max_index + 2, sizeof(uintptr_t));
-		tcb[0] = dtv;
+		tcb->tcb_dtv = dtv;
 		dtv[0] = tls_dtv_generation;
 		dtv[1] = tls_max_index;
 
@@ -5524,7 +5525,7 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign __unused)
 	tlsstart = (uintptr_t)tcb + TLS_TCB_SIZE + post_size;
 	tlsend = (uintptr_t)tcb + tls_static_space;
 
-	dtv = *(uintptr_t **)tcb;
+	dtv = ((struct tcb *)tcb)->tcb_dtv;
 	dtvsize = dtv[1];
 	for (i = 0; i < dtvsize; i++) {
 		if (dtv[i + 2] != 0 && (dtv[i + 2] < tlsstart ||
@@ -5550,7 +5551,7 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign)
 	size_t size, ralign;
 	char *tls_block;
 	uintptr_t *dtv, *olddtv;
-	uintptr_t **tcb;
+	struct tcb *tcb;
 	char *addr;
 	size_t i;
 
@@ -5563,9 +5564,9 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign)
 	tls_block = xmalloc_aligned(size, ralign, 0 /* XXX */);
 	dtv = xcalloc(tls_max_index + 2, sizeof(uintptr_t));
 
-	tcb = (uintptr_t **)(tls_block + roundup(tls_static_space, ralign));
-	tcb[0] = (uintptr_t *)tcb;
-	tcb[1] = dtv;
+	tcb = (struct tcb *)(tls_block + roundup(tls_static_space, ralign));
+	tcb->tcb_self = tcb;
+	tcb->tcb_dtv = dtv;
 
 	dtv[0] = tls_dtv_generation;
 	dtv[1] = tls_max_index;
@@ -5582,7 +5583,7 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign)
 		 * If any dynamic TLS blocks have been created tls_get_addr(),
 		 * move them over.
 		 */
-		olddtv = ((uintptr_t **)oldtcb)[1];
+		olddtv = ((struct tcb *)oldtcb)->tcb_dtv;
 		for (i = 0; i < olddtv[1]; i++) {
 			if (olddtv[i + 2] < (uintptr_t)oldtcb - size ||
 			    olddtv[i + 2] > (uintptr_t)oldtcb) {
@@ -5631,7 +5632,7 @@ free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign)
 		ralign = tls_static_max_align;
 	size = roundup(tls_static_space, ralign);
 
-	dtv = ((uintptr_t **)tcb)[1];
+	dtv = ((struct tcb *)tcb)->tcb_dtv;
 	dtvsize = dtv[1];
 	tlsend = (uintptr_t)tcb;
 	tlsstart = tlsend - size;