| 1 | const std = @import("std"); |
| 2 | const assert = std.debug.assert; |
| 3 | |
| 4 | const Compilation = @import("../Compilation.zig"); |
| 5 | const build_options = @import("build_options"); |
| 6 | const trace = @import("../tracy.zig").trace; |
| 7 | const Module = @import("../Module.zig"); |
| 8 | |
| 9 | pub const BuildError = error{ |
| 10 | OutOfMemory, |
| 11 | AlreadyReported, |
| 12 | ZigCompilerNotBuiltWithLLVMExtensions, |
| 13 | TSANUnsupportedCPUArchitecture, |
| 14 | } || std.Io.Cancelable; |
| 15 | |
| 16 | pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { |
| 17 | if (!build_options.have_llvm) { |
| 18 | return error.ZigCompilerNotBuiltWithLLVMExtensions; |
| 19 | } |
| 20 | |
| 21 | const tracy = trace(@src()); |
| 22 | defer tracy.end(); |
| 23 | |
| 24 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); |
| 25 | defer arena_allocator.deinit(); |
| 26 | const arena = arena_allocator.allocator(); |
| 27 | |
| 28 | const io = comp.io; |
| 29 | const target = comp.getTarget(); |
| 30 | const root_name = switch (target.os.tag) { |
| 31 | // On Apple platforms, we use the same name as LLVM because the |
| 32 | // TSAN library implementation hard-codes a check for these names. |
| 33 | .driverkit, .maccatalyst, .macos => "clang_rt.tsan_osx_dynamic", |
| 34 | .ios => if (target.abi == .simulator) "clang_rt.tsan_iossim_dynamic" else "clang_rt.tsan_ios_dynamic", |
| 35 | .tvos => if (target.abi == .simulator) "clang_rt.tsan_tvossim_dynamic" else "clang_rt.tsan_tvos_dynamic", |
| 36 | .visionos => if (target.abi == .simulator) "clang_rt.tsan_xrossim_dynamic" else "clang_rt.tsan_xros_dynamic", |
| 37 | .watchos => if (target.abi == .simulator) "clang_rt.tsan_watchossim_dynamic" else "clang_rt.tsan_watchos_dynamic", |
| 38 | else => "tsan", |
| 39 | }; |
| 40 | const link_mode: std.lang.LinkMode = if (target.os.tag.isDarwin()) .dynamic else .static; |
| 41 | const output_mode = .Lib; |
| 42 | const basename = try std.zig.binNameAlloc(arena, .{ |
| 43 | .root_name = root_name, |
| 44 | .cpu_arch = target.cpu.arch, |
| 45 | .os_tag = target.os.tag, |
| 46 | .ofmt = target.ofmt, |
| 47 | .abi = target.abi, |
| 48 | .output_mode = output_mode, |
| 49 | .link_mode = link_mode, |
| 50 | }); |
| 51 | |
| 52 | const optimize_mode = comp.compilerRtOptMode(); |
| 53 | const strip = comp.compilerRtStrip(); |
| 54 | const unwind_tables: std.lang.UnwindTables = |
| 55 | if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .async; |
| 56 | const link_libcpp = target.os.tag.isDarwin(); |
| 57 | |
| 58 | const config = Compilation.Config.resolve(.{ |
| 59 | .output_mode = output_mode, |
| 60 | .link_mode = link_mode, |
| 61 | .resolved_target = comp.root_mod.resolved_target, |
| 62 | .is_test = false, |
| 63 | .have_zcu = false, |
| 64 | .emit_bin = true, |
| 65 | .root_optimize_mode = optimize_mode, |
| 66 | .root_strip = strip, |
| 67 | .link_libc = true, |
| 68 | .link_libcpp = link_libcpp, |
| 69 | .any_unwind_tables = unwind_tables != .none, |
| 70 | // LLVM disables LTO for its libtsan. |
| 71 | .lto = .none, |
| 72 | }) catch |err| { |
| 73 | comp.lockAndSetMiscFailure( |
| 74 | .libtsan, |
| 75 | "unable to build thread sanitizer runtime: resolving configuration failed: {s}", |
| 76 | .{@errorName(err)}, |
| 77 | ); |
| 78 | return error.AlreadyReported; |
| 79 | }; |
| 80 | |
| 81 | const common_flags = [_][]const u8{ |
| 82 | "-DTSAN_CONTAINS_UBSAN=0", |
| 83 | }; |
| 84 | |
| 85 | const root_mod = Module.create(arena, .{ |
| 86 | .paths = .{ |
| 87 | .root = .zig_lib_root, |
| 88 | .root_src_path = "", |
| 89 | }, |
| 90 | .fully_qualified_name = "root", |
| 91 | .inherited = .{ |
| 92 | .resolved_target = comp.root_mod.resolved_target, |
| 93 | .strip = strip, |
| 94 | .stack_check = false, |
| 95 | .stack_protector = 0, |
| 96 | .sanitize_c = .off, |
| 97 | .sanitize_thread = false, |
| 98 | .red_zone = comp.root_mod.red_zone, |
| 99 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 100 | .valgrind = false, |
| 101 | .unwind_tables = unwind_tables, |
| 102 | .optimize_mode = optimize_mode, |
| 103 | .pic = true, |
| 104 | .no_builtin = true, |
| 105 | .code_model = comp.root_mod.code_model, |
| 106 | }, |
| 107 | .global = config, |
| 108 | .cc_argv = &common_flags, |
| 109 | .parent = null, |
| 110 | }) catch |err| { |
| 111 | comp.lockAndSetMiscFailure( |
| 112 | .libtsan, |
| 113 | "unable to build thread sanitizer runtime: creating module failed: {s}", |
| 114 | .{@errorName(err)}, |
| 115 | ); |
| 116 | return error.AlreadyReported; |
| 117 | }; |
| 118 | |
| 119 | var c_source_files = std.array_list.Managed(Compilation.CSourceFile).init(arena); |
| 120 | try c_source_files.ensureUnusedCapacity(tsan_sources.len); |
| 121 | |
| 122 | const tsan_include_path = try comp.dirs.zig_lib.join(arena, &.{"libtsan"}); |
| 123 | for (tsan_sources) |tsan_src| { |
| 124 | var cflags = std.array_list.Managed([]const u8).init(arena); |
| 125 | |
| 126 | try cflags.append("-I"); |
| 127 | try cflags.append(tsan_include_path); |
| 128 | |
| 129 | try addCcArgs(target, &cflags); |
| 130 | |
| 131 | c_source_files.appendAssumeCapacity(.{ |
| 132 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }), |
| 133 | .extra_flags = cflags.items, |
| 134 | .owner = root_mod, |
| 135 | }); |
| 136 | } |
| 137 | |
| 138 | const platform_tsan_sources = switch (target.os.tag) { |
| 139 | .driverkit, .ios, .maccatalyst, .macos, .watchos, .tvos, .visionos => &darwin_tsan_sources, |
| 140 | .windows => &windows_tsan_sources, |
| 141 | else => &unix_tsan_sources, |
| 142 | }; |
| 143 | try c_source_files.ensureUnusedCapacity(platform_tsan_sources.len); |
| 144 | for (platform_tsan_sources) |tsan_src| { |
| 145 | var cflags = std.array_list.Managed([]const u8).init(arena); |
| 146 | |
| 147 | try cflags.append("-I"); |
| 148 | try cflags.append(tsan_include_path); |
| 149 | |
| 150 | try addCcArgs(target, &cflags); |
| 151 | |
| 152 | c_source_files.appendAssumeCapacity(.{ |
| 153 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }), |
| 154 | .extra_flags = cflags.items, |
| 155 | .owner = root_mod, |
| 156 | }); |
| 157 | } |
| 158 | { |
| 159 | const asm_source = switch (target.cpu.arch) { |
| 160 | .aarch64, .aarch64_be => "tsan_rtl_aarch64.S", |
| 161 | .loongarch64 => "tsan_rtl_loongarch64.S", |
| 162 | .mips64, .mips64el => "tsan_rtl_mips64.S", |
| 163 | .powerpc64, .powerpc64le => "tsan_rtl_ppc64.S", |
| 164 | .riscv64 => "tsan_rtl_riscv64.S", |
| 165 | .s390x => "tsan_rtl_s390x.S", |
| 166 | .x86_64 => "tsan_rtl_amd64.S", |
| 167 | else => return error.TSANUnsupportedCPUArchitecture, |
| 168 | }; |
| 169 | var cflags = std.array_list.Managed([]const u8).init(arena); |
| 170 | |
| 171 | try cflags.append("-I"); |
| 172 | try cflags.append(tsan_include_path); |
| 173 | |
| 174 | try cflags.append("-DNDEBUG"); |
| 175 | |
| 176 | c_source_files.appendAssumeCapacity(.{ |
| 177 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", asm_source }), |
| 178 | .extra_flags = cflags.items, |
| 179 | .owner = root_mod, |
| 180 | }); |
| 181 | } |
| 182 | |
| 183 | try c_source_files.ensureUnusedCapacity(sanitizer_common_sources.len); |
| 184 | const sanitizer_common_include_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 185 | "libtsan", "sanitizer_common", |
| 186 | }); |
| 187 | for (sanitizer_common_sources) |common_src| { |
| 188 | var cflags = std.array_list.Managed([]const u8).init(arena); |
| 189 | |
| 190 | try cflags.append("-I"); |
| 191 | try cflags.append(sanitizer_common_include_path); |
| 192 | try cflags.append("-I"); |
| 193 | try cflags.append(tsan_include_path); |
| 194 | |
| 195 | try addCcArgs(target, &cflags); |
| 196 | |
| 197 | c_source_files.appendAssumeCapacity(.{ |
| 198 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 199 | "libtsan", "sanitizer_common", common_src, |
| 200 | }), |
| 201 | .extra_flags = cflags.items, |
| 202 | .owner = root_mod, |
| 203 | }); |
| 204 | } |
| 205 | |
| 206 | const to_c_or_not_to_c_sources = if (comp.config.link_libc) |
| 207 | &sanitizer_libcdep_sources |
| 208 | else |
| 209 | &sanitizer_nolibc_sources; |
| 210 | try c_source_files.ensureUnusedCapacity(to_c_or_not_to_c_sources.len); |
| 211 | for (to_c_or_not_to_c_sources) |c_src| { |
| 212 | var cflags = std.array_list.Managed([]const u8).init(arena); |
| 213 | |
| 214 | try cflags.append("-I"); |
| 215 | try cflags.append(sanitizer_common_include_path); |
| 216 | try cflags.append("-I"); |
| 217 | try cflags.append(tsan_include_path); |
| 218 | |
| 219 | try addCcArgs(target, &cflags); |
| 220 | |
| 221 | c_source_files.appendAssumeCapacity(.{ |
| 222 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 223 | "libtsan", "sanitizer_common", c_src, |
| 224 | }), |
| 225 | .extra_flags = cflags.items, |
| 226 | .owner = root_mod, |
| 227 | }); |
| 228 | } |
| 229 | |
| 230 | try c_source_files.ensureUnusedCapacity(sanitizer_symbolizer_sources.len); |
| 231 | for (sanitizer_symbolizer_sources) |c_src| { |
| 232 | var cflags = std.array_list.Managed([]const u8).init(arena); |
| 233 | |
| 234 | try cflags.append("-I"); |
| 235 | try cflags.append(tsan_include_path); |
| 236 | |
| 237 | try addCcArgs(target, &cflags); |
| 238 | |
| 239 | c_source_files.appendAssumeCapacity(.{ |
| 240 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 241 | "libtsan", "sanitizer_common", c_src, |
| 242 | }), |
| 243 | .extra_flags = cflags.items, |
| 244 | .owner = root_mod, |
| 245 | }); |
| 246 | } |
| 247 | |
| 248 | const interception_include_path = try comp.dirs.zig_lib.join(arena, &.{"interception"}); |
| 249 | |
| 250 | try c_source_files.ensureUnusedCapacity(interception_sources.len); |
| 251 | for (interception_sources) |c_src| { |
| 252 | var cflags = std.array_list.Managed([]const u8).init(arena); |
| 253 | |
| 254 | try cflags.append("-I"); |
| 255 | try cflags.append(interception_include_path); |
| 256 | |
| 257 | try cflags.append("-I"); |
| 258 | try cflags.append(tsan_include_path); |
| 259 | |
| 260 | try addCcArgs(target, &cflags); |
| 261 | |
| 262 | c_source_files.appendAssumeCapacity(.{ |
| 263 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 264 | "libtsan", "interception", c_src, |
| 265 | }), |
| 266 | .extra_flags = cflags.items, |
| 267 | .owner = root_mod, |
| 268 | }); |
| 269 | } |
| 270 | |
| 271 | const skip_linker_dependencies = !target.os.tag.isDarwin(); |
| 272 | const linker_allow_shlib_undefined = target.os.tag.isDarwin(); |
| 273 | const install_name = if (target.os.tag.isDarwin()) |
| 274 | try std.fmt.allocPrintSentinel(arena, "@rpath/{s}", .{basename}, 0) |
| 275 | else |
| 276 | null; |
| 277 | // Workaround for https://github.com/llvm/llvm-project/issues/97627 |
| 278 | const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null; |
| 279 | |
| 280 | const misc_task: Compilation.MiscTask = .libtsan; |
| 281 | |
| 282 | var sub_create_diag: Compilation.CreateDiagnostic = undefined; |
| 283 | const sub_compilation = Compilation.create(comp.gpa, arena, io, &sub_create_diag, .{ |
| 284 | .thread_limit = comp.thread_limit, |
| 285 | .dirs = comp.dirs.withoutLocalCache(), |
| 286 | .self_exe_path = comp.self_exe_path, |
| 287 | .cache_mode = .whole, |
| 288 | .config = config, |
| 289 | .root_mod = root_mod, |
| 290 | .root_name = root_name, |
| 291 | .libc_installation = comp.libc_installation, |
| 292 | .emit_bin = .yes_cache, |
| 293 | .function_sections = true, |
| 294 | .data_sections = true, |
| 295 | .c_source_files = c_source_files.items, |
| 296 | .verbose_cc = comp.verbose_cc, |
| 297 | .verbose_link = comp.verbose_link, |
| 298 | .verbose_air = comp.verbose_air, |
| 299 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 300 | .verbose_llvm_bc = comp.verbose_llvm_bc, |
| 301 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 302 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 303 | .skip_linker_dependencies = skip_linker_dependencies, |
| 304 | .linker_allow_shlib_undefined = linker_allow_shlib_undefined, |
| 305 | .install_name = install_name, |
| 306 | .headerpad_size = headerpad_size, |
| 307 | .environ_map = comp.environ_map, |
| 308 | }) catch |err| { |
| 309 | switch (err) { |
| 310 | else => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {t}", .{ misc_task, err }), |
| 311 | error.CreateFail => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {f}", .{ misc_task, sub_create_diag }), |
| 312 | } |
| 313 | return error.AlreadyReported; |
| 314 | }; |
| 315 | defer sub_compilation.destroy(); |
| 316 | |
| 317 | comp.updateSubCompilation(sub_compilation, misc_task, prog_node) catch |err| switch (err) { |
| 318 | error.AlreadyReported => |e| return e, |
| 319 | else => |e| { |
| 320 | comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: compilation failed: {s}", .{ misc_task, @errorName(e) }); |
| 321 | return error.AlreadyReported; |
| 322 | }, |
| 323 | }; |
| 324 | |
| 325 | // libtsan contains `.preinit_array` entries that must run for correctness, hence `must_link = true`. |
| 326 | const crt_file = try sub_compilation.toCrtFile(); |
| 327 | try comp.queuePrelinkTaskMode(crt_file.full_object_path, true, &config); |
| 328 | assert(comp.tsan_lib == null); |
| 329 | comp.tsan_lib = crt_file; |
| 330 | } |
| 331 | |
| 332 | fn addCcArgs(target: *const std.Target, args: *std.array_list.Managed([]const u8)) error{OutOfMemory}!void { |
| 333 | try args.appendSlice(&[_][]const u8{ |
| 334 | "-nostdinc++", |
| 335 | "-fvisibility=hidden", |
| 336 | "-fvisibility-inlines-hidden", |
| 337 | "-std=c++17", |
| 338 | "-fno-rtti", |
| 339 | "-fno-exceptions", |
| 340 | "-w", // Disable all warnings. |
| 341 | }); |
| 342 | |
| 343 | if (target.abi.isAndroid() and target.os.version_range.linux.android >= 29) { |
| 344 | try args.append("-fno-emulated-tls"); |
| 345 | } |
| 346 | |
| 347 | if (target.isMinGW()) { |
| 348 | try args.append("-fms-extensions"); |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | const tsan_sources = [_][]const u8{ |
| 353 | "tsan_debugging.cpp", |
| 354 | "tsan_external.cpp", |
| 355 | "tsan_fd.cpp", |
| 356 | "tsan_flags.cpp", |
| 357 | "tsan_ignoreset.cpp", |
| 358 | "tsan_interceptors_memintrinsics.cpp", |
| 359 | "tsan_interceptors_posix.cpp", |
| 360 | "tsan_interface.cpp", |
| 361 | "tsan_interface_ann.cpp", |
| 362 | "tsan_interface_atomic.cpp", |
| 363 | "tsan_interface_java.cpp", |
| 364 | "tsan_malloc_mac.cpp", |
| 365 | "tsan_md5.cpp", |
| 366 | "tsan_mman.cpp", |
| 367 | "tsan_mutexset.cpp", |
| 368 | "tsan_new_delete.cpp", |
| 369 | "tsan_platform_windows.cpp", |
| 370 | "tsan_preinit.cpp", |
| 371 | "tsan_report.cpp", |
| 372 | "tsan_rtl.cpp", |
| 373 | "tsan_rtl_access.cpp", |
| 374 | "tsan_rtl_mutex.cpp", |
| 375 | "tsan_rtl_proc.cpp", |
| 376 | "tsan_rtl_report.cpp", |
| 377 | "tsan_rtl_thread.cpp", |
| 378 | "tsan_stack_trace.cpp", |
| 379 | "tsan_suppressions.cpp", |
| 380 | "tsan_symbolize.cpp", |
| 381 | "tsan_sync.cpp", |
| 382 | "tsan_vector_clock.cpp", |
| 383 | }; |
| 384 | |
| 385 | const darwin_tsan_sources = [_][]const u8{ |
| 386 | "tsan_interceptors_mac.cpp", |
| 387 | "tsan_interceptors_mach_vm.cpp", |
| 388 | "tsan_platform_mac.cpp", |
| 389 | "tsan_platform_posix.cpp", |
| 390 | }; |
| 391 | |
| 392 | const unix_tsan_sources = [_][]const u8{ |
| 393 | "tsan_platform_linux.cpp", |
| 394 | "tsan_platform_posix.cpp", |
| 395 | }; |
| 396 | |
| 397 | const windows_tsan_sources = [_][]const u8{ |
| 398 | "tsan_platform_windows.cpp", |
| 399 | }; |
| 400 | |
| 401 | const sanitizer_common_sources = [_][]const u8{ |
| 402 | "sanitizer_allocator.cpp", |
| 403 | "sanitizer_chained_origin_depot.cpp", |
| 404 | "sanitizer_common.cpp", |
| 405 | "sanitizer_deadlock_detector1.cpp", |
| 406 | "sanitizer_deadlock_detector2.cpp", |
| 407 | "sanitizer_errno.cpp", |
| 408 | "sanitizer_file.cpp", |
| 409 | "sanitizer_flag_parser.cpp", |
| 410 | "sanitizer_flags.cpp", |
| 411 | "sanitizer_fuchsia.cpp", |
| 412 | "sanitizer_haiku.cpp", |
| 413 | "sanitizer_libc.cpp", |
| 414 | "sanitizer_libignore.cpp", |
| 415 | "sanitizer_linux.cpp", |
| 416 | "sanitizer_linux_s390.cpp", |
| 417 | "sanitizer_mac.cpp", |
| 418 | "sanitizer_mutex.cpp", |
| 419 | "sanitizer_netbsd.cpp", |
| 420 | "sanitizer_platform_limits_freebsd.cpp", |
| 421 | "sanitizer_platform_limits_linux.cpp", |
| 422 | "sanitizer_platform_limits_netbsd.cpp", |
| 423 | "sanitizer_platform_limits_posix.cpp", |
| 424 | "sanitizer_platform_limits_solaris.cpp", |
| 425 | "sanitizer_posix.cpp", |
| 426 | "sanitizer_printf.cpp", |
| 427 | "sanitizer_procmaps_bsd.cpp", |
| 428 | "sanitizer_procmaps_common.cpp", |
| 429 | "sanitizer_procmaps_fuchsia.cpp", |
| 430 | "sanitizer_procmaps_haiku.cpp", |
| 431 | "sanitizer_procmaps_linux.cpp", |
| 432 | "sanitizer_procmaps_mac.cpp", |
| 433 | "sanitizer_procmaps_solaris.cpp", |
| 434 | "sanitizer_range.cpp", |
| 435 | "sanitizer_solaris.cpp", |
| 436 | "sanitizer_stoptheworld_fuchsia.cpp", |
| 437 | "sanitizer_stoptheworld_mac.cpp", |
| 438 | "sanitizer_stoptheworld_win.cpp", |
| 439 | "sanitizer_suppressions.cpp", |
| 440 | "sanitizer_termination.cpp", |
| 441 | "sanitizer_thread_arg_retval.cpp", |
| 442 | "sanitizer_thread_registry.cpp", |
| 443 | "sanitizer_tls_get_addr.cpp", |
| 444 | "sanitizer_type_traits.cpp", |
| 445 | "sanitizer_win.cpp", |
| 446 | "sanitizer_win_interception.cpp", |
| 447 | }; |
| 448 | |
| 449 | const sanitizer_nolibc_sources = [_][]const u8{ |
| 450 | "sanitizer_common_nolibc.cpp", |
| 451 | }; |
| 452 | |
| 453 | const sanitizer_libcdep_sources = [_][]const u8{ |
| 454 | "sanitizer_common_libcdep.cpp", |
| 455 | "sanitizer_allocator_checks.cpp", |
| 456 | "sanitizer_dl.cpp", |
| 457 | "sanitizer_linux_libcdep.cpp", |
| 458 | "sanitizer_mac_libcdep.cpp", |
| 459 | "sanitizer_posix_libcdep.cpp", |
| 460 | "sanitizer_stoptheworld_linux_libcdep.cpp", |
| 461 | "sanitizer_stoptheworld_netbsd_libcdep.cpp", |
| 462 | }; |
| 463 | |
| 464 | const sanitizer_symbolizer_sources = [_][]const u8{ |
| 465 | "sanitizer_allocator_report.cpp", |
| 466 | "sanitizer_stack_store.cpp", |
| 467 | "sanitizer_stackdepot.cpp", |
| 468 | "sanitizer_stacktrace.cpp", |
| 469 | "sanitizer_stacktrace_libcdep.cpp", |
| 470 | "sanitizer_stacktrace_printer.cpp", |
| 471 | "sanitizer_stacktrace_sparc.cpp", |
| 472 | "sanitizer_symbolizer.cpp", |
| 473 | "sanitizer_symbolizer_libbacktrace.cpp", |
| 474 | "sanitizer_symbolizer_libcdep.cpp", |
| 475 | "sanitizer_symbolizer_mac.cpp", |
| 476 | "sanitizer_symbolizer_markup.cpp", |
| 477 | "sanitizer_symbolizer_markup_fuchsia.cpp", |
| 478 | "sanitizer_symbolizer_posix_libcdep.cpp", |
| 479 | "sanitizer_symbolizer_report.cpp", |
| 480 | "sanitizer_symbolizer_report_fuchsia.cpp", |
| 481 | "sanitizer_symbolizer_win.cpp", |
| 482 | "sanitizer_thread_history.cpp", |
| 483 | "sanitizer_unwind_linux_libcdep.cpp", |
| 484 | "sanitizer_unwind_fuchsia.cpp", |
| 485 | "sanitizer_unwind_win.cpp", |
| 486 | }; |
| 487 | |
| 488 | const interception_sources = [_][]const u8{ |
| 489 | "interception_linux.cpp", |
| 490 | "interception_mac.cpp", |
| 491 | "interception_win.cpp", |
| 492 | "interception_type_test.cpp", |
| 493 | }; |