1const std = @import("std");
2const assert = std.debug.assert;
3const abi = std.Build.abi.fuzz;
4const native_endian = @import("builtin").cpu.arch.endian();
5
6fn testOne() callconv(.c) bool {
7 return false;
8}
9
10export fn runner_test_run(i: u32) void {
11 assert(i == 0);
12 abi.fuzzer_set_test(testOne);
13 abi.fuzzer_new_input(.fromSlice(""));
14 abi.fuzzer_new_input(.fromSlice("hello"));
15 abi.fuzzer_start_test();
16}
17
18export fn runner_test_name(i: u32) abi.Slice {
19 assert(i == 0);
20 return .fromSlice("test");
21}
22
23export fn runner_start_input_poller() void {}
24export fn runner_stop_input_poller() void {}
25
26export fn runner_futex_wait(ptr: *const u32, expected: u32) bool {
27 assert(ptr.* == expected); // single-threaded
28 return false;
29}
30
31export fn runner_futex_wake(ptr: *const u32, waiters: u32) void {
32 _ = ptr;
33 _ = waiters;
34}
35
36export fn runner_broadcast_input(test_i: u32, bytes: abi.Slice) void {
37 _ = test_i;
38 _ = bytes;
39}
40
41pub fn main(init: std.process.Init) !void {
42 const gpa = init.gpa;
43 const io = init.io;
44
45 var args = try init.minimal.args.iterateAllocator(gpa);
46 defer args.deinit();
47 _ = args.skip(); // executable name
48
49 const cache_dir_path = args.next() orelse @panic("expected cache directory path argument");
50 var cache_dir = try std.Io.Dir.cwd().openDir(io, cache_dir_path, .{});
51 defer cache_dir.close(io);
52
53 abi.fuzzer_init(.fromSlice(cache_dir_path));
54 abi.fuzzer_main(1, 0, .iterations, 100);
55
56 const pc_digest = abi.fuzzer_coverage().id;
57 const coverage_file_path = "v/" ++ std.fmt.hex(pc_digest);
58 const coverage_file = try cache_dir.openFile(io, coverage_file_path, .{});
59 defer coverage_file.close(io);
60
61 var read_buf: [@sizeOf(abi.SeenPcsHeader)]u8 = undefined;
62 var r = coverage_file.reader(io, &read_buf);
63 const pcs_header = r.interface.takeStruct(abi.SeenPcsHeader, native_endian) catch return r.err.?;
64
65 if (pcs_header.pcs_len == 0)
66 return error.ZeroPcs;
67 const expected_len = @sizeOf(abi.SeenPcsHeader) +
68 try std.math.divCeil(usize, pcs_header.pcs_len, @bitSizeOf(usize)) * @sizeOf(usize) +
69 pcs_header.pcs_len * @sizeOf(usize);
70 if (try coverage_file.length(io) != expected_len)
71 return error.WrongEnd;
72}