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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
50a68f3
[𝘀𝗽𝗿] changes to main this commit is based on
jroelofs Nov 28, 2023
d4d16df
[𝘀𝗽𝗿] initial version
jroelofs Nov 28, 2023
0d426a9
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Nov 28, 2023
15d50f3
rebase
jroelofs Nov 28, 2023
3b44869
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Nov 28, 2023
8d9c2a2
rebase
jroelofs Nov 28, 2023
6205bfd
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Nov 29, 2023
68e1755
rebase
jroelofs Nov 29, 2023
aeb39b9
adjust tests per review feedback
jroelofs Nov 29, 2023
c259170
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Nov 29, 2023
edf4acd
review feedback
jroelofs Nov 29, 2023
8825586
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Nov 29, 2023
80f3bd6
rebase
jroelofs Nov 29, 2023
520912e
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Nov 29, 2023
ed97a63
rebase
jroelofs Nov 29, 2023
f11d250
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 1, 2023
d313d09
rebase
jroelofs Dec 1, 2023
7f2f351
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 1, 2023
655e788
rebase
jroelofs Dec 1, 2023
ac12665
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 5, 2023
049e5e1
rebase
jroelofs Dec 5, 2023
cf02c55
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 6, 2023
4b49db8
rebase
jroelofs Dec 6, 2023
df0e90e
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 6, 2023
6ff0110
rebase
jroelofs Dec 6, 2023
7adcec3
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 6, 2023
73aca76
rebase
jroelofs Dec 6, 2023
e7533bc
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 6, 2023
61c05b4
rebase
jroelofs Dec 6, 2023
81ee3f8
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 6, 2023
1c5dc08
rebase
jroelofs Dec 6, 2023
347c0bd
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 8, 2023
5072af3
rebase
jroelofs Dec 8, 2023
56f080a
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 8, 2023
f1b4f98
rebase
jroelofs Dec 8, 2023
f6e1fe8
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 8, 2023
06b95a9
rebase
jroelofs Dec 8, 2023
b6ae551
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 9, 2023
4905b8e
rebase
jroelofs Dec 9, 2023
bd1d6a5
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 14, 2023
8c65db7
rebase
jroelofs Dec 14, 2023
952d096
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 14, 2023
305ec18
rebase
jroelofs Dec 14, 2023
4ce1e1a
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 14, 2023
f75c2ef
rebase
jroelofs Dec 14, 2023
7cf1f8d
[𝘀𝗽𝗿] landed version
jroelofs Dec 14, 2023
8361221
[𝘀𝗽𝗿] landed version
jroelofs Dec 14, 2023
d0e7c98
[𝘀𝗽𝗿] changes introduced through rebase
jroelofs Dec 14, 2023
3b7a350
rebase
jroelofs Dec 14, 2023
b9122d3
[𝘀𝗽𝗿] landed version
jroelofs Dec 14, 2023
835af6c
[𝘀𝗽𝗿] landed version
jroelofs Dec 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -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() }];
Expand Down Expand Up @@ -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]>;
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -5535,7 +5535,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.
Mach-O 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 Mach-O currently do not support this attribute.
}];
}

Expand Down
20 changes: 20 additions & 0 deletions clang/test/CodeGen/attr-ifunc.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify %s
// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only -DCHECK_ALIASES %s
// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsyntax-only -verify -emit-llvm-only %s

#if defined(_WIN32)
void foo(void) {}
Expand Down Expand Up @@ -36,6 +37,25 @@ void *f6_resolver(void) __attribute__((ifunc("f6_resolver_resolver")));
void f6(void) __attribute__((ifunc("f6_resolver")));
// expected-error@-1 {{ifunc must point to a defined function}}

#elif defined(__APPLE__)

// NOTE: aliases are not supported on Darwin, so the above tests are not relevant.

#define STR2(X) #X
#define STR(X) STR2(X)
#define PREFIX STR(__USER_LABEL_PREFIX__)

void f1a(void) __asm("f1");
void f1a(void) {}
// expected-note@-1 {{previous definition is here}}
void f1(void) __attribute__((ifunc(PREFIX "f1_ifunc"))) __asm("f1");
// expected-error@-1 {{definition with same mangled name '<U+0001>f1' as another definition}}
void *f1_ifunc(void) { return 0; }

void *f6_ifunc(int i);
void __attribute__((ifunc(PREFIX "f6_ifunc"))) f6(void) {}
// expected-error@-1 {{definition 'f6' cannot also be an ifunc}}

#else
void f1a(void) __asm("f1");
void f1a(void) {}
Expand Down
4 changes: 4 additions & 0 deletions clang/test/CodeGen/attr-ifunc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsyntax-only -verify -emit-llvm-only %s
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify -emit-llvm-only %s
// RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -triple x86_64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -triple arm64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s

void *f1_ifunc(void) { return nullptr; }
void f1(void) __attribute__((ifunc("f1_ifunc")));
Expand Down
12 changes: 12 additions & 0 deletions clang/test/CodeGen/ifunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
// 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 arm64-apple-macosx -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-apple-macosx -O2 -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 arm64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN
// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=MACSAN
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsanitize=address -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")));

Expand Down Expand Up @@ -44,9 +52,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 {{.*}}
2 changes: 2 additions & 0 deletions clang/test/CodeGenCXX/externc-ifunc-resolver.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-apple-macosx -emit-llvm -o - %s | FileCheck %s

extern "C" {
__attribute__((used)) static void *resolve_foo() { return 0; }
Expand Down
4 changes: 4 additions & 0 deletions clang/test/SemaCXX/externc-ifunc-resolver.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-linux-gnu -verify %s
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-macosx -verify %s
// RUN: %clang_cc1 -emit-llvm-only -triple arm64-apple-macosx -verify %s
// RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -triple x86_64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -triple arm64-apple-macosx -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s

extern "C" {
__attribute__((used)) static void *resolve_foo() { return 0; }
Expand Down
16 changes: 16 additions & 0 deletions clang/test/SemaCXX/ifunc-has-attribute.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-linux-gnu -verify %s -DSUPPORTED=1
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-macosx -verify %s -DSUPPORTED=1
// RUN: %clang_cc1 -emit-llvm-only -triple arm64-apple-macosx -verify %s -DSUPPORTED=1
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-win32 -verify %s -DNOT_SUPPORTED=1

// expected-no-diagnostics

#if __has_attribute(ifunc)
# if NOT_SUPPORTED
# error "ifunc appears to be supported on this platform, but shouldn't be"
# endif
#else
# if SUPPORTED
# error "ifunc should be supported on this platform, but isn't"
# endif
#endif