diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-10-03 00:27:14 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-10-03 00:29:41 -0400 |
| commit | b5054625093ef22b3f228199b6fbf70e1c50b703 (patch) | |
| tree | 09b000d9205b1f378d0d6a78700c3f3b642894d8 | |
| parent | f1bd02e6f46821415d96f54f6a3258159ba5a9c5 (diff) | |
| download | zig-b5054625093ef22b3f228199b6fbf70e1c50b703.tar.gz zig-b5054625093ef22b3f228199b6fbf70e1c50b703.zip | |
replace __chkstk function with a stub that does not crash
Closes #508
See #302
| -rw-r--r-- | src/codegen.cpp | 17 | ||||
| -rw-r--r-- | src/link.cpp | 2 | ||||
| -rw-r--r-- | std/special/bootstrap.zig | 24 | ||||
| -rw-r--r-- | std/special/compiler_rt/index.zig | 27 |
4 files changed, 21 insertions, 49 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 6a0e7e12f4..efcf6ea3e3 100644 --- a/src/codegen.cpp +++ b/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 = ""; diff --git a/src/link.cpp b/src/link.cpp index bd17ff1ea4..35b350df0f 100644 --- a/src/link.cpp +++ b/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"); } } diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index 3067406431..fea062712b 100644 --- a/std/special/bootstrap.zig +++ b/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); diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig index 36ad997120..f27e3069f0 100644 --- a/std/special/compiler_rt/index.zig +++ b/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; } |
