authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-07 01:12:11-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-07 01:12:11-07:00
log8184912a9895523d23d03aa9bdcf607a56122a20
treef6f1d8382aa05ccb48826a30ba5ed518b7d8b16d
parentc0681d6b6e74bd70228bb79c6bf719da5a5fe444
parentcb1fffb29eae6eafd46c87d3950911f496288ab2
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20925 from alexrp/windows-tls

`std`: Some Windows TLS cleanup and fixes

3 files changed, 53 insertions(+), 51 deletions(-)

lib/std/os/windows/tls.zig created+50
...@@ -0,0 +1,50 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const windows = std.os.windows;
4
5export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES;
6export var _tls_start: ?*anyopaque linksection(".tls") = null;
7export var _tls_end: ?*anyopaque linksection(".tls$ZZZ") = null;
8export var __xl_a: windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null;
9export var __xl_z: windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null;
10
11comptime {
12 if (builtin.cpu.arch == .x86 and builtin.abi == .msvc and builtin.zig_backend != .stage2_c) {
13 // The __tls_array is the offset of the ThreadLocalStoragePointer field
14 // in the TEB block whose base address held in the %fs segment.
15 asm (
16 \\ .global __tls_array
17 \\ __tls_array = 0x2C
18 );
19 }
20}
21
22// TODO this is how I would like it to be expressed
23//export const _tls_used linksection(".rdata$T") = std.os.windows.IMAGE_TLS_DIRECTORY {
24// .StartAddressOfRawData = @intFromPtr(&_tls_start),
25// .EndAddressOfRawData = @intFromPtr(&_tls_end),
26// .AddressOfIndex = @intFromPtr(&_tls_index),
27// .AddressOfCallBacks = @intFromPtr(__xl_a),
28// .SizeOfZeroFill = 0,
29// .Characteristics = 0,
30//};
31// This is the workaround because we can't do @intFromPtr at comptime like that.
32pub const IMAGE_TLS_DIRECTORY = extern struct {
33 StartAddressOfRawData: *?*anyopaque,
34 EndAddressOfRawData: *?*anyopaque,
35 AddressOfIndex: *u32,
36 AddressOfCallBacks: [*:null]windows.PIMAGE_TLS_CALLBACK,
37 SizeOfZeroFill: u32,
38 Characteristics: u32,
39};
40export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY{
41 .StartAddressOfRawData = &_tls_start,
42 .EndAddressOfRawData = &_tls_end,
43 .AddressOfIndex = &_tls_index,
44 // __xl_a is just a global variable containing a null pointer; the actual callbacks sit in
45 // between __xl_a and __xl_z. So we need to skip over __xl_a here. If there are no callbacks,
46 // this just means we point to __xl_z (the null terminator).
47 .AddressOfCallBacks = @as([*:null]windows.PIMAGE_TLS_CALLBACK, @ptrCast(&__xl_a)) + 1,
48 .SizeOfZeroFill = 0,
49 .Characteristics = 0,
50};
lib/std/start.zig+3-3
...@@ -176,7 +176,7 @@ fn _DllMainCRTStartup(...@@ -176,7 +176,7 @@ fn _DllMainCRTStartup(
176 lpReserved: std.os.windows.LPVOID,176 lpReserved: std.os.windows.LPVOID,
177) callconv(std.os.windows.WINAPI) std.os.windows.BOOL {177) callconv(std.os.windows.WINAPI) std.os.windows.BOOL {
178 if (!builtin.single_threaded and !builtin.link_libc) {178 if (!builtin.single_threaded and !builtin.link_libc) {
179 _ = @import("start_windows_tls.zig");179 _ = @import("os/windows/tls.zig");
180 }180 }
181181
182 if (@hasDecl(root, "DllMain")) {182 if (@hasDecl(root, "DllMain")) {
...@@ -434,7 +434,7 @@ fn _start() callconv(.Naked) noreturn {...@@ -434,7 +434,7 @@ fn _start() callconv(.Naked) noreturn {
434fn WinStartup() callconv(std.os.windows.WINAPI) noreturn {434fn WinStartup() callconv(std.os.windows.WINAPI) noreturn {
435 @setAlignStack(16);435 @setAlignStack(16);
436 if (!builtin.single_threaded and !builtin.link_libc) {436 if (!builtin.single_threaded and !builtin.link_libc) {
437 _ = @import("start_windows_tls.zig");437 _ = @import("os/windows/tls.zig");
438 }438 }
439439
440 std.debug.maybeEnableSegfaultHandler();440 std.debug.maybeEnableSegfaultHandler();
...@@ -445,7 +445,7 @@ fn WinStartup() callconv(std.os.windows.WINAPI) noreturn {...@@ -445,7 +445,7 @@ fn WinStartup() callconv(std.os.windows.WINAPI) noreturn {
445fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn {445fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn {
446 @setAlignStack(16);446 @setAlignStack(16);
447 if (!builtin.single_threaded and !builtin.link_libc) {447 if (!builtin.single_threaded and !builtin.link_libc) {
448 _ = @import("start_windows_tls.zig");448 _ = @import("os/windows/tls.zig");
449 }449 }
450450
451 std.debug.maybeEnableSegfaultHandler();451 std.debug.maybeEnableSegfaultHandler();
lib/std/start_windows_tls.zig deleted-48
...@@ -1,48 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3
4export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES;
5export var _tls_start: u8 linksection(".tls") = 0;
6export var _tls_end: u8 linksection(".tls$ZZZ") = 0;
7export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null;
8export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null;
9
10comptime {
11 if (builtin.target.cpu.arch == .x86 and builtin.zig_backend != .stage2_c) {
12 // The __tls_array is the offset of the ThreadLocalStoragePointer field
13 // in the TEB block whose base address held in the %fs segment.
14 asm (
15 \\ .global __tls_array
16 \\ __tls_array = 0x2C
17 );
18 }
19}
20
21// TODO this is how I would like it to be expressed
22// TODO also note, ReactOS has a +1 on StartAddressOfRawData and AddressOfCallBacks. Investigate
23// why they do that.
24//export const _tls_used linksection(".rdata$T") = std.os.windows.IMAGE_TLS_DIRECTORY {
25// .StartAddressOfRawData = @intFromPtr(&_tls_start),
26// .EndAddressOfRawData = @intFromPtr(&_tls_end),
27// .AddressOfIndex = @intFromPtr(&_tls_index),
28// .AddressOfCallBacks = @intFromPtr(__xl_a),
29// .SizeOfZeroFill = 0,
30// .Characteristics = 0,
31//};
32// This is the workaround because we can't do @intFromPtr at comptime like that.
33pub const IMAGE_TLS_DIRECTORY = extern struct {
34 StartAddressOfRawData: *anyopaque,
35 EndAddressOfRawData: *anyopaque,
36 AddressOfIndex: *anyopaque,
37 AddressOfCallBacks: *anyopaque,
38 SizeOfZeroFill: u32,
39 Characteristics: u32,
40};
41export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY{
42 .StartAddressOfRawData = &_tls_start,
43 .EndAddressOfRawData = &_tls_end,
44 .AddressOfIndex = &_tls_index,
45 .AddressOfCallBacks = @as(*anyopaque, @ptrCast(&__xl_a)),
46 .SizeOfZeroFill = 0,
47 .Characteristics = 0,
48};