| author | |
| committer | |
| log | 839b3a61ad51b385ac28a0123b6cc63d90ef83f8 |
| tree | 07e83fd37897962fb6d3a561e15d909ed5e27856 |
| parent | f8cd981c04e60530b99c9f360c3e79041d75ca96 |
| signature | Commit is signed but in an unrecognized format. |
and disable C sanitization when building libcs.
Empirically, they seem to trigger undef-sanitization.6 files changed, 52 insertions(+), 6 deletions(-)
lib/std/build.zig+5| ... | @@ -1034,6 +1034,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1034,6 +1034,7 @@ pub const LibExeObjStep = struct { |
| 1034 | disable_gen_h: bool, | 1034 | disable_gen_h: bool, |
| 1035 | bundle_compiler_rt: bool, | 1035 | bundle_compiler_rt: bool, |
| 1036 | disable_stack_probing: bool, | 1036 | disable_stack_probing: bool, |
| 1037 | disable_sanitize_c: bool, | ||
| 1037 | c_std: Builder.CStd, | 1038 | c_std: Builder.CStd, |
| 1038 | override_lib_dir: ?[]const u8, | 1039 | override_lib_dir: ?[]const u8, |
| 1039 | main_pkg_path: ?[]const u8, | 1040 | main_pkg_path: ?[]const u8, |
| ... | @@ -1183,6 +1184,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1183,6 +1184,7 @@ pub const LibExeObjStep = struct { |
| 1183 | .disable_gen_h = false, | 1184 | .disable_gen_h = false, |
| 1184 | .bundle_compiler_rt = false, | 1185 | .bundle_compiler_rt = false, |
| 1185 | .disable_stack_probing = false, | 1186 | .disable_stack_probing = false, |
| 1187 | .disable_sanitize_c = false, | ||
| 1186 | .output_dir = null, | 1188 | .output_dir = null, |
| 1187 | .need_system_paths = false, | 1189 | .need_system_paths = false, |
| 1188 | .single_threaded = false, | 1190 | .single_threaded = false, |
| ... | @@ -1822,6 +1824,9 @@ pub const LibExeObjStep = struct { | ... | @@ -1822,6 +1824,9 @@ pub const LibExeObjStep = struct { |
| 1822 | if (self.disable_stack_probing) { | 1824 | if (self.disable_stack_probing) { |
| 1823 | try zig_args.append("-fno-stack-check"); | 1825 | try zig_args.append("-fno-stack-check"); |
| 1824 | } | 1826 | } |
| 1827 | if (self.disable_sanitize_c) { | ||
| 1828 | try zig_args.append("-fno-sanitize-c"); | ||
| 1829 | } | ||
| 1825 | 1830 | ||
| 1826 | switch (self.target) { | 1831 | switch (self.target) { |
| 1827 | .Native => {}, | 1832 | .Native => {}, |
src/all_types.hpp+8| ... | @@ -1928,6 +1928,12 @@ enum WantStackCheck { | ... | @@ -1928,6 +1928,12 @@ enum WantStackCheck { |
| 1928 | WantStackCheckEnabled, | 1928 | WantStackCheckEnabled, |
| 1929 | }; | 1929 | }; |
| 1930 | 1930 | ||
| 1931 | enum WantCSanitize { | ||
| 1932 | WantCSanitizeAuto, | ||
| 1933 | WantCSanitizeDisabled, | ||
| 1934 | WantCSanitizeEnabled, | ||
| 1935 | }; | ||
| 1936 | |||
| 1931 | struct CFile { | 1937 | struct CFile { |
| 1932 | ZigList<const char *> args; | 1938 | ZigList<const char *> args; |
| 1933 | const char *source_path; | 1939 | const char *source_path; |
| ... | @@ -2096,6 +2102,7 @@ struct CodeGen { | ... | @@ -2096,6 +2102,7 @@ struct CodeGen { |
| 2096 | 2102 | ||
| 2097 | WantPIC want_pic; | 2103 | WantPIC want_pic; |
| 2098 | WantStackCheck want_stack_check; | 2104 | WantStackCheck want_stack_check; |
| 2105 | WantCSanitize want_sanitize_c; | ||
| 2099 | CacheHash cache_hash; | 2106 | CacheHash cache_hash; |
| 2100 | ErrColor err_color; | 2107 | ErrColor err_color; |
| 2101 | uint32_t next_unresolved_index; | 2108 | uint32_t next_unresolved_index; |
| ... | @@ -2170,6 +2177,7 @@ struct CodeGen { | ... | @@ -2170,6 +2177,7 @@ struct CodeGen { |
| 2170 | bool have_pic; | 2177 | bool have_pic; |
| 2171 | bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic | 2178 | bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic |
| 2172 | bool have_stack_probing; | 2179 | bool have_stack_probing; |
| 2180 | bool have_sanitize_c; | ||
| 2173 | bool function_sections; | 2181 | bool function_sections; |
| 2174 | bool enable_dump_analysis; | 2182 | bool enable_dump_analysis; |
| 2175 | bool enable_doc_generation; | 2183 | bool enable_doc_generation; |
src/codegen.cpp+25-6| ... | @@ -8261,6 +8261,20 @@ static bool detect_stack_probing(CodeGen *g) { | ... | @@ -8261,6 +8261,20 @@ static bool detect_stack_probing(CodeGen *g) { |
| 8261 | zig_unreachable(); | 8261 | zig_unreachable(); |
| 8262 | } | 8262 | } |
| 8263 | 8263 | ||
| 8264 | static bool detect_sanitize_c(CodeGen *g) { | ||
| 8265 | if (!target_supports_sanitize_c(g->zig_target)) | ||
| 8266 | return false; | ||
| 8267 | switch (g->want_sanitize_c) { | ||
| 8268 | case WantCSanitizeDisabled: | ||
| 8269 | return false; | ||
| 8270 | case WantCSanitizeEnabled: | ||
| 8271 | return true; | ||
| 8272 | case WantCSanitizeAuto: | ||
| 8273 | return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug; | ||
| 8274 | } | ||
| 8275 | zig_unreachable(); | ||
| 8276 | } | ||
| 8277 | |||
| 8264 | // Returns TargetSubsystemAuto to mean "no subsystem" | 8278 | // Returns TargetSubsystemAuto to mean "no subsystem" |
| 8265 | TargetSubsystem detect_subsystem(CodeGen *g) { | 8279 | TargetSubsystem detect_subsystem(CodeGen *g) { |
| 8266 | if (g->subsystem != TargetSubsystemAuto) | 8280 | if (g->subsystem != TargetSubsystemAuto) |
| ... | @@ -8297,6 +8311,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -8297,6 +8311,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8297 | g->have_dynamic_link = detect_dynamic_link(g); | 8311 | g->have_dynamic_link = detect_dynamic_link(g); |
| 8298 | g->have_pic = detect_pic(g); | 8312 | g->have_pic = detect_pic(g); |
| 8299 | g->have_stack_probing = detect_stack_probing(g); | 8313 | g->have_stack_probing = detect_stack_probing(g); |
| 8314 | g->have_sanitize_c = detect_sanitize_c(g); | ||
| 8300 | g->is_single_threaded = detect_single_threaded(g); | 8315 | g->is_single_threaded = detect_single_threaded(g); |
| 8301 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | 8316 | g->have_err_ret_tracing = detect_err_ret_tracing(g); |
| 8302 | 8317 | ||
| ... | @@ -8582,6 +8597,7 @@ static void init(CodeGen *g) { | ... | @@ -8582,6 +8597,7 @@ static void init(CodeGen *g) { |
| 8582 | g->have_dynamic_link = detect_dynamic_link(g); | 8597 | g->have_dynamic_link = detect_dynamic_link(g); |
| 8583 | g->have_pic = detect_pic(g); | 8598 | g->have_pic = detect_pic(g); |
| 8584 | g->have_stack_probing = detect_stack_probing(g); | 8599 | g->have_stack_probing = detect_stack_probing(g); |
| 8600 | g->have_sanitize_c = detect_sanitize_c(g); | ||
| 8585 | g->is_single_threaded = detect_single_threaded(g); | 8601 | g->is_single_threaded = detect_single_threaded(g); |
| 8586 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | 8602 | g->have_err_ret_tracing = detect_err_ret_tracing(g); |
| 8587 | 8603 | ||
| ... | @@ -8971,11 +8987,13 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa | ... | @@ -8971,11 +8987,13 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa |
| 8971 | args.append("-fomit-frame-pointer"); | 8987 | args.append("-fomit-frame-pointer"); |
| 8972 | } | 8988 | } |
| 8973 | 8989 | ||
| 8990 | if (g->have_sanitize_c) { | ||
| 8991 | args.append("-fsanitize=undefined"); | ||
| 8992 | args.append("-fsanitize-trap=undefined"); | ||
| 8993 | } | ||
| 8994 | |||
| 8974 | switch (g->build_mode) { | 8995 | switch (g->build_mode) { |
| 8975 | case BuildModeDebug: | 8996 | case BuildModeDebug: |
| 8976 | args.append("-fsanitize=undefined"); | ||
| 8977 | args.append("-fsanitize-trap=undefined"); | ||
| 8978 | |||
| 8979 | // windows c runtime requires -D_DEBUG if using debug libraries | 8997 | // windows c runtime requires -D_DEBUG if using debug libraries |
| 8980 | args.append("-D_DEBUG"); | 8998 | args.append("-D_DEBUG"); |
| 8981 | 8999 | ||
| ... | @@ -8988,9 +9006,6 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa | ... | @@ -8988,9 +9006,6 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa |
| 8988 | } | 9006 | } |
| 8989 | break; | 9007 | break; |
| 8990 | case BuildModeSafeRelease: | 9008 | case BuildModeSafeRelease: |
| 8991 | args.append("-fsanitize=undefined"); | ||
| 8992 | args.append("-fsanitize-trap=undefined"); | ||
| 8993 | |||
| 8994 | // See the comment in the BuildModeFastRelease case for why we pass -O2 rather | 9009 | // See the comment in the BuildModeFastRelease case for why we pass -O2 rather |
| 8995 | // than -O3 here. | 9010 | // than -O3 here. |
| 8996 | args.append("-O2"); | 9011 | args.append("-O2"); |
| ... | @@ -9312,6 +9327,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose | ... | @@ -9312,6 +9327,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose |
| 9312 | cache_bool(cache_hash, g->strip_debug_symbols); | 9327 | cache_bool(cache_hash, g->strip_debug_symbols); |
| 9313 | cache_int(cache_hash, g->build_mode); | 9328 | cache_int(cache_hash, g->build_mode); |
| 9314 | cache_bool(cache_hash, g->have_pic); | 9329 | cache_bool(cache_hash, g->have_pic); |
| 9330 | cache_bool(cache_hash, g->have_sanitize_c); | ||
| 9315 | cache_bool(cache_hash, want_valgrind_support(g)); | 9331 | cache_bool(cache_hash, want_valgrind_support(g)); |
| 9316 | cache_bool(cache_hash, g->function_sections); | 9332 | cache_bool(cache_hash, g->function_sections); |
| 9317 | for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { | 9333 | for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { |
| ... | @@ -10090,6 +10106,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10090,6 +10106,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10090 | cache_bool(ch, g->have_pic); | 10106 | cache_bool(ch, g->have_pic); |
| 10091 | cache_bool(ch, g->have_dynamic_link); | 10107 | cache_bool(ch, g->have_dynamic_link); |
| 10092 | cache_bool(ch, g->have_stack_probing); | 10108 | cache_bool(ch, g->have_stack_probing); |
| 10109 | cache_bool(ch, g->have_sanitize_c); | ||
| 10093 | cache_bool(ch, g->is_dummy_so); | 10110 | cache_bool(ch, g->is_dummy_so); |
| 10094 | cache_bool(ch, g->function_sections); | 10111 | cache_bool(ch, g->function_sections); |
| 10095 | cache_bool(ch, g->enable_dump_analysis); | 10112 | cache_bool(ch, g->enable_dump_analysis); |
| ... | @@ -10210,6 +10227,7 @@ void codegen_build_and_link(CodeGen *g) { | ... | @@ -10210,6 +10227,7 @@ void codegen_build_and_link(CodeGen *g) { |
| 10210 | g->have_pic = detect_pic(g); | 10227 | g->have_pic = detect_pic(g); |
| 10211 | g->is_single_threaded = detect_single_threaded(g); | 10228 | g->is_single_threaded = detect_single_threaded(g); |
| 10212 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | 10229 | g->have_err_ret_tracing = detect_err_ret_tracing(g); |
| 10230 | g->have_sanitize_c = detect_sanitize_c(g); | ||
| 10213 | detect_libc(g); | 10231 | detect_libc(g); |
| 10214 | detect_dynamic_linker(g); | 10232 | detect_dynamic_linker(g); |
| 10215 | 10233 | ||
| ... | @@ -10398,6 +10416,7 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o | ... | @@ -10398,6 +10416,7 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o |
| 10398 | child_gen->root_out_name = buf_create_from_str(name); | 10416 | child_gen->root_out_name = buf_create_from_str(name); |
| 10399 | child_gen->disable_gen_h = true; | 10417 | child_gen->disable_gen_h = true; |
| 10400 | child_gen->want_stack_check = WantStackCheckDisabled; | 10418 | child_gen->want_stack_check = WantStackCheckDisabled; |
| 10419 | child_gen->want_sanitize_c = WantCSanitizeDisabled; | ||
| 10401 | child_gen->verbose_tokenize = parent_gen->verbose_tokenize; | 10420 | child_gen->verbose_tokenize = parent_gen->verbose_tokenize; |
| 10402 | child_gen->verbose_ast = parent_gen->verbose_ast; | 10421 | child_gen->verbose_ast = parent_gen->verbose_ast; |
| 10403 | child_gen->verbose_link = parent_gen->verbose_link; | 10422 | child_gen->verbose_link = parent_gen->verbose_link; |
src/main.cpp+9| ... | @@ -59,6 +59,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -59,6 +59,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 59 | " --enable-valgrind include valgrind client requests release builds\n" | 59 | " --enable-valgrind include valgrind client requests release builds\n" |
| 60 | " -fstack-check enable stack probing in unsafe builds\n" | 60 | " -fstack-check enable stack probing in unsafe builds\n" |
| 61 | " -fno-stack-check disable stack probing in safe builds\n" | 61 | " -fno-stack-check disable stack probing in safe builds\n" |
| 62 | " -fsanitize-c enable C undefined behavior detection in unsafe builds\n" | ||
| 63 | " -fno-sanitize-c disable C undefined behavior detection in safe builds\n" | ||
| 62 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" | 64 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" |
| 63 | " -fPIC enable Position Independent Code\n" | 65 | " -fPIC enable Position Independent Code\n" |
| 64 | " -fno-PIC disable Position Independent Code\n" | 66 | " -fno-PIC disable Position Independent Code\n" |
| ... | @@ -524,6 +526,7 @@ int main(int argc, char **argv) { | ... | @@ -524,6 +526,7 @@ int main(int argc, char **argv) { |
| 524 | ValgrindSupport valgrind_support = ValgrindSupportAuto; | 526 | ValgrindSupport valgrind_support = ValgrindSupportAuto; |
| 525 | WantPIC want_pic = WantPICAuto; | 527 | WantPIC want_pic = WantPICAuto; |
| 526 | WantStackCheck want_stack_check = WantStackCheckAuto; | 528 | WantStackCheck want_stack_check = WantStackCheckAuto; |
| 529 | WantCSanitize want_sanitize_c = WantCSanitizeAuto; | ||
| 527 | bool function_sections = false; | 530 | bool function_sections = false; |
| 528 | 531 | ||
| 529 | ZigList<const char *> llvm_argv = {0}; | 532 | ZigList<const char *> llvm_argv = {0}; |
| ... | @@ -722,6 +725,10 @@ int main(int argc, char **argv) { | ... | @@ -722,6 +725,10 @@ int main(int argc, char **argv) { |
| 722 | want_stack_check = WantStackCheckEnabled; | 725 | want_stack_check = WantStackCheckEnabled; |
| 723 | } else if (strcmp(arg, "-fno-stack-check") == 0) { | 726 | } else if (strcmp(arg, "-fno-stack-check") == 0) { |
| 724 | want_stack_check = WantStackCheckDisabled; | 727 | want_stack_check = WantStackCheckDisabled; |
| 728 | } else if (strcmp(arg, "-fsanitize-c") == 0) { | ||
| 729 | want_sanitize_c = WantCSanitizeEnabled; | ||
| 730 | } else if (strcmp(arg, "-fno-sanitize-c") == 0) { | ||
| 731 | want_sanitize_c = WantCSanitizeDisabled; | ||
| 725 | } else if (strcmp(arg, "--system-linker-hack") == 0) { | 732 | } else if (strcmp(arg, "--system-linker-hack") == 0) { |
| 726 | system_linker_hack = true; | 733 | system_linker_hack = true; |
| 727 | } else if (strcmp(arg, "--single-threaded") == 0) { | 734 | } else if (strcmp(arg, "--single-threaded") == 0) { |
| ... | @@ -1093,6 +1100,7 @@ int main(int argc, char **argv) { | ... | @@ -1093,6 +1100,7 @@ int main(int argc, char **argv) { |
| 1093 | g->valgrind_support = valgrind_support; | 1100 | g->valgrind_support = valgrind_support; |
| 1094 | g->want_pic = want_pic; | 1101 | g->want_pic = want_pic; |
| 1095 | g->want_stack_check = want_stack_check; | 1102 | g->want_stack_check = want_stack_check; |
| 1103 | g->want_sanitize_c = want_sanitize_c; | ||
| 1096 | g->want_single_threaded = want_single_threaded; | 1104 | g->want_single_threaded = want_single_threaded; |
| 1097 | Buf *builtin_source = codegen_generate_builtin_source(g); | 1105 | Buf *builtin_source = codegen_generate_builtin_source(g); |
| 1098 | if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { | 1106 | if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { |
| ... | @@ -1192,6 +1200,7 @@ int main(int argc, char **argv) { | ... | @@ -1192,6 +1200,7 @@ int main(int argc, char **argv) { |
| 1192 | g->valgrind_support = valgrind_support; | 1200 | g->valgrind_support = valgrind_support; |
| 1193 | g->want_pic = want_pic; | 1201 | g->want_pic = want_pic; |
| 1194 | g->want_stack_check = want_stack_check; | 1202 | g->want_stack_check = want_stack_check; |
| 1203 | g->want_sanitize_c = want_sanitize_c; | ||
| 1195 | g->subsystem = subsystem; | 1204 | g->subsystem = subsystem; |
| 1196 | 1205 | ||
| 1197 | g->enable_time_report = timing_info; | 1206 | g->enable_time_report = timing_info; |
src/target.cpp+4| ... | @@ -1606,6 +1606,10 @@ bool target_supports_stack_probing(const ZigTarget *target) { | ... | @@ -1606,6 +1606,10 @@ bool target_supports_stack_probing(const ZigTarget *target) { |
| 1606 | return target->os != OsWindows && target->os != OsUefi && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64); | 1606 | return target->os != OsWindows && target->os != OsUefi && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64); |
| 1607 | } | 1607 | } |
| 1608 | 1608 | ||
| 1609 | bool target_supports_sanitize_c(const ZigTarget *target) { | ||
| 1610 | return true; | ||
| 1611 | } | ||
| 1612 | |||
| 1609 | bool target_requires_pic(const ZigTarget *target, bool linking_libc) { | 1613 | bool target_requires_pic(const ZigTarget *target, bool linking_libc) { |
| 1610 | // This function returns whether non-pic code is completely invalid on the given target. | 1614 | // This function returns whether non-pic code is completely invalid on the given target. |
| 1611 | return target_is_android(target) || target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) || | 1615 | return target_is_android(target) || target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) || |
src/target.hpp+1| ... | @@ -194,6 +194,7 @@ bool target_is_riscv(const ZigTarget *target); | ... | @@ -194,6 +194,7 @@ bool target_is_riscv(const ZigTarget *target); |
| 194 | bool target_is_android(const ZigTarget *target); | 194 | bool target_is_android(const ZigTarget *target); |
| 195 | bool target_is_single_threaded(const ZigTarget *target); | 195 | bool target_is_single_threaded(const ZigTarget *target); |
| 196 | bool target_supports_stack_probing(const ZigTarget *target); | 196 | bool target_supports_stack_probing(const ZigTarget *target); |
| 197 | bool target_supports_sanitize_c(const ZigTarget *target); | ||
| 197 | bool target_has_debug_info(const ZigTarget *target); | 198 | bool target_has_debug_info(const ZigTarget *target); |
| 198 | const char *target_arch_musl_name(ZigLLVM_ArchType arch); | 199 | const char *target_arch_musl_name(ZigLLVM_ArchType arch); |
| 199 | bool target_supports_libunwind(const ZigTarget *target); | 200 | bool target_supports_libunwind(const ZigTarget *target); |