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
This commit is contained in:
Peter Collingbourne
2015-09-10 02:17:40 +00:00
parent d3b904d440
commit 2c7f7e31c4
19 changed files with 229 additions and 125 deletions

View File

@@ -941,6 +941,20 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
if (FD->isReplaceableGlobalAllocationFunction())
F->addAttribute(llvm::AttributeSet::FunctionIndex,
llvm::Attribute::NoBuiltin);
// If we are checking indirect calls and this is not a non-static member
// function, emit a bit set entry for the function type.
if (LangOpts.Sanitize.has(SanitizerKind::CFIICall) &&
!(isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())) {
llvm::NamedMDNode *BitsetsMD =
getModule().getOrInsertNamedMetadata("llvm.bitsets");
llvm::Metadata *BitsetOps[] = {
CreateMetadataIdentifierForType(FD->getType()),
llvm::ConstantAsMetadata::get(F),
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int64Ty, 0))};
BitsetsMD->addOperand(llvm::MDTuple::get(getLLVMContext(), BitsetOps));
}
}
void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) {
@@ -3824,12 +3838,8 @@ llvm::Metadata *CodeGenModule::CreateMetadataIdentifierForType(QualType T) {
llvm::MDTuple *CodeGenModule::CreateVTableBitSetEntry(
llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD) {
std::string OutName;
llvm::raw_string_ostream Out(OutName);
getCXXABI().getMangleContext().mangleCXXVTableBitSet(RD, Out);
llvm::Metadata *BitsetOps[] = {
llvm::MDString::get(getLLVMContext(), Out.str()),
CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)),
llvm::ConstantAsMetadata::get(VTable),
llvm::ConstantAsMetadata::get(
llvm::ConstantInt::get(Int64Ty, Offset.getQuantity()))};