diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-02-03 22:18:55 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-02-03 22:18:55 +0000 |
commit | f31ea30694af66ffbd7e2e265090c97e1b91e8d9 (patch) | |
tree | e3d8aeb52cf82910b95cc3849c82f7362d84d7e6 /clang/lib/CodeGen/CGExpr.cpp | |
parent | 0cdb86bd382c26c6543540961fc2c3a54d6bf1f8 (diff) | |
download | bcm5719-llvm-f31ea30694af66ffbd7e2e265090c97e1b91e8d9.tar.gz bcm5719-llvm-f31ea30694af66ffbd7e2e265090c97e1b91e8d9.zip |
[cfi] Safe handling of unaddressable vtable pointers (clang).
Avoid crashing when printing diagnostics for vtable-related CFI
errors. In diagnostic mode, the frontend does an additional check of
the vtable pointer against the set of all known vtable addresses and
lets the runtime handler know if it is safe to inspect the vtable.
http://reviews.llvm.org/D16823
llvm-svn: 259716
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 10547a4ecf0..0855b450797 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2636,6 +2636,14 @@ void CodeGenFunction::EmitCfiCheckFail() { Address CheckKindAddr(V, getIntAlign()); llvm::Value *CheckKind = Builder.CreateLoad(CheckKindAddr); + llvm::Value *AllVtables = llvm::MetadataAsValue::get( + CGM.getLLVMContext(), + llvm::MDString::get(CGM.getLLVMContext(), "all-vtables")); + llvm::Value *ValidVtable = Builder.CreateZExt( + Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::bitset_test), + {Addr, AllVtables}), + IntPtrTy); + const std::pair<int, SanitizerMask> CheckKinds[] = { {CFITCK_VCall, SanitizerKind::CFIVCall}, {CFITCK_NVCall, SanitizerKind::CFINVCall}, @@ -2649,7 +2657,8 @@ void CodeGenFunction::EmitCfiCheckFail() { SanitizerMask Mask = CheckKindMaskPair.second; llvm::Value *Cond = Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind)); - EmitCheck(std::make_pair(Cond, Mask), "cfi_check_fail", {}, {Data, Addr}); + EmitCheck(std::make_pair(Cond, Mask), "cfi_check_fail", {}, + {Data, Addr, ValidVtable}); } FinishFunction(); @@ -3970,7 +3979,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, CastedCallee, StaticData); } else { EmitCheck(std::make_pair(BitSetTest, SanitizerKind::CFIICall), - "cfi_check_fail", StaticData, CastedCallee); + "cfi_check_fail", StaticData, + {CastedCallee, llvm::UndefValue::get(IntPtrTy)}); } } |