From f31ea30694af66ffbd7e2e265090c97e1b91e8d9 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Wed, 3 Feb 2016 22:18:55 +0000 Subject: [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 --- clang/lib/CodeGen/CodeGenModule.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4d7f627..a30e624 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4021,6 +4021,20 @@ llvm::Metadata *CodeGenModule::CreateMetadataIdentifierForType(QualType T) { return InternalId; } +/// Returns whether this module needs the "all-vtables" bitset. +bool CodeGenModule::NeedAllVtablesBitSet() const { + // Returns true if at least one of vtable-based CFI checkers is enabled and + // is not in the trapping mode. + return ((LangOpts.Sanitize.has(SanitizerKind::CFIVCall) && + !CodeGenOpts.SanitizeTrap.has(SanitizerKind::CFIVCall)) || + (LangOpts.Sanitize.has(SanitizerKind::CFINVCall) && + !CodeGenOpts.SanitizeTrap.has(SanitizerKind::CFINVCall)) || + (LangOpts.Sanitize.has(SanitizerKind::CFIDerivedCast) && + !CodeGenOpts.SanitizeTrap.has(SanitizerKind::CFIDerivedCast)) || + (LangOpts.Sanitize.has(SanitizerKind::CFIUnrelatedCast) && + !CodeGenOpts.SanitizeTrap.has(SanitizerKind::CFIUnrelatedCast))); +} + void CodeGenModule::CreateVTableBitSetEntry(llvm::NamedMDNode *BitsetsMD, llvm::GlobalVariable *VTable, CharUnits Offset, @@ -4043,6 +4057,17 @@ void CodeGenModule::CreateVTableBitSetEntry(llvm::NamedMDNode *BitsetsMD, BitsetsMD->addOperand(llvm::MDTuple::get(getLLVMContext(), BitsetOps2)); } } + + if (NeedAllVtablesBitSet()) { + llvm::Metadata *MD = llvm::MDString::get(getLLVMContext(), "all-vtables"); + llvm::Metadata *BitsetOps[] = { + MD, llvm::ConstantAsMetadata::get(VTable), + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int64Ty, Offset.getQuantity()))}; + // Avoid adding a node to BitsetsMD twice. + if (!llvm::MDTuple::getIfExists(getLLVMContext(), BitsetOps)) + BitsetsMD->addOperand(llvm::MDTuple::get(getLLVMContext(), BitsetOps)); + } } // Fills in the supplied string map with the set of target features for the -- cgit v1.1