| author | |
| committer | |
| log | b5054625093ef22b3f228199b6fbf70e1c50b703 |
| tree | 09b000d9205b1f378d0d6a78700c3f3b642894d8 |
| parent | f1bd02e6f46821415d96f54f6a3258159ba5a9c5 |
Closes #508
See #3024 files changed, 21 insertions(+), 49 deletions(-)
src/codegen.cpp+5-12| ... | @@ -867,7 +867,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -867,7 +867,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 867 | addLLVMFnAttr(fn_val, "noreturn"); | 867 | addLLVMFnAttr(fn_val, "noreturn"); |
| 868 | addLLVMFnAttr(fn_val, "cold"); | 868 | addLLVMFnAttr(fn_val, "cold"); |
| 869 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); | 869 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| 870 | LLVMSetFunctionCallConv(fn_val, LLVMFastCallConv); | 870 | LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); |
| 871 | addLLVMFnAttr(fn_val, "nounwind"); | 871 | addLLVMFnAttr(fn_val, "nounwind"); |
| 872 | if (g->build_mode == BuildModeDebug) { | 872 | if (g->build_mode == BuildModeDebug) { |
| 873 | ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); | 873 | ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); |
| ... | @@ -924,7 +924,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { | ... | @@ -924,7 +924,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 924 | 924 | ||
| 925 | static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) { | 925 | static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) { |
| 926 | LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g); | 926 | LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g); |
| 927 | ZigLLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, LLVMFastCallConv, false, ""); | 927 | ZigLLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, get_llvm_cc(g, CallingConventionUnspecified), |
| 928 | false, ""); | ||
| 928 | LLVMBuildUnreachable(g->builder); | 929 | LLVMBuildUnreachable(g->builder); |
| 929 | } | 930 | } |
| 930 | 931 | ||
| ... | @@ -5007,16 +5008,8 @@ static void init(CodeGen *g) { | ... | @@ -5007,16 +5008,8 @@ static void init(CodeGen *g) { |
| 5007 | const char *target_specific_cpu_args; | 5008 | const char *target_specific_cpu_args; |
| 5008 | const char *target_specific_features; | 5009 | const char *target_specific_features; |
| 5009 | if (g->is_native_target) { | 5010 | if (g->is_native_target) { |
| 5010 | // LLVM creates invalid binaries on Windows sometimes. | 5011 | target_specific_cpu_args = ZigLLVMGetHostCPUName(); |
| 5011 | // See https://github.com/zig-lang/zig/issues/508 | 5012 | target_specific_features = ZigLLVMGetNativeFeatures(); |
| 5012 | // As a workaround we do not use target native features on Windows. | ||
| 5013 | if (g->zig_target.os == ZigLLVM_Win32) { | ||
| 5014 | target_specific_cpu_args = ""; | ||
| 5015 | target_specific_features = ""; | ||
| 5016 | } else { | ||
| 5017 | target_specific_cpu_args = ZigLLVMGetHostCPUName(); | ||
| 5018 | target_specific_features = ZigLLVMGetNativeFeatures(); | ||
| 5019 | } | ||
| 5020 | } else { | 5013 | } else { |
| 5021 | target_specific_cpu_args = ""; | 5014 | target_specific_cpu_args = ""; |
| 5022 | target_specific_features = ""; | 5015 | target_specific_features = ""; |
src/link.cpp+1-1| ... | @@ -423,7 +423,7 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -423,7 +423,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 423 | if (g->have_winmain) { | 423 | if (g->have_winmain) { |
| 424 | lj->args.append("-ENTRY:WinMain"); | 424 | lj->args.append("-ENTRY:WinMain"); |
| 425 | } else { | 425 | } else { |
| 426 | lj->args.append("-ENTRY:_start"); | 426 | lj->args.append("-ENTRY:WinMainCRTStartup"); |
| 427 | } | 427 | } |
| 428 | } | 428 | } |
| 429 | 429 |
std/special/bootstrap.zig+9-15| ... | @@ -5,12 +5,13 @@ const root = @import("@root"); | ... | @@ -5,12 +5,13 @@ const root = @import("@root"); |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | const is_windows = builtin.os == builtin.Os.windows; | ||
| 8 | const want_main_symbol = builtin.link_libc; | 9 | const want_main_symbol = builtin.link_libc; |
| 9 | const want_start_symbol = !want_main_symbol; | 10 | const want_start_symbol = !want_main_symbol and !is_windows; |
| 11 | const want_WinMainCRTStartup = is_windows and !builtin.link_libc; | ||
| 10 | 12 | ||
| 11 | var argc_ptr: &usize = undefined; | 13 | var argc_ptr: &usize = undefined; |
| 12 | 14 | ||
| 13 | const is_windows = builtin.os == builtin.Os.windows; | ||
| 14 | 15 | ||
| 15 | export nakedcc fn _start() -> noreturn { | 16 | export nakedcc fn _start() -> noreturn { |
| 16 | if (!want_start_symbol) { | 17 | if (!want_start_symbol) { |
| ... | @@ -18,18 +19,6 @@ export nakedcc fn _start() -> noreturn { | ... | @@ -18,18 +19,6 @@ export nakedcc fn _start() -> noreturn { |
| 18 | unreachable; | 19 | unreachable; |
| 19 | } | 20 | } |
| 20 | 21 | ||
| 21 | if (is_windows) { | ||
| 22 | if (builtin.arch == builtin.Arch.x86_64) { | ||
| 23 | // Align the stack pointer to 16 bytes. | ||
| 24 | asm volatile ( | ||
| 25 | \\ and $0xfffffffffffffff0,%%rsp | ||
| 26 | \\ sub $0x10,%%rsp | ||
| 27 | :::"rsp" | ||
| 28 | ); | ||
| 29 | } | ||
| 30 | windowsCallMainAndExit() | ||
| 31 | } | ||
| 32 | |||
| 33 | switch (builtin.arch) { | 22 | switch (builtin.arch) { |
| 34 | builtin.Arch.x86_64 => { | 23 | builtin.Arch.x86_64 => { |
| 35 | argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize)); | 24 | argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize)); |
| ... | @@ -42,8 +31,13 @@ export nakedcc fn _start() -> noreturn { | ... | @@ -42,8 +31,13 @@ export nakedcc fn _start() -> noreturn { |
| 42 | posixCallMainAndExit() | 31 | posixCallMainAndExit() |
| 43 | } | 32 | } |
| 44 | 33 | ||
| 45 | fn windowsCallMainAndExit() -> noreturn { | 34 | export fn WinMainCRTStartup() -> noreturn { |
| 35 | if (!want_WinMainCRTStartup) { | ||
| 36 | @setGlobalLinkage(WinMainCRTStartup, builtin.GlobalLinkage.Internal); | ||
| 37 | unreachable; | ||
| 38 | } | ||
| 46 | @setAlignStack(16); | 39 | @setAlignStack(16); |
| 40 | |||
| 47 | std.debug.user_main_fn = root.main; | 41 | std.debug.user_main_fn = root.main; |
| 48 | root.main() %% std.os.windows.ExitProcess(1); | 42 | root.main() %% std.os.windows.ExitProcess(1); |
| 49 | std.os.windows.ExitProcess(0); | 43 | std.os.windows.ExitProcess(0); |
std/special/compiler_rt/index.zig+6-21| ... | @@ -155,32 +155,17 @@ export nakedcc fn _chkstk() align(4) { | ... | @@ -155,32 +155,17 @@ export nakedcc fn _chkstk() align(4) { |
| 155 | @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal); | 155 | @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | export nakedcc fn __chkstk() align(4) { | 158 | // TODO The implementation from compiler-rt causes crashes and |
| 159 | // the implementation from disassembled ntdll seems to depend on | ||
| 160 | // thread local storage. So we have given up this safety check | ||
| 161 | // and simply have `ret`. | ||
| 162 | export nakedcc fn __chkstk() align(8) { | ||
| 159 | @setDebugSafety(this, false); | 163 | @setDebugSafety(this, false); |
| 160 | 164 | ||
| 161 | if (win64_nocrt) { | 165 | if (win64_nocrt) { |
| 162 | @setGlobalLinkage(__chkstk, strong_linkage); | 166 | @setGlobalLinkage(__chkstk, strong_linkage); |
| 163 | asm volatile ( | 167 | asm volatile ( |
| 164 | \\ push %%rcx | 168 | \\ ret |
| 165 | \\ cmp $0x1000,%%rax | ||
| 166 | \\ lea 16(%%rsp),%%rcx // rsp before calling this routine -> rcx | ||
| 167 | \\ jb 1f | ||
| 168 | \\ 2: | ||
| 169 | \\ sub $0x1000,%%rcx | ||
| 170 | \\ test %%rcx,(%%rcx) | ||
| 171 | \\ sub $0x1000,%%rax | ||
| 172 | \\ cmp $0x1000,%%rax | ||
| 173 | \\ ja 2b | ||
| 174 | \\ 1: | ||
| 175 | \\ sub %%rax,%%rcx | ||
| 176 | \\ test %%rcx,(%%rcx) | ||
| 177 | \\ | ||
| 178 | \\ lea 8(%%rsp),%%rax // load pointer to the return address into rax | ||
| 179 | \\ mov %%rcx,%%rsp // install the new top of stack pointer into rsp | ||
| 180 | \\ mov -8(%%rax),%%rcx // restore rcx | ||
| 181 | \\ push (%%rax) // push return address onto the stack | ||
| 182 | \\ sub %%rsp,%%rax // restore the original value in rax | ||
| 183 | \\ ret | ||
| 184 | ); | 169 | ); |
| 185 | unreachable; | 170 | unreachable; |
| 186 | } | 171 | } |