Commit 2c0280ba08
Changed files (6)
src/all_types.hpp
@@ -1633,6 +1633,12 @@ enum WantPIC {
WantPICEnabled,
};
+enum WantStackCheck {
+ WantStackCheckAuto,
+ WantStackCheckDisabled,
+ WantStackCheckEnabled,
+};
+
struct CFile {
ZigList<const char *> args;
const char *source_path;
@@ -1790,6 +1796,8 @@ struct CodeGen {
TldFn *panic_tld_fn;
AstNode *root_export_decl;
+ WantPIC want_pic;
+ WantStackCheck want_stack_check;
CacheHash cache_hash;
ErrColor err_color;
uint32_t next_unresolved_index;
@@ -1807,8 +1815,6 @@ struct CodeGen {
bool have_dllmain_crt_startup;
bool have_pub_panic;
bool have_err_ret_tracing;
- bool have_pic;
- bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic
bool c_want_stdint;
bool c_want_stdbool;
bool verbose_tokenize;
@@ -1824,6 +1830,7 @@ struct CodeGen {
bool enable_time_report;
bool system_linker_hack;
bool reported_bad_link_libc_error;
+ bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
//////////////////////////// Participates in Input Parameter Cache Hash
/////// Note: there is a separate cache hash for builtin.zig, when adding fields,
@@ -1852,8 +1859,6 @@ struct CodeGen {
const ZigTarget *zig_target;
TargetSubsystem subsystem;
ValgrindSupport valgrind_support;
- WantPIC want_pic;
- bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
bool strip_debug_symbols;
bool is_test_build;
bool is_single_threaded;
@@ -1863,7 +1868,9 @@ struct CodeGen {
bool is_dummy_so;
bool disable_gen_h;
bool bundle_compiler_rt;
- bool disable_stack_probing;
+ bool have_pic;
+ bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic
+ bool have_stack_probing;
Buf *mmacosx_version_min;
Buf *mios_version_min;
src/codegen.cpp
@@ -399,15 +399,6 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
}
}
-static void add_probe_stack_attr(CodeGen *g, LLVMValueRef fn_val) {
- // Windows already emits its own stack probes
- if (!g->disable_stack_probing && g->zig_target->os != OsWindows &&
- (g->zig_target->arch == ZigLLVM_x86 ||
- g->zig_target->arch == ZigLLVM_x86_64)) {
- addLLVMFnAttrStr(fn_val, "probe-stack", "__zig_probe_stack");
- }
-}
-
static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
switch (id) {
case GlobalLinkageIdInternal:
@@ -596,8 +587,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong");
addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4");
}
-
- add_probe_stack_attr(g, fn_table_entry->llvm_value);
+ }
+ if (g->have_stack_probing && !fn_table_entry->def_scope->safety_off) {
+ addLLVMFnAttrStr(fn_table_entry->llvm_value, "probe-stack", "__zig_probe_stack");
}
} else {
maybe_import_dll(g, fn_table_entry->llvm_value, linkage);
@@ -7458,6 +7450,20 @@ static bool detect_pic(CodeGen *g) {
zig_unreachable();
}
+static bool detect_stack_probing(CodeGen *g) {
+ if (!target_supports_stack_probing(g->zig_target))
+ return false;
+ switch (g->want_stack_check) {
+ case WantStackCheckDisabled:
+ return false;
+ case WantStackCheckEnabled:
+ return true;
+ case WantStackCheckAuto:
+ return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug;
+ }
+ zig_unreachable();
+}
+
static bool detect_single_threaded(CodeGen *g) {
if (g->want_single_threaded)
return true;
@@ -7476,6 +7482,7 @@ static bool detect_err_ret_tracing(CodeGen *g) {
Buf *codegen_generate_builtin_source(CodeGen *g) {
g->have_dynamic_link = detect_dynamic_link(g);
g->have_pic = detect_pic(g);
+ g->have_stack_probing = detect_stack_probing(g);
g->is_single_threaded = detect_single_threaded(g);
g->have_err_ret_tracing = detect_err_ret_tracing(g);
@@ -7982,6 +7989,7 @@ static void init(CodeGen *g) {
g->have_dynamic_link = detect_dynamic_link(g);
g->have_pic = detect_pic(g);
+ g->have_stack_probing = detect_stack_probing(g);
g->is_single_threaded = detect_single_threaded(g);
g->have_err_ret_tracing = detect_err_ret_tracing(g);
@@ -9351,10 +9359,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
cache_bool(ch, g->each_lib_rpath);
cache_bool(ch, g->disable_gen_h);
cache_bool(ch, g->bundle_compiler_rt);
- cache_bool(ch, g->disable_stack_probing);
cache_bool(ch, want_valgrind_support(g));
cache_bool(ch, g->have_pic);
cache_bool(ch, g->have_dynamic_link);
+ cache_bool(ch, g->have_stack_probing);
cache_bool(ch, g->is_dummy_so);
cache_buf_opt(ch, g->mmacosx_version_min);
cache_buf_opt(ch, g->mios_version_min);
src/link.cpp
@@ -25,7 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou
CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,
parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path());
child_gen->disable_gen_h = true;
- child_gen->disable_stack_probing = true;
+ child_gen->want_stack_check = WantStackCheckDisabled;
child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
child_gen->verbose_ast = parent_gen->verbose_ast;
child_gen->verbose_link = parent_gen->verbose_link;
src/main.cpp
@@ -55,7 +55,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
" --disable-gen-h do not generate a C header file (.h)\n"
" --disable-valgrind omit valgrind client requests in debug builds\n"
" --enable-valgrind include valgrind client requests release builds\n"
- " --disable-stack-probing workaround for macosx\n"
+ " -fstack-check enable stack probing in unsafe builds\n"
+ " -fno-stack-check disable stack probing in safe builds\n"
" --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
" -fPIC enable Position Independent Code\n"
" -fno-PIC disable Position Independent Code\n"
@@ -443,12 +444,12 @@ int main(int argc, char **argv) {
bool want_single_threaded = false;
bool disable_gen_h = false;
bool bundle_compiler_rt = false;
- bool disable_stack_probing = false;
Buf *override_std_dir = nullptr;
Buf *override_lib_dir = nullptr;
Buf *main_pkg_path = nullptr;
ValgrindSupport valgrind_support = ValgrindSupportAuto;
WantPIC want_pic = WantPICAuto;
+ WantStackCheck want_stack_check = WantStackCheckAuto;
ZigList<const char *> llvm_argv = {0};
llvm_argv.append("zig (LLVM option parsing)");
@@ -648,6 +649,10 @@ int main(int argc, char **argv) {
want_pic = WantPICEnabled;
} else if (strcmp(arg, "-fno-PIC") == 0) {
want_pic = WantPICDisabled;
+ } else if (strcmp(arg, "-fstack-check") == 0) {
+ want_stack_check = WantStackCheckEnabled;
+ } else if (strcmp(arg, "-fno-stack-check") == 0) {
+ want_stack_check = WantStackCheckDisabled;
} else if (strcmp(arg, "--system-linker-hack") == 0) {
system_linker_hack = true;
} else if (strcmp(arg, "--single-threaded") == 0) {
@@ -656,8 +661,6 @@ int main(int argc, char **argv) {
disable_gen_h = true;
} else if (strcmp(arg, "--bundle-compiler-rt") == 0) {
bundle_compiler_rt = true;
- } else if (strcmp(arg, "--disable-stack-probing") == 0) {
- disable_stack_probing = true;
} else if (strcmp(arg, "--test-cmd-bin") == 0) {
test_exec_args.append(nullptr);
} else if (arg[1] == 'L' && arg[2] != 0) {
@@ -953,6 +956,7 @@ int main(int argc, char **argv) {
out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);
g->valgrind_support = valgrind_support;
g->want_pic = want_pic;
+ g->want_stack_check = want_stack_check;
g->want_single_threaded = want_single_threaded;
Buf *builtin_source = codegen_generate_builtin_source(g);
if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
@@ -1048,6 +1052,7 @@ int main(int argc, char **argv) {
if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
g->valgrind_support = valgrind_support;
g->want_pic = want_pic;
+ g->want_stack_check = want_stack_check;
g->subsystem = subsystem;
g->enable_time_report = timing_info;
@@ -1074,7 +1079,6 @@ int main(int argc, char **argv) {
g->output_dir = output_dir;
g->disable_gen_h = disable_gen_h;
g->bundle_compiler_rt = bundle_compiler_rt;
- g->disable_stack_probing = disable_stack_probing;
codegen_set_errmsg_color(g, color);
g->system_linker_hack = system_linker_hack;
src/target.cpp
@@ -1356,6 +1356,10 @@ bool target_supports_fpic(const ZigTarget *target) {
return target->os != OsWindows;
}
+bool target_supports_stack_probing(const ZigTarget *target) {
+ return target->os != OsWindows && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64);
+}
+
bool target_requires_pic(const ZigTarget *target, bool linking_libc) {
// This function returns whether non-pic code is completely invalid on the given target.
return target->os == OsWindows || target_os_requires_libc(target->os) ||
src/target.hpp
@@ -172,6 +172,7 @@ bool target_is_glibc(const ZigTarget *target);
bool target_is_musl(const ZigTarget *target);
bool target_is_wasm(const ZigTarget *target);
bool target_is_single_threaded(const ZigTarget *target);
+bool target_supports_stack_probing(const ZigTarget *target);
uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);