diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 36 |
2 files changed, 25 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index eafe2667443..f7d9c8201d9 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -762,6 +762,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, if (CGM.getCodeGenOpts().ProfileSampleAccurate) Fn->addFnAttr("profile-sample-accurate"); + if (D && D->hasAttr<CFICanonicalJumpTableAttr>()) + Fn->addFnAttr("cfi-canonical-jump-table"); + if (getLangOpts().OpenCL) { // Add metadata for a kernel function. if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index b650526629b..8943b407bdc 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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>()) |