@@ -158,8 +158,8 @@ static cl::opt<bool>
158158
159159static cl::opt<bool > ClGatedCallbacks (
160160 " sanitizer-coverage-gated-trace-callbacks" ,
161- cl::desc (" Gate the invocation of the tracing callbacks on a global "
162- " variable . Currently only supported for trace-pc-guard." ),
161+ cl::desc (" Gate the invocation of the tracing callbacks on a global variable "
162+ " . Currently only supported for trace-pc-guard and trace-cmp ." ),
163163 cl::Hidden, cl::init(false ));
164164
165165namespace {
@@ -234,17 +234,19 @@ class ModuleSanitizerCoverage {
234234 void instrumentFunction (Function &F);
235235 void InjectCoverageForIndirectCalls (Function &F,
236236 ArrayRef<Instruction *> IndirCalls);
237- void InjectTraceForCmp (Function &F, ArrayRef<Instruction *> CmpTraceTargets);
237+ void InjectTraceForCmp (Function &F, ArrayRef<Instruction *> CmpTraceTargets,
238+ Value *&FunctionGateCmp);
238239 void InjectTraceForDiv (Function &F,
239240 ArrayRef<BinaryOperator *> DivTraceTargets);
240241 void InjectTraceForGep (Function &F,
241242 ArrayRef<GetElementPtrInst *> GepTraceTargets);
242243 void InjectTraceForLoadsAndStores (Function &F, ArrayRef<LoadInst *> Loads,
243244 ArrayRef<StoreInst *> Stores);
244245 void InjectTraceForSwitch (Function &F,
245- ArrayRef<Instruction *> SwitchTraceTargets);
246+ ArrayRef<Instruction *> SwitchTraceTargets,
247+ Value *&FunctionGateCmp);
246248 bool InjectCoverage (Function &F, ArrayRef<BasicBlock *> AllBlocks,
247- bool IsLeafFunc);
249+ Value *&FunctionGateCmp, bool IsLeafFunc);
248250 GlobalVariable *CreateFunctionLocalArrayInSection (size_t NumElements,
249251 Function &F, Type *Ty,
250252 const char *Section);
@@ -494,9 +496,9 @@ bool ModuleSanitizerCoverage::instrumentModule() {
494496 SanCovLowestStack->setInitializer (Constant::getAllOnesValue (IntptrTy));
495497
496498 if (Options.GatedCallbacks ) {
497- if (!Options.TracePCGuard ) {
499+ if (!Options.TracePCGuard && !Options. TraceCmp ) {
498500 C->emitError (StringRef (" '" ) + ClGatedCallbacks.ArgStr +
499- " ' is only supported with trace-pc-guard" );
501+ " ' is only supported with trace-pc-guard or trace-cmp " );
500502 return true ;
501503 }
502504
@@ -725,10 +727,11 @@ void ModuleSanitizerCoverage::instrumentFunction(Function &F) {
725727 if (Options.CollectControlFlow )
726728 createFunctionControlFlow (F);
727729
728- InjectCoverage (F, BlocksToInstrument, IsLeafFunc);
730+ Value *FunctionGateCmp = nullptr ;
731+ InjectCoverage (F, BlocksToInstrument, FunctionGateCmp, IsLeafFunc);
729732 InjectCoverageForIndirectCalls (F, IndirCalls);
730- InjectTraceForCmp (F, CmpTraceTargets);
731- InjectTraceForSwitch (F, SwitchTraceTargets);
733+ InjectTraceForCmp (F, CmpTraceTargets, FunctionGateCmp );
734+ InjectTraceForSwitch (F, SwitchTraceTargets, FunctionGateCmp );
732735 InjectTraceForDiv (F, DivTraceTargets);
733736 InjectTraceForGep (F, GepTraceTargets);
734737 InjectTraceForLoadsAndStores (F, Loads, Stores);
@@ -837,10 +840,10 @@ Instruction *ModuleSanitizerCoverage::CreateGateBranch(Function &F,
837840
838841bool ModuleSanitizerCoverage::InjectCoverage (Function &F,
839842 ArrayRef<BasicBlock *> AllBlocks,
843+ Value *&FunctionGateCmp,
840844 bool IsLeafFunc) {
841845 if (AllBlocks.empty ()) return false ;
842846 CreateFunctionLocalArrays (F, AllBlocks);
843- Value *FunctionGateCmp = nullptr ;
844847 for (size_t i = 0 , N = AllBlocks.size (); i < N; i++)
845848 InjectCoverageAtBlock (F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc);
846849 return true ;
@@ -874,7 +877,8 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
874877// {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
875878
876879void ModuleSanitizerCoverage::InjectTraceForSwitch (
877- Function &, ArrayRef<Instruction *> SwitchTraceTargets) {
880+ Function &F, ArrayRef<Instruction *> SwitchTraceTargets,
881+ Value *&FunctionGateCmp) {
878882 for (auto *I : SwitchTraceTargets) {
879883 if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
880884 InstrumentationIRBuilder IRB (I);
@@ -905,7 +909,13 @@ void ModuleSanitizerCoverage::InjectTraceForSwitch(
905909 *CurModule, ArrayOfInt64Ty, false , GlobalVariable::InternalLinkage,
906910 ConstantArray::get (ArrayOfInt64Ty, Initializers),
907911 " __sancov_gen_cov_switch_values" );
908- IRB.CreateCall (SanCovTraceSwitchFunction, {Cond, GV});
912+ if (Options.GatedCallbacks ) {
913+ auto GateBranch = CreateGateBranch (F, FunctionGateCmp, I);
914+ IRBuilder<> GateIRB (GateBranch);
915+ GateIRB.CreateCall (SanCovTraceSwitchFunction, {Cond, GV});
916+ } else {
917+ IRB.CreateCall (SanCovTraceSwitchFunction, {Cond, GV});
918+ }
909919 }
910920 }
911921}
@@ -969,7 +979,8 @@ void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
969979}
970980
971981void ModuleSanitizerCoverage::InjectTraceForCmp (
972- Function &, ArrayRef<Instruction *> CmpTraceTargets) {
982+ Function &F, ArrayRef<Instruction *> CmpTraceTargets,
983+ Value *&FunctionGateCmp) {
973984 for (auto *I : CmpTraceTargets) {
974985 if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
975986 InstrumentationIRBuilder IRB (ICMP);
@@ -997,8 +1008,15 @@ void ModuleSanitizerCoverage::InjectTraceForCmp(
9971008 }
9981009
9991010 auto Ty = Type::getIntNTy (*C, TypeSize);
1000- IRB.CreateCall (CallbackFunc, {IRB.CreateIntCast (A0, Ty, true ),
1001- IRB.CreateIntCast (A1, Ty, true )});
1011+ if (Options.GatedCallbacks ) {
1012+ auto GateBranch = CreateGateBranch (F, FunctionGateCmp, I);
1013+ IRBuilder<> GateIRB (GateBranch);
1014+ GateIRB.CreateCall (CallbackFunc, {GateIRB.CreateIntCast (A0, Ty, true ),
1015+ GateIRB.CreateIntCast (A1, Ty, true )});
1016+ } else {
1017+ IRB.CreateCall (CallbackFunc, {IRB.CreateIntCast (A0, Ty, true ),
1018+ IRB.CreateIntCast (A1, Ty, true )});
1019+ }
10021020 }
10031021 }
10041022}
0 commit comments