[llvm] r281845 - [libFuzzer] use 'if guard' instead of 'if guard >= 0' with trace-pc; change the guard type to intptr_t; use separate array for 8-bit counters

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 17 21:52:23 PDT 2016


Author: kcc
Date: Sat Sep 17 23:52:23 2016
New Revision: 281845

URL: http://llvm.org/viewvc/llvm-project?rev=281845&view=rev
Log:
[libFuzzer] use 'if guard' instead of 'if guard >= 0' with trace-pc; change the guard type to intptr_t; use separate array for 8-bit counters

Modified:
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
    llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=281845&r1=281844&r2=281845&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Sat Sep 17 23:52:23 2016
@@ -358,8 +358,8 @@ private:
 // See TracePC.cpp
 class TracePC {
  public:
-  void HandleTrace(uint64_t *guard, uintptr_t PC);
-  void HandleInit(uint64_t *start, uint64_t *stop);
+  void HandleTrace(uintptr_t *guard, uintptr_t PC);
+  void HandleInit(uintptr_t *start, uintptr_t *stop);
   void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
   size_t GetTotalCoverage() { return TotalCoverage; }
   void SetUseCounters(bool UC) { UseCounters = UC; }
@@ -398,13 +398,16 @@ private:
   void ResetGuards();
 
   struct Module {
-    uint64_t *Start, *Stop;
+    uintptr_t *Start, *Stop;
   };
 
   Module Modules[4096];
   size_t NumModules = 0;
   size_t NumGuards = 0;
 
+  static const size_t kNumCounters = 1 << 14;
+  uint8_t Counters[kNumCounters];
+
   ValueBitMap CounterMap;
   ValueBitMap TotalCoverageMap;
 };

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=281845&r1=281844&r2=281845&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp Sat Sep 17 23:52:23 2016
@@ -17,39 +17,35 @@
 namespace fuzzer {
 
 TracePC TPC;
+const size_t TracePC::kNumCounters;
 
-void TracePC::HandleTrace(uint64_t *Guard, uintptr_t PC) {
-  const uint64_t kBit63 = 1ULL << 63;
-  uint64_t Value = *Guard;
-  if (Value & kBit63) return;
-  // Printf("   >> %16zx %p\n", Value, Guard);
+void TracePC::HandleTrace(uintptr_t *Guard, uintptr_t PC) {
+  uintptr_t Idx = *Guard;
+  if (!Idx) return;
   if (UseCounters) {
-    uint64_t Counter = Value & 0xff;
+    uint8_t Counter = Counters[Idx % kNumCounters];
     if (Counter == 0) {
-      size_t Idx = Value >> 32;
       if (TotalCoverageMap.AddValue(Idx)) {
         TotalCoverage++;
         AddNewPC(PC);
       }
     }
-    if (Counter < 255)
-      Value++;
+    if (Counter < 128)
+      Counters[Idx % kNumCounters] = Counter + 1;
     else
-      Value |= kBit63;
+      *Guard = 0;
   } else {
-    Value |= kBit63;
+    *Guard = 0;
     TotalCoverage++;
     AddNewPC(PC);
   }
-  // Printf("   << %16zx\n", Value);
-  *Guard = Value;
 }
 
-void TracePC::HandleInit(uint64_t *Start, uint64_t *Stop) {
+void TracePC::HandleInit(uintptr_t *Start, uintptr_t *Stop) {
   if (Start == Stop || *Start) return;
   assert(NumModules < sizeof(Modules) / sizeof(Modules[0]));
-  for (uint64_t *P = Start; P < Stop; P++)
-    *P = (++NumGuards) << 32;
+  for (uintptr_t *P = Start; P < Stop; P++)
+    *P = ++NumGuards;
   Modules[NumModules].Start = Start;
   Modules[NumModules].Stop = Stop;
   NumModules++;
@@ -63,30 +59,29 @@ void TracePC::PrintModuleInfo() {
 }
 
 void TracePC::ResetGuards() {
+  uintptr_t N = 0;
   for (size_t M = 0; M < NumModules; M++)
-    for (uint64_t *X = Modules[M].Start; X < Modules[M].Stop; X++)
-      *X = (*X >> 32) << 32;
+    for (uintptr_t *X = Modules[M].Start; X < Modules[M].Stop; X++)
+      *X = ++N;
+  assert(N == NumGuards);
 }
 
 void TracePC::FinalizeTrace() {
   if (UseCounters && TotalCoverage) {
-    for (size_t M = 0; M < NumModules; M++) {
-      for (uint64_t *X = Modules[M].Start; X < Modules[M].Stop; X++) {
-        uint64_t Value = *X & 0xff;
-        uint64_t Idx = *X >> 32;
-        if (Value >= 1) {
-          unsigned Bit = 0;
-          /**/ if (Value >= 128) Bit = 7;
-          else if (Value >= 32) Bit = 6;
-          else if (Value >= 16) Bit = 5;
-          else if (Value >= 8) Bit = 4;
-          else if (Value >= 4) Bit = 3;
-          else if (Value >= 3) Bit = 2;
-          else if (Value >= 2) Bit = 1;
-          CounterMap.AddValue(Idx * 8 + Bit);
-        }
-        *X = Idx << 32;
-      }
+    for (size_t Idx = 1, N = std::min(kNumCounters, NumGuards); Idx < N;
+         Idx++) {
+      uint8_t Counter = Counters[Idx];
+      if (!Counter) continue;
+      Counters[Idx] = 0;
+      unsigned Bit = 0;
+      /**/ if (Counter >= 128) Bit = 7;
+      else if (Counter >= 32) Bit = 6;
+      else if (Counter >= 16) Bit = 5;
+      else if (Counter >= 8) Bit = 4;
+      else if (Counter >= 4) Bit = 3;
+      else if (Counter >= 3) Bit = 2;
+      else if (Counter >= 2) Bit = 1;
+      CounterMap.AddValue(Idx * 8 + Bit);
     }
   }
 }
@@ -109,13 +104,13 @@ void TracePC::HandleCallerCallee(uintptr
 
 extern "C" {
 __attribute__((visibility("default")))
-void __sanitizer_cov_trace_pc_guard(uint64_t *Guard) {
+void __sanitizer_cov_trace_pc_guard(uintptr_t *Guard) {
   uintptr_t PC = (uintptr_t)__builtin_return_address(0);
   fuzzer::TPC.HandleTrace(Guard, PC);
 }
 
 __attribute__((visibility("default")))
-void __sanitizer_cov_trace_pc_guard_init(uint64_t *Start, uint64_t *Stop) {
+void __sanitizer_cov_trace_pc_guard_init(uintptr_t *Start, uintptr_t *Stop) {
   fuzzer::TPC.HandleInit(Start, Stop);
 }
 

Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=281845&r1=281844&r2=281845&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Sat Sep 17 23:52:23 2016
@@ -223,7 +223,7 @@ private:
   Function *SanCovTraceGepFunction;
   Function *SanCovTraceSwitchFunction;
   InlineAsm *EmptyAsm;
-  Type *IntptrTy, *Int64Ty, *Int64PtrTy;
+  Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy;
   Module *CurModule;
   LLVMContext *C;
   const DataLayout *DL;
@@ -243,6 +243,7 @@ bool SanitizerCoverageModule::runOnModul
   DL = &M.getDataLayout();
   CurModule = &M;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
+  IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
   IRBuilder<> IRB(*C);
   Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
@@ -293,7 +294,7 @@ bool SanitizerCoverageModule::runOnModul
   SanCovTracePC = checkSanitizerInterfaceFunction(
       M.getOrInsertFunction(SanCovTracePCName, VoidTy, nullptr));
   SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
-      SanCovTracePCGuardName, VoidTy, Int64PtrTy, nullptr));
+      SanCovTracePCGuardName, VoidTy, IntptrPtrTy, nullptr));
   SanCovTraceEnter = checkSanitizerInterfaceFunction(
       M.getOrInsertFunction(SanCovTraceEnterName, VoidTy, Int32PtrTy, nullptr));
   SanCovTraceBB = checkSanitizerInterfaceFunction(
@@ -355,15 +356,16 @@ bool SanitizerCoverageModule::runOnModul
     GlobalVariable *Bounds[2];
     const char *Prefix[2] = {"__start_", "__stop_"};
     for (int i = 0; i < 2; i++) {
-      Bounds[i] = new GlobalVariable(M, Int64PtrTy, false,
+      Bounds[i] = new GlobalVariable(M, IntptrPtrTy, false,
                                      GlobalVariable::ExternalLinkage, nullptr,
                                      Prefix[i] + SectionName);
       Bounds[i]->setVisibility(GlobalValue::HiddenVisibility);
     }
     std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
         M, SanCovModuleCtorName, SanCovTracePCGuardInitName,
-        {Int64PtrTy, Int64PtrTy}, {IRB.CreatePointerCast(Bounds[0], Int64PtrTy),
-                                 IRB.CreatePointerCast(Bounds[1], Int64PtrTy)});
+        {IntptrPtrTy, IntptrPtrTy},
+        {IRB.CreatePointerCast(Bounds[0], IntptrPtrTy),
+         IRB.CreatePointerCast(Bounds[1], IntptrPtrTy)});
 
     appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
 
@@ -669,13 +671,13 @@ void SanitizerCoverageModule::InjectCove
         Constant::getNullValue(Int64Ty), "__sancov_guard." + F.getName());
     // TODO: add debug into to GuardVar.
     GuardVar->setSection(SanCovTracePCGuardSection);
-    auto GuardPtr = IRB.CreatePointerCast(GuardVar, Int64PtrTy);
+    auto GuardPtr = IRB.CreatePointerCast(GuardVar, IntptrPtrTy);
     if (!UseCalls) {
       auto GuardLoad = IRB.CreateLoad(GuardPtr);
       GuardLoad->setAtomic(AtomicOrdering::Monotonic);
       GuardLoad->setAlignment(8);
       SetNoSanitizeMetadata(GuardLoad);  // Don't instrument with e.g. asan.
-      auto Cmp = IRB.CreateICmpSGE(
+      auto Cmp = IRB.CreateICmpNE(
           GuardLoad, Constant::getNullValue(GuardLoad->getType()));
       auto Ins = SplitBlockAndInsertIfThen(
           Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000));




More information about the llvm-commits mailing list