This revision was automatically updated to reflect the committed changes. Closed by commit rGfd5e26270660: [ModuleUtils][KCFI] Set patchable-function-prefix for synthesized functions (authored by samitolvanen).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D141172/new/ https://reviews.llvm.org/D141172 Files: clang/lib/CodeGen/CodeGenModule.cpp clang/test/CodeGen/kcfi.c llvm/lib/Transforms/Utils/ModuleUtils.cpp llvm/test/Instrumentation/AddressSanitizer/kcfi-offset.ll Index: llvm/test/Instrumentation/AddressSanitizer/kcfi-offset.ll =================================================================== --- /dev/null +++ llvm/test/Instrumentation/AddressSanitizer/kcfi-offset.ll @@ -0,0 +1,15 @@ +;; Test that we set patchable-function-prefix for asan.module_ctor when kcfi-offset is defined. + +; RUN: opt < %s -passes=asan -S | FileCheck %s + +; CHECK: @llvm.global_ctors = {{.*}}{ i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor } + +; CHECK: define internal void @asan.module_ctor() +; CHECK-SAME: #[[#ATTR:]] +; CHECK-SAME: !kcfi_type + +; CHECK: attributes #[[#ATTR]] = { {{.*}} "patchable-function-prefix"="3" } + +!llvm.module.flags = !{!0, !1} +!0 = !{i32 4, !"kcfi", i32 1} +!1 = !{i32 4, !"kcfi-offset", i32 3} Index: llvm/lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -161,6 +161,13 @@ MDNode::get(Ctx, MDB.createConstant(ConstantInt::get( Type::getInt32Ty(Ctx), static_cast<uint32_t>(xxHash64(MangledType)))))); + // If the module was compiled with -fpatchable-function-entry, ensure + // we use the same patchable-function-prefix. + if (auto *MD = mdconst::extract_or_null<ConstantInt>( + M.getModuleFlag("kcfi-offset"))) { + if (unsigned Offset = MD->getZExtValue()) + F.addFnAttr("patchable-function-prefix", std::to_string(Offset)); + } } FunctionCallee Index: clang/test/CodeGen/kcfi.c =================================================================== --- clang/test/CodeGen/kcfi.c +++ clang/test/CodeGen/kcfi.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -o - %s | FileCheck %s // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -x c++ -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fpatchable-function-entry-offset=3 -o - %s | FileCheck %s --check-prefixes=CHECK,OFFSET #if !__has_feature(kcfi) #error Missing kcfi? #endif @@ -54,5 +55,6 @@ } // CHECK-DAG: ![[#]] = !{i32 4, !"kcfi", i32 1} +// OFFSET-DAG: ![[#]] = !{i32 4, !"kcfi-offset", i32 3} // CHECK-DAG: ![[#TYPE]] = !{i32 [[#HASH]]} // CHECK-DAG: ![[#TYPE2]] = !{i32 [[#%d,HASH2:]]} Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -758,8 +758,14 @@ CodeGenOpts.SanitizeCfiCanonicalJumpTables); } - if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) + if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) { getModule().addModuleFlag(llvm::Module::Override, "kcfi", 1); + // KCFI assumes patchable-function-prefix is the same for all indirectly + // called functions. Store the expected offset for code generation. + if (CodeGenOpts.PatchableFunctionEntryOffset) + getModule().addModuleFlag(llvm::Module::Override, "kcfi-offset", + CodeGenOpts.PatchableFunctionEntryOffset); + } if (CodeGenOpts.CFProtectionReturn && Target.checkCFProtectionReturnSupported(getDiags())) {
Index: llvm/test/Instrumentation/AddressSanitizer/kcfi-offset.ll =================================================================== --- /dev/null +++ llvm/test/Instrumentation/AddressSanitizer/kcfi-offset.ll @@ -0,0 +1,15 @@ +;; Test that we set patchable-function-prefix for asan.module_ctor when kcfi-offset is defined. + +; RUN: opt < %s -passes=asan -S | FileCheck %s + +; CHECK: @llvm.global_ctors = {{.*}}{ i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor } + +; CHECK: define internal void @asan.module_ctor() +; CHECK-SAME: #[[#ATTR:]] +; CHECK-SAME: !kcfi_type + +; CHECK: attributes #[[#ATTR]] = { {{.*}} "patchable-function-prefix"="3" } + +!llvm.module.flags = !{!0, !1} +!0 = !{i32 4, !"kcfi", i32 1} +!1 = !{i32 4, !"kcfi-offset", i32 3} Index: llvm/lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -161,6 +161,13 @@ MDNode::get(Ctx, MDB.createConstant(ConstantInt::get( Type::getInt32Ty(Ctx), static_cast<uint32_t>(xxHash64(MangledType)))))); + // If the module was compiled with -fpatchable-function-entry, ensure + // we use the same patchable-function-prefix. + if (auto *MD = mdconst::extract_or_null<ConstantInt>( + M.getModuleFlag("kcfi-offset"))) { + if (unsigned Offset = MD->getZExtValue()) + F.addFnAttr("patchable-function-prefix", std::to_string(Offset)); + } } FunctionCallee Index: clang/test/CodeGen/kcfi.c =================================================================== --- clang/test/CodeGen/kcfi.c +++ clang/test/CodeGen/kcfi.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -o - %s | FileCheck %s // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -x c++ -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fpatchable-function-entry-offset=3 -o - %s | FileCheck %s --check-prefixes=CHECK,OFFSET #if !__has_feature(kcfi) #error Missing kcfi? #endif @@ -54,5 +55,6 @@ } // CHECK-DAG: ![[#]] = !{i32 4, !"kcfi", i32 1} +// OFFSET-DAG: ![[#]] = !{i32 4, !"kcfi-offset", i32 3} // CHECK-DAG: ![[#TYPE]] = !{i32 [[#HASH]]} // CHECK-DAG: ![[#TYPE2]] = !{i32 [[#%d,HASH2:]]} Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -758,8 +758,14 @@ CodeGenOpts.SanitizeCfiCanonicalJumpTables); } - if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) + if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) { getModule().addModuleFlag(llvm::Module::Override, "kcfi", 1); + // KCFI assumes patchable-function-prefix is the same for all indirectly + // called functions. Store the expected offset for code generation. + if (CodeGenOpts.PatchableFunctionEntryOffset) + getModule().addModuleFlag(llvm::Module::Override, "kcfi-offset", + CodeGenOpts.PatchableFunctionEntryOffset); + } if (CodeGenOpts.CFProtectionReturn && Target.checkCFProtectionReturnSupported(getDiags())) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits