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. --- .../gcc.target/aarch64/ifunc-resolver-0.c | 11 +++++ .../gcc.target/aarch64/ifunc-resolver-1.c | 12 +++++ .../gcc.target/aarch64/ifunc-resolver-2.c | 13 +++++ .../gcc.target/aarch64/ifunc-resolver-3.c | 14 ++++++ .../gcc.target/aarch64/ifunc-resolver-4.c | 15 ++++++ .../gcc.target/aarch64/ifunc-resolver.in | 48 +++++++++++++++++++ 6 files changed, 113 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in 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 00000000000..4e2c67068a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c @@ -0,0 +1,11 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { 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 00000000000..c19be8f30df --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { 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 00000000000..f43e812bd1c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { 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 00000000000..274eb255cf3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { 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 00000000000..6c18a3d770a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { 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 00000000000..ada0b337f39 --- /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 (); +} -- 2.39.5