diff options
| author | gingerBill <bill@gingerbill.org> | 2023-09-21 09:40:33 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-09-21 09:40:33 +0100 |
| commit | 2160484b62ebde52ba6f486ad652f1a72cfe9143 (patch) | |
| tree | 07faa7a8ece3962d504853c70400717dd04130d7 /src | |
| parent | f0ab58dfbb4be6103fb7340ec570d218e2137a4b (diff) | |
Support `-sanitize:<string>` for `address`, `memory`, `thread` for LLVM 17
Diffstat (limited to 'src')
| -rw-r--r-- | src/build_settings.cpp | 16 | ||||
| -rw-r--r-- | src/llvm_backend.cpp | 18 | ||||
| -rw-r--r-- | src/main.cpp | 19 |
3 files changed, 52 insertions, 1 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 79f6e8a2c..57dac0ca3 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -264,6 +264,14 @@ u64 get_vet_flag_from_name(String const &name) { } +enum SanitizerFlags : u32 { + SanitizerFlag_NONE = 0, + SanitizerFlag_Address = 1u<<0, + SanitizerFlag_Memory = 1u<<1, + SanitizerFlag_Thread = 1u<<2, +}; + + // This stores the information for the specify architecture of this build struct BuildContext { @@ -305,6 +313,7 @@ struct BuildContext { String pdb_filepath; u64 vet_flags; + u32 sanitizer_flags; bool has_resource; String link_flags; @@ -1738,6 +1747,13 @@ gb_internal bool init_build_paths(String init_filename) { return false; } + if (build_context.sanitizer_flags & SanitizerFlag_Memory) { + if (build_context.metrics.os != TargetOs_linux) { + gb_printf_err("-sanitize:memory is only supported on linux\n"); + return false; + } + } + if (bc->target_features_string.len != 0) { enable_target_feature({}, bc->target_features_string); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 8ced9ccee..68223d8c9 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1478,12 +1478,28 @@ gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) { passes = gb_string_appendc(passes, "default<O0>"); break; case 1: - passes = gb_string_appendc(passes, "default<O1>"); + passes = gb_string_appendc(passes, "default<Os>"); break; case 2: passes = gb_string_appendc(passes, "default<O2>"); break; } + + // asan - Linux, Darwin, Windows + // msan - linux + // tsan - Linux, Darwin + // ubsan - Linux, Darwin, Windows (NOT SUPPORTED WITH LLVM C-API) + + if (build_context.sanitizer_flags & SanitizerFlag_Address) { + passes = gb_string_appendc(passes, ",asan"); + } + if (build_context.sanitizer_flags & SanitizerFlag_Memory) { + passes = gb_string_appendc(passes, ",msan"); + } + if (build_context.sanitizer_flags & SanitizerFlag_Thread) { + passes = gb_string_appendc(passes, ",tsan"); + } + LLVMErrorRef llvm_err = LLVMRunPasses(wd->m->mod, passes, wd->target_machine, pb_options); defer (LLVMConsumeError(llvm_err)); if (llvm_err != nullptr) { diff --git a/src/main.cpp b/src/main.cpp index 3d8637757..3d2dd3c44 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,6 +300,8 @@ enum BuildFlagKind { BuildFlag_Tilde, + BuildFlag_Sanitize, + #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, BuildFlag_ResourceFile, @@ -486,6 +488,8 @@ gb_internal bool parse_build_flags(Array<String> args) { add_flag(&build_flags, BuildFlag_Tilde, str_lit("tilde"), BuildFlagParam_None, Command__does_build); #endif + add_flag(&build_flags, BuildFlag_Sanitize, str_lit("sanitize"), BuildFlagParam_String, Command__does_build, true); + #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_ResourceFile, str_lit("resource"), BuildFlagParam_String, Command__does_build); @@ -1194,6 +1198,21 @@ gb_internal bool parse_build_flags(Array<String> args) { build_context.tilde_backend = true; break; + case BuildFlag_Sanitize: + GB_ASSERT(value.kind == ExactValue_String); + + if (str_eq_ignore_case(value.value_string, str_lit("address"))) { + build_context.sanitizer_flags |= SanitizerFlag_Address; + } else if (str_eq_ignore_case(value.value_string, str_lit("memory"))) { + build_context.sanitizer_flags |= SanitizerFlag_Memory; + } else if (str_eq_ignore_case(value.value_string, str_lit("thread"))) { + build_context.sanitizer_flags |= SanitizerFlag_Thread; + } else { + gb_printf_err("-sanitize:<string> options are 'address', 'memory', and 'thread'\n"); + bad_flags = true; + } + break; + #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: { GB_ASSERT(value.kind == ExactValue_Invalid); |