| author | |
| committer | |
| log | 89ffb5819703c81514e4f29d2cadb5b74ea1f840 |
| tree | 455eda3ef65b2a2f08f292586b219468aa755f06 |
| parent | d2602b442e7cdea2e74584f9529917d7a53625fd |
6 files changed, 70 insertions(+), 8 deletions(-)
CMakeLists.txt+1| ... | ... | @@ -596,6 +596,7 @@ set(ZIG_STD_FILES |
| 596 | 596 | "os/windows/ntdll.zig" |
| 597 | 597 | "os/windows/ole32.zig" |
| 598 | 598 | "os/windows/shell32.zig" |
| 599 | "os/windows/tls.zig" | |
| 599 | 600 | "os/windows/util.zig" |
| 600 | 601 | "os/zen.zig" |
| 601 | 602 | "pdb.zig" |
src/codegen.cpp+8-6| ... | ... | @@ -6365,6 +6365,12 @@ static void validate_inline_fns(CodeGen *g) { |
| 6365 | 6365 | report_errors_and_maybe_exit(g); |
| 6366 | 6366 | } |
| 6367 | 6367 | |
| 6368 | static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { | |
| 6369 | if (var->is_thread_local && !g->is_single_threaded) { | |
| 6370 | LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel); | |
| 6371 | } | |
| 6372 | } | |
| 6373 | ||
| 6368 | 6374 | static void do_code_gen(CodeGen *g) { |
| 6369 | 6375 | assert(!g->errors.length); |
| 6370 | 6376 | |
| ... | ... | @@ -6449,9 +6455,7 @@ static void do_code_gen(CodeGen *g) { |
| 6449 | 6455 | maybe_import_dll(g, global_value, GlobalLinkageIdStrong); |
| 6450 | 6456 | LLVMSetAlignment(global_value, var->align_bytes); |
| 6451 | 6457 | LLVMSetGlobalConstant(global_value, var->gen_is_const); |
| 6452 | if (var->is_thread_local && !g->is_single_threaded) { | |
| 6453 | LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel); | |
| 6454 | } | |
| 6458 | set_global_tls(g, var, global_value); | |
| 6455 | 6459 | } |
| 6456 | 6460 | } else { |
| 6457 | 6461 | bool exported = (var->linkage == VarLinkageExport); |
| ... | ... | @@ -6477,9 +6481,7 @@ static void do_code_gen(CodeGen *g) { |
| 6477 | 6481 | } |
| 6478 | 6482 | |
| 6479 | 6483 | LLVMSetGlobalConstant(global_value, var->gen_is_const); |
| 6480 | if (var->is_thread_local && !g->is_single_threaded) { | |
| 6481 | LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel); | |
| 6482 | } | |
| 6484 | set_global_tls(g, var, global_value); | |
| 6483 | 6485 | } |
| 6484 | 6486 | |
| 6485 | 6487 | var->value_ref = global_value; |
std/os/windows/index.zig+18-1| ... | ... | @@ -49,7 +49,10 @@ pub const UNICODE = false; |
| 49 | 49 | pub const WCHAR = u16; |
| 50 | 50 | pub const WORD = u16; |
| 51 | 51 | pub const LARGE_INTEGER = i64; |
| 52 | pub const LONG = c_long; | |
| 52 | pub const ULONG = u32; | |
| 53 | pub const LONG = i32; | |
| 54 | pub const ULONGLONG = u64; | |
| 55 | pub const LONGLONG = i64; | |
| 53 | 56 | |
| 54 | 57 | pub const TRUE = 1; |
| 55 | 58 | pub const FALSE = 0; |
| ... | ... | @@ -380,3 +383,17 @@ pub const COORD = extern struct { |
| 380 | 383 | }; |
| 381 | 384 | |
| 382 | 385 | pub const CREATE_UNICODE_ENVIRONMENT = 1024; |
| 386 | ||
| 387 | pub const TLS_OUT_OF_INDEXES = 4294967295; | |
| 388 | pub const IMAGE_TLS_DIRECTORY = extern struct { | |
| 389 | StartAddressOfRawData: usize, | |
| 390 | EndAddressOfRawData: usize, | |
| 391 | AddressOfIndex: usize, | |
| 392 | AddressOfCallBacks: usize, | |
| 393 | SizeOfZeroFill: u32, | |
| 394 | Characteristics: u32, | |
| 395 | }; | |
| 396 | pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY; | |
| 397 | pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY; | |
| 398 | ||
| 399 | pub const PIMAGE_TLS_CALLBACK = ?extern fn(PVOID, DWORD, PVOID) void; |
std/os/windows/kernel32.zig+4| ... | ... | @@ -164,6 +164,10 @@ pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void; |
| 164 | 164 | |
| 165 | 165 | pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL; |
| 166 | 166 | |
| 167 | pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD; | |
| 168 | ||
| 169 | pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL; | |
| 170 | ||
| 167 | 171 | pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD; |
| 168 | 172 | |
| 169 | 173 | pub extern "kernel32" stdcallcc fn WriteFile( |
std/os/windows/tls.zig created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | const std = @import("../../index.zig"); | |
| 2 | ||
| 3 | export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES; | |
| 4 | export var _tls_start: u8 linksection(".tls") = 0; | |
| 5 | export var _tls_end: u8 linksection(".tls$ZZZ") = 0; | |
| 6 | export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null; | |
| 7 | export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null; | |
| 8 | ||
| 9 | // TODO this is how I would like it to be expressed | |
| 10 | // TODO also note, ReactOS has a +1 on StartAddressOfRawData and AddressOfCallBacks. Investigate | |
| 11 | // why they do that. | |
| 12 | //export const _tls_used linksection(".rdata$T") = std.os.windows.IMAGE_TLS_DIRECTORY { | |
| 13 | // .StartAddressOfRawData = @ptrToInt(&_tls_start), | |
| 14 | // .EndAddressOfRawData = @ptrToInt(&_tls_end), | |
| 15 | // .AddressOfIndex = @ptrToInt(&_tls_index), | |
| 16 | // .AddressOfCallBacks = @ptrToInt(__xl_a), | |
| 17 | // .SizeOfZeroFill = 0, | |
| 18 | // .Characteristics = 0, | |
| 19 | //}; | |
| 20 | // This is the workaround because we can't do @ptrToInt at comptime like that. | |
| 21 | pub const IMAGE_TLS_DIRECTORY = extern struct { | |
| 22 | StartAddressOfRawData: *c_void, | |
| 23 | EndAddressOfRawData: *c_void, | |
| 24 | AddressOfIndex: *c_void, | |
| 25 | AddressOfCallBacks: *c_void, | |
| 26 | SizeOfZeroFill: u32, | |
| 27 | Characteristics: u32, | |
| 28 | }; | |
| 29 | export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY { | |
| 30 | .StartAddressOfRawData = &_tls_start, | |
| 31 | .EndAddressOfRawData = &_tls_end, | |
| 32 | .AddressOfIndex = &_tls_index, | |
| 33 | .AddressOfCallBacks = &__xl_a, | |
| 34 | .SizeOfZeroFill = 0, | |
| 35 | .Characteristics = 0, | |
| 36 | }; |
std/special/bootstrap.zig+3-1| ... | ... | @@ -45,7 +45,9 @@ nakedcc fn _start() noreturn { |
| 45 | 45 | |
| 46 | 46 | extern fn WinMainCRTStartup() noreturn { |
| 47 | 47 | @setAlignStack(16); |
| 48 | ||
| 48 | if (!builtin.single_threaded) { | |
| 49 | _ = @import("../os/windows/tls.zig"); | |
| 50 | } | |
| 49 | 51 | std.os.windows.ExitProcess(callMain()); |
| 50 | 52 | } |
| 51 | 53 |