@@ -4,6 +4,7 @@ const builtin = @import("builtin");
44const std = @import ("std" );
55const testing = std .testing ;
66const assert = std .debug .assert ;
7+ const fuzz_abi = std .Build .abi .fuzz ;
78
89pub const std_options : std.Options = .{
910 .logFn = log ,
@@ -57,7 +58,7 @@ pub fn main() void {
5758 fba .reset ();
5859 if (builtin .fuzz ) {
5960 const cache_dir = opt_cache_dir orelse @panic ("missing --cache-dir=[path] argument" );
60- fuzzer_init (FuzzerSlice .fromSlice (cache_dir ));
61+ fuzz_abi . fuzzer_init (.fromSlice (cache_dir ));
6162 }
6263
6364 if (listen ) {
@@ -78,7 +79,7 @@ fn mainServer() !void {
7879 });
7980
8081 if (builtin .fuzz ) {
81- const coverage_id = fuzzer_coverage_id ();
82+ const coverage_id = fuzz_abi . fuzzer_coverage_id ();
8283 try server .serveU64Message (.coverage_id , coverage_id );
8384 }
8485
@@ -152,14 +153,19 @@ fn mainServer() !void {
152153 });
153154 },
154155 .start_fuzzing = > {
156+ // This ensures that this code won't be analyzed and hence reference fuzzer symbols
157+ // since they are not present.
155158 if (! builtin .fuzz ) unreachable ;
159+
156160 const index = try server .receiveBody_u32 ();
157161 const test_fn = builtin .test_functions [index ];
158162 const entry_addr = @intFromPtr (test_fn .func );
163+
159164 try server .serveU64Message (.fuzz_start_addr , entry_addr );
160165 defer if (testing .allocator_instance .deinit () == .leak ) std .process .exit (1 );
161166 is_fuzz_test = false ;
162- fuzzer_set_name (test_fn .name .ptr , test_fn .name .len );
167+ fuzz_test_index = index ;
168+
163169 test_fn .func () catch | err | switch (err ) {
164170 error .SkipZigTest = > return ,
165171 else = > {
@@ -184,6 +190,8 @@ fn mainServer() !void {
184190
185191fn mainTerminal () void {
186192 @disableInstrumentation ();
193+ if (builtin .fuzz ) @panic ("fuzz test requires server" );
194+
187195 const test_fn_list = builtin .test_functions ;
188196 var ok_count : usize = 0 ;
189197 var skip_count : usize = 0 ;
@@ -333,28 +341,8 @@ pub fn mainSimple() anyerror!void {
333341 if (failed != 0 ) std .process .exit (1 );
334342}
335343
336- const FuzzerSlice = extern struct {
337- ptr : [* ]const u8 ,
338- len : usize ,
339-
340- /// Inline to avoid fuzzer instrumentation.
341- inline fn toSlice (s : FuzzerSlice ) []const u8 {
342- return s .ptr [0.. s .len ];
343- }
344-
345- /// Inline to avoid fuzzer instrumentation.
346- inline fn fromSlice (s : []const u8 ) FuzzerSlice {
347- return .{ .ptr = s .ptr , .len = s .len };
348- }
349- };
350-
351344var is_fuzz_test : bool = undefined ;
352-
353- extern fn fuzzer_set_name (name_ptr : [* ]const u8 , name_len : usize ) void ;
354- extern fn fuzzer_init (cache_dir : FuzzerSlice ) void ;
355- extern fn fuzzer_init_corpus_elem (input_ptr : [* ]const u8 , input_len : usize ) void ;
356- extern fn fuzzer_start (testOne : * const fn ([* ]const u8 , usize ) callconv (.c ) void ) void ;
357- extern fn fuzzer_coverage_id () u64 ;
345+ var fuzz_test_index : u32 = undefined ;
358346
359347pub fn fuzz (
360348 context : anytype ,
@@ -385,12 +373,12 @@ pub fn fuzz(
385373 const global = struct {
386374 var ctx : @TypeOf (context ) = undefined ;
387375
388- fn fuzzer_one ( input_ptr : [ * ] const u8 , input_len : usize ) callconv (.c ) void {
376+ fn test_one ( input : fuzz_abi.Slice ) callconv (.c ) void {
389377 @disableInstrumentation ();
390378 testing .allocator_instance = .{};
391379 defer if (testing .allocator_instance .deinit () == .leak ) std .process .exit (1 );
392380 log_err_count = 0 ;
393- testOne (ctx , input_ptr [0 .. input_len ] ) catch | err | switch (err ) {
381+ testOne (ctx , input . toSlice () ) catch | err | switch (err ) {
394382 error .SkipZigTest = > return ,
395383 else = > {
396384 std .debug .lockStdErr ();
@@ -411,10 +399,11 @@ pub fn fuzz(
411399 testing .allocator_instance = .{};
412400 defer testing .allocator_instance = prev_allocator_state ;
413401
414- for (options .corpus ) | elem | fuzzer_init_corpus_elem (elem .ptr , elem .len );
415-
416402 global .ctx = context ;
417- fuzzer_start (& global .fuzzer_one );
403+ fuzz_abi .fuzzer_init_test (& global .test_one , .fromSlice (builtin .test_functions [fuzz_test_index ].name ));
404+ for (options .corpus ) | elem |
405+ fuzz_abi .fuzzer_new_input (.fromSlice (elem ));
406+ fuzz_abi .fuzzer_main ();
418407 return ;
419408 }
420409
0 commit comments