| author | |
| committer | |
| log | 4b7e04f75aef8da6d2f95977cee69cd9b3b440a5 |
| tree | 4124c318dc04edcfb0fa24265c467ad4e5d64166 |
| parent | ae72a982242fbd46f389f933c18b036e919093bc |
| signature |
9 files changed, 207 insertions(+), 207 deletions(-)
CMakeLists.txt+3-3| ... | @@ -651,9 +651,9 @@ set(ZIG_STD_FILES | ... | @@ -651,9 +651,9 @@ set(ZIG_STD_FILES |
| 651 | "rb.zig" | 651 | "rb.zig" |
| 652 | "segmented_list.zig" | 652 | "segmented_list.zig" |
| 653 | "sort.zig" | 653 | "sort.zig" |
| 654 | "special/bootstrap.zig" | 654 | "special/start.zig" |
| 655 | "special/bootstrap_lib.zig" | 655 | "special/start_lib.zig" |
| 656 | "special/bootstrap_windows_tls.zig" | 656 | "special/start_windows_tls.zig" |
| 657 | "special/build_runner.zig" | 657 | "special/build_runner.zig" |
| 658 | "special/c.zig" | 658 | "special/c.zig" |
| 659 | "special/compiler_rt.zig" | 659 | "special/compiler_rt.zig" |
src/all_types.hpp+1-1| ... | @@ -1759,7 +1759,7 @@ struct CodeGen { | ... | @@ -1759,7 +1759,7 @@ struct CodeGen { |
| 1759 | ZigPackage *compile_var_package; | 1759 | ZigPackage *compile_var_package; |
| 1760 | ZigType *compile_var_import; | 1760 | ZigType *compile_var_import; |
| 1761 | ZigType *root_import; | 1761 | ZigType *root_import; |
| 1762 | ZigType *bootstrap_import; | 1762 | ZigType *start_import; |
| 1763 | ZigType *test_runner_import; | 1763 | ZigType *test_runner_import; |
| 1764 | 1764 | ||
| 1765 | struct { | 1765 | struct { |
src/codegen.cpp+5-5| ... | @@ -8524,8 +8524,8 @@ static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *ba | ... | @@ -8524,8 +8524,8 @@ static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *ba |
| 8524 | return add_source_file(g, package, resolved_path, import_code, SourceKindPkgMain); | 8524 | return add_source_file(g, package, resolved_path, import_code, SourceKindPkgMain); |
| 8525 | } | 8525 | } |
| 8526 | 8526 | ||
| 8527 | static ZigPackage *create_bootstrap_pkg(CodeGen *g, ZigPackage *pkg_with_main) { | 8527 | static ZigPackage *create_start_pkg(CodeGen *g, ZigPackage *pkg_with_main) { |
| 8528 | ZigPackage *package = codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "bootstrap.zig", "std.special"); | 8528 | ZigPackage *package = codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "start.zig", "std.special"); |
| 8529 | package->package_table.put(buf_create_from_str("root"), pkg_with_main); | 8529 | package->package_table.put(buf_create_from_str("root"), pkg_with_main); |
| 8530 | return package; | 8530 | return package; |
| 8531 | } | 8531 | } |
| ... | @@ -8651,12 +8651,12 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -8651,12 +8651,12 @@ static void gen_root_source(CodeGen *g) { |
| 8651 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && | 8651 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && |
| 8652 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) | 8652 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
| 8653 | { | 8653 | { |
| 8654 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig"); | 8654 | g->start_import = add_special_code(g, create_start_pkg(g, g->root_package), "start.zig"); |
| 8655 | } | 8655 | } |
| 8656 | if (g->zig_target->os == OsWindows && !g->have_dllmain_crt_startup && | 8656 | if (g->zig_target->os == OsWindows && !g->have_dllmain_crt_startup && |
| 8657 | g->out_type == OutTypeLib && g->is_dynamic) | 8657 | g->out_type == OutTypeLib && g->is_dynamic) |
| 8658 | { | 8658 | { |
| 8659 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); | 8659 | g->start_import = add_special_code(g, create_start_pkg(g, g->root_package), "start_lib.zig"); |
| 8660 | } | 8660 | } |
| 8661 | 8661 | ||
| 8662 | if (!g->error_during_imports) { | 8662 | if (!g->error_during_imports) { |
| ... | @@ -8664,7 +8664,7 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -8664,7 +8664,7 @@ static void gen_root_source(CodeGen *g) { |
| 8664 | } | 8664 | } |
| 8665 | if (g->is_test_build) { | 8665 | if (g->is_test_build) { |
| 8666 | create_test_compile_var_and_add_test_runner(g); | 8666 | create_test_compile_var_and_add_test_runner(g); |
| 8667 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->test_runner_package), "bootstrap.zig"); | 8667 | g->start_import = add_special_code(g, create_start_pkg(g, g->test_runner_package), "start.zig"); |
| 8668 | 8668 | ||
| 8669 | if (!g->error_during_imports) { | 8669 | if (!g->error_during_imports) { |
| 8670 | semantic_analyze(g); | 8670 | semantic_analyze(g); |
std/special/bootstrap.zig deleted-146| ... | @@ -1,146 +0,0 @@ | ||
| 1 | // This file is included in the compilation unit when exporting an executable. | ||
| 2 | |||
| 3 | const root = @import("root"); | ||
| 4 | const std = @import("std"); | ||
| 5 | const builtin = @import("builtin"); | ||
| 6 | const assert = std.debug.assert; | ||
| 7 | |||
| 8 | var argc_ptr: [*]usize = undefined; | ||
| 9 | |||
| 10 | const is_wasm = switch (builtin.arch) { | ||
| 11 | .wasm32, .wasm64 => true, | ||
| 12 | else => false, | ||
| 13 | }; | ||
| 14 | |||
| 15 | comptime { | ||
| 16 | if (builtin.link_libc) { | ||
| 17 | @export("main", main, .Strong); | ||
| 18 | } else if (builtin.os == .windows) { | ||
| 19 | @export("WinMainCRTStartup", WinMainCRTStartup, .Strong); | ||
| 20 | } else if (is_wasm and builtin.os == .freestanding) { | ||
| 21 | @export("_start", wasm_freestanding_start, .Strong); | ||
| 22 | } else { | ||
| 23 | @export("_start", _start, .Strong); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | extern fn wasm_freestanding_start() void { | ||
| 28 | _ = callMain(); | ||
| 29 | } | ||
| 30 | |||
| 31 | nakedcc fn _start() noreturn { | ||
| 32 | if (builtin.os == builtin.Os.wasi) { | ||
| 33 | std.os.wasi.proc_exit(callMain()); | ||
| 34 | } | ||
| 35 | |||
| 36 | switch (builtin.arch) { | ||
| 37 | .x86_64 => { | ||
| 38 | argc_ptr = asm ("lea (%%rsp), %[argc]" | ||
| 39 | : [argc] "=r" (-> [*]usize) | ||
| 40 | ); | ||
| 41 | }, | ||
| 42 | .i386 => { | ||
| 43 | argc_ptr = asm ("lea (%%esp), %[argc]" | ||
| 44 | : [argc] "=r" (-> [*]usize) | ||
| 45 | ); | ||
| 46 | }, | ||
| 47 | .aarch64, .aarch64_be => { | ||
| 48 | argc_ptr = asm ("mov %[argc], sp" | ||
| 49 | : [argc] "=r" (-> [*]usize) | ||
| 50 | ); | ||
| 51 | }, | ||
| 52 | else => @compileError("unsupported arch"), | ||
| 53 | } | ||
| 54 | // If LLVM inlines stack variables into _start, they will overwrite | ||
| 55 | // the command line argument data. | ||
| 56 | @noInlineCall(posixCallMainAndExit); | ||
| 57 | } | ||
| 58 | |||
| 59 | extern fn WinMainCRTStartup() noreturn { | ||
| 60 | @setAlignStack(16); | ||
| 61 | if (!builtin.single_threaded) { | ||
| 62 | _ = @import("bootstrap_windows_tls.zig"); | ||
| 63 | } | ||
| 64 | std.os.windows.kernel32.ExitProcess(callMain()); | ||
| 65 | } | ||
| 66 | |||
| 67 | // TODO https://github.com/ziglang/zig/issues/265 | ||
| 68 | fn posixCallMainAndExit() noreturn { | ||
| 69 | if (builtin.os == builtin.Os.freebsd) { | ||
| 70 | @setAlignStack(16); | ||
| 71 | } | ||
| 72 | const argc = argc_ptr[0]; | ||
| 73 | const argv = @ptrCast([*][*]u8, argc_ptr + 1); | ||
| 74 | |||
| 75 | const envp_optional = @ptrCast([*]?[*]u8, argv + argc + 1); | ||
| 76 | var envp_count: usize = 0; | ||
| 77 | while (envp_optional[envp_count]) |_| : (envp_count += 1) {} | ||
| 78 | const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count]; | ||
| 79 | |||
| 80 | if (builtin.os == .linux) { | ||
| 81 | // Find the beginning of the auxiliary vector | ||
| 82 | const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1); | ||
| 83 | std.os.linux.elf_aux_maybe = auxv; | ||
| 84 | // Initialize the TLS area | ||
| 85 | std.os.linux.tls.initTLS(); | ||
| 86 | |||
| 87 | if (std.os.linux.tls.tls_image) |tls_img| { | ||
| 88 | const tls_addr = std.os.linux.tls.allocateTLS(tls_img.alloc_size); | ||
| 89 | const tp = std.os.linux.tls.copyTLS(tls_addr); | ||
| 90 | std.os.linux.tls.setThreadPointer(tp); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | std.os.exit(callMainWithArgs(argc, argv, envp)); | ||
| 95 | } | ||
| 96 | |||
| 97 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | ||
| 98 | // and we want fewer call frames in stack traces. | ||
| 99 | inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 { | ||
| 100 | std.os.argv = argv[0..argc]; | ||
| 101 | std.os.environ = envp; | ||
| 102 | return callMain(); | ||
| 103 | } | ||
| 104 | |||
| 105 | extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 { | ||
| 106 | var env_count: usize = 0; | ||
| 107 | while (c_envp[env_count] != null) : (env_count += 1) {} | ||
| 108 | const envp = @ptrCast([*][*]u8, c_envp)[0..env_count]; | ||
| 109 | return callMainWithArgs(@intCast(usize, c_argc), c_argv, envp); | ||
| 110 | } | ||
| 111 | |||
| 112 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | ||
| 113 | // and we want fewer call frames in stack traces. | ||
| 114 | inline fn callMain() u8 { | ||
| 115 | switch (@typeId(@typeOf(root.main).ReturnType)) { | ||
| 116 | .NoReturn => { | ||
| 117 | root.main(); | ||
| 118 | }, | ||
| 119 | .Void => { | ||
| 120 | root.main(); | ||
| 121 | return 0; | ||
| 122 | }, | ||
| 123 | .Int => { | ||
| 124 | if (@typeOf(root.main).ReturnType.bit_count != 8) { | ||
| 125 | @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"); | ||
| 126 | } | ||
| 127 | return root.main(); | ||
| 128 | }, | ||
| 129 | .ErrorUnion => { | ||
| 130 | root.main() catch |err| { | ||
| 131 | std.debug.warn("error: {}\n", @errorName(err)); | ||
| 132 | if (builtin.os != builtin.Os.zen) { | ||
| 133 | if (@errorReturnTrace()) |trace| { | ||
| 134 | std.debug.dumpStackTrace(trace.*); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | return 1; | ||
| 138 | }; | ||
| 139 | return 0; | ||
| 140 | }, | ||
| 141 | else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"), | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | const main_thread_tls_align = 32; | ||
| 146 | var main_thread_tls_bytes: [64]u8 align(main_thread_tls_align) = [1]u8{0} ** 64; | ||
std/special/bootstrap_lib.zig deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | // This file is included in the compilation unit when exporting a DLL on windows. | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | const builtin = @import("builtin"); | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | @export("_DllMainCRTStartup", _DllMainCRTStartup, builtin.GlobalLinkage.Strong); | ||
| 8 | } | ||
| 9 | |||
| 10 | stdcallcc fn _DllMainCRTStartup( | ||
| 11 | hinstDLL: std.os.windows.HINSTANCE, | ||
| 12 | fdwReason: std.os.windows.DWORD, | ||
| 13 | lpReserved: std.os.windows.LPVOID, | ||
| 14 | ) std.os.windows.BOOL { | ||
| 15 | return std.os.windows.TRUE; | ||
| 16 | } | ||
std/special/bootstrap_windows_tls.zig deleted-36| ... | @@ -1,36 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 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/start.zig created+146| ... | @@ -0,0 +1,146 @@ | ||
| 1 | // This file is included in the compilation unit when exporting an executable. | ||
| 2 | |||
| 3 | const root = @import("root"); | ||
| 4 | const std = @import("std"); | ||
| 5 | const builtin = @import("builtin"); | ||
| 6 | const assert = std.debug.assert; | ||
| 7 | |||
| 8 | var argc_ptr: [*]usize = undefined; | ||
| 9 | |||
| 10 | const is_wasm = switch (builtin.arch) { | ||
| 11 | .wasm32, .wasm64 => true, | ||
| 12 | else => false, | ||
| 13 | }; | ||
| 14 | |||
| 15 | comptime { | ||
| 16 | if (builtin.link_libc) { | ||
| 17 | @export("main", main, .Strong); | ||
| 18 | } else if (builtin.os == .windows) { | ||
| 19 | @export("WinMainCRTStartup", WinMainCRTStartup, .Strong); | ||
| 20 | } else if (is_wasm and builtin.os == .freestanding) { | ||
| 21 | @export("_start", wasm_freestanding_start, .Strong); | ||
| 22 | } else { | ||
| 23 | @export("_start", _start, .Strong); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | extern fn wasm_freestanding_start() void { | ||
| 28 | _ = callMain(); | ||
| 29 | } | ||
| 30 | |||
| 31 | nakedcc fn _start() noreturn { | ||
| 32 | if (builtin.os == builtin.Os.wasi) { | ||
| 33 | std.os.wasi.proc_exit(callMain()); | ||
| 34 | } | ||
| 35 | |||
| 36 | switch (builtin.arch) { | ||
| 37 | .x86_64 => { | ||
| 38 | argc_ptr = asm ("lea (%%rsp), %[argc]" | ||
| 39 | : [argc] "=r" (-> [*]usize) | ||
| 40 | ); | ||
| 41 | }, | ||
| 42 | .i386 => { | ||
| 43 | argc_ptr = asm ("lea (%%esp), %[argc]" | ||
| 44 | : [argc] "=r" (-> [*]usize) | ||
| 45 | ); | ||
| 46 | }, | ||
| 47 | .aarch64, .aarch64_be => { | ||
| 48 | argc_ptr = asm ("mov %[argc], sp" | ||
| 49 | : [argc] "=r" (-> [*]usize) | ||
| 50 | ); | ||
| 51 | }, | ||
| 52 | else => @compileError("unsupported arch"), | ||
| 53 | } | ||
| 54 | // If LLVM inlines stack variables into _start, they will overwrite | ||
| 55 | // the command line argument data. | ||
| 56 | @noInlineCall(posixCallMainAndExit); | ||
| 57 | } | ||
| 58 | |||
| 59 | extern fn WinMainCRTStartup() noreturn { | ||
| 60 | @setAlignStack(16); | ||
| 61 | if (!builtin.single_threaded) { | ||
| 62 | _ = @import("start_windows_tls.zig"); | ||
| 63 | } | ||
| 64 | std.os.windows.kernel32.ExitProcess(callMain()); | ||
| 65 | } | ||
| 66 | |||
| 67 | // TODO https://github.com/ziglang/zig/issues/265 | ||
| 68 | fn posixCallMainAndExit() noreturn { | ||
| 69 | if (builtin.os == builtin.Os.freebsd) { | ||
| 70 | @setAlignStack(16); | ||
| 71 | } | ||
| 72 | const argc = argc_ptr[0]; | ||
| 73 | const argv = @ptrCast([*][*]u8, argc_ptr + 1); | ||
| 74 | |||
| 75 | const envp_optional = @ptrCast([*]?[*]u8, argv + argc + 1); | ||
| 76 | var envp_count: usize = 0; | ||
| 77 | while (envp_optional[envp_count]) |_| : (envp_count += 1) {} | ||
| 78 | const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count]; | ||
| 79 | |||
| 80 | if (builtin.os == .linux) { | ||
| 81 | // Find the beginning of the auxiliary vector | ||
| 82 | const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1); | ||
| 83 | std.os.linux.elf_aux_maybe = auxv; | ||
| 84 | // Initialize the TLS area | ||
| 85 | std.os.linux.tls.initTLS(); | ||
| 86 | |||
| 87 | if (std.os.linux.tls.tls_image) |tls_img| { | ||
| 88 | const tls_addr = std.os.linux.tls.allocateTLS(tls_img.alloc_size); | ||
| 89 | const tp = std.os.linux.tls.copyTLS(tls_addr); | ||
| 90 | std.os.linux.tls.setThreadPointer(tp); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | std.os.exit(callMainWithArgs(argc, argv, envp)); | ||
| 95 | } | ||
| 96 | |||
| 97 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | ||
| 98 | // and we want fewer call frames in stack traces. | ||
| 99 | inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 { | ||
| 100 | std.os.argv = argv[0..argc]; | ||
| 101 | std.os.environ = envp; | ||
| 102 | return callMain(); | ||
| 103 | } | ||
| 104 | |||
| 105 | extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 { | ||
| 106 | var env_count: usize = 0; | ||
| 107 | while (c_envp[env_count] != null) : (env_count += 1) {} | ||
| 108 | const envp = @ptrCast([*][*]u8, c_envp)[0..env_count]; | ||
| 109 | return callMainWithArgs(@intCast(usize, c_argc), c_argv, envp); | ||
| 110 | } | ||
| 111 | |||
| 112 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | ||
| 113 | // and we want fewer call frames in stack traces. | ||
| 114 | inline fn callMain() u8 { | ||
| 115 | switch (@typeId(@typeOf(root.main).ReturnType)) { | ||
| 116 | .NoReturn => { | ||
| 117 | root.main(); | ||
| 118 | }, | ||
| 119 | .Void => { | ||
| 120 | root.main(); | ||
| 121 | return 0; | ||
| 122 | }, | ||
| 123 | .Int => { | ||
| 124 | if (@typeOf(root.main).ReturnType.bit_count != 8) { | ||
| 125 | @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"); | ||
| 126 | } | ||
| 127 | return root.main(); | ||
| 128 | }, | ||
| 129 | .ErrorUnion => { | ||
| 130 | root.main() catch |err| { | ||
| 131 | std.debug.warn("error: {}\n", @errorName(err)); | ||
| 132 | if (builtin.os != builtin.Os.zen) { | ||
| 133 | if (@errorReturnTrace()) |trace| { | ||
| 134 | std.debug.dumpStackTrace(trace.*); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | return 1; | ||
| 138 | }; | ||
| 139 | return 0; | ||
| 140 | }, | ||
| 141 | else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"), | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | const main_thread_tls_align = 32; | ||
| 146 | var main_thread_tls_bytes: [64]u8 align(main_thread_tls_align) = [1]u8{0} ** 64; | ||
std/special/start_lib.zig created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | // This file is included in the compilation unit when exporting a DLL on windows. | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | const builtin = @import("builtin"); | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | @export("_DllMainCRTStartup", _DllMainCRTStartup, builtin.GlobalLinkage.Strong); | ||
| 8 | } | ||
| 9 | |||
| 10 | stdcallcc fn _DllMainCRTStartup( | ||
| 11 | hinstDLL: std.os.windows.HINSTANCE, | ||
| 12 | fdwReason: std.os.windows.DWORD, | ||
| 13 | lpReserved: std.os.windows.LPVOID, | ||
| 14 | ) std.os.windows.BOOL { | ||
| 15 | return std.os.windows.TRUE; | ||
| 16 | } | ||
std/special/start_windows_tls.zig created+36| ... | @@ -0,0 +1,36 @@ | ||
| 1 | const std = @import("std"); | ||
| 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 | }; | ||