[libFuzzer] change trace-pc to use 8-byte guards

llvm-svn: 281810
diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
index f729a5e..8fa9257 100644
--- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp
+++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
@@ -18,49 +18,67 @@
 
 TracePC TPC;
 
-void TracePC::HandleTrace(uint8_t *Guard, uintptr_t PC) {
+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);
   if (UseCounters) {
-    uintptr_t GV = *Guard;
-    if (GV == 0) {
-      size_t Idx = Guard - Start;
+    uint64_t Counter = Value & 0xff;
+    if (Counter == 0) {
+      size_t Idx = Value >> 32;
       if (TotalCoverageMap.AddValue(Idx)) {
         TotalCoverage++;
         AddNewPC(PC);
       }
     }
-    if (GV < 255)
-      GV++;
-    *Guard = GV;
+    if (Counter < 255)
+      Value++;
   } else {
-    *Guard = 0xff;
+    Value |= kBit63;
     TotalCoverage++;
     AddNewPC(PC);
   }
+  // Printf("   << %16zx\n", Value);
+  *Guard = Value;
 }
 
-void TracePC::HandleInit(uint8_t *Start, uint8_t *Stop) {
-  // TODO: this handles only one DSO/binary.
-  this->Start = Start;
-  this->Stop = Stop;
+void TracePC::HandleInit(uint64_t *Start, uint64_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;
+  Modules[NumModules].Start = Start;
+  Modules[NumModules].Stop = Stop;
+  NumModules++;
+}
+
+void TracePC::PrintModuleInfo() {
+  Printf("INFO: Loaded %zd modules (%zd guards): ", NumModules, NumGuards);
+  for (size_t i = 0; i < NumModules; i++)
+    Printf("[%p, %p), ", Modules[i].Start, Modules[i].Stop);
+  Printf("\n");
 }
 
 void TracePC::FinalizeTrace() {
   if (UseCounters && TotalCoverage) {
-    for (uint8_t *X = Start; X < Stop; X++) {
-      uint8_t Value = *X;
-      size_t Idx = X - Start;
-      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);
+    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;
       }
-      *X = 0;
     }
   }
 }
@@ -83,13 +101,13 @@
 
 extern "C" {
 __attribute__((visibility("default")))
-void __sanitizer_cov_trace_pc_guard(uint8_t *Guard) {
+void __sanitizer_cov_trace_pc_guard(uint64_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(uint8_t *Start, uint8_t *Stop) {
+void __sanitizer_cov_trace_pc_guard_init(uint64_t *Start, uint64_t *Stop) {
   fuzzer::TPC.HandleInit(Start, Stop);
 }