[llvm] r272072 - [LibFuzzer] Declare and use sanitizer functions in ``fuzzer::ExternalFunctions``

Dan Liew via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 7 16:32:50 PDT 2016


Author: delcypher
Date: Tue Jun  7 18:32:50 2016
New Revision: 272072

URL: http://llvm.org/viewvc/llvm-project?rev=272072&view=rev
Log:
[LibFuzzer] Declare and use sanitizer functions in ``fuzzer::ExternalFunctions``

This fixes linking problems on OSX.

Unfortunately it turns out we need to use an instance of the
``fuzzer::ExternalFunctions`` object in several places so this
commit also replaces all instances with a single global instance.

It also turns out initializing a global ``fuzzer::ExternalFunctions``
before main is entered (i.e. letting the object be initialised by the
global initializers) is not safe (on OSX the call to ``Printf()`` in the
CTOR crashes if it is called from a global initializer) so we instead
have a global ``fuzzer::ExternalFunctions*`` and initialize it inside
``FuzzerDriver()``.

Multiple unit tests depend also depend on the
``fuzzer::ExternalFunctions*`` global so a ``main()`` function has been
added that initializes it before running any tests.

Differential Revision: http://reviews.llvm.org/D20943

Modified:
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def
    llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h
    llvm/trunk/lib/Fuzzer/FuzzerIO.cpp
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
    llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
    llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp

Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Tue Jun  7 18:32:50 2016
@@ -269,9 +269,9 @@ static bool AllInputsAreFiles() {
 int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
   using namespace fuzzer;
   assert(argc && argv && "Argument pointers cannot be nullptr");
-  fuzzer::ExternalFunctions EF;
-  if (EF.LLVMFuzzerInitialize)
-    EF.LLVMFuzzerInitialize(argc, argv);
+  EF = new ExternalFunctions();
+  if (EF->LLVMFuzzerInitialize)
+    EF->LLVMFuzzerInitialize(argc, argv);
   const std::vector<std::string> Args(*argv, *argv + *argc);
   assert(!Args.empty());
   ProgName = new std::string(Args[0]);
@@ -422,4 +422,8 @@ int FuzzerDriver(int *argc, char ***argv
 
   exit(0);  // Don't let F destroy itself.
 }
+
+// Storage for global ExternalFunctions object.
+ExternalFunctions *EF = nullptr;
+
 }  // namespace fuzzer

Modified: llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def Tue Jun  7 18:32:50 2016
@@ -25,4 +25,18 @@ EXT_FUNC(LLVMFuzzerCustomCrossOver, size
           uint8_t * Out, size_t MaxOutSize, unsigned int Seed),
          false);
 
-// TODO: Sanitizer functions
+// Sanitizer functions
+EXT_FUNC(__lsan_enable, void, (), false);
+EXT_FUNC(__lsan_disable, void, (), false);
+EXT_FUNC(__lsan_do_recoverable_leak_check, int, (), false);
+EXT_FUNC(__sanitizer_get_coverage_pc_buffer, uintptr_t, (uintptr_t**), true);
+EXT_FUNC(__sanitizer_get_number_of_counters, size_t, (), false);
+EXT_FUNC(__sanitizer_get_total_unique_caller_callee_pairs, size_t, (), false);
+EXT_FUNC(__sanitizer_get_total_unique_coverage, size_t, (), true);
+EXT_FUNC(__sanitizer_print_memory_profile, int, (size_t), false);
+EXT_FUNC(__sanitizer_print_stack_trace, void, (), true);
+EXT_FUNC(__sanitizer_reset_coverage, void, (), true);
+EXT_FUNC(__sanitizer_set_death_callback, void, (void (*)(void)), true);
+EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);
+EXT_FUNC(__sanitizer_update_counter_bitset_and_clear_counters, uintptr_t,
+  (uint8_t*), false);

Modified: llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h Tue Jun  7 18:32:50 2016
@@ -17,8 +17,9 @@
 namespace fuzzer {
 
 struct ExternalFunctions {
-  // Initialize function pointers. Functions that are not available
-  // will be set to nullptr.
+  // Initialize function pointers. Functions that are not available will be set
+  // to nullptr.  Do not call this constructor  before ``main()`` has been
+  // entered.
   ExternalFunctions();
 
 #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \

Modified: llvm/trunk/lib/Fuzzer/FuzzerIO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerIO.cpp?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerIO.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerIO.cpp Tue Jun  7 18:32:50 2016
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 // IO functions.
 //===----------------------------------------------------------------------===//
+#include "FuzzerExtFunctions.h"
 #include "FuzzerInternal.h"
 #include <iterator>
 #include <fstream>
@@ -18,10 +19,6 @@
 #include <cstdarg>
 #include <cstdio>
 
-extern "C" {
-__attribute__((weak)) void __sanitizer_set_report_fd(void *);
-}
-
 namespace fuzzer {
 
 static FILE *OutputFile = stderr;
@@ -126,8 +123,8 @@ void DupAndCloseStderr() {
     FILE *NewOutputFile = fdopen(OutputFd, "w");
     if (NewOutputFile) {
       OutputFile = NewOutputFile;
-      if (__sanitizer_set_report_fd)
-        __sanitizer_set_report_fd(reinterpret_cast<void*>(OutputFd));
+      if (EF->__sanitizer_set_report_fd)
+        EF->__sanitizer_set_report_fd(reinterpret_cast<void *>(OutputFd));
       close(2);
     }
   }

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Tue Jun  7 18:32:50 2016
@@ -279,9 +279,6 @@ private:
   size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
                     const std::vector<Mutator> &Mutators);
 
-  // Interface to functions that may or may not be available.
-  const ExternalFunctions EF;
-
   Random &Rand;
   // Dictionary provided by the user via -dict=DICT_FILE.
   Dictionary ManualDictionary;
@@ -483,12 +480,11 @@ private:
 
   // Need to know our own thread.
   static thread_local bool IsMyThread;
-
-  // Interface to functions that may or may not be available.
-  // For future use, currently not used.
-  const ExternalFunctions EF;
 };
 
+// Global interface to functions that may or may not be available.
+extern ExternalFunctions *EF;
+
 }; // namespace fuzzer
 
 #endif // LLVM_FUZZER_INTERNAL_H

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Tue Jun  7 18:32:50 2016
@@ -31,47 +31,23 @@
 #endif
 #endif
 
-extern "C" {
-// Re-declare some of the sanitizer functions as "weak" so that
-// libFuzzer can be linked w/o the sanitizers and sanitizer-coverage
-// (in which case it will complain at start-up time).
-__attribute__((weak)) void __sanitizer_print_stack_trace();
-__attribute__((weak)) void __sanitizer_reset_coverage();
-__attribute__((weak)) size_t __sanitizer_get_total_unique_caller_callee_pairs();
-__attribute__((weak)) size_t __sanitizer_get_total_unique_coverage();
-__attribute__((weak)) void
-__sanitizer_set_death_callback(void (*callback)(void));
-__attribute__((weak)) size_t __sanitizer_get_number_of_counters();
-__attribute__((weak)) uintptr_t
-__sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);
-__attribute__((weak)) uintptr_t
-__sanitizer_get_coverage_pc_buffer(uintptr_t **data);
-
-__attribute__((weak)) void __sanitizer_malloc_hook(void *ptr, size_t size);
-__attribute__((weak)) void __sanitizer_free_hook(void *ptr);
-__attribute__((weak)) void __lsan_enable();
-__attribute__((weak)) void __lsan_disable();
-__attribute__((weak)) int __lsan_do_recoverable_leak_check();
-__attribute__((weak)) int __sanitizer_print_memory_profile(size_t);
-}
-
 namespace fuzzer {
 static const size_t kMaxUnitSizeToPrint = 256;
 static const size_t TruncateMaxRuns = 1000;
 
 thread_local bool Fuzzer::IsMyThread;
 
-static void MissingWeakApiFunction(const char *FnName) {
+static void MissingExternalApiFunction(const char *FnName) {
   Printf("ERROR: %s is not defined. Exiting.\n"
          "Did you use -fsanitize-coverage=... to build your code?\n",
          FnName);
   exit(1);
 }
 
-#define CHECK_WEAK_API_FUNCTION(fn)                                            \
+#define CHECK_EXTERNAL_FUNCTION(fn)                                            \
   do {                                                                         \
-    if (!fn)                                                                   \
-      MissingWeakApiFunction(#fn);                                             \
+    if (!(EF->fn))                                                             \
+      MissingExternalApiFunction(#fn);                                         \
   } while (false)
 
 // Only one Fuzzer per process.
@@ -79,21 +55,21 @@ static Fuzzer *F;
 
 struct CoverageController {
   static void Reset() {
-    CHECK_WEAK_API_FUNCTION(__sanitizer_reset_coverage);
-    __sanitizer_reset_coverage();
+    CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage);
+    EF->__sanitizer_reset_coverage();
     PcMapResetCurrent();
   }
 
   static void ResetCounters(const Fuzzer::FuzzingOptions &Options) {
     if (Options.UseCounters) {
-      __sanitizer_update_counter_bitset_and_clear_counters(0);
+      EF->__sanitizer_update_counter_bitset_and_clear_counters(0);
     }
   }
 
   static void Prepare(const Fuzzer::FuzzingOptions &Options,
                       Fuzzer::Coverage *C) {
     if (Options.UseCounters) {
-      size_t NumCounters = __sanitizer_get_number_of_counters();
+      size_t NumCounters = EF->__sanitizer_get_number_of_counters();
       C->CounterBitmap.resize(NumCounters);
     }
   }
@@ -104,16 +80,16 @@ struct CoverageController {
                         Fuzzer::Coverage *C) {
     bool Res = false;
 
-    uint64_t NewBlockCoverage = __sanitizer_get_total_unique_coverage();
+    uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();
     if (NewBlockCoverage > C->BlockCoverage) {
       Res = true;
       C->BlockCoverage = NewBlockCoverage;
     }
 
     if (Options.UseIndirCalls &&
-        __sanitizer_get_total_unique_caller_callee_pairs) {
+        EF->__sanitizer_get_total_unique_caller_callee_pairs) {
       uint64_t NewCallerCalleeCoverage =
-          __sanitizer_get_total_unique_caller_callee_pairs();
+          EF->__sanitizer_get_total_unique_caller_callee_pairs();
       if (NewCallerCalleeCoverage > C->CallerCalleeCoverage) {
         Res = true;
         C->CallerCalleeCoverage = NewCallerCalleeCoverage;
@@ -122,7 +98,7 @@ struct CoverageController {
 
     if (Options.UseCounters) {
       uint64_t CounterDelta =
-          __sanitizer_update_counter_bitset_and_clear_counters(
+          EF->__sanitizer_update_counter_bitset_and_clear_counters(
               C->CounterBitmap.data());
       if (CounterDelta > 0) {
         Res = true;
@@ -137,7 +113,8 @@ struct CoverageController {
     }
 
     uintptr_t *CoverageBuf;
-    uint64_t NewPcBufferLen = __sanitizer_get_coverage_pc_buffer(&CoverageBuf);
+    uint64_t NewPcBufferLen =
+        EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);
     if (NewPcBufferLen > C->PcBufferLen) {
       Res = true;
       C->PcBufferLen = NewPcBufferLen;
@@ -163,8 +140,8 @@ void Fuzzer::LazyAllocateCurrentUnitData
 }
 
 void Fuzzer::SetDeathCallback() {
-  CHECK_WEAK_API_FUNCTION(__sanitizer_set_death_callback);
-  __sanitizer_set_death_callback(StaticDeathCallback);
+  CHECK_EXTERNAL_FUNCTION(__sanitizer_set_death_callback);
+  EF->__sanitizer_set_death_callback(StaticDeathCallback);
 }
 
 void Fuzzer::StaticDeathCallback() {
@@ -206,8 +183,8 @@ void Fuzzer::StaticInterruptCallback() {
 
 void Fuzzer::CrashCallback() {
   Printf("==%d== ERROR: libFuzzer: deadly signal\n", GetPid());
-  if (__sanitizer_print_stack_trace)
-    __sanitizer_print_stack_trace();
+  if (EF->__sanitizer_print_stack_trace)
+    EF->__sanitizer_print_stack_trace();
   Printf("NOTE: libFuzzer has rudimentary signal handlers.\n"
          "      Combine libFuzzer with AddressSanitizer or similar for better "
          "crash reports.\n");
@@ -242,8 +219,8 @@ void Fuzzer::AlarmCallback() {
     DumpCurrentUnit("timeout-");
     Printf("==%d== ERROR: libFuzzer: timeout after %d seconds\n", GetPid(),
            Seconds);
-    if (__sanitizer_print_stack_trace)
-      __sanitizer_print_stack_trace();
+    if (EF->__sanitizer_print_stack_trace)
+      EF->__sanitizer_print_stack_trace();
     Printf("SUMMARY: libFuzzer: timeout\n");
     PrintFinalStats();
     _Exit(Options.TimeoutExitCode); // Stop right now.
@@ -255,8 +232,8 @@ void Fuzzer::RssLimitCallback() {
       "==%d== ERROR: libFuzzer: out-of-memory (used: %zdMb; limit: %zdMb)\n",
       GetPid(), GetPeakRSSMb(), Options.RssLimitMb);
   Printf("   To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");
-  if (__sanitizer_print_memory_profile)
-    __sanitizer_print_memory_profile(50);
+  if (EF->__sanitizer_print_memory_profile)
+    EF->__sanitizer_print_memory_profile(50);
   DumpCurrentUnit("oom-");
   Printf("SUMMARY: libFuzzer: out-of-memory\n");
   PrintFinalStats();
@@ -422,7 +399,7 @@ bool Fuzzer::UpdateMaxCoverage() {
 
   if (Options.PrintNewCovPcs && PrevBufferLen != MaxCoverage.PcBufferLen) {
     uintptr_t *CoverageBuf;
-    __sanitizer_get_coverage_pc_buffer(&CoverageBuf);
+    EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);
     assert(CoverageBuf);
     for (size_t I = PrevBufferLen; I < MaxCoverage.PcBufferLen; ++I) {
       Printf("%p\n", CoverageBuf[I]);
@@ -651,13 +628,14 @@ void Fuzzer::TryDetectingAMemoryLeak(con
                                      bool DuringInitialCorpusExecution) {
   if (!HasMoreMallocsThanFrees) return;  // mallocs==frees, a leak is unlikely.
   if (!Options.DetectLeaks) return;
-  if (!&__lsan_enable || !&__lsan_disable || !__lsan_do_recoverable_leak_check)
+  if (!&(EF->__lsan_enable) || !&(EF->__lsan_disable) ||
+      !(EF->__lsan_do_recoverable_leak_check))
     return;  // No lsan.
   // Run the target once again, but with lsan disabled so that if there is
   // a real leak we do not report it twice.
-  __lsan_disable();
+  EF->__lsan_disable();
   RunOne(Data, Size);
-  __lsan_enable();
+  EF->__lsan_enable();
   if (!HasMoreMallocsThanFrees) return;  // a leak is unlikely.
   if (NumberOfLeakDetectionAttempts++ > 1000) {
     Options.DetectLeaks = false;
@@ -670,7 +648,7 @@ void Fuzzer::TryDetectingAMemoryLeak(con
   }
   // Now perform the actual lsan pass. This is expensive and we must ensure
   // we don't call it too often.
-  if (__lsan_do_recoverable_leak_check()) {  // Leak is found, report it.
+  if (EF->__lsan_do_recoverable_leak_check()) { // Leak is found, report it.
     if (DuringInitialCorpusExecution)
       Printf("\nINFO: a leak has been found in the initial corpus.\n\n");
     Printf("INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.\n\n");

Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Tue Jun  7 18:32:50 2016
@@ -37,12 +37,12 @@ MutationDispatcher::MutationDispatcher(R
            "AddFromPersAutoDict"},
       });
 
-  if (EF.LLVMFuzzerCustomMutator)
+  if (EF->LLVMFuzzerCustomMutator)
     Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
   else
     Mutators = DefaultMutators;
 
-  if (EF.LLVMFuzzerCustomCrossOver)
+  if (EF->LLVMFuzzerCustomCrossOver)
     Mutators.push_back(
         {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
 }
@@ -67,7 +67,7 @@ static char RandCh(Random &Rand) {
 
 size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
                                          size_t MaxSize) {
-  return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
+  return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
 }
 
 size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
@@ -80,7 +80,7 @@ size_t MutationDispatcher::Mutate_Custom
     return 0;
   MutateInPlaceHere.resize(MaxSize);
   auto &U = MutateInPlaceHere;
-  size_t NewSize = EF.LLVMFuzzerCustomCrossOver(
+  size_t NewSize = EF->LLVMFuzzerCustomCrossOver(
       Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand());
   if (!NewSize)
     return 0;

Modified: llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=272072&r1=272071&r2=272072&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp Tue Jun  7 18:32:50 2016
@@ -3,6 +3,7 @@
 
 #include "FuzzerInternal.h"
 #include "gtest/gtest.h"
+#include <memory>
 #include <set>
 
 using namespace fuzzer;
@@ -14,6 +15,8 @@ extern "C" int LLVMFuzzerTestOneInput(co
 }
 
 TEST(Fuzzer, CrossOver) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   Unit A({0, 1, 2}), B({5, 6, 7});
@@ -82,6 +85,8 @@ typedef size_t (MutationDispatcher::*Mut
                                               size_t MaxSize);
 
 void TestEraseByte(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
@@ -116,6 +121,8 @@ TEST(FuzzerMutate, EraseByte2) {
 }
 
 void TestInsertByte(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   int FoundMask = 0;
@@ -150,6 +157,8 @@ TEST(FuzzerMutate, InsertByte2) {
 }
 
 void TestChangeByte(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   int FoundMask = 0;
@@ -184,6 +193,8 @@ TEST(FuzzerMutate, ChangeByte2) {
 }
 
 void TestChangeBit(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   int FoundMask = 0;
@@ -218,6 +229,8 @@ TEST(FuzzerMutate, ChangeBit2) {
 }
 
 void TestShuffleBytes(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   int FoundMask = 0;
@@ -246,6 +259,8 @@ TEST(FuzzerMutate, ShuffleBytes2) {
 }
 
 void TestAddWordFromDictionary(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
@@ -286,6 +301,8 @@ TEST(FuzzerMutate, AddWordFromDictionary
 }
 
 void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};
@@ -313,6 +330,8 @@ TEST(FuzzerMutate, AddWordFromDictionary
 }
 
 void TestChangeASCIIInteger(Mutator M, int NumIter) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
 
@@ -405,6 +424,8 @@ TEST(FuzzerUtil, Base64) {
 }
 
 TEST(Corpus, Distribution) {
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
+  fuzzer::EF = t.get();
   Random Rand(0);
   MutationDispatcher MD(Rand);
   Fuzzer::FuzzingOptions Options;




More information about the llvm-commits mailing list