improve the stack check CLI options

See #2526
This commit is contained in:
Andrew Kelley 2019-05-27 20:59:19 -04:00
parent 3fccc07479
commit 2c0280ba08
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
6 changed files with 47 additions and 23 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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) ||

View File

@ -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);