@@ -158,8 +158,8 @@ static cl::opt<bool>
158
158
159
159
static cl::opt<bool > ClGatedCallbacks (
160
160
" 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 ." ),
163
163
cl::Hidden, cl::init(false ));
164
164
165
165
namespace {
@@ -234,17 +234,19 @@ class ModuleSanitizerCoverage {
234
234
void instrumentFunction (Function &F);
235
235
void InjectCoverageForIndirectCalls (Function &F,
236
236
ArrayRef<Instruction *> IndirCalls);
237
- void InjectTraceForCmp (Function &F, ArrayRef<Instruction *> CmpTraceTargets);
237
+ void InjectTraceForCmp (Function &F, ArrayRef<Instruction *> CmpTraceTargets,
238
+ Value *&FunctionGateCmp);
238
239
void InjectTraceForDiv (Function &F,
239
240
ArrayRef<BinaryOperator *> DivTraceTargets);
240
241
void InjectTraceForGep (Function &F,
241
242
ArrayRef<GetElementPtrInst *> GepTraceTargets);
242
243
void InjectTraceForLoadsAndStores (Function &F, ArrayRef<LoadInst *> Loads,
243
244
ArrayRef<StoreInst *> Stores);
244
245
void InjectTraceForSwitch (Function &F,
245
- ArrayRef<Instruction *> SwitchTraceTargets);
246
+ ArrayRef<Instruction *> SwitchTraceTargets,
247
+ Value *&FunctionGateCmp);
246
248
bool InjectCoverage (Function &F, ArrayRef<BasicBlock *> AllBlocks,
247
- bool IsLeafFunc);
249
+ Value *&FunctionGateCmp, bool IsLeafFunc);
248
250
GlobalVariable *CreateFunctionLocalArrayInSection (size_t NumElements,
249
251
Function &F, Type *Ty,
250
252
const char *Section);
@@ -494,9 +496,9 @@ bool ModuleSanitizerCoverage::instrumentModule() {
494
496
SanCovLowestStack->setInitializer (Constant::getAllOnesValue (IntptrTy));
495
497
496
498
if (Options.GatedCallbacks ) {
497
- if (!Options.TracePCGuard ) {
499
+ if (!Options.TracePCGuard && !Options. TraceCmp ) {
498
500
C->emitError (StringRef (" '" ) + ClGatedCallbacks.ArgStr +
499
- " ' is only supported with trace-pc-guard" );
501
+ " ' is only supported with trace-pc-guard or trace-cmp " );
500
502
return true ;
501
503
}
502
504
@@ -725,10 +727,11 @@ void ModuleSanitizerCoverage::instrumentFunction(Function &F) {
725
727
if (Options.CollectControlFlow )
726
728
createFunctionControlFlow (F);
727
729
728
- InjectCoverage (F, BlocksToInstrument, IsLeafFunc);
730
+ Value *FunctionGateCmp = nullptr ;
731
+ InjectCoverage (F, BlocksToInstrument, FunctionGateCmp, IsLeafFunc);
729
732
InjectCoverageForIndirectCalls (F, IndirCalls);
730
- InjectTraceForCmp (F, CmpTraceTargets);
731
- InjectTraceForSwitch (F, SwitchTraceTargets);
733
+ InjectTraceForCmp (F, CmpTraceTargets, FunctionGateCmp );
734
+ InjectTraceForSwitch (F, SwitchTraceTargets, FunctionGateCmp );
732
735
InjectTraceForDiv (F, DivTraceTargets);
733
736
InjectTraceForGep (F, GepTraceTargets);
734
737
InjectTraceForLoadsAndStores (F, Loads, Stores);
@@ -837,10 +840,10 @@ Instruction *ModuleSanitizerCoverage::CreateGateBranch(Function &F,
837
840
838
841
bool ModuleSanitizerCoverage::InjectCoverage (Function &F,
839
842
ArrayRef<BasicBlock *> AllBlocks,
843
+ Value *&FunctionGateCmp,
840
844
bool IsLeafFunc) {
841
845
if (AllBlocks.empty ()) return false ;
842
846
CreateFunctionLocalArrays (F, AllBlocks);
843
- Value *FunctionGateCmp = nullptr ;
844
847
for (size_t i = 0 , N = AllBlocks.size (); i < N; i++)
845
848
InjectCoverageAtBlock (F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc);
846
849
return true ;
@@ -874,7 +877,8 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
874
877
// {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
875
878
876
879
void ModuleSanitizerCoverage::InjectTraceForSwitch (
877
- Function &, ArrayRef<Instruction *> SwitchTraceTargets) {
880
+ Function &F, ArrayRef<Instruction *> SwitchTraceTargets,
881
+ Value *&FunctionGateCmp) {
878
882
for (auto *I : SwitchTraceTargets) {
879
883
if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
880
884
InstrumentationIRBuilder IRB (I);
@@ -905,7 +909,13 @@ void ModuleSanitizerCoverage::InjectTraceForSwitch(
905
909
*CurModule, ArrayOfInt64Ty, false , GlobalVariable::InternalLinkage,
906
910
ConstantArray::get (ArrayOfInt64Ty, Initializers),
907
911
" __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
+ }
909
919
}
910
920
}
911
921
}
@@ -969,7 +979,8 @@ void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
969
979
}
970
980
971
981
void ModuleSanitizerCoverage::InjectTraceForCmp (
972
- Function &, ArrayRef<Instruction *> CmpTraceTargets) {
982
+ Function &F, ArrayRef<Instruction *> CmpTraceTargets,
983
+ Value *&FunctionGateCmp) {
973
984
for (auto *I : CmpTraceTargets) {
974
985
if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
975
986
InstrumentationIRBuilder IRB (ICMP);
@@ -997,8 +1008,15 @@ void ModuleSanitizerCoverage::InjectTraceForCmp(
997
1008
}
998
1009
999
1010
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
+ }
1002
1020
}
1003
1021
}
1004
1022
}
0 commit comments