authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-23 17:30:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-23 17:30:53-07:00
log26d2a7960e9199989d9387e0af29497581422f93
tree232000f18467d891a23c70b8e2b3ca48e9d62c8c
parent33d47424562672834ff758770b7ce89c637d4a1d

default "trace pc guard" coverage off

* Add -f(no-)sanitize-coverage-trace-pc-guard CLI flag which defaults to off. This value lowers to TracePCGuard = true (LLVM backend) and -Xclang -fsanitize-coverage-trace-pc-guard. These settings are not automatically included with -ffuzz. * Add `Build.Step.Compile` flag for sanitize_coverage_trace_pc_guard with appropriate documentation. * Add `zig cc` integration for the respective flags. * Avoid crashing in ELF linker code when -ffuzz -femit-llvm-ir used together.

8 files changed, 69 insertions(+), 9 deletions(-)

lib/std/Build/Step/Compile.zig+9
...@@ -217,6 +217,14 @@ no_builtin: bool = false,...@@ -217,6 +217,14 @@ no_builtin: bool = false,
217/// Managed by the build runner, not user build script.217/// Managed by the build runner, not user build script.
218zig_process: ?*Step.ZigProcess,218zig_process: ?*Step.ZigProcess,
219219
220/// Enables deprecated coverage instrumentation that is only useful if you
221/// are using third party fuzzers that depend on it. Otherwise, slows down
222/// the instrumented binary with unnecessary function calls.
223///
224/// To enable fuzz testing instrumentation on a compilation, see the `fuzz`
225/// flag in `Module`.
226sanitize_coverage_trace_pc_guard: ?bool = null,
227
220pub const ExpectedCompileErrors = union(enum) {228pub const ExpectedCompileErrors = union(enum) {
221 contains: []const u8,229 contains: []const u8,
222 exact: []const []const u8,230 exact: []const []const u8,
...@@ -1656,6 +1664,7 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {...@@ -1656,6 +1664,7 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
16561664
1657 try addFlag(&zig_args, "PIE", compile.pie);1665 try addFlag(&zig_args, "PIE", compile.pie);
1658 try addFlag(&zig_args, "lto", compile.want_lto);1666 try addFlag(&zig_args, "lto", compile.want_lto);
1667 try addFlag(&zig_args, "sanitize-coverage-trace-pc-guard", compile.sanitize_coverage_trace_pc_guard);
16591668
1660 if (compile.subsystem) |subsystem| {1669 if (compile.subsystem) |subsystem| {
1661 try zig_args.append("--subsystem");1670 try zig_args.append("--subsystem");
src/Compilation.zig+2-1
...@@ -1412,6 +1412,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1412,6 +1412,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1412 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_docs);1412 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_docs);
1413 cache.hash.addBytes(options.root_name);1413 cache.hash.addBytes(options.root_name);
1414 cache.hash.add(options.config.wasi_exec_model);1414 cache.hash.add(options.config.wasi_exec_model);
1415 cache.hash.add(options.config.san_cov_trace_pc_guard);
1415 // TODO audit this and make sure everything is in it1416 // TODO audit this and make sure everything is in it
14161417
1417 const main_mod = options.main_mod orelse options.root_mod;1418 const main_mod = options.main_mod orelse options.root_mod;
...@@ -5653,7 +5654,7 @@ pub fn addCCArgs(...@@ -5653,7 +5654,7 @@ pub fn addCCArgs(
5653 try argv.append("-fno-sanitize=function");5654 try argv.append("-fno-sanitize=function");
5654 }5655 }
56555656
5656 if (mod.fuzz) {5657 if (comp.config.san_cov_trace_pc_guard) {
5657 try argv.appendSlice(&.{ "-Xclang", "-fsanitize-coverage-trace-pc-guard" });5658 try argv.appendSlice(&.{ "-Xclang", "-fsanitize-coverage-trace-pc-guard" });
5658 }5659 }
5659 }5660 }
src/Compilation/Config.zig+3
...@@ -60,6 +60,7 @@ root_strip: bool,...@@ -60,6 +60,7 @@ root_strip: bool,
60root_error_tracing: bool,60root_error_tracing: bool,
61dll_export_fns: bool,61dll_export_fns: bool,
62rdynamic: bool,62rdynamic: bool,
63san_cov_trace_pc_guard: bool,
6364
64pub const CFrontend = enum { clang, aro };65pub const CFrontend = enum { clang, aro };
6566
...@@ -108,6 +109,7 @@ pub const Options = struct {...@@ -108,6 +109,7 @@ pub const Options = struct {
108 debug_format: ?DebugFormat = null,109 debug_format: ?DebugFormat = null,
109 dll_export_fns: ?bool = null,110 dll_export_fns: ?bool = null,
110 rdynamic: ?bool = null,111 rdynamic: ?bool = null,
112 san_cov_trace_pc_guard: bool = false,
111};113};
112114
113pub const ResolveError = error{115pub const ResolveError = error{
...@@ -489,6 +491,7 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -489,6 +491,7 @@ pub fn resolve(options: Options) ResolveError!Config {
489 .any_error_tracing = any_error_tracing,491 .any_error_tracing = any_error_tracing,
490 .any_sanitize_thread = options.any_sanitize_thread,492 .any_sanitize_thread = options.any_sanitize_thread,
491 .any_fuzz = options.any_fuzz,493 .any_fuzz = options.any_fuzz,
494 .san_cov_trace_pc_guard = options.san_cov_trace_pc_guard,
492 .root_error_tracing = root_error_tracing,495 .root_error_tracing = root_error_tracing,
493 .pie = pie,496 .pie = pie,
494 .lto = lto,497 .lto = lto,
src/clang_options_data.zig+10-3
...@@ -3825,7 +3825,14 @@ flagpd1("fsanitize-coverage-trace-div"),...@@ -3825,7 +3825,14 @@ flagpd1("fsanitize-coverage-trace-div"),
3825flagpd1("fsanitize-coverage-trace-gep"),3825flagpd1("fsanitize-coverage-trace-gep"),
3826flagpd1("fsanitize-coverage-trace-loads"),3826flagpd1("fsanitize-coverage-trace-loads"),
3827flagpd1("fsanitize-coverage-trace-pc"),3827flagpd1("fsanitize-coverage-trace-pc"),
3828flagpd1("fsanitize-coverage-trace-pc-guard"),3828.{
3829 .name = "fsanitize-coverage-trace-pc-guard",
3830 .syntax = .flag,
3831 .zig_equivalent = .san_cov_trace_pc_guard,
3832 .pd1 = true,
3833 .pd2 = false,
3834 .psl = false,
3835},
3829flagpd1("fsanitize-coverage-trace-stores"),3836flagpd1("fsanitize-coverage-trace-stores"),
3830flagpd1("fsanitize-hwaddress-experimental-aliasing"),3837flagpd1("fsanitize-hwaddress-experimental-aliasing"),
3831flagpd1("fsanitize-link-c++-runtime"),3838flagpd1("fsanitize-link-c++-runtime"),
...@@ -6012,7 +6019,7 @@ joinpd1("fmodules-ignore-macro="),...@@ -6012,7 +6019,7 @@ joinpd1("fmodules-ignore-macro="),
6012.{6019.{
6013 .name = "fno-sanitize-coverage=",6020 .name = "fno-sanitize-coverage=",
6014 .syntax = .comma_joined,6021 .syntax = .comma_joined,
6015 .zig_equivalent = .other,6022 .zig_equivalent = .no_san_cov,
6016 .pd1 = true,6023 .pd1 = true,
6017 .pd2 = false,6024 .pd2 = false,
6018 .psl = false,6025 .psl = false,
...@@ -6149,7 +6156,7 @@ joinpd1("fprofile-instr-use="),...@@ -6149,7 +6156,7 @@ joinpd1("fprofile-instr-use="),
6149.{6156.{
6150 .name = "fsanitize-coverage=",6157 .name = "fsanitize-coverage=",
6151 .syntax = .comma_joined,6158 .syntax = .comma_joined,
6152 .zig_equivalent = .other,6159 .zig_equivalent = .san_cov,
6153 .pd1 = true,6160 .pd1 = true,
6154 .pd2 = false,6161 .pd2 = false,
6155 .psl = false,6162 .psl = false,
src/codegen/llvm.zig+1-1
...@@ -1298,7 +1298,7 @@ pub const Object = struct {...@@ -1298,7 +1298,7 @@ pub const Object = struct {
1298 .TraceGep = false,1298 .TraceGep = false,
1299 .Use8bitCounters = false,1299 .Use8bitCounters = false,
1300 .TracePC = false,1300 .TracePC = false,
1301 .TracePCGuard = true,1301 .TracePCGuard = comp.config.san_cov_trace_pc_guard,
1302 .Inline8bitCounters = true,1302 .Inline8bitCounters = true,
1303 .InlineBoolFlag = false,1303 .InlineBoolFlag = false,
1304 .PCTable = true,1304 .PCTable = true,
src/link/Elf.zig+6-4
...@@ -2673,12 +2673,14 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s...@@ -2673,12 +2673,14 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
2673 try argv.append(p);2673 try argv.append(p);
2674 }2674 }
26752675
2676 if (comp.config.any_sanitize_thread) {2676 if (comp.tsan_lib) |lib| {
2677 try argv.append(comp.tsan_lib.?.full_object_path);2677 assert(comp.config.any_sanitize_thread);
2678 try argv.append(lib.full_object_path);
2678 }2679 }
26792680
2680 if (comp.config.any_fuzz) {2681 if (comp.fuzzer_lib) |lib| {
2681 try argv.append(comp.fuzzer_lib.?.full_object_path);2682 assert(comp.config.any_fuzz);
2683 try argv.append(lib.full_object_path);
2682 }2684 }
26832685
2684 // libc2686 // libc
src/main.zig+26
...@@ -1454,6 +1454,10 @@ fn buildOutputType(...@@ -1454,6 +1454,10 @@ fn buildOutputType(
1454 create_module.opts.use_clang = true;1454 create_module.opts.use_clang = true;
1455 } else if (mem.eql(u8, arg, "-fno-clang")) {1455 } else if (mem.eql(u8, arg, "-fno-clang")) {
1456 create_module.opts.use_clang = false;1456 create_module.opts.use_clang = false;
1457 } else if (mem.eql(u8, arg, "-fsanitize-coverage-trace-pc-guard")) {
1458 create_module.opts.san_cov_trace_pc_guard = true;
1459 } else if (mem.eql(u8, arg, "-fno-sanitize-coverage-trace-pc-guard")) {
1460 create_module.opts.san_cov_trace_pc_guard = false;
1457 } else if (mem.eql(u8, arg, "-freference-trace")) {1461 } else if (mem.eql(u8, arg, "-freference-trace")) {
1458 reference_trace = 256;1462 reference_trace = 256;
1459 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {1463 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
...@@ -2025,6 +2029,25 @@ fn buildOutputType(...@@ -2025,6 +2029,25 @@ fn buildOutputType(
2025 }2029 }
2026 }2030 }
2027 },2031 },
2032 .san_cov_trace_pc_guard => create_module.opts.san_cov_trace_pc_guard = true,
2033 .san_cov => {
2034 var split_it = mem.splitScalar(u8, it.only_arg, ',');
2035 while (split_it.next()) |san_arg| {
2036 if (std.mem.eql(u8, san_arg, "trace-pc-guard")) {
2037 create_module.opts.san_cov_trace_pc_guard = true;
2038 }
2039 }
2040 try cc_argv.appendSlice(arena, it.other_args);
2041 },
2042 .no_san_cov => {
2043 var split_it = mem.splitScalar(u8, it.only_arg, ',');
2044 while (split_it.next()) |san_arg| {
2045 if (std.mem.eql(u8, san_arg, "trace-pc-guard")) {
2046 create_module.opts.san_cov_trace_pc_guard = false;
2047 }
2048 }
2049 try cc_argv.appendSlice(arena, it.other_args);
2050 },
2028 .optimize => {2051 .optimize => {
2029 // Alright, what release mode do they want?2052 // Alright, what release mode do they want?
2030 const level = if (it.only_arg.len >= 1 and it.only_arg[0] == 'O') it.only_arg[1..] else it.only_arg;2053 const level = if (it.only_arg.len >= 1 and it.only_arg[0] == 'O') it.only_arg[1..] else it.only_arg;
...@@ -5803,6 +5826,9 @@ pub const ClangArgIterator = struct {...@@ -5803,6 +5826,9 @@ pub const ClangArgIterator = struct {
5803 undefined,5826 undefined,
5804 force_load_objc,5827 force_load_objc,
5805 mingw_unicode_entry_point,5828 mingw_unicode_entry_point,
5829 san_cov_trace_pc_guard,
5830 san_cov,
5831 no_san_cov,
5806 };5832 };
58075833
5808 const Args = struct {5834 const Args = struct {
tools/update_clang_options.zig+12
...@@ -536,6 +536,18 @@ const known_options = [_]KnownOpt{...@@ -536,6 +536,18 @@ const known_options = [_]KnownOpt{
536 .name = "municode",536 .name = "municode",
537 .ident = "mingw_unicode_entry_point",537 .ident = "mingw_unicode_entry_point",
538 },538 },
539 .{
540 .name = "fsanitize-coverage-trace-pc-guard",
541 .ident = "san_cov_trace_pc_guard",
542 },
543 .{
544 .name = "fsanitize-coverage",
545 .ident = "san_cov",
546 },
547 .{
548 .name = "fno-sanitize-coverage",
549 .ident = "no_san_cov",
550 },
539};551};
540552
541const blacklisted_options = [_][]const u8{};553const blacklisted_options = [_][]const u8{};