Author: george.karpenkov Date: Mon Apr 24 13:23:24 2017 New Revision: 301212
URL: http://llvm.org/viewvc/llvm-project?rev=301212&view=rev Log: Flag -fsanitize=fuzzer to enable libfuzzer Previously, adding libfuzzer to a project was a multi-step procedure, involving libfuzzer compilation, linking the library, and specifying coverage flags. With this change,libfuzzer can be enabled by adding a single -fsanitize=fuzzer flag instead. Added: cfe/trunk/test/Driver/fuzzer.c Modified: cfe/trunk/include/clang/Basic/Sanitizers.def cfe/trunk/include/clang/Driver/SanitizerArgs.h cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp cfe/trunk/lib/Driver/ToolChains/Darwin.cpp cfe/trunk/lib/Driver/ToolChains/Darwin.h cfe/trunk/lib/Driver/ToolChains/Linux.cpp Modified: cfe/trunk/include/clang/Basic/Sanitizers.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Sanitizers.def?rev=301212&r1=301211&r2=301212&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Sanitizers.def (original) +++ cfe/trunk/include/clang/Basic/Sanitizers.def Mon Apr 24 13:23:24 2017 @@ -47,6 +47,9 @@ SANITIZER("kernel-address", KernelAddres // MemorySanitizer SANITIZER("memory", Memory) +// libFuzzer +SANITIZER("fuzzer", Fuzzer) + // ThreadSanitizer SANITIZER("thread", Thread) Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/SanitizerArgs.h?rev=301212&r1=301211&r2=301212&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/SanitizerArgs.h (original) +++ cfe/trunk/include/clang/Driver/SanitizerArgs.h Mon Apr 24 13:23:24 2017 @@ -50,6 +50,7 @@ class SanitizerArgs { bool needsSharedAsanRt() const { return AsanSharedRuntime; } bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } + bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); } bool needsLsanRt() const { return Sanitizers.has(SanitizerKind::Leak) && !Sanitizers.has(SanitizerKind::Address); Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=301212&r1=301211&r2=301212&view=diff ============================================================================== --- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original) +++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Mon Apr 24 13:23:24 2017 @@ -265,6 +265,10 @@ SanitizerArgs::SanitizerArgs(const ToolC Add &= ~InvalidTrappingKinds; Add &= Supported; + // Enable coverage if the fuzzing flag is set. + if (Add & Fuzzer) + CoverageFeatures |= CoverageTracePCGuard | CoverageIndirCall | CoverageTraceCmp; + Kinds |= Add; } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) { Arg->claim(); Modified: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp?rev=301212&r1=301211&r2=301212&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp Mon Apr 24 13:23:24 2017 @@ -577,6 +577,17 @@ collectSanitizerRuntimes(const ToolChain StaticRuntimes.push_back("esan"); } +static void addLibFuzzerRuntime(const ToolChain &TC, + const ArgList &Args, + ArgStringList &CmdArgs) { + StringRef ParentDir = llvm::sys::path::parent_path(TC.getDriver().InstalledDir); + SmallString<128> P(ParentDir); + llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a"); + CmdArgs.push_back(Args.MakeArgString(P)); + TC.AddCXXStdlibLibArgs(Args, CmdArgs); +} + + // Should be called before we add system libraries (C++ ABI, libstdc++/libc++, // C runtime, etc). Returns true if sanitizer system deps need to be linked in. bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, @@ -586,6 +597,11 @@ bool tools::addSanitizerRuntimes(const T collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes, NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols); + // Inject libfuzzer dependencies. + if (TC.getSanitizerArgs().needsFuzzer()) { + addLibFuzzerRuntime(TC, Args, CmdArgs); + } + for (auto RT : SharedRuntimes) addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false); for (auto RT : HelperStaticRuntimes) Modified: cfe/trunk/lib/Driver/ToolChains/Darwin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Darwin.cpp?rev=301212&r1=301211&r2=301212&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/Darwin.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Darwin.cpp Mon Apr 24 13:23:24 2017 @@ -930,6 +930,18 @@ void MachO::AddLinkRuntimeLib(const ArgL } } +void MachO::AddFuzzerLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + + // Go up one directory from Clang to find the libfuzzer archive file. + StringRef ParentDir = llvm::sys::path::parent_path(getDriver().InstalledDir); + SmallString<128> P(ParentDir); + llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a"); + CmdArgs.push_back(Args.MakeArgString(P)); + + // Libfuzzer is written in C++ and requires libcxx. + AddCXXStdlibLibArgs(Args, CmdArgs); +} + StringRef Darwin::getPlatformFamily() const { switch (TargetPlatform) { case DarwinPlatformKind::MacOS: @@ -1041,6 +1053,8 @@ void DarwinClang::AddLinkRuntimeLibArgs( AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan"); if (Sanitize.needsTsanRt()) AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan"); + if (Sanitize.needsFuzzer()) + AddFuzzerLinkArgs(Args, CmdArgs); if (Sanitize.needsStatsRt()) { StringRef OS = isTargetMacOS() ? "osx" : "iossim"; AddLinkRuntimeLib(Args, CmdArgs, @@ -1895,6 +1909,7 @@ SanitizerMask Darwin::getSupportedSaniti SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; Res |= SanitizerKind::Leak; + Res |= SanitizerKind::Fuzzer; if (isTargetMacOS()) { if (!isMacosxVersionLT(10, 9)) Res |= SanitizerKind::Vptr; Modified: cfe/trunk/lib/Driver/ToolChains/Darwin.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Darwin.h?rev=301212&r1=301211&r2=301212&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/Darwin.h (original) +++ cfe/trunk/lib/Driver/ToolChains/Darwin.h Mon Apr 24 13:23:24 2017 @@ -154,6 +154,8 @@ public: /// Add the linker arguments to link the compiler runtime library. virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + virtual void AddFuzzerLinkArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const { Modified: cfe/trunk/lib/Driver/ToolChains/Linux.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Linux.cpp?rev=301212&r1=301211&r2=301212&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/Linux.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Linux.cpp Mon Apr 24 13:23:24 2017 @@ -869,6 +869,7 @@ SanitizerMask Linux::getSupportedSanitiz llvm::Triple::thumbeb; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::KernelAddress; Res |= SanitizerKind::Vptr; Res |= SanitizerKind::SafeStack; Added: cfe/trunk/test/Driver/fuzzer.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fuzzer.c?rev=301212&view=auto ============================================================================== --- cfe/trunk/test/Driver/fuzzer.c (added) +++ cfe/trunk/test/Driver/fuzzer.c Mon Apr 24 13:23:24 2017 @@ -0,0 +1,22 @@ +// Test flags inserted by -fsanitize=fuzzer. + +// RUN: %clang -fsanitize=fuzzer %s -### 2>&1 | FileCheck --check-prefixes=CHECK-FUZZER-LIB,CHECK-COVERAGE-FLAGS %s +// +// CHECK-FUZZER-LIB: libLLVMFuzzer.a +// CHECK-COVERAGE: -fsanitize-coverage-trace-pc-guard +// CHECK-COVERAGE-SAME: -fsanitize-coverage-indirect-calls +// CHECK-COVERAGE-SAME: -fsanitize-coverage-trace-cmp + +// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-LINUX %s +// +// CHECK-LIBCXX-LINUX: -lstdc++ + +// RUN: %clang -target x86_64-apple-darwin14 -fsanitize=fuzzer %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-DARWIN %s +// +// CHECK-LIBCXX-DARWIN: -lc++ + +// RUN: %clang -fsanitize=fuzzer %s + +int LLVMFuzzerTestOneInput(const char *Data, long Size) { + return 0; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits