|
|
Message-ID:
<BN0SPR01MB00023DB344ABAA7F6D553E88B9FD2@BN0SPR01MB0002.namprd20.prod.outlook.com>
Date: Tue, 11 Feb 2025 19:50:40 +0000
From: Daniil Kovalev <dkovalev@...esssoftek.com>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
Subject: [PATCH] aarch64: handle TLSDESC relocs against undef weak symbols
if a weak symbol is undefined, it's address must be null. when accessing
a thread-local symbol via tlsdesc, the value of TPIDR_EL0 is added to the
return value of the tls descriptor function. so, in case of an undefined
symbol, the descriptor function should return -TPIDR_EL0 which will give
null after adding TPIDR_EL0.
---
arch/aarch64/reloc.h | 2 ++
ldso/dynlink.c | 6 ++++++
src/internal/dynlink.h | 3 +++
src/ldso/aarch64/tlsdesc.s | 9 +++++++++
4 files changed, 20 insertions(+)
diff --git a/arch/aarch64/reloc.h b/arch/aarch64/reloc.h
index b1b68c72..a8229982 100644
--- a/arch/aarch64/reloc.h
+++ b/arch/aarch64/reloc.h
@@ -20,5 +20,7 @@
#define REL_TPOFF R_AARCH64_TLS_TPREL64
#define REL_TLSDESC R_AARCH64_TLSDESC
+#define TLSDESC_UNDEF_WEAK_SUPPORT 1
+
#define CRTJMP(pc,sp) __asm__ __volatile__( \
"mov sp,%1 ; br %0" : : "r"(pc), "r"(sp) : "memory" )
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 3b57c07f..4b19ef0d 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -515,6 +515,12 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
#endif
case REL_TLSDESC:
if (stride<3) addend = reloc_addr[!TLSDESC_BACKWARDS];
+#ifdef TLSDESC_UNDEF_WEAK_SUPPORT
+ if (sym && sym->st_info>>4 == STB_WEAK && sym->st_shndx == SHN_UNDEF) {
+ reloc_addr[0] = (size_t)__tlsdesc_undef_weak;
+ reloc_addr[1] = 0;
+ } else
+#endif
if (def.dso->tls_id > static_tls_cnt) {
struct td_index *new = malloc(sizeof *new);
if (!new) {
diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
index 40c743e2..588458f3 100644
--- a/src/internal/dynlink.h
+++ b/src/internal/dynlink.h
@@ -112,6 +112,9 @@ hidden int __dl_invalid_handle(void *);
hidden void __dl_vseterr(const char *, va_list);
hidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
+#ifdef TLSDESC_UNDEF_WEAK_SUPPORT
+hidden ptrdiff_t __tlsdesc_undef_weak();
+#endif
hidden extern int __malloc_replaced;
hidden extern int __aligned_alloc_replaced;
diff --git a/src/ldso/aarch64/tlsdesc.s b/src/ldso/aarch64/tlsdesc.s
index c6c685b3..e4b0f9a6 100644
--- a/src/ldso/aarch64/tlsdesc.s
+++ b/src/ldso/aarch64/tlsdesc.s
@@ -29,3 +29,12 @@ __tlsdesc_dynamic:
add x0,x1,x2 // dtv[p->modidx] + p->off - tp
ldp x1,x2,[sp],#16
ret
+
+.global __tlsdesc_undef_weak
+.hidden __tlsdesc_undef_weak
+.type __tlsdesc_undef_weak,@function
+__tlsdesc_undef_weak:
+ mov x0,#0
+ mrs x8,TPIDR_EL0
+ sub x0,x0,x8
+ ret
--
2.48.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.