diff --git a/SOURCES/glibc-post_upgrade.patch b/SOURCES/glibc-post_upgrade.patch
deleted file mode 100644
index a64adfc..0000000
--- a/SOURCES/glibc-post_upgrade.patch
+++ /dev/null
@@ -1,272 +0,0 @@
-Short description: RPM Post-upgrade cleanup program.
-Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
-Origin: PATCH
-Upstream status: not-needed
-
-A helper program is needed to clean up the system configuration
-early during RPM package installation, so that other scriptlets
-can run successfully.
-
-diff --git a/elf/Makefile b/elf/Makefile
-index 2a432d8beebcd207..368dcae477fff2ae 100644
---- a/elf/Makefile
-+++ b/elf/Makefile
-@@ -117,6 +117,14 @@ others-extras   = $(ldconfig-modules)
- endif
- endif
- 
-+# This needs to be statically linked because it is executed at a time
-+# when there might be incompatible shared objects on disk, and the
-+# purpose of this program is to remove them (among other things).
-+others-static += glibc_post_upgrade
-+others += glibc_post_upgrade
-+glibc_post_upgrade-modules := static-stubs
-+CFLAGS-glibc_post_upgrade.c += -DGCONV_MODULES_DIR='"$(gconvdir)"'
-+
- # To find xmalloc.c and xstrdup.c
- vpath %.c ../locale/programs
- 
-@@ -559,6 +567,8 @@ $(objpfx)sln: $(sln-modules:%=$(objpfx)%.o)
- 
- $(objpfx)ldconfig: $(ldconfig-modules:%=$(objpfx)%.o)
- 
-+$(objpfx)glibc_post_upgrade: $(glibc_post_upgrade-modules:%=$(objpfx)%.o)
-+
- SYSCONF-FLAGS := -D'SYSCONFDIR="$(sysconfdir)"'
- CFLAGS-ldconfig.c += $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \
- 		    -D'SLIBDIR="$(slibdir)"'
-diff --git a/elf/glibc_post_upgrade.c b/elf/glibc_post_upgrade.c
-new file mode 100644
-index 0000000000000000..19b59f70e2308032
---- /dev/null
-+++ b/elf/glibc_post_upgrade.c
-@@ -0,0 +1,229 @@
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+#include <stdio.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <sys/time.h>
-+#include <dirent.h>
-+#include <stddef.h>
-+#include <fcntl.h>
-+#include <string.h>
-+
-+#define LD_SO_CONF "/etc/ld.so.conf"
-+#define ICONVCONFIG "/usr/sbin/iconvconfig"
-+
-+#define verbose_exec(failcode, path...) \
-+  do                                                    \
-+    {                                                   \
-+      char *const arr[] = { path, NULL };               \
-+      vexec (failcode, arr);                            \
-+    } while (0)
-+
-+__attribute__((noinline)) static void vexec (int failcode, char *const path[]);
-+__attribute__((noinline)) static void says (const char *str);
-+__attribute__((noinline)) static void sayn (long num);
-+__attribute__((noinline)) static void message (char *const path[]);
-+
-+int
-+main (void)
-+{
-+  char initpath[256];
-+
-+  char buffer[4096];
-+  struct pref {
-+    const char *p;
-+    int len;
-+  } prefix[] = { { "libc-", 5 }, { "libm-", 5 },
-+                 { "librt-", 6 }, { "libpthread-", 11 },
-+                 { "librtkaio-", 10 }, { "libthread_db-", 13 } };
-+  int i, j, fd;
-+  off_t base;
-+  ssize_t ret;
-+
-+  /* In order to support in-place upgrades, we must immediately remove
-+     obsolete platform directories after installing a new glibc
-+     version.  RPM only deletes files removed by updates near the end
-+     of the transaction.  If we did not remove the obsolete platform
-+     directories here, they would be preferred by the dynamic linker
-+     during the execution of subsequent RPM scriptlets, likely
-+     resulting in process startup failures.  */
-+  const char *remove_dirs[] =
-+    {
-+#if defined (__i386__)
-+      "/lib/i686",
-+      "/lib/i686/nosegneg",
-+#elif defined (__powerpc64__) && _CALL_ELF != 2
-+      "/lib64/power6",
-+#endif
-+    };
-+  for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j)
-+    {
-+      size_t rmlen = strlen (remove_dirs[j]);
-+      fd = open (remove_dirs[j], O_RDONLY);
-+      if (fd >= 0
-+          && (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
-+             >= (ssize_t) offsetof (struct dirent, d_name))
-+        {
-+          for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
-+            {
-+              struct dirent *d = (struct dirent *) (buffer + base);
-+
-+              for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
-+                if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
-+                  {
-+                    char *p = d->d_name + prefix[i].len;
-+
-+                    while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
-+                    if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
-+                        && p + 3 - d->d_name
-+                           < sizeof (initpath) - rmlen - 1)
-+                      {
-+                        memcpy (initpath, remove_dirs[j], rmlen);
-+                        initpath[rmlen] = '/';
-+                        strcpy (initpath + rmlen + 1, d->d_name);
-+                        unlink (initpath);
-+                        break;
-+                      }
-+                  }
-+              base += d->d_reclen;
-+            }
-+          close (fd);
-+        }
-+    }
-+
-+  int ldsocfd = open (LD_SO_CONF, O_RDONLY);
-+  struct stat ldsocst;
-+  if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0)
-+    {
-+      char p[ldsocst.st_size + 1];
-+      if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size)
-+        {
-+          p[ldsocst.st_size] = '\0';
-+          if (strstr (p, "include ld.so.conf.d/*.conf") == NULL)
-+            {
-+              close (ldsocfd);
-+              ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC);
-+              if (ldsocfd >= 0)
-+                {
-+                  size_t slen = strlen ("include ld.so.conf.d/*.conf\n");
-+                  if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen)
-+                      != slen
-+                      || write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size)
-+                    _exit (109);
-+                }
-+            }
-+        }
-+      if (ldsocfd >= 0)
-+        close (ldsocfd);
-+    }
-+
-+  /* If installing bi-arch glibc, rpm sometimes doesn't unpack all files
-+     before running one of the lib's %post scriptlet.  /sbin/ldconfig will
-+     then be run by the other arch's %post.  */
-+  if (! access ("/sbin/ldconfig", X_OK))
-+    verbose_exec (110,
-+                  (char *) "/sbin/ldconfig",
-+                  (char *) "/sbin/ldconfig");
-+
-+  if (! utimes (GCONV_MODULES_DIR "/gconv-modules.cache", NULL))
-+    {
-+      const char *iconv_cache = GCONV_MODULES_DIR "/gconv-modules.cache";
-+      const char *iconv_dir = GCONV_MODULES_DIR;
-+      verbose_exec (113,
-+                    (char *) ICONVCONFIG,
-+                    (char *) "/usr/sbin/iconvconfig",
-+                    (char *) "-o",
-+                    (char *) iconv_cache,
-+                    (char *) "--nostdlib",
-+                    (char *) iconv_dir);
-+    }
-+
-+  _exit(0);
-+}
-+
-+void
-+vexec (int failcode, char *const path[])
-+{
-+  pid_t pid;
-+  int status, save_errno;
-+  int devnull = 0;
-+
-+  if (failcode < 0)
-+    {
-+      devnull = 1;
-+      failcode = -failcode;
-+    }
-+  pid = vfork ();
-+  if (pid == 0)
-+    {
-+      int fd;
-+      if (devnull && (fd = open ("/dev/null", O_WRONLY)) >= 0)
-+        {
-+          dup2 (fd, 1);
-+          dup2 (fd, 2);
-+          close (fd);
-+        }
-+      execv (path[0], path + 1);
-+      save_errno = errno;
-+      message (path);
-+      says (" exec failed with errno ");
-+      sayn (save_errno);
-+      says ("\n");
-+      _exit (failcode);
-+    }
-+  else if (pid < 0)
-+    {
-+      save_errno = errno;
-+      message (path);
-+      says (" fork failed with errno ");
-+      sayn (save_errno);
-+      says ("\n");
-+      _exit (failcode + 1);
-+    }
-+  if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
-+    {
-+      message (path);
-+      says (" child terminated abnormally\n");
-+      _exit (failcode + 2);
-+    }
-+  if (WEXITSTATUS (status))
-+    {
-+      message (path);
-+      says (" child exited with exit code ");
-+      sayn (WEXITSTATUS (status));
-+      says ("\n");
-+      _exit (WEXITSTATUS (status));
-+    }
-+}
-+
-+static void
-+says (const char *str)
-+{
-+  write (1, str, strlen (str));
-+}
-+
-+static void
-+sayn (long num)
-+{
-+  char string[sizeof (long) * 3 + 1];
-+  char *p = string + sizeof (string) - 1;
-+
-+  *p = '\0';
-+  if (num == 0)
-+    *--p = '0';
-+  else
-+    while (num)
-+      {
-+        *--p = '0' + num % 10;
-+        num = num / 10;
-+      }
-+
-+  says (p);
-+}
-+
-+static void
-+message (char *const path[])
-+{
-+  says ("/usr/sbin/glibc_post_upgrade: While trying to execute ");
-+  says (path[0]);
-+}
diff --git a/SOURCES/glibc-rh1577438.patch b/SOURCES/glibc-rh1577438.patch
new file mode 100644
index 0000000..aab01cc
--- /dev/null
+++ b/SOURCES/glibc-rh1577438.patch
@@ -0,0 +1,24 @@
+Patch by Hanataka Shinya <hanataka.shinya@gmail.com> from
+<https://sourceware.org/bugzilla/show_bug.cgi?id=24405>.  Confirmed by TAMUKI
+Shoichi's patch in
+<https://sourceware.org/ml/libc-alpha/2019-04/msg00005.html>.
+
+The official announcement by the Japanese Prime Minister in
+<https://www.kantei.go.jp/jp/tyoukanpress/201904/1_a.html> uses U+4EE4 U+548C
+as well.
+
+diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
+index 1fd2fee44b2879d9..30190b624856cc53 100644
+--- a/localedata/locales/ja_JP
++++ b/localedata/locales/ja_JP
+@@ -14946,7 +14946,9 @@ am_pm	"<U5348><U524D>";"<U5348><U5F8C>"
+ 
+ t_fmt_ampm "%p%I<U6642>%M<U5206>%S<U79D2>"
+ 
+-era	"+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
++era	"+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
++	"+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
++	"+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
+ 	"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
+ 	"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
+ 	"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
diff --git a/SOURCES/glibc-rh1623537.patch b/SOURCES/glibc-rh1623537.patch
new file mode 100644
index 0000000..5165785
--- /dev/null
+++ b/SOURCES/glibc-rh1623537.patch
@@ -0,0 +1,61 @@
+commit b297581acb66f80b513996c1580158b0fb12d469
+Author: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+Date:   Mon Jan 14 17:54:44 2019 -0200
+
+    Add XFAIL_ROUNDING_IBM128_LIBGCC to more fma() tests
+    
+    Ignore 16 errors in math/test-ldouble-fma and 4 errors in
+    math/test-ildouble-fma when IBM 128-bit long double used.
+    These errors are caused by spurious overflows from libgcc.
+    
+            * math/libm-test-fma.inc (fma_test_data): Set
+            XFAIL_ROUNDING_IBM128_LIBGCC to more tests.
+    
+    Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+    (cherry picked from commit ecdacd34a2ac3b6d5a529ff218b29261d9d98a7a)
+
+diff --git a/math/libm-test-fma.inc b/math/libm-test-fma.inc
+index 5b29fb820194e055..a7ee40992420c1ab 100644
+--- a/math/libm-test-fma.inc
++++ b/math/libm-test-fma.inc
+@@ -119,32 +119,32 @@ static const struct test_fff_f_data fma_test_data[] =
+     TEST_fff_f (fma, plus_infty, plus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, plus_infty, plus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, plus_infty, plus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
++    TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
++    TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
+     TEST_fff_f (fma, plus_infty, minus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, plus_infty, minus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, plus_infty, minus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, plus_infty, minus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, plus_infty, minus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, plus_infty, minus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
++    TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
++    TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
+     TEST_fff_f (fma, minus_infty, plus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, plus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, plus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, plus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, plus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, plus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
++    TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
++    TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
+     TEST_fff_f (fma, minus_infty, minus_infty, plus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, minus_infty, minus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, minus_infty, min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, minus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, minus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+     TEST_fff_f (fma, minus_infty, minus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+-    TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
++    TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
++    TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
+ 
+     AUTO_TESTS_fff_f (fma),
+   };
diff --git a/SOURCES/glibc-rh1639343-1.patch b/SOURCES/glibc-rh1639343-1.patch
new file mode 100644
index 0000000..51d2226
--- /dev/null
+++ b/SOURCES/glibc-rh1639343-1.patch
@@ -0,0 +1,35 @@
+commit f9b645b4b0a10c43753296ce3fa40053fa44606a
+Author: Mike Frysinger <vapier@gentoo.org>
+Date:   Wed Apr 24 13:32:22 2019 +0200
+
+    memusagestat: use local glibc when linking [BZ #18465]
+    
+    The memusagestat is the only binary that has its own link line which
+    causes it to be linked against the existing installed C library.  It
+    has been this way since it was originally committed in 1999, but I
+    don't see any reason as to why.  Since we want all the programs we
+    build locally to be against the new copy of glibc, change the build
+    to be like all other programs.
+
+diff --git a/malloc/Makefile b/malloc/Makefile
+index 388cf7e9ee3a2569..228a1279a5960d8c 100644
+--- a/malloc/Makefile
++++ b/malloc/Makefile
+@@ -131,6 +131,7 @@ ifneq ($(cross-compiling),yes)
+ # If the gd library is available we build the `memusagestat' program.
+ ifneq ($(LIBGD),no)
+ others: $(objpfx)memusage
++others += memusagestat
+ install-bin = memusagestat
+ install-bin-script += memusage
+ generated += memusagestat memusage
+@@ -154,8 +155,7 @@ cpp-srcs-left := $(memusagestat-modules)
+ lib := memusagestat
+ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
+ 
+-$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
+-	$(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
++LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm
+ 
+ ifeq ($(run-built-tests),yes)
+ ifeq (yes,$(build-shared))
diff --git a/SOURCES/glibc-rh1639343-2.patch b/SOURCES/glibc-rh1639343-2.patch
new file mode 100644
index 0000000..c5e4aa5
--- /dev/null
+++ b/SOURCES/glibc-rh1639343-2.patch
@@ -0,0 +1,90 @@
+commit 94a4e9e4f401ffe829a992820439977ead0a0ce7
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 10:41:43 2019 +0200
+
+    Extend BIND_NOW to installed programs with --enable-bind-now
+    
+    Commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix
+    --enable-bind-now [BZ #21015]") extended BIND_NOW to all installed
+    shared objects.  This change also covers installed programs.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/INSTALL b/INSTALL
+index d6c8e899fbb47dac..d56e102ec9ed3281 100644
+--- a/INSTALL
++++ b/INSTALL
+@@ -169,10 +169,10 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
+      protection.
+ 
+ '--enable-bind-now'
+-     Disable lazy binding for installed shared objects.  This provides
+-     additional security hardening because it enables full RELRO and a
+-     read-only global offset table (GOT), at the cost of slightly
+-     increased program load times.
++     Disable lazy binding for installed shared objects and programs.
++     This provides additional security hardening because it enables full
++     RELRO and a read-only global offset table (GOT), at the cost of
++     slightly increased program load times.
+ 
+ '--enable-pt_chown'
+      The file 'pt_chown' is a helper binary for 'grantpt' (*note
+diff --git a/Makeconfig b/Makeconfig
+index 8dc2fec9dc683416..742c0c0783a14bfa 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -398,6 +398,8 @@ endif
+ # test modules.
+ ifeq ($(bind-now),yes)
+ LDFLAGS-lib.so += -Wl,-z,now
++# Extra flags for dynamically linked non-test main programs.
++link-extra-flags += -Wl,-z,now
+ endif
+ 
+ # Command to run after every final link (executable or shared object).
+@@ -426,7 +428,7 @@ ifndef +link-pie
+ 	     $(link-extra-libs)
+ +link-pie-after-libc = $(+postctorS) $(+postinit)
+ define +link-pie
+-$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-pie-after-libc)
++$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-pie-tests
+@@ -454,7 +456,7 @@ ifndef +link-static
+ 	      $(link-extra-libs-static)
+ +link-static-after-libc = $(+postctorT) $(+postinit)
+ define +link-static
+-$(+link-static-before-libc) $(link-libc-static) $(+link-static-after-libc)
++$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-static-tests
+@@ -485,7 +487,7 @@ else  # not build-pie-default
+ 	      $(link-extra-libs)
+ +link-after-libc = $(+postctor) $(+postinit)
+ define +link
+-$(+link-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-after-libc)
++$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-tests
+diff --git a/manual/install.texi b/manual/install.texi
+index e757891dc2eebb2e..351d67c68b255f62 100644
+--- a/manual/install.texi
++++ b/manual/install.texi
+@@ -199,10 +199,10 @@ number of routines called directly from assembler are excluded from this
+ protection.
+ 
+ @item --enable-bind-now
+-Disable lazy binding for installed shared objects.  This provides
+-additional security hardening because it enables full RELRO and a
+-read-only global offset table (GOT), at the cost of slightly increased
+-program load times.
++Disable lazy binding for installed shared objects and programs.  This
++provides additional security hardening because it enables full RELRO
++and a read-only global offset table (GOT), at the cost of slightly
++increased program load times.
+ 
+ @pindex pt_chown
+ @findex grantpt
diff --git a/SOURCES/glibc-rh1639343-3.patch b/SOURCES/glibc-rh1639343-3.patch
new file mode 100644
index 0000000..4e4e146
--- /dev/null
+++ b/SOURCES/glibc-rh1639343-3.patch
@@ -0,0 +1,43 @@
+commit b5ffdc48c20ae865b197b67e5a9068a528fbc198
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 10:41:52 2019 +0200
+
+    benchtests: Enable BIND_NOW if configured with --enable-bind-now
+    
+    Benchmarks should reflect distribution build policies, so it makes
+    sense to honor the BIND_NOW configuration for them.
+    
+    This commit keeps using $(+link-tests), so that the benchmarks are
+    linked according to the --enable-hardcoded-path-in-tests configure
+    option.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/benchtests/Makefile b/benchtests/Makefile
+index bcd6a9c26d9a0005..28d6b0c43f5bd390 100644
+--- a/benchtests/Makefile
++++ b/benchtests/Makefile
+@@ -235,13 +235,21 @@ bench-func: $(binaries-bench)
+ 	  scripts/benchout.schema.json; \
+ 	fi
+ 
+-$(timing-type) $(binaries-bench) $(binaries-benchset) \
+-	$(binaries-bench-malloc): %: %.o $(objpfx)json-lib.o \
++ifeq ($(bind-now),yes)
++link-bench-bind-now = -Wl,-z,now
++endif
++
++bench-link-targets = $(timing-type) $(binaries-bench) $(binaries-benchset) \
++	$(binaries-bench-malloc)
++
++$(bench-link-targets): %: %.o $(objpfx)json-lib.o \
+ 	$(link-extra-libs-tests) \
+   $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
+   $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
+ 	$(+link-tests)
+ 
++$(bench-link-targets): LDFLAGS += $(link-bench-bind-now)
++
+ $(objpfx)bench-%.c: %-inputs $(bench-deps)
+ 	{ if [ -n "$($*-INCLUDE)" ]; then \
+ 	  cat $($*-INCLUDE); \
diff --git a/SOURCES/glibc-rh1639343-4.patch b/SOURCES/glibc-rh1639343-4.patch
new file mode 100644
index 0000000..10d4b48
--- /dev/null
+++ b/SOURCES/glibc-rh1639343-4.patch
@@ -0,0 +1,100 @@
+commit e30fb31c0ad8d31babd1d0d0f05e37c6579a870b
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Apr 26 07:16:47 2019 +0200
+
+    Makeconfig: Move $(CC) to +link command variables
+    
+    This change is needed to add linker flags which come very early in the
+    command linke (before LDFLAGS) and are not applied to test programs
+    (only to installed programs).
+
+diff --git a/Makeconfig b/Makeconfig
+index 742c0c0783a14bfa..1ad25fc5a7251aea 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -415,7 +415,7 @@ link-extra-libs-tests = $(libsupport)
+ 
+ # Command for linking PIE programs with the C library.
+ ifndef +link-pie
+-+link-pie-before-libc = $(CC) $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
+++link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
+ 	     -Wl,-O1 -nostdlib -nostartfiles -o $@ \
+ 	     $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
+ 	     $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
+@@ -428,23 +428,24 @@ ifndef +link-pie
+ 	     $(link-extra-libs)
+ +link-pie-after-libc = $(+postctorS) $(+postinit)
+ define +link-pie
+-$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
++$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \
++  $(link-libc) $(+link-pie-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-pie-tests
+-$(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
+-			 $(+link-pie-after-libc)
++$(CC) $(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
++  $(+link-pie-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-pie-printers-tests
+-$(+link-pie-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \
+-			 $(+link-pie-after-libc)
++$(CC) $(+link-pie-before-libc) $(built-rtld-LDFLAGS) \
++  $(link-libc-printers-tests) $(+link-pie-after-libc)
+ $(call after-link,$@)
+ endef
+ endif
+ # Command for statically linking programs with the C library.
+ ifndef +link-static
+-+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
+++link-static-before-libc = -nostdlib -nostartfiles -static -o $@ \
+ 	      $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \
+ 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
+ 	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \
+@@ -456,11 +457,13 @@ ifndef +link-static
+ 	      $(link-extra-libs-static)
+ +link-static-after-libc = $(+postctorT) $(+postinit)
+ define +link-static
+-$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc)
++$(CC) $(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) \
++  $(+link-static-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-static-tests
+-$(+link-static-before-libc) $(link-libc-static-tests) $(+link-static-after-libc)
++$(CC) $(+link-static-before-libc) $(link-libc-static-tests) \
++  $(+link-static-after-libc)
+ $(call after-link,$@)
+ endef
+ endif
+@@ -475,7 +478,7 @@ ifeq (yes,$(build-pie-default))
+ +link-tests = $(+link-pie-tests)
+ +link-printers-tests = $(+link-pie-printers-tests)
+ else  # not build-pie-default
+-+link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \
+++link-before-libc = -nostdlib -nostartfiles -o $@ \
+ 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
+ 	      $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
+ 	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \
+@@ -487,16 +490,17 @@ else  # not build-pie-default
+ 	      $(link-extra-libs)
+ +link-after-libc = $(+postctor) $(+postinit)
+ define +link
+-$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc)
++$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \
++  $(+link-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-tests
+-$(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
++$(CC) $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
+ 		     $(+link-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-printers-tests
+-$(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \
++$(CC) $(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \
+ 		     $(+link-after-libc)
+ $(call after-link,$@)
+ endef
diff --git a/SOURCES/glibc-rh1639343-5.patch b/SOURCES/glibc-rh1639343-5.patch
new file mode 100644
index 0000000..cefd167
--- /dev/null
+++ b/SOURCES/glibc-rh1639343-5.patch
@@ -0,0 +1,74 @@
+commit a8ff215e56050a907189e713fd449bcafe99ff6b
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Apr 26 07:16:30 2019 +0200
+
+    Makeconfig: Move -Wl,-rpath-link options before library references
+    
+    Previously, the -Wl,-rpath-link options came after the libraries
+    injected using LDLIBS-* variables on the link editor command line for
+    main programs.  As a result, it could happen that installed libraries
+    that reference glibc libraries used the installed glibc from the system
+    directories, instead of the glibc from the build tree.  This can lead to
+    link failures if the wrong version of libpthread.so.0 is used, for
+    instance, due to differences in the internal GLIBC_PRIVATE interfaces,
+    as seen with memusagestat and -lgd after commit
+    f9b645b4b0a10c43753296ce3fa40053fa44606a ("memusagestat: use local glibc
+    when linking [BZ #18465]").
+    
+    The isolation is necessarily imperfect because these installed
+    libraries are linked against the installed glibc in the system
+    directories.  However, in most cases, the built glibc will be newer
+    than the installed glibc, and this link is permitted because of the
+    ABI backwards compatibility glibc provides.
+
+diff --git a/Makeconfig b/Makeconfig
+index 1ad25fc5a7251aea..e315fb8a75ca5063 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -428,8 +428,8 @@ ifndef +link-pie
+ 	     $(link-extra-libs)
+ +link-pie-after-libc = $(+postctorS) $(+postinit)
+ define +link-pie
+-$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \
+-  $(link-libc) $(+link-pie-after-libc)
++$(CC) $(link-libc-rpath-link) $(+link-pie-before-libc) $(rtld-LDFLAGS) \
++  $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-pie-tests
+@@ -490,8 +490,8 @@ else  # not build-pie-default
+ 	      $(link-extra-libs)
+ +link-after-libc = $(+postctor) $(+postinit)
+ define +link
+-$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \
+-  $(+link-after-libc)
++$(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \
++  $(link-extra-flags) $(link-libc) $(+link-after-libc)
+ $(call after-link,$@)
+ endef
+ define +link-tests
+@@ -552,6 +552,15 @@ ifeq (yes,$(build-shared))
+ link-libc-rpath = -Wl,-rpath=$(rpath-link)
+ link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link)
+ 
++# For programs which are not tests, $(link-libc-rpath-link) is added
++# directly in $(+link), $(+link-pie) above, so that -Wl,-rpath-link
++# comes before the expansion of LDLIBS-* and affects libraries added
++# there.  For shared objects, -Wl,-rpath-link is added via
++# $(build-shlib-helper) and $(build-module-helper) in Makerules (also
++# before the expansion of LDLIBS-* variables).
++
++# Tests use -Wl,-rpath instead of -Wl,-rpath-link for
++# build-hardcoded-path-in-tests.
+ ifeq (yes,$(build-hardcoded-path-in-tests))
+ link-libc-tests-rpath-link = $(link-libc-rpath)
+ else
+@@ -562,7 +571,7 @@ link-libc-before-gnulib = $(common-objpfx)libc.so$(libc.so-version) \
+ 			  $(common-objpfx)$(patsubst %,$(libtype.oS),c) \
+ 			  $(as-needed) $(elf-objpfx)ld.so \
+ 			  $(no-as-needed)
+-link-libc = $(link-libc-rpath-link) $(link-libc-before-gnulib) $(gnulib)
++link-libc = $(link-libc-before-gnulib) $(gnulib)
+ 
+ link-libc-tests-after-rpath-link = $(link-libc-before-gnulib) $(gnulib-tests)
+ link-libc-tests = $(link-libc-tests-rpath-link) \
diff --git a/SOURCES/glibc-rh1639343-6.patch b/SOURCES/glibc-rh1639343-6.patch
new file mode 100644
index 0000000..643e192
--- /dev/null
+++ b/SOURCES/glibc-rh1639343-6.patch
@@ -0,0 +1,25 @@
+commit c57afec0a9b318bb691e0f5fa4e9681cf30df7a4
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Apr 26 07:16:56 2019 +0200
+
+    elf: Link sotruss-lib.so with BIND_NOW for --enable-bind-now
+    
+    The audit module itself can be linked with BIND_NOW; it does not
+    affect its functionality.
+    
+    This should complete the leftovers from commit
+    2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix
+    --enable-bind-now [BZ #21015]").
+
+diff --git a/elf/Makefile b/elf/Makefile
+index f5285b99e22fe84d..9194339836900b9d 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -133,6 +133,7 @@ install-others += $(inst_auditdir)/sotruss-lib.so
+ install-bin-script += sotruss
+ generated += sotruss
+ libof-sotruss-lib = extramodules
++LDFLAGS-sotruss-lib.so += $(z-now-$(bind-now))
+ $(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os
+ 	$(build-module-asneeded)
+ $(objpfx)sotruss-lib.so: $(common-objpfx)libc.so $(objpfx)ld.so \
diff --git a/SOURCES/glibc-rh1651283-1.patch b/SOURCES/glibc-rh1651283-1.patch
new file mode 100644
index 0000000..cd7e903
--- /dev/null
+++ b/SOURCES/glibc-rh1651283-1.patch
@@ -0,0 +1,31 @@
+commit d6db68e66dff25d12c3bc5641b60cbd7fb6ab44f
+Author: Moritz Eckert <m.eckert@cs.ucsb.edu>
+Date:   Thu Aug 16 21:08:36 2018 -0400
+
+    malloc: Mitigate null-byte overflow attacks
+    
+    * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
+    (malloc_consolidate): Likewise.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 13c52f376859562d..e450597e2e527fb7 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -4306,6 +4306,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+       prevsize = prev_size (p);
+       size += prevsize;
+       p = chunk_at_offset(p, -((long) prevsize));
++      if (__glibc_unlikely (chunksize(p) != prevsize))
++        malloc_printerr ("corrupted size vs. prev_size while consolidating");
+       unlink(av, p, bck, fwd);
+     }
+ 
+@@ -4467,6 +4469,8 @@ static void malloc_consolidate(mstate av)
+ 	  prevsize = prev_size (p);
+ 	  size += prevsize;
+ 	  p = chunk_at_offset(p, -((long) prevsize));
++	  if (__glibc_unlikely (chunksize(p) != prevsize))
++	    malloc_printerr ("corrupted size vs. prev_size in fastbins");
+ 	  unlink(av, p, bck, fwd);
+ 	}
+ 
diff --git a/SOURCES/glibc-rh1651283-2.patch b/SOURCES/glibc-rh1651283-2.patch
new file mode 100644
index 0000000..ad64396
--- /dev/null
+++ b/SOURCES/glibc-rh1651283-2.patch
@@ -0,0 +1,30 @@
+commit 30a17d8c95fbfb15c52d1115803b63aaa73a285c
+Author: Pochang Chen <johnchen902@gmail.com>
+Date:   Thu Aug 16 15:24:24 2018 -0400
+
+    malloc: Verify size of top chunk.
+    
+    The House of Force is a well-known technique to exploit heap
+    overflow. In essence, this exploit takes three steps:
+    1. Overwrite the size of top chunk with very large value (e.g. -1).
+    2. Request x bytes from top chunk. As the size of top chunk
+       is corrupted, x can be arbitrarily large and top chunk will
+       still be offset by x.
+    3. The next allocation from top chunk will thus be controllable.
+    
+    If we verify the size of top chunk at step 2, we can stop such attack.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index e450597e2e527fb7..d8d4581a9dcea80a 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -4084,6 +4084,9 @@ _int_malloc (mstate av, size_t bytes)
+       victim = av->top;
+       size = chunksize (victim);
+ 
++      if (__glibc_unlikely (size > av->system_mem))
++        malloc_printerr ("malloc(): corrupted top size");
++
+       if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
+         {
+           remainder_size = size - nb;
diff --git a/SOURCES/glibc-rh1651283-3.patch b/SOURCES/glibc-rh1651283-3.patch
new file mode 100644
index 0000000..65a07db
--- /dev/null
+++ b/SOURCES/glibc-rh1651283-3.patch
@@ -0,0 +1,122 @@
+commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c
+Author: Istvan Kurucsai <pistukem@gmail.com>
+Date:   Tue Jan 16 14:54:32 2018 +0100
+
+    malloc: Additional checks for unsorted bin integrity I.
+    
+    On Thu, Jan 11, 2018 at 3:50 PM, Florian Weimer <fweimer@redhat.com> wrote:
+    > On 11/07/2017 04:27 PM, Istvan Kurucsai wrote:
+    >>
+    >> +          next = chunk_at_offset (victim, size);
+    >
+    >
+    > For new code, we prefer declarations with initializers.
+    
+    Noted.
+    
+    >> +          if (__glibc_unlikely (chunksize_nomask (victim) <= 2 * SIZE_SZ)
+    >> +              || __glibc_unlikely (chunksize_nomask (victim) >
+    >> av->system_mem))
+    >> +            malloc_printerr("malloc(): invalid size (unsorted)");
+    >> +          if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ)
+    >> +              || __glibc_unlikely (chunksize_nomask (next) >
+    >> av->system_mem))
+    >> +            malloc_printerr("malloc(): invalid next size (unsorted)");
+    >> +          if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) !=
+    >> size))
+    >> +            malloc_printerr("malloc(): mismatching next->prev_size
+    >> (unsorted)");
+    >
+    >
+    > I think this check is redundant because prev_size (next) and chunksize
+    > (victim) are loaded from the same memory location.
+    
+    I'm fairly certain that it compares mchunk_size of victim against
+    mchunk_prev_size of the next chunk, i.e. the size of victim in its
+    header and footer.
+    
+    >> +          if (__glibc_unlikely (bck->fd != victim)
+    >> +              || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
+    >> +            malloc_printerr("malloc(): unsorted double linked list
+    >> corrupted");
+    >> +          if (__glibc_unlikely (prev_inuse(next)))
+    >> +            malloc_printerr("malloc(): invalid next->prev_inuse
+    >> (unsorted)");
+    >
+    >
+    > There's a missing space after malloc_printerr.
+    
+    Noted.
+    
+    > Why do you keep using chunksize_nomask?  We never investigated why the
+    > original code uses it.  It may have been an accident.
+    
+    You are right, I don't think it makes a difference in these checks. So
+    the size local can be reused for the checks against victim. For next,
+    leaving it as such avoids the masking operation.
+    
+    > Again, for non-main arenas, the checks against av->system_mem could be made
+    > tighter (against the heap size).  Maybe you could put the condition into a
+    > separate inline function?
+    
+    We could also do a chunk boundary check similar to what I proposed in
+    the thread for the first patch in the series to be even more strict.
+    I'll gladly try to implement either but believe that refining these
+    checks would bring less benefits than in the case of the top chunk.
+    Intra-arena or intra-heap overlaps would still be doable here with
+    unsorted chunks and I don't see any way to counter that besides more
+    generic measures like randomizing allocations and your metadata
+    encoding patches.
+    
+    I've attached a revised version with the above comments incorporated
+    but without the refined checks.
+    
+    Thanks,
+    Istvan
+    
+    From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001
+    From: Istvan Kurucsai <pistukem@gmail.com>
+    Date: Tue, 16 Jan 2018 14:48:16 +0100
+    Subject: [PATCH v2 1/1] malloc: Additional checks for unsorted bin integrity
+     I.
+    
+    Ensure the following properties of chunks encountered during binning:
+    - victim chunk has reasonable size
+    - next chunk has reasonable size
+    - next->prev_size == victim->size
+    - valid double linked list
+    - PREV_INUSE of next chunk is unset
+    
+        * malloc/malloc.c (_int_malloc): Additional binning code checks.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index d8d4581a9dcea80a..dad0e73735789530 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -3724,11 +3724,22 @@ _int_malloc (mstate av, size_t bytes)
+       while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
+         {
+           bck = victim->bk;
+-          if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
+-              || __builtin_expect (chunksize_nomask (victim)
+-				   > av->system_mem, 0))
+-            malloc_printerr ("malloc(): memory corruption");
+           size = chunksize (victim);
++          mchunkptr next = chunk_at_offset (victim, size);
++
++          if (__glibc_unlikely (size <= 2 * SIZE_SZ)
++              || __glibc_unlikely (size > av->system_mem))
++            malloc_printerr ("malloc(): invalid size (unsorted)");
++          if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ)
++              || __glibc_unlikely (chunksize_nomask (next) > av->system_mem))
++            malloc_printerr ("malloc(): invalid next size (unsorted)");
++          if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size))
++            malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)");
++          if (__glibc_unlikely (bck->fd != victim)
++              || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
++            malloc_printerr ("malloc(): unsorted double linked list corrupted");
++          if (__glibc_unlikely (prev_inuse(next)))
++            malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");
+ 
+           /*
+              If a small request, try to use last remainder if it is the
diff --git a/SOURCES/glibc-rh1651283-4.patch b/SOURCES/glibc-rh1651283-4.patch
new file mode 100644
index 0000000..fcec8ee
--- /dev/null
+++ b/SOURCES/glibc-rh1651283-4.patch
@@ -0,0 +1,26 @@
+The below commit contains only a whitespace change and was backported in
+order to avoid future conflicts.
+
+commit 35cfefd96062145eeb8aee6bd72d07e0909a6b2e
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Aug 20 14:57:13 2018 +0200
+
+    malloc: Add ChangeLog for accidentally committed change
+    
+    Commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c ("malloc: Additional
+    checks for unsorted bin integrity I.") was committed without a
+    whitespace fix, so it is adjusted here as well.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index c07463001a65af90..eb6a8ff33c0c313b 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -3745,7 +3745,7 @@ _int_malloc (mstate av, size_t bytes)
+           if (__glibc_unlikely (bck->fd != victim)
+               || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
+             malloc_printerr ("malloc(): unsorted double linked list corrupted");
+-          if (__glibc_unlikely (prev_inuse(next)))
++          if (__glibc_unlikely (prev_inuse (next)))
+             malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");
+ 
+           /*
diff --git a/SOURCES/glibc-rh1651283-5.patch b/SOURCES/glibc-rh1651283-5.patch
new file mode 100644
index 0000000..e18b513
--- /dev/null
+++ b/SOURCES/glibc-rh1651283-5.patch
@@ -0,0 +1,38 @@
+commit ebe544bf6e8eec35e754fd49efb027c6f161b6cb
+Author: Istvan Kurucsai <pistukem@gmail.com>
+Date:   Thu Dec 20 23:30:07 2018 -0500
+
+    malloc: Add more integrity checks to mremap_chunk.
+    
+    * malloc/malloc.c (mremap_chunk): Additional checks.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index eb6a8ff33c0c313b..4df5cb4862a7b854 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -2856,16 +2856,22 @@ mremap_chunk (mchunkptr p, size_t new_size)
+   char *cp;
+ 
+   assert (chunk_is_mmapped (p));
+-  assert (((size + offset) & (GLRO (dl_pagesize) - 1)) == 0);
++
++  uintptr_t block = (uintptr_t) p - offset;
++  uintptr_t mem = (uintptr_t) chunk2mem(p);
++  size_t total_size = offset + size;
++  if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0
++      || __glibc_unlikely (!powerof2 (mem & (pagesize - 1))))
++    malloc_printerr("mremap_chunk(): invalid pointer");
+ 
+   /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */
+   new_size = ALIGN_UP (new_size + offset + SIZE_SZ, pagesize);
+ 
+   /* No need to remap if the number of pages does not change.  */
+-  if (size + offset == new_size)
++  if (total_size == new_size)
+     return p;
+ 
+-  cp = (char *) __mremap ((char *) p - offset, size + offset, new_size,
++  cp = (char *) __mremap ((char *) block, total_size, new_size,
+                           MREMAP_MAYMOVE);
+ 
+   if (cp == MAP_FAILED)
diff --git a/SOURCES/glibc-rh1651283-6.patch b/SOURCES/glibc-rh1651283-6.patch
new file mode 100644
index 0000000..c578d11
--- /dev/null
+++ b/SOURCES/glibc-rh1651283-6.patch
@@ -0,0 +1,38 @@
+commit c0e82f117357a941e4d40fcc08babbd6a3c3a1b5
+Author: Istvan Kurucsai <pistukem@gmail.com>
+Date:   Fri Dec 21 00:13:01 2018 -0500
+
+    malloc: Check the alignment of mmapped chunks before unmapping.
+    
+    * malloc/malloc.c (munmap_chunk): Verify chunk alignment.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 4df5cb4862a7b854..4412a4ffc83b013b 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -2817,6 +2817,7 @@ systrim (size_t pad, mstate av)
+ static void
+ munmap_chunk (mchunkptr p)
+ {
++  size_t pagesize = GLRO (dl_pagesize);
+   INTERNAL_SIZE_T size = chunksize (p);
+ 
+   assert (chunk_is_mmapped (p));
+@@ -2826,6 +2827,7 @@ munmap_chunk (mchunkptr p)
+   if (DUMPED_MAIN_ARENA_CHUNK (p))
+     return;
+ 
++  uintptr_t mem = (uintptr_t) chunk2mem (p);
+   uintptr_t block = (uintptr_t) p - prev_size (p);
+   size_t total_size = prev_size (p) + size;
+   /* Unfortunately we have to do the compilers job by hand here.  Normally
+@@ -2833,7 +2835,8 @@ munmap_chunk (mchunkptr p)
+      page size.  But gcc does not recognize the optimization possibility
+      (in the moment at least) so we combine the two values into one before
+      the bit test.  */
+-  if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0))
++  if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0
++      || __glibc_unlikely (!powerof2 (mem & (pagesize - 1))))
+     malloc_printerr ("munmap_chunk(): invalid pointer");
+ 
+   atomic_decrement (&mp_.n_mmaps);
diff --git a/SOURCES/glibc-rh1651283-7.patch b/SOURCES/glibc-rh1651283-7.patch
new file mode 100644
index 0000000..af0f92b
--- /dev/null
+++ b/SOURCES/glibc-rh1651283-7.patch
@@ -0,0 +1,31 @@
+commit 5b06f538c5aee0389ed034f60d90a8884d6d54de
+Author: Adam Maris <amaris@redhat.com>
+Date:   Thu Mar 14 16:51:16 2019 -0400
+
+    malloc: Check for large bin list corruption when inserting unsorted chunk
+    
+    Fixes bug 24216. This patch adds security checks for bk and bk_nextsize pointers
+    of chunks in large bin when inserting chunk from unsorted bin. It was possible
+    to write the pointer to victim (newly inserted chunk) to arbitrary memory
+    locations if bk or bk_nextsize pointers of the next large bin chunk
+    got corrupted.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 4412a4ffc83b013b..723d393f529bdb4c 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -3876,10 +3876,14 @@ _int_malloc (mstate av, size_t bytes)
+                         {
+                           victim->fd_nextsize = fwd;
+                           victim->bk_nextsize = fwd->bk_nextsize;
++                          if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd))
++                            malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)");
+                           fwd->bk_nextsize = victim;
+                           victim->bk_nextsize->fd_nextsize = victim;
+                         }
+                       bck = fwd->bk;
++                      if (bck->fd != fwd)
++                        malloc_printerr ("malloc(): largebin double linked list corrupted (bk)");
+                     }
+                 }
+               else
diff --git a/SOURCES/glibc-rh1651742.patch b/SOURCES/glibc-rh1651742.patch
new file mode 100644
index 0000000..1851691
--- /dev/null
+++ b/SOURCES/glibc-rh1651742.patch
@@ -0,0 +1,307 @@
+commit f0458cf4f9ff3d870c43b624e6dccaaf657d5e83
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Mon Aug 27 09:42:50 2018 -0300
+
+    powerpc: Only enable TLE with PPC_FEATURE2_HTM_NOSC
+    
+    Linux from 3.9 through 4.2 does not abort HTM transaction on syscalls,
+    instead it suspend and resume it when leaving the kernel.  The
+    side-effects of the syscall will always remain visible, even if the
+    transaction is aborted.  This is an issue when transaction is used along
+    with futex syscall, on pthread_cond_wait for instance, where the futex
+    call might succeed but the transaction is rolled back leading the
+    pthread_cond object in an inconsistent state.
+    
+    Glibc used to prevent it by always aborting a transaction before issuing
+    a syscall.  Linux 4.2 also decided to abort active transaction in
+    syscalls which makes the glibc workaround superfluous.  Worse, glibc
+    transaction abortion leads to a performance issue on recent kernels
+    where the HTM state is saved/restore lazily (v4.9).  By aborting a
+    transaction on every syscalls, regardless whether a transaction has being
+    initiated before, GLIBS makes the kernel always save/restore HTM state
+    (it can not even lazily disable it after a certain number of syscall
+    iterations).
+    
+    Because of this shortcoming, Transactional Lock Elision is just enabled
+    when it has been explicitly set (either by tunables of by a configure
+    switch) and if kernel aborts HTM transactions on syscalls
+    (PPC_FEATURE2_HTM_NOSC).  It is reported that using simple benchmark [1],
+    the context-switch is about 5% faster by not issuing a tabort in every
+    syscall in newer kernels.
+    
+    Checked on powerpc64le-linux-gnu with 4.4.0 kernel (Ubuntu 16.04).
+    
+    	* NEWS: Add note about new TLE support on powerpc64le.
+    	* sysdeps/powerpc/nptl/tcb-offsets.sym (TM_CAPABLE): Remove.
+    	* sysdeps/powerpc/nptl/tls.h (tcbhead_t): Rename tm_capable to
+    	__ununsed1.
+    	(TLS_INIT_TP, TLS_DEFINE_INIT_TP): Remove tm_capable setup.
+    	(THREAD_GET_TM_CAPABLE, THREAD_SET_TM_CAPABLE): Remove macros.
+    	* sysdeps/powerpc/powerpc32/sysdep.h,
+    	sysdeps/powerpc/powerpc64/sysdep.h (ABORT_TRANSACTION_IMPL,
+    	ABORT_TRANSACTION): Remove macros.
+    	* sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise.
+    	* sysdeps/unix/sysv/linux/powerpc/elision-conf.c (elision_init): Set
+    	__pthread_force_elision iff PPC_FEATURE2_HTM_NOSC is set.
+    	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h,
+    	sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
+    	sysdeps/unix/sysv/linux/powerpc/syscall.S (ABORT_TRANSACTION): Remove
+    	usage.
+    	* sysdeps/unix/sysv/linux/powerpc/not-errno.h: Remove file.
+    
+    Reported-by: Breno Leitão <leitao@debian.org>
+
+diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym
+index e5bb2b3..4c01615 100644
+--- a/sysdeps/powerpc/nptl/tcb-offsets.sym
++++ b/sysdeps/powerpc/nptl/tcb-offsets.sym
+@@ -21,7 +21,6 @@ DSO_SLOT2			(offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_
+ #ifdef __powerpc64__
+ TCB_AT_PLATFORM			(offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t))
+ #endif
+-TM_CAPABLE			(offsetof (tcbhead_t, tm_capable) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
+ #ifndef __powerpc64__
+ TCB_AT_PLATFORM			(offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t))
+ PADDING				(offsetof (tcbhead_t, padding) - TLS_TCB_OFFSET - sizeof(tcbhead_t))
+diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
+index f88fed5..8317ca7 100644
+--- a/sysdeps/powerpc/nptl/tls.h
++++ b/sysdeps/powerpc/nptl/tls.h
+@@ -67,8 +67,7 @@ typedef struct
+   uint32_t padding;
+   uint32_t at_platform;
+ #endif
+-  /* Indicate if HTM capable (ISA 2.07).  */
+-  uint32_t tm_capable;
++  uint32_t __unused;
+   /* Reservation for AT_PLATFORM data - powerpc64.  */
+ #ifdef __powerpc64__
+   uint32_t at_platform;
+@@ -142,7 +141,6 @@ register void *__thread_register __asm__ ("r13");
+ # define TLS_INIT_TP(tcbp) \
+   ({ 									      \
+     __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET;		      \
+-    THREAD_SET_TM_CAPABLE (__tcb_hwcap & PPC_FEATURE2_HAS_HTM ? 1 : 0);	      \
+     THREAD_SET_HWCAP (__tcb_hwcap);					      \
+     THREAD_SET_AT_PLATFORM (__tcb_platform);				      \
+     NULL;								      \
+@@ -151,8 +149,6 @@ register void *__thread_register __asm__ ("r13");
+ /* Value passed to 'clone' for initialization of the thread register.  */
+ # define TLS_DEFINE_INIT_TP(tp, pd) \
+     void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE;	      \
+-    (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) =	      \
+-      THREAD_GET_TM_CAPABLE ();						      \
+     (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].hwcap) =	      \
+       THREAD_GET_HWCAP ();						      \
+     (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].at_platform) =	      \
+@@ -210,13 +206,6 @@ register void *__thread_register __asm__ ("r13");
+ 		     + TLS_PRE_TCB_SIZE))[-1].pointer_guard		      \
+      = THREAD_GET_POINTER_GUARD())
+ 
+-/* tm_capable field in TCB head.  */
+-# define THREAD_GET_TM_CAPABLE() \
+-    (((tcbhead_t *) ((char *) __thread_register				      \
+-		     - TLS_TCB_OFFSET))[-1].tm_capable)
+-# define THREAD_SET_TM_CAPABLE(value) \
+-    (THREAD_GET_TM_CAPABLE () = (value))
+-
+ /* hwcap field in TCB head.  */
+ # define THREAD_GET_HWCAP() \
+     (((tcbhead_t *) ((char *) __thread_register				      \
+diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
+index 5f1294e..93097c5 100644
+--- a/sysdeps/powerpc/powerpc32/sysdep.h
++++ b/sysdeps/powerpc/powerpc32/sysdep.h
+@@ -90,24 +90,7 @@ GOT_LABEL:			;					      \
+   cfi_endproc;								      \
+   ASM_SIZE_DIRECTIVE(name)
+ 
+-#if !IS_IN(rtld) && !defined(__SPE__)
+-# define ABORT_TRANSACTION_IMPL \
+-    cmpwi    2,0;		\
+-    beq      1f;		\
+-    lwz      0,TM_CAPABLE(2);	\
+-    cmpwi    0,0;		\
+-    beq	     1f;		\
+-    li       11,_ABORT_SYSCALL;	\
+-    tabort.  11;		\
+-    .align 4;			\
+-1:
+-#else
+-# define ABORT_TRANSACTION_IMPL
+-#endif
+-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL
+-
+ #define DO_CALL(syscall)						      \
+-    ABORT_TRANSACTION							      \
+     li 0,syscall;							      \
+     sc
+ 
+diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
+index 2df1d9b..50e64f9 100644
+--- a/sysdeps/powerpc/powerpc64/sysdep.h
++++ b/sysdeps/powerpc/powerpc64/sysdep.h
+@@ -263,24 +263,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
+   TRACEBACK_MASK(name,mask);	\
+   END_2(name)
+ 
+-#if !IS_IN(rtld)
+-# define ABORT_TRANSACTION_IMPL \
+-    cmpdi    13,0;		\
+-    beq      1f;		\
+-    lwz      0,TM_CAPABLE(13);	\
+-    cmpwi    0,0;		\
+-    beq	     1f;		\
+-    li       11,_ABORT_SYSCALL;	\
+-    tabort.  11;		\
+-    .p2align 4;			\
+-1:
+-#else
+-# define ABORT_TRANSACTION_IMPL
+-#endif
+-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL
+-
+ #define DO_CALL(syscall) \
+-    ABORT_TRANSACTION \
+     li 0,syscall; \
+     sc
+ 
+diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h
+index 8a6d236..c8bf25e 100644
+--- a/sysdeps/powerpc/sysdep.h
++++ b/sysdeps/powerpc/sysdep.h
+@@ -21,8 +21,6 @@
+  */
+ #define _SYSDEPS_SYSDEP_H 1
+ #include <bits/hwcap.h>
+-#include <tls.h>
+-#include <htm.h>
+ 
+ #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC)
+ 
+@@ -166,22 +164,4 @@
+ #define ALIGNARG(log2) log2
+ #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+ 
+-#else
+-
+-/* Linux kernel powerpc documentation [1] states issuing a syscall inside a
+-   transaction is not recommended and may lead to undefined behavior.  It
+-   also states syscalls do not abort transactions.  To avoid such traps,
+-   we abort transaction just before syscalls.
+-
+-   [1] Documentation/powerpc/transactional_memory.txt [Syscalls]  */
+-#if !IS_IN(rtld) && !defined(__SPE__)
+-# define ABORT_TRANSACTION \
+-  ({ 						\
+-    if (THREAD_GET_TM_CAPABLE ())		\
+-      __libc_tabort (_ABORT_SYSCALL);	\
+-  })
+-#else
+-# define ABORT_TRANSACTION
+-#endif
+-
+ #endif	/* __ASSEMBLER__ */
+diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
+index 906882a..fc82bd1 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
++++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
+@@ -127,6 +127,26 @@ elision_init (int argc __attribute__ ((unused)),
+ 	       TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort));
+ #endif
+ 
++  /* Linux from 3.9 through 4.2 do not abort HTM transaction on syscalls,
++     instead it suspends the transaction and resumes it when returning to
++     usercode.  The side-effects of the syscall will always remain visible,
++     even if the transaction is aborted.  This is an issue when a transaction
++     is used along with futex syscall, on pthread_cond_wait for instance,
++     where futex might succeed but the transaction is rolled back leading
++     the condition variable object in an inconsistent state.
++
++     Glibc used to prevent it by always aborting a transaction before issuing
++     a syscall.  Linux 4.2 also decided to abort active transaction in
++     syscalls which makes the glibc workaround superflours.  Worse, glibc
++     transaction abortions leads to a performance issues on recent kernels.
++
++     So Lock Elision is just enabled when it has been explict set (either
++     by tunables of by a configure switch) and if kernel aborts HTM
++     transactions on syscalls (PPC_FEATURE2_HTM_NOSC)  */
++
++  __pthread_force_elision = (__pthread_force_elision
++			     && GLRO (dl_hwcap2) & PPC_FEATURE2_HTM_NOSC);
++
+   if (!__pthread_force_elision)
+     __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks.  */
+ }
+diff --git a/sysdeps/unix/sysv/linux/powerpc/not-errno.h b/sysdeps/unix/sysv/linux/powerpc/not-errno.h
+deleted file mode 100644
+index 27da21b..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/not-errno.h
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/* Syscall wrapper that do not set errno.  Linux powerpc version.
+-   Copyright (C) 2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* __access_noerrno is used during process initialization in elf/dl-tunables.c
+-   before the TCB is initialized, prohibiting the usage of
+-   ABORT_TRANSACTION.  */
+-#undef ABORT_TRANSACTION
+-#define ABORT_TRANSACTION
+-
+-#include "sysdeps/unix/sysv/linux/not-errno.h"
+-
+-/* Recover ABORT_TRANSACTION's previous value, in order to not affect
+-   other syscalls.  */
+-#undef ABORT_TRANSACTION
+-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
+index f7277d5..ec5c525 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
+@@ -109,7 +109,6 @@
+     register long int r11 __asm__ ("r11");				\
+     register long int r12 __asm__ ("r12");				\
+     LOADARGS_##nr(name, args);						\
+-    ABORT_TRANSACTION;							\
+     __asm__ __volatile__						\
+       ("sc   \n\t"							\
+        "mfcr %0"							\
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
+index 0956cf0..1f17f7b 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
+@@ -131,7 +131,6 @@
+     register long int r7  __asm__ ("r7");				\
+     register long int r8  __asm__ ("r8");				\
+     LOADARGS_##nr (name, ##args);					\
+-    ABORT_TRANSACTION;							\
+     __asm__ __volatile__						\
+       ("sc\n\t"								\
+        "mfcr  %0\n\t"							\
+diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S
+index 2da9172..bbab613 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S
++++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S
+@@ -18,7 +18,6 @@
+ #include <sysdep.h>
+ 
+ ENTRY (syscall)
+-	ABORT_TRANSACTION
+ 	mr   r0,r3
+ 	mr   r3,r4
+ 	mr   r4,r5
diff --git a/SOURCES/glibc-rh1658901.patch b/SOURCES/glibc-rh1658901.patch
new file mode 100644
index 0000000..59d7cab
--- /dev/null
+++ b/SOURCES/glibc-rh1658901.patch
@@ -0,0 +1,140 @@
+Upstream commit 1d880d4a9bf7608c2cd33bbe954ce6995f79121a
+
+From: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+Date: Wed, 12 Dec 2018 12:41:52 +0000 (-0200)
+Subject: powerpc: Add missing CFI register information (bug #23614)
+X-Git-Tag: glibc-2.29~210
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=1d880d4a9bf7608c2cd33bbe954ce6995f79121a
+
+powerpc: Add missing CFI register information (bug #23614)
+
+Add CFI information about the offset of registers stored in the stack
+frame.
+
+	[BZ #23614]
+	* sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for
+	registers saved in the stack frame.
+	* sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise.
+	* sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise.
+
+Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+Reviewed-by: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+---
+
+diff --git a/sysdeps/powerpc/powerpc64/addmul_1.S b/sysdeps/powerpc/powerpc64/addmul_1.S
+index 48e3b1b..e450d6a 100644
+--- a/sysdeps/powerpc/powerpc64/addmul_1.S
++++ b/sysdeps/powerpc/powerpc64/addmul_1.S
+@@ -34,16 +34,27 @@
+ #define N   r5
+ #define VL  r6
+ 
++#define R27SAVE  (-40)
++#define R28SAVE  (-32)
++#define R29SAVE  (-24)
++#define R30SAVE  (-16)
++#define R31SAVE  (-8)
++
+ ENTRY_TOCLESS (FUNC, 5)
+-	std	r31, -8(r1)
++	std	r31, R31SAVE(r1)
+ 	rldicl.	r0, N, 0, 62
+-	std	r30, -16(r1)
++	std	r30, R30SAVE(r1)
+ 	cmpdi	VL, r0, 2
+-	std	r29, -24(r1)
++	std	r29, R29SAVE(r1)
+ 	addi	N, N, 3
+-	std	r28, -32(r1)
++	std	r28, R28SAVE(r1)
+ 	srdi	N, N, 2
+-	std	r27, -40(r1)
++	std	r27, R27SAVE(r1)
++	cfi_offset(r31, R31SAVE)
++	cfi_offset(r30, R30SAVE)
++	cfi_offset(r29, R29SAVE)
++	cfi_offset(r28, R28SAVE)
++	cfi_offset(r27, R27SAVE)
+ 	mtctr	N
+ 	beq	cr0, L(b00)
+ 	blt	cr6, L(b01)
+@@ -199,10 +210,10 @@ L(end):	mulld	r0, r9, VL
+ 	addic	r11, r11, 1
+ #endif
+ 	addze	RP, r8
+-	ld	r31, -8(r1)
+-	ld	r30, -16(r1)
+-	ld	r29, -24(r1)
+-	ld	r28, -32(r1)
+-	ld	r27, -40(r1)
++	ld	r31, R31SAVE(r1)
++	ld	r30, R30SAVE(r1)
++	ld	r29, R29SAVE(r1)
++	ld	r28, R28SAVE(r1)
++	ld	r27, R27SAVE(r1)
+ 	blr
+ END(FUNC)
+diff --git a/sysdeps/powerpc/powerpc64/lshift.S b/sysdeps/powerpc/powerpc64/lshift.S
+index 8b6396e..855d6f2 100644
+--- a/sysdeps/powerpc/powerpc64/lshift.S
++++ b/sysdeps/powerpc/powerpc64/lshift.S
+@@ -26,11 +26,15 @@
+ #define TNC      r0
+ #define U0      r30
+ #define U1      r31
++#define U0SAVE  (-16)
++#define U1SAVE  (-8)
+ #define RETVAL   r5
+ 
+ ENTRY_TOCLESS (__mpn_lshift, 5)
+-	std	U1, -8(r1)
+-	std	U0, -16(r1)
++	std	U1, U1SAVE(r1)
++	std	U0, U0SAVE(r1)
++	cfi_offset(U1, U1SAVE)
++	cfi_offset(U0, U0SAVE)
+ 	subfic	TNC, CNT, 64
+ 	sldi	r7, N, RP
+ 	add	UP, UP, r7
+@@ -170,8 +174,8 @@ L(cj3):	or	r10, r12, r7
+ L(cj2):	std	r10, -32(RP)
+ 	std	r8, -40(RP)
+ 
+-L(ret):	ld	U1, -8(r1)
+-	ld	U0, -16(r1)
++L(ret):	ld	U1, U1SAVE(r1)
++	ld	U0, U0SAVE(r1)
+ 	mr	RP, RETVAL
+ 	blr
+ END(__mpn_lshift)
+diff --git a/sysdeps/powerpc/powerpc64/mul_1.S b/sysdeps/powerpc/powerpc64/mul_1.S
+index 953ded8..cade365 100644
+--- a/sysdeps/powerpc/powerpc64/mul_1.S
++++ b/sysdeps/powerpc/powerpc64/mul_1.S
+@@ -24,9 +24,14 @@
+ #define N   r5
+ #define VL  r6
+ 
++#define R26SAVE  (-48)
++#define R27SAVE  (-40)
++
+ ENTRY_TOCLESS (__mpn_mul_1, 5)
+-	std	r27, -40(r1)
+-	std	r26, -48(r1)
++	std	r27, R27SAVE(r1)
++	std	r26, R26SAVE(r1)
++	cfi_offset(r27, R27SAVE)
++	cfi_offset(r26, R26SAVE)
+ 	li	r12, 0
+ 	ld	r26, 0(UP)
+ 
+@@ -129,7 +134,7 @@ L(end):	mulld	r0, r26, VL
+ 	std	r0, 0(RP)
+ 	std	r7, 8(RP)
+ L(ret):	addze	RP, r8
+-	ld	r27, -40(r1)
+-	ld	r26, -48(r1)
++	ld	r27, R27SAVE(r1)
++	ld	r26, R26SAVE(r1)
+ 	blr
+ END(__mpn_mul_1)
diff --git a/SOURCES/glibc-rh1659293-1.patch b/SOURCES/glibc-rh1659293-1.patch
new file mode 100644
index 0000000..cf8ca21
--- /dev/null
+++ b/SOURCES/glibc-rh1659293-1.patch
@@ -0,0 +1,663 @@
+nptl: Fix pthread_rwlock_try*lock stalls (Bug 23844)
+
+For a full analysis of both the pthread_rwlock_tryrdlock() stall
+and the pthread_rwlock_trywrlock() stall see:
+https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14
+
+In the pthread_rwlock_trydlock() function we fail to inspect for
+PTHREAD_RWLOCK_FUTEX_USED in __wrphase_futex and wake the waiting
+readers.
+
+In the pthread_rwlock_trywrlock() function we write 1 to
+__wrphase_futex and loose the setting of the PTHREAD_RWLOCK_FUTEX_USED
+bit, again failing to wake waiting readers during unlock.
+
+The fix in the case of pthread_rwlock_trydlock() is to check for
+PTHREAD_RWLOCK_FUTEX_USED and wake the readers.
+
+The fix in the case of pthread_rwlock_trywrlock() is to only write
+1 to __wrphase_futex if we installed the write phase, since all other
+readers would be spinning waiting for this step.
+
+We add two new tests, one exercises the stall for
+pthread_rwlock_trywrlock() which is easy to exercise, and one exercises
+the stall for pthread_rwlock_trydlock() which is harder to exercise.
+
+The pthread_rwlock_trywrlock() test fails consistently without the fix,
+and passes after. The pthread_rwlock_tryrdlock() test fails roughly
+5-10% of the time without the fix, and passes all the time after.
+
+Signed-off-by: Carlos O'Donell <carlos@redhat.com>
+Signed-off-by: Torvald Riegel <triegel@redhat.com>
+Signed-off-by: Rik Prohaska <prohaska7@gmail.com>
+Co-authored-by: Torvald Riegel <triegel@redhat.com>
+Co-authored-by: Rik Prohaska <prohaska7@gmail.com>
+(cherry picked from commit 5fc9ed4c4058bfbdf51ad6e7aac7d209b580e8c4)
+
+diff --git a/ChangeLog b/ChangeLog
+index 08b42bd2f56471e3..ed1a2ffe8356fd96 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,20 @@
++2019-01-31  Carlos O'Donell  <carlos@redhat.com>
++	    Torvald Riegel  <triegel@redhat.com>
++	    Rik Prohaska  <prohaska7@gmail.com>
++
++	[BZ# 23844]
++	* nptl/Makefile (tests): Add tst-rwlock-tryrdlock-stall, and
++	tst-rwlock-trywrlock-stall.
++	* nptl/pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock):
++	Wake waiters if PTHREAD_RWLOCK_FUTEX_USED is set.
++	* nptl/pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock):
++	Set __wrphase_fute to 1 only if we started the write phase.
++	* nptl/tst-rwlock-tryrdlock-stall.c: New file.
++	* nptl/tst-rwlock-trywrlock-stall.c: New file.
++	* support/Makefile (libsupport-routines): Add xpthread_rwlock_destroy.
++	* support/xpthread_rwlock_destroy.c: New file.
++	* support/xthread.h: Declare xpthread_rwlock_destroy.
++
+ 2018-08-01  Carlos O'Donel  <carlos@redhat.com>
+ 
+ 	* version.h (RELEASE): Set to "stable".
+diff --git a/nptl/Makefile b/nptl/Makefile
+index 2d2db648f730db61..b1003cf56b31ddfa 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -319,7 +319,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
+ 	tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
+ 	tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \
+ 	tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \
+-	tst-rwlock-pwn
++	tst-rwlock-pwn \
++	tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall
+ 
+ tests-internal := tst-rwlock19 tst-rwlock20 \
+ 		  tst-sem11 tst-sem12 tst-sem13 \
+diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c
+index 4aec1fc15acb2448..31a88d33a6e8f256 100644
+--- a/nptl/pthread_rwlock_tryrdlock.c
++++ b/nptl/pthread_rwlock_tryrdlock.c
+@@ -94,15 +94,22 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+       /* Same as in __pthread_rwlock_rdlock_full:
+ 	 We started the read phase, so we are also responsible for
+ 	 updating the write-phase futex.  Relaxed MO is sufficient.
+-	 Note that there can be no other reader that we have to wake
+-	 because all other readers will see the read phase started by us
+-	 (or they will try to start it themselves); if a writer started
+-	 the read phase, we cannot have started it.  Furthermore, we
+-	 cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will
+-	 overwrite the value set by the most recent writer (or the readers
+-	 before it in case of explicit hand-over) and we know that there
+-	 are no waiting readers.  */
+-      atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
++	 We have to do the same steps as a writer would when handing over the
++	 read phase to use because other readers cannot distinguish between
++	 us and the writer.
++	 Note that __pthread_rwlock_tryrdlock callers will not have to be
++	 woken up because they will either see the read phase started by us
++	 or they will try to start it themselves; however, callers of
++	 __pthread_rwlock_rdlock_full just increase the reader count and then
++	 check what state the lock is in, so they cannot distinguish between
++	 us and a writer that acquired and released the lock in the
++	 meantime.  */
++      if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
++	  & PTHREAD_RWLOCK_FUTEX_USED) != 0)
++	{
++	  int private = __pthread_rwlock_get_private (rwlock);
++	  futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
++	}
+     }
+ 
+   return 0;
+diff --git a/nptl/pthread_rwlock_trywrlock.c b/nptl/pthread_rwlock_trywrlock.c
+index 5a73eba756077297..f2e3443466a2554f 100644
+--- a/nptl/pthread_rwlock_trywrlock.c
++++ b/nptl/pthread_rwlock_trywrlock.c
+@@ -46,8 +46,15 @@ __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+ 	  &rwlock->__data.__readers, &r,
+ 	  r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
+ 	{
++	  /* We have become the primary writer and we cannot have shared
++	     the PTHREAD_RWLOCK_FUTEX_USED flag with someone else, so we
++	     can simply enable blocking (see full wrlock code).  */
+ 	  atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
+-	  atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
++	  /* If we started a write phase, we need to enable readers to
++	     wait.  If we did not, we must not change it because other threads
++	     may have set the PTHREAD_RWLOCK_FUTEX_USED in the meantime.  */
++	  if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
++	    atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
+ 	  atomic_store_relaxed (&rwlock->__data.__cur_writer,
+ 	      THREAD_GETMEM (THREAD_SELF, tid));
+ 	  return 0;
+diff --git a/nptl/tst-rwlock-tryrdlock-stall.c b/nptl/tst-rwlock-tryrdlock-stall.c
+new file mode 100644
+index 0000000000000000..5e476da2b8d00c6a
+--- /dev/null
++++ b/nptl/tst-rwlock-tryrdlock-stall.c
+@@ -0,0 +1,355 @@
++/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* For a full analysis see comment:
++   https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14
++
++   Provided here for reference:
++
++   --- Analysis of pthread_rwlock_tryrdlock() stall ---
++   A read lock begins to execute.
++
++   In __pthread_rwlock_rdlock_full:
++
++   We can attempt a read lock, but find that the lock is
++   in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit
++   is set), and the lock is held by a primary writer
++   (PTHREAD_RWLOCK_WRLOCKED is set). In this case we must
++   wait for explicit hand over from the writer to us or
++   one of the other waiters. The read lock threads are
++   about to execute:
++
++   341   r = (atomic_fetch_add_acquire (&rwlock->__data.__readers,
++   342                                  (1 << PTHREAD_RWLOCK_READER_SHIFT))
++   343        + (1 << PTHREAD_RWLOCK_READER_SHIFT));
++
++   An unlock beings to execute.
++
++   Then in __pthread_rwlock_wrunlock:
++
++   547   unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
++   ...
++   549   while (!atomic_compare_exchange_weak_release
++   550          (&rwlock->__data.__readers, &r,
++   551           ((r ^ PTHREAD_RWLOCK_WRLOCKED)
++   552            ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
++   553               : PTHREAD_RWLOCK_WRPHASE))))
++   554     {
++   ...
++   556     }
++
++   We clear PTHREAD_RWLOCK_WRLOCKED, and if there are
++   no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE.
++
++   Back in the read lock.
++
++   The read lock adjusts __readres as above.
++
++   383   while ((r & PTHREAD_RWLOCK_WRPHASE) != 0
++   384          && (r & PTHREAD_RWLOCK_WRLOCKED) == 0)
++   385     {
++   ...
++   390       if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r,
++   391                                                 r ^ PTHREAD_RWLOCK_WRPHASE))
++   392         {
++
++   And then attemps to start the read phase.
++
++   Assume there happens to be a tryrdlock at this point, noting
++   that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE
++   is 1. So the try lock attemps to start the read phase.
++
++   In __pthread_rwlock_tryrdlock:
++
++    44       if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
++    45         {
++   ...
++    49           if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
++    50               && (rwlock->__data.__flags
++    51                   == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP))
++    52             return EBUSY;
++    53           rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT);
++    54         }
++   ...
++    89   while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers,
++    90       &r, rnew));
++
++   And succeeds.
++
++   Back in the write unlock:
++
++   557   if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0)
++   558     {
++   ...
++   563       if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
++   564            & PTHREAD_RWLOCK_FUTEX_USED) != 0)
++   565         futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
++   566     }
++
++   We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero
++   and don't wake anyone. This is OK because we handed
++   over to the trylock. It will be the trylock's responsibility
++   to wake any waiters.
++
++   Back in the read lock:
++
++   The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because
++   the __readers value was adjusted by the trylock, and so it falls through
++   to waiting on the lock for explicit handover from either a new writer
++   or a new reader.
++
++   448           int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
++   449                                          1 | PTHREAD_RWLOCK_FUTEX_USED,
++   450                                          abstime, private);
++
++   We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex
++   is in use.
++
++   At this point we have readers waiting on the read lock
++   to unlock. The wrlock is done. The trylock is finishing
++   the installation of the read phase.
++
++    92   if ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
++    93     {
++   ...
++   105       atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
++   106     }
++
++   The trylock does note that we were the one that
++   installed the read phase, but the comments are not
++   correct, the execution ordering above shows that
++   readers might indeed be waiting, and they are.
++
++   The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED,
++   and the waiting reader is never worken becuase as noted
++   above it is conditional on the futex being used.
++
++   The solution is for the trylock thread to inspect
++   PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers.
++
++   --- Analysis of pthread_rwlock_trywrlock() stall ---
++
++   A write lock begins to execute, takes the write lock,
++   and then releases the lock...
++
++   In pthread_rwlock_wrunlock():
++
++   547   unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
++   ...
++   549   while (!atomic_compare_exchange_weak_release
++   550          (&rwlock->__data.__readers, &r,
++   551           ((r ^ PTHREAD_RWLOCK_WRLOCKED)
++   552            ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
++   553               : PTHREAD_RWLOCK_WRPHASE))))
++   554     {
++   ...
++   556     }
++
++   ... leaving it in the write phase with zero readers
++   (the case where we leave the write phase in place
++   during a write unlock).
++
++   A write trylock begins to execute.
++
++   In __pthread_rwlock_trywrlock:
++
++    40   while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0)
++    41       && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
++    42           || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0))))
++    43     {
++
++   The lock is not locked.
++
++   There are no readers.
++
++    45       if (atomic_compare_exchange_weak_acquire (
++    46           &rwlock->__data.__readers, &r,
++    47           r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
++
++   We atomically install the write phase and we take the
++   exclusive write lock.
++
++    48         {
++    49           atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
++
++   We get this far.
++
++   A reader lock begins to execute.
++
++   In pthread_rwlock_rdlock:
++
++   437   for (;;)
++   438     {
++   439       while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
++   440               | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
++   441         {
++   442           int private = __pthread_rwlock_get_private (rwlock);
++   443           if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
++   444               && (!atomic_compare_exchange_weak_relaxed
++   445                   (&rwlock->__data.__wrphase_futex,
++   446                    &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)))
++   447             continue;
++   448           int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
++   449                                          1 | PTHREAD_RWLOCK_FUTEX_USED,
++   450                                          abstime, private);
++
++   We are in a write phase, so the while() on line 439 is true.
++
++   The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set
++   since this is the first reader to lock.
++
++   The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED
++   on the expectation that this reader will be woken during
++   the handoff.
++
++   Back in pthread_rwlock_trywrlock:
++
++    50           atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
++    51           atomic_store_relaxed (&rwlock->__data.__cur_writer,
++    52               THREAD_GETMEM (THREAD_SELF, tid));
++    53           return 0;
++    54         }
++   ...
++    57     }
++
++   We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED,
++   and so in the unlock we will not awaken the waiting reader.
++
++   The solution to this is to realize that if we did not start the write
++   phase we need not write 1 or any other value to __wrphase_futex.
++   This ensures that any readers (which saw __wrphase_futex != 0) can
++   set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to
++   wake them.
++
++   If we installed the write phase then all other readers are looping
++   here:
++
++   In __pthread_rwlock_rdlock_full:
++
++   437   for (;;)
++   438     {
++   439       while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
++   440               | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
++   441         {
++   ...
++   508     }
++
++   waiting for the write phase to be installed or removed before they
++   can begin waiting on __wrphase_futex (part of the algorithm), or
++   taking a concurrent read lock, and thus we can safely write 1 to
++   __wrphase_futex.
++
++   If we did not install the write phase then the readers may already
++   be waiting on the futex, the original writer wrote 1 to __wrphase_futex
++   as part of starting the write phase, and we cannot also write 1
++   without loosing the PTHREAD_RWLOCK_FUTEX_USED bit.
++
++   ---
++
++   Summary for the pthread_rwlock_tryrdlock() stall:
++
++   The stall is caused by pthread_rwlock_tryrdlock failing to check
++   that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex
++   and then waking the futex.
++
++   The fix for bug 23844 ensures that waiters on __wrphase_futex are
++   correctly woken.  Before the fix the test stalls as readers can
++   wait forever on __wrphase_futex.  */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <pthread.h>
++#include <support/xthread.h>
++#include <errno.h>
++
++/* We need only one lock to reproduce the issue. We will need multiple
++   threads to get the exact case where we have a read, try, and unlock
++   all interleaving to produce the case where the readers are waiting
++   and the try fails to wake them.  */
++pthread_rwlock_t onelock;
++
++/* The number of threads is arbitrary but empirically chosen to have
++   enough threads that we see the condition where waiting readers are
++   not woken by a successful tryrdlock.  */
++#define NTHREADS 32
++
++_Atomic int do_exit;
++
++void *
++run_loop (void *arg)
++{
++  int i = 0, ret;
++  while (!do_exit)
++    {
++      /* Arbitrarily choose if we are the writer or reader.  Choose a
++	 high enough ratio of readers to writers to make it likely
++	 that readers block (and eventually are susceptable to
++	 stalling).
++
++         If we are a writer, take the write lock, and then unlock.
++	 If we are a reader, try the lock, then lock, then unlock.  */
++      if ((i % 8) != 0)
++	xpthread_rwlock_wrlock (&onelock);
++      else
++	{
++	  if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0)
++	    {
++	      if (ret == EBUSY)
++		xpthread_rwlock_rdlock (&onelock);
++	      else
++		exit (EXIT_FAILURE);
++	    }
++	}
++      /* Thread does some work and then unlocks.  */
++      xpthread_rwlock_unlock (&onelock);
++      i++;
++    }
++  return NULL;
++}
++
++int
++do_test (void)
++{
++  int i;
++  pthread_t tids[NTHREADS];
++  xpthread_rwlock_init (&onelock, NULL);
++  for (i = 0; i < NTHREADS; i++)
++    tids[i] = xpthread_create (NULL, run_loop, NULL);
++  /* Run for some amount of time.  Empirically speaking exercising
++     the stall via pthread_rwlock_tryrdlock is much harder, and on
++     a 3.5GHz 4 core x86_64 VM system it takes somewhere around
++     20-200s to stall, approaching 100% stall past 200s.  We can't
++     wait that long for a regression test so we just test for 20s,
++     and expect the stall to happen with a 5-10% chance (enough for
++     developers to see).  */
++  sleep (20);
++  /* Then exit.  */
++  printf ("INFO: Exiting...\n");
++  do_exit = 1;
++  /* If any readers stalled then we will timeout waiting for them.  */
++  for (i = 0; i < NTHREADS; i++)
++    xpthread_join (tids[i]);
++  printf ("INFO: Done.\n");
++  xpthread_rwlock_destroy (&onelock);
++  printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n");
++  return 0;
++}
++
++#define TIMEOUT 30
++#include <support/test-driver.c>
+diff --git a/nptl/tst-rwlock-trywrlock-stall.c b/nptl/tst-rwlock-trywrlock-stall.c
+new file mode 100644
+index 0000000000000000..14d27cbcbc882cb1
+--- /dev/null
++++ b/nptl/tst-rwlock-trywrlock-stall.c
+@@ -0,0 +1,108 @@
++/* Bug 23844: Test for pthread_rwlock_trywrlock stalls.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c.
++
++   Summary for the pthread_rwlock_trywrlock() stall:
++
++   The stall is caused by pthread_rwlock_trywrlock setting
++   __wrphase_futex futex to 1 and loosing the
++   PTHREAD_RWLOCK_FUTEX_USED bit.
++
++   The fix for bug 23844 ensures that waiters on __wrphase_futex are
++   correctly woken.  Before the fix the test stalls as readers can
++   wait forever on  __wrphase_futex.  */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <pthread.h>
++#include <support/xthread.h>
++#include <errno.h>
++
++/* We need only one lock to reproduce the issue. We will need multiple
++   threads to get the exact case where we have a read, try, and unlock
++   all interleaving to produce the case where the readers are waiting
++   and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a
++   subsequent unlock fails to wake them.  */
++pthread_rwlock_t onelock;
++
++/* The number of threads is arbitrary but empirically chosen to have
++   enough threads that we see the condition where waiting readers are
++   not woken by a successful unlock.  */
++#define NTHREADS 32
++
++_Atomic int do_exit;
++
++void *
++run_loop (void *arg)
++{
++  int i = 0, ret;
++  while (!do_exit)
++    {
++      /* Arbitrarily choose if we are the writer or reader.  Choose a
++	 high enough ratio of readers to writers to make it likely
++	 that readers block (and eventually are susceptable to
++	 stalling).
++
++         If we are a writer, take the write lock, and then unlock.
++	 If we are a reader, try the lock, then lock, then unlock.  */
++      if ((i % 8) != 0)
++	{
++	  if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0)
++	    {
++	      if (ret == EBUSY)
++		xpthread_rwlock_wrlock (&onelock);
++	      else
++		exit (EXIT_FAILURE);
++	    }
++	}
++      else
++	xpthread_rwlock_rdlock (&onelock);
++      /* Thread does some work and then unlocks.  */
++      xpthread_rwlock_unlock (&onelock);
++      i++;
++    }
++  return NULL;
++}
++
++int
++do_test (void)
++{
++  int i;
++  pthread_t tids[NTHREADS];
++  xpthread_rwlock_init (&onelock, NULL);
++  for (i = 0; i < NTHREADS; i++)
++    tids[i] = xpthread_create (NULL, run_loop, NULL);
++  /* Run for some amount of time.  The pthread_rwlock_tryrwlock stall
++     is very easy to trigger and happens in seconds under the test
++     conditions.  */
++  sleep (10);
++  /* Then exit.  */
++  printf ("INFO: Exiting...\n");
++  do_exit = 1;
++  /* If any readers stalled then we will timeout waiting for them.  */
++  for (i = 0; i < NTHREADS; i++)
++    xpthread_join (tids[i]);
++  printf ("INFO: Done.\n");
++  xpthread_rwlock_destroy (&onelock);
++  printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n");
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/support/Makefile b/support/Makefile
+index 93a514301654132e..41da4abaaa5a645a 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -129,6 +129,7 @@ libsupport-routines = \
+   xpthread_mutexattr_settype \
+   xpthread_once \
+   xpthread_rwlock_init \
++  xpthread_rwlock_destroy \
+   xpthread_rwlock_rdlock \
+   xpthread_rwlock_unlock \
+   xpthread_rwlock_wrlock \
+diff --git a/support/xpthread_rwlock_destroy.c b/support/xpthread_rwlock_destroy.c
+new file mode 100644
+index 0000000000000000..6d6e95356963b47f
+--- /dev/null
++++ b/support/xpthread_rwlock_destroy.c
+@@ -0,0 +1,26 @@
++/* pthread_rwlock_destroy with error checking.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/xthread.h>
++
++void
++xpthread_rwlock_destroy (pthread_rwlock_t *rwlock)
++{
++  xpthread_check_return ("pthread_rwlock_destroy",
++                         pthread_rwlock_destroy (rwlock));
++}
+diff --git a/support/xthread.h b/support/xthread.h
+index 623f5ad0acb895ef..1af77280871464c2 100644
+--- a/support/xthread.h
++++ b/support/xthread.h
+@@ -84,6 +84,7 @@ void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref);
+ void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
+ void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
+ void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock);
++void xpthread_rwlock_destroy (pthread_rwlock_t *rwlock);
+ 
+ __END_DECLS
+ 
diff --git a/SOURCES/glibc-rh1659293-2.patch b/SOURCES/glibc-rh1659293-2.patch
new file mode 100644
index 0000000..eca43d2
--- /dev/null
+++ b/SOURCES/glibc-rh1659293-2.patch
@@ -0,0 +1,61 @@
+nptl/tst-rwlock14: Test pthread_rwlock_timedwrlock correctly
+
+(cherry picked from commit 82849fde3b8cb9b9396fa8cadf842dc2b1d2cced)
+
+diff --git a/ChangeLog b/ChangeLog
+index ed1a2ffe8356fd96..74e634670c62d5c2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++2019-03-25  Mike Crowe  <mac@mcrowe.com>
++
++	* nptl/tst-rwlock14.c (do_test): Replace duplicate calls to
++	pthread_rwlock_timedrdlock with calls to
++	pthread_rwlock_timedwrlock to ensure that the latter is tested
++	too. Use new function name in diagnostic messages too.
++
+ 2019-01-31  Carlos O'Donell  <carlos@redhat.com>
+ 	    Torvald Riegel  <triegel@redhat.com>
+ 	    Rik Prohaska  <prohaska7@gmail.com>
+diff --git a/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c
+index d6fda87c61e9aed4..073e6c98d2f5cc12 100644
+--- a/nptl/tst-rwlock14.c
++++ b/nptl/tst-rwlock14.c
+@@ -117,15 +117,15 @@ do_test (void)
+       result = 1;
+     }
+ 
+-  e = pthread_rwlock_timedrdlock (&r, &ts);
++  e = pthread_rwlock_timedwrlock (&r, &ts);
+   if (e == 0)
+     {
+-      puts ("second rwlock_timedrdlock did not fail");
++      puts ("second rwlock_timedwrlock did not fail");
+       result = 1;
+     }
+   else if (e != EINVAL)
+     {
+-      puts ("second rwlock_timedrdlock did not return EINVAL");
++      puts ("second rwlock_timedwrlock did not return EINVAL");
+       result = 1;
+     }
+ 
+@@ -145,15 +145,15 @@ do_test (void)
+       result = 1;
+     }
+ 
+-  e = pthread_rwlock_timedrdlock (&r, &ts);
++  e = pthread_rwlock_timedwrlock (&r, &ts);
+   if (e == 0)
+     {
+-      puts ("third rwlock_timedrdlock did not fail");
++      puts ("third rwlock_timedwrlock did not fail");
+       result = 1;
+     }
+   else if (e != EINVAL)
+     {
+-      puts ("third rwlock_timedrdlock did not return EINVAL");
++      puts ("third rwlock_timedwrlock did not return EINVAL");
+       result = 1;
+     }
+ 
diff --git a/SOURCES/glibc-rh1659438-1.patch b/SOURCES/glibc-rh1659438-1.patch
new file mode 100644
index 0000000..6e22946
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-1.patch
@@ -0,0 +1,118 @@
+commit b8686c0d7098168481a246f8199ab2d865f52d3d
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:03 2018 +0100
+
+    S390: Add configure check to detect z10 as mininum architecture level set.
+    
+    Add a configure check for z10 in the same way as done for z196.
+    
+    ChangeLog:
+    
+            * config.h.in (HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT): New undefine.
+            * sysdeps/s390/configure.ac: Add check for z10 support.
+            * sysdeps/s390/configure: Regenerated.
+
+diff --git a/config.h.in b/config.h.in
+index 141db213a9046eb4..beecc39d5b8c3f4a 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -62,6 +62,9 @@
+ /* Define if assembler supports AVX512DQ.  */
+ #undef  HAVE_AVX512DQ_ASM_SUPPORT
+ 
++/* Define if assembler supports z10 zarch instructions as default on S390.  */
++#undef  HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
++
+ /* Define if assembler supports z196 zarch instructions as default on S390.  */
+ #undef  HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+ 
+diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
+index 74b415f2ab0fa982..f30f8644361f474a 100644
+--- a/sysdeps/s390/configure
++++ b/sysdeps/s390/configure
+@@ -112,6 +112,45 @@ then
+ 
+ fi
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z10 zarch instruction support as default" >&5
++$as_echo_n "checking for S390 z10 zarch instruction support as default... " >&6; }
++if ${libc_cv_asm_s390_min_z10_zarch+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.c <<\EOF
++void testinsn (void *a, void *b, int n)
++{
++    __asm__ ("exrl %2,1f \n\t"
++	     "j 2f \n\t"
++	     "1: mvc 0(1,%0),0(%1) \n\t"
++	     "2:"
++	     : : "a" (a), "a" (b), "d" (n)
++	     : "memory", "cc");
++}
++EOF
++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; } ;
++then
++  libc_cv_asm_s390_min_z10_zarch=yes
++else
++  libc_cv_asm_s390_min_z10_zarch=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z10_zarch" >&5
++$as_echo "$libc_cv_asm_s390_min_z10_zarch" >&6; }
++
++if test "$libc_cv_asm_s390_min_z10_zarch" = yes ;
++then
++  $as_echo "#define HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT 1" >>confdefs.h
++
++fi
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z196 zarch instruction support as default" >&5
+ $as_echo_n "checking for S390 z196 zarch instruction support as default... " >&6; }
+ if ${libc_cv_asm_s390_min_z196_zarch+:} false; then :
+diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
+index 1cdb0212825a3f18..981f7a79dd7066fc 100644
+--- a/sysdeps/s390/configure.ac
++++ b/sysdeps/s390/configure.ac
+@@ -80,6 +80,35 @@ then
+   AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT)
+ fi
+ 
++AC_CACHE_CHECK(for S390 z10 zarch instruction support as default,
++	       libc_cv_asm_s390_min_z10_zarch, [dnl
++cat > conftest.c <<\EOF
++void testinsn (void *a, void *b, int n)
++{
++    __asm__ ("exrl %2,1f \n\t"
++	     "j 2f \n\t"
++	     "1: mvc 0(1,%0),0(%1) \n\t"
++	     "2:"
++	     : : "a" (a), "a" (b), "d" (n)
++	     : "memory", "cc");
++}
++EOF
++dnl
++dnl test, if assembler supports S390 z10 zarch instructions as default
++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null]) ;
++then
++  libc_cv_asm_s390_min_z10_zarch=yes
++else
++  libc_cv_asm_s390_min_z10_zarch=no
++fi
++rm -f conftest* ])
++
++if test "$libc_cv_asm_s390_min_z10_zarch" = yes ;
++then
++  AC_DEFINE(HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT)
++fi
++
+ AC_CACHE_CHECK(for S390 z196 zarch instruction support as default,
+ 	       libc_cv_asm_s390_min_z196_zarch, [dnl
+ cat > conftest.c <<\EOF
diff --git a/SOURCES/glibc-rh1659438-10.patch b/SOURCES/glibc-rh1659438-10.patch
new file mode 100644
index 0000000..729f1b5
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-10.patch
@@ -0,0 +1,189 @@
+commit e099aab060df178a7fcd5a55282650fe45ccea66
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:07 2018 +0100
+
+    S390: Remove s390 specific implementation of bcopy.
+    
+    Nowadays gcc is automatically replacing a call to bcopy
+    with a call to memmove.  Thus only old binaries will call
+    the s390 specific bcopy implementation.
+    
+    The s390 specific implementation is using an own
+    implementation for memcpy in the forward case and is
+    relying on memmove in the backward case.
+    
+    After removing the s390 specific bcopy, the common code
+    bcopy is used.  It just performs a tail call to memmove.
+    
+    ChangeLog:
+            * sysdeps/s390/s390-32/bcopy.S: Remove.
+            * sysdeps/s390/s390-64/bcopy.S: Likewise.
+
+diff --git a/sysdeps/s390/s390-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S
+deleted file mode 100644
+index 560e04fdee93dafb..0000000000000000
+--- a/sysdeps/s390/s390-32/bcopy.S
++++ /dev/null
+@@ -1,85 +0,0 @@
+-/* bcopy -- copy a block from source to destination.  S/390 version.
+-   This file is part of the GNU C Library.
+-   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of source
+-     %r3 = address of destination
+-     %r4 = number of bytes to copy.  */
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-        .text
+-ENTRY(__bcopy)
+-	ltr     %r1,%r4             # zero bcopy ?
+-	jz      .L4
+-        clr     %r2,%r3             # check against destructive overlap
+-        jnl     .L0
+-        alr     %r1,%r2
+-        clr     %r1,%r3
+-        jh      .L7
+-.L0:	ahi     %r4,-1              # length - 1
+-	lr      %r1,%r4
+-	srl     %r1,8
+-	ltr     %r1,%r1             # < 256 bytes to move ?
+-	jz      .L2
+-	chi     %r1,255             # > 1MB to move ?
+-	jh      .L5
+-.L1:	mvc     0(256,%r3),0(%r2)   # move in 256 byte chunks
+-	la      %r2,256(%r2)
+-	la      %r3,256(%r3)
+-	brct    %r1,.L1
+-.L2:	bras    %r1,.L3             # setup base pointer for execute
+-	mvc     0(1,%r3),0(%r2)     # instruction for execute
+-.L3:	ex      %r4,0(%r1)          # execute mvc with length ((%r4)&255)+1
+-.L4:	br      %r14
+-
+-	# data copies > 1MB are faster with mvcle.
+-.L5:	ahi     %r4,1               # length + 1
+-	lr      %r5,%r4	            # source length
+-	lr	%r4,%r2             # source address
+-	lr	%r2,%r3             # set destination
+-	lr	%r3,%r5             # destination length = source length
+-.L6:	mvcle	%r2,%r4,0           # thats it, MVCLE is your friend
+-	jo	.L6
+-	br	%r14
+-.L7:                                # destructive overlay, can not use mvcle
+-        lr     %r1,%r2              # bcopy is called with source,dest
+-        lr     %r2,%r3              # memmove with dest,source! Oh, well...
+-        lr     %r3,%r1
+-        basr   %r1,0
+-.L8:
+-#ifdef PIC
+-        al     %r1,.L9-.L8(%r1)     # get address of global offset table
+-                                    # load address of memmove
+-        l      %r1,memmove@GOT(%r1)
+-        br     %r1
+-.L9:    .long  _GLOBAL_OFFSET_TABLE_-.L8
+-#else
+-        al     %r1,.L9-.L8(%r1)     # load address of memmove
+-        br     %r1                  # jump to memmove
+-.L9:    .long  memmove-.L8
+-#endif
+-
+-END(__bcopy)
+-
+-#ifndef NO_WEAK_ALIAS
+-weak_alias (__bcopy, bcopy)
+-#endif
+-
+diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S
+deleted file mode 100644
+index 806dd15d0203d32a..0000000000000000
+--- a/sysdeps/s390/s390-64/bcopy.S
++++ /dev/null
+@@ -1,71 +0,0 @@
+-/* bcopy -- copy a block from source to destination.  64 bit S/390 version.
+-   This file is part of the GNU C Library.
+-   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of source
+-     %r3 = address of destination
+-     %r4 = number of bytes to copy.  */
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-	.text
+-ENTRY(__bcopy)
+-	ltgr	%r1,%r4		    # zero bcopy ?
+-	jz	.L4
+-	clgr	%r2,%r3		    # check against destructive overlap
+-	jnl	.L0
+-	algr	%r1,%r2
+-	clgr	%r1,%r3
+-	jh	.L7
+-.L0:	aghi	%r4,-1		    # length - 1
+-	srlg	%r1,%r4,8
+-	ltgr	%r1,%r1             # < 256 bytes to move ?
+-	jz	.L2
+-	cghi    %r1,255             # > 1MB to move ?
+-	jh      .L5
+-.L1:	mvc	0(256,%r3),0(%r2)   # move in 256 byte chunks
+-	la	%r2,256(%r2)
+-	la	%r3,256(%r3)
+-	brctg	%r1,.L1
+-.L2:	bras	%r1,.L3		    # setup base pointer for execute
+-	mvc	0(1,%r3),0(%r2)	    # instruction for execute
+-.L3:	ex	%r4,0(%r1)	    # execute mvc with length ((%r4)&255)+1
+-.L4:	br	%r14
+-	# data copies > 1MB are faster with mvcle.
+-.L5:	aghi    %r4,1               # length + 1
+-	lgr	%r5,%r4	            # source length
+-	lgr	%r4,%r2             # source address
+-	lgr	%r2,%r3             # set destination
+-	lgr	%r3,%r5             # destination length = source length
+-.L6:	mvcle	%r2,%r4,0           # thats it, MVCLE is your friend
+-	jo	.L6
+-	br	%r14
+-.L7:				    # destructive overlay, can not use mvcle
+-	lgr	%r1,%r2		    # bcopy is called with source,dest
+-	lgr	%r2,%r3		    # memmove with dest,source! Oh, well...
+-	lgr	%r3,%r1
+-	jg	HIDDEN_BUILTIN_JUMPTARGET(memmove)
+-
+-END(__bcopy)
+-
+-#ifndef NO_WEAK_ALIAS
+-weak_alias (__bcopy, bcopy)
+-#endif
+-
diff --git a/SOURCES/glibc-rh1659438-11.patch b/SOURCES/glibc-rh1659438-11.patch
new file mode 100644
index 0000000..71d20a3
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-11.patch
@@ -0,0 +1,43 @@
+commit d097d97626e44bc6e76d5daf80ce3ff7d147b623
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:07 2018 +0100
+
+    S390: Use memcpy for forward cases in memmove.
+    
+    The s390/s390x memcpy implementations are safe to be
+    used by memmove.  Starting with this commit, memmove is
+    using memcpy for the forward cases on s390.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/memcopy.h: New file.
+
+diff --git a/sysdeps/s390/memcopy.h b/sysdeps/s390/memcopy.h
+new file mode 100644
+index 0000000000000000..9a76196502f25bbf
+--- /dev/null
++++ b/sysdeps/s390/memcopy.h
+@@ -0,0 +1,23 @@
++/* memcopy.h -- definitions for memory copy functions.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/generic/memcopy.h>
++
++/* The s390/s390x memcpy implementations are safe to be used by memmove.  */
++#undef MEMCPY_OK_FOR_FWD_MEMMOVE
++#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
diff --git a/SOURCES/glibc-rh1659438-12.patch b/SOURCES/glibc-rh1659438-12.patch
new file mode 100644
index 0000000..e257c4e
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-12.patch
@@ -0,0 +1,114 @@
+commit 2ee1bc57ab50737ee2ab88c4d796b90e08b4bf93
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:08 2018 +0100
+
+    S390: Add configure check to detect z13 as mininum architecture level set.
+    
+    Add a configure check for z13 in the same way as done for z196.
+    
+    ChangeLog:
+    
+            * config.h.in (HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT): New undefine.
+            * sysdeps/s390/configure.ac: Add check for z13 support.
+            * sysdeps/s390/configure: Regenerated.
+
+diff --git a/config.h.in b/config.h.in
+index beecc39d5b8c3f4a..422a6036ab16e3b6 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -68,6 +68,9 @@
+ /* Define if assembler supports z196 zarch instructions as default on S390.  */
+ #undef  HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+ 
++/* Define if assembler supports z13 zarch instructions as default on S390.  */
++#undef  HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++
+ /* Define if assembler supports vector instructions on S390.  */
+ #undef  HAVE_S390_VX_ASM_SUPPORT
+ 
+diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
+index f30f8644361f474a..4a44775e3083d8c3 100644
+--- a/sysdeps/s390/configure
++++ b/sysdeps/s390/configure
+@@ -187,5 +187,43 @@ then
+ 
+ fi
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z13 zarch instruction support as default" >&5
++$as_echo_n "checking for S390 z13 zarch instruction support as default... " >&6; }
++if ${libc_cv_asm_s390_min_z13_zarch+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.c <<\EOF
++int testinsn (void)
++{
++    int i;
++    __asm__ ("vl %%v16,0(%%r15)\n\t"
++	     "vlgvf %0,%%v16,0"
++	     : "=d" (i) : : "memory", "v16");
++    return i;
++}
++EOF
++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; } ;
++then
++  libc_cv_asm_s390_min_z13_zarch=yes
++else
++  libc_cv_asm_s390_min_z13_zarch=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z13_zarch" >&5
++$as_echo "$libc_cv_asm_s390_min_z13_zarch" >&6; }
++
++if test "$libc_cv_asm_s390_min_z13_zarch" = yes ;
++then
++  $as_echo "#define HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT 1" >>confdefs.h
++
++fi
++
+ test -n "$critic_missing" && as_fn_error $? "
+ *** $critic_missing" "$LINENO" 5
+diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
+index 981f7a79dd7066fc..4dfb5574b49d5949 100644
+--- a/sysdeps/s390/configure.ac
++++ b/sysdeps/s390/configure.ac
+@@ -135,5 +135,33 @@ then
+   AC_DEFINE(HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT)
+ fi
+ 
++AC_CACHE_CHECK(for S390 z13 zarch instruction support as default,
++	       libc_cv_asm_s390_min_z13_zarch, [dnl
++cat > conftest.c <<\EOF
++int testinsn (void)
++{
++    int i;
++    __asm__ ("vl %%v16,0(%%r15)\n\t"
++	     "vlgvf %0,%%v16,0"
++	     : "=d" (i) : : "memory", "v16");
++    return i;
++}
++EOF
++dnl
++dnl test, if assembler supports S390 z13 zarch instructions as default
++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null]) ;
++then
++  libc_cv_asm_s390_min_z13_zarch=yes
++else
++  libc_cv_asm_s390_min_z13_zarch=no
++fi
++rm -f conftest* ])
++
++if test "$libc_cv_asm_s390_min_z13_zarch" = yes ;
++then
++  AC_DEFINE(HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT)
++fi
++
+ test -n "$critic_missing" && AC_MSG_ERROR([
+ *** $critic_missing])
diff --git a/SOURCES/glibc-rh1659438-13.patch b/SOURCES/glibc-rh1659438-13.patch
new file mode 100644
index 0000000..4f8aa88
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-13.patch
@@ -0,0 +1,327 @@
+commit cdd927d98cc38acf55e1c6594b5c9451df8f239f
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:08 2018 +0100
+
+    S390: Add z13 memmove ifunc variant.
+    
+    This patch introduces a z13 specific ifunc variant for memmove.
+    As the common code implementation, it checks if we can copy from
+    the beginning to the end - with z196 memcpy implementation - or
+    if we have to copy from the end to the beginning.
+    The latter case is done by using vector load/store instructions.
+    
+    If vector instructions are not available, the common-code is
+    used as fallback.  Therefore it is implemented in memmove-c with
+    a different name.
+    Furthermore the ifunc logic decides if we need the common-code
+    implementation at all.  If vector instructions are supported
+    due to the minimum architecture level set we can skip the
+    common-code ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/Makefile (sysdep_routines): Add memmove-c.
+            * sysdeps/s390/ifunc-memcpy.h (HAVE_MEMMOVE_IFUNC,
+            HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT, MEMMOVE_DEFAULT,
+            HAVE_MEMMOVE_C, MEMMOVE_C,  HAVE_MEMMOVE_Z13, MEMMOVE_Z13):
+            New defines.
+            * sysdeps/s390/memcpy-z900.S: Add z13 memmove implementation.
+            * sysdeps/s390/memmove-c.c: New file.
+            * sysdeps/s390/memmove.c: Likewise.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Add ifunc variants for memmove.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 838950a5ab958e31..3a7cccdf8f147398 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -33,5 +33,6 @@ endif
+ ifeq ($(subdir),string)
+ sysdep_routines += bzero memset memset-z900 \
+ 		   memcmp memcmp-z900 \
+-		   mempcpy memcpy memcpy-z900
++		   mempcpy memcpy memcpy-z900 \
++		   memmove memmove-c
+ endif
+diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h
+index 51c71baa2c0b0452..0e701968c8f39014 100644
+--- a/sysdeps/s390/ifunc-memcpy.h
++++ b/sysdeps/s390/ifunc-memcpy.h
+@@ -43,6 +43,29 @@
+ # define HAVE_MEMCPY_Z196	HAVE_MEMCPY_IFUNC
+ #endif
+ 
++#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc)	\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_MEMMOVE_IFUNC	1
++#else
++# define HAVE_MEMMOVE_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT HAVE_MEMMOVE_IFUNC
++#else
++# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define MEMMOVE_DEFAULT	MEMMOVE_Z13
++# define HAVE_MEMMOVE_C		0
++# define HAVE_MEMMOVE_Z13	1
++#else
++# define MEMMOVE_DEFAULT	MEMMOVE_C
++# define HAVE_MEMMOVE_C		1
++# define HAVE_MEMMOVE_Z13	HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT
++#endif
++
+ #if HAVE_MEMCPY_Z900_G5
+ # define MEMCPY_Z900_G5		__memcpy_default
+ # define MEMPCPY_Z900_G5	__mempcpy_default
+@@ -66,3 +89,15 @@
+ # define MEMCPY_Z196		NULL
+ # define MEMPCPY_Z196		NULL
+ #endif
++
++#if HAVE_MEMMOVE_C
++# define MEMMOVE_C		__memmove_c
++#else
++# define MEMMOVE_C		NULL
++#endif
++
++#if HAVE_MEMMOVE_Z13
++# define MEMMOVE_Z13		__memmove_z13
++#else
++# define MEMMOVE_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S
+index 3a50cf44d85d2417..bd3b1950ee442c0c 100644
+--- a/sysdeps/s390/memcpy-z900.S
++++ b/sysdeps/s390/memcpy-z900.S
+@@ -182,6 +182,7 @@ ENTRY(MEMCPY_Z196)
+ # endif /* !defined __s390x__  */
+ 	ltgr    %r4,%r4
+ 	je      .L_Z196_4
++.L_Z196_start2:
+ 	aghi    %r4,-1
+ 	srlg    %r5,%r4,8
+ 	ltgr    %r5,%r5
+@@ -207,6 +208,75 @@ ENTRY(MEMCPY_Z196)
+ END(MEMCPY_Z196)
+ #endif /* HAVE_MEMCPY_Z196  */
+ 
++#if HAVE_MEMMOVE_Z13
++ENTRY(MEMMOVE_Z13)
++	.machine "z13"
++	.machinemode "zarch_nohighgprs"
++# if !defined __s390x__
++	/* Note: The 31bit dst and src pointers are prefixed with zeroes.  */
++	llgfr	%r4,%r4
++	llgfr	%r3,%r3
++	llgfr	%r2,%r2
++# endif /* !defined __s390x__ */
++	sgrk	%r0,%r2,%r3
++	clgijh	%r4,16,.L_MEMMOVE_Z13_LARGE
++	aghik	%r5,%r4,-1
++.L_MEMMOVE_Z13_SMALL:
++	jl .L_MEMMOVE_Z13_END		/* Jump away if len was zero.  */
++	/* Store up to 16 bytes with vll/vstl which needs the index
++	   instead of lengths.  */
++	vll	%v16,%r5,0(%r3)
++	vstl	%v16,%r5,0(%r2)
++.L_MEMMOVE_Z13_END:
++	br      %r14
++.L_MEMMOVE_Z13_LARGE:
++	lgr     %r1,%r2			/* For memcpy: r1: Use as dest ;
++					   r2: Return dest  */
++	/* The unsigned comparison (dst - src >= len) determines if we can
++	   execute the forward case with memcpy.  */
++#if ! HAVE_MEMCPY_Z196
++# error The z13 variant of memmove needs the z196 variant of memcpy!
++#endif
++	clgrjhe %r0,%r4,.L_Z196_start2
++	risbgn	%r5,%r4,4,128+63,60	/* r5 = r4 / 16  */
++	aghi	%r4,-16
++	clgijhe	%r5,8,.L_MEMMOVE_Z13_LARGE_64B
++.L_MEMMOVE_Z13_LARGE_16B_LOOP:
++	/* Store at least 16 bytes with vl/vst. The number of 16byte blocks
++	   is stored in r5.  */
++	vl	%v16,0(%r4,%r3)
++	vst	%v16,0(%r4,%r2)
++	aghi	%r4,-16
++	brctg	%r5,.L_MEMMOVE_Z13_LARGE_16B_LOOP
++	aghik	%r5,%r4,15
++	j	.L_MEMMOVE_Z13_SMALL
++.L_MEMMOVE_Z13_LARGE_64B:
++	/* Store at least 128 bytes with 4x vl/vst. The number of 64byte blocks
++	   will be stored in r0.  */
++	aghi	%r4,-48
++	srlg	%r0,%r5,2		/* r5 = %r0 / 4
++					   => Number of 64byte blocks.  */
++.L_MEMMOVE_Z13_LARGE_64B_LOOP:
++	vl	%v20,48(%r4,%r3)
++	vl	%v19,32(%r4,%r3)
++	vl	%v18,16(%r4,%r3)
++	vl	%v17,0(%r4,%r3)
++	vst	%v20,48(%r4,%r2)
++	vst	%v19,32(%r4,%r2)
++	vst	%v18,16(%r4,%r2)
++	vst	%v17,0(%r4,%r2)
++	aghi	%r4,-64
++	brctg	%r0,.L_MEMMOVE_Z13_LARGE_64B_LOOP
++	aghi	%r4,48
++	/* Recalculate the number of 16byte blocks.  */
++	risbg	%r5,%r5,62,128+63,0	/* r5 = r5 & 3
++					   => Remaining 16byte blocks.  */
++	jne	.L_MEMMOVE_Z13_LARGE_16B_LOOP
++	aghik	%r5,%r4,15
++	j	.L_MEMMOVE_Z13_SMALL
++END(MEMMOVE_Z13)
++#endif /* HAVE_MEMMOVE_Z13  */
++
+ #if ! HAVE_MEMCPY_IFUNC
+ /* If we don't use ifunc, define an alias for mem[p]cpy here.
+    Otherwise see sysdeps/s390/mem[p]cpy.c.  */
+@@ -215,10 +285,27 @@ strong_alias (MEMPCPY_DEFAULT, __mempcpy)
+ weak_alias (__mempcpy, mempcpy)
+ #endif
+ 
++#if ! HAVE_MEMMOVE_IFUNC
++/* If we don't use ifunc, define an alias for memmove here.
++   Otherwise see sysdeps/s390/memmove.c.  */
++# if ! HAVE_MEMMOVE_C
++/* If the c variant is needed, then sysdeps/s390/memmove-c.c
++   defines memmove.
++   Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it.  */
++strong_alias (MEMMOVE_DEFAULT, memmove)
++# endif
++#endif
++
+ #if defined SHARED && IS_IN (libc)
+ /* Defines the internal symbols.
+    Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c.  */
+ strong_alias (MEMCPY_DEFAULT, __GI_memcpy)
+ strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy)
+ strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy)
++# if ! HAVE_MEMMOVE_C
++/* If the c variant is needed, then sysdeps/s390/memmove-c.c
++   defines the internal symbol.
++   Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it.  */
++strong_alias (MEMMOVE_DEFAULT, __GI_memmove)
++# endif
+ #endif
+diff --git a/sysdeps/s390/memmove-c.c b/sysdeps/s390/memmove-c.c
+new file mode 100644
+index 0000000000000000..be571093e019a38d
+--- /dev/null
++++ b/sysdeps/s390/memmove-c.c
+@@ -0,0 +1,37 @@
++/* Fallback C version of memmove.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-memcpy.h>
++
++#if HAVE_MEMMOVE_C
++# if HAVE_MEMMOVE_IFUNC
++/* If we use ifunc, then the memmove symbol is defined
++   in sysdeps/s390/memmove.c and we use a different name here.
++   Otherwise, we have to define memmove here or in
++   sysdeps/s390/memcpy.S depending on the used default implementation.  */
++#  define MEMMOVE MEMMOVE_C
++#  if defined SHARED && IS_IN (libc)
++/* Define the internal symbol.  */
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
++  __hidden_ver1 (__memmove_c, __GI_memmove, __memmove_c);
++#  endif
++# endif
++
++# include <string/memmove.c>
++#endif
+diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c
+new file mode 100644
+index 0000000000000000..ac34edf80f2678cd
+--- /dev/null
++++ b/sysdeps/s390/memmove.c
+@@ -0,0 +1,44 @@
++/* Multiple versions of memmove.
++   Copyright (C) 2016-2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-memcpy.h>
++
++#if HAVE_MEMMOVE_IFUNC
++/* If we don't use ifunc, an alias is defined for memmove
++   in sysdeps/s390/memmove-c.c or sysdeps/s390/memcpy.S
++   depending on the used default implementation.  */
++# undef memmove
++# define memmove __redirect_memmove
++# include <string.h>
++# include <ifunc-resolve.h>
++# undef memmove
++
++# if HAVE_MEMMOVE_C
++extern __typeof (__redirect_memmove) MEMMOVE_C attribute_hidden;
++# endif
++
++# if HAVE_MEMMOVE_Z13
++extern __typeof (__redirect_memmove) MEMMOVE_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect_memmove, memmove,
++		      (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? MEMMOVE_Z13
++		      : MEMMOVE_DEFAULT
++		      )
++#endif
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 6969c480cc40e0e2..c05c63e00608dcd7 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -126,6 +126,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 	      )
+ #endif /* HAVE_MEMCPY_IFUNC  */
+ 
++#if HAVE_MEMMOVE_IFUNC
++    IFUNC_IMPL (i, name, memmove,
++# if HAVE_MEMMOVE_Z13
++		IFUNC_IMPL_ADD (array, i, memmove,
++				dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13)
++# endif
++# if HAVE_MEMMOVE_C
++		IFUNC_IMPL_ADD (array, i, memmove, 1, MEMMOVE_C)
++# endif
++		)
++#endif /* HAVE_MEMMOVE_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
diff --git a/SOURCES/glibc-rh1659438-14.patch b/SOURCES/glibc-rh1659438-14.patch
new file mode 100644
index 0000000..7209f89
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-14.patch
@@ -0,0 +1,263 @@
+commit 8c25dddd2e32bce47dfe01ca51c8aab535dbe23d
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:09 2018 +0100
+
+    S390: Add z13 strstr ifunc variant.
+    
+    The new vector variant of strstr is using the common code
+    implementation, but instead of calling the default
+    str* / mem* functions, the vector variants are called.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/Makefile (sysdep_routines): Add strstr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Add ifunc variants for strstr.
+            * sysdeps/s390/ifunc-strstr.h: New file.
+            * sysdeps/s390/strstr.c: Likewise.
+            * sysdeps/s390/strstr-c.c: Likewise.
+            * sysdeps/s390/strstr-vx.c: Likewise.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 3a7cccdf8f147398..4441e7a5cf6fa167 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -34,5 +34,6 @@ ifeq ($(subdir),string)
+ sysdep_routines += bzero memset memset-z900 \
+ 		   memcmp memcmp-z900 \
+ 		   mempcpy memcpy memcpy-z900 \
+-		   memmove memmove-c
++		   memmove memmove-c \
++		   strstr strstr-vx strstr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h
+new file mode 100644
+index 0000000000000000..e6ccfd4e44a1a790
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strstr.h
+@@ -0,0 +1,52 @@
++/* strstr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRSTR_IFUNC	1
++#else
++# define HAVE_STRSTR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT HAVE_STRSTR_IFUNC
++#else
++# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRSTR_DEFAULT		STRSTR_Z13
++# define HAVE_STRSTR_C		0
++# define HAVE_STRSTR_Z13	1
++#else
++# define STRSTR_DEFAULT		STRSTR_C
++# define HAVE_STRSTR_C		1
++# define HAVE_STRSTR_Z13	HAVE_STRSTR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRSTR_C
++# define STRSTR_C		__strstr_c
++#else
++# define STRSTR_C		NULL
++#endif
++
++#if HAVE_STRSTR_Z13
++# define STRSTR_Z13		__strstr_vx
++#else
++# define STRSTR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index c05c63e00608dcd7..14727f8fef5431dd 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -24,6 +24,7 @@
+ #include <ifunc-memset.h>
+ #include <ifunc-memcmp.h>
+ #include <ifunc-memcpy.h>
++#include <ifunc-strstr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -138,6 +139,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_MEMMOVE_IFUNC  */
+ 
++#if HAVE_STRSTR_IFUNC
++    IFUNC_IMPL (i, name, strstr,
++# if HAVE_STRSTR_Z13
++		IFUNC_IMPL_ADD (array, i, strstr,
++				dl_hwcap & HWCAP_S390_VX, STRSTR_Z13)
++# endif
++# if HAVE_STRSTR_C
++		IFUNC_IMPL_ADD (array, i, strstr, 1, STRSTR_C)
++# endif
++		)
++#endif /* HAVE_STRSTR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+diff --git a/sysdeps/s390/strstr-c.c b/sysdeps/s390/strstr-c.c
+new file mode 100644
+index 0000000000000000..53717bfb276fed3d
+--- /dev/null
++++ b/sysdeps/s390/strstr-c.c
+@@ -0,0 +1,32 @@
++/* Default strstr implementation for S/390.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-strstr.h>
++
++#if HAVE_STRSTR_C
++# if HAVE_STRSTR_IFUNC
++#  define STRSTR STRSTR_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)		\
++  __hidden_ver1 (__strstr_c, __GI_strstr, __strstr_c);
++#  endif
++# endif
++
++# include <string/strstr.c>
++#endif
+diff --git a/sysdeps/s390/strstr-vx.c b/sysdeps/s390/strstr-vx.c
+new file mode 100644
+index 0000000000000000..effae9d5eb7d2fb1
+--- /dev/null
++++ b/sysdeps/s390/strstr-vx.c
+@@ -0,0 +1,52 @@
++/* Default strstr implementation with vector string functions for S/390.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-strstr.h>
++
++#if HAVE_STRSTR_Z13
++# if HAVE_STRSTR_IFUNC
++#  define STRSTR STRSTR_Z13
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   if HAVE_STRSTR_C
++#    define libc_hidden_builtin_def(name)
++#   else
++#    define libc_hidden_builtin_def(name)		\
++  __hidden_ver1 (__strstr_vx, __GI_strstr, __strstr_vx);
++#   endif
++#  endif
++# endif
++
++# include <string.h>
++
++# ifdef USE_MULTIARCH
++extern __typeof (strchr) __strchr_vx attribute_hidden;
++#  define strchr __strchr_vx
++
++extern __typeof (strlen) __strlen_vx attribute_hidden;
++#  define strlen __strlen_vx
++
++extern __typeof (__strnlen) __strnlen_vx attribute_hidden;
++#  define __strnlen __strnlen_vx
++
++extern __typeof (memcmp) __memcmp_z196 attribute_hidden;
++#  define memcmp __memcmp_z196
++# endif
++
++# include <string/strstr.c>
++#endif
+diff --git a/sysdeps/s390/strstr.c b/sysdeps/s390/strstr.c
+new file mode 100644
+index 0000000000000000..f8432349a7254cc6
+--- /dev/null
++++ b/sysdeps/s390/strstr.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of strstr.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-strstr.h>
++
++#if HAVE_STRSTR_IFUNC
++# define strstr __redirect_strstr
++# include <string.h>
++# include <ifunc-resolve.h>
++# undef strstr
++
++# if HAVE_STRSTR_C
++extern __typeof (__redirect_strstr) STRSTR_C attribute_hidden;
++# endif
++
++# if HAVE_STRSTR_Z13
++extern __typeof (__redirect_strstr) STRSTR_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect_strstr, strstr,
++		      (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRSTR_Z13
++		      : STRSTR_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-15.patch b/SOURCES/glibc-rh1659438-15.patch
new file mode 100644
index 0000000..0cb1dbe
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-15.patch
@@ -0,0 +1,290 @@
+commit d2c4c403feddd6f0b9dbf31ca7541b37f90ee30a
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:09 2018 +0100
+
+    S390: Add z13 memmem ifunc variant.
+    
+    The new vector variant of memmem is using the common code
+    implementation, but instead of calling the default
+    mem* functions, the vector variants are called.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/Makefile (sysdep_routines): Add memmem variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Add ifunc variants for memmem.
+            * sysdeps/s390/ifunc-memmem.h: New file.
+            * sysdeps/s390/memmem.c: Likewise.
+            * sysdeps/s390/memmem-c.c: Likewise.
+            * sysdeps/s390/memmem-vx.c: Likewise.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 4441e7a5cf6fa167..47d606d3d5d99274 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -35,5 +35,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   memcmp memcmp-z900 \
+ 		   mempcpy memcpy memcpy-z900 \
+ 		   memmove memmove-c \
+-		   strstr strstr-vx strstr-c
++		   strstr strstr-vx strstr-c \
++		   memmem memmem-vx memmem-c
+ endif
+diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h
+new file mode 100644
+index 0000000000000000..0f860d8d40080acf
+--- /dev/null
++++ b/sysdeps/s390/ifunc-memmem.h
+@@ -0,0 +1,52 @@
++/* memmem variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_MEMMEM_IFUNC	1
++#else
++# define HAVE_MEMMEM_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT HAVE_MEMMEM_IFUNC
++#else
++# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define MEMMEM_DEFAULT		MEMMEM_Z13
++# define HAVE_MEMMEM_C		0
++# define HAVE_MEMMEM_Z13	1
++#else
++# define MEMMEM_DEFAULT		MEMMEM_C
++# define HAVE_MEMMEM_C		1
++# define HAVE_MEMMEM_Z13	HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_MEMMEM_C
++# define MEMMEM_C		__memmem_c
++#else
++# define MEMMEM_C		NULL
++#endif
++
++#if HAVE_MEMMEM_Z13
++# define MEMMEM_Z13		__memmem_vx
++#else
++# define MEMMEM_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/memmem-c.c b/sysdeps/s390/memmem-c.c
+new file mode 100644
+index 0000000000000000..1d8ffefcb840b8d2
+--- /dev/null
++++ b/sysdeps/s390/memmem-c.c
+@@ -0,0 +1,47 @@
++/* Default memmem implementation for S/390.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-memmem.h>
++
++#if HAVE_MEMMEM_C
++# if HAVE_MEMMEM_IFUNC
++#  include <string.h>
++
++#  ifndef _LIBC
++#   define memmem MEMMEM_C
++#  else
++#   define __memmem MEMMEM_C
++#  endif
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   define libc_hidden_def(name)				\
++  strong_alias (__memmem_c, __memmem_c_1);			\
++  __hidden_ver1 (__memmem_c, __GI___memmem, __memmem_c);
++
++#   undef libc_hidden_weak
++#   define libc_hidden_weak(name)					\
++  __hidden_ver1 (__memmem_c_1, __GI_memmem, __memmem_c_1) __attribute__((weak));
++#  endif
++
++#  undef weak_alias
++#  define weak_alias(a, b)
++# endif
++
++# include <string/memmem.c>
++#endif
+diff --git a/sysdeps/s390/memmem-vx.c b/sysdeps/s390/memmem-vx.c
+new file mode 100644
+index 0000000000000000..af6e200e4e0af1a5
+--- /dev/null
++++ b/sysdeps/s390/memmem-vx.c
+@@ -0,0 +1,61 @@
++/* Default memmem implementation with vector string functions for S/390.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-memmem.h>
++
++#if HAVE_MEMMEM_Z13
++# include <string.h>
++# if HAVE_MEMMEM_IFUNC
++
++#  ifndef _LIBC
++#   define memmem MEMMEM_Z13
++#  else
++#   define __memmem MEMMEM_Z13
++#  endif
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   undef libc_hidden_weak
++
++#   if HAVE_MEMMEM_C
++#    define libc_hidden_def(name)
++#    define libc_hidden_weak(name)
++#   else
++#    define libc_hidden_def(name)				\
++  strong_alias (__memmem_vx, __memmem_vx_1);			\
++  __hidden_ver1 (__memmem_vx, __GI___memmem, __memmem_vx);
++
++#    define libc_hidden_weak(name)					\
++  __hidden_ver1 (__memmem_vx_1, __GI_memmem, __memmem_vx_1) __attribute__((weak));
++#   endif
++#  endif
++
++#  undef weak_alias
++#  define weak_alias(a, b)
++# endif
++
++# ifdef USE_MULTIARCH
++extern __typeof (memchr) __memchr_vx attribute_hidden;
++# define memchr __memchr_vx
++
++extern __typeof (memcmp) __memcmp_z196 attribute_hidden;
++# define memcmp __memcmp_z196
++# endif
++
++# include <string/memmem.c>
++#endif
+diff --git a/sysdeps/s390/memmem.c b/sysdeps/s390/memmem.c
+new file mode 100644
+index 0000000000000000..8c50b3f403eb8d1f
+--- /dev/null
++++ b/sysdeps/s390/memmem.c
+@@ -0,0 +1,43 @@
++/* Multiple versions of memmem.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-memmem.h>
++
++#if HAVE_MEMMEM_IFUNC
++# define memmem __redirect_memmem
++# define __memmem __redirect___memmem
++# include <string.h>
++# include <ifunc-resolve.h>
++# undef memmem
++# undef __memmem
++
++# if HAVE_MEMMEM_C
++extern __typeof (__redirect_memmem) MEMMEM_C attribute_hidden;
++# endif
++
++# if HAVE_MEMMEM_Z13
++extern __typeof (__redirect_memmem) MEMMEM_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect_memmem, __memmem,
++		      (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? MEMMEM_Z13
++		      : MEMMEM_DEFAULT
++		      )
++weak_alias (__memmem, memmem)
++#endif
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 14727f8fef5431dd..da8696d917abf51c 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -25,6 +25,7 @@
+ #include <ifunc-memcmp.h>
+ #include <ifunc-memcpy.h>
+ #include <ifunc-strstr.h>
++#include <ifunc-memmem.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -151,6 +152,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRSTR_IFUNC  */
+ 
++#if HAVE_MEMMEM_IFUNC
++    IFUNC_IMPL (i, name, memmem,
++# if HAVE_MEMMEM_Z13
++		IFUNC_IMPL_ADD (array, i, memmem,
++				dl_hwcap & HWCAP_S390_VX, MEMMEM_Z13)
++# endif
++# if HAVE_MEMMEM_C
++		IFUNC_IMPL_ADD (array, i, memmem, 1, MEMMEM_C)
++# endif
++		)
++#endif /* HAVE_MEMMEM_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
diff --git a/SOURCES/glibc-rh1659438-16.patch b/SOURCES/glibc-rh1659438-16.patch
new file mode 100644
index 0000000..b55bebc
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-16.patch
@@ -0,0 +1,259 @@
+commit ff3ca3743a00af749258cc242457b648d65a1537
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:10 2018 +0100
+
+    S390: Refactor strlen ifunc handling.
+    
+    The ifunc handling for strlen is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strlen variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strlen variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strlen.
+            * sysdeps/s390/multiarch/strlen-c.c: Move to ...
+            * sysdeps/s390/strlen-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strlen-vx.S: Move to ...
+            * sysdeps/s390/strlen-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strlen.c: Move to ...
+            * sysdeps/s390/strlen.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strlen.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 47d606d3d5d99274..600d8e629df7090e 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -36,5 +36,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   mempcpy memcpy memcpy-z900 \
+ 		   memmove memmove-c \
+ 		   strstr strstr-vx strstr-c \
+-		   memmem memmem-vx memmem-c
++		   memmem memmem-vx memmem-c \
++		   strlen strlen-vx strlen-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strlen.h b/sysdeps/s390/ifunc-strlen.h
+new file mode 100644
+index 0000000000000000..f2070596636f29a9
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strlen.h
+@@ -0,0 +1,52 @@
++/* strlen variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRLEN_IFUNC	1
++#else
++# define HAVE_STRLEN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT HAVE_STRLEN_IFUNC
++#else
++# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRLEN_DEFAULT		STRLEN_Z13
++# define HAVE_STRLEN_C		0
++# define HAVE_STRLEN_Z13	1
++#else
++# define STRLEN_DEFAULT		STRLEN_C
++# define HAVE_STRLEN_C		1
++# define HAVE_STRLEN_Z13	HAVE_STRLEN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRLEN_C
++# define STRLEN_C		__strlen_c
++#else
++# define STRLEN_C		NULL
++#endif
++
++#if HAVE_STRLEN_Z13
++# define STRLEN_Z13		__strlen_vx
++#else
++# define STRLEN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 24949cd3a88b8015..601523919c235f76 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strlen strlen-vx strlen-c \
+-		   strnlen strnlen-vx strnlen-c \
++sysdep_routines += strnlen strnlen-vx strnlen-c \
+ 		   strcpy strcpy-vx \
+ 		   stpcpy stpcpy-vx stpcpy-c \
+ 		   strncpy strncpy-vx \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index da8696d917abf51c..c531be4bc7eb3f55 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -26,6 +26,7 @@
+ #include <ifunc-memcpy.h>
+ #include <ifunc-strstr.h>
+ #include <ifunc-memmem.h>
++#include <ifunc-strlen.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -164,6 +165,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_MEMMEM_IFUNC  */
+ 
++#if HAVE_STRLEN_IFUNC
++    IFUNC_IMPL (i, name, strlen,
++# if HAVE_STRLEN_Z13
++		IFUNC_IMPL_ADD (array, i, strlen,
++				dl_hwcap & HWCAP_S390_VX, STRLEN_Z13)
++# endif
++# if HAVE_STRLEN_C
++		IFUNC_IMPL_ADD (array, i, strlen, 1, STRLEN_C)
++# endif
++		)
++#endif /* HAVE_STRLEN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -172,7 +185,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (strlen);
+   IFUNC_VX_IMPL (wcslen);
+ 
+   IFUNC_VX_IMPL (strnlen);
+diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/strlen-c.c
+similarity index 78%
+rename from sysdeps/s390/multiarch/strlen-c.c
+rename to sysdeps/s390/strlen-c.c
+index a2c8e43624a9bc91..b4569701af96f4a9 100644
+--- a/sysdeps/s390/multiarch/strlen-c.c
++++ b/sysdeps/s390/strlen-c.c
+@@ -16,13 +16,17 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRLEN  __strlen_c
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)			\
++#include <ifunc-strlen.h>
++
++#if HAVE_STRLEN_C
++# if HAVE_STRLEN_IFUNC
++#  define STRLEN STRLEN_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)		\
+   __hidden_ver1 (__strlen_c, __GI_strlen, __strlen_c);
+-# endif /* SHARED */
++#  endif
++# endif
+ 
+ # include <string/strlen.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/strlen-vx.S
+similarity index 90%
+rename from sysdeps/s390/multiarch/strlen-vx.S
+rename to sysdeps/s390/strlen-vx.S
+index 9308b332371dcdaa..39ef43107d11ec73 100644
+--- a/sysdeps/s390/multiarch/strlen-vx.S
++++ b/sysdeps/s390/strlen-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strlen.h>
++#if HAVE_STRLEN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -34,7 +35,7 @@
+    -r5=current_len and return_value
+    -v16=part of s
+ */
+-ENTRY(__strlen_vx)
++ENTRY(STRLEN_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -80,5 +81,13 @@ ENTRY(__strlen_vx)
+ 	vlgvb	%r2,%v16,7	/* Load byte index of zero.  */
+ 	algr	%r2,%r5
+ 	br	%r14
+-END(__strlen_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRLEN_Z13)
++
++# if ! HAVE_STRLEN_IFUNC
++strong_alias (STRLEN_Z13, strlen)
++# endif
++
++# if ! HAVE_STRLEN_C && defined SHARED && IS_IN (libc)
++strong_alias (STRLEN_Z13, __GI_strlen)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/strlen.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/strlen.c
+rename to sysdeps/s390/strlen.c
+index 0edf8b7d0231cf31..6ba0fe86fe9789f0 100644
+--- a/sysdeps/s390/multiarch/strlen.c
++++ b/sysdeps/s390/strlen.c
+@@ -16,14 +16,25 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strlen.h>
++
++#if HAVE_STRLEN_IFUNC
+ # define strlen __redirect_strlen
+ # include <string.h>
+ # include <ifunc-resolve.h>
+ # undef strlen
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen)
++# if HAVE_STRLEN_C
++extern __typeof (__redirect_strlen) STRLEN_C attribute_hidden;
++# endif
++
++# if HAVE_STRLEN_Z13
++extern __typeof (__redirect_strlen) STRLEN_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strlen.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_strlen, strlen,
++		      (HAVE_STRLEN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRLEN_Z13
++		      : STRLEN_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-17.patch b/SOURCES/glibc-rh1659438-17.patch
new file mode 100644
index 0000000..da43ae2
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-17.patch
@@ -0,0 +1,269 @@
+commit de10e44dda686e3ed6a7a1463869df846ea39825
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:10 2018 +0100
+
+    S390: Refactor strnlen ifunc handling.
+    
+    The ifunc handling for strnlen is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strnlen variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strnlen variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strnlen.
+            * sysdeps/s390/multiarch/strnlen-c.c: Move to ...
+            * sysdeps/s390/strnlen-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strnlen-vx.S: Move to ...
+            * sysdeps/s390/strnlen-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strnlen.c: Move to ...
+            * sysdeps/s390/strnlen.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strnlen.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 600d8e629df7090e..f092355743e3908f 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -37,5 +37,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   memmove memmove-c \
+ 		   strstr strstr-vx strstr-c \
+ 		   memmem memmem-vx memmem-c \
+-		   strlen strlen-vx strlen-c
++		   strlen strlen-vx strlen-c \
++		   strnlen strnlen-vx strnlen-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strnlen.h b/sysdeps/s390/ifunc-strnlen.h
+new file mode 100644
+index 0000000000000000..e92329888773304d
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strnlen.h
+@@ -0,0 +1,52 @@
++/* strnlen variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRNLEN_IFUNC	1
++#else
++# define HAVE_STRNLEN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT HAVE_STRNLEN_IFUNC
++#else
++# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRNLEN_DEFAULT	STRNLEN_Z13
++# define HAVE_STRNLEN_C		0
++# define HAVE_STRNLEN_Z13	1
++#else
++# define STRNLEN_DEFAULT	STRNLEN_C
++# define HAVE_STRNLEN_C		1
++# define HAVE_STRNLEN_Z13	HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRNLEN_C
++# define STRNLEN_C		__strnlen_c
++#else
++# define STRNLEN_C		NULL
++#endif
++
++#if HAVE_STRNLEN_Z13
++# define STRNLEN_Z13		__strnlen_vx
++#else
++# define STRNLEN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 601523919c235f76..35ba223c5d4fb52f 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strnlen strnlen-vx strnlen-c \
+-		   strcpy strcpy-vx \
++sysdep_routines += strcpy strcpy-vx \
+ 		   stpcpy stpcpy-vx stpcpy-c \
+ 		   strncpy strncpy-vx \
+ 		   stpncpy stpncpy-vx stpncpy-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index c531be4bc7eb3f55..680e5b738bfb7f32 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -27,6 +27,7 @@
+ #include <ifunc-strstr.h>
+ #include <ifunc-memmem.h>
+ #include <ifunc-strlen.h>
++#include <ifunc-strnlen.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -177,6 +178,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRLEN_IFUNC  */
+ 
++#if HAVE_STRNLEN_IFUNC
++    IFUNC_IMPL (i, name, strnlen,
++# if HAVE_STRNLEN_Z13
++		IFUNC_IMPL_ADD (array, i, strnlen,
++				dl_hwcap & HWCAP_S390_VX, STRNLEN_Z13)
++# endif
++# if HAVE_STRNLEN_C
++		IFUNC_IMPL_ADD (array, i, strnlen, 1, STRNLEN_C)
++# endif
++		)
++#endif /* HAVE_STRNLEN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -187,7 +200,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcslen);
+ 
+-  IFUNC_VX_IMPL (strnlen);
+   IFUNC_VX_IMPL (wcsnlen);
+ 
+   IFUNC_VX_IMPL (strcpy);
+diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/strnlen-c.c
+similarity index 81%
+rename from sysdeps/s390/multiarch/strnlen-c.c
+rename to sysdeps/s390/strnlen-c.c
+index 353e83ed356ca080..c2d887f1e4f504e8 100644
+--- a/sysdeps/s390/multiarch/strnlen-c.c
++++ b/sysdeps/s390/strnlen-c.c
+@@ -16,15 +16,19 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRNLEN  __strnlen_c
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)					\
++#include <ifunc-strnlen.h>
++
++#if HAVE_STRNLEN_C
++# if HAVE_STRNLEN_IFUNC
++#  define STRNLEN STRNLEN_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   define libc_hidden_def(name)					\
+   __hidden_ver1 (__strnlen_c, __GI_strnlen, __strnlen_c);	\
+   strong_alias (__strnlen_c, __strnlen_c_1);			\
+   __hidden_ver1 (__strnlen_c_1, __GI___strnlen, __strnlen_c_1);
+-# endif /* SHARED */
++#  endif
++# endif
+ 
+ # include <string/strnlen.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/strnlen-vx.S
+similarity index 90%
+rename from sysdeps/s390/multiarch/strnlen-vx.S
+rename to sysdeps/s390/strnlen-vx.S
+index fc659a956cfc1fa1..0b8fe3da342f6803 100644
+--- a/sysdeps/s390/multiarch/strnlen-vx.S
++++ b/sysdeps/s390/strnlen-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strnlen.h>
++
++#if HAVE_STRNLEN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -34,7 +36,7 @@
+    -r5=current_len and return_value
+    -v16=part of s
+ */
+-ENTRY(__strnlen_vx)
++ENTRY(STRNLEN_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -130,5 +132,16 @@ ENTRY(__strnlen_vx)
+ 	clgrjl	%r1,%r3,.Lloop64
+ 
+ 	j	.Llt64
+-END(__strnlen_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRNLEN_Z13)
++
++# if ! HAVE_STRNLEN_IFUNC
++strong_alias (STRNLEN_Z13, __strnlen)
++weak_alias (__strnlen, strnlen)
++# endif
++
++# if ! HAVE_STRNLEN_C && defined SHARED && IS_IN (libc)
++strong_alias (STRNLEN_Z13, __GI_strnlen)
++strong_alias (STRNLEN_Z13, __GI___strnlen)
++# endif
++
++#endif /* HAVE_STRNLEN_Z13  */
+diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/strnlen.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/strnlen.c
+rename to sysdeps/s390/strnlen.c
+index 0f9cff5d69b017ae..aa4953d5035bc2fc 100644
+--- a/sysdeps/s390/multiarch/strnlen.c
++++ b/sysdeps/s390/strnlen.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strnlen.h>
++
++#if HAVE_STRNLEN_IFUNC
+ # define strnlen __redirect_strnlen
+ # define __strnlen __redirect___strnlen
+ # include <string.h>
+@@ -24,9 +26,18 @@
+ # undef __strnlen
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen)
+-weak_alias (__strnlen, strnlen)
++# if HAVE_STRNLEN_C
++extern __typeof (__redirect_strnlen) STRNLEN_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strnlen.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_STRNLEN_Z13
++extern __typeof (__redirect_strnlen) STRNLEN_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___strnlen, __strnlen,
++		      (HAVE_STRNLEN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRNLEN_Z13
++		      : STRNLEN_DEFAULT
++		      )
++weak_alias (__strnlen, strnlen)
++#endif /* HAVE_STRNLEN_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-18.patch b/SOURCES/glibc-rh1659438-18.patch
new file mode 100644
index 0000000..bcd7958
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-18.patch
@@ -0,0 +1,398 @@
+commit 914a4e05572e108201d71dcd3e47da8aeeecd70d
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:10 2018 +0100
+
+    S390: Refactor strcpy ifunc handling.
+    
+    The ifunc handling for strcpy is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    Note: The fallback s390-32/s390-64 ifunc variants with mvst instruction
+    are now moved to the unified strcpy-z900.S file which can be used for
+    31/64bit. The s390-32/s390-64 files multiarch/strcpy.c and strcpy.S
+    are deleted.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strcpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strcpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strcpy.
+            * sysdeps/s390/multiarch/strcpy-vx.S: Move to ...
+            * sysdeps/s390/strcpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strcpy.c: Move to ...
+            * sysdeps/s390/strcpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strcpy.h: New file.
+            * sysdeps/s390/s390-64/strcpy.S: Move to ...
+            * sysdeps/s390/strcpy-z900.S: ... here and adjust to be usable
+            for 31/64bit and ifunc handling.
+            * sysdeps/s390/s390-32/multiarch/strcpy.c: Delete file.
+            * sysdeps/s390/s390-64/multiarch/strcpy.c: Likewise.
+            * sysdeps/s390/s390-32/strcpy.S: Likewise.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index f092355743e3908f..e4191319531ecb01 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -38,5 +38,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strstr strstr-vx strstr-c \
+ 		   memmem memmem-vx memmem-c \
+ 		   strlen strlen-vx strlen-c \
+-		   strnlen strnlen-vx strnlen-c
++		   strnlen strnlen-vx strnlen-c \
++		   strcpy strcpy-vx strcpy-z900
+ endif
+diff --git a/sysdeps/s390/ifunc-strcpy.h b/sysdeps/s390/ifunc-strcpy.h
+new file mode 100644
+index 0000000000000000..85e45556e6a61dd5
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strcpy.h
+@@ -0,0 +1,52 @@
++/* strcpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRCPY_IFUNC	1
++#else
++# define HAVE_STRCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT HAVE_STRCPY_IFUNC
++#else
++# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRCPY_DEFAULT		STRCPY_Z13
++# define HAVE_STRCPY_Z900_G5	0
++# define HAVE_STRCPY_Z13	1
++#else
++# define STRCPY_DEFAULT		STRCPY_Z900_G5
++# define HAVE_STRCPY_Z900_G5	1
++# define HAVE_STRCPY_Z13	HAVE_STRCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRCPY_Z900_G5
++# define STRCPY_Z900_G5		__strcpy_default
++#else
++# define STRCPY_Z900_G5		NULL
++#endif
++
++#if HAVE_STRCPY_Z13
++# define STRCPY_Z13		__strcpy_vx
++#else
++# define STRCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 35ba223c5d4fb52f..50f7f0b78df723bb 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strcpy strcpy-vx \
+-		   stpcpy stpcpy-vx stpcpy-c \
++sysdep_routines += stpcpy stpcpy-vx stpcpy-c \
+ 		   strncpy strncpy-vx \
+ 		   stpncpy stpncpy-vx stpncpy-c \
+ 		   strcat strcat-vx strcat-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 680e5b738bfb7f32..1784372db9828463 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -28,6 +28,7 @@
+ #include <ifunc-memmem.h>
+ #include <ifunc-strlen.h>
+ #include <ifunc-strnlen.h>
++#include <ifunc-strcpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -190,6 +191,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRNLEN_IFUNC  */
+ 
++#if HAVE_STRCPY_IFUNC
++    IFUNC_IMPL (i, name, strcpy,
++# if HAVE_STRCPY_Z13
++		IFUNC_IMPL_ADD (array, i, strcpy,
++				dl_hwcap & HWCAP_S390_VX, STRCPY_Z13)
++# endif
++# if HAVE_STRCPY_Z900_G5
++		IFUNC_IMPL_ADD (array, i, strcpy, 1, STRCPY_Z900_G5)
++# endif
++		)
++#endif /* HAVE_STRCPY_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -202,7 +215,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcsnlen);
+ 
+-  IFUNC_VX_IMPL (strcpy);
+   IFUNC_VX_IMPL (wcscpy);
+ 
+   IFUNC_VX_IMPL (stpcpy);
+diff --git a/sysdeps/s390/s390-32/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c
+deleted file mode 100644
+index 6a22e31a03c8c1c4..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/strcpy.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of strcpy.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/strcpy.S will be used.  */
+-#include <sysdeps/s390/multiarch/strcpy.c>
+diff --git a/sysdeps/s390/s390-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S
+deleted file mode 100644
+index d49136ee92b83378..0000000000000000
+--- a/sysdeps/s390/s390-32/strcpy.S
++++ /dev/null
+@@ -1,36 +0,0 @@
+-/* strcpy - copy a string from source to destination. For IBM S390
+-   This file is part of the GNU C Library.
+-   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/*
+- * R2 = address of destination
+- * R3 = address of source
+- */
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-	.text
+-ENTRY(strcpy)
+-	slr   %r0,%r0
+-	lr    %r1,%r2
+-0:      mvst  %r1,%r3
+-	jo    0b
+-	br    %r14
+-END(strcpy)
+-libc_hidden_builtin_def (strcpy)
+diff --git a/sysdeps/s390/s390-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c
+deleted file mode 100644
+index 6a22e31a03c8c1c4..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/strcpy.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of strcpy.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/strcpy.S will be used.  */
+-#include <sysdeps/s390/multiarch/strcpy.c>
+diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/strcpy-vx.S
+similarity index 85%
+rename from sysdeps/s390/multiarch/strcpy-vx.S
+rename to sysdeps/s390/strcpy-vx.S
+index 52197f57f7b5d5cf..844d23e4fee32c9b 100644
+--- a/sysdeps/s390/multiarch/strcpy-vx.S
++++ b/sysdeps/s390/strcpy-vx.S
+@@ -16,13 +16,13 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-
+-# include "sysdep.h"
+-# include "asm-syntax.h"
++#include <ifunc-strcpy.h>
++#include "sysdep.h"
++#include "asm-syntax.h"
+ 
+ 	.text
+ 
++#if HAVE_STRCPY_Z13
+ /* char * strcpy (const char *dest, const char *src)
+    Copy string src to dest.
+ 
+@@ -36,7 +36,7 @@
+    -v17=index of zero
+    -v18=part of src
+ */
+-ENTRY(__strcpy_vx)
++ENTRY(STRCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -97,13 +97,13 @@ ENTRY(__strcpy_vx)
+ .Lfound_align:
+ 	vstl	%v16,%r5,0(%r2)	/* Copy characters including zero.  */
+ 	br	%r14
+-END(__strcpy_vx)
++END(STRCPY_Z13)
+ 
+-/* Use mvst-strcpy-implementation as default implementation.  */
+-# define strcpy __strcpy_c
+-# undef libc_hidden_builtin_def
+-# define libc_hidden_builtin_def(name) strong_alias(__strcpy_c, __GI_strcpy)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++# if ! HAVE_STRCPY_IFUNC
++strong_alias (STRCPY_Z13, strcpy)
++# endif
+ 
+-/* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory.  */
+-#include <strcpy.S>
++# if ! HAVE_STRCPY_Z900_G5 && defined SHARED && IS_IN (libc)
++strong_alias (STRCPY_Z13, __GI_strcpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/strcpy-z900.S
+similarity index 66%
+rename from sysdeps/s390/s390-64/strcpy.S
+rename to sysdeps/s390/strcpy-z900.S
+index 203c73c905d0d86c..42798b1fd5c51187 100644
+--- a/sysdeps/s390/s390-64/strcpy.S
++++ b/sysdeps/s390/strcpy-z900.S
+@@ -1,4 +1,4 @@
+-/* strcpy - copy a string from source to destination.  64 bit S/390 version.
++/* strcpy - copy a string from source to destination.  64/31 bit S/390 version.
+    Copyright (C) 2001-2018 Free Software Foundation, Inc.
+    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+    This file is part of the GNU C Library.
+@@ -21,15 +21,36 @@
+      %r2 = address of destination
+      %r3 = address of source.  */
+ 
++#include <ifunc-strcpy.h>
+ #include "sysdep.h"
+ #include "asm-syntax.h"
+ 
++#if HAVE_STRCPY_Z900_G5
++# if defined __s390x__
++#  define SLGR	slgr
++#  define LGR	lgr
++# else
++#  define SLGR	slr
++#  define LGR	lr
++# endif /* ! defined __s390x__  */
++
+         .text
+-ENTRY(strcpy)
+-	slgr  %r0,%r0
+-	lgr   %r1,%r2
++ENTRY(STRCPY_Z900_G5)
++	SLGR  %r0,%r0
++	LGR   %r1,%r2
+ 0:	mvst  %r1,%r3
+ 	jo    0b
+ 	br    %r14
+-END(strcpy)
+-libc_hidden_builtin_def (strcpy)
++END(STRCPY_Z900_G5)
++
++# undef SLGR
++# undef LGR
++
++# if ! HAVE_STRCPY_IFUNC
++strong_alias (STRCPY_Z900_G5, strcpy)
++# endif
++
++# if defined SHARED && IS_IN (libc)
++strong_alias (STRCPY_Z900_G5, __GI_strcpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/strcpy.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/strcpy.c
+rename to sysdeps/s390/strcpy.c
+index 8f32a13f6730c427..f4e28e24c85b7162 100644
+--- a/sysdeps/s390/multiarch/strcpy.c
++++ b/sysdeps/s390/strcpy.c
+@@ -16,12 +16,25 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strcpy.h>
++
++#if HAVE_STRCPY_IFUNC
+ # define strcpy __redirect_strcpy
+ # include <string.h>
+ # undef strcpy
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy)
++# if HAVE_STRCPY_Z900_G5
++extern __typeof (__redirect_strcpy) STRCPY_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_STRCPY_Z13
++extern __typeof (__redirect_strcpy) STRCPY_Z13 attribute_hidden;
++# endif
+ 
++s390_libc_ifunc_expr (__redirect_strcpy, strcpy,
++		      (HAVE_STRCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRCPY_Z13
++		      : STRCPY_DEFAULT
++		      )
+ #endif
diff --git a/SOURCES/glibc-rh1659438-19.patch b/SOURCES/glibc-rh1659438-19.patch
new file mode 100644
index 0000000..b80b640
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-19.patch
@@ -0,0 +1,279 @@
+commit 970449311ded3cacb6058c96143dd4c057900589
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:11 2018 +0100
+
+    S390: Refactor stpcpy ifunc handling.
+    
+    The ifunc handling for stpcpy is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove stpcpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add stpcpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for stpcpy.
+            * sysdeps/s390/multiarch/stpcpy-c.c: Move to ...
+            * sysdeps/s390/stpcpy-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/stpcpy-vx.S: Move to ...
+            * sysdeps/s390/stpcpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/stpcpy.c: Move to ...
+            * sysdeps/s390/stpcpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-stpcpy.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index e4191319531ecb01..b7e1bc8aecf2f8c9 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -39,5 +39,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   memmem memmem-vx memmem-c \
+ 		   strlen strlen-vx strlen-c \
+ 		   strnlen strnlen-vx strnlen-c \
+-		   strcpy strcpy-vx strcpy-z900
++		   strcpy strcpy-vx strcpy-z900 \
++		   stpcpy stpcpy-vx stpcpy-c
+ endif
+diff --git a/sysdeps/s390/ifunc-stpcpy.h b/sysdeps/s390/ifunc-stpcpy.h
+new file mode 100644
+index 0000000000000000..9a70cd7c8c4f4582
+--- /dev/null
++++ b/sysdeps/s390/ifunc-stpcpy.h
+@@ -0,0 +1,52 @@
++/* stpcpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STPCPY_IFUNC	1
++#else
++# define HAVE_STPCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT HAVE_STPCPY_IFUNC
++#else
++# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STPCPY_DEFAULT		STPCPY_Z13
++# define HAVE_STPCPY_C		0
++# define HAVE_STPCPY_Z13	1
++#else
++# define STPCPY_DEFAULT		STPCPY_C
++# define HAVE_STPCPY_C		1
++# define HAVE_STPCPY_Z13	HAVE_STPCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STPCPY_C
++# define STPCPY_C		__stpcpy_c
++#else
++# define STPCPY_C		NULL
++#endif
++
++#if HAVE_STPCPY_Z13
++# define STPCPY_Z13		__stpcpy_vx
++#else
++# define STPCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 50f7f0b78df723bb..9517417dcbe1c701 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += stpcpy stpcpy-vx stpcpy-c \
+-		   strncpy strncpy-vx \
++sysdep_routines += strncpy strncpy-vx \
+ 		   stpncpy stpncpy-vx stpncpy-c \
+ 		   strcat strcat-vx strcat-c \
+ 		   strncat strncat-vx strncat-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 1784372db9828463..678ed13833332f11 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -29,6 +29,7 @@
+ #include <ifunc-strlen.h>
+ #include <ifunc-strnlen.h>
+ #include <ifunc-strcpy.h>
++#include <ifunc-stpcpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -203,6 +204,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRCPY_IFUNC  */
+ 
++#if HAVE_STPCPY_IFUNC
++    IFUNC_IMPL (i, name, stpcpy,
++# if HAVE_STPCPY_Z13
++		IFUNC_IMPL_ADD (array, i, stpcpy,
++				dl_hwcap & HWCAP_S390_VX, STPCPY_Z13)
++# endif
++# if HAVE_STPCPY_C
++		IFUNC_IMPL_ADD (array, i, stpcpy, 1, STPCPY_C)
++# endif
++		)
++#endif /* HAVE_STPCPY_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -217,7 +230,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcscpy);
+ 
+-  IFUNC_VX_IMPL (stpcpy);
+   IFUNC_VX_IMPL (wcpcpy);
+ 
+   IFUNC_VX_IMPL (strncpy);
+diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/stpcpy-c.c
+similarity index 74%
+rename from sysdeps/s390/multiarch/stpcpy-c.c
+rename to sysdeps/s390/stpcpy-c.c
+index 4a1c3e5832c9b544..76ec88462717799c 100644
+--- a/sysdeps/s390/multiarch/stpcpy-c.c
++++ b/sysdeps/s390/stpcpy-c.c
+@@ -16,20 +16,25 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STPCPY  __stpcpy_c
+-# undef weak_alias
+-# define weak_alias(a, b)
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)					\
++#include <ifunc-stpcpy.h>
++
++#if HAVE_STPCPY_C
++# if HAVE_STPCPY_IFUNC
++#  define STPCPY STPCPY_C
++
++#  undef weak_alias
++#  define weak_alias(a, b)
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   define libc_hidden_def(name)				\
+   __hidden_ver1 (__stpcpy_c, __GI___stpcpy, __stpcpy_c);
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)				\
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
+   strong_alias (__stpcpy_c, __stpcpy_c_1);			\
+   __hidden_ver1 (__stpcpy_c_1, __GI_stpcpy, __stpcpy_c_1);
+-# endif /* SHARED */
+-
++#  endif
++# endif
+ 
+ # include <string/stpcpy.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/stpcpy-vx.S
+similarity index 90%
+rename from sysdeps/s390/multiarch/stpcpy-vx.S
+rename to sysdeps/s390/stpcpy-vx.S
+index 6c17def0fc35d60d..d2db02d0cd714d27 100644
+--- a/sysdeps/s390/multiarch/stpcpy-vx.S
++++ b/sysdeps/s390/stpcpy-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-stpcpy.h>
++
++#if HAVE_STPCPY_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -36,7 +38,7 @@
+    -v17=index of zero
+    -v18=part of src
+ */
+-ENTRY(__stpcpy_vx)
++ENTRY(STPCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -100,5 +102,15 @@ ENTRY(__stpcpy_vx)
+ 	vstl	%v16,%r5,0(%r2)	/* Copy characters including zero.  */
+ 	la	%r2,0(%r5,%r2)	/* Return pointer to zero.  */
+ 	br	%r14
+-END(__stpcpy_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STPCPY_Z13)
++
++# if ! HAVE_STPCPY_IFUNC
++strong_alias (STPCPY_Z13, __stpcpy)
++weak_alias (__stpcpy, stpcpy)
++# endif
++
++# if ! HAVE_STPCPY_C && defined SHARED && IS_IN (libc)
++strong_alias (STPCPY_Z13, __GI_stpcpy)
++strong_alias (STPCPY_Z13, __GI___stpcpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/stpcpy.c
+similarity index 74%
+rename from sysdeps/s390/multiarch/stpcpy.c
+rename to sysdeps/s390/stpcpy.c
+index 654f9dfbef512e34..670604e2de3806b7 100644
+--- a/sysdeps/s390/multiarch/stpcpy.c
++++ b/sysdeps/s390/stpcpy.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-stpcpy.h>
++
++#if HAVE_STPCPY_IFUNC
+ # define stpcpy __redirect_stpcpy
+ # define __stpcpy __redirect___stpcpy
+ /* Omit the stpcpy inline definitions because it would redefine stpcpy.  */
+@@ -27,9 +29,18 @@
+ # undef __stpcpy
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy);
+-weak_alias (__stpcpy, stpcpy)
++# if HAVE_STPCPY_C
++extern __typeof (__redirect_stpcpy) STPCPY_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/stpcpy.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_STPCPY_Z13
++extern __typeof (__redirect_stpcpy) STPCPY_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___stpcpy, __stpcpy,
++		      (HAVE_STPCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STPCPY_Z13
++		      : STPCPY_DEFAULT
++		      )
++weak_alias (__stpcpy, stpcpy)
++#endif
diff --git a/SOURCES/glibc-rh1659438-2.patch b/SOURCES/glibc-rh1659438-2.patch
new file mode 100644
index 0000000..855686c
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-2.patch
@@ -0,0 +1,58 @@
+commit e8023f2685c9f97e72bbe9d2a9c968e0d8438371
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:03 2018 +0100
+
+    S390: Use hwcap instead of dl_hwcap in ifunc-resolvers.
+    
+    The renaming of hwcap arguments in ifunc-resolvers is needed
+    in order to prepare for further commits which refactors
+    ifunc handling for memset, memcmp, and memcpy.  Now you are able
+    to use s390_libc_ifunc_init which stores the stfle bits
+    within the expression for an ifunc-resolver generated by
+    s390_libc_ifunc_expr.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/ifunc-resolve.h
+            (s390_libc_ifunc_init, s390_libc_ifunc,
+            s390_vx_libc_ifunc2_redirected): Use hwcap instead of dl_hwcap.
+
+diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
+index b42ed922fd27834b..b7e20abc59638251 100644
+--- a/sysdeps/s390/multiarch/ifunc-resolve.h
++++ b/sysdeps/s390/multiarch/ifunc-resolve.h
+@@ -42,9 +42,9 @@
+ 		       : : "cc");
+ #define s390_libc_ifunc_init()						\
+   unsigned long long stfle_bits = 0ULL;					\
+-  if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE)			\
+-		     && (dl_hwcap & HWCAP_S390_ZARCH)			\
+-		     && (dl_hwcap & HWCAP_S390_HIGH_GPRS)))		\
++  if (__glibc_likely ((hwcap & HWCAP_S390_STFLE)			\
++		      && (hwcap & HWCAP_S390_ZARCH)			\
++		      && (hwcap & HWCAP_S390_HIGH_GPRS)))		\
+     {									\
+       S390_STORE_STFLE (stfle_bits);					\
+     }
+@@ -61,7 +61,7 @@
+ 	   : __glibc_likely (S390_IS_Z10 (stfle_bits))			\
+ 	     ? RESOLVERFUNC##_z10					\
+ 	     : RESOLVERFUNC##_default,					\
+-	   unsigned long int dl_hwcap, s390_libc_ifunc_init);
++	   unsigned long int hwcap, s390_libc_ifunc_init);
+ 
+ #define s390_vx_libc_ifunc(FUNC)		\
+   s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC)
+@@ -79,10 +79,10 @@
+   extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden;	\
+   extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden;	\
+   __ifunc (TYPE_FUNC, FUNC,						\
+-	   (dl_hwcap & HWCAP_S390_VX)					\
++	   (hwcap & HWCAP_S390_VX)					\
+ 	   ? RESOLVERFUNC##_vx						\
+ 	   : RESOLVERFUNC##_c,						\
+-	   unsigned long int dl_hwcap, s390_vx_libc_ifunc_init);
++	   unsigned long int hwcap, s390_vx_libc_ifunc_init);
+ 
+ #define s390_libc_ifunc_expr_init()
+ #define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR)		\
diff --git a/SOURCES/glibc-rh1659438-20.patch b/SOURCES/glibc-rh1659438-20.patch
new file mode 100644
index 0000000..855354d
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-20.patch
@@ -0,0 +1,378 @@
+commit d1bdbf380908c34f31ba145ec9afebade3f1418f
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:11 2018 +0100
+
+    S390: Refactor strncpy ifunc handling.
+    
+    The ifunc handling for strncpy is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    Note: The fallback s390-32/s390-64 ifunc variants are now moved to
+    the strncpy-z900.S files. The s390-32/s390-64 files multiarch/strncpy.c
+    and strncpy.S are deleted.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strncpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strncpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strncpy.
+            * sysdeps/s390/multiarch/strncpy-vx.S: Move to ...
+            * sysdeps/s390/strncpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strncpy.c: Move to ...
+            * sysdeps/s390/strncpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strncpy.h: New file.
+            * sysdeps/s390/s390-64/strncpy.S: Move to ...
+            * sysdeps/s390/s390-64/strncpy-z900.S: ... here
+            and adjust ifunc handling.
+            * sysdeps/s390/s390-32/strncpy.S: Move to ...
+            * sysdeps/s390/s390-32/strncpy-z900.S: ... here
+            and adjust ifunc handling.
+            * sysdeps/s390/s390-32/multiarch/strncpy.c: Delete file.
+            * sysdeps/s390/s390-64/multiarch/strncpy.c: Likewise.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index b7e1bc8aecf2f8c9..db060c81aade84ca 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -40,5 +40,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strlen strlen-vx strlen-c \
+ 		   strnlen strnlen-vx strnlen-c \
+ 		   strcpy strcpy-vx strcpy-z900 \
+-		   stpcpy stpcpy-vx stpcpy-c
++		   stpcpy stpcpy-vx stpcpy-c \
++		   strncpy strncpy-vx strncpy-z900
+ endif
+diff --git a/sysdeps/s390/ifunc-strncpy.h b/sysdeps/s390/ifunc-strncpy.h
+new file mode 100644
+index 0000000000000000..31e87e93c529c443
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strncpy.h
+@@ -0,0 +1,52 @@
++/* strncpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRNCPY_IFUNC	1
++#else
++# define HAVE_STRNCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT HAVE_STRNCPY_IFUNC
++#else
++# define HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRNCPY_DEFAULT	STRNCPY_Z13
++# define HAVE_STRNCPY_Z900_G5	0
++# define HAVE_STRNCPY_Z13	1
++#else
++# define STRNCPY_DEFAULT	STRNCPY_Z900_G5
++# define HAVE_STRNCPY_Z900_G5	1
++# define HAVE_STRNCPY_Z13	HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRNCPY_Z900_G5
++# define STRNCPY_Z900_G5	__strncpy_default
++#else
++# define STRNCPY_Z900_G5	NULL
++#endif
++
++#if HAVE_STRNCPY_Z13
++# define STRNCPY_Z13		__strncpy_vx
++#else
++# define STRNCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 9517417dcbe1c701..c5189b556cf3762d 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strncpy strncpy-vx \
+-		   stpncpy stpncpy-vx stpncpy-c \
++sysdep_routines += stpncpy stpncpy-vx stpncpy-c \
+ 		   strcat strcat-vx strcat-c \
+ 		   strncat strncat-vx strncat-c \
+ 		   strcmp strcmp-vx \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 678ed13833332f11..d598fc5c22050da2 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -30,6 +30,7 @@
+ #include <ifunc-strnlen.h>
+ #include <ifunc-strcpy.h>
+ #include <ifunc-stpcpy.h>
++#include <ifunc-strncpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -216,6 +217,19 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STPCPY_IFUNC  */
+ 
++#if HAVE_STRNCPY_IFUNC
++    IFUNC_IMPL (i, name, strncpy,
++# if HAVE_STRNCPY_Z13
++		IFUNC_IMPL_ADD (array, i, strncpy,
++				dl_hwcap & HWCAP_S390_VX, STRNCPY_Z13)
++# endif
++# if HAVE_STRNCPY_Z900_G5
++		IFUNC_IMPL_ADD (array, i, strncpy, 1, STRNCPY_Z900_G5)
++# endif
++		)
++#endif /* HAVE_STRNCPY_IFUNC  */
++
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -232,7 +246,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcpcpy);
+ 
+-  IFUNC_VX_IMPL (strncpy);
+   IFUNC_VX_IMPL (wcsncpy);
+ 
+   IFUNC_VX_IMPL (stpncpy);
+diff --git a/sysdeps/s390/s390-32/multiarch/strncpy.c b/sysdeps/s390/s390-32/multiarch/strncpy.c
+deleted file mode 100644
+index 57f9df18d12c1959..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/strncpy.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of strncpy.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/strncpy.S will be used.  */
+-#include <sysdeps/s390/multiarch/strncpy.c>
+diff --git a/sysdeps/s390/s390-32/strncpy.S b/sysdeps/s390/s390-32/strncpy-z900.S
+similarity index 89%
+rename from sysdeps/s390/s390-32/strncpy.S
+rename to sysdeps/s390/s390-32/strncpy-z900.S
+index 9086eb1c707bdfb3..ebdaba015214bc59 100644
+--- a/sysdeps/s390/s390-32/strncpy.S
++++ b/sysdeps/s390/s390-32/strncpy-z900.S
+@@ -24,10 +24,12 @@
+  * R4 = max of bytes to copy
+  */
+ 
++#include <ifunc-strncpy.h>
+ #include "sysdep.h"
+ #include "asm-syntax.h"
+ 
+-ENTRY(strncpy)
++#if HAVE_STRNCPY_Z900_G5
++ENTRY(STRNCPY_Z900_G5)
+ 	.text
+ 	st    %r2,24(%r15)          # save dst pointer
+ 	slr   %r2,%r3               # %r3 points to src, %r2+%r3 to dst
+@@ -75,5 +77,13 @@ ENTRY(strncpy)
+ 	jo    .L9
+ .Lexit: l     %r2,24(%r15)          # return dst pointer
+ 	br    %r14
+-END(strncpy)
+-libc_hidden_builtin_def (strncpy)
++END(STRNCPY_Z900_G5)
++
++# if ! HAVE_STRNCPY_IFUNC
++strong_alias (STRNCPY_Z900_G5, strncpy)
++# endif
++
++# if defined SHARED && IS_IN (libc)
++strong_alias (STRNCPY_Z900_G5, __GI_strncpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/s390-64/multiarch/strncpy.c b/sysdeps/s390/s390-64/multiarch/strncpy.c
+deleted file mode 100644
+index 57f9df18d12c1959..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/strncpy.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of strncpy.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/strncpy.S will be used.  */
+-#include <sysdeps/s390/multiarch/strncpy.c>
+diff --git a/sysdeps/s390/s390-64/strncpy.S b/sysdeps/s390/s390-64/strncpy-z900.S
+similarity index 90%
+rename from sysdeps/s390/s390-64/strncpy.S
+rename to sysdeps/s390/s390-64/strncpy-z900.S
+index be40aa32d5d9a2df..5732e6d83b5e8f30 100644
+--- a/sysdeps/s390/s390-64/strncpy.S
++++ b/sysdeps/s390/s390-64/strncpy-z900.S
+@@ -23,10 +23,12 @@
+      %r3 = address of source (src)
+      %r4 = max of bytes to copy.  */
+ 
++#include <ifunc-strncpy.h>
+ #include "sysdep.h"
+ #include "asm-syntax.h"
+ 
+-ENTRY(strncpy)
++#if HAVE_STRNCPY_Z900_G5
++ENTRY(STRNCPY_Z900_G5)
+ 	.text
+ 	stg   %r2,48(%r15)	    # save dst pointer
+ 	slgr  %r2,%r3		    # %r3 points to src, %r2+%r3 to dst
+@@ -86,5 +88,13 @@ ENTRY(strncpy)
+ 	jo    .L13
+ .Lexit: lg    %r2,48(%r15)	    # return dst pointer
+ 	br    %r14
+-END(strncpy)
+-libc_hidden_builtin_def (strncpy)
++END(STRNCPY_Z900_G5)
++
++# if ! HAVE_STRNCPY_IFUNC
++strong_alias (STRNCPY_Z900_G5, strncpy)
++# endif
++
++# if defined SHARED && IS_IN (libc)
++strong_alias (STRNCPY_Z900_G5, __GI_strncpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/strncpy-vx.S b/sysdeps/s390/strncpy-vx.S
+similarity index 93%
+rename from sysdeps/s390/multiarch/strncpy-vx.S
+rename to sysdeps/s390/strncpy-vx.S
+index 2a37b7b84e0a2514..be09ddf092388c72 100644
+--- a/sysdeps/s390/multiarch/strncpy-vx.S
++++ b/sysdeps/s390/strncpy-vx.S
+@@ -16,13 +16,13 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-
+-# include "sysdep.h"
+-# include "asm-syntax.h"
++#include <ifunc-strncpy.h>
++#include "sysdep.h"
++#include "asm-syntax.h"
+ 
+ 	.text
+ 
++#if HAVE_STRNCPY_Z13
+ /* char * strncpy (const char *dest, const char *src, size_t n)
+    Copy at most n characters of string  src to dest.
+ 
+@@ -40,7 +40,7 @@
+    -v18=part of src
+    -v31=register save area for r6, r7
+ */
+-ENTRY(__strncpy_vx)
++ENTRY(STRNCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -196,12 +196,13 @@ ENTRY(__strncpy_vx)
+ 
+ 	vl	%v16,0(%r5,%r3)	/* Load s.  */
+ 	j	.Llt64
+-END(__strncpy_vx)
++END(STRNCPY_Z13)
+ 
+-# define strncpy __strncpy_c
+-# undef libc_hidden_builtin_def
+-# define libc_hidden_builtin_def(name) strong_alias(__strncpy_c, __GI_strncpy)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++# if ! HAVE_STRNCPY_IFUNC
++strong_alias (STRNCPY_Z13, strncpy)
++# endif
+ 
+-/* Include strncpy-implementation in s390-32/s390-64 subdirectory.  */
+-#include <strncpy.S>
++# if ! HAVE_STRNCPY_Z900_G5 && defined SHARED && IS_IN (libc)
++strong_alias (STRNCPY_Z13, __GI_strncpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/strncpy.c
+similarity index 71%
+rename from sysdeps/s390/multiarch/strncpy.c
+rename to sysdeps/s390/strncpy.c
+index 2d4c456d96dad0d6..ec8a26471b6536e8 100644
+--- a/sysdeps/s390/multiarch/strncpy.c
++++ b/sysdeps/s390/strncpy.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strncpy.h>
++
++#if HAVE_STRNCPY_IFUNC
+ # define strncpy __redirect_strncpy
+ /* Omit the strncpy inline definitions because it would redefine strncpy.  */
+ # define __NO_STRING_INLINES
+@@ -24,6 +26,17 @@
+ # undef strncpy
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strncpy, __strncpy, strncpy);
++# if HAVE_STRNCPY_Z900_G5
++extern __typeof (__redirect_strncpy) STRNCPY_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_STRNCPY_Z13
++extern __typeof (__redirect_strncpy) STRNCPY_Z13 attribute_hidden;
++# endif
+ 
++s390_libc_ifunc_expr (__redirect_strncpy, strncpy,
++		      (HAVE_STRNCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRNCPY_Z13
++		      : STRNCPY_DEFAULT
++		      )
+ #endif
diff --git a/SOURCES/glibc-rh1659438-21.patch b/SOURCES/glibc-rh1659438-21.patch
new file mode 100644
index 0000000..91393ae
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-21.patch
@@ -0,0 +1,267 @@
+commit 25218822bdbfb49b8ea0f419e8a20d2b9bd47cd0
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:11 2018 +0100
+
+    S390: Refactor stpncpy ifunc handling.
+    
+    The ifunc handling for stpncpy is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove stpncpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add stpncpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for stpncpy.
+            * sysdeps/s390/multiarch/stpncpy-c.c: Move to ...
+            * sysdeps/s390/stpncpy-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/stpncpy-vx.S: Move to ...
+            * sysdeps/s390/stpncpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/stpncpy.c: Move to ...
+            * sysdeps/s390/stpncpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-stpncpy.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index db060c81aade84ca..a9882b3996c30322 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -41,5 +41,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strnlen strnlen-vx strnlen-c \
+ 		   strcpy strcpy-vx strcpy-z900 \
+ 		   stpcpy stpcpy-vx stpcpy-c \
+-		   strncpy strncpy-vx strncpy-z900
++		   strncpy strncpy-vx strncpy-z900 \
++		   stpncpy stpncpy-vx stpncpy-c
+ endif
+diff --git a/sysdeps/s390/ifunc-stpncpy.h b/sysdeps/s390/ifunc-stpncpy.h
+new file mode 100644
+index 0000000000000000..46e57334e8439c1c
+--- /dev/null
++++ b/sysdeps/s390/ifunc-stpncpy.h
+@@ -0,0 +1,52 @@
++/* stpncpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STPNCPY_IFUNC	1
++#else
++# define HAVE_STPNCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT HAVE_STPNCPY_IFUNC
++#else
++# define HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STPNCPY_DEFAULT	STPNCPY_Z13
++# define HAVE_STPNCPY_C		0
++# define HAVE_STPNCPY_Z13	1
++#else
++# define STPNCPY_DEFAULT	STPNCPY_C
++# define HAVE_STPNCPY_C		1
++# define HAVE_STPNCPY_Z13	HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STPNCPY_C
++# define STPNCPY_C		__stpncpy_c
++#else
++# define STPNCPY_C		NULL
++#endif
++
++#if HAVE_STPNCPY_Z13
++# define STPNCPY_Z13		__stpncpy_vx
++#else
++# define STPNCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index c5189b556cf3762d..3d97d21da1fc852b 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += stpncpy stpncpy-vx stpncpy-c \
+-		   strcat strcat-vx strcat-c \
++sysdep_routines += strcat strcat-vx strcat-c \
+ 		   strncat strncat-vx strncat-c \
+ 		   strcmp strcmp-vx \
+ 		   strncmp strncmp-vx strncmp-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index d598fc5c22050da2..021e9f247fff44df 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -31,6 +31,7 @@
+ #include <ifunc-strcpy.h>
+ #include <ifunc-stpcpy.h>
+ #include <ifunc-strncpy.h>
++#include <ifunc-stpncpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -229,6 +230,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRNCPY_IFUNC  */
+ 
++#if HAVE_STPNCPY_IFUNC
++    IFUNC_IMPL (i, name, stpncpy,
++# if HAVE_STPNCPY_Z13
++		IFUNC_IMPL_ADD (array, i, stpncpy,
++				dl_hwcap & HWCAP_S390_VX, STPNCPY_Z13)
++# endif
++# if HAVE_STPNCPY_C
++		IFUNC_IMPL_ADD (array, i, stpncpy, 1, STPNCPY_C)
++# endif
++		)
++#endif /* HAVE_STPNCPY_IFUNC  */
++
+ 
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+@@ -248,7 +261,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcsncpy);
+ 
+-  IFUNC_VX_IMPL (stpncpy);
+   IFUNC_VX_IMPL (wcpncpy);
+ 
+   IFUNC_VX_IMPL (strcat);
+diff --git a/sysdeps/s390/multiarch/stpncpy-c.c b/sysdeps/s390/stpncpy-c.c
+similarity index 74%
+rename from sysdeps/s390/multiarch/stpncpy-c.c
+rename to sysdeps/s390/stpncpy-c.c
+index 45e50aa9e7df0b5e..e5d1ae867562da6c 100644
+--- a/sysdeps/s390/multiarch/stpncpy-c.c
++++ b/sysdeps/s390/stpncpy-c.c
+@@ -16,13 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STPNCPY  __stpncpy_c
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)  \
+-     __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c);
+-# endif /* SHARED */
++#include <ifunc-stpncpy.h>
++
++#if HAVE_STPNCPY_C
++# if HAVE_STPNCPY_IFUNC
++#  define STPNCPY STPNCPY_C
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   define libc_hidden_def(name)				\
++  __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c);
++#  endif
++# endif
+ 
+ # include <string/stpncpy.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/stpncpy-vx.S b/sysdeps/s390/stpncpy-vx.S
+similarity index 95%
+rename from sysdeps/s390/multiarch/stpncpy-vx.S
+rename to sysdeps/s390/stpncpy-vx.S
+index 922bd7a355a2d8a0..3dccc10be3b58d8d 100644
+--- a/sysdeps/s390/multiarch/stpncpy-vx.S
++++ b/sysdeps/s390/stpncpy-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-stpncpy.h>
++
++#if HAVE_STPNCPY_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -38,7 +40,7 @@
+    -%r6 = loaded bytes
+    -%r7 = border, tmp
+ */
+-ENTRY(__stpncpy_vx)
++ENTRY(STPNCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -196,5 +198,14 @@ ENTRY(__stpncpy_vx)
+ 
+ 	vl	%v16,0(%r5,%r3)	/* Load s.  */
+ 	j	.Llt64
+-END(__stpncpy_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STPNCPY_Z13)
++
++# if ! HAVE_STPNCPY_IFUNC
++strong_alias (STPNCPY_Z13, __stpncpy)
++weak_alias (__stpncpy, stpncpy)
++# endif
++
++# if ! HAVE_STPNCPY_C && defined SHARED && IS_IN (libc)
++strong_alias (STPNCPY_Z13, __GI___stpncpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/stpncpy.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/stpncpy.c
+rename to sysdeps/s390/stpncpy.c
+index f7f9d51a50db47d7..250dc68ed19bf6d9 100644
+--- a/sysdeps/s390/multiarch/stpncpy.c
++++ b/sysdeps/s390/stpncpy.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-stpncpy.h>
++
++#if HAVE_STPNCPY_IFUNC
+ # define stpncpy __redirect_stpncpy
+ # define __stpncpy __redirect___stpncpy
+ # include <string.h>
+@@ -24,9 +26,18 @@
+ # undef __stpncpy
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc_redirected (__redirect___stpncpy, __stpncpy)
+-weak_alias (__stpncpy, stpncpy)
++# if HAVE_STPNCPY_C
++extern __typeof (__redirect_stpncpy) STPNCPY_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/stpncpy.c>
+-#endif  /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_STPNCPY_Z13
++extern __typeof (__redirect_stpncpy) STPNCPY_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___stpncpy, __stpncpy,
++		      (HAVE_STPNCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STPNCPY_Z13
++		      : STPNCPY_DEFAULT
++		      )
++weak_alias (__stpncpy, stpncpy)
++#endif
diff --git a/SOURCES/glibc-rh1659438-22.patch b/SOURCES/glibc-rh1659438-22.patch
new file mode 100644
index 0000000..3e74480
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-22.patch
@@ -0,0 +1,259 @@
+commit 8e5a0afbbf0a96fb873e27aa064c9bacc9cfd9c6
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:12 2018 +0100
+
+    S390: Refactor strcat ifunc handling.
+    
+    The ifunc handling for strcat is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strcat variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strcat variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strcat.
+            * sysdeps/s390/multiarch/strcat-c.c: Move to ...
+            * sysdeps/s390/strcat-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strcat-vx.S: Move to ...
+            * sysdeps/s390/strcat-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strcat.c: Move to ...
+            * sysdeps/s390/strcat.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strcat.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index a9882b3996c30322..de2d5e5652dde412 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -42,5 +42,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strcpy strcpy-vx strcpy-z900 \
+ 		   stpcpy stpcpy-vx stpcpy-c \
+ 		   strncpy strncpy-vx strncpy-z900 \
+-		   stpncpy stpncpy-vx stpncpy-c
++		   stpncpy stpncpy-vx stpncpy-c \
++		   strcat strcat-vx strcat-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strcat.h b/sysdeps/s390/ifunc-strcat.h
+new file mode 100644
+index 0000000000000000..6fd2f7dd31fff64f
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strcat.h
+@@ -0,0 +1,52 @@
++/* strcat variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRCAT_IFUNC	1
++#else
++# define HAVE_STRCAT_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRCAT_IFUNC_AND_VX_SUPPORT HAVE_STRCAT_IFUNC
++#else
++# define HAVE_STRCAT_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRCAT_DEFAULT		STRCAT_Z13
++# define HAVE_STRCAT_C		0
++# define HAVE_STRCAT_Z13	1
++#else
++# define STRCAT_DEFAULT		STRCAT_C
++# define HAVE_STRCAT_C		1
++# define HAVE_STRCAT_Z13	HAVE_STRCAT_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRCAT_C
++# define STRCAT_C		__strcat_c
++#else
++# define STRCAT_C		NULL
++#endif
++
++#if HAVE_STRCAT_Z13
++# define STRCAT_Z13		__strcat_vx
++#else
++# define STRCAT_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 3d97d21da1fc852b..9b66237aaf9eb47e 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strcat strcat-vx strcat-c \
+-		   strncat strncat-vx strncat-c \
++sysdep_routines += strncat strncat-vx strncat-c \
+ 		   strcmp strcmp-vx \
+ 		   strncmp strncmp-vx strncmp-c \
+ 		   strchr strchr-vx strchr-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 021e9f247fff44df..1b7f3df3a3cfe561 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -32,6 +32,7 @@
+ #include <ifunc-stpcpy.h>
+ #include <ifunc-strncpy.h>
+ #include <ifunc-stpncpy.h>
++#include <ifunc-strcat.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -242,6 +243,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STPNCPY_IFUNC  */
+ 
++#if HAVE_STRCAT_IFUNC
++    IFUNC_IMPL (i, name, strcat,
++# if HAVE_STRCAT_Z13
++		IFUNC_IMPL_ADD (array, i, strcat,
++				dl_hwcap & HWCAP_S390_VX, STRCAT_Z13)
++# endif
++# if HAVE_STRCAT_C
++		IFUNC_IMPL_ADD (array, i, strcat, 1, STRCAT_C)
++# endif
++		)
++#endif /* HAVE_STRCAT_IFUNC  */
+ 
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+@@ -263,7 +275,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcpncpy);
+ 
+-  IFUNC_VX_IMPL (strcat);
+   IFUNC_VX_IMPL (wcscat);
+ 
+   IFUNC_VX_IMPL (strncat);
+diff --git a/sysdeps/s390/multiarch/strcat-c.c b/sysdeps/s390/strcat-c.c
+similarity index 73%
+rename from sysdeps/s390/multiarch/strcat-c.c
+rename to sysdeps/s390/strcat-c.c
+index f871faa7b563e74b..7accc6c7ef80ecf2 100644
+--- a/sysdeps/s390/multiarch/strcat-c.c
++++ b/sysdeps/s390/strcat-c.c
+@@ -16,13 +16,17 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRCAT  __strcat_c
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)				\
+-     __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c);
+-# endif /* SHARED */
++#include <ifunc-strcat.h>
++
++#if HAVE_STRCAT_C
++# if HAVE_STRCAT_IFUNC
++# define STRCAT STRCAT_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)		\
++  __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c);
++#  endif
++# endif
+ 
+ # include <string/strcat.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strcat-vx.S b/sysdeps/s390/strcat-vx.S
+similarity index 94%
+rename from sysdeps/s390/multiarch/strcat-vx.S
+rename to sysdeps/s390/strcat-vx.S
+index 3abbbcccedad0eb4..218e301f10c6abe3 100644
+--- a/sysdeps/s390/multiarch/strcat-vx.S
++++ b/sysdeps/s390/strcat-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strcat.h>
++#if HAVE_STRCAT_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +38,7 @@
+    -v17=index of zero
+    -v18=part of src
+ */
+-ENTRY(__strcat_vx)
++ENTRY(STRCAT_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -157,5 +158,13 @@ ENTRY(__strcat_vx)
+ 	vstl	%v16,%r5,0(%r2)	/* Copy characters including zero.  */
+ 	lgr	%r2,%r0		/* Load saved dest-ptr.  */
+ 	br	%r14
+-END(__strcat_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRCAT_Z13)
++
++# if ! HAVE_STRCAT_IFUNC
++strong_alias (STRCAT_Z13, strcat)
++# endif
++
++# if ! HAVE_STRCAT_C && defined SHARED && IS_IN (libc)
++strong_alias (STRCAT_Z13, __GI_strcat)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/strcat.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/strcat.c
+rename to sysdeps/s390/strcat.c
+index 7d4126b44f23679a..d378519c8af59620 100644
+--- a/sysdeps/s390/multiarch/strcat.c
++++ b/sysdeps/s390/strcat.c
+@@ -16,14 +16,25 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strcat.h>
++
++#if HAVE_STRCAT_IFUNC
+ # define strcat __redirect_strcat
+ # include <string.h>
+ # undef strcat
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat)
++# if HAVE_STRCAT_C
++extern __typeof (__redirect_strcat) STRCAT_C attribute_hidden;
++# endif
++
++# if HAVE_STRCAT_Z13
++extern __typeof (__redirect_strcat) STRCAT_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strcat.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_strcat, strcat,
++		      (HAVE_STRCAT_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRCAT_Z13
++		      : STRCAT_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-23.patch b/SOURCES/glibc-rh1659438-23.patch
new file mode 100644
index 0000000..46f3173
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-23.patch
@@ -0,0 +1,252 @@
+commit b935335155d65971fe2a54e32c0eb74303d4e4fc
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:12 2018 +0100
+
+    S390: Refactor strncat ifunc handling.
+    
+    The ifunc handling for strncat is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strncat variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strncat variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strncat.
+            * sysdeps/s390/multiarch/strncat-c.c: Move to ...
+            * sysdeps/s390/strncat-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strncat-vx.S: Move to ...
+            * sysdeps/s390/strncat-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strncat.c: Move to ...
+            * sysdeps/s390/strncat.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strncat.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index de2d5e5652dde412..cb5dc1d4f95fd11c 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -43,5 +43,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   stpcpy stpcpy-vx stpcpy-c \
+ 		   strncpy strncpy-vx strncpy-z900 \
+ 		   stpncpy stpncpy-vx stpncpy-c \
+-		   strcat strcat-vx strcat-c
++		   strcat strcat-vx strcat-c \
++		   strncat strncat-vx strncat-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strncat.h b/sysdeps/s390/ifunc-strncat.h
+new file mode 100644
+index 0000000000000000..bb164dcc32905b18
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strncat.h
+@@ -0,0 +1,52 @@
++/* strncat variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRNCAT_IFUNC	1
++#else
++# define HAVE_STRNCAT_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT HAVE_STRNCAT_IFUNC
++#else
++# define HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRNCAT_DEFAULT	STRNCAT_Z13
++# define HAVE_STRNCAT_C		0
++# define HAVE_STRNCAT_Z13	1
++#else
++# define STRNCAT_DEFAULT	STRNCAT_C
++# define HAVE_STRNCAT_C		1
++# define HAVE_STRNCAT_Z13	HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRNCAT_C
++# define STRNCAT_C		__strncat_c
++#else
++# define STRNCAT_C		NULL
++#endif
++
++#if HAVE_STRNCAT_Z13
++# define STRNCAT_Z13		__strncat_vx
++#else
++# define STRNCAT_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 9b66237aaf9eb47e..24be3eac5131fd4a 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strncat strncat-vx strncat-c \
+-		   strcmp strcmp-vx \
++sysdep_routines += strcmp strcmp-vx \
+ 		   strncmp strncmp-vx strncmp-c \
+ 		   strchr strchr-vx strchr-c \
+ 		   strchrnul strchrnul-vx strchrnul-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 1b7f3df3a3cfe561..3abcaf08e0ccd385 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -33,6 +33,7 @@
+ #include <ifunc-strncpy.h>
+ #include <ifunc-stpncpy.h>
+ #include <ifunc-strcat.h>
++#include <ifunc-strncat.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -255,6 +256,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRCAT_IFUNC  */
+ 
++#if HAVE_STRNCAT_IFUNC
++    IFUNC_IMPL (i, name, strncat,
++# if HAVE_STRNCAT_Z13
++		IFUNC_IMPL_ADD (array, i, strncat,
++				dl_hwcap & HWCAP_S390_VX, STRNCAT_Z13)
++# endif
++# if HAVE_STRNCAT_C
++		IFUNC_IMPL_ADD (array, i, strncat, 1, STRNCAT_C)
++# endif
++		)
++#endif /* HAVE_STRNCAT_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -277,7 +290,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcscat);
+ 
+-  IFUNC_VX_IMPL (strncat);
+   IFUNC_VX_IMPL (wcsncat);
+ 
+   IFUNC_VX_IMPL (strcmp);
+diff --git a/sysdeps/s390/multiarch/strncat-c.c b/sysdeps/s390/strncat-c.c
+similarity index 86%
+rename from sysdeps/s390/multiarch/strncat-c.c
+rename to sysdeps/s390/strncat-c.c
+index 9e6c245ccbbc2e23..86df89887c7b6293 100644
+--- a/sysdeps/s390/multiarch/strncat-c.c
++++ b/sysdeps/s390/strncat-c.c
+@@ -16,8 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRNCAT  __strncat_c
+-# define STRNCAT_PRIMARY
++#include <ifunc-strncat.h>
++
++#if HAVE_STRNCAT_C
++# if HAVE_STRNCAT_IFUNC
++#  define STRNCAT STRNCAT_C
++#  define STRNCAT_PRIMARY
++# endif
+ # include <string/strncat.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/strncat-vx.S b/sysdeps/s390/strncat-vx.S
+similarity index 94%
+rename from sysdeps/s390/multiarch/strncat-vx.S
+rename to sysdeps/s390/strncat-vx.S
+index e6584d0f438f0e38..76345e7dd702dd85 100644
+--- a/sysdeps/s390/multiarch/strncat-vx.S
++++ b/sysdeps/s390/strncat-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strncat.h>
++#if HAVE_STRNCAT_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -40,7 +41,7 @@
+    -v18=part of src
+    -v31=register save area for r6, r7
+ */
+-ENTRY(__strncat_vx)
++ENTRY(STRNCAT_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -235,5 +236,17 @@ ENTRY(__strncat_vx)
+ 
+ 	vl	%v16,0(%r5,%r3)	/* Load s.  */
+ 	j	.Lcpy_lt64
+-END(__strncat_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRNCAT_Z13)
++
++# if ! HAVE_STRNCAT_IFUNC
++strong_alias (STRNCAT_Z13, strncat)
++# endif
++
++# if ! HAVE_STRNCAT_C
++/* See string/strncat.c and define STRNCAT_PRIMARY.  */
++strong_alias (STRNCAT_Z13, __strncat)
++#  if defined SHARED && IS_IN (libc)
++strong_alias (__strncat, __GI___strncat)
++#  endif
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/strncat.c b/sysdeps/s390/strncat.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/strncat.c
+rename to sysdeps/s390/strncat.c
+index 94b8dffa85420cfa..b4b3656c5ae9c535 100644
+--- a/sysdeps/s390/multiarch/strncat.c
++++ b/sysdeps/s390/strncat.c
+@@ -16,12 +16,23 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strncat.h>
++
++#if HAVE_STRNCAT_IFUNC
+ # include <string.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2 (__strncat, strncat)
++# if HAVE_STRNCAT_C
++extern __typeof (__strncat) STRNCAT_C attribute_hidden;
++# endif
++
++# if HAVE_STRNCAT_Z13
++extern __typeof (__strncat) STRNCAT_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strncat.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__strncat, strncat,
++		      (HAVE_STRNCAT_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRNCAT_Z13
++		      : STRNCAT_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-24.patch b/SOURCES/glibc-rh1659438-24.patch
new file mode 100644
index 0000000..b0f4be8
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-24.patch
@@ -0,0 +1,394 @@
+commit cdab85fe33b0443a645509cbb5b929a0d3307f18
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:13 2018 +0100
+
+    S390: Refactor strcmp ifunc handling.
+    
+    The ifunc handling for strcmp is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    Note: The fallback s390-32/s390-64 ifunc variants with clst instruction
+    are now moved to the unified strcmp-z900.S file which can be used for
+    31/64bit. The s390-32/s390-64 files multiarch/strcmp.c and strcmp.S
+    are deleted.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strcmp variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strcmp variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strcmp.
+            * sysdeps/s390/multiarch/strcmp-vx.S: Move to ...
+            * sysdeps/s390/strcmp-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strcmp.c: Move to ...
+            * sysdeps/s390/strcmp.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strcmp.h: New file.
+            * sysdeps/s390/s390-64/strcmp.S: Move to ...
+            * sysdeps/s390/strcmp-z900.S: ... here and adjust to be usable
+            for 31/64bit and ifunc handling.
+            * sysdeps/s390/s390-32/multiarch/strcmp.c: Delete file.
+            * sysdeps/s390/s390-64/multiarch/strcmp.c: Likewise.
+            * sysdeps/s390/s390-32/strcmp.S: Likewise.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index cb5dc1d4f95fd11c..71a4658b43aeb745 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -44,5 +44,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strncpy strncpy-vx strncpy-z900 \
+ 		   stpncpy stpncpy-vx stpncpy-c \
+ 		   strcat strcat-vx strcat-c \
+-		   strncat strncat-vx strncat-c
++		   strncat strncat-vx strncat-c \
++		   strcmp strcmp-vx strcmp-z900
+ endif
+diff --git a/sysdeps/s390/ifunc-strcmp.h b/sysdeps/s390/ifunc-strcmp.h
+new file mode 100644
+index 0000000000000000..86ffe686ade52b64
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strcmp.h
+@@ -0,0 +1,52 @@
++/* strcmp variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRCMP_IFUNC	1
++#else
++# define HAVE_STRCMP_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRCMP_IFUNC_AND_VX_SUPPORT HAVE_STRCMP_IFUNC
++#else
++# define HAVE_STRCMP_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRCMP_DEFAULT		STRCMP_Z13
++# define HAVE_STRCMP_Z900_G5	0
++# define HAVE_STRCMP_Z13	1
++#else
++# define STRCMP_DEFAULT		STRCMP_Z900_G5
++# define HAVE_STRCMP_Z900_G5	1
++# define HAVE_STRCMP_Z13	HAVE_STRCMP_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRCMP_Z900_G5
++# define STRCMP_Z900_G5		__strcmp_default
++#else
++# define STRCMP_Z900_G5		NULL
++#endif
++
++#if HAVE_STRCMP_Z13
++# define STRCMP_Z13		__strcmp_vx
++#else
++# define STRCMP_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 24be3eac5131fd4a..97421a499625c7f2 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strcmp strcmp-vx \
+-		   strncmp strncmp-vx strncmp-c \
++sysdep_routines += strncmp strncmp-vx strncmp-c \
+ 		   strchr strchr-vx strchr-c \
+ 		   strchrnul strchrnul-vx strchrnul-c \
+ 		   strrchr strrchr-vx strrchr-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 3abcaf08e0ccd385..44637c431b144c66 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -34,6 +34,7 @@
+ #include <ifunc-stpncpy.h>
+ #include <ifunc-strcat.h>
+ #include <ifunc-strncat.h>
++#include <ifunc-strcmp.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -268,6 +269,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRNCAT_IFUNC  */
+ 
++#if HAVE_STRCMP_IFUNC
++    IFUNC_IMPL (i, name, strcmp,
++# if HAVE_STRCMP_Z13
++		IFUNC_IMPL_ADD (array, i, strcmp,
++				dl_hwcap & HWCAP_S390_VX, STRCMP_Z13)
++# endif
++# if HAVE_STRCMP_Z900_G5
++		IFUNC_IMPL_ADD (array, i, strcmp, 1, STRCMP_Z900_G5)
++# endif
++		)
++#endif /* HAVE_STRCMP_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -292,7 +305,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcsncat);
+ 
+-  IFUNC_VX_IMPL (strcmp);
+   IFUNC_VX_IMPL (wcscmp);
+ 
+   IFUNC_VX_IMPL (strncmp);
+diff --git a/sysdeps/s390/s390-32/multiarch/strcmp.c b/sysdeps/s390/s390-32/multiarch/strcmp.c
+deleted file mode 100644
+index d06b0f3436b2abfd..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/strcmp.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of strcmp.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/strcmp.S will be used.  */
+-#include <sysdeps/s390/multiarch/strcmp.c>
+diff --git a/sysdeps/s390/s390-32/strcmp.S b/sysdeps/s390/s390-32/strcmp.S
+deleted file mode 100644
+index 3cf3f239fddccce8..0000000000000000
+--- a/sysdeps/s390/s390-32/strcmp.S
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/* strcmp - compare two string.  S/390 version.
+-   This file is part of the GNU C Library.
+-   Copyright (C) 2001-2018 Free Software Foundation, Inc.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of string 1
+-     %r3 = address of string 2.  */
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-	.text
+-ENTRY(strcmp)
+-        slr   %r0,%r0
+-0:	clst  %r2,%r3
+-	jo    0b
+-	jp    1f
+-	jm    2f
+-	slr   %r2,%r2
+-	br    %r14
+-1:	lhi   %r2,1
+-	br    %r14
+-2:	lhi   %r2,-1
+-	br    %r14
+-END(strcmp)
+-libc_hidden_builtin_def (strcmp)
+diff --git a/sysdeps/s390/s390-64/multiarch/strcmp.c b/sysdeps/s390/s390-64/multiarch/strcmp.c
+deleted file mode 100644
+index d06b0f3436b2abfd..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/strcmp.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of strcmp.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/strcmp.S will be used.  */
+-#include <sysdeps/s390/multiarch/strcmp.c>
+diff --git a/sysdeps/s390/multiarch/strcmp-vx.S b/sysdeps/s390/strcmp-vx.S
+similarity index 90%
+rename from sysdeps/s390/multiarch/strcmp-vx.S
+rename to sysdeps/s390/strcmp-vx.S
+index bcaeb564d47c58ff..801ad9d32bbd76c0 100644
+--- a/sysdeps/s390/multiarch/strcmp-vx.S
++++ b/sysdeps/s390/strcmp-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strcmp.h>
++#if HAVE_STRCMP_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -36,7 +37,7 @@
+    -v17=part of s2
+    -v18=index of unequal
+ */
+-ENTRY(__strcmp_vx)
++ENTRY(STRCMP_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -106,11 +107,13 @@ ENTRY(__strcmp_vx)
+ .Lend_equal:
+ 	lghi	%r2,0
+ 	br	%r14
+-END(__strcmp_vx)
++END(STRCMP_Z13)
+ 
+-# define strcmp __strcmp_c
+-# undef libc_hidden_builtin_def
+-# define libc_hidden_builtin_def(name) strong_alias(__strcmp_c, __GI_strcmp)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++# if ! HAVE_STRCMP_IFUNC
++strong_alias (STRCMP_Z13, strcmp)
++# endif
+ 
+-#include <strcmp.S>
++# if ! HAVE_STRCMP_Z900_G5 && defined SHARED && IS_IN (libc)
++strong_alias (STRCMP_Z13, __GI_strcmp)
++# endif
++#endif
+diff --git a/sysdeps/s390/s390-64/strcmp.S b/sysdeps/s390/strcmp-z900.S
+similarity index 70%
+rename from sysdeps/s390/s390-64/strcmp.S
+rename to sysdeps/s390/strcmp-z900.S
+index 6cf1addd8bdf1a19..67b3c8b2e5989cd2 100644
+--- a/sysdeps/s390/s390-64/strcmp.S
++++ b/sysdeps/s390/strcmp-z900.S
+@@ -21,21 +21,39 @@
+      %r2 = address of string 1
+      %r3 = address of string 2.  */
+ 
++#include <ifunc-strcmp.h>
+ #include "sysdep.h"
+ #include "asm-syntax.h"
+ 
++#if HAVE_STRCMP_Z900_G5
++# if defined __s390x__
++#  define SLGR	slgr
++#  define LGHI	lghi
++# else
++#  define SLGR	slr
++#  define LGHI	lhi
++# endif /* ! defined __s390x__  */
++
+ 	.text
+-ENTRY(strcmp)
+-        slr   %r0,%r0
++ENTRY(STRCMP_Z900_G5)
++	SLGR   %r0,%r0
+ 0:	clst  %r2,%r3
+ 	jo    0b
+ 	jp    1f
+ 	jm    2f
+-	slgr  %r2,%r2
++	SLGR  %r2,%r2
+ 	br    %r14
+-1:	lghi  %r2,1
++1:	LGHI  %r2,1
+ 	br    %r14
+-2:	lghi  %r2,-1
++2:	LGHI  %r2,-1
+ 	br    %r14
+-END(strcmp)
+-libc_hidden_builtin_def (strcmp)
++END(STRCMP_Z900_G5)
++
++# if ! HAVE_STRCMP_IFUNC
++strong_alias (STRCMP_Z900_G5, strcmp)
++# endif
++
++# if defined SHARED && IS_IN (libc)
++strong_alias (STRCMP_Z900_G5, __GI_strcmp)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/strcmp.c
+similarity index 71%
+rename from sysdeps/s390/multiarch/strcmp.c
+rename to sysdeps/s390/strcmp.c
+index 7c8b17b3041dd549..9efa30acaf21f4e8 100644
+--- a/sysdeps/s390/multiarch/strcmp.c
++++ b/sysdeps/s390/strcmp.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strcmp.h>
++
++#if HAVE_STRCMP_IFUNC
+ # define strcmp __redirect_strcmp
+ /* Omit the strcmp inline definitions because it would redefine strcmp.  */
+ # define __NO_STRING_INLINES
+@@ -24,6 +26,17 @@
+ # include <ifunc-resolve.h>
+ # undef strcmp
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strcmp, __strcmp, strcmp)
++# if HAVE_STRCMP_Z900_G5
++extern __typeof (__redirect_strcmp) STRCMP_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_STRCMP_Z13
++extern __typeof (__redirect_strcmp) STRCMP_Z13 attribute_hidden;
++# endif
+ 
++s390_libc_ifunc_expr (__redirect_strcmp, strcmp,
++		      (HAVE_STRCMP_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRCMP_Z13
++		      : STRCMP_DEFAULT
++		      )
+ #endif
diff --git a/SOURCES/glibc-rh1659438-25.patch b/SOURCES/glibc-rh1659438-25.patch
new file mode 100644
index 0000000..afe7ad0
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-25.patch
@@ -0,0 +1,263 @@
+commit 316b88421993d540513a6b25b59ec16df267e9b4
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:13 2018 +0100
+
+    S390: Refactor strncmp ifunc handling.
+    
+    The ifunc handling for strncmp is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strncmp variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strncmp variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strncmp.
+            * sysdeps/s390/multiarch/strncmp-c.c: Move to ...
+            * sysdeps/s390/strncmp-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strncmp-vx.S: Move to ...
+            * sysdeps/s390/strncmp-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strncmp.c: Move to ...
+            * sysdeps/s390/strncmp.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strncmp.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 71a4658b43aeb745..adf3521876725ac8 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -45,5 +45,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   stpncpy stpncpy-vx stpncpy-c \
+ 		   strcat strcat-vx strcat-c \
+ 		   strncat strncat-vx strncat-c \
+-		   strcmp strcmp-vx strcmp-z900
++		   strcmp strcmp-vx strcmp-z900 \
++		   strncmp strncmp-vx strncmp-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strncmp.h b/sysdeps/s390/ifunc-strncmp.h
+new file mode 100644
+index 0000000000000000..511b3e9720520a0c
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strncmp.h
+@@ -0,0 +1,52 @@
++/* strncmp variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRNCMP_IFUNC	1
++#else
++# define HAVE_STRNCMP_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT HAVE_STRNCMP_IFUNC
++#else
++# define HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRNCMP_DEFAULT	STRNCMP_Z13
++# define HAVE_STRNCMP_C		0
++# define HAVE_STRNCMP_Z13	1
++#else
++# define STRNCMP_DEFAULT	STRNCMP_C
++# define HAVE_STRNCMP_C		1
++# define HAVE_STRNCMP_Z13	HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRNCMP_C
++# define STRNCMP_C		__strncmp_c
++#else
++# define STRNCMP_C		NULL
++#endif
++
++#if HAVE_STRNCMP_Z13
++# define STRNCMP_Z13		__strncmp_vx
++#else
++# define STRNCMP_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 97421a499625c7f2..381376bf9fcb0f58 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strncmp strncmp-vx strncmp-c \
+-		   strchr strchr-vx strchr-c \
++sysdep_routines += strchr strchr-vx strchr-c \
+ 		   strchrnul strchrnul-vx strchrnul-c \
+ 		   strrchr strrchr-vx strrchr-c \
+ 		   strspn strspn-vx strspn-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 44637c431b144c66..d982de5788c0b5d5 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -35,6 +35,7 @@
+ #include <ifunc-strcat.h>
+ #include <ifunc-strncat.h>
+ #include <ifunc-strcmp.h>
++#include <ifunc-strncmp.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -281,6 +282,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRCMP_IFUNC  */
+ 
++#if HAVE_STRNCMP_IFUNC
++    IFUNC_IMPL (i, name, strncmp,
++# if HAVE_STRNCMP_Z13
++		IFUNC_IMPL_ADD (array, i, strncmp,
++				dl_hwcap & HWCAP_S390_VX, STRNCMP_Z13)
++# endif
++# if HAVE_STRNCMP_C
++		IFUNC_IMPL_ADD (array, i, strncmp, 1, STRNCMP_C)
++# endif
++		)
++#endif /* HAVE_STRNCMP_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -307,7 +320,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcscmp);
+ 
+-  IFUNC_VX_IMPL (strncmp);
+   IFUNC_VX_IMPL (wcsncmp);
+ 
+   IFUNC_VX_IMPL (strchr);
+diff --git a/sysdeps/s390/multiarch/strncmp-c.c b/sysdeps/s390/strncmp-c.c
+similarity index 78%
+rename from sysdeps/s390/multiarch/strncmp-c.c
+rename to sysdeps/s390/strncmp-c.c
+index e54277ec1b10f8d7..c7ffdb03e37dc8d8 100644
+--- a/sysdeps/s390/multiarch/strncmp-c.c
++++ b/sysdeps/s390/strncmp-c.c
+@@ -16,13 +16,17 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRNCMP  __strncmp_c
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)			\
++#include <ifunc-strncmp.h>
++
++#if HAVE_STRNCMP_C
++# if HAVE_STRNCMP_IFUNC
++#  define STRNCMP STRNCMP_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
+   __hidden_ver1 (__strncmp_c, __GI_strncmp, __strncmp_c);
+-# endif /* SHARED */
++#  endif
++# endif
+ 
+ # include <string/strncmp.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strncmp-vx.S b/sysdeps/s390/strncmp-vx.S
+similarity index 93%
+rename from sysdeps/s390/multiarch/strncmp-vx.S
+rename to sysdeps/s390/strncmp-vx.S
+index 168fd657da2a1173..f557afb336d418ff 100644
+--- a/sysdeps/s390/multiarch/strncmp-vx.S
++++ b/sysdeps/s390/strncmp-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strncmp.h>
++
++#if HAVE_STRNCMP_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +39,7 @@
+    -v17=part of s2
+    -v18=index of unequal
+ */
+-ENTRY(__strncmp_vx)
++ENTRY(STRNCMP_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -133,5 +135,14 @@ ENTRY(__strncmp_vx)
+ .Lend_equal:
+ 	lghi	%r2,0
+ 	br	%r14
+-END(__strncmp_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRNCMP_Z13)
++
++# if ! HAVE_STRNCMP_IFUNC
++strong_alias (STRNCMP_Z13, strncmp)
++# endif
++
++# if ! HAVE_STRNCMP_C && defined SHARED && IS_IN (libc)
++strong_alias (STRNCMP_Z13, __GI_strncmp)
++# endif
++
++#endif /* HAVE_STRNCMP_Z13  */
+diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/strncmp.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/strncmp.c
+rename to sysdeps/s390/strncmp.c
+index 0ec472c3b03419a3..71351273c4058129 100644
+--- a/sysdeps/s390/multiarch/strncmp.c
++++ b/sysdeps/s390/strncmp.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strncmp.h>
++
++#if HAVE_STRNCMP_IFUNC
+ # define strncmp __redirect_strncmp
+ /* Omit the strncmp inline definitions because it would redefine strncmp.  */
+ # define __NO_STRING_INLINES
+@@ -24,8 +26,17 @@
+ # undef strncmp
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp)
++# if HAVE_STRNCMP_C
++extern __typeof (__redirect_strncmp) STRNCMP_C attribute_hidden;
++# endif
++
++# if HAVE_STRNCMP_Z13
++extern __typeof (__redirect_strncmp) STRNCMP_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strncmp.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_strncmp, strncmp,
++		      (HAVE_STRNCMP_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRNCMP_Z13
++		      : STRNCMP_DEFAULT
++		      )
++#endif /* HAVE_STRNCMP_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-26.patch b/SOURCES/glibc-rh1659438-26.patch
new file mode 100644
index 0000000..65995ca
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-26.patch
@@ -0,0 +1,268 @@
+commit 32f12653d4ea2fbff409351bf8067f9a0b4a3963
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:14 2018 +0100
+
+    S390: Refactor strchr ifunc handling.
+    
+    The ifunc handling for strchr is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strchr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strchr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strchr.
+            * sysdeps/s390/multiarch/strchr-c.c: Move to ...
+            * sysdeps/s390/strchr-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strchr-vx.S: Move to ...
+            * sysdeps/s390/strchr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strchr.c: Move to ...
+            * sysdeps/s390/strchr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strchr.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index adf3521876725ac8..8bb396f498e0b0b0 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -46,5 +46,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strcat strcat-vx strcat-c \
+ 		   strncat strncat-vx strncat-c \
+ 		   strcmp strcmp-vx strcmp-z900 \
+-		   strncmp strncmp-vx strncmp-c
++		   strncmp strncmp-vx strncmp-c \
++		   strchr strchr-vx strchr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strchr.h b/sysdeps/s390/ifunc-strchr.h
+new file mode 100644
+index 0000000000000000..cfeb00eeda890512
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strchr.h
+@@ -0,0 +1,52 @@
++/* strchr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRCHR_IFUNC	1
++#else
++# define HAVE_STRCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRCHR_IFUNC_AND_VX_SUPPORT HAVE_STRCHR_IFUNC
++#else
++# define HAVE_STRCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRCHR_DEFAULT		STRCHR_Z13
++# define HAVE_STRCHR_C		0
++# define HAVE_STRCHR_Z13	1
++#else
++# define STRCHR_DEFAULT		STRCHR_C
++# define HAVE_STRCHR_C		1
++# define HAVE_STRCHR_Z13	HAVE_STRCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRCHR_C
++# define STRCHR_C		__strchr_c
++#else
++# define STRCHR_C		NULL
++#endif
++
++#if HAVE_STRCHR_Z13
++# define STRCHR_Z13		__strchr_vx
++#else
++# define STRCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 381376bf9fcb0f58..a8e9d0acd9ebf986 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strchr strchr-vx strchr-c \
+-		   strchrnul strchrnul-vx strchrnul-c \
++sysdep_routines += strchrnul strchrnul-vx strchrnul-c \
+ 		   strrchr strrchr-vx strrchr-c \
+ 		   strspn strspn-vx strspn-c \
+ 		   strpbrk strpbrk-vx strpbrk-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index d982de5788c0b5d5..e809ca3bacb18aa9 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -36,6 +36,7 @@
+ #include <ifunc-strncat.h>
+ #include <ifunc-strcmp.h>
+ #include <ifunc-strncmp.h>
++#include <ifunc-strchr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -294,6 +295,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRNCMP_IFUNC  */
+ 
++#if HAVE_STRCHR_IFUNC
++    IFUNC_IMPL (i, name, strchr,
++# if HAVE_STRCHR_Z13
++		IFUNC_IMPL_ADD (array, i, strchr,
++				dl_hwcap & HWCAP_S390_VX, STRCHR_Z13)
++# endif
++# if HAVE_STRCHR_C
++		IFUNC_IMPL_ADD (array, i, strchr, 1, STRCHR_C)
++# endif
++		)
++#endif /* HAVE_STRCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -322,7 +335,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcsncmp);
+ 
+-  IFUNC_VX_IMPL (strchr);
+   IFUNC_VX_IMPL (wcschr);
+ 
+   IFUNC_VX_IMPL (strchrnul);
+diff --git a/sysdeps/s390/multiarch/strchr-c.c b/sysdeps/s390/strchr-c.c
+similarity index 77%
+rename from sysdeps/s390/multiarch/strchr-c.c
+rename to sysdeps/s390/strchr-c.c
+index 606cb56788966153..3d3579a1d3bc06d0 100644
+--- a/sysdeps/s390/multiarch/strchr-c.c
++++ b/sysdeps/s390/strchr-c.c
+@@ -16,14 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRCHR  __strchr_c
+-# undef weak_alias
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)				\
++#include <ifunc-strchr.h>
++
++#if HAVE_STRCHR_C
++# if HAVE_STRCHR_IFUNC
++#  define STRCHR STRCHR_C
++#  undef weak_alias
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
+      __hidden_ver1 (__strchr_c, __GI_strchr, __strchr_c);
+-# endif /* SHARED */
++#  endif
++# endif
+ 
+ # include <string/strchr.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strchr-vx.S b/sysdeps/s390/strchr-vx.S
+similarity index 90%
+rename from sysdeps/s390/multiarch/strchr-vx.S
+rename to sysdeps/s390/strchr-vx.S
+index 6e744fb82f3249a6..6ffa06f78c14c8da 100644
+--- a/sysdeps/s390/multiarch/strchr-vx.S
++++ b/sysdeps/s390/strchr-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strchr.h>
++
++#if HAVE_STRCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -36,7 +38,7 @@
+    -v17=index of unequal
+    -v18=replicated c
+ */
+-ENTRY(__strchr_vx)
++ENTRY(STRCHR_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -96,5 +98,15 @@ ENTRY(__strchr_vx)
+ 	clije	%r3,0,.Lcharacter /* Found zero and c is zero.  */
+ 	lghi	%r2,0		/* Return null if character not found.  */
+ 	br	%r14
+-END(__strchr_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRCHR_Z13)
++
++# if ! HAVE_STRCHR_IFUNC
++strong_alias (STRCHR_Z13, strchr)
++weak_alias (strchr, index)
++# endif
++
++# if ! HAVE_STRCHR_C && defined SHARED && IS_IN (libc)
++strong_alias (STRCHR_Z13, __GI_strchr)
++# endif
++
++#endif /* HAVE_STRCHR_Z13  */
+diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/strchr.c
+similarity index 71%
+rename from sysdeps/s390/multiarch/strchr.c
+rename to sysdeps/s390/strchr.c
+index 8aa33a51cc7e91de..a106c6106dcd5307 100644
+--- a/sysdeps/s390/multiarch/strchr.c
++++ b/sysdeps/s390/strchr.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strchr.h>
++
++#if HAVE_STRCHR_IFUNC
+ # define strchr __redirect_strchr
+ /* Omit the strchr inline definitions because it would redefine strchr.  */
+ # define __NO_STRING_INLINES
+@@ -24,9 +26,18 @@
+ # undef strchr
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strchr, __strchr, strchr)
+-weak_alias (strchr, index)
++# if HAVE_STRCHR_C
++extern __typeof (__redirect_strchr) STRCHR_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strchr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_STRCHR_Z13
++extern __typeof (__redirect_strchr) STRCHR_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect_strchr, strchr,
++		      (HAVE_STRCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRCHR_Z13
++		      : STRCHR_DEFAULT
++		      )
++weak_alias (strchr, index)
++#endif /* HAVE_STRCHR_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-27.patch b/SOURCES/glibc-rh1659438-27.patch
new file mode 100644
index 0000000..9fb75a4
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-27.patch
@@ -0,0 +1,253 @@
+commit a1361e65617c660a3ba7d561e081dcd18762a688
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:14 2018 +0100
+
+    S390: Refactor strchrnul ifunc handling.
+    
+    The ifunc handling for strchrnul is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strchrnul variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strchrnul variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strchrnul.
+            * sysdeps/s390/multiarch/strchrnul-c.c: Move to ...
+            * sysdeps/s390/strchrnul-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strchrnul-vx.S: Move to ...
+            * sysdeps/s390/strchrnul-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strchrnul.c: Move to ...
+            * sysdeps/s390/strchrnul.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strchrnul.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 8bb396f498e0b0b0..c54bb82f4d4f8a67 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -47,5 +47,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strncat strncat-vx strncat-c \
+ 		   strcmp strcmp-vx strcmp-z900 \
+ 		   strncmp strncmp-vx strncmp-c \
+-		   strchr strchr-vx strchr-c
++		   strchr strchr-vx strchr-c \
++		   strchrnul strchrnul-vx strchrnul-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strchrnul.h b/sysdeps/s390/ifunc-strchrnul.h
+new file mode 100644
+index 0000000000000000..cac817e6f0a9406d
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strchrnul.h
+@@ -0,0 +1,52 @@
++/* strchrnul variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRCHRNUL_IFUNC	1
++#else
++# define HAVE_STRCHRNUL_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT HAVE_STRCHRNUL_IFUNC
++#else
++# define HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRCHRNUL_DEFAULT	STRCHRNUL_Z13
++# define HAVE_STRCHRNUL_C	0
++# define HAVE_STRCHRNUL_Z13	1
++#else
++# define STRCHRNUL_DEFAULT	STRCHRNUL_C
++# define HAVE_STRCHRNUL_C	1
++# define HAVE_STRCHRNUL_Z13	HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRCHRNUL_C
++# define STRCHRNUL_C		__strchrnul_c
++#else
++# define STRCHRNUL_C		NULL
++#endif
++
++#if HAVE_STRCHRNUL_Z13
++# define STRCHRNUL_Z13		__strchrnul_vx
++#else
++# define STRCHRNUL_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index a8e9d0acd9ebf986..999a979fee1417b2 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strchrnul strchrnul-vx strchrnul-c \
+-		   strrchr strrchr-vx strrchr-c \
++sysdep_routines += strrchr strrchr-vx strrchr-c \
+ 		   strspn strspn-vx strspn-c \
+ 		   strpbrk strpbrk-vx strpbrk-c \
+ 		   strcspn strcspn-vx strcspn-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index e809ca3bacb18aa9..0a47ffeac3492b3e 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -37,6 +37,7 @@
+ #include <ifunc-strcmp.h>
+ #include <ifunc-strncmp.h>
+ #include <ifunc-strchr.h>
++#include <ifunc-strchrnul.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -307,6 +308,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRCHR_IFUNC  */
+ 
++#if HAVE_STRCHRNUL_IFUNC
++    IFUNC_IMPL (i, name, strchrnul,
++# if HAVE_STRCHRNUL_Z13
++		IFUNC_IMPL_ADD (array, i, strchrnul,
++				dl_hwcap & HWCAP_S390_VX, STRCHRNUL_Z13)
++# endif
++# if HAVE_STRCHRNUL_C
++		IFUNC_IMPL_ADD (array, i, strchrnul, 1, STRCHRNUL_C)
++# endif
++		)
++#endif /* HAVE_STRCHRNUL_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -337,7 +350,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcschr);
+ 
+-  IFUNC_VX_IMPL (strchrnul);
+   IFUNC_VX_IMPL (wcschrnul);
+ 
+   IFUNC_VX_IMPL (strrchr);
+diff --git a/sysdeps/s390/multiarch/strchrnul-c.c b/sysdeps/s390/strchrnul-c.c
+similarity index 81%
+rename from sysdeps/s390/multiarch/strchrnul-c.c
+rename to sysdeps/s390/strchrnul-c.c
+index 020cebcf3e275b07..585273f5de8b82bc 100644
+--- a/sysdeps/s390/multiarch/strchrnul-c.c
++++ b/sysdeps/s390/strchrnul-c.c
+@@ -16,11 +16,15 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRCHRNUL  __strchrnul_c
+-# define __strchrnul STRCHRNUL
+-# undef weak_alias
+-# define weak_alias(name, alias)
++#include <ifunc-strchrnul.h>
++
++#if HAVE_STRCHRNUL_C
++# if HAVE_STRCHRNUL_IFUNC
++#  define STRCHRNUL STRCHRNUL_C
++#  define __strchrnul STRCHRNUL
++#  undef weak_alias
++#  define weak_alias(name, alias)
++# endif
+ 
+ # include <string/strchrnul.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/strchrnul-vx.S b/sysdeps/s390/strchrnul-vx.S
+similarity index 91%
+rename from sysdeps/s390/multiarch/strchrnul-vx.S
+rename to sysdeps/s390/strchrnul-vx.S
+index d561825e0432458c..0cd587bc32cf811f 100644
+--- a/sysdeps/s390/multiarch/strchrnul-vx.S
++++ b/sysdeps/s390/strchrnul-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strchrnul.h>
++
++#if HAVE_STRCHRNUL_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -35,7 +37,7 @@
+    -v16=part of s
+    -v18=vector with c replicated in every byte
+ */
+-ENTRY(__strchrnul_vx)
++ENTRY(STRCHRNUL_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -89,5 +91,11 @@ ENTRY(__strchrnul_vx)
+ 
+ .Lend:
+ 	br	%r14
+-END(__strchrnul_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRCHRNUL_Z13)
++
++# if ! HAVE_STRCHRNUL_IFUNC
++strong_alias (STRCHRNUL_Z13, __strchrnul)
++weak_alias (__strchrnul, strchrnul)
++# endif
++
++#endif /* HAVE_STRCHRNUL_Z13  */
+diff --git a/sysdeps/s390/multiarch/strchrnul.c b/sysdeps/s390/strchrnul.c
+similarity index 67%
+rename from sysdeps/s390/multiarch/strchrnul.c
+rename to sysdeps/s390/strchrnul.c
+index 62dfc6bd90638b60..e9fefe1bdc77f038 100644
+--- a/sysdeps/s390/multiarch/strchrnul.c
++++ b/sysdeps/s390/strchrnul.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strchrnul.h>
++
++#if HAVE_STRCHRNUL_IFUNC
+ # include <string.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__strchrnul)
+-weak_alias (__strchrnul, strchrnul)
++# if HAVE_STRCHRNUL_C
++extern __typeof (__strchrnul) STRCHRNUL_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strchrnul.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_STRCHRNUL_Z13
++extern __typeof (__strchrnul) STRCHRNUL_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__strchrnul, __strchrnul,
++		      (HAVE_STRCHRNUL_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRCHRNUL_Z13
++		      : STRCHRNUL_DEFAULT
++		      )
++weak_alias (__strchrnul, strchrnul)
++#endif /* HAVE_STRCHRNUL_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-28.patch b/SOURCES/glibc-rh1659438-28.patch
new file mode 100644
index 0000000..2e29a54
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-28.patch
@@ -0,0 +1,266 @@
+commit 26ea8760877cf03272e98c21eb1a7745ceca76c4
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:14 2018 +0100
+
+    S390: Refactor strrchr ifunc handling.
+    
+    The ifunc handling for strrchr is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strrchr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strrchr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strrchr.
+            * sysdeps/s390/multiarch/strrchr-c.c: Move to ...
+            * sysdeps/s390/strrchr-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strrchr-vx.S: Move to ...
+            * sysdeps/s390/strrchr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strrchr.c: Move to ...
+            * sysdeps/s390/strrchr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strrchr.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index c54bb82f4d4f8a67..3ad44c997e9f1f6b 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -48,5 +48,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strcmp strcmp-vx strcmp-z900 \
+ 		   strncmp strncmp-vx strncmp-c \
+ 		   strchr strchr-vx strchr-c \
+-		   strchrnul strchrnul-vx strchrnul-c
++		   strchrnul strchrnul-vx strchrnul-c \
++		   strrchr strrchr-vx strrchr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strrchr.h b/sysdeps/s390/ifunc-strrchr.h
+new file mode 100644
+index 0000000000000000..7185fc32601f7388
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strrchr.h
+@@ -0,0 +1,52 @@
++/* strrchr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRRCHR_IFUNC	1
++#else
++# define HAVE_STRRCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT HAVE_STRRCHR_IFUNC
++#else
++# define HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRRCHR_DEFAULT	STRRCHR_Z13
++# define HAVE_STRRCHR_C		0
++# define HAVE_STRRCHR_Z13	1
++#else
++# define STRRCHR_DEFAULT	STRRCHR_C
++# define HAVE_STRRCHR_C		1
++# define HAVE_STRRCHR_Z13	HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRRCHR_C
++# define STRRCHR_C		__strrchr_c
++#else
++# define STRRCHR_C		NULL
++#endif
++
++#if HAVE_STRRCHR_Z13
++# define STRRCHR_Z13		__strrchr_vx
++#else
++# define STRRCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 999a979fee1417b2..c8267555585b617e 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strrchr strrchr-vx strrchr-c \
+-		   strspn strspn-vx strspn-c \
++sysdep_routines += strspn strspn-vx strspn-c \
+ 		   strpbrk strpbrk-vx strpbrk-c \
+ 		   strcspn strcspn-vx strcspn-c \
+ 		   memchr memchr-vx \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 0a47ffeac3492b3e..60cd705ffa4e2c35 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -38,6 +38,7 @@
+ #include <ifunc-strncmp.h>
+ #include <ifunc-strchr.h>
+ #include <ifunc-strchrnul.h>
++#include <ifunc-strrchr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -320,6 +321,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRCHRNUL_IFUNC  */
+ 
++#if HAVE_STRRCHR_IFUNC
++    IFUNC_IMPL (i, name, strrchr,
++# if HAVE_STRRCHR_Z13
++		IFUNC_IMPL_ADD (array, i, strrchr,
++				dl_hwcap & HWCAP_S390_VX, STRRCHR_Z13)
++# endif
++# if HAVE_STRRCHR_C
++		IFUNC_IMPL_ADD (array, i, strrchr, 1, STRRCHR_C)
++# endif
++		)
++#endif /* HAVE_STRRCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -352,7 +365,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcschrnul);
+ 
+-  IFUNC_VX_IMPL (strrchr);
+   IFUNC_VX_IMPL (wcsrchr);
+ 
+   IFUNC_VX_IMPL (strspn);
+diff --git a/sysdeps/s390/multiarch/strrchr-c.c b/sysdeps/s390/strrchr-c.c
+similarity index 77%
+rename from sysdeps/s390/multiarch/strrchr-c.c
+rename to sysdeps/s390/strrchr-c.c
+index 53ceb8086f0711c8..615f16da7d9db5ef 100644
+--- a/sysdeps/s390/multiarch/strrchr-c.c
++++ b/sysdeps/s390/strrchr-c.c
+@@ -16,14 +16,18 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRRCHR  __strrchr_c
+-# undef weak_alias
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)				\
++#include <ifunc-strrchr.h>
++
++#if HAVE_STRRCHR_C
++# if HAVE_STRRCHR_IFUNC
++#  define STRRCHR STRRCHR_C
++#  undef weak_alias
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
+      __hidden_ver1 (__strrchr_c, __GI_strrchr, __strrchr_c);
+-# endif /* SHARED */
++#  endif
++# endif
+ 
+ # include <string/strrchr.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strrchr-vx.S b/sysdeps/s390/strrchr-vx.S
+similarity index 94%
+rename from sysdeps/s390/multiarch/strrchr-vx.S
+rename to sysdeps/s390/strrchr-vx.S
+index 8b3b989631f23de5..5f4ac14ee338c790 100644
+--- a/sysdeps/s390/multiarch/strrchr-vx.S
++++ b/sysdeps/s390/strrchr-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strrchr.h>
++
++#if HAVE_STRRCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -39,7 +41,7 @@
+    -v19=part of s with last occurence of c.
+    -v20=permute pattern
+ */
+-ENTRY(__strrchr_vx)
++ENTRY(STRRCHR_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -176,5 +178,15 @@ ENTRY(__strrchr_vx)
+ .Lpermute_mask:
+ 	.byte	0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08
+ 	.byte	0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
+-END(__strrchr_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRRCHR_Z13)
++
++# if ! HAVE_STRRCHR_IFUNC
++strong_alias (STRRCHR_Z13, strrchr)
++weak_alias (strrchr, rindex)
++# endif
++
++# if ! HAVE_STRRCHR_C && defined SHARED && IS_IN (libc)
++strong_alias (STRRCHR_Z13, __GI_strrchr)
++# endif
++
++#endif /* HAVE_STRRCHR_Z13  */
+diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/strrchr.c
+similarity index 66%
+rename from sysdeps/s390/multiarch/strrchr.c
+rename to sysdeps/s390/strrchr.c
+index e00e25a3a4f51b1e..9a8cecff0b29c057 100644
+--- a/sysdeps/s390/multiarch/strrchr.c
++++ b/sysdeps/s390/strrchr.c
+@@ -16,15 +16,26 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strrchr.h>
++
++#if HAVE_STRRCHR_IFUNC
+ # define strrchr __redirect_strrchr
+ # include <string.h>
+ # undef strrchr
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr)
+-weak_alias (strrchr, rindex);
++# if HAVE_STRRCHR_C
++extern __typeof (__redirect_strrchr) STRRCHR_C attribute_hidden;
++# endif
++
++# if HAVE_STRRCHR_Z13
++extern __typeof (__redirect_strrchr) STRRCHR_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strrchr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_strrchr, strrchr,
++		      (HAVE_STRRCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRRCHR_Z13
++		      : STRRCHR_DEFAULT
++		      )
++weak_alias (strrchr, rindex)
++#endif /* HAVE_STRRCHR_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-29.patch b/SOURCES/glibc-rh1659438-29.patch
new file mode 100644
index 0000000..edb4940
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-29.patch
@@ -0,0 +1,263 @@
+commit 483fc56978d11c7118326f92ea678bea2f092300
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:15 2018 +0100
+
+    S390: Refactor strspn ifunc handling.
+    
+    The ifunc handling for strspn is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strspn variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strspn variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strspn.
+            * sysdeps/s390/multiarch/strspn-c.c: Move to ...
+            * sysdeps/s390/strspn-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strspn-vx.S: Move to ...
+            * sysdeps/s390/strspn-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strspn.c: Move to ...
+            * sysdeps/s390/strspn.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strspn.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 3ad44c997e9f1f6b..c0a402117197b87f 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -49,5 +49,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strncmp strncmp-vx strncmp-c \
+ 		   strchr strchr-vx strchr-c \
+ 		   strchrnul strchrnul-vx strchrnul-c \
+-		   strrchr strrchr-vx strrchr-c
++		   strrchr strrchr-vx strrchr-c \
++		   strspn strspn-vx strspn-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strspn.h b/sysdeps/s390/ifunc-strspn.h
+new file mode 100644
+index 0000000000000000..1152ba1f3d3b9b62
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strspn.h
+@@ -0,0 +1,52 @@
++/* strspn variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRSPN_IFUNC	1
++#else
++# define HAVE_STRSPN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRSPN_IFUNC_AND_VX_SUPPORT HAVE_STRSPN_IFUNC
++#else
++# define HAVE_STRSPN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRSPN_DEFAULT		STRSPN_Z13
++# define HAVE_STRSPN_C		0
++# define HAVE_STRSPN_Z13	1
++#else
++# define STRSPN_DEFAULT		STRSPN_C
++# define HAVE_STRSPN_C		1
++# define HAVE_STRSPN_Z13	HAVE_STRSPN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRSPN_C
++# define STRSPN_C		__strspn_c
++#else
++# define STRSPN_C		NULL
++#endif
++
++#if HAVE_STRSPN_Z13
++# define STRSPN_Z13		__strspn_vx
++#else
++# define STRSPN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index c8267555585b617e..9b141e338ca551ec 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strspn strspn-vx strspn-c \
+-		   strpbrk strpbrk-vx strpbrk-c \
++sysdep_routines += strpbrk strpbrk-vx strpbrk-c \
+ 		   strcspn strcspn-vx strcspn-c \
+ 		   memchr memchr-vx \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 60cd705ffa4e2c35..c39e1f793aad530c 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -39,6 +39,7 @@
+ #include <ifunc-strchr.h>
+ #include <ifunc-strchrnul.h>
+ #include <ifunc-strrchr.h>
++#include <ifunc-strspn.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -333,6 +334,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRRCHR_IFUNC  */
+ 
++#if HAVE_STRSPN_IFUNC
++    IFUNC_IMPL (i, name, strspn,
++# if HAVE_STRSPN_Z13
++		IFUNC_IMPL_ADD (array, i, strspn,
++				dl_hwcap & HWCAP_S390_VX, STRSPN_Z13)
++# endif
++# if HAVE_STRSPN_C
++		IFUNC_IMPL_ADD (array, i, strspn, 1, STRSPN_C)
++# endif
++		)
++#endif /* HAVE_STRSPN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -367,7 +380,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcsrchr);
+ 
+-  IFUNC_VX_IMPL (strspn);
+   IFUNC_VX_IMPL (wcsspn);
+ 
+   IFUNC_VX_IMPL (strpbrk);
+diff --git a/sysdeps/s390/multiarch/strspn-c.c b/sysdeps/s390/strspn-c.c
+similarity index 78%
+rename from sysdeps/s390/multiarch/strspn-c.c
+rename to sysdeps/s390/strspn-c.c
+index 0efe61bfb2f89caf..506f6683212f03ab 100644
+--- a/sysdeps/s390/multiarch/strspn-c.c
++++ b/sysdeps/s390/strspn-c.c
+@@ -16,13 +16,17 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRSPN  __strspn_c
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)				\
++#include <ifunc-strspn.h>
++
++#if HAVE_STRSPN_C
++# if HAVE_STRSPN_IFUNC
++#  define STRSPN STRSPN_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
+      __hidden_ver1 (__strspn_c, __GI_strspn, __strspn_c);
+-# endif /* SHARED */
++#  endif
++# endif
+ 
+ # include <string/strspn.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strspn-vx.S b/sysdeps/s390/strspn-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/strspn-vx.S
+rename to sysdeps/s390/strspn-vx.S
+index 6aa823e63b1189c3..ae5529b567ee7435 100644
+--- a/sysdeps/s390/multiarch/strspn-vx.S
++++ b/sysdeps/s390/strspn-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strspn.h>
++
++#if HAVE_STRSPN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -57,7 +59,7 @@
+ 	otherwise =0;
+    r9: loaded byte count of vlbb accept-string
+ */
+-ENTRY(__strspn_vx)
++ENTRY(STRSPN_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -252,5 +254,14 @@ ENTRY(__strspn_vx)
+ 				   Check for zero is in jump-target.  */
+ 	j	.Lslow_next_acc_notonbb /* ... and search for zero in
+ 					    fully loaded vreg again.  */
+-END(__strspn_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRSPN_Z13)
++
++# if ! HAVE_STRSPN_IFUNC
++strong_alias (STRSPN_Z13, strspn)
++# endif
++
++# if ! HAVE_STRSPN_C && defined SHARED && IS_IN (libc)
++strong_alias (STRSPN_Z13, __GI_strspn)
++# endif
++
++#endif /* HAVE_STRSPN_Z13  */
+diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/strspn.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/strspn.c
+rename to sysdeps/s390/strspn.c
+index bedbe98cfc4ab14d..91401fdaf89ed8a2 100644
+--- a/sysdeps/s390/multiarch/strspn.c
++++ b/sysdeps/s390/strspn.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strspn.h>
++
++#if HAVE_STRSPN_IFUNC
+ # define strspn __redirect_strspn
+ /* Omit the strspn inline definitions because it would redefine strspn.  */
+ # define __NO_STRING_INLINES
+@@ -24,8 +26,17 @@
+ # undef strspn
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strspn, __strspn, strspn)
++# if HAVE_STRSPN_C
++extern __typeof (__redirect_strspn) STRSPN_C attribute_hidden;
++# endif
++
++# if HAVE_STRSPN_Z13
++extern __typeof (__redirect_strspn) STRSPN_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strspn.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_strspn, strspn,
++		      (HAVE_STRSPN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRSPN_Z13
++		      : STRSPN_DEFAULT
++		      )
++#endif /* HAVE_STRSPN_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-3.patch b/SOURCES/glibc-rh1659438-3.patch
new file mode 100644
index 0000000..161448c
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-3.patch
@@ -0,0 +1,440 @@
+commit 5f1743d118047ff1fbefe713f2397090e0418deb
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:04 2018 +0100
+
+    S390: Unify 31/64bit memset.
+    
+    The implementation of memset for s390-32 (31bit) and
+    s390-64 (64bit) is nearly the same.
+    This patch unifies it for maintability reasons.
+    
+    __memset_z10 and __memset_z196 differs between 31 and 64bit:
+    -31bit needs .machinemode "zarch_nohighgprs" and llgfr   %r4,%r4
+    -lr vs lgr and some other instructions:
+    But lgr and co can be also used on 31bit as this ifunc variant
+    is only called if we are on a zarch machine.
+    
+    __memset_default differs between 31 and 64bit:
+    -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr.
+    Solved with 31/64 specific instruction macros).
+    -The address of mvc instruction is setup in different ways
+    (larl vs bras). Solved with #if defined __s390x__.
+    
+    Otherwise 31/64bit implementation has the same structure of the code.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/s390-64/memset.S: Move to ...
+            * sysdeps/s390/memset.S: ... here.
+            Adjust to be usable for 31/64bit.
+            * sysdeps/s390/s390-32/memset.S: Delete File.
+            * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memset.
+            * sysdeps/s390/s390-32/multiarch/Makefile (sysdep_routines):
+            Remove memset.
+            * sysdeps/s390/s390-64/multiarch/Makefile: Likewise.
+            * sysdeps/s390/s390-64/multiarch/memset-s390x.S: Move to ...
+            * sysdeps/s390/multiarch/memset-s390x.S: ... here.
+            Adjust to be usable for 31/64bit.
+            * sysdeps/s390/s390-32/multiarch/memset-s390.S: Delete File.
+            * sysdeps/s390/s390-64/multiarch/memset.c: Move to ...
+            * sysdeps/s390/multiarch/memset.c: ... here.
+            * sysdeps/s390/s390-32/multiarch/memset.c: Delete File.
+
+diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/memset.S
+similarity index 58%
+rename from sysdeps/s390/s390-64/memset.S
+rename to sysdeps/s390/memset.S
+index 8799c6592ce2dacf..72e7c5a42efbaf6c 100644
+--- a/sysdeps/s390/s390-64/memset.S
++++ b/sysdeps/s390/memset.S
+@@ -1,4 +1,4 @@
+-/* Set a block of memory to some byte value.  64 bit S/390 version.
++/* Set a block of memory to some byte value.  31/64 bit S/390 version.
+    Copyright (C) 2001-2018 Free Software Foundation, Inc.
+    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+    This file is part of the GNU C Library.
+@@ -28,33 +28,60 @@
+ 
+        .text
+ 
++#if defined __s390x__
++# define LTGR	ltgr
++# define CGHI	cghi
++# define LGR	lgr
++# define AGHI	aghi
++# define BRCTG	brctg
++#else
++# define LTGR	ltr
++# define CGHI	chi
++# define LGR	lr
++# define AGHI	ahi
++# define BRCTG	brct
++#endif /* ! defined __s390x__  */
++
+ #ifdef USE_MULTIARCH
+ ENTRY(__memset_default)
+ #else
+ ENTRY(memset)
+ #endif
++#if defined __s390x__
+ 	.machine "z900"
+-	ltgr    %r4,%r4
+-	je      .L_Z900_4
++#else
++	.machine "g5"
++#endif /* ! defined __s390x__  */
++	LTGR    %r4,%r4
++	je      .L_Z900_G5_4
+ 	stc     %r3,0(%r2)
+-	cghi    %r4,1
+-	lgr     %r1,%r2
+-	je      .L_Z900_4
+-	aghi    %r4,-2
++	CGHI    %r4,1
++	LGR     %r1,%r2
++	je      .L_Z900_G5_4
++	AGHI    %r4,-2
++#if defined __s390x__
++	larl    %r5,.L_Z900_G5_18
+ 	srlg    %r3,%r4,8
+-	ltgr    %r3,%r3
+-	jne     .L_Z900_14
+-.L_Z900_3:
+-	larl    %r3,.L_Z900_18
+-	ex      %r4,0(%r3)
+-.L_Z900_4:
++# define Z900_G5_EX_D 0
++#else
++	basr    %r5,0
++.L_Z900_G5_19:
++# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19
++	lr      %r3,%r4
++	srl     %r3,8
++#endif /* ! defined __s390x__  */
++	LTGR    %r3,%r3
++	jne     .L_Z900_G5_14
++.L_Z900_G5_3:
++	ex      %r4,Z900_G5_EX_D(%r5)
++.L_Z900_G5_4:
+ 	br      %r14
+-.L_Z900_14:
++.L_Z900_G5_14:
+ 	mvc     1(256,%r1),0(%r1)
+ 	la      %r1,256(%r1)
+-	brctg   %r3,.L_Z900_14
+-	j       .L_Z900_3
+-.L_Z900_18:
++	BRCTG   %r3,.L_Z900_G5_14
++	j       .L_Z900_G5_3
++.L_Z900_G5_18:
+ 	mvc     1(1,%r1),0(%r1)
+ #ifdef USE_MULTIARCH
+ END(__memset_default)
+@@ -62,3 +89,9 @@ END(__memset_default)
+ END(memset)
+ libc_hidden_builtin_def (memset)
+ #endif
++
++#undef LTGR
++#undef CGHI
++#undef LGR
++#undef AGHI
++#undef BRCTG
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index c893ebc5659fd4ae..93ad21bfa2686ee5 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -19,7 +19,8 @@ sysdep_routines += strlen strlen-vx strlen-c \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c \
+-		   mempcpy
++		   mempcpy \
++		   memset memset-s390x
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+diff --git a/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/sysdeps/s390/multiarch/memset-s390x.S
+similarity index 90%
+rename from sysdeps/s390/s390-64/multiarch/memset-s390x.S
+rename to sysdeps/s390/multiarch/memset-s390x.S
+index 0c5aaef34fdf47e6..aca3ac3fda1dd228 100644
+--- a/sysdeps/s390/s390-64/multiarch/memset-s390x.S
++++ b/sysdeps/s390/multiarch/memset-s390x.S
+@@ -1,4 +1,4 @@
+-/* Set a block of memory to some byte value.  64 bit S/390 version.
++/* Set a block of memory to some byte value.  31/64 bit S/390 version.
+    Copyright (C) 2012-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -31,6 +31,10 @@
+ 
+ ENTRY(__memset_z196)
+ 	.machine "z196"
++	.machinemode "zarch_nohighgprs"
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
+ 	ltgr    %r4,%r4
+ 	je      .L_Z196_4
+ 	stc     %r3,0(%r2)
+@@ -61,6 +65,10 @@ END(__memset_z196)
+ 
+ ENTRY(__memset_z10)
+ 	.machine "z10"
++	.machinemode "zarch_nohighgprs"
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
+ 	cgije   %r4,0,.L_Z10_4
+ 	stc     %r3,0(%r2)
+ 	lgr     %r1,%r2
+diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/multiarch/memset.c
+similarity index 100%
+rename from sysdeps/s390/s390-32/multiarch/memset.c
+rename to sysdeps/s390/multiarch/memset.c
+diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S
+deleted file mode 100644
+index 57f08e1cae1abd01..0000000000000000
+--- a/sysdeps/s390/s390-32/memset.S
++++ /dev/null
+@@ -1,65 +0,0 @@
+-/* Set a block of memory to some byte value.  For IBM S390
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = address to memory area
+-     %r3 = byte to fill memory with
+-     %r4 = number of bytes to fill.  */
+-
+-       .text
+-
+-#ifdef USE_MULTIARCH
+-ENTRY(__memset_default)
+-#else
+-ENTRY(memset)
+-#endif
+-	.machine "g5"
+-	basr    %r5,0
+-.L_G5_19:
+-	ltr     %r4,%r4
+-	je      .L_G5_4
+-	stc     %r3,0(%r2)
+-	chi     %r4,1
+-	lr      %r1,%r2
+-	je      .L_G5_4
+-	ahi     %r4,-2
+-	lr      %r3,%r4
+-	srl     %r3,8
+-	ltr     %r3,%r3
+-	jne     .L_G5_14
+-	ex      %r4,.L_G5_20-.L_G5_19(%r5)
+-.L_G5_4:
+-	br      %r14
+-.L_G5_14:
+-	mvc     1(256,%r1),0(%r1)
+-	la      %r1,256(%r1)
+-	brct    %r3,.L_G5_14
+-	ex      %r4,.L_G5_20-.L_G5_19(%r5)
+-	j       .L_G5_4
+-.L_G5_20:
+-	mvc     1(1,%r1),0(%r1)
+-#ifdef USE_MULTIARCH
+-END(__memset_default)
+-#else
+-END(memset)
+-libc_hidden_builtin_def (memset)
+-#endif
+diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile
+index f8aee14bbd4736ad..4b11e28656ac19ab 100644
+--- a/sysdeps/s390/s390-32/multiarch/Makefile
++++ b/sysdeps/s390/s390-32/multiarch/Makefile
+@@ -1,4 +1,3 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += memset memset-s390 memcpy memcpy-s390 \
+-		   memcmp memcmp-s390
++sysdep_routines += memcpy memcpy-s390 memcmp memcmp-s390
+ endif
+diff --git a/sysdeps/s390/s390-32/multiarch/memset-s390.S b/sysdeps/s390/s390-32/multiarch/memset-s390.S
+deleted file mode 100644
+index b092073d6bef6b56..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/memset-s390.S
++++ /dev/null
+@@ -1,116 +0,0 @@
+-/* Set a block of memory to some byte value.  32 bit S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of memory area
+-     %r3 = byte to fill memory with
+-     %r4 = number of bytes to fill.  */
+-
+-       .text
+-
+-#if IS_IN (libc)
+-
+-ENTRY(__memset_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-	llgfr   %r4,%r4
+-	ltgr    %r4,%r4
+-	je      .L_Z196_4
+-	stc     %r3,0(%r2)
+-	lr      %r1,%r2
+-	cghi    %r4,1
+-	je      .L_Z196_4
+-	aghi    %r4,-2
+-	srlg    %r5,%r4,8
+-	ltgr    %r5,%r5
+-	jne     .L_Z196_1
+-.L_Z196_3:
+-	exrl    %r4,.L_Z196_17
+-.L_Z196_4:
+-	br      %r14
+-.L_Z196_1:
+-	cgfi	%r5,1048576
+-	jh	__memset_mvcle	   # Switch to mvcle for >256MB
+-.L_Z196_2:
+-	pfd     2,1024(%r1)
+-	mvc     1(256,%r1),0(%r1)
+-	aghi    %r5,-1
+-	la      %r1,256(%r1)
+-	jne     .L_Z196_2
+-	j       .L_Z196_3
+-.L_Z196_17:
+-	mvc     1(1,%r1),0(%r1)
+-END(__memset_z196)
+-
+-ENTRY(__memset_z10)
+-	.machine "z10"
+-	.machinemode "zarch_nohighgprs"
+-	llgfr   %r4,%r4
+-	cgije   %r4,0,.L_Z10_4
+-	stc     %r3,0(%r2)
+-	lr      %r1,%r2
+-	cgije   %r4,1,.L_Z10_4
+-	aghi    %r4,-2
+-	srlg    %r5,%r4,8
+-	cgijlh  %r5,0,.L_Z10_15
+-.L_Z10_3:
+-	exrl    %r4,.L_Z10_18
+-.L_Z10_4:
+-	br      %r14
+-.L_Z10_15:
+-	cgfi	%r5,163840          # Switch to mvcle for >40MB
+-	jh	__memset_mvcle
+-.L_Z10_14:
+-	pfd     2,1024(%r1)
+-	mvc     1(256,%r1),0(%r1)
+-	la      %r1,256(%r1)
+-	brctg   %r5,.L_Z10_14
+-	j       .L_Z10_3
+-.L_Z10_18:
+-	mvc     1(1,%r1),0(%r1)
+-END(__memset_z10)
+-
+-ENTRY(__memset_mvcle)
+-	ahi	%r4,2               # take back the change done by the caller
+-	lr      %r0,%r2             # save source address
+-	lr      %r1,%r3             # move pad byte to R1
+-	lr      %r3,%r4
+-	sr      %r4,%r4             # no source for MVCLE, only a pad byte
+-	sr      %r5,%r5
+-.L0:    mvcle   %r2,%r4,0(%r1)      # thats it, MVCLE is your friend
+-	jo      .L0
+-	lr      %r2,%r0             # return value is source address
+-.L1:
+-	br      %r14
+-END(__memset_mvcle)
+-
+-#endif /* IS_IN (libc) */
+-
+-#include "../memset.S"
+-
+-#if !IS_IN (libc)
+-.globl   memset
+-.set     memset,__memset_default
+-#elif defined SHARED && IS_IN (libc)
+-.globl   __GI_memset
+-.set     __GI_memset,__memset_default
+-#endif
+diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile
+index 91053b536420aabb..e4870c7ee177ad0d 100644
+--- a/sysdeps/s390/s390-64/multiarch/Makefile
++++ b/sysdeps/s390/s390-64/multiarch/Makefile
+@@ -1,4 +1,3 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += memset memset-s390x memcpy memcpy-s390x \
+-		   memcmp memcmp-s390x
++sysdep_routines += memcpy memcpy-s390x memcmp memcmp-s390x
+ endif
+diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c
+deleted file mode 100644
+index 760b3e9df201b8b4..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/memset.c
++++ /dev/null
+@@ -1,26 +0,0 @@
+-/* Multiple versions of memset.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-#if IS_IN (libc)
+-# define memset __redirect_memset
+-# include <string.h>
+-# undef memset
+-# include <ifunc-resolve.h>
+-
+-s390_libc_ifunc (__redirect_memset, __memset, memset)
+-#endif
diff --git a/SOURCES/glibc-rh1659438-30.patch b/SOURCES/glibc-rh1659438-30.patch
new file mode 100644
index 0000000..9e7db8e
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-30.patch
@@ -0,0 +1,264 @@
+commit 572cca93fafa59d641c11372a9556722d95b038c
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:15 2018 +0100
+
+    S390: Refactor strpbrk ifunc handling.
+    
+    The ifunc handling for strpbrk is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strpbrk variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strpbrk variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strpbrk.
+            * sysdeps/s390/multiarch/strpbrk-c.c: Move to ...
+            * sysdeps/s390/strpbrk-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strpbrk-vx.S: Move to ...
+            * sysdeps/s390/strpbrk-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strpbrk.c: Move to ...
+            * sysdeps/s390/strpbrk.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strpbrk.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index c0a402117197b87f..a21fa7507b1d64a1 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -50,5 +50,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strchr strchr-vx strchr-c \
+ 		   strchrnul strchrnul-vx strchrnul-c \
+ 		   strrchr strrchr-vx strrchr-c \
+-		   strspn strspn-vx strspn-c
++		   strspn strspn-vx strspn-c \
++		   strpbrk strpbrk-vx strpbrk-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strpbrk.h b/sysdeps/s390/ifunc-strpbrk.h
+new file mode 100644
+index 0000000000000000..4a3138c6bf377286
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strpbrk.h
+@@ -0,0 +1,52 @@
++/* strpbrk variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRPBRK_IFUNC	1
++#else
++# define HAVE_STRPBRK_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT HAVE_STRPBRK_IFUNC
++#else
++# define HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRPBRK_DEFAULT	STRPBRK_Z13
++# define HAVE_STRPBRK_C		0
++# define HAVE_STRPBRK_Z13	1
++#else
++# define STRPBRK_DEFAULT	STRPBRK_C
++# define HAVE_STRPBRK_C		1
++# define HAVE_STRPBRK_Z13	HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRPBRK_C
++# define STRPBRK_C		__strpbrk_c
++#else
++# define STRPBRK_C		NULL
++#endif
++
++#if HAVE_STRPBRK_Z13
++# define STRPBRK_Z13		__strpbrk_vx
++#else
++# define STRPBRK_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 9b141e338ca551ec..1a3fed9fc88012d1 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strpbrk strpbrk-vx strpbrk-c \
+-		   strcspn strcspn-vx strcspn-c \
++sysdep_routines += strcspn strcspn-vx strcspn-c \
+ 		   memchr memchr-vx \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index c39e1f793aad530c..8e23416730f8a8d5 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -40,6 +40,7 @@
+ #include <ifunc-strchrnul.h>
+ #include <ifunc-strrchr.h>
+ #include <ifunc-strspn.h>
++#include <ifunc-strpbrk.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -346,6 +347,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRSPN_IFUNC  */
+ 
++#if HAVE_STRPBRK_IFUNC
++    IFUNC_IMPL (i, name, strpbrk,
++# if HAVE_STRPBRK_Z13
++		IFUNC_IMPL_ADD (array, i, strpbrk,
++				dl_hwcap & HWCAP_S390_VX, STRPBRK_Z13)
++# endif
++# if HAVE_STRPBRK_C
++		IFUNC_IMPL_ADD (array, i, strpbrk, 1, STRPBRK_C)
++# endif
++		)
++#endif /* HAVE_STRPBRK_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -382,7 +395,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcsspn);
+ 
+-  IFUNC_VX_IMPL (strpbrk);
+   IFUNC_VX_IMPL (wcspbrk);
+ 
+   IFUNC_VX_IMPL (strcspn);
+diff --git a/sysdeps/s390/multiarch/strpbrk-c.c b/sysdeps/s390/strpbrk-c.c
+similarity index 73%
+rename from sysdeps/s390/multiarch/strpbrk-c.c
+rename to sysdeps/s390/strpbrk-c.c
+index 2c0517aeb52985b3..70cc5db672adb6c9 100644
+--- a/sysdeps/s390/multiarch/strpbrk-c.c
++++ b/sysdeps/s390/strpbrk-c.c
+@@ -16,13 +16,17 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRPBRK  __strpbrk_c
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)				\
+-     __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c);
+-# endif /* SHARED */
++#include <ifunc-strpbrk.h>
++
++#if HAVE_STRPBRK_C
++# if HAVE_STRPBRK_IFUNC
++#  define STRPBRK STRPBRK_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
++  __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c);
++#  endif
++# endif
+ 
+ # include <string/strpbrk.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strpbrk-vx.S b/sysdeps/s390/strpbrk-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/strpbrk-vx.S
+rename to sysdeps/s390/strpbrk-vx.S
+index e19c550ed404a9a8..0fc7dc143337779f 100644
+--- a/sysdeps/s390/multiarch/strpbrk-vx.S
++++ b/sysdeps/s390/strpbrk-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strpbrk.h>
++
++#if HAVE_STRPBRK_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -59,7 +61,7 @@
+ 	otherwise =0;
+    r9:  loaded byte count of vlbb accept-string
+ */
+-ENTRY(__strpbrk_vx)
++ENTRY(STRPBRK_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -298,5 +300,14 @@ ENTRY(__strpbrk_vx)
+ 	vlgvg	%r9,%v31,1
+ 	lgr	%r2,%r1
+ 	br	%r14
+-END(__strpbrk_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRPBRK_Z13)
++
++# if ! HAVE_STRPBRK_IFUNC
++strong_alias (STRPBRK_Z13, strpbrk)
++# endif
++
++# if ! HAVE_STRPBRK_C && defined SHARED && IS_IN (libc)
++strong_alias (STRPBRK_Z13, __GI_strpbrk)
++# endif
++
++#endif /* HAVE_STRPBRK_Z13  */
+diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/strpbrk.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/strpbrk.c
+rename to sysdeps/s390/strpbrk.c
+index 11afc268f702ce09..41ce00a1aedf0020 100644
+--- a/sysdeps/s390/multiarch/strpbrk.c
++++ b/sysdeps/s390/strpbrk.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strpbrk.h>
++
++#if HAVE_STRPBRK_IFUNC
+ # define strpbrk __redirect_strpbrk
+ /* Omit the strpbrk inline definitions because it would redefine strpbrk.  */
+ # define __NO_STRING_INLINES
+@@ -24,8 +26,17 @@
+ # undef strpbrk
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strpbrk, __strpbrk, strpbrk)
++# if HAVE_STRPBRK_C
++extern __typeof (__redirect_strpbrk) STRPBRK_C attribute_hidden;
++# endif
++
++# if HAVE_STRPBRK_Z13
++extern __typeof (__redirect_strpbrk) STRPBRK_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strpbrk.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_strpbrk, strpbrk,
++		      (HAVE_STRPBRK_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRPBRK_Z13
++		      : STRPBRK_DEFAULT
++		      )
++#endif /* HAVE_STRPBRK_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-31.patch b/SOURCES/glibc-rh1659438-31.patch
new file mode 100644
index 0000000..e448fc9
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-31.patch
@@ -0,0 +1,264 @@
+commit 5d2ec20a997b87c1667e0e71b3ff1e9df96eac15
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:15 2018 +0100
+
+    S390: Refactor strcspn ifunc handling.
+    
+    The ifunc handling for strcspn is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove strcspn variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add strcspn variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for strcspn.
+            * sysdeps/s390/multiarch/strcspn-c.c: Move to ...
+            * sysdeps/s390/strcspn-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strcspn-vx.S: Move to ...
+            * sysdeps/s390/strcspn-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/strcspn.c: Move to ...
+            * sysdeps/s390/strcspn.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-strcspn.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index a21fa7507b1d64a1..092d55826fbd15a5 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -51,5 +51,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strchrnul strchrnul-vx strchrnul-c \
+ 		   strrchr strrchr-vx strrchr-c \
+ 		   strspn strspn-vx strspn-c \
+-		   strpbrk strpbrk-vx strpbrk-c
++		   strpbrk strpbrk-vx strpbrk-c \
++		   strcspn strcspn-vx strcspn-c
+ endif
+diff --git a/sysdeps/s390/ifunc-strcspn.h b/sysdeps/s390/ifunc-strcspn.h
+new file mode 100644
+index 0000000000000000..9b7032509a2fb9a8
+--- /dev/null
++++ b/sysdeps/s390/ifunc-strcspn.h
+@@ -0,0 +1,52 @@
++/* strcspn variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_STRCSPN_IFUNC	1
++#else
++# define HAVE_STRCSPN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT HAVE_STRCSPN_IFUNC
++#else
++# define HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define STRCSPN_DEFAULT	STRCSPN_Z13
++# define HAVE_STRCSPN_C		0
++# define HAVE_STRCSPN_Z13	1
++#else
++# define STRCSPN_DEFAULT	STRCSPN_C
++# define HAVE_STRCSPN_C		1
++# define HAVE_STRCSPN_Z13	HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_STRCSPN_C
++# define STRCSPN_C		__strcspn_c
++#else
++# define STRCSPN_C		NULL
++#endif
++
++#if HAVE_STRCSPN_Z13
++# define STRCSPN_Z13		__strcspn_vx
++#else
++# define STRCSPN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 1a3fed9fc88012d1..1578f21af4a1bd06 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += strcspn strcspn-vx strcspn-c \
+-		   memchr memchr-vx \
++sysdep_routines += memchr memchr-vx \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 8e23416730f8a8d5..2d48c99c8d5663fe 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -41,6 +41,7 @@
+ #include <ifunc-strrchr.h>
+ #include <ifunc-strspn.h>
+ #include <ifunc-strpbrk.h>
++#include <ifunc-strcspn.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -359,6 +360,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRPBRK_IFUNC  */
+ 
++#if HAVE_STRCSPN_IFUNC
++    IFUNC_IMPL (i, name, strcspn,
++# if HAVE_STRCSPN_Z13
++		IFUNC_IMPL_ADD (array, i, strcspn,
++				dl_hwcap & HWCAP_S390_VX, STRCSPN_Z13)
++# endif
++# if HAVE_STRCSPN_C
++		IFUNC_IMPL_ADD (array, i, strcspn, 1, STRCSPN_C)
++# endif
++		)
++#endif /* HAVE_STRCSPN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -397,7 +410,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcspbrk);
+ 
+-  IFUNC_VX_IMPL (strcspn);
+   IFUNC_VX_IMPL (wcscspn);
+ 
+   IFUNC_VX_IMPL (memchr);
+diff --git a/sysdeps/s390/multiarch/strcspn-c.c b/sysdeps/s390/strcspn-c.c
+similarity index 73%
+rename from sysdeps/s390/multiarch/strcspn-c.c
+rename to sysdeps/s390/strcspn-c.c
+index 7b454f5b56077abc..9f51f92bdbd49a67 100644
+--- a/sysdeps/s390/multiarch/strcspn-c.c
++++ b/sysdeps/s390/strcspn-c.c
+@@ -16,13 +16,17 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define STRCSPN  __strcspn_c
+-# ifdef SHARED
+-#  undef libc_hidden_builtin_def
+-#  define libc_hidden_builtin_def(name)				\
+-     __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c);
+-# endif /* SHARED */
++#include <ifunc-strcspn.h>
++
++#if HAVE_STRCSPN_C
++# if HAVE_STRCSPN_IFUNC
++#  define STRCSPN STRCSPN_C
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_builtin_def
++#   define libc_hidden_builtin_def(name)			\
++  __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c);
++#  endif
++# endif
+ 
+ # include <string/strcspn.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/strcspn-vx.S b/sysdeps/s390/strcspn-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/strcspn-vx.S
+rename to sysdeps/s390/strcspn-vx.S
+index ea1668742bd1c7ff..ff5b1be549e6e210 100644
+--- a/sysdeps/s390/multiarch/strcspn-vx.S
++++ b/sysdeps/s390/strcspn-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strcspn.h>
++
++#if HAVE_STRCSPN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -58,7 +60,7 @@
+ 			otherwise =0;
+    r9:  loaded byte count of vlbb reject-string
+ */
+-ENTRY(__strcspn_vx)
++ENTRY(STRCSPN_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -277,5 +279,14 @@ ENTRY(__strcspn_vx)
+ 	vlgvg	%r8,%v31,0
+ 	vlgvg	%r9,%v31,1
+ 	br	%r14
+-END(__strcspn_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(STRCSPN_Z13)
++
++# if ! HAVE_STRCSPN_IFUNC
++strong_alias (STRCSPN_Z13, strcspn)
++# endif
++
++# if ! HAVE_STRCSPN_C && defined SHARED && IS_IN (libc)
++strong_alias (STRCSPN_Z13, __GI_strcspn)
++# endif
++
++#endif /* HAVE_STRCSPN_Z13  */
+diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/strcspn.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/strcspn.c
+rename to sysdeps/s390/strcspn.c
+index 418ffcdded76fe50..a3f35d39c50dd5e5 100644
+--- a/sysdeps/s390/multiarch/strcspn.c
++++ b/sysdeps/s390/strcspn.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-strcspn.h>
++
++#if HAVE_STRCSPN_IFUNC
+ # define strcspn __redirect_strcspn
+ /* Omit the strcspn inline definitions because it would redefine strcspn.  */
+ # define __NO_STRING_INLINES
+@@ -24,8 +26,17 @@
+ # undef strcspn
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_strcspn, __strcspn, strcspn)
++# if HAVE_STRCSPN_C
++extern __typeof (__redirect_strcspn) STRCSPN_C attribute_hidden;
++# endif
++
++# if HAVE_STRCSPN_Z13
++extern __typeof (__redirect_strcspn) STRCSPN_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/strcspn.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_strcspn, strcspn,
++		      (HAVE_STRCSPN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? STRCSPN_Z13
++		      : STRCSPN_DEFAULT
++		      )
++#endif /* HAVE_STRCSPN_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-32.patch b/SOURCES/glibc-rh1659438-32.patch
new file mode 100644
index 0000000..85327b9
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-32.patch
@@ -0,0 +1,403 @@
+commit 581a051c2e09a847332d4750f6132de0f0ad15b6
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:16 2018 +0100
+
+    S390: Refactor memchr ifunc handling.
+    
+    The ifunc handling for memchr is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    Note: The fallback s390-32/s390-64 ifunc variants with srst instruction
+    are now moved to the unified memchr-z900.S file which can be used for
+    31/64bit. The s390-32/s390-64 files multiarch/memchr.c and memchr.S
+    are deleted.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove memchr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add memchr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for memchr.
+            * sysdeps/s390/multiarch/memchr-vx.S: Move to ...
+            * sysdeps/s390/memchr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/memchr.c: Move to ...
+            * sysdeps/s390/memchr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-memchr.h: New file.
+            * sysdeps/s390/s390-64/memchr.S: Move to ...
+            * sysdeps/s390/memchr-z900.S: ... here and adjust to be usable
+            for 31/64bit and ifunc handling.
+            * sysdeps/s390/s390-32/multiarch/memchr.c: Delete file.
+            * sysdeps/s390/s390-64/multiarch/memchr.c: Likewise.
+            * sysdeps/s390/s390-32/memchr.S: Likewise.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 092d55826fbd15a5..816b2fccdc75e4cf 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -52,5 +52,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strrchr strrchr-vx strrchr-c \
+ 		   strspn strspn-vx strspn-c \
+ 		   strpbrk strpbrk-vx strpbrk-c \
+-		   strcspn strcspn-vx strcspn-c
++		   strcspn strcspn-vx strcspn-c \
++		   memchr memchr-vx memchr-z900
+ endif
+diff --git a/sysdeps/s390/ifunc-memchr.h b/sysdeps/s390/ifunc-memchr.h
+new file mode 100644
+index 0000000000000000..5d1327b45353322b
+--- /dev/null
++++ b/sysdeps/s390/ifunc-memchr.h
+@@ -0,0 +1,52 @@
++/* memchr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_MEMCHR_IFUNC	1
++#else
++# define HAVE_MEMCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT HAVE_MEMCHR_IFUNC
++#else
++# define HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define MEMCHR_DEFAULT		MEMCHR_Z13
++# define HAVE_MEMCHR_Z900_G5	0
++# define HAVE_MEMCHR_Z13	1
++#else
++# define MEMCHR_DEFAULT		MEMCHR_Z900_G5
++# define HAVE_MEMCHR_Z900_G5	1
++# define HAVE_MEMCHR_Z13	HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_MEMCHR_Z900_G5
++# define MEMCHR_Z900_G5		__memchr_default
++#else
++# define MEMCHR_Z900_G5		NULL
++#endif
++
++#if HAVE_MEMCHR_Z13
++# define MEMCHR_Z13		__memchr_vx
++#else
++# define MEMCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/memchr-vx.S b/sysdeps/s390/memchr-vx.S
+similarity index 92%
+rename from sysdeps/s390/multiarch/memchr-vx.S
+rename to sysdeps/s390/memchr-vx.S
+index 77d31e0036915665..274e7971ca7e9413 100644
+--- a/sysdeps/s390/multiarch/memchr-vx.S
++++ b/sysdeps/s390/memchr-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-memchr.h>
++#if HAVE_MEMCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -38,7 +39,7 @@
+    -v17=index of found c
+    -v18=c replicated
+ */
+-ENTRY(__memchr_vx)
++ENTRY(MEMCHR_Z13)
+ 
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+@@ -149,11 +150,14 @@ ENTRY(__memchr_vx)
+ 	clgrjl	%r0,%r4,.Lloop64
+ 
+ 	j	.Llt64
+-END(__memchr_vx)
++END(MEMCHR_Z13)
+ 
+-# define memchr __memchr_c
+-# undef libc_hidden_builtin_def
+-# define libc_hidden_builtin_def(name) strong_alias(__memchr_c, __GI_memchr)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++# if ! HAVE_MEMCHR_IFUNC
++strong_alias (MEMCHR_Z13, __memchr)
++weak_alias (__memchr, memchr)
++# endif
+ 
+-#include <memchr.S>
++# if ! HAVE_MEMCHR_Z900_G5 && defined SHARED && IS_IN (libc)
++strong_alias (MEMCHR_Z13, __GI_memchr)
++# endif
++#endif
+diff --git a/sysdeps/s390/s390-64/memchr.S b/sysdeps/s390/memchr-z900.S
+similarity index 63%
+rename from sysdeps/s390/s390-64/memchr.S
+rename to sysdeps/s390/memchr-z900.S
+index a19fcafa147dc338..c016bc41c61be2dc 100644
+--- a/sysdeps/s390/s390-64/memchr.S
++++ b/sysdeps/s390/memchr-z900.S
+@@ -1,4 +1,4 @@
+-/* Search a character in a block of memory.  64 bit S/390 version.
++/* Search a character in a block of memory.  31/64 bit S/390 version.
+    Copyright (C) 2001-2018 Free Software Foundation, Inc.
+    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+    This file is part of the GNU C Library.
+@@ -22,19 +22,42 @@
+      %r3 = character to find
+      %r4 = number of bytes to search.  */
+ 
++#include <ifunc-memchr.h>
+ #include "sysdep.h"
+ #include "asm-syntax.h"
+ 
++#if HAVE_MEMCHR_Z900_G5
++# if defined __s390x__
++#  define SLGR	slgr
++#  define LGHI	lghi
++#  define NGR	ngr
++#  define LGR	lgr
++# else
++#  define SLGR	slr
++#  define LGHI	lhi
++#  define NGR	nr
++#  define LGR	lr
++# endif /* ! defined __s390x__  */
++
+ 	.text
+-ENTRY(memchr)
+-	lghi  %r0,0xff
+-	ngr   %r0,%r3
+-	lgr   %r1,%r2
++ENTRY(MEMCHR_Z900_G5)
++	LGHI  %r0,0xff
++	NGR   %r0,%r3
++	LGR   %r1,%r2
+ 	la    %r2,0(%r4,%r1)
+ 0:	srst  %r2,%r1
+ 	jo    0b
+ 	brc   13,1f
+-	slgr  %r2,%r2
++	SLGR  %r2,%r2
+ 1:	br    %r14
+-END(memchr)
+-libc_hidden_builtin_def (memchr)
++END(MEMCHR_Z900_G5)
++
++# if ! HAVE_MEMCHR_IFUNC
++strong_alias (MEMCHR_Z900_G5, __memchr)
++weak_alias (__memchr, memchr)
++# endif
++
++# if defined SHARED && IS_IN (libc)
++strong_alias (MEMCHR_Z900_G5, __GI_memchr)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/memchr.c
+similarity index 68%
+rename from sysdeps/s390/multiarch/memchr.c
+rename to sysdeps/s390/memchr.c
+index 3885ebaa4d90ed1a..490f1b66002aae05 100644
+--- a/sysdeps/s390/multiarch/memchr.c
++++ b/sysdeps/s390/memchr.c
+@@ -16,12 +16,26 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-memchr.h>
++
++#if HAVE_MEMCHR_IFUNC
+ # define memchr __redirect_memchr
+ # include <string.h>
+ # undef memchr
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr)
++# if HAVE_MEMCHR_Z900_G5
++extern __typeof (__redirect_memchr) MEMCHR_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_MEMCHR_Z13
++extern __typeof (__redirect_memchr) MEMCHR_Z13 attribute_hidden;
++# endif
+ 
++s390_libc_ifunc_expr (__redirect_memchr, __memchr,
++		      (HAVE_MEMCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? MEMCHR_Z13
++		      : MEMCHR_DEFAULT
++		      )
++weak_alias (__memchr, memchr)
+ #endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 1578f21af4a1bd06..fa1f7b81db912be0 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += memchr memchr-vx \
+-		   rawmemchr rawmemchr-vx rawmemchr-c \
++sysdep_routines += rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c
+ endif
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 2d48c99c8d5663fe..b4be0140424aed69 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -42,6 +42,7 @@
+ #include <ifunc-strspn.h>
+ #include <ifunc-strpbrk.h>
+ #include <ifunc-strcspn.h>
++#include <ifunc-memchr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -372,6 +373,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_STRCSPN_IFUNC  */
+ 
++#if HAVE_MEMCHR_IFUNC
++    IFUNC_IMPL (i, name, memchr,
++# if HAVE_MEMCHR_Z13
++		IFUNC_IMPL_ADD (array, i, memchr,
++				dl_hwcap & HWCAP_S390_VX, MEMCHR_Z13)
++# endif
++# if HAVE_MEMCHR_Z900_G5
++		IFUNC_IMPL_ADD (array, i, memchr, 1, MEMCHR_Z900_G5)
++# endif
++		)
++#endif /* HAVE_MEMCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -412,7 +425,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wcscspn);
+ 
+-  IFUNC_VX_IMPL (memchr);
+   IFUNC_VX_IMPL (wmemchr);
+   IFUNC_VX_IMPL (rawmemchr);
+ 
+diff --git a/sysdeps/s390/s390-32/memchr.S b/sysdeps/s390/s390-32/memchr.S
+deleted file mode 100644
+index 54f9b85f578fa1c7..0000000000000000
+--- a/sysdeps/s390/s390-32/memchr.S
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/* Search a character in a block of memory.  For IBM S390
+-   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/*
+- * R2 = address to memory area
+- * R3 = character to find
+- * R4 = number of bytes to search
+- */
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-	.text
+-ENTRY(memchr)
+-	lhi   %r0,0xff
+-	nr    %r0,%r3
+-	lr    %r1,%r2
+-	la    %r2,0(%r4,%r1)
+-0:      srst  %r2,%r1
+-	jo    0b
+-	brc   13,1f
+-	slr   %r2,%r2
+-1:      br    %r14
+-END(memchr)
+-libc_hidden_builtin_def (memchr)
+diff --git a/sysdeps/s390/s390-32/multiarch/memchr.c b/sysdeps/s390/s390-32/multiarch/memchr.c
+deleted file mode 100644
+index 5e1610afa43ee549..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/memchr.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of memchr.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/memchr.S will be used.  */
+-#include <sysdeps/s390/multiarch/memchr.c>
+diff --git a/sysdeps/s390/s390-64/multiarch/memchr.c b/sysdeps/s390/s390-64/multiarch/memchr.c
+deleted file mode 100644
+index 5e1610afa43ee549..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/memchr.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/* Multiple versions of memchr.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* This wrapper-file is needed, because otherwise file
+-   sysdeps/s390/s390-[32|64]/memchr.S will be used.  */
+-#include <sysdeps/s390/multiarch/memchr.c>
diff --git a/SOURCES/glibc-rh1659438-33.patch b/SOURCES/glibc-rh1659438-33.patch
new file mode 100644
index 0000000..b2b59ee
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-33.patch
@@ -0,0 +1,287 @@
+commit 4c7b3cec113d9bb7dfc004e22c7a98e310ab9bcc
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:16 2018 +0100
+
+    S390: Refactor rawmemchr ifunc handling.
+    
+    The ifunc handling for rawmemchr is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove rawmemchr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add rawmemchr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for rawmemchr.
+            * sysdeps/s390/multiarch/rawmemchr-c.c: Move to ...
+            * sysdeps/s390/rawmemchr-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/rawmemchr-vx.S: Move to ...
+            * sysdeps/s390/rawmemchr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/rawmemchr.c: Move to ...
+            * sysdeps/s390/rawmemchr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-rawmemchr.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 816b2fccdc75e4cf..9b38b461b34176b0 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -53,5 +53,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strspn strspn-vx strspn-c \
+ 		   strpbrk strpbrk-vx strpbrk-c \
+ 		   strcspn strcspn-vx strcspn-c \
+-		   memchr memchr-vx memchr-z900
++		   memchr memchr-vx memchr-z900 \
++		   rawmemchr rawmemchr-vx rawmemchr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-rawmemchr.h b/sysdeps/s390/ifunc-rawmemchr.h
+new file mode 100644
+index 0000000000000000..bfcbeae802fb372e
+--- /dev/null
++++ b/sysdeps/s390/ifunc-rawmemchr.h
+@@ -0,0 +1,52 @@
++/* rawmemchr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_RAWMEMCHR_IFUNC	1
++#else
++# define HAVE_RAWMEMCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT HAVE_RAWMEMCHR_IFUNC
++#else
++# define HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define RAWMEMCHR_DEFAULT	RAWMEMCHR_Z13
++# define HAVE_RAWMEMCHR_C	0
++# define HAVE_RAWMEMCHR_Z13	1
++#else
++# define RAWMEMCHR_DEFAULT	RAWMEMCHR_C
++# define HAVE_RAWMEMCHR_C	1
++# define HAVE_RAWMEMCHR_Z13	HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_RAWMEMCHR_C
++# define RAWMEMCHR_C		__rawmemchr_c
++#else
++# define RAWMEMCHR_C		NULL
++#endif
++
++#if HAVE_RAWMEMCHR_Z13
++# define RAWMEMCHR_Z13		__rawmemchr_vx
++#else
++# define RAWMEMCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index fa1f7b81db912be0..ac6cfcf9c7dbbc3a 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += rawmemchr rawmemchr-vx rawmemchr-c \
+-		   memccpy memccpy-vx memccpy-c \
++sysdep_routines += memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c
+ endif
+ 
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index b4be0140424aed69..bf3b40e111a6bd31 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -43,6 +43,7 @@
+ #include <ifunc-strpbrk.h>
+ #include <ifunc-strcspn.h>
+ #include <ifunc-memchr.h>
++#include <ifunc-rawmemchr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -385,6 +386,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_MEMCHR_IFUNC  */
+ 
++#if HAVE_RAWMEMCHR_IFUNC
++    IFUNC_IMPL (i, name, rawmemchr,
++# if HAVE_RAWMEMCHR_Z13
++		IFUNC_IMPL_ADD (array, i, rawmemchr,
++				dl_hwcap & HWCAP_S390_VX, RAWMEMCHR_Z13)
++# endif
++# if HAVE_RAWMEMCHR_C
++		IFUNC_IMPL_ADD (array, i, rawmemchr, 1, RAWMEMCHR_C)
++# endif
++		)
++#endif /* HAVE_RAWMEMCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -426,7 +439,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   IFUNC_VX_IMPL (wcscspn);
+ 
+   IFUNC_VX_IMPL (wmemchr);
+-  IFUNC_VX_IMPL (rawmemchr);
+ 
+   IFUNC_VX_IMPL (memccpy);
+ 
+diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/rawmemchr-c.c
+similarity index 67%
+rename from sysdeps/s390/multiarch/rawmemchr.c
+rename to sysdeps/s390/rawmemchr-c.c
+index 5fdb2252df7f8fa1..8b8208e542092383 100644
+--- a/sysdeps/s390/multiarch/rawmemchr.c
++++ b/sysdeps/s390/rawmemchr-c.c
+@@ -1,4 +1,4 @@
+-/* Multiple versions of rawmemchr.
++/* Default rawmemchr implementation for S/390.
+    Copyright (C) 2015-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -16,16 +16,19 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define __rawmemchr __redirect___rawmemchr
+-# include <string.h>
+-# undef __rawmemchr
+-# include <ifunc-resolve.h>
++#include <ifunc-rawmemchr.h>
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr
+-				, __rawmemchr)
+-weak_alias (__rawmemchr, rawmemchr)
++#if HAVE_RAWMEMCHR_C
++# if HAVE_RAWMEMCHR_IFUNC
++#  define RAWMEMCHR RAWMEMCHR_C
++#  undef weak_alias
++#  define weak_alias(a, b)
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   define libc_hidden_def(name)					\
++  __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c);
++#  endif
++# endif
+ 
+-#else
+ # include <string/rawmemchr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++#endif
+diff --git a/sysdeps/s390/multiarch/rawmemchr-vx.S b/sysdeps/s390/rawmemchr-vx.S
+similarity index 87%
+rename from sysdeps/s390/multiarch/rawmemchr-vx.S
+rename to sysdeps/s390/rawmemchr-vx.S
+index d5778be068394394..f04c0e8b616a76ea 100644
+--- a/sysdeps/s390/multiarch/rawmemchr-vx.S
++++ b/sysdeps/s390/rawmemchr-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-rawmemchr.h>
++
++#if HAVE_RAWMEMCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +39,7 @@
+    -v17=index of unequal
+    -v18=c replicated
+ */
+-ENTRY(__rawmemchr_vx)
++ENTRY(RAWMEMCHR_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -88,5 +90,15 @@ ENTRY(__rawmemchr_vx)
+ .Lend_found:
+ 	la	%r2,0(%r5,%r2)	/* Return pointer to character.  */
+ 	br	%r14
+-END(__rawmemchr_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(RAWMEMCHR_Z13)
++
++# if ! HAVE_RAWMEMCHR_IFUNC
++strong_alias (RAWMEMCHR_Z13, __rawmemchr)
++weak_alias (__rawmemchr, rawmemchr)
++# endif
++
++# if ! HAVE_RAWMEMCHR_C && defined SHARED && IS_IN (libc)
++strong_alias (RAWMEMCHR_Z13, __GI___rawmemchr)
++# endif
++
++#endif /* HAVE_RAWMEMCHR_Z13  */
+diff --git a/sysdeps/s390/multiarch/rawmemchr-c.c b/sysdeps/s390/rawmemchr.c
+similarity index 56%
+rename from sysdeps/s390/multiarch/rawmemchr-c.c
+rename to sysdeps/s390/rawmemchr.c
+index f43c883a76e52480..d9263ce208ea6361 100644
+--- a/sysdeps/s390/multiarch/rawmemchr-c.c
++++ b/sysdeps/s390/rawmemchr.c
+@@ -1,4 +1,4 @@
+-/* Default rawmemchr implementation for S/390.
++/* Multiple versions of rawmemchr.
+    Copyright (C) 2015-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -16,19 +16,26 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-rawmemchr.h>
++
++#if HAVE_RAWMEMCHR_IFUNC
++# define __rawmemchr __redirect___rawmemchr
+ # include <string.h>
++# undef __rawmemchr
++# include <ifunc-resolve.h>
+ 
+-# define RAWMEMCHR  __rawmemchr_c
+-# undef weak_alias
+-# define weak_alias(a, b)
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)				\
+-     __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c);
+-# endif /* SHARED */
++# if HAVE_RAWMEMCHR_C
++extern __typeof (__redirect___rawmemchr) RAWMEMCHR_C attribute_hidden;
++# endif
+ 
+-extern __typeof (rawmemchr) __rawmemchr_c attribute_hidden;
++# if HAVE_RAWMEMCHR_Z13
++extern __typeof (__redirect___rawmemchr) RAWMEMCHR_Z13 attribute_hidden;
++# endif
+ 
+-# include <string/rawmemchr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect___rawmemchr, __rawmemchr,
++		      (HAVE_RAWMEMCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? RAWMEMCHR_Z13
++		      : RAWMEMCHR_DEFAULT
++		      )
++weak_alias (__rawmemchr, rawmemchr)
++#endif /* HAVE_RAWMEMCHR_IFUNC  */
diff --git a/SOURCES/glibc-rh1659438-34.patch b/SOURCES/glibc-rh1659438-34.patch
new file mode 100644
index 0000000..f2fbe7f
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-34.patch
@@ -0,0 +1,252 @@
+commit 196655ba54ebdcdcc0468bcb6e136757b013d350
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:16 2018 +0100
+
+    S390: Refactor memccpy ifunc handling.
+    
+    The ifunc handling for memccpy is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove memccpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add memccpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for memccpy.
+            * sysdeps/s390/multiarch/memccpy-c.c: Move to ...
+            * sysdeps/s390/memccpy-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/memccpy-vx.S: Move to ...
+            * sysdeps/s390/memccpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/memccpy.c: Move to ...
+            * sysdeps/s390/memccpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-memccpy.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 9b38b461b34176b0..239426dbc1ce9d09 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -54,5 +54,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strpbrk strpbrk-vx strpbrk-c \
+ 		   strcspn strcspn-vx strcspn-c \
+ 		   memchr memchr-vx memchr-z900 \
+-		   rawmemchr rawmemchr-vx rawmemchr-c
++		   rawmemchr rawmemchr-vx rawmemchr-c \
++		   memccpy memccpy-vx memccpy-c
+ endif
+diff --git a/sysdeps/s390/ifunc-memccpy.h b/sysdeps/s390/ifunc-memccpy.h
+new file mode 100644
+index 0000000000000000..8f7a1d0f9fffe106
+--- /dev/null
++++ b/sysdeps/s390/ifunc-memccpy.h
+@@ -0,0 +1,52 @@
++/* memccpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_MEMCCPY_IFUNC	1
++#else
++# define HAVE_MEMCCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT HAVE_MEMCCPY_IFUNC
++#else
++# define HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define MEMCCPY_DEFAULT	MEMCCPY_Z13
++# define HAVE_MEMCCPY_C		0
++# define HAVE_MEMCCPY_Z13	1
++#else
++# define MEMCCPY_DEFAULT	MEMCCPY_C
++# define HAVE_MEMCCPY_C		1
++# define HAVE_MEMCCPY_Z13	HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_MEMCCPY_C
++# define MEMCCPY_C		__memccpy_c
++#else
++# define MEMCCPY_C		NULL
++#endif
++
++#if HAVE_MEMCCPY_Z13
++# define MEMCCPY_Z13		__memccpy_vx
++#else
++# define MEMCCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/memccpy-c.c b/sysdeps/s390/memccpy-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/memccpy-c.c
+rename to sysdeps/s390/memccpy-c.c
+index 1f4c5481991fcb70..2b2f81eb9cfe9369 100644
+--- a/sysdeps/s390/multiarch/memccpy-c.c
++++ b/sysdeps/s390/memccpy-c.c
+@@ -16,10 +16,14 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define MEMCCPY  __memccpy_c
++#include <ifunc-memccpy.h>
++
++#if HAVE_MEMCCPY_C
++# if HAVE_MEMCCPY_IFUNC
++#  define MEMCCPY MEMCCPY_C
++#  undef weak_alias
++#  define weak_alias(a, b)
++#endif
+ 
+-# include <string.h>
+-extern __typeof (__memccpy) __memccpy_c;
+ # include <string/memccpy.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/memccpy-vx.S b/sysdeps/s390/memccpy-vx.S
+similarity index 95%
+rename from sysdeps/s390/multiarch/memccpy-vx.S
+rename to sysdeps/s390/memccpy-vx.S
+index 150aa0e4a48ca181..44f7bc582410ba22 100644
+--- a/sysdeps/s390/multiarch/memccpy-vx.S
++++ b/sysdeps/s390/memccpy-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-memccpy.h>
++
++#if HAVE_MEMCCPY_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -42,7 +44,7 @@
+    -v19=part #2 of s
+    -v31=save area for r6
+ */
+-ENTRY(__memccpy_vx)
++ENTRY(MEMCCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -152,5 +154,11 @@ ENTRY(__memccpy_vx)
+ 	vlgvg	%r7,%v31,1
+ 	lghi	%r2,0		/* Return null.  */
+ 	br	%r14
+-END(__memccpy_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(MEMCCPY_Z13)
++
++# if ! HAVE_MEMCCPY_IFUNC
++strong_alias (MEMCCPY_Z13, __memccpy)
++weak_alias (__memccpy, memccpy)
++# endif
++
++#endif /* HAVE_MEMCCPY_Z13  */
+diff --git a/sysdeps/s390/multiarch/memccpy.c b/sysdeps/s390/memccpy.c
+similarity index 68%
+rename from sysdeps/s390/multiarch/memccpy.c
+rename to sysdeps/s390/memccpy.c
+index 30aae82321048b7d..bcfeb31e86c56115 100644
+--- a/sysdeps/s390/multiarch/memccpy.c
++++ b/sysdeps/s390/memccpy.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-memccpy.h>
++
++#if HAVE_MEMCCPY_IFUNC
+ # include <string.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__memccpy)
+-weak_alias (__memccpy, memccpy)
++# if HAVE_MEMCCPY_C
++extern __typeof (__memccpy) MEMCCPY_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/memccpy.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_MEMCCPY_Z13
++extern __typeof (__memccpy) MEMCCPY_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__memccpy, __memccpy,
++		      (HAVE_MEMCCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? MEMCCPY_Z13
++		      : MEMCCPY_DEFAULT
++		      )
++weak_alias (__memccpy, memccpy)
++#endif /* HAVE_MEMCCPY_IFUNC  */
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index ac6cfcf9c7dbbc3a..d5a32fc309ba4b3c 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += memccpy memccpy-vx memccpy-c \
+-		   memrchr memrchr-vx memrchr-c
++sysdep_routines += memrchr memrchr-vx memrchr-c
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index bf3b40e111a6bd31..b8917747f0f23cd9 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -44,6 +44,7 @@
+ #include <ifunc-strcspn.h>
+ #include <ifunc-memchr.h>
+ #include <ifunc-rawmemchr.h>
++#include <ifunc-memccpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -398,6 +399,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_RAWMEMCHR_IFUNC  */
+ 
++#if HAVE_MEMCCPY_IFUNC
++    IFUNC_IMPL (i, name, memccpy,
++# if HAVE_MEMCCPY_Z13
++		IFUNC_IMPL_ADD (array, i, memccpy,
++				dl_hwcap & HWCAP_S390_VX, MEMCCPY_Z13)
++# endif
++# if HAVE_MEMCCPY_C
++		IFUNC_IMPL_ADD (array, i, memccpy, 1, MEMCCPY_C)
++# endif
++		)
++#endif /* HAVE_MEMCCPY_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -440,8 +453,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wmemchr);
+ 
+-  IFUNC_VX_IMPL (memccpy);
+-
+   IFUNC_VX_IMPL (wmemset);
+ 
+   IFUNC_VX_IMPL (wmemcmp);
diff --git a/SOURCES/glibc-rh1659438-35.patch b/SOURCES/glibc-rh1659438-35.patch
new file mode 100644
index 0000000..53091b6
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-35.patch
@@ -0,0 +1,250 @@
+commit 89bfcbdf9d3d36eff0d544f655991149a7ae680b
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:17 2018 +0100
+
+    S390: Refactor memrchr ifunc handling.
+    
+    The ifunc handling for memrchr is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove memrchr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add memrchr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for memrchr.
+            * sysdeps/s390/multiarch/memrchr-c.c: Move to ...
+            * sysdeps/s390/memrchr-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/memrchr-vx.S: Move to ...
+            * sysdeps/s390/memrchr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/memrchr.c: Move to ...
+            * sysdeps/s390/memrchr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-memrchr.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 239426dbc1ce9d09..9a16ce1692e51607 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -55,5 +55,6 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   strcspn strcspn-vx strcspn-c \
+ 		   memchr memchr-vx memchr-z900 \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+-		   memccpy memccpy-vx memccpy-c
++		   memccpy memccpy-vx memccpy-c \
++		   memrchr memrchr-vx memrchr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-memrchr.h b/sysdeps/s390/ifunc-memrchr.h
+new file mode 100644
+index 0000000000000000..9d80d5528dc92dab
+--- /dev/null
++++ b/sysdeps/s390/ifunc-memrchr.h
+@@ -0,0 +1,52 @@
++/* memrchr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_MEMRCHR_IFUNC	1
++#else
++# define HAVE_MEMRCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT HAVE_MEMRCHR_IFUNC
++#else
++# define HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define MEMRCHR_DEFAULT	MEMRCHR_Z13
++# define HAVE_MEMRCHR_C		0
++# define HAVE_MEMRCHR_Z13	1
++#else
++# define MEMRCHR_DEFAULT	MEMRCHR_C
++# define HAVE_MEMRCHR_C		1
++# define HAVE_MEMRCHR_Z13	HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_MEMRCHR_C
++# define MEMRCHR_C		__memrchr_c
++#else
++# define MEMRCHR_C		NULL
++#endif
++
++#if HAVE_MEMRCHR_Z13
++# define MEMRCHR_Z13		__memrchr_vx
++#else
++# define MEMRCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/memrchr-c.c b/sysdeps/s390/memrchr-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/memrchr-c.c
+rename to sysdeps/s390/memrchr-c.c
+index 1e3c914a5d61dbc5..333c0fc8d1855323 100644
+--- a/sysdeps/s390/multiarch/memrchr-c.c
++++ b/sysdeps/s390/memrchr-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define MEMRCHR  __memrchr_c
++#include <ifunc-memrchr.h>
++
++#if HAVE_MEMRCHR_C
++# if HAVE_MEMRCHR_IFUNC
++#  define MEMRCHR MEMRCHR_C
++# endif
+ 
+-# include <string.h>
+-extern __typeof (__memrchr) __memrchr_c;
+ # include <string/memrchr.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/memrchr-vx.S b/sysdeps/s390/memrchr-vx.S
+similarity index 94%
+rename from sysdeps/s390/multiarch/memrchr-vx.S
+rename to sysdeps/s390/memrchr-vx.S
+index 8e81f5ed7519c2cc..ba832f1b21ad5a4c 100644
+--- a/sysdeps/s390/multiarch/memrchr-vx.S
++++ b/sysdeps/s390/memrchr-vx.S
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-memrchr.h>
++
++#if HAVE_MEMRCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -40,7 +42,7 @@
+    -v18=c replicated
+    -v20=permute pattern
+ */
+-ENTRY(__memrchr_vx)
++ENTRY(MEMRCHR_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -156,5 +158,11 @@ ENTRY(__memrchr_vx)
+ 
+ 	clgijhe	%r4,64,.Lloop64	/* If n >= 64 -> loop64.  */
+ 	j	.Llt64
+-END(__memrchr_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(MEMRCHR_Z13)
++
++# if ! HAVE_MEMRCHR_IFUNC
++strong_alias (MEMRCHR_Z13, __memrchr)
++weak_alias (__memrchr, memrchr)
++# endif
++
++#endif /* HAVE_MEMRCHR_Z13  */
+diff --git a/sysdeps/s390/multiarch/memrchr.c b/sysdeps/s390/memrchr.c
+similarity index 68%
+rename from sysdeps/s390/multiarch/memrchr.c
+rename to sysdeps/s390/memrchr.c
+index 43a44abcf6cc3bdc..d995e9961c1cc9eb 100644
+--- a/sysdeps/s390/multiarch/memrchr.c
++++ b/sysdeps/s390/memrchr.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-memrchr.h>
++
++#if HAVE_MEMRCHR_IFUNC
+ # include <string.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__memrchr)
+-weak_alias (__memrchr, memrchr)
++# if HAVE_MEMRCHR_C
++extern __typeof (__memrchr) MEMRCHR_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <string/memrchr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_MEMRCHR_Z13
++extern __typeof (__memrchr) MEMRCHR_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__memrchr, __memrchr,
++		      (HAVE_MEMRCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? MEMRCHR_Z13
++		      : MEMRCHR_DEFAULT
++		      )
++weak_alias (__memrchr, memrchr)
++#endif /* HAVE_MEMRCHR_IFUNC  */
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index d5a32fc309ba4b3c..260b514936b93306 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,7 +1,3 @@
+-ifeq ($(subdir),string)
+-sysdep_routines += memrchr memrchr-vx memrchr-c
+-endif
+-
+ ifeq ($(subdir),wcsmbs)
+ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsnlen wcsnlen-vx wcsnlen-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index b8917747f0f23cd9..0f01b99691002be0 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -45,6 +45,7 @@
+ #include <ifunc-memchr.h>
+ #include <ifunc-rawmemchr.h>
+ #include <ifunc-memccpy.h>
++#include <ifunc-memrchr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -411,6 +412,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_MEMCCPY_IFUNC  */
+ 
++#if HAVE_MEMRCHR_IFUNC
++    IFUNC_IMPL (i, name, memrchr,
++# if HAVE_MEMRCHR_Z13
++		IFUNC_IMPL_ADD (array, i, memrchr,
++				dl_hwcap & HWCAP_S390_VX, MEMRCHR_Z13)
++# endif
++# if HAVE_MEMRCHR_C
++		IFUNC_IMPL_ADD (array, i, memrchr, 1, MEMRCHR_C)
++# endif
++		)
++#endif /* HAVE_MEMRCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -457,8 +470,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+   IFUNC_VX_IMPL (wmemcmp);
+ 
+-  IFUNC_VX_IMPL (memrchr);
+-
+ #endif /* HAVE_S390_VX_ASM_SUPPORT */
+ 
+   return i;
diff --git a/SOURCES/glibc-rh1659438-36.patch b/SOURCES/glibc-rh1659438-36.patch
new file mode 100644
index 0000000..146d137
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-36.patch
@@ -0,0 +1,252 @@
+commit 2e02d0b7a9bf3421638d2d0f2526275a1df5c0da
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:17 2018 +0100
+
+    S390: Refactor wcslen ifunc handling.
+    
+    The ifunc handling for wcslen is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcslen variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcslen variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcslen.
+            * sysdeps/s390/multiarch/wcslen-c.c: Move to ...
+            * sysdeps/s390/wcslen-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcslen-vx.S: Move to ...
+            * sysdeps/s390/wcslen-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcslen.c: Move to ...
+            * sysdeps/s390/wcslen.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcslen.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 9a16ce1692e51607..65e89118936bb668 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -58,3 +58,7 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c
+ endif
++
++ifeq ($(subdir),wcsmbs)
++sysdep_routines += wcslen wcslen-vx wcslen-c
++endif
+diff --git a/sysdeps/s390/ifunc-wcslen.h b/sysdeps/s390/ifunc-wcslen.h
+new file mode 100644
+index 0000000000000000..50d879caf2b8186b
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcslen.h
+@@ -0,0 +1,53 @@
++/* wcslen variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSLEN_IFUNC	1
++#else
++# define HAVE_WCSLEN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT HAVE_WCSLEN_IFUNC
++#else
++# define HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSLEN_DEFAULT		WCSLEN_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSLEN_C		1
++# define HAVE_WCSLEN_Z13	1
++#else
++# define WCSLEN_DEFAULT		WCSLEN_C
++# define HAVE_WCSLEN_C		1
++# define HAVE_WCSLEN_Z13	HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSLEN_C
++# define WCSLEN_C		__wcslen_c
++#else
++# define WCSLEN_C		NULL
++#endif
++
++#if HAVE_WCSLEN_Z13
++# define WCSLEN_Z13		__wcslen_vx
++#else
++# define WCSLEN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 260b514936b93306..421d40d020b81560 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcslen wcslen-vx wcslen-c \
+-		   wcsnlen wcsnlen-vx wcsnlen-c \
++sysdep_routines += wcsnlen wcsnlen-vx wcsnlen-c \
+ 		   wcscpy wcscpy-vx wcscpy-c \
+ 		   wcpcpy wcpcpy-vx wcpcpy-c \
+ 		   wcsncpy wcsncpy-vx wcsncpy-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 0f01b99691002be0..7bf5f14c015b54fe 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -46,6 +46,7 @@
+ #include <ifunc-rawmemchr.h>
+ #include <ifunc-memccpy.h>
+ #include <ifunc-memrchr.h>
++#include <ifunc-wcslen.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -424,6 +425,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_MEMRCHR_IFUNC  */
+ 
++#if HAVE_WCSLEN_IFUNC
++    IFUNC_IMPL (i, name, wcslen,
++# if HAVE_WCSLEN_Z13
++		IFUNC_IMPL_ADD (array, i, wcslen,
++				dl_hwcap & HWCAP_S390_VX, WCSLEN_Z13)
++# endif
++# if HAVE_WCSLEN_C
++		IFUNC_IMPL_ADD (array, i, wcslen, 1, WCSLEN_C)
++# endif
++		)
++#endif /* HAVE_WCSLEN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -432,8 +445,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcslen);
+-
+   IFUNC_VX_IMPL (wcsnlen);
+ 
+   IFUNC_VX_IMPL (wcscpy);
+diff --git a/sysdeps/s390/multiarch/wcslen-c.c b/sysdeps/s390/wcslen-c.c
+similarity index 86%
+rename from sysdeps/s390/multiarch/wcslen-c.c
+rename to sysdeps/s390/wcslen-c.c
+index 32a23e206d2e9cf9..45399cff3a127b5e 100644
+--- a/sysdeps/s390/multiarch/wcslen-c.c
++++ b/sysdeps/s390/wcslen-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSLEN  __wcslen_c
++#include <ifunc-wcslen.h>
++
++#if HAVE_WCSLEN_C
++# if HAVE_WCSLEN_IFUNC || HAVE_WCSLEN_Z13
++#  define WCSLEN WCSLEN_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (__wcslen) __wcslen_c;
+ # include <wcsmbs/wcslen.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcslen-vx.S b/sysdeps/s390/wcslen-vx.S
+similarity index 92%
+rename from sysdeps/s390/multiarch/wcslen-vx.S
+rename to sysdeps/s390/wcslen-vx.S
+index 337cbed6ec21db76..114f7ef743b10c63 100644
+--- a/sysdeps/s390/multiarch/wcslen-vx.S
++++ b/sysdeps/s390/wcslen-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcslen.h>
++#if HAVE_WCSLEN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -34,7 +35,7 @@
+    -r5=current_len and return_value
+    -v16=part of s
+ */
+-ENTRY(__wcslen_vx)
++ENTRY(WCSLEN_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -86,6 +87,11 @@ ENTRY(__wcslen_vx)
+ 	srlg	%r2,%r2,2	/* Convert byte-count to character-count.  */
+ 	br	%r14
+ .Lfallback:
+-	jg	__wcslen_c
+-END(__wcslen_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSLEN_C
++END(WCSLEN_Z13)
++
++# if ! HAVE_WCSLEN_IFUNC
++strong_alias (WCSLEN_Z13, __wcslen)
++weak_alias (__wcslen, wcslen)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcslen.c b/sysdeps/s390/wcslen.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcslen.c
+rename to sysdeps/s390/wcslen.c
+index 3a1d1a32c9a99749..a5eee83f6cae7166 100644
+--- a/sysdeps/s390/multiarch/wcslen.c
++++ b/sysdeps/s390/wcslen.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcslen.h>
++
++#if HAVE_WCSLEN_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__wcslen)
+-weak_alias (__wcslen, wcslen)
++# if HAVE_WCSLEN_C
++extern __typeof (__wcslen) WCSLEN_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcslen.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCSLEN_Z13
++extern __typeof (__wcslen) WCSLEN_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__wcslen, __wcslen,
++		      (HAVE_WCSLEN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSLEN_Z13
++		      : WCSLEN_DEFAULT
++		      )
++weak_alias (__wcslen, wcslen)
++#endif
diff --git a/SOURCES/glibc-rh1659438-37.patch b/SOURCES/glibc-rh1659438-37.patch
new file mode 100644
index 0000000..827d82d
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-37.patch
@@ -0,0 +1,253 @@
+commit c7e7cd266ed123b6dfb722f599934ca5dcfd3e93
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:18 2018 +0100
+
+    S390: Refactor wcsnlen ifunc handling.
+    
+    The ifunc handling for wcsnlen is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    Glibc internal calls will use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcsnlen variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcsnlen variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcsnlen.
+            * sysdeps/s390/multiarch/wcsnlen-c.c: Move to ...
+            * sysdeps/s390/wcsnlen-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsnlen-vx.S: Move to ...
+            * sysdeps/s390/wcsnlen-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsnlen.c: Move to ...
+            * sysdeps/s390/wcsnlen.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcsnlen.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 65e89118936bb668..f5983815479a76da 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -60,5 +60,6 @@ sysdep_routines += bzero memset memset-z900 \
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcslen wcslen-vx wcslen-c
++sysdep_routines += wcslen wcslen-vx wcslen-c \
++		   wcsnlen wcsnlen-vx wcsnlen-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcsnlen.h b/sysdeps/s390/ifunc-wcsnlen.h
+new file mode 100644
+index 0000000000000000..b5b21da2f17d9cd9
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcsnlen.h
+@@ -0,0 +1,53 @@
++/* wcsnlen variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSNLEN_IFUNC	1
++#else
++# define HAVE_WCSNLEN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT HAVE_WCSNLEN_IFUNC
++#else
++# define HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSNLEN_DEFAULT	WCSNLEN_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSNLEN_C		1
++# define HAVE_WCSNLEN_Z13	1
++#else
++# define WCSNLEN_DEFAULT	WCSNLEN_C
++# define HAVE_WCSNLEN_C		1
++# define HAVE_WCSNLEN_Z13	HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSNLEN_C
++# define WCSNLEN_C		__wcsnlen_c
++#else
++# define WCSNLEN_C		NULL
++#endif
++
++#if HAVE_WCSNLEN_Z13
++# define WCSNLEN_Z13		__wcsnlen_vx
++#else
++# define WCSNLEN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 421d40d020b81560..ce2e7ce5f4eef0fa 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcsnlen wcsnlen-vx wcsnlen-c \
+-		   wcscpy wcscpy-vx wcscpy-c \
++sysdep_routines += wcscpy wcscpy-vx wcscpy-c \
+ 		   wcpcpy wcpcpy-vx wcpcpy-c \
+ 		   wcsncpy wcsncpy-vx wcsncpy-c \
+ 		   wcpncpy wcpncpy-vx wcpncpy-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 7bf5f14c015b54fe..c199fd0e0b43e4b4 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -47,6 +47,7 @@
+ #include <ifunc-memccpy.h>
+ #include <ifunc-memrchr.h>
+ #include <ifunc-wcslen.h>
++#include <ifunc-wcsnlen.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -437,6 +438,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSLEN_IFUNC  */
+ 
++#if HAVE_WCSNLEN_IFUNC
++    IFUNC_IMPL (i, name, wcsnlen,
++# if HAVE_WCSNLEN_Z13
++		IFUNC_IMPL_ADD (array, i, wcsnlen,
++				dl_hwcap & HWCAP_S390_VX, WCSNLEN_Z13)
++# endif
++# if HAVE_WCSNLEN_C
++		IFUNC_IMPL_ADD (array, i, wcsnlen, 1, WCSNLEN_C)
++# endif
++		)
++#endif /* HAVE_WCSNLEN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -445,8 +458,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcsnlen);
+-
+   IFUNC_VX_IMPL (wcscpy);
+ 
+   IFUNC_VX_IMPL (wcpcpy);
+diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/wcsnlen-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wcsnlen-c.c
+rename to sysdeps/s390/wcsnlen-c.c
+index 8f43f5104f2eab3f..7495a6f97cfeca62 100644
+--- a/sysdeps/s390/multiarch/wcsnlen-c.c
++++ b/sysdeps/s390/wcsnlen-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSNLEN  __wcsnlen_c
++#include <ifunc-wcsnlen.h>
++
++#if HAVE_WCSNLEN_C
++# if HAVE_WCSNLEN_IFUNC || HAVE_WCSNLEN_Z13
++#  define WCSNLEN WCSNLEN_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (__wcsnlen) __wcsnlen_c;
+ # include <wcsmbs/wcsnlen.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcsnlen-vx.S b/sysdeps/s390/wcsnlen-vx.S
+similarity index 95%
+rename from sysdeps/s390/multiarch/wcsnlen-vx.S
+rename to sysdeps/s390/wcsnlen-vx.S
+index 420f29fbc0d2965a..47f4ca82840538d9 100644
+--- a/sysdeps/s390/multiarch/wcsnlen-vx.S
++++ b/sysdeps/s390/wcsnlen-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsnlen.h>
++#if HAVE_WCSNLEN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -34,7 +35,7 @@
+    -r5=current_len and return_value
+    -v16=part of s
+ */
+-ENTRY(__wcsnlen_vx)
++ENTRY(WCSNLEN_Z13)
+ 
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+@@ -146,6 +147,11 @@ ENTRY(__wcsnlen_vx)
+ 	j	.Llt64
+ 
+ .Lfallback:
+-	jg	__wcsnlen_c
+-END(__wcsnlen_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSNLEN_C
++END(WCSNLEN_Z13)
++
++# if ! HAVE_WCSNLEN_IFUNC
++strong_alias (WCSNLEN_Z13, __wcsnlen)
++weak_alias (__wcsnlen, wcsnlen)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/wcsnlen.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcsnlen.c
+rename to sysdeps/s390/wcsnlen.c
+index 5234074b1fce8ca1..b5c8ad9fde5a9752 100644
+--- a/sysdeps/s390/multiarch/wcsnlen.c
++++ b/sysdeps/s390/wcsnlen.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsnlen.h>
++
++#if HAVE_WCSNLEN_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__wcsnlen)
+-weak_alias (__wcsnlen, wcsnlen)
++# if HAVE_WCSNLEN_C
++extern __typeof (__wcsnlen) WCSNLEN_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcsnlen.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCSNLEN_Z13
++extern __typeof (__wcsnlen) WCSNLEN_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__wcsnlen, __wcsnlen,
++		      (HAVE_WCSNLEN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSNLEN_Z13
++		      : WCSNLEN_DEFAULT
++		      )
++weak_alias (__wcsnlen, wcsnlen)
++#endif
diff --git a/SOURCES/glibc-rh1659438-38.patch b/SOURCES/glibc-rh1659438-38.patch
new file mode 100644
index 0000000..7549d69
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-38.patch
@@ -0,0 +1,249 @@
+commit 804f2e5c73b1363836ce5db29a0abb3d36e1286a
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:18 2018 +0100
+
+    S390: Refactor wcscpy ifunc handling.
+    
+    The ifunc handling for wcscpy is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcscpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcscpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcscpy.
+            * sysdeps/s390/multiarch/wcscpy-c.c: Move to ...
+            * sysdeps/s390/wcscpy-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscpy-vx.S: Move to ...
+            * sysdeps/s390/wcscpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscpy.c: Move to ...
+            * sysdeps/s390/wcscpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcscpy.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index f5983815479a76da..8bdbd1b5d8e9df01 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -61,5 +61,6 @@ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+ sysdep_routines += wcslen wcslen-vx wcslen-c \
+-		   wcsnlen wcsnlen-vx wcsnlen-c
++		   wcsnlen wcsnlen-vx wcsnlen-c \
++		   wcscpy wcscpy-vx wcscpy-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcscpy.h b/sysdeps/s390/ifunc-wcscpy.h
+new file mode 100644
+index 0000000000000000..fba7c9c7a7c354d1
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcscpy.h
+@@ -0,0 +1,53 @@
++/* wcscpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSCPY_IFUNC	1
++#else
++# define HAVE_WCSCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT HAVE_WCSCPY_IFUNC
++#else
++# define HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSCPY_DEFAULT		WCSCPY_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSCPY_C		1
++# define HAVE_WCSCPY_Z13	1
++#else
++# define WCSCPY_DEFAULT		WCSCPY_C
++# define HAVE_WCSCPY_C		1
++# define HAVE_WCSCPY_Z13	HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSCPY_C
++# define WCSCPY_C		__wcscpy_c
++#else
++# define WCSCPY_C		NULL
++#endif
++
++#if HAVE_WCSCPY_Z13
++# define WCSCPY_Z13		__wcscpy_vx
++#else
++# define WCSCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index ce2e7ce5f4eef0fa..8828897a59ae580c 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcscpy wcscpy-vx wcscpy-c \
+-		   wcpcpy wcpcpy-vx wcpcpy-c \
++sysdep_routines += wcpcpy wcpcpy-vx wcpcpy-c \
+ 		   wcsncpy wcsncpy-vx wcsncpy-c \
+ 		   wcpncpy wcpncpy-vx wcpncpy-c \
+ 		   wcscat wcscat-vx wcscat-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index c199fd0e0b43e4b4..aac8f4ea4671d0cf 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -48,6 +48,7 @@
+ #include <ifunc-memrchr.h>
+ #include <ifunc-wcslen.h>
+ #include <ifunc-wcsnlen.h>
++#include <ifunc-wcscpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -450,6 +451,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSNLEN_IFUNC  */
+ 
++#if HAVE_WCSCPY_IFUNC
++    IFUNC_IMPL (i, name, wcscpy,
++# if HAVE_WCSCPY_Z13
++		IFUNC_IMPL_ADD (array, i, wcscpy,
++				dl_hwcap & HWCAP_S390_VX, WCSCPY_Z13)
++# endif
++# if HAVE_WCSCPY_C
++		IFUNC_IMPL_ADD (array, i, wcscpy, 1, WCSCPY_C)
++# endif
++		)
++#endif /* HAVE_WCSCPY_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -458,8 +471,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcscpy);
+-
+   IFUNC_VX_IMPL (wcpcpy);
+ 
+   IFUNC_VX_IMPL (wcsncpy);
+diff --git a/sysdeps/s390/multiarch/wcscpy-c.c b/sysdeps/s390/wcscpy-c.c
+similarity index 86%
+rename from sysdeps/s390/multiarch/wcscpy-c.c
+rename to sysdeps/s390/wcscpy-c.c
+index 4a510f466be80679..db2967f47d7bc3cc 100644
+--- a/sysdeps/s390/multiarch/wcscpy-c.c
++++ b/sysdeps/s390/wcscpy-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSCPY  __wcscpy_c
++#include <ifunc-wcscpy.h>
++
++#if HAVE_WCSCPY_C
++# if HAVE_WCSCPY_IFUNC || HAVE_WCSCPY_Z13
++#  define WCSCPY WCSCPY_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (wcscpy) __wcscpy_c;
+ # include <wcsmbs/wcscpy.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcscpy-vx.S b/sysdeps/s390/wcscpy-vx.S
+similarity index 95%
+rename from sysdeps/s390/multiarch/wcscpy-vx.S
+rename to sysdeps/s390/wcscpy-vx.S
+index c2e81055be958907..8fe12f4d8b3e66a8 100644
+--- a/sysdeps/s390/multiarch/wcscpy-vx.S
++++ b/sysdeps/s390/wcscpy-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscpy.h>
++#if HAVE_WCSCPY_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +38,7 @@
+    -v17=index of zero
+    -v18=part of src
+ */
+-ENTRY(__wcscpy_vx)
++ENTRY(WCSCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -106,6 +107,10 @@ ENTRY(__wcscpy_vx)
+ 	br	%r14
+ 
+ .Lfallback:
+-	jg	__wcscpy_c
+-END(__wcscpy_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSCPY_C
++END(WCSCPY_Z13)
++
++# if ! HAVE_WCSCPY_IFUNC
++strong_alias (WCSCPY_Z13, wcscpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcscpy.c b/sysdeps/s390/wcscpy.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcscpy.c
+rename to sysdeps/s390/wcscpy.c
+index e69baa6c59906df3..51f07327da1bec74 100644
+--- a/sysdeps/s390/multiarch/wcscpy.c
++++ b/sysdeps/s390/wcscpy.c
+@@ -16,12 +16,23 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscpy.h>
++
++#if HAVE_WCSCPY_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2 (__wcscpy, wcscpy)
++# if HAVE_WCSCPY_C
++extern __typeof (wcscpy) WCSCPY_C attribute_hidden;
++# endif
++
++# if HAVE_WCSCPY_Z13
++extern __typeof (wcscpy) WCSCPY_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcscpy.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (wcscpy, wcscpy,
++		      (HAVE_WCSCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSCPY_Z13
++		      : WCSCPY_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-39.patch b/SOURCES/glibc-rh1659438-39.patch
new file mode 100644
index 0000000..8fe2754
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-39.patch
@@ -0,0 +1,252 @@
+commit 0582e4284529b4ea0fcd1a8973ccab7d95ec0e87
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:19 2018 +0100
+
+    S390: Refactor wcpcpy ifunc handling.
+    
+    The ifunc handling for wcpcpy is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcpcpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcpcpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcpcpy.
+            * sysdeps/s390/multiarch/wcpcpy-c.c: Move to ...
+            * sysdeps/s390/wcpcpy-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcpcpy-vx.S: Move to ...
+            * sysdeps/s390/wcpcpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcpcpy.c: Move to ...
+            * sysdeps/s390/wcpcpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcpcpy.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 8bdbd1b5d8e9df01..5b6446f55299af03 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -62,5 +62,6 @@ endif
+ ifeq ($(subdir),wcsmbs)
+ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsnlen wcsnlen-vx wcsnlen-c \
+-		   wcscpy wcscpy-vx wcscpy-c
++		   wcscpy wcscpy-vx wcscpy-c \
++		   wcpcpy wcpcpy-vx wcpcpy-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcpcpy.h b/sysdeps/s390/ifunc-wcpcpy.h
+new file mode 100644
+index 0000000000000000..0d5e2ba1a0b09905
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcpcpy.h
+@@ -0,0 +1,53 @@
++/* wcpcpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCPCPY_IFUNC	1
++#else
++# define HAVE_WCPCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT HAVE_WCPCPY_IFUNC
++#else
++# define HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCPCPY_DEFAULT		WCPCPY_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCPCPY_C		1
++# define HAVE_WCPCPY_Z13	1
++#else
++# define WCPCPY_DEFAULT		WCPCPY_C
++# define HAVE_WCPCPY_C		1
++# define HAVE_WCPCPY_Z13	HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCPCPY_C
++# define WCPCPY_C		__wcpcpy_c
++#else
++# define WCPCPY_C		NULL
++#endif
++
++#if HAVE_WCPCPY_Z13
++# define WCPCPY_Z13		__wcpcpy_vx
++#else
++# define WCPCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 8828897a59ae580c..7d7b05dcf21cff7d 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcpcpy wcpcpy-vx wcpcpy-c \
+-		   wcsncpy wcsncpy-vx wcsncpy-c \
++sysdep_routines += wcsncpy wcsncpy-vx wcsncpy-c \
+ 		   wcpncpy wcpncpy-vx wcpncpy-c \
+ 		   wcscat wcscat-vx wcscat-c \
+ 		   wcsncat wcsncat-vx wcsncat-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index aac8f4ea4671d0cf..656ab59db66dbb48 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -49,6 +49,7 @@
+ #include <ifunc-wcslen.h>
+ #include <ifunc-wcsnlen.h>
+ #include <ifunc-wcscpy.h>
++#include <ifunc-wcpcpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -463,6 +464,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSCPY_IFUNC  */
+ 
++#if HAVE_WCPCPY_IFUNC
++    IFUNC_IMPL (i, name, wcpcpy,
++# if HAVE_WCPCPY_Z13
++		IFUNC_IMPL_ADD (array, i, wcpcpy,
++				dl_hwcap & HWCAP_S390_VX, WCPCPY_Z13)
++# endif
++# if HAVE_WCPCPY_C
++		IFUNC_IMPL_ADD (array, i, wcpcpy, 1, WCPCPY_C)
++# endif
++		)
++#endif /* HAVE_WCPCPY_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -471,8 +484,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcpcpy);
+-
+   IFUNC_VX_IMPL (wcsncpy);
+ 
+   IFUNC_VX_IMPL (wcpncpy);
+diff --git a/sysdeps/s390/multiarch/wcpcpy-c.c b/sysdeps/s390/wcpcpy-c.c
+similarity index 86%
+rename from sysdeps/s390/multiarch/wcpcpy-c.c
+rename to sysdeps/s390/wcpcpy-c.c
+index e3282fde19c5262a..ed1539cde2f6f858 100644
+--- a/sysdeps/s390/multiarch/wcpcpy-c.c
++++ b/sysdeps/s390/wcpcpy-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCPCPY  __wcpcpy_c
++#include <ifunc-wcpcpy.h>
++
++#if HAVE_WCPCPY_C
++# if HAVE_WCPCPY_IFUNC || HAVE_WCPCPY_Z13
++#  define WCPCPY WCPCPY_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (__wcpcpy) __wcpcpy_c;
+ # include <wcsmbs/wcpcpy.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcpcpy-vx.S b/sysdeps/s390/wcpcpy-vx.S
+similarity index 94%
+rename from sysdeps/s390/multiarch/wcpcpy-vx.S
+rename to sysdeps/s390/wcpcpy-vx.S
+index bff6e8562884066c..5154ad44610c1ed1 100644
+--- a/sysdeps/s390/multiarch/wcpcpy-vx.S
++++ b/sysdeps/s390/wcpcpy-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcpcpy.h>
++#if HAVE_WCPCPY_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +38,7 @@
+    -v17=index of zero
+    -v18=part of src
+ */
+-ENTRY(__wcpcpy_vx)
++ENTRY(WCPCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -109,6 +110,11 @@ ENTRY(__wcpcpy_vx)
+ 	br	%r14
+ 
+ .Lfallback:
+-	jg	__wcpcpy_c
+-END(__wcpcpy_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCPCPY_C
++END(WCPCPY_Z13)
++
++# if ! HAVE_WCPCPY_IFUNC
++strong_alias (WCPCPY_Z13, __wcpcpy)
++weak_alias (__wcpcpy, wcpcpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcpcpy.c b/sysdeps/s390/wcpcpy.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcpcpy.c
+rename to sysdeps/s390/wcpcpy.c
+index f19d376d8530d0a4..34ac68b31fedcb09 100644
+--- a/sysdeps/s390/multiarch/wcpcpy.c
++++ b/sysdeps/s390/wcpcpy.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcpcpy.h>
++
++#if HAVE_WCPCPY_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__wcpcpy)
+-weak_alias (__wcpcpy, wcpcpy)
++# if HAVE_WCPCPY_C
++extern __typeof (__wcpcpy) WCPCPY_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcpcpy.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCPCPY_Z13
++extern __typeof (__wcpcpy) WCPCPY_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__wcpcpy, __wcpcpy,
++		      (HAVE_WCPCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCPCPY_Z13
++		      : WCPCPY_DEFAULT
++		      )
++weak_alias (__wcpcpy, wcpcpy)
++#endif
diff --git a/SOURCES/glibc-rh1659438-4.patch b/SOURCES/glibc-rh1659438-4.patch
new file mode 100644
index 0000000..38bf785
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-4.patch
@@ -0,0 +1,521 @@
+commit 712a254a97ade7f48fb7a434339faa05c048ce1f
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:04 2018 +0100
+
+    S390: Refactor memset ifunc handling.
+    
+    This patch moves all ifunc variants for memset
+    to sysdeps/s390/memset-z900.S. The configure-check/preprocessor logic
+    in sysdeps/s390/ifunc-memset.h decides if ifunc is needed at all
+    and which ifunc variants should be available.
+    E.g. if the compiler/assembler already supports z196 by default,
+    the older ifunc variants are not included.
+    If we only need the newest ifunc variant,
+    then we can skip ifunc at all.
+    
+    Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted
+    in order to handle only the available ifunc variants.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/ifunc-memset.h: New File.
+            * sysdeps/s390/memset.S: Move to ...
+            * sysdeps/s390/memset-z900.S ... here.
+            Move implementations from memset-s390x.s to here.
+            * sysdeps/s390/multiarch/memset-s390x.S: Delete File.
+            * sysdeps/s390/multiarch/Makefile (sysdep_routines):
+            Remove memset variants.
+            * sysdeps/s390/Makefile (sysdep_routines):
+            Add memset variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Adjust ifunc variants for
+            memset.
+            * sysdeps/s390/multiarch/memset.c: Move ifunc resolver
+            to ...
+            * sysdeps/s390/memset.c: ... here.
+            Adjust ifunc variants for memset.
+
+Conflicts:
+	sysdeps/s390/Makefile
+	  Missing backport of commit 69e2444ab1444ab8210598abbcb4822701d368b9
+          ("S390: Test that lazy binding does not clobber R0").
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 8a54f88cd7ac880e..360838e172f4ca37 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -29,3 +29,7 @@ $(inst_gconvdir)/%.so: $(objpfx)%.so $(+force)
+ 
+ sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules
+ endif
++
++ifeq ($(subdir),string)
++sysdep_routines += memset memset-z900
++endif
+diff --git a/sysdeps/s390/ifunc-memset.h b/sysdeps/s390/ifunc-memset.h
+new file mode 100644
+index 0000000000000000..9a13b1001fed9979
+--- /dev/null
++++ b/sysdeps/s390/ifunc-memset.h
+@@ -0,0 +1,65 @@
++/* memset variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)	\
++  && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# define HAVE_MEMSET_IFUNC	1
++#else
++# define HAVE_MEMSET_IFUNC	0
++#endif
++
++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# define MEMSET_DEFAULT		MEMSET_Z196
++# define HAVE_MEMSET_Z900_G5	0
++# define HAVE_MEMSET_Z10	0
++# define HAVE_MEMSET_Z196	1
++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
++# define MEMSET_DEFAULT		MEMSET_Z10
++# define HAVE_MEMSET_Z900_G5	0
++# define HAVE_MEMSET_Z10	1
++# define HAVE_MEMSET_Z196	HAVE_MEMSET_IFUNC
++#else
++# define MEMSET_DEFAULT		MEMSET_Z900_G5
++# define HAVE_MEMSET_Z900_G5	1
++# define HAVE_MEMSET_Z10	HAVE_MEMSET_IFUNC
++# define HAVE_MEMSET_Z196	HAVE_MEMSET_IFUNC
++#endif
++
++#if HAVE_MEMSET_Z10 || HAVE_MEMSET_Z196
++# define HAVE_MEMSET_MVCLE	1
++#else
++# define HAVE_MEMSET_MVCLE	0
++#endif
++
++#if HAVE_MEMSET_Z900_G5
++# define MEMSET_Z900_G5		__memset_default
++#else
++# define MEMSET_Z900_G5		NULL
++#endif
++
++#if HAVE_MEMSET_Z10
++# define MEMSET_Z10		__memset_z10
++#else
++# define MEMSET_Z10		NULL
++#endif
++
++#if HAVE_MEMSET_Z196
++# define MEMSET_Z196		__memset_z196
++#else
++# define MEMSET_Z196		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/memset-s390x.S b/sysdeps/s390/memset-z900.S
+similarity index 57%
+rename from sysdeps/s390/multiarch/memset-s390x.S
+rename to sysdeps/s390/memset-z900.S
+index aca3ac3fda1dd228..eaf13402bd3e251d 100644
+--- a/sysdeps/s390/multiarch/memset-s390x.S
++++ b/sysdeps/s390/memset-z900.S
+@@ -1,5 +1,6 @@
+ /* Set a block of memory to some byte value.  31/64 bit S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
++   Copyright (C) 2001-2018 Free Software Foundation, Inc.
++   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+@@ -17,8 +18,9 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ 
+-#include "sysdep.h"
++#include <sysdep.h>
+ #include "asm-syntax.h"
++#include <ifunc-memset.h>
+ 
+ /* INPUT PARAMETERS
+      %r2 = address of memory area
+@@ -27,43 +29,68 @@
+ 
+        .text
+ 
+-#if IS_IN (libc)
++#if HAVE_MEMSET_Z900_G5
++# if defined __s390x__
++#  define LTGR	ltgr
++#  define CGHI	cghi
++#  define LGR	lgr
++#  define AGHI	aghi
++#  define BRCTG	brctg
++# else
++#  define LTGR	ltr
++#  define CGHI	chi
++#  define LGR	lr
++#  define AGHI	ahi
++#  define BRCTG	brct
++# endif /* ! defined __s390x__  */
+ 
+-ENTRY(__memset_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-# if !defined __s390x__
+-	llgfr	%r4,%r4
+-# endif /* !defined __s390x__  */
+-	ltgr    %r4,%r4
+-	je      .L_Z196_4
++ENTRY(MEMSET_Z900_G5)
++#if defined __s390x__
++	.machine "z900"
++#else
++	.machine "g5"
++#endif /* ! defined __s390x__  */
++	LTGR    %r4,%r4
++	je      .L_Z900_G5_4
+ 	stc     %r3,0(%r2)
+-	lgr     %r1,%r2
+-	cghi    %r4,1
+-	je      .L_Z196_4
+-	aghi    %r4,-2
+-	srlg    %r5,%r4,8
+-	ltgr    %r5,%r5
+-	jne     .L_Z196_1
+-.L_Z196_3:
+-	exrl    %r4,.L_Z196_17
+-.L_Z196_4:
++	CGHI    %r4,1
++	LGR     %r1,%r2
++	je      .L_Z900_G5_4
++	AGHI    %r4,-2
++#if defined __s390x__
++	larl    %r5,.L_Z900_G5_18
++	srlg    %r3,%r4,8
++# define Z900_G5_EX_D 0
++#else
++	basr    %r5,0
++.L_Z900_G5_19:
++# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19
++	lr      %r3,%r4
++	srl     %r3,8
++#endif /* ! defined __s390x__  */
++	LTGR    %r3,%r3
++	jne     .L_Z900_G5_14
++.L_Z900_G5_3:
++	ex      %r4,Z900_G5_EX_D(%r5)
++.L_Z900_G5_4:
+ 	br      %r14
+-.L_Z196_1:
+-	cgfi	%r5,1048576
+-	jh	__memset_mvcle	   # Switch to mvcle for >256MB
+-.L_Z196_2:
+-	pfd     2,1024(%r1)
++.L_Z900_G5_14:
+ 	mvc     1(256,%r1),0(%r1)
+-	aghi    %r5,-1
+ 	la      %r1,256(%r1)
+-	jne     .L_Z196_2
+-	j       .L_Z196_3
+-.L_Z196_17:
++	BRCTG   %r3,.L_Z900_G5_14
++	j       .L_Z900_G5_3
++.L_Z900_G5_18:
+ 	mvc     1(1,%r1),0(%r1)
+-END(__memset_z196)
++END(MEMSET_Z900_G5)
++# undef LTGR
++# undef CGHI
++# undef LGR
++# undef AGHI
++# undef BRCTG
++#endif /*  HAVE_MEMSET_Z900_G5  */
+ 
+-ENTRY(__memset_z10)
++#if HAVE_MEMSET_Z10
++ENTRY(MEMSET_Z10)
+ 	.machine "z10"
+ 	.machinemode "zarch_nohighgprs"
+ # if !defined __s390x__
+@@ -91,8 +118,46 @@ ENTRY(__memset_z10)
+ 	j       .L_Z10_3
+ .L_Z10_18:
+ 	mvc     1(1,%r1),0(%r1)
+-END(__memset_z10)
++END(MEMSET_Z10)
++#endif /* HAVE_MEMSET_Z10  */
++
++#if HAVE_MEMSET_Z196
++ENTRY(MEMSET_Z196)
++	.machine "z196"
++	.machinemode "zarch_nohighgprs"
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
++	ltgr    %r4,%r4
++	je      .L_Z196_4
++	stc     %r3,0(%r2)
++	lgr     %r1,%r2
++	cghi    %r4,1
++	je      .L_Z196_4
++	aghi    %r4,-2
++	srlg    %r5,%r4,8
++	ltgr    %r5,%r5
++	jne     .L_Z196_1
++.L_Z196_3:
++	exrl    %r4,.L_Z196_17
++.L_Z196_4:
++	br      %r14
++.L_Z196_1:
++	cgfi	%r5,1048576
++	jh	__memset_mvcle	   # Switch to mvcle for >256MB
++.L_Z196_2:
++	pfd     2,1024(%r1)
++	mvc     1(256,%r1),0(%r1)
++	aghi    %r5,-1
++	la      %r1,256(%r1)
++	jne     .L_Z196_2
++	j       .L_Z196_3
++.L_Z196_17:
++	mvc     1(1,%r1),0(%r1)
++END(MEMSET_Z196)
++#endif /* HAVE_MEMSET_Z196  */
+ 
++#if HAVE_MEMSET_MVCLE
+ ENTRY(__memset_mvcle)
+ 	aghi	%r4,2               # take back the change done by the caller
+ 	lgr	%r0,%r2		    # save source address
+@@ -106,15 +171,16 @@ ENTRY(__memset_mvcle)
+ .L1:
+ 	br	%r14
+ END(__memset_mvcle)
++#endif /* HAVE_MEMSET_MVCLE  */
+ 
+-#endif /* IS_IN (libc) */
+-
+-#include "../memset.S"
++#if ! HAVE_MEMSET_IFUNC
++/* If we don't use ifunc, define an alias for memset here.
++   Otherwise see sysdeps/s390/memset.c.  */
++strong_alias (MEMSET_DEFAULT, memset)
++#endif
+ 
+-#if !IS_IN (libc)
+-.globl   memset
+-.set     memset,__memset_default
+-#elif defined SHARED && IS_IN (libc)
+-.globl   __GI_memset
+-.set     __GI_memset,__memset_default
++#if defined SHARED && IS_IN (libc)
++/* Defines the internal symbol.
++   Compare to libc_hidden_builtin_def (memset) in string/memset.c.  */
++strong_alias (MEMSET_DEFAULT, __GI_memset)
+ #endif
+diff --git a/sysdeps/s390/memset.S b/sysdeps/s390/memset.S
+deleted file mode 100644
+index 72e7c5a42efbaf6c..0000000000000000
+--- a/sysdeps/s390/memset.S
++++ /dev/null
+@@ -1,97 +0,0 @@
+-/* Set a block of memory to some byte value.  31/64 bit S/390 version.
+-   Copyright (C) 2001-2018 Free Software Foundation, Inc.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include <sysdep.h>
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of memory area
+-     %r3 = byte to fill memory with
+-     %r4 = number of bytes to fill.  */
+-
+-       .text
+-
+-#if defined __s390x__
+-# define LTGR	ltgr
+-# define CGHI	cghi
+-# define LGR	lgr
+-# define AGHI	aghi
+-# define BRCTG	brctg
+-#else
+-# define LTGR	ltr
+-# define CGHI	chi
+-# define LGR	lr
+-# define AGHI	ahi
+-# define BRCTG	brct
+-#endif /* ! defined __s390x__  */
+-
+-#ifdef USE_MULTIARCH
+-ENTRY(__memset_default)
+-#else
+-ENTRY(memset)
+-#endif
+-#if defined __s390x__
+-	.machine "z900"
+-#else
+-	.machine "g5"
+-#endif /* ! defined __s390x__  */
+-	LTGR    %r4,%r4
+-	je      .L_Z900_G5_4
+-	stc     %r3,0(%r2)
+-	CGHI    %r4,1
+-	LGR     %r1,%r2
+-	je      .L_Z900_G5_4
+-	AGHI    %r4,-2
+-#if defined __s390x__
+-	larl    %r5,.L_Z900_G5_18
+-	srlg    %r3,%r4,8
+-# define Z900_G5_EX_D 0
+-#else
+-	basr    %r5,0
+-.L_Z900_G5_19:
+-# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19
+-	lr      %r3,%r4
+-	srl     %r3,8
+-#endif /* ! defined __s390x__  */
+-	LTGR    %r3,%r3
+-	jne     .L_Z900_G5_14
+-.L_Z900_G5_3:
+-	ex      %r4,Z900_G5_EX_D(%r5)
+-.L_Z900_G5_4:
+-	br      %r14
+-.L_Z900_G5_14:
+-	mvc     1(256,%r1),0(%r1)
+-	la      %r1,256(%r1)
+-	BRCTG   %r3,.L_Z900_G5_14
+-	j       .L_Z900_G5_3
+-.L_Z900_G5_18:
+-	mvc     1(1,%r1),0(%r1)
+-#ifdef USE_MULTIARCH
+-END(__memset_default)
+-#else
+-END(memset)
+-libc_hidden_builtin_def (memset)
+-#endif
+-
+-#undef LTGR
+-#undef CGHI
+-#undef LGR
+-#undef AGHI
+-#undef BRCTG
+diff --git a/sysdeps/s390/multiarch/memset.c b/sysdeps/s390/memset.c
+similarity index 60%
+rename from sysdeps/s390/multiarch/memset.c
+rename to sysdeps/s390/memset.c
+index 760b3e9df201b8b4..57a35aebc7d3c794 100644
+--- a/sysdeps/s390/multiarch/memset.c
++++ b/sysdeps/s390/memset.c
+@@ -16,11 +16,33 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if IS_IN (libc)
++#include <ifunc-memset.h>
++#if HAVE_MEMSET_IFUNC
+ # define memset __redirect_memset
+ # include <string.h>
+ # undef memset
+ # include <ifunc-resolve.h>
+ 
+-s390_libc_ifunc (__redirect_memset, __memset, memset)
++# if HAVE_MEMSET_Z900_G5
++extern __typeof (__redirect_memset) MEMSET_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_MEMSET_Z10
++extern __typeof (__redirect_memset) MEMSET_Z10 attribute_hidden;
++# endif
++
++# if HAVE_MEMSET_Z196
++extern __typeof (__redirect_memset) MEMSET_Z196 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect_memset, memset,
++		      ({
++			s390_libc_ifunc_init ();
++			(HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits))
++			  ? MEMSET_Z196
++			  : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits))
++			  ? MEMSET_Z10
++			  : MEMSET_DEFAULT;
++		      })
++		      )
+ #endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 93ad21bfa2686ee5..c893ebc5659fd4ae 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -19,8 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c \
+-		   mempcpy \
+-		   memset memset-s390x
++		   mempcpy
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index ec3373ae2653d66e..2f671eac1f4f1ffd 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -21,6 +21,7 @@
+ #include <wchar.h>
+ #include <ifunc-impl-list.h>
+ #include <ifunc-resolve.h>
++#include <ifunc-memset.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -46,12 +47,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+       S390_STORE_STFLE (stfle_bits);
+     }
+ 
++#if HAVE_MEMSET_IFUNC
+   IFUNC_IMPL (i, name, memset,
++# if HAVE_MEMSET_Z196
+ 	      IFUNC_IMPL_ADD (array, i, memset,
+-			      S390_IS_Z196 (stfle_bits), __memset_z196)
++			      S390_IS_Z196 (stfle_bits), MEMSET_Z196)
++# endif
++# if HAVE_MEMSET_Z10
+ 	      IFUNC_IMPL_ADD (array, i, memset,
+-			      S390_IS_Z10 (stfle_bits), __memset_z10)
+-	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_default))
++			      S390_IS_Z10 (stfle_bits), MEMSET_Z10)
++# endif
++# if HAVE_MEMSET_Z900_G5
++	      IFUNC_IMPL_ADD (array, i, memset, 1, MEMSET_Z900_G5)
++# endif
++	      )
++#endif /* HAVE_MEMSET_IFUNC */
+ 
+   IFUNC_IMPL (i, name, memcmp,
+ 	      IFUNC_IMPL_ADD (array, i, memcmp,
diff --git a/SOURCES/glibc-rh1659438-40.patch b/SOURCES/glibc-rh1659438-40.patch
new file mode 100644
index 0000000..3eddef4
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-40.patch
@@ -0,0 +1,253 @@
+commit 0966dd86896d7cd6c107c751ba7d3b69542ca11d
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:19 2018 +0100
+
+    S390: Refactor wcsncpy ifunc handling.
+    
+    The ifunc handling for wcsncpy is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcsncpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcsncpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncpy.
+            * sysdeps/s390/multiarch/wcsncpy-c.c: Move to ...
+            * sysdeps/s390/wcsncpy-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsncpy-vx.S: Move to ...
+            * sysdeps/s390/wcsncpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsncpy.c: Move to ...
+            * sysdeps/s390/wcsncpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcsncpy.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 5b6446f55299af03..cc8357361e1f2574 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -63,5 +63,6 @@ ifeq ($(subdir),wcsmbs)
+ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsnlen wcsnlen-vx wcsnlen-c \
+ 		   wcscpy wcscpy-vx wcscpy-c \
+-		   wcpcpy wcpcpy-vx wcpcpy-c
++		   wcpcpy wcpcpy-vx wcpcpy-c \
++		   wcsncpy wcsncpy-vx wcsncpy-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcsncpy.h b/sysdeps/s390/ifunc-wcsncpy.h
+new file mode 100644
+index 0000000000000000..d7beca128aaaebc8
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcsncpy.h
+@@ -0,0 +1,53 @@
++/* wcsncpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSNCPY_IFUNC	1
++#else
++# define HAVE_WCSNCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT HAVE_WCSNCPY_IFUNC
++#else
++# define HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSNCPY_DEFAULT	WCSNCPY_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSNCPY_C		1
++# define HAVE_WCSNCPY_Z13	1
++#else
++# define WCSNCPY_DEFAULT	WCSNCPY_C
++# define HAVE_WCSNCPY_C		1
++# define HAVE_WCSNCPY_Z13	HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSNCPY_C
++# define WCSNCPY_C		__wcsncpy_c
++#else
++# define WCSNCPY_C		NULL
++#endif
++
++#if HAVE_WCSNCPY_Z13
++# define WCSNCPY_Z13		__wcsncpy_vx
++#else
++# define WCSNCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 7d7b05dcf21cff7d..6631fd14d32fde72 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcsncpy wcsncpy-vx wcsncpy-c \
+-		   wcpncpy wcpncpy-vx wcpncpy-c \
++sysdep_routines += wcpncpy wcpncpy-vx wcpncpy-c \
+ 		   wcscat wcscat-vx wcscat-c \
+ 		   wcsncat wcsncat-vx wcsncat-c \
+ 		   wcscmp wcscmp-vx wcscmp-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 656ab59db66dbb48..9ebaf4de6f2eb841 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -50,6 +50,7 @@
+ #include <ifunc-wcsnlen.h>
+ #include <ifunc-wcscpy.h>
+ #include <ifunc-wcpcpy.h>
++#include <ifunc-wcsncpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -476,6 +477,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCPCPY_IFUNC  */
+ 
++#if HAVE_WCSNCPY_IFUNC
++    IFUNC_IMPL (i, name, wcsncpy,
++# if HAVE_WCSNCPY_Z13
++		IFUNC_IMPL_ADD (array, i, wcsncpy,
++				dl_hwcap & HWCAP_S390_VX, WCSNCPY_Z13)
++# endif
++# if HAVE_WCSNCPY_C
++		IFUNC_IMPL_ADD (array, i, wcsncpy, 1, WCSNCPY_C)
++# endif
++		)
++#endif /* HAVE_WCSNCPY_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -484,8 +497,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcsncpy);
+-
+   IFUNC_VX_IMPL (wcpncpy);
+ 
+   IFUNC_VX_IMPL (wcscat);
+diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/wcsncpy-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wcsncpy-c.c
+rename to sysdeps/s390/wcsncpy-c.c
+index 6b89b8c14bf58198..4d0ddb09ecb1c849 100644
+--- a/sysdeps/s390/multiarch/wcsncpy-c.c
++++ b/sysdeps/s390/wcsncpy-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSNCPY  __wcsncpy_c
++#include <ifunc-wcsncpy.h>
++
++#if HAVE_WCSNCPY_C
++# if HAVE_WCSNCPY_IFUNC || HAVE_WCSNCPY_Z13
++#  define WCSNCPY WCSNCPY_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (__wcsncpy) __wcsncpy_c;
+ # include <wcsmbs/wcsncpy.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcsncpy-vx.S b/sysdeps/s390/wcsncpy-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/wcsncpy-vx.S
+rename to sysdeps/s390/wcsncpy-vx.S
+index b3400d50d9ab3324..9bcbdbf3229033da 100644
+--- a/sysdeps/s390/multiarch/wcsncpy-vx.S
++++ b/sysdeps/s390/wcsncpy-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsncpy.h>
++#if HAVE_WCSNCPY_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -40,7 +41,7 @@
+    -v18=part of src
+    -v31=register save area for r6, r7
+ */
+-ENTRY(__wcsncpy_vx)
++ENTRY(WCSNCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -217,7 +218,11 @@ ENTRY(__wcsncpy_vx)
+ 	j	.Llt64
+ 
+ .Lfallback:
+-	jg	__wcsncpy_c
+-END(__wcsncpy_vx)
+-
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSNCPY_C
++END(WCSNCPY_Z13)
++
++# if ! HAVE_WCSNCPY_IFUNC
++strong_alias (WCSNCPY_Z13, __wcsncpy)
++weak_alias (__wcsncpy, wcsncpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/wcsncpy.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcsncpy.c
+rename to sysdeps/s390/wcsncpy.c
+index 7209c7d4310d6013..e011de7ee7652bec 100644
+--- a/sysdeps/s390/multiarch/wcsncpy.c
++++ b/sysdeps/s390/wcsncpy.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsncpy.h>
++
++#if HAVE_WCSNCPY_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__wcsncpy)
+-weak_alias (__wcsncpy, wcsncpy)
++# if HAVE_WCSNCPY_C
++extern __typeof (__wcsncpy) WCSNCPY_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcsncpy.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCSNCPY_Z13
++extern __typeof (__wcsncpy) WCSNCPY_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__wcsncpy, __wcsncpy,
++		      (HAVE_WCSNCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSNCPY_Z13
++		      : WCSNCPY_DEFAULT
++		      )
++weak_alias (__wcsncpy, wcsncpy)
++#endif
diff --git a/SOURCES/glibc-rh1659438-41.patch b/SOURCES/glibc-rh1659438-41.patch
new file mode 100644
index 0000000..ee4a97f
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-41.patch
@@ -0,0 +1,252 @@
+commit c3081bcbd91a619115f047c2ceea90a9090d5216
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:19 2018 +0100
+
+    S390: Refactor wcpncpy ifunc handling.
+    
+    The ifunc handling for wcpncpy is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcpncpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcpncpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcpncpy.
+            * sysdeps/s390/multiarch/wcpncpy-c.c: Move to ...
+            * sysdeps/s390/wcpncpy-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcpncpy-vx.S: Move to ...
+            * sysdeps/s390/wcpncpy-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcpncpy.c: Move to ...
+            * sysdeps/s390/wcpncpy.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcpncpy.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index cc8357361e1f2574..640177370382235f 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -64,5 +64,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsnlen wcsnlen-vx wcsnlen-c \
+ 		   wcscpy wcscpy-vx wcscpy-c \
+ 		   wcpcpy wcpcpy-vx wcpcpy-c \
+-		   wcsncpy wcsncpy-vx wcsncpy-c
++		   wcsncpy wcsncpy-vx wcsncpy-c \
++		   wcpncpy wcpncpy-vx wcpncpy-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcpncpy.h b/sysdeps/s390/ifunc-wcpncpy.h
+new file mode 100644
+index 0000000000000000..0dd5633aa9cd780b
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcpncpy.h
+@@ -0,0 +1,53 @@
++/* wcpncpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCPNCPY_IFUNC	1
++#else
++# define HAVE_WCPNCPY_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT HAVE_WCPNCPY_IFUNC
++#else
++# define HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCPNCPY_DEFAULT	WCPNCPY_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCPNCPY_C		1
++# define HAVE_WCPNCPY_Z13	1
++#else
++# define WCPNCPY_DEFAULT	WCPNCPY_C
++# define HAVE_WCPNCPY_C		1
++# define HAVE_WCPNCPY_Z13	HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCPNCPY_C
++# define WCPNCPY_C		__wcpncpy_c
++#else
++# define WCPNCPY_C		NULL
++#endif
++
++#if HAVE_WCPNCPY_Z13
++# define WCPNCPY_Z13		__wcpncpy_vx
++#else
++# define WCPNCPY_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 6631fd14d32fde72..158fb495523438b4 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcpncpy wcpncpy-vx wcpncpy-c \
+-		   wcscat wcscat-vx wcscat-c \
++sysdep_routines += wcscat wcscat-vx wcscat-c \
+ 		   wcsncat wcsncat-vx wcsncat-c \
+ 		   wcscmp wcscmp-vx wcscmp-c \
+ 		   wcsncmp wcsncmp-vx wcsncmp-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 9ebaf4de6f2eb841..e60238fcde4dcd4f 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -51,6 +51,7 @@
+ #include <ifunc-wcscpy.h>
+ #include <ifunc-wcpcpy.h>
+ #include <ifunc-wcsncpy.h>
++#include <ifunc-wcpncpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -489,6 +490,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSNCPY_IFUNC  */
+ 
++#if HAVE_WCPNCPY_IFUNC
++    IFUNC_IMPL (i, name, wcpncpy,
++# if HAVE_WCPNCPY_Z13
++		IFUNC_IMPL_ADD (array, i, wcpncpy,
++				dl_hwcap & HWCAP_S390_VX, WCPNCPY_Z13)
++# endif
++# if HAVE_WCPNCPY_C
++		IFUNC_IMPL_ADD (array, i, wcpncpy, 1, WCPNCPY_C)
++# endif
++		)
++#endif /* HAVE_WCPNCPY_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -497,8 +510,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcpncpy);
+-
+   IFUNC_VX_IMPL (wcscat);
+ 
+   IFUNC_VX_IMPL (wcsncat);
+diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/wcpncpy-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wcpncpy-c.c
+rename to sysdeps/s390/wcpncpy-c.c
+index 1f44bacea9b65d44..d03359217e98a1f3 100644
+--- a/sysdeps/s390/multiarch/wcpncpy-c.c
++++ b/sysdeps/s390/wcpncpy-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCPNCPY  __wcpncpy_c
++#include <ifunc-wcpncpy.h>
++
++#if HAVE_WCPNCPY_C
++# if HAVE_WCPNCPY_IFUNC || HAVE_WCPNCPY_Z13
++#  define WCPNCPY WCPNCPY_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (__wcpncpy) __wcpncpy_c;
+ # include <wcsmbs/wcpncpy.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcpncpy-vx.S b/sysdeps/s390/wcpncpy-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/wcpncpy-vx.S
+rename to sysdeps/s390/wcpncpy-vx.S
+index 004f512e1f1a7982..7b5e4ad32d42d44b 100644
+--- a/sysdeps/s390/multiarch/wcpncpy-vx.S
++++ b/sysdeps/s390/wcpncpy-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcpncpy.h>
++#if HAVE_WCPNCPY_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -38,7 +39,7 @@
+    -%r6 = loaded bytes
+    -%r7 = border, tmp
+ */
+-ENTRY(__wcpncpy_vx)
++ENTRY(WCPNCPY_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -217,6 +218,11 @@ ENTRY(__wcpncpy_vx)
+ 	j	.Llt64
+ 
+ .Lfallback:
+-	jg	__wcpncpy_c
+-END(__wcpncpy_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCPNCPY_C
++END(WCPNCPY_Z13)
++
++# if ! HAVE_WCPNCPY_IFUNC
++strong_alias (WCPNCPY_Z13, __wcpncpy)
++weak_alias (__wcpncpy, wcpncpy)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/wcpncpy.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcpncpy.c
+rename to sysdeps/s390/wcpncpy.c
+index b72265fbe9df65d0..08d097dd2cb6dfd7 100644
+--- a/sysdeps/s390/multiarch/wcpncpy.c
++++ b/sysdeps/s390/wcpncpy.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcpncpy.h>
++
++#if HAVE_WCPNCPY_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__wcpncpy)
+-weak_alias (__wcpncpy, wcpncpy)
++# if HAVE_WCPNCPY_C
++extern __typeof (__wcpncpy) WCPNCPY_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcpncpy.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCPNCPY_Z13
++extern __typeof (__wcpncpy) WCPNCPY_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__wcpncpy, __wcpncpy,
++		      (HAVE_WCPNCPY_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCPNCPY_Z13
++		      : WCPNCPY_DEFAULT
++		      )
++weak_alias (__wcpncpy, wcpncpy)
++#endif
diff --git a/SOURCES/glibc-rh1659438-42.patch b/SOURCES/glibc-rh1659438-42.patch
new file mode 100644
index 0000000..49b154b
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-42.patch
@@ -0,0 +1,252 @@
+commit 3389cae427b4032c3a991cb32b5178a85a652d84
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:20 2018 +0100
+
+    S390: Refactor wcscat ifunc handling.
+    
+    The ifunc handling for wcscat is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcscat variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcscat variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcscat.
+            * sysdeps/s390/multiarch/wcscat-c.c: Move to ...
+            * sysdeps/s390/wcscat-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscat-vx.S: Move to ...
+            * sysdeps/s390/wcscat-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscat.c: Move to ...
+            * sysdeps/s390/wcscat.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcscat.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 640177370382235f..5fd00ad4a8661c4c 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -65,5 +65,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcscpy wcscpy-vx wcscpy-c \
+ 		   wcpcpy wcpcpy-vx wcpcpy-c \
+ 		   wcsncpy wcsncpy-vx wcsncpy-c \
+-		   wcpncpy wcpncpy-vx wcpncpy-c
++		   wcpncpy wcpncpy-vx wcpncpy-c \
++		   wcscat wcscat-vx wcscat-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcscat.h b/sysdeps/s390/ifunc-wcscat.h
+new file mode 100644
+index 0000000000000000..fecae21403e4c664
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcscat.h
+@@ -0,0 +1,53 @@
++/* wcscat variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSCAT_IFUNC	1
++#else
++# define HAVE_WCSCAT_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT HAVE_WCSCAT_IFUNC
++#else
++# define HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSCAT_DEFAULT		WCSCAT_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSCAT_C		1
++# define HAVE_WCSCAT_Z13	1
++#else
++# define WCSCAT_DEFAULT		WCSCAT_C
++# define HAVE_WCSCAT_C		1
++# define HAVE_WCSCAT_Z13	HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSCAT_C
++# define WCSCAT_C		__wcscat_c
++#else
++# define WCSCAT_C		NULL
++#endif
++
++#if HAVE_WCSCAT_Z13
++# define WCSCAT_Z13		__wcscat_vx
++#else
++# define WCSCAT_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 158fb495523438b4..617017496c79e2ca 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcscat wcscat-vx wcscat-c \
+-		   wcsncat wcsncat-vx wcsncat-c \
++sysdep_routines += wcsncat wcsncat-vx wcsncat-c \
+ 		   wcscmp wcscmp-vx wcscmp-c \
+ 		   wcsncmp wcsncmp-vx wcsncmp-c \
+ 		   wcschr wcschr-vx wcschr-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index e60238fcde4dcd4f..b05bd35fd898d0a6 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -52,6 +52,7 @@
+ #include <ifunc-wcpcpy.h>
+ #include <ifunc-wcsncpy.h>
+ #include <ifunc-wcpncpy.h>
++#include <ifunc-wcscat.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -502,6 +503,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCPNCPY_IFUNC  */
+ 
++#if HAVE_WCSCAT_IFUNC
++    IFUNC_IMPL (i, name, wcscat,
++# if HAVE_WCSCAT_Z13
++		IFUNC_IMPL_ADD (array, i, wcscat,
++				dl_hwcap & HWCAP_S390_VX, WCSCAT_Z13)
++# endif
++# if HAVE_WCSCAT_C
++		IFUNC_IMPL_ADD (array, i, wcscat, 1, WCSCAT_C)
++# endif
++		)
++#endif /* HAVE_WCSCAT_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -510,8 +523,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcscat);
+-
+   IFUNC_VX_IMPL (wcsncat);
+ 
+   IFUNC_VX_IMPL (wcscmp);
+diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/wcscat-c.c
+similarity index 86%
+rename from sysdeps/s390/multiarch/wcscat-c.c
+rename to sysdeps/s390/wcscat-c.c
+index 9a31c65a0ba668e5..bc1a50b1a52da259 100644
+--- a/sysdeps/s390/multiarch/wcscat-c.c
++++ b/sysdeps/s390/wcscat-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSCAT  __wcscat_c
++#include <ifunc-wcscat.h>
++
++#if HAVE_WCSCAT_C
++# if HAVE_WCSCAT_IFUNC || HAVE_WCSCAT_Z13
++#  define WCSCAT WCSCAT_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (__wcscat) __wcscat_c;
+ # include <wcsmbs/wcscat.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcscat-vx.S b/sysdeps/s390/wcscat-vx.S
+similarity index 96%
+rename from sysdeps/s390/multiarch/wcscat-vx.S
+rename to sysdeps/s390/wcscat-vx.S
+index 2164a8da411eadaa..4e40d69e8417d6d1 100644
+--- a/sysdeps/s390/multiarch/wcscat-vx.S
++++ b/sysdeps/s390/wcscat-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscat.h>
++#if HAVE_WCSCAT_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +38,7 @@
+    -v17=index of zero
+    -v18=part of src
+ */
+-ENTRY(__wcscat_vx)
++ENTRY(WCSCAT_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -170,6 +171,11 @@ ENTRY(__wcscat_vx)
+ 	lgr	%r2,%r0		/* Load saved dest-ptr.  */
+ 	br	%r14
+ .Lfallback:
+-	jg	__wcscat_c
+-END(__wcscat_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSCAT_C
++END(WCSCAT_Z13)
++
++# if ! HAVE_WCSCAT_IFUNC
++strong_alias (WCSCAT_Z13, __wcscat)
++weak_alias (__wcscat, wcscat)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/wcscat.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcscat.c
+rename to sysdeps/s390/wcscat.c
+index 33e4f6da3ff8eea7..3741210a177f8029 100644
+--- a/sysdeps/s390/multiarch/wcscat.c
++++ b/sysdeps/s390/wcscat.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscat.h>
++
++#if HAVE_WCSCAT_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__wcscat)
+-weak_alias (__wcscat, wcscat)
++# if HAVE_WCSCAT_C
++extern __typeof (__wcscat) WCSCAT_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcscat.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCSCAT_Z13
++extern __typeof (__wcscat) WCSCAT_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__wcscat, __wcscat,
++		      (HAVE_WCSCAT_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSCAT_Z13
++		      : WCSCAT_DEFAULT
++		      )
++weak_alias (__wcscat, wcscat)
++#endif
diff --git a/SOURCES/glibc-rh1659438-43.patch b/SOURCES/glibc-rh1659438-43.patch
new file mode 100644
index 0000000..df2053a
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-43.patch
@@ -0,0 +1,249 @@
+commit 814a76e1bcc59e6c4899279ede887bf9fecf5a40
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:20 2018 +0100
+
+    S390: Refactor wcsncat ifunc handling.
+    
+    The ifunc handling for wcsncat is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcsncat variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcsncat variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncat.
+            * sysdeps/s390/multiarch/wcsncat-c.c: Move to ...
+            * sysdeps/s390/wcsncat-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsncat-vx.S: Move to ...
+            * sysdeps/s390/wcsncat-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsncat.c: Move to ...
+            * sysdeps/s390/wcsncat.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcsncat.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 5fd00ad4a8661c4c..cafabe62165f0213 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -66,5 +66,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcpcpy wcpcpy-vx wcpcpy-c \
+ 		   wcsncpy wcsncpy-vx wcsncpy-c \
+ 		   wcpncpy wcpncpy-vx wcpncpy-c \
+-		   wcscat wcscat-vx wcscat-c
++		   wcscat wcscat-vx wcscat-c \
++		   wcsncat wcsncat-vx wcsncat-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcsncat.h b/sysdeps/s390/ifunc-wcsncat.h
+new file mode 100644
+index 0000000000000000..99495e0e640611ca
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcsncat.h
+@@ -0,0 +1,53 @@
++/* wcsncat variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSNCAT_IFUNC	1
++#else
++# define HAVE_WCSNCAT_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT HAVE_WCSNCAT_IFUNC
++#else
++# define HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSNCAT_DEFAULT	WCSNCAT_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSNCAT_C		1
++# define HAVE_WCSNCAT_Z13	1
++#else
++# define WCSNCAT_DEFAULT	WCSNCAT_C
++# define HAVE_WCSNCAT_C		1
++# define HAVE_WCSNCAT_Z13	HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSNCAT_C
++# define WCSNCAT_C		__wcsncat_c
++#else
++# define WCSNCAT_C		NULL
++#endif
++
++#if HAVE_WCSNCAT_Z13
++# define WCSNCAT_Z13		__wcsncat_vx
++#else
++# define WCSNCAT_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 617017496c79e2ca..6cb75950c2c453f6 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcsncat wcsncat-vx wcsncat-c \
+-		   wcscmp wcscmp-vx wcscmp-c \
++sysdep_routines += wcscmp wcscmp-vx wcscmp-c \
+ 		   wcsncmp wcsncmp-vx wcsncmp-c \
+ 		   wcschr wcschr-vx wcschr-c \
+ 		   wcschrnul wcschrnul-vx wcschrnul-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index b05bd35fd898d0a6..7b7b1e7497ec1a4f 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -53,6 +53,7 @@
+ #include <ifunc-wcsncpy.h>
+ #include <ifunc-wcpncpy.h>
+ #include <ifunc-wcscat.h>
++#include <ifunc-wcsncat.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -515,6 +516,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSCAT_IFUNC  */
+ 
++#if HAVE_WCSNCAT_IFUNC
++    IFUNC_IMPL (i, name, wcsncat,
++# if HAVE_WCSNCAT_Z13
++		IFUNC_IMPL_ADD (array, i, wcsncat,
++				dl_hwcap & HWCAP_S390_VX, WCSNCAT_Z13)
++# endif
++# if HAVE_WCSNCAT_C
++		IFUNC_IMPL_ADD (array, i, wcsncat, 1, WCSNCAT_C)
++# endif
++		)
++#endif /* HAVE_WCSNCAT_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -523,8 +536,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcsncat);
+-
+   IFUNC_VX_IMPL (wcscmp);
+ 
+   IFUNC_VX_IMPL (wcsncmp);
+diff --git a/sysdeps/s390/multiarch/wcsncat-c.c b/sysdeps/s390/wcsncat-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wcsncat-c.c
+rename to sysdeps/s390/wcsncat-c.c
+index 2cf1a76385932c64..5782d5cb28c9e7f6 100644
+--- a/sysdeps/s390/multiarch/wcsncat-c.c
++++ b/sysdeps/s390/wcsncat-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSNCAT  __wcsncat_c
++#include <ifunc-wcsncat.h>
++
++#if HAVE_WCSNCAT_C
++# if HAVE_WCSNCAT_IFUNC || HAVE_WCSNCAT_Z13
++#  define WCSNCAT WCSNCAT_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (wcsncat) __wcsncat_c;
+ # include <wcsmbs/wcsncat.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcsncat-vx.S b/sysdeps/s390/wcsncat-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/wcsncat-vx.S
+rename to sysdeps/s390/wcsncat-vx.S
+index 1d3935690d9f91a3..7c89d3d856faee24 100644
+--- a/sysdeps/s390/multiarch/wcsncat-vx.S
++++ b/sysdeps/s390/wcsncat-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsncat.h>
++#if HAVE_WCSNCAT_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -40,7 +41,7 @@
+    -v18=part of src
+    -v31=register save area for r6, r7
+ */
+-ENTRY(__wcsncat_vx)
++ENTRY(WCSNCAT_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -260,6 +261,10 @@ ENTRY(__wcsncat_vx)
+ 	j	.Lcpy_lt64
+ 
+ .Lfallback:
+-	jg	__wcsncat_c
+-END(__wcsncat_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSNCAT_C
++END(WCSNCAT_Z13)
++
++# if ! HAVE_WCSNCAT_IFUNC
++strong_alias (WCSNCAT_Z13, wcsncat)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcsncat.c b/sysdeps/s390/wcsncat.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/wcsncat.c
+rename to sysdeps/s390/wcsncat.c
+index c49b8ff78671cb99..722429fd5b5b4d9d 100644
+--- a/sysdeps/s390/multiarch/wcsncat.c
++++ b/sysdeps/s390/wcsncat.c
+@@ -16,12 +16,23 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsncat.h>
++
++#if HAVE_WCSNCAT_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2 (__wcsncat, wcsncat)
++# if HAVE_WCSNCAT_C
++extern __typeof (wcsncat) WCSNCAT_C attribute_hidden;
++# endif
++
++# if HAVE_WCSNCAT_Z13
++extern __typeof (wcsncat) WCSNCAT_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcsncat.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (wcsncat, wcsncat,
++		      (HAVE_WCSNCAT_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSNCAT_Z13
++		      : WCSNCAT_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-44.patch b/SOURCES/glibc-rh1659438-44.patch
new file mode 100644
index 0000000..c49fa9a
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-44.patch
@@ -0,0 +1,269 @@
+commit 3459e23dd4ae4aa8999df7111d833a0bb9add7cd
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:21 2018 +0100
+
+    S390: Refactor wcscmp ifunc handling.
+    
+    The ifunc handling for wcscmp is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    Glibc internal calls will then also use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcscmp variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcscmp variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcscmp.
+            * sysdeps/s390/multiarch/wcscmp-c.c: Move to ...
+            * sysdeps/s390/wcscmp-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscmp-vx.S: Move to ...
+            * sysdeps/s390/wcscmp-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscmp.c: Move to ...
+            * sysdeps/s390/wcscmp.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcscmp.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index cafabe62165f0213..fb104af231c48d3a 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -67,5 +67,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsncpy wcsncpy-vx wcsncpy-c \
+ 		   wcpncpy wcpncpy-vx wcpncpy-c \
+ 		   wcscat wcscat-vx wcscat-c \
+-		   wcsncat wcsncat-vx wcsncat-c
++		   wcsncat wcsncat-vx wcsncat-c \
++		   wcscmp wcscmp-vx wcscmp-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcscmp.h b/sysdeps/s390/ifunc-wcscmp.h
+new file mode 100644
+index 0000000000000000..99fe0213021458ae
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcscmp.h
+@@ -0,0 +1,52 @@
++/* wcscmp variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSCMP_IFUNC	1
++#else
++# define HAVE_WCSCMP_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT HAVE_WCSCMP_IFUNC
++#else
++# define HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSCMP_DEFAULT		WCSCMP_Z13
++# define HAVE_WCSCMP_C		0
++# define HAVE_WCSCMP_Z13	1
++#else
++# define WCSCMP_DEFAULT		WCSCMP_C
++# define HAVE_WCSCMP_C		1
++# define HAVE_WCSCMP_Z13	HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSCMP_C
++# define WCSCMP_C		__wcscmp_c
++#else
++# define WCSCMP_C		NULL
++#endif
++
++#if HAVE_WCSCMP_Z13
++# define WCSCMP_Z13		__wcscmp_vx
++#else
++# define WCSCMP_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 6cb75950c2c453f6..70162d0eaa6a0dee 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcscmp wcscmp-vx wcscmp-c \
+-		   wcsncmp wcsncmp-vx wcsncmp-c \
++sysdep_routines += wcsncmp wcsncmp-vx wcsncmp-c \
+ 		   wcschr wcschr-vx wcschr-c \
+ 		   wcschrnul wcschrnul-vx wcschrnul-c \
+ 		   wcsrchr wcsrchr-vx wcsrchr-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 7b7b1e7497ec1a4f..f461063c80b364fb 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -54,6 +54,7 @@
+ #include <ifunc-wcpncpy.h>
+ #include <ifunc-wcscat.h>
+ #include <ifunc-wcsncat.h>
++#include <ifunc-wcscmp.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -528,6 +529,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSNCAT_IFUNC  */
+ 
++#if HAVE_WCSCMP_IFUNC
++    IFUNC_IMPL (i, name, wcscmp,
++# if HAVE_WCSCMP_Z13
++		IFUNC_IMPL_ADD (array, i, wcscmp,
++				dl_hwcap & HWCAP_S390_VX, WCSCMP_Z13)
++# endif
++# if HAVE_WCSCMP_C
++		IFUNC_IMPL_ADD (array, i, wcscmp, 1, WCSCMP_C)
++# endif
++		)
++#endif /* HAVE_WCSCMP_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -536,8 +549,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcscmp);
+-
+   IFUNC_VX_IMPL (wcsncmp);
+ 
+   IFUNC_VX_IMPL (wcschr);
+diff --git a/sysdeps/s390/multiarch/wcscmp-c.c b/sysdeps/s390/wcscmp-c.c
+similarity index 72%
+rename from sysdeps/s390/multiarch/wcscmp-c.c
+rename to sysdeps/s390/wcscmp-c.c
+index ce0817ae97deab77..643ba7a682469e73 100644
+--- a/sysdeps/s390/multiarch/wcscmp-c.c
++++ b/sysdeps/s390/wcscmp-c.c
+@@ -16,17 +16,19 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSCMP  __wcscmp_c
++#include <ifunc-wcscmp.h>
+ 
+-# include <wchar.h>
+-extern __typeof (wcscmp) __wcscmp_c;
+-# undef weak_alias
+-# define weak_alias(name, alias)
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)				\
++#if HAVE_WCSCMP_C
++# if HAVE_WCSCMP_IFUNC
++#  define WCSCMP WCSCMP_C
++#  undef weak_alias
++#  define weak_alias(name, alias)
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   define libc_hidden_def(name)				\
+   __hidden_ver1 (__wcscmp_c, __GI___wcscmp, __wcscmp_c);
+-# endif /* SHARED */
++#  endif
++# endif
++
+ # include <wcsmbs/wcscmp.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/wcscmp-vx.S b/sysdeps/s390/wcscmp-vx.S
+similarity index 92%
+rename from sysdeps/s390/multiarch/wcscmp-vx.S
+rename to sysdeps/s390/wcscmp-vx.S
+index 14267dbfc7d9b936..a2789d8a693802cc 100644
+--- a/sysdeps/s390/multiarch/wcscmp-vx.S
++++ b/sysdeps/s390/wcscmp-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscmp.h>
++#if HAVE_WCSCMP_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -36,7 +37,7 @@
+    -v17=part of s2
+    -v18=index of unequal
+ */
+-ENTRY(__wcscmp_vx)
++ENTRY(WCSCMP_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -127,5 +128,14 @@ ENTRY(__wcscmp_vx)
+ .Lend_equal:
+ 	lghi	%r2,0
+ 	br	%r14
+-END(__wcscmp_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(WCSCMP_Z13)
++
++# if ! HAVE_WCSCMP_IFUNC
++strong_alias (WCSCMP_Z13, __wcscmp)
++weak_alias (__wcscmp, wcscmp)
++# endif
++
++# if ! HAVE_WCSCMP_C && defined SHARED && IS_IN (libc)
++strong_alias (WCSCMP_Z13, __GI___wcscmp)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/wcscmp.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wcscmp.c
+rename to sysdeps/s390/wcscmp.c
+index 5ee0fd4d881db9cb..769c73506e40c3a0 100644
+--- a/sysdeps/s390/multiarch/wcscmp.c
++++ b/sysdeps/s390/wcscmp.c
+@@ -16,15 +16,26 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscmp.h>
++
++#if HAVE_WCSCMP_IFUNC
+ # define __wcscmp __redirect___wcscmp
+ # include <wchar.h>
+ # undef __wcscmp
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp)
+-weak_alias (__wcscmp, wcscmp)
++# if HAVE_WCSCMP_C
++extern __typeof (__redirect___wcscmp) WCSCMP_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcscmp.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCSCMP_Z13
++extern __typeof (__redirect___wcscmp) WCSCMP_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___wcscmp, __wcscmp,
++		      (HAVE_WCSCMP_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSCMP_Z13
++		      : WCSCMP_DEFAULT
++		      )
++weak_alias (__wcscmp, wcscmp)
++#endif
diff --git a/SOURCES/glibc-rh1659438-45.patch b/SOURCES/glibc-rh1659438-45.patch
new file mode 100644
index 0000000..a4233ac
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-45.patch
@@ -0,0 +1,245 @@
+commit e9873e1d47c870d707117ada91c9be21e3bf1537
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:21 2018 +0100
+
+    S390: Refactor wcsncmp ifunc handling.
+    
+    The ifunc handling for wcsncmp is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcsncmp variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcsncmp variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncmp.
+            * sysdeps/s390/multiarch/wcsncmp-c.c: Move to ...
+            * sysdeps/s390/wcsncmp-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsncmp-vx.S: Move to ...
+            * sysdeps/s390/wcsncmp-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsncmp.c: Move to ...
+            * sysdeps/s390/wcsncmp.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcsncmp.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index fb104af231c48d3a..9146b32a939fd5bd 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -68,5 +68,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcpncpy wcpncpy-vx wcpncpy-c \
+ 		   wcscat wcscat-vx wcscat-c \
+ 		   wcsncat wcsncat-vx wcsncat-c \
+-		   wcscmp wcscmp-vx wcscmp-c
++		   wcscmp wcscmp-vx wcscmp-c \
++		   wcsncmp wcsncmp-vx wcsncmp-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcsncmp.h b/sysdeps/s390/ifunc-wcsncmp.h
+new file mode 100644
+index 0000000000000000..3a22bc9c126107ad
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcsncmp.h
+@@ -0,0 +1,52 @@
++/* wcsncmp variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSNCMP_IFUNC	1
++#else
++# define HAVE_WCSNCMP_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT HAVE_WCSNCMP_IFUNC
++#else
++# define HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSNCMP_DEFAULT	WCSNCMP_Z13
++# define HAVE_WCSNCMP_C		0
++# define HAVE_WCSNCMP_Z13	1
++#else
++# define WCSNCMP_DEFAULT	WCSNCMP_C
++# define HAVE_WCSNCMP_C		1
++# define HAVE_WCSNCMP_Z13	HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSNCMP_C
++# define WCSNCMP_C		__wcsncmp_c
++#else
++# define WCSNCMP_C		NULL
++#endif
++
++#if HAVE_WCSNCMP_Z13
++# define WCSNCMP_Z13		__wcsncmp_vx
++#else
++# define WCSNCMP_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 70162d0eaa6a0dee..d1740fa8e4f5faa8 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcsncmp wcsncmp-vx wcsncmp-c \
+-		   wcschr wcschr-vx wcschr-c \
++sysdep_routines += wcschr wcschr-vx wcschr-c \
+ 		   wcschrnul wcschrnul-vx wcschrnul-c \
+ 		   wcsrchr wcsrchr-vx wcsrchr-c \
+ 		   wcsspn wcsspn-vx wcsspn-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index f461063c80b364fb..8c9e788ae5962e2a 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -55,6 +55,7 @@
+ #include <ifunc-wcscat.h>
+ #include <ifunc-wcsncat.h>
+ #include <ifunc-wcscmp.h>
++#include <ifunc-wcsncmp.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -541,6 +542,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSCMP_IFUNC  */
+ 
++#if HAVE_WCSNCMP_IFUNC
++    IFUNC_IMPL (i, name, wcsncmp,
++# if HAVE_WCSNCMP_Z13
++		IFUNC_IMPL_ADD (array, i, wcsncmp,
++				dl_hwcap & HWCAP_S390_VX, WCSNCMP_Z13)
++# endif
++# if HAVE_WCSNCMP_C
++		IFUNC_IMPL_ADD (array, i, wcsncmp, 1, WCSNCMP_C)
++# endif
++		)
++#endif /* HAVE_WCSNCMP_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -549,8 +562,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcsncmp);
+-
+   IFUNC_VX_IMPL (wcschr);
+ 
+   IFUNC_VX_IMPL (wcschrnul);
+diff --git a/sysdeps/s390/multiarch/wcsncmp-c.c b/sysdeps/s390/wcsncmp-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wcsncmp-c.c
+rename to sysdeps/s390/wcsncmp-c.c
+index 92ab5e8b50bd93d0..a9ccb8de8276e97c 100644
+--- a/sysdeps/s390/multiarch/wcsncmp-c.c
++++ b/sysdeps/s390/wcsncmp-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSNCMP  __wcsncmp_c
++#include <ifunc-wcsncmp.h>
++
++#if HAVE_WCSNCMP_C
++# if HAVE_WCSNCMP_IFUNC
++#  define WCSNCMP WCSNCMP_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (wcsncmp) __wcsncmp_c;
+ # include <wcsmbs/wcsncmp.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/wcsncmp-vx.S
+rename to sysdeps/s390/wcsncmp-vx.S
+index 34c203bc90b2b012..9bdd21acefc2d44d 100644
+--- a/sysdeps/s390/multiarch/wcsncmp-vx.S
++++ b/sysdeps/s390/wcsncmp-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsncmp.h>
++#if HAVE_WCSNCMP_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +38,7 @@
+    -v17=part of s2
+    -v18=index of unequal
+ */
+-ENTRY(__wcsncmp_vx)
++ENTRY(WCSNCMP_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -173,5 +174,9 @@ ENTRY(__wcsncmp_vx)
+ 	lghi	%r1,-1
+ 	locgrl	%r2,%r1
+ 	br	%r14
+-END(__wcsncmp_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(WCSNCMP_Z13)
++
++# if ! HAVE_WCSNCMP_IFUNC
++strong_alias (WCSNCMP_Z13, wcsncmp)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcsncmp.c b/sysdeps/s390/wcsncmp.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/wcsncmp.c
+rename to sysdeps/s390/wcsncmp.c
+index ee5f08c1e4106495..101db445918b0f7d 100644
+--- a/sysdeps/s390/multiarch/wcsncmp.c
++++ b/sysdeps/s390/wcsncmp.c
+@@ -16,12 +16,23 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsncmp.h>
++
++#if HAVE_WCSNCMP_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2 (__wcsncmp, wcsncmp)
++# if HAVE_WCSNCMP_C
++extern __typeof (wcsncmp) WCSNCMP_C attribute_hidden;
++# endif
++
++# if HAVE_WCSNCMP_Z13
++extern __typeof (wcsncmp) WCSNCMP_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcsncmp.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (wcsncmp, wcsncmp,
++		      (HAVE_WCSNCMP_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSNCMP_Z13
++		      : WCSNCMP_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-46.patch b/SOURCES/glibc-rh1659438-46.patch
new file mode 100644
index 0000000..a4a0eb0
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-46.patch
@@ -0,0 +1,292 @@
+commit cf3ccc31a3d76a9b4db410d3087055c3aff2b71b
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:22 2018 +0100
+
+    S390: Refactor wcschr ifunc handling.
+    
+    The ifunc handling for wcschr is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    Glibc internal calls will use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcschr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcschr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcschr.
+            * sysdeps/s390/multiarch/wcschr-c.c: Move to ...
+            * sysdeps/s390/wcschr-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcschr-vx.S: Move to ...
+            * sysdeps/s390/wcschr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcschr.c: Move to ...
+            * sysdeps/s390/wcschr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcschr.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 9146b32a939fd5bd..91ee84a54b713e4a 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -69,5 +69,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcscat wcscat-vx wcscat-c \
+ 		   wcsncat wcsncat-vx wcsncat-c \
+ 		   wcscmp wcscmp-vx wcscmp-c \
+-		   wcsncmp wcsncmp-vx wcsncmp-c
++		   wcsncmp wcsncmp-vx wcsncmp-c \
++		   wcschr wcschr-vx wcschr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcschr.h b/sysdeps/s390/ifunc-wcschr.h
+new file mode 100644
+index 0000000000000000..2fe9110f7c9564d2
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcschr.h
+@@ -0,0 +1,53 @@
++/* wcschr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSCHR_IFUNC	1
++#else
++# define HAVE_WCSCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT HAVE_WCSCHR_IFUNC
++#else
++# define HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSCHR_DEFAULT		WCSCHR_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSCHR_C		1
++# define HAVE_WCSCHR_Z13	1
++#else
++# define WCSCHR_DEFAULT		WCSCHR_C
++# define HAVE_WCSCHR_C		1
++# define HAVE_WCSCHR_Z13	HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSCHR_C
++# define WCSCHR_C		__wcschr_c
++#else
++# define WCSCHR_C		NULL
++#endif
++
++#if HAVE_WCSCHR_Z13
++# define WCSCHR_Z13		__wcschr_vx
++#else
++# define WCSCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index d1740fa8e4f5faa8..b282613b4705bb14 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcschr wcschr-vx wcschr-c \
+-		   wcschrnul wcschrnul-vx wcschrnul-c \
++sysdep_routines += wcschrnul wcschrnul-vx wcschrnul-c \
+ 		   wcsrchr wcsrchr-vx wcsrchr-c \
+ 		   wcsspn wcsspn-vx wcsspn-c \
+ 		   wcspbrk wcspbrk-vx wcspbrk-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 8c9e788ae5962e2a..c69165465dc97111 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -56,6 +56,7 @@
+ #include <ifunc-wcsncat.h>
+ #include <ifunc-wcscmp.h>
+ #include <ifunc-wcsncmp.h>
++#include <ifunc-wcschr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -554,6 +555,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSNCMP_IFUNC  */
+ 
++#if HAVE_WCSCHR_IFUNC
++    IFUNC_IMPL (i, name, wcschr,
++# if HAVE_WCSCHR_Z13
++		IFUNC_IMPL_ADD (array, i, wcschr,
++				dl_hwcap & HWCAP_S390_VX, WCSCHR_Z13)
++# endif
++# if HAVE_WCSCHR_C
++		IFUNC_IMPL_ADD (array, i, wcschr, 1, WCSCHR_C)
++# endif
++		)
++#endif /* HAVE_WCSCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -562,8 +575,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcschr);
+-
+   IFUNC_VX_IMPL (wcschrnul);
+ 
+   IFUNC_VX_IMPL (wcsrchr);
+diff --git a/sysdeps/s390/multiarch/wcschr-c.c b/sysdeps/s390/wcschr-c.c
+similarity index 61%
+rename from sysdeps/s390/multiarch/wcschr-c.c
+rename to sysdeps/s390/wcschr-c.c
+index 8d6679c7f2f89864..4908492a0a72ed28 100644
+--- a/sysdeps/s390/multiarch/wcschr-c.c
++++ b/sysdeps/s390/wcschr-c.c
+@@ -16,22 +16,29 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSCHR  __wcschr_c
+-
+-# include <wchar.h>
+-extern __typeof (__wcschr) __wcschr_c;
+-# undef weak_alias
+-# define weak_alias(name, alias)
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)					\
+-  __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c);		\
+-  strong_alias (__wcschr_c, __wcschr_c_1);			\
++#include <ifunc-wcschr.h>
++
++#if HAVE_WCSCHR_C
++# if HAVE_WCSCHR_IFUNC || HAVE_WCSCHR_Z13
++#  define WCSCHR WCSCHR_C
++
++#  undef weak_alias
++#  define weak_alias(name, alias)
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_weak
++#   define libc_hidden_weak(name)
++#   undef libc_hidden_def
++#   if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#    define libc_hidden_def(name)					\
++  __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c)  __attribute__((weak)); \
++  strong_alias (__wcschr_c, __wcschr_c_1);				\
+   __hidden_ver1 (__wcschr_c_1, __GI___wcschr, __wcschr_c_1);
+-#  undef libc_hidden_weak
+-#  define libc_hidden_weak(name)
+-# endif /* SHARED */
++#   else
++#    define libc_hidden_def(name)
++#   endif
++#  endif
++# endif
+ 
+ # include <wcsmbs/wcschr.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/wcschr-vx.S b/sysdeps/s390/wcschr-vx.S
+similarity index 88%
+rename from sysdeps/s390/multiarch/wcschr-vx.S
+rename to sysdeps/s390/wcschr-vx.S
+index 94e5df7f365aa361..dd24998390c7e2e6 100644
+--- a/sysdeps/s390/multiarch/wcschr-vx.S
++++ b/sysdeps/s390/wcschr-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcschr.h>
++#if HAVE_WCSCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -36,7 +37,7 @@
+    -v17=index of unequal
+    -v18=replicated c
+ */
+-ENTRY(__wcschr_vx)
++ENTRY(WCSCHR_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -98,6 +99,17 @@ ENTRY(__wcschr_vx)
+ 	lghi	%r2,0		/* Return null if character not found.  */
+ 	br	%r14
+ .Lfallback:
+-	jg	__wcschr_c
+-END(__wcschr_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSCHR_C
++END(WCSCHR_Z13)
++
++# if ! HAVE_WCSCHR_IFUNC
++strong_alias (WCSCHR_Z13, __wcschr)
++weak_alias (__wcschr, wcschr)
++# endif
++
++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \
++	&& defined SHARED && IS_IN (libc)
++strong_alias (WCSCHR_Z13, __GI___wcschr)
++weak_alias (WCSCHR_Z13, __GI_wcschr)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/wcschr.c
+similarity index 71%
+rename from sysdeps/s390/multiarch/wcschr.c
+rename to sysdeps/s390/wcschr.c
+index f44138f771f9f9cb..9923864ff8f5ef1f 100644
+--- a/sysdeps/s390/multiarch/wcschr.c
++++ b/sysdeps/s390/wcschr.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcschr.h>
++
++#if HAVE_WCSCHR_IFUNC
+ # define wcschr __redirect_wcschr
+ # define __wcschr __redirect___wcschr
+ # include <wchar.h>
+@@ -24,9 +26,18 @@
+ # undef __wcschr
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc_redirected (__redirect___wcschr, __wcschr)
+-weak_alias (__wcschr, wcschr)
++# if HAVE_WCSCHR_C
++extern __typeof (__redirect___wcschr) WCSCHR_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcschr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCSCHR_Z13
++extern __typeof (__redirect___wcschr) WCSCHR_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___wcschr, __wcschr,
++		      (HAVE_WCSCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSCHR_Z13
++		      : WCSCHR_DEFAULT
++		      )
++weak_alias (__wcschr, wcschr)
++#endif
diff --git a/SOURCES/glibc-rh1659438-47.patch b/SOURCES/glibc-rh1659438-47.patch
new file mode 100644
index 0000000..d79d982
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-47.patch
@@ -0,0 +1,252 @@
+commit c09c1b6f014a45f6c4ba189f5ae94b1fb1a2982a
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:22 2018 +0100
+
+    S390: Refactor wcschrnul ifunc handling.
+    
+    The ifunc handling for wcschrnul is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcschrnul variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcschrnul variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcschrnul.
+            * sysdeps/s390/multiarch/wcschrnul-c.c: Move to ...
+            * sysdeps/s390/wcschrnul-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcschrnul-vx.S: Move to ...
+            * sysdeps/s390/wcschrnul-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcschrnul.c: Move to ...
+            * sysdeps/s390/wcschrnul.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcschrnul.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 91ee84a54b713e4a..a6ebf11ad1913cc4 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -70,5 +70,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsncat wcsncat-vx wcsncat-c \
+ 		   wcscmp wcscmp-vx wcscmp-c \
+ 		   wcsncmp wcsncmp-vx wcsncmp-c \
+-		   wcschr wcschr-vx wcschr-c
++		   wcschr wcschr-vx wcschr-c \
++		   wcschrnul wcschrnul-vx wcschrnul-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcschrnul.h b/sysdeps/s390/ifunc-wcschrnul.h
+new file mode 100644
+index 0000000000000000..39d4120eb3cfafdf
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcschrnul.h
+@@ -0,0 +1,53 @@
++/* wcschrnul variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSCHRNUL_IFUNC	1
++#else
++# define HAVE_WCSCHRNUL_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT HAVE_WCSCHRNUL_IFUNC
++#else
++# define HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSCHRNUL_DEFAULT	WCSCHRNUL_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSCHRNUL_C	1
++# define HAVE_WCSCHRNUL_Z13	1
++#else
++# define WCSCHRNUL_DEFAULT	WCSCHRNUL_C
++# define HAVE_WCSCHRNUL_C	1
++# define HAVE_WCSCHRNUL_Z13	HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSCHRNUL_C
++# define WCSCHRNUL_C		__wcschrnul_c
++#else
++# define WCSCHRNUL_C		NULL
++#endif
++
++#if HAVE_WCSCHRNUL_Z13
++# define WCSCHRNUL_Z13		__wcschrnul_vx
++#else
++# define WCSCHRNUL_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index b282613b4705bb14..0eb01d5d84c60408 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcschrnul wcschrnul-vx wcschrnul-c \
+-		   wcsrchr wcsrchr-vx wcsrchr-c \
++sysdep_routines += wcsrchr wcsrchr-vx wcsrchr-c \
+ 		   wcsspn wcsspn-vx wcsspn-c \
+ 		   wcspbrk wcspbrk-vx wcspbrk-c \
+ 		   wcscspn wcscspn-vx wcscspn-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index c69165465dc97111..553a76c39ecc87ae 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -57,6 +57,7 @@
+ #include <ifunc-wcscmp.h>
+ #include <ifunc-wcsncmp.h>
+ #include <ifunc-wcschr.h>
++#include <ifunc-wcschrnul.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -567,6 +568,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSCHR_IFUNC  */
+ 
++#if HAVE_WCSCHRNUL_IFUNC
++    IFUNC_IMPL (i, name, wcschrnul,
++# if HAVE_WCSCHRNUL_Z13
++		IFUNC_IMPL_ADD (array, i, wcschrnul,
++				dl_hwcap & HWCAP_S390_VX, WCSCHRNUL_Z13)
++# endif
++# if HAVE_WCSCHRNUL_C
++		IFUNC_IMPL_ADD (array, i, wcschrnul, 1, WCSCHRNUL_C)
++# endif
++		)
++#endif /* HAVE_WCSCHRNUL_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -575,8 +588,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcschrnul);
+-
+   IFUNC_VX_IMPL (wcsrchr);
+ 
+   IFUNC_VX_IMPL (wcsspn);
+diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/wcschrnul-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wcschrnul-c.c
+rename to sysdeps/s390/wcschrnul-c.c
+index 00e776a3adc11e67..410cee1399a67914 100644
+--- a/sysdeps/s390/multiarch/wcschrnul-c.c
++++ b/sysdeps/s390/wcschrnul-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSCHRNUL  __wcschrnul_c
++#include <ifunc-wcschrnul.h>
++
++#if HAVE_WCSCHRNUL_C
++# if HAVE_WCSCHRNUL_IFUNC || HAVE_WCSCHRNUL_Z13
++#  define WCSCHRNUL WCSCHRNUL_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (__wcschrnul) __wcschrnul_c;
+ # include <wcsmbs/wcschrnul.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcschrnul-vx.S b/sysdeps/s390/wcschrnul-vx.S
+similarity index 92%
+rename from sysdeps/s390/multiarch/wcschrnul-vx.S
+rename to sysdeps/s390/wcschrnul-vx.S
+index ebcd32b8703608d6..4ffb937c6bbd7008 100644
+--- a/sysdeps/s390/multiarch/wcschrnul-vx.S
++++ b/sysdeps/s390/wcschrnul-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcschrnul.h>
++#if HAVE_WCSCHRNUL_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -35,7 +36,7 @@
+    -v16=part of s
+    -v18=vector with c replicated in every byte
+ */
+-ENTRY(__wcschrnul_vx)
++ENTRY(WCSCHRNUL_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -92,6 +93,11 @@ ENTRY(__wcschrnul_vx)
+ .Lend:
+ 	br	%r14
+ .Lfallback:
+-	jg	__wcschrnul_c
+-END(__wcschrnul_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSCHRNUL_C
++END(WCSCHRNUL_Z13)
++
++# if ! HAVE_WCSCHRNUL_IFUNC
++strong_alias (WCSCHRNUL_Z13, __wcschrnul)
++weak_alias (__wcschrnul, wcschrnul)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/wcschrnul.c
+similarity index 68%
+rename from sysdeps/s390/multiarch/wcschrnul.c
+rename to sysdeps/s390/wcschrnul.c
+index 807d7ee08963a601..ab5aaf04020bb571 100644
+--- a/sysdeps/s390/multiarch/wcschrnul.c
++++ b/sysdeps/s390/wcschrnul.c
+@@ -16,13 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcschrnul.h>
++
++#if HAVE_WCSCHRNUL_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc (__wcschrnul)
+-weak_alias (__wcschrnul, wcschrnul)
++# if HAVE_WCSCHRNUL_C
++extern __typeof (__wcschrnul) WCSCHRNUL_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcschrnul.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WCSCHRNUL_Z13
++extern __typeof (__wcschrnul) WCSCHRNUL_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__wcschrnul, __wcschrnul,
++		      (HAVE_WCSCHRNUL_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSCHRNUL_Z13
++		      : WCSCHRNUL_DEFAULT
++		      )
++weak_alias (__wcschrnul, wcschrnul)
++#endif
diff --git a/SOURCES/glibc-rh1659438-48.patch b/SOURCES/glibc-rh1659438-48.patch
new file mode 100644
index 0000000..f786c3b
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-48.patch
@@ -0,0 +1,249 @@
+commit 4753713aaed400d88cfc598e25d504478120b065
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:22 2018 +0100
+
+    S390: Refactor wcsrchr ifunc handling.
+    
+    The ifunc handling for wcsrchr is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcsrchr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcsrchr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcsrchr.
+            * sysdeps/s390/multiarch/wcsrchr-c.c: Move to ...
+            * sysdeps/s390/wcsrchr-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsrchr-vx.S: Move to ...
+            * sysdeps/s390/wcsrchr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsrchr.c: Move to ...
+            * sysdeps/s390/wcsrchr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcsrchr.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index a6ebf11ad1913cc4..19a556eccf285e2f 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -71,5 +71,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcscmp wcscmp-vx wcscmp-c \
+ 		   wcsncmp wcsncmp-vx wcsncmp-c \
+ 		   wcschr wcschr-vx wcschr-c \
+-		   wcschrnul wcschrnul-vx wcschrnul-c
++		   wcschrnul wcschrnul-vx wcschrnul-c \
++		   wcsrchr wcsrchr-vx wcsrchr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcsrchr.h b/sysdeps/s390/ifunc-wcsrchr.h
+new file mode 100644
+index 0000000000000000..4eec0c17074c99fc
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcsrchr.h
+@@ -0,0 +1,53 @@
++/* wcsrchr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSRCHR_IFUNC	1
++#else
++# define HAVE_WCSRCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT HAVE_WCSRCHR_IFUNC
++#else
++# define HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSRCHR_DEFAULT	WCSRCHR_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSRCHR_C		1
++# define HAVE_WCSRCHR_Z13	1
++#else
++# define WCSRCHR_DEFAULT	WCSRCHR_C
++# define HAVE_WCSRCHR_C		1
++# define HAVE_WCSRCHR_Z13	HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSRCHR_C
++# define WCSRCHR_C		__wcsrchr_c
++#else
++# define WCSRCHR_C		NULL
++#endif
++
++#if HAVE_WCSRCHR_Z13
++# define WCSRCHR_Z13		__wcsrchr_vx
++#else
++# define WCSRCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 0eb01d5d84c60408..3d72cbb5f32e68f3 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcsrchr wcsrchr-vx wcsrchr-c \
+-		   wcsspn wcsspn-vx wcsspn-c \
++sysdep_routines += wcsspn wcsspn-vx wcsspn-c \
+ 		   wcspbrk wcspbrk-vx wcspbrk-c \
+ 		   wcscspn wcscspn-vx wcscspn-c \
+ 		   wmemchr wmemchr-vx wmemchr-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 553a76c39ecc87ae..ffb4d5b6872ef9db 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -58,6 +58,7 @@
+ #include <ifunc-wcsncmp.h>
+ #include <ifunc-wcschr.h>
+ #include <ifunc-wcschrnul.h>
++#include <ifunc-wcsrchr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -580,6 +581,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSCHRNUL_IFUNC  */
+ 
++#if HAVE_WCSRCHR_IFUNC
++    IFUNC_IMPL (i, name, wcsrchr,
++# if HAVE_WCSRCHR_Z13
++		IFUNC_IMPL_ADD (array, i, wcsrchr,
++				dl_hwcap & HWCAP_S390_VX, WCSRCHR_Z13)
++# endif
++# if HAVE_WCSRCHR_C
++		IFUNC_IMPL_ADD (array, i, wcsrchr, 1, WCSRCHR_C)
++# endif
++		)
++#endif /* HAVE_WCSRCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -588,8 +601,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcsrchr);
+-
+   IFUNC_VX_IMPL (wcsspn);
+ 
+   IFUNC_VX_IMPL (wcspbrk);
+diff --git a/sysdeps/s390/multiarch/wcsrchr-c.c b/sysdeps/s390/wcsrchr-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wcsrchr-c.c
+rename to sysdeps/s390/wcsrchr-c.c
+index 615250358ba9c00a..65164a897fb773f7 100644
+--- a/sysdeps/s390/multiarch/wcsrchr-c.c
++++ b/sysdeps/s390/wcsrchr-c.c
+@@ -16,10 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSRCHR  __wcsrchr_c
++#include <ifunc-wcsrchr.h>
++
++#if HAVE_WCSRCHR_C
++# if HAVE_WCSRCHR_IFUNC || HAVE_WCSRCHR_Z13
++#  define WCSRCHR WCSRCHR_C
++# endif
+ 
+-# include <wchar.h>
+-extern __typeof (wcsrchr) __wcsrchr_c;
+ # include <wcsmbs/wcsrchr.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcsrchr-vx.S b/sysdeps/s390/wcsrchr-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/wcsrchr-vx.S
+rename to sysdeps/s390/wcsrchr-vx.S
+index e40a554e5d9a216d..c7b6585beaeaef53 100644
+--- a/sysdeps/s390/multiarch/wcsrchr-vx.S
++++ b/sysdeps/s390/wcsrchr-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsrchr.h>
++#if HAVE_WCSRCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -39,7 +40,7 @@
+    -v19=part of s with last occurence of c.
+    -v20=permute pattern
+ */
+-ENTRY(__wcsrchr_vx)
++ENTRY(WCSRCHR_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -185,6 +186,10 @@ ENTRY(__wcsrchr_vx)
+ 	.byte	0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B
+ 	.byte	0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03
+ .Lfallback:
+-	jg	__wcsrchr_c
+-END(__wcsrchr_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSRCHR_C
++END(WCSRCHR_Z13)
++
++# if ! HAVE_WCSRCHR_IFUNC
++strong_alias (WCSRCHR_Z13, wcsrchr)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcsrchr.c b/sysdeps/s390/wcsrchr.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/wcsrchr.c
+rename to sysdeps/s390/wcsrchr.c
+index aa0b8a8f82545f64..eb70f270383880f2 100644
+--- a/sysdeps/s390/multiarch/wcsrchr.c
++++ b/sysdeps/s390/wcsrchr.c
+@@ -16,12 +16,23 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsrchr.h>
++
++#if HAVE_WCSRCHR_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2 (__wcsrchr, wcsrchr)
++# if HAVE_WCSRCHR_C
++extern __typeof (wcsrchr) WCSRCHR_C attribute_hidden;
++# endif
++
++# if HAVE_WCSRCHR_Z13
++extern __typeof (wcsrchr) WCSRCHR_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcsrchr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (wcsrchr, wcsrchr,
++		      (HAVE_WCSRCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSRCHR_Z13
++		      : WCSRCHR_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-49.patch b/SOURCES/glibc-rh1659438-49.patch
new file mode 100644
index 0000000..3508d5e
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-49.patch
@@ -0,0 +1,271 @@
+commit 8507e831907ff46d06382fe453c6832db2594e0b
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:23 2018 +0100
+
+    S390: Refactor wcsspn ifunc handling.
+    
+    The ifunc handling for wcsspn is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    Glibc internal calls will use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcsspn variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcsspn variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcsspn.
+            * sysdeps/s390/multiarch/wcsspn-c.c: Move to ...
+            * sysdeps/s390/wcsspn-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsspn-vx.S: Move to ...
+            * sysdeps/s390/wcsspn-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcsspn.c: Move to ...
+            * sysdeps/s390/wcsspn.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcsspn.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 19a556eccf285e2f..38dbba8ccfd3cd66 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -72,5 +72,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsncmp wcsncmp-vx wcsncmp-c \
+ 		   wcschr wcschr-vx wcschr-c \
+ 		   wcschrnul wcschrnul-vx wcschrnul-c \
+-		   wcsrchr wcsrchr-vx wcsrchr-c
++		   wcsrchr wcsrchr-vx wcsrchr-c \
++		   wcsspn wcsspn-vx wcsspn-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcsspn.h b/sysdeps/s390/ifunc-wcsspn.h
+new file mode 100644
+index 0000000000000000..1189c6b93ff9fbec
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcsspn.h
+@@ -0,0 +1,53 @@
++/* wcsspn variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSSPN_IFUNC	1
++#else
++# define HAVE_WCSSPN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT HAVE_WCSSPN_IFUNC
++#else
++# define HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSSPN_DEFAULT		WCSSPN_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSSPN_C		1
++# define HAVE_WCSSPN_Z13	1
++#else
++# define WCSSPN_DEFAULT		WCSSPN_C
++# define HAVE_WCSSPN_C		1
++# define HAVE_WCSSPN_Z13	HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSSPN_C
++# define WCSSPN_C		__wcsspn_c
++#else
++# define WCSSPN_C		NULL
++#endif
++
++#if HAVE_WCSSPN_Z13
++# define WCSSPN_Z13		__wcsspn_vx
++#else
++# define WCSSPN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 3d72cbb5f32e68f3..091f5150847a404a 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcsspn wcsspn-vx wcsspn-c \
+-		   wcspbrk wcspbrk-vx wcspbrk-c \
++sysdep_routines += wcspbrk wcspbrk-vx wcspbrk-c \
+ 		   wcscspn wcscspn-vx wcscspn-c \
+ 		   wmemchr wmemchr-vx wmemchr-c \
+ 		   wmemset wmemset-vx wmemset-c \
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index ffb4d5b6872ef9db..6f4de2845ba0a378 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -59,6 +59,7 @@
+ #include <ifunc-wcschr.h>
+ #include <ifunc-wcschrnul.h>
+ #include <ifunc-wcsrchr.h>
++#include <ifunc-wcsspn.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -593,6 +594,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSRCHR_IFUNC  */
+ 
++#if HAVE_WCSSPN_IFUNC
++    IFUNC_IMPL (i, name, wcsspn,
++# if HAVE_WCSSPN_Z13
++		IFUNC_IMPL_ADD (array, i, wcsspn,
++				dl_hwcap & HWCAP_S390_VX, WCSSPN_Z13)
++# endif
++# if HAVE_WCSSPN_C
++		IFUNC_IMPL_ADD (array, i, wcsspn, 1, WCSSPN_C)
++# endif
++		)
++#endif /* HAVE_WCSSPN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -601,8 +614,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcsspn);
+-
+   IFUNC_VX_IMPL (wcspbrk);
+ 
+   IFUNC_VX_IMPL (wcscspn);
+diff --git a/sysdeps/s390/multiarch/wcsspn-c.c b/sysdeps/s390/wcsspn-c.c
+similarity index 72%
+rename from sysdeps/s390/multiarch/wcsspn-c.c
+rename to sysdeps/s390/wcsspn-c.c
+index 2c0bd0f4e69516de..db3bdb9b9f09e500 100644
+--- a/sysdeps/s390/multiarch/wcsspn-c.c
++++ b/sysdeps/s390/wcsspn-c.c
+@@ -16,16 +16,22 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSSPN  __wcsspn_c
++#include <ifunc-wcsspn.h>
+ 
+-# include <wchar.h>
+-extern __typeof (wcsspn) __wcsspn_c;
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)				\
++#if HAVE_WCSSPN_C
++# if HAVE_WCSSPN_IFUNC || HAVE_WCSSPN_Z13
++#  define WCSSPN WCSSPN_C
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#    define libc_hidden_def(name)			\
+   __hidden_ver1 (__wcsspn_c, __GI_wcsspn, __wcsspn_c);
+-# endif /* SHARED */
++#   else
++#    define libc_hidden_def(name)
++#   endif
++#  endif
++# endif
+ 
+ # include <wcsmbs/wcsspn.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/wcsspn-vx.S b/sysdeps/s390/wcsspn-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/wcsspn-vx.S
+rename to sysdeps/s390/wcsspn-vx.S
+index 548f2ad1644c8e88..61f7d6d0902125b7 100644
+--- a/sysdeps/s390/multiarch/wcsspn-vx.S
++++ b/sysdeps/s390/wcsspn-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsspn.h>
++#if HAVE_WCSSPN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -57,7 +58,7 @@
+ 	otherwise =0;
+    r9: loaded byte count of vlbb accept-string
+ */
+-ENTRY(__wcsspn_vx)
++ENTRY(WCSSPN_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -265,6 +266,15 @@ ENTRY(__wcsspn_vx)
+ 	j	.Lslow_next_acc_notonbb /* ... and search for zero in
+ 					   fully loaded vreg again.  */
+ .Lfallback:
+-	jg	__wcsspn_c
+-END(__wcsspn_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSSPN_C
++END(WCSSPN_Z13)
++
++# if ! HAVE_WCSSPN_IFUNC
++strong_alias (WCSSPN_Z13, wcsspn)
++# endif
++
++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \
++	&& defined SHARED && IS_IN (libc)
++strong_alias (WCSSPN_Z13, __GI_wcsspn)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/wcsspn.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/wcsspn.c
+rename to sysdeps/s390/wcsspn.c
+index 7743144a8ca7c2ee..e916b1e4414e774d 100644
+--- a/sysdeps/s390/multiarch/wcsspn.c
++++ b/sysdeps/s390/wcsspn.c
+@@ -16,14 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcsspn.h>
++
++#if HAVE_WCSSPN_IFUNC
+ # define wcsspn __redirect_wcsspn
+ # include <wchar.h>
+ # undef wcsspn
+ # include <ifunc-resolve.h>
++# if HAVE_WCSSPN_C
++extern __typeof (__redirect_wcsspn) WCSSPN_C attribute_hidden;
++# endif
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn)
++# if HAVE_WCSSPN_Z13
++extern __typeof (__redirect_wcsspn) WCSSPN_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcsspn.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_wcsspn, wcsspn,
++		      (HAVE_WCSSPN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSSPN_Z13
++		      : WCSSPN_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-5.patch b/SOURCES/glibc-rh1659438-5.patch
new file mode 100644
index 0000000..440659f
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-5.patch
@@ -0,0 +1,306 @@
+commit 07be392807ac78330da90f01408aa7e042a97a88
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:05 2018 +0100
+
+    S390: Implement bzero with memset.
+    
+    This patch removes the bzero s390 implementation with mvcle and
+    adds entry points for bzero in memset ifunc variants.
+    Therefore an ifunc resolver is implemented for bzero, too.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/s390-32/bzero.S: Delete file.
+            * sysdeps/s390/s390-64/bzero.S: Likewise.
+            * sysdeps/s390/Makefile (sysdep_routines): Add bzero.
+            * sysdeps/s390/bzero.c: New file.
+            * sysdeps/s390/memset-z900.S: Add bzero entry points.
+            * sysdeps/s390/ifunc-memset.h: Add bzero function macros.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Add bzero ifunc variants.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 360838e172f4ca37..e40e5bd982e54d89 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -31,5 +31,5 @@ sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules
+ endif
+ 
+ ifeq ($(subdir),string)
+-sysdep_routines += memset memset-z900
++sysdep_routines += bzero memset memset-z900
+ endif
+diff --git a/sysdeps/s390/s390-32/bzero.S b/sysdeps/s390/bzero.c
+similarity index 52%
+rename from sysdeps/s390/s390-32/bzero.S
+rename to sysdeps/s390/bzero.c
+index 897aa2154a861b7f..9f8d95781bf2fb68 100644
+--- a/sysdeps/s390/s390-32/bzero.S
++++ b/sysdeps/s390/bzero.c
+@@ -1,7 +1,6 @@
+-/* bzero -- set a block of memory to zero.  IBM S390 version
++/* Multiple versions of bzero.
++   Copyright (C) 2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+-   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+@@ -17,26 +16,32 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-/*
+- * R2 = address to memory area
+- * R3 = number of bytes to fill
+- */
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-	.text
+-ENTRY(__bzero)
+-	ltr     %r3,%r3
+-	jz      .L1
+-	sr      %r1,%r1             # set pad byte to zero
+-	sr      %r4,%r4             # no source for MVCLE, only a pad byte
+-	sr      %r5,%r5
+-.L0:    mvcle   %r2,%r4,0(%r1)      # thats it, MVCLE is your friend
+-	jo      .L0
+-.L1:    br      %r14
+-END(__bzero)
+-
+-#ifndef NO_WEAK_ALIAS
++#include <ifunc-memset.h>
++#if HAVE_MEMSET_IFUNC
++# include <string.h>
++# include <ifunc-resolve.h>
++
++# if HAVE_MEMSET_Z900_G5
++extern __typeof (__bzero) BZERO_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_MEMSET_Z10
++extern __typeof (__bzero) BZERO_Z10 attribute_hidden;
++# endif
++
++# if HAVE_MEMSET_Z196
++extern __typeof (__bzero) BZERO_Z196 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__bzero, __bzero,
++		      ({
++			s390_libc_ifunc_init ();
++			(HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits))
++			  ? BZERO_Z196
++			  : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits))
++			  ? BZERO_Z10
++			  : BZERO_DEFAULT;
++		      })
++		      )
+ weak_alias (__bzero, bzero)
+ #endif
+diff --git a/sysdeps/s390/ifunc-memset.h b/sysdeps/s390/ifunc-memset.h
+index 9a13b1001fed9979..32bc155f7e79fa26 100644
+--- a/sysdeps/s390/ifunc-memset.h
++++ b/sysdeps/s390/ifunc-memset.h
+@@ -25,16 +25,19 @@
+ 
+ #if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+ # define MEMSET_DEFAULT		MEMSET_Z196
++# define BZERO_DEFAULT		BZERO_Z196
+ # define HAVE_MEMSET_Z900_G5	0
+ # define HAVE_MEMSET_Z10	0
+ # define HAVE_MEMSET_Z196	1
+ #elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
+ # define MEMSET_DEFAULT		MEMSET_Z10
++# define BZERO_DEFAULT		BZERO_Z10
+ # define HAVE_MEMSET_Z900_G5	0
+ # define HAVE_MEMSET_Z10	1
+ # define HAVE_MEMSET_Z196	HAVE_MEMSET_IFUNC
+ #else
+ # define MEMSET_DEFAULT		MEMSET_Z900_G5
++# define BZERO_DEFAULT		BZERO_Z900_G5
+ # define HAVE_MEMSET_Z900_G5	1
+ # define HAVE_MEMSET_Z10	HAVE_MEMSET_IFUNC
+ # define HAVE_MEMSET_Z196	HAVE_MEMSET_IFUNC
+@@ -48,18 +51,24 @@
+ 
+ #if HAVE_MEMSET_Z900_G5
+ # define MEMSET_Z900_G5		__memset_default
++# define BZERO_Z900_G5		__bzero_default
+ #else
+ # define MEMSET_Z900_G5		NULL
++# define BZERO_Z900_G5		NULL
+ #endif
+ 
+ #if HAVE_MEMSET_Z10
+ # define MEMSET_Z10		__memset_z10
++# define BZERO_Z10		__bzero_z10
+ #else
+ # define MEMSET_Z10		NULL
++# define BZERO_Z10		NULL
+ #endif
+ 
+ #if HAVE_MEMSET_Z196
+ # define MEMSET_Z196		__memset_z196
++# define BZERO_Z196		__bzero_z196
+ #else
+ # define MEMSET_Z196		NULL
++# define BZERO_Z196		NULL
+ #endif
+diff --git a/sysdeps/s390/memset-z900.S b/sysdeps/s390/memset-z900.S
+index eaf13402bd3e251d..bfc659ae0b029eb4 100644
+--- a/sysdeps/s390/memset-z900.S
++++ b/sysdeps/s390/memset-z900.S
+@@ -22,10 +22,14 @@
+ #include "asm-syntax.h"
+ #include <ifunc-memset.h>
+ 
+-/* INPUT PARAMETERS
++/* INPUT PARAMETERS - MEMSET
+      %r2 = address of memory area
+      %r3 = byte to fill memory with
+-     %r4 = number of bytes to fill.  */
++     %r4 = number of bytes to fill.
++
++   INPUT PARAMETERS - BZERO
++     %r2 = address of memory area
++     %r3 = number of bytes to fill.  */
+ 
+        .text
+ 
+@@ -44,7 +48,14 @@
+ #  define BRCTG	brct
+ # endif /* ! defined __s390x__  */
+ 
++ENTRY(BZERO_Z900_G5)
++	LGR	%r4,%r3
++	xr	%r3,%r3
++	j	.L_Z900_G5_start
++END(BZERO_Z900_G5)
++
+ ENTRY(MEMSET_Z900_G5)
++.L_Z900_G5_start:
+ #if defined __s390x__
+ 	.machine "z900"
+ #else
+@@ -90,7 +101,16 @@ END(MEMSET_Z900_G5)
+ #endif /*  HAVE_MEMSET_Z900_G5  */
+ 
+ #if HAVE_MEMSET_Z10
++ENTRY(BZERO_Z10)
++	.machine "z10"
++	.machinemode "zarch_nohighgprs"
++	lgr	%r4,%r3
++	xr	%r3,%r3
++	j	.L_Z10_start
++END(BZERO_Z10)
++
+ ENTRY(MEMSET_Z10)
++.L_Z10_start:
+ 	.machine "z10"
+ 	.machinemode "zarch_nohighgprs"
+ # if !defined __s390x__
+@@ -122,7 +142,16 @@ END(MEMSET_Z10)
+ #endif /* HAVE_MEMSET_Z10  */
+ 
+ #if HAVE_MEMSET_Z196
++ENTRY(BZERO_Z196)
++	.machine "z196"
++	.machinemode "zarch_nohighgprs"
++	lgr	%r4,%r3
++	xr	%r3,%r3
++	j	.L_Z196_start
++END(BZERO_Z196)
++
+ ENTRY(MEMSET_Z196)
++.L_Z196_start:
+ 	.machine "z196"
+ 	.machinemode "zarch_nohighgprs"
+ # if !defined __s390x__
+@@ -177,6 +206,10 @@ END(__memset_mvcle)
+ /* If we don't use ifunc, define an alias for memset here.
+    Otherwise see sysdeps/s390/memset.c.  */
+ strong_alias (MEMSET_DEFAULT, memset)
++/* Same for bzero.  If ifunc is used, see
++   sysdeps/s390/bzero.c.  */
++strong_alias (BZERO_DEFAULT, __bzero)
++weak_alias (__bzero, bzero)
+ #endif
+ 
+ #if defined SHARED && IS_IN (libc)
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 2f671eac1f4f1ffd..253f36045b57cc3c 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -59,6 +59,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ # endif
+ # if HAVE_MEMSET_Z900_G5
+ 	      IFUNC_IMPL_ADD (array, i, memset, 1, MEMSET_Z900_G5)
++# endif
++	      )
++
++  /* Note: bzero is implemented in memset.  */
++  IFUNC_IMPL (i, name, bzero,
++# if HAVE_MEMSET_Z196
++	      IFUNC_IMPL_ADD (array, i, bzero,
++			      S390_IS_Z196 (stfle_bits), BZERO_Z196)
++# endif
++# if HAVE_MEMSET_Z10
++	      IFUNC_IMPL_ADD (array, i, bzero,
++			      S390_IS_Z10 (stfle_bits), BZERO_Z10)
++# endif
++# if HAVE_MEMSET_Z900_G5
++	      IFUNC_IMPL_ADD (array, i, bzero, 1, BZERO_Z900_G5)
+ # endif
+ 	      )
+ #endif /* HAVE_MEMSET_IFUNC */
+diff --git a/sysdeps/s390/s390-64/bzero.S b/sysdeps/s390/s390-64/bzero.S
+deleted file mode 100644
+index b3216652985cc239..0000000000000000
+--- a/sysdeps/s390/s390-64/bzero.S
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/* bzero -- set a block of memory to zero.  64 bit S/390 version.
+-   This file is part of the GNU C Library.
+-   Copyright (C) 2001-2018 Free Software Foundation, Inc.
+-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of memory area
+-     %r3 = number of bytes to fill.  */
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-	.text
+-ENTRY(__bzero)
+-	ltgr	%r3,%r3
+-	jz	.L1
+-	sgr	%r1,%r1		    # set pad byte to zero
+-	sgr	%r4,%r4		    # no source for MVCLE, only a pad byte
+-	sgr	%r5,%r5
+-.L0:	mvcle	%r2,%r4,0(%r1)	    # thats it, MVCLE is your friend
+-	jo	.L0
+-.L1:	br	%r14
+-END(__bzero)
+-
+-#ifndef NO_WEAK_ALIAS
+-weak_alias (__bzero, bzero)
+-#endif
diff --git a/SOURCES/glibc-rh1659438-50.patch b/SOURCES/glibc-rh1659438-50.patch
new file mode 100644
index 0000000..41d29db
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-50.patch
@@ -0,0 +1,271 @@
+commit 8e87c1f6d45a63dc2175825c2dc5d66192a13aab
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:23 2018 +0100
+
+    S390: Refactor wcspbrk ifunc handling.
+    
+    The ifunc handling for wcspbrk is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    Glibc internal calls will use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcspbrk variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcspbrk variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcspbrk.
+            * sysdeps/s390/multiarch/wcspbrk-c.c: Move to ...
+            * sysdeps/s390/wcspbrk-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcspbrk-vx.S: Move to ...
+            * sysdeps/s390/wcspbrk-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcspbrk.c: Move to ...
+            * sysdeps/s390/wcspbrk.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcspbrk.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 38dbba8ccfd3cd66..af595050d43c63ed 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -73,5 +73,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcschr wcschr-vx wcschr-c \
+ 		   wcschrnul wcschrnul-vx wcschrnul-c \
+ 		   wcsrchr wcsrchr-vx wcsrchr-c \
+-		   wcsspn wcsspn-vx wcsspn-c
++		   wcsspn wcsspn-vx wcsspn-c \
++		   wcspbrk wcspbrk-vx wcspbrk-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcspbrk.h b/sysdeps/s390/ifunc-wcspbrk.h
+new file mode 100644
+index 0000000000000000..d3b9b7363a73fab0
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcspbrk.h
+@@ -0,0 +1,53 @@
++/* wcspbrk variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSPBRK_IFUNC	1
++#else
++# define HAVE_WCSPBRK_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT HAVE_WCSPBRK_IFUNC
++#else
++# define HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSPBRK_DEFAULT	WCSPBRK_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSPBRK_C		1
++# define HAVE_WCSPBRK_Z13	1
++#else
++# define WCSPBRK_DEFAULT	WCSPBRK_C
++# define HAVE_WCSPBRK_C		1
++# define HAVE_WCSPBRK_Z13	HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSPBRK_C
++# define WCSPBRK_C		__wcspbrk_c
++#else
++# define WCSPBRK_C		NULL
++#endif
++
++#if HAVE_WCSPBRK_Z13
++# define WCSPBRK_Z13		__wcspbrk_vx
++#else
++# define WCSPBRK_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 091f5150847a404a..e1e2d9dc7495ebdc 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcspbrk wcspbrk-vx wcspbrk-c \
+-		   wcscspn wcscspn-vx wcscspn-c \
++sysdep_routines += wcscspn wcscspn-vx wcscspn-c \
+ 		   wmemchr wmemchr-vx wmemchr-c \
+ 		   wmemset wmemset-vx wmemset-c \
+ 		   wmemcmp wmemcmp-vx wmemcmp-c
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 6f4de2845ba0a378..89d6e8ad7e323fec 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -60,6 +60,7 @@
+ #include <ifunc-wcschrnul.h>
+ #include <ifunc-wcsrchr.h>
+ #include <ifunc-wcsspn.h>
++#include <ifunc-wcspbrk.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -606,6 +607,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSSPN_IFUNC  */
+ 
++#if HAVE_WCSPBRK_IFUNC
++    IFUNC_IMPL (i, name, wcspbrk,
++# if HAVE_WCSPBRK_Z13
++		IFUNC_IMPL_ADD (array, i, wcspbrk,
++				dl_hwcap & HWCAP_S390_VX, WCSPBRK_Z13)
++# endif
++# if HAVE_WCSPBRK_C
++		IFUNC_IMPL_ADD (array, i, wcspbrk, 1, WCSPBRK_C)
++# endif
++		)
++#endif /* HAVE_WCSPBRK_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -614,8 +627,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcspbrk);
+-
+   IFUNC_VX_IMPL (wcscspn);
+ 
+   IFUNC_VX_IMPL (wmemchr);
+diff --git a/sysdeps/s390/multiarch/wcspbrk-c.c b/sysdeps/s390/wcspbrk-c.c
+similarity index 72%
+rename from sysdeps/s390/multiarch/wcspbrk-c.c
+rename to sysdeps/s390/wcspbrk-c.c
+index 6b6e7aade46942ed..e79c6a85503dc32b 100644
+--- a/sysdeps/s390/multiarch/wcspbrk-c.c
++++ b/sysdeps/s390/wcspbrk-c.c
+@@ -16,16 +16,22 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSPBRK  __wcspbrk_c
++#include <ifunc-wcspbrk.h>
+ 
+-# include <wchar.h>
+-extern __typeof (wcspbrk) __wcspbrk_c;
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)				\
++#if HAVE_WCSPBRK_C
++# if HAVE_WCSPBRK_IFUNC || HAVE_WCSPBRK_Z13
++#  define WCSPBRK WCSPBRK_C
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_def
++#   if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#    define libc_hidden_def(name)			\
+   __hidden_ver1 (__wcspbrk_c, __GI_wcspbrk, __wcspbrk_c);
+-# endif /* SHARED */
++#   else
++#    define libc_hidden_def(name)
++#   endif
++#  endif
++# endif
+ 
+ # include <wcsmbs/wcspbrk.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/wcspbrk-vx.S b/sysdeps/s390/wcspbrk-vx.S
+similarity index 97%
+rename from sysdeps/s390/multiarch/wcspbrk-vx.S
+rename to sysdeps/s390/wcspbrk-vx.S
+index 5c89ec5d336c1acd..5870c4684d140ab0 100644
+--- a/sysdeps/s390/multiarch/wcspbrk-vx.S
++++ b/sysdeps/s390/wcspbrk-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcspbrk.h>
++#if HAVE_WCSPBRK_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -59,7 +60,7 @@
+ 	otherwise =0;
+    r9:  loaded byte count of vlbb accept-string
+ */
+-ENTRY(__wcspbrk_vx)
++ENTRY(WCSPBRK_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -310,6 +311,15 @@ ENTRY(__wcspbrk_vx)
+ 	lgr	%r2,%r1
+ 	br	%r14
+ .Lfallback:
+-	jg	__wcspbrk_c
+-END(__wcspbrk_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSPBRK_C
++END(WCSPBRK_Z13)
++
++# if ! HAVE_WCSPBRK_IFUNC
++strong_alias (WCSPBRK_Z13, wcspbrk)
++# endif
++
++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \
++	&& defined SHARED && IS_IN (libc)
++strong_alias (WCSPBRK_Z13, __GI_wcspbrk)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/wcspbrk.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/wcspbrk.c
+rename to sysdeps/s390/wcspbrk.c
+index 97876328b5ad9425..84ab911a24fba3c4 100644
+--- a/sysdeps/s390/multiarch/wcspbrk.c
++++ b/sysdeps/s390/wcspbrk.c
+@@ -16,14 +16,24 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcspbrk.h>
++
++#if HAVE_WCSPBRK_IFUNC
+ # define wcspbrk __redirect_wcspbrk
+ # include <wchar.h>
+ # undef wcspbrk
+ # include <ifunc-resolve.h>
++# if HAVE_WCSPBRK_C
++extern __typeof (__redirect_wcspbrk) WCSPBRK_C attribute_hidden;
++# endif
+ 
+-s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk)
++# if HAVE_WCSPBRK_Z13
++extern __typeof (__redirect_wcspbrk) WCSPBRK_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcspbrk.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (__redirect_wcspbrk, wcspbrk,
++		      (HAVE_WCSPBRK_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSPBRK_Z13
++		      : WCSPBRK_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-51.patch b/SOURCES/glibc-rh1659438-51.patch
new file mode 100644
index 0000000..264a0e1
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-51.patch
@@ -0,0 +1,249 @@
+commit 79b44cf61115bd48006227bb325b709f294c56f9
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:23 2018 +0100
+
+    S390: Refactor wcscspn ifunc handling.
+    
+    The ifunc handling for wcscspn is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wcscspn variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wcscspn variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wcscspn.
+            * sysdeps/s390/multiarch/wcscspn-c.c: Move to ...
+            * sysdeps/s390/wcscspn-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscspn-vx.S: Move to ...
+            * sysdeps/s390/wcscspn-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wcscspn.c: Move to ...
+            * sysdeps/s390/wcscspn.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wcscspn.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index af595050d43c63ed..da96ac3a36bd7f4e 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -74,5 +74,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcschrnul wcschrnul-vx wcschrnul-c \
+ 		   wcsrchr wcsrchr-vx wcsrchr-c \
+ 		   wcsspn wcsspn-vx wcsspn-c \
+-		   wcspbrk wcspbrk-vx wcspbrk-c
++		   wcspbrk wcspbrk-vx wcspbrk-c \
++		   wcscspn wcscspn-vx wcscspn-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wcscspn.h b/sysdeps/s390/ifunc-wcscspn.h
+new file mode 100644
+index 0000000000000000..23f3667ba3823e99
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wcscspn.h
+@@ -0,0 +1,53 @@
++/* wcscspn variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WCSCSPN_IFUNC	1
++#else
++# define HAVE_WCSCSPN_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT HAVE_WCSCSPN_IFUNC
++#else
++# define HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WCSCSPN_DEFAULT	WCSCSPN_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WCSCSPN_C		1
++# define HAVE_WCSCSPN_Z13	1
++#else
++# define WCSCSPN_DEFAULT	WCSCSPN_C
++# define HAVE_WCSCSPN_C		1
++# define HAVE_WCSCSPN_Z13	HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WCSCSPN_C
++# define WCSCSPN_C		__wcscspn_c
++#else
++# define WCSCSPN_C		NULL
++#endif
++
++#if HAVE_WCSCSPN_Z13
++# define WCSCSPN_Z13		__wcscspn_vx
++#else
++# define WCSCSPN_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index e1e2d9dc7495ebdc..5be635542361b355 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wcscspn wcscspn-vx wcscspn-c \
+-		   wmemchr wmemchr-vx wmemchr-c \
++sysdep_routines += wmemchr wmemchr-vx wmemchr-c \
+ 		   wmemset wmemset-vx wmemset-c \
+ 		   wmemcmp wmemcmp-vx wmemcmp-c
+ endif
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 89d6e8ad7e323fec..7d8031a069bd23ba 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -61,6 +61,7 @@
+ #include <ifunc-wcsrchr.h>
+ #include <ifunc-wcsspn.h>
+ #include <ifunc-wcspbrk.h>
++#include <ifunc-wcscspn.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -619,6 +620,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSPBRK_IFUNC  */
+ 
++#if HAVE_WCSCSPN_IFUNC
++    IFUNC_IMPL (i, name, wcscspn,
++# if HAVE_WCSCSPN_Z13
++		IFUNC_IMPL_ADD (array, i, wcscspn,
++				dl_hwcap & HWCAP_S390_VX, WCSCSPN_Z13)
++# endif
++# if HAVE_WCSCSPN_C
++		IFUNC_IMPL_ADD (array, i, wcscspn, 1, WCSCSPN_C)
++# endif
++		)
++#endif /* HAVE_WCSCSPN_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -627,8 +640,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wcscspn);
+-
+   IFUNC_VX_IMPL (wmemchr);
+ 
+   IFUNC_VX_IMPL (wmemset);
+diff --git a/sysdeps/s390/multiarch/wcscspn-c.c b/sysdeps/s390/wcscspn-c.c
+similarity index 86%
+rename from sysdeps/s390/multiarch/wcscspn-c.c
+rename to sysdeps/s390/wcscspn-c.c
+index 161e52e686c73907..d47cb6b75be14e14 100644
+--- a/sysdeps/s390/multiarch/wcscspn-c.c
++++ b/sysdeps/s390/wcscspn-c.c
+@@ -16,11 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WCSCSPN  __wcscspn_c
++#include <ifunc-wcscspn.h>
+ 
+-# include <wchar.h>
+-extern __typeof (wcscspn) __wcscspn_c;
++#if HAVE_WCSCSPN_C
++# if HAVE_WCSCSPN_IFUNC || HAVE_WCSCSPN_Z13
++#  define WCSCSPN WCSCSPN_C
++# endif
+ 
+ # include <wcsmbs/wcscspn.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wcscspn-vx.S b/sysdeps/s390/wcscspn-vx.S
+similarity index 98%
+rename from sysdeps/s390/multiarch/wcscspn-vx.S
+rename to sysdeps/s390/wcscspn-vx.S
+index 06bc4e25d0456aea..882cb93fb807caa1 100644
+--- a/sysdeps/s390/multiarch/wcscspn-vx.S
++++ b/sysdeps/s390/wcscspn-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscspn.h>
++#if HAVE_WCSCSPN_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -57,7 +58,7 @@
+ 			otherwise =0;
+    r9:  loaded byte count of vlbb reject-string
+ */
+-ENTRY(__wcscspn_vx)
++ENTRY(WCSCSPN_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -288,6 +289,10 @@ ENTRY(__wcscspn_vx)
+ 	vlgvg	%r9,%v31,1
+ 	br	%r14
+ .Lfallback:
+-	jg	__wcscspn_c
+-END(__wcscspn_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WCSCSPN_C
++END(WCSCSPN_Z13)
++
++# if ! HAVE_WCSCSPN_IFUNC
++strong_alias (WCSCSPN_Z13, wcscspn)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wcscspn.c b/sysdeps/s390/wcscspn.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/wcscspn.c
+rename to sysdeps/s390/wcscspn.c
+index 707327522ad20287..0ce31b8aabf3b429 100644
+--- a/sysdeps/s390/multiarch/wcscspn.c
++++ b/sysdeps/s390/wcscspn.c
+@@ -16,12 +16,23 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wcscspn.h>
++
++#if HAVE_WCSCSPN_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2 (__wcscspn, wcscspn)
++# if HAVE_WCSCSPN_C
++extern __typeof (wcscspn) WCSCSPN_C attribute_hidden;
++# endif
++
++# if HAVE_WCSCSPN_Z13
++extern __typeof (wcscspn) WCSCSPN_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wcscspn.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (wcscspn, wcscspn,
++		      (HAVE_WCSCSPN_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WCSCSPN_Z13
++		      : WCSCSPN_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-52.patch b/SOURCES/glibc-rh1659438-52.patch
new file mode 100644
index 0000000..c46c2ec
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-52.patch
@@ -0,0 +1,292 @@
+commit c62534ae524111eae48b2c2adf3f9a2ca90824f5
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:24 2018 +0100
+
+    S390: Refactor wmemchr ifunc handling.
+    
+    The ifunc handling for wmemchr is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    Glibc internal calls will use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wmemchr variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wmemchr variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wmemchr.
+            * sysdeps/s390/multiarch/wmemchr-c.c: Move to ...
+            * sysdeps/s390/wmemchr-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wmemchr-vx.S: Move to ...
+            * sysdeps/s390/wmemchr-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wmemchr.c: Move to ...
+            * sysdeps/s390/wmemchr.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wmemchr.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index da96ac3a36bd7f4e..fdfd1c605c28ddc7 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -75,5 +75,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsrchr wcsrchr-vx wcsrchr-c \
+ 		   wcsspn wcsspn-vx wcsspn-c \
+ 		   wcspbrk wcspbrk-vx wcspbrk-c \
+-		   wcscspn wcscspn-vx wcscspn-c
++		   wcscspn wcscspn-vx wcscspn-c \
++		   wmemchr wmemchr-vx wmemchr-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wmemchr.h b/sysdeps/s390/ifunc-wmemchr.h
+new file mode 100644
+index 0000000000000000..0610cfb5d4a7fb18
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wmemchr.h
+@@ -0,0 +1,53 @@
++/* wmemchr variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WMEMCHR_IFUNC	1
++#else
++# define HAVE_WMEMCHR_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT HAVE_WMEMCHR_IFUNC
++#else
++# define HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WMEMCHR_DEFAULT	WMEMCHR_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WMEMCHR_C		1
++# define HAVE_WMEMCHR_Z13	1
++#else
++# define WMEMCHR_DEFAULT	WMEMCHR_C
++# define HAVE_WMEMCHR_C		1
++# define HAVE_WMEMCHR_Z13	HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WMEMCHR_C
++# define WMEMCHR_C		__wmemchr_c
++#else
++# define WMEMCHR_C		NULL
++#endif
++
++#if HAVE_WMEMCHR_Z13
++# define WMEMCHR_Z13		__wmemchr_vx
++#else
++# define WMEMCHR_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 5be635542361b355..92e28dc45ddbae37 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wmemchr wmemchr-vx wmemchr-c \
+-		   wmemset wmemset-vx wmemset-c \
++sysdep_routines += wmemset wmemset-vx wmemset-c \
+ 		   wmemcmp wmemcmp-vx wmemcmp-c
+ endif
+ 
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 7d8031a069bd23ba..b5f55deb7faae9c4 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -62,6 +62,7 @@
+ #include <ifunc-wcsspn.h>
+ #include <ifunc-wcspbrk.h>
+ #include <ifunc-wcscspn.h>
++#include <ifunc-wmemchr.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -632,6 +633,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WCSCSPN_IFUNC  */
+ 
++#if HAVE_WMEMCHR_IFUNC
++    IFUNC_IMPL (i, name, wmemchr,
++# if HAVE_WMEMCHR_Z13
++		IFUNC_IMPL_ADD (array, i, wmemchr,
++				dl_hwcap & HWCAP_S390_VX, WMEMCHR_Z13)
++# endif
++# if HAVE_WMEMCHR_C
++		IFUNC_IMPL_ADD (array, i, wmemchr, 1, WMEMCHR_C)
++# endif
++		)
++#endif /* HAVE_WMEMCHR_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -640,8 +653,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wmemchr);
+-
+   IFUNC_VX_IMPL (wmemset);
+ 
+   IFUNC_VX_IMPL (wmemcmp);
+diff --git a/sysdeps/s390/multiarch/wmemchr-c.c b/sysdeps/s390/wmemchr-c.c
+similarity index 59%
+rename from sysdeps/s390/multiarch/wmemchr-c.c
+rename to sysdeps/s390/wmemchr-c.c
+index 089392b512d29187..bb2526e76c41d0c7 100644
+--- a/sysdeps/s390/multiarch/wmemchr-c.c
++++ b/sysdeps/s390/wmemchr-c.c
+@@ -16,22 +16,29 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WMEMCHR  __wmemchr_c
+-
+-# include <wchar.h>
+-extern __typeof (wmemchr) __wmemchr_c;
+-# undef weak_alias
+-# define weak_alias(name, alias)
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)			\
+-  __hidden_ver1 (__wmemchr_c, __GI___wmemchr, __wmemchr_c);
+-#  undef libc_hidden_weak
+-#  define libc_hidden_weak(name)					\
++#include <ifunc-wmemchr.h>
++
++#if HAVE_WMEMCHR_C
++# if HAVE_WMEMCHR_IFUNC || HAVE_WMEMCHR_Z13
++#  define WMEMCHR WMEMCHR_C
++
++#  undef weak_alias
++#  define weak_alias(name, alias)
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_weak
++#   define libc_hidden_weak(name)
++#   undef libc_hidden_def
++#   if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#    define libc_hidden_def(name)					\
++  __hidden_ver1 (__wmemchr_c, __GI_wmemchr, __wmemchr_c)  __attribute__((weak)); \
+   strong_alias (__wmemchr_c, __wmemchr_c_1);				\
+-  __hidden_ver1 (__wmemchr_c_1, __GI_wmemchr, __wmemchr_c_1);
+-# endif /* SHARED */
++  __hidden_ver1 (__wmemchr_c_1, __GI___wmemchr, __wmemchr_c_1);
++#   else
++#    define libc_hidden_def(name)
++#   endif
++#  endif
++# endif
+ 
+ # include <wcsmbs/wmemchr.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/wmemchr-vx.S b/sysdeps/s390/wmemchr-vx.S
+similarity index 92%
+rename from sysdeps/s390/multiarch/wmemchr-vx.S
+rename to sysdeps/s390/wmemchr-vx.S
+index db057b579a7230f0..72e9ef59af77b8f7 100644
+--- a/sysdeps/s390/multiarch/wmemchr-vx.S
++++ b/sysdeps/s390/wmemchr-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wmemchr.h>
++#if HAVE_WMEMCHR_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -38,7 +39,7 @@
+    -v17=index of found c
+    -v18=c replicated
+ */
+-ENTRY(__wmemchr_vx)
++ENTRY(WMEMCHR_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -161,6 +162,17 @@ ENTRY(__wmemchr_vx)
+ 
+ 	j	.Llt64
+ .Lfallback:
+-	jg	__wmemchr_c
+-END(__wmemchr_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WMEMCHR_C
++END(WMEMCHR_Z13)
++
++# if ! HAVE_WMEMCHR_IFUNC
++strong_alias (WMEMCHR_Z13, __wmemchr)
++weak_alias (__wmemchr, wmemchr)
++# endif
++
++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \
++	&& defined SHARED && IS_IN (libc)
++strong_alias (WMEMCHR_Z13, __GI___wmemchr)
++weak_alias (WMEMCHR_Z13, __GI_wmemchr)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/wmemchr.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wmemchr.c
+rename to sysdeps/s390/wmemchr.c
+index 6b55c1d7fa10afb9..0d2fbb22c6d65a97 100644
+--- a/sysdeps/s390/multiarch/wmemchr.c
++++ b/sysdeps/s390/wmemchr.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wmemchr.h>
++
++#if HAVE_WMEMCHR_IFUNC
+ # define wmemchr __redirect_wmemchr
+ # define __wmemchr __redirect___wmemchr
+ # include <wchar.h>
+@@ -24,9 +26,18 @@
+ # undef __wmemchr
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc_redirected (__redirect___wmemchr, __wmemchr)
+-weak_alias (__wmemchr, wmemchr)
++# if HAVE_WMEMCHR_C
++extern __typeof (__redirect___wmemchr) WMEMCHR_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wmemchr.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WMEMCHR_Z13
++extern __typeof (__redirect___wmemchr) WMEMCHR_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___wmemchr, __wmemchr,
++		      (HAVE_WMEMCHR_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WMEMCHR_Z13
++		      : WMEMCHR_DEFAULT
++		      )
++weak_alias (__wmemchr, wmemchr)
++#endif
diff --git a/SOURCES/glibc-rh1659438-53.patch b/SOURCES/glibc-rh1659438-53.patch
new file mode 100644
index 0000000..7d8150d
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-53.patch
@@ -0,0 +1,292 @@
+commit d2a7436c1c6144bbba2eb2a7b25db9b90515f0e6
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:24 2018 +0100
+
+    S390: Refactor wmemset ifunc handling.
+    
+    The ifunc handling for wmemset is adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Unfortunately the c ifunc variant can't be omitted at all as it is used
+    by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned.
+    Glibc internal calls will use the "newer" ifunc variant.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wmemset variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wmemset variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wmemset.
+            * sysdeps/s390/multiarch/wmemset-c.c: Move to ...
+            * sysdeps/s390/wmemset-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wmemset-vx.S: Move to ...
+            * sysdeps/s390/wmemset-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wmemset.c: Move to ...
+            * sysdeps/s390/wmemset.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wmemset.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index fdfd1c605c28ddc7..f9a71276331b396a 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -76,5 +76,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcsspn wcsspn-vx wcsspn-c \
+ 		   wcspbrk wcspbrk-vx wcspbrk-c \
+ 		   wcscspn wcscspn-vx wcscspn-c \
+-		   wmemchr wmemchr-vx wmemchr-c
++		   wmemchr wmemchr-vx wmemchr-c \
++		   wmemset wmemset-vx wmemset-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wmemset.h b/sysdeps/s390/ifunc-wmemset.h
+new file mode 100644
+index 0000000000000000..c9d1d17c3bfc7e9e
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wmemset.h
+@@ -0,0 +1,53 @@
++/* wmemset variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WMEMSET_IFUNC	1
++#else
++# define HAVE_WMEMSET_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT HAVE_WMEMSET_IFUNC
++#else
++# define HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WMEMSET_DEFAULT	WMEMSET_Z13
++/* The z13 ifunc variant is using the common code variant as fallback!  */
++# define HAVE_WMEMSET_C		1
++# define HAVE_WMEMSET_Z13	1
++#else
++# define WMEMSET_DEFAULT	WMEMSET_C
++# define HAVE_WMEMSET_C		1
++# define HAVE_WMEMSET_Z13	HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WMEMSET_C
++# define WMEMSET_C		__wmemset_c
++#else
++# define WMEMSET_C		NULL
++#endif
++
++#if HAVE_WMEMSET_Z13
++# define WMEMSET_Z13		__wmemset_vx
++#else
++# define WMEMSET_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 92e28dc45ddbae37..cc6dd7adb10ee8ad 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,6 +1,5 @@
+ ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wmemset wmemset-vx wmemset-c \
+-		   wmemcmp wmemcmp-vx wmemcmp-c
++sysdep_routines += wmemcmp wmemcmp-vx wmemcmp-c
+ endif
+ 
+ ifeq ($(subdir),iconvdata)
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index b5f55deb7faae9c4..7040959269c1612b 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -63,6 +63,7 @@
+ #include <ifunc-wcspbrk.h>
+ #include <ifunc-wcscspn.h>
+ #include <ifunc-wmemchr.h>
++#include <ifunc-wmemset.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -645,6 +646,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WMEMCHR_IFUNC  */
+ 
++#if HAVE_WMEMSET_IFUNC
++    IFUNC_IMPL (i, name, wmemset,
++# if HAVE_WMEMSET_Z13
++		IFUNC_IMPL_ADD (array, i, wmemset,
++				dl_hwcap & HWCAP_S390_VX, WMEMSET_Z13)
++# endif
++# if HAVE_WMEMSET_C
++		IFUNC_IMPL_ADD (array, i, wmemset, 1, WMEMSET_C)
++# endif
++		)
++#endif /* HAVE_WMEMSET_IFUNC  */
++
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+ # define IFUNC_VX_IMPL(FUNC)						\
+@@ -653,8 +666,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 			      __##FUNC##_vx)				\
+ 	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+ 
+-  IFUNC_VX_IMPL (wmemset);
+-
+   IFUNC_VX_IMPL (wmemcmp);
+ 
+ #endif /* HAVE_S390_VX_ASM_SUPPORT */
+diff --git a/sysdeps/s390/multiarch/wmemset-c.c b/sysdeps/s390/wmemset-c.c
+similarity index 59%
+rename from sysdeps/s390/multiarch/wmemset-c.c
+rename to sysdeps/s390/wmemset-c.c
+index 1969cf93dcf08892..01e625496d8c2e4e 100644
+--- a/sysdeps/s390/multiarch/wmemset-c.c
++++ b/sysdeps/s390/wmemset-c.c
+@@ -16,22 +16,29 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WMEMSET  __wmemset_c
+-
+-# include <wchar.h>
+-extern __typeof (__wmemset) __wmemset_c;
+-# undef weak_alias
+-# define weak_alias(name, alias)
+-# ifdef SHARED
+-#  undef libc_hidden_def
+-#  define libc_hidden_def(name)					\
+-  __hidden_ver1 (__wmemset_c, __GI___wmemset, __wmemset_c);
+-#  undef libc_hidden_weak
+-#  define libc_hidden_weak(name)					\
++#include <ifunc-wmemset.h>
++
++#if HAVE_WMEMSET_C
++# if HAVE_WMEMSET_IFUNC || HAVE_WMEMSET_Z13
++#  define WMEMSET WMEMSET_C
++
++#  undef weak_alias
++#  define weak_alias(name, alias)
++
++#  if defined SHARED && IS_IN (libc)
++#   undef libc_hidden_weak
++#   define libc_hidden_weak(name)
++#   undef libc_hidden_def
++#   if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#    define libc_hidden_def(name)					\
++  __hidden_ver1 (__wmemset_c, __GI_wmemset, __wmemset_c)  __attribute__((weak)); \
+   strong_alias (__wmemset_c, __wmemset_c_1);				\
+-  __hidden_ver1 (__wmemset_c_1, __GI_wmemset, __wmemset_c_1);
+-# endif /* SHARED */
++  __hidden_ver1 (__wmemset_c_1, __GI___wmemset, __wmemset_c_1);
++#   else
++#    define libc_hidden_def(name)
++#   endif
++#  endif
++# endif
+ 
+ # include <wcsmbs/wmemset.c>
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++#endif
+diff --git a/sysdeps/s390/multiarch/wmemset-vx.S b/sysdeps/s390/wmemset-vx.S
+similarity index 91%
+rename from sysdeps/s390/multiarch/wmemset-vx.S
+rename to sysdeps/s390/wmemset-vx.S
+index 0c2f6337b0e554ec..4b6050b5accd732b 100644
+--- a/sysdeps/s390/multiarch/wmemset-vx.S
++++ b/sysdeps/s390/wmemset-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wmemset.h>
++#if HAVE_WMEMSET_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -38,7 +39,7 @@
+    -v17,v18,v19=copy of v16 for vstm
+    -v31=saved dest for return
+ */
+-ENTRY(__wmemset_vx)
++ENTRY(WMEMSET_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -137,6 +138,17 @@ ENTRY(__wmemset_vx)
+ 	br	%r14
+ .Lfallback:
+ 	srlg	%r4,%r4,2	/* Convert byte-count to character-count.  */
+-	jg	__wmemset_c
+-END(__wmemset_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++	jg	WMEMSET_C
++END(WMEMSET_Z13)
++
++# if ! HAVE_WMEMSET_IFUNC
++strong_alias (WMEMSET_Z13, __wmemset)
++weak_alias (__wmemset, wmemset)
++# endif
++
++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \
++	&& defined SHARED && IS_IN (libc)
++strong_alias (WMEMSET_Z13, __GI___wmemset)
++weak_alias (WMEMSET_Z13, __GI_wmemset)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/wmemset.c
+similarity index 70%
+rename from sysdeps/s390/multiarch/wmemset.c
+rename to sysdeps/s390/wmemset.c
+index 149b4814708d820a..6118754d1df71948 100644
+--- a/sysdeps/s390/multiarch/wmemset.c
++++ b/sysdeps/s390/wmemset.c
+@@ -16,7 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wmemset.h>
++
++#if HAVE_WMEMSET_IFUNC
+ # define wmemset __redirect_wmemset
+ # define __wmemset __redirect___wmemset
+ # include <wchar.h>
+@@ -24,9 +26,18 @@
+ # undef __wmemset
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc_redirected (__redirect___wmemset, __wmemset)
+-weak_alias (__wmemset, wmemset)
++# if HAVE_WMEMSET_C
++extern __typeof (__redirect___wmemset) WMEMSET_C attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wmemset.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++# if HAVE_WMEMSET_Z13
++extern __typeof (__redirect___wmemset) WMEMSET_Z13 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___wmemset, __wmemset,
++		      (HAVE_WMEMSET_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WMEMSET_Z13
++		      : WMEMSET_DEFAULT
++		      )
++weak_alias (__wmemset, wmemset)
++#endif
diff --git a/SOURCES/glibc-rh1659438-54.patch b/SOURCES/glibc-rh1659438-54.patch
new file mode 100644
index 0000000..2bd37c0
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-54.patch
@@ -0,0 +1,246 @@
+commit 25654a8c74dce51e162c29749c6bd6d2a67490e6
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:25 2018 +0100
+
+    S390: Refactor wmemcmp ifunc handling.
+    
+    The ifunc handling for wmemcmp is adjusted in order to omit ifunc
+    variants if those will never be used as the minimum architecture level
+    already supports newer CPUs by default.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/Makefile
+            (sysdep_routines): Remove wmemcmp variants.
+            * sysdeps/s390/Makefile (sysdep_routines): Add wmemcmp variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Refactor ifunc handling for wmemcmp.
+            * sysdeps/s390/multiarch/wmemcmp-c.c: Move to ...
+            * sysdeps/s390/wmemcmp-c.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wmemcmp-vx.S: Move to ...
+            * sysdeps/s390/wmemcmp-vx.S: ... here and adjust ifunc handling.
+            * sysdeps/s390/multiarch/wmemcmp.c: Move to ...
+            * sysdeps/s390/wmemcmp.c: ... here and adjust ifunc handling.
+            * sysdeps/s390/ifunc-wmemcmp.h: New file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index f9a71276331b396a..3f7de6613c343819 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -77,5 +77,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
+ 		   wcspbrk wcspbrk-vx wcspbrk-c \
+ 		   wcscspn wcscspn-vx wcscspn-c \
+ 		   wmemchr wmemchr-vx wmemchr-c \
+-		   wmemset wmemset-vx wmemset-c
++		   wmemset wmemset-vx wmemset-c \
++		   wmemcmp wmemcmp-vx wmemcmp-c
+ endif
+diff --git a/sysdeps/s390/ifunc-wmemcmp.h b/sysdeps/s390/ifunc-wmemcmp.h
+new file mode 100644
+index 0000000000000000..1b38a014590ec060
+--- /dev/null
++++ b/sysdeps/s390/ifunc-wmemcmp.h
+@@ -0,0 +1,52 @@
++/* wmemcmp variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)		\
++  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define HAVE_WMEMCMP_IFUNC	1
++#else
++# define HAVE_WMEMCMP_IFUNC	0
++#endif
++
++#ifdef HAVE_S390_VX_ASM_SUPPORT
++# define HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT HAVE_WMEMCMP_IFUNC
++#else
++# define HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++# define WMEMCMP_DEFAULT	WMEMCMP_Z13
++# define HAVE_WMEMCMP_C		0
++# define HAVE_WMEMCMP_Z13	1
++#else
++# define WMEMCMP_DEFAULT	WMEMCMP_C
++# define HAVE_WMEMCMP_C		1
++# define HAVE_WMEMCMP_Z13	HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT
++#endif
++
++#if HAVE_WMEMCMP_C
++# define WMEMCMP_C		__wmemcmp_c
++#else
++# define WMEMCMP_C		NULL
++#endif
++
++#if HAVE_WMEMCMP_Z13
++# define WMEMCMP_Z13		__wmemcmp_vx
++#else
++# define WMEMCMP_Z13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index cc6dd7adb10ee8ad..fec36153047e4585 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -1,7 +1,3 @@
+-ifeq ($(subdir),wcsmbs)
+-sysdep_routines += wmemcmp wmemcmp-vx wmemcmp-c
+-endif
+-
+ ifeq ($(subdir),iconvdata)
+ override define generate-8bit-table
+ $(make-target-directory)
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 7040959269c1612b..177c5fd6fe269d9b 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -64,6 +64,7 @@
+ #include <ifunc-wcscspn.h>
+ #include <ifunc-wmemchr.h>
+ #include <ifunc-wmemset.h>
++#include <ifunc-wmemcmp.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -658,17 +659,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 		)
+ #endif /* HAVE_WMEMSET_IFUNC  */
+ 
+-#ifdef HAVE_S390_VX_ASM_SUPPORT
+-
+-# define IFUNC_VX_IMPL(FUNC)						\
+-  IFUNC_IMPL (i, name, FUNC,						\
+-	      IFUNC_IMPL_ADD (array, i, FUNC, dl_hwcap & HWCAP_S390_VX, \
+-			      __##FUNC##_vx)				\
+-	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c))
+-
+-  IFUNC_VX_IMPL (wmemcmp);
+-
+-#endif /* HAVE_S390_VX_ASM_SUPPORT */
++#if HAVE_WMEMCMP_IFUNC
++    IFUNC_IMPL (i, name, wmemcmp,
++# if HAVE_WMEMCMP_Z13
++		IFUNC_IMPL_ADD (array, i, wmemcmp,
++				dl_hwcap & HWCAP_S390_VX, WMEMCMP_Z13)
++# endif
++# if HAVE_WMEMCMP_C
++		IFUNC_IMPL_ADD (array, i, wmemcmp, 1, WMEMCMP_C)
++# endif
++		)
++#endif /* HAVE_WMEMCMP_IFUNC  */
+ 
+   return i;
+ }
+diff --git a/sysdeps/s390/multiarch/wmemcmp-c.c b/sysdeps/s390/wmemcmp-c.c
+similarity index 85%
+rename from sysdeps/s390/multiarch/wmemcmp-c.c
+rename to sysdeps/s390/wmemcmp-c.c
+index 2fd39d501360e6f8..0c73636adda82f8b 100644
+--- a/sysdeps/s390/multiarch/wmemcmp-c.c
++++ b/sysdeps/s390/wmemcmp-c.c
+@@ -16,11 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+-# define WMEMCMP  __wmemcmp_c
++#include <ifunc-wmemcmp.h>
+ 
+-# include <wchar.h>
+-extern __typeof (wmemcmp) __wmemcmp_c;
++#if HAVE_WMEMCMP_C
++# if HAVE_WMEMCMP_IFUNC
++#  define WMEMCMP WMEMCMP_C
++# endif
+ 
+ # include <wcsmbs/wmemcmp.c>
+ #endif
+diff --git a/sysdeps/s390/multiarch/wmemcmp-vx.S b/sysdeps/s390/wmemcmp-vx.S
+similarity index 95%
+rename from sysdeps/s390/multiarch/wmemcmp-vx.S
+rename to sysdeps/s390/wmemcmp-vx.S
+index e2fc21e4192b0dd8..87ae21b4f13c5d69 100644
+--- a/sysdeps/s390/multiarch/wmemcmp-vx.S
++++ b/sysdeps/s390/wmemcmp-vx.S
+@@ -16,7 +16,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wmemcmp.h>
++#if HAVE_WMEMCMP_Z13
+ 
+ # include "sysdep.h"
+ # include "asm-syntax.h"
+@@ -37,7 +38,7 @@
+    -v17=part of s2
+    -v18=index of unequal
+ */
+-ENTRY(__wmemcmp_vx)
++ENTRY(WMEMCMP_Z13)
+ 	.machine "z13"
+ 	.machinemode "zarch_nohighgprs"
+ 
+@@ -145,5 +146,9 @@ ENTRY(__wmemcmp_vx)
+ 	la	%r2,0(%r5,%r2)
+ 	la	%r3,0(%r5,%r3)
+ 	j	.Lremaining
+-END(__wmemcmp_vx)
+-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
++END(WMEMCMP_Z13)
++
++# if ! HAVE_WMEMCMP_IFUNC
++strong_alias (WMEMCMP_Z13, wmemcmp)
++# endif
++#endif
+diff --git a/sysdeps/s390/multiarch/wmemcmp.c b/sysdeps/s390/wmemcmp.c
+similarity index 69%
+rename from sysdeps/s390/multiarch/wmemcmp.c
+rename to sysdeps/s390/wmemcmp.c
+index a4cb440c452fd6a9..6c8ca5f0e8ffdb50 100644
+--- a/sysdeps/s390/multiarch/wmemcmp.c
++++ b/sysdeps/s390/wmemcmp.c
+@@ -16,12 +16,23 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
++#include <ifunc-wmemcmp.h>
++
++#if HAVE_WMEMCMP_IFUNC
+ # include <wchar.h>
+ # include <ifunc-resolve.h>
+ 
+-s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp)
++# if HAVE_WMEMCMP_C
++extern __typeof (wmemcmp) WMEMCMP_C attribute_hidden;
++# endif
++
++# if HAVE_WMEMCMP_Z13
++extern __typeof (wmemcmp) WMEMCMP_Z13 attribute_hidden;
++# endif
+ 
+-#else
+-# include <wcsmbs/wmemcmp.c>
+-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
++s390_libc_ifunc_expr (wmemcmp, wmemcmp,
++		      (HAVE_WMEMCMP_Z13 && (hwcap & HWCAP_S390_VX))
++		      ? WMEMCMP_Z13
++		      : WMEMCMP_DEFAULT
++		      )
++#endif
diff --git a/SOURCES/glibc-rh1659438-55.patch b/SOURCES/glibc-rh1659438-55.patch
new file mode 100644
index 0000000..e4be220
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-55.patch
@@ -0,0 +1,53 @@
+commit 12f0dcb8da2c7c74d673583ec3286c0354273f52
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:25 2018 +0100
+
+    S390: Refactor gconv_simple ifunc handling.
+    
+    The ifunc handling for various __gconv_transform_* functions
+    which are using IFUNC on s390x are adjusted in order to omit ifunc
+    if the minimum architecture level already supports newer CPUs by default.
+    Instead those functions are just an alias to the vector variants.
+    
+    Furthermore the ifunc-macro s390_libc_ifunc_expr is now used instead of
+    s390_vx_libc_ifunc.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/gconv_simple.c (ICONV_VX_IFUNC):
+            Define macro dependent on HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT.
+
+diff --git a/sysdeps/s390/multiarch/gconv_simple.c b/sysdeps/s390/multiarch/gconv_simple.c
+index aaa1ebf74acf4dde..078d992c13eb548c 100644
+--- a/sysdeps/s390/multiarch/gconv_simple.c
++++ b/sysdeps/s390/multiarch/gconv_simple.c
+@@ -27,17 +27,18 @@
+ 
+ # define ICONV_C_NAME(NAME) __##NAME##_c
+ # define ICONV_VX_NAME(NAME) __##NAME##_vx
+-# define ICONV_VX_IFUNC(FUNC)						\
+-  extern __typeof (ICONV_C_NAME (FUNC)) __##FUNC;			\
+-  s390_vx_libc_ifunc (__##FUNC)						\
+-  int FUNC (struct __gconv_step *step, struct __gconv_step_data *data,	\
+-	    const unsigned char **inptrp, const unsigned char *inend,	\
+-	    unsigned char **outbufstart, size_t *irreversible,		\
+-	    int do_flush, int consume_incomplete)			\
+-  {									\
+-    return __##FUNC (step, data, inptrp, inend,outbufstart,		\
+-		     irreversible, do_flush, consume_incomplete);	\
+-  }
++# ifdef HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++/* We support z13 instructions by default -> Just use the vector variant.  */
++#  define ICONV_VX_IFUNC(FUNC) strong_alias (ICONV_VX_NAME (FUNC), FUNC)
++# else
++/* We have to use ifunc to determine if z13 instructions are supported.  */
++#  define ICONV_VX_IFUNC(FUNC)						\
++  s390_libc_ifunc_expr (ICONV_C_NAME (FUNC), FUNC,			\
++			(hwcap & HWCAP_S390_VX)				\
++			? ICONV_VX_NAME (FUNC)				\
++			: ICONV_C_NAME (FUNC)				\
++			)
++# endif
+ # define ICONV_VX_SINGLE(NAME)						\
+   static __typeof (NAME##_single) __##NAME##_vx_single __attribute__((alias(#NAME "_single")));
+ 
diff --git a/SOURCES/glibc-rh1659438-56.patch b/SOURCES/glibc-rh1659438-56.patch
new file mode 100644
index 0000000..934b8da
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-56.patch
@@ -0,0 +1,152 @@
+commit 80190d2b0e3f48d973724218f37d2da5bf1a20ab
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:25 2018 +0100
+
+    S390: Cleanup ifunc-resolve.h.
+    
+    The ifunc macros s390_vx_libc* are no longer used and
+    can be removed as all users are now relying on
+    s390_libc_ifunc_expr.
+    
+    The same applies to s390_libc_ifunc.  The macro
+    s390_libc_ifunc_init is now renamed to
+    s390_libc_ifunc_expr_stfle_init and the users are
+    adjusted accordingly.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/multiarch/ifunc-resolve.h
+            (s390_vx_libc_ifunc, s390_vx_libc_ifunc_redirected,
+            s390_vx_libc_ifunc2, s390_vx_libc_ifunc_init,
+            s390_vx_libc_ifunc2_redirected, s390_libc_ifunc):
+            Delete macro definition.
+            (s390_libc_ifunc_init): Rename to
+            s390_libc_ifunc_expr_stfle_init.
+            * sysdeps/s390/bzero: Use
+            s390_libc_ifunc_expr_stfle_init instead of
+            s390_libc_ifunc_init.
+            * sysdeps/s390/memcmp.c: Likewise.
+            * sysdeps/s390/memcpy.c: Likewise.
+            * sysdeps/s390/mempcpy.c: Likewise.
+            * sysdeps/s390/memset.c: Likewise.
+
+diff --git a/sysdeps/s390/bzero.c b/sysdeps/s390/bzero.c
+index 9f8d95781bf2fb68..6b5d471c40250543 100644
+--- a/sysdeps/s390/bzero.c
++++ b/sysdeps/s390/bzero.c
+@@ -35,7 +35,7 @@ extern __typeof (__bzero) BZERO_Z196 attribute_hidden;
+ 
+ s390_libc_ifunc_expr (__bzero, __bzero,
+ 		      ({
+-			s390_libc_ifunc_init ();
++			s390_libc_ifunc_expr_stfle_init ();
+ 			(HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits))
+ 			  ? BZERO_Z196
+ 			  : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits))
+diff --git a/sysdeps/s390/memcmp.c b/sysdeps/s390/memcmp.c
+index 952ff6af7364fd92..6d9276320abbe332 100644
+--- a/sysdeps/s390/memcmp.c
++++ b/sysdeps/s390/memcmp.c
+@@ -37,7 +37,7 @@ extern __typeof (__redirect_memcmp) MEMCMP_Z196 attribute_hidden;
+ 
+ s390_libc_ifunc_expr (__redirect_memcmp, memcmp,
+ 		      ({
+-			s390_libc_ifunc_init ();
++			s390_libc_ifunc_expr_stfle_init ();
+ 			(HAVE_MEMCMP_Z196 && S390_IS_Z196 (stfle_bits))
+ 			  ? MEMCMP_Z196
+ 			  : (HAVE_MEMCMP_Z10 && S390_IS_Z10 (stfle_bits))
+diff --git a/sysdeps/s390/memcpy.c b/sysdeps/s390/memcpy.c
+index 90a53ac27d4be755..0ff24f18cf3600da 100644
+--- a/sysdeps/s390/memcpy.c
++++ b/sysdeps/s390/memcpy.c
+@@ -38,7 +38,7 @@ extern __typeof (__redirect_memcpy) MEMCPY_Z196 attribute_hidden;
+ 
+ s390_libc_ifunc_expr (__redirect_memcpy, memcpy,
+ 		      ({
+-			s390_libc_ifunc_init ();
++			s390_libc_ifunc_expr_stfle_init ();
+ 			(HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits))
+ 			  ? MEMCPY_Z196
+ 			  : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits))
+diff --git a/sysdeps/s390/mempcpy.c b/sysdeps/s390/mempcpy.c
+index a6a237312659c2c1..b687b3362034bfb0 100644
+--- a/sysdeps/s390/mempcpy.c
++++ b/sysdeps/s390/mempcpy.c
+@@ -42,7 +42,7 @@ extern __typeof (__redirect___mempcpy) MEMPCPY_Z196 attribute_hidden;
+ 
+ s390_libc_ifunc_expr (__redirect___mempcpy, __mempcpy,
+ 		      ({
+-			s390_libc_ifunc_init ();
++			s390_libc_ifunc_expr_stfle_init ();
+ 			(HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits))
+ 			  ? MEMPCPY_Z196
+ 			  : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits))
+diff --git a/sysdeps/s390/memset.c b/sysdeps/s390/memset.c
+index 57a35aebc7d3c794..75b011f1a24f39bc 100644
+--- a/sysdeps/s390/memset.c
++++ b/sysdeps/s390/memset.c
+@@ -37,7 +37,7 @@ extern __typeof (__redirect_memset) MEMSET_Z196 attribute_hidden;
+ 
+ s390_libc_ifunc_expr (__redirect_memset, memset,
+ 		      ({
+-			s390_libc_ifunc_init ();
++			s390_libc_ifunc_expr_stfle_init ();
+ 			(HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits))
+ 			  ? MEMSET_Z196
+ 			  : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits))
+diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
+index b7e20abc59638251..b2be015401313d4b 100644
+--- a/sysdeps/s390/multiarch/ifunc-resolve.h
++++ b/sysdeps/s390/multiarch/ifunc-resolve.h
+@@ -40,7 +40,7 @@
+ 		       ".machine pop"         "\n"			\
+ 		       : "=QS" (STFLE_BITS), "+d" (reg0)		\
+ 		       : : "cc");
+-#define s390_libc_ifunc_init()						\
++#define s390_libc_ifunc_expr_stfle_init()				\
+   unsigned long long stfle_bits = 0ULL;					\
+   if (__glibc_likely ((hwcap & HWCAP_S390_STFLE)			\
+ 		      && (hwcap & HWCAP_S390_ZARCH)			\
+@@ -49,41 +49,6 @@
+       S390_STORE_STFLE (stfle_bits);					\
+     }
+ 
+-#define s390_libc_ifunc(TYPE_FUNC, RESOLVERFUNC, FUNC)			\
+-  /* Make the declarations of the optimized functions hidden in order
+-     to prevent GOT slots being generated for them. */			\
+-  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z196 attribute_hidden;	\
+-  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z10 attribute_hidden;      \
+-  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_default attribute_hidden;  \
+-  __ifunc (TYPE_FUNC, FUNC,						\
+-	   __glibc_likely (S390_IS_Z196 (stfle_bits))			\
+-	   ? RESOLVERFUNC##_z196					\
+-	   : __glibc_likely (S390_IS_Z10 (stfle_bits))			\
+-	     ? RESOLVERFUNC##_z10					\
+-	     : RESOLVERFUNC##_default,					\
+-	   unsigned long int hwcap, s390_libc_ifunc_init);
+-
+-#define s390_vx_libc_ifunc(FUNC)		\
+-  s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC)
+-
+-#define s390_vx_libc_ifunc_redirected(TYPE_FUNC, FUNC)	\
+-  s390_vx_libc_ifunc2_redirected(TYPE_FUNC, FUNC, FUNC)
+-
+-#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC)	\
+-  s390_vx_libc_ifunc2_redirected(FUNC, RESOLVERFUNC, FUNC)
+-
+-#define s390_vx_libc_ifunc_init()
+-#define s390_vx_libc_ifunc2_redirected(TYPE_FUNC, RESOLVERFUNC, FUNC)	\
+-  /* Make the declarations of the optimized functions hidden in order
+-     to prevent GOT slots being generated for them.  */			\
+-  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden;	\
+-  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden;	\
+-  __ifunc (TYPE_FUNC, FUNC,						\
+-	   (hwcap & HWCAP_S390_VX)					\
+-	   ? RESOLVERFUNC##_vx						\
+-	   : RESOLVERFUNC##_c,						\
+-	   unsigned long int hwcap, s390_vx_libc_ifunc_init);
+-
+ #define s390_libc_ifunc_expr_init()
+ #define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR)		\
+   __ifunc (TYPE_FUNC, FUNC, EXPR, unsigned long int hwcap,	\
diff --git a/SOURCES/glibc-rh1659438-57.patch b/SOURCES/glibc-rh1659438-57.patch
new file mode 100644
index 0000000..50b5945
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-57.patch
@@ -0,0 +1,29 @@
+commit 61f5e9470fb397a4c334938ac5a667427d9047df
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Thu Mar 21 09:14:26 2019 +0100
+
+    S390: Mark vx and vxe as important hwcap.
+    
+    This patch adds vx and vxe as important hwcaps
+    which allows one to provide shared libraries
+    tuned for platforms with non-vx/-vxe, vx or vxe.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT):
+            Add HWCAP_S390_VX and HWCAP_S390_VXE.
+
+diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
+index b0383bfb4cef7972..f71d64c3ab24e715 100644
+--- a/sysdeps/s390/dl-procinfo.h
++++ b/sysdeps/s390/dl-procinfo.h
+@@ -57,7 +57,8 @@ enum
+ };
+ 
+ #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
+-			  | HWCAP_S390_EIMM | HWCAP_S390_DFP)
++			 | HWCAP_S390_EIMM | HWCAP_S390_DFP  \
++			 | HWCAP_S390_VX | HWCAP_S390_VXE)
+ 
+ /* We cannot provide a general printing function.  */
+ #define _dl_procinfo(type, word) -1
diff --git a/SOURCES/glibc-rh1659438-58.patch b/SOURCES/glibc-rh1659438-58.patch
new file mode 100644
index 0000000..3f16140
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-58.patch
@@ -0,0 +1,88 @@
+commit 1a7df49c92f62e14d8727f083fd055eba7c91ad9
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Fri Mar 22 11:14:07 2019 +0100
+
+    S390: Add new hwcap values for new cpu architecture arch13.
+    
+    The new hwcap values indicate support for:
+    -"Vector-Enhancements Facility 2" (tag "vxe2", hwcap 2^15)
+    -"Vector-Packed-Decimal-Enhancement Facility" (tag "vxp", hwcap 2^16)
+    -"Enhanced-Sort Facility" (tag "sort", hwcap 2^17)
+    -"Deflate-Conversion Facility" (tag "dflt", hwcap 2^18)
+    
+    The vxe2 hwcap is also marked as important hwcap.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/dl-procinfo.c (_dl_s390_cap_flags):
+            Add vxe2, vxp, dflt, sort flags.
+            * sysdeps/s390/dl-procinfo.h: Add HWCAP_S390_VXRS_EXT2,
+            HWCAP_S390_VXRS_PDE, HWCAP_S390_SORT, HWCAP_S390_DFLT
+            capabilities.
+            (HWCAP_IMPORTANT): Add HWCAP_S390_VXRS_EXT2.
+            * sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+            (HWCAP_S390_VXRS_EXT2, HWCAP_S390_VXRS_PDE, HWCAP_S390_SORT,
+            HWCAP_S390_DFLT): Define.
+
+diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
+index 86c964caff6a1bc4..6ea220a171d8fab7 100644
+--- a/sysdeps/s390/dl-procinfo.c
++++ b/sysdeps/s390/dl-procinfo.c
+@@ -46,12 +46,12 @@
+ #if !defined PROCINFO_DECL && defined SHARED
+   ._dl_s390_cap_flags
+ #else
+-PROCINFO_CLASS const char _dl_s390_cap_flags[15][9]
++PROCINFO_CLASS const char _dl_s390_cap_flags[19][9]
+ #endif
+ #ifndef PROCINFO_DECL
+ = {
+      "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh",
+-     "highgprs", "te", "vx", "vxd", "vxe", "gs"
++     "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt"
+   }
+ #endif
+ #if !defined SHARED || defined PROCINFO_DECL
+diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
+index f71d64c3ab24e715..d03c69fffdbd06de 100644
+--- a/sysdeps/s390/dl-procinfo.h
++++ b/sysdeps/s390/dl-procinfo.h
+@@ -21,7 +21,7 @@
+ #define _DL_PROCINFO_H	1
+ #include <ldsodefs.h>
+ 
+-#define _DL_HWCAP_COUNT 15
++#define _DL_HWCAP_COUNT 19
+ 
+ #define _DL_PLATFORMS_COUNT	9
+ 
+@@ -54,11 +54,16 @@ enum
+   HWCAP_S390_VXD = 1 << 12,
+   HWCAP_S390_VXE = 1 << 13,
+   HWCAP_S390_GS = 1 << 14,
++  HWCAP_S390_VXRS_EXT2 = 1 << 15,
++  HWCAP_S390_VXRS_PDE = 1 << 16,
++  HWCAP_S390_SORT = 1 << 17,
++  HWCAP_S390_DFLT = 1 << 18,
+ };
+ 
+ #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
+ 			 | HWCAP_S390_EIMM | HWCAP_S390_DFP  \
+-			 | HWCAP_S390_VX | HWCAP_S390_VXE)
++			 | HWCAP_S390_VX | HWCAP_S390_VXE    \
++			 | HWCAP_S390_VXRS_EXT2)
+ 
+ /* We cannot provide a general printing function.  */
+ #define _dl_procinfo(type, word) -1
+diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+index 2564712399948375..6b9b59522e3d3bec 100644
+--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+@@ -39,3 +39,7 @@
+ #define HWCAP_S390_VXD          4096
+ #define HWCAP_S390_VXE          8192
+ #define HWCAP_S390_GS           16384
++#define HWCAP_S390_VXRS_EXT2    32768
++#define HWCAP_S390_VXRS_PDE     65536
++#define HWCAP_S390_SORT         131072
++#define HWCAP_S390_DFLT         262144
diff --git a/SOURCES/glibc-rh1659438-59.patch b/SOURCES/glibc-rh1659438-59.patch
new file mode 100644
index 0000000..8cb861c
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-59.patch
@@ -0,0 +1,195 @@
+commit a899a5512f618d5c4093a2d65e8dee07c791b0ab
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Fri Mar 22 11:14:08 2019 +0100
+
+    S390: Add configure check to detect support for arch13.
+    
+    Add two configure checks which detect if arch13 is supported
+    by the assembler at all - by explicitely setting the machine -
+    and if it is supported with default settings.
+    
+    ChangeLog:
+    
+            * config.h.in (HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT,
+            HAVE_S390_ARCH13_ASM_SUPPORT): New undefine.
+            * sysdeps/s390/configure.ac: Add checks for arch13 support.
+            * sysdeps/s390/configure: Regenerated.
+
+diff --git a/config.h.in b/config.h.in
+index 422a6036ab16e3b6..f63f6c8442914aa1 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -71,6 +71,9 @@
+ /* Define if assembler supports z13 zarch instructions as default on S390.  */
+ #undef  HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
+ 
++/* Define if assembler supports arch13 zarch instruction as default on S390.  */
++#undef  HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT
++
+ /* Define if assembler supports vector instructions on S390.  */
+ #undef  HAVE_S390_VX_ASM_SUPPORT
+ 
+@@ -78,6 +81,9 @@
+    on S390.  */
+ #undef  HAVE_S390_VX_GCC_SUPPORT
+ 
++/* Define if assembler supports arch13 instructions on S390.  */
++#undef  HAVE_S390_ARCH13_ASM_SUPPORT
++
+ /* Define if assembler supports Intel MPX.  */
+ #undef  HAVE_MPX_SUPPORT
+ 
+diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
+index 4a44775e3083d8c3..fa46e9e351e37e55 100644
+--- a/sysdeps/s390/configure
++++ b/sysdeps/s390/configure
+@@ -112,6 +112,43 @@ then
+ 
+ fi
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 arch13 zarch instruction support" >&5
++$as_echo_n "checking for S390 arch13 zarch instruction support... " >&6; }
++if ${libc_cv_asm_s390_arch13+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.c <<\EOF
++void testinsn (char *buf)
++{
++    __asm__ (".machine \"arch13\" \n\t"
++	     ".machinemode \"zarch_nohighgprs\" \n\t"
++	     "lghi %%r0,16 \n\t"
++	     "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++}
++EOF
++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; } ;
++then
++  libc_cv_asm_s390_arch13=yes
++else
++  libc_cv_asm_s390_arch13=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_arch13" >&5
++$as_echo "$libc_cv_asm_s390_arch13" >&6; }
++if test "$libc_cv_asm_s390_arch13" = yes ;
++then
++  $as_echo "#define HAVE_S390_ARCH13_ASM_SUPPORT 1" >>confdefs.h
++
++fi
++
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z10 zarch instruction support as default" >&5
+ $as_echo_n "checking for S390 z10 zarch instruction support as default... " >&6; }
+ if ${libc_cv_asm_s390_min_z10_zarch+:} false; then :
+@@ -225,5 +262,39 @@ then
+ 
+ fi
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 arch13 zarch instruction support as default" >&5
++$as_echo_n "checking for S390 arch13 zarch instruction support as default... " >&6; }
++if ${libc_cv_asm_s390_min_arch13_zarch+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.c <<\EOF
++void testinsn (char *buf)
++{
++    __asm__ ("lghi %%r0,16 \n\t"
++	     "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++}
++EOF
++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; } ;
++then
++  libc_cv_asm_s390_min_arch13_zarch=yes
++else
++  libc_cv_asm_s390_min_arch13_zarch=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_arch13_zarch" >&5
++$as_echo "$libc_cv_asm_s390_min_arch13_zarch" >&6; }
++if test "$libc_cv_asm_s390_min_arch13_zarch" = yes ;
++then
++  $as_echo "#define HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT 1" >>confdefs.h
++
++fi
++
+ test -n "$critic_missing" && as_fn_error $? "
+ *** $critic_missing" "$LINENO" 5
+diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
+index 4dfb5574b49d5949..3ed5a8ef87f9694b 100644
+--- a/sysdeps/s390/configure.ac
++++ b/sysdeps/s390/configure.ac
+@@ -80,6 +80,32 @@ then
+   AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT)
+ fi
+ 
++AC_CACHE_CHECK(for S390 arch13 zarch instruction support,
++	       libc_cv_asm_s390_arch13, [dnl
++cat > conftest.c <<\EOF
++void testinsn (char *buf)
++{
++    __asm__ (".machine \"arch13\" \n\t"
++	     ".machinemode \"zarch_nohighgprs\" \n\t"
++	     "lghi %%r0,16 \n\t"
++	     "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++}
++EOF
++dnl test, if assembler supports S390 arch13 instructions
++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null]) ;
++then
++  libc_cv_asm_s390_arch13=yes
++else
++  libc_cv_asm_s390_arch13=no
++fi
++rm -f conftest* ])
++if test "$libc_cv_asm_s390_arch13" = yes ;
++then
++  AC_DEFINE(HAVE_S390_ARCH13_ASM_SUPPORT)
++fi
++
++
+ AC_CACHE_CHECK(for S390 z10 zarch instruction support as default,
+ 	       libc_cv_asm_s390_min_z10_zarch, [dnl
+ cat > conftest.c <<\EOF
+@@ -163,5 +189,28 @@ then
+   AC_DEFINE(HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT)
+ fi
+ 
++AC_CACHE_CHECK(for S390 arch13 zarch instruction support as default,
++	       libc_cv_asm_s390_min_arch13_zarch, [dnl
++cat > conftest.c <<\EOF
++void testinsn (char *buf)
++{
++    __asm__ ("lghi %%r0,16 \n\t"
++	     "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++}
++EOF
++dnl test, if assembler supports S390 arch13 zarch instructions as default
++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
++			-o conftest.o &> /dev/null]) ;
++then
++  libc_cv_asm_s390_min_arch13_zarch=yes
++else
++  libc_cv_asm_s390_min_arch13_zarch=no
++fi
++rm -f conftest* ])
++if test "$libc_cv_asm_s390_min_arch13_zarch" = yes ;
++then
++  AC_DEFINE(HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT)
++fi
++
+ test -n "$critic_missing" && AC_MSG_ERROR([
+ *** $critic_missing])
diff --git a/SOURCES/glibc-rh1659438-6.patch b/SOURCES/glibc-rh1659438-6.patch
new file mode 100644
index 0000000..9f4157d
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-6.patch
@@ -0,0 +1,429 @@
+commit 6c6b8c747096d74b900e2711b9b0d463677f6d31
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:05 2018 +0100
+
+    S390: Unify 31/64bit memcmp.
+    
+    The implementation of memcmp for s390-32 (31bit) and
+    s390-64 (64bit) is nearly the same.
+    This patch unifies it for maintability reasons.
+    
+    __memcmp_z10 and __memcmp_z196 differs between 31 and 64bit:
+    -31bit needs .machinemode "zarch_nohighgprs" and llgfr   %r4,%r4
+    -lr vs lgr and some other instructions:
+    But lgr and co can be also used on 31bit as this ifunc variant
+    is only called if we are on a zarch machine.
+    
+    __memcmp_default differs between 31 and 64bit:
+    -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr.
+    Solved with 31/64 specific instruction macros).
+    -The address of mvc instruction is setup in different ways
+    (larl vs bras). Solved with #if defined __s390x__.
+    
+    Otherwise 31/64bit implementation has the same structure of the code.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/s390-64/memcmp.S: Move to ...
+            * sysdeps/s390/memcmp.S: ... here.
+            Adjust to be usable for 31/64bit.
+            * sysdeps/s390/s390-32/memcmp.S: Delete File.
+            * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memcmp.
+            * sysdeps/s390/s390-32/multiarch/Makefile (sysdep_routines):
+            Remove memcmp.
+            * sysdeps/s390/s390-64/multiarch/Makefile: Likewise.
+            * sysdeps/s390/s390-64/multiarch/memcmp-s390x.S: Move to ...
+            * sysdeps/s390/multiarch/memcmp-s390x.S: ... here.
+            Adjust to be usable for 31/64bit.
+            * sysdeps/s390/s390-32/multiarch/memcmp-s390.S: Delete File.
+            * sysdeps/s390/s390-64/multiarch/memcmp.c: Move to ...
+            * sysdeps/s390/multiarch/memcmp.c: ... here.
+            * sysdeps/s390/s390-32/multiarch/memcmp.c: Delete File.
+
+diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/memcmp.S
+similarity index 60%
+rename from sysdeps/s390/s390-64/memcmp.S
+rename to sysdeps/s390/memcmp.S
+index 005b19de45fcd883..751293a99e34f530 100644
+--- a/sysdeps/s390/s390-64/memcmp.S
++++ b/sysdeps/s390/memcmp.S
+@@ -1,4 +1,4 @@
+-/* memcmp - compare two memory blocks.  64 bit S/390 version.
++/* memcmp - compare two memory blocks.  31/64 bit S/390 version.
+    Copyright (C) 2012-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -26,34 +26,62 @@
+      %r4 = number of bytes to compare.  */
+ 
+        .text
++#if defined __s390x__
++# define LTGR	ltgr
++# define AGHI	aghi
++# define BRCTG	brctg
++#else
++# define LTGR	ltr
++# define AGHI	ahi
++# define BRCTG	brct
++#endif /* ! defined __s390x__  */
++
+ #ifdef USE_MULTIARCH
+ ENTRY(__memcmp_default)
+ #else
+ ENTRY(memcmp)
+ #endif
++#if defined __s390x__
+ 	.machine "z900"
+-	ltgr    %r4,%r4
+-	je      .L_Z900_4
+-	aghi    %r4,-1
++#else
++	.machine "g5"
++	basr    %r5,0
++.L_Z900_G5_16:
++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16
++#endif /* ! defined __s390x__  */
++	LTGR    %r4,%r4
++	je      .L_Z900_G5_4
++	AGHI    %r4,-1
++#if defined __s390x__
+ 	srlg    %r1,%r4,8
+-	ltgr    %r1,%r1
+-	jne     .L_Z900_12
+-.L_Z900_3:
+-	larl    %r1,.L_Z900_15
+-	ex      %r4,0(%r1)
+-.L_Z900_4:
++	larl    %r5,.L_Z900_G5_15
++# define Z900_G5_EX_D 0
++#else
++	lr	%r1,%r4
++	srl	%r1,8
++#endif /* ! defined __s390x__  */
++	LTGR    %r1,%r1
++	jne     .L_Z900_G5_12
++.L_Z900_G5_3:
++	ex      %r4,Z900_G5_EX_D(%r5)
++.L_Z900_G5_4:
+ 	ipm     %r2
++#if defined __s390x__
+ 	sllg    %r2,%r2,34
+ 	srag    %r2,%r2,62
++#else
++	sll     %r2,2
++	sra     %r2,30
++#endif /* ! defined __s390x__  */
+ 	br      %r14
+-.L_Z900_12:
++.L_Z900_G5_12:
+ 	clc     0(256,%r3),0(%r2)
+-	jne     .L_Z900_4
++	jne     .L_Z900_G5_4
+ 	la      %r3,256(%r3)
+ 	la      %r2,256(%r2)
+-	brctg   %r1,.L_Z900_12
+-	j       .L_Z900_3
+-.L_Z900_15:
++	BRCTG   %r1,.L_Z900_G5_12
++	j       .L_Z900_G5_3
++.L_Z900_G5_15:
+ 	clc     0(1,%r3),0(%r2)
+ #ifdef USE_MULTIARCH
+ END(__memcmp_default)
+@@ -62,3 +90,7 @@ END(memcmp)
+ libc_hidden_builtin_def (memcmp)
+ weak_alias (memcmp, bcmp)
+ #endif
++
++#undef LTGR
++#undef AGHI
++#undef BRCTG
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index c893ebc5659fd4ae..53dd8654d73677db 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -19,7 +19,8 @@ sysdep_routines += strlen strlen-vx strlen-c \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c \
+-		   mempcpy
++		   mempcpy \
++		   memcmp memcmp-s390x
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+diff --git a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/sysdeps/s390/multiarch/memcmp-s390x.S
+similarity index 89%
+rename from sysdeps/s390/s390-64/multiarch/memcmp-s390x.S
+rename to sysdeps/s390/multiarch/memcmp-s390x.S
+index 35f9bf9cf72da503..6321737acec821ec 100644
+--- a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S
++++ b/sysdeps/s390/multiarch/memcmp-s390x.S
+@@ -1,4 +1,4 @@
+-/* CPU specific memcmp implementations.  64 bit S/390 version.
++/* CPU specific memcmp implementations.  31/64 bit S/390 version.
+    Copyright (C) 2012-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -31,6 +31,10 @@
+ 
+ ENTRY(__memcmp_z196)
+ 	.machine "z196"
++	.machinemode "zarch_nohighgprs"
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
+ 	ltgr    %r4,%r4
+ 	je      .L_Z196_4
+ 	aghi    %r4,-1
+@@ -64,6 +68,10 @@ END(__memcmp_z196)
+ 
+ ENTRY(__memcmp_z10)
+ 	.machine "z10"
++	.machinemode "zarch_nohighgprs"
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
+ 	ltgr    %r4,%r4
+ 	je      .L_Z10_4
+ 	aghi    %r4,-1
+diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.c b/sysdeps/s390/multiarch/memcmp.c
+similarity index 100%
+rename from sysdeps/s390/s390-32/multiarch/memcmp.c
+rename to sysdeps/s390/multiarch/memcmp.c
+diff --git a/sysdeps/s390/s390-32/memcmp.S b/sysdeps/s390/s390-32/memcmp.S
+deleted file mode 100644
+index f9ad0bc745daf05f..0000000000000000
+--- a/sysdeps/s390/s390-32/memcmp.S
++++ /dev/null
+@@ -1,66 +0,0 @@
+-/* memcmp - compare two memory blocks.  32 bit S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of first memory area
+-     %r3 = address of second memory area
+-     %r4 = number of bytes to compare.  */
+-
+-       .text
+-#ifdef USE_MULTIARCH
+-ENTRY(__memcmp_default)
+-#else
+-ENTRY(memcmp)
+-#endif
+-	.machine "g5"
+-	basr    %r5,0
+-.L_G5_16:
+-	ltr     %r4,%r4
+-	je      .L_G5_4
+-	ahi     %r4,-1
+-	lr      %r1,%r4
+-	srl     %r1,8
+-	ltr     %r1,%r1
+-	jne     .L_G5_12
+-	ex      %r4,.L_G5_17-.L_G5_16(%r5)
+-.L_G5_4:
+-	ipm     %r2
+-	sll     %r2,2
+-	sra     %r2,30
+-	br      %r14
+-.L_G5_12:
+-	clc     0(256,%r3),0(%r2)
+-	jne     .L_G5_4
+-	la      %r3,256(%r3)
+-	la      %r2,256(%r2)
+-	brct    %r1,.L_G5_12
+-	ex      %r4,.L_G5_17-.L_G5_16(%r5)
+-	j       .L_G5_4
+-.L_G5_17:
+-	clc     0(1,%r3),0(%r2)
+-#ifdef USE_MULTIARCH
+-END(__memcmp_default)
+-#else
+-END(memcmp)
+-libc_hidden_builtin_def (memcmp)
+-weak_alias(memcmp, bcmp)
+-#endif
+diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile
+index 4b11e28656ac19ab..82a7492eb8436479 100644
+--- a/sysdeps/s390/s390-32/multiarch/Makefile
++++ b/sysdeps/s390/s390-32/multiarch/Makefile
+@@ -1,3 +1,3 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += memcpy memcpy-s390 memcmp memcmp-s390
++sysdep_routines += memcpy memcpy-s390
+ endif
+diff --git a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S
+deleted file mode 100644
+index e53b508c98bebeba..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S
++++ /dev/null
+@@ -1,107 +0,0 @@
+-/* CPU specific memcmp implementations.  32 bit S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of first memory area
+-     %r3 = address of second memory area
+-     %r4 = number of bytes to compare.  */
+-
+-       .text
+-
+-#if IS_IN (libc)
+-
+-ENTRY(__memcmp_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-	ltr     %r4,%r4
+-	je      .L_Z196_4
+-	ahi     %r4,-1
+-	srlk    %r1,%r4,8
+-	ltr     %r1,%r1
+-	jne     .L_Z196_2
+-.L_Z196_3:
+-	exrl    %r4,.L_Z196_14
+-.L_Z196_4:
+-	ipm     %r2
+-	sll     %r2,2
+-	sra     %r2,30
+-	br      %r14
+-.L_Z196_17:
+-	la      %r3,256(%r3)
+-	la      %r2,256(%r2)
+-	ahi     %r1,-1
+-	je      .L_Z196_3
+-.L_Z196_2:
+-	pfd     1,512(%r3)
+-	pfd     1,512(%r2)
+-	clc     0(256,%r3),0(%r2)
+-	je      .L_Z196_17
+-	ipm     %r2
+-	sll     %r2,2
+-	sra     %r2,30
+-	br      %r14
+-.L_Z196_14:
+-	clc     0(1,%r3),0(%r2)
+-END(__memcmp_z196)
+-
+-ENTRY(__memcmp_z10)
+-	.machine "z10"
+-	.machinemode "zarch_nohighgprs"
+-	ltr     %r4,%r4
+-	je      .L_Z10_4
+-	ahi     %r4,-1
+-	lr      %r1,%r4
+-	srl     %r1,8
+-	cijlh   %r1,0,.L_Z10_12
+-.L_Z10_3:
+-	exrl    %r4,.L_Z10_15
+-.L_Z10_4:
+-	ipm     %r2
+-	sll     %r2,2
+-	sra     %r2,30
+-	br      %r14
+-.L_Z10_12:
+-	pfd     1,512(%r3)
+-	pfd     1,512(%r2)
+-	clc     0(256,%r3),0(%r2)
+-	jne     .L_Z10_4
+-	la      %r3,256(%r3)
+-	la      %r2,256(%r2)
+-	brct    %r1,.L_Z10_12
+-	j       .L_Z10_3
+-.L_Z10_15:
+-	clc     0(1,%r3),0(%r2)
+-END(__memcmp_z10)
+-
+-#endif /* IS_IN (libc) */
+-
+-#include "../memcmp.S"
+-
+-#if !IS_IN (libc)
+-.globl   memcmp
+-.set     memcmp,__memcmp_default
+-.weak    bcmp
+-.set	 bcmp,__memcmp_default
+-#elif defined SHARED && IS_IN (libc)
+-.globl   __GI_memcmp
+-.set     __GI_memcmp,__memcmp_default
+-#endif
+diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile
+index e4870c7ee177ad0d..8a043e3327a1527a 100644
+--- a/sysdeps/s390/s390-64/multiarch/Makefile
++++ b/sysdeps/s390/s390-64/multiarch/Makefile
+@@ -1,3 +1,3 @@
+ ifeq ($(subdir),string)
+-sysdep_routines += memcpy memcpy-s390x memcmp memcmp-s390x
++sysdep_routines += memcpy memcpy-s390x
+ endif
+diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c
+deleted file mode 100644
+index 1e6f31806e172d7d..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/memcmp.c
++++ /dev/null
+@@ -1,27 +0,0 @@
+-/* Multiple versions of memcmp.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-#if IS_IN (libc)
+-# define memcmp __redirect_memcmp
+-# include <string.h>
+-# undef memcmp
+-# include <ifunc-resolve.h>
+-
+-s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
+-weak_alias (memcmp, bcmp);
+-#endif
diff --git a/SOURCES/glibc-rh1659438-60.patch b/SOURCES/glibc-rh1659438-60.patch
new file mode 100644
index 0000000..6eacc7f
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-60.patch
@@ -0,0 +1,202 @@
+commit 96fbb9a328232e42814334d6e29a9a9c7995c01d
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Fri Mar 22 11:14:08 2019 +0100
+
+    S390: Add arch13 memmove ifunc variant.
+    
+    This patch introduces the new arch13 ifunc variant for memmove.
+    For the forward or non-overlapping case it is just using memcpy.
+    For the backward case it relies on the new instruction mvcrl.
+    The instruction copies up to 256 bytes at once.
+    In case of an overlap, it copies the bytes like copying them
+    one by one starting from right to left.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/ifunc-memcpy.h (HAVE_MEMMOVE_ARCH13, MEMMOVE_ARCH13
+            HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT): New defines.
+            * sysdeps/s390/memcpy-z900.S: Add arch13 memmove implementation.
+            * sysdeps/s390/memmove.c (memmove): Add arch13 variant in
+            ifunc selector.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Add ifunc variant for arch13 memmove.
+            * sysdeps/s390/multiarch/ifunc-resolve.h (S390_STFLE_BITS_ARCH13_MIE3,
+            S390_IS_ARCH13_MIE3): New defines.
+
+diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h
+index 0e701968c8f39014..e8cd794587b44922 100644
+--- a/sysdeps/s390/ifunc-memcpy.h
++++ b/sysdeps/s390/ifunc-memcpy.h
+@@ -44,7 +44,7 @@
+ #endif
+ 
+ #if defined SHARED && defined USE_MULTIARCH && IS_IN (libc)	\
+-  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++  && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT
+ # define HAVE_MEMMOVE_IFUNC	1
+ #else
+ # define HAVE_MEMMOVE_IFUNC	0
+@@ -56,14 +56,27 @@
+ # define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT 0
+ #endif
+ 
+-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT
++# define HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT HAVE_MEMMOVE_IFUNC
++#else
++# define HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT
++# define MEMMOVE_DEFAULT	MEMMOVE_ARCH13
++# define HAVE_MEMMOVE_C		0
++# define HAVE_MEMMOVE_Z13	0
++# define HAVE_MEMMOVE_ARCH13	1
++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
+ # define MEMMOVE_DEFAULT	MEMMOVE_Z13
+ # define HAVE_MEMMOVE_C		0
+ # define HAVE_MEMMOVE_Z13	1
++# define HAVE_MEMMOVE_ARCH13	HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT
+ #else
+ # define MEMMOVE_DEFAULT	MEMMOVE_C
+ # define HAVE_MEMMOVE_C		1
+ # define HAVE_MEMMOVE_Z13	HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT
++# define HAVE_MEMMOVE_ARCH13	HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT
+ #endif
+ 
+ #if HAVE_MEMCPY_Z900_G5
+@@ -101,3 +114,9 @@
+ #else
+ # define MEMMOVE_Z13		NULL
+ #endif
++
++#if HAVE_MEMMOVE_ARCH13
++# define MEMMOVE_ARCH13		__memmove_arch13
++#else
++# define MEMMOVE_ARCH13		NULL
++#endif
+diff --git a/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S
+index bd3b1950ee442c0c..45eddc67a48e991e 100644
+--- a/sysdeps/s390/memcpy-z900.S
++++ b/sysdeps/s390/memcpy-z900.S
+@@ -277,6 +277,61 @@ ENTRY(MEMMOVE_Z13)
+ END(MEMMOVE_Z13)
+ #endif /* HAVE_MEMMOVE_Z13  */
+ 
++#if HAVE_MEMMOVE_ARCH13
++ENTRY(MEMMOVE_ARCH13)
++	.machine "arch13"
++	.machinemode "zarch_nohighgprs"
++# if ! defined __s390x__
++	/* Note: The 31bit dst and src pointers are prefixed with zeroes.  */
++	llgfr	%r4,%r4
++	llgfr	%r3,%r3
++	llgfr	%r2,%r2
++# endif /* ! defined __s390x__ */
++	sgrk	%r5,%r2,%r3
++	aghik	%r0,%r4,-1	/* Both vstl and mvcrl needs highest index.  */
++	clgijh	%r4,16,.L_MEMMOVE_ARCH13_LARGE
++.L_MEMMOVE_ARCH13_SMALL:
++	jl .L_MEMMOVE_ARCH13_END /* Return if len was zero (cc of aghik).  */
++	/* Store up to 16 bytes with vll/vstl (needs highest index).  */
++	vll	%v16,%r0,0(%r3)
++	vstl	%v16,%r0,0(%r2)
++.L_MEMMOVE_ARCH13_END:
++	br      %r14
++.L_MEMMOVE_ARCH13_LARGE:
++	lgr     %r1,%r2	/* For memcpy: r1: Use as dest ; r2: Return dest  */
++	/* The unsigned comparison (dst - src >= len) determines if we can
++	   execute the forward case with memcpy.  */
++#if ! HAVE_MEMCPY_Z196
++# error The arch13 variant of memmove needs the z196 variant of memcpy!
++#endif
++	/* Backward case.  */
++	clgrjhe %r5,%r4,.L_Z196_start2
++	clgijh	%r0,255,.L_MEMMOVE_ARCH13_LARGER_256B
++	/* Move up to 256bytes with mvcrl (move right to left).  */
++	mvcrl	0(%r1),0(%r3)	/* Move (r0 + 1) bytes from r3 to r1.  */
++	br      %r14
++.L_MEMMOVE_ARCH13_LARGER_256B:
++	/* First move the "remaining" block of up to 256 bytes at the end of
++	   src/dst buffers.  Then move blocks of 256bytes in a loop starting
++	   with the block at the end.
++	   (If src/dst pointers are aligned e.g. to 256 bytes, then the pointers
++	   passed to mvcrl instructions are aligned, too)  */
++	risbgn	%r5,%r0,8,128+63,56	/* r5 = r0 / 256  */
++	risbgn	%r0,%r0,56,128+63,0	/* r0 = r0 & 0xFF  */
++	slgr	%r4,%r0
++	lay	%r1,-1(%r4,%r1)
++	lay	%r3,-1(%r4,%r3)
++	mvcrl	0(%r1),0(%r3)	/* Move (r0 + 1) bytes from r3 to r1.  */
++	lghi	%r0,255		/* Always copy 256 bytes in the loop below!  */
++.L_MEMMOVE_ARCH13_LARGE_256B_LOOP:
++	aghi	%r1,-256
++	aghi	%r3,-256
++	mvcrl	0(%r1),0(%r3)	/* Move (r0 + 1) bytes from r3 to r1.  */
++	brctg	%r5,.L_MEMMOVE_ARCH13_LARGE_256B_LOOP
++	br      %r14
++END(MEMMOVE_ARCH13)
++#endif /* HAVE_MEMMOVE_ARCH13  */
++
+ #if ! HAVE_MEMCPY_IFUNC
+ /* If we don't use ifunc, define an alias for mem[p]cpy here.
+    Otherwise see sysdeps/s390/mem[p]cpy.c.  */
+diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c
+index ac34edf80f2678cd..f6d31a4fcd56355b 100644
+--- a/sysdeps/s390/memmove.c
++++ b/sysdeps/s390/memmove.c
+@@ -36,9 +36,19 @@ extern __typeof (__redirect_memmove) MEMMOVE_C attribute_hidden;
+ extern __typeof (__redirect_memmove) MEMMOVE_Z13 attribute_hidden;
+ # endif
+ 
++# if HAVE_MEMMOVE_ARCH13
++extern __typeof (__redirect_memmove) MEMMOVE_ARCH13 attribute_hidden;
++# endif
++
+ s390_libc_ifunc_expr (__redirect_memmove, memmove,
+-		      (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX))
+-		      ? MEMMOVE_Z13
+-		      : MEMMOVE_DEFAULT
++		      ({
++			s390_libc_ifunc_expr_stfle_init ();
++			(HAVE_MEMMOVE_ARCH13
++			 && S390_IS_ARCH13_MIE3 (stfle_bits))
++			  ? MEMMOVE_ARCH13
++			  : (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX))
++			  ? MEMMOVE_Z13
++			  : MEMMOVE_DEFAULT;
++		      })
+ 		      )
+ #endif
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 177c5fd6fe269d9b..c24bfc95f2d7a22d 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -169,6 +169,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+ #if HAVE_MEMMOVE_IFUNC
+     IFUNC_IMPL (i, name, memmove,
++# if HAVE_MEMMOVE_ARCH13
++		IFUNC_IMPL_ADD (array, i, memmove,
++				S390_IS_ARCH13_MIE3 (stfle_bits),
++				MEMMOVE_ARCH13)
++# endif
+ # if HAVE_MEMMOVE_Z13
+ 		IFUNC_IMPL_ADD (array, i, memmove,
+ 				dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13)
+diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
+index b2be015401313d4b..db735bb341ab6b86 100644
+--- a/sysdeps/s390/multiarch/ifunc-resolve.h
++++ b/sysdeps/s390/multiarch/ifunc-resolve.h
+@@ -22,6 +22,11 @@
+ 
+ #define S390_STFLE_BITS_Z10  34 /* General instructions extension */
+ #define S390_STFLE_BITS_Z196 45 /* Distinct operands, pop ... */
++#define S390_STFLE_BITS_ARCH13_MIE3 61 /* Miscellaneous-Instruction-Extensions
++					  Facility 3, e.g. mvcrl.  */
++
++#define S390_IS_ARCH13_MIE3(STFLE_BITS)			\
++  ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_ARCH13_MIE3))) != 0)
+ 
+ #define S390_IS_Z196(STFLE_BITS)			\
+   ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_Z196))) != 0)
diff --git a/SOURCES/glibc-rh1659438-61.patch b/SOURCES/glibc-rh1659438-61.patch
new file mode 100644
index 0000000..32e535a
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-61.patch
@@ -0,0 +1,332 @@
+commit 6f47401bd5fc71209219779a0426170a9a7395b0
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Fri Mar 22 11:14:08 2019 +0100
+
+    S390: Add arch13 strstr ifunc variant.
+    
+    This patch introduces the new arch13 ifunc variant for strstr.
+    For needles longer than 9 charachters it is relying on the common-code
+    implementation.  For shorter needles it is using the new vstrs instruction
+    which is able to search a substring within a vector register.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/Makefile (sysdep_routines): Add strstr-arch13.
+            * sysdeps/s390/ifunc-strstr.h (HAVE_STRSTR_ARCH13, STRSTR_ARCH13,
+            STRSTR_Z13_ONLY_USED_AS_FALLBACK, HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT):
+            New defines.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Add ifunc variant for arch13 strstr.
+            * sysdeps/s390/strstr-arch13.S: New file.
+            * sysdeps/s390/strstr-vx.c: Omit GI symbol for z13 strstr ifunc variant
+            if it is only used as fallback.
+            * sysdeps/s390/strstr.c (strstr): Add arch13 variant in ifunc selector.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 3f7de6613c343819..7287b1833da9500f 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -35,7 +35,7 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   memcmp memcmp-z900 \
+ 		   mempcpy memcpy memcpy-z900 \
+ 		   memmove memmove-c \
+-		   strstr strstr-vx strstr-c \
++		   strstr strstr-arch13 strstr-vx strstr-c \
+ 		   memmem memmem-vx memmem-c \
+ 		   strlen strlen-vx strlen-c \
+ 		   strnlen strnlen-vx strnlen-c \
+diff --git a/sysdeps/s390/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h
+index e6ccfd4e44a1a790..809184d425ad06b0 100644
+--- a/sysdeps/s390/ifunc-strstr.h
++++ b/sysdeps/s390/ifunc-strstr.h
+@@ -17,7 +17,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #if defined USE_MULTIARCH && IS_IN (libc)		\
+-  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++  && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT
+ # define HAVE_STRSTR_IFUNC	1
+ #else
+ # define HAVE_STRSTR_IFUNC	0
+@@ -29,14 +29,32 @@
+ # define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT 0
+ #endif
+ 
+-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT
++# define HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT HAVE_STRSTR_IFUNC
++#else
++# define HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT
++# define STRSTR_DEFAULT		STRSTR_ARCH13
++# define HAVE_STRSTR_C		0
++# define HAVE_STRSTR_Z13	1
++# define STRSTR_Z13_ONLY_USED_AS_FALLBACK 1
++# define HAVE_STRSTR_ARCH13	1
++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
+ # define STRSTR_DEFAULT		STRSTR_Z13
+ # define HAVE_STRSTR_C		0
+ # define HAVE_STRSTR_Z13	1
++# define HAVE_STRSTR_ARCH13	HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT
+ #else
+ # define STRSTR_DEFAULT		STRSTR_C
+ # define HAVE_STRSTR_C		1
+ # define HAVE_STRSTR_Z13	HAVE_STRSTR_IFUNC_AND_VX_SUPPORT
++# define HAVE_STRSTR_ARCH13	HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT
++#endif
++
++#ifndef STRSTR_Z13_ONLY_USED_AS_FALLBACK
++# define STRSTR_Z13_ONLY_USED_AS_FALLBACK 0
+ #endif
+ 
+ #if HAVE_STRSTR_C
+@@ -50,3 +68,9 @@
+ #else
+ # define STRSTR_Z13		NULL
+ #endif
++
++#if HAVE_STRSTR_ARCH13
++# define STRSTR_ARCH13		__strstr_arch13
++#else
++# define STRSTR_ARCH13		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index c24bfc95f2d7a22d..67a6a9c94afccd48 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -186,6 +186,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+ #if HAVE_STRSTR_IFUNC
+     IFUNC_IMPL (i, name, strstr,
++# if HAVE_STRSTR_ARCH13
++		IFUNC_IMPL_ADD (array, i, strstr,
++				dl_hwcap & HWCAP_S390_VXRS_EXT2, STRSTR_ARCH13)
++# endif
+ # if HAVE_STRSTR_Z13
+ 		IFUNC_IMPL_ADD (array, i, strstr,
+ 				dl_hwcap & HWCAP_S390_VX, STRSTR_Z13)
+diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S
+new file mode 100644
+index 0000000000000000..929b026adfeba740
+--- /dev/null
++++ b/sysdeps/s390/strstr-arch13.S
+@@ -0,0 +1,179 @@
++/* Vector optimized 32/64 bit S/390 version of strstr.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-strstr.h>
++#if HAVE_STRSTR_ARCH13
++# include "sysdep.h"
++# include "asm-syntax.h"
++	.text
++
++/* char *strstr (const char *haystack=r2, const char *needle=r3)
++   Locate a substring.  */
++ENTRY(STRSTR_ARCH13)
++	.machine "arch13"
++	.machinemode "zarch_nohighgprs"
++	lcbb	%r1,0(%r3),6
++	jo	.Lneedle_on_bb	/* Needle on block-boundary?  */
++	vl	%v18,0(%r3),6	/* Load needle.  */
++	vfenezb %v19,%v18,%v18	/* v19[7] contains the length of needle.  */
++.Lneedle_loaded:
++	vlgvb	%r4,%v19,7	/* Get index of zero or 16 if not found.  */
++	lghi	%r5,17		/* See below: min-skip-partial-match-index.  */
++	cgibe	%r4,0,0(%r14)	/* Test if needle is zero and return.  */
++
++	/* The vstrs instruction is able to handle needles up to a length of 16,
++	   but then we may have to load the next part of haystack with a
++	   small offset.  This will be slow - see examples:
++	   haystack =mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm...mmmmmmmmmmmmmmmmmmma
++	   needle   =  mmmmmmmmmmmmmma0
++	   => needle_len=15; vstrs reports a partial match; haystack+=2
++	   haystack =mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm...mmmmmmmmmmmmmmmmmmma
++	   needle   =        mmmmmmmma0000000
++	   => needle_len=9; vstrs reports a partial match; haystack+=8  */
++# if ! HAVE_STRSTR_Z13
++#  error The arch13 variant of strstr needs the z13 variant of strstr!
++# endif
++	clgfi	%r4,9
++	jh	STRSTR_Z13
++
++	/* In case of a partial match, the vstrs instruction returns the index
++	   of the partial match in a vector-register.  Then we have to
++	   reload the string at the "current-position plus this index" and run
++	   vstrs again in order to determine if it was a full match or no match.
++	   Transferring this index from vr to gr, compute the haystack-address
++	   and loading with vl is quite slow as all instructions have data
++	   dependencies.  Thus we assume, that a partial match is always at the
++	   first possible index and just load the next part of haystack from
++	   there instead of waiting until the correct index is computed:
++	   min-skip-partial-match-index = (16 - n_len) + 1  */
++	sgr	%r5,%r4
++
++.Lloop:
++	lcbb	%r1,0(%r2),6
++	jo	.Lloop_haystack_on_bb	/* Haystack on block-boundary?  */
++	vl	%v16,0(%r2)		/* Load next part of haystack.  */
++.Lloop_haystack_loaded:
++	/* Vector string search with zero search (cc=0 => no match).  */
++	vstrs	%v20,%v16,%v18,%v19,0,2
++	jne	.Lloop_vstrs_nonzero_cc
++	lcbb	%r1,16(%r2),6		/* Next part of haystack.  */
++	jo	.Lloop_haystack_on_bb16
++	vl	%v16,16(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,2
++	jne	.Lloop_vstrs_nonzero_cc16
++	lcbb	%r1,32(%r2),6		/* Next part of haystack.  */
++	jo	.Lloop_haystack_on_bb32
++	vl	%v16,32(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,2
++	jne	.Lloop_vstrs_nonzero_cc32
++	lcbb	%r1,48(%r2),6		/* Next part of haystack.  */
++	jo	.Lloop_haystack_on_bb48
++	vl	%v16,48(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,2
++	jne	.Lloop_vstrs_nonzero_cc48
++	la	%r2,64(%r2)
++	j	.Lloop
++
++.Lloop_vstrs_nonzero_cc48:
++	la	%r2,16(%r2)
++.Lloop_vstrs_nonzero_cc32:
++	la	%r2,16(%r2)
++.Lloop_vstrs_nonzero_cc16:
++	la	%r2,16(%r2)
++.Lloop_vstrs_nonzero_cc:
++	jh	.Lend_match_found /* cc == 2 (full match)  */
++	jl	.Lend_no_match	/* cc == 1 (no match, end of string)  */
++	/* cc == 3 (partial match) See above: min-skip-partial-match-index!  */
++	lcbb	%r1,0(%r5,%r2),6
++	la	%r2,0(%r5,%r2)
++	jo	.Lloop_haystack_on_bb
++	vl	%v16,0(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,2
++.Lloop_vstrs_nonzero_cc_loop:
++	jh	.Lend_match_found
++	jl	.Lend_no_match
++	la	%r2,0(%r5,%r2)
++	je	.Lloop
++	lcbb	%r1,0(%r2),6		/* Next part of haystack.  */
++	jo	.Lloop_haystack_on_bb
++	vl	%v16,0(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,2
++	jh	.Lend_match_found
++	jl	.Lend_no_match
++	la	%r2,0(%r5,%r2)
++	je	.Lloop
++	lcbb	%r1,0(%r2),6		/* Next part of haystack.  */
++	jo	.Lloop_haystack_on_bb
++	vl	%v16,0(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,2
++	jh	.Lend_match_found
++	jl	.Lend_no_match
++	la	%r2,0(%r5,%r2)
++	je	.Lloop
++	lcbb	%r1,0(%r2),6		/* Next part of haystack.  */
++	jo	.Lloop_haystack_on_bb
++	vl	%v16,0(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,2
++	j	.Lloop_vstrs_nonzero_cc_loop
++
++.Lend_no_match:
++	lghi	%r2,0
++	br	%r14
++.Lend_match_found:
++	vlgvb	%r4,%v20,7
++	la	%r2,0(%r4,%r2)
++	br	%r14
++
++.Lloop_haystack_on_bb48:
++	la	%r2,16(%r2)
++.Lloop_haystack_on_bb32:
++	la	%r2,16(%r2)
++.Lloop_haystack_on_bb16:
++	la	%r2,16(%r2)
++.Lloop_haystack_on_bb:
++	/* Haystack located on page-boundary.  */
++	ahi	%r1,-1		/* vll needs highest index instead of count.  */
++	vll	%v16,%r1,0(%r2)
++	vlvgb	%v21,%r1,7
++	vfenezb	%v17,%v16,%v16	/* Search zero in loaded haystack bytes.  */
++	veclb	%v17,%v21		/* Zero index <= loaded byte index?  */
++	jle	.Lloop_haystack_loaded	/* -> v16 contains full haystack.  */
++	vl	%v16,0(%r2)	/* Load haystack beyond page boundary.  */
++	j	.Lloop_haystack_loaded
++
++.Lneedle_on_bb:
++	/* Needle located on page-boundary.  */
++	ahi	%r1,-1		/* vll needs highest index instead of count.  */
++	vll	%v18,%r1,0(%r3)
++	vlvgb	%v21,%r1,7
++	vfenezb	%v19,%v18,%v18	/* Search zero in loaded needle bytes.  */
++	veclb	%v19,%v21	/* Zero index <= max loaded byte index?  */
++	jle	.Lneedle_loaded	/* -> v18 contains full needle.  */
++	vl	%v16,0(%r3)	/* Load needle beyond page boundary.  */
++	vfenezb	%v19,%v18,%v18
++	j	.Lneedle_loaded
++END(STRSTR_ARCH13)
++
++# if ! HAVE_STRSTR_IFUNC
++strong_alias (STRSTR_ARCH13, strstr)
++# endif
++
++# if STRSTR_Z13_ONLY_USED_AS_FALLBACK && defined SHARED && IS_IN (libc)
++strong_alias (STRSTR_ARCH13, __GI_strstr)
++# endif
++#endif
+diff --git a/sysdeps/s390/strstr-vx.c b/sysdeps/s390/strstr-vx.c
+index effae9d5eb7d2fb1..f69159ffc198b10b 100644
+--- a/sysdeps/s390/strstr-vx.c
++++ b/sysdeps/s390/strstr-vx.c
+@@ -19,11 +19,11 @@
+ #include <ifunc-strstr.h>
+ 
+ #if HAVE_STRSTR_Z13
+-# if HAVE_STRSTR_IFUNC
++# if HAVE_STRSTR_IFUNC || STRSTR_Z13_ONLY_USED_AS_FALLBACK
+ #  define STRSTR STRSTR_Z13
+ #  if defined SHARED && IS_IN (libc)
+ #   undef libc_hidden_builtin_def
+-#   if HAVE_STRSTR_C
++#   if HAVE_STRSTR_C || STRSTR_Z13_ONLY_USED_AS_FALLBACK
+ #    define libc_hidden_builtin_def(name)
+ #   else
+ #    define libc_hidden_builtin_def(name)		\
+diff --git a/sysdeps/s390/strstr.c b/sysdeps/s390/strstr.c
+index f8432349a7254cc6..d2969fd0a68fadbf 100644
+--- a/sysdeps/s390/strstr.c
++++ b/sysdeps/s390/strstr.c
+@@ -32,8 +32,14 @@ extern __typeof (__redirect_strstr) STRSTR_C attribute_hidden;
+ extern __typeof (__redirect_strstr) STRSTR_Z13 attribute_hidden;
+ # endif
+ 
++# if HAVE_STRSTR_ARCH13
++extern __typeof (__redirect_strstr) STRSTR_ARCH13 attribute_hidden;
++# endif
++
+ s390_libc_ifunc_expr (__redirect_strstr, strstr,
+-		      (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX))
++		      (HAVE_STRSTR_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2))
++		      ? STRSTR_ARCH13
++		      : (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX))
+ 		      ? STRSTR_Z13
+ 		      : STRSTR_DEFAULT
+ 		      )
diff --git a/SOURCES/glibc-rh1659438-62.patch b/SOURCES/glibc-rh1659438-62.patch
new file mode 100644
index 0000000..9d430c0
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-62.patch
@@ -0,0 +1,318 @@
+commit 421749d693c4147017bc55f5ac3227c3a6e4bf31
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Fri Mar 22 11:14:09 2019 +0100
+
+    S390: Add arch13 memmem ifunc variant.
+    
+    This patch introduces the new arch13 ifunc variant for memmem.
+    For needles longer than 9 bytes it is relying on the common-code
+    implementation.  For shorter needles it is using the new vstrs instruction
+    which is able to search a substring within a vector register.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/Makefile (sysdep_routines): Add memmem-arch13.
+            * sysdeps/s390/ifunc-memmem.h (HAVE_MEMMEM_ARCH13, MEMMEM_ARCH13,
+            MEMMEM_Z13_ONLY_USED_AS_FALLBACK, HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT):
+            New defines.
+            * sysdeps/s390/memmem-arch13.S: New file.
+            * sysdeps/s390/memmem-vx.c: Omit GI symbol for z13 memmem ifunc variant
+            if it is only used as fallback.
+            * sysdeps/s390/memmem.c (memmem): Add arch13 variant in ifunc selector.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Add ifunc variant for arch13 memmem.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index 7287b1833da9500f..8bc82e523f9049db 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -36,7 +36,7 @@ sysdep_routines += bzero memset memset-z900 \
+ 		   mempcpy memcpy memcpy-z900 \
+ 		   memmove memmove-c \
+ 		   strstr strstr-arch13 strstr-vx strstr-c \
+-		   memmem memmem-vx memmem-c \
++		   memmem memmem-arch13 memmem-vx memmem-c \
+ 		   strlen strlen-vx strlen-c \
+ 		   strnlen strnlen-vx strnlen-c \
+ 		   strcpy strcpy-vx strcpy-z900 \
+diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h
+index 0f860d8d40080acf..48079b22b070f381 100644
+--- a/sysdeps/s390/ifunc-memmem.h
++++ b/sysdeps/s390/ifunc-memmem.h
+@@ -17,7 +17,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #if defined USE_MULTIARCH && IS_IN (libc)		\
+-  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++  && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT
+ # define HAVE_MEMMEM_IFUNC	1
+ #else
+ # define HAVE_MEMMEM_IFUNC	0
+@@ -29,14 +29,32 @@
+ # define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT 0
+ #endif
+ 
+-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT
++# define HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT HAVE_MEMMEM_IFUNC
++#else
++# define HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT 0
++#endif
++
++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT
++# define MEMMEM_DEFAULT		MEMMEM_ARCH13
++# define HAVE_MEMMEM_C		0
++# define HAVE_MEMMEM_Z13	1
++# define MEMMEM_Z13_ONLY_USED_AS_FALLBACK 1
++# define HAVE_MEMMEM_ARCH13	1
++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
+ # define MEMMEM_DEFAULT		MEMMEM_Z13
+ # define HAVE_MEMMEM_C		0
+ # define HAVE_MEMMEM_Z13	1
++# define HAVE_MEMMEM_ARCH13	HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT
+ #else
+ # define MEMMEM_DEFAULT		MEMMEM_C
+ # define HAVE_MEMMEM_C		1
+ # define HAVE_MEMMEM_Z13	HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT
++# define HAVE_MEMMEM_ARCH13	HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT
++#endif
++
++#ifndef MEMMEM_Z13_ONLY_USED_AS_FALLBACK
++# define MEMMEM_Z13_ONLY_USED_AS_FALLBACK 0
+ #endif
+ 
+ #if HAVE_MEMMEM_C
+@@ -50,3 +68,9 @@
+ #else
+ # define MEMMEM_Z13		NULL
+ #endif
++
++#if HAVE_MEMMEM_ARCH13
++# define MEMMEM_ARCH13		__memmem_arch13
++#else
++# define MEMMEM_ARCH13		NULL
++#endif
+diff --git a/sysdeps/s390/memmem-arch13.S b/sysdeps/s390/memmem-arch13.S
+new file mode 100644
+index 0000000000000000..b59d60acf0f6aaa0
+--- /dev/null
++++ b/sysdeps/s390/memmem-arch13.S
+@@ -0,0 +1,161 @@
++/* Vector optimized 32/64 bit S/390 version of memmem.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ifunc-memmem.h>
++#if HAVE_MEMMEM_ARCH13
++# include "sysdep.h"
++# include "asm-syntax.h"
++	.text
++
++/* void *memmem(const void *haystack=r2, size_t haystacklen=r3,
++		const void *needle=r4, size_t needlelen=r5);
++   Locate a substring.  */
++ENTRY(MEMMEM_ARCH13)
++	.machine "arch13"
++	.machinemode "zarch_nohighgprs"
++# if ! defined __s390x__
++	llgfr	%r3,%r3
++	llgfr	%r5,%r5
++	llgfr	%r4,%r4
++	llgfr	%r2,%r2
++# endif /* ! defined __s390x__ */
++	clgrjl	%r3,%r5,.Lend_no_match	/* Haystack < needle?  */
++
++	/* Jump to fallback if needle > 9.  See also strstr-arch13.S.  */
++# if ! HAVE_MEMMEM_Z13
++#  error The arch13 variant of memmem needs the z13 variant of memmem!
++# endif
++	clgfi	%r5,9
++	jh	MEMMEM_Z13
++
++	aghik	%r0,%r5,-1		/* vll needs highest index.  */
++	bc	4,0(%r14)		/* cc==1: return if needle-len == 0.  */
++	vll	%v18,%r0,0(%r4)		/* Load needle.  */
++	vlvgb	%v19,%r5,7		/* v19[7] contains length of needle.  */
++
++	clgijh	%r3,16,.Lhaystack_larger_16
++.Lhaystack_smaller_16_on_bb:
++	aghik	%r0,%r3,-1		/* vll needs highest index.  */
++	vll	%v16,%r0,0(%r2)		/* Load haystack.  */
++.Lhaystack_smaller_16:
++	sgr	%r3,%r5			/* r3 = largest valid match-index.  */
++	jl	.Lend_no_match		/* Haystack-len < needle-len?  */
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	/* Vector string search without zero search where v20 will contain
++	   the index of a partial/full match or 16 (index is named k).
++	   cc=0 (no match; k=16): .Lend_no_match
++	   cc=1 (only available with zero-search): Ignore
++	   cc=2 (full match; k<16): Needle found, but could be beyond haystack!
++	   cc=3 (partial match; k<16): Always at end of v16 and thus beyond!  */
++	brc	9,.Lend_no_match	/* Jump away if cc == 0 || cc == 3.  */
++	vlgvb	%r1,%v20,7
++	/* Verify that the full-match (cc=2) is valid!  */
++	clgrjh	%r1,%r3,.Lend_no_match	/* Jump away if match is beyond.  */
++	la	%r2,0(%r1,%r2)
++	br	%r14
++.Lend_no_match:
++	lghi	%r2,0
++	br	%r14
++
++.Lhaystack_larger_16:
++	vl	%v16,0(%r2)
++	lghi	%r1,17
++	lay	%r4,-16(%r3,%r2)	/* Boundary for loading with vl.  */
++	lay	%r0,-64(%r3,%r2)	/* Boundary for loading with 4xvl.  */
++	/* See also strstr-arch13.S:
++	   min-skip-partial-match-index = (16 - n_len) + 1  */
++	sgr	%r1,%r5
++	clgfi	%r3,64			/* Set Boundary to zero ...  */
++	la	%r3,0(%r3,%r2)
++	locghil	%r0,0			/* ... if haystack < 64bytes.  */
++	jh	.Lloop64
++.Lloop:
++	la	%r2,16(%r2)
++	/* Vector string search with zero search.  cc=0 => no match.  */
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	jne	.Lloop_vstrs_nonzero_cc
++	clgrjh	%r2,%r4,.Lhaystack_too_small
++.Lloop16:
++	vl	%v16,0(%r2)
++	la	%r2,16(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	jne	.Lloop_vstrs_nonzero_cc
++	clgrjle	%r2,%r4,.Lloop16
++.Lhaystack_too_small:
++	sgr	%r3,%r2			/* r3 = (haystack + len) - curr_pos  */
++	je	.Lend_no_match		/* Remaining haystack is empty.  */
++	lcbb	%r0,0(%r2),6
++	jo	.Lhaystack_smaller_16_on_bb
++	vl	%v16,0(%r2)		/* Load haystack.  */
++	j	.Lhaystack_smaller_16
++
++.Lend_match_found:
++	vlgvb	%r4,%v20,7
++	sgr	%r2,%r1
++	la	%r2,0(%r4,%r2)
++	br	%r14
++
++.Lloop_vstrs_nonzero_cc32:
++	la	%r2,16(%r2)
++.Lloop_vstrs_nonzero_cc16:
++	la	%r2,16(%r2)
++.Lloop_vstrs_nonzero_cc0:
++	la	%r2,16(%r2)
++.Lloop_vstrs_nonzero_cc:
++	lay	%r2,-16(%r1,%r2)	/* Compute next load address.  */
++	jh	.Lend_match_found	/* cc == 2 (full match)  */
++	clgrjh	%r2,%r4,.Lhaystack_too_small
++	vl	%v16,0(%r2)
++.Lloop_vstrs_nonzero_cc_loop:
++	la	%r2,0(%r1,%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	jh	.Lend_match_found
++	clgrjh	%r2,%r4,.Lhaystack_too_small
++	vl	%v16,0(%r2)		/* Next part of haystack.  */
++	jo	.Lloop_vstrs_nonzero_cc_loop
++	/* Case: no-match.  */
++	clgrjh	%r2,%r0,.Lloop	/* Jump away if haystack has less than 64b.  */
++.Lloop64:
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	jne	.Lloop_vstrs_nonzero_cc0
++	vl	%v16,16(%r2)		/* Next part of haystack.  */
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	jne	.Lloop_vstrs_nonzero_cc16
++	vl	%v16,32(%r2)		/* Next part of haystack.  */
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	jne	.Lloop_vstrs_nonzero_cc32
++	vl	%v16,48(%r2)		/* Next part of haystack.  */
++	la	%r2,64(%r2)
++	vstrs	%v20,%v16,%v18,%v19,0,0
++	jne	.Lloop_vstrs_nonzero_cc
++	clgrjh	%r2,%r4,.Lhaystack_too_small
++	vl	%v16,0(%r2)		/* Next part of haystack.  */
++	clgrjle	%r2,%r0,.Lloop64
++	j	.Lloop
++END(MEMMEM_ARCH13)
++
++# if ! HAVE_MEMMEM_IFUNC
++strong_alias (MEMMEM_ARCH13, __memmem)
++weak_alias (__memmem, memmem)
++# endif
++
++# if MEMMEM_Z13_ONLY_USED_AS_FALLBACK && defined SHARED && IS_IN (libc)
++weak_alias (MEMMEM_ARCH13, __GI_memmem)
++strong_alias (MEMMEM_ARCH13, __GI___memmem)
++# endif
++#endif
+diff --git a/sysdeps/s390/memmem-vx.c b/sysdeps/s390/memmem-vx.c
+index af6e200e4e0af1a5..e5608be77f05f2a9 100644
+--- a/sysdeps/s390/memmem-vx.c
++++ b/sysdeps/s390/memmem-vx.c
+@@ -20,7 +20,7 @@
+ 
+ #if HAVE_MEMMEM_Z13
+ # include <string.h>
+-# if HAVE_MEMMEM_IFUNC
++# if HAVE_MEMMEM_IFUNC || MEMMEM_Z13_ONLY_USED_AS_FALLBACK
+ 
+ #  ifndef _LIBC
+ #   define memmem MEMMEM_Z13
+@@ -32,7 +32,7 @@
+ #   undef libc_hidden_def
+ #   undef libc_hidden_weak
+ 
+-#   if HAVE_MEMMEM_C
++#   if HAVE_MEMMEM_C || MEMMEM_Z13_ONLY_USED_AS_FALLBACK
+ #    define libc_hidden_def(name)
+ #    define libc_hidden_weak(name)
+ #   else
+diff --git a/sysdeps/s390/memmem.c b/sysdeps/s390/memmem.c
+index 8c50b3f403eb8d1f..28871cd4b24868cc 100644
+--- a/sysdeps/s390/memmem.c
++++ b/sysdeps/s390/memmem.c
+@@ -34,8 +34,14 @@ extern __typeof (__redirect_memmem) MEMMEM_C attribute_hidden;
+ extern __typeof (__redirect_memmem) MEMMEM_Z13 attribute_hidden;
+ # endif
+ 
++# if HAVE_MEMMEM_ARCH13
++extern __typeof (__redirect_memmem) MEMMEM_ARCH13 attribute_hidden;
++# endif
++
+ s390_libc_ifunc_expr (__redirect_memmem, __memmem,
+-		      (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX))
++		      (HAVE_MEMMEM_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2))
++		      ? MEMMEM_ARCH13
++		      : (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX))
+ 		      ? MEMMEM_Z13
+ 		      : MEMMEM_DEFAULT
+ 		      )
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 67a6a9c94afccd48..787d40688f4110ff 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -202,6 +202,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 
+ #if HAVE_MEMMEM_IFUNC
+     IFUNC_IMPL (i, name, memmem,
++# if HAVE_MEMMEM_ARCH13
++	      IFUNC_IMPL_ADD (array, i, memmem,
++			      dl_hwcap & HWCAP_S390_VXRS_EXT2, MEMMEM_ARCH13)
++# endif
+ # if HAVE_MEMMEM_Z13
+ 		IFUNC_IMPL_ADD (array, i, memmem,
+ 				dl_hwcap & HWCAP_S390_VX, MEMMEM_Z13)
diff --git a/SOURCES/glibc-rh1659438-7.patch b/SOURCES/glibc-rh1659438-7.patch
new file mode 100644
index 0000000..bad570b
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-7.patch
@@ -0,0 +1,503 @@
+commit b7e024a838452a85870256d8f1ab946dc8f931cd
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:05 2018 +0100
+
+    S390: Refactor memcmp ifunc handling.
+    
+    This patch moves all ifunc variants for memcmp
+    to sysdeps/s390/memcmp-z900.S. The configure-check/preprocessor logic
+    in sysdeps/s390/ifunc-memcmp.h decides if ifunc is needed at all
+    and which ifunc variants should be available.
+    E.g. if the compiler/assembler already supports z196 by default,
+    the older ifunc variants are not included.
+    If we only need the newest ifunc variant,
+    then we can skip ifunc at all.
+    
+    Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted
+    in order to handle only the available ifunc variants.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/ifunc-memcmp.h: New File.
+            * sysdeps/s390/memcmp.S: Move to ...
+            * sysdeps/s390/memcmp-z900.S ... here.
+            Move implementations from memcmp-s390x.s to here.
+            * sysdeps/s390/multiarch/memcmp-s390x.S: Delete File.
+            * sysdeps/s390/multiarch/Makefile (sysdep_routines):
+            Remove memcmp variants.
+            * sysdeps/s390/Makefile (sysdep_routines):
+            Add memcmp variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Adjust ifunc variants for
+            memcmp.
+            * sysdeps/s390/multiarch/memcmp.c: Move ifunc resolver
+            to ...
+            * sysdeps/s390/memcmp.c: ... here.
+            Adjust ifunc variants for memcmp.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index e40e5bd982e54d89..c59cbdc25aad408a 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -31,5 +31,6 @@ sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules
+ endif
+ 
+ ifeq ($(subdir),string)
+-sysdep_routines += bzero memset memset-z900
++sysdep_routines += bzero memset memset-z900 \
++		   memcmp memcmp-z900
+ endif
+diff --git a/sysdeps/s390/ifunc-memcmp.h b/sysdeps/s390/ifunc-memcmp.h
+new file mode 100644
+index 0000000000000000..536ac455d177c027
+--- /dev/null
++++ b/sysdeps/s390/ifunc-memcmp.h
+@@ -0,0 +1,59 @@
++/* memcmp variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined USE_MULTIARCH && IS_IN (libc)	\
++  && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# define HAVE_MEMCMP_IFUNC	1
++#else
++# define HAVE_MEMCMP_IFUNC	0
++#endif
++
++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# define MEMCMP_DEFAULT		MEMCMP_Z196
++# define HAVE_MEMCMP_Z900_G5	0
++# define HAVE_MEMCMP_Z10	0
++# define HAVE_MEMCMP_Z196	1
++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
++# define MEMCMP_DEFAULT		MEMCMP_Z10
++# define HAVE_MEMCMP_Z900_G5	0
++# define HAVE_MEMCMP_Z10	1
++# define HAVE_MEMCMP_Z196	HAVE_MEMCMP_IFUNC
++#else
++# define MEMCMP_DEFAULT		MEMCMP_Z900_G5
++# define HAVE_MEMCMP_Z900_G5	1
++# define HAVE_MEMCMP_Z10	HAVE_MEMCMP_IFUNC
++# define HAVE_MEMCMP_Z196	HAVE_MEMCMP_IFUNC
++#endif
++
++#if HAVE_MEMCMP_Z900_G5
++# define MEMCMP_Z900_G5		__memcmp_default
++#else
++# define MEMCMP_Z900_G5		NULL
++#endif
++
++#if HAVE_MEMCMP_Z10
++# define MEMCMP_Z10		__memcmp_z10
++#else
++# define MEMCMP_Z10		NULL
++#endif
++
++#if HAVE_MEMCMP_Z196
++# define MEMCMP_Z196		__memcmp_z196
++#else
++# define MEMCMP_Z196		NULL
++#endif
+diff --git a/sysdeps/s390/multiarch/memcmp-s390x.S b/sysdeps/s390/memcmp-z900.S
+similarity index 54%
+rename from sysdeps/s390/multiarch/memcmp-s390x.S
+rename to sysdeps/s390/memcmp-z900.S
+index 6321737acec821ec..c3b3677ba78264ee 100644
+--- a/sysdeps/s390/multiarch/memcmp-s390x.S
++++ b/sysdeps/s390/memcmp-z900.S
+@@ -1,4 +1,4 @@
+-/* CPU specific memcmp implementations.  31/64 bit S/390 version.
++/* memcmp - compare two memory blocks.  31/64 bit S/390 version.
+    Copyright (C) 2012-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -17,8 +17,9 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ 
+-#include "sysdep.h"
++#include <sysdep.h>
+ #include "asm-syntax.h"
++#include <ifunc-memcmp.h>
+ 
+ /* INPUT PARAMETERS
+      %r2 = address of first memory area
+@@ -27,46 +28,67 @@
+ 
+        .text
+ 
+-#if IS_IN (libc)
+-
+-ENTRY(__memcmp_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-# if !defined __s390x__
+-	llgfr	%r4,%r4
+-# endif /* !defined __s390x__  */
+-	ltgr    %r4,%r4
+-	je      .L_Z196_4
+-	aghi    %r4,-1
++#if HAVE_MEMCMP_Z900_G5
++# if defined __s390x__
++#  define LTGR	ltgr
++#  define AGHI	aghi
++#  define BRCTG	brctg
++# else
++#  define LTGR	ltr
++#  define AGHI	ahi
++#  define BRCTG	brct
++# endif /* ! defined __s390x__  */
++ENTRY(MEMCMP_Z900_G5)
++# if defined __s390x__
++	.machine "z900"
++# else
++	.machine "g5"
++	basr    %r5,0
++.L_Z900_G5_16:
++#  define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16
++# endif /* ! defined __s390x__  */
++	LTGR    %r4,%r4
++	je      .L_Z900_G5_4
++	AGHI    %r4,-1
++# if defined __s390x__
+ 	srlg    %r1,%r4,8
+-	ltgr    %r1,%r1
+-	jne     .L_Z196_2
+-.L_Z196_3:
+-	exrl    %r4,.L_Z196_14
+-.L_Z196_4:
++	larl    %r5,.L_Z900_G5_15
++#  define Z900_G5_EX_D 0
++# else
++	lr	%r1,%r4
++	srl	%r1,8
++# endif /* ! defined __s390x__  */
++	LTGR    %r1,%r1
++	jne     .L_Z900_G5_12
++.L_Z900_G5_3:
++	ex      %r4,Z900_G5_EX_D(%r5)
++.L_Z900_G5_4:
+ 	ipm     %r2
++# if defined __s390x__
+ 	sllg    %r2,%r2,34
+ 	srag    %r2,%r2,62
++# else
++	sll     %r2,2
++	sra     %r2,30
++# endif /* ! defined __s390x__  */
+ 	br      %r14
+-.L_Z196_17:
++.L_Z900_G5_12:
++	clc     0(256,%r3),0(%r2)
++	jne     .L_Z900_G5_4
+ 	la      %r3,256(%r3)
+ 	la      %r2,256(%r2)
+-	aghi    %r1,-1
+-	je      .L_Z196_3
+-.L_Z196_2:
+-	pfd     1,512(%r3)
+-	pfd     1,512(%r2)
+-	clc     0(256,%r3),0(%r2)
+-	je      .L_Z196_17
+-	ipm     %r2
+-	sllg    %r2,%r2,34
+-	srag    %r2,%r2,62
+-	br      %r14
+-.L_Z196_14:
++	BRCTG   %r1,.L_Z900_G5_12
++	j       .L_Z900_G5_3
++.L_Z900_G5_15:
+ 	clc     0(1,%r3),0(%r2)
+-END(__memcmp_z196)
++END(MEMCMP_Z900_G5)
++# undef LTGR
++# undef AGHI
++# undef BRCTG
++#endif /* HAVE_MEMCMP_Z900_G5  */
+ 
+-ENTRY(__memcmp_z10)
++#if HAVE_MEMCMP_Z10
++ENTRY(MEMCMP_Z10)
+ 	.machine "z10"
+ 	.machinemode "zarch_nohighgprs"
+ # if !defined __s390x__
+@@ -95,18 +117,57 @@ ENTRY(__memcmp_z10)
+ 	j       .L_Z10_3
+ .L_Z10_15:
+ 	clc     0(1,%r3),0(%r2)
+-END(__memcmp_z10)
++END(MEMCMP_Z10)
++#endif /* HAVE_MEMCMP_Z10  */
+ 
+-#endif /* IS_IN (libc) */
++#if HAVE_MEMCMP_Z196
++ENTRY(MEMCMP_Z196)
++	.machine "z196"
++	.machinemode "zarch_nohighgprs"
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
++	ltgr    %r4,%r4
++	je      .L_Z196_4
++	aghi    %r4,-1
++	srlg    %r1,%r4,8
++	ltgr    %r1,%r1
++	jne     .L_Z196_2
++.L_Z196_3:
++	exrl    %r4,.L_Z196_14
++.L_Z196_4:
++	ipm     %r2
++	sllg    %r2,%r2,34
++	srag    %r2,%r2,62
++	br      %r14
++.L_Z196_17:
++	la      %r3,256(%r3)
++	la      %r2,256(%r2)
++	aghi    %r1,-1
++	je      .L_Z196_3
++.L_Z196_2:
++	pfd     1,512(%r3)
++	pfd     1,512(%r2)
++	clc     0(256,%r3),0(%r2)
++	je      .L_Z196_17
++	ipm     %r2
++	sllg    %r2,%r2,34
++	srag    %r2,%r2,62
++	br      %r14
++.L_Z196_14:
++	clc     0(1,%r3),0(%r2)
++END(MEMCMP_Z196)
++#endif /* HAVE_MEMCMP_Z196  */
+ 
+-#include "../memcmp.S"
++#if ! HAVE_MEMCMP_IFUNC
++/* If we don't use ifunc, define an alias for memcmp here.
++   Otherwise see sysdeps/s390/memcmp.c.  */
++strong_alias (MEMCMP_DEFAULT, memcmp)
++weak_alias (memcmp, bcmp)
++#endif
+ 
+-#if !IS_IN (libc)
+-.globl   memcmp
+-.set     memcmp,__memcmp_default
+-.weak    bcmp
+-.set	 bcmp,__memcmp_default
+-#elif defined SHARED && IS_IN (libc)
+-.globl   __GI_memcmp
+-.set     __GI_memcmp,__memcmp_default
++#if defined SHARED && IS_IN (libc)
++/* Defines the internal symbols.
++   Compare to libc_hidden_builtin_def (memcmp) in string/memcmp.c.  */
++strong_alias (MEMCMP_DEFAULT, __GI_memcmp)
+ #endif
+diff --git a/sysdeps/s390/memcmp.S b/sysdeps/s390/memcmp.S
+deleted file mode 100644
+index 751293a99e34f530..0000000000000000
+--- a/sysdeps/s390/memcmp.S
++++ /dev/null
+@@ -1,96 +0,0 @@
+-/* memcmp - compare two memory blocks.  31/64 bit S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include <sysdep.h>
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of first memory area
+-     %r3 = address of second memory area
+-     %r4 = number of bytes to compare.  */
+-
+-       .text
+-#if defined __s390x__
+-# define LTGR	ltgr
+-# define AGHI	aghi
+-# define BRCTG	brctg
+-#else
+-# define LTGR	ltr
+-# define AGHI	ahi
+-# define BRCTG	brct
+-#endif /* ! defined __s390x__  */
+-
+-#ifdef USE_MULTIARCH
+-ENTRY(__memcmp_default)
+-#else
+-ENTRY(memcmp)
+-#endif
+-#if defined __s390x__
+-	.machine "z900"
+-#else
+-	.machine "g5"
+-	basr    %r5,0
+-.L_Z900_G5_16:
+-# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16
+-#endif /* ! defined __s390x__  */
+-	LTGR    %r4,%r4
+-	je      .L_Z900_G5_4
+-	AGHI    %r4,-1
+-#if defined __s390x__
+-	srlg    %r1,%r4,8
+-	larl    %r5,.L_Z900_G5_15
+-# define Z900_G5_EX_D 0
+-#else
+-	lr	%r1,%r4
+-	srl	%r1,8
+-#endif /* ! defined __s390x__  */
+-	LTGR    %r1,%r1
+-	jne     .L_Z900_G5_12
+-.L_Z900_G5_3:
+-	ex      %r4,Z900_G5_EX_D(%r5)
+-.L_Z900_G5_4:
+-	ipm     %r2
+-#if defined __s390x__
+-	sllg    %r2,%r2,34
+-	srag    %r2,%r2,62
+-#else
+-	sll     %r2,2
+-	sra     %r2,30
+-#endif /* ! defined __s390x__  */
+-	br      %r14
+-.L_Z900_G5_12:
+-	clc     0(256,%r3),0(%r2)
+-	jne     .L_Z900_G5_4
+-	la      %r3,256(%r3)
+-	la      %r2,256(%r2)
+-	BRCTG   %r1,.L_Z900_G5_12
+-	j       .L_Z900_G5_3
+-.L_Z900_G5_15:
+-	clc     0(1,%r3),0(%r2)
+-#ifdef USE_MULTIARCH
+-END(__memcmp_default)
+-#else
+-END(memcmp)
+-libc_hidden_builtin_def (memcmp)
+-weak_alias (memcmp, bcmp)
+-#endif
+-
+-#undef LTGR
+-#undef AGHI
+-#undef BRCTG
+diff --git a/sysdeps/s390/multiarch/memcmp.c b/sysdeps/s390/memcmp.c
+similarity index 60%
+rename from sysdeps/s390/multiarch/memcmp.c
+rename to sysdeps/s390/memcmp.c
+index 1e6f31806e172d7d..952ff6af7364fd92 100644
+--- a/sysdeps/s390/multiarch/memcmp.c
++++ b/sysdeps/s390/memcmp.c
+@@ -16,12 +16,34 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#if IS_IN (libc)
++#include <ifunc-memcmp.h>
++#if HAVE_MEMCMP_IFUNC
+ # define memcmp __redirect_memcmp
+ # include <string.h>
+ # undef memcmp
+ # include <ifunc-resolve.h>
+ 
+-s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
++# if HAVE_MEMCMP_Z900_G5
++extern __typeof (__redirect_memcmp) MEMCMP_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_MEMCMP_Z10
++extern __typeof (__redirect_memcmp) MEMCMP_Z10 attribute_hidden;
++# endif
++
++# if HAVE_MEMCMP_Z196
++extern __typeof (__redirect_memcmp) MEMCMP_Z196 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect_memcmp, memcmp,
++		      ({
++			s390_libc_ifunc_init ();
++			(HAVE_MEMCMP_Z196 && S390_IS_Z196 (stfle_bits))
++			  ? MEMCMP_Z196
++			  : (HAVE_MEMCMP_Z10 && S390_IS_Z10 (stfle_bits))
++			  ? MEMCMP_Z10
++			  : MEMCMP_DEFAULT;
++		      })
++		      )
+ weak_alias (memcmp, bcmp);
+ #endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 53dd8654d73677db..c893ebc5659fd4ae 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -19,8 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c \
+-		   mempcpy \
+-		   memcmp memcmp-s390x
++		   mempcpy
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 253f36045b57cc3c..2e57d01abc21522e 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -22,6 +22,7 @@
+ #include <ifunc-impl-list.h>
+ #include <ifunc-resolve.h>
+ #include <ifunc-memset.h>
++#include <ifunc-memcmp.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -78,12 +79,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 	      )
+ #endif /* HAVE_MEMSET_IFUNC */
+ 
++#if HAVE_MEMCMP_IFUNC
+   IFUNC_IMPL (i, name, memcmp,
++# if HAVE_MEMCMP_Z196
+ 	      IFUNC_IMPL_ADD (array, i, memcmp,
+-			      S390_IS_Z196 (stfle_bits), __memcmp_z196)
++			      S390_IS_Z196 (stfle_bits), MEMCMP_Z196)
++# endif
++# if HAVE_MEMCMP_Z10
+ 	      IFUNC_IMPL_ADD (array, i, memcmp,
+-			      S390_IS_Z10 (stfle_bits), __memcmp_z10)
+-	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_default))
++			      S390_IS_Z10 (stfle_bits), MEMCMP_Z10)
++# endif
++# if HAVE_MEMCMP_Z900_G5
++	      IFUNC_IMPL_ADD (array, i, memcmp, 1, MEMCMP_Z900_G5)
++# endif
++	      )
++#endif /* HAVE_MEMCMP_IFUNC */
+ 
+ #ifdef SHARED
+ 
diff --git a/SOURCES/glibc-rh1659438-8.patch b/SOURCES/glibc-rh1659438-8.patch
new file mode 100644
index 0000000..464f5d2
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-8.patch
@@ -0,0 +1,538 @@
+commit df3eb8de31a530f285f54f3c41cd7b636816c062
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:06 2018 +0100
+
+    S390: Unify 31/64bit memcpy.
+    
+    The implementation of memcpy/mempcpy for s390-32 (31bit)
+    and s390-64 (64bit) is nearly the same.
+    This patch unifies it for maintability reasons.
+    
+    __mem[p]cpy_z10 and __mem[p]cpy_z196 differs between 31 and 64bit:
+    -31bit needs .machinemode "zarch_nohighgprs" and llgfr   %r4,%r4
+    -lr vs lgr; lgr can be also used on 31bit as this ifunc variant
+    is only called if we are on a zarch machine.
+    
+    __mem[p]cpy_default differs between 31 and 64bit:
+    -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr.
+    Solved with 31/64 specific instruction macros).
+    -The address of mvc instruction is setup in different ways
+    (larl vs bras). Solved with #if defined __s390x__.
+    
+    __memcpy_mvcle differs between 31 and 64bit:
+    -lr vs lgr; ahi vs aghi;
+    Solved with 31/64bit specific instruction macros.
+    
+    Otherwise 31/64bit implementation has the same structure of the code.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/s390-64/memcpy.S: Move to ...
+            * sysdeps/s390/memcpy.S: ... here.
+            Adjust to be usable for 31/64bit.
+            * sysdeps/s390/s390-32/memcpy.S: Delete File.
+            * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memcpy.
+            * sysdeps/s390/s390-32/multiarch/Makefile: Delete file.
+            * sysdeps/s390/s390-64/multiarch/Makefile: Likewise.
+            * sysdeps/s390/s390-64/multiarch/memcpy-s390x.S: Move to ...
+            * sysdeps/s390/multiarch/memcpy-s390x.S: ... here.
+            Adjust to be usable for 31/64bit.
+            * sysdeps/s390/s390-32/multiarch/memcpy-s390.S: Delete File.
+            * sysdeps/s390/s390-64/multiarch/memcpy.c: Move to ...
+            * sysdeps/s390/multiarch/memcpy.c: ... here.
+            * sysdeps/s390/s390-32/multiarch/memcpy.c: Delete File.
+
+diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/memcpy.S
+similarity index 52%
+rename from sysdeps/s390/s390-64/memcpy.S
+rename to sysdeps/s390/memcpy.S
+index 2e5490df23d64325..2a6c6b750377c7bb 100644
+--- a/sysdeps/s390/s390-64/memcpy.S
++++ b/sysdeps/s390/memcpy.S
+@@ -1,4 +1,4 @@
+-/* memcpy - copy a block from source to destination.  64 bit S/390 version.
++/* memcpy - copy a block from source to destination.  31/64 bit S/390 version.
+    Copyright (C) 2012-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -25,13 +25,31 @@
+      %r3 = address of source memory area
+      %r4 = number of bytes to copy.  */
+ 
+-
+        .text
++
++#if defined __s390x__
++# define LTGR	ltgr
++# define CGHI	cghi
++# define LGR	lgr
++# define AGHI	aghi
++# define BRCTG	brctg
++#else
++# define LTGR	ltr
++# define CGHI	chi
++# define LGR	lr
++# define AGHI	ahi
++# define BRCTG	brct
++#endif /* ! defined __s390x__  */
++
+ ENTRY(__mempcpy)
++#if defined __s390x__
+ 	.machine "z900"
+-	lgr     %r1,%r2             # Use as dest
++#else
++	.machine "g5"
++#endif /* ! defined __s390x__  */
++	LGR     %r1,%r2             # Use as dest
+ 	la      %r2,0(%r4,%r2)      # Return dest + n
+-	j	.L_Z900_start
++	j	.L_Z900_G5_start
+ END(__mempcpy)
+ #ifndef USE_MULTIARCH
+ libc_hidden_def (__mempcpy)
+@@ -40,30 +58,46 @@ libc_hidden_builtin_def (mempcpy)
+ #endif
+ 
+ ENTRY(memcpy)
++#if defined __s390x__
+ 	.machine "z900"
+-	lgr     %r1,%r2             # r1: Use as dest ; r2: Return dest
+-.L_Z900_start:
+-	ltgr    %r4,%r4
+-	je      .L_Z900_4
+-	aghi    %r4,-1
+-	srlg    %r5,%r4,8
+-	ltgr    %r5,%r5
+-	jne     .L_Z900_13
+-.L_Z900_3:
+-	larl    %r5,.L_Z900_15
+-	ex      %r4,0(%r5)
+-.L_Z900_4:
++#else
++	.machine "g5"
++#endif /* ! defined __s390x__  */
++	LGR     %r1,%r2             # r1: Use as dest ; r2: Return dest
++.L_Z900_G5_start:
++	LTGR    %r4,%r4
++	je      .L_Z900_G5_4
++	AGHI    %r4,-1
++#if defined __s390x__
++	srlg	%r5,%r4,8
++#else
++	lr	%r5,%r4
++	srl	%r5,8
++#endif /* ! defined __s390x__  */
++	LTGR    %r5,%r5
++	jne     .L_Z900_G5_13
++.L_Z900_G5_3:
++#if defined __s390x__
++	larl    %r5,.L_Z900_G5_15
++# define Z900_G5_EX_D 0
++#else
++	basr    %r5,0
++.L_Z900_G5_14:
++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14
++#endif /* ! defined __s390x__  */
++	ex      %r4,Z900_G5_EX_D(%r5)
++.L_Z900_G5_4:
+ 	br      %r14
+-.L_Z900_13:
+-	cghi	%r5,4096            # Switch to mvcle for copies >1MB
++.L_Z900_G5_13:
++	CGHI	%r5,4096            # Switch to mvcle for copies >1MB
+ 	jh      __memcpy_mvcle
+-.L_Z900_12:
++.L_Z900_G5_12:
+ 	mvc     0(256,%r1),0(%r3)
+ 	la      %r1,256(%r1)
+ 	la      %r3,256(%r3)
+-	brctg   %r5,.L_Z900_12
+-	j       .L_Z900_3
+-.L_Z900_15:
++	BRCTG   %r5,.L_Z900_G5_12
++	j       .L_Z900_G5_3
++.L_Z900_G5_15:
+ 	mvc     0(1,%r1),0(%r3)
+ END(memcpy)
+ #ifndef USE_MULTIARCH
+@@ -74,15 +108,21 @@ ENTRY(__memcpy_mvcle)
+ 	# Using as standalone function will result in unexpected
+ 	# results since the length field is incremented by 1 in order to
+ 	# compensate the changes already done in the functions above.
+-	lgr     %r0,%r2             # backup return dest [ + n ]
+-	aghi    %r4,1               # length + 1
+-	lgr     %r5,%r4             # source length
+-	lgr     %r4,%r3             # source address
+-	lgr     %r2,%r1             # destination address
+-	lgr     %r3,%r5             # destination length = source length
++	LGR     %r0,%r2             # backup return dest [ + n ]
++	AGHI    %r4,1               # length + 1
++	LGR     %r5,%r4             # source length
++	LGR     %r4,%r3             # source address
++	LGR     %r2,%r1             # destination address
++	LGR     %r3,%r5             # destination length = source length
+ .L_MVCLE_1:
+ 	mvcle   %r2,%r4,0           # thats it, MVCLE is your friend
+ 	jo      .L_MVCLE_1
+-	lgr     %r2,%r0             # return destination address
++	LGR     %r2,%r0             # return destination address
+ 	br      %r14
+ END(__memcpy_mvcle)
++
++#undef LTGR
++#undef CGHI
++#undef LGR
++#undef AGHI
++#undef BRCTG
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index c893ebc5659fd4ae..3cbd5fad69e355a5 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -19,7 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+ 		   memrchr memrchr-vx memrchr-c \
+-		   mempcpy
++		   mempcpy memcpy memcpy-s390x
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+diff --git a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/sysdeps/s390/multiarch/memcpy-s390x.S
+similarity index 89%
+rename from sysdeps/s390/s390-64/multiarch/memcpy-s390x.S
+rename to sysdeps/s390/multiarch/memcpy-s390x.S
+index 6d60a70834c32120..b38caac72b8742e6 100644
+--- a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S
++++ b/sysdeps/s390/multiarch/memcpy-s390x.S
+@@ -1,4 +1,4 @@
+-/* CPU specific memcpy implementations.  64 bit S/390 version.
++/* CPU specific memcpy implementations.  31/64 bit S/390 version.
+    Copyright (C) 2012-2018 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -31,6 +31,7 @@
+ 
+ ENTRY(____mempcpy_z196)
+ 	.machine "z196"
++	.machinemode "zarch_nohighgprs"
+ 	lgr     %r1,%r2         # Use as dest
+ 	la      %r2,0(%r4,%r2)  # Return dest + n
+ 	j	.L_Z196_start
+@@ -38,8 +39,12 @@ END(____mempcpy_z196)
+ 
+ ENTRY(__memcpy_z196)
+ 	.machine "z196"
++	.machinemode "zarch_nohighgprs"
+ 	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
+ .L_Z196_start:
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
+ 	ltgr    %r4,%r4
+ 	je      .L_Z196_4
+ 	aghi    %r4,-1
+@@ -68,6 +73,7 @@ END(__memcpy_z196)
+ 
+ ENTRY(____mempcpy_z10)
+ 	.machine "z10"
++	.machinemode "zarch_nohighgprs"
+ 	lgr     %r1,%r2         # Use as dest
+ 	la      %r2,0(%r4,%r2)  # Return dest + n
+ 	j	.L_Z10_start
+@@ -75,8 +81,12 @@ END(____mempcpy_z10)
+ 
+ ENTRY(__memcpy_z10)
+ 	.machine "z10"
++	.machinemode "zarch_nohighgprs"
+ 	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
+ .L_Z10_start:
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
+ 	cgije   %r4,0,.L_Z10_4
+ 	aghi    %r4,-1
+ 	srlg    %r5,%r4,8
+diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/multiarch/memcpy.c
+similarity index 100%
+rename from sysdeps/s390/s390-32/multiarch/memcpy.c
+rename to sysdeps/s390/multiarch/memcpy.c
+diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S
+deleted file mode 100644
+index 493cc18aba67d6ec..0000000000000000
+--- a/sysdeps/s390/s390-32/memcpy.S
++++ /dev/null
+@@ -1,89 +0,0 @@
+-/* memcpy - copy a block from source to destination.  S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = address of destination memory area
+-     %r3 = address of source memory area
+-     %r4 = number of bytes to copy.  */
+-
+-       .text
+-ENTRY(__mempcpy)
+-	.machine "g5"
+-	lr      %r1,%r2             # Use as dest
+-	la      %r2,0(%r4,%r2)      # Return dest + n
+-	j	.L_G5_start
+-END(__mempcpy)
+-#ifndef USE_MULTIARCH
+-libc_hidden_def (__mempcpy)
+-weak_alias (__mempcpy, mempcpy)
+-libc_hidden_builtin_def (mempcpy)
+-#endif
+-
+-ENTRY(memcpy)
+-	.machine "g5"
+-	lr      %r1,%r2             # r1: Use as dest ; r2: Return dest
+-.L_G5_start:
+-	ltr     %r4,%r4
+-	je      .L_G5_99
+-	ahi     %r4,-1
+-	lr      %r5,%r4
+-	srl     %r5,8
+-	ltr     %r5,%r5
+-	jne     .L_G5_13
+-.L_G5_4:
+-	basr    %r5,0
+-.L_G5_16:
+-	ex      %r4,.L_G5_17-.L_G5_16(%r5)
+-.L_G5_99:
+-	br      %r14
+-.L_G5_13:
+-	chi	%r5,4096            # Switch to mvcle for copies >1MB
+-	jh	__memcpy_mvcle
+-.L_G5_12:
+-	mvc     0(256,%r1),0(%r3)
+-	la      %r1,256(%r1)
+-	la      %r3,256(%r3)
+-	brct    %r5,.L_G5_12
+-	j       .L_G5_4
+-.L_G5_17:
+-	mvc     0(1,%r1),0(%r3)
+-END(memcpy)
+-#ifndef USE_MULTIARCH
+-libc_hidden_builtin_def (memcpy)
+-#endif
+-
+-ENTRY(__memcpy_mvcle)
+-	# Using as standalone function will result in unexpected
+-	# results since the length field is incremented by 1 in order to
+-	# compensate the changes already done in the functions above.
+-	lr      %r0,%r2             # backup return dest [ + n ]
+-	ahi     %r4,1               # length + 1
+-	lr      %r5,%r4             # source length
+-	lr      %r4,%r3             # source address
+-	lr      %r2,%r1             # destination address
+-	lr      %r3,%r5             # destination length = source length
+-.L_MVCLE_1:
+-	mvcle   %r2,%r4,0           # thats it, MVCLE is your friend
+-	jo      .L_MVCLE_1
+-	lr      %r2,%r0             # return destination address
+-	br      %r14
+-END(__memcpy_mvcle)
+diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile
+deleted file mode 100644
+index 82a7492eb8436479..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/Makefile
++++ /dev/null
+@@ -1,3 +0,0 @@
+-ifeq ($(subdir),string)
+-sysdep_routines += memcpy memcpy-s390
+-endif
+diff --git a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S
+deleted file mode 100644
+index aad13bd07c31dab9..0000000000000000
+--- a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S
++++ /dev/null
+@@ -1,128 +0,0 @@
+-/* CPU specific memcpy implementations.  32 bit S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = target operands address
+-     %r3 = source operands address
+-     %r4 = number of bytes to copy.  */
+-
+-       .text
+-
+-#if defined SHARED && IS_IN (libc)
+-
+-ENTRY(____mempcpy_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-	lr      %r1,%r2         # Use as dest
+-	la      %r2,0(%r4,%r2)  # Return dest + n
+-	j	.L_Z196_start
+-END(____mempcpy_z196)
+-
+-ENTRY(__memcpy_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-	lr      %r1,%r2         # r1: Use as dest ; r2: Return dest
+-.L_Z196_start:
+-	llgfr   %r4,%r4
+-	ltgr    %r4,%r4
+-	je      .L_Z196_4
+-	aghi    %r4,-1
+-	srlg    %r5,%r4,8
+-	ltgr    %r5,%r5
+-	jne     .L_Z196_5
+-.L_Z196_3:
+-	exrl    %r4,.L_Z196_14
+-.L_Z196_4:
+-	br      %r14
+-.L_Z196_5:
+-	cgfi    %r5,262144      # Switch to mvcle for copies >64MB
+-	jh      __memcpy_mvcle
+-.L_Z196_2:
+-	pfd     1,768(%r3)
+-	pfd     2,768(%r1)
+-	mvc     0(256,%r1),0(%r3)
+-	aghi    %r5,-1
+-	la      %r1,256(%r1)
+-	la      %r3,256(%r3)
+-	jne     .L_Z196_2
+-	j       .L_Z196_3
+-.L_Z196_14:
+-	mvc     0(1,%r1),0(%r3)
+-END(__memcpy_z196)
+-
+-ENTRY(____mempcpy_z10)
+-	.machine "z10"
+-	.machinemode "zarch_nohighgprs"
+-	lr      %r1,%r2         # Use as dest
+-	la      %r2,0(%r4,%r2)  # Return dest + n
+-	j	.L_Z10_start
+-END(____mempcpy_z10)
+-
+-ENTRY(__memcpy_z10)
+-	.machine "z10"
+-	.machinemode "zarch_nohighgprs"
+-	lr      %r1,%r2         # r1: Use as dest ; r2: Return dest
+-.L_Z10_start:
+-	llgfr   %r4,%r4
+-	cgije   %r4,0,.L_Z10_4
+-	aghi    %r4,-1
+-	srlg    %r5,%r4,8
+-	cgijlh  %r5,0,.L_Z10_13
+-.L_Z10_3:
+-	exrl    %r4,.L_Z10_15
+-.L_Z10_4:
+-	br      %r14
+-.L_Z10_13:
+-	cgfi    %r5,65535	# Switch to mvcle for copies >16MB
+-	jh      __memcpy_mvcle
+-.L_Z10_12:
+-	pfd     1,768(%r3)
+-	pfd     2,768(%r1)
+-	mvc     0(256,%r1),0(%r3)
+-	la      %r1,256(%r1)
+-	la      %r3,256(%r3)
+-	brctg   %r5,.L_Z10_12
+-	j       .L_Z10_3
+-.L_Z10_15:
+-	mvc     0(1,%r1),0(%r3)
+-END(__memcpy_z10)
+-
+-# define __mempcpy ____mempcpy_default
+-#endif /* SHARED && IS_IN (libc) */
+-
+-#define memcpy __memcpy_default
+-#include "../memcpy.S"
+-#undef memcpy
+-
+-#if defined SHARED && IS_IN (libc)
+-.globl   __GI_memcpy
+-.set     __GI_memcpy,__memcpy_default
+-.globl   __GI_mempcpy
+-.set     __GI_mempcpy,____mempcpy_default
+-.globl   __GI___mempcpy
+-.set     __GI___mempcpy,____mempcpy_default
+-#else
+-.globl   memcpy
+-.set     memcpy,__memcpy_default
+-.weak    mempcpy
+-.set     mempcpy,__mempcpy
+-#endif
+diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile
+deleted file mode 100644
+index 8a043e3327a1527a..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/Makefile
++++ /dev/null
+@@ -1,3 +0,0 @@
+-ifeq ($(subdir),string)
+-sysdep_routines += memcpy memcpy-s390x
+-endif
+diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c
+deleted file mode 100644
+index c9577a854a0c7e68..0000000000000000
+--- a/sysdeps/s390/s390-64/multiarch/memcpy.c
++++ /dev/null
+@@ -1,27 +0,0 @@
+-/* Multiple versions of memcpy.
+-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* In the static lib memcpy is needed before the reloc is resolved.  */
+-#if defined SHARED && IS_IN (libc)
+-# define memcpy __redirect_memcpy
+-# include <string.h>
+-# undef memcpy
+-# include <ifunc-resolve.h>
+-
+-s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy)
+-#endif
diff --git a/SOURCES/glibc-rh1659438-9.patch b/SOURCES/glibc-rh1659438-9.patch
new file mode 100644
index 0000000..d3387ca
--- /dev/null
+++ b/SOURCES/glibc-rh1659438-9.patch
@@ -0,0 +1,656 @@
+commit 18eb862d454a41012ccdd5127715ef7cd2a711ec
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Tue Dec 18 13:57:06 2018 +0100
+
+    S390: Refactor memcpy/mempcpy ifunc handling.
+    
+    This patch moves all ifunc variants for memcpy/mempcpy
+    to sysdeps/s390/memcpy-z900.S. The configure-check/preprocessor logic
+    in sysdeps/s390/ifunc-memcpy.h decides if ifunc is needed at all
+    and which ifunc variants should be available.
+    E.g. if the compiler/assembler already supports z196 by default,
+    the older ifunc variants are not included.
+    If we only need the newest ifunc variant,
+    then we can skip ifunc at all.
+    
+    Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted
+    in order to handle only the available ifunc variants.
+    
+    ChangeLog:
+    
+            * sysdeps/s390/ifunc-memcpy.h: New File.
+            * sysdeps/s390/memcpy.S: Move to ...
+            * sysdeps/s390/memcpy-z900.S ... here.
+            Move implementations from memcpy-s390x.s to here.
+            * sysdeps/s390/multiarch/memcpy-s390x.S: Delete File.
+            * sysdeps/s390/multiarch/Makefile (sysdep_routines):
+            Remove memcpy/mempcpy variants.
+            * sysdeps/s390/Makefile (sysdep_routines):
+            Add memcpy/mempcpy variants.
+            * sysdeps/s390/multiarch/ifunc-impl-list.c
+            (__libc_ifunc_impl_list): Adjust ifunc variants for
+            memcpy and mempcpy.
+            * sysdeps/s390/multiarch/memcpy.c: Move ifunc resolver
+            to ...
+            * sysdeps/s390/memcpy.c: ... here.
+            Adjust ifunc variants for memcpy.
+            * sysdeps/s390/multiarch/mempcpy.c: Move to ...
+            * sysdeps/s390/mempcpy.c: ... here.
+            Adjust ifunc variants for mempcpy.
+            * sysdeps/s390/mempcpy.S: Delete file.
+
+diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
+index c59cbdc25aad408a..838950a5ab958e31 100644
+--- a/sysdeps/s390/Makefile
++++ b/sysdeps/s390/Makefile
+@@ -32,5 +32,6 @@ endif
+ 
+ ifeq ($(subdir),string)
+ sysdep_routines += bzero memset memset-z900 \
+-		   memcmp memcmp-z900
++		   memcmp memcmp-z900 \
++		   mempcpy memcpy memcpy-z900
+ endif
+diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h
+new file mode 100644
+index 0000000000000000..51c71baa2c0b0452
+--- /dev/null
++++ b/sysdeps/s390/ifunc-memcpy.h
+@@ -0,0 +1,68 @@
++/* memcpy variant information on S/390 version.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc)	\
++  && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# define HAVE_MEMCPY_IFUNC	1
++#else
++# define HAVE_MEMCPY_IFUNC	0
++#endif
++
++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# define MEMCPY_DEFAULT		MEMCPY_Z196
++# define MEMPCPY_DEFAULT	MEMPCPY_Z196
++# define HAVE_MEMCPY_Z900_G5	0
++# define HAVE_MEMCPY_Z10	0
++# define HAVE_MEMCPY_Z196	1
++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
++# define MEMCPY_DEFAULT		MEMCPY_Z10
++# define MEMPCPY_DEFAULT	MEMPCPY_Z10
++# define HAVE_MEMCPY_Z900_G5	0
++# define HAVE_MEMCPY_Z10	1
++# define HAVE_MEMCPY_Z196	HAVE_MEMCPY_IFUNC
++#else
++# define MEMCPY_DEFAULT		MEMCPY_Z900_G5
++# define MEMPCPY_DEFAULT	MEMPCPY_Z900_G5
++# define HAVE_MEMCPY_Z900_G5	1
++# define HAVE_MEMCPY_Z10	HAVE_MEMCPY_IFUNC
++# define HAVE_MEMCPY_Z196	HAVE_MEMCPY_IFUNC
++#endif
++
++#if HAVE_MEMCPY_Z900_G5
++# define MEMCPY_Z900_G5		__memcpy_default
++# define MEMPCPY_Z900_G5	__mempcpy_default
++#else
++# define MEMCPY_Z900_G5		NULL
++# define MEMPCPY_Z900_G5	NULL
++#endif
++
++#if HAVE_MEMCPY_Z10
++# define MEMCPY_Z10		__memcpy_z10
++# define MEMPCPY_Z10		__mempcpy_z10
++#else
++# define MEMCPY_Z10		NULL
++# define MEMPCPY_Z10		NULL
++#endif
++
++#if HAVE_MEMCPY_Z196
++# define MEMCPY_Z196		__memcpy_z196
++# define MEMPCPY_Z196		__mempcpy_z196
++#else
++# define MEMCPY_Z196		NULL
++# define MEMPCPY_Z196		NULL
++#endif
+diff --git a/sysdeps/s390/memcpy.S b/sysdeps/s390/memcpy-z900.S
+similarity index 50%
+rename from sysdeps/s390/memcpy.S
+rename to sysdeps/s390/memcpy-z900.S
+index 2a6c6b750377c7bb..3a50cf44d85d2417 100644
+--- a/sysdeps/s390/memcpy.S
++++ b/sysdeps/s390/memcpy-z900.S
+@@ -19,6 +19,7 @@
+ 
+ #include <sysdep.h>
+ #include "asm-syntax.h"
++#include <ifunc-memcpy.h>
+ 
+ /* INPUT PARAMETERS
+      %r2 = address of destination memory area
+@@ -41,50 +42,46 @@
+ # define BRCTG	brct
+ #endif /* ! defined __s390x__  */
+ 
+-ENTRY(__mempcpy)
+-#if defined __s390x__
++#if HAVE_MEMCPY_Z900_G5
++ENTRY(MEMPCPY_Z900_G5)
++# if defined __s390x__
+ 	.machine "z900"
+-#else
++# else
+ 	.machine "g5"
+-#endif /* ! defined __s390x__  */
++# endif /* ! defined __s390x__  */
+ 	LGR     %r1,%r2             # Use as dest
+ 	la      %r2,0(%r4,%r2)      # Return dest + n
+ 	j	.L_Z900_G5_start
+-END(__mempcpy)
+-#ifndef USE_MULTIARCH
+-libc_hidden_def (__mempcpy)
+-weak_alias (__mempcpy, mempcpy)
+-libc_hidden_builtin_def (mempcpy)
+-#endif
++END(MEMPCPY_Z900_G5)
+ 
+-ENTRY(memcpy)
+-#if defined __s390x__
++ENTRY(MEMCPY_Z900_G5)
++# if defined __s390x__
+ 	.machine "z900"
+-#else
++# else
+ 	.machine "g5"
+-#endif /* ! defined __s390x__  */
++# endif /* ! defined __s390x__  */
+ 	LGR     %r1,%r2             # r1: Use as dest ; r2: Return dest
+ .L_Z900_G5_start:
+ 	LTGR    %r4,%r4
+ 	je      .L_Z900_G5_4
+ 	AGHI    %r4,-1
+-#if defined __s390x__
++# if defined __s390x__
+ 	srlg	%r5,%r4,8
+-#else
++# else
+ 	lr	%r5,%r4
+ 	srl	%r5,8
+-#endif /* ! defined __s390x__  */
++# endif /* ! defined __s390x__  */
+ 	LTGR    %r5,%r5
+ 	jne     .L_Z900_G5_13
+ .L_Z900_G5_3:
+-#if defined __s390x__
++# if defined __s390x__
+ 	larl    %r5,.L_Z900_G5_15
+-# define Z900_G5_EX_D 0
+-#else
++#  define Z900_G5_EX_D 0
++# else
+ 	basr    %r5,0
+ .L_Z900_G5_14:
+-# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14
+-#endif /* ! defined __s390x__  */
++#  define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14
++# endif /* ! defined __s390x__  */
+ 	ex      %r4,Z900_G5_EX_D(%r5)
+ .L_Z900_G5_4:
+ 	br      %r14
+@@ -99,10 +96,8 @@ ENTRY(memcpy)
+ 	j       .L_Z900_G5_3
+ .L_Z900_G5_15:
+ 	mvc     0(1,%r1),0(%r3)
+-END(memcpy)
+-#ifndef USE_MULTIARCH
+-libc_hidden_builtin_def (memcpy)
+-#endif
++END(MEMCPY_Z900_G5)
++#endif /* HAVE_MEMCPY_Z900_G5  */
+ 
+ ENTRY(__memcpy_mvcle)
+ 	# Using as standalone function will result in unexpected
+@@ -126,3 +121,104 @@ END(__memcpy_mvcle)
+ #undef LGR
+ #undef AGHI
+ #undef BRCTG
++
++#if HAVE_MEMCPY_Z10
++ENTRY(MEMPCPY_Z10)
++	.machine "z10"
++	.machinemode "zarch_nohighgprs"
++	lgr     %r1,%r2         # Use as dest
++	la      %r2,0(%r4,%r2)  # Return dest + n
++	j	.L_Z10_start
++END(MEMPCPY_Z10)
++
++ENTRY(MEMCPY_Z10)
++	.machine "z10"
++	.machinemode "zarch_nohighgprs"
++	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
++.L_Z10_start:
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
++	cgije   %r4,0,.L_Z10_4
++	aghi    %r4,-1
++	srlg    %r5,%r4,8
++	cgijlh  %r5,0,.L_Z10_13
++.L_Z10_3:
++	exrl    %r4,.L_Z10_15
++.L_Z10_4:
++	br      %r14
++.L_Z10_13:
++	cgfi    %r5,65535	# Switch to mvcle for copies >16MB
++	jh      __memcpy_mvcle
++.L_Z10_12:
++	pfd     1,768(%r3)
++	pfd     2,768(%r1)
++	mvc     0(256,%r1),0(%r3)
++	la      %r1,256(%r1)
++	la      %r3,256(%r3)
++	brctg   %r5,.L_Z10_12
++	j       .L_Z10_3
++.L_Z10_15:
++	mvc     0(1,%r1),0(%r3)
++END(MEMCPY_Z10)
++#endif /* HAVE_MEMCPY_Z10  */
++
++#if HAVE_MEMCPY_Z196
++ENTRY(MEMPCPY_Z196)
++	.machine "z196"
++	.machinemode "zarch_nohighgprs"
++	lgr     %r1,%r2         # Use as dest
++	la      %r2,0(%r4,%r2)  # Return dest + n
++	j	.L_Z196_start
++END(MEMPCPY_Z196)
++
++ENTRY(MEMCPY_Z196)
++	.machine "z196"
++	.machinemode "zarch_nohighgprs"
++	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
++.L_Z196_start:
++# if !defined __s390x__
++	llgfr	%r4,%r4
++# endif /* !defined __s390x__  */
++	ltgr    %r4,%r4
++	je      .L_Z196_4
++	aghi    %r4,-1
++	srlg    %r5,%r4,8
++	ltgr    %r5,%r5
++	jne     .L_Z196_5
++.L_Z196_3:
++	exrl    %r4,.L_Z196_14
++.L_Z196_4:
++	br      %r14
++.L_Z196_5:
++	cgfi    %r5,262144      # Switch to mvcle for copies >64MB
++	jh      __memcpy_mvcle
++.L_Z196_2:
++	pfd     1,768(%r3)
++	pfd     2,768(%r1)
++	mvc     0(256,%r1),0(%r3)
++	aghi    %r5,-1
++	la      %r1,256(%r1)
++	la      %r3,256(%r3)
++	jne     .L_Z196_2
++	j       .L_Z196_3
++.L_Z196_14:
++	mvc     0(1,%r1),0(%r3)
++END(MEMCPY_Z196)
++#endif /* HAVE_MEMCPY_Z196  */
++
++#if ! HAVE_MEMCPY_IFUNC
++/* If we don't use ifunc, define an alias for mem[p]cpy here.
++   Otherwise see sysdeps/s390/mem[p]cpy.c.  */
++strong_alias (MEMCPY_DEFAULT, memcpy)
++strong_alias (MEMPCPY_DEFAULT, __mempcpy)
++weak_alias (__mempcpy, mempcpy)
++#endif
++
++#if defined SHARED && IS_IN (libc)
++/* Defines the internal symbols.
++   Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c.  */
++strong_alias (MEMCPY_DEFAULT, __GI_memcpy)
++strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy)
++strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy)
++#endif
+diff --git a/sysdeps/s390/multiarch/memcpy.c b/sysdeps/s390/memcpy.c
+similarity index 60%
+rename from sysdeps/s390/multiarch/memcpy.c
+rename to sysdeps/s390/memcpy.c
+index c9577a854a0c7e68..90a53ac27d4be755 100644
+--- a/sysdeps/s390/multiarch/memcpy.c
++++ b/sysdeps/s390/memcpy.c
+@@ -16,12 +16,34 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-/* In the static lib memcpy is needed before the reloc is resolved.  */
+-#if defined SHARED && IS_IN (libc)
++#include <ifunc-memcpy.h>
++
++#if HAVE_MEMCPY_IFUNC
+ # define memcpy __redirect_memcpy
+ # include <string.h>
+ # undef memcpy
+ # include <ifunc-resolve.h>
+ 
+-s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy)
++# if HAVE_MEMCPY_Z900_G5
++extern __typeof (__redirect_memcpy) MEMCPY_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_MEMCPY_Z10
++extern __typeof (__redirect_memcpy) MEMCPY_Z10 attribute_hidden;
++# endif
++
++# if HAVE_MEMCPY_Z196
++extern __typeof (__redirect_memcpy) MEMCPY_Z196 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect_memcpy, memcpy,
++		      ({
++			s390_libc_ifunc_init ();
++			(HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits))
++			  ? MEMCPY_Z196
++			  : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits))
++			  ? MEMCPY_Z10
++			  : MEMCPY_DEFAULT;
++		      })
++		      )
+ #endif
+diff --git a/sysdeps/s390/mempcpy.S b/sysdeps/s390/mempcpy.S
+deleted file mode 100644
+index 18ef29213e26e76d..0000000000000000
+--- a/sysdeps/s390/mempcpy.S
++++ /dev/null
+@@ -1,19 +0,0 @@
+-/* CPU specific mempcpy without multiarch - 32/64 bit S/390 version.
+-   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* mempcpy is implemented in memcpy.S.  */
+diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/mempcpy.c
+similarity index 63%
+rename from sysdeps/s390/multiarch/mempcpy.c
+rename to sysdeps/s390/mempcpy.c
+index 363fe47aefb80978..a6a237312659c2c1 100644
+--- a/sysdeps/s390/multiarch/mempcpy.c
++++ b/sysdeps/s390/mempcpy.c
+@@ -16,8 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <ifunc-memcpy.h>
+ 
+-#if defined SHARED && IS_IN (libc)
++#if HAVE_MEMCPY_IFUNC
+ # define mempcpy __redirect_mempcpy
+ # define __mempcpy __redirect___mempcpy
+ # define __NO_STRING_INLINES
+@@ -27,6 +28,27 @@
+ # undef __mempcpy
+ # include <ifunc-resolve.h>
+ 
+-s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy)
++# if HAVE_MEMCPY_Z900_G5
++extern __typeof (__redirect___mempcpy) MEMPCPY_Z900_G5 attribute_hidden;
++# endif
++
++# if HAVE_MEMCPY_Z10
++extern __typeof (__redirect___mempcpy) MEMPCPY_Z10 attribute_hidden;
++# endif
++
++# if HAVE_MEMCPY_Z196
++extern __typeof (__redirect___mempcpy) MEMPCPY_Z196 attribute_hidden;
++# endif
++
++s390_libc_ifunc_expr (__redirect___mempcpy, __mempcpy,
++		      ({
++			s390_libc_ifunc_init ();
++			(HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits))
++			  ? MEMPCPY_Z196
++			  : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits))
++			  ? MEMPCPY_Z10
++			  : MEMPCPY_DEFAULT;
++		      })
++		      )
+ weak_alias (__mempcpy, mempcpy);
+ #endif
+diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
+index 3cbd5fad69e355a5..24949cd3a88b8015 100644
+--- a/sysdeps/s390/multiarch/Makefile
++++ b/sysdeps/s390/multiarch/Makefile
+@@ -18,8 +18,7 @@ sysdep_routines += strlen strlen-vx strlen-c \
+ 		   memchr memchr-vx \
+ 		   rawmemchr rawmemchr-vx rawmemchr-c \
+ 		   memccpy memccpy-vx memccpy-c \
+-		   memrchr memrchr-vx memrchr-c \
+-		   mempcpy memcpy memcpy-s390x
++		   memrchr memrchr-vx memrchr-c
+ endif
+ 
+ ifeq ($(subdir),wcsmbs)
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index 2e57d01abc21522e..6969c480cc40e0e2 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -23,6 +23,7 @@
+ #include <ifunc-resolve.h>
+ #include <ifunc-memset.h>
+ #include <ifunc-memcmp.h>
++#include <ifunc-memcpy.h>
+ 
+ /* Maximum number of IFUNC implementations.  */
+ #define MAX_IFUNC	3
+@@ -95,23 +96,35 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ 	      )
+ #endif /* HAVE_MEMCMP_IFUNC */
+ 
+-#ifdef SHARED
+-
++#if HAVE_MEMCPY_IFUNC
+   IFUNC_IMPL (i, name, memcpy,
++# if HAVE_MEMCPY_Z196
+ 	      IFUNC_IMPL_ADD (array, i, memcpy,
+-			      S390_IS_Z196 (stfle_bits), __memcpy_z196)
++			      S390_IS_Z196 (stfle_bits), MEMCPY_Z196)
++# endif
++# if HAVE_MEMCPY_Z10
+ 	      IFUNC_IMPL_ADD (array, i, memcpy,
+-			      S390_IS_Z10 (stfle_bits), __memcpy_z10)
+-	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default))
++			      S390_IS_Z10 (stfle_bits), MEMCPY_Z10)
++# endif
++# if HAVE_MEMCPY_Z900_G5
++	      IFUNC_IMPL_ADD (array, i, memcpy, 1, MEMCPY_Z900_G5)
++# endif
++	      )
+ 
+   IFUNC_IMPL (i, name, mempcpy,
++# if HAVE_MEMCPY_Z196
+ 	      IFUNC_IMPL_ADD (array, i, mempcpy,
+-			      S390_IS_Z196 (stfle_bits), ____mempcpy_z196)
++			      S390_IS_Z196 (stfle_bits), MEMPCPY_Z196)
++# endif
++# if HAVE_MEMCPY_Z10
+ 	      IFUNC_IMPL_ADD (array, i, mempcpy,
+-			      S390_IS_Z10 (stfle_bits), ____mempcpy_z10)
+-	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, ____mempcpy_default))
+-
+-#endif /* SHARED */
++			      S390_IS_Z10 (stfle_bits), MEMPCPY_Z10)
++# endif
++# if HAVE_MEMCPY_Z900_G5
++	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, MEMPCPY_Z900_G5)
++# endif
++	      )
++#endif /* HAVE_MEMCPY_IFUNC  */
+ 
+ #ifdef HAVE_S390_VX_ASM_SUPPORT
+ 
+diff --git a/sysdeps/s390/multiarch/memcpy-s390x.S b/sysdeps/s390/multiarch/memcpy-s390x.S
+deleted file mode 100644
+index b38caac72b8742e6..0000000000000000
+--- a/sysdeps/s390/multiarch/memcpy-s390x.S
++++ /dev/null
+@@ -1,132 +0,0 @@
+-/* CPU specific memcpy implementations.  31/64 bit S/390 version.
+-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-
+-#include "sysdep.h"
+-#include "asm-syntax.h"
+-
+-/* INPUT PARAMETERS
+-     %r2 = target operands address
+-     %r3 = source operands address
+-     %r4 = number of bytes to copy.  */
+-
+-       .text
+-
+-#if defined SHARED && IS_IN (libc)
+-
+-ENTRY(____mempcpy_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-	lgr     %r1,%r2         # Use as dest
+-	la      %r2,0(%r4,%r2)  # Return dest + n
+-	j	.L_Z196_start
+-END(____mempcpy_z196)
+-
+-ENTRY(__memcpy_z196)
+-	.machine "z196"
+-	.machinemode "zarch_nohighgprs"
+-	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
+-.L_Z196_start:
+-# if !defined __s390x__
+-	llgfr	%r4,%r4
+-# endif /* !defined __s390x__  */
+-	ltgr    %r4,%r4
+-	je      .L_Z196_4
+-	aghi    %r4,-1
+-	srlg    %r5,%r4,8
+-	ltgr    %r5,%r5
+-	jne     .L_Z196_5
+-.L_Z196_3:
+-	exrl    %r4,.L_Z196_14
+-.L_Z196_4:
+-	br      %r14
+-.L_Z196_5:
+-	cgfi    %r5,262144      # Switch to mvcle for copies >64MB
+-	jh      __memcpy_mvcle
+-.L_Z196_2:
+-	pfd     1,768(%r3)
+-	pfd     2,768(%r1)
+-	mvc     0(256,%r1),0(%r3)
+-	aghi    %r5,-1
+-	la      %r1,256(%r1)
+-	la      %r3,256(%r3)
+-	jne     .L_Z196_2
+-	j       .L_Z196_3
+-.L_Z196_14:
+-	mvc     0(1,%r1),0(%r3)
+-END(__memcpy_z196)
+-
+-ENTRY(____mempcpy_z10)
+-	.machine "z10"
+-	.machinemode "zarch_nohighgprs"
+-	lgr     %r1,%r2         # Use as dest
+-	la      %r2,0(%r4,%r2)  # Return dest + n
+-	j	.L_Z10_start
+-END(____mempcpy_z10)
+-
+-ENTRY(__memcpy_z10)
+-	.machine "z10"
+-	.machinemode "zarch_nohighgprs"
+-	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
+-.L_Z10_start:
+-# if !defined __s390x__
+-	llgfr	%r4,%r4
+-# endif /* !defined __s390x__  */
+-	cgije   %r4,0,.L_Z10_4
+-	aghi    %r4,-1
+-	srlg    %r5,%r4,8
+-	cgijlh  %r5,0,.L_Z10_13
+-.L_Z10_3:
+-	exrl    %r4,.L_Z10_15
+-.L_Z10_4:
+-	br      %r14
+-.L_Z10_13:
+-	cgfi    %r5,65535	# Switch to mvcle for copies >16MB
+-	jh      __memcpy_mvcle
+-.L_Z10_12:
+-	pfd     1,768(%r3)
+-	pfd     2,768(%r1)
+-	mvc     0(256,%r1),0(%r3)
+-	la      %r1,256(%r1)
+-	la      %r3,256(%r3)
+-	brctg   %r5,.L_Z10_12
+-	j       .L_Z10_3
+-.L_Z10_15:
+-	mvc     0(1,%r1),0(%r3)
+-END(__memcpy_z10)
+-
+-# define __mempcpy ____mempcpy_default
+-#endif /* SHARED && IS_IN (libc) */
+-
+-#define memcpy __memcpy_default
+-#include "../memcpy.S"
+-#undef memcpy
+-
+-#if defined SHARED && IS_IN (libc)
+-.globl   __GI_memcpy
+-.set     __GI_memcpy,__memcpy_default
+-.globl   __GI_mempcpy
+-.set     __GI_mempcpy,____mempcpy_default
+-.globl   __GI___mempcpy
+-.set     __GI___mempcpy,____mempcpy_default
+-#else
+-.globl   memcpy
+-.set     memcpy,__memcpy_default
+-.weak    mempcpy
+-.set     mempcpy,__mempcpy
+-#endif
diff --git a/SOURCES/glibc-rh1659512-1.patch b/SOURCES/glibc-rh1659512-1.patch
new file mode 100644
index 0000000..71956e9
--- /dev/null
+++ b/SOURCES/glibc-rh1659512-1.patch
@@ -0,0 +1,312 @@
+commit c70271662aa53aee0c4794d480dca6d9ba3ccc3d
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Sep 19 11:12:05 2018 -0700
+
+    Use libsupport for tst-spawn.c
+    
+    No function changes is done.  Checked on x86_64-linux-gnu.
+    
+            * posix/tst-spawn.c (do_prepare, handle_restart, do_test):
+            Use libsupport.
+
+diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c
+index 7c785c430c..41f1a65243 100644
+--- a/posix/tst-spawn.c
++++ b/posix/tst-spawn.c
+@@ -17,16 +17,20 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <stdio.h>
++#include <getopt.h>
+ #include <errno.h>
+ #include <error.h>
+ #include <fcntl.h>
+ #include <spawn.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <wait.h>
+ #include <sys/param.h>
++
+ #include <support/check.h>
+ #include <support/xunistd.h>
++#include <support/temp_file.h>
++#include <support/support.h>
+ 
+ 
+ /* Nonzero if the program gets called via `exec'.  */
+@@ -36,16 +40,6 @@ static int restart;
+ #define CMDLINE_OPTIONS \
+   { "restart", no_argument, &restart, 1 },
+ 
+-/* Prototype for our test function.  */
+-extern void do_prepare (int argc, char *argv[]);
+-extern int do_test (int argc, char *argv[]);
+-
+-/* We have a preparation function.  */
+-#define PREPARE do_prepare
+-
+-#include "../test-skeleton.c"
+-
+-
+ /* Name of the temporary files.  */
+ static char *name1;
+ static char *name2;
+@@ -63,19 +57,18 @@ static const char fd3string[] = "This file will be opened";
+ 
+ 
+ /* We have a preparation function.  */
+-void
++static void
+ do_prepare (int argc, char *argv[])
+ {
+   /* We must not open any files in the restart case.  */
+   if (restart)
+     return;
+ 
+-  temp_fd1 = create_temp_file ("spawn", &name1);
+-  temp_fd2 = create_temp_file ("spawn", &name2);
+-  temp_fd3 = create_temp_file ("spawn", &name3);
+-  if (temp_fd1 < 0 || temp_fd2 < 0 || temp_fd3 < 0)
+-    exit (1);
++  TEST_VERIFY_EXIT ((temp_fd1 = create_temp_file ("spawn", &name1)) != -1);
++  TEST_VERIFY_EXIT ((temp_fd2 = create_temp_file ("spawn", &name2)) != -1);
++  TEST_VERIFY_EXIT ((temp_fd3 = create_temp_file ("spawn", &name3)) != -1);
+ }
++#define PREPARE do_prepare
+ 
+ 
+ static int
+@@ -95,64 +88,45 @@ handle_restart (const char *fd1s, const char *fd2s, const char *fd3s,
+   fd4 = atol (fd4s);
+ 
+   /* Sanity check.  */
+-  if (fd1 == fd2)
+-    error (EXIT_FAILURE, 0, "value of fd1 and fd2 is the same");
+-  if (fd1 == fd3)
+-    error (EXIT_FAILURE, 0, "value of fd1 and fd3 is the same");
+-  if (fd1 == fd4)
+-    error (EXIT_FAILURE, 0, "value of fd1 and fd4 is the same");
+-  if (fd2 == fd3)
+-    error (EXIT_FAILURE, 0, "value of fd2 and fd3 is the same");
+-  if (fd2 == fd4)
+-    error (EXIT_FAILURE, 0, "value of fd2 and fd4 is the same");
+-  if (fd3 == fd4)
+-    error (EXIT_FAILURE, 0, "value of fd3 and fd4 is the same");
++  TEST_VERIFY_EXIT (fd1 != fd2);
++  TEST_VERIFY_EXIT (fd1 != fd3);
++  TEST_VERIFY_EXIT (fd1 != fd4);
++  TEST_VERIFY_EXIT (fd2 != fd3);
++  TEST_VERIFY_EXIT (fd2 != fd4);
++  TEST_VERIFY_EXIT (fd3 != fd4);
+ 
+   /* First the easy part: read from the file descriptor which is
+      supposed to be open.  */
+-  if (lseek (fd2, 0, SEEK_CUR) != strlen (fd2string))
+-    error (EXIT_FAILURE, errno, "file 2 not in right position");
++  TEST_COMPARE (xlseek (fd2, 0, SEEK_CUR), strlen (fd2string));
+   /* The duped descriptor must have the same position.  */
+-  if (lseek (fd4, 0, SEEK_CUR) != strlen (fd2string))
+-    error (EXIT_FAILURE, errno, "file 4 not in right position");
+-  if (lseek (fd2, 0, SEEK_SET) != 0)
+-    error (EXIT_FAILURE, 0, "cannot reset position in file 2");
+-  if (lseek (fd4, 0, SEEK_CUR) != 0)
+-    error (EXIT_FAILURE, errno, "file 4 not set back, too");
+-  if (read (fd2, buf, sizeof buf) != strlen (fd2string))
+-    error (EXIT_FAILURE, 0, "cannot read file 2");
+-  if (memcmp (fd2string, buf, strlen (fd2string)) != 0)
+-    error (EXIT_FAILURE, 0, "file 2 does not match");
++  TEST_COMPARE (xlseek (fd4, 0, SEEK_CUR), strlen (fd2string));
++  TEST_COMPARE (xlseek (fd2, 0, SEEK_SET), 0);
++  TEST_COMPARE (xlseek (fd4, 0, SEEK_CUR), 0);
++  TEST_COMPARE (read (fd2, buf, sizeof buf), strlen (fd2string));
++  TEST_COMPARE_BLOB (fd2string, strlen (fd2string), buf, strlen (fd2string));
+ 
+   /* Now read from the third file.  */
+-  if (read (fd3, buf, sizeof buf) != strlen (fd3string))
+-    error (EXIT_FAILURE, 0, "cannot read file 3");
+-  if (memcmp (fd3string, buf, strlen (fd3string)) != 0)
+-    error (EXIT_FAILURE, 0, "file 3 does not match");
++  TEST_COMPARE (read (fd3, buf, sizeof buf), strlen (fd3string));
++  TEST_COMPARE_BLOB (fd3string, strlen (fd3string), buf, strlen (fd3string));
+   /* Try to write to the file.  This should not be allowed.  */
+-  if (write (fd3, "boo!", 4) != -1 || errno != EBADF)
+-    error (EXIT_FAILURE, 0, "file 3 is writable");
++  TEST_COMPARE (write (fd3, "boo!", 4), -1);
++  TEST_COMPARE (errno, EBADF);
+ 
+   /* Now try to read the first file.  First make sure it is not opened.  */
+-  if (lseek (fd1, 0, SEEK_CUR) != (off_t) -1 || errno != EBADF)
+-    error (EXIT_FAILURE, 0, "file 1 (%d) is not closed", fd1);
++  TEST_COMPARE (lseek (fd1, 0, SEEK_CUR), (off_t) -1);
++  TEST_COMPARE (errno, EBADF);
+ 
+   /* Now open the file and read it.  */
+-  fd1 = open (name, O_RDONLY);
+-  if (fd1 == -1)
+-    error (EXIT_FAILURE, errno,
+-	   "cannot open first file \"%s\" for verification", name);
++  fd1 = xopen (name, O_RDONLY, 0600);
+ 
+-  if (read (fd1, buf, sizeof buf) != strlen (fd1string))
+-    error (EXIT_FAILURE, errno, "cannot read file 1");
+-  if (memcmp (fd1string, buf, strlen (fd1string)) != 0)
+-    error (EXIT_FAILURE, 0, "file 1 does not match");
++  TEST_COMPARE (read (fd1, buf, sizeof buf), strlen (fd1string));
++  TEST_COMPARE_BLOB (fd1string, strlen (fd1string), buf, strlen (fd1string));
+ 
+   return 0;
+ }
+ 
+ 
+-int
++static int
+ do_test (int argc, char *argv[])
+ {
+   pid_t pid;
+@@ -181,7 +155,7 @@ do_test (int argc, char *argv[])
+        + the name of the closed descriptor
+   */
+   if (argc != (restart ? 6 : 2) && argc != (restart ? 6 : 5))
+-    error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc);
++    FAIL_EXIT1 ("wrong number of arguments (%d)", argc);
+ 
+   if (restart)
+     return handle_restart (argv[1], argv[2], argv[3], argv[4], argv[5]);
+@@ -189,77 +163,73 @@ do_test (int argc, char *argv[])
+   /* Prepare the test.  We are creating two files: one which file descriptor
+      will be marked with FD_CLOEXEC, another which is not.  */
+ 
+-   /* Write something in the files.  */
+-   if (write (temp_fd1, fd1string, strlen (fd1string)) != strlen (fd1string))
+-     error (EXIT_FAILURE, errno, "cannot write to first file");
+-   if (write (temp_fd2, fd2string, strlen (fd2string)) != strlen (fd2string))
+-     error (EXIT_FAILURE, errno, "cannot write to second file");
+-   if (write (temp_fd3, fd3string, strlen (fd3string)) != strlen (fd3string))
+-     error (EXIT_FAILURE, errno, "cannot write to third file");
+-
+-   /* Close the third file.  It'll be opened by `spawn'.  */
+-   close (temp_fd3);
+-
+-   /* Tell `spawn' what to do.  */
+-   if (posix_spawn_file_actions_init (&actions) != 0)
+-     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_init");
+-   /* Close `temp_fd1'.  */
+-   if (posix_spawn_file_actions_addclose (&actions, temp_fd1) != 0)
+-     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
+-   /* We want to open the third file.  */
+-   name3_copy = strdup (name3);
+-   if (name3_copy == NULL)
+-     error (EXIT_FAILURE, errno, "strdup");
+-   if (posix_spawn_file_actions_addopen (&actions, temp_fd3, name3_copy,
+-					 O_RDONLY, 0666) != 0)
+-     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
+-   /* Overwrite the name to check that a copy has been made.  */
+-   memset (name3_copy, 'X', strlen (name3_copy));
+-
+-   /* We dup the second descriptor.  */
+-   fd4 = MAX (2, MAX (temp_fd1, MAX (temp_fd2, temp_fd3))) + 1;
+-   if (posix_spawn_file_actions_adddup2 (&actions, temp_fd2, fd4) != 0)
+-     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_adddup2");
+-
+-   /* Now spawn the process.  */
+-   snprintf (fd1name, sizeof fd1name, "%d", temp_fd1);
+-   snprintf (fd2name, sizeof fd2name, "%d", temp_fd2);
+-   snprintf (fd3name, sizeof fd3name, "%d", temp_fd3);
+-   snprintf (fd4name, sizeof fd4name, "%d", fd4);
+-
+-   for (i = 0; i < (argc == (restart ? 6 : 5) ? 4 : 1); i++)
+-     spargv[i] = argv[i + 1];
+-   spargv[i++] = (char *) "--direct";
+-   spargv[i++] = (char *) "--restart";
+-   spargv[i++] = fd1name;
+-   spargv[i++] = fd2name;
+-   spargv[i++] = fd3name;
+-   spargv[i++] = fd4name;
+-   spargv[i++] = name1;
+-   spargv[i] = NULL;
+-
+-   if (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ) != 0)
+-     error (EXIT_FAILURE, errno, "posix_spawn");
+-
+-   /* Same test but with a NULL pid argument.  */
+-   if (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ) != 0)
+-     error (EXIT_FAILURE, errno, "posix_spawn");
+-
+-   /* Cleanup.  */
+-   if (posix_spawn_file_actions_destroy (&actions) != 0)
+-     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");
+-   free (name3_copy);
++  /* Write something in the files.  */
++  xwrite (temp_fd1, fd1string, strlen (fd1string));
++  xwrite (temp_fd2, fd2string, strlen (fd2string));
++  xwrite (temp_fd3, fd3string, strlen (fd3string));
++
++  /* Close the third file.  It'll be opened by `spawn'.  */
++  xclose (temp_fd3);
++
++  /* Tell `spawn' what to do.  */
++  TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0);
++  /* Close `temp_fd1'.  */
++  TEST_COMPARE (posix_spawn_file_actions_addclose (&actions, temp_fd1), 0);
++  /* We want to open the third file.  */
++  name3_copy = xstrdup (name3);
++  TEST_COMPARE (posix_spawn_file_actions_addopen (&actions, temp_fd3,
++						  name3_copy,
++						  O_RDONLY, 0666),
++		0);
++  /* Overwrite the name to check that a copy has been made.  */
++  memset (name3_copy, 'X', strlen (name3_copy));
++
++  /* We dup the second descriptor.  */
++  fd4 = MAX (2, MAX (temp_fd1, MAX (temp_fd2, temp_fd3))) + 1;
++  TEST_COMPARE (posix_spawn_file_actions_adddup2 (&actions, temp_fd2, fd4),
++	        0);
++
++  /* Now spawn the process.  */
++  snprintf (fd1name, sizeof fd1name, "%d", temp_fd1);
++  snprintf (fd2name, sizeof fd2name, "%d", temp_fd2);
++  snprintf (fd3name, sizeof fd3name, "%d", temp_fd3);
++  snprintf (fd4name, sizeof fd4name, "%d", fd4);
++
++  for (i = 0; i < (argc == (restart ? 6 : 5) ? 4 : 1); i++)
++    spargv[i] = argv[i + 1];
++  spargv[i++] = (char *) "--direct";
++  spargv[i++] = (char *) "--restart";
++  spargv[i++] = fd1name;
++  spargv[i++] = fd2name;
++  spargv[i++] = fd3name;
++  spargv[i++] = fd4name;
++  spargv[i++] = name1;
++  spargv[i] = NULL;
++
++  TEST_COMPARE (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ),
++		0);
++
++  /* Same test but with a NULL pid argument.  */
++  TEST_COMPARE (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ),
++		0);
++
++  /* Cleanup.  */
++  TEST_COMPARE (posix_spawn_file_actions_destroy (&actions), 0);
++  free (name3_copy);
+ 
+   /* Wait for the children.  */
+-  TEST_VERIFY (xwaitpid (pid, &status, 0) == pid);
++  TEST_COMPARE (xwaitpid (pid, &status, 0), pid);
+   TEST_VERIFY (WIFEXITED (status));
+   TEST_VERIFY (!WIFSIGNALED (status));
+-  TEST_VERIFY (WEXITSTATUS (status) == 0);
++  TEST_COMPARE (WEXITSTATUS (status), 0);
+ 
+   xwaitpid (-1, &status, 0);
+   TEST_VERIFY (WIFEXITED (status));
+   TEST_VERIFY (!WIFSIGNALED (status));
+-  TEST_VERIFY (WEXITSTATUS (status) == 0);
++  TEST_COMPARE (WEXITSTATUS (status), 0);
+ 
+   return 0;
+ }
++
++#define TEST_FUNCTION_ARGV do_test
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1659512-2.patch b/SOURCES/glibc-rh1659512-2.patch
new file mode 100644
index 0000000..ac36900
--- /dev/null
+++ b/SOURCES/glibc-rh1659512-2.patch
@@ -0,0 +1,62 @@
+commit 114f792eaea2505cd8aee02d330aad37238da6a5
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Fri Feb 1 11:03:35 2019 +0100
+
+    posix/tst-spawn: Fix racy tests in spawned processes.
+    
+    From time to time I get fails in tst-spawn like:
+    tst-spawn.c:111: numeric comparison failure
+       left: 0 (0x0); from: xlseek (fd2, 0, SEEK_CUR)
+      right: 28 (0x1c); from: strlen (fd2string)
+    error: 1 test failures
+    tst-spawn.c:252: numeric comparison failure
+       left: 1 (0x1); from: WEXITSTATUS (status)
+      right: 0 (0x0); from: 0
+    error: 1 test failures
+    
+    It turned out, that a child process is testing it's open file descriptors
+    with e.g. a sequence of testing the current position, setting the position
+    to zero and reading a specific amount of bytes.
+    
+    Unfortunately starting with commit 2a69f853c03034c2e383e0f9c35b5402ce8b5473
+    the test is spawning a second child process which is sharing some of the
+    file descriptors.  If the test sequence as mentioned above is running in parallel
+    it leads to test failures.
+    
+    As the second call of posix_spawn shall test a NULL pid argument,
+    this patch is just moving the waitpid of the first child
+    before the posix_spawn of the second child.
+    
+    ChangeLog:
+    
+            * posix/tst-spawn do_test(): Move waitpid before posix_spawn.
+
+diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c
+index eea5addbf3..9aa7e621e6 100644
+--- a/posix/tst-spawn.c
++++ b/posix/tst-spawn.c
+@@ -237,6 +237,12 @@ do_test (int argc, char *argv[])
+   TEST_COMPARE (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ),
+ 		0);
+ 
++  /* Wait for the children.  */
++  TEST_COMPARE (xwaitpid (pid, &status, 0), pid);
++  TEST_VERIFY (WIFEXITED (status));
++  TEST_VERIFY (!WIFSIGNALED (status));
++  TEST_COMPARE (WEXITSTATUS (status), 0);
++
+   /* Same test but with a NULL pid argument.  */
+   TEST_COMPARE (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ),
+ 		0);
+@@ -246,11 +252,6 @@ do_test (int argc, char *argv[])
+   free (name3_copy);
+ 
+   /* Wait for the children.  */
+-  TEST_COMPARE (xwaitpid (pid, &status, 0), pid);
+-  TEST_VERIFY (WIFEXITED (status));
+-  TEST_VERIFY (!WIFSIGNALED (status));
+-  TEST_COMPARE (WEXITSTATUS (status), 0);
+-
+   xwaitpid (-1, &status, 0);
+   TEST_VERIFY (WIFEXITED (status));
+   TEST_VERIFY (!WIFSIGNALED (status));
diff --git a/SOURCES/glibc-rh1662843-1.patch b/SOURCES/glibc-rh1662843-1.patch
new file mode 100644
index 0000000..5261045
--- /dev/null
+++ b/SOURCES/glibc-rh1662843-1.patch
@@ -0,0 +1,206 @@
+commit 1ecba1fafc160ca70f81211b23f688df8676e612
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Nov 12 14:15:14 2018 +0100
+
+    malloc: Convert the unlink macro to the unlink_chunk function
+    
+    This commit is in preparation of turning the macro into a proper
+    function.  The output arguments of the macro were in fact unused.
+    
+    Also clean up uses of __builtin_expect.
+
+diff --git a/malloc/arena.c b/malloc/arena.c
+index 497ae475e7a85902..ff8fd5d2a7e51ac8 100644
+--- a/malloc/arena.c
++++ b/malloc/arena.c
+@@ -596,7 +596,7 @@ heap_trim (heap_info *heap, size_t pad)
+ {
+   mstate ar_ptr = heap->ar_ptr;
+   unsigned long pagesz = GLRO (dl_pagesize);
+-  mchunkptr top_chunk = top (ar_ptr), p, bck, fwd;
++  mchunkptr top_chunk = top (ar_ptr), p;
+   heap_info *prev_heap;
+   long new_size, top_size, top_area, extra, prev_size, misalign;
+ 
+@@ -625,7 +625,7 @@ heap_trim (heap_info *heap, size_t pad)
+       if (!prev_inuse (p)) /* consolidate backward */
+         {
+           p = prev_chunk (p);
+-          unlink (ar_ptr, p, bck, fwd);
++          unlink_chunk (ar_ptr, p);
+         }
+       assert (((unsigned long) ((char *) p + new_size) & (pagesz - 1)) == 0);
+       assert (((char *) p + new_size) == ((char *) heap + heap->size));
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index e450597e2e527fb7..7bfa66a56786d110 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -1384,39 +1384,6 @@ typedef struct malloc_chunk *mbinptr;
+ #define first(b)     ((b)->fd)
+ #define last(b)      ((b)->bk)
+ 
+-/* Take a chunk off a bin list */
+-#define unlink(AV, P, BK, FD) {                                            \
+-    if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0))      \
+-      malloc_printerr ("corrupted size vs. prev_size");			      \
+-    FD = P->fd;								      \
+-    BK = P->bk;								      \
+-    if (__builtin_expect (FD->bk != P || BK->fd != P, 0))		      \
+-      malloc_printerr ("corrupted double-linked list");			      \
+-    else {								      \
+-        FD->bk = BK;							      \
+-        BK->fd = FD;							      \
+-        if (!in_smallbin_range (chunksize_nomask (P))			      \
+-            && __builtin_expect (P->fd_nextsize != NULL, 0)) {		      \
+-	    if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)	      \
+-		|| __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))    \
+-	      malloc_printerr ("corrupted double-linked list (not small)");   \
+-            if (FD->fd_nextsize == NULL) {				      \
+-                if (P->fd_nextsize == P)				      \
+-                  FD->fd_nextsize = FD->bk_nextsize = FD;		      \
+-                else {							      \
+-                    FD->fd_nextsize = P->fd_nextsize;			      \
+-                    FD->bk_nextsize = P->bk_nextsize;			      \
+-                    P->fd_nextsize->bk_nextsize = FD;			      \
+-                    P->bk_nextsize->fd_nextsize = FD;			      \
+-                  }							      \
+-              } else {							      \
+-                P->fd_nextsize->bk_nextsize = P->bk_nextsize;		      \
+-                P->bk_nextsize->fd_nextsize = P->fd_nextsize;		      \
+-              }								      \
+-          }								      \
+-      }									      \
+-}
+-
+ /*
+    Indexing
+ 
+@@ -1489,6 +1456,46 @@ typedef struct malloc_chunk *mbinptr;
+ #define bin_index(sz) \
+   ((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz))
+ 
++/* Take a chunk off a bin list.  */
++static void
++unlink_chunk (mstate av, mchunkptr p)
++{
++  if (chunksize (p) != prev_size (next_chunk (p)))
++    malloc_printerr ("corrupted size vs. prev_size");
++
++  mchunkptr fd = p->fd;
++  mchunkptr bk = p->bk;
++
++  if (__builtin_expect (fd->bk != p || bk->fd != p, 0))
++    malloc_printerr ("corrupted double-linked list");
++
++  fd->bk = bk;
++  bk->fd = fd;
++  if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL)
++    {
++      if (p->fd_nextsize->bk_nextsize != p
++	  || p->bk_nextsize->fd_nextsize != p)
++	malloc_printerr ("corrupted double-linked list (not small)");
++
++      if (fd->fd_nextsize == NULL)
++	{
++	  if (p->fd_nextsize == p)
++	    fd->fd_nextsize = fd->bk_nextsize = fd;
++	  else
++	    {
++	      fd->fd_nextsize = p->fd_nextsize;
++	      fd->bk_nextsize = p->bk_nextsize;
++	      p->fd_nextsize->bk_nextsize = fd;
++	      p->bk_nextsize->fd_nextsize = fd;
++	    }
++	}
++      else
++	{
++	  p->fd_nextsize->bk_nextsize = p->bk_nextsize;
++	  p->bk_nextsize->fd_nextsize = p->fd_nextsize;
++	}
++    }
++}
+ 
+ /*
+    Unsorted chunks
+@@ -3917,7 +3924,7 @@ _int_malloc (mstate av, size_t bytes)
+                 victim = victim->fd;
+ 
+               remainder_size = size - nb;
+-              unlink (av, victim, bck, fwd);
++              unlink_chunk (av, victim);
+ 
+               /* Exhaust */
+               if (remainder_size < MINSIZE)
+@@ -4019,7 +4026,7 @@ _int_malloc (mstate av, size_t bytes)
+               remainder_size = size - nb;
+ 
+               /* unlink */
+-              unlink (av, victim, bck, fwd);
++              unlink_chunk (av, victim);
+ 
+               /* Exhaust */
+               if (remainder_size < MINSIZE)
+@@ -4308,7 +4315,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+       p = chunk_at_offset(p, -((long) prevsize));
+       if (__glibc_unlikely (chunksize(p) != prevsize))
+         malloc_printerr ("corrupted size vs. prev_size while consolidating");
+-      unlink(av, p, bck, fwd);
++      unlink_chunk (av, p);
+     }
+ 
+     if (nextchunk != av->top) {
+@@ -4317,7 +4324,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
+ 
+       /* consolidate forward */
+       if (!nextinuse) {
+-	unlink(av, nextchunk, bck, fwd);
++	unlink_chunk (av, nextchunk);
+ 	size += nextsize;
+       } else
+ 	clear_inuse_bit_at_offset(nextchunk, 0);
+@@ -4430,8 +4437,6 @@ static void malloc_consolidate(mstate av)
+   INTERNAL_SIZE_T nextsize;
+   INTERNAL_SIZE_T prevsize;
+   int             nextinuse;
+-  mchunkptr       bck;
+-  mchunkptr       fwd;
+ 
+   atomic_store_relaxed (&av->have_fastchunks, false);
+ 
+@@ -4471,7 +4476,7 @@ static void malloc_consolidate(mstate av)
+ 	  p = chunk_at_offset(p, -((long) prevsize));
+ 	  if (__glibc_unlikely (chunksize(p) != prevsize))
+ 	    malloc_printerr ("corrupted size vs. prev_size in fastbins");
+-	  unlink(av, p, bck, fwd);
++	  unlink_chunk (av, p);
+ 	}
+ 
+ 	if (nextchunk != av->top) {
+@@ -4479,7 +4484,7 @@ static void malloc_consolidate(mstate av)
+ 
+ 	  if (!nextinuse) {
+ 	    size += nextsize;
+-	    unlink(av, nextchunk, bck, fwd);
++	    unlink_chunk (av, nextchunk);
+ 	  } else
+ 	    clear_inuse_bit_at_offset(nextchunk, 0);
+ 
+@@ -4527,9 +4532,6 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
+   mchunkptr        remainder;       /* extra space at end of newp */
+   unsigned long    remainder_size;  /* its size */
+ 
+-  mchunkptr        bck;             /* misc temp for linking */
+-  mchunkptr        fwd;             /* misc temp for linking */
+-
+   unsigned long    copysize;        /* bytes to copy */
+   unsigned int     ncopies;         /* INTERNAL_SIZE_T words to copy */
+   INTERNAL_SIZE_T* s;               /* copy source */
+@@ -4579,7 +4581,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
+                (unsigned long) (nb))
+         {
+           newp = oldp;
+-          unlink (av, next, bck, fwd);
++          unlink_chunk (av, next);
+         }
+ 
+       /* allocate, copy, free */
diff --git a/SOURCES/glibc-rh1662843-2.patch b/SOURCES/glibc-rh1662843-2.patch
new file mode 100644
index 0000000..27fe8c8
--- /dev/null
+++ b/SOURCES/glibc-rh1662843-2.patch
@@ -0,0 +1,73 @@
+commit b50dd3bc8cbb1efe85399b03d7e6c0310c2ead84
+Author: Florian Weimer <fw@deneb.enyo.de>
+Date:   Mon Dec 31 22:04:36 2018 +0100
+
+    malloc: Always call memcpy in _int_realloc [BZ #24027]
+    
+    This commit removes the custom memcpy implementation from _int_realloc
+    for small chunk sizes.  The ncopies variable has the wrong type, and
+    an integer wraparound could cause the existing code to copy too few
+    elements (leaving the new memory region mostly uninitialized).
+    Therefore, removing this code fixes bug 24027.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 7bfa66a56786d110..0234d968c0ce65a0 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -4532,11 +4532,6 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
+   mchunkptr        remainder;       /* extra space at end of newp */
+   unsigned long    remainder_size;  /* its size */
+ 
+-  unsigned long    copysize;        /* bytes to copy */
+-  unsigned int     ncopies;         /* INTERNAL_SIZE_T words to copy */
+-  INTERNAL_SIZE_T* s;               /* copy source */
+-  INTERNAL_SIZE_T* d;               /* copy destination */
+-
+   /* oldmem size */
+   if (__builtin_expect (chunksize_nomask (oldp) <= 2 * SIZE_SZ, 0)
+       || __builtin_expect (oldsize >= av->system_mem, 0))
+@@ -4604,43 +4599,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
+             }
+           else
+             {
+-              /*
+-                 Unroll copy of <= 36 bytes (72 if 8byte sizes)
+-                 We know that contents have an odd number of
+-                 INTERNAL_SIZE_T-sized words; minimally 3.
+-               */
+-
+-              copysize = oldsize - SIZE_SZ;
+-              s = (INTERNAL_SIZE_T *) (chunk2mem (oldp));
+-              d = (INTERNAL_SIZE_T *) (newmem);
+-              ncopies = copysize / sizeof (INTERNAL_SIZE_T);
+-              assert (ncopies >= 3);
+-
+-              if (ncopies > 9)
+-                memcpy (d, s, copysize);
+-
+-              else
+-                {
+-                  *(d + 0) = *(s + 0);
+-                  *(d + 1) = *(s + 1);
+-                  *(d + 2) = *(s + 2);
+-                  if (ncopies > 4)
+-                    {
+-                      *(d + 3) = *(s + 3);
+-                      *(d + 4) = *(s + 4);
+-                      if (ncopies > 6)
+-                        {
+-                          *(d + 5) = *(s + 5);
+-                          *(d + 6) = *(s + 6);
+-                          if (ncopies > 8)
+-                            {
+-                              *(d + 7) = *(s + 7);
+-                              *(d + 8) = *(s + 8);
+-                            }
+-                        }
+-                    }
+-                }
+-
++	      memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ);
+               _int_free (av, oldp, 1);
+               check_inuse_chunk (av, newp);
+               return chunk2mem (newp);
diff --git a/SOURCES/glibc-rh1663035.patch b/SOURCES/glibc-rh1663035.patch
new file mode 100644
index 0000000..ec38f0a
--- /dev/null
+++ b/SOURCES/glibc-rh1663035.patch
@@ -0,0 +1,22 @@
+commit 8c1aafc1f34d090a5b41dc527c33e8687f6a1287
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Dec 21 16:08:55 2018 +0100
+
+    intl: Do not return NULL on asprintf failure in gettext [BZ #24018]
+    
+    Fixes commit 9695dd0c9309712ed8e9c17a7040fe7af347f2dc ("DCIGETTEXT:
+    Use getcwd, asprintf to construct absolute pathname").
+
+diff --git a/intl/dcigettext.c b/intl/dcigettext.c
+index 2a5036994824875b..25f47c5bd3b0ea04 100644
+--- a/intl/dcigettext.c
++++ b/intl/dcigettext.c
+@@ -631,7 +631,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
+ 	  int ret = __asprintf (&xdirname, "%s/%s", cwd, dirname);
+ 	  free (cwd);
+ 	  if (ret < 0)
+-	      return NULL;
++	    goto return_untranslated;
+ 	  dirname = xdirname;
+ 	}
+ #ifndef IN_LIBGLOCALE
diff --git a/SOURCES/glibc-rh1664408.patch b/SOURCES/glibc-rh1664408.patch
new file mode 100644
index 0000000..f2f960f
--- /dev/null
+++ b/SOURCES/glibc-rh1664408.patch
@@ -0,0 +1,131 @@
+commit 2ef427168818ce04b03cecb7b739f9db0156e3e4
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Thu Jan 3 15:51:37 2019 +0100
+
+    Only build libm with -fno-math-errno (bug 24024)
+    
+    Commit 1294b1892e ("Add support for sqrt asm redirects") added the
+    -fno-math-errno flag to build most of the glibc in order to enable GCC
+    to inline math functions. Due to GCC bug #88576, saving and restoring
+    errno around calls to malloc are optimized-out. In turn this causes
+    strerror to set errno to ENOMEM if it get passed an invalid error number
+    and if malloc sets errno to ENOMEM (which might happen even if it
+    succeeds). This is not allowed by POSIX.
+    
+    This patch changes the build flags, building only libm with
+    -fno-math-errno and all the remaining code with -fno-math-errno. This
+    should be safe as libm doesn't contain any code saving and restoring
+    errno around malloc. This patch can probably be reverted once the GCC
+    bug is fixed and available in stable releases.
+    
+    Tested on x86-64, no regression in the testsuite.
+    
+    Changelog:
+            [BZ #24024]
+            * Makeconfig: Build libm with -fno-math-errno but build the remaining
+            code with -fmath-errno.
+            * string/Makefile [$(build-shared)] (tests): Add test-strerror-errno.
+            [$(build-shared)] (LDLIBS-test-strerror-errno): New variable.
+            * string/test-strerror-errno.c: New file.
+
+diff --git a/Makeconfig b/Makeconfig
+index 92e76d6200bbcd5b..8dc2fec9dc683416 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -831,8 +831,10 @@ endif
+ # disable any optimization that assume default rounding mode.
+ +math-flags = -frounding-math
+ 
+-# Build libc/libm using -fno-math-errno, but run testsuite with -fmath-errno.
+-+extra-math-flags = $(if $(filter libnldbl nonlib testsuite,$(in-module)),-fmath-errno,-fno-math-errno)
++# Logically only "libnldbl", "nonlib" and "testsuite" should be using
++# -fno-math-errno. However due to GCC bug #88576, only "libm" can use
++# -fno-math-errno.
+++extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno)
+ 
+ # We might want to compile with some stack-protection flag.
+ ifneq ($(stack-protector),)
+diff --git a/string/Makefile b/string/Makefile
+index 680431f92185f914..aa2da9ca72262886 100644
+--- a/string/Makefile
++++ b/string/Makefile
+@@ -64,6 +64,12 @@ tests		:= tester inl-tester noinl-tester testcopy test-ffs	\
+ # This test allocates a lot of memory and can run for a long time.
+ xtests = tst-strcoll-overflow
+ 
++# This test needs libdl.
++ifeq (yes,$(build-shared))
++tests += test-strerror-errno
++LDLIBS-test-strerror-errno = $(libdl)
++endif
++
+ ifeq ($(run-built-tests),yes)
+ tests-special += $(objpfx)tst-svc-cmp.out
+ endif
+diff --git a/string/test-strerror-errno.c b/string/test-strerror-errno.c
+new file mode 100644
+index 0000000000000000..8e744e7ed9df5924
+--- /dev/null
++++ b/string/test-strerror-errno.c
+@@ -0,0 +1,61 @@
++/* BZ #24024 strerror and errno test.
++
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <dlfcn.h>
++#include <errno.h>
++#include <string.h>
++
++#include <support/check.h>
++#include <support/support.h>
++
++/* malloc is allowed to change errno to a value different than 0, even when
++   there is no actual error.  This happens for example when the memory
++   allocation through sbrk fails.  Simulate this by interposing our own
++   malloc implementation which sets errno to ENOMEM and calls the original
++   malloc.  */
++void
++*malloc (size_t size)
++{
++  static void *(*real_malloc) (size_t size);
++
++  if (!real_malloc)
++    real_malloc = dlsym (RTLD_NEXT, "malloc");
++
++  errno = ENOMEM;
++
++  return (*real_malloc) (size);
++}
++
++/* strerror must not change the value of errno.  Unfortunately due to GCC bug
++   #88576, this happens when -fmath-errno is used.  This simple test checks
++   that it doesn't happen.  */
++static int
++do_test (void)
++{
++  char *msg;
++
++  errno = 0;
++  msg = strerror (-3);
++  (void) msg;
++  TEST_COMPARE (errno, 0);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1670043-1.patch b/SOURCES/glibc-rh1670043-1.patch
new file mode 100644
index 0000000..73939d9
--- /dev/null
+++ b/SOURCES/glibc-rh1670043-1.patch
@@ -0,0 +1,104 @@
+commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Mar 12 11:40:47 2019 +0100
+
+    resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047]
+    
+    The Linux kernel suppresses some ICMP error messages by default for
+    UDP sockets.  This commit enables full ICMP error reporting,
+    hopefully resulting in faster failover to working name servers.
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 8f22e6a154..ebe1b733f2 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -105,7 +105,7 @@ libresolv-routines := res_comp res_debug \
+ 		      res_data res_mkquery res_query res_send		\
+ 		      inet_net_ntop inet_net_pton inet_neta base64	\
+ 		      ns_parse ns_name ns_netint ns_ttl ns_print	\
+-		      ns_samedomain ns_date \
++		      ns_samedomain ns_date res_enable_icmp \
+ 		      compat-hooks compat-gethnamaddr
+ 
+ libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \
+diff --git a/resolv/res_enable_icmp.c b/resolv/res_enable_icmp.c
+new file mode 100644
+index 0000000000..bdc9220f08
+--- /dev/null
++++ b/resolv/res_enable_icmp.c
+@@ -0,0 +1,37 @@
++/* Enable full ICMP errors on a socket.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <netinet/in.h>
++#include <sys/socket.h>
++
++int
++__res_enable_icmp (int family, int fd)
++{
++  int one = 1;
++  switch (family)
++    {
++    case AF_INET:
++      return setsockopt (fd, SOL_IP, IP_RECVERR, &one, sizeof (one));
++    case AF_INET6:
++      return setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &one, sizeof (one));
++    default:
++      __set_errno (EAFNOSUPPORT);
++      return -1;
++    }
++}
+diff --git a/resolv/res_send.c b/resolv/res_send.c
+index fa040c1198..0f6ec83a7b 100644
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -943,6 +943,18 @@ reopen (res_state statp, int *terrno, int ns)
+ 			return (-1);
+ 		}
+ 
++		/* Enable full ICMP error reporting for this
++		   socket.  */
++		if (__res_enable_icmp (nsap->sa_family,
++				       EXT (statp).nssocks[ns]) < 0)
++		  {
++		    int saved_errno = errno;
++		    __res_iclose (statp, false);
++		    __set_errno (saved_errno);
++		    *terrno = saved_errno;
++		    return -1;
++		  }
++
+ 		/*
+ 		 * On a 4.3BSD+ machine (client and server,
+ 		 * actually), sending to a nameserver datagram
+diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h
+index 6ab8f2af09..1500adc607 100644
+--- a/resolv/resolv-internal.h
++++ b/resolv/resolv-internal.h
+@@ -100,4 +100,10 @@ libc_hidden_proto (__inet_pton_length)
+ /* Called as part of the thread shutdown sequence.  */
+ void __res_thread_freeres (void) attribute_hidden;
+ 
++/* The Linux kernel does not enable all ICMP messages on a UDP socket
++   by default.  A call this function enables full error reporting for
++   the socket FD.  FAMILY must be AF_INET or AF_INET6.  Returns 0 on
++   success, -1 on failure.  */
++int __res_enable_icmp (int family, int fd) attribute_hidden;
++
+ #endif  /* _RESOLV_INTERNAL_H */
diff --git a/SOURCES/glibc-rh1670043-2.patch b/SOURCES/glibc-rh1670043-2.patch
new file mode 100644
index 0000000..d73d211
--- /dev/null
+++ b/SOURCES/glibc-rh1670043-2.patch
@@ -0,0 +1,47 @@
+commit 043440e761d395e1f507d9faa6e82b3fe4536c3f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Mar 13 14:58:58 2019 +0100
+
+    hurd: Add no-op version of __res_enable_icmp [BZ #24047]
+    
+    Mach does not support IP_RECVERR, so replace this function with a
+    stub in a sysdeps override for Hurd.
+    
+    This fixes commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda
+    ("resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047]").
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/sysdeps/mach/hurd/res_enable_icmp.c b/sysdeps/mach/hurd/res_enable_icmp.c
+new file mode 100644
+index 0000000000..4b0456340c
+--- /dev/null
++++ b/sysdeps/mach/hurd/res_enable_icmp.c
+@@ -0,0 +1,27 @@
++/* Enable full ICMP errors on a socket.  No-op version for Hurd.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* Mach does not support the IP_RECVERR extension.  */
++
++#include <resolv.h>
++
++int
++__res_enable_icmp (int family, int fd)
++{
++  return 0;
++}
diff --git a/SOURCES/glibc-rh1672773.patch b/SOURCES/glibc-rh1672773.patch
new file mode 100644
index 0000000..1e34531
--- /dev/null
+++ b/SOURCES/glibc-rh1672773.patch
@@ -0,0 +1,199 @@
+commit 823624bdc47f1f80109c9c52dee7939b9386d708
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Thu Feb 7 15:18:36 2019 +0100
+
+    Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock. [BZ #24180]
+    
+    While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and
+    Heiko Carstens found a bug in pthread_mutex_trylock due to misordered
+    instructions:
+    140:   a5 1b 00 01             oill    %r1,1
+    144:   e5 48 a0 f0 00 00       mvghi   240(%r10),0   <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+    14a:   e3 10 a0 e0 00 24       stg     %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI
+    
+    vs (with compiler barriers):
+    140:   a5 1b 00 01             oill    %r1,1
+    144:   e3 10 a0 e0 00 24       stg     %r1,224(%r10)
+    14a:   e5 48 a0 f0 00 00       mvghi   240(%r10),0
+    
+    Please have a look at the discussion:
+    "Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede"
+    (https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/)
+    
+    This patch is introducing the same compiler barriers and comments
+    for pthread_mutex_trylock as introduced for pthread_mutex_lock and
+    pthread_mutex_timedlock by commit 8f9450a0b7a9e78267e8ae1ab1000ebca08e473e
+    "Add compiler barriers around modifications of the robust mutex list."
+    
+    ChangeLog:
+    
+            [BZ #24180]
+            * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock):
+
+diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
+index 8fe43b8f0f..bf2869eca2 100644
+--- a/nptl/pthread_mutex_trylock.c
++++ b/nptl/pthread_mutex_trylock.c
+@@ -94,6 +94,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+     case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ 		     &mutex->__data.__list.__next);
++      /* We need to set op_pending before starting the operation.  Also
++	 see comments at ENQUEUE_MUTEX.  */
++      __asm ("" ::: "memory");
+ 
+       oldval = mutex->__data.__lock;
+       do
+@@ -119,7 +122,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	      /* But it is inconsistent unless marked otherwise.  */
+ 	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+ 
++	      /* We must not enqueue the mutex before we have acquired it.
++		 Also see comments at ENQUEUE_MUTEX.  */
++	      __asm ("" ::: "memory");
+ 	      ENQUEUE_MUTEX (mutex);
++	      /* We need to clear op_pending after we enqueue the mutex.  */
++	      __asm ("" ::: "memory");
+ 	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 	      /* Note that we deliberately exist here.  If we fall
+@@ -135,6 +143,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	      int kind = PTHREAD_MUTEX_TYPE (mutex);
+ 	      if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ 		{
++		  /* We do not need to ensure ordering wrt another memory
++		     access.  Also see comments at ENQUEUE_MUTEX. */
+ 		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ 				 NULL);
+ 		  return EDEADLK;
+@@ -142,6 +152,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 
+ 	      if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+ 		{
++		  /* We do not need to ensure ordering wrt another memory
++		     access.  */
+ 		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ 				 NULL);
+ 
+@@ -160,6 +172,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 							id, 0);
+ 	  if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
+ 	    {
++	      /* We haven't acquired the lock as it is already acquired by
++		 another owner.  We do not need to ensure ordering wrt another
++		 memory access.  */
+ 	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 	      return EBUSY;
+@@ -173,13 +188,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	      if (oldval == id)
+ 		lll_unlock (mutex->__data.__lock,
+ 			    PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
++	      /* FIXME This violates the mutex destruction requirements.  See
++		 __pthread_mutex_unlock_full.  */
+ 	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 	      return ENOTRECOVERABLE;
+ 	    }
+ 	}
+       while ((oldval & FUTEX_OWNER_DIED) != 0);
+ 
++      /* We must not enqueue the mutex before we have acquired it.
++	 Also see comments at ENQUEUE_MUTEX.  */
++      __asm ("" ::: "memory");
+       ENQUEUE_MUTEX (mutex);
++      /* We need to clear op_pending after we enqueue the mutex.  */
++      __asm ("" ::: "memory");
+       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+       mutex->__data.__owner = id;
+@@ -211,10 +233,15 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	}
+ 
+ 	if (robust)
+-	  /* Note: robust PI futexes are signaled by setting bit 0.  */
+-	  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+-			 (void *) (((uintptr_t) &mutex->__data.__list.__next)
+-				   | 1));
++	  {
++	    /* Note: robust PI futexes are signaled by setting bit 0.  */
++	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++			   (void *) (((uintptr_t) &mutex->__data.__list.__next)
++				     | 1));
++	    /* We need to set op_pending before starting the operation.  Also
++	       see comments at ENQUEUE_MUTEX.  */
++	    __asm ("" ::: "memory");
++	  }
+ 
+ 	oldval = mutex->__data.__lock;
+ 
+@@ -223,12 +250,16 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	  {
+ 	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+ 	      {
++		/* We do not need to ensure ordering wrt another memory
++		   access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 		return EDEADLK;
+ 	      }
+ 
+ 	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+ 	      {
++		/* We do not need to ensure ordering wrt another memory
++		   access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 		/* Just bump the counter.  */
+@@ -250,6 +281,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	  {
+ 	    if ((oldval & FUTEX_OWNER_DIED) == 0)
+ 	      {
++		/* We haven't acquired the lock as it is already acquired by
++		   another owner.  We do not need to ensure ordering wrt another
++		   memory access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 		return EBUSY;
+@@ -270,6 +304,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	    if (INTERNAL_SYSCALL_ERROR_P (e, __err)
+ 		&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
+ 	      {
++		/* The kernel has not yet finished the mutex owner death.
++		   We do not need to ensure ordering wrt another memory
++		   access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 		return EBUSY;
+@@ -287,7 +324,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 	    /* But it is inconsistent unless marked otherwise.  */
+ 	    mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+ 
++	    /* We must not enqueue the mutex before we have acquired it.
++	       Also see comments at ENQUEUE_MUTEX.  */
++	    __asm ("" ::: "memory");
+ 	    ENQUEUE_MUTEX (mutex);
++	    /* We need to clear op_pending after we enqueue the mutex.  */
++	    __asm ("" ::: "memory");
+ 	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 	    /* Note that we deliberately exit here.  If we fall
+@@ -310,13 +352,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
+ 						  PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+ 			      0, 0);
+ 
++	    /* To the kernel, this will be visible after the kernel has
++	       acquired the mutex in the syscall.  */
+ 	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 	    return ENOTRECOVERABLE;
+ 	  }
+ 
+ 	if (robust)
+ 	  {
++	    /* We must not enqueue the mutex before we have acquired it.
++	       Also see comments at ENQUEUE_MUTEX.  */
++	    __asm ("" ::: "memory");
+ 	    ENQUEUE_MUTEX_PI (mutex);
++	    /* We need to clear op_pending after we enqueue the mutex.  */
++	    __asm ("" ::: "memory");
+ 	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 	  }
+ 
diff --git a/SOURCES/glibc-rh1691528-1.patch b/SOURCES/glibc-rh1691528-1.patch
new file mode 100644
index 0000000..9f07b78
--- /dev/null
+++ b/SOURCES/glibc-rh1691528-1.patch
@@ -0,0 +1,48 @@
+commit ac64195ccd4f320659fd0058bc7524c6fd0b37b4
+Author: DJ Delorie <dj@redhat.com>
+Date:   Wed Mar 20 23:56:59 2019 -0400
+
+    iconv, localedef: avoid floating point rounding differences [BZ #24372]
+    
+    Two cases of "int * 1.4" may result in imprecise results, which
+    in at least one case resulted in i686 and x86-64 producing
+    different locale files.  This replaced that floating point multiply
+    with integer operations.  While the hash table margin is increased
+    from 40% to 50%, testing shows only 2% increase in overall size
+    of the locale archive.
+    
+    https://bugzilla.redhat.com/show_bug.cgi?id=1311954
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index d5e8e714233f78d8..696fc8d31231ca2d 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -1079,9 +1079,9 @@ write_output (void)
+ 
+   /* Create the hashing table.  We know how many strings we have.
+      Creating a perfect hash table is not reasonable here.  Therefore
+-     we use open hashing and a table size which is the next prime 40%
++     we use open hashing and a table size which is the next prime 50%
+      larger than the number of strings.  */
+-  hash_size = next_prime (nnames * 1.4);
++  hash_size = next_prime (nnames + nnames >> 1);
+   hash_table = (struct hash_entry *) xcalloc (hash_size,
+ 					      sizeof (struct hash_entry));
+   /* Fill the hash table.  */
+diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
+index d2eebcfdbb0677e5..9a1639b999d0e2aa 100644
+--- a/locale/programs/ld-collate.c
++++ b/locale/programs/ld-collate.c
+@@ -2401,8 +2401,8 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
+ 
+       runp = runp->next;
+     }
+-  /* Add 40% and find the next prime number.  */
+-  elem_size = next_prime (elem_size * 1.4);
++  /* Add 50% and find the next prime number.  */
++  elem_size = next_prime (elem_size + elem_size >> 1);
+ 
+   /* Allocate the table.  Each entry consists of two words: the hash
+      value and an index in a secondary table which provides the index
diff --git a/SOURCES/glibc-rh1691528-2.patch b/SOURCES/glibc-rh1691528-2.patch
new file mode 100644
index 0000000..568320e
--- /dev/null
+++ b/SOURCES/glibc-rh1691528-2.patch
@@ -0,0 +1,49 @@
+commit 5abcddd7949270998c6e8d99fdbbba821b664f8b
+Author: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+Date:   Thu Mar 21 17:24:30 2019 -0300
+
+    Fix parentheses error in iconvconfig.c and ld-collate.c [BZ #24372]
+    
+    When -Werror=parentheses is in use, iconvconfig.c builds fail with:
+    
+      iconvconfig.c: In function ‘write_output’:
+      iconvconfig.c:1084:34: error: suggest parentheses around ‘+’ inside ‘>>’ [-Werror=parentheses]
+         hash_size = next_prime (nnames + nnames >> 1);
+                                 ~~~~~~~^~~~~~~~
+    
+    This patch adds parentheses to the expression.  Not where suggested by
+    the compiler warning, but where it produces the expected result, i.e.:
+    where it has the effect of multiplying nnames by 1.5.
+    
+    Likewise for elem_size in ld-collate.c.
+    
+    Tested for powerpc64le.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index 696fc8d31231ca2d..b6fef1553cbbdd3d 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -1081,7 +1081,7 @@ write_output (void)
+      Creating a perfect hash table is not reasonable here.  Therefore
+      we use open hashing and a table size which is the next prime 50%
+      larger than the number of strings.  */
+-  hash_size = next_prime (nnames + nnames >> 1);
++  hash_size = next_prime (nnames + (nnames >> 1));
+   hash_table = (struct hash_entry *) xcalloc (hash_size,
+ 					      sizeof (struct hash_entry));
+   /* Fill the hash table.  */
+diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
+index 9a1639b999d0e2aa..a5530655fd5638b5 100644
+--- a/locale/programs/ld-collate.c
++++ b/locale/programs/ld-collate.c
+@@ -2402,7 +2402,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
+       runp = runp->next;
+     }
+   /* Add 50% and find the next prime number.  */
+-  elem_size = next_prime (elem_size + elem_size >> 1);
++  elem_size = next_prime (elem_size + (elem_size >> 1));
+ 
+   /* Allocate the table.  Each entry consists of two words: the hash
+      value and an index in a secondary table which provides the index
diff --git a/SOURCES/glibc-rh1692450.patch b/SOURCES/glibc-rh1692450.patch
deleted file mode 100644
index aab01cc..0000000
--- a/SOURCES/glibc-rh1692450.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-Patch by Hanataka Shinya <hanataka.shinya@gmail.com> from
-<https://sourceware.org/bugzilla/show_bug.cgi?id=24405>.  Confirmed by TAMUKI
-Shoichi's patch in
-<https://sourceware.org/ml/libc-alpha/2019-04/msg00005.html>.
-
-The official announcement by the Japanese Prime Minister in
-<https://www.kantei.go.jp/jp/tyoukanpress/201904/1_a.html> uses U+4EE4 U+548C
-as well.
-
-diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
-index 1fd2fee44b2879d9..30190b624856cc53 100644
---- a/localedata/locales/ja_JP
-+++ b/localedata/locales/ja_JP
-@@ -14946,7 +14946,9 @@ am_pm	"<U5348><U524D>";"<U5348><U5F8C>"
- 
- t_fmt_ampm "%p%I<U6642>%M<U5206>%S<U79D2>"
- 
--era	"+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
-+era	"+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
-+	"+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
-+	"+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
- 	"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
- 	"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
- 	"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
diff --git a/SOURCES/glibc-rh1699194-1.patch b/SOURCES/glibc-rh1699194-1.patch
new file mode 100644
index 0000000..3db05de
--- /dev/null
+++ b/SOURCES/glibc-rh1699194-1.patch
@@ -0,0 +1,23 @@
+commit 4e75c2a43bb3208f32556a2b19c939cfe1f54ba6
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Jun 12 10:41:19 2019 +0200
+
+    <sys/cdefs.h>: Add __glibc_has_include macro
+
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index 3f6fe3cc8563b493..0500779d0c1b64c2 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -412,6 +412,12 @@
+ # define __glibc_has_attribute(attr)	0
+ #endif
+ 
++#ifdef __has_include
++# define __glibc_has_include(header)	__has_include (header)
++#else
++# define __glibc_has_include(header)	0
++#endif
++
+ #if (!defined _Noreturn \
+      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
+      &&  !__GNUC_PREREQ (4,7))
diff --git a/SOURCES/glibc-rh1699194-2.patch b/SOURCES/glibc-rh1699194-2.patch
new file mode 100644
index 0000000..e292641
--- /dev/null
+++ b/SOURCES/glibc-rh1699194-2.patch
@@ -0,0 +1,383 @@
+commit 5dad6ffbb2b76215cfcd38c3001778536ada8e8a
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Jun 12 12:04:09 2019 +0200
+
+    <sys/stat.h>: Use Linux UAPI header for statx if available and useful
+    
+    This will automatically import new STATX_* constants.  It also avoids
+    a conflict between <sys/stat.h> and <linux/stat.h>.
+
+Conflicts:
+	io/bits/statx.h
+	  (Year range in copyright header.)
+
+diff --git a/include/bits/statx-generic.h b/include/bits/statx-generic.h
+new file mode 100644
+index 0000000000000000..21674721b6d85265
+--- /dev/null
++++ b/include/bits/statx-generic.h
+@@ -0,0 +1 @@
++#include <io/bits/statx-generic.h>
+diff --git a/include/bits/types/struct_statx.h b/include/bits/types/struct_statx.h
+new file mode 100644
+index 0000000000000000..82add6484f2ee963
+--- /dev/null
++++ b/include/bits/types/struct_statx.h
+@@ -0,0 +1 @@
++#include <io/bits/types/struct_statx.h>
+diff --git a/include/bits/types/struct_statx_timestamp.h b/include/bits/types/struct_statx_timestamp.h
+new file mode 100644
+index 0000000000000000..9fbedd5749fc1172
+--- /dev/null
++++ b/include/bits/types/struct_statx_timestamp.h
+@@ -0,0 +1 @@
++#include <io/bits/types/struct_statx_timestamp.h>
+diff --git a/io/Makefile b/io/Makefile
+index ec5c6d7a2fb87914..787a5c550ab64b17 100644
+--- a/io/Makefile
++++ b/io/Makefile
+@@ -25,7 +25,9 @@ include ../Makeconfig
+ headers := sys/stat.h bits/stat.h sys/statfs.h bits/statfs.h sys/vfs.h \
+ 	   sys/statvfs.h bits/statvfs.h fcntl.h sys/fcntl.h bits/fcntl.h \
+ 	   poll.h sys/poll.h bits/poll.h bits/fcntl2.h bits/poll2.h \
+-	   bits/statx.h utime.h ftw.h fts.h sys/sendfile.h
++	   bits/statx.h bits/statx-generic.h bits/types/struct_statx.h \
++	   bits/types/struct_statx_timestamp.h \
++	   utime.h ftw.h fts.h sys/sendfile.h
+ 
+ routines :=								\
+ 	utime								\
+diff --git a/io/bits/statx-generic.h b/io/bits/statx-generic.h
+new file mode 100644
+index 0000000000000000..1f5abbf148681e9b
+--- /dev/null
++++ b/io/bits/statx-generic.h
+@@ -0,0 +1,60 @@
++/* Generic statx-related definitions and declarations.
++   Copyright (C) 2018-2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This interface is based on <linux/stat.h> in Linux.  */
++
++#ifndef _SYS_STAT_H
++# error Never include <bits/statx-generic.h> directly, include <sys/stat.h> instead.
++#endif
++
++#include <bits/types/struct_statx_timestamp.h>
++#include <bits/types/struct_statx.h>
++
++#ifndef STATX_TYPE
++# define STATX_TYPE 0x0001U
++# define STATX_MODE 0x0002U
++# define STATX_NLINK 0x0004U
++# define STATX_UID 0x0008U
++# define STATX_GID 0x0010U
++# define STATX_ATIME 0x0020U
++# define STATX_MTIME 0x0040U
++# define STATX_CTIME 0x0080U
++# define STATX_INO 0x0100U
++# define STATX_SIZE 0x0200U
++# define STATX_BLOCKS 0x0400U
++# define STATX_BASIC_STATS 0x07ffU
++# define STATX_ALL 0x0fffU
++# define STATX_BTIME 0x0800U
++# define STATX__RESERVED 0x80000000U
++
++# define STATX_ATTR_COMPRESSED 0x0004
++# define STATX_ATTR_IMMUTABLE 0x0010
++# define STATX_ATTR_APPEND 0x0020
++# define STATX_ATTR_NODUMP 0x0040
++# define STATX_ATTR_ENCRYPTED 0x0800
++# define STATX_ATTR_AUTOMOUNT 0x1000
++#endif /* !STATX_TYPE */
++
++__BEGIN_DECLS
++
++/* Fill *BUF with information about PATH in DIRFD.  */
++int statx (int __dirfd, const char *__restrict __path, int __flags,
++           unsigned int __mask, struct statx *__restrict __buf)
++  __THROW __nonnull ((2, 5));
++
++__END_DECLS
+diff --git a/io/bits/statx.h b/io/bits/statx.h
+index e31254e3617bb17b..b3147bfa8af1818f 100644
+--- a/io/bits/statx.h
++++ b/io/bits/statx.h
+@@ -1,5 +1,5 @@
+-/* statx-related definitions and declarations.
+-   Copyright (C) 2018 Free Software Foundation, Inc.
++/* statx-related definitions and declarations.  Generic version.
++   Copyright (C) 2018-2019 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+@@ -19,73 +19,8 @@
+ /* This interface is based on <linux/stat.h> in Linux.  */
+ 
+ #ifndef _SYS_STAT_H
+-# error Never include <bits/stat.x.h> directly, include <sys/stat.h> instead.
++# error Never include <bits/statx.h> directly, include <sys/stat.h> instead.
+ #endif
+ 
+-struct statx_timestamp
+-{
+-  __int64_t tv_sec;
+-  __uint32_t tv_nsec;
+-  __int32_t __statx_timestamp_pad1[1];
+-};
+-
+-/* Warning: The kernel may add additional fields to this struct in the
+-   future.  Only use this struct for calling the statx function, not
+-   for storing data.  (Expansion will be controlled by the mask
+-   argument of the statx function.)  */
+-struct statx
+-{
+-  __uint32_t stx_mask;
+-  __uint32_t stx_blksize;
+-  __uint64_t stx_attributes;
+-  __uint32_t stx_nlink;
+-  __uint32_t stx_uid;
+-  __uint32_t stx_gid;
+-  __uint16_t stx_mode;
+-  __uint16_t __statx_pad1[1];
+-  __uint64_t stx_ino;
+-  __uint64_t stx_size;
+-  __uint64_t stx_blocks;
+-  __uint64_t stx_attributes_mask;
+-  struct statx_timestamp stx_atime;
+-  struct statx_timestamp stx_btime;
+-  struct statx_timestamp stx_ctime;
+-  struct statx_timestamp stx_mtime;
+-  __uint32_t stx_rdev_major;
+-  __uint32_t stx_rdev_minor;
+-  __uint32_t stx_dev_major;
+-  __uint32_t stx_dev_minor;
+-  __uint64_t __statx_pad2[14];
+-};
+-
+-#define STATX_TYPE 0x0001U
+-#define STATX_MODE 0x0002U
+-#define STATX_NLINK 0x0004U
+-#define STATX_UID 0x0008U
+-#define STATX_GID 0x0010U
+-#define STATX_ATIME 0x0020U
+-#define STATX_MTIME 0x0040U
+-#define STATX_CTIME 0x0080U
+-#define STATX_INO 0x0100U
+-#define STATX_SIZE 0x0200U
+-#define STATX_BLOCKS 0x0400U
+-#define STATX_BASIC_STATS 0x07ffU
+-#define STATX_ALL 0x0fffU
+-#define STATX_BTIME 0x0800U
+-#define STATX__RESERVED 0x80000000U
+-
+-#define STATX_ATTR_COMPRESSED 0x0004
+-#define STATX_ATTR_IMMUTABLE 0x0010
+-#define STATX_ATTR_APPEND 0x0020
+-#define STATX_ATTR_NODUMP 0x0040
+-#define STATX_ATTR_ENCRYPTED 0x0800
+-#define STATX_ATTR_AUTOMOUNT 0x1000
+-
+-__BEGIN_DECLS
+-
+-/* Fill *BUF with information about PATH in DIRFD.  */
+-int statx (int __dirfd, const char *__restrict __path, int __flags,
+-           unsigned int __mask, struct statx *__restrict __buf)
+-  __THROW __nonnull ((2, 5));
+-
+-__END_DECLS
++/* Use the generic definitions.  */
++#include <bits/statx-generic.h>
+diff --git a/io/bits/types/struct_statx.h b/io/bits/types/struct_statx.h
+new file mode 100644
+index 0000000000000000..4f3ae3ece62a0ad2
+--- /dev/null
++++ b/io/bits/types/struct_statx.h
+@@ -0,0 +1,55 @@
++/* Definition of the generic version of struct statx.
++   Copyright (C) 2018-2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#ifndef _SYS_STAT_H
++# error Never include <bits/types/struct_statx.h> directly, include <sys/stat.h> instead.
++#endif
++
++#ifndef __statx_defined
++#define __statx_defined 1
++
++/* Warning: The kernel may add additional fields to this struct in the
++   future.  Only use this struct for calling the statx function, not
++   for storing data.  (Expansion will be controlled by the mask
++   argument of the statx function.)  */
++struct statx
++{
++  __uint32_t stx_mask;
++  __uint32_t stx_blksize;
++  __uint64_t stx_attributes;
++  __uint32_t stx_nlink;
++  __uint32_t stx_uid;
++  __uint32_t stx_gid;
++  __uint16_t stx_mode;
++  __uint16_t __statx_pad1[1];
++  __uint64_t stx_ino;
++  __uint64_t stx_size;
++  __uint64_t stx_blocks;
++  __uint64_t stx_attributes_mask;
++  struct statx_timestamp stx_atime;
++  struct statx_timestamp stx_btime;
++  struct statx_timestamp stx_ctime;
++  struct statx_timestamp stx_mtime;
++  __uint32_t stx_rdev_major;
++  __uint32_t stx_rdev_minor;
++  __uint32_t stx_dev_major;
++  __uint32_t stx_dev_minor;
++  __uint64_t __statx_pad2[14];
++};
++
++#endif /* __statx_defined */
+diff --git a/io/bits/types/struct_statx_timestamp.h b/io/bits/types/struct_statx_timestamp.h
+new file mode 100644
+index 0000000000000000..0f104ef84ed7d356
+--- /dev/null
++++ b/io/bits/types/struct_statx_timestamp.h
+@@ -0,0 +1,33 @@
++/* Definition of the generic version of struct statx_timestamp.
++   Copyright (C) 2018-2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#ifndef _SYS_STAT_H
++# error Never include <bits/types/struct_statx_timestamp.h> directly, include <sys/stat.h> instead.
++#endif
++
++#ifndef __statx_timestamp_defined
++#define __statx_timestamp_defined 1
++
++struct statx_timestamp
++{
++  __int64_t tv_sec;
++  __uint32_t tv_nsec;
++  __int32_t __statx_timestamp_pad1[1];
++};
++
++#endif /* __statx_timestamp_defined */
+diff --git a/io/statx_generic.c b/io/statx_generic.c
+index df327f8c525f748c..987c84fb45f5db63 100644
+--- a/io/statx_generic.c
++++ b/io/statx_generic.c
+@@ -18,9 +18,16 @@
+ 
+ #include <errno.h>
+ #include <fcntl.h>
++#include <string.h>
+ #include <sys/stat.h>
+ #include <sys/sysmacros.h>
+ 
++/* Obtain the original definition of struct statx.  */
++#undef __statx_defined
++#define statx original_statx
++#include <bits/types/struct_statx.h>
++#undef statx
++
+ static inline struct statx_timestamp
+ statx_convert_timestamp (struct timespec tv)
+ {
+@@ -57,7 +64,7 @@ statx_generic (int fd, const char *path, int flags,
+   /* The interface is defined in such a way that unused (padding)
+      fields have to be cleared.  STATX_BASIC_STATS corresponds to the
+      data which is available via fstatat64.  */
+-  *buf = (struct statx)
++  struct original_statx obuf =
+     {
+       .stx_mask = STATX_BASIC_STATS,
+       .stx_blksize = st.st_blksize,
+@@ -76,6 +83,8 @@ statx_generic (int fd, const char *path, int flags,
+       .stx_dev_major = major (st.st_dev),
+       .stx_dev_minor = minor (st.st_dev),
+     };
++  _Static_assert (sizeof (*buf) >= sizeof (obuf), "struct statx size");
++  memcpy (buf, &obuf, sizeof (obuf));
+ 
+   return 0;
+ }
+diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h
+new file mode 100644
+index 0000000000000000..d36f44efc60a0bed
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/bits/statx.h
+@@ -0,0 +1,34 @@
++/* statx-related definitions and declarations.  Linux version.
++   Copyright (C) 2018-2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This interface is based on <linux/stat.h> in Linux.  */
++
++#ifndef _SYS_STAT_H
++# error Never include <bits/statx.h> directly, include <sys/stat.h> instead.
++#endif
++
++/* Use the Linux kernel header if available.  */
++#if __glibc_has_include (<linux/stat.h>)
++# include <linux/stat.h>
++# ifdef STATX_TYPE
++#  define __statx_timestamp_defined 1
++#  define __statx_defined 1
++# endif
++#endif
++
++#include <bits/statx-generic.h>
diff --git a/SOURCES/glibc-rh1699194-3.patch b/SOURCES/glibc-rh1699194-3.patch
new file mode 100644
index 0000000..ced417e
--- /dev/null
+++ b/SOURCES/glibc-rh1699194-3.patch
@@ -0,0 +1,28 @@
+commit 8d141877e07cc594e9fefc3795b8ba729288093c
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Jun 14 15:46:02 2019 +0200
+
+    <sys/cdefs.h>: Inhibit macro expansion for __glibc_has_include
+    
+    This is currently ineffective with GCC because of GCC PR 80005, but
+    it makes sense to anticipate a fix for this defect.
+    
+    Suggested by Zack Weinberg.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index 0500779d0c1b64c2..9e840e602f815d86 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -413,7 +413,9 @@
+ #endif
+ 
+ #ifdef __has_include
+-# define __glibc_has_include(header)	__has_include (header)
++/* Do not use a function-like macro, so that __has_include can inhibit
++   macro expansion.  */
++# define __glibc_has_include __has_include
+ #else
+ # define __glibc_has_include(header)	0
+ #endif
diff --git a/SOURCES/glibc-rh1699194-4.patch b/SOURCES/glibc-rh1699194-4.patch
new file mode 100644
index 0000000..1892855
--- /dev/null
+++ b/SOURCES/glibc-rh1699194-4.patch
@@ -0,0 +1,37 @@
+commit 48c3c1238925410b4e777dc94e2fde4cc9132d44
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Jun 14 16:28:41 2019 +0200
+
+    Linux: Fix __glibc_has_include use for <sys/stat.h> and statx
+    
+    The identifier linux is used as a predefined macro, so the actually
+    used path is 1/stat.h or 1/stat64.h.  Using the quote-based version
+    triggers a file lookup for /usr/include/bits/linux/stat.h (or whatever
+    directory is used to store bits/statx.h), but since bits/ is pretty
+    much reserved by glibc, this appears to be acceptable.
+    
+    This is related to GCC PR 80005: incorrect macro expansion of the
+    argument of __has_include.
+    
+    Suggested by Zack Weinberg.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h
+index d36f44efc60a0bed..206878723fd37881 100644
+--- a/sysdeps/unix/sysv/linux/bits/statx.h
++++ b/sysdeps/unix/sysv/linux/bits/statx.h
+@@ -23,8 +23,11 @@
+ #endif
+ 
+ /* Use the Linux kernel header if available.  */
+-#if __glibc_has_include (<linux/stat.h>)
+-# include <linux/stat.h>
++
++/* Use "" to work around incorrect macro expansion of the
++   __has_include argument (GCC PR 80005).  */
++#if __glibc_has_include ("linux/stat.h")
++# include "linux/stat.h"
+ # ifdef STATX_TYPE
+ #  define __statx_timestamp_defined 1
+ #  define __statx_defined 1
diff --git a/SOURCES/glibc-rh1701605-1.patch b/SOURCES/glibc-rh1701605-1.patch
new file mode 100644
index 0000000..b21720c
--- /dev/null
+++ b/SOURCES/glibc-rh1701605-1.patch
@@ -0,0 +1,298 @@
+commit e485b2b6e006a7efa5d73e6be7e357a395c77fe3
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Apr 23 18:16:26 2019 +0200
+
+    locale: Add LOCPATH diagnostics to the locale program
+    
+    The implementation of quote_string is based on support_quote_blob.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/locale/Makefile b/locale/Makefile
+index fd9972279ba7fe0b..42bb36c7d374eebe 100644
+--- a/locale/Makefile
++++ b/locale/Makefile
+@@ -28,6 +28,7 @@ routines	= setlocale findlocale loadlocale loadarchive \
+ 		  localeconv nl_langinfo nl_langinfo_l mb_cur_max \
+ 		  newlocale duplocale freelocale uselocale
+ tests		= tst-C-locale tst-locname tst-duplocale
++tests-special	= $(objpfx)tst-locale-locpath.out
+ categories	= ctype messages monetary numeric time paper name \
+ 		  address telephone measurement identification collate
+ aux		= $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \
+@@ -104,3 +105,7 @@ cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \
+ 		 $(lib-modules)
+ lib := locale-programs
+ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
++
++$(objpfx)tst-locale-locpath.out : tst-locale-locpath.sh $(objpfx)locale
++	$(SHELL) $< '$(common-objpfx)' '$(test-wrapper)' '$(test-wrapper-env)' > $@; \
++	$(evaluate-test)
+diff --git a/locale/programs/locale.c b/locale/programs/locale.c
+index 86941e4ef6e67d78..0e2e3e4e5788246f 100644
+--- a/locale/programs/locale.c
++++ b/locale/programs/locale.c
+@@ -173,6 +173,9 @@ static int write_archive_locales (void **all_datap, char *linebuf);
+ static void write_charmaps (void);
+ static void show_locale_vars (void);
+ static void show_info (const char *name);
++static void try_setlocale (int category, const char *category_name);
++static char *quote_string (const char *input);
++static void setlocale_diagnostics (void);
+ 
+ 
+ int
+@@ -186,10 +189,8 @@ main (int argc, char *argv[])
+ 
+   /* Set locale.  Do not set LC_ALL because the other categories must
+      not be affected (according to POSIX.2).  */
+-  if (setlocale (LC_CTYPE, "") == NULL)
+-    error (0, errno, gettext ("Cannot set LC_CTYPE to default locale"));
+-  if (setlocale (LC_MESSAGES, "") == NULL)
+-    error (0, errno, gettext ("Cannot set LC_MESSAGES to default locale"));
++  try_setlocale (LC_CTYPE, "LC_CTYPE");
++  try_setlocale (LC_MESSAGES, "LC_MESSAGES");
+ 
+   /* Initialize the message catalog.  */
+   textdomain (PACKAGE);
+@@ -200,9 +201,8 @@ main (int argc, char *argv[])
+   /* `-a' requests the names of all available locales.  */
+   if (do_all != 0)
+     {
+-      if (setlocale (LC_COLLATE, "") == NULL)
+-	error (0, errno,
+-	       gettext ("Cannot set LC_COLLATE to default locale"));
++      setlocale_diagnostics ();
++      try_setlocale (LC_COLLATE, "LC_COLLATE");
+       write_locales ();
+       exit (EXIT_SUCCESS);
+     }
+@@ -211,14 +211,15 @@ main (int argc, char *argv[])
+      used for the -f argument to localedef(1).  */
+   if (do_charmaps != 0)
+     {
++      setlocale_diagnostics ();
+       write_charmaps ();
+       exit (EXIT_SUCCESS);
+     }
+ 
+   /* Specific information about the current locale are requested.
+      Change to this locale now.  */
+-  if (setlocale (LC_ALL, "") == NULL)
+-    error (0, errno, gettext ("Cannot set LC_ALL to default locale"));
++  try_setlocale (LC_ALL, "LC_ALL");
++  setlocale_diagnostics ();
+ 
+   /* If no real argument is given we have to print the contents of the
+      current locale definition variables.  These are LANG and the LC_*.  */
+@@ -983,3 +984,121 @@ show_info (const char *name)
+      For testing and perhaps advanced use allow some more symbols.  */
+   locale_special (name, show_category_name, show_keyword_name);
+ }
++
++/* Set to true by try_setlocale if setlocale fails.  Used by
++   setlocale_diagnostics.  */
++static bool setlocale_failed;
++
++/* Call setlocale, with non-fatal error reporting.  */
++static void
++try_setlocale (int category, const char *category_name)
++{
++  if (setlocale (category, "") == NULL)
++    {
++      error (0, errno, gettext ("Cannot set %s to default locale"),
++	     category_name);
++      setlocale_failed = true;
++    }
++}
++
++/* Return a quoted version of the passed string, or NULL on error.  */
++static char *
++quote_string (const char *input)
++{
++  char *buffer;
++  size_t length;
++  FILE *stream = open_memstream (&buffer, &length);
++  if (stream == NULL)
++    return NULL;
++
++  while (true)
++    {
++      unsigned char ch = *input++;
++      if (ch == '\0')
++	break;
++
++      /* Use C backslash escapes for those control characters for
++         which they are defined.  */
++      switch (ch)
++        {
++          case '\a':
++            putc_unlocked ('\\', stream);
++            putc_unlocked ('a', stream);
++            break;
++          case '\b':
++            putc_unlocked ('\\', stream);
++            putc_unlocked ('b', stream);
++            break;
++          case '\f':
++            putc_unlocked ('\\', stream);
++            putc_unlocked ('f', stream);
++            break;
++          case '\n':
++            putc_unlocked ('\\', stream);
++            putc_unlocked ('n', stream);
++            break;
++          case '\r':
++            putc_unlocked ('\\', stream);
++            putc_unlocked ('r', stream);
++            break;
++          case '\t':
++            putc_unlocked ('\\', stream);
++            putc_unlocked ('t', stream);
++            break;
++          case '\v':
++            putc_unlocked ('\\', stream);
++            putc_unlocked ('v', stream);
++            break;
++          case '\\':
++          case '\'':
++          case '\"':
++            putc_unlocked ('\\', stream);
++            putc_unlocked (ch, stream);
++            break;
++        default:
++          if (ch < ' ' || ch > '~')
++            /* Use octal sequences because they are fixed width,
++               unlike hexadecimal sequences.  */
++            fprintf (stream, "\\%03o", ch);
++          else
++            putc_unlocked (ch, stream);
++        }
++    }
++
++  if (ferror (stream))
++    {
++      fclose (stream);
++      free (buffer);
++      return NULL;
++    }
++  if (fclose (stream) != 0)
++    {
++      free (buffer);
++      return NULL;
++    }
++
++  return buffer;
++}
++
++/* Print additional information if there was a setlocale error (during
++   try_setlocale).  */
++static void
++setlocale_diagnostics (void)
++{
++  if (setlocale_failed)
++    {
++      const char *locpath = getenv ("LOCPATH");
++      if (locpath != NULL)
++	{
++	  char *quoted = quote_string (locpath);
++	  if (quoted != NULL)
++	    fprintf (stderr,
++		     gettext ("\
++warning: The LOCPATH variable is set to \"%s\"\n"),
++		     quoted);
++	  else
++	    fputs ("warning: The LOCPATH variable is set\n", stderr);
++	  free (quoted);
++	}
++    }
++}
+diff --git a/locale/tst-locale-locpath.sh b/locale/tst-locale-locpath.sh
+new file mode 100644
+index 0000000000000000..b83de90a39121af6
+--- /dev/null
++++ b/locale/tst-locale-locpath.sh
+@@ -0,0 +1,83 @@
++#!/bin/sh
++# Test that locale prints LOCPATH on failure.
++# Copyright (C) 2019 Free Software Foundation, Inc.
++# This file is part of the GNU C Library.
++
++# The GNU C Library is free software; you can redistribute it and/or
++# modify it under the terms of the GNU Lesser General Public
++# License as published by the Free Software Foundation; either
++# version 2.1 of the License, or (at your option) any later version.
++
++# The GNU C Library is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++# Lesser General Public License for more details.
++
++# You should have received a copy of the GNU Lesser General Public
++# License along with the GNU C Library; if not, see
++# <http://www.gnu.org/licenses/>.
++
++set -ex
++
++common_objpfx=$1
++test_wrapper_env=$2
++run_program_env=$3
++
++LIBPATH="$common_objpfx"
++
++testroot="${common_objpfx}locale/tst-locale-locpath-directory"
++cleanup () {
++    rm -rf "$testroot"
++}
++trap cleanup 0
++
++rm -rf "$testroot"
++mkdir -p $testroot
++
++unset LANG
++
++${test_wrapper_env} \
++${run_program_env} LC_ALL=invalid-locale LOCPATH=does-not-exist \
++${common_objpfx}elf/ld.so --library-path "$LIBPATH" \
++  "${common_objpfx}locale/locale" \
++  > "$testroot/stdout" 2> "$testroot/stderr"
++
++echo "* standard error"
++cat "$testroot/stderr"
++echo "* standard output"
++cat "$testroot/stdout"
++
++cat > "$testroot/stderr-expected" <<EOF
++${common_objpfx}locale/locale: Cannot set LC_CTYPE to default locale: No such file or directory
++${common_objpfx}locale/locale: Cannot set LC_MESSAGES to default locale: No such file or directory
++${common_objpfx}locale/locale: Cannot set LC_ALL to default locale: No such file or directory
++warning: The LOCPATH variable is set to "does-not-exist"
++EOF
++
++cat > "$testroot/stdout-expected" <<EOF
++LANG=
++LC_CTYPE="invalid-locale"
++LC_NUMERIC="invalid-locale"
++LC_TIME="invalid-locale"
++LC_COLLATE="invalid-locale"
++LC_MONETARY="invalid-locale"
++LC_MESSAGES="invalid-locale"
++LC_PAPER="invalid-locale"
++LC_NAME="invalid-locale"
++LC_ADDRESS="invalid-locale"
++LC_TELEPHONE="invalid-locale"
++LC_MEASUREMENT="invalid-locale"
++LC_IDENTIFICATION="invalid-locale"
++LC_ALL=invalid-locale
++EOF
++
++errors=0
++if ! cmp -s "$testroot/stderr-expected" "$testroot/stderr" ; then
++    echo "error: standard error not correct"
++    errors=1
++fi
++if ! cmp -s "$testroot/stdout-expected" "$testroot/stdout" ; then
++    echo "error: standard output not correct"
++    errors=1
++fi
++exit $errors
diff --git a/SOURCES/glibc-rh1701605-2.patch b/SOURCES/glibc-rh1701605-2.patch
new file mode 100644
index 0000000..ff04c64
--- /dev/null
+++ b/SOURCES/glibc-rh1701605-2.patch
@@ -0,0 +1,29 @@
+commit 439bf53496d6ed5fcef1d2e71793b46369f8205f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Apr 24 07:31:29 2019 +0200
+
+    locale/tst-locale-locpath: Run test only for $(run-built-tests) == yes
+
+diff --git a/locale/Makefile b/locale/Makefile
+index 42bb36c7d374eebe..23a71321b6646c49 100644
+--- a/locale/Makefile
++++ b/locale/Makefile
+@@ -28,7 +28,6 @@ routines	= setlocale findlocale loadlocale loadarchive \
+ 		  localeconv nl_langinfo nl_langinfo_l mb_cur_max \
+ 		  newlocale duplocale freelocale uselocale
+ tests		= tst-C-locale tst-locname tst-duplocale
+-tests-special	= $(objpfx)tst-locale-locpath.out
+ categories	= ctype messages monetary numeric time paper name \
+ 		  address telephone measurement identification collate
+ aux		= $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \
+@@ -61,6 +60,10 @@ lib-modules		:= charmap-dir simple-hash xmalloc xstrdup \
+ GPERF = gperf
+ GPERFFLAGS = -acCgopt -k1,2,5,9,$$ -L ANSI-C
+ 
++ifeq ($(run-built-tests),yes)
++tests-special += $(objpfx)tst-locale-locpath.out
++endif
++
+ include ../Rules
+ 
+ CFLAGS-md5.c += -I../crypt
diff --git a/SOURCES/glibc-rh1702539-1.patch b/SOURCES/glibc-rh1702539-1.patch
new file mode 100644
index 0000000..8023b6c
--- /dev/null
+++ b/SOURCES/glibc-rh1702539-1.patch
@@ -0,0 +1,789 @@
+This patch is a rework of the following upstream patch:
+
+commit 0e169691290a6d2187a4ff41495fc5678cbfdcdc
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Apr 12 17:39:53 2019 -0300
+
+    support: Add support_capture_subprogram
+
+    Its API is similar to support_capture_subprocess, but rather creates a
+    new process based on the input path and arguments.  Under the hoods it
+    uses posix_spawn to create the new process.
+
+    It also allows the use of other support_capture_* functions to check
+    for expected results and free the resources.
+
+    Checked on x86_64-linux-gnu.
+
+        * support/Makefile (libsupport-routines): Add support_subprocess,
+        xposix_spawn, xposix_spawn_file_actions_addclose, and
+        xposix_spawn_file_actions_adddup2.
+        (tst-support_capture_subprocess-ARGS): New rule.
+        * support/capture_subprocess.h (support_capture_subprogram): New
+        prototype.
+        * support/support_capture_subprocess.c (support_capture_subprocess):
+        Refactor to use support_subprocess and support_capture_poll.
+        (support_capture_subprogram): New function.
+        * support/tst-support_capture_subprocess.c (write_mode_to_str,
+        str_to_write_mode, test_common, parse_int, handle_restart,
+        do_subprocess, do_subprogram, do_multiple_tests): New functions.
+        (do_test): Add support_capture_subprogram tests.
+        * support/subprocess.h: New file.
+        * support/support_subprocess.c: Likewise.
+        * support/xposix_spawn.c: Likewise.
+        * support/xposix_spawn_file_actions_addclose.c: Likewise.
+        * support/xposix_spawn_file_actions_adddup2.c: Likewise.
+        * support/xspawn.h: Likewise.
+
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+
+
+diff -Nrup a/support/capture_subprocess.h b/support/capture_subprocess.h
+--- a/support/capture_subprocess.h	2018-08-01 01:10:47.000000000 -0400
++++ b/support/capture_subprocess.h	2019-05-16 23:37:19.903845257 -0400
+@@ -35,6 +35,12 @@ struct support_capture_subprocess
+ struct support_capture_subprocess support_capture_subprocess
+   (void (*callback) (void *), void *closure);
+ 
++/* Issue FILE with ARGV arguments by using posix_spawn and capture standard
++   output, standard error, and the exit status.  The out.buffer and err.buffer
++   are handle as support_capture_subprocess.  */
++struct support_capture_subprocess support_capture_subprogram
++  (const char *file, char *const argv[]);
++
+ /* Deallocate the subprocess data captured by
+    support_capture_subprocess.  */
+ void support_capture_subprocess_free (struct support_capture_subprocess *);
+diff -Nrup a/support/Makefile b/support/Makefile
+--- a/support/Makefile	2019-05-16 23:36:51.066665814 -0400
++++ b/support/Makefile	2019-05-17 10:31:24.268313761 -0400
+@@ -63,6 +63,7 @@ libsupport-routines = \
+   support_record_failure \
+   support_run_diff \
+   support_shared_allocate \
++  support_subprocess \
+   support_test_compare_blob \
+   support_test_compare_failure \
+   support_test_compare_string \
+@@ -147,6 +148,9 @@ libsupport-routines = \
+   xsigaction \
+   xsignal \
+   xsocket \
++  xposix_spawn \
++  xposix_spawn_file_actions_addclose \
++  xposix_spawn_file_actions_adddup2 \
+   xstrdup \
+   xstrndup \
+   xsymlink \
+@@ -221,4 +225,6 @@ endif
+ 
+ $(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so
+ 
++tst-support_capture_subprocess-ARGS = -- $(host-test-program-cmd)
++
+ include ../Rules
+diff -Nrup a/support/subprocess.h b/support/subprocess.h
+--- a/support/subprocess.h	1969-12-31 19:00:00.000000000 -0500
++++ b/support/subprocess.h	2019-05-16 23:37:19.903845257 -0400
+@@ -0,0 +1,49 @@
++/* Create a subprocess.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#ifndef SUPPORT_SUBPROCESS_H
++#define SUPPORT_SUBPROCESS_H
++
++#include <sys/types.h>
++
++struct support_subprocess
++{
++  int stdout_pipe[2];
++  int stderr_pipe[2];
++  pid_t pid;
++};
++
++/* Invoke CALLBACK (CLOSURE) in a subprocess created with fork and return
++   its PID, a pipe redirected to STDOUT, and a pipe redirected to STDERR.  */
++struct support_subprocess support_subprocess
++  (void (*callback) (void *), void *closure);
++
++/* Issue FILE with ARGV arguments by using posix_spawn and return is PID, a
++   pipe redirected to STDOUT, and a pipe redirected to STDERR.  */
++struct support_subprocess support_subprogram
++  (const char *file, char *const argv[]);
++
++/* Wait for the subprocess indicated by PROC::PID.  Return the status
++   indicate by waitpid call.  */
++int support_process_wait (struct support_subprocess *proc);
++
++/* Terminate the subprocess indicated by PROC::PID, first with a SIGTERM and
++   then with a SIGKILL.  Return the status as for waitpid call.  */
++int support_process_terminate (struct support_subprocess *proc);
++
++#endif
+diff -Nrup a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
+--- a/support/support_capture_subprocess.c	2019-05-16 23:36:50.672677025 -0400
++++ b/support/support_capture_subprocess.c	2019-05-16 23:38:34.298728367 -0400
+@@ -16,6 +16,7 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <support/subprocess.h>
+ #include <support/capture_subprocess.h>
+ 
+ #include <errno.h>
+@@ -23,6 +24,7 @@
+ #include <support/check.h>
+ #include <support/xunistd.h>
+ #include <support/xsocket.h>
++#include <support/xspawn.h>
+ 
+ static void
+ transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream)
+@@ -50,59 +52,52 @@ transfer (const char *what, struct pollf
+     }
+ }
+ 
+-struct support_capture_subprocess
+-support_capture_subprocess (void (*callback) (void *), void *closure)
++static void
++support_capture_poll (struct support_capture_subprocess *result,
++                     struct support_subprocess *proc)
+ {
+-  struct support_capture_subprocess result;
+-  xopen_memstream (&result.out);
+-  xopen_memstream (&result.err);
+-
+-  int stdout_pipe[2];
+-  xpipe (stdout_pipe);
+-  TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO);
+-  TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO);
+-  int stderr_pipe[2];
+-  xpipe (stderr_pipe);
+-  TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO);
+-  TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO);
+-
+-  TEST_VERIFY (fflush (stdout) == 0);
+-  TEST_VERIFY (fflush (stderr) == 0);
+-
+-  pid_t pid = xfork ();
+-  if (pid == 0)
+-    {
+-      xclose (stdout_pipe[0]);
+-      xclose (stderr_pipe[0]);
+-      xdup2 (stdout_pipe[1], STDOUT_FILENO);
+-      xdup2 (stderr_pipe[1], STDERR_FILENO);
+-      xclose (stdout_pipe[1]);
+-      xclose (stderr_pipe[1]);
+-      callback (closure);
+-      _exit (0);
+-    }
+-  xclose (stdout_pipe[1]);
+-  xclose (stderr_pipe[1]);
+-
+   struct pollfd fds[2] =
+     {
+-      { .fd = stdout_pipe[0], .events = POLLIN },
+-      { .fd = stderr_pipe[0], .events = POLLIN },
++      { .fd = proc->stdout_pipe[0], .events = POLLIN },
++      { .fd = proc->stderr_pipe[0], .events = POLLIN },
+     };
+ 
+   do
+     {
+       xpoll (fds, 2, -1);
+-      transfer ("stdout", &fds[0], &result.out);
+-      transfer ("stderr", &fds[1], &result.err);
++      transfer ("stdout", &fds[0], &result->out);
++      transfer ("stderr", &fds[1], &result->err);
+     }
+   while (fds[0].events != 0 || fds[1].events != 0);
+-  xclose (stdout_pipe[0]);
+-  xclose (stderr_pipe[0]);
++  xfclose_memstream (&result->out);
++  xfclose_memstream (&result->err);
++
++  result->status = support_process_wait (proc);
++}
++
++struct support_capture_subprocess
++support_capture_subprocess (void (*callback) (void *), void *closure)
++{
++  struct support_capture_subprocess result;
++  xopen_memstream (&result.out);
++  xopen_memstream (&result.err);
++
++  struct support_subprocess proc = support_subprocess (callback, closure);
++
++  support_capture_poll (&result, &proc);
++  return result;
++}
++
++struct support_capture_subprocess
++support_capture_subprogram (const char *file, char *const argv[])
++{
++  struct support_capture_subprocess result;
++  xopen_memstream (&result.out);
++  xopen_memstream (&result.err);
++
++  struct support_subprocess proc = support_subprogram (file, argv);
+ 
+-  xfclose_memstream (&result.out);
+-  xfclose_memstream (&result.err);
+-  xwaitpid (pid, &result.status, 0);
++  support_capture_poll (&result, &proc);
+   return result;
+ }
+ 
+diff -Nrup a/support/support_subprocess.c b/support/support_subprocess.c
+--- a/support/support_subprocess.c	1969-12-31 19:00:00.000000000 -0500
++++ b/support/support_subprocess.c	2019-05-16 23:37:19.903845257 -0400
+@@ -0,0 +1,152 @@
++/* Create subprocess.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <signal.h>
++#include <time.h>
++#include <sys/wait.h>
++#include <stdbool.h>
++#include <support/xspawn.h>
++#include <support/check.h>
++#include <support/xunistd.h>
++#include <support/subprocess.h>
++
++static struct support_subprocess
++support_suprocess_init (void)
++{
++  struct support_subprocess result;
++
++  xpipe (result.stdout_pipe);
++  TEST_VERIFY (result.stdout_pipe[0] > STDERR_FILENO);
++  TEST_VERIFY (result.stdout_pipe[1] > STDERR_FILENO);
++
++  xpipe (result.stderr_pipe);
++  TEST_VERIFY (result.stderr_pipe[0] > STDERR_FILENO);
++  TEST_VERIFY (result.stderr_pipe[1] > STDERR_FILENO);
++
++  TEST_VERIFY (fflush (stdout) == 0);
++  TEST_VERIFY (fflush (stderr) == 0);
++
++  return result;
++}
++
++struct support_subprocess
++support_subprocess (void (*callback) (void *), void *closure)
++{
++  struct support_subprocess result = support_suprocess_init ();
++
++  result.pid = xfork ();
++  if (result.pid == 0)
++    {
++      xclose (result.stdout_pipe[0]);
++      xclose (result.stderr_pipe[0]);
++      xdup2 (result.stdout_pipe[1], STDOUT_FILENO);
++      xdup2 (result.stderr_pipe[1], STDERR_FILENO);
++      xclose (result.stdout_pipe[1]);
++      xclose (result.stderr_pipe[1]);
++      callback (closure);
++     _exit (0);
++    }
++  xclose (result.stdout_pipe[1]);
++  xclose (result.stderr_pipe[1]);
++
++  return result;
++}
++
++struct support_subprocess
++support_subprogram (const char *file, char *const argv[])
++{
++  struct support_subprocess result = support_suprocess_init ();
++
++  posix_spawn_file_actions_t fa;
++  /* posix_spawn_file_actions_init does not fail.  */
++  posix_spawn_file_actions_init (&fa);
++
++  xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[0]);
++  xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[0]);
++  xposix_spawn_file_actions_adddup2 (&fa, result.stdout_pipe[1], STDOUT_FILENO);
++  xposix_spawn_file_actions_adddup2 (&fa, result.stderr_pipe[1], STDERR_FILENO);
++  xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[1]);
++  xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[1]);
++
++  result.pid = xposix_spawn (file, &fa, NULL, argv, NULL);
++
++  xclose (result.stdout_pipe[1]);
++  xclose (result.stderr_pipe[1]);
++
++  return result;
++}
++
++int
++support_process_wait (struct support_subprocess *proc)
++{
++  xclose (proc->stdout_pipe[0]);
++  xclose (proc->stderr_pipe[0]);
++
++  int status;
++  xwaitpid (proc->pid, &status, 0);
++  return status;
++}
++
++
++static bool
++support_process_kill (int pid, int signo, int *status)
++{
++  /* Kill the whole process group.  */
++  kill (-pid, signo);
++  /* In case setpgid failed in the child, kill it individually too.  */
++  kill (pid, signo);
++
++  /* Wait for it to terminate.  */
++  pid_t killed;
++  for (int i = 0; i < 5; ++i)
++    {
++      int status;
++      killed = xwaitpid (pid, &status, WNOHANG|WUNTRACED);
++      if (killed != 0)
++        break;
++
++      /* Delay, give the system time to process the kill.  If the
++         nanosleep() call return prematurely, all the better.  We
++         won't restart it since this probably means the child process
++         finally died.  */
++      nanosleep (&((struct timespec) { 0, 100000000 }), NULL);
++    }
++  if (killed != 0 && killed != pid)
++    return false;
++
++  return true;
++}
++
++int
++support_process_terminate (struct support_subprocess *proc)
++{
++  xclose (proc->stdout_pipe[0]);
++  xclose (proc->stderr_pipe[0]);
++
++  int status;
++  pid_t killed = xwaitpid (proc->pid, &status, WNOHANG|WUNTRACED);
++  if (killed != 0 && killed == proc->pid)
++    return status;
++
++  /* Subprocess is still running, terminate it.  */
++  if (!support_process_kill (proc->pid, SIGTERM, &status) )
++    support_process_kill (proc->pid, SIGKILL, &status);
++
++  return status;
++}
+diff -Nrup a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c
+--- a/support/tst-support_capture_subprocess.c	2018-08-01 01:10:47.000000000 -0400
++++ b/support/tst-support_capture_subprocess.c	2019-05-16 23:37:19.904845228 -0400
+@@ -23,8 +23,20 @@
+ #include <support/capture_subprocess.h>
+ #include <support/check.h>
+ #include <support/support.h>
++#include <support/temp_file.h>
+ #include <sys/wait.h>
+ #include <unistd.h>
++#include <paths.h>
++#include <getopt.h>
++#include <limits.h>
++#include <errno.h>
++#include <array_length.h>
++
++/* Nonzero if the program gets called via 'exec'.  */
++static int restart;
++
++/* Hold the four initial argument used to respawn the process.  */
++static char *initial_argv[5];
+ 
+ /* Write one byte at *P to FD and advance *P.  Do nothing if *P is
+    '\0'.  */
+@@ -42,6 +54,30 @@ transfer (const unsigned char **p, int f
+ enum write_mode { out_first, err_first, interleave,
+                   write_mode_last =  interleave };
+ 
++static const char *
++write_mode_to_str (enum write_mode mode)
++{
++  switch (mode)
++    {
++    case out_first:  return "out_first";
++    case err_first:  return "err_first";
++    case interleave: return "interleave";
++    default:         return "write_mode_last";
++    }
++}
++
++static enum write_mode
++str_to_write_mode (const char *mode)
++{
++  if (strcmp (mode, "out_first") == 0)
++    return out_first;
++  else if (strcmp (mode, "err_first") == 0)
++    return err_first;
++  else if (strcmp (mode, "interleave") == 0)
++    return interleave;
++  return write_mode_last;
++}
++
+ /* Describe what to write in the subprocess.  */
+ struct test
+ {
+@@ -52,11 +88,9 @@ struct test
+   int status;
+ };
+ 
+-/* For use with support_capture_subprocess.  */
+-static void
+-callback (void *closure)
++_Noreturn static void
++test_common (const struct test *test)
+ {
+-  const struct test *test = closure;
+   bool mode_ok = false;
+   switch (test->write_mode)
+     {
+@@ -95,6 +129,40 @@ callback (void *closure)
+   exit (test->status);
+ }
+ 
++static int
++parse_int (const char *str)
++{
++  char *endptr;
++  long int ret = strtol (str, &endptr, 10);
++  TEST_COMPARE (errno, 0);
++  TEST_VERIFY (ret >= 0 && ret <= INT_MAX);
++  return ret;
++}
++
++/* For use with support_capture_subprogram.  */
++_Noreturn static void
++handle_restart (char *out, char *err, const char *write_mode,
++               const char *signal, const char *status)
++{
++  struct test test =
++    {
++      out,
++      err,
++      str_to_write_mode (write_mode),
++      parse_int (signal),
++      parse_int (status)
++    };
++  test_common (&test);
++}
++
++/* For use with support_capture_subprocess.  */
++_Noreturn static void
++callback (void *closure)
++{
++  const struct test *test = closure;
++  test_common (test);
++}
++
+ /* Create a heap-allocated random string of letters.  */
+ static char *
+ random_string (size_t length)
+@@ -130,12 +198,59 @@ check_stream (const char *what, const st
+     }
+ }
+ 
++static struct support_capture_subprocess
++do_subprocess (struct test *test)
++{
++  return support_capture_subprocess (callback, test);
++}
++
++static struct support_capture_subprocess
++do_subprogram (const struct test *test)
++{
++  /* Three digits per byte plus null terminator.  */
++  char signalstr[3 * sizeof(int) + 1];
++  snprintf (signalstr, sizeof (signalstr), "%d", test->signal);
++  char statusstr[3 * sizeof(int) + 1];
++  snprintf (statusstr, sizeof (statusstr), "%d", test->status);
++
++  int argc = 0;
++  enum {
++    /* 4 elements from initial_argv (path to ld.so, '--library-path', the
++       path', and application name'), 2 for restart argument ('--direct',
++       '--restart'), 5 arguments plus NULL.  */
++    argv_size = 12
++  };
++  char *args[argv_size];
++
++  for (char **arg = initial_argv; *arg != NULL; arg++)
++    args[argc++] = *arg;
++
++  args[argc++] = (char*) "--direct";
++  args[argc++] = (char*) "--restart";
++
++  args[argc++] = test->out;
++  args[argc++] = test->err;
++  args[argc++] = (char*) write_mode_to_str (test->write_mode);
++  args[argc++] = signalstr;
++  args[argc++] = statusstr;
++  args[argc]   = NULL;
++  TEST_VERIFY (argc < argv_size);
++
++  return support_capture_subprogram (args[0], args);
++}
++
++enum test_type
++{
++  subprocess,
++  subprogram,
++};
++
+ static int
+-do_test (void)
++do_multiple_tests (enum test_type type)
+ {
+   const int lengths[] = {0, 1, 17, 512, 20000, -1};
+ 
+-  /* Test multiple combinations of support_capture_subprocess.
++  /* Test multiple combinations of support_capture_sub{process,program}.
+ 
+      length_idx_stdout: Index into the lengths array above,
+        controls how many bytes are written by the subprocess to
+@@ -164,8 +279,10 @@ do_test (void)
+               TEST_VERIFY (strlen (test.out) == lengths[length_idx_stdout]);
+               TEST_VERIFY (strlen (test.err) == lengths[length_idx_stderr]);
+ 
+-              struct support_capture_subprocess result
+-                = support_capture_subprocess (callback, &test);
++             struct support_capture_subprocess result
++               = type == subprocess ? do_subprocess (&test)
++                                    : do_subprogram (&test);
++
+               check_stream ("stdout", &result.out, test.out);
+               check_stream ("stderr", &result.err, test.err);
+               if (test.signal != 0)
+@@ -185,4 +302,54 @@ do_test (void)
+   return 0;
+ }
+ 
++static int
++do_test (int argc, char *argv[])
++{
++  /* We must have either:
++
++     - one or four parameters if called initially:
++       + argv[1]: path for ld.so        optional
++       + argv[2]: "--library-path"      optional
++       + argv[3]: the library path      optional
++       + argv[4]: the application name
++
++     - six parameters left if called through re-execution:
++       + argv[1]: the application name
++       + argv[2]: the stdout to print
++       + argv[3]: the stderr to print
++       + argv[4]: the write mode to use
++       + argv[5]: the signal to issue
++       + argv[6]: the exit status code to use
++
++     * When built with --enable-hardcoded-path-in-tests or issued without
++       using the loader directly.
++  */
++
++  if (argc != (restart ? 6 : 5) && argc != (restart ? 6 : 2))
++    FAIL_EXIT1 ("wrong number of arguments (%d)", argc);
++
++  if (restart)
++    {
++      handle_restart (argv[1],  /* stdout  */
++                     argv[2],  /* stderr  */
++                     argv[3],  /* write_mode  */
++                     argv[4],  /* signal  */
++                     argv[5]); /* status  */
++    }
++
++  initial_argv[0] = argv[1]; /* path for ld.so  */
++  initial_argv[1] = argv[2]; /* "--library-path"  */
++  initial_argv[2] = argv[3]; /* the library path  */
++  initial_argv[3] = argv[4]; /* the application name  */
++  initial_argv[4] = NULL;
++
++  do_multiple_tests (subprocess);
++  do_multiple_tests (subprogram);
++
++  return 0;
++}
++
++#define CMDLINE_OPTIONS \
++  { "restart", no_argument, &restart, 1 },
++#define TEST_FUNCTION_ARGV do_test
+ #include <support/test-driver.c>
+diff -Nrup a/support/xposix_spawn.c b/support/xposix_spawn.c
+--- a/support/xposix_spawn.c	1969-12-31 19:00:00.000000000 -0500
++++ b/support/xposix_spawn.c	2019-05-16 23:37:19.904845228 -0400
+@@ -0,0 +1,32 @@
++/* xposix_spawn implementation.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/xspawn.h>
++#include <support/check.h>
++
++pid_t
++xposix_spawn (const char *file, const posix_spawn_file_actions_t *fa,
++             const posix_spawnattr_t *attr, char *const args[],
++             char *const envp[])
++{
++  pid_t pid;
++  int status = posix_spawn (&pid, file, fa, attr, args, envp);
++  if (status != 0)
++    FAIL_EXIT1 ("posix_spawn to %s file failed: %m", file);
++  return pid;
++}
+diff -Nrup a/support/xposix_spawn_file_actions_addclose.c b/support/xposix_spawn_file_actions_addclose.c
+--- a/support/xposix_spawn_file_actions_addclose.c	1969-12-31 19:00:00.000000000 -0500
++++ b/support/xposix_spawn_file_actions_addclose.c	2019-05-16 23:37:19.904845228 -0400
+@@ -0,0 +1,29 @@
++/* xposix_spawn_file_actions_addclose implementation.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/xspawn.h>
++#include <support/check.h>
++
++int
++xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *fa, int fd)
++{
++  int status = posix_spawn_file_actions_addclose (fa, fd);
++  if (status == -1)
++    FAIL_EXIT1 ("posix_spawn_file_actions_addclose failed: %m\n");
++  return status;
++}
+diff -Nrup a/support/xposix_spawn_file_actions_adddup2.c b/support/xposix_spawn_file_actions_adddup2.c
+--- a/support/xposix_spawn_file_actions_adddup2.c	1969-12-31 19:00:00.000000000 -0500
++++ b/support/xposix_spawn_file_actions_adddup2.c	2019-05-16 23:37:19.904845228 -0400
+@@ -0,0 +1,30 @@
++/* xposix_spawn_file_actions_adddup2 implementation.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/xspawn.h>
++#include <support/check.h>
++
++int
++xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *fa, int fd,
++                                  int newfd)
++{
++  int status = posix_spawn_file_actions_adddup2 (fa, fd, newfd);
++  if (status == -1)
++    FAIL_EXIT1 ("posix_spawn_file_actions_adddup2 failed: %m\n");
++  return status;
++}
+diff -Nrup a/support/xspawn.h b/support/xspawn.h
+--- a/support/xspawn.h	1969-12-31 19:00:00.000000000 -0500
++++ b/support/xspawn.h	2019-05-16 23:37:19.904845228 -0400
+@@ -0,0 +1,34 @@
++/* posix_spawn with support checks.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#ifndef SUPPORT_XSPAWN_H
++#define SUPPORT_XSPAWN_H
++
++#include <spawn.h>
++
++__BEGIN_DECLS
++
++int xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *, int);
++int xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *, int, int);
++
++pid_t xposix_spawn (const char *, const posix_spawn_file_actions_t *,
++                   const posix_spawnattr_t *, char *const [], char *const []);
++
++__END_DECLS
++
++#endif
diff --git a/SOURCES/glibc-rh1702539-2.patch b/SOURCES/glibc-rh1702539-2.patch
new file mode 100644
index 0000000..1c1b8bb
--- /dev/null
+++ b/SOURCES/glibc-rh1702539-2.patch
@@ -0,0 +1,558 @@
+This patch is a rework of the following upstream patch:
+
+commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Thu Apr 11 18:12:00 2019 -0300
+
+    elf: Fix pldd (BZ#18035)
+
+    Since 9182aa67994 (Fix vDSO l_name for GDB's, BZ#387) the initial link_map
+    for executable itself and loader will have both l_name and l_libname->name
+    holding the same value due:
+
+     elf/dl-object.c
+
+     95   new->l_name = *realname ? realname : (char *) newname->name + libname_len - 1;
+
+    Since newname->name points to new->l_libname->name.
+
+    This leads to pldd to an infinite call at:
+
+     elf/pldd-xx.c
+
+    203     again:
+    204       while (1)
+    205         {
+    206           ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset);
+
+    228           /* Try the l_libname element.  */
+    229           struct E(libname_list) ln;
+    230           if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
+    231             {
+    232               name_offset = ln.name;
+    233               goto again;
+    234             }
+
+    Since the value at ln.name (l_libname->name) will be the same as previously
+    read. The straightforward fix is just avoid the check and read the new list
+    entry.
+
+    I checked also against binaries issues with old loaders with fix for BZ#387,
+    and pldd could dump the shared objects.
+
+    Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, and
+    powerpc64le-linux-gnu.
+
+diff -Nrup a/elf/Makefile b/elf/Makefile
+--- a/elf/Makefile	2019-05-17 12:35:12.663074766 -0400
++++ b/elf/Makefile	2019-05-17 12:35:45.816147975 -0400
+@@ -201,6 +201,7 @@ tests-internal += loadtest unload unload
+ 	 neededtest neededtest2 neededtest3 neededtest4 \
+ 	 tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
+ 	 tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym
++tests-container += tst-pldd
+ ifeq ($(build-hardcoded-path-in-tests),yes)
+ tests += tst-dlopen-aout
+ tst-dlopen-aout-no-pie = yes
+diff -Nrup a/elf/pldd.c b/elf/pldd.c
+--- a/elf/pldd.c	2018-08-01 01:10:47.000000000 -0400
++++ b/elf/pldd.c	2019-05-17 12:35:45.817147947 -0400
+@@ -17,23 +17,17 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <alloca.h>
++#define _FILE_OFFSET_BITS 64
++
+ #include <argp.h>
+-#include <assert.h>
+ #include <dirent.h>
+-#include <elf.h>
+-#include <errno.h>
+ #include <error.h>
+ #include <fcntl.h>
+ #include <libintl.h>
+-#include <link.h>
+-#include <stddef.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+-#include <string.h>
+ #include <unistd.h>
+ #include <sys/ptrace.h>
+-#include <sys/stat.h>
+ #include <sys/wait.h>
+ #include <scratch_buffer.h>
+ 
+@@ -76,14 +70,8 @@ static struct argp argp =
+   options, parse_opt, args_doc, doc, NULL, more_help, NULL
+ };
+ 
+-// File descriptor of /proc/*/mem file.
+-static int memfd;
+-
+-/* Name of the executable  */
+-static char *exe;
+-
+ /* Local functions.  */
+-static int get_process_info (int dfd, long int pid);
++static int get_process_info (const char *exe, int dfd, long int pid);
+ static void wait_for_ptrace_stop (long int pid);
+ 
+ 
+@@ -102,8 +90,10 @@ main (int argc, char *argv[])
+       return 1;
+     }
+ 
+-  assert (sizeof (pid_t) == sizeof (int)
+-	  || sizeof (pid_t) == sizeof (long int));
++  _Static_assert (sizeof (pid_t) == sizeof (int)
++                 || sizeof (pid_t) == sizeof (long int),
++                 "sizeof (pid_t) != sizeof (int) or sizeof (long int)");
++
+   char *endp;
+   errno = 0;
+   long int pid = strtol (argv[remaining], &endp, 10);
+@@ -119,25 +109,24 @@ main (int argc, char *argv[])
+   if (dfd == -1)
+     error (EXIT_FAILURE, errno, gettext ("cannot open %s"), buf);
+ 
+-  struct scratch_buffer exebuf;
+-  scratch_buffer_init (&exebuf);
++  /* Name of the executable  */
++  struct scratch_buffer exe;
++  scratch_buffer_init (&exe);
+   ssize_t nexe;
+   while ((nexe = readlinkat (dfd, "exe",
+-			     exebuf.data, exebuf.length)) == exebuf.length)
++                            exe.data, exe.length)) == exe.length)
+     {
+-      if (!scratch_buffer_grow (&exebuf))
++      if (!scratch_buffer_grow (&exe))
+ 	{
+ 	  nexe = -1;
+ 	  break;
+ 	}
+     }
+   if (nexe == -1)
+-    exe = (char *) "<program name undetermined>";
++    /* Default stack allocation is at least 1024.  */
++    snprintf (exe.data, exe.length, "<program name undetermined>");
+   else
+-    {
+-      exe = exebuf.data;
+-      exe[nexe] = '\0';
+-    }
++    ((char*)exe.data)[nexe] = '\0';
+ 
+   /* Stop all threads since otherwise the list of loaded modules might
+      change while we are reading it.  */
+@@ -155,8 +144,8 @@ main (int argc, char *argv[])
+     error (EXIT_FAILURE, errno, gettext ("cannot prepare reading %s/task"),
+ 	   buf);
+ 
+-  struct dirent64 *d;
+-  while ((d = readdir64 (dir)) != NULL)
++  struct dirent *d;
++  while ((d = readdir (dir)) != NULL)
+     {
+       if (! isdigit (d->d_name[0]))
+ 	continue;
+@@ -182,7 +171,7 @@ main (int argc, char *argv[])
+ 
+       wait_for_ptrace_stop (tid);
+ 
+-      struct thread_list *newp = alloca (sizeof (*newp));
++      struct thread_list *newp = xmalloc (sizeof (*newp));
+       newp->tid = tid;
+       newp->next = thread_list;
+       thread_list = newp;
+@@ -190,17 +179,22 @@ main (int argc, char *argv[])
+ 
+   closedir (dir);
+ 
+-  int status = get_process_info (dfd, pid);
++  if (thread_list == NULL)
++    error (EXIT_FAILURE, 0, gettext ("no valid %s/task entries"), buf);
++
++  int status = get_process_info (exe.data, dfd, pid);
+ 
+-  assert (thread_list != NULL);
+   do
+     {
+       ptrace (PTRACE_DETACH, thread_list->tid, NULL, NULL);
++      struct thread_list *prev = thread_list;
+       thread_list = thread_list->next;
++      free (prev);
+     }
+   while (thread_list != NULL);
+ 
+   close (dfd);
++  scratch_buffer_free (&exe);
+ 
+   return status;
+ }
+@@ -281,9 +275,10 @@ warranty; not even for MERCHANTABILITY o
+ 
+ 
+ static int
+-get_process_info (int dfd, long int pid)
++get_process_info (const char *exe, int dfd, long int pid)
+ {
+-  memfd = openat (dfd, "mem", O_RDONLY);
++  /* File descriptor of /proc/<pid>/mem file.  */
++  int memfd = openat (dfd, "mem", O_RDONLY);
+   if (memfd == -1)
+     goto no_info;
+ 
+@@ -333,9 +328,9 @@ get_process_info (int dfd, long int pid)
+ 
+   int retval;
+   if (e_ident[EI_CLASS] == ELFCLASS32)
+-    retval = find_maps32 (pid, auxv, auxv_size);
++    retval = find_maps32 (exe, memfd, pid, auxv, auxv_size);
+   else
+-    retval = find_maps64 (pid, auxv, auxv_size);
++    retval = find_maps64 (exe, memfd, pid, auxv, auxv_size);
+ 
+   free (auxv);
+   close (memfd);
+diff -Nrup a/elf/pldd-xx.c b/elf/pldd-xx.c
+--- a/elf/pldd-xx.c	2018-08-01 01:10:47.000000000 -0400
++++ b/elf/pldd-xx.c	2019-05-17 13:05:29.587147445 -0400
+@@ -23,10 +23,6 @@
+ #define EW_(e, w, t) EW__(e, w, _##t)
+ #define EW__(e, w, t) e##w##t
+ 
+-#define pldd_assert(name, exp) \
+-  typedef int __assert_##name[((exp) != 0) - 1]
+-
+-
+ struct E(link_map)
+ {
+   EW(Addr) l_addr;
+@@ -39,12 +35,12 @@ struct E(link_map)
+   EW(Addr) l_libname;
+ };
+ #if CLASS == __ELF_NATIVE_CLASS
+-pldd_assert (l_addr, (offsetof (struct link_map, l_addr)
+-			== offsetof (struct E(link_map), l_addr)));
+-pldd_assert (l_name, (offsetof (struct link_map, l_name)
+-			== offsetof (struct E(link_map), l_name)));
+-pldd_assert (l_next, (offsetof (struct link_map, l_next)
+-			== offsetof (struct E(link_map), l_next)));
++_Static_assert (offsetof (struct link_map, l_addr)
++               == offsetof (struct E(link_map), l_addr), "l_addr");
++_Static_assert (offsetof (struct link_map, l_name)
++               == offsetof (struct E(link_map), l_name), "l_name");
++_Static_assert (offsetof (struct link_map, l_next)
++               == offsetof (struct E(link_map), l_next), "l_next");
+ #endif
+ 
+ 
+@@ -54,10 +50,10 @@ struct E(libname_list)
+   EW(Addr) next;
+ };
+ #if CLASS == __ELF_NATIVE_CLASS
+-pldd_assert (name, (offsetof (struct libname_list, name)
+-		      == offsetof (struct E(libname_list), name)));
+-pldd_assert (next, (offsetof (struct libname_list, next)
+-		      == offsetof (struct E(libname_list), next)));
++_Static_assert (offsetof (struct libname_list, name)
++               == offsetof (struct E(libname_list), name), "name");
++_Static_assert (offsetof (struct libname_list, next)
++               == offsetof (struct E(libname_list), next), "next");
+ #endif
+ 
+ struct E(r_debug)
+@@ -69,16 +65,17 @@ struct E(r_debug)
+   EW(Addr) r_map;
+ };
+ #if CLASS == __ELF_NATIVE_CLASS
+-pldd_assert (r_version, (offsetof (struct r_debug, r_version)
+-			   == offsetof (struct E(r_debug), r_version)));
+-pldd_assert (r_map, (offsetof (struct r_debug, r_map)
+-		       == offsetof (struct E(r_debug), r_map)));
++_Static_assert (offsetof (struct r_debug, r_version)
++               == offsetof (struct E(r_debug), r_version), "r_version");
++_Static_assert (offsetof (struct r_debug, r_map)
++               == offsetof (struct E(r_debug), r_map), "r_map");
+ #endif
+ 
+ 
+ static int
+ 
+-E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
++E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv,
++             size_t auxv_size)
+ {
+   EW(Addr) phdr = 0;
+   unsigned int phnum = 0;
+@@ -104,12 +101,9 @@ E(find_maps) (pid_t pid, void *auxv, siz
+   if (phdr == 0 || phnum == 0 || phent == 0)
+     error (EXIT_FAILURE, 0, gettext ("cannot find program header of process"));
+ 
+-  EW(Phdr) *p = alloca (phnum * phent);
+-  if (pread64 (memfd, p, phnum * phent, phdr) != phnum * phent)
+-    {
+-      error (0, 0, gettext ("cannot read program header"));
+-      return EXIT_FAILURE;
+-    }
++  EW(Phdr) *p = xmalloc (phnum * phent);
++  if (pread (memfd, p, phnum * phent, phdr) != phnum * phent)
++    error (EXIT_FAILURE, 0, gettext ("cannot read program header"));
+ 
+   /* Determine the load offset.  We need this for interpreting the
+      other program header entries so we do this in a separate loop.
+@@ -129,24 +123,18 @@ E(find_maps) (pid_t pid, void *auxv, siz
+     if (p[i].p_type == PT_DYNAMIC)
+       {
+ 	EW(Dyn) *dyn = xmalloc (p[i].p_filesz);
+-	if (pread64 (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr)
++       if (pread (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr)
+ 	    != p[i].p_filesz)
+-	  {
+-	    error (0, 0, gettext ("cannot read dynamic section"));
+-	    return EXIT_FAILURE;
+-	  }
++         error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section"));
+ 
+ 	/* Search for the DT_DEBUG entry.  */
+ 	for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j)
+ 	  if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0)
+ 	    {
+ 	      struct E(r_debug) r;
+-	      if (pread64 (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr)
++             if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr)
+ 		  != sizeof (r))
+-		{
+-		  error (0, 0, gettext ("cannot read r_debug"));
+-		  return EXIT_FAILURE;
+-		}
++               error (EXIT_FAILURE, 0, gettext ("cannot read r_debug"));
+ 
+ 	      if (r.r_map != 0)
+ 		{
+@@ -160,13 +148,10 @@ E(find_maps) (pid_t pid, void *auxv, siz
+       }
+     else if (p[i].p_type == PT_INTERP)
+       {
+-	interp = alloca (p[i].p_filesz);
+-	if (pread64 (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr)
++       interp = xmalloc (p[i].p_filesz);
++       if (pread (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr)
+ 	    != p[i].p_filesz)
+-	  {
+-	    error (0, 0, gettext ("cannot read program interpreter"));
+-	    return EXIT_FAILURE;
+-	  }
++         error (EXIT_FAILURE, 0, gettext ("cannot read program interpreter"));
+       }
+ 
+   if (list == 0)
+@@ -174,14 +159,16 @@ E(find_maps) (pid_t pid, void *auxv, siz
+       if (interp == NULL)
+ 	{
+ 	  // XXX check whether the executable itself is the loader
+-	  return EXIT_FAILURE;
++         exit (EXIT_FAILURE);
+ 	}
+ 
+       // XXX perhaps try finding ld.so and _r_debug in it
+-
+-      return EXIT_FAILURE;
++      exit (EXIT_FAILURE);
+     }
+ 
++  free (p);
++  free (interp);
++
+   /* Print the PID and program name first.  */
+   printf ("%lu:\t%s\n", (unsigned long int) pid, exe);
+ 
+@@ -192,47 +179,27 @@ E(find_maps) (pid_t pid, void *auxv, siz
+   do
+     {
+       struct E(link_map) m;
+-      if (pread64 (memfd, &m, sizeof (m), list) != sizeof (m))
+-	{
+-	  error (0, 0, gettext ("cannot read link map"));
+-	  status = EXIT_FAILURE;
+-	  goto out;
+-	}
++      if (pread (memfd, &m, sizeof (m), list) != sizeof (m))
++       error (EXIT_FAILURE, 0, gettext ("cannot read link map"));
+ 
+       EW(Addr) name_offset = m.l_name;
+-    again:
+       while (1)
+ 	{
+-	  ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset);
++         ssize_t n = pread (memfd, tmpbuf.data, tmpbuf.length, name_offset);
+ 	  if (n == -1)
+-	    {
+-	      error (0, 0, gettext ("cannot read object name"));
+-	      status = EXIT_FAILURE;
+-	      goto out;
+-	    }
++           error (EXIT_FAILURE, 0, gettext ("cannot read object name"));
+ 
+ 	  if (memchr (tmpbuf.data, '\0', n) != NULL)
+ 	    break;
+ 
+ 	  if (!scratch_buffer_grow (&tmpbuf))
+-	    {
+-	      error (0, 0, gettext ("cannot allocate buffer for object name"));
+-	      status = EXIT_FAILURE;
+-	      goto out;
+-	    }
++           error (EXIT_FAILURE, 0,
++                  gettext ("cannot allocate buffer for object name"));
+ 	}
+ 
+-      if (((char *)tmpbuf.data)[0] == '\0' && name_offset == m.l_name
+-	  && m.l_libname != 0)
+-	{
+-	  /* Try the l_libname element.  */
+-	  struct E(libname_list) ln;
+-	  if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
+-	    {
+-	      name_offset = ln.name;
+-	      goto again;
+-	    }
+-	}
++      /* The m.l_name and m.l_libname.name for loader linkmap points to same
++        values (since BZ#387 fix).  Trying to use l_libname name as the
++        shared object name might lead to an infinite loop (BZ#18035).  */
+ 
+       /* Skip over the executable.  */
+       if (((char *)tmpbuf.data)[0] != '\0')
+@@ -242,7 +209,6 @@ E(find_maps) (pid_t pid, void *auxv, siz
+     }
+   while (list != 0);
+ 
+- out:
+   scratch_buffer_free (&tmpbuf);
+   return status;
+ }
+diff -Nrup a/elf/tst-pldd.c b/elf/tst-pldd.c
+--- a/elf/tst-pldd.c	1969-12-31 19:00:00.000000000 -0500
++++ b/elf/tst-pldd.c	2019-05-17 12:35:45.817147947 -0400
+@@ -0,0 +1,118 @@
++/* Basic tests for pldd program.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <string.h>
++#include <unistd.h>
++#include <stdint.h>
++#include <libgen.h>
++#include <stdbool.h>
++
++#include <array_length.h>
++#include <gnu/lib-names.h>
++
++#include <support/subprocess.h>
++#include <support/capture_subprocess.h>
++#include <support/check.h>
++
++static void
++target_process (void *arg)
++{
++  pause ();
++}
++
++/* The test runs in a container because pldd does not support tracing
++   a binary started by the loader iself (as with testrun.sh).  */
++
++static int
++do_test (void)
++{
++  /* Create a copy of current test to check with pldd.  */
++  struct support_subprocess target = support_subprocess (target_process, NULL);
++
++  /* Run 'pldd' on test subprocess.  */
++  struct support_capture_subprocess pldd;
++  {
++    /* Three digits per byte plus null terminator.  */
++    char pid[3 * sizeof (uint32_t) + 1];
++    snprintf (pid, array_length (pid), "%d", target.pid);
++
++    const char prog[] = "/usr/bin/pldd";
++
++    pldd = support_capture_subprogram (prog,
++      (char *const []) { (char *) prog, pid, NULL });
++
++    support_capture_subprocess_check (&pldd, "pldd", 0, sc_allow_stdout);
++  }
++
++  /* Check 'pldd' output.  The test is expected to be linked against only
++     loader and libc.  */
++  {
++    pid_t pid;
++    char buffer[512];
++#define STRINPUT(size) "%" # size "s"
++
++    FILE *out = fmemopen (pldd.out.buffer, pldd.out.length, "r");
++    TEST_VERIFY (out != NULL);
++
++    /* First line is in the form of <pid>: <full path of executable>  */
++    TEST_COMPARE (fscanf (out, "%u: " STRINPUT (512), &pid, buffer), 2);
++
++    TEST_COMPARE (pid, target.pid);
++    TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0);
++
++    /* It expects only one loader and libc loaded by the program.  */
++    bool interpreter_found = false, libc_found = false;
++    while (fgets (buffer, array_length (buffer), out) != NULL)
++      {
++       /* Ignore vDSO.  */
++        if (buffer[0] != '/')
++         continue;
++
++       /* Remove newline so baseline (buffer) can compare against the
++          LD_SO and LIBC_SO macros unmodified.  */
++       if (buffer[strlen(buffer)-1] == '\n')
++         buffer[strlen(buffer)-1] = '\0';
++
++       if (strcmp (basename (buffer), LD_SO) == 0)
++         {
++           TEST_COMPARE (interpreter_found, false);
++           interpreter_found = true;
++           continue;
++         }
++
++       if (strcmp (basename (buffer), LIBC_SO) == 0)
++         {
++           TEST_COMPARE (libc_found, false);
++           libc_found = true;
++           continue;
++         }
++      }
++    TEST_COMPARE (interpreter_found, true);
++    TEST_COMPARE (libc_found, true);
++
++    fclose (out);
++  }
++
++  support_capture_subprocess_free (&pldd);
++  support_process_terminate (&target);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1706777.patch b/SOURCES/glibc-rh1706777.patch
new file mode 100644
index 0000000..9e64daa
--- /dev/null
+++ b/SOURCES/glibc-rh1706777.patch
@@ -0,0 +1,44 @@
+commit 38b0593e9a862c3b35392a0f5b202696b8116aa3
+Author: Tobias Klauser <tklauser@distanz.ch>
+Date:   Tue Aug 21 17:22:53 2018 +0000
+
+    Add PF_XDP, AF_XDP and SOL_XDP from Linux 4.18 to bits/socket.h.
+    
+    This patch adds the PF_XDP, AF_XDP and SOL_XDP macros from Linux 4.18 to
+    sysdeps/unix/sysv/linux/bits/socket.h.
+    
+            * sysdeps/unix/sysv/linux/bits/socket.h (PF_MAX): Set to 45.
+            (PF_XDP): New macro.
+            (AF_XDP): New macro.
+            (SOL_XDP): New macro.
+
+diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
+index fa409f0fabc22d33..c3fbb2110296273c 100644
+--- a/sysdeps/unix/sysv/linux/bits/socket.h
++++ b/sysdeps/unix/sysv/linux/bits/socket.h
+@@ -85,7 +85,8 @@ typedef __socklen_t socklen_t;
+ #define PF_KCM		41	/* Kernel Connection Multiplexor.  */
+ #define PF_QIPCRTR	42	/* Qualcomm IPC Router.  */
+ #define PF_SMC		43	/* SMC sockets.  */
+-#define PF_MAX		44	/* For now..  */
++#define PF_XDP		44	/* XDP sockets.  */
++#define PF_MAX		45	/* For now..  */
+ 
+ /* Address families.  */
+ #define AF_UNSPEC	PF_UNSPEC
+@@ -135,6 +136,7 @@ typedef __socklen_t socklen_t;
+ #define AF_KCM		PF_KCM
+ #define AF_QIPCRTR	PF_QIPCRTR
+ #define AF_SMC		PF_SMC
++#define AF_XDP		PF_XDP
+ #define AF_MAX		PF_MAX
+ 
+ /* Socket level values.  Others are defined in the appropriate headers.
+@@ -164,6 +166,7 @@ typedef __socklen_t socklen_t;
+ #define SOL_NFC		280
+ #define SOL_KCM		281
+ #define SOL_TLS		282
++#define SOL_XDP		283
+ 
+ /* Maximum queue length specifiable by listen.  */
+ #define SOMAXCONN	128
diff --git a/SOURCES/glibc-rh1710478.patch b/SOURCES/glibc-rh1710478.patch
new file mode 100644
index 0000000..3546690
--- /dev/null
+++ b/SOURCES/glibc-rh1710478.patch
@@ -0,0 +1,107 @@
+commit 32ff397533715988c19cbf3675dcbd727ec13e18
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Tue May 14 17:14:59 2019 +0200
+
+    Fix crash in _IO_wfile_sync (bug 20568)
+    
+    When computing the length of the converted part of the stdio buffer, use
+    the number of consumed wide characters, not the (negative) distance to the
+    end of the wide buffer.
+
+Conflicts:
+	libio/Makefile
+	  (Usual conflict when adding tests due to missing backports.)
+
+diff --git a/libio/Makefile b/libio/Makefile
+index cab0eae946b1f307..cbfaf3832a45fc22 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -64,7 +64,8 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
+ 	bug-memstream1 bug-wmemstream1 \
+ 	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
+ 	tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
+-	tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof
++	tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
++	tst-wfile-sync
+ 
+ tests-internal = tst-vtables tst-vtables-interposed tst-readline
+ 
+@@ -207,6 +208,7 @@ $(objpfx)tst-ungetwc1.out: $(gen-locales)
+ $(objpfx)tst-ungetwc2.out: $(gen-locales)
+ $(objpfx)tst-widetext.out: $(gen-locales)
+ $(objpfx)tst_wprintf2.out: $(gen-locales)
++$(objpfx)tst-wfile-sync.out: $(gen-locales)
+ endif
+ 
+ $(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen
+diff --git a/libio/tst-wfile-sync.c b/libio/tst-wfile-sync.c
+new file mode 100644
+index 0000000000000000..618682064da4035c
+--- /dev/null
++++ b/libio/tst-wfile-sync.c
+@@ -0,0 +1,39 @@
++/* Test that _IO_wfile_sync does not crash (bug 20568).
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <locale.h>
++#include <stdio.h>
++#include <wchar.h>
++#include <support/check.h>
++#include <support/xunistd.h>
++
++static int
++do_test (void)
++{
++  TEST_VERIFY_EXIT (setlocale (LC_ALL, "de_DE.UTF-8") != NULL);
++  /* Fill the stdio buffer and advance the read pointer.  */
++  TEST_VERIFY_EXIT (fgetwc (stdin) != WEOF);
++  /* This calls _IO_wfile_sync, it should not crash.  */
++  TEST_VERIFY_EXIT (setvbuf (stdin, NULL, _IONBF, 0) == 0);
++  /* Verify that the external file offset has been synchronized.  */
++  TEST_COMPARE (xlseek (0, 0, SEEK_CUR), 1);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/libio/tst-wfile-sync.input b/libio/tst-wfile-sync.input
+new file mode 100644
+index 0000000000000000..12d0958f7aaa3865
+--- /dev/null
++++ b/libio/tst-wfile-sync.input
+@@ -0,0 +1 @@
++This is a test of _IO_wfile_sync.
+diff --git a/libio/wfileops.c b/libio/wfileops.c
+index 63cb687652c72ce1..10e7343f8fdb8781 100644
+--- a/libio/wfileops.c
++++ b/libio/wfileops.c
+@@ -508,11 +508,12 @@ _IO_wfile_sync (FILE *fp)
+ 	     generate the wide characters up to the current reading
+ 	     position.  */
+ 	  int nread;
+-
++	  size_t wnread = (fp->_wide_data->_IO_read_ptr
++			   - fp->_wide_data->_IO_read_base);
+ 	  fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
+ 	  nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
+ 					      fp->_IO_read_base,
+-					      fp->_IO_read_end, delta);
++					      fp->_IO_read_end, wnread);
+ 	  fp->_IO_read_ptr = fp->_IO_read_base + nread;
+ 	  delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
+ 	}
diff --git a/SOURCES/glibc-rh1710894.patch b/SOURCES/glibc-rh1710894.patch
new file mode 100644
index 0000000..790d27a
--- /dev/null
+++ b/SOURCES/glibc-rh1710894.patch
@@ -0,0 +1,310 @@
+commit a9368c34d70cef91ca59b09941f496df11d6b146
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed May 15 13:51:35 2019 +0200
+
+    nss: Turn __nss_database_lookup into a compatibility symbol
+    
+    The function uses the internal service_user type, so it is not
+    really usable from the outside of glibc.  Rename the function
+    to __nss_database_lookup2 for internal use, and change
+    __nss_database_lookup to always indicate failure to the caller.
+    
+    __nss_next already was a compatibility symbol.  The new
+    implementation always fails and no longer calls __nss_next2.
+    
+    unscd, the alternative nscd implementation, does not use
+    __nss_database_lookup, so it is not affected by this change.
+
+DJ - Added 2.30 clause to nss/Versions as RHEL 8 will always be 2.28.
+
+diff -rup a/grp/initgroups.c b/grp/initgroups.c
+--- a/grp/initgroups.c	2019-06-06 17:15:32.184092617 -0400
++++ b/grp/initgroups.c	2019-06-06 17:16:59.136114679 -0400
+@@ -79,12 +79,12 @@ internal_getgrouplist (const char *user,
+ 
+   if (__nss_initgroups_database == NULL)
+     {
+-      if (__nss_database_lookup ("initgroups", NULL, "",
+-				 &__nss_initgroups_database) < 0)
++      if (__nss_database_lookup2 ("initgroups", NULL, "",
++				  &__nss_initgroups_database) < 0)
+ 	{
+ 	  if (__nss_group_database == NULL)
+-	    no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG,
+-					     &__nss_group_database);
++	    no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG,
++					      &__nss_group_database);
+ 
+ 	  __nss_initgroups_database = __nss_group_database;
+ 	}
+diff -rup a/nscd/aicache.c b/nscd/aicache.c
+--- a/nscd/aicache.c	2018-08-01 01:10:47.000000000 -0400
++++ b/nscd/aicache.c	2019-06-06 17:16:59.501114771 -0400
+@@ -93,9 +93,9 @@ addhstaiX (struct database_dyn *db, int
+   int herrno = 0;
+ 
+   if (hosts_database == NULL)
+-    no_more = __nss_database_lookup ("hosts", NULL,
+-				     "dns [!UNAVAIL=return] files",
+-				     &hosts_database);
++    no_more = __nss_database_lookup2 ("hosts", NULL,
++				      "dns [!UNAVAIL=return] files",
++				      &hosts_database);
+   else
+     no_more = 0;
+   nip = hosts_database;
+diff -rup a/nscd/initgrcache.c b/nscd/initgrcache.c
+--- a/nscd/initgrcache.c	2019-06-06 17:15:32.205092622 -0400
++++ b/nscd/initgrcache.c	2019-06-06 17:16:59.510114774 -0400
+@@ -88,8 +88,8 @@ addinitgroupsX (struct database_dyn *db,
+   int no_more;
+ 
+   if (group_database == NULL)
+-    no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG,
+-				     &group_database);
++    no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG,
++				      &group_database);
+   else
+     no_more = 0;
+   nip = group_database;
+diff -rup a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+--- a/nscd/netgroupcache.c	2019-06-06 17:15:32.151092608 -0400
++++ b/nscd/netgroupcache.c	2019-06-06 17:16:59.514114775 -0400
+@@ -143,7 +143,7 @@ addgetnetgrentX (struct database_dyn *db
+   *tofreep = NULL;
+ 
+   if (netgroup_database == NULL
+-      && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
++      && __nss_database_lookup2 ("netgroup", NULL, NULL, &netgroup_database))
+     {
+       /* No such service.  */
+       cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+diff -rup a/nss/Versions b/nss/Versions
+--- a/nss/Versions	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/Versions	2019-06-10 16:59:34.920054974 -0400
+@@ -1,21 +1,26 @@
+ libc {
+   GLIBC_2.0 {
+-     # functions used in other libraries
++    __nss_configure_lookup;
++
++    # Functions exported as no-op compat symbols.
+     __nss_passwd_lookup; __nss_group_lookup; __nss_hosts_lookup; __nss_next;
+-    __nss_database_lookup; __nss_configure_lookup;
++    __nss_database_lookup;
+   }
+   GLIBC_2.2.2 {
+     __nss_hostname_digits_dots;
+   }
+   GLIBC_2.27 {
+   }
++  GLIBC_2.30 {
++    # Added for rhbz 1710894
++  }
+   GLIBC_PRIVATE {
+     _nss_files_parse_grent; _nss_files_parse_pwent; _nss_files_parse_spent;
+     __nss_disable_nscd; __nss_lookup_function; _nss_files_parse_sgent;
+ 
+     __nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2;
+     __nss_services_lookup2; __nss_next2; __nss_lookup;
+-    __nss_hash;
++    __nss_hash; __nss_database_lookup2;
+   }
+ }
+ 
+diff -rup a/nss/XXX-lookup.c b/nss/XXX-lookup.c
+--- a/nss/XXX-lookup.c	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/XXX-lookup.c	2019-06-06 17:16:59.562114786 -0400
+@@ -57,8 +57,8 @@ DB_LOOKUP_FCT (service_user **ni, const
+ 	       void **fctp)
+ {
+   if (DATABASE_NAME_SYMBOL == NULL
+-      && __nss_database_lookup (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING,
+-				DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0)
++      && __nss_database_lookup2 (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING,
++				 DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0)
+     return -1;
+ 
+   *ni = DATABASE_NAME_SYMBOL;
+diff -rup a/nss/compat-lookup.c b/nss/compat-lookup.c
+--- a/nss/compat-lookup.c	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/compat-lookup.c	2019-06-07 22:14:09.057668330 -0400
+@@ -16,11 +16,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <nsswitch.h>
++
+ #include <shlib-compat.h>
+ #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27)
+ 
+ # include <errno.h>
+-# include <nsswitch.h>
+ 
+ /* On i386, the function calling convention changed from the standard
+    ABI calling convention to three register parameters in glibc 2.8.
+@@ -40,3 +41,31 @@ strong_alias (__nss_passwd_lookup, __nss
+ compat_symbol (libc, __nss_hosts_lookup, __nss_hosts_lookup, GLIBC_2_0);
+ 
+ #endif /* SHLIB_COMPAT */
++
++
++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_30)
++
++/* These functions were exported under a non-GLIBC_PRIVATE version,
++   even though it is not usable externally due to the service_user
++   type dependency.  */
++
++int
++attribute_compat_text_section
++__nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
++            int all_values)
++{
++  return -1;
++}
++compat_symbol (libc, __nss_next, __nss_next, GLIBC_2_0);
++
++int
++attribute_compat_text_section
++__nss_database_lookup (const char *database, const char *alternate_name,
++                       const char *defconfig, service_user **ni)
++{
++  *ni = NULL;
++  return -1;
++}
++compat_symbol (libc, __nss_database_lookup, __nss_database_lookup, GLIBC_2_0);
++
++#endif /* SHLIB_COMPAT */
+diff -rup a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c
+--- a/nss/nss_compat/compat-grp.c	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/nss_compat/compat-grp.c	2019-06-06 17:16:59.618114799 -0400
+@@ -78,7 +78,7 @@ static bool in_blacklist (const char *,
+ static void
+ init_nss_interface (void)
+ {
+-  if (__nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0)
++  if (__nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0)
+     {
+       nss_setgrent = __nss_lookup_function (ni, "setgrent");
+       nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r");
+diff -rup a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c
+--- a/nss/nss_compat/compat-initgroups.c	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/nss_compat/compat-initgroups.c	2019-06-06 17:16:59.646114807 -0400
+@@ -89,7 +89,7 @@ init_nss_interface (void)
+ 
+   /* Retest.  */
+   if (ni == NULL
+-      && __nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0)
++      && __nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0)
+     {
+       nss_initgroups_dyn = __nss_lookup_function (ni, "initgroups_dyn");
+       nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r");
+diff -rup a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c
+--- a/nss/nss_compat/compat-pwd.c	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/nss_compat/compat-pwd.c	2019-06-06 17:16:59.654114809 -0400
+@@ -88,7 +88,7 @@ static bool in_blacklist (const char *,
+ static void
+ init_nss_interface (void)
+ {
+-  if (__nss_database_lookup ("passwd_compat", NULL, "nis", &ni) >= 0)
++  if (__nss_database_lookup2 ("passwd_compat", NULL, "nis", &ni) >= 0)
+     {
+       nss_setpwent = __nss_lookup_function (ni, "setpwent");
+       nss_getpwnam_r = __nss_lookup_function (ni, "getpwnam_r");
+diff -rup a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c
+--- a/nss/nss_compat/compat-spwd.c	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/nss_compat/compat-spwd.c	2019-06-06 17:16:59.668114812 -0400
+@@ -85,8 +85,8 @@ static bool in_blacklist (const char *,
+ static void
+ init_nss_interface (void)
+ {
+-  if (__nss_database_lookup ("shadow_compat", "passwd_compat",
+-			     "nis", &ni) >= 0)
++  if (__nss_database_lookup2 ("shadow_compat", "passwd_compat",
++			      "nis", &ni) >= 0)
+     {
+       nss_setspent = __nss_lookup_function (ni, "setspent");
+       nss_getspnam_r = __nss_lookup_function (ni, "getspnam_r");
+diff -rup a/nss/nsswitch.c b/nss/nsswitch.c
+--- a/nss/nsswitch.c	2019-06-06 17:15:32.210092623 -0400
++++ b/nss/nsswitch.c	2019-06-06 17:16:59.672114813 -0400
+@@ -115,8 +115,8 @@ static void (*nscd_init_cb) (size_t, str
+ /* -1 == database not found
+     0 == database entry pointer stored */
+ int
+-__nss_database_lookup (const char *database, const char *alternate_name,
+-		       const char *defconfig, service_user **ni)
++__nss_database_lookup2 (const char *database, const char *alternate_name,
++			const char *defconfig, service_user **ni)
+ {
+   /* Prevent multiple threads to change the service table.  */
+   __libc_lock_lock (lock);
+@@ -185,7 +185,7 @@ __nss_database_lookup (const char *datab
+ 
+   return *ni != NULL ? 0 : -1;
+ }
+-libc_hidden_def (__nss_database_lookup)
++libc_hidden_def (__nss_database_lookup2)
+ 
+ 
+ /* -1 == not found
+@@ -260,16 +260,6 @@ __nss_next2 (service_user **ni, const ch
+ }
+ libc_hidden_def (__nss_next2)
+ 
+-
+-int
+-attribute_compat_text_section
+-__nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
+-	    int all_values)
+-{
+-  return __nss_next2 (ni, fct_name, NULL, fctp, status, all_values);
+-}
+-
+-
+ int
+ __nss_configure_lookup (const char *dbname, const char *service_line)
+ {
+@@ -835,7 +825,7 @@ nss_load_all_libraries (const char *serv
+ {
+   service_user *ni = NULL;
+ 
+-  if (__nss_database_lookup (service, NULL, def, &ni) == 0)
++  if (__nss_database_lookup2 (service, NULL, def, &ni) == 0)
+     while (ni != NULL)
+       {
+ 	nss_load_library (ni);
+diff -rup a/nss/nsswitch.h b/nss/nsswitch.h
+--- a/nss/nsswitch.h	2018-08-01 01:10:47.000000000 -0400
++++ b/nss/nsswitch.h	2019-06-06 17:16:59.691114818 -0400
+@@ -125,10 +125,10 @@ extern bool __nss_database_custom[NSS_DB
+    If there is no configuration for this database in the file,
+    parse a service list from DEFCONFIG and use that.  More
+    than one function can use the database.  */
+-extern int __nss_database_lookup (const char *database,
+-				  const char *alternative_name,
+-				  const char *defconfig, service_user **ni);
+-libc_hidden_proto (__nss_database_lookup)
++extern int __nss_database_lookup2 (const char *database,
++				   const char *alternative_name,
++				   const char *defconfig, service_user **ni);
++libc_hidden_proto (__nss_database_lookup2)
+ 
+ /* Put first function with name FCT_NAME for SERVICE in FCTP.  The
+    position is remembered in NI.  The function returns a value < 0 if
+diff -rup a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+--- a/sysdeps/posix/getaddrinfo.c	2018-08-01 01:10:47.000000000 -0400
++++ b/sysdeps/posix/getaddrinfo.c	2019-06-06 17:16:59.724114827 -0400
+@@ -737,9 +737,9 @@ gaih_inet (const char *name, const struc
+ #endif
+ 
+ 	  if (__nss_hosts_database == NULL)
+-	    no_more = __nss_database_lookup ("hosts", NULL,
+-					     "dns [!UNAVAIL=return] files",
+-					     &__nss_hosts_database);
++	    no_more = __nss_database_lookup2 ("hosts", NULL,
++					      "dns [!UNAVAIL=return] files",
++					      &__nss_hosts_database);
+ 	  else
+ 	    no_more = 0;
+ 	  nip = __nss_hosts_database;
diff --git a/SOURCES/glibc-rh1717438.patch b/SOURCES/glibc-rh1717438.patch
new file mode 100644
index 0000000..8bfaec8
--- /dev/null
+++ b/SOURCES/glibc-rh1717438.patch
@@ -0,0 +1,71 @@
+commit 11b451c8868d8a2b0edc5dfd44fc58d9ee538be0
+Author: Mark Wielaard <mark@klomp.org>
+Date:   Wed May 15 17:14:01 2019 +0200
+
+    dlfcn: Guard __dlerror_main_freeres with __libc_once_get (once) [BZ# 24476]
+    
+    dlerror.c (__dlerror_main_freeres) will try to free resources which only
+    have been initialized when init () has been called. That function is
+    called when resources are needed using __libc_once (once, init) where
+    once is a __libc_once_define (static, once) in the dlerror.c file.
+    Trying to free those resources if init () hasn't been called will
+    produce errors under valgrind memcheck. So guard the freeing of those
+    resources using __libc_once_get (once) and make sure we have a valid
+    key. Also add a similar guard to __dlerror ().
+    
+            * dlfcn/dlerror.c (__dlerror_main_freeres): Guard using
+            __libc_once_get (once) and static_bug == NULL.
+            (__dlerror): Check we have a valid key, set result to static_buf
+            otherwise.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
+index 96bf92533335036b..06732460ea1512cd 100644
+--- a/dlfcn/dlerror.c
++++ b/dlfcn/dlerror.c
+@@ -72,9 +72,16 @@ __dlerror (void)
+   __libc_once (once, init);
+ 
+   /* Get error string.  */
+-  result = (struct dl_action_result *) __libc_getspecific (key);
+-  if (result == NULL)
+-    result = &last_result;
++  if (static_buf != NULL)
++    result = static_buf;
++  else
++    {
++      /* init () has been run and we don't use the static buffer.
++	 So we have a valid key.  */
++      result = (struct dl_action_result *) __libc_getspecific (key);
++      if (result == NULL)
++	result = &last_result;
++    }
+ 
+   /* Test whether we already returned the string.  */
+   if (result->returned != 0)
+@@ -230,13 +237,19 @@ free_key_mem (void *mem)
+ void
+ __dlerror_main_freeres (void)
+ {
+-  void *mem;
+   /* Free the global memory if used.  */
+   check_free (&last_result);
+-  /* Free the TSD memory if used.  */
+-  mem = __libc_getspecific (key);
+-  if (mem != NULL)
+-    free_key_mem (mem);
++
++  if (__libc_once_get (once) && static_buf == NULL)
++    {
++      /* init () has been run and we don't use the static buffer.
++	 So we have a valid key.  */
++      void *mem;
++      /* Free the TSD memory if used.  */
++      mem = __libc_getspecific (key);
++      if (mem != NULL)
++	free_key_mem (mem);
++    }
+ }
+ 
+ struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon));
diff --git a/SOURCES/glibc-rh1722215.patch b/SOURCES/glibc-rh1722215.patch
new file mode 100644
index 0000000..cbda401
--- /dev/null
+++ b/SOURCES/glibc-rh1722215.patch
@@ -0,0 +1,186 @@
+commit 21cc130b78a4db9113fb6695e2b951e697662440
+Author: Dmitry V. Levin <ldv@altlinux.org>
+Date:   Wed Feb 13 01:20:51 2019 +0000
+
+    libio: do not attempt to free wide buffers of legacy streams [BZ #24228]
+    
+    Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693
+    ("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
+    when _G_HAVE_MMAP is turned off.") introduced a regression:
+    _IO_unbuffer_all now invokes _IO_wsetb to free wide buffers of all
+    files, including legacy standard files which are small statically
+    allocated objects that do not have wide buffers and the _mode member,
+    causing memory corruption.
+    
+    Another memory corruption in _IO_unbuffer_all happens when -1
+    is assigned to the _mode member of legacy standard files that
+    do not have it.
+    
+    [BZ #24228]
+    * libio/genops.c (_IO_unbuffer_all)
+    [SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide
+    buffers and access _IO_FILE_complete members of legacy libio streams.
+    * libio/tst-bz24228.c: New file.
+    * libio/tst-bz24228.map: Likewise.
+    * libio/Makefile [build-shared] (tests): Add tst-bz24228.
+    [build-shared] (generated): Add tst-bz24228.mtrace and
+    tst-bz24228.check.
+    [run-built-tests && build-shared] (tests-special): Add
+    $(objpfx)tst-bz24228-mem.out.
+    (LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
+    ($(objpfx)tst-bz24228-mem.out): New rule.
+
+# Conflicts:
+#	libio/Makefile
+
+diff --git a/libio/Makefile b/libio/Makefile
+index cbfaf3832a45fc22..314e03d5ce72be2d 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -73,6 +73,9 @@ ifeq (yes,$(build-shared))
+ # Add test-fopenloc only if shared library is enabled since it depends on
+ # shared localedata objects.
+ tests += tst-fopenloc
++# Add tst-bz24228 only if shared library is enabled since it can never meet its
++# objective with static linking because the relevant code just is not there.
++tests += tst-bz24228
+ endif
+ test-srcs = test-freopen
+ 
+@@ -153,11 +156,14 @@ CFLAGS-oldtmpfile.c += -fexceptions
+ 
+ CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\"
+ 
++LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map
++
+ tst_wprintf2-ARGS = "Some Text"
+ 
+ test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace
+ tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
+ tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace
++tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace
+ 
+ generated += test-fmemopen.mtrace test-fmemopen.check
+ generated += tst-fopenloc.mtrace tst-fopenloc.check
+@@ -166,6 +172,7 @@ generated += tst-bz22415.mtrace tst-bz22415.check
+ aux	:= fileops genops stdfiles stdio strops
+ 
+ ifeq ($(build-shared),yes)
++generated += tst-bz24228.mtrace tst-bz24228.check
+ aux	+= oldfileops oldstdfiles
+ endif
+ 
+@@ -180,7 +187,8 @@ tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \
+ ifeq (yes,$(build-shared))
+ # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
+ # library is enabled since they depend on tst-fopenloc.out.
+-tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out
++tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out \
++		 $(objpfx)tst-bz24228-mem.out
+ endif
+ endif
+ 
+@@ -232,3 +240,7 @@ $(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out
+ $(objpfx)tst-bz22415-mem.out: $(objpfx)tst-bz22415.out
+ 	$(common-objpfx)malloc/mtrace $(objpfx)tst-bz22415.mtrace > $@; \
+ 	$(evaluate-test)
++
++$(objpfx)tst-bz24228-mem.out: $(objpfx)tst-bz24228.out
++	$(common-objpfx)malloc/mtrace $(objpfx)tst-bz24228.mtrace > $@; \
++	$(evaluate-test)
+diff --git a/libio/genops.c b/libio/genops.c
+index 2fec221b99729718..a8241dd26640bbcb 100644
+--- a/libio/genops.c
++++ b/libio/genops.c
+@@ -789,9 +789,16 @@ _IO_unbuffer_all (void)
+ 
+   for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
+     {
++      int legacy = 0;
++
++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
++      if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
++	legacy = 1;
++#endif
++
+       if (! (fp->_flags & _IO_UNBUFFERED)
+ 	  /* Iff stream is un-orientated, it wasn't used. */
+-	  && fp->_mode != 0)
++	  && (legacy || fp->_mode != 0))
+ 	{
+ #ifdef _IO_MTSAFE_IO
+ 	  int cnt;
+@@ -805,7 +812,7 @@ _IO_unbuffer_all (void)
+ 	      __sched_yield ();
+ #endif
+ 
+-	  if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
++	  if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
+ 	    {
+ 	      fp->_flags |= _IO_USER_BUF;
+ 
+@@ -816,7 +823,7 @@ _IO_unbuffer_all (void)
+ 
+ 	  _IO_SETBUF (fp, NULL, 0);
+ 
+-	  if (fp->_mode > 0)
++	  if (! legacy && fp->_mode > 0)
+ 	    _IO_wsetb (fp, NULL, NULL, 0);
+ 
+ #ifdef _IO_MTSAFE_IO
+@@ -827,7 +834,8 @@ _IO_unbuffer_all (void)
+ 
+       /* Make sure that never again the wide char functions can be
+ 	 used.  */
+-      fp->_mode = -1;
++      if (! legacy)
++	fp->_mode = -1;
+     }
+ 
+ #ifdef _IO_MTSAFE_IO
+diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c
+new file mode 100644
+index 0000000000000000..6a74500d473ceeab
+--- /dev/null
++++ b/libio/tst-bz24228.c
+@@ -0,0 +1,29 @@
++/* BZ #24228 check for memory corruption in legacy libio
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <mcheck.h>
++#include <support/test-driver.h>
++
++static int
++do_test (void)
++{
++  mtrace ();
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map
+new file mode 100644
+index 0000000000000000..4383e0817d7f5583
+--- /dev/null
++++ b/libio/tst-bz24228.map
+@@ -0,0 +1,5 @@
++# Hide the symbol from libc.so.6 to switch to the libio/oldfileops.c
++# implementation when it is available for the architecture.
++{
++  local: _IO_stdin_used;
++};
diff --git a/SOURCES/glibc-rh1724975.patch b/SOURCES/glibc-rh1724975.patch
new file mode 100644
index 0000000..7ea3267
--- /dev/null
+++ b/SOURCES/glibc-rh1724975.patch
@@ -0,0 +1,1013 @@
+commit 5a659ccc0ec217ab02a4c273a1f6d346a359560a
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Jun 28 09:39:21 2019 +0200
+
+    io: Remove copy_file_range emulation [BZ #24744]
+    
+    The kernel is evolving this interface (e.g., removal of the
+    restriction on cross-device copies), and keeping up with that
+    is difficult.  Applications which need the function should
+    run kernels which support the system call instead of relying on
+    the imperfect glibc emulation.
+    
+    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+# Conflicts:
+#	io/copy_file_range-compat.c
+#	io/copy_file_range.c
+#	io/tst-copy_file_range-compat.c
+#	io/tst-copy_file_range.c
+#	sysdeps/unix/sysv/linux/arm/kernel-features.h
+#	sysdeps/unix/sysv/linux/microblaze/kernel-features.h
+#	sysdeps/unix/sysv/linux/sh/kernel-features.h
+
+diff --git a/io/Makefile b/io/Makefile
+index 787a5c550ab64b17..62e71b4cbe879dbc 100644
+--- a/io/Makefile
++++ b/io/Makefile
+@@ -75,11 +75,6 @@ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
+ 		   tst-fts tst-fts-lfs tst-open-tmpfile \
+ 		   tst-copy_file_range tst-getcwd-abspath \
+ 
+-# This test includes the compat implementation of copy_file_range,
+-# which uses internal, unexported libc functions.
+-tests-static += tst-copy_file_range-compat
+-tests-internal += tst-copy_file_range-compat
+-
+ # Likewise for statx, but we do not need static linking here.
+ tests-internal += tst-statx
+ 
+diff --git a/io/copy_file_range-compat.c b/io/copy_file_range-compat.c
+deleted file mode 100644
+index 4ab22cad19146ca9..0000000000000000
+--- a/io/copy_file_range-compat.c
++++ /dev/null
+@@ -1,160 +0,0 @@
+-/* Emulation of copy_file_range.
+-   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* The following macros should be defined before including this
+-   file:
+-
+-   COPY_FILE_RANGE_DECL   Declaration specifiers for the function below.
+-   COPY_FILE_RANGE        Name of the function to define.  */
+-
+-#include <errno.h>
+-#include <fcntl.h>
+-#include <inttypes.h>
+-#include <limits.h>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <unistd.h>
+-
+-COPY_FILE_RANGE_DECL
+-ssize_t
+-COPY_FILE_RANGE (int infd, __off64_t *pinoff,
+-                 int outfd, __off64_t *poutoff,
+-                 size_t length, unsigned int flags)
+-{
+-  if (flags != 0)
+-    {
+-      __set_errno (EINVAL);
+-      return -1;
+-    }
+-
+-  {
+-    struct stat64 instat;
+-    struct stat64 outstat;
+-    if (fstat64 (infd, &instat) != 0 || fstat64 (outfd, &outstat) != 0)
+-      return -1;
+-    if (S_ISDIR (instat.st_mode) || S_ISDIR (outstat.st_mode))
+-      {
+-        __set_errno (EISDIR);
+-        return -1;
+-      }
+-    if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode))
+-      {
+-        /* We need a regular input file so that the we can seek
+-           backwards in case of a write failure.  */
+-        __set_errno (EINVAL);
+-        return -1;
+-      }
+-    if (instat.st_dev != outstat.st_dev)
+-      {
+-        /* Cross-device copies are not supported.  */
+-        __set_errno (EXDEV);
+-        return -1;
+-      }
+-  }
+-
+-  /* The output descriptor must not have O_APPEND set.  */
+-  {
+-    int flags = __fcntl (outfd, F_GETFL);
+-    if (flags & O_APPEND)
+-      {
+-        __set_errno (EBADF);
+-        return -1;
+-      }
+-  }
+-
+-  /* Avoid an overflow in the result.  */
+-  if (length > SSIZE_MAX)
+-    length = SSIZE_MAX;
+-
+-  /* Main copying loop.  The buffer size is arbitrary and is a
+-     trade-off between stack size consumption, cache usage, and
+-     amortization of system call overhead.  */
+-  size_t copied = 0;
+-  char buf[8192];
+-  while (length > 0)
+-    {
+-      size_t to_read = length;
+-      if (to_read > sizeof (buf))
+-        to_read = sizeof (buf);
+-
+-      /* Fill the buffer.  */
+-      ssize_t read_count;
+-      if (pinoff == NULL)
+-        read_count = read (infd, buf, to_read);
+-      else
+-        read_count = __libc_pread64 (infd, buf, to_read, *pinoff);
+-      if (read_count == 0)
+-        /* End of file reached prematurely.  */
+-        return copied;
+-      if (read_count < 0)
+-        {
+-          if (copied > 0)
+-            /* Report the number of bytes copied so far.  */
+-            return copied;
+-          return -1;
+-        }
+-      if (pinoff != NULL)
+-        *pinoff += read_count;
+-
+-      /* Write the buffer part which was read to the destination.  */
+-      char *end = buf + read_count;
+-      for (char *p = buf; p < end; )
+-        {
+-          ssize_t write_count;
+-          if (poutoff == NULL)
+-            write_count = write (outfd, p, end - p);
+-          else
+-            write_count = __libc_pwrite64 (outfd, p, end - p, *poutoff);
+-          if (write_count < 0)
+-            {
+-              /* Adjust the input read position to match what we have
+-                 written, so that the caller can pick up after the
+-                 error.  */
+-              size_t written = p - buf;
+-              /* NB: This needs to be signed so that we can form the
+-                 negative value below.  */
+-              ssize_t overread = read_count - written;
+-              if (pinoff == NULL)
+-                {
+-                  if (overread > 0)
+-                    {
+-                      /* We are on an error recovery path, so we
+-                         cannot deal with failure here.  */
+-                      int save_errno = errno;
+-                      (void) __libc_lseek64 (infd, -overread, SEEK_CUR);
+-                      __set_errno (save_errno);
+-                    }
+-                }
+-              else /* pinoff != NULL */
+-                *pinoff -= overread;
+-
+-              if (copied + written > 0)
+-                /* Report the number of bytes copied so far.  */
+-                return copied + written;
+-              return -1;
+-            }
+-          p += write_count;
+-          if (poutoff != NULL)
+-            *poutoff += write_count;
+-        } /* Write loop.  */
+-
+-      copied += read_count;
+-      length -= read_count;
+-    }
+-  return copied;
+-}
+diff --git a/io/copy_file_range.c b/io/copy_file_range.c
+index 98bff8bd2615b214..59fb979773b2b202 100644
+--- a/io/copy_file_range.c
++++ b/io/copy_file_range.c
+@@ -1,5 +1,5 @@
+-/* Generic implementation of copy_file_range.
+-   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++/* Stub implementation of copy_file_range.
++   Copyright (C) 2017-2019 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+@@ -16,7 +16,15 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#define COPY_FILE_RANGE_DECL
+-#define COPY_FILE_RANGE copy_file_range
++#include <errno.h>
++#include <unistd.h>
+ 
+-#include <io/copy_file_range-compat.c>
++ssize_t
++copy_file_range (int infd, __off64_t *pinoff,
++                 int outfd, __off64_t *poutoff,
++                 size_t length, unsigned int flags)
++{
++  __set_errno (ENOSYS);
++  return -1;
++}
++stub_warning (copy_file_range)
+diff --git a/io/tst-copy_file_range-compat.c b/io/tst-copy_file_range-compat.c
+deleted file mode 100644
+index 00c109a74d3c9d64..0000000000000000
+--- a/io/tst-copy_file_range-compat.c
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/* Test the fallback implementation of copy_file_range.
+-   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* Get the declaration of the official copy_of_range function.  */
+-#include <unistd.h>
+-
+-/* Compile a local version of copy_file_range.  */
+-#define COPY_FILE_RANGE_DECL static
+-#define COPY_FILE_RANGE copy_file_range_compat
+-#include <io/copy_file_range-compat.c>
+-
+-/* Re-use the test, but run it against copy_file_range_compat defined
+-   above.  */
+-#define copy_file_range copy_file_range_compat
+-#include "tst-copy_file_range.c"
+diff --git a/io/tst-copy_file_range.c b/io/tst-copy_file_range.c
+index 3d531a19370911e5..4504020d2ee7d2ee 100644
+--- a/io/tst-copy_file_range.c
++++ b/io/tst-copy_file_range.c
+@@ -20,22 +20,15 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <inttypes.h>
+-#include <libgen.h>
+-#include <poll.h>
+-#include <sched.h>
+ #include <stdbool.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <support/check.h>
+-#include <support/namespace.h>
+ #include <support/support.h>
+ #include <support/temp_file.h>
+ #include <support/test-driver.h>
+ #include <support/xunistd.h>
+-#ifdef CLONE_NEWNS
+-# include <sys/mount.h>
+-#endif
+ 
+ /* Boolean flags which indicate whether to use pointers with explicit
+    output flags.  */
+@@ -49,10 +42,6 @@ static int infd;
+ static char *outfile;
+ static int outfd;
+ 
+-/* Like the above, but on a different file system.  xdevfile can be
+-   NULL if no suitable file system has been found.  */
+-static char *xdevfile;
+-
+ /* Input and output offsets.  Set according to do_inoff and do_outoff
+    before the test.  The offsets themselves are always set to
+    zero.  */
+@@ -61,13 +50,10 @@ static off64_t *pinoff;
+ static off64_t outoff;
+ static off64_t *poutoff;
+ 
+-/* These are a collection of copy sizes used in tests.  The selection
+-   takes into account that the fallback implementation uses an
+-   internal buffer of 8192 bytes.  */
++/* These are a collection of copy sizes used in tests.    */
+ enum { maximum_size = 99999 };
+ static const int typical_sizes[] =
+-  { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, 16383, 16384, 16385,
+-    maximum_size };
++  { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, maximum_size };
+ 
+ /* The random contents of this array can be used as a pattern to check
+    for correct write operations.  */
+@@ -76,101 +62,6 @@ static unsigned char random_data[maximum_size];
+ /* The size chosen by the test harness.  */
+ static int current_size;
+ 
+-/* Maximum writable file offset.  Updated by find_maximum_offset
+-   below.  */
+-static off64_t maximum_offset;
+-
+-/* Error code when crossing the offset.  */
+-static int maximum_offset_errno;
+-
+-/* If true: Writes which cross the limit will fail.  If false: Writes
+-   which cross the limit will result in a partial write.  */
+-static bool maximum_offset_hard_limit;
+-
+-/* Fills maximum_offset etc. above.  Truncates outfd as a side
+-   effect.  */
+-static void
+-find_maximum_offset (void)
+-{
+-  xftruncate (outfd, 0);
+-  if (maximum_offset != 0)
+-    return;
+-
+-  uint64_t upper = -1;
+-  upper >>= 1;                  /* Maximum of off64_t.  */
+-  TEST_VERIFY ((off64_t) upper > 0);
+-  TEST_VERIFY ((off64_t) (upper + 1) < 0);
+-  if (lseek64 (outfd, upper, SEEK_SET) >= 0)
+-    {
+-      if (write (outfd, "", 1) == 1)
+-        FAIL_EXIT1 ("created a file larger than the off64_t range");
+-    }
+-
+-  uint64_t lower = 1024 * 1024; /* A reasonable minimum file size.  */
+-  /* Loop invariant: writing at lower succeeds, writing at upper fails.  */
+-  while (lower + 1 < upper)
+-    {
+-      uint64_t middle = (lower + upper) / 2;
+-      if (test_verbose > 0)
+-        printf ("info: %s: remaining test range %" PRIu64 " .. %" PRIu64
+-                ", probe at %" PRIu64 "\n", __func__, lower, upper, middle);
+-      xftruncate (outfd, 0);
+-      if (lseek64 (outfd, middle, SEEK_SET) >= 0
+-          && write (outfd, "", 1) == 1)
+-        lower = middle;
+-      else
+-        upper = middle;
+-    }
+-  TEST_VERIFY (lower + 1 == upper);
+-  maximum_offset = lower;
+-  printf ("info: maximum writable file offset: %" PRIu64 " (%" PRIx64 ")\n",
+-          lower, lower);
+-
+-  /* Check that writing at the valid offset actually works.  */
+-  xftruncate (outfd, 0);
+-  xlseek (outfd, lower, SEEK_SET);
+-  TEST_COMPARE (write (outfd, "", 1), 1);
+-
+-  /* Cross the boundary with a two-byte write.  This can either result
+-     in a short write, or a failure.  */
+-  xlseek (outfd, lower, SEEK_SET);
+-  ssize_t ret = write (outfd, " ", 2);
+-  if (ret < 0)
+-    {
+-      maximum_offset_errno = errno;
+-      maximum_offset_hard_limit = true;
+-    }
+-  else
+-    maximum_offset_hard_limit = false;
+-
+-  /* Check that writing at the next offset actually fails.  This also
+-     obtains the expected errno value.  */
+-  xftruncate (outfd, 0);
+-  const char *action;
+-  if (lseek64 (outfd, lower + 1, SEEK_SET) != 0)
+-    {
+-      if (write (outfd, "", 1) != -1)
+-        FAIL_EXIT1 ("write to impossible offset %" PRIu64 " succeeded",
+-                    lower + 1);
+-      action = "writing";
+-      int errno_copy = errno;
+-      if (maximum_offset_hard_limit)
+-        TEST_COMPARE (errno_copy, maximum_offset_errno);
+-      else
+-        maximum_offset_errno = errno_copy;
+-    }
+-  else
+-    {
+-      action = "seeking";
+-      maximum_offset_errno = errno;
+-    }
+-  printf ("info: %s out of range fails with %m (%d)\n",
+-          action, maximum_offset_errno);
+-
+-  xftruncate (outfd, 0);
+-  xlseek (outfd, 0, SEEK_SET);
+-}
+-
+ /* Perform a copy of a file.  */
+ static void
+ simple_file_copy (void)
+@@ -247,390 +138,6 @@ simple_file_copy (void)
+   free (bytes);
+ }
+ 
+-/* Test that reading from a pipe willfails.  */
+-static void
+-pipe_as_source (void)
+-{
+-  int pipefds[2];
+-  xpipe (pipefds);
+-
+-  for (int length = 0; length < 2; ++length)
+-    {
+-      if (test_verbose > 0)
+-        printf ("info: %s: length=%d\n", __func__, length);
+-
+-      /* Make sure that there is something to copy in the pipe.  */
+-      xwrite (pipefds[1], "@", 1);
+-
+-      TEST_COMPARE (copy_file_range (pipefds[0], pinoff, outfd, poutoff,
+-                                     length, 0), -1);
+-      /* Linux 4.10 and later return EINVAL.  Older kernels return
+-         EXDEV.  */
+-      TEST_VERIFY (errno == EINVAL || errno == EXDEV);
+-      TEST_COMPARE (inoff, 0);
+-      TEST_COMPARE (outoff, 0);
+-      TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 0);
+-
+-      /* Make sure that nothing was read.  */
+-      char buf = 'A';
+-      TEST_COMPARE (read (pipefds[0], &buf, 1), 1);
+-      TEST_COMPARE (buf, '@');
+-    }
+-
+-  xclose (pipefds[0]);
+-  xclose (pipefds[1]);
+-}
+-
+-/* Test that writing to a pipe fails.  */
+-static void
+-pipe_as_destination (void)
+-{
+-  /* Make sure that there is something to read in the input file.  */
+-  xwrite (infd, "abc", 3);
+-  xlseek (infd, 0, SEEK_SET);
+-
+-  int pipefds[2];
+-  xpipe (pipefds);
+-
+-  for (int length = 0; length < 2; ++length)
+-    {
+-      if (test_verbose > 0)
+-        printf ("info: %s: length=%d\n", __func__, length);
+-
+-      TEST_COMPARE (copy_file_range (infd, pinoff, pipefds[1], poutoff,
+-                                     length, 0), -1);
+-      /* Linux 4.10 and later return EINVAL.  Older kernels return
+-         EXDEV.  */
+-      TEST_VERIFY (errno == EINVAL || errno == EXDEV);
+-      TEST_COMPARE (inoff, 0);
+-      TEST_COMPARE (outoff, 0);
+-      TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
+-
+-      /* Make sure that nothing was written.  */
+-      struct pollfd pollfd = { .fd = pipefds[0], .events = POLLIN, };
+-      TEST_COMPARE (poll (&pollfd, 1, 0), 0);
+-    }
+-
+-  xclose (pipefds[0]);
+-  xclose (pipefds[1]);
+-}
+-
+-/* Test a write failure after (potentially) writing some bytes.
+-   Failure occurs near the start of the buffer.  */
+-static void
+-delayed_write_failure_beginning (void)
+-{
+-  /* We need to write something to provoke the error.  */
+-  if (current_size == 0)
+-    return;
+-  xwrite (infd, random_data, sizeof (random_data));
+-  xlseek (infd, 0, SEEK_SET);
+-
+-  /* Write failure near the start.  The actual error code varies among
+-     file systems.  */
+-  find_maximum_offset ();
+-  off64_t where = maximum_offset;
+-
+-  if (current_size == 1)
+-    ++where;
+-  outoff = where;
+-  if (do_outoff)
+-    xlseek (outfd, 1, SEEK_SET);
+-  else
+-    xlseek (outfd, where, SEEK_SET);
+-  if (maximum_offset_hard_limit || where > maximum_offset)
+-    {
+-      TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
+-                                     sizeof (random_data), 0), -1);
+-      TEST_COMPARE (errno, maximum_offset_errno);
+-      TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
+-      TEST_COMPARE (inoff, 0);
+-      if (do_outoff)
+-        TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1);
+-      else
+-        TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where);
+-      TEST_COMPARE (outoff, where);
+-      struct stat64 st;
+-      xfstat (outfd, &st);
+-      TEST_COMPARE (st.st_size, 0);
+-    }
+-  else
+-    {
+-      /* The offset is not a hard limit.  This means we write one
+-         byte.  */
+-      TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
+-                                     sizeof (random_data), 0), 1);
+-      if (do_inoff)
+-        {
+-          TEST_COMPARE (inoff, 1);
+-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
+-        }
+-      else
+-        {
+-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 1);
+-          TEST_COMPARE (inoff, 0);
+-        }
+-      if (do_outoff)
+-        {
+-          TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1);
+-          TEST_COMPARE (outoff, where + 1);
+-        }
+-      else
+-        {
+-          TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where + 1);
+-          TEST_COMPARE (outoff, where);
+-        }
+-      struct stat64 st;
+-      xfstat (outfd, &st);
+-      TEST_COMPARE (st.st_size, where + 1);
+-    }
+-}
+-
+-/* Test a write failure after (potentially) writing some bytes.
+-   Failure occurs near the end of the buffer.  */
+-static void
+-delayed_write_failure_end (void)
+-{
+-  if (current_size <= 1)
+-    /* This would be same as the first test because there is not
+-       enough data to write to make a difference.  */
+-    return;
+-  xwrite (infd, random_data, sizeof (random_data));
+-  xlseek (infd, 0, SEEK_SET);
+-
+-  find_maximum_offset ();
+-  off64_t where = maximum_offset - current_size + 1;
+-  if (current_size == sizeof (random_data))
+-    /* Otherwise we do not reach the non-writable byte.  */
+-    ++where;
+-  outoff = where;
+-  if (do_outoff)
+-    xlseek (outfd, 1, SEEK_SET);
+-  else
+-    xlseek (outfd, where, SEEK_SET);
+-  ssize_t ret = copy_file_range (infd, pinoff, outfd, poutoff,
+-                                 sizeof (random_data), 0);
+-  if (ret < 0)
+-    {
+-      TEST_COMPARE (ret, -1);
+-      TEST_COMPARE (errno, maximum_offset_errno);
+-      struct stat64 st;
+-      xfstat (outfd, &st);
+-      TEST_COMPARE (st.st_size, 0);
+-    }
+-  else
+-    {
+-      /* The first copy succeeded.  This happens in the emulation
+-         because the internal buffer of limited size does not
+-         necessarily cross the off64_t boundary on the first write
+-         operation.  */
+-      if (test_verbose > 0)
+-        printf ("info:   copy_file_range (%zu) returned %zd\n",
+-                sizeof (random_data), ret);
+-      TEST_VERIFY (ret > 0);
+-      TEST_VERIFY (ret < maximum_size);
+-      struct stat64 st;
+-      xfstat (outfd, &st);
+-      TEST_COMPARE (st.st_size, where + ret);
+-      if (do_inoff)
+-        {
+-          TEST_COMPARE (inoff, ret);
+-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
+-        }
+-      else
+-          TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), ret);
+-
+-      char *buffer = xmalloc (ret);
+-      TEST_COMPARE (pread64 (outfd, buffer, ret, where), ret);
+-      TEST_VERIFY (memcmp (buffer, random_data, ret) == 0);
+-      free (buffer);
+-
+-      /* The second copy fails.  */
+-      TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
+-                                     sizeof (random_data), 0), -1);
+-      TEST_COMPARE (errno, maximum_offset_errno);
+-    }
+-}
+-
+-/* Test a write failure across devices.  */
+-static void
+-cross_device_failure (void)
+-{
+-  if (xdevfile == NULL)
+-    /* Subtest not supported due to missing cross-device file.  */
+-    return;
+-
+-  /* We need something to write.  */
+-  xwrite (infd, random_data, sizeof (random_data));
+-  xlseek (infd, 0, SEEK_SET);
+-
+-  int xdevfd = xopen (xdevfile, O_RDWR | O_LARGEFILE, 0);
+-  TEST_COMPARE (copy_file_range (infd, pinoff, xdevfd, poutoff,
+-                                 current_size, 0), -1);
+-  TEST_COMPARE (errno, EXDEV);
+-  TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0);
+-  struct stat64 st;
+-  xfstat (xdevfd, &st);
+-  TEST_COMPARE (st.st_size, 0);
+-
+-  xclose (xdevfd);
+-}
+-
+-/* Try to exercise ENOSPC behavior with a tempfs file system (so that
+-   we do not have to fill up a regular file system to get the error).
+-   This function runs in a subprocess, so that we do not change the
+-   mount namespace of the actual test process.  */
+-static void
+-enospc_failure_1 (void *closure)
+-{
+-#ifdef CLONE_NEWNS
+-  support_become_root ();
+-
+-  /* Make sure that we do not alter the file system mounts of the
+-     parents.  */
+-  if (! support_enter_mount_namespace ())
+-    {
+-      printf ("warning: ENOSPC test skipped\n");
+-      return;
+-    }
+-
+-  char *mountpoint = closure;
+-  if (mount ("none", mountpoint, "tmpfs", MS_NODEV | MS_NOEXEC,
+-             "size=500k") != 0)
+-    {
+-      printf ("warning: could not mount tmpfs at %s: %m\n", mountpoint);
+-      return;
+-    }
+-
+-  /* The source file must reside on the same file system.  */
+-  char *intmpfsfile = xasprintf ("%s/%s", mountpoint, "in");
+-  int intmpfsfd = xopen (intmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600);
+-  xwrite (intmpfsfd, random_data, sizeof (random_data));
+-  xlseek (intmpfsfd, 1, SEEK_SET);
+-  inoff = 1;
+-
+-  char *outtmpfsfile = xasprintf ("%s/%s", mountpoint, "out");
+-  int outtmpfsfd = xopen (outtmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600);
+-
+-  /* Fill the file with data until ENOSPC is reached.  */
+-  while (true)
+-    {
+-      ssize_t ret = write (outtmpfsfd, random_data, sizeof (random_data));
+-      if (ret < 0 && errno != ENOSPC)
+-        FAIL_EXIT1 ("write to %s: %m", outtmpfsfile);
+-      if (ret < sizeof (random_data))
+-        break;
+-    }
+-  TEST_COMPARE (write (outtmpfsfd, "", 1), -1);
+-  TEST_COMPARE (errno, ENOSPC);
+-  off64_t maxsize = xlseek (outtmpfsfd, 0, SEEK_CUR);
+-  TEST_VERIFY_EXIT (maxsize > sizeof (random_data));
+-
+-  /* Constructed the expected file contents.  */
+-  char *expected = xmalloc (maxsize);
+-  TEST_COMPARE (pread64 (outtmpfsfd, expected, maxsize, 0), maxsize);
+-  /* Go back a little, so some bytes can be written.  */
+-  enum { offset = 20000 };
+-  TEST_VERIFY_EXIT (offset < maxsize);
+-  TEST_VERIFY_EXIT (offset < sizeof (random_data));
+-  memcpy (expected + maxsize - offset, random_data + 1, offset);
+-
+-  if (do_outoff)
+-    {
+-      outoff = maxsize - offset;
+-      xlseek (outtmpfsfd, 2, SEEK_SET);
+-    }
+-  else
+-    xlseek (outtmpfsfd, -offset, SEEK_CUR);
+-
+-  /* First call is expected to succeed because we made room for some
+-     bytes.  */
+-  TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff,
+-                                 maximum_size, 0), offset);
+-  if (do_inoff)
+-    {
+-      TEST_COMPARE (inoff, 1 + offset);
+-      TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1);
+-    }
+-  else
+-      TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset);
+-  if (do_outoff)
+-    {
+-      TEST_COMPARE (outoff, maxsize);
+-      TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2);
+-    }
+-  else
+-    TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize);
+-  struct stat64 st;
+-  xfstat (outtmpfsfd, &st);
+-  TEST_COMPARE (st.st_size, maxsize);
+-  char *actual = xmalloc (st.st_size);
+-  TEST_COMPARE (pread64 (outtmpfsfd, actual, st.st_size, 0), st.st_size);
+-  TEST_VERIFY (memcmp (expected, actual, maxsize) == 0);
+-
+-  /* Second call should fail with ENOSPC.  */
+-  TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff,
+-                                 maximum_size, 0), -1);
+-  TEST_COMPARE (errno, ENOSPC);
+-
+-  /* Offsets should be unchanged.  */
+-  if (do_inoff)
+-    {
+-      TEST_COMPARE (inoff, 1 + offset);
+-      TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1);
+-    }
+-  else
+-    TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset);
+-  if (do_outoff)
+-    {
+-      TEST_COMPARE (outoff, maxsize);
+-      TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2);
+-    }
+-  else
+-    TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize);
+-  TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_END), maxsize);
+-  TEST_COMPARE (pread64 (outtmpfsfd, actual, maxsize, 0), maxsize);
+-  TEST_VERIFY (memcmp (expected, actual, maxsize) == 0);
+-
+-  free (actual);
+-  free (expected);
+-
+-  xclose (intmpfsfd);
+-  xclose (outtmpfsfd);
+-  free (intmpfsfile);
+-  free (outtmpfsfile);
+-
+-#else /* !CLONE_NEWNS */
+-  puts ("warning: ENOSPC test skipped (no mount namespaces)");
+-#endif
+-}
+-
+-/* Call enospc_failure_1 in a subprocess.  */
+-static void
+-enospc_failure (void)
+-{
+-  char *mountpoint
+-    = support_create_temp_directory ("tst-copy_file_range-enospc-");
+-  support_isolate_in_subprocess (enospc_failure_1, mountpoint);
+-  free (mountpoint);
+-}
+-
+-/* The target file descriptor must have O_APPEND enabled.  */
+-static void
+-oappend_failure (void)
+-{
+-  /* Add data, to make sure we do not fail because there is
+-     insufficient input data.  */
+-  xwrite (infd, random_data, current_size);
+-  xlseek (infd, 0, SEEK_SET);
+-
+-  xclose (outfd);
+-  outfd = xopen (outfile, O_RDWR | O_APPEND, 0);
+-  TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff,
+-                                 current_size, 0), -1);
+-  TEST_COMPARE (errno, EBADF);
+-}
+-
+ /* Test that a short input file results in a shortened copy.  */
+ static void
+ short_copy (void)
+@@ -721,14 +228,6 @@ struct test_case
+ static struct test_case tests[] =
+   {
+     { "simple_file_copy", simple_file_copy, .sizes = true },
+-    { "pipe_as_source", pipe_as_source, },
+-    { "pipe_as_destination", pipe_as_destination, },
+-    { "delayed_write_failure_beginning", delayed_write_failure_beginning,
+-      .sizes = true },
+-    { "delayed_write_failure_end", delayed_write_failure_end, .sizes = true },
+-    { "cross_device_failure", cross_device_failure, .sizes = true },
+-    { "enospc_failure", enospc_failure, },
+-    { "oappend_failure", oappend_failure, .sizes = true },
+     { "short_copy", short_copy, .sizes = true },
+   };
+ 
+@@ -739,53 +238,18 @@ do_test (void)
+     *p = rand () >> 24;
+ 
+   infd = create_temp_file ("tst-copy_file_range-in-", &infile);
+-  xclose (create_temp_file ("tst-copy_file_range-out-", &outfile));
+-
+-  /* Try to find a different directory from the default input/output
+-     file.  */
++  outfd = create_temp_file ("tst-copy_file_range-out-", &outfile);
+   {
+-    struct stat64 instat;
+-    xfstat (infd, &instat);
+-    static const char *const candidates[] =
+-      { NULL, "/var/tmp", "/dev/shm" };
+-    for (const char *const *c = candidates; c < array_end (candidates); ++c)
+-      {
+-        const char *path = *c;
+-        char *to_free = NULL;
+-        if (path == NULL)
+-          {
+-            to_free = xreadlink ("/proc/self/exe");
+-            path = dirname (to_free);
+-          }
+-
+-        struct stat64 cstat;
+-        xstat (path, &cstat);
+-        if (cstat.st_dev == instat.st_dev)
+-          {
+-            free (to_free);
+-            continue;
+-          }
+-
+-        printf ("info: using alternate temporary files directory: %s\n", path);
+-        xdevfile = xasprintf ("%s/tst-copy_file_range-xdev-XXXXXX", path);
+-        free (to_free);
+-        break;
+-      }
+-    if (xdevfile != NULL)
++    ssize_t ret = copy_file_range (infd, NULL, outfd, NULL, 0, 0);
++    if (ret != 0)
+       {
+-        int xdevfd = mkstemp (xdevfile);
+-        if (xdevfd < 0)
+-          FAIL_EXIT1 ("mkstemp (\"%s\"): %m", xdevfile);
+-        struct stat64 xdevst;
+-        xfstat (xdevfd, &xdevst);
+-        TEST_VERIFY (xdevst.st_dev != instat.st_dev);
+-        add_temp_file (xdevfile);
+-        xclose (xdevfd);
++        if (errno == ENOSYS)
++          FAIL_UNSUPPORTED ("copy_file_range is not support on this system");
++        FAIL_EXIT1 ("copy_file_range probing call: %m");
+       }
+-    else
+-      puts ("warning: no alternate directory on different file system found");
+   }
+   xclose (infd);
++  xclose (outfd);
+ 
+   for (do_inoff = 0; do_inoff < 2; ++do_inoff)
+     for (do_outoff = 0; do_outoff < 2; ++do_outoff)
+@@ -827,7 +291,6 @@ do_test (void)
+ 
+   free (infile);
+   free (outfile);
+-  free (xdevfile);
+ 
+   return 0;
+ }
+diff --git a/manual/llio.texi b/manual/llio.texi
+index 2733b9cb7331df07..26f7d2cb3ea220d9 100644
+--- a/manual/llio.texi
++++ b/manual/llio.texi
+@@ -1404,10 +1404,13 @@ failure occurs.  The return value is zero if the end of the input file
+ is encountered immediately.
+ 
+ If no bytes can be copied, to report an error, @code{copy_file_range}
+-returns the value @math{-1} and sets @code{errno}.  The following
+-@code{errno} error conditions are specific to this function:
++returns the value @math{-1} and sets @code{errno}.  The table below
++lists some of the error conditions for this function.
+ 
+ @table @code
++@item ENOSYS
++The kernel does not implement the required functionality.
++
+ @item EISDIR
+ At least one of the descriptors @var{inputfd} or @var{outputfd} refers
+ to a directory.
+@@ -1437,9 +1440,6 @@ reading.
+ 
+ The argument @var{outputfd} is not a valid file descriptor open for
+ writing, or @var{outputfd} has been opened with @code{O_APPEND}.
+-
+-@item EXDEV
+-The input and output files reside on different file systems.
+ @end table
+ 
+ In addition, @code{copy_file_range} can fail with the error codes
+diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h
+index 402d2573d75794d5..26344cd610a1f8e7 100644
+--- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h
++++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h
+@@ -48,7 +48,6 @@
+ /* Support for copy_file_range, statx was added in kernel 4.13.  */
+ #if __LINUX_KERNEL_VERSION < 0x040D00
+ # undef __ASSUME_MLOCK2
+-# undef __ASSUME_COPY_FILE_RANGE
+ # undef __ASSUME_STATX
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/copy_file_range.c b/sysdeps/unix/sysv/linux/copy_file_range.c
+index 7b1a50f7529f2a84..b88b7c9e2ecd825f 100644
+--- a/sysdeps/unix/sysv/linux/copy_file_range.c
++++ b/sysdeps/unix/sysv/linux/copy_file_range.c
+@@ -20,27 +20,16 @@
+ #include <sysdep-cancel.h>
+ #include <unistd.h>
+ 
+-/* Include the fallback implementation.  */
+-#ifndef __ASSUME_COPY_FILE_RANGE
+-#define COPY_FILE_RANGE_DECL static
+-#define COPY_FILE_RANGE copy_file_range_compat
+-#include <io/copy_file_range-compat.c>
+-#endif
+-
+ ssize_t
+ copy_file_range (int infd, __off64_t *pinoff,
+                  int outfd, __off64_t *poutoff,
+                  size_t length, unsigned int flags)
+ {
+ #ifdef __NR_copy_file_range
+-  ssize_t ret = SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff,
+-                                length, flags);
+-# ifndef __ASSUME_COPY_FILE_RANGE
+-  if (ret == -1 && errno == ENOSYS)
+-    ret = copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags);
+-# endif
+-  return ret;
+-#else  /* !__NR_copy_file_range */
+-  return copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags);
++  return SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff,
++                         length, flags);
++#else
++  __set_errno (ENOSYS);
++  return -1;
+ #endif
+ }
+diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
+index 5543d92d7e32e501..7a74835495250268 100644
+--- a/sysdeps/unix/sysv/linux/kernel-features.h
++++ b/sysdeps/unix/sysv/linux/kernel-features.h
+@@ -111,10 +111,6 @@
+ # define __ASSUME_MLOCK2 1
+ #endif
+ 
+-#if __LINUX_KERNEL_VERSION >= 0x040500
+-# define __ASSUME_COPY_FILE_RANGE 1
+-#endif
+-
+ /* Support for statx was added in kernel 4.11.  */
+ #if __LINUX_KERNEL_VERSION >= 0x040B00
+ # define __ASSUME_STATX 1
+diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
+index e8e2ac6a873126ac..1c49f099b7993f1d 100644
+--- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
++++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h
+@@ -58,11 +58,6 @@
+ # undef __ASSUME_EXECVEAT
+ #endif
+ 
+-/* Support for the copy_file_range syscall was added in 4.10.  */
+-#if __LINUX_KERNEL_VERSION < 0x040A00
+-# undef __ASSUME_COPY_FILE_RANGE
+-#endif
+-
+ /* Support for statx was added in kernel 4.12.  */
+ #if __LINUX_KERNEL_VERSION < 0X040C00
+ # undef __ASSUME_STATX
diff --git a/SOURCES/glibc-rh1727152.patch b/SOURCES/glibc-rh1727152.patch
new file mode 100644
index 0000000..8a5ed92
--- /dev/null
+++ b/SOURCES/glibc-rh1727152.patch
@@ -0,0 +1,22 @@
+commit 61595e3d36ded374f97961503e843a314b0203c2
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Tue May 15 14:42:37 2018 +0200
+
+    nscd: avoid assertion failure during persistent db check
+    
+    nscd should not abort when it finds inconsistencies in the persistent db.
+
+diff --git a/nscd/connections.c b/nscd/connections.c
+index 47fbb9923aa2aac7..98182007646a33d5 100644
+--- a/nscd/connections.c
++++ b/nscd/connections.c
+@@ -304,7 +304,8 @@ static int
+ check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
+ 	   enum usekey use, ref_t start, size_t len)
+ {
+-  assert (len >= 2);
++  if (len < 2)
++    return 0;
+ 
+   if (start > first_free || start + len > first_free
+       || (start & BLOCK_ALIGN_M1))
diff --git a/SOURCES/glibc-rh1727241-1.patch b/SOURCES/glibc-rh1727241-1.patch
new file mode 100644
index 0000000..5842b08
--- /dev/null
+++ b/SOURCES/glibc-rh1727241-1.patch
@@ -0,0 +1,221 @@
+commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 21 08:59:42 2019 +0100
+
+    resolv: Reformat inet_addr, inet_aton to GNU style
+
+diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
+index 022f7ea0841b6bae..32f58b0e13598b32 100644
+--- a/resolv/inet_addr.c
++++ b/resolv/inet_addr.c
+@@ -1,3 +1,21 @@
++/* Legacy IPv4 text-to-address functions.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
+ /*
+  * Copyright (c) 1983, 1990, 1993
+  *    The Regents of the University of California.  All rights reserved.
+@@ -78,105 +96,97 @@
+ #include <limits.h>
+ #include <errno.h>
+ 
+-/*
+- * Ascii internet address interpretation routine.
+- * The value returned is in network order.
+- */
++/* ASCII IPv4 Internet address interpretation routine.  The value
++   returned is in network order.  */
+ in_addr_t
+-__inet_addr(const char *cp) {
+-	struct in_addr val;
++__inet_addr (const char *cp)
++{
++  struct in_addr val;
+ 
+-	if (__inet_aton(cp, &val))
+-		return (val.s_addr);
+-	return (INADDR_NONE);
++  if (__inet_aton (cp, &val))
++    return val.s_addr;
++  return INADDR_NONE;
+ }
+ weak_alias (__inet_addr, inet_addr)
+ 
+-/*
+- * Check whether "cp" is a valid ascii representation
+- * of an Internet address and convert to a binary address.
+- * Returns 1 if the address is valid, 0 if not.
+- * This replaces inet_addr, the return value from which
+- * cannot distinguish between failure and a local broadcast address.
+- */
++/* Check whether "cp" is a valid ASCII representation of an IPv4
++   Internet address and convert it to a binary address.  Returns 1 if
++   the address is valid, 0 if not.  This replaces inet_addr, the
++   return value from which cannot distinguish between failure and a
++   local broadcast address.  */
+ int
+-__inet_aton(const char *cp, struct in_addr *addr)
++__inet_aton (const char *cp, struct in_addr *addr)
+ {
+-	static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
+-	in_addr_t val;
+-	char c;
+-	union iaddr {
+-	  uint8_t bytes[4];
+-	  uint32_t word;
+-	} res;
+-	uint8_t *pp = res.bytes;
+-	int digit;
+-
+-	int saved_errno = errno;
+-	__set_errno (0);
+-
+-	res.word = 0;
+-
+-	c = *cp;
+-	for (;;) {
+-		/*
+-		 * Collect number up to ``.''.
+-		 * Values are specified as for C:
+-		 * 0x=hex, 0=octal, isdigit=decimal.
+-		 */
+-		if (!isdigit(c))
+-			goto ret_0;
+-		{
+-			char *endp;
+-			unsigned long ul = strtoul (cp, (char **) &endp, 0);
+-			if (ul == ULONG_MAX && errno == ERANGE)
+-				goto ret_0;
+-			if (ul > 0xfffffffful)
+-				goto ret_0;
+-			val = ul;
+-			digit = cp != endp;
+-			cp = endp;
+-		}
+-		c = *cp;
+-		if (c == '.') {
+-			/*
+-			 * Internet format:
+-			 *	a.b.c.d
+-			 *	a.b.c	(with c treated as 16 bits)
+-			 *	a.b	(with b treated as 24 bits)
+-			 */
+-			if (pp > res.bytes + 2 || val > 0xff)
+-				goto ret_0;
+-			*pp++ = val;
+-			c = *++cp;
+-		} else
+-			break;
+-	}
+-	/*
+-	 * Check for trailing characters.
+-	 */
+-	if (c != '\0' && (!isascii(c) || !isspace(c)))
+-		goto ret_0;
+-	/*
+-	 * Did we get a valid digit?
+-	 */
+-	if (!digit)
+-		goto ret_0;
+-
+-	/* Check whether the last part is in its limits depending on
+-	   the number of parts in total.  */
+-	if (val > max[pp - res.bytes])
++  static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
++  in_addr_t val;
++  char c;
++  union iaddr
++  {
++    uint8_t bytes[4];
++    uint32_t word;
++  } res;
++  uint8_t *pp = res.bytes;
++  int digit;
++
++  int saved_errno = errno;
++  __set_errno (0);
++
++  res.word = 0;
++
++  c = *cp;
++  for (;;)
++    {
++      /* Collect number up to ``.''.  Values are specified as for C:
++	 0x=hex, 0=octal, isdigit=decimal.  */
++      if (!isdigit (c))
++	goto ret_0;
++      {
++	char *endp;
++	unsigned long ul = strtoul (cp, &endp, 0);
++	if (ul == ULONG_MAX && errno == ERANGE)
+ 	  goto ret_0;
+-
+-	if (addr != NULL)
+-		addr->s_addr = res.word | htonl (val);
+-
+-	__set_errno (saved_errno);
+-	return (1);
+-
+-ret_0:
+-	__set_errno (saved_errno);
+-	return (0);
++	if (ul > 0xfffffffful)
++	  goto ret_0;
++	val = ul;
++	digit = cp != endp;
++	cp = endp;
++      }
++      c = *cp;
++      if (c == '.')
++	{
++	  /* Internet format:
++	     a.b.c.d
++	     a.b.c	(with c treated as 16 bits)
++	     a.b	(with b treated as 24 bits).  */
++	  if (pp > res.bytes + 2 || val > 0xff)
++	    goto ret_0;
++	  *pp++ = val;
++	  c = *++cp;
++	}
++      else
++	break;
++    }
++  /* Check for trailing characters.  */
++  if (c != '\0' && (!isascii (c) || !isspace (c)))
++    goto ret_0;
++  /*  Did we get a valid digit?  */
++  if (!digit)
++    goto ret_0;
++
++  /* Check whether the last part is in its limits depending on the
++     number of parts in total.  */
++  if (val > max[pp - res.bytes])
++    goto ret_0;
++
++  if (addr != NULL)
++    addr->s_addr = res.word | htonl (val);
++
++  __set_errno (saved_errno);
++  return 1;
++
++ ret_0:
++  __set_errno (saved_errno);
++  return 0;
+ }
+ weak_alias (__inet_aton, inet_aton)
+ libc_hidden_def (__inet_aton)
diff --git a/SOURCES/glibc-rh1727241-2.patch b/SOURCES/glibc-rh1727241-2.patch
new file mode 100644
index 0000000..7f9f417
--- /dev/null
+++ b/SOURCES/glibc-rh1727241-2.patch
@@ -0,0 +1,80 @@
+commit 6ca53a2453598804a2559a548a08424fca96434a
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 21 09:26:41 2019 +0100
+
+    resolv: Do not send queries for non-host-names in nss_dns [BZ #24112]
+    
+    Before this commit, nss_dns would send a query which did not contain a
+    host name as the query name (such as invalid\032name.example.com) and
+    then reject the answer in getanswer_r and gaih_getanswer_slice, using
+    a check based on res_hnok.  With this commit, no query is sent, and a
+    host-not-found error is returned to NSS without network interaction.
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index 5dc2829cd148a568..99c3b61e1cee4d42 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -274,11 +274,26 @@ gethostbyname3_context (struct resolv_context *ctx,
+   return status;
+ }
+ 
++/* Verify that the name looks like a host name.  There is no point in
++   sending a query which will not produce a usable name in the
++   response.  */
++static enum nss_status
++check_name (const char *name, int *h_errnop)
++{
++  if (res_hnok (name))
++    return NSS_STATUS_SUCCESS;
++  *h_errnop = HOST_NOT_FOUND;
++  return NSS_STATUS_NOTFOUND;
++}
++
+ enum nss_status
+ _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
+ 			   char *buffer, size_t buflen, int *errnop,
+ 			   int *h_errnop)
+ {
++  enum nss_status status = check_name (name, h_errnop);
++  if (status != NSS_STATUS_SUCCESS)
++    return status;
+   return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop,
+ 				    h_errnop, NULL, NULL);
+ }
+@@ -289,6 +304,9 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
+ 			  char *buffer, size_t buflen, int *errnop,
+ 			  int *h_errnop)
+ {
++  enum nss_status status = check_name (name, h_errnop);
++  if (status != NSS_STATUS_SUCCESS)
++    return status;
+   struct resolv_context *ctx = __resolv_context_get ();
+   if (ctx == NULL)
+     {
+@@ -296,7 +314,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
+       *h_errnop = NETDB_INTERNAL;
+       return NSS_STATUS_UNAVAIL;
+     }
+-  enum nss_status status = NSS_STATUS_NOTFOUND;
++  status = NSS_STATUS_NOTFOUND;
+   if (res_use_inet6 ())
+     status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer,
+ 				     buflen, errnop, h_errnop, NULL, NULL);
+@@ -313,6 +331,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+ 			   char *buffer, size_t buflen, int *errnop,
+ 			   int *herrnop, int32_t *ttlp)
+ {
++  enum nss_status status = check_name (name, herrnop);
++  if (status != NSS_STATUS_SUCCESS)
++    return status;
+   struct resolv_context *ctx = __resolv_context_get ();
+   if (ctx == NULL)
+     {
+@@ -347,7 +368,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+   int ans2p_malloced = 0;
+ 
+   int olderr = errno;
+-  enum nss_status status;
+   int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
+ 				host_buffer.buf->buf, 2048, &host_buffer.ptr,
+ 				&ans2p, &nans2p, &resplen2, &ans2p_malloced);
diff --git a/SOURCES/glibc-rh1727241-3.patch b/SOURCES/glibc-rh1727241-3.patch
new file mode 100644
index 0000000..f578ebd
--- /dev/null
+++ b/SOURCES/glibc-rh1727241-3.patch
@@ -0,0 +1,698 @@
+commit 108bc4049f8ae82710aec26a92ffdb4b439c83fd
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 21 21:26:03 2019 +0100
+
+    CVE-2016-10739: getaddrinfo: Fully parse IPv4 address strings [BZ #20018]
+    
+    The IPv4 address parser in the getaddrinfo function is changed so that
+    it does not ignore trailing whitespace and all characters after it.
+    For backwards compatibility, the getaddrinfo function still recognizes
+    legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8
+    (octal).
+    
+    This commit does not change the behavior of inet_addr and inet_aton.
+    gethostbyname already had additional sanity checks (but is switched
+    over to the new __inet_aton_exact function for completeness as well).
+    
+    To avoid sending the problematic query names over DNS, commit
+    6ca53a2453598804a2559a548a08424fca96434a ("resolv: Do not send queries
+    for non-host-names in nss_dns [BZ #24112]") is needed.
+
+diff --git a/include/arpa/inet.h b/include/arpa/inet.h
+index c3f28f2baaa2ed66..19aec74275069a45 100644
+--- a/include/arpa/inet.h
++++ b/include/arpa/inet.h
+@@ -1,10 +1,10 @@
+ #include <inet/arpa/inet.h>
+ 
+ #ifndef _ISOMAC
+-extern int __inet_aton (const char *__cp, struct in_addr *__inp);
+-libc_hidden_proto (__inet_aton)
++/* Variant of inet_aton which rejects trailing garbage.  */
++extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp);
++libc_hidden_proto (__inet_aton_exact)
+ 
+-libc_hidden_proto (inet_aton)
+ libc_hidden_proto (inet_ntop)
+ libc_hidden_proto (inet_pton)
+ extern __typeof (inet_pton) __inet_pton;
+diff --git a/nscd/gai.c b/nscd/gai.c
+index 24bdfee1db3791e2..f57f396f574a6e52 100644
+--- a/nscd/gai.c
++++ b/nscd/gai.c
+@@ -19,7 +19,6 @@
+ 
+ /* This file uses the getaddrinfo code but it compiles it without NSCD
+    support.  We just need a few symbol renames.  */
+-#define __inet_aton inet_aton
+ #define __ioctl ioctl
+ #define __getsockname getsockname
+ #define __socket socket
+diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c
+index 7beb9dce9f4b350c..f792c4fcd042d13d 100644
+--- a/nscd/gethstbynm3_r.c
++++ b/nscd/gethstbynm3_r.c
+@@ -38,8 +38,6 @@
+ #define HAVE_LOOKUP_BUFFER	1
+ #define HAVE_AF			1
+ 
+-#define __inet_aton inet_aton
+-
+ /* We are nscd, so we don't want to be talking to ourselves.  */
+ #undef	USE_NSCD
+ 
+diff --git a/nss/digits_dots.c b/nss/digits_dots.c
+index 39bff38865a1ac5b..5441bce16ea8b2e9 100644
+--- a/nss/digits_dots.c
++++ b/nss/digits_dots.c
+@@ -29,7 +29,6 @@
+ #include "nsswitch.h"
+ 
+ #ifdef USE_NSCD
+-# define inet_aton __inet_aton
+ # include <nscd/nscd_proto.h>
+ #endif
+ 
+@@ -160,7 +159,7 @@ __nss_hostname_digits_dots_context (struct resolv_context *ctx,
+ 		     255.255.255.255?  The test below will succeed
+ 		     spuriously... ???  */
+ 		  if (af == AF_INET)
+-		    ok = __inet_aton (name, (struct in_addr *) host_addr);
++		    ok = __inet_aton_exact (name, (struct in_addr *) host_addr);
+ 		  else
+ 		    {
+ 		      assert (af == AF_INET6);
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 56718654eeab85a3..72a0f196506ac489 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -34,6 +34,9 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
+ tests = tst-aton tst-leaks tst-inet_ntop
+ xtests = tst-leaks2
+ 
++tests-internal += tst-inet_aton_exact
++
++
+ generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
+ 
+ extra-libs := libresolv libnss_dns
+@@ -54,8 +57,10 @@ tests += \
+   tst-resolv-binary \
+   tst-resolv-edns \
+   tst-resolv-network \
++  tst-resolv-nondecimal \
+   tst-resolv-res_init-multi \
+   tst-resolv-search \
++  tst-resolv-trailing \
+ 
+ # These tests need libdl.
+ ifeq (yes,$(build-shared))
+@@ -190,9 +195,11 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
+   $(shared-thread-library)
+ $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \
+   $(shared-thread-library)
++$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-threads: \
+   $(libdl) $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-canonname: \
+diff --git a/resolv/Versions b/resolv/Versions
+index b05778d9654aa0f2..9a82704af75f789b 100644
+--- a/resolv/Versions
++++ b/resolv/Versions
+@@ -27,6 +27,7 @@ libc {
+     __h_errno; __resp;
+ 
+     __res_iclose;
++    __inet_aton_exact;
+     __inet_pton_length;
+     __resolv_context_get;
+     __resolv_context_get_preinit;
+diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
+index 32f58b0e13598b32..41b6166a5bd5a44b 100644
+--- a/resolv/inet_addr.c
++++ b/resolv/inet_addr.c
+@@ -96,26 +96,14 @@
+ #include <limits.h>
+ #include <errno.h>
+ 
+-/* ASCII IPv4 Internet address interpretation routine.  The value
+-   returned is in network order.  */
+-in_addr_t
+-__inet_addr (const char *cp)
+-{
+-  struct in_addr val;
+-
+-  if (__inet_aton (cp, &val))
+-    return val.s_addr;
+-  return INADDR_NONE;
+-}
+-weak_alias (__inet_addr, inet_addr)
+-
+ /* Check whether "cp" is a valid ASCII representation of an IPv4
+    Internet address and convert it to a binary address.  Returns 1 if
+    the address is valid, 0 if not.  This replaces inet_addr, the
+    return value from which cannot distinguish between failure and a
+-   local broadcast address.  */
+-int
+-__inet_aton (const char *cp, struct in_addr *addr)
++   local broadcast address.  Write a pointer to the first
++   non-converted character to *endp.  */
++static int
++inet_aton_end (const char *cp, struct in_addr *addr, const char **endp)
+ {
+   static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
+   in_addr_t val;
+@@ -180,6 +168,7 @@ __inet_aton (const char *cp, struct in_addr *addr)
+ 
+   if (addr != NULL)
+     addr->s_addr = res.word | htonl (val);
++  *endp = cp;
+ 
+   __set_errno (saved_errno);
+   return 1;
+@@ -188,6 +177,41 @@ __inet_aton (const char *cp, struct in_addr *addr)
+   __set_errno (saved_errno);
+   return 0;
+ }
+-weak_alias (__inet_aton, inet_aton)
+-libc_hidden_def (__inet_aton)
+-libc_hidden_weak (inet_aton)
++
++int
++__inet_aton_exact (const char *cp, struct in_addr *addr)
++{
++  struct in_addr val;
++  const char *endp;
++  /* Check that inet_aton_end parsed the entire string.  */
++  if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0)
++    {
++      *addr = val;
++      return 1;
++    }
++  else
++    return 0;
++}
++libc_hidden_def (__inet_aton_exact)
++
++/* inet_aton ignores trailing garbage.  */
++int
++__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr)
++{
++  const char *endp;
++  return  inet_aton_end (cp, addr, &endp);
++}
++weak_alias (__inet_aton_ignore_trailing, inet_aton)
++
++/* ASCII IPv4 Internet address interpretation routine.  The value
++   returned is in network order.  */
++in_addr_t
++__inet_addr (const char *cp)
++{
++  struct in_addr val;
++  const char *endp;
++  if (inet_aton_end (cp, &val, &endp))
++    return val.s_addr;
++  return INADDR_NONE;
++}
++weak_alias (__inet_addr, inet_addr)
+diff --git a/resolv/res_init.c b/resolv/res_init.c
+index f5e52cbbb9377762..94743a252e39d64a 100644
+--- a/resolv/res_init.c
++++ b/resolv/res_init.c
+@@ -399,8 +399,16 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+               cp = parser->buffer + sizeof ("nameserver") - 1;
+               while (*cp == ' ' || *cp == '\t')
+                 cp++;
++
++              /* Ignore trailing contents on the name server line.  */
++              {
++                char *el;
++                if ((el = strpbrk (cp, " \t\n")) != NULL)
++                  *el = '\0';
++              }
++
+               struct sockaddr *sa;
+-              if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a))
++              if ((*cp != '\0') && (*cp != '\n') && __inet_aton_exact (cp, &a))
+                 {
+                   sa = allocate_address_v4 (a, NAMESERVER_PORT);
+                   if (sa == NULL)
+@@ -410,9 +418,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+                 {
+                   struct in6_addr a6;
+                   char *el;
+-
+-                  if ((el = strpbrk (cp, " \t\n")) != NULL)
+-                    *el = '\0';
+                   if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL)
+                     *el = '\0';
+                   if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0))
+@@ -472,7 +477,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+                   char separator = *cp;
+                   *cp = 0;
+                   struct resolv_sortlist_entry e;
+-                  if (__inet_aton (net, &a))
++                  if (__inet_aton_exact (net, &a))
+                     {
+                       e.addr = a;
+                       if (is_sort_mask (separator))
+@@ -484,7 +489,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+                             cp++;
+                           separator = *cp;
+                           *cp = 0;
+-                          if (__inet_aton (net, &a))
++                          if (__inet_aton_exact (net, &a))
+                             e.mask = a.s_addr;
+                           else
+                             e.mask = net_mask (e.addr);
+diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c
+index 08110a007af909ff..eb734d7758d6ed87 100644
+--- a/resolv/tst-aton.c
++++ b/resolv/tst-aton.c
+@@ -1,11 +1,29 @@
++/* Test legacy IPv4 text-to-address function inet_aton.
++   Copyright (C) 1998-2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <array_length.h>
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ 
+-
+-static struct tests
++static const struct tests
+ {
+   const char *input;
+   int valid;
+@@ -16,6 +34,7 @@ static struct tests
+   { "-1", 0, 0 },
+   { "256", 1, 0x00000100 },
+   { "256.", 0, 0 },
++  { "255a", 0, 0 },
+   { "256a", 0, 0 },
+   { "0x100", 1, 0x00000100 },
+   { "0200.0x123456", 1, 0x80123456 },
+@@ -40,7 +59,12 @@ static struct tests
+   { "1.2.256.4", 0, 0 },
+   { "1.2.3.0x100", 0, 0 },
+   { "323543357756889", 0, 0 },
+-  { "10.1.2.3.4", 0, 0},
++  { "10.1.2.3.4", 0, 0 },
++  { "192.0.2.1", 1, 0xc0000201 },
++  { "192.0.2.2\nX", 1, 0xc0000202 },
++  { "192.0.2.3 Y", 1, 0xc0000203 },
++  { "192.0.2.3Z", 0, 0 },
++  { "192.000.002.010", 1, 0xc0000208 },
+ };
+ 
+ 
+@@ -50,7 +74,7 @@ do_test (void)
+   int result = 0;
+   size_t cnt;
+ 
+-  for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt)
++  for (cnt = 0; cnt < array_length (tests); ++cnt)
+     {
+       struct in_addr addr;
+ 
+@@ -73,5 +97,4 @@ do_test (void)
+   return result;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c
+new file mode 100644
+index 0000000000000000..0fdfa3d6aa9aef91
+--- /dev/null
++++ b/resolv/tst-inet_aton_exact.c
+@@ -0,0 +1,47 @@
++/* Test internal legacy IPv4 text-to-address function __inet_aton_exact.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <arpa/inet.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  struct in_addr addr = { };
++
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.1", &addr), 1);
++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000201);
++
++  TEST_COMPARE (__inet_aton_exact ("192.000.002.010", &addr), 1);
++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000208);
++  TEST_COMPARE (__inet_aton_exact ("0xC0000234", &addr), 1);
++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000234);
++
++  /* Trailing content is not accepted.  */
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.2X", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.3 Y", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.4\nZ", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.5\tT", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.6 Y", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.7\n", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.8\t", &addr), 0);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-nondecimal.c b/resolv/tst-resolv-nondecimal.c
+new file mode 100644
+index 0000000000000000..a0df6f332ae8faf7
+--- /dev/null
++++ b/resolv/tst-resolv-nondecimal.c
+@@ -0,0 +1,139 @@
++/* Test name resolution behavior for octal, hexadecimal IPv4 addresses.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <netdb.h>
++#include <stdlib.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  /* The tests are not supposed send any DNS queries.  */
++  FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
++}
++
++static void
++run_query_addrinfo (const char *query, const char *address)
++{
++  char *quoted_query = support_quote_string (query);
++
++  struct addrinfo *ai;
++  struct addrinfo hints =
++    {
++     .ai_socktype = SOCK_STREAM,
++     .ai_protocol = IPPROTO_TCP,
++    };
++
++  char *context = xasprintf ("getaddrinfo \"%s\" AF_INET", quoted_query);
++  char *expected = xasprintf ("address: STREAM/TCP %s 80\n", address);
++  hints.ai_family = AF_INET;
++  int ret = getaddrinfo (query, "80", &hints, &ai);
++  check_addrinfo (context, ai, ret, expected);
++  if (ret == 0)
++    freeaddrinfo (ai);
++  free (context);
++
++  context = xasprintf ("getaddrinfo \"%s\" AF_UNSPEC", quoted_query);
++  hints.ai_family = AF_UNSPEC;
++  ret = getaddrinfo (query, "80", &hints, &ai);
++  check_addrinfo (context, ai, ret, expected);
++  if (ret == 0)
++    freeaddrinfo (ai);
++  free (expected);
++  free (context);
++
++  context = xasprintf ("getaddrinfo \"%s\" AF_INET6", quoted_query);
++  expected = xasprintf ("flags: AI_V4MAPPED\n"
++                        "address: STREAM/TCP ::ffff:%s 80\n",
++                        address);
++  hints.ai_family = AF_INET6;
++  hints.ai_flags = AI_V4MAPPED;
++  ret = getaddrinfo (query, "80", &hints, &ai);
++  check_addrinfo (context, ai, ret, expected);
++  if (ret == 0)
++    freeaddrinfo (ai);
++  free (expected);
++  free (context);
++
++  free (quoted_query);
++}
++
++static void
++run_query (const char *query, const char *address)
++{
++  char *quoted_query = support_quote_string (query);
++  char *context = xasprintf ("gethostbyname (\"%s\")", quoted_query);
++  char *expected = xasprintf ("name: %s\n"
++                              "address: %s\n", query, address);
++  check_hostent (context, gethostbyname (query), expected);
++  free (context);
++
++  context = xasprintf ("gethostbyname_r \"%s\"", quoted_query);
++  struct hostent storage;
++  char buf[4096];
++  struct hostent *e = NULL;
++  TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
++                                 &e, &h_errno), 0);
++  check_hostent (context, e, expected);
++  free (context);
++
++  context = xasprintf ("gethostbyname2 (\"%s\", AF_INET)", quoted_query);
++  check_hostent (context, gethostbyname2 (query, AF_INET), expected);
++  free (context);
++
++  context = xasprintf ("gethostbyname2_r \"%s\" AF_INET", quoted_query);
++  e = NULL;
++  TEST_COMPARE (gethostbyname2_r (query, AF_INET, &storage, buf, sizeof (buf),
++                                  &e, &h_errno), 0);
++  check_hostent (context, e, expected);
++  free (context);
++  free (expected);
++
++  free (quoted_query);
++
++  /* The gethostbyname tests are always valid for getaddrinfo, but not
++     vice versa.  */
++  run_query_addrinfo (query, address);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *aux = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response,
++     });
++
++  run_query ("192.000.002.010", "192.0.2.8");
++
++  /* Hexadecimal numbers are not accepted by gethostbyname.  */
++  run_query_addrinfo ("0xc0000210", "192.0.2.16");
++  run_query_addrinfo ("192.0x234", "192.0.2.52");
++
++  resolv_test_end (aux);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-trailing.c b/resolv/tst-resolv-trailing.c
+new file mode 100644
+index 0000000000000000..7504bdae572ed8d0
+--- /dev/null
++++ b/resolv/tst-resolv-trailing.c
+@@ -0,0 +1,136 @@
++/* Test name resolution behavior with trailing characters.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <array_length.h>
++#include <netdb.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  /* The tests are not supposed send any DNS queries.  */
++  FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *aux = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response,
++     });
++
++  static const char *const queries[] =
++    {
++     "192.0.2.1 ",
++     "192.0.2.2\t",
++     "192.0.2.3\n",
++     "192.0.2.4 X",
++     "192.0.2.5\tY",
++     "192.0.2.6\nZ",
++     "192.0.2. ",
++     "192.0.2.\t",
++     "192.0.2.\n",
++     "192.0.2. X",
++     "192.0.2.\tY",
++     "192.0.2.\nZ",
++     "2001:db8::1 ",
++     "2001:db8::2\t",
++     "2001:db8::3\n",
++     "2001:db8::4 X",
++     "2001:db8::5\tY",
++     "2001:db8::6\nZ",
++    };
++  for (size_t query_idx = 0; query_idx < array_length (queries); ++query_idx)
++    {
++      const char *query = queries[query_idx];
++      struct hostent storage;
++      char buf[4096];
++      struct hostent *e;
++
++      h_errno = 0;
++      TEST_VERIFY (gethostbyname (query) == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      e = NULL;
++      TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
++                                     &e, &h_errno), 0);
++      TEST_VERIFY (e == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      TEST_VERIFY (gethostbyname2 (query, AF_INET) == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      e = NULL;
++      TEST_COMPARE (gethostbyname2_r (query, AF_INET,
++                                      &storage, buf, sizeof (buf),
++                                     &e, &h_errno), 0);
++      TEST_VERIFY (e == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      TEST_VERIFY (gethostbyname2 (query, AF_INET6) == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      e = NULL;
++      TEST_COMPARE (gethostbyname2_r (query, AF_INET6,
++                                      &storage, buf, sizeof (buf),
++                                     &e, &h_errno), 0);
++      TEST_VERIFY (e == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      static const int gai_flags[] =
++        {
++         0,
++         AI_ADDRCONFIG,
++         AI_NUMERICHOST,
++         AI_IDN,
++         AI_IDN | AI_NUMERICHOST,
++         AI_V4MAPPED,
++         AI_V4MAPPED | AI_NUMERICHOST,
++        };
++      for (size_t gai_flags_idx; gai_flags_idx < array_length (gai_flags);
++             ++gai_flags_idx)
++        {
++          struct addrinfo hints = { .ai_flags = gai_flags[gai_flags_idx], };
++          struct addrinfo *ai;
++          hints.ai_family = AF_INET;
++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
++          hints.ai_family = AF_INET6;
++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
++          hints.ai_family = AF_UNSPEC;
++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
++        }
++    };
++
++  resolv_test_end (aux);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 00e0d94a8f5bb30d..6a5805c9e63a257c 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -488,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
+ 	  malloc_name = true;
+ 	}
+ 
+-      if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
++      if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
+ 	{
+ 	  if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
+ 	    at->family = AF_INET;
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index 8388f74..a416a96 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -1,6 +1,6 @@
 %define glibcsrcdir glibc-2.28
 %define glibcversion 2.28
-%define glibcrelease 42%{?dist}.1
+%define glibcrelease 72%{?dist}
 # Pre-release tarballs are pulled in from git using a command that is
 # effectively:
 #
@@ -138,7 +138,6 @@ Source12: ChangeLog.old
 # - See each individual patch file for origin and upstream status.
 # - For new patches follow template.patch format.
 ##############################################################################
-Patch1: glibc-post_upgrade.patch
 Patch2: glibc-fedora-nscd.patch
 Patch3: glibc-rh697421.patch
 Patch4: glibc-fedora-linux-tcsetattr.patch
@@ -206,7 +205,116 @@ Patch70: glibc-rh1642094-2.patch
 Patch71: glibc-rh1642094-3.patch
 Patch72: glibc-rh1654872-1.patch
 Patch73: glibc-rh1654872-2.patch
-Patch74: glibc-rh1692450.patch
+Patch74: glibc-rh1651283-1.patch
+Patch75: glibc-rh1662843-1.patch
+Patch76: glibc-rh1662843-2.patch
+Patch77: glibc-rh1623537.patch
+Patch78: glibc-rh1577438.patch
+Patch79: glibc-rh1664408.patch
+Patch80: glibc-rh1651742.patch
+Patch81: glibc-rh1672773.patch
+Patch82: glibc-rh1651283-2.patch
+Patch83: glibc-rh1651283-3.patch
+Patch84: glibc-rh1651283-4.patch
+Patch85: glibc-rh1651283-5.patch
+Patch86: glibc-rh1651283-6.patch
+Patch87: glibc-rh1651283-7.patch
+Patch88: glibc-rh1659293-1.patch
+Patch89: glibc-rh1659293-2.patch
+Patch90: glibc-rh1639343-1.patch
+Patch91: glibc-rh1639343-2.patch
+Patch92: glibc-rh1639343-3.patch
+Patch93: glibc-rh1639343-4.patch
+Patch94: glibc-rh1639343-5.patch
+Patch95: glibc-rh1639343-6.patch
+Patch96: glibc-rh1663035.patch
+Patch97: glibc-rh1658901.patch
+Patch98: glibc-rh1659512-1.patch
+Patch99: glibc-rh1659512-2.patch
+Patch100: glibc-rh1659438-1.patch
+Patch101: glibc-rh1659438-2.patch
+Patch102: glibc-rh1659438-3.patch
+Patch103: glibc-rh1659438-4.patch
+Patch104: glibc-rh1659438-5.patch
+Patch105: glibc-rh1659438-6.patch
+Patch106: glibc-rh1659438-7.patch
+Patch107: glibc-rh1659438-8.patch
+Patch108: glibc-rh1659438-9.patch
+Patch109: glibc-rh1659438-10.patch
+Patch110: glibc-rh1659438-11.patch
+Patch111: glibc-rh1659438-12.patch
+Patch112: glibc-rh1659438-13.patch
+Patch113: glibc-rh1659438-14.patch
+Patch114: glibc-rh1659438-15.patch
+Patch115: glibc-rh1659438-16.patch
+Patch116: glibc-rh1659438-17.patch
+Patch117: glibc-rh1659438-18.patch
+Patch118: glibc-rh1659438-19.patch
+Patch119: glibc-rh1659438-20.patch
+Patch120: glibc-rh1659438-21.patch
+Patch121: glibc-rh1659438-22.patch
+Patch122: glibc-rh1659438-23.patch
+Patch123: glibc-rh1659438-24.patch
+Patch124: glibc-rh1659438-25.patch
+Patch125: glibc-rh1659438-26.patch
+Patch126: glibc-rh1659438-27.patch
+Patch127: glibc-rh1659438-28.patch
+Patch128: glibc-rh1659438-29.patch
+Patch129: glibc-rh1659438-30.patch
+Patch130: glibc-rh1659438-31.patch
+Patch131: glibc-rh1659438-32.patch
+Patch132: glibc-rh1659438-33.patch
+Patch133: glibc-rh1659438-34.patch
+Patch134: glibc-rh1659438-35.patch
+Patch135: glibc-rh1659438-36.patch
+Patch136: glibc-rh1659438-37.patch
+Patch137: glibc-rh1659438-38.patch
+Patch138: glibc-rh1659438-39.patch
+Patch139: glibc-rh1659438-40.patch
+Patch140: glibc-rh1659438-41.patch
+Patch141: glibc-rh1659438-42.patch
+Patch142: glibc-rh1659438-43.patch
+Patch143: glibc-rh1659438-44.patch
+Patch144: glibc-rh1659438-45.patch
+Patch145: glibc-rh1659438-46.patch
+Patch146: glibc-rh1659438-47.patch
+Patch147: glibc-rh1659438-48.patch
+Patch148: glibc-rh1659438-49.patch
+Patch149: glibc-rh1659438-50.patch
+Patch150: glibc-rh1659438-51.patch
+Patch151: glibc-rh1659438-52.patch
+Patch152: glibc-rh1659438-53.patch
+Patch153: glibc-rh1659438-54.patch
+Patch154: glibc-rh1659438-55.patch
+Patch155: glibc-rh1659438-56.patch
+Patch156: glibc-rh1659438-57.patch
+Patch157: glibc-rh1659438-58.patch
+Patch158: glibc-rh1659438-59.patch
+Patch159: glibc-rh1659438-60.patch
+Patch160: glibc-rh1659438-61.patch
+Patch161: glibc-rh1659438-62.patch
+Patch162: glibc-rh1702539-1.patch
+Patch163: glibc-rh1702539-2.patch
+Patch164: glibc-rh1701605-1.patch
+Patch165: glibc-rh1701605-2.patch
+Patch166: glibc-rh1691528-1.patch
+Patch167: glibc-rh1691528-2.patch
+Patch168: glibc-rh1706777.patch
+Patch169: glibc-rh1710478.patch
+Patch170: glibc-rh1670043-1.patch
+Patch171: glibc-rh1670043-2.patch
+Patch172: glibc-rh1710894.patch
+Patch173: glibc-rh1699194-1.patch
+Patch174: glibc-rh1699194-2.patch
+Patch175: glibc-rh1699194-3.patch
+Patch176: glibc-rh1699194-4.patch
+Patch177: glibc-rh1727241-1.patch
+Patch178: glibc-rh1727241-2.patch
+Patch179: glibc-rh1727241-3.patch
+Patch180: glibc-rh1717438.patch
+Patch181: glibc-rh1727152.patch
+Patch182: glibc-rh1724975.patch
+Patch183: glibc-rh1722215.patch
 
 ##############################################################################
 # Continued list of core "glibc" package information:
@@ -287,8 +395,8 @@ BuildRequires: make >= 4.0
 # The intl subsystem generates a parser using bison.
 BuildRequires: bison >= 2.7
 
-# binutils 2.30-17 is needed for --generate-missing-build-notes.
-BuildRequires: binutils >= 2.30-17
+# binutils 2.30-51 is needed for z13 support on s390x.
+BuildRequires: binutils >= 2.30-51
 
 # Earlier releases have broken support for IRELATIVE relocations
 Conflicts: prelink < 0.4.2
@@ -445,8 +553,11 @@ libraries, as well as national language (locale) support.
 /sbin/ldconfig
 %end
 
-# We need to run ldconfig manually because ldconfig cannot handle the
-# relative include path in the /etc/ld.so.conf file we gneerate.
+# We need to run ldconfig manually because __brp_ldconfig assumes that
+# glibc itself is always installed in $RPM_BUILD_ROOT, but with sysroots
+# we may be installed into a subdirectory of that path.  Therefore we
+# unset __brp_ldconfig and run ldconfig by hand with the sysroots path
+# passed to -r.
 %undefine __brp_ldconfig
 
 ######################################################################
@@ -1086,8 +1197,19 @@ $olddir/build-%{target}/elf/ld.so \
         $olddir/build-%{target}/locale/localedef \
         --prefix %{glibc_sysroot} --add-to-archive \
         eo *_*
-# Setup the locale-archive template for use by glibc-all-langpacks.
-mv locale-archive{,.tmpl}
+# Setup the locale-archive template for use by glibc-all-langpacks.  We
+# copy the archive in place to keep the size of the file. Even though we
+# mark the file with "ghost" the size is used by rpm to compute the
+# required free space (see rhbz#1725131). We do this because there is a
+# point in the install when build-locale-archive has copied 100% of the
+# template into the new locale archive and so this consumes twice the
+# amount of diskspace. Note that this doesn't account for copying
+# existing compiled locales into the archive, this may consume even more
+# disk space and we can't fix that issue. In upstream we have moved away
+# from this process, removing build-locale-archive and installing a
+# default locale-archive without modification, and leaving compiled
+# locales as they are (without inclusion into the archive).
+cp locale-archive{,.tmpl}
 # Create the file lists for the language specific sub-packages:
 for i in eo *_*
 do
@@ -1141,10 +1263,6 @@ truncate -s 0 %{glibc_sysroot}/etc/gai.conf
 truncate -s 0 %{glibc_sysroot}%{_libdir}/gconv/gconv-modules.cache
 chmod 644 %{glibc_sysroot}%{_libdir}/gconv/gconv-modules.cache
 
-# Install the upgrade program
-install -m 700 build-%{target}/elf/glibc_post_upgrade \
-  %{glibc_sysroot}%{_prefix}/sbin/glibc_post_upgrade.%{_target_cpu}
-
 ##############################################################################
 # Install debug copies of unstripped static libraries
 # - This step must be last in order to capture any additional static
@@ -1167,8 +1285,8 @@ rm -rf %{glibc_sysroot}%{_prefix}/share/zoneinfo
 #
 # XXX: Ideally ld.so.conf should have the timestamp of the spec file, but there
 # doesn't seem to be any macro to give us that.  So we do the next best thing,
-# which is to at least keep the timestamp consistent.  The choice of using
-# glibc_post_upgrade.c is arbitrary.
+# which is to at least keep the timestamp consistent. The choice of using
+# SOURCE0 is arbitrary.
 touch -r %{SOURCE0} %{glibc_sysroot}/etc/ld.so.conf
 touch -r sunrpc/etc.rpc %{glibc_sysroot}/etc/rpc
 
@@ -1231,7 +1349,6 @@ rm -f %{glibc_sysroot}%{_infodir}/dir
 %endif
 
 %ifnarch %{auxarches}
-truncate -s 0 %{glibc_sysroot}/%{_prefix}/lib/locale/locale-archive
 mkdir -p %{glibc_sysroot}/var/{db,run}/nscd
 touch %{glibc_sysroot}/var/{db,run}/nscd/{passwd,group,hosts,services}
 touch %{glibc_sysroot}/var/run/nscd/{socket,nscd.pid}
@@ -1404,8 +1521,9 @@ chmod 0444 master.filelist
 # - The partial (lib*_p.a) static libraries, include files.
 # - The static files, objects, unversioned DSOs, and nscd.
 # - The bin, locale, some sbin, and share.
-#   - The use of [^gi] is meant to exclude all files except glibc_post_upgrade,
-#     and iconvconfig, which we want in the main packages.
+#   - We want iconvconfig in the main package and we do this by using
+#     a double negation of -v and [^i] so it removes all files in
+#     sbin *but* iconvconfig.
 # - All the libnss files (we add back the ones we want later).
 # - All bench test binaries.
 # - The aux-cache, since it's handled specially in the files section.
@@ -1421,7 +1539,7 @@ cat master.filelist \
 	-e 'nscd' \
 	-e '%{_prefix}/bin' \
 	-e '%{_prefix}/lib/locale' \
-	-e '%{_prefix}/sbin/[^gi]' \
+	-e '%{_prefix}/sbin/[^i]' \
 	-e '%{_prefix}/share' \
 	-e '/var/db/Makefile' \
 	-e '/libnss_.*\.so[0-9.]*$' \
@@ -1498,10 +1616,13 @@ grep '%{_libdir}/lib.*\.a' < master.filelist \
 ###############################################################################
 
 # All of the bin and certain sbin files go into the common package except
-# glibc_post_upgrade.* and iconvconfig which need to go in glibc. Likewise
-# nscd is excluded because it goes in nscd.
+# iconvconfig which needs to go in glibc. Likewise nscd is excluded because
+# it goes in nscd. The iconvconfig binary is kept in the main glibc package
+# because we use it in the post-install scriptlet to rebuild the
+# gconv-modules.cache.
 grep '%{_prefix}/bin' master.filelist >> common.filelist
-grep '%{_prefix}/sbin/[^gi]' master.filelist \
+grep '%{_prefix}/sbin' master.filelist \
+	| grep -v '%{_prefix}/sbin/iconvconfig' \
 	| grep -v 'nscd' >> common.filelist
 # All of the files under share go into the common package since they should be
 # multilib-independent.
@@ -1595,7 +1716,7 @@ echo "%{_libdir}/libpthread_nonshared.a" >> compat-libpthread-nonshared.filelist
 # glibc-debuginfocommon, and glibc-debuginfo
 ###############################################################################
 
-find_debuginfo_args='--strict-build-id -g'
+find_debuginfo_args='--strict-build-id -g -i'
 %ifarch %{debuginfocommonarches}
 find_debuginfo_args="$find_debuginfo_args \
 	-l common.filelist \
@@ -1799,7 +1920,135 @@ if rpm.vercmp(rel, required) < 0 then
   error("FATAL: kernel too old", 0)
 end
 
-%post -p %{_prefix}/sbin/glibc_post_upgrade.%{_target_cpu}
+%post -p <lua>
+-- We use lua's posix.exec because there may be no shell that we can
+-- run during glibc upgrade.
+function post_exec (program, ...)
+  local pid = posix.fork ()
+  if pid == 0 then
+    assert (posix.exec (program, ...))
+  elseif pid > 0 then
+    posix.wait (pid)
+  end
+end
+
+-- (1) Remove multilib libraries from previous installs.
+-- In order to support in-place upgrades, we must immediately remove
+-- obsolete platform directories after installing a new glibc
+-- version.  RPM only deletes files removed by updates near the end
+-- of the transaction.  If we did not remove the obsolete platform
+-- directories here, they may be preferred by the dynamic linker
+-- during the execution of subsequent RPM scriptlets, likely
+-- resulting in process startup failures.
+
+-- Full set of libraries glibc may install.
+install_libs = { "anl", "BrokenLocale", "c", "dl", "m", "mvec",
+		 "nss_compat", "nss_db", "nss_dns", "nss_files",
+		 "nss_hesiod", "pthread", "resolv", "rt", "SegFault",
+		 "thread_db", "util" }
+
+-- We are going to remove these libraries. Generally speaking we remove
+-- all core libraries in the multilib directory.
+-- We employ a tight match where X.Y is in [2.0,9.9*], so we would
+-- match "libc-2.0.so" and so on up to "libc-9.9*".
+remove_regexps = {}
+for i = 1, #install_libs do
+  remove_regexps[i] = ("lib" .. install_libs[i]
+                       .. "%%-[2-9]%%.[0-9]+%%.so$")
+end
+
+-- Two exceptions:
+remove_regexps[#install_libs + 1] = "libthread_db%%-1%%.0%%.so"
+remove_regexps[#install_libs + 2] = "libSegFault%%.so"
+
+-- We are going to search these directories.
+local remove_dirs = { "%{_libdir}/i686",
+		      "%{_libdir}/i686/nosegneg",
+		      "%{_libdir}/power6",
+		      "%{_libdir}/power7",
+		      "%{_libdir}/power8" }
+
+-- Walk all the directories with files we need to remove...
+for _, rdir in ipairs (remove_dirs) do
+  if posix.access (rdir) then
+    -- If the directory exists we look at all the files...
+    local remove_files = posix.files (rdir)
+    for rfile in remove_files do
+      for _, rregexp in ipairs (remove_regexps) do
+	-- Does it match the regexp?
+	local dso = string.match (rfile, rregexp)
+        if (dso ~= nil) then
+	  -- Removing file...
+	  os.remove (rdir .. '/' .. rfile)
+	end
+      end
+    end
+  end
+end
+
+-- (2) Update /etc/ld.so.conf
+-- Next we update /etc/ld.so.conf to ensure that it starts with
+-- a literal "include ld.so.conf.d/*.conf".
+
+local ldsoconf = "/etc/ld.so.conf"
+local ldsoconf_tmp = "/etc/glibc_post_upgrade.ld.so.conf"
+
+if posix.access (ldsoconf) then
+
+  -- We must have a "include ld.so.conf.d/*.conf" line.
+  local have_include = false
+  for line in io.lines (ldsoconf) do
+    -- This must match, and we don't ignore whitespace.
+    if string.match (line, "^include ld.so.conf.d/%%*%%.conf$") ~= nil then
+      have_include = true
+    end
+  end
+
+  if not have_include then
+    -- Insert "include ld.so.conf.d/*.conf" line at the start of the
+    -- file. We only support one of these post upgrades running at
+    -- a time (temporary file name is fixed).
+    local tmp_fd = io.open (ldsoconf_tmp, "w")
+    if tmp_fd ~= nil then
+      tmp_fd:write ("include ld.so.conf.d/*.conf\n")
+      for line in io.lines (ldsoconf) do
+        tmp_fd:write (line .. "\n")
+      end
+      tmp_fd:close ()
+      local res = os.rename (ldsoconf_tmp, ldsoconf)
+      if res == nil then
+        io.stdout:write ("Error: Unable to update configuration file (rename).\n")
+      end
+    else
+      io.stdout:write ("Error: Unable to update configuration file (open).\n")
+    end
+  end
+end
+
+-- (3) Rebuild ld.so.cache early.
+-- If the format of the cache changes then we need to rebuild
+-- the cache early to avoid any problems running binaries with
+-- the new glibc.
+
+-- Note: We use _prefix because Fedora's UsrMove says so.
+post_exec ("%{_prefix}/sbin/ldconfig")
+
+-- (4) Update gconv modules cache.
+-- If the /usr/lib/gconv/gconv-modules.cache exists, then update it
+-- with the latest set of modules that were just installed.
+-- We assume that the cache is in _libdir/gconv and called
+-- "gconv-modules.cache".
+
+local iconv_dir = "%{_libdir}/gconv"
+local iconv_cache = iconv_dir .. "/gconv-modules.cache"
+if (posix.utime (iconv_cache) == 0) then
+  post_exec ("%{_prefix}/sbin/iconvconfig",
+	     "-o", iconv_cache,
+	     "--nostdlib",
+	     iconv_dir)
+else
+  io.stdout:write ("Error: Missing " .. iconv_cache .. " file.\n")
+end
 
 %posttrans all-langpacks -e -p <lua>
 -- If at the end of the transaction we are still installed
@@ -1816,11 +2065,11 @@ if posix.stat("%{_prefix}/lib/locale/locale-archive.tmpl", "size") > 0 then
 end
 
 %postun all-langpacks -p <lua>
--- In the postun we always remove the locale cache.
--- We are being uninstalled and if this is an upgrade
--- then the new packages template will be used to
--- recreate a new copy of the cache.
-os.remove("%{_prefix}/lib/locale/locale-archive")
+-- In the postun we remove the locale cache if unstalling.
+-- (build-locale-archive will delete the archive during an upgrade.)
+if arg[2] == 0 then
+  os.remove("%{_prefix}/lib/locale/locale-archive")
+end
 
 %if %{with docs}
 %post devel
@@ -1891,7 +2140,7 @@ fi
 
 %files all-langpacks
 %attr(0644,root,root) %verify(not md5 size mtime) %{_prefix}/lib/locale/locale-archive.tmpl
-%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %config(missingok,noreplace) %{_prefix}/lib/locale/locale-archive
+%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %{_prefix}/lib/locale/locale-archive
 
 %files locale-source
 %dir %{_prefix}/share/i18n/locales
@@ -1952,8 +2201,99 @@ fi
 %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
 
 %changelog
-* Mon Apr  1 2019 Florian Weimer <fweimer@redhat.com> - 2.28-42.1
-- ja_JP: Add new Japanese Era name (#1692450)
+* Mon Jul 22 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-72
+- Skip wide buffer handling for legacy stdio handles (#1722215)
+
+* Mon Jul 22 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-71
+- Remove copy_file_range emulation (#1724975)
+
+* Mon Jul 22 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-70
+- Avoid nscd assertion failure during persistent db check (#1727152)
+
+* Mon Jul 22 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-69
+- Fix invalid free under valgrind with libdl (#1717438)
+
+* Thu Jul 18 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-68
+- Account for size of locale-archive in rpm package (#1725131)
+
+* Thu Jul 18 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-67
+- Reject IP addresses with trailing characters in getaddrinfo (#1727241)
+
+* Fri Jun 14 2019 Florian Weimer <fweimer@redhat.com> - 2.28-66
+- Avoid header conflict between <sys/stat.h> and <linux/stat.h> (#1699194)
+
+* Wed Jun 12 2019 Florian Weimer <fweimer@redhat.com> - 2.28-65
+- glibc-all-langpacks: Do not delete locale archive during update (#1717347)
+- Do not mark /usr/lib/locale/locale-archive as a configuration file
+  because it is always automatically overwritten by build-locale-archive.
+
+* Mon Jun 10 2019 DJ Delorie <dj@redhat.com> - 2.28-64
+- Avoid ABI exposure of the NSS service_user type (#1710894)
+
+* Thu Jun  6 2019 Patsy Griffin Franklin <patsy@redhat.com> - 2.28-63
+- Enable full ICMP errors for UDP DNS sockets. (#1670043)
+
+* Mon Jun  3 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-62
+- Convert post-install binary to rpm lua scriptlet (#1639346)
+
+* Mon Jun  3 2019 Florian Weimer <fweimer@redhat.com> - 2.28-61
+- Fix crash during wide stream buffer flush (#1710478)
+
+* Fri May 31 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-60
+- Add PF_XDP, AF_XDP and SOL_XDP from Linux 4.18 (#1706777)
+
+* Wed May 22 2019 DJ Delorie <dj@redhat.com> - 2.28-59
+- Add .gdb_index to debug information (#1612448)
+
+* Wed May 22 2019 DJ Delorie <dj@redhat.com) - 2.28-58
+- iconv, localedef: avoid floating point rounding differences (#1691528)
+
+* Wed May 22 2019 Arjun Shankar <arjun@redhat.com> - 2.28-57
+- locale: Add LOCPATH diagnostics to the locale program (#1701605)
+
+* Fri May 17 2019 Patsy Griffin Franklin <patsy@redhat.com> - 2.28-56
+- Fix hang in pldd.  (#1702539)
+
+* Mon May 13 2019 Florian Weimer <fweimer@redhat.com> - 2.28-55
+- s390x string function improvements (#1659438)
+
+* Thu May  2 2019 Patsy Griffin Franklin <patsy@redhat.com> - 2.28-54
+- Fix test suite failures due to race conditions in posix/tst-spawn
+  spawned processes. (#1659512)
+
+* Wed May  1 2019 DJ Delorie <dj@redhat.com> - 2.28-53
+- Add missing CFI data to __mpn_* functions on ppc64le (#1658901)
+
+* Fri Apr 26 2019 Arjun Shankar <arjun@redhat.com> - 2.28-52
+- intl: Do not return NULL on asprintf failure in gettext (#1663035)
+
+* Fri Apr 26 2019 Florian Weimer <fweimer@redhat.com> - 2.28-51
+- Increase BIND_NOW coverage (#1639343)
+
+* Tue Apr 23 2019 Carlos O'Donell <carlos@redhat.com> - 2.28-50
+- Fix pthread_rwlock_trywrlock and pthread_rwlock_tryrdlock stalls (#1659293)
+
+* Tue Apr 23 2019 Arjun Shankar <arjun@redhat.com> - 2.28-49
+- malloc: Improve bad chunk detection (#1651283)
+
+* Mon Apr 22 2019 Patsy Griffin Franklin <patsy@redhat.com> - 2.28-48
+- Add compiler barriers around modifications of the robust mutex list
+  for pthread_mutex_trylock. (#1672773)
+
+* Tue Apr 16 2019 DJ Delorie <dj@redhat.com> - 2.28-47
+- powerpc: Only enable HTM if kernel supports PPC_FEATURE2_HTM_NOSC (#1651742)
+
+* Fri Apr 12 2019 Florian Weimer <fweimer@redhat.com> - 2.28-46
+- Only build libm with -fno-math-errno (#1664408)
+
+* Tue Apr  2 2019 Florian Weimer <fweimer@redhat.com> - 2.28-45
+- ja_JP: Add new Japanese Era name (#1577438)
+
+* Wed Mar  6 2019 Florian Weimer <fweimer@redhat.com> - 2.28-44
+- math: Add XFAILs for some IBM 128-bit long double fma tests (#1623537)
+
+* Fri Mar  1 2019 Florian Weimer <fweimer@redhat.com> - 2.28-43
+- malloc: realloc ncopies integer overflow (#1662843)
 
 * Fri Dec 14 2018 Florian Weimer <fweimer@redhat.com> - 2.28-42
 - Fix rdlock stall with PREFER_WRITER_NONRECURSIVE_NP (#1654872)