From 6c3be9e0e7a90e63cb91d890f1a63e682f413d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 11 Oct 2026 09:23:01 +0200 Subject: [PATCH] compiler_rt.elf.tls: fix a couple of bugs in __tls_get_addr() and __tls_get_offset() * We need to add current_dtv_offset in __tls_get_addr() because we aren't reading the actual DTV entry (where that value would be baked in). * In both __tls_get_addr() and __tls_get_offset(), we need to subtract area_info.abi_tcb.offset rather than area_info.block.size because we apply align_factor to the block size when computing the area layout. --- lib/compiler_rt/elf/tls.zig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/compiler_rt/elf/tls.zig b/lib/compiler_rt/elf/tls.zig index fd5f8fe6913253af4d950c4b921f088cd708cb93..944cf394b65e1d629787fd09114dfee02bb080c5 100644 --- a/lib/compiler_rt/elf/tls.zig +++ b/lib/compiler_rt/elf/tls.zig @@ -743,14 +743,14 @@ fn __tls_get_addr(ti: *const TlsIndex) callconv(.c) *anyopaque { assert(ti.module == 1); // The executable's module ID is always 1 const tp = getThreadPointer(); - const block: [*]u8 = switch (current_variant) { - .I_original => @ptrFromInt(tp -% area_info.abi_tcb.offset +% area_info.block.offset), - .I_modified => @ptrFromInt(tp -% current_tp_offset), + const block = switch (current_variant) { + .I_original => tp -% area_info.abi_tcb.offset +% area_info.block.offset, + .I_modified => tp -% current_tp_offset, // The `.I_original` approach would also work for `.II`, but there is an // alternative strategy which is one less operation: - .II => @ptrFromInt(tp -% area_info.block.size), + .II => tp -% area_info.abi_tcb.offset, }; - return block[@intCast(ti.offset)..]; + return @ptrFromInt(block +% current_dtv_offset +% @as(usize, @intCast(ti.offset))); } fn ___tls_get_addr() callconv(.naked) *anyopaque { @@ -772,10 +772,10 @@ fn __tls_get_offset() callconv(.naked) noreturn { asm volatile ( \\ la %%r1, 0(%%r12, %%r2) \\ lg %%r2, 8(%%r1) - \\ lgrl %%r0, %[block_size] + \\ lgrl %%r0, %[abi_tcb_offset] \\ sgr %%r2, %%r0 \\ br %%r14 : - : [block_size] "s" (&area_info.block.size), + : [abi_tcb_offset] "s" (&area_info.abi_tcb.offset), ); } -- 2.54.0