ifuncs: start sharing.

We're going to have to add ifuncs to libm, and there will be some SVE
ones for arm64 soon too, so let's start sharing the absolute minimum...

Test: builds
Change-Id: Idbb9dd9477291ed3c15dc3902f65e593b766dfb9
diff --git a/libc/arch-arm/dynamic_function_dispatch.cpp b/libc/arch-arm/dynamic_function_dispatch.cpp
index 5e1b8b0..75000a2 100644
--- a/libc/arch-arm/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm/dynamic_function_dispatch.cpp
@@ -29,6 +29,8 @@
 #include <fcntl.h>
 #include <sys/syscall.h>
 
+#include <private/bionic_ifuncs.h>
+
 extern "C" {
 
 enum CpuVariant {
@@ -89,20 +91,6 @@
     return r0;
 }
 
-#define DEFINE_IFUNC(name) \
-    name##_func name __attribute__((ifunc(#name "_resolver"))); \
-    __attribute__((visibility("hidden"))) \
-    name##_func* name##_resolver()
-
-#define DECLARE_FUNC(type, name) \
-    __attribute__((visibility("hidden"))) \
-    type name
-
-#define RETURN_FUNC(type, name) { \
-        DECLARE_FUNC(type, name); \
-        return name; \
-    }
-
 static bool is_same_name(const char* a, const char* b) {
     static_assert(MAX_CPU_NAME_LEN % sizeof(int) == 0, "");
     const int* ia = reinterpret_cast<const int*>(a);
@@ -155,17 +143,17 @@
 }
 
 typedef void* memmove_func(void* __dst, const void* __src, size_t __n);
-DEFINE_IFUNC(memmove) {
+DEFINE_IFUNC_FOR(memmove) {
     RETURN_FUNC(memmove_func, memmove_a15);
 }
 
 typedef void* memcpy_func(void*, const void*, size_t);
-DEFINE_IFUNC(memcpy) {
+DEFINE_IFUNC_FOR(memcpy) {
     return memmove_resolver();
 }
 
 typedef void* __memcpy_func(void*, const void*, size_t);
-DEFINE_IFUNC(__memcpy) {
+DEFINE_IFUNC_FOR(__memcpy) {
     switch(get_cpu_variant()) {
         case kCortexA7:
             RETURN_FUNC(__memcpy_func, __memcpy_a7);
@@ -185,7 +173,7 @@
 }
 
 typedef void* __memset_chk_func(void* s, int c, size_t n, size_t n2);
-DEFINE_IFUNC(__memset_chk) {
+DEFINE_IFUNC_FOR(__memset_chk) {
     switch(get_cpu_variant()) {
         case kCortexA7:
         case kCortexA53:
@@ -202,7 +190,7 @@
 }
 
 typedef void* memset_func(void* __dst, int __ch, size_t __n);
-DEFINE_IFUNC(memset) {
+DEFINE_IFUNC_FOR(memset) {
     switch(get_cpu_variant()) {
         case kCortexA7:
         case kCortexA53:
@@ -219,7 +207,7 @@
 }
 
 typedef char* strcpy_func(char* __dst, const char* __src);
-DEFINE_IFUNC(strcpy) {
+DEFINE_IFUNC_FOR(strcpy) {
     switch(get_cpu_variant()) {
         case kCortexA9:
             RETURN_FUNC(strcpy_func, strcpy_a9);
@@ -229,7 +217,7 @@
 }
 
 typedef char* __strcpy_chk_func(char* dst, const char* src, size_t dst_len);
-DEFINE_IFUNC(__strcpy_chk) {
+DEFINE_IFUNC_FOR(__strcpy_chk) {
     switch(get_cpu_variant()) {
         case kCortexA7:
             RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a7);
@@ -248,7 +236,7 @@
 }
 
 typedef char* stpcpy_func(char* __dst, const char* __src);
-DEFINE_IFUNC(stpcpy) {
+DEFINE_IFUNC_FOR(stpcpy) {
     switch(get_cpu_variant()) {
         case kCortexA9:
             RETURN_FUNC(stpcpy_func, stpcpy_a9);
@@ -258,7 +246,7 @@
 }
 
 typedef char* strcat_func(char* __dst, const char* __src);
-DEFINE_IFUNC(strcat) {
+DEFINE_IFUNC_FOR(strcat) {
     switch(get_cpu_variant()) {
         case kCortexA9:
             RETURN_FUNC(strcat_func, strcat_a9);
@@ -268,7 +256,7 @@
 }
 
 typedef char* __strcat_chk_func(char* dst, const char* src, size_t dst_buf_size);
-DEFINE_IFUNC(__strcat_chk) {
+DEFINE_IFUNC_FOR(__strcat_chk) {
     switch(get_cpu_variant()) {
         case kCortexA7:
             RETURN_FUNC(__strcat_chk_func, __strcat_chk_a7);
@@ -287,12 +275,12 @@
 }
 
 typedef int strcmp_func(const char* __lhs, const char* __rhs);
-DEFINE_IFUNC(strcmp) {
+DEFINE_IFUNC_FOR(strcmp) {
     RETURN_FUNC(strcmp_func, strcmp_a15);
 }
 
 typedef size_t strlen_func(const char* __s);
-DEFINE_IFUNC(strlen) {
+DEFINE_IFUNC_FOR(strlen) {
     switch(get_cpu_variant()) {
         case kCortexA9:
             RETURN_FUNC(strlen_func, strlen_a9);
diff --git a/libc/arch-x86/dynamic_function_dispatch.cpp b/libc/arch-x86/dynamic_function_dispatch.cpp
index 370b372..e94fa1f 100644
--- a/libc/arch-x86/dynamic_function_dispatch.cpp
+++ b/libc/arch-x86/dynamic_function_dispatch.cpp
@@ -28,22 +28,10 @@
 
 #include <stddef.h>
 
+#include <private/bionic_ifuncs.h>
+
 extern "C" {
 
-#define DEFINE_IFUNC_FOR(name) \
-    name##_func name __attribute__((ifunc(#name "_resolver"))); \
-    __attribute__((visibility("hidden"))) \
-    name##_func* name##_resolver()
-
-#define DECLARE_FUNC(type, name) \
-    __attribute__((visibility("hidden"))) \
-    type name
-
-#define RETURN_FUNC(type, name) { \
-        DECLARE_FUNC(type, name); \
-        return name; \
-    }
-
 typedef int memcmp_func(const void* __lhs, const void* __rhs, size_t __n);
 DEFINE_IFUNC_FOR(memcmp) {
     __builtin_cpu_init();
diff --git a/libc/private/bionic_ifuncs.h b/libc/private/bionic_ifuncs.h
new file mode 100644
index 0000000..35961fb
--- /dev/null
+++ b/libc/private/bionic_ifuncs.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#define DEFINE_IFUNC_FOR(name) \
+    name##_func name __attribute__((ifunc(#name "_resolver"))); \
+    __attribute__((visibility("hidden"))) \
+    name##_func* name##_resolver()
+
+#define DECLARE_FUNC(type, name) \
+    __attribute__((visibility("hidden"))) \
+    type name
+
+#define RETURN_FUNC(type, name) { \
+        DECLARE_FUNC(type, name); \
+        return name; \
+    }