diff --git a/nix/devShell.nix b/nix/devShell.nix index df08fc204..d1df9fefa 100644 --- a/nix/devShell.nix +++ b/nix/devShell.nix @@ -227,8 +227,22 @@ in unset SDKROOT unset DEVELOPER_DIR + # AFL++ needs to use the Homebrew/system Apple toolchain directly. + # The Nix compiler wrapper variables leak a Nix linker into afl-cc, + # which breaks even trivial fuzz harness links on macOS. + unset NIX_CC + unset NIX_CFLAGS_COMPILE + unset NIX_LDFLAGS + unset LD + unset CC + unset CXX + unset CFLAGS + unset CPPFLAGS + unset LDFLAGS + # We need to remove "xcrun" from the PATH. It is injected by # some dependency but we need to rely on system Xcode tools export PATH=$(echo "$PATH" | awk -v RS=: -v ORS=: '$0 !~ /xcrun/ || $0 == "/usr/bin" {print}' | sed 's/:$//') + export PATH="/opt/homebrew/opt/llvm/bin:/opt/homebrew/bin:/usr/local/opt/llvm/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH" ''); } diff --git a/pkg/afl++/build.zig b/pkg/afl++/build.zig index 9de3ad01e..9f6f70e96 100644 --- a/pkg/afl++/build.zig +++ b/pkg/afl++/build.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); /// Creates a build step that produces an AFL++-instrumented fuzzing /// executable. @@ -23,6 +24,12 @@ pub fn addInstrumentedExe( @panic("Could not find 'afl-cc', which is required to build"), "-O3", }); + if (builtin.target.os.tag.isDarwin()) { + // Apple's newer ld asserts on the custom section names emitted by + // AFL's LLVM instrumentation when linking our Zig-produced bitcode. + // lld links the same inputs without issue. + afl_cc.addArg("-fuse-ld=lld"); + } afl_cc.addArg("-o"); const fuzz_exe = afl_cc.addOutputFileArg(obj.name); afl_cc.addFileArg(pkg.path("afl.c")); diff --git a/test/fuzz-libghostty/build.zig b/test/fuzz-libghostty/build.zig index ec73c39c9..88d748a68 100644 --- a/test/fuzz-libghostty/build.zig +++ b/test/fuzz-libghostty/build.zig @@ -23,7 +23,10 @@ const fuzzers: []const Fuzzer = &.{ }; pub fn build(b: *std.Build) void { - const target = b.standardTargetOptions(.{}); + // Resolve a "generic" host target so the emitted LLVM bitcode does not + // contain native CPU features (e.g. +zcm, +zcz) that the LLVM version + // bundled with afl-cc may not recognise, which would produce warnings. + const target = b.resolveTargetQuery(.{}); const optimize = b.standardOptimizeOption(.{}); const ghostty_dep = b.lazyDependency("ghostty", .{