<div dir="ltr">We still need attribute weak for malloc/free hooks.<div>This change broke one of our use cases apparently not covered by any test. :( <br><div>I've added weak attributes for these two functions back in r272116, hopefully it does not break Mac. </div><div>Please check. </div><div><br></div><div>The current solution with lsan is bad in many ways but we'll have</div><div>to live with it for some time until we figure out a better way. </div><div><br></div><div>--kcc </div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 7, 2016 at 4:32 PM, Dan Liew via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: delcypher<br>
Date: Tue Jun  7 18:32:50 2016<br>
New Revision: 272072<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=272072&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=272072&view=rev</a><br>
Log:<br>
[LibFuzzer] Declare and use sanitizer functions in ``fuzzer::ExternalFunctions``<br>
<br>
This fixes linking problems on OSX.<br>
<br>
Unfortunately it turns out we need to use an instance of the<br>
``fuzzer::ExternalFunctions`` object in several places so this<br>
commit also replaces all instances with a single global instance.<br>
<br>
It also turns out initializing a global ``fuzzer::ExternalFunctions``<br>
before main is entered (i.e. letting the object be initialised by the<br>
global initializers) is not safe (on OSX the call to ``Printf()`` in the<br>
CTOR crashes if it is called from a global initializer) so we instead<br>
have a global ``fuzzer::ExternalFunctions*`` and initialize it inside<br>
``FuzzerDriver()``.<br>
<br>
Multiple unit tests depend also depend on the<br>
``fuzzer::ExternalFunctions*`` global so a ``main()`` function has been<br>
added that initializes it before running any tests.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D20943" rel="noreferrer" target="_blank">http://reviews.llvm.org/D20943</a><br>
<br>
Modified:<br>
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp<br>
    llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def<br>
    llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h<br>
    llvm/trunk/lib/Fuzzer/FuzzerIO.cpp<br>
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h<br>
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp<br>
    llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp<br>
    llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)<br>
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Tue Jun  7 18:32:50 2016<br>
@@ -269,9 +269,9 @@ static bool AllInputsAreFiles() {<br>
 int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {<br>
   using namespace fuzzer;<br>
   assert(argc && argv && "Argument pointers cannot be nullptr");<br>
-  fuzzer::ExternalFunctions EF;<br>
-  if (EF.LLVMFuzzerInitialize)<br>
-    EF.LLVMFuzzerInitialize(argc, argv);<br>
+  EF = new ExternalFunctions();<br>
+  if (EF->LLVMFuzzerInitialize)<br>
+    EF->LLVMFuzzerInitialize(argc, argv);<br>
   const std::vector<std::string> Args(*argv, *argv + *argc);<br>
   assert(!Args.empty());<br>
   ProgName = new std::string(Args[0]);<br>
@@ -422,4 +422,8 @@ int FuzzerDriver(int *argc, char ***argv<br>
<br>
   exit(0);  // Don't let F destroy itself.<br>
 }<br>
+<br>
+// Storage for global ExternalFunctions object.<br>
+ExternalFunctions *EF = nullptr;<br>
+<br>
 }  // namespace fuzzer<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def (original)<br>
+++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def Tue Jun  7 18:32:50 2016<br>
@@ -25,4 +25,18 @@ EXT_FUNC(LLVMFuzzerCustomCrossOver, size<br>
           uint8_t * Out, size_t MaxOutSize, unsigned int Seed),<br>
          false);<br>
<br>
-// TODO: Sanitizer functions<br>
+// Sanitizer functions<br>
+EXT_FUNC(__lsan_enable, void, (), false);<br>
+EXT_FUNC(__lsan_disable, void, (), false);<br>
+EXT_FUNC(__lsan_do_recoverable_leak_check, int, (), false);<br>
+EXT_FUNC(__sanitizer_get_coverage_pc_buffer, uintptr_t, (uintptr_t**), true);<br>
+EXT_FUNC(__sanitizer_get_number_of_counters, size_t, (), false);<br>
+EXT_FUNC(__sanitizer_get_total_unique_caller_callee_pairs, size_t, (), false);<br>
+EXT_FUNC(__sanitizer_get_total_unique_coverage, size_t, (), true);<br>
+EXT_FUNC(__sanitizer_print_memory_profile, int, (size_t), false);<br>
+EXT_FUNC(__sanitizer_print_stack_trace, void, (), true);<br>
+EXT_FUNC(__sanitizer_reset_coverage, void, (), true);<br>
+EXT_FUNC(__sanitizer_set_death_callback, void, (void (*)(void)), true);<br>
+EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);<br>
+EXT_FUNC(__sanitizer_update_counter_bitset_and_clear_counters, uintptr_t,<br>
+  (uint8_t*), false);<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h (original)<br>
+++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h Tue Jun  7 18:32:50 2016<br>
@@ -17,8 +17,9 @@<br>
 namespace fuzzer {<br>
<br>
 struct ExternalFunctions {<br>
-  // Initialize function pointers. Functions that are not available<br>
-  // will be set to nullptr.<br>
+  // Initialize function pointers. Functions that are not available will be set<br>
+  // to nullptr.  Do not call this constructor  before ``main()`` has been<br>
+  // entered.<br>
   ExternalFunctions();<br>
<br>
 #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/FuzzerIO.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerIO.cpp?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerIO.cpp?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/FuzzerIO.cpp (original)<br>
+++ llvm/trunk/lib/Fuzzer/FuzzerIO.cpp Tue Jun  7 18:32:50 2016<br>
@@ -8,6 +8,7 @@<br>
 //===----------------------------------------------------------------------===//<br>
 // IO functions.<br>
 //===----------------------------------------------------------------------===//<br>
+#include "FuzzerExtFunctions.h"<br>
 #include "FuzzerInternal.h"<br>
 #include <iterator><br>
 #include <fstream><br>
@@ -18,10 +19,6 @@<br>
 #include <cstdarg><br>
 #include <cstdio><br>
<br>
-extern "C" {<br>
-__attribute__((weak)) void __sanitizer_set_report_fd(void *);<br>
-}<br>
-<br>
 namespace fuzzer {<br>
<br>
 static FILE *OutputFile = stderr;<br>
@@ -126,8 +123,8 @@ void DupAndCloseStderr() {<br>
     FILE *NewOutputFile = fdopen(OutputFd, "w");<br>
     if (NewOutputFile) {<br>
       OutputFile = NewOutputFile;<br>
-      if (__sanitizer_set_report_fd)<br>
-        __sanitizer_set_report_fd(reinterpret_cast<void*>(OutputFd));<br>
+      if (EF->__sanitizer_set_report_fd)<br>
+        EF->__sanitizer_set_report_fd(reinterpret_cast<void *>(OutputFd));<br>
       close(2);<br>
     }<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)<br>
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Tue Jun  7 18:32:50 2016<br>
@@ -279,9 +279,6 @@ private:<br>
   size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,<br>
                     const std::vector<Mutator> &Mutators);<br>
<br>
-  // Interface to functions that may or may not be available.<br>
-  const ExternalFunctions EF;<br>
-<br>
   Random &Rand;<br>
   // Dictionary provided by the user via -dict=DICT_FILE.<br>
   Dictionary ManualDictionary;<br>
@@ -483,12 +480,11 @@ private:<br>
<br>
   // Need to know our own thread.<br>
   static thread_local bool IsMyThread;<br>
-<br>
-  // Interface to functions that may or may not be available.<br>
-  // For future use, currently not used.<br>
-  const ExternalFunctions EF;<br>
 };<br>
<br>
+// Global interface to functions that may or may not be available.<br>
+extern ExternalFunctions *EF;<br>
+<br>
 }; // namespace fuzzer<br>
<br>
 #endif // LLVM_FUZZER_INTERNAL_H<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)<br>
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Tue Jun  7 18:32:50 2016<br>
@@ -31,47 +31,23 @@<br>
 #endif<br>
 #endif<br>
<br>
-extern "C" {<br>
-// Re-declare some of the sanitizer functions as "weak" so that<br>
-// libFuzzer can be linked w/o the sanitizers and sanitizer-coverage<br>
-// (in which case it will complain at start-up time).<br>
-__attribute__((weak)) void __sanitizer_print_stack_trace();<br>
-__attribute__((weak)) void __sanitizer_reset_coverage();<br>
-__attribute__((weak)) size_t __sanitizer_get_total_unique_caller_callee_pairs();<br>
-__attribute__((weak)) size_t __sanitizer_get_total_unique_coverage();<br>
-__attribute__((weak)) void<br>
-__sanitizer_set_death_callback(void (*callback)(void));<br>
-__attribute__((weak)) size_t __sanitizer_get_number_of_counters();<br>
-__attribute__((weak)) uintptr_t<br>
-__sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);<br>
-__attribute__((weak)) uintptr_t<br>
-__sanitizer_get_coverage_pc_buffer(uintptr_t **data);<br>
-<br>
-__attribute__((weak)) void __sanitizer_malloc_hook(void *ptr, size_t size);<br>
-__attribute__((weak)) void __sanitizer_free_hook(void *ptr);<br>
-__attribute__((weak)) void __lsan_enable();<br>
-__attribute__((weak)) void __lsan_disable();<br>
-__attribute__((weak)) int __lsan_do_recoverable_leak_check();<br>
-__attribute__((weak)) int __sanitizer_print_memory_profile(size_t);<br>
-}<br>
-<br>
 namespace fuzzer {<br>
 static const size_t kMaxUnitSizeToPrint = 256;<br>
 static const size_t TruncateMaxRuns = 1000;<br>
<br>
 thread_local bool Fuzzer::IsMyThread;<br>
<br>
-static void MissingWeakApiFunction(const char *FnName) {<br>
+static void MissingExternalApiFunction(const char *FnName) {<br>
   Printf("ERROR: %s is not defined. Exiting.\n"<br>
          "Did you use -fsanitize-coverage=... to build your code?\n",<br>
          FnName);<br>
   exit(1);<br>
 }<br>
<br>
-#define CHECK_WEAK_API_FUNCTION(fn)                                            \<br>
+#define CHECK_EXTERNAL_FUNCTION(fn)                                            \<br>
   do {                                                                         \<br>
-    if (!fn)                                                                   \<br>
-      MissingWeakApiFunction(#fn);                                             \<br>
+    if (!(EF->fn))                                                             \<br>
+      MissingExternalApiFunction(#fn);                                         \<br>
   } while (false)<br>
<br>
 // Only one Fuzzer per process.<br>
@@ -79,21 +55,21 @@ static Fuzzer *F;<br>
<br>
 struct CoverageController {<br>
   static void Reset() {<br>
-    CHECK_WEAK_API_FUNCTION(__sanitizer_reset_coverage);<br>
-    __sanitizer_reset_coverage();<br>
+    CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage);<br>
+    EF->__sanitizer_reset_coverage();<br>
     PcMapResetCurrent();<br>
   }<br>
<br>
   static void ResetCounters(const Fuzzer::FuzzingOptions &Options) {<br>
     if (Options.UseCounters) {<br>
-      __sanitizer_update_counter_bitset_and_clear_counters(0);<br>
+      EF->__sanitizer_update_counter_bitset_and_clear_counters(0);<br>
     }<br>
   }<br>
<br>
   static void Prepare(const Fuzzer::FuzzingOptions &Options,<br>
                       Fuzzer::Coverage *C) {<br>
     if (Options.UseCounters) {<br>
-      size_t NumCounters = __sanitizer_get_number_of_counters();<br>
+      size_t NumCounters = EF->__sanitizer_get_number_of_counters();<br>
       C->CounterBitmap.resize(NumCounters);<br>
     }<br>
   }<br>
@@ -104,16 +80,16 @@ struct CoverageController {<br>
                         Fuzzer::Coverage *C) {<br>
     bool Res = false;<br>
<br>
-    uint64_t NewBlockCoverage = __sanitizer_get_total_unique_coverage();<br>
+    uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();<br>
     if (NewBlockCoverage > C->BlockCoverage) {<br>
       Res = true;<br>
       C->BlockCoverage = NewBlockCoverage;<br>
     }<br>
<br>
     if (Options.UseIndirCalls &&<br>
-        __sanitizer_get_total_unique_caller_callee_pairs) {<br>
+        EF->__sanitizer_get_total_unique_caller_callee_pairs) {<br>
       uint64_t NewCallerCalleeCoverage =<br>
-          __sanitizer_get_total_unique_caller_callee_pairs();<br>
+          EF->__sanitizer_get_total_unique_caller_callee_pairs();<br>
       if (NewCallerCalleeCoverage > C->CallerCalleeCoverage) {<br>
         Res = true;<br>
         C->CallerCalleeCoverage = NewCallerCalleeCoverage;<br>
@@ -122,7 +98,7 @@ struct CoverageController {<br>
<br>
     if (Options.UseCounters) {<br>
       uint64_t CounterDelta =<br>
-          __sanitizer_update_counter_bitset_and_clear_counters(<br>
+          EF->__sanitizer_update_counter_bitset_and_clear_counters(<br>
               C->CounterBitmap.data());<br>
       if (CounterDelta > 0) {<br>
         Res = true;<br>
@@ -137,7 +113,8 @@ struct CoverageController {<br>
     }<br>
<br>
     uintptr_t *CoverageBuf;<br>
-    uint64_t NewPcBufferLen = __sanitizer_get_coverage_pc_buffer(&CoverageBuf);<br>
+    uint64_t NewPcBufferLen =<br>
+        EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);<br>
     if (NewPcBufferLen > C->PcBufferLen) {<br>
       Res = true;<br>
       C->PcBufferLen = NewPcBufferLen;<br>
@@ -163,8 +140,8 @@ void Fuzzer::LazyAllocateCurrentUnitData<br>
 }<br>
<br>
 void Fuzzer::SetDeathCallback() {<br>
-  CHECK_WEAK_API_FUNCTION(__sanitizer_set_death_callback);<br>
-  __sanitizer_set_death_callback(StaticDeathCallback);<br>
+  CHECK_EXTERNAL_FUNCTION(__sanitizer_set_death_callback);<br>
+  EF->__sanitizer_set_death_callback(StaticDeathCallback);<br>
 }<br>
<br>
 void Fuzzer::StaticDeathCallback() {<br>
@@ -206,8 +183,8 @@ void Fuzzer::StaticInterruptCallback() {<br>
<br>
 void Fuzzer::CrashCallback() {<br>
   Printf("==%d== ERROR: libFuzzer: deadly signal\n", GetPid());<br>
-  if (__sanitizer_print_stack_trace)<br>
-    __sanitizer_print_stack_trace();<br>
+  if (EF->__sanitizer_print_stack_trace)<br>
+    EF->__sanitizer_print_stack_trace();<br>
   Printf("NOTE: libFuzzer has rudimentary signal handlers.\n"<br>
          "      Combine libFuzzer with AddressSanitizer or similar for better "<br>
          "crash reports.\n");<br>
@@ -242,8 +219,8 @@ void Fuzzer::AlarmCallback() {<br>
     DumpCurrentUnit("timeout-");<br>
     Printf("==%d== ERROR: libFuzzer: timeout after %d seconds\n", GetPid(),<br>
            Seconds);<br>
-    if (__sanitizer_print_stack_trace)<br>
-      __sanitizer_print_stack_trace();<br>
+    if (EF->__sanitizer_print_stack_trace)<br>
+      EF->__sanitizer_print_stack_trace();<br>
     Printf("SUMMARY: libFuzzer: timeout\n");<br>
     PrintFinalStats();<br>
     _Exit(Options.TimeoutExitCode); // Stop right now.<br>
@@ -255,8 +232,8 @@ void Fuzzer::RssLimitCallback() {<br>
       "==%d== ERROR: libFuzzer: out-of-memory (used: %zdMb; limit: %zdMb)\n",<br>
       GetPid(), GetPeakRSSMb(), Options.RssLimitMb);<br>
   Printf("   To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");<br>
-  if (__sanitizer_print_memory_profile)<br>
-    __sanitizer_print_memory_profile(50);<br>
+  if (EF->__sanitizer_print_memory_profile)<br>
+    EF->__sanitizer_print_memory_profile(50);<br>
   DumpCurrentUnit("oom-");<br>
   Printf("SUMMARY: libFuzzer: out-of-memory\n");<br>
   PrintFinalStats();<br>
@@ -422,7 +399,7 @@ bool Fuzzer::UpdateMaxCoverage() {<br>
<br>
   if (Options.PrintNewCovPcs && PrevBufferLen != MaxCoverage.PcBufferLen) {<br>
     uintptr_t *CoverageBuf;<br>
-    __sanitizer_get_coverage_pc_buffer(&CoverageBuf);<br>
+    EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);<br>
     assert(CoverageBuf);<br>
     for (size_t I = PrevBufferLen; I < MaxCoverage.PcBufferLen; ++I) {<br>
       Printf("%p\n", CoverageBuf[I]);<br>
@@ -651,13 +628,14 @@ void Fuzzer::TryDetectingAMemoryLeak(con<br>
                                      bool DuringInitialCorpusExecution) {<br>
   if (!HasMoreMallocsThanFrees) return;  // mallocs==frees, a leak is unlikely.<br>
   if (!Options.DetectLeaks) return;<br>
-  if (!&__lsan_enable || !&__lsan_disable || !__lsan_do_recoverable_leak_check)<br>
+  if (!&(EF->__lsan_enable) || !&(EF->__lsan_disable) ||<br>
+      !(EF->__lsan_do_recoverable_leak_check))<br>
     return;  // No lsan.<br>
   // Run the target once again, but with lsan disabled so that if there is<br>
   // a real leak we do not report it twice.<br>
-  __lsan_disable();<br>
+  EF->__lsan_disable();<br>
   RunOne(Data, Size);<br>
-  __lsan_enable();<br>
+  EF->__lsan_enable();<br>
   if (!HasMoreMallocsThanFrees) return;  // a leak is unlikely.<br>
   if (NumberOfLeakDetectionAttempts++ > 1000) {<br>
     Options.DetectLeaks = false;<br>
@@ -670,7 +648,7 @@ void Fuzzer::TryDetectingAMemoryLeak(con<br>
   }<br>
   // Now perform the actual lsan pass. This is expensive and we must ensure<br>
   // we don't call it too often.<br>
-  if (__lsan_do_recoverable_leak_check()) {  // Leak is found, report it.<br>
+  if (EF->__lsan_do_recoverable_leak_check()) { // Leak is found, report it.<br>
     if (DuringInitialCorpusExecution)<br>
       Printf("\nINFO: a leak has been found in the initial corpus.\n\n");<br>
     Printf("INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.\n\n");<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)<br>
+++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Tue Jun  7 18:32:50 2016<br>
@@ -37,12 +37,12 @@ MutationDispatcher::MutationDispatcher(R<br>
            "AddFromPersAutoDict"},<br>
       });<br>
<br>
-  if (EF.LLVMFuzzerCustomMutator)<br>
+  if (EF->LLVMFuzzerCustomMutator)<br>
     Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});<br>
   else<br>
     Mutators = DefaultMutators;<br>
<br>
-  if (EF.LLVMFuzzerCustomCrossOver)<br>
+  if (EF->LLVMFuzzerCustomCrossOver)<br>
     Mutators.push_back(<br>
         {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});<br>
 }<br>
@@ -67,7 +67,7 @@ static char RandCh(Random &Rand) {<br>
<br>
 size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,<br>
                                          size_t MaxSize) {<br>
-  return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());<br>
+  return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());<br>
 }<br>
<br>
 size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,<br>
@@ -80,7 +80,7 @@ size_t MutationDispatcher::Mutate_Custom<br>
     return 0;<br>
   MutateInPlaceHere.resize(MaxSize);<br>
   auto &U = MutateInPlaceHere;<br>
-  size_t NewSize = EF.LLVMFuzzerCustomCrossOver(<br>
+  size_t NewSize = EF->LLVMFuzzerCustomCrossOver(<br>
       Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand());<br>
   if (!NewSize)<br>
     return 0;<br>
<br>
Modified: llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=272072&r1=272071&r2=272072&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=272072&r1=272071&r2=272072&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp (original)<br>
+++ llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp Tue Jun  7 18:32:50 2016<br>
@@ -3,6 +3,7 @@<br>
<br>
 #include "FuzzerInternal.h"<br>
 #include "gtest/gtest.h"<br>
+#include <memory><br>
 #include <set><br>
<br>
 using namespace fuzzer;<br>
@@ -14,6 +15,8 @@ extern "C" int LLVMFuzzerTestOneInput(co<br>
 }<br>
<br>
 TEST(Fuzzer, CrossOver) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   Unit A({0, 1, 2}), B({5, 6, 7});<br>
@@ -82,6 +85,8 @@ typedef size_t (MutationDispatcher::*Mut<br>
                                               size_t MaxSize);<br>
<br>
 void TestEraseByte(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};<br>
   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};<br>
   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};<br>
@@ -116,6 +121,8 @@ TEST(FuzzerMutate, EraseByte2) {<br>
 }<br>
<br>
 void TestInsertByte(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   int FoundMask = 0;<br>
@@ -150,6 +157,8 @@ TEST(FuzzerMutate, InsertByte2) {<br>
 }<br>
<br>
 void TestChangeByte(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   int FoundMask = 0;<br>
@@ -184,6 +193,8 @@ TEST(FuzzerMutate, ChangeByte2) {<br>
 }<br>
<br>
 void TestChangeBit(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   int FoundMask = 0;<br>
@@ -218,6 +229,8 @@ TEST(FuzzerMutate, ChangeBit2) {<br>
 }<br>
<br>
 void TestShuffleBytes(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   int FoundMask = 0;<br>
@@ -246,6 +259,8 @@ TEST(FuzzerMutate, ShuffleBytes2) {<br>
 }<br>
<br>
 void TestAddWordFromDictionary(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};<br>
@@ -286,6 +301,8 @@ TEST(FuzzerMutate, AddWordFromDictionary<br>
 }<br>
<br>
 void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};<br>
@@ -313,6 +330,8 @@ TEST(FuzzerMutate, AddWordFromDictionary<br>
 }<br>
<br>
 void TestChangeASCIIInteger(Mutator M, int NumIter) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
<br>
@@ -405,6 +424,8 @@ TEST(FuzzerUtil, Base64) {<br>
 }<br>
<br>
 TEST(Corpus, Distribution) {<br>
+  std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());<br>
+  fuzzer::EF = t.get();<br>
   Random Rand(0);<br>
   MutationDispatcher MD(Rand);<br>
   Fuzzer::FuzzingOptions Options;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>