|
@@ -535,6 +535,12 @@ void CodeGenModule::Release() {
|
|
|
getModule().addModuleFlag(llvm::Module::Override, "Cross-DSO CFI", 1);
|
|
|
}
|
|
|
|
|
|
+ if (LangOpts.Sanitize.has(SanitizerKind::CFIICall)) {
|
|
|
+ getModule().addModuleFlag(llvm::Module::Override,
|
|
|
+ "CFI Canonical Jump Tables",
|
|
|
+ CodeGenOpts.SanitizeCfiCanonicalJumpTables);
|
|
|
+ }
|
|
|
+
|
|
|
if (CodeGenOpts.CFProtectionReturn &&
|
|
|
Target.checkCFProtectionReturnSupported(getDiags())) {
|
|
|
// Indicate that we want to instrument return control flow protection.
|
|
@@ -1605,10 +1611,17 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
|
|
|
F->setAlignment(2);
|
|
|
}
|
|
|
|
|
|
- // In the cross-dso CFI mode, we want !type attributes on definitions only.
|
|
|
- if (CodeGenOpts.SanitizeCfiCrossDso)
|
|
|
- if (auto *FD = dyn_cast<FunctionDecl>(D))
|
|
|
- CreateFunctionTypeMetadataForIcall(FD, F);
|
|
|
+ // In the cross-dso CFI mode with canonical jump tables, we want !type
|
|
|
+ // attributes on definitions only.
|
|
|
+ if (CodeGenOpts.SanitizeCfiCrossDso &&
|
|
|
+ CodeGenOpts.SanitizeCfiCanonicalJumpTables) {
|
|
|
+ if (auto *FD = dyn_cast<FunctionDecl>(D)) {
|
|
|
+ // Skip available_externally functions. They won't be codegen'ed in the
|
|
|
+ // current module anyway.
|
|
|
+ if (getContext().GetGVALinkageForFunction(FD) != GVA_AvailableExternally)
|
|
|
+ CreateFunctionTypeMetadataForIcall(FD, F);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// Emit type metadata on member functions for member function pointer checks.
|
|
|
// These are only ever necessary on definitions; we're guaranteed that the
|
|
@@ -1765,14 +1778,6 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
|
|
|
if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
|
|
|
return;
|
|
|
|
|
|
- // Additionally, if building with cross-DSO support...
|
|
|
- if (CodeGenOpts.SanitizeCfiCrossDso) {
|
|
|
- // Skip available_externally functions. They won't be codegen'ed in the
|
|
|
- // current module anyway.
|
|
|
- if (getContext().GetGVALinkageForFunction(FD) == GVA_AvailableExternally)
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
llvm::Metadata *MD = CreateMetadataIdentifierForType(FD->getType());
|
|
|
F->addTypeMetadata(0, MD);
|
|
|
F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
|
|
@@ -1849,8 +1854,11 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
|
|
|
F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
|
|
|
|
|
// Don't emit entries for function declarations in the cross-DSO mode. This
|
|
|
- // is handled with better precision by the receiving DSO.
|
|
|
- if (!CodeGenOpts.SanitizeCfiCrossDso)
|
|
|
+ // is handled with better precision by the receiving DSO. But if jump tables
|
|
|
+ // are non-canonical then we need type metadata in order to produce the local
|
|
|
+ // jump table.
|
|
|
+ if (!CodeGenOpts.SanitizeCfiCrossDso ||
|
|
|
+ !CodeGenOpts.SanitizeCfiCanonicalJumpTables)
|
|
|
CreateFunctionTypeMetadataForIcall(FD, F);
|
|
|
|
|
|
if (getLangOpts().OpenMP && FD->hasAttr<OMPDeclareSimdDeclAttr>())
|