r301212 - Flag -fsanitize=fuzzer to enable libfuzzer

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 24 11:23:25 PDT 2017


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;
+}




More information about the cfe-commits mailing list