llvm.org GIT mirror llvm / 111f62d
[sanitizer-coverage] one more flavor of coverage: -fsanitize-coverage=inline-8bit-counters. Experimental so far, not documenting yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304630 91177308-0d34-0410-b5e6-96231b3b80d8 Kostya Serebryany 2 years ago
3 changed file(s) with 57 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
176176 bool Use8bitCounters = false;
177177 bool TracePC = false;
178178 bool TracePCGuard = false;
179 bool Inline8bitCounters = false;
179180 bool NoPrune = false;
180181
181182 SanitizerCoverageOptions() = default;
5656 "__sanitizer_cov_trace_pc_guard";
5757 static const char *const SanCovTracePCGuardInitName =
5858 "__sanitizer_cov_trace_pc_guard_init";
59 static const char *const SanCov8bitCountersInitName =
60 "__sanitizer_cov_8bit_counters_init";
5961
6062 static const char *const SanCovGuardsSectionName = "sancov_guards";
63 static const char *const SanCovCountersSectionName = "sancov_counters";
6164
6265 static cl::opt ClCoverageLevel(
6366 "sanitizer-coverage-level",
6568 "3: all blocks and critical edges"),
6669 cl::Hidden, cl::init(0));
6770
68 static cl::opt ClExperimentalTracePC("sanitizer-coverage-trace-pc",
69 cl::desc("Experimental pc tracing"),
70 cl::Hidden, cl::init(false));
71 static cl::opt ClTracePC("sanitizer-coverage-trace-pc",
72 cl::desc("Experimental pc tracing"), cl::Hidden,
73 cl::init(false));
7174
7275 static cl::opt ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
7376 cl::desc("pc tracing with a guard"),
77 cl::Hidden, cl::init(false));
78
79 static cl::opt ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters",
80 cl::desc("increments 8-bit counter for every edge"),
7481 cl::Hidden, cl::init(false));
7582
7683 static cl::opt
124131 Options.TraceCmp |= ClCMPTracing;
125132 Options.TraceDiv |= ClDIVTracing;
126133 Options.TraceGep |= ClGEPTracing;
127 Options.TracePC |= ClExperimentalTracePC;
134 Options.TracePC |= ClTracePC;
128135 Options.TracePCGuard |= ClTracePCGuard;
129 if (!Options.TracePCGuard && !Options.TracePC)
136 Options.Inline8bitCounters |= ClInline8bitCounters;
137 if (!Options.TracePCGuard && !Options.TracePC && !Options.Inline8bitCounters)
130138 Options.TracePCGuard = true; // TracePCGuard is default.
131139 Options.NoPrune |= !ClPruneBlocks;
132140 return Options;
168176 void CreateInitCallForSection(Module &M, const char *InitFunctionName,
169177 Type *Ty, const std::string &Section);
170178
179 void SetNoSanitizeMetadata(Instruction *I) {
180 I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
181 MDNode::get(*C, None));
182 }
183
171184 std::string getSectionName(const std::string &Section) const;
172185 std::string getSectionStart(const std::string &Section) const;
173186 std::string getSectionEnd(const std::string &Section) const;
178191 Function *SanCovTraceGepFunction;
179192 Function *SanCovTraceSwitchFunction;
180193 InlineAsm *EmptyAsm;
181 Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy;
194 Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
195 *Int8Ty, *Int8PtrTy;
182196 Module *CurModule;
183197 Triple TargetTriple;
184198 LLVMContext *C;
185199 const DataLayout *DL;
186200
187201 GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
202 GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters.
188203
189204 SanitizerCoverageOptions Options;
190205 };
226241 CurModule = &M;
227242 TargetTriple = Triple(M.getTargetTriple());
228243 FunctionGuardArray = nullptr;
244 Function8bitCounterArray = nullptr;
229245 IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
230246 IntptrPtrTy = PointerType::getUnqual(IntptrTy);
231247 Type *VoidTy = Type::getVoidTy(*C);
232248 IRBuilder<> IRB(*C);
233249 Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
234250 Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
251 Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
235252 Int64Ty = IRB.getInt64Ty();
236253 Int32Ty = IRB.getInt32Ty();
254 Int8Ty = IRB.getInt8Ty();
237255
238256 SanCovTracePCIndir = checkSanitizerInterfaceFunction(
239257 M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy));
279297 if (FunctionGuardArray)
280298 CreateInitCallForSection(M, SanCovTracePCGuardInitName, Int32PtrTy,
281299 SanCovGuardsSectionName);
300 if (Function8bitCounterArray)
301 CreateInitCallForSection(M, SanCov8bitCountersInitName, Int8PtrTy,
302 SanCovCountersSectionName);
282303
283304 return true;
284305 }
419440 if (Options.TracePCGuard)
420441 FunctionGuardArray = CreateFunctionLocalArrayInSection(
421442 NumGuards, F, Int32Ty, SanCovGuardsSectionName);
443 if (Options.Inline8bitCounters)
444 Function8bitCounterArray = CreateFunctionLocalArrayInSection(
445 NumGuards, F, Int8Ty, SanCovCountersSectionName);
422446 }
423447
424448 bool SanitizerCoverageModule::InjectCoverage(Function &F,
451475 Function &F, ArrayRef IndirCalls) {
452476 if (IndirCalls.empty())
453477 return;
454 assert(Options.TracePC || Options.TracePCGuard);
478 assert(Options.TracePC || Options.TracePCGuard || Options.Inline8bitCounters);
455479 for (auto I : IndirCalls) {
456480 IRBuilder<> IRB(I);
457481 CallSite CS(I);
579603 if (Options.TracePC) {
580604 IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC.
581605 IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
582 } else {
583 assert(Options.TracePCGuard);
606 }
607 if (Options.TracePCGuard) {
584608 auto GuardPtr = IRB.CreateIntToPtr(
585609 IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
586610 ConstantInt::get(IntptrTy, Idx * 4)),
587611 Int32PtrTy);
588612 IRB.CreateCall(SanCovTracePCGuard, GuardPtr);
589613 IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
614 }
615 if (Options.Inline8bitCounters) {
616 auto CounterPtr = IRB.CreateGEP(
617 Function8bitCounterArray,
618 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
619 auto Load = IRB.CreateLoad(CounterPtr);
620 auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
621 auto Store = IRB.CreateStore(Inc, CounterPtr);
622 SetNoSanitizeMetadata(Load);
623 SetNoSanitizeMetadata(Store);
590624 }
591625 }
592626
0 ; Test -sanitizer-coverage-inline-8bit-counters=1
1 ; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -S | FileCheck %s
2
3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
4 target triple = "x86_64-unknown-linux-gnu"
5 define void @foo() {
6 entry:
7 ; CHECK: %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize
8 ; CHECK: %1 = add i8 %0, 1
9 ; CHECK: store i8 %1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize
10 ret void
11 }
12 ; CHECK: call void @__sanitizer_cov_8bit_counters_init(i8* bitcast (i8** @__start___sancov_counters to i8*), i8* bitcast (i8** @__stop___sancov_counters to i8*))