authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-11 09:23:01+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-11 10:45:45+02:00
log6c3be9e0e7a90e63cb91d890f1a63e682f413d0d
tree74ee3c81ada8dc9d8ead0a71c2e6c1c7fc765ba6
parent19e06b06ddc1a434c3b0f31cd4f47e17b4295918
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

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.

1 files changed, 7 insertions(+), 7 deletions(-)

lib/compiler_rt/elf/tls.zig+7-7
......@@ -743,14 +743,14 @@ fn __tls_get_addr(ti: *const TlsIndex) callconv(.c) *anyopaque {
743743
744744 assert(ti.module == 1); // The executable's module ID is always 1
745745 const tp = getThreadPointer();
746 const block: [*]u8 = switch (current_variant) {
747 .I_original => @ptrFromInt(tp -% area_info.abi_tcb.offset +% area_info.block.offset),
748 .I_modified => @ptrFromInt(tp -% current_tp_offset),
746 const block = switch (current_variant) {
747 .I_original => tp -% area_info.abi_tcb.offset +% area_info.block.offset,
748 .I_modified => tp -% current_tp_offset,
749749 // The `.I_original` approach would also work for `.II`, but there is an
750750 // alternative strategy which is one less operation:
751 .II => @ptrFromInt(tp -% area_info.block.size),
751 .II => tp -% area_info.abi_tcb.offset,
752752 };
753 return block[@intCast(ti.offset)..];
753 return @ptrFromInt(block +% current_dtv_offset +% @as(usize, @intCast(ti.offset)));
754754}
755755
756756fn ___tls_get_addr() callconv(.naked) *anyopaque {
......@@ -772,10 +772,10 @@ fn __tls_get_offset() callconv(.naked) noreturn {
772772 asm volatile (
773773 \\ la %%r1, 0(%%r12, %%r2)
774774 \\ lg %%r2, 8(%%r1)
775 \\ lgrl %%r0, %[block_size]
775 \\ lgrl %%r0, %[abi_tcb_offset]
776776 \\ sgr %%r2, %%r0
777777 \\ br %%r14
778778 :
779 : [block_size] "s" (&area_info.block.size),
779 : [abi_tcb_offset] "s" (&area_info.abi_tcb.offset),
780780 );
781781}