Commit b505462509

Andrew Kelley <superjoe30@gmail.com>
2017-10-03 06:27:14
replace __chkstk function with a stub that does not crash
Closes #508 See #302
1 parent f1bd02e
Changed files (4)
src
std
special
src/codegen.cpp
@@ -867,7 +867,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
     addLLVMFnAttr(fn_val, "noreturn");
     addLLVMFnAttr(fn_val, "cold");
     LLVMSetLinkage(fn_val, LLVMInternalLinkage);
-    LLVMSetFunctionCallConv(fn_val, LLVMFastCallConv);
+    LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
     addLLVMFnAttr(fn_val, "nounwind");
     if (g->build_mode == BuildModeDebug) {
         ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
@@ -924,7 +924,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
 
 static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
     LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);
-    ZigLLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, LLVMFastCallConv, false, "");
+    ZigLLVMBuildCall(g->builder, safety_crash_err_fn, &err_val, 1, get_llvm_cc(g, CallingConventionUnspecified),
+        false, "");
     LLVMBuildUnreachable(g->builder);
 }
 
@@ -5007,16 +5008,8 @@ static void init(CodeGen *g) {
     const char *target_specific_cpu_args;
     const char *target_specific_features;
     if (g->is_native_target) {
-        // LLVM creates invalid binaries on Windows sometimes.
-        // See https://github.com/zig-lang/zig/issues/508
-        // As a workaround we do not use target native features on Windows.
-        if (g->zig_target.os == ZigLLVM_Win32) {
-            target_specific_cpu_args = "";
-            target_specific_features = "";
-        } else {
-            target_specific_cpu_args = ZigLLVMGetHostCPUName();
-            target_specific_features = ZigLLVMGetNativeFeatures();
-        }
+        target_specific_cpu_args = ZigLLVMGetHostCPUName();
+        target_specific_features = ZigLLVMGetNativeFeatures();
     } else {
         target_specific_cpu_args = "";
         target_specific_features = "";
src/link.cpp
@@ -423,7 +423,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
         if (g->have_winmain) {
             lj->args.append("-ENTRY:WinMain");
         } else {
-            lj->args.append("-ENTRY:_start");
+            lj->args.append("-ENTRY:WinMainCRTStartup");
         }
     }
 
std/special/compiler_rt/index.zig
@@ -155,32 +155,17 @@ export nakedcc fn _chkstk() align(4) {
     @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal);
 }
 
-export nakedcc fn __chkstk() align(4) {
+// TODO The implementation from compiler-rt causes crashes and
+// the implementation from disassembled ntdll seems to depend on
+// thread local storage. So we have given up this safety check
+// and simply have `ret`.
+export nakedcc fn __chkstk() align(8) {
     @setDebugSafety(this, false);
 
     if (win64_nocrt) {
         @setGlobalLinkage(__chkstk, strong_linkage);
         asm volatile (
-            \\         push   %%rcx
-            \\         cmp    $0x1000,%%rax
-            \\         lea    16(%%rsp),%%rcx     // rsp before calling this routine -> rcx
-            \\         jb     1f
-            \\ 2:
-            \\         sub    $0x1000,%%rcx
-            \\         test   %%rcx,(%%rcx)
-            \\         sub    $0x1000,%%rax
-            \\         cmp    $0x1000,%%rax
-            \\         ja     2b
-            \\ 1:
-            \\         sub    %%rax,%%rcx
-            \\         test   %%rcx,(%%rcx)
-            \\ 
-            \\         lea    8(%%rsp),%%rax     // load pointer to the return address into rax
-            \\         mov    %%rcx,%%rsp        // install the new top of stack pointer into rsp
-            \\         mov    -8(%%rax),%%rcx    // restore rcx
-            \\         push   (%%rax)           // push return address onto the stack
-            \\         sub    %%rsp,%%rax        // restore the original value in rax
-            \\         ret
+            \\ ret
         );
         unreachable;
     }
std/special/bootstrap.zig
@@ -5,12 +5,13 @@ const root = @import("@root");
 const std = @import("std");
 const builtin = @import("builtin");
 
+const is_windows = builtin.os == builtin.Os.windows;
 const want_main_symbol = builtin.link_libc;
-const want_start_symbol = !want_main_symbol;
+const want_start_symbol = !want_main_symbol and !is_windows;
+const want_WinMainCRTStartup = is_windows and !builtin.link_libc;
 
 var argc_ptr: &usize = undefined;
 
-const is_windows = builtin.os == builtin.Os.windows;
 
 export nakedcc fn _start() -> noreturn {
     if (!want_start_symbol) {
@@ -18,18 +19,6 @@ export nakedcc fn _start() -> noreturn {
         unreachable;
     }
 
-    if (is_windows) {
-        if (builtin.arch == builtin.Arch.x86_64) {
-            // Align the stack pointer to 16 bytes.
-            asm volatile (
-                \\ and    $0xfffffffffffffff0,%%rsp
-                \\ sub    $0x10,%%rsp
-                :::"rsp"
-            );
-        }
-        windowsCallMainAndExit()
-    }
-
     switch (builtin.arch) {
         builtin.Arch.x86_64 => {
             argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));
@@ -42,8 +31,13 @@ export nakedcc fn _start() -> noreturn {
     posixCallMainAndExit()
 }
 
-fn windowsCallMainAndExit() -> noreturn {
+export fn WinMainCRTStartup() -> noreturn {
+    if (!want_WinMainCRTStartup) {
+        @setGlobalLinkage(WinMainCRTStartup, builtin.GlobalLinkage.Internal);
+        unreachable;
+    }
     @setAlignStack(16);
+
     std.debug.user_main_fn = root.main;
     root.main() %% std.os.windows.ExitProcess(1);
     std.os.windows.ExitProcess(0);