git: 4d2752925a4f - main - rtld-elf: Extract part of allocate_tls_offset into allocate_tls_offset_common

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Thu, 10 Jul 2025 19:06:06 UTC
The branch main has been updated by jrtc27:

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

commit 4d2752925a4f75547a67f093dfe249da54196803
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2025-07-10 19:00:28 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2025-07-10 19:00:28 +0000

    rtld-elf: Extract part of allocate_tls_offset into allocate_tls_offset_common
    
    This will be used to allocate additional space for a TAILQ_ENTRY by rtld
    at a known offset from the TCB, as if it were TLS data.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D51068
---
 libexec/rtld-elf/rtld.c | 54 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 1459b38f3720..7172fbf1d794 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -5698,32 +5698,22 @@ allocate_module_tls(struct tcb *tcb, int index)
 	return (p);
 }
 
-bool
-allocate_tls_offset(Obj_Entry *obj)
+static bool
+allocate_tls_offset_common(size_t *offp, size_t tlssize, size_t tlsalign,
+    size_t tlspoffset __unused)
 {
 	size_t off;
 
-	if (obj->tls_dynamic)
-		return (false);
-
-	if (obj->tls_static)
-		return (true);
-
-	if (obj->tlssize == 0) {
-		obj->tls_static = true;
-		return (true);
-	}
-
 	if (tls_last_offset == 0)
-		off = calculate_first_tls_offset(obj->tlssize, obj->tlsalign,
-		    obj->tlspoffset);
+		off = calculate_first_tls_offset(tlssize, tlsalign,
+		    tlspoffset);
 	else
 		off = calculate_tls_offset(tls_last_offset, tls_last_size,
-		    obj->tlssize, obj->tlsalign, obj->tlspoffset);
+		    tlssize, tlsalign, tlspoffset);
 
-	obj->tlsoffset = off;
+	*offp = off;
 #ifdef TLS_VARIANT_I
-	off += obj->tlssize;
+	off += tlssize;
 #endif
 
 	/*
@@ -5735,12 +5725,34 @@ allocate_tls_offset(Obj_Entry *obj)
 	if (tls_static_space != 0) {
 		if (off > tls_static_space)
 			return (false);
-	} else if (obj->tlsalign > tls_static_max_align) {
-		tls_static_max_align = obj->tlsalign;
+	} else if (tlsalign > tls_static_max_align) {
+		tls_static_max_align = tlsalign;
 	}
 
 	tls_last_offset = off;
-	tls_last_size = obj->tlssize;
+	tls_last_size = tlssize;
+
+	return (true);
+}
+
+bool
+allocate_tls_offset(Obj_Entry *obj)
+{
+	if (obj->tls_dynamic)
+		return (false);
+
+	if (obj->tls_static)
+		return (true);
+
+	if (obj->tlssize == 0) {
+		obj->tls_static = true;
+		return (true);
+	}
+
+	if (!allocate_tls_offset_common(&obj->tlsoffset, obj->tlssize,
+	    obj->tlsalign, obj->tlspoffset))
+		return (false);
+
 	obj->tls_static = true;
 
 	return (true);