Commit eb0979189b
Changed files (7)
src/link.cpp
@@ -78,14 +78,6 @@ static Buf *build_compiler_rt(CodeGen *parent_gen) {
return build_o_raw(parent_gen, "compiler_rt", full_path);
}
-static const char *get_exe_file_extension(CodeGen *g) {
- if (g->zig_target.os == ZigLLVM_Win32) {
- return ".exe";
- } else {
- return "";
- }
-}
-
static const char *get_darwin_arch_string(const ZigTarget *t) {
switch (t->arch.arch) {
case ZigLLVM_aarch64:
@@ -835,7 +827,7 @@ void codegen_link(CodeGen *g, const char *out_file) {
buf_init_from_buf(&lj.out_file, g->root_out_name);
if (g->out_type == OutTypeExe) {
- buf_append_str(&lj.out_file, get_exe_file_extension(g));
+ buf_append_str(&lj.out_file, target_exe_file_ext(&g->zig_target));
}
}
src/main.cpp
@@ -509,6 +509,36 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
+ init_all_targets();
+
+ ZigTarget alloc_target;
+ ZigTarget *target;
+ if (!target_arch && !target_os && !target_environ) {
+ target = nullptr;
+ } else {
+ target = &alloc_target;
+ get_unknown_target(target);
+ if (target_arch) {
+ if (parse_target_arch(target_arch, &target->arch)) {
+ fprintf(stderr, "invalid --target-arch argument\n");
+ return usage(arg0);
+ }
+ }
+ if (target_os) {
+ if (parse_target_os(target_os, &target->os)) {
+ fprintf(stderr, "invalid --target-os argument\n");
+ return usage(arg0);
+ }
+ }
+ if (target_environ) {
+ if (parse_target_environ(target_environ, &target->env_type)) {
+ fprintf(stderr, "invalid --target-environ argument\n");
+ return usage(arg0);
+ }
+ }
+ }
+
+
switch (cmd) {
case CmdBuild:
case CmdParseH:
@@ -527,35 +557,6 @@ int main(int argc, char **argv) {
assert(cmd != CmdBuild || out_type != OutTypeUnknown);
- init_all_targets();
-
- ZigTarget alloc_target;
- ZigTarget *target;
- if (!target_arch && !target_os && !target_environ) {
- target = nullptr;
- } else {
- target = &alloc_target;
- get_unknown_target(target);
- if (target_arch) {
- if (parse_target_arch(target_arch, &target->arch)) {
- fprintf(stderr, "invalid --target-arch argument\n");
- return usage(arg0);
- }
- }
- if (target_os) {
- if (parse_target_os(target_os, &target->os)) {
- fprintf(stderr, "invalid --target-os argument\n");
- return usage(arg0);
- }
- }
- if (target_environ) {
- if (parse_target_environ(target_environ, &target->env_type)) {
- fprintf(stderr, "invalid --target-environ argument\n");
- return usage(arg0);
- }
- }
- }
-
bool need_name = (cmd == CmdBuild || cmd == CmdParseH);
Buf *in_file_buf = nullptr;
@@ -674,24 +675,30 @@ int main(int argc, char **argv) {
codegen_print_timing_report(g, stdout);
return EXIT_SUCCESS;
} else if (cmd == CmdTest) {
- codegen_build(g);
- codegen_link(g, "./test");
-
ZigTarget native;
get_native_target(&native);
+
+ ZigTarget *non_null_target = target ? target : &native;
+
+ Buf *test_exe_name = buf_sprintf("./test%s", target_exe_file_ext(non_null_target));
+
+ codegen_build(g);
+ codegen_link(g, buf_ptr(test_exe_name));
+
bool is_native_target = target == nullptr || (target->os == native.os &&
target->arch.arch == native.arch.arch && target->arch.sub_arch == native.arch.sub_arch);
if (!is_native_target) {
- fprintf(stderr, "Skipping execution of non-native test binary.\n");
+ fprintf(stderr, "Created %s but skipping execution because it is non-native.\n",
+ buf_ptr(test_exe_name));
return 0;
}
ZigList<const char *> args = {0};
Termination term;
- os_spawn_process("./test", args, &term);
+ os_spawn_process(buf_ptr(test_exe_name), args, &term);
if (term.how != TerminationIdClean || term.code != 0) {
fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n");
- fprintf(stderr, "./test\n");
+ fprintf(stderr, "%s\n", buf_ptr(test_exe_name));
} else if (timing_info) {
codegen_print_timing_report(g, stdout);
}
src/target.cpp
@@ -555,6 +555,14 @@ const char *target_o_file_ext(ZigTarget *target) {
}
}
+const char *target_exe_file_ext(ZigTarget *target) {
+ if (target->os == ZigLLVM_Win32) {
+ return ".exe";
+ } else {
+ return "";
+ }
+}
+
enum FloatAbi {
FloatAbiHard,
FloatAbiSoft,
src/target.hpp
@@ -73,6 +73,7 @@ void resolve_target_object_format(ZigTarget *target);
uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);
const char *target_o_file_ext(ZigTarget *target);
+const char *target_exe_file_ext(ZigTarget *target);
Buf *target_dynamic_linker(ZigTarget *target);
std/special/compiler_rt/index.zig
@@ -98,6 +98,38 @@ export nakedcc fn __aeabi_uidivmod() {
@setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal);
}
+export nakedcc fn __chkstk() {
+ @setDebugSafety(this, false);
+
+ if (comptime builtin.arch == builtin.Arch.x86_64) {
+ 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
+ );
+ unreachable;
+ }
+
+ @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal);
+}
+
export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
@setDebugSafety(this, is_test);
@setGlobalLinkage(__udivmodsi4, builtin.GlobalLinkage.LinkOnce);
@@ -316,3 +348,4 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) {
const q: u32 = __udivsi3(a, b);
assert(q == expected_q);
}
+
std/special/builtin.zig
@@ -22,8 +22,8 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
(??dest)[index] = (??src)[index];
}
-export fn __stack_chk_fail() {
- if (builtin.mode == builtin.Mode.ReleaseFast) {
+export fn __stack_chk_fail() -> noreturn {
+ if (builtin.mode == builtin.Mode.ReleaseFast or builtin.os == builtin.Os.windows) {
@setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal);
unreachable;
}
test/tests.zig
@@ -36,6 +36,11 @@ const test_targets = []TestTarget {
.arch = builtin.Arch.x86_64,
.environ = builtin.Environ.unknown,
},
+ TestTarget {
+ .os = builtin.Os.windows,
+ .arch = builtin.Arch.x86_64,
+ .environ = builtin.Environ.msvc,
+ },
};
error TestFailed;