authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-03 00:27:14-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-03 00:29:41-04:00
logb5054625093ef22b3f228199b6fbf70e1c50b703
tree09b000d9205b1f378d0d6a78700c3f3b642894d8
parentf1bd02e6f46821415d96f54f6a3258159ba5a9c5

replace __chkstk function with a stub that does not crash

Closes #508 See #302

4 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) {
924924
925static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {925static 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}
930931
...@@ -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/5085012 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 }
429429
std/special/bootstrap.zig+9-15
...@@ -5,12 +5,13 @@ const root = @import("@root");...@@ -5,12 +5,13 @@ const root = @import("@root");
5const std = @import("std");5const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8const is_windows = builtin.os == builtin.Os.windows;
8const want_main_symbol = builtin.link_libc;9const want_main_symbol = builtin.link_libc;
9const want_start_symbol = !want_main_symbol;10const want_start_symbol = !want_main_symbol and !is_windows;
11const want_WinMainCRTStartup = is_windows and !builtin.link_libc;
1012
11var argc_ptr: &usize = undefined;13var argc_ptr: &usize = undefined;
1214
13const is_windows = builtin.os == builtin.Os.windows;
1415
15export nakedcc fn _start() -> noreturn {16export 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 }
2021
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}
4433
45fn windowsCallMainAndExit() -> noreturn {34export 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}
157157
158export 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`.
162export nakedcc fn __chkstk() align(8) {
159 @setDebugSafety(this, false);163 @setDebugSafety(this, false);
160164
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 %%rcx168 \\ 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 }