diff options
| author | Matthew Lugg <mlugg@mlugg.co.uk> | 2025-11-20 17:48:35 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-20 17:48:35 +0000 |
| commit | 8a73fc8d8ee0065e4d07e473ce6ab095cebfaece (patch) | |
| tree | 36bed2955666bdfce7b96e2f33c9409bd26f03c1 /lib/std/Build | |
| parent | a9568ed2963298864e5c9a92a3eafe81771128ff (diff) | |
| parent | a87b5332319b20347916f77e57253e2df4b2a3af (diff) | |
| download | zig-8a73fc8d8ee0065e4d07e473ce6ab095cebfaece.tar.gz zig-8a73fc8d8ee0065e4d07e473ce6ab095cebfaece.zip | |
Merge pull request #25981 from mlugg/macos-fuzz-2
make the fuzzer vaguely work on macOS
Diffstat (limited to 'lib/std/Build')
| -rw-r--r-- | lib/std/Build/Fuzz.zig | 29 | ||||
| -rw-r--r-- | lib/std/Build/Step/CheckObject.zig | 29 | ||||
| -rw-r--r-- | lib/std/Build/Step/Compile.zig | 5 | ||||
| -rw-r--r-- | lib/std/Build/Step/Run.zig | 13 | ||||
| -rw-r--r-- | lib/std/Build/abi.zig | 1 |
5 files changed, 56 insertions, 21 deletions
diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig index 6dd4f70f9f..7a22522d6b 100644 --- a/lib/std/Build/Fuzz.zig +++ b/lib/std/Build/Fuzz.zig @@ -383,7 +383,14 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO errdefer gop.value_ptr.coverage.deinit(fuzz.gpa); const rebuilt_exe_path = run_step.rebuilt_executable.?; - var debug_info = std.debug.Info.load(fuzz.gpa, rebuilt_exe_path, &gop.value_ptr.coverage) catch |err| { + const target = run_step.producer.?.rootModuleTarget(); + var debug_info = std.debug.Info.load( + fuzz.gpa, + rebuilt_exe_path, + &gop.value_ptr.coverage, + target.ofmt, + target.cpu.arch, + ) catch |err| { log.err("step '{s}': failed to load debug information for '{f}': {s}", .{ run_step.step.name, rebuilt_exe_path, @errorName(err), }); @@ -479,9 +486,23 @@ fn addEntryPoint(fuzz: *Fuzz, coverage_id: u64, addr: u64) error{ AlreadyReporte if (false) { const sl = coverage_map.source_locations[index]; const file_name = coverage_map.coverage.stringAt(coverage_map.coverage.fileAt(sl.file).basename); - log.debug("server found entry point for 0x{x} at {s}:{d}:{d} - index {d} between {x} and {x}", .{ - addr, file_name, sl.line, sl.column, index, pcs[index - 1], pcs[index + 1], - }); + if (pcs.len == 1) { + log.debug("server found entry point for 0x{x} at {s}:{d}:{d} - index 0 (final)", .{ + addr, file_name, sl.line, sl.column, + }); + } else if (index == 0) { + log.debug("server found entry point for 0x{x} at {s}:{d}:{d} - index 0 before {x}", .{ + addr, file_name, sl.line, sl.column, pcs[index + 1], + }); + } else if (index == pcs.len - 1) { + log.debug("server found entry point for 0x{x} at {s}:{d}:{d} - index {d} (final) after {x}", .{ + addr, file_name, sl.line, sl.column, index, pcs[index - 1], + }); + } else { + log.debug("server found entry point for 0x{x} at {s}:{d}:{d} - index {d} between {x} and {x}", .{ + addr, file_name, sl.line, sl.column, index, pcs[index - 1], pcs[index + 1], + }); + } } try coverage_map.entry_points.append(fuzz.gpa, @intCast(index)); } diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index d9935d4f3d..ab10d368b2 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -729,10 +729,10 @@ const MachODumper = struct { imports: std.ArrayListUnmanaged([]const u8) = .empty, fn parse(ctx: *ObjectContext) !void { - var it = ctx.getLoadCommandIterator(); + var it = try ctx.getLoadCommandIterator(); var i: usize = 0; - while (it.next()) |cmd| { - switch (cmd.cmd()) { + while (try it.next()) |cmd| { + switch (cmd.hdr.cmd) { .SEGMENT_64 => { const seg = cmd.cast(macho.segment_command_64).?; try ctx.segments.append(ctx.gpa, seg); @@ -771,14 +771,13 @@ const MachODumper = struct { return mem.sliceTo(@as([*:0]const u8, @ptrCast(ctx.strtab.items.ptr + off)), 0); } - fn getLoadCommandIterator(ctx: ObjectContext) macho.LoadCommandIterator { - const data = ctx.data[@sizeOf(macho.mach_header_64)..][0..ctx.header.sizeofcmds]; - return .{ .ncmds = ctx.header.ncmds, .buffer = data }; + fn getLoadCommandIterator(ctx: ObjectContext) !macho.LoadCommandIterator { + return .init(&ctx.header, ctx.data[@sizeOf(macho.mach_header_64)..]); } - fn getLoadCommand(ctx: ObjectContext, cmd: macho.LC) ?macho.LoadCommandIterator.LoadCommand { - var it = ctx.getLoadCommandIterator(); - while (it.next()) |lc| if (lc.cmd() == cmd) { + fn getLoadCommand(ctx: ObjectContext, cmd: macho.LC) !?macho.LoadCommandIterator.LoadCommand { + var it = try ctx.getLoadCommandIterator(); + while (try it.next()) |lc| if (lc.hdr.cmd == cmd) { return lc; }; return null; @@ -872,9 +871,9 @@ const MachODumper = struct { \\LC {d} \\cmd {s} \\cmdsize {d} - , .{ index, @tagName(lc.cmd()), lc.cmdsize() }); + , .{ index, @tagName(lc.hdr.cmd), lc.hdr.cmdsize }); - switch (lc.cmd()) { + switch (lc.hdr.cmd) { .SEGMENT_64 => { const seg = lc.cast(macho.segment_command_64).?; try writer.writeByte('\n'); @@ -1592,9 +1591,9 @@ const MachODumper = struct { .headers => { try ObjectContext.dumpHeader(ctx.header, writer); - var it = ctx.getLoadCommandIterator(); + var it = try ctx.getLoadCommandIterator(); var i: usize = 0; - while (it.next()) |cmd| { + while (try it.next()) |cmd| { try ObjectContext.dumpLoadCommand(cmd, i, writer); try writer.writeByte('\n'); @@ -1615,7 +1614,7 @@ const MachODumper = struct { .dyld_weak_bind, .dyld_lazy_bind, => { - const cmd = ctx.getLoadCommand(.DYLD_INFO_ONLY) orelse + const cmd = try ctx.getLoadCommand(.DYLD_INFO_ONLY) orelse return step.fail("no dyld info found", .{}); const lc = cmd.cast(macho.dyld_info_command).?; @@ -1649,7 +1648,7 @@ const MachODumper = struct { }, .exports => blk: { - if (ctx.getLoadCommand(.DYLD_INFO_ONLY)) |cmd| { + if (try ctx.getLoadCommand(.DYLD_INFO_ONLY)) |cmd| { const lc = cmd.cast(macho.dyld_info_command).?; if (lc.export_size > 0) { const data = ctx.data[lc.export_off..][0..lc.export_size]; diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 7dd9c17273..4ea09538c2 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -1932,6 +1932,11 @@ pub fn rebuildInFuzzMode(c: *Compile, gpa: Allocator, progress_node: std.Progres c.step.result_error_bundle.deinit(gpa); c.step.result_error_bundle = std.zig.ErrorBundle.empty; + if (c.step.result_failed_command) |cmd| { + gpa.free(cmd); + c.step.result_failed_command = null; + } + const zig_args = try getZigArgs(c, true); const maybe_output_bin_path = try c.step.evalZigProcess(zig_args, progress_node, false, null, gpa); return maybe_output_bin_path.?; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 52a690ef94..dfae77ffb5 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1140,6 +1140,12 @@ pub fn rerunInFuzzMode( .output_file, .output_directory => unreachable, } } + + if (run.step.result_failed_command) |cmd| { + fuzz.gpa.free(cmd); + run.step.result_failed_command = null; + } + const has_side_effects = false; const rand_int = std.crypto.random.int(u64); const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); @@ -1150,7 +1156,7 @@ pub fn rerunInFuzzMode( .web_server = null, // only needed for time reports .ttyconf = fuzz.ttyconf, .unit_test_timeout_ns = null, // don't time out fuzz tests for now - .gpa = undefined, // not used by `runCommand` + .gpa = fuzz.gpa, }, .{ .unit_test_index = unit_test_index, .fuzz = fuzz, @@ -1870,7 +1876,10 @@ fn pollZigTest( // test. For instance, if the test runner leaves this much time between us requesting a test to // start and it acknowledging the test starting, we terminate the child and raise an error. This // *should* never happen, but could in theory be caused by some very unlucky IB in a test. - const response_timeout_ns = @max(options.unit_test_timeout_ns orelse 0, 60 * std.time.ns_per_s); + const response_timeout_ns: ?u64 = ns: { + if (fuzz_context != null) break :ns null; // don't timeout fuzz tests + break :ns @max(options.unit_test_timeout_ns orelse 0, 60 * std.time.ns_per_s); + }; const stdout = poller.reader(.stdout); const stderr = poller.reader(.stderr); diff --git a/lib/std/Build/abi.zig b/lib/std/Build/abi.zig index eb8f6cb1be..b7c1e7379d 100644 --- a/lib/std/Build/abi.zig +++ b/lib/std/Build/abi.zig @@ -145,6 +145,7 @@ pub const fuzz = struct { pub extern fn fuzzer_init_test(test_one: TestOne, unit_test_name: Slice) void; pub extern fn fuzzer_new_input(bytes: Slice) void; pub extern fn fuzzer_main(limit_kind: LimitKind, amount: u64) void; + pub extern fn fuzzer_unslide_address(addr: usize) usize; pub const Slice = extern struct { ptr: [*]const u8, |
