From 6a687bda76a34775bde35ee386e59f53961341f7 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 6 Oct 2019 16:45:51 +0200 Subject: [PATCH] Support for TLS on Win32 --- lib/std/os/test.zig | 1 - lib/std/special/start_windows_tls.zig | 12 ++++++++++++ test/stage1/behavior/misc.zig | 3 --- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index 7a6d359236..d886597a38 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -116,7 +116,6 @@ test "AtomicFile" { test "thread local storage" { if (builtin.single_threaded) return error.SkipZigTest; - if (builtin.os == .windows) return error.SkipZigTest; const thread1 = try Thread.spawn({}, testTls); const thread2 = try Thread.spawn({}, testTls); testTls({}); diff --git a/lib/std/special/start_windows_tls.zig b/lib/std/special/start_windows_tls.zig index 71165d355b..bfd0e44122 100644 --- a/lib/std/special/start_windows_tls.zig +++ b/lib/std/special/start_windows_tls.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES; export var _tls_start: u8 linksection(".tls") = 0; @@ -6,6 +7,17 @@ export var _tls_end: u8 linksection(".tls$ZZZ") = 0; export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null; export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null; +comptime { + if (builtin.arch == .i386) { + // The __tls_array is the offset of the ThreadLocalStoragePointer field + // in the TEB block whose base address held in the %fs segment. + asm ( + \\ .global __tls_array + \\ __tls_array = 0x2C + ); + } +} + // TODO this is how I would like it to be expressed // TODO also note, ReactOS has a +1 on StartAddressOfRawData and AddressOfCallBacks. Investigate // why they do that. diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index 5ac12003c5..ab16b08be8 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -687,9 +687,6 @@ fn getNull() ?*i32 { } test "thread local variable" { - if (builtin.os == .windows and builtin.arch == .i386) - return error.SkipZigTest; - const S = struct { threadlocal var t: i32 = 1234; };