summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-09-10 02:17:40 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2015-09-10 02:17:40 +0000
commit2c7f7e31c4c0afc84f8614a48ef7e1449b458c58 (patch)
treec086262a5904b3d67a23e8baa1d5ae186989ad56 /clang/lib/CodeGen/CGExpr.cpp
parentd3b904d440fee3c869d8c8a2c33dffd8bc82b384 (diff)
downloadbcm5719-llvm-2c7f7e31c4c0afc84f8614a48ef7e1449b458c58.tar.gz
bcm5719-llvm-2c7f7e31c4c0afc84f8614a48ef7e1449b458c58.zip
CFI: Introduce -fsanitize=cfi-icall flag.
This flag causes the compiler to emit bit set entries for functions as well as runtime bitset checks at indirect call sites. Depends on the new function bitset mechanism. Differential Revision: http://reviews.llvm.org/D11857 llvm-svn: 247238
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 8339444c20e..5e6c4de4087 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3780,6 +3780,29 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
}
}
+ // If we are checking indirect calls and this call is indirect, check that the
+ // function pointer is a member of the bit set for the function type.
+ if (SanOpts.has(SanitizerKind::CFIICall) &&
+ (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
+ SanitizerScope SanScope(this);
+
+ llvm::Value *BitSetName = llvm::MetadataAsValue::get(
+ getLLVMContext(),
+ CGM.CreateMetadataIdentifierForType(QualType(FnType, 0)));
+
+ llvm::Value *CastedCallee = Builder.CreateBitCast(Callee, Int8PtrTy);
+ llvm::Value *BitSetTest =
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::bitset_test),
+ {CastedCallee, BitSetName});
+
+ llvm::Constant *StaticData[] = {
+ EmitCheckSourceLocation(E->getLocStart()),
+ EmitCheckTypeDescriptor(QualType(FnType, 0)),
+ };
+ EmitCheck(std::make_pair(BitSetTest, SanitizerKind::CFIICall),
+ "cfi_bad_icall", StaticData, CastedCallee);
+ }
+
CallArgList Args;
if (Chain)
Args.add(RValue::get(Builder.CreateBitCast(Chain, CGM.VoidPtrTy)),
OpenPOWER on IntegriCloud