From 93d2b23ad2b96ed47b68a7e3c142cb306f418f2a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 14 Jul 2024 11:18:55 -0700 Subject: [PATCH] [test] Improve ifunc tests Add ifunc-after-resolver tests to inprove coverage and demonstrate the -fsanitize=kcfi issue reported at #96400. --- clang/test/CodeGen/ifunc.c | 25 +++++++++++++++---------- clang/test/CodeGen/kcfi.c | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/clang/test/CodeGen/ifunc.c b/clang/test/CodeGen/ifunc.c index 3aa29f7dff74de..b049739daf2aad 100644 --- a/clang/test/CodeGen/ifunc.c +++ b/clang/test/CodeGen/ifunc.c @@ -7,11 +7,12 @@ // 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 +// RUN: %clang_cc1 -triple arm64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN +// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN +// RUN: %clang_cc1 -triple arm64-apple-macosx -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN +// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN +/// The ifunc is emitted before its resolver. int foo(int) __attribute__ ((ifunc("foo_ifunc"))); static int f1(int i) { @@ -45,20 +46,24 @@ extern void goo(void) __attribute__ ((ifunc("goo_ifunc"))); void* goo_ifunc(void) { return 0; } + +/// The ifunc is emitted after its resolver. +void *hoo_ifunc(void) { return 0; } +extern void hoo(int) __attribute__ ((ifunc("hoo_ifunc"))); + // CHECK: @foo = ifunc i32 (i32), ptr @foo_ifunc // CHECK: @goo = ifunc void (), ptr @goo_ifunc +// CHECK: @hoo = ifunc void (i32), ptr @hoo_ifunc // CHECK: call i32 @foo(i32 // CHECK: call void @goo() // SAN: define internal nonnull {{(noundef )?}}ptr @foo_ifunc() #[[#FOO_IFUNC:]] { -// MACSAN: define internal nonnull {{(noundef )?}}ptr @foo_ifunc() #[[#FOO_IFUNC:]] { -// SAN: define dso_local noalias {{(noundef )?}}ptr @goo_ifunc() #[[#GOO_IFUNC:]] { -// MACSAN: define noalias {{(noundef )?}}ptr @goo_ifunc() #[[#GOO_IFUNC:]] { +// SAN: define {{(dso_local )?}}noalias {{(noundef )?}}ptr @goo_ifunc() #[[#GOO_IFUNC:]] { -// SAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} -// MACSAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} +// SAN: define {{(dso_local )?}}noalias {{(noundef )?}}ptr @hoo_ifunc() #[[#HOO_IFUNC:]] { +// SAN-DAG: attributes #[[#FOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} // SAN-DAG: attributes #[[#GOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} -// MACSAN-DAG: attributes #[[#GOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} +// SAN-DAG: attributes #[[#HOO_IFUNC]] = {{{.*}} disable_sanitizer_instrumentation {{.*}} diff --git a/clang/test/CodeGen/kcfi.c b/clang/test/CodeGen/kcfi.c index f6b2e4b398aa7c..c29429f644ba17 100644 --- a/clang/test/CodeGen/kcfi.c +++ b/clang/test/CodeGen/kcfi.c @@ -1,4 +1,4 @@ -// 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 -o - %s | FileCheck %s --check-prefixes=CHECK,C // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -x c++ -o - %s | FileCheck %s --check-prefixes=CHECK,MEMBER // 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) @@ -10,6 +10,9 @@ // CHECK: module asm ".set __kcfi_typeid_[[F4]], [[#%d,HASH:]]" /// Must not __kcfi_typeid symbols for non-address-taken declarations // CHECK-NOT: module asm ".weak __kcfi_typeid_{{f6|_Z2f6v}}" + +// C: @ifunc1 = ifunc i32 (i32), ptr @resolver1 +// C: @ifunc2 = ifunc i64 (i64), ptr @resolver2 typedef int (*fn_t)(void); // CHECK: define dso_local{{.*}} i32 @{{f1|_Z2f1v}}(){{.*}} !kcfi_type ![[#TYPE:]] @@ -30,6 +33,16 @@ 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; }