git: 98200077809a - main - rtld-elf: Use a proper struct type for tlsdesc entries

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Wed, 05 Jun 2024 16:42:12 UTC
The branch main has been updated by jrtc27:

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

commit 98200077809a0926ae1775e4d56dd02651131e88
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2024-06-05 16:41:54 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2024-06-05 16:41:54 +0000

    rtld-elf: Use a proper struct type for tlsdesc entries
    
    This clarifies the code and makes it less error-prone. It also makes it
    easier to extend downstream in CheriBSD (where pointer and integer
    members no longer have the same representation and an additional member
    is present).
    
    Reviewed by:    jhb, kib
    Differential Revision:  https://reviews.freebsd.org/D45143
---
 libexec/rtld-elf/aarch64/reloc.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/libexec/rtld-elf/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c
index 78e2e2b1aaae..5dfe19e3d4f4 100644
--- a/libexec/rtld-elf/aarch64/reloc.c
+++ b/libexec/rtld-elf/aarch64/reloc.c
@@ -183,7 +183,7 @@ struct tls_data {
 	Elf_Addr	tls_offs;
 };
 
-static Elf_Addr
+static struct tls_data *
 reloc_tlsdesc_alloc(int tlsindex, Elf_Addr tlsoffs)
 {
 	struct tls_data *tlsdesc;
@@ -193,18 +193,26 @@ reloc_tlsdesc_alloc(int tlsindex, Elf_Addr tlsoffs)
 	tlsdesc->tls_index = tlsindex;
 	tlsdesc->tls_offs = tlsoffs;
 
-	return ((Elf_Addr)tlsdesc);
+	return (tlsdesc);
 }
 
+struct tlsdesc_entry {
+	void	*(*func)(void *);
+	union {
+		Elf_Ssize	addend;
+		Elf_Size	offset;
+		struct tls_data	*data;
+	};
+};
+
 static void
-reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *where,
-    int flags, RtldLockState *lockstate)
+reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rela *rela,
+    struct tlsdesc_entry *where, int flags, RtldLockState *lockstate)
 {
 	const Elf_Sym *def;
 	const Obj_Entry *defobj;
 	Elf_Addr offs;
 
-
 	offs = 0;
 	if (ELF_R_SYM(rela->r_info) != 0) {
 		def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, flags,
@@ -215,8 +223,8 @@ reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *where,
 		obj = defobj;
 		if (def->st_shndx == SHN_UNDEF) {
 			/* Weak undefined thread variable */
-			where[0] = (Elf_Addr)_rtld_tlsdesc_undef;
-			where[1] = rela->r_addend;
+			where->func = _rtld_tlsdesc_undef;
+			where->addend = rela->r_addend;
 			return;
 		}
 	}
@@ -224,12 +232,12 @@ reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *where,
 
 	if (obj->tlsoffset != 0) {
 		/* Variable is in initialy allocated TLS segment */
-		where[0] = (Elf_Addr)_rtld_tlsdesc_static;
-		where[1] = obj->tlsoffset + offs;
+		where->func = _rtld_tlsdesc_static;
+		where->offset = obj->tlsoffset + offs;
 	} else {
 		/* TLS offest is unknown at load time, use dynamic resolving */
-		where[0] = (Elf_Addr)_rtld_tlsdesc_dynamic;
-		where[1] = reloc_tlsdesc_alloc(obj->tlsindex, offs);
+		where->func = _rtld_tlsdesc_dynamic;
+		where->data = reloc_tlsdesc_alloc(obj->tlsindex, offs);
 	}
 }
 
@@ -289,8 +297,8 @@ reloc_plt(Obj_Entry *obj, int flags, RtldLockState *lockstate)
 			}
 			break;
 		case R_AARCH64_TLSDESC:
-			reloc_tlsdesc(obj, rela, where, SYMLOOK_IN_PLT | flags,
-			    lockstate);
+			reloc_tlsdesc(obj, rela, (struct tlsdesc_entry *)where,
+			    SYMLOOK_IN_PLT | flags, lockstate);
 			break;
 		case R_AARCH64_IRELATIVE:
 			obj->irelative = true;
@@ -549,7 +557,8 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
 			}
 			break;
 		case R_AARCH64_TLSDESC:
-			reloc_tlsdesc(obj, rela, where, flags, lockstate);
+			reloc_tlsdesc(obj, rela, (struct tlsdesc_entry *)where,
+			    flags, lockstate);
 			break;
 		case R_AARCH64_TLS_TPREL64:
 			/*