No ifunc for strcmp and strlen

This is a workaround to unbreak bank apps

Bug: 120254692
Test: Run broken apps
Change-Id: I47a655e9648a6d5f50856f712d8e1cf2be24b440
(cherry picked from commit e4788d4c7e842b0ca24363ebc5544a16c9e3b185)
diff --git a/libc/Android.bp b/libc/Android.bp
index 0098d07..d2c6300 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1429,7 +1429,12 @@
             srcs: ["arch-x86/dynamic_function_dispatch.cpp"],
         },
         arm: {
-            srcs: ["arch-arm/dynamic_function_dispatch.cpp"],
+            srcs: [
+                "arch-arm/dynamic_function_dispatch.cpp",
+
+                // Workaround for b/120254692.
+                "arch-arm/dynamic_function_wrapper.S",
+            ],
         },
     },
 
diff --git a/libc/arch-arm/dynamic_function_dispatch.cpp b/libc/arch-arm/dynamic_function_dispatch.cpp
index 640f330..09fd8f3 100644
--- a/libc/arch-arm/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm/dynamic_function_dispatch.cpp
@@ -89,11 +89,15 @@
     return r0;
 }
 
-#define DEFINE_IFUNC(name) \
-    name##_func name __attribute__((ifunc(#name "_resolver"))); \
+#define DEFINE_IFUNC_WITH_SUFFIX(name, suffix) \
+    name##_func name##suffix __attribute__((ifunc(#name "_resolver"))); \
     __attribute__((visibility("hidden"))) \
     name##_func* name##_resolver()
 
+#define DEFINE_IFUNC(name) DEFINE_IFUNC_WITH_SUFFIX(name, )
+
+#define DEFINE_INTERNAL_IFUNC(name) DEFINE_IFUNC_WITH_SUFFIX(name, _internal)
+
 #define DECLARE_FUNC(type, name) \
     __attribute__((visibility("hidden"))) \
     type name
@@ -287,7 +291,7 @@
 }
 
 typedef int strcmp_func(const char* __lhs, const char* __rhs);
-DEFINE_IFUNC(strcmp) {
+DEFINE_INTERNAL_IFUNC(strcmp) {
     switch(get_cpu_variant()) {
         case kCortexA9:
             RETURN_FUNC(strcmp_func, strcmp_a9);
@@ -301,7 +305,7 @@
 }
 
 typedef size_t strlen_func(const char* __s);
-DEFINE_IFUNC(strlen) {
+DEFINE_INTERNAL_IFUNC(strlen) {
     switch(get_cpu_variant()) {
         case kCortexA9:
             RETURN_FUNC(strlen_func, strlen_a9);
diff --git a/libc/arch-arm/dynamic_function_wrapper.S b/libc/arch-arm/dynamic_function_wrapper.S
new file mode 100644
index 0000000..1d2842b
--- /dev/null
+++ b/libc/arch-arm/dynamic_function_wrapper.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <private/bionic_asm.h>
+
+#define FUNCTION_DELEGATE(name, impl) \
+ENTRY(name); \
+    b impl; \
+END(name)
+
+FUNCTION_DELEGATE(strcmp, strcmp_internal)
+FUNCTION_DELEGATE(strlen, strlen_internal)