From dae7c7c466500733ef74c72874e7755cc3f218b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 11 Oct 2026 09:18:36 +0200 Subject: [PATCH] compiler_rt.elf.tls: add ___tls_get_addr() which is used by 32-bit x86 As per usual, we have GNU to thank. --- lib/compiler_rt/elf/tls.zig | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/compiler_rt/elf/tls.zig b/lib/compiler_rt/elf/tls.zig index dccd2018ce02a2b32050b239a30f9d30dc9d06bd..1d53b6de023feb126a9a459a642ed7798ff414c8 100644 --- a/lib/compiler_rt/elf/tls.zig +++ b/lib/compiler_rt/elf/tls.zig @@ -29,10 +29,14 @@ comptime { // function for the GD and LD models. This function is unlikely to actually be used, since the // linker should be able to relax every TLS access to the LE model and therefore eliminate all // calls to this function, but that isn't guaranteed. - if (native_arch == .s390x) - symbol(&__tls_get_offset, "__tls_get_offset") - else + if (native_arch == .s390x) { + symbol(&__tls_get_offset, "__tls_get_offset"); + } else { symbol(&__tls_get_addr, "__tls_get_addr"); + if (native_arch == .x86) { + symbol(&___tls_get_addr, "___tls_get_addr"); + } + } } /// Represents an ELF TLS variant. @@ -740,6 +744,18 @@ fn __tls_get_addr(ti: *const TlsIndex) callconv(.c) *anyopaque { return block[@intCast(ti.offset)..]; } +fn ___tls_get_addr() callconv(.naked) *anyopaque { + comptime assert(native_arch == .x86); + + // We receive the `TlsIndex` pointer in eax. + comptime assert(@sizeOf(AbiTcb) + @sizeOf(ZigTcb) + @offsetOf(Dtv, "tls_block") == 12); + asm volatile ( + \\ mov 4(%%eax), %%eax + \\ add %%gs:12, %%eax + \\ ret + ); +} + fn __tls_get_offset() callconv(.naked) noreturn { comptime assert(native_arch == .s390x); -- 2.54.0