[clang] [CodeGen] Set attributes on resolvers emitted after ifuncs (PR #98832)
Fangrui Song via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 14 12:57:18 PDT 2024
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/98832
>From 15011e64e79627a3de2e4434549fabbf7fe86e09 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sun, 14 Jul 2024 12:11:17 -0700
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
clang/lib/CodeGen/CodeGenModule.cpp | 19 ++++++++++++-------
clang/test/CodeGen/ifunc.c | 9 ++++-----
clang/test/CodeGen/kcfi.c | 20 ++++++++++----------
3 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 08cfa694cfb81..250041d380cb1 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -721,6 +721,11 @@ void CodeGenModule::checkAliases() {
cast<llvm::GlobalAlias>(Alias)->setAliasee(Aliasee);
}
}
+ // ifunc resolvers are usually implemented to run before sanitizer
+ // initialization. Disable instrumentation to prevent the ordering issue.
+ if (IsIFunc)
+ cast<llvm::Function>(Aliasee)->addFnAttr(
+ llvm::Attribute::DisableSanitizerInstrumentation);
}
if (!Error)
return;
@@ -6106,11 +6111,14 @@ void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) {
Aliases.push_back(GD);
+ // The resolver might not be visited yet. Specify a dummy non-function type to
+ // indicate IsIncompleteFunction. Either the type is ignored (if the resolver
+ // was emitted or will be eagerly emitted) or the whole function will replaced
+ // (if the resolver will be inserted into DeferredDeclsToEmit).
+ llvm::Constant *Resolver = GetOrCreateLLVMFunction(
+ IFA->getResolver(), llvm::Type::getVoidTy(getLLVMContext()), {},
+ /*ForVTable=*/false);
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
- llvm::Type *ResolverTy = llvm::GlobalIFunc::getResolverFunctionType(DeclTy);
- llvm::Constant *Resolver =
- GetOrCreateLLVMFunction(IFA->getResolver(), ResolverTy, {},
- /*ForVTable=*/false);
llvm::GlobalIFunc *GIF =
llvm::GlobalIFunc::create(DeclTy, 0, llvm::Function::ExternalLinkage,
"", Resolver, &getModule());
@@ -6134,9 +6142,6 @@ void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) {
Entry->eraseFromParent();
} else
GIF->setName(MangledName);
- if (auto *F = dyn_cast<llvm::Function>(Resolver)) {
- F->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
- }
SetCommonAttributes(GD, GIF);
}
diff --git a/clang/test/CodeGen/ifunc.c b/clang/test/CodeGen/ifunc.c
index b049739daf2aa..58a00ada687cb 100644
--- a/clang/test/CodeGen/ifunc.c
+++ b/clang/test/CodeGen/ifunc.c
@@ -58,12 +58,11 @@ extern void hoo(int) __attribute__ ((ifunc("hoo_ifunc")));
// CHECK: call i32 @foo(i32
// CHECK: call void @goo()
-// SAN: define internal nonnull {{(noundef )?}}ptr @foo_ifunc() #[[#FOO_IFUNC:]] {
-
// SAN: define {{(dso_local )?}}noalias {{(noundef )?}}ptr @goo_ifunc() #[[#GOO_IFUNC:]] {
-// SAN: define {{(dso_local )?}}noalias {{(noundef )?}}ptr @hoo_ifunc() #[[#HOO_IFUNC:]] {
+// SAN: define {{(dso_local )?}}noalias {{(noundef )?}}ptr @hoo_ifunc() #[[#GOO_IFUNC]] {
+
+// SAN: define internal {{(noundef )?}}nonnull ptr @foo_ifunc() #[[#FOO_IFUNC:]] {
-// SAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}
// SAN-DAG: attributes #[[#GOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}
-// SAN-DAG: attributes #[[#HOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}
+// SAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}
diff --git a/clang/test/CodeGen/kcfi.c b/clang/test/CodeGen/kcfi.c
index c29429f644ba1..622843cedba50 100644
--- a/clang/test/CodeGen/kcfi.c
+++ b/clang/test/CodeGen/kcfi.c
@@ -33,16 +33,6 @@ int call(fn_t f) {
return f();
}
-#ifndef __cplusplus
-// C: define internal ptr @resolver1() #[[#]] {
-int ifunc1(int) __attribute__((ifunc("resolver1")));
-static void *resolver1(void) { return 0; }
-
-// C: define internal ptr @resolver2() #[[#]] {
-static void *resolver2(void) { return 0; }
-long ifunc2(long) __attribute__((ifunc("resolver2")));
-#endif
-
// CHECK-DAG: define internal{{.*}} i32 @{{f3|_ZL2f3v}}(){{.*}} !kcfi_type ![[#TYPE]]
static int f3(void) { return 1; }
@@ -58,6 +48,16 @@ static int f5(void) { return 2; }
// CHECK-DAG: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @{{f6|_Z2f6v}}()
extern int f6(void);
+#ifndef __cplusplus
+// C: define internal ptr @resolver1() #[[#]] !kcfi_type ![[#]] {
+int ifunc1(int) __attribute__((ifunc("resolver1")));
+static void *resolver1(void) { return 0; }
+
+// C: define internal ptr @resolver2() #[[#]] !kcfi_type ![[#]] {
+static void *resolver2(void) { return 0; }
+long ifunc2(long) __attribute__((ifunc("resolver2")));
+#endif
+
int test(void) {
return call(f1) +
__call((fn_t)f2) +
>From a7e188949b0dcf6025d6f547d20a5a6d9aba57c3 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sun, 14 Jul 2024 12:57:10 -0700
Subject: [PATCH 2/2] .
Created using spr 1.3.5-bogner
---
clang/lib/CodeGen/CodeGenModule.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 250041d380cb1..46681d2c0a43e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -6113,11 +6113,11 @@ void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) {
// The resolver might not be visited yet. Specify a dummy non-function type to
// indicate IsIncompleteFunction. Either the type is ignored (if the resolver
- // was emitted or will be eagerly emitted) or the whole function will replaced
- // (if the resolver will be inserted into DeferredDeclsToEmit).
- llvm::Constant *Resolver = GetOrCreateLLVMFunction(
- IFA->getResolver(), llvm::Type::getVoidTy(getLLVMContext()), {},
- /*ForVTable=*/false);
+ // was emitted) or the whole function will be replaced (if the resolver has
+ // not be emitted).
+ llvm::Constant *Resolver =
+ GetOrCreateLLVMFunction(IFA->getResolver(), VoidTy, {},
+ /*ForVTable=*/false);
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
llvm::GlobalIFunc *GIF =
llvm::GlobalIFunc::create(DeclTy, 0, llvm::Function::ExternalLinkage,
More information about the cfe-commits
mailing list