https://gcc.gnu.org/g:ccffdcbbe90381eefb84c479aa9b7ff982fde6f1
commit r16-2668-gccffdcbbe90381eefb84c479aa9b7ff982fde6f1 Author: Yury Khrustalev <yury.khrusta...@arm.com> Date: Tue Jul 22 15:49:37 2025 +0100 testsuite: Add tests for __init_cpu_features_constructor Add tests that would call __init_cpu_features_resolver() directly from an ifunc resolver that would in tern call the function under test __init_cpu_features_constructor() using synthetic parameters for different sizes of the 2nd argument. gcc/testsuite/ChangeLog: * gcc.target/aarch64/ifunc-resolver.in: add core test functions. * gcc.target/aarch64/ifunc-resolver-0.c: new test. * gcc.target/aarch64/ifunc-resolver-1.c: ditto. * gcc.target/aarch64/ifunc-resolver-2.c: ditto. * gcc.target/aarch64/ifunc-resolver-3.c: ditto. * gcc.target/aarch64/ifunc-resolver-4.c: as above. Diff: --- .../gcc.target/aarch64/ifunc-resolver-0.c | 12 ++++++ .../gcc.target/aarch64/ifunc-resolver-1.c | 13 ++++++ .../gcc.target/aarch64/ifunc-resolver-2.c | 14 +++++++ .../gcc.target/aarch64/ifunc-resolver-3.c | 15 +++++++ .../gcc.target/aarch64/ifunc-resolver-4.c | 16 ++++++++ gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in | 48 ++++++++++++++++++++++ 6 files changed, 118 insertions(+) diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c new file mode 100644 index 000000000000..e544b04fa084 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-require-effective-target mmap } */ +/* { dg-options "-Wno-experimental-fmv-target" } */ + +#include <stdint.h> + +typedef struct { + uint64_t size; +} ifunc_arg_t; + +#include "ifunc-resolver.in" diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c new file mode 100644 index 000000000000..be70687dd1b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-require-effective-target mmap } */ +/* { dg-options "-Wno-experimental-fmv-target" } */ + +#include <stdint.h> + +typedef struct { + uint64_t size; + uint64_t hwcap; +} ifunc_arg_t; + +#include "ifunc-resolver.in" diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c new file mode 100644 index 000000000000..bf594d05f698 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-require-effective-target mmap } */ +/* { dg-options "-Wno-experimental-fmv-target" } */ + +#include <stdint.h> + +typedef struct { + uint64_t size; + uint64_t hwcap; + uint64_t hwcap2; +} ifunc_arg_t; + +#include "ifunc-resolver.in" diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c new file mode 100644 index 000000000000..f16d01b312d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-require-effective-target mmap } */ +/* { dg-options "-Wno-experimental-fmv-target" } */ + +#include <stdint.h> + +typedef struct { + uint64_t size; + uint64_t hwcap; + uint64_t hwcap2; + uint64_t hwcap3; +} ifunc_arg_t; + +#include "ifunc-resolver.in" diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c new file mode 100644 index 000000000000..1b4ccbda1d4f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-require-effective-target mmap } */ +/* { dg-options "-Wno-experimental-fmv-target" } */ + +#include <stdint.h> + +typedef struct { + uint64_t size; + uint64_t hwcap; + uint64_t hwcap2; + uint64_t hwcap3; + uint64_t hwcap4; +} ifunc_arg_t; + +#include "ifunc-resolver.in" diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in new file mode 100644 index 000000000000..ada0b337f397 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in @@ -0,0 +1,48 @@ +#include <unistd.h> +#include <string.h> +#include <sys/mman.h> + +/* Allocate memory buffer of size LEN with a protected page + following right after the buffer end so that any memory + accesses past the end of the buffer would trigger SEGFAUL. */ +void *allocate_mem (size_t len) +{ + size_t pagesize = sysconf (_SC_PAGESIZE); + char *m = mmap (NULL, pagesize * 2, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + mprotect (m + pagesize, pagesize, PROT_NONE); + m = m + pagesize - len; + memset(m, 0, len); + return m; +} + +int impl () +{ + return 0; +} + +#ifndef _IFUNC_ARG_HWCAP +#define _IFUNC_ARG_HWCAP (1ULL << 62) +#endif + +void +__init_cpu_features_resolver (unsigned long hwcap, const void *arg); + +static void * +fun_resolver (uint64_t a0, const uint64_t *a1) +{ + ifunc_arg_t *arg = allocate_mem (sizeof (ifunc_arg_t)); + arg->size = sizeof (ifunc_arg_t); + /* Call this function with synthetic ifunc_arg_t arg. */ + __init_cpu_features_resolver (_IFUNC_ARG_HWCAP, arg); + return (void *)(uintptr_t)impl; +} + +int fun (void) __attribute__ ((ifunc ("fun_resolver"))); + +int main (int argc, char *argv[]) +{ + return fun (); +}