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

Reply via email to