fa3bfd
From 42e0828f582dcc4ff92d65039910ffe5fa9d881b Mon Sep 17 00:00:00 2001
fa3bfd
From: Stefan Liebler <stli@linux.vnet.ibm.com>
fa3bfd
Date: Thu, 27 Jul 2017 10:53:58 +0200
fa3bfd
Subject: [PATCH 02/10] S390: Use new s390_libc_ifunc_expr macro in s390
fa3bfd
 8bit-generic.c.
fa3bfd
fa3bfd
upstream-commit 51213e2b8d89164527131f3bf6c5946b811c5e3e
fa3bfd
fa3bfd
This patch adds s390_libc_ifunc_expr macro which uses the __ifunc base macro
fa3bfd
(upstream it is in include/libc-symbols.h; this backport implements it
fa3bfd
in s390-header) and lets the user define a generic expression to
fa3bfd
choose the correct ifunc variant.  Furthermore as the base macro is used,
fa3bfd
the ifunc resolver functions are now also using inhibit_stack_protector.
fa3bfd
S390 needs its own version due to the hwcap argument of the ifunc resolver.
fa3bfd
fa3bfd
This new macro is now used in iconv code in 8bit-generic.c instead of using
fa3bfd
gcc attribute ifunc directly.
fa3bfd
fa3bfd
ChangeLog:
fa3bfd
fa3bfd
	* sysdeps/s390/multiarch/ifunc-resolve.h
fa3bfd
	(s390_libc_ifunc_expr_init, s390_libc_ifunc_expr, __ifunc,
fa3bfd
	__ifunc_resolver): New Define.
fa3bfd
	* sysdeps/s390/multiarch/8bit-generic.c
fa3bfd
	(__to_generic, __from_generic): Use s390_libc_ifunc_expr to
fa3bfd
	define ifunc resolvers.
fa3bfd
---
fa3bfd
 sysdeps/s390/multiarch/8bit-generic.c  | 41 ++++++++++------------------------
fa3bfd
 sysdeps/s390/multiarch/ifunc-resolve.h | 20 +++++++++++++++++
fa3bfd
 2 files changed, 32 insertions(+), 29 deletions(-)
fa3bfd
fa3bfd
diff --git a/sysdeps/s390/multiarch/8bit-generic.c b/sysdeps/s390/multiarch/8bit-generic.c
fa3bfd
index 93565e1..9232240 100644
fa3bfd
--- a/sysdeps/s390/multiarch/8bit-generic.c
fa3bfd
+++ b/sysdeps/s390/multiarch/8bit-generic.c
fa3bfd
@@ -40,8 +40,7 @@
fa3bfd
    to translate between multiple generic characters and "1 byte UCS4"
fa3bfd
    characters at once. The vector instructions are used to convert between
fa3bfd
    the "1 byte UCS4" and UCS4.  */
fa3bfd
-# include <unistd.h>
fa3bfd
-# include <dl-procinfo.h>
fa3bfd
+# include <ifunc-resolve.h>
fa3bfd
 
fa3bfd
 # undef FROM_LOOP
fa3bfd
 # undef TO_LOOP
fa3bfd
@@ -372,33 +371,17 @@
fa3bfd
 
fa3bfd
 
fa3bfd
 /* Generate ifunc'ed loop function.  */
fa3bfd
-__typeof(__from_generic_c)
fa3bfd
-__attribute__ ((ifunc ("__from_generic_resolver")))
fa3bfd
-__from_generic;
fa3bfd
+s390_libc_ifunc_expr (__from_generic_c, __from_generic,
fa3bfd
+		      (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256
fa3bfd
+		       && hwcap & HWCAP_S390_VX)
fa3bfd
+		      ? __from_generic_vx
fa3bfd
+		      : __from_generic_c);
fa3bfd
 
fa3bfd
-static void *
fa3bfd
-__from_generic_resolver (unsigned long int dl_hwcap)
fa3bfd
-{
fa3bfd
-  if (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256
fa3bfd
-      && dl_hwcap & HWCAP_S390_VX)
fa3bfd
-    return &__from_generic_vx;
fa3bfd
-  else
fa3bfd
-    return &__from_generic_c;
fa3bfd
-}
fa3bfd
-
fa3bfd
-__typeof(__to_generic_c)
fa3bfd
-__attribute__ ((ifunc ("__to_generic_resolver")))
fa3bfd
-__to_generic;
fa3bfd
-
fa3bfd
-static void *
fa3bfd
-__to_generic_resolver (unsigned long int dl_hwcap)
fa3bfd
-{
fa3bfd
-  if (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256
fa3bfd
-      && dl_hwcap & HWCAP_S390_VX)
fa3bfd
-    return &__to_generic_vx;
fa3bfd
-  else
fa3bfd
-    return &__to_generic_c;
fa3bfd
-}
fa3bfd
+s390_libc_ifunc_expr (__to_generic_c, __to_generic,
fa3bfd
+		      (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256
fa3bfd
+		       && hwcap & HWCAP_S390_VX)
fa3bfd
+		      ? __to_generic_vx
fa3bfd
+		      : __to_generic_c);
fa3bfd
 
fa3bfd
 strong_alias (__to_generic_c_single, __to_generic_single)
fa3bfd
 
fa3bfd
@@ -410,6 +393,6 @@ strong_alias (__to_generic_c_single, __to_generic_single)
fa3bfd
 
fa3bfd
 #else
fa3bfd
 /* Generate this module without ifunc if build environment lacks vector
fa3bfd
-   support. Instead the common 8bit-generic.c is used.  */
fa3bfd
+   support.  Instead the common 8bit-generic.c is used.  */
fa3bfd
 # include "iconvdata/8bit-generic.c"
fa3bfd
 #endif /* !defined HAVE_S390_VX_ASM_SUPPORT */
fa3bfd
diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
fa3bfd
index e9fd90e..883365b 100644
fa3bfd
--- a/sysdeps/s390/multiarch/ifunc-resolve.h
fa3bfd
+++ b/sysdeps/s390/multiarch/ifunc-resolve.h
fa3bfd
@@ -92,3 +92,23 @@
fa3bfd
       return &RESOLVERFUNC##_c;						\
fa3bfd
   }									\
fa3bfd
  __asm__ (".type " #FUNC ", %gnu_indirect_function");
fa3bfd
+
fa3bfd
+/* Helper / base  macros for indirect function symbols
fa3bfd
+   (See include/libc-symbols in upstream glibc).  */
fa3bfd
+#define __ifunc_resolver(type_name, name, expr, arg, init, classifier)	\
fa3bfd
+  classifier void *name##_ifunc (arg)					\
fa3bfd
+  {									\
fa3bfd
+    init ();								\
fa3bfd
+    __typeof (type_name) *res = expr;					\
fa3bfd
+    return res;								\
fa3bfd
+  }
fa3bfd
+
fa3bfd
+#define __ifunc(type_name, name, expr, arg, init)			\
fa3bfd
+  extern __typeof (type_name) name __attribute__			\
fa3bfd
+			      ((ifunc (#name "_ifunc")));		\
fa3bfd
+  __ifunc_resolver (type_name, name, expr, arg, init, static)
fa3bfd
+
fa3bfd
+#define s390_libc_ifunc_expr_init()
fa3bfd
+#define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR)		\
fa3bfd
+  __ifunc (TYPE_FUNC, FUNC, EXPR, unsigned long int hwcap,	\
fa3bfd
+	   s390_libc_ifunc_expr_init);
fa3bfd
-- 
fa3bfd
1.8.3.1
fa3bfd