Skip to content

[clang] Support __attribute__((ifunc(...))) on Darwin platforms #73687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

jroelofs
Copy link
Contributor

Unlike ELF targets, MachO does not support the same kind of dynamic symbol
resolution at load time. Instead, the corresponding MachO feature resolves
symbols lazily on first call.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 28, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2023

@llvm/pr-subscribers-clang

Author: Jon Roelofs (jroelofs)

Changes

Unlike ELF targets, MachO does not support the same kind of dynamic symbol
resolution at load time. Instead, the corresponding MachO feature resolves
symbols lazily on first call.


Full diff: https://github.com/llvm/llvm-project/pull/73687.diff

3 Files Affected:

  • (modified) clang/include/clang/Basic/Attr.td (+4-1)
  • (modified) clang/include/clang/Basic/AttrDocs.td (+3-1)
  • (modified) clang/test/CodeGen/ifunc.c (+8)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 03ed6accf700c4e..cef9f5578fa2baa 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -455,6 +455,9 @@ def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch6
 def TargetELF : TargetSpec {
   let ObjectFormats = ["ELF"];
 }
+def TargetELFOrMachO : TargetSpec {
+  let ObjectFormats = ["ELF", "MachO"];
+}
 
 def TargetSupportsInitPriority : TargetSpec {
   let CustomCode = [{ !Target.getTriple().isOSzOS() }];
@@ -1665,7 +1668,7 @@ def IBOutletCollection : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def IFunc : Attr, TargetSpecificAttr<TargetELF> {
+def IFunc : Attr, TargetSpecificAttr<TargetELFOrMachO> {
   let Spellings = [GCC<"ifunc">];
   let Args = [StringArgument<"Resolver">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index be74535e28d8a60..4c4c4eb606fb0dc 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5408,7 +5408,9 @@ considered inline.
 Not all targets support this attribute. ELF target support depends on both the
 linker and runtime linker, and is available in at least lld 4.0 and later,
 binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
-Non-ELF targets currently do not support this attribute.
+MachO targets support it, but with slightly different semantics: the resolver is
+run at first call, instead of at load time by the runtime linker. Targets other
+than ELF and MachO currently do not support this attribute.
   }];
 }
 
diff --git a/clang/test/CodeGen/ifunc.c b/clang/test/CodeGen/ifunc.c
index 0b0a0549620f8b8..99d60dc0ea85dbd 100644
--- a/clang/test/CodeGen/ifunc.c
+++ b/clang/test/CodeGen/ifunc.c
@@ -3,6 +3,10 @@
 // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
 // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
 // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsanitize=memory -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -O2 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN
 
 int foo(int) __attribute__ ((ifunc("foo_ifunc")));
 
@@ -44,9 +48,13 @@ void* goo_ifunc(void) {
 // CHECK: call void @goo()
 
 // SAN: define internal nonnull ptr @foo_ifunc() #[[#FOO_IFUNC:]] {
+// MACSAN: define internal nonnull ptr @foo_ifunc() #[[#FOO_IFUNC:]] {
 
 // SAN: define dso_local noalias ptr @goo_ifunc() #[[#GOO_IFUNC:]] {
+// MACSAN: define noalias ptr @goo_ifunc() #[[#GOO_IFUNC:]] {
 
 // SAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}
+// MACSAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}
 
 // SAN-DAG: attributes #[[#GOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}
+// MACSAN-DAG: attributes #[[#GOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}}

Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
@echristo
Copy link
Contributor

Do you need an OS version check here?

@tahonermann
Copy link
Contributor

Added @erichkeane as a reviewer.

I recommend extending test coverage to all of the following tests:

  • clang/test/CodeGenCXX/externc-ifunc-resolver.cpp
  • clang/test/SemaCXX/externc-ifunc-resolver.cpp
  • clang/test/CodeGen/ifunc.c (already done)
  • clang/test/CodeGen/attr-ifunc.cpp
  • clang/test/CodeGen/attr-ifunc.c

@jroelofs
Copy link
Contributor Author

Do you need an OS version check here?

I don't think so, at least not yet. With #73686, support for this is entirely up to the compiler.

@echristo
Copy link
Contributor

echristo commented Nov 29, 2023 via email

Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4
Created using spr 1.3.4
@jroelofs jroelofs changed the base branch from users/jroelofs/spr/main.clang-support-__attribute__ifunc-on-darwin-platforms to main December 14, 2023 21:52
@jroelofs jroelofs merged commit acf9aa3 into main Dec 14, 2023
@jroelofs jroelofs deleted the users/jroelofs/spr/clang-support-__attribute__ifunc-on-darwin-platforms branch December 14, 2023 21:52
jroelofs added a commit to swiftlang/llvm-project that referenced this pull request Jan 10, 2024
Unlike ELF targets, MachO does not support the same kind of dynamic symbol
resolution at load time.  Instead, the corresponding MachO feature resolves
symbols lazily on first call.

Reviewers:
JDevlieghere, dmpolukhin, ahmedbougacha, tahonermann, echristo, MaskRay, erichkeane

Reviewed By: MaskRay, echristo, ahmedbougacha

Pull Request: llvm#73687
jroelofs added a commit to swiftlang/llvm-project that referenced this pull request Jan 10, 2024
Unlike ELF targets, MachO does not support the same kind of dynamic symbol
resolution at load time.  Instead, the corresponding MachO feature resolves
symbols lazily on first call.

Reviewers:
JDevlieghere, dmpolukhin, ahmedbougacha, tahonermann, echristo, MaskRay, erichkeane

Reviewed By: MaskRay, echristo, ahmedbougacha

Pull Request: llvm#73687
qihangkong pushed a commit to rvgpu/rvgpu-llvm that referenced this pull request Apr 23, 2024
Unlike ELF targets, MachO does not support the same kind of dynamic symbol
resolution at load time.  Instead, the corresponding MachO feature resolves
symbols lazily on first call.

Reviewers:
JDevlieghere, dmpolukhin, ahmedbougacha, tahonermann, echristo, MaskRay, erichkeane

Reviewed By: MaskRay, echristo, ahmedbougacha

Pull Request: llvm/llvm-project#73687
giordano pushed a commit to JuliaLang/julia that referenced this pull request Aug 28, 2024
Macos has a native tls implementation in clang since at least clang 3.7
which much older than what we require so lets enable it for some small
performance gains.

We may want to turn on the ifunc optimization that's there as well but I
haven't tested it and it's only in clang 18 and up so it would be off
for most since Apple clang is 16 on their latest beta
llvm/llvm-project#73687
KristofferC pushed a commit to JuliaLang/julia that referenced this pull request Sep 12, 2024
Macos has a native tls implementation in clang since at least clang 3.7
which much older than what we require so lets enable it for some small
performance gains.

We may want to turn on the ifunc optimization that's there as well but I
haven't tested it and it's only in clang 18 and up so it would be off
for most since Apple clang is 16 on their latest beta
llvm/llvm-project#73687
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants