summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2017-08-10 15:00:13 +0000
committerAlexander Potapenko <glider@google.com>2017-08-10 15:00:13 +0000
commit5241081532ccc318579958ce9b7bed25e5ed9a45 (patch)
tree338b8f77df74fb9d8a035fa137bb4d56efe8f1f8 /llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
parentc3bcdc2f1a2c2e5476059870ba570987d15c3fe2 (diff)
downloadbcm5719-llvm-5241081532ccc318579958ce9b7bed25e5ed9a45.tar.gz
bcm5719-llvm-5241081532ccc318579958ce9b7bed25e5ed9a45.zip
[sanitizer-coverage] Change cmp instrumentation to distinguish const operands
This implementation of SanitizerCoverage instrumentation inserts different callbacks depending on constantness of operands: 1. If both operands are non-const, then a usual __sanitizer_cov_trace_cmp[1248] call is inserted. 2. If exactly one operand is const, then a __sanitizer_cov_trace_const_cmp[1248] call is inserted. The first argument of the call is always the constant one. 3. If both operands are const, then no callback is inserted. This separation comes useful in fuzzing when tasks like "find one operand of the comparison in input arguments and replace it with the other one" have to be done. The new instrumentation allows us to not waste time on searching the constant operands in the input. Patch by Victor Chibotaru. llvm-svn: 310600
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp')
-rw-r--r--llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp44
1 files changed, 40 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 767c2b03e18..de4b8da78fe 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -46,6 +46,14 @@ static const char *const SanCovTraceCmp1 = "__sanitizer_cov_trace_cmp1";
static const char *const SanCovTraceCmp2 = "__sanitizer_cov_trace_cmp2";
static const char *const SanCovTraceCmp4 = "__sanitizer_cov_trace_cmp4";
static const char *const SanCovTraceCmp8 = "__sanitizer_cov_trace_cmp8";
+static const char *const SanCovTraceConstCmp1 =
+ "__sanitizer_cov_trace_const_cmp1";
+static const char *const SanCovTraceConstCmp2 =
+ "__sanitizer_cov_trace_const_cmp2";
+static const char *const SanCovTraceConstCmp4 =
+ "__sanitizer_cov_trace_const_cmp4";
+static const char *const SanCovTraceConstCmp8 =
+ "__sanitizer_cov_trace_const_cmp8";
static const char *const SanCovTraceDiv4 = "__sanitizer_cov_trace_div4";
static const char *const SanCovTraceDiv8 = "__sanitizer_cov_trace_div8";
static const char *const SanCovTraceGep = "__sanitizer_cov_trace_gep";
@@ -204,12 +212,13 @@ private:
Function *SanCovTracePCIndir;
Function *SanCovTracePC, *SanCovTracePCGuard;
Function *SanCovTraceCmpFunction[4];
+ Function *SanCovTraceConstCmpFunction[4];
Function *SanCovTraceDivFunction[2];
Function *SanCovTraceGepFunction;
Function *SanCovTraceSwitchFunction;
InlineAsm *EmptyAsm;
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
- *Int8Ty, *Int8PtrTy;
+ *Int16Ty, *Int8Ty, *Int8PtrTy;
Module *CurModule;
Triple TargetTriple;
LLVMContext *C;
@@ -281,6 +290,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
Int64Ty = IRB.getInt64Ty();
Int32Ty = IRB.getInt32Ty();
+ Int16Ty = IRB.getInt16Ty();
Int8Ty = IRB.getInt8Ty();
SanCovTracePCIndir = checkSanitizerInterfaceFunction(
@@ -298,6 +308,19 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty));
+ SanCovTraceConstCmpFunction[0] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp1, VoidTy, Int8Ty, Int8Ty));
+ SanCovTraceConstCmpFunction[1] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp2, VoidTy, Int16Ty, Int16Ty));
+ SanCovTraceConstCmpFunction[2] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp4, VoidTy, Int32Ty, Int32Ty));
+ SanCovTraceConstCmpFunction[3] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty));
+
SanCovTraceDivFunction[0] =
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
SanCovTraceDiv4, VoidTy, IRB.getInt32Ty()));
@@ -316,6 +339,8 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
for (int i = 0; i < 3; i++) {
SanCovTraceCmpFunction[i]->addParamAttr(0, Attribute::ZExt);
SanCovTraceCmpFunction[i]->addParamAttr(1, Attribute::ZExt);
+ SanCovTraceConstCmpFunction[i]->addParamAttr(0, Attribute::ZExt);
+ SanCovTraceConstCmpFunction[i]->addParamAttr(1, Attribute::ZExt);
}
SanCovTraceDivFunction[0]->addParamAttr(0, Attribute::ZExt);
}
@@ -644,10 +669,21 @@ void SanitizerCoverageModule::InjectTraceForCmp(
TypeSize == 64 ? 3 : -1;
if (CallbackIdx < 0) continue;
// __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
+ auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
+ bool FirstIsConst = isa<ConstantInt>(A0);
+ bool SecondIsConst = isa<ConstantInt>(A1);
+ // If both are const, then we don't need such a comparison.
+ if (FirstIsConst && SecondIsConst) continue;
+ // If only one is const, then make it the first callback argument.
+ if (FirstIsConst || SecondIsConst) {
+ CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
+ if (SecondIsConst)
+ std::swap(A0, A1);
+ }
+
auto Ty = Type::getIntNTy(*C, TypeSize);
- IRB.CreateCall(
- SanCovTraceCmpFunction[CallbackIdx],
- {IRB.CreateIntCast(A0, Ty, true), IRB.CreateIntCast(A1, Ty, true)});
+ IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty, true),
+ IRB.CreateIntCast(A1, Ty, true)});
}
}
}
OpenPOWER on IntegriCloud