1import lit.formats 2import sys 3import os 4 5config.name = "libFuzzer" + config.name_suffix 6config.test_format = lit.formats.ShTest(True) 7config.suffixes = [".test"] 8config.test_source_root = os.path.dirname(__file__) 9config.available_features.add(config.target_arch) 10 11# Choose between lit's internal shell pipeline runner and a real shell. If 12# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. 13use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") 14if use_lit_shell: 15 # 0 is external, "" is default, and everything else is internal. 16 execute_external = use_lit_shell == "0" 17else: 18 # Otherwise we default to internal on Windows and external elsewhere, as 19 # bash on Windows is usually very slow. 20 execute_external = not sys.platform in ["win32"] 21 22# testFormat: The test format to use to interpret tests. 23# 24# For now we require '&&' between commands, until they get globally killed and 25# the test runner updated. 26config.test_format = lit.formats.ShTest(execute_external) 27 28# LeakSanitizer is not supported on OSX or Windows right now. 29if ( 30 sys.platform.startswith("darwin") 31 or sys.platform.startswith("freebsd") 32 or sys.platform.startswith("win") 33): 34 lit_config.note("lsan feature unavailable") 35else: 36 config.available_features.add("lsan") 37 38# MemorySanitizer is not supported on OSX or Windows right now 39if ( 40 sys.platform.startswith("darwin") 41 or sys.platform.startswith("win") 42): 43 lit_config.note("msan feature unavailable") 44 assert "msan" not in config.available_features 45elif config.target_arch == "i386": 46 assert "msan" not in config.available_features 47else: 48 config.available_features.add("msan") 49 50if sys.platform.startswith("win") or sys.platform.startswith("cygwin"): 51 config.available_features.add("windows") 52 53if sys.platform.startswith("darwin"): 54 config.available_features.add("darwin") 55 56if sys.platform.startswith("linux"): 57 # Note the value of ``sys.platform`` is not consistent 58 # between python 2 and 3, hence the use of ``.startswith()``. 59 config.available_features.add("linux") 60 61if config.arm_thumb: 62 config.available_features.add("thumb") 63 64config.substitutions.append(("%build_dir", config.cmake_binary_dir)) 65libfuzzer_src_root = os.path.join(config.compiler_rt_src_root, "lib", "fuzzer") 66config.substitutions.append(("%libfuzzer_src", libfuzzer_src_root)) 67 68config.substitutions.append(("%python", '"%s"' % (sys.executable))) 69 70 71def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False): 72 compiler_cmd = config.clang 73 extra_cmd = config.target_flags 74 75 if is_cpp: 76 std_cmd = "--driver-mode=g++" 77 else: 78 std_cmd = "" 79 80 if msan_enabled: 81 sanitizers = ["memory"] 82 else: 83 sanitizers = ["address"] 84 if fuzzer_enabled: 85 sanitizers.append("fuzzer") 86 sanitizers_cmd = "-fsanitize=%s" % ",".join(sanitizers) 87 88 # Since clang_rt.fuzzer-x86_64.lib is built without -fsanitize=address and 89 # we're building with that flag here, the MSVC STL needs all libs to be 90 # compiled with the same -fsanitize flags, see: 91 # https://learn.microsoft.com/en-us/cpp/sanitizers/error-container-overflow?view=msvc-170 92 # Avoids linker error: 93 # /failifmismatch: mismatch detected for 'annotate_string' 94 if "windows" in config.available_features: 95 extra_cmd = extra_cmd + " -D_DISABLE_VECTOR_ANNOTATION -D_DISABLE_STRING_ANNOTATION" 96 97 if "darwin" in config.available_features and getattr( 98 config, "darwin_linker_version", None 99 ): 100 extra_cmd = extra_cmd + " -mlinker-version=" + config.darwin_linker_version 101 102 return " ".join( 103 [ 104 compiler_cmd, 105 config.target_cflags, 106 std_cmd, 107 "-O2 -gline-tables-only", 108 sanitizers_cmd, 109 "-I%s" % libfuzzer_src_root, 110 extra_cmd, 111 ] 112 ) 113 114 115config.substitutions.append( 116 ("%cpp_compiler", generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True)) 117) 118 119config.substitutions.append( 120 ("%c_compiler", generate_compiler_cmd(is_cpp=False, fuzzer_enabled=True)) 121) 122 123config.substitutions.append( 124 ( 125 "%no_fuzzer_cpp_compiler", 126 generate_compiler_cmd(is_cpp=True, fuzzer_enabled=False), 127 ) 128) 129 130config.substitutions.append( 131 ("%no_fuzzer_c_compiler", generate_compiler_cmd(is_cpp=False, fuzzer_enabled=False)) 132) 133 134config.substitutions.append( 135 ( 136 "%msan_compiler", 137 generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=True), 138 ) 139) 140 141default_asan_opts_str = ":".join(config.default_sanitizer_opts) 142if default_asan_opts_str: 143 config.environment["ASAN_OPTIONS"] = default_asan_opts_str 144 default_asan_opts_str += ":" 145config.substitutions.append( 146 ("%env_asan_opts=", "env ASAN_OPTIONS=" + default_asan_opts_str) 147) 148 149if not config.parallelism_group: 150 config.parallelism_group = "shadow-memory" 151 152if config.host_os == "NetBSD": 153 config.substitutions.insert(0, ("%run", config.netbsd_noaslr_prefix)) 154