From 2bed90363fd0a646c9809864076c7c059b551bf4 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Sun, 18 Sep 2016 04:52:23 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Fuzzer/FuzzerInternal.h | 9 ++- lib/Fuzzer/FuzzerTracePC.cpp | 69 ++++++++++------------ .../Instrumentation/SanitizerCoverage.cpp | 16 ++--- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index 3cecd21ab46..4d05c08f0dd 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -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; }; diff --git a/lib/Fuzzer/FuzzerTracePC.cpp b/lib/Fuzzer/FuzzerTracePC.cpp index dbc136a8cb2..888e7b3d532 100644 --- a/lib/Fuzzer/FuzzerTracePC.cpp +++ b/lib/Fuzzer/FuzzerTracePC.cpp @@ -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_t Caller, uintptr_t Callee) { 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); } diff --git a/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 3c137c97679..a2755adc7fa 100644 --- a/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -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::runOnModule(Module &M) { 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::runOnModule(Module &M) { 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::runOnModule(Module &M) { 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::InjectCoverageAtBlock(Function &F, BasicBlock &BB, 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)); -- 2.11.0