diff --git a/SOURCES/glibc-rh1642150-1.patch b/SOURCES/glibc-rh1642150-1.patch
new file mode 100644
index 0000000..381ad0b
--- /dev/null
+++ b/SOURCES/glibc-rh1642150-1.patch
@@ -0,0 +1,176 @@
+commit a803367bab167f5ec4fde1f0d0ec447707c29520
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Feb 14 20:55:39 2020 +0100
+
+    powerpc64: Add memory protection key support [BZ #23202]
+    
+    The 32-bit protection key behavior is somewhat unclear on 32-bit powerpc,
+    so this change is restricted to the 64-bit variants.
+    
+    Flag translation is needed because of hardware differences between the
+    POWER implementation (read and write flags) and the Intel implementation
+    (write and read+write flags).
+
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h
+new file mode 100644
+index 0000000000000000..623b073d5a585d51
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h
+@@ -0,0 +1,55 @@
++/* Helper functions for manipulating memory protection keys, for powerpc64.
++   Copyright (C) 2017-2020 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 _ARCH_PKEY_H
++#define _ARCH_PKEY_H
++
++/* Read and write access bits in the AMR register.  Needs to be
++   translated from and to PKEY_DISABLE_* flags.  */
++#define PKEY_AMR_READ 1UL
++#define PKEY_AMR_WRITE 2UL
++
++/* Return the value of the AMR register.  */
++static inline unsigned long int
++pkey_read (void)
++{
++  unsigned long int result;
++  __asm__ volatile ("mfspr %0, 13" : "=r" (result));
++  return result;
++}
++
++/* Overwrite the AMR register with VALUE.  */
++static inline void
++pkey_write (unsigned long int value)
++{
++  __asm__ volatile ("mtspr 13, %0" : : "r" (value));
++}
++
++/* Number of the largest supported key.  This depends on the width of
++   the AMR register.  */
++#define PKEY_MAX (sizeof (unsigned long int) * 8 / 2 - 1)
++_Static_assert (PKEY_MAX == 15 || PKEY_MAX == 31, "PKEY_MAX value");
++
++/* Translate key number into AMR index position.  */
++static inline int
++pkey_index (int key)
++{
++  return 2 * (PKEY_MAX - key);
++}
++
++#endif /* _ARCH_PKEY_H */
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c
+new file mode 100644
+index 0000000000000000..856ba061b90eabd2
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c
+@@ -0,0 +1,42 @@
++/* Reading the per-thread memory protection key, powerpc64 version.
++   Copyright (C) 2017-2020 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 <arch-pkey.h>
++#include <errno.h>
++#include <sys/mman.h>
++
++int
++pkey_get (int key)
++{
++  if (key < 0 || key > PKEY_MAX)
++    {
++      __set_errno (EINVAL);
++      return -1;
++    }
++  unsigned int index = pkey_index (key);
++  unsigned long int amr = pkey_read ();
++  unsigned int bits = (amr >> index) & 3;
++
++  /* Translate from AMR values.  PKEY_AMR_READ standing alone is not
++     currently representable.  */
++  if (bits & PKEY_AMR_READ)
++    return PKEY_DISABLE_ACCESS;
++  else if (bits == PKEY_AMR_WRITE)
++    return PKEY_DISABLE_WRITE;
++  return 0;
++}
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c
+new file mode 100644
+index 0000000000000000..20b372ee2983abd5
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c
+@@ -0,0 +1,48 @@
++/* Changing the per-thread memory protection key, powerpc64 version.
++   Copyright (C) 2017-2020 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 <arch-pkey.h>
++#include <errno.h>
++#include <sys/mman.h>
++
++int
++pkey_set (int key, unsigned int rights)
++{
++  if (key < 0 || key > PKEY_MAX || rights > 3)
++    {
++      __set_errno (EINVAL);
++      return -1;
++    }
++
++  /* Translate to AMR bit values.  */
++  unsigned long int bits;
++  if (rights & PKEY_DISABLE_ACCESS)
++    /* The PKEY_DISABLE_WRITE bit does not matter.  */
++    bits = PKEY_AMR_READ | PKEY_AMR_WRITE;
++  else if (rights == PKEY_DISABLE_WRITE)
++    bits = PKEY_AMR_WRITE;
++  else
++    bits = 0;
++
++  unsigned int index = pkey_index (key);
++  unsigned long int mask = 3UL << index;
++  unsigned long int amr = pkey_read ();
++  amr = (amr & ~mask) | (bits << index);
++  pkey_write (amr);
++  return 0;
++}
diff --git a/SOURCES/glibc-rh1642150-2.patch b/SOURCES/glibc-rh1642150-2.patch
new file mode 100644
index 0000000..129ed9d
--- /dev/null
+++ b/SOURCES/glibc-rh1642150-2.patch
@@ -0,0 +1,53 @@
+commit 8d42bf859a289944749d9f978c076cd318119867
+Author: Lucas A. M. Magalhaes <lamm@linux.ibm.com>
+Date:   Mon Feb 17 09:09:52 2020 -0300
+
+    Fix tst-pkey expectations on pkey_get [BZ #23202]
+    
+    From the GNU C Library manual, the pkey_set can receive a combination of
+    PKEY_DISABLE_WRITE and PKEY_DISABLE_ACCESS.  However PKEY_DISABLE_ACCESS
+    is more restrictive than PKEY_DISABLE_WRITE and includes its behavior.
+    
+    The test expects that after setting
+    (PKEY_DISABLE_WRITE|PKEY_DISABLE_ACCESS) pkey_get should return the
+    same.  This may not be true as PKEY_DISABLE_ACCESS will succeed in
+    describing the state of the key in this case.
+    
+    The pkey behavior during signal handling is different between x86 and
+    POWER.  This change make the test compatible with both architectures.
+    
+    Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+
+diff --git a/sysdeps/unix/sysv/linux/tst-pkey.c b/sysdeps/unix/sysv/linux/tst-pkey.c
+index 5f721d4444490945..600b6f0098def773 100644
+--- a/sysdeps/unix/sysv/linux/tst-pkey.c
++++ b/sysdeps/unix/sysv/linux/tst-pkey.c
+@@ -37,7 +37,7 @@ static pthread_barrier_t barrier;
+ 
+ /* The keys used for testing.  These have been allocated with access
+    rights set based on their array index.  */
+-enum { key_count = 4 };
++enum { key_count = 3 };
+ static int keys[key_count];
+ static volatile int *pages[key_count];
+ 
+@@ -111,14 +111,16 @@ check_page_access (int page, bool write)
+ }
+ 
+ static volatile sig_atomic_t sigusr1_handler_ran;
+-
+-/* Used to check that access is revoked in signal handlers.  */
++/* Used to check the behavior in signal handlers.  In x86 all access are
++   revoked during signal handling.  In PowerPC the key permissions are
++   inherited by the interrupted thread. This test accept both approaches.  */
+ static void
+ sigusr1_handler (int signum)
+ {
+   TEST_COMPARE (signum, SIGUSR1);
+   for (int i = 0; i < key_count; ++i)
+-    TEST_COMPARE (pkey_get (keys[i]), PKEY_DISABLE_ACCESS);
++    TEST_VERIFY (pkey_get (keys[i]) == PKEY_DISABLE_ACCESS
++                 || pkey_get (keys[i]) == i);
+   sigusr1_handler_ran = 1;
+ }
+ 
diff --git a/SOURCES/glibc-rh1642150-3.patch b/SOURCES/glibc-rh1642150-3.patch
new file mode 100644
index 0000000..84a2191
--- /dev/null
+++ b/SOURCES/glibc-rh1642150-3.patch
@@ -0,0 +1,46 @@
+commit 70ba28f7ab2923d4e36ffc9d5d2e32357353b25c
+Author: Lucas A. M. Magalhaes <lamm@linux.ibm.com>
+Date:   Thu Jan 16 10:39:12 2020 -0300
+
+    Fix tst-pkey.c pkey_alloc return checks and manual
+    
+    This test was failing in some powerpc systems as it was not checking
+    for ENOSPC return.
+    
+    As said on the Linux man-pages and can be observed by the implementation
+    at mm/mprotect.c in the Linux Kernel source.  The syscall pkey_alloc can
+    return EINVAL or ENOSPC.  ENOSPC will indicate either that all keys are
+    in use or that the kernel does not support pkeys.
+    
+    Reviewed-by: Gabriel F. T. Gomes <gabriel@inconstante.net.br>
+
+diff --git a/manual/memory.texi b/manual/memory.texi
+index a1435aad1acd3239..4731a38bcc5701e0 100644
+--- a/manual/memory.texi
++++ b/manual/memory.texi
+@@ -3289,6 +3289,10 @@ in which memory protection keys are disabled.
+ 
+ @item ENOSPC
+ All available protection keys already have been allocated.
++
++The system does not implement memory protection keys or runs in a mode
++in which memory protection keys are disabled.
++
+ @end table
+ @end deftypefun
+ 
+diff --git a/sysdeps/unix/sysv/linux/tst-pkey.c b/sysdeps/unix/sysv/linux/tst-pkey.c
+index 600b6f0098def773..40d7e9f24dec3e57 100644
+--- a/sysdeps/unix/sysv/linux/tst-pkey.c
++++ b/sysdeps/unix/sysv/linux/tst-pkey.c
+@@ -199,6 +199,10 @@ do_test (void)
+       if (errno == EINVAL)
+         FAIL_UNSUPPORTED
+           ("CPU does not support memory protection keys: %m");
++      if (errno == ENOSPC)
++        FAIL_UNSUPPORTED
++          ("no keys available or kernel does not support memory"
++           " protection keys");
+       FAIL_EXIT1 ("pkey_alloc: %m");
+     }
+   TEST_COMPARE (pkey_get (keys[0]), 0);
diff --git a/SOURCES/glibc-rh1743445-1.patch b/SOURCES/glibc-rh1743445-1.patch
new file mode 100644
index 0000000..759879a
--- /dev/null
+++ b/SOURCES/glibc-rh1743445-1.patch
@@ -0,0 +1,151 @@
+From: Ian Kent <ikent@redhat.com>
+Date: Mon, 2 Sep 2019 11:26:14 +0000 (+0200)
+Subject: Use autofs "ignore" mount hint in getmntent_r/getmntent
+X-Git-Tag: changelog-ends-here~75
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=08b7e9988272113ca5640cf5e115ea51449fb392
+
+Use autofs "ignore" mount hint in getmntent_r/getmntent
+
+Historically autofs mounts were not included in mount table
+listings. This is the case in other SysV autofs implementations
+and was also the case with Linux autofs.
+
+But now that /etc/mtab is a symlink to the proc filesystem
+mount table the autofs mount entries appear in the mount table
+on Linux.
+
+Prior to the symlinking of /etc/mtab mount table it was
+sufficient to call mount(2) and simply not update /etc/mtab
+to exclude autofs mounts from mount listings.
+
+Also, with the symlinking of /etc/mtab we have seen a shift in
+usage toward using the proc mount tables directly.
+
+But the autofs mount entries need to be retained when coming
+from the proc file system for applications that need them
+(largely autofs file system users themselves) so filtering out
+these entries within the kernel itself can't be done. So it
+needs be done in user space.
+
+There are three reasons to omit the autofs mount entries.
+
+One is that certain types of auto-mounts have an autofs mount
+for every entry in their autofs mount map and these maps can
+be quite large. This leads to mount table listings containing
+a lot of unnecessary entries.
+
+Also, this change in behaviour between autofs implementations
+can cause problems for applications that use getmntent(3) in
+other OS implementations as well as Linux.
+
+Lastly, there's very little that user space can do with autofs
+mount entries since this must be left to the autofs mount owner,
+typically the automount daemon. But it can also lead to attempts
+to access automount managed paths resulting mounts being triggered
+when they aren't needed or mounts staying mounted for much longer
+thay they need be. While the point of this change ins't to help
+with these problems (and it can be quite a problem) it may be
+a welcome side effect.
+
+So the Linux autofs file system has been modified to accept a
+pseudo mount option of "ignore" (as is used in other OS
+implementations) so that user space can use this as a hint to
+skip autofs entries on reading the mount table.
+
+The Linux autofs automount daemon used getmntent(3) itself and
+has been modified to use the proc file system directly so that
+it can "ignore" mount option.
+
+The use of this mount option is opt-in and a configuration
+option has been added which defaults to not use this option
+so if there are applications that need these entries, other
+than autofs itself, they can be retained. Also, since this
+filtering is based on an added mount option earlier versions
+of Linux autofs iand other autofs file system users will not
+use the option and so won't be affected by the change.
+---
+
+diff --git a/misc/mntent_r.c b/misc/mntent_r.c
+index 5d88c45c6f..d90e8d7087 100644
+--- a/misc/mntent_r.c
++++ b/misc/mntent_r.c
+@@ -18,6 +18,7 @@
+ 
+ #include <alloca.h>
+ #include <mntent.h>
++#include <stdbool.h>
+ #include <stdio.h>
+ #include <stdio_ext.h>
+ #include <string.h>
+@@ -112,26 +113,18 @@ decode_name (char *buf)
+   return buf;
+ }
+ 
+-
+-/* Read one mount table entry from STREAM.  Returns a pointer to storage
+-   reused on the next call, or null for EOF or error (use feof/ferror to
+-   check).  */
+-struct mntent *
+-__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
++static bool
++get_mnt_entry (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
+ {
+   char *cp;
+   char *head;
+ 
+-  flockfile (stream);
+   do
+     {
+       char *end_ptr;
+ 
+       if (__fgets_unlocked (buffer, bufsiz, stream) == NULL)
+-	{
+-	  funlockfile (stream);
+-	  return NULL;
+-	}
++	  return false;
+ 
+       end_ptr = strchr (buffer, '\n');
+       if (end_ptr != NULL)	/* chop newline */
+@@ -181,9 +174,40 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
+     case 2:
+       break;
+     }
++
++  return true;
++}
++
++/* Read one mount table entry from STREAM.  Returns a pointer to storage
++   reused on the next call, or null for EOF or error (use feof/ferror to
++   check).  */
++struct mntent *
++__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
++{
++  struct mntent *result;
++
++  flockfile (stream);
++  while (true)
++    if (get_mnt_entry (stream, mp, buffer, bufsiz))
++      {
++	/* If the file system is autofs look for a mount option hint
++	   ("ignore") to skip the entry.  */
++	if (strcmp (mp->mnt_type, "autofs") == 0 && __hasmntopt (mp, "ignore"))
++	  memset (mp, 0, sizeof (*mp));
++	else
++	  {
++	    result = mp;
++	    break;
++	  }
++      }
++    else
++      {
++	result = NULL;
++	break;
++      }
+   funlockfile (stream);
+ 
+-  return mp;
++  return result;
+ }
+ libc_hidden_def (__getmntent_r)
+ weak_alias (__getmntent_r, getmntent_r)
diff --git a/SOURCES/glibc-rh1743445-2.patch b/SOURCES/glibc-rh1743445-2.patch
new file mode 100644
index 0000000..a14fe60
--- /dev/null
+++ b/SOURCES/glibc-rh1743445-2.patch
@@ -0,0 +1,169 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 2 Sep 2019 10:40:38 +0000 (+0200)
+Subject: Add misc/tst-mntent-autofs, testing autofs "ignore" filtering
+X-Git-Tag: changelog-ends-here~74
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=9a1e7257a4292d3aea45c8317df3956f4331d8ce
+
+Add misc/tst-mntent-autofs, testing autofs "ignore" filtering
+---
+
+diff -rup a/misc/Makefile b/misc/Makefile
+--- a/misc/Makefile	2020-03-25 18:30:42.275895917 -0400
++++ b/misc/Makefile	2020-03-25 18:37:55.527738814 -0400
+@@ -84,7 +84,8 @@ tests := tst-dirname tst-tsearch tst-fds
+ 	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \
+ 	 tst-mntent-blank-corrupt tst-mntent-blank-passno bug18240 \
+ 	 tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
+-	 tst-preadvwritev2 tst-preadvwritev64v2
++	 tst-preadvwritev2 tst-preadvwritev64v2 \
++	 tst-mntent-autofs
+ 
+ # Tests which need libdl.
+ ifeq (yes,$(build-shared))
+diff --git a/misc/tst-mntent-autofs.c b/misc/tst-mntent-autofs.c
+new file mode 100644
+index 0000000000..bf4d4e73b4
+--- /dev/null
++++ b/misc/tst-mntent-autofs.c
+@@ -0,0 +1,141 @@
++/* Test autofs "ignore" filtering for getment_r.
++   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 <errno.h>
++#include <mntent.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/temp_file.h>
++#include <support/xstdio.h>
++#include <support/xunistd.h>
++
++struct test_case
++{
++  const char *line;
++  struct
++  {
++    /* Like struct mntent, but with const pointers.  */
++    const char *mnt_fsname;
++    const char *mnt_dir;
++    const char *mnt_type;
++    const char *mnt_opts;
++    int mnt_freq;
++    int mnt_passno;
++  } expected;
++};
++
++static struct test_case test_cases[] =
++  {
++    { "/etc/auto.direct /mnt/auto/1 autofs defaults 0 0",
++      { "/etc/auto.direct", "/mnt/auto/1", "autofs", "defaults", 0, 0 } },
++
++    /* These entries are filtered out.  */
++    { "/etc/auto.2 /mnt/auto/2 autofs ignore 0 0", { NULL, } },
++    { "/etc/auto.3 /mnt/auto/3 autofs ignore,other 1 2", { NULL, } },
++    { "/etc/auto.4 /mnt/auto/4 autofs other,ignore 3 4", { NULL, } },
++    { "/etc/auto.5 /mnt/auto/5 autofs opt1,ignore,opt2 5 6", { NULL, } },
++
++    /* Dummy entry to make the desynchronization more obvious.  */
++    { "/dev/sda1 / xfs defaults 0 0",
++      { "/dev/sda1", "/", "xfs", "defaults", 0, 0 } },
++
++    /* These are not filtered because the file system is not autofs.  */
++    { "/etc/auto.direct /mnt/auto/6 autofs1 ignore 0 0",
++      { "/etc/auto.direct", "/mnt/auto/6", "autofs1", "ignore", 0, 0 } },
++    { "/etc/auto.direct /mnt/auto/7 autofs1 ignore,other 0 0",
++      { "/etc/auto.direct", "/mnt/auto/7", "autofs1", "ignore,other", 0, 0 } },
++    { "/etc/auto.direct /mnt/auto/8 autofs1 other,ignore 0 0",
++      { "/etc/auto.direct", "/mnt/auto/8", "autofs1", "other,ignore", 0, 0 } },
++    { "/etc/auto.direct /mnt/auto/9 autofs1 opt1,ignore,opt2 0 0",
++      { "/etc/auto.direct", "/mnt/auto/9", "autofs1", "opt1,ignore,opt2", } },
++
++    /* These are not filtered because the string "ignore" is not an
++       option name.  */
++    { "/etc/auto.direct /mnt/auto/10 autofs noignore 1 2",
++      { "/etc/auto.direct", "/mnt/auto/10", "autofs", "noignore", 1, 2 } },
++    { "/etc/auto.direct /mnt/auto/11 autofs noignore,other 0 0",
++      { "/etc/auto.direct", "/mnt/auto/11", "autofs", "noignore,other", } },
++    { "/etc/auto.direct /mnt/auto/12 autofs other,noignore 0 0",
++      { "/etc/auto.direct", "/mnt/auto/12", "autofs", "other,noignore", } },
++    { "/etc/auto.direct /mnt/auto/13 autofs errors=ignore 0 0",
++      { "/etc/auto.direct", "/mnt/auto/13", "autofs", "errors=ignore", } },
++    { "/etc/auto.direct /mnt/auto/14 autofs errors=ignore,other 0 0",
++      { "/etc/auto.direct", "/mnt/auto/14", "autofs",
++        "errors=ignore,other", } },
++    { "/etc/auto.direct /mnt/auto/15 autofs other,errors=ignore 0 0",
++      { "/etc/auto.direct", "/mnt/auto/15", "autofs",
++        "other,errors=ignore", } },
++
++    /* These are not filtered because the string is escaped.  '\151'
++       is 'i', but it is not actually decoded by the parser.  */
++    { "/etc/auto.\\151gnore /mnt/auto/16 autofs \\151gnore 0 0",
++      { "/etc/auto.\\151gnore", "/mnt/auto/16", "autofs",
++        "\\151gnore", } },
++  };
++
++static int
++do_test (void)
++{
++  char *path;
++  xclose (create_temp_file ("tst-mntent-autofs-", &path));
++
++  /* Write the test file.  */
++  FILE *fp = xfopen (path, "w");
++  for (size_t i = 0; i < array_length (test_cases); ++i)
++    fprintf (fp, "%s\n", test_cases[i].line);
++  xfclose (fp);
++
++  /* Open the test file again, this time for parsing.  */
++  fp = setmntent (path, "r");
++  TEST_VERIFY_EXIT (fp != NULL);
++  char buffer[512];
++  struct mntent me;
++
++  for (size_t i = 0; i < array_length (test_cases); ++i)
++    {
++      if (test_cases[i].expected.mnt_type == NULL)
++        continue;
++
++      memset (buffer, 0xcc, sizeof (buffer));
++      memset (&me, 0xcc, sizeof (me));
++      struct mntent *pme = getmntent_r (fp, &me, buffer, sizeof (buffer));
++      TEST_VERIFY_EXIT (pme != NULL);
++      TEST_VERIFY (pme == &me);
++      TEST_COMPARE_STRING (test_cases[i].expected.mnt_fsname, me.mnt_fsname);
++      TEST_COMPARE_STRING (test_cases[i].expected.mnt_dir, me.mnt_dir);
++      TEST_COMPARE_STRING (test_cases[i].expected.mnt_type, me.mnt_type);
++      TEST_COMPARE_STRING (test_cases[i].expected.mnt_opts, me.mnt_opts);
++      TEST_COMPARE (test_cases[i].expected.mnt_freq, me.mnt_freq);
++      TEST_COMPARE (test_cases[i].expected.mnt_passno, me.mnt_passno);
++    }
++
++  TEST_VERIFY (getmntent_r (fp, &me, buffer, sizeof (buffer)) == NULL);
++
++  TEST_COMPARE (feof (fp), 1);
++  TEST_COMPARE (ferror (fp), 0);
++  errno = 0;
++  TEST_COMPARE (endmntent (fp), 1);
++  TEST_COMPARE (errno, 0);
++  free (path);
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1757354.patch b/SOURCES/glibc-rh1757354.patch
new file mode 100644
index 0000000..d159b26
--- /dev/null
+++ b/SOURCES/glibc-rh1757354.patch
@@ -0,0 +1,1163 @@
+commit 8e42fc6811ba94a01e194d46572c3cf803b3aae0
+Author: Mike FABIAN <mfabian@redhat.com>
+Date:   Tue Sep 17 17:20:32 2019 +0200
+
+    Sync "language", "lang_name", "territory", "country_name" with CLDR/langtable
+    
+    Sync these values with CLDR and langtable as much as possible.  Add
+    missing values.
+    
+    If possible, take the values from CLDR, if CLDR does not have it,
+    take it from langtable. The values from langtable which are not from
+    CLDR are from  Wikipedia or native speakers.
+
+diff --git a/localedata/locales/az_AZ b/localedata/locales/az_AZ
+index 6fe8839f25cc7450..3c0db0be3de1e6d3 100644
+--- a/localedata/locales/az_AZ
++++ b/localedata/locales/az_AZ
+@@ -243,7 +243,7 @@ country_ab3 "AZE"
+ country_num 031
+ country_car    "AZ"
+ % Azərbaycanca
+-lang_name    "az<U0259>rbaycan dili"
++lang_name    "az<U0259>rbaycan"
+ lang_ab      "az"
+ lang_term    "aze"
+ lang_lib    "aze"
+diff --git a/localedata/locales/be_BY@latin b/localedata/locales/be_BY@latin
+index 43b13cc27812aaa0..fef339f6247a0eb6 100644
+--- a/localedata/locales/be_BY@latin
++++ b/localedata/locales/be_BY@latin
+@@ -156,7 +156,7 @@ country_ab2 "BY"
+ country_ab3 "BLR"
+ country_num 112
+ country_car    "BY"
+-lang_name    "bie<U0142>aruskaja mova"
++lang_name    "bie<U0142>aruskaja"
+ lang_ab      "be"
+ lang_term    "bel"
+ lang_lib    "bel"
+diff --git a/localedata/locales/ber_DZ b/localedata/locales/ber_DZ
+index 79f3d289b1ee771c..4fa1bdfff94b9efd 100644
+--- a/localedata/locales/ber_DZ
++++ b/localedata/locales/ber_DZ
+@@ -8,7 +8,7 @@ escape_char /
+ % exempt you from the conditions of the license if your use would
+ % otherwise be governed by that license.
+ 
+-% Amazigh Language Locale for Algeria (latin)
++% Berber Language Locale for Algeria (latin)
+ % Source:
+ % Contact: Pablo Saratxaga
+ % Email: <pablo@mandrakesoft.com>
+@@ -20,14 +20,14 @@ escape_char /
+ % Users: general
+ 
+ LC_IDENTIFICATION
+-title "Amazigh language locale for Algeria (latin)"
++title "Berber language locale for Algeria (latin)"
+ source ""
+ address ""
+ contact "Pablo Saratxaga"
+ email "pablo@mandrakesoft.com"
+ tel ""
+ fax ""
+-language "Amazigh"
++language "Berber"
+ territory "Algeria"
+ revision "0.1"
+ date "2002-04-16"
+@@ -253,14 +253,15 @@ LC_ADDRESS
+ % This is the ISO_IEC TR14652 Locale definition for the
+ % LC_ADDRESS
+ postal_fmt  "%z%c%T%s%b%e%r"
++country_name "Lezzayer"
+ %country_post ""
+ country_ab2 "DZ"
+ country_ab3 "DZA"
+ country_num 012
+ %country_isbn ""
+ country_car  "DZ"
+-% ⵜⴰⵎⴰⵣⵉⵖⵜ
+-lang_name "<U2D5C><U2D30><U2D4E><U2D30><U2D49><U2D56><U2D5C>"
++% Tamaziɣt
++lang_name "Tamazi<U0263>t"
+ %lang_ab
+ lang_term "ber"
+ lang_lib "ber"
+diff --git a/localedata/locales/ber_MA b/localedata/locales/ber_MA
+index b9bd64868cda3412..5d19354ad65069eb 100644
+--- a/localedata/locales/ber_MA
++++ b/localedata/locales/ber_MA
+@@ -8,7 +8,7 @@ escape_char /
+ % exempt you from the conditions of the license if your use would
+ % otherwise be governed by that license.
+ 
+-% Amazigh Language Locale for Morocco (tifinagh)
++% Berber Language Locale for Morocco (tifinagh)
+ % Source:
+ % Contact: Pablo Saratxaga
+ % Email: <pablo@mandrakesoft.com>
+@@ -20,14 +20,14 @@ escape_char /
+ % Users: general
+ 
+ LC_IDENTIFICATION
+-title "Amazigh language locale for Morocco (tifinagh)"
++title "Berber language locale for Morocco (tifinagh)"
+ source ""
+ address ""
+ contact "Pablo Saratxaga"
+ email "pablo@mandrakesoft.com"
+ tel ""
+ fax ""
+-language "Amazigh"
++language "Berber"
+ territory "Morocco"
+ revision "0.1"
+ date "2002-06-26"
+@@ -204,6 +204,8 @@ LC_ADDRESS
+ % This is the ISO_IEC TR14652 Locale definition for the
+ % LC_ADDRESS
+ postal_fmt  "%z%c%T%s%b%e%r"
++% https://en.wikipedia.org/wiki/Morocco ⵜⴰⴳⵍⴷⵉⵜ ⵏ ⵍⵎⵖⵔⵉⴱ
++country_name "<U2D5C><U2D30><U2D33><U2D4D><U2D37><U2D49><U2D5C> <U2D4F> <U2D4D><U2D4E><U2D56><U2D54><U2D49><U2D31>"
+ %country_post ""
+ country_ab2 "MA"
+ country_ab3 "MAR"
+@@ -211,7 +213,7 @@ country_num 504
+ %country_isbn ""
+ country_car  "MA"
+ % ⵜⴰⵎⴰⵣⵉⵖⵜ
+-lang_name "<U2D5C><U2D30><U2D4E><U2D30><U2D49><U2D56><U2D5C>"
++lang_name "<U2D5C><U2D30><U2D4E><U2D30><U2D63><U2D49><U2D56><U2D5C>"
+ % lang_ab
+ lang_term "ber"
+ lang_lib "ber"
+diff --git a/localedata/locales/bhb_IN b/localedata/locales/bhb_IN
+index 549974de2cfd4843..80d590d068582de6 100644
+--- a/localedata/locales/bhb_IN
++++ b/localedata/locales/bhb_IN
+@@ -145,11 +145,13 @@ LC_ADDRESS
+ % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category
+ % generated by IBM Basic CountryPack Transformer.
+ postal_fmt "%z%c%T%s%b%e%r"
++country_name "<U092D><U093E><U0930><U0924>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_car "IND"
+ country_num 356
+-lang_name     "bhili"
++% भीली
++lang_name     "<U092D><U0940><U0932><U0940>"
+ lang_ab       ""
+ lang_term     "bhb"
+ lang_lib      "bhb"
+diff --git a/localedata/locales/bho_IN b/localedata/locales/bho_IN
+index 99a91c2553ecdeae..4a0f25d6aceaa023 100644
+--- a/localedata/locales/bho_IN
++++ b/localedata/locales/bho_IN
+@@ -147,6 +147,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt  "%z%c%T%s%b%e%r"
++country_name "<U092D><U093E><U0930><U0924>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+diff --git a/localedata/locales/chr_US b/localedata/locales/chr_US
+index 290d1b24551dd3ba..86868c02e9ae2e1c 100644
+--- a/localedata/locales/chr_US
++++ b/localedata/locales/chr_US
+@@ -113,7 +113,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt "%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N"
+-country_name "<U13A0><U13B9><U13F0><U13DF>"
++country_name "<U13CC><U13CA><U0020><U13A2><U13F3><U13BE><U13B5><U13CD><U13D4><U13C5><U0020><U13CD><U13A6><U13DA><U13A9>"
+ country_post "USA"
+ country_ab2  "US"
+ country_ab3  "USA"
+diff --git a/localedata/locales/crh_UA b/localedata/locales/crh_UA
+index b2ac8c66d78521b0..86281a27db1cc64d 100644
+--- a/localedata/locales/crh_UA
++++ b/localedata/locales/crh_UA
+@@ -198,8 +198,8 @@ country_ab2 "UA"
+ country_ab3 "UKR"
+ country_num 804
+ country_car  "UA"
+-% Qırımtatarca
+-lang_name    "Q<U0131>r<U0131>mtatarca"
++% qırımtatar tili
++lang_name    "q<U0131>r<U0131>mtatar tili"
+ lang_term    "crh"
+ lang_lib    "crh"
+ END LC_ADDRESS
+diff --git a/localedata/locales/csb_PL b/localedata/locales/csb_PL
+index c8572f8fc54853b3..662dcefa15a2cae3 100644
+--- a/localedata/locales/csb_PL
++++ b/localedata/locales/csb_PL
+@@ -210,6 +210,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
++country_name "P<U00F2>lsk<U00F4>"
+ country_ab2 "PL"
+ country_ab3 "POL"
+ country_num 616
+diff --git a/localedata/locales/doi_IN b/localedata/locales/doi_IN
+index 0428ae50a9bf60e8..df9dfc6e2a428abb 100644
+--- a/localedata/locales/doi_IN
++++ b/localedata/locales/doi_IN
+@@ -156,6 +156,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt  "%z%c%T%s%b%e%r"
++country_name "<U092D><U093E><U0930><U0924>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+diff --git a/localedata/locales/dv_MV b/localedata/locales/dv_MV
+index 0d7842f39f7edf85..ab78fa5ce33cfe0e 100644
+--- a/localedata/locales/dv_MV
++++ b/localedata/locales/dv_MV
+@@ -182,9 +182,8 @@ country_ab2 "MV"
+ country_ab3 "MDV"
+ country_num 462
+ country_car "MV"
+-% lang_name FIXME
+-% Cannot represent Dhivehi in Thaana script
+-% http://en.wikipedia.org/wiki/Maldivian_language
++% ދިވެހި
++lang_name    "<U078B><U07A8><U0788><U07AC><U0780><U07A8>"
+ lang_ab      "dv"
+ lang_term    "div"
+ lang_lib    "div"
+diff --git a/localedata/locales/eo b/localedata/locales/eo
+index 33a81033e23caadd..b2ad5758004b67d8 100644
+--- a/localedata/locales/eo
++++ b/localedata/locales/eo
+@@ -206,7 +206,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt   "%f%N%a%N%d%N%b%N%s %h %e %r%N%%z %T%N%c%N"
+-lang_name    "Esperanto"
++lang_name    "esperanto"
+ lang_ab      "eo"
+ lang_term    "epo"
+ END LC_ADDRESS
+diff --git a/localedata/locales/hak_TW b/localedata/locales/hak_TW
+index f62937e91b634416..87f2a00489d1574e 100644
+--- a/localedata/locales/hak_TW
++++ b/localedata/locales/hak_TW
+@@ -187,8 +187,8 @@ country_ab3  "TWN"
+ country_num  158
+ country_car "RC"
+ country_isbn 957
+-% 漢語客家語
+-lang_name    "<U6F22><U8A9E><U5BA2><U5BB6><U8A9E>"
++% 客家語
++lang_name    "<U5BA2><U5BB6><U8A71>"
+ lang_term    "hak"
+ lang_lib     "hak"
+ END LC_ADDRESS
+diff --git a/localedata/locales/hif_FJ b/localedata/locales/hif_FJ
+index 5433bb4a2a54636e..a6868b791025c8f4 100644
+--- a/localedata/locales/hif_FJ
++++ b/localedata/locales/hif_FJ
+@@ -176,7 +176,8 @@ country_car  "FJI"
+ country_num 242
+ % https://en.wikipedia.org/wiki/ISO_3166-1_numeric
+ % https://en.wikipedia.org/wiki/Fiji_Hindi
+-lang_name    "Fiji Baat"
++% फ़िजी बात
++lang_name    "<U0939><U093F><U0928><U094D><U0926><U0940>"
+ % iso-639-1
+ lang_ab      ""
+ % iso-639-3
+diff --git a/localedata/locales/hne_IN b/localedata/locales/hne_IN
+index 7abec636304b9e67..d8b83610165a6844 100644
+--- a/localedata/locales/hne_IN
++++ b/localedata/locales/hne_IN
+@@ -154,6 +154,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt  "%z%c%T%s%b%e%r"
++country_name "<U092D><U093E><U0930><U0924>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+diff --git a/localedata/locales/ia_FR b/localedata/locales/ia_FR
+index f3fbf213a3f7f267..4ce7c7fe4a416541 100644
+--- a/localedata/locales/ia_FR
++++ b/localedata/locales/ia_FR
+@@ -127,7 +127,7 @@ country_ab3 "FRA"
+ country_num 250
+ country_isbn "979-10"
+ country_car "F"
+-lang_name "Interlingua"
++lang_name "interlingua"
+ lang_ab      "ia"
+ lang_term    "ina"
+ lang_lib     "ina"
+diff --git a/localedata/locales/id_ID b/localedata/locales/id_ID
+index 3ddd8d07daed6697..92ff81df23b059a0 100644
+--- a/localedata/locales/id_ID
++++ b/localedata/locales/id_ID
+@@ -155,7 +155,7 @@ country_ab2 "ID"
+ country_ab3 "IDN"
+ country_num 360
+ country_car    "RI"
+-lang_name    "Bahasa Indonesia"
++lang_name    "Indonesia"
+ lang_ab      "id"
+ lang_term    "ind"
+ lang_lib    "ind"
+diff --git a/localedata/locales/ig_NG b/localedata/locales/ig_NG
+index bddd2ccde523dca8..113294a0f58ab576 100644
+--- a/localedata/locales/ig_NG
++++ b/localedata/locales/ig_NG
+@@ -321,11 +321,11 @@ LC_ADDRESS
+ % "end of line
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
+ 
+-% Country name in Igbo - "Nigeria"
+-country_name  "Nigeria"
++% Country name in Igbo - "Naịjịrịa"
++country_name  "Na<U1ECB>j<U1ECB>r<U1ECB>a"
+ 
+-% Language name in Igbo - "Igbo"
+-lang_name     "Igbo"
++% Language name in Igbo - "Asụsụ Igbo"
++lang_name     "As<U1EE5>s<U1EE5> Igbo"
+ 
+ % CEPT MAILCODES are suggested
+ % Alternatively use the code found on your countries postal item tracking number
+diff --git a/localedata/locales/kab_DZ b/localedata/locales/kab_DZ
+index a165f53f01370c94..ef572357c22615f7 100644
+--- a/localedata/locales/kab_DZ
++++ b/localedata/locales/kab_DZ
+@@ -154,7 +154,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt   "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
+-country_name "Zzayer"
++country_name "Lezzayer"
+ country_ab2  "DZ"
+ country_ab3  "DZA"
+ country_num  012
+diff --git a/localedata/locales/ks_IN b/localedata/locales/ks_IN
+index 6992a5536887d9f6..e1efea342d4b55a0 100644
+--- a/localedata/locales/ks_IN
++++ b/localedata/locales/ks_IN
+@@ -167,7 +167,7 @@ LC_ADDRESS
+ % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category
+ % generated by IBM Basic CountryPack Transformer.
+ postal_fmt  "%z%c%T%s%b%e%r"
+-country_name "<U06C1><U0650><U0646><U065B><U062F><U0648><U0633><U062A><U0627><U0646>"
++country_name "<U06C1><U0650><U0646><U062F><U0648><U0633><U062A><U0627><U0646>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+diff --git a/localedata/locales/ku_TR b/localedata/locales/ku_TR
+index 595cdb14bc9ef29d..f6a8925608ea046d 100644
+--- a/localedata/locales/ku_TR
++++ b/localedata/locales/ku_TR
+@@ -182,14 +182,14 @@ END LC_NAME
+ LC_ADDRESS
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
+ % TODO
+-country_name "Turkey"
++country_name "Tirkiye"
+ country_post "TR"
+ country_ab2  "TR"
+ country_ab3  "TUR"
+ country_num  792
+ country_isbn 975
+ country_car    "TR"
+-lang_name   "kurdi"
++lang_name   "kurd<U00EE>"
+ lang_ab      "ku"
+ lang_term    "kur"
+ lang_lib     "kur"
+diff --git a/localedata/locales/mag_IN b/localedata/locales/mag_IN
+index b8f65f70e26f4481..c86d9ba075ef2577 100644
+--- a/localedata/locales/mag_IN
++++ b/localedata/locales/mag_IN
+@@ -152,6 +152,7 @@ END LC_NAME
+ LC_ADDRESS
+ 
+ postal_fmt  "%z%c%T%s%b%e%r"
++country_name "<U092D><U093E><U0930><U0924>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+diff --git a/localedata/locales/mfe_MU b/localedata/locales/mfe_MU
+index 7415e9250fb78d50..7fabc5f80d9ae5e5 100644
+--- a/localedata/locales/mfe_MU
++++ b/localedata/locales/mfe_MU
+@@ -170,7 +170,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt   "%f%N%h%s%N%T"
+-country_name "Mauritius"
++country_name "Moris"
+ country_ab2  "MU"
+ country_ab3  "MUS"
+ country_num  480
+diff --git a/localedata/locales/mhr_RU b/localedata/locales/mhr_RU
+index 85ac21b35af25c87..02bec3e9aed6fddc 100644
+--- a/localedata/locales/mhr_RU
++++ b/localedata/locales/mhr_RU
+@@ -159,6 +159,8 @@ country_ab2 "RU"
+ country_ab3 "RUS"
+ country_num 643
+ country_car    "RUS"
++% марий йылме
++lang_name    "<U043C><U0430><U0440><U0438><U0439> <U0439><U044B><U043B><U043C><U0435>"
+ lang_term    "mhr"
+ lang_lib    "mhr"
+ END LC_ADDRESS
+diff --git a/localedata/locales/mi_NZ b/localedata/locales/mi_NZ
+index 782f02359cb096d4..d08bc249427581c2 100644
+--- a/localedata/locales/mi_NZ
++++ b/localedata/locales/mi_NZ
+@@ -157,7 +157,7 @@ country_ab2   "NZ"
+ country_ab3   "NZL"
+ country_num   554
+ country_car   "NZ"
+-lang_name    "Te Reo"
++lang_name    "M<U0101>ori"
+ lang_ab      "mi"
+ lang_term    "mri"
+ lang_lib    "mao"
+diff --git a/localedata/locales/ms_MY b/localedata/locales/ms_MY
+index 66b5dd98e99e5da3..8ffe9156b6e3d022 100644
+--- a/localedata/locales/ms_MY
++++ b/localedata/locales/ms_MY
+@@ -184,7 +184,7 @@ country_ab3 "MYS"
+ country_num 458
+ country_car "MAL"
+ % Bahasa Melayu
+-lang_name    "Bahasa Melayu"
++lang_name    "Melayu"
+ lang_ab      "ms"
+ lang_term    "msa"
+ lang_lib    "may"
+diff --git a/localedata/locales/my_MM b/localedata/locales/my_MM
+index d612e5305aff7e2b..846363223883723b 100644
+--- a/localedata/locales/my_MM
++++ b/localedata/locales/my_MM
+@@ -309,7 +309,8 @@ country_ab2     "MM"
+ country_num 104
+ country_car "MYA"
+ lang_ab         "my"
+-lang_name       "<U1017><U1019><U102C>"
++% မြန်မာ
++lang_name       "<U1019><U103C><U1014><U103A><U1019><U102C>"
+ lang_term   "mya"
+ lang_lib    "bur"
+ END LC_ADDRESS
+diff --git a/localedata/locales/nan_TW b/localedata/locales/nan_TW
+index f5bc5d1642c2ce9b..53884e02ffd16d2c 100644
+--- a/localedata/locales/nan_TW
++++ b/localedata/locales/nan_TW
+@@ -188,8 +188,8 @@ country_ab3  "TWN"
+ country_num  158
+ country_car "RC"
+ country_isbn 957
+-% 漢語閩南語
+-lang_name    "<U6F22><U8A9E><U95A9><U5357><U8A9E>"
++% 閩南語
++lang_name    "<U95A9><U5357><U8A9E>"
+ lang_term    "nan"
+ lang_lib     "nan"
+ END LC_ADDRESS
+diff --git a/localedata/locales/nan_TW@latin b/localedata/locales/nan_TW@latin
+index d4579a4cdf032d4c..104f4152a98b37ab 100644
+--- a/localedata/locales/nan_TW@latin
++++ b/localedata/locales/nan_TW@latin
+@@ -165,8 +165,8 @@ country_ab3	"TWN"
+ country_num	158
+ country_car "RC"
+ country_isbn	957
+-%lang_name "Bân-lâm-gú, Hō-ló-oē"
+-lang_name "B<U00E2>n-l<U00E2>m-g<U00FA>, H<U014D>-l<U00F3>-o<U0113>"
++%lang_name "Bân-lâm-gú"
++lang_name "B<U00E2>n-l<U00E2>m-g<U00FA>"
+ lang_term "nan"
+ lang_lib "nan"
+ END LC_ADDRESS
+diff --git a/localedata/locales/nds_DE b/localedata/locales/nds_DE
+index 232f9e4455ca74cc..d6200b7972b6b820 100644
+--- a/localedata/locales/nds_DE
++++ b/localedata/locales/nds_DE
+@@ -45,7 +45,7 @@ country_ab3   "DEU"
+ country_car   "D"
+ country_num 276
+ country_isbn "3"
+-lang_name "Neddersassisch"
++lang_name "Neddersass<U2019>sch"
+ %lang_ab
+ lang_term "nds"
+ lang_lib "nds"
+diff --git a/localedata/locales/nds_NL b/localedata/locales/nds_NL
+index 8c8bebd93530938f..9fd50fb6256d3823 100644
+--- a/localedata/locales/nds_NL
++++ b/localedata/locales/nds_NL
+@@ -44,7 +44,7 @@ country_ab3 "NLD"
+ country_car "NL"
+ country_num 528
+ country_isbn "3"
+-lang_name "Neddersassisch"
++lang_name "Neddersass<U2019>sch"
+ %lang_ab
+ lang_term "nds"
+ lang_lib "nds"
+diff --git a/localedata/locales/nhn_MX b/localedata/locales/nhn_MX
+index 88a89765e88f060b..2dbfcb3c6572cd0c 100644
+--- a/localedata/locales/nhn_MX
++++ b/localedata/locales/nhn_MX
+@@ -133,11 +133,12 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
++country_name  "Mexihco"
+ country_ab2   "MX"
+ country_ab3   "MEX"
+ country_num   484
+ country_car    "MEX"
+-lang_name    "Tlaxcala-Puebla Nahuatl"
++lang_name    "Tlahco n<U0101>huatlaht<U014D>lli"
+ lang_term    "nhn"
+ lang_lib    "nhn"
+ END LC_ADDRESS
+diff --git a/localedata/locales/niu_NU b/localedata/locales/niu_NU
+index 553c5d9edcddfc86..387e109109fc0374 100644
+--- a/localedata/locales/niu_NU
++++ b/localedata/locales/niu_NU
+@@ -163,10 +163,12 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt   "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
++country_name "Niu<U0113>"
+ country_post "NU"
+ country_ab2  "NU"
+ country_ab3  "NIU"
+ country_num  570
++lang_name    "ko e vagahau Niu<U0113>"
+ lang_term    "niu"
+ lang_lib    "niu"
+ END LC_ADDRESS
+diff --git a/localedata/locales/niu_NZ b/localedata/locales/niu_NZ
+index 560101b447c22251..2eba7d2630f8a46d 100644
+--- a/localedata/locales/niu_NZ
++++ b/localedata/locales/niu_NZ
+@@ -99,6 +99,7 @@ country_ab2  "NZ"
+ country_ab3  "NZL"
+ country_num  554
+ country_car    "NZ"
++lang_name    "ko e vagahau Niu<U0113>"
+ lang_term    "niu"
+ lang_lib    "niu"
+ END LC_ADDRESS
+diff --git a/localedata/locales/nr_ZA b/localedata/locales/nr_ZA
+index 7de6420a6b52977e..f64434fadbad4e69 100644
+--- a/localedata/locales/nr_ZA
++++ b/localedata/locales/nr_ZA
+@@ -225,7 +225,7 @@ country_car   "ZA"
+ country_num 710
+ 
+ % Language name in Southern Ndebele
+-lang_name "IsiNdebele"
++lang_name "isiNdebele"
+ 
+ % ISO 639 two and three letter language names
+ % see http://www.loc.gov/standards/iso639-2/englangn.html
+diff --git a/localedata/locales/oc_FR b/localedata/locales/oc_FR
+index 707927ee2662ac91..a106f8d1c1152959 100644
+--- a/localedata/locales/oc_FR
++++ b/localedata/locales/oc_FR
+@@ -44,7 +44,7 @@ country_ab3 "FRA"
+ country_num 250
+ country_isbn "979-10"
+ country_car "F"
+-lang_name    "Occitan"
++lang_name    "occitan"
+ lang_ab      "oc"
+ lang_term    "oci"
+ lang_lib     "oci"
+diff --git a/localedata/locales/or_IN b/localedata/locales/or_IN
+index ef28b58895c342b6..2e4975e7b710b592 100644
+--- a/localedata/locales/or_IN
++++ b/localedata/locales/or_IN
+@@ -20,7 +20,7 @@ contact     ""
+ email       "bug-glibc@gnu.org"
+ tel         ""
+ fax         ""
+-language    "Oriya"
++language    "Odia"
+ territory   "India"
+ revision    "1.0"
+ date        "2006-05-25"
+diff --git a/localedata/locales/pa_PK b/localedata/locales/pa_PK
+index 1f49bdc90d7ce637..0a584114b8f06590 100644
+--- a/localedata/locales/pa_PK
++++ b/localedata/locales/pa_PK
+@@ -173,7 +173,7 @@ END LC_NAME
+ LC_ADDRESS
+ % FIXME
+ postal_fmt    "%a%N%f%N%d%N%b%N%h %s %e %r%N%T %z%N%c%N"
+-country_name "<U0A2A><U0A3E><U0A15><U0A3F><U0A38><U0A24><U0A3E><U0A28>"
++country_name "<U067E><U06A9><U0633><U062A><U0627><U0646>"
+ country_ab2 "PK"
+ country_ab3 "PAK"
+ country_num 586
+diff --git a/localedata/locales/ps_AF b/localedata/locales/ps_AF
+index 66f560ef4406be61..23dc86dcf1c1453b 100644
+--- a/localedata/locales/ps_AF
++++ b/localedata/locales/ps_AF
+@@ -308,8 +308,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt	"%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"
+-country_name	"<U0627><U0641><U063A><U0627><U0646>/
+-<U0633><U062A><U0627><U0646>"
++country_name	"<U0627><U0641><U063A><U0627><U0646><U0633><U062A><U0627><U0646>"
+ country_post	"AF"
+ country_ab2	"AF"
+ country_ab3	"AFG"
+diff --git a/localedata/locales/quz_PE b/localedata/locales/quz_PE
+index f6b1956b937100df..9ed890cbb0e6c762 100644
+--- a/localedata/locales/quz_PE
++++ b/localedata/locales/quz_PE
+@@ -10,7 +10,7 @@ escape_char /
+ 
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+-% Quechua (Cusco-Collao) language locale for Peru
++% Cusco Quechua language locale for Peru
+ %
+ % Prepared and contributed to glibc by Chris Leonard <cjl@sugarlabs.org>
+ % and Amos Batto
+@@ -25,14 +25,14 @@ escape_char /
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ 
+ LC_IDENTIFICATION
+-title        "Quechua (Cusco-Collao) locale for Peru"
++title        "Cusco Quechua locale for Peru"
+ source       "Sugar Labs // OLPC"
+ address      ""
+ contact      "sugarlabs.org"
+ email        "libc-alpha@sourceware.org"
+ tel          ""
+ fax          ""
+-language     "Quechua (Cusco-Collao)"
++language     "Cusco Quechua"
+ territory    "Peru"
+ revision     "1.0"
+ date         "2013-08-24"
+@@ -144,7 +144,7 @@ country_ab2   "PE"
+ country_ab3   "PER"
+ country_num   604
+ country_car   "PE"
+-lang_name    "Quechua (Cusco)"
++lang_name    "Qusqu runasimi"
+ lang_term    "quz"
+ lang_lib    "quz"
+ END LC_ADDRESS
+diff --git a/localedata/locales/raj_IN b/localedata/locales/raj_IN
+index ece080223e8de94b..ce009e406ab5c332 100644
+--- a/localedata/locales/raj_IN
++++ b/localedata/locales/raj_IN
+@@ -158,7 +158,16 @@ name_ms     "<U0915><U0941><U092E><U093E><U0930>"
+ END LC_NAME
+ 
+ LC_ADDRESS
+-copy "hi_IN"
++postal_fmt  "%z%c%T%s%b%e%r"
++country_name "<U092D><U093E><U0930><U0924>"
++country_ab2 "IN"
++country_ab3 "IND"
++country_num 356
++country_car "IND"
++% राजस्थानी
++lang_name    "<U0930><U093E><U091C><U0938><U094D><U0925><U093E><U0928><U0940>"
++lang_term    "raj"
++lang_lib    "raj"
+ END LC_ADDRESS
+ 
+ LC_TELEPHONE
+diff --git a/localedata/locales/rw_RW b/localedata/locales/rw_RW
+index e0bc763c5a484c15..31cb4673dfa4a3aa 100644
+--- a/localedata/locales/rw_RW
++++ b/localedata/locales/rw_RW
+@@ -132,7 +132,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
+-country_name   "Rwanda"
++country_name   "U Rwanda"
+ country_ab2    "RW"
+ country_ab3    "RWA"
+ country_num 646
+diff --git a/localedata/locales/sah_RU b/localedata/locales/sah_RU
+index 80f67219c39cceb2..2b5a4b7bd660fb6e 100644
+--- a/localedata/locales/sah_RU
++++ b/localedata/locales/sah_RU
+@@ -1,7 +1,7 @@
+ escape_char  /
+ comment_char  %
+ 
+-% Yakut (Sakha) locale for Russian Federation
++% Sakha (Yakut) locale for Russian Federation
+ % Source: Valery Timiriliyev
+ % Email: timiriliyev@gmail.com
+ % Tel:
+@@ -13,14 +13,14 @@ comment_char  %
+ % Users: general
+ 
+ LC_IDENTIFICATION
+-title      "Yakut (Sakha) locale for Russian Federation"
++title      "Sakha (Yakut) locale for Russian Federation"
+ source     "Valery Timiriliyev"
+ address    ""
+ contact    "Valery Timiriliyev"
+ email      "timiriliyev@gmail.com"
+ tel        ""
+ fax        ""
+-language   "Yakut"
++language   "Sakha"
+ territory  "Russian Federation"
+ revision   "1.1.0"
+ date       "2018-07-06"
+@@ -264,11 +264,11 @@ END LC_NAME
+ LC_ADDRESS
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
+ 
+-% Россия
+-country_name  "<U0420><U043E><U0441><U0441><U0438><U044F>"
++% Арассыыйа
++country_name  "<U0410><U0440><U0430><U0441><U0441><U044B><U044B><U0439><U0430>"
+ 
+-% Саха тыла
+-lang_name     "<U0421><U0430><U0445><U0430> <U0442><U044B><U043B><U0430>"
++% саха тыла
++lang_name     "<U0441><U0430><U0445><U0430><U0020><U0442><U044B><U043B><U0430>"
+ 
+ % UN Geneve 1949:68 Distinguishing signs of vehicles in international traffic
+ % RUS
+diff --git a/localedata/locales/sat_IN b/localedata/locales/sat_IN
+index 134eb8a572c836a7..e1775a4072ff7d9c 100644
+--- a/localedata/locales/sat_IN
++++ b/localedata/locales/sat_IN
+@@ -158,12 +158,13 @@ END LC_NAME
+ LC_ADDRESS
+ 
+ postal_fmt  "%z%c%T%s%b%e%r"
++country_name "<U1C65><U1C64><U1C67><U1C5A><U1C5B>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+ country_car    "IND"
+-% Satār
+-lang_name    "Sat<U0101>r"
++% ᱥᱟᱱᱛᱟᱲᱤ
++lang_name    "<U1C65><U1C5F><U1C71><U1C5B><U1C5F><U1C72><U1C64>"
+ lang_term    "sat"
+ lang_lib    "sat"
+ END LC_ADDRESS
+diff --git a/localedata/locales/sc_IT b/localedata/locales/sc_IT
+index 1488744575dae32a..32626404d2956e8c 100644
+--- a/localedata/locales/sc_IT
++++ b/localedata/locales/sc_IT
+@@ -144,7 +144,7 @@ country_ab3 "ITA"
+ country_num 380
+ country_isbn "978-88,979-12"
+ country_car  "I"
+-lang_name    "Sardu"
++lang_name    "sardu"
+ lang_ab      "sc"
+ lang_term    "srd"
+ lang_lib    "srd"
+diff --git a/localedata/locales/sd_IN b/localedata/locales/sd_IN
+index 66aa0e254cefe0d7..64c5366c31dcd818 100644
+--- a/localedata/locales/sd_IN
++++ b/localedata/locales/sd_IN
+@@ -164,12 +164,14 @@ LC_ADDRESS
+ % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category
+ % generated by IBM Basic CountryPack Transformer.
+ postal_fmt  "%z%c%T%s%b%e%r"
+-% https://sd.wikipedia.org/wiki/%DA%80%D8%A7%D8%B1%D8%AA : "ڀارت"
+-country_name "<U0680><U0627><U0631><U062A>"
++% From cldr: انڊيا
++country_name "<U0627><U0646><U068A><U064A><U0627>"
+ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+ country_car    "IND"
++% سنڌي
++lang_name    "<U0633><U0646><U068C><U064A>"
+ lang_ab      "sd"
+ lang_term    "snd"
+ lang_lib    "snd"
+diff --git a/localedata/locales/sd_IN@devanagari b/localedata/locales/sd_IN@devanagari
+index b1ce87df93f9c3d6..97357e08559ea64f 100644
+--- a/localedata/locales/sd_IN@devanagari
++++ b/localedata/locales/sd_IN@devanagari
+@@ -167,6 +167,8 @@ country_ab2 "IN"
+ country_ab3 "IND"
+ country_num 356
+ country_car    "IND"
++% सिन्धी
++lang_name    "<U0938><U093F><U0928><U094D><U0927><U0940>"
+ lang_ab      "sd"
+ lang_term    "snd"
+ lang_lib    "snd"
+diff --git a/localedata/locales/shn_MM b/localedata/locales/shn_MM
+index 4212c50ec5ae0066..a837f5fb394b1bb5 100644
+--- a/localedata/locales/shn_MM
++++ b/localedata/locales/shn_MM
+@@ -281,7 +281,8 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt   "%a%N%d%N%f%N%b%N%h%t%r%t%e%t%s%N%T%t%z%N%c%N"
+-country_name "<U1019><U1062><U107C><U103A><U1088>"
++% https://shn.wikipedia.org/wiki/%E1%80%99%E1%80%AD%E1%80%B0%E1%80%84%E1%80%BA%E1%80%B8%E1%80%99%E1%81%A2%E1%81%BC%E1%80%BA%E1%82%88 မိူင်းမၢၼ်ႈ
++country_name "<U1019><U102D><U1030><U1004><U103A><U1038><U1019><U1062><U107C><U103A><U1088>"
+ country_post "Myanmar"
+ country_ab2  "MM"
+ country_num  104
+diff --git a/localedata/locales/shs_CA b/localedata/locales/shs_CA
+index a5b675a316945608..ab48d600ef72ba75 100644
+--- a/localedata/locales/shs_CA
++++ b/localedata/locales/shs_CA
+@@ -8,7 +8,7 @@ escape_char /
+ % exempt you from the conditions of the license if your use would
+ % otherwise be governed by that license.
+ 
+-% Secwepemctsin (Shuswap) language locale for Canada
++% Shuswap language locale for Canada
+ % sorting according to CAN/CSA-Z243.4.1-1992
+ % Source: Neskie Manuel
+ % Address: 745 Ska-Hiish Dr
+@@ -25,14 +25,14 @@ escape_char /
+ % Users: general
+ 
+ LC_IDENTIFICATION
+-title      "Secwepemctsin locale for Canada"
++title      "Shuswap locale for Canada"
+ source     "Neskie Manuel"
+ address    "745 Ska-Hiish Dr, Chase BC V0E 1M3"
+ contact    ""
+ email      "bug-glibc-locales@gnu.org"
+ tel        ""
+ fax        ""
+-language   "Secwepemctsin"
++language   "Shuswap"
+ territory  "Canada"
+ revision   "1.0"
+ date       "2008-01-15"
+@@ -155,7 +155,7 @@ country_ab2 "CA"
+ country_ab3 "CAN"
+ country_num 124
+ country_car    "CDN"
+-lang_name "Secwepemctsin"
++lang_name "Secwepemcts<U00ED>n"
+ lang_term "shs"
+ lang_lib "shs"
+ END LC_ADDRESS
+diff --git a/localedata/locales/sm_WS b/localedata/locales/sm_WS
+index 6058fbdc38283bb2..2823005c0635b6cf 100644
+--- a/localedata/locales/sm_WS
++++ b/localedata/locales/sm_WS
+@@ -159,7 +159,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt    "%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N"
+-country_name "Samoa"
++country_name "S<U0101>moa"
+ country_post "%a %N   %f %N   %d %N   %b %N   %h %s %e %/
+ r %N   %T, %c  %N"
+ % http://laendercode.net/en/2-letter-list.html
+diff --git a/localedata/locales/ss_ZA b/localedata/locales/ss_ZA
+index 7532a1940b3556f9..8e08a85f461aed9b 100644
+--- a/localedata/locales/ss_ZA
++++ b/localedata/locales/ss_ZA
+@@ -228,7 +228,7 @@ country_car   "ZA"
+ % country_isbn ""
+ 
+ % Language name in Swati
+-lang_name "SiSwati"
++lang_name "siSwati"
+ 
+ % ISO 639 two and three letter language names
+ % see http://www.loc.gov/standards/iso639-2/englangn.html
+diff --git a/localedata/locales/szl_PL b/localedata/locales/szl_PL
+index 8d5de2112e54b7ad..88f1df4e905c5bdf 100644
+--- a/localedata/locales/szl_PL
++++ b/localedata/locales/szl_PL
+@@ -188,6 +188,7 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
++country_name "Polska"
+ country_ab2 "PL"
+ country_ab3 "POL"
+ country_num 616
+diff --git a/localedata/locales/te_IN b/localedata/locales/te_IN
+index fb5bb21b09ae0647..cb1b1109690b20bb 100644
+--- a/localedata/locales/te_IN
++++ b/localedata/locales/te_IN
+@@ -177,7 +177,7 @@ LC_ADDRESS
+ % generated by IBM Basic CountryPack Transformer.
+ 
+ postal_fmt      "%a%N%d%N%f%N%r%t%e%N%h%t%b%N%s%t%N%T%t%z%N%S%N%c"
+-country_name    "<U0C2D><U0C3E><U0C30><U0C24> <U0C26><U0C47><U0C36><U0C02>"
++country_name    "<U0C2D><U0C3E><U0C30><U0C24><U0C26><U0C47><U0C36><U0C02>"
+ country_ab2     "IN"
+ country_ab3     "IND"
+ country_num     356
+diff --git a/localedata/locales/tg_TJ b/localedata/locales/tg_TJ
+index 35dfca4574d4b5b9..6d1e4d8ab339501f 100644
+--- a/localedata/locales/tg_TJ
++++ b/localedata/locales/tg_TJ
+@@ -222,6 +222,8 @@ country_ab2 "TJ"
+ country_ab3 "TJK"
+ country_num 762
+ country_car    "TJ"
++% тоҷикӣ
++lang_name    "<U0442><U043E><U04B7><U0438><U043A><U04E3>"
+ lang_ab      "tg"
+ lang_term    "tgk"
+ lang_lib    "tgk"
+diff --git a/localedata/locales/the_NP b/localedata/locales/the_NP
+index 993e62fbfc5cea64..296e9970885ee490 100644
+--- a/localedata/locales/the_NP
++++ b/localedata/locales/the_NP
+@@ -162,10 +162,14 @@ LC_ADDRESS
+ postal_fmt  "%z%c%T%s%b%e%r"
+ lang_term    "the"
+ lang_lib     "the"
++% नेपाल
++country_name "<U0928><U0947><U092A><U093E><U0932>"
+ country_ab2 "NP"
+ country_ab3 "NPL"
+ country_num 524
+ country_car "NEP"
++% थारु
++lang_name   "<U0925><U093E><U0930><U0941>"
+ END LC_ADDRESS
+ 
+ 
+diff --git a/localedata/locales/tk_TM b/localedata/locales/tk_TM
+index 410afaf6c76c920b..e29ae20408763196 100644
+--- a/localedata/locales/tk_TM
++++ b/localedata/locales/tk_TM
+@@ -399,7 +399,7 @@ country_num  795
+ country_ab2 "TM"
+ country_ab3 "TKM"
+ % Türkmençe
+-lang_name   "t<U00FC>rkmen<U00E7>e"
++lang_name   "t<U00FC>rkmen dili"
+ lang_term   "tuk"
+ lang_lib    "tuk"
+ lang_ab     "tk"
+diff --git a/localedata/locales/tl_PH b/localedata/locales/tl_PH
+index 40fd71d96095be12..03b8350749ab2c0a 100644
+--- a/localedata/locales/tl_PH
++++ b/localedata/locales/tl_PH
+@@ -138,6 +138,7 @@ country_ab2 "PH"
+ country_ab3 "PHL"
+ country_num 608
+ country_car    "RP"
++lang_name    "Tagalog"
+ lang_ab      "tl"
+ lang_term    "tgl"
+ lang_lib    "tgl"
+diff --git a/localedata/locales/to_TO b/localedata/locales/to_TO
+index 7abe8685df8488cf..403a1219126bb189 100644
+--- a/localedata/locales/to_TO
++++ b/localedata/locales/to_TO
+@@ -169,7 +169,7 @@ country_ab3  "TON"
+ country_car  "TON"
+ country_num 776
+ % Tongan
+-lang_name    "Tonga<U000A>"
++lang_name    "lea fakatonga"
+ % https://en.wikipedia.org/wiki/Tongan_language
+ lang_ab      "to"
+ lang_term    "ton"
+diff --git a/localedata/locales/tpi_PG b/localedata/locales/tpi_PG
+index 3315c27633ba58c6..885481974c8b531b 100644
+--- a/localedata/locales/tpi_PG
++++ b/localedata/locales/tpi_PG
+@@ -172,7 +172,8 @@ END LC_NAME
+ LC_ADDRESS
+ % http://www.addressexamples.com/papua-new-guinea-address-format/
+ postal_fmt    "%a%s%z%C"
+-country_name "Papua New Guinea"
++% https://tpi.wikipedia.org/wiki/Papua_Niugini
++country_name "Papua Niugini"
+ country_post ""
+ country_ab2  "PG"
+ country_ab3  "PNG"
+@@ -180,7 +181,7 @@ country_car  "PNG"
+ % https://en.wikipedia.org/wiki/ISO_3166-1_numeric
+ country_num 598
+ % Tok Pisin
+-lang_name    "Tok  Pisin"
++lang_name    "Tok Pisin"
+ % https://en.wikipedia.org/wiki/Tok_Pisin
+ lang_ab      ""
+ lang_term    "tpi"
+diff --git a/localedata/locales/tt_RU@iqtelif b/localedata/locales/tt_RU@iqtelif
+index d4737c888e41352b..b52b1299946f372f 100644
+--- a/localedata/locales/tt_RU@iqtelif
++++ b/localedata/locales/tt_RU@iqtelif
+@@ -155,10 +155,12 @@ END LC_MEASUREMENT
+ 
+ LC_ADDRESS
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
++country_name  "Ur<U0131>s Pat<U015F>ahl<U0131>q"
+ country_ab2 "RU"
+ country_ab3 "RUS"
+ country_num 643
+ country_car    "RUS"
++lang_name    "tatar tele"
+ lang_ab      "tt"
+ lang_term    "tat"
+ lang_lib    "tat"
+diff --git a/localedata/locales/ug_CN b/localedata/locales/ug_CN
+index 1ba583c588e074d2..acb8b68239c4a653 100644
+--- a/localedata/locales/ug_CN
++++ b/localedata/locales/ug_CN
+@@ -195,6 +195,8 @@ country_ab3	"CHN"
+ country_num	156
+ country_car "CHN"
+ country_isbn	7
++% ئۇيغۇرچە
++lang_name    "<U0626><U06C7><U064A><U063A><U06C7><U0631><U0686><U06D5>"
+ lang_ab      "ug"
+ lang_term    "uig"
+ lang_lib    "uig"
+diff --git a/localedata/locales/unm_US b/localedata/locales/unm_US
+index 1e62c60443b83ec6..ef458e22dc195809 100644
+--- a/localedata/locales/unm_US
++++ b/localedata/locales/unm_US
+@@ -139,7 +139,7 @@ country_ab3   "USA"
+ country_num   840
+ country_car   "USA"
+ country_isbn  0
+-% lang_name     ""
++lang_name     "Lenape"
+ % lang_ab       ""
+ lang_term    "unm"
+ lang_lib    "unm"
+diff --git a/localedata/locales/wa_BE b/localedata/locales/wa_BE
+index e97493089eb287b0..afec10f41c8b1612 100644
+--- a/localedata/locales/wa_BE
++++ b/localedata/locales/wa_BE
+@@ -44,7 +44,7 @@ country_ab3 "BEL"
+ country_num 056
+ country_isbn "2"
+ country_car  "B"
+-lang_name "Walon"
++lang_name "walon"
+ lang_ab      "wa"
+ lang_term    "wln"
+ lang_lib     "wln"
+diff --git a/localedata/locales/wo_SN b/localedata/locales/wo_SN
+index 47263d2eab6db94e..20190925034c9ab4 100644
+--- a/localedata/locales/wo_SN
++++ b/localedata/locales/wo_SN
+@@ -161,6 +161,7 @@ country_ab2 "SN"
+ country_ab3 "SEN"
+ country_num 686
+ country_car "SN"
++lang_name    "Wolof"
+ lang_ab      "wo"
+ lang_term    "wol"
+ lang_lib    "wol"
+diff --git a/localedata/locales/xh_ZA b/localedata/locales/xh_ZA
+index 4564137e851b0cda..327f7250987aaa57 100644
+--- a/localedata/locales/xh_ZA
++++ b/localedata/locales/xh_ZA
+@@ -209,13 +209,13 @@ END LC_NAME
+ 
+ LC_ADDRESS
+ % https://xh.wikipedia.org/wiki/UMzantsi_Afrika
+-country_name "UMzantsi Afrika"
++country_name "uMzantsi Afrika"
+ %
+ % Abbreviated country postal name
+ country_post "ZA"
+ %
+ % Language name in Sotho
+-lang_name "IsiXhosa"
++lang_name "isiXhosa"
+ 
+ % UN Geneve 1949:68 Distinguishing signs of vehicles in international traffic
+ % http://www.unece.org/trans/conventn/disting-signs-5-2001.pdf
+diff --git a/localedata/locales/yo_NG b/localedata/locales/yo_NG
+index ec72d078bb7eab6d..a3102270bf0fd38b 100644
+--- a/localedata/locales/yo_NG
++++ b/localedata/locales/yo_NG
+@@ -271,8 +271,8 @@ LC_ADDRESS
+ % "country designation for the <country_post> keyword",
+ % "end of line
+ postal_fmt    "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N"
+-
+-country_name "Or<U00ED>l<U1EB9><U0301><U00E8>de N<U00E0><U00EC>j<U00ED>r<U00ED><U00E0>"
++% https://yo.wikipedia.org/wiki/N%C3%A0%C3%ACj%C3%ADr%C3%AD%C3%A0 and CLDR: Orilẹ̀-èdè Nàìjíríà
++country_name "Oril<U1EB9><U0300><U002D><U00E8>d<U00E8> N<U00E0><U00EC>j<U00ED>r<U00ED><U00E0>"
+ 
+ % Language name in Yoruba - "Yorùbá"
+ lang_name     "<U00C8>d<U00E8> Yor<U00F9>b<U00E1>"
+diff --git a/localedata/locales/yuw_PG b/localedata/locales/yuw_PG
+index 0cb3cadf4ae485a1..55e787a5cdfc559f 100644
+--- a/localedata/locales/yuw_PG
++++ b/localedata/locales/yuw_PG
+@@ -16,7 +16,7 @@ contact    "Hannah Sarvasy"
+ email      "nungon.localization@gmail.com"
+ tel        ""
+ fax        ""
+-language   "Yau/Nungon"
++language   "Yau"
+ territory  "Papua New Guinea"
+ revision   "1.0"
+ date       "2016-12-07"
+@@ -133,8 +133,8 @@ country_ab2  "PG"
+ country_ab3  "PNG"
+ % ISO 3166-1 numeric code for PNG
+ country_num 598
+-% Yau/Nungon
+-lang_name    "Yau/Nungon"
++% See: https://en.wikipedia.org/wiki/Yau_language, the endonym seems to be Uruwa
++lang_name    "Uruwa"
+ country_car  "PNG"
+ lang_ab      ""
+ lang_term    "yuw"
+diff --git a/localedata/locales/zh_HK b/localedata/locales/zh_HK
+index c130878f3d6e0ace..e8097d6ed0704670 100644
+--- a/localedata/locales/zh_HK
++++ b/localedata/locales/zh_HK
+@@ -178,6 +178,7 @@ country_ab2 "HK"
+ country_ab3 "HKG"
+ country_num 344
+ country_car "HK"
++lang_name       "<U7E41><U9AD4><U4E2D><U6587>"
+ lang_ab		"zh"
+ lang_term	"zho"
+ lang_lib	"chi"
+diff --git a/localedata/locales/zh_SG b/localedata/locales/zh_SG
+index 2427cd3ead3583dc..472843c7f77b8ed6 100644
+--- a/localedata/locales/zh_SG
++++ b/localedata/locales/zh_SG
+@@ -175,6 +175,7 @@ country_ab3 "SGP"
+ country_num 702
+ % SGP
+ country_car    "SGP"
++lang_name       "<U7B80><U4F53><U4E2D><U6587>"
+ lang_ab		"zh"
+ lang_term	"zho"
+ lang_lib	"chi"
diff --git a/SOURCES/glibc-rh1774114.patch b/SOURCES/glibc-rh1774114.patch
new file mode 100644
index 0000000..bdee317
--- /dev/null
+++ b/SOURCES/glibc-rh1774114.patch
@@ -0,0 +1,85 @@
+commit 58e8f5fd2ba47b6dc47fd4d0a35e4175c7c87aaa
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Wed Oct 9 17:46:47 2019 +0200
+
+    ldconfig: handle .dynstr located in separate segment (bug 25087)
+    
+    To determine the load offset of the DT_STRTAB section search for the
+    segment containing it, instead of using the load offset of the first
+    segment.
+
+diff --git a/elf/readelflib.c b/elf/readelflib.c
+index 5a1e2dc2dfa36599..8774e779f5abbfbb 100644
+--- a/elf/readelflib.c
++++ b/elf/readelflib.c
+@@ -45,7 +45,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
+ {
+   int i;
+   unsigned int j;
+-  ElfW(Addr) loadaddr;
+   unsigned int dynamic_addr;
+   size_t dynamic_size;
+   char *program_interpreter;
+@@ -87,7 +86,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
+      libc5/libc6.  */
+   *flag = FLAG_ELF;
+ 
+-  loadaddr = -1;
+   dynamic_addr = 0;
+   dynamic_size = 0;
+   program_interpreter = NULL;
+@@ -98,11 +96,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
+ 
+       switch (segment->p_type)
+ 	{
+-	case PT_LOAD:
+-	  if (loadaddr == (ElfW(Addr)) -1)
+-	    loadaddr = segment->p_vaddr - segment->p_offset;
+-	  break;
+-
+ 	case PT_DYNAMIC:
+ 	  if (dynamic_addr)
+ 	    error (0, 0, _("more than one dynamic segment\n"));
+@@ -176,11 +169,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
+ 	}
+ 
+     }
+-  if (loadaddr == (ElfW(Addr)) -1)
+-    {
+-      /* Very strange. */
+-      loadaddr = 0;
+-    }
+ 
+   /* Now we can read the dynamic sections.  */
+   if (dynamic_size == 0)
+@@ -197,7 +185,29 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
+       check_ptr (dyn_entry);
+       if (dyn_entry->d_tag == DT_STRTAB)
+ 	{
+-	  dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
++	  /* Find the file offset of the segment containing the dynamic
++	     string table.  */
++	  ElfW(Off) loadoff = -1;
++	  for (i = 0, segment = elf_pheader;
++	       i < elf_header->e_phnum; i++, segment++)
++	    {
++	      if (segment->p_type == PT_LOAD
++		  && dyn_entry->d_un.d_val >= segment->p_vaddr
++		  && (dyn_entry->d_un.d_val - segment->p_vaddr
++		      < segment->p_filesz))
++		{
++		  loadoff = segment->p_vaddr - segment->p_offset;
++		  break;
++		}
++	    }
++	  if (loadoff == (ElfW(Off)) -1)
++	    {
++	      /* Very strange. */
++	      loadoff = 0;
++	    }
++
++	  dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val
++				      - loadoff);
+ 	  check_ptr (dynamic_strings);
+ 	  break;
+ 	}
diff --git a/SOURCES/glibc-rh1774115.patch b/SOURCES/glibc-rh1774115.patch
new file mode 100644
index 0000000..a660644
--- /dev/null
+++ b/SOURCES/glibc-rh1774115.patch
@@ -0,0 +1,103 @@
+Partial backport without the new tst-dlopen-aout-pie test.  The test
+fails because the a self-dlopen of a PIE binary succeeds, as commit
+23d2e5faf0bca6d9b31bef4aa162b95ee64cbfc6 ("elf: Self-dlopen failure
+with explict loader invocation [BZ #24900]") has not been backported.
+
+commit 77523d5e43cb5721c23855eb6045b0607a3b30a0
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Oct 4 21:23:51 2019 +0200
+
+    elf: Assign TLS modid later during dlopen [BZ #24930]
+    
+    Commit a42faf59d6d9f82e5293a9ebcc26d9c9e562b12b ("Fix BZ #16634.")
+    attempted to fix a TLS modid consistency issue by adding additional
+    checks to the open_verify function.  However, this is fragile
+    because open_verify cannot reliably predict whether
+    _dl_map_object_from_fd will later fail in the more complex cases
+    (such as memory allocation failures).  Therefore, this commit
+    assigns the TLS modid as late as possible.  At that point, the link
+    map pointer will eventually be passed to _dl_close, which will undo
+    the TLS modid assignment.
+    
+    Reviewed-by: Gabriel F. T. Gomes <gabrielftg@linux.ibm.com>
+
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index bb839ef70ff46f37..b190b28e32e47391 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1134,27 +1134,21 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
+ 	     offset.  We will adjust it later.  */
+ 	  l->l_tls_initimage = (void *) ph->p_vaddr;
+ 
+-	  /* If not loading the initial set of shared libraries,
+-	     check whether we should permit loading a TLS segment.  */
+-	  if (__glibc_likely (l->l_type == lt_library)
+-	      /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did
+-		 not set up TLS data structures, so don't use them now.  */
+-	      || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL))
+-	    {
+-	      /* Assign the next available module ID.  */
+-	      l->l_tls_modid = _dl_next_tls_modid ();
+-	      break;
+-	    }
++	  /* l->l_tls_modid is assigned below, once there is no
++	     possibility for failure.  */
+ 
++	  if (l->l_type != lt_library
++	      && GL(dl_tls_dtv_slotinfo_list) == NULL)
++	    {
+ #ifdef SHARED
+-	  /* We are loading the executable itself when the dynamic
+-	     linker was executed directly.  The setup will happen
+-	     later.  Otherwise, the TLS data structures are already
+-	     initialized, and we assigned a TLS modid above.  */
+-	  assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0);
++	      /* We are loading the executable itself when the dynamic
++		 linker was executed directly.  The setup will happen
++		 later.  */
++	      assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0);
+ #else
+-	  assert (false && "TLS not initialized in static application");
++	      assert (false && "TLS not initialized in static application");
+ #endif
++	    }
+ 	  break;
+ 
+ 	case PT_GNU_STACK:
+@@ -1395,6 +1389,18 @@ cannot enable executable stack as shared object requires");
+     add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
+ 			    + l->l_info[DT_SONAME]->d_un.d_val));
+ 
++  /* _dl_close can only eventually undo the module ID assignment (via
++     remove_slotinfo) if this function returns a pointer to a link
++     map.  Therefore, delay this step until all possibilities for
++     failure have been excluded.  */
++  if (l->l_tls_blocksize > 0
++      && (__glibc_likely (l->l_type == lt_library)
++	  /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did
++	     not set up TLS data structures, so don't use them now.  */
++	  || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL)))
++    /* Assign the next available module ID.  */
++    l->l_tls_modid = _dl_next_tls_modid ();
++
+ #ifdef DL_AFTER_LOAD
+   DL_AFTER_LOAD (l);
+ #endif
+@@ -1662,17 +1668,6 @@ open_verify (const char *name, int fd,
+ 	  errstring = N_("only ET_DYN and ET_EXEC can be loaded");
+ 	  goto call_lose;
+ 	}
+-      else if (__glibc_unlikely (ehdr->e_type == ET_EXEC
+-				 && (mode & __RTLD_OPENEXEC) == 0))
+-	{
+-	  /* BZ #16634. It is an error to dlopen ET_EXEC (unless
+-	     __RTLD_OPENEXEC is explicitly set).  We return error here
+-	     so that code in _dl_map_object_from_fd does not try to set
+-	     l_tls_modid for this module.  */
+-
+-	  errstring = N_("cannot dynamically load executable");
+-	  goto call_lose;
+-	}
+       else if (__glibc_unlikely (ehdr->e_phentsize != sizeof (ElfW(Phdr))))
+ 	{
+ 	  errstring = N_("ELF file's phentsize not the expected size");
diff --git a/SOURCES/glibc-rh1775819.patch b/SOURCES/glibc-rh1775819.patch
new file mode 100644
index 0000000..a9e6338
--- /dev/null
+++ b/SOURCES/glibc-rh1775819.patch
@@ -0,0 +1,33 @@
+commit f55e312bcd6582b5ff68fdcc1781c7017796dc91
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Nov 28 14:42:11 2019 +0100
+
+    libio: Disable vtable validation for pre-2.1 interposed handles [BZ #25203]
+    
+    Commit c402355dfa7807b8e0adb27c009135a7e2b9f1b0 ("libio: Disable
+    vtable validation in case of interposition [BZ #23313]") only covered
+    the interposable glibc 2.1 handles, in libio/stdfiles.c.  The
+    parallel code in libio/oldstdfiles.c needs similar detection logic.
+    
+    Fixes (again) commit db3476aff19b75c4fdefbe65fcd5f0a90588ba51
+    ("libio: Implement vtable verification [BZ #20191]").
+    
+    Change-Id: Ief6f9f17e91d1f7263421c56a7dc018f4f595c21
+    (cherry picked from commit cb61630ed712d033f54295f776967532d3f4b46a)
+
+diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c
+index f3dda89004..9fe809bd68 100644
+--- a/libio/oldstdfiles.c
++++ b/libio/oldstdfiles.c
+@@ -87,6 +87,11 @@ _IO_check_libio (void)
+ 	stdout->_vtable_offset = stderr->_vtable_offset =
+ 	((int) sizeof (struct _IO_FILE)
+ 	 - (int) sizeof (struct _IO_FILE_complete));
++
++      if (_IO_stdin_.vtable != &_IO_old_file_jumps
++	  || _IO_stdout_.vtable != &_IO_old_file_jumps
++	  || _IO_stderr_.vtable != &_IO_old_file_jumps)
++	IO_set_accept_foreign_vtables (&_IO_vtable_check);
+     }
+ }
+ 
diff --git a/SOURCES/glibc-rh1780204-01.patch b/SOURCES/glibc-rh1780204-01.patch
new file mode 100644
index 0000000..33a1752
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-01.patch
@@ -0,0 +1,48 @@
+From 34e75eb497941f829115e6e8f34e899575f4e342 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Fri, 18 Oct 2019 14:57:14 +0200
+Subject: [PATCH 01/28] S390: Add new s390 platform z15.
+
+The new IBM z15 is added to platform string array.
+The macro _DL_PLATFORMS_COUNT is incremented.
+
+(cherry picked from commit 2901743568452403849be7295c8732faa7732339)
+---
+ sysdeps/s390/dl-procinfo.c | 4 ++--
+ sysdeps/s390/dl-procinfo.h | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
+index 6ea220a171..6d76d7d008 100644
+--- a/sysdeps/s390/dl-procinfo.c
++++ b/sysdeps/s390/dl-procinfo.c
+@@ -63,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[19][9]
+ #if !defined PROCINFO_DECL && defined SHARED
+   ._dl_s390_platforms
+ #else
+-PROCINFO_CLASS const char _dl_s390_platforms[9][7]
++PROCINFO_CLASS const char _dl_s390_platforms[10][7]
+ #endif
+ #ifndef PROCINFO_DECL
+ = {
+-    "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14"
++    "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15"
+   }
+ #endif
+ #if !defined SHARED || defined PROCINFO_DECL
+diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
+index d03c69fffd..b367bbe8ce 100644
+--- a/sysdeps/s390/dl-procinfo.h
++++ b/sysdeps/s390/dl-procinfo.h
+@@ -23,7 +23,7 @@
+ 
+ #define _DL_HWCAP_COUNT 19
+ 
+-#define _DL_PLATFORMS_COUNT	9
++#define _DL_PLATFORMS_COUNT	10
+ 
+ /* The kernel provides up to 32 capability bits with elf_hwcap.  */
+ #define _DL_FIRST_PLATFORM	32
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-02.patch b/SOURCES/glibc-rh1780204-02.patch
new file mode 100644
index 0000000..e9d2ea3
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-02.patch
@@ -0,0 +1,159 @@
+From 73f98d03d2cde34255c0a39ef18902bffdce0185 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:14 +0100
+Subject: [PATCH 02/28] Always use wordsize-64 version of s_rint.c.
+
+This patch replaces s_rint.c in sysdeps/dbl-64 with the one in
+sysdeps/dbl-64/wordsize-64 and removes the latter one.
+The code is not changed except changes in code style.
+
+Also adjusted the include path in x86_64 file.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit ab48bdd098a675dddb360faafc497a61c4bd4334)
+---
+ sysdeps/ieee754/dbl-64/s_rint.c             | 32 ++++++------
+ sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c | 57 ---------------------
+ sysdeps/x86_64/fpu/multiarch/s_rint-c.c     |  2 +-
+ 3 files changed, 17 insertions(+), 74 deletions(-)
+ delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c
+
+diff --git a/sysdeps/ieee754/dbl-64/s_rint.c b/sysdeps/ieee754/dbl-64/s_rint.c
+index cb0f5ca298..7f3dc87b96 100644
+--- a/sysdeps/ieee754/dbl-64/s_rint.c
++++ b/sysdeps/ieee754/dbl-64/s_rint.c
+@@ -1,4 +1,3 @@
+-/* @(#)s_rint.c 5.1 93/09/24 */
+ /*
+  * ====================================================
+  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+@@ -25,38 +24,39 @@
+ #include <libm-alias-double.h>
+ 
+ static const double
+-  TWO52[2] = {
+-  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
++TWO52[2] = {
++	    4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
++	    -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+ };
+ 
+ double
+ __rint (double x)
+ {
+-  int32_t i0, j0, sx;
+-  double w, t;
+-  GET_HIGH_WORD (i0, x);
+-  sx = (i0 >> 31) & 1;
+-  j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
++  int64_t i0, sx;
++  int32_t j0;
++  EXTRACT_WORDS64 (i0, x);
++  sx = (i0 >> 63) & 1;
++  j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
+   if (j0 < 52)
+     {
+       if (j0 < 0)
+ 	{
+-	  w = TWO52[sx] + x;
+-	  t = w - TWO52[sx];
+-	  GET_HIGH_WORD (i0, t);
+-	  SET_HIGH_WORD (t, (i0 & 0x7fffffff) | (sx << 31));
++	  double w = TWO52[sx] + x;
++	  double t =  w - TWO52[sx];
++	  EXTRACT_WORDS64 (i0, t);
++	  INSERT_WORDS64 (t, (i0 & UINT64_C (0x7fffffffffffffff))
++			  | (sx << 63));
+ 	  return t;
+ 	}
+     }
+   else
+     {
+       if (j0 == 0x400)
+-	return x + x;                   /* inf or NaN */
++	return x + x;			/* inf or NaN  */
+       else
+-	return x;                       /* x is integral */
++	return x;			/* x is integral  */
+     }
+-  w = TWO52[sx] + x;
++  double w = TWO52[sx] + x;
+   return w - TWO52[sx];
+ }
+ #ifndef __rint
+diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c
+deleted file mode 100644
+index 622e479c5f..0000000000
+--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c
++++ /dev/null
+@@ -1,57 +0,0 @@
+-/*
+- * ====================================================
+- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+- *
+- * Developed at SunPro, a Sun Microsystems, Inc. business.
+- * Permission to use, copy, modify, and distribute this
+- * software is freely granted, provided that this notice
+- * is preserved.
+- * ====================================================
+- */
+-
+-/*
+- * rint(x)
+- * Return x rounded to integral value according to the prevailing
+- * rounding mode.
+- * Method:
+- *	Using floating addition.
+- * Exception:
+- *	Inexact flag raised if x not equal to rint(x).
+- */
+-
+-#include <math.h>
+-#include <math_private.h>
+-#include <libm-alias-double.h>
+-
+-static const double
+-TWO52[2]={
+-  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+-};
+-
+-double
+-__rint(double x)
+-{
+-	int64_t i0,sx;
+-	int32_t j0;
+-	EXTRACT_WORDS64(i0,x);
+-	sx = (i0>>63)&1;
+-	j0 = ((i0>>52)&0x7ff)-0x3ff;
+-	if(j0<52) {
+-	    if(j0<0) {
+-		double w = TWO52[sx]+x;
+-		double t =  w-TWO52[sx];
+-		EXTRACT_WORDS64(i0,t);
+-		INSERT_WORDS64(t,(i0&UINT64_C(0x7fffffffffffffff))|(sx<<63));
+-		return t;
+-	    }
+-	} else {
+-	    if(j0==0x400) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
+-	}
+-	double w = TWO52[sx]+x;
+-	return w-TWO52[sx];
+-}
+-#ifndef __rint
+-libm_alias_double (__rint, rint)
+-#endif
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-c.c b/sysdeps/x86_64/fpu/multiarch/s_rint-c.c
+index 162a630ff9..b010150f52 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_rint-c.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_rint-c.c
+@@ -1,3 +1,3 @@
+ #undef __rint
+ #define __rint __rint_c
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c>
++#include <sysdeps/ieee754/dbl-64/s_rint.c>
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-03.patch b/SOURCES/glibc-rh1780204-03.patch
new file mode 100644
index 0000000..1e5d46f
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-03.patch
@@ -0,0 +1,257 @@
+From 7741c9c7f566d09f57db45df9377ac497f6232a5 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:15 +0100
+Subject: [PATCH 03/28] Always use wordsize-64 version of s_floor.c.
+
+This patch replaces s_floor.c in sysdeps/dbl-64 with the one in
+sysdeps/dbl-64/wordsize-64 and removes the latter one.
+The code is not changed except changes in code style.
+
+Also adjusted the include path in x86_64 and sparc64 files.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 95b0c2c431510013eb2f7385fc078ee2498f83bf)
+Note: glibc 2.28 had no NO_MATH_REDIRECT in wordsize-64 version.
+---
+ sysdeps/ieee754/dbl-64/s_floor.c              | 92 +++++++++----------
+ sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c  | 71 --------------
+ .../sparc64/fpu/multiarch/s_floor-generic.c   |  2 +-
+ .../sparc64/fpu/multiarch/s_floor-vis3.c      |  2 +-
+ sysdeps/x86_64/fpu/multiarch/s_floor-c.c      |  2 +-
+ 5 files changed, 45 insertions(+), 124 deletions(-)
+ delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c
+
+diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c
+index f27c6f3ad2..b551a1aafa 100644
+--- a/sysdeps/ieee754/dbl-64/s_floor.c
++++ b/sysdeps/ieee754/dbl-64/s_floor.c
+@@ -1,4 +1,24 @@
+-/* @(#)s_floor.c 5.1 93/09/24 */
++/* Round double to integer away from zero.
++   Copyright (C) 2011-2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2011.
++
++   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/>.  */
++
++/* Based on a version which carries the following copyright:  */
++
+ /*
+  * ====================================================
+  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+@@ -10,6 +30,11 @@
+  * ====================================================
+  */
+ 
++#include <math.h>
++#include <math_private.h>
++#include <stdint.h>
++#include <libm-alias-double.h>
++
+ /*
+  * floor(x)
+  * Return x rounded toward -inf to integral value
+@@ -17,68 +42,35 @@
+  *	Bit twiddling.
+  */
+ 
+-#include <math.h>
+-#include <math_private.h>
+-#include <libm-alias-double.h>
+-
+ double
+ __floor (double x)
+ {
+-  int32_t i0, i1, j0;
+-  uint32_t i, j;
+-  EXTRACT_WORDS (i0, i1, x);
+-  j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+-  if (j0 < 20)
++  int64_t i0;
++  EXTRACT_WORDS64 (i0, x);
++  int32_t j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
++  if (__glibc_likely (j0 < 52))
+     {
+       if (j0 < 0)
+ 	{
+-	  /* return 0*sign(x) if |x|<1 */
++	  /* return 0 * sign (x) if |x| < 1  */
+ 	  if (i0 >= 0)
+-	    {
+-	      i0 = i1 = 0;
+-	    }
+-	  else if (((i0 & 0x7fffffff) | i1) != 0)
+-	    {
+-	      i0 = 0xbff00000; i1 = 0;
+-	    }
++	    i0 = 0;
++	  else if ((i0 & 0x7fffffffffffffffl) != 0)
++	    i0 = 0xbff0000000000000l;
+ 	}
+       else
+ 	{
+-	  i = (0x000fffff) >> j0;
+-	  if (((i0 & i) | i1) == 0)
+-	    return x;                        /* x is integral */
++	  uint64_t i = 0x000fffffffffffffl >> j0;
++	  if ((i0 & i) == 0)
++	    return x;			 /* x is integral */
+ 	  if (i0 < 0)
+-	    i0 += (0x00100000) >> j0;
+-	  i0 &= (~i); i1 = 0;
+-	}
+-    }
+-  else if (j0 > 51)
+-    {
+-      if (j0 == 0x400)
+-	return x + x;                   /* inf or NaN */
+-      else
+-	return x;                       /* x is integral */
+-    }
+-  else
+-    {
+-      i = ((uint32_t) (0xffffffff)) >> (j0 - 20);
+-      if ((i1 & i) == 0)
+-	return x;                       /* x is integral */
+-      if (i0 < 0)
+-	{
+-	  if (j0 == 20)
+-	    i0 += 1;
+-	  else
+-	    {
+-	      j = i1 + (1 << (52 - j0));
+-	      if (j < i1)
+-		i0 += 1;                /* got a carry */
+-	      i1 = j;
+-	    }
++	    i0 += 0x0010000000000000l >> j0;
++	  i0 &= ~i;
+ 	}
+-      i1 &= (~i);
++      INSERT_WORDS64 (x, i0);
+     }
+-  INSERT_WORDS (x, i0, i1);
++  else if (j0 == 0x400)
++    return x + x;			/* inf or NaN */
+   return x;
+ }
+ #ifndef __floor
+diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c
+deleted file mode 100644
+index f7e0a77ec3..0000000000
+--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c
++++ /dev/null
+@@ -1,71 +0,0 @@
+-/* Round double to integer away from zero.
+-   Copyright (C) 2011-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2011.
+-
+-   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/>.  */
+-
+-/* Based on a version which carries the following copyright:  */
+-
+-/*
+- * ====================================================
+- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+- *
+- * Developed at SunPro, a Sun Microsystems, Inc. business.
+- * Permission to use, copy, modify, and distribute this
+- * software is freely granted, provided that this notice
+- * is preserved.
+- * ====================================================
+- */
+-
+-#include <math.h>
+-#include <math_private.h>
+-#include <stdint.h>
+-#include <libm-alias-double.h>
+-
+-/*
+- * floor(x)
+- * Return x rounded toward -inf to integral value
+- * Method:
+- *	Bit twiddling.
+- */
+-
+-
+-double
+-__floor (double x)
+-{
+-	int64_t i0;
+-	EXTRACT_WORDS64(i0,x);
+-	int32_t j0 = ((i0>>52)&0x7ff)-0x3ff;
+-	if(__builtin_expect(j0<52, 1)) {
+-	    if(j0<0) {
+-		/* return 0*sign(x) if |x|<1 */
+-		if(i0>=0) {i0=0;}
+-		else if((i0&0x7fffffffffffffffl)!=0)
+-		  { i0=0xbff0000000000000l;}
+-	    } else {
+-		uint64_t i = (0x000fffffffffffffl)>>j0;
+-		if((i0&i)==0) return x; /* x is integral */
+-		if(i0<0) i0 += (0x0010000000000000l)>>j0;
+-		i0 &= (~i);
+-	    }
+-	    INSERT_WORDS64(x,i0);
+-	} else if (j0==0x400)
+-	    return x+x;	/* inf or NaN */
+-	return x;
+-}
+-#ifndef __floor
+-libm_alias_double (__floor, floor)
+-#endif
+diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c
+index 0f3361a9fb..c92b600df1 100644
+--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c
++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c
+@@ -1,2 +1,2 @@
+ #define __floor __floor_generic
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c>
++#include <sysdeps/ieee754/dbl-64/s_floor.c>
+diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c
+index d9974161b0..35564b9139 100644
+--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c
++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c
+@@ -20,4 +20,4 @@
+ 
+ #define __floor __floor_vis3
+ 
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c>
++#include <sysdeps/ieee754/dbl-64/s_floor.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c b/sysdeps/x86_64/fpu/multiarch/s_floor-c.c
+index 68733b69ef..002d12247e 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_floor-c.c
+@@ -1,3 +1,3 @@
+ #undef __floor
+ #define __floor __floor_c
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c>
++#include <sysdeps/ieee754/dbl-64/s_floor.c>
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-04.patch b/SOURCES/glibc-rh1780204-04.patch
new file mode 100644
index 0000000..e447d66
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-04.patch
@@ -0,0 +1,192 @@
+From d3833cb69c7ff42ac8df68ed7b646c98c3a32eb8 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:16 +0100
+Subject: [PATCH 04/28] Always use wordsize-64 version of s_ceil.c.
+
+This patch replaces s_ceil.c in sysdeps/dbl-64 with the one in
+sysdeps/dbl-64/wordsize-64 and removes the latter one.
+The code is not changed except changes in code style.
+
+Also adjusted the include path in x86_64 and sparc64 files.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 9f234eafe8698fd9a441ca2309a299d0bd771156)
+---
+ sysdeps/ieee754/dbl-64/s_ceil.c               | 59 ++++++-------------
+ sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c   | 51 ----------------
+ .../sparc64/fpu/multiarch/s_ceil-generic.c    |  2 +-
+ .../sparc/sparc64/fpu/multiarch/s_ceil-vis3.c |  2 +-
+ sysdeps/x86_64/fpu/multiarch/s_ceil-c.c       |  2 +-
+ 5 files changed, 21 insertions(+), 95 deletions(-)
+ delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c
+
+diff --git a/sysdeps/ieee754/dbl-64/s_ceil.c b/sysdeps/ieee754/dbl-64/s_ceil.c
+index 5a7434c737..3becdfc515 100644
+--- a/sysdeps/ieee754/dbl-64/s_ceil.c
++++ b/sysdeps/ieee754/dbl-64/s_ceil.c
+@@ -24,61 +24,38 @@
+ double
+ __ceil (double x)
+ {
+-  int32_t i0, i1, j0;
+-  uint32_t i, j;
+-  EXTRACT_WORDS (i0, i1, x);
+-  j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+-  if (j0 < 20)
++  int64_t i0, i;
++  int32_t j0;
++  EXTRACT_WORDS64 (i0, x);
++  j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
++  if (j0 <= 51)
+     {
+       if (j0 < 0)
+ 	{
+-	  /* return 0*sign(x) if |x|<1 */
++	  /* return 0 * sign(x) if |x| < 1  */
+ 	  if (i0 < 0)
+-	    {
+-	      i0 = 0x80000000; i1 = 0;
+-	    }
+-	  else if ((i0 | i1) != 0)
+-	    {
+-	      i0 = 0x3ff00000; i1 = 0;
+-	    }
++	    i0 = INT64_C (0x8000000000000000);
++	  else if (i0 != 0)
++	    i0 = INT64_C (0x3ff0000000000000);
+ 	}
+       else
+ 	{
+-	  i = (0x000fffff) >> j0;
+-	  if (((i0 & i) | i1) == 0)
+-	    return x;                        /* x is integral */
++	  i = INT64_C (0x000fffffffffffff) >> j0;
++	  if ((i0 & i) == 0)
++	    return x;			/* x is integral  */
+ 	  if (i0 > 0)
+-	    i0 += (0x00100000) >> j0;
+-	  i0 &= (~i); i1 = 0;
++	    i0 += UINT64_C (0x0010000000000000) >> j0;
++	  i0 &= ~i;
+ 	}
+     }
+-  else if (j0 > 51)
++  else
+     {
+       if (j0 == 0x400)
+-	return x + x;                   /* inf or NaN */
++	return x + x;			/* inf or NaN  */
+       else
+-	return x;                       /* x is integral */
+-    }
+-  else
+-    {
+-      i = ((uint32_t) (0xffffffff)) >> (j0 - 20);
+-      if ((i1 & i) == 0)
+-	return x;                       /* x is integral */
+-      if (i0 > 0)
+-	{
+-	  if (j0 == 20)
+-	    i0 += 1;
+-	  else
+-	    {
+-	      j = i1 + (1 << (52 - j0));
+-	      if (j < i1)
+-		i0 += 1;                /* got a carry */
+-	      i1 = j;
+-	    }
+-	}
+-      i1 &= (~i);
++	return x;			/* x is integral  */
+     }
+-  INSERT_WORDS (x, i0, i1);
++  INSERT_WORDS64 (x, i0);
+   return x;
+ }
+ #ifndef __ceil
+diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c
+deleted file mode 100644
+index b99829d2b0..0000000000
+--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c
++++ /dev/null
+@@ -1,51 +0,0 @@
+-/* @(#)s_ceil.c 5.1 93/09/24 */
+-/*
+- * ====================================================
+- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+- *
+- * Developed at SunPro, a Sun Microsystems, Inc. business.
+- * Permission to use, copy, modify, and distribute this
+- * software is freely granted, provided that this notice
+- * is preserved.
+- * ====================================================
+- */
+-
+-/*
+- * ceil(x)
+- * Return x rounded toward -inf to integral value
+- * Method:
+- *	Bit twiddling.
+- */
+-
+-#include <math.h>
+-#include <math_private.h>
+-#include <libm-alias-double.h>
+-
+-double
+-__ceil(double x)
+-{
+-	int64_t i0,i;
+-	int32_t j0;
+-	EXTRACT_WORDS64(i0,x);
+-	j0 = ((i0>>52)&0x7ff)-0x3ff;
+-	if(j0<=51) {
+-	    if(j0<0) {
+-	      /* return 0*sign(x) if |x|<1 */
+-	      if(i0<0) {i0=INT64_C(0x8000000000000000);}
+-	      else if(i0!=0) { i0=INT64_C(0x3ff0000000000000);}
+-	    } else {
+-		i = INT64_C(0x000fffffffffffff)>>j0;
+-		if((i0&i)==0) return x; /* x is integral */
+-		if(i0>0) i0 += UINT64_C(0x0010000000000000)>>j0;
+-		i0 &= (~i);
+-	    }
+-	} else {
+-	    if(j0==0x400) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
+-	}
+-	INSERT_WORDS64(x,i0);
+-	return x;
+-}
+-#ifndef __ceil
+-libm_alias_double (__ceil, ceil)
+-#endif
+diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c
+index febea745e1..80f68b6766 100644
+--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c
++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c
+@@ -1,2 +1,2 @@
+ #define __ceil __ceil_generic
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c>
++#include <sysdeps/ieee754/dbl-64/s_ceil.c>
+diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c
+index a03a0090f0..59822e0f8c 100644
+--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c
++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c
+@@ -20,4 +20,4 @@
+ 
+ #define __ceil __ceil_vis3
+ 
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c>
++#include <sysdeps/ieee754/dbl-64/s_ceil.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c b/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c
+index 6a5ea3ff27..ada28baa1a 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c
+@@ -1,2 +1,2 @@
+ #define __ceil __ceil_c
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c>
++#include <sysdeps/ieee754/dbl-64/s_ceil.c>
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-05.patch b/SOURCES/glibc-rh1780204-05.patch
new file mode 100644
index 0000000..3c139a2
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-05.patch
@@ -0,0 +1,157 @@
+From e8f1c08a49d313b210ed4104c20646c105bab6a4 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:17 +0100
+Subject: [PATCH 05/28] Always use wordsize-64 version of s_trunc.c.
+
+This patch replaces s_trunc.c in sysdeps/dbl-64 with the one in
+sysdeps/dbl-64/wordsize-64 and removes the latter one.
+The code is not changed except changes in code style.
+
+Also adjusted the include path in x86_64 and sparc64 files.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 1c94bf0f0a50ce66c808e2ea9b7e417785798b73)
+---
+ sysdeps/ieee754/dbl-64/s_trunc.c              | 25 ++++-----
+ sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c  | 54 -------------------
+ .../sparc64/fpu/multiarch/s_trunc-generic.c   |  2 +-
+ .../sparc64/fpu/multiarch/s_trunc-vis3.c      |  2 +-
+ sysdeps/x86_64/fpu/multiarch/s_trunc-c.c      |  2 +-
+ 5 files changed, 13 insertions(+), 72 deletions(-)
+ delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c
+
+diff --git a/sysdeps/ieee754/dbl-64/s_trunc.c b/sysdeps/ieee754/dbl-64/s_trunc.c
+index 6ffabb410a..38bb33d337 100644
+--- a/sysdeps/ieee754/dbl-64/s_trunc.c
++++ b/sysdeps/ieee754/dbl-64/s_trunc.c
+@@ -26,31 +26,26 @@
+ double
+ __trunc (double x)
+ {
+-  int32_t i0, j0;
+-  uint32_t i1;
+-  int sx;
+-
+-  EXTRACT_WORDS (i0, i1, x);
+-  sx = i0 & 0x80000000;
+-  j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+-  if (j0 < 20)
++  int64_t i0, j0;
++  int64_t sx;
++
++  EXTRACT_WORDS64 (i0, x);
++  sx = i0 & UINT64_C (0x8000000000000000);
++  j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
++  if (j0 < 52)
+     {
+       if (j0 < 0)
+ 	/* The magnitude of the number is < 1 so the result is +-0.  */
+-	INSERT_WORDS (x, sx, 0);
++	INSERT_WORDS64 (x, sx);
+       else
+-	INSERT_WORDS (x, sx | (i0 & ~(0x000fffff >> j0)), 0);
++	INSERT_WORDS64 (x, sx | (i0 & ~(UINT64_C (0x000fffffffffffff) >> j0)));
+     }
+-  else if (j0 > 51)
++  else
+     {
+       if (j0 == 0x400)
+ 	/* x is inf or NaN.  */
+ 	return x + x;
+     }
+-  else
+-    {
+-      INSERT_WORDS (x, i0, i1 & ~(0xffffffffu >> (j0 - 20)));
+-    }
+ 
+   return x;
+ }
+diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c
+deleted file mode 100644
+index 19a09b894e..0000000000
+--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c
++++ /dev/null
+@@ -1,54 +0,0 @@
+-/* Truncate argument to nearest integral value not larger than the argument.
+-   Copyright (C) 1997-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+-
+-   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 <math.h>
+-
+-#include <math_private.h>
+-#include <libm-alias-double.h>
+-
+-
+-double
+-__trunc (double x)
+-{
+-  int64_t i0, j0;
+-  int64_t sx;
+-
+-  EXTRACT_WORDS64 (i0, x);
+-  sx = i0 & UINT64_C(0x8000000000000000);
+-  j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
+-  if (j0 < 52)
+-    {
+-      if (j0 < 0)
+-	/* The magnitude of the number is < 1 so the result is +-0.  */
+-	INSERT_WORDS64 (x, sx);
+-      else
+-	INSERT_WORDS64 (x, sx | (i0 & ~(UINT64_C(0x000fffffffffffff) >> j0)));
+-    }
+-  else
+-    {
+-      if (j0 == 0x400)
+-	/* x is inf or NaN.  */
+-	return x + x;
+-    }
+-
+-  return x;
+-}
+-#ifndef __trunc
+-libm_alias_double (__trunc, trunc)
+-#endif
+diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c
+index 00abd2a643..c198ebb3d5 100644
+--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c
++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c
+@@ -1,2 +1,2 @@
+ #define __trunc __trunc_generic
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c>
++#include <sysdeps/ieee754/dbl-64/s_trunc.c>
+diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c
+index a89916ba89..766bb22629 100644
+--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c
++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c
+@@ -20,4 +20,4 @@
+ 
+ #define __trunc __trunc_vis3
+ 
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c>
++#include <sysdeps/ieee754/dbl-64/s_trunc.c>
+diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c b/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c
+index 6204ae3c77..8aa499fbb8 100644
+--- a/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c
++++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c
+@@ -1,2 +1,2 @@
+ #define __trunc __trunc_c
+-#include <sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c>
++#include <sysdeps/ieee754/dbl-64/s_trunc.c>
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-06.patch b/SOURCES/glibc-rh1780204-06.patch
new file mode 100644
index 0000000..b0d1765
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-06.patch
@@ -0,0 +1,167 @@
+From 577943dac79a5657bdfe51e06e289eb2473c3d2e Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:17 +0100
+Subject: [PATCH 06/28] Always use wordsize-64 version of s_round.c.
+
+This patch replaces s_round.c in sysdeps/dbl-64 with the one in
+sysdeps/dbl-64/wordsize-64 and removes the latter one.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 36e9acbd5cb2c330c0d53195db4a0ee31f2c3097)
+---
+ sysdeps/ieee754/dbl-64/s_round.c             | 39 ++++--------
+ sysdeps/ieee754/dbl-64/wordsize-64/s_round.c | 65 --------------------
+ 2 files changed, 12 insertions(+), 92 deletions(-)
+ delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_round.c
+
+diff --git a/sysdeps/ieee754/dbl-64/s_round.c b/sysdeps/ieee754/dbl-64/s_round.c
+index fa9e83196e..bf9922edca 100644
+--- a/sysdeps/ieee754/dbl-64/s_round.c
++++ b/sysdeps/ieee754/dbl-64/s_round.c
+@@ -21,38 +21,36 @@
+ 
+ #include <math_private.h>
+ #include <libm-alias-double.h>
++#include <stdint.h>
+ 
+ 
+ double
+ __round (double x)
+ {
+-  int32_t i0, j0;
+-  uint32_t i1;
++  int64_t i0, j0;
+ 
+-  EXTRACT_WORDS (i0, i1, x);
+-  j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+-  if (j0 < 20)
++  EXTRACT_WORDS64 (i0, x);
++  j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
++  if (__glibc_likely (j0 < 52))
+     {
+       if (j0 < 0)
+ 	{
+-	  i0 &= 0x80000000;
++	  i0 &= UINT64_C (0x8000000000000000);
+ 	  if (j0 == -1)
+-	    i0 |= 0x3ff00000;
+-	  i1 = 0;
++	    i0 |= UINT64_C (0x3ff0000000000000);
+ 	}
+       else
+ 	{
+-	  uint32_t i = 0x000fffff >> j0;
+-	  if (((i0 & i) | i1) == 0)
++	  uint64_t i = UINT64_C (0x000fffffffffffff) >> j0;
++	  if ((i0 & i) == 0)
+ 	    /* X is integral.  */
+ 	    return x;
+ 
+-	  i0 += 0x00080000 >> j0;
++	  i0 += UINT64_C (0x0008000000000000) >> j0;
+ 	  i0 &= ~i;
+-	  i1 = 0;
+ 	}
+     }
+-  else if (j0 > 51)
++  else
+     {
+       if (j0 == 0x400)
+ 	/* Inf or NaN.  */
+@@ -60,21 +58,8 @@ __round (double x)
+       else
+ 	return x;
+     }
+-  else
+-    {
+-      uint32_t i = 0xffffffff >> (j0 - 20);
+-      if ((i1 & i) == 0)
+-	/* X is integral.  */
+-	return x;
+-
+-      uint32_t j = i1 + (1 << (51 - j0));
+-      if (j < i1)
+-	i0 += 1;
+-      i1 = j;
+-      i1 &= ~i;
+-    }
+ 
+-  INSERT_WORDS (x, i0, i1);
++  INSERT_WORDS64 (x, i0);
+   return x;
+ }
+ libm_alias_double (__round, round)
+diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c
+deleted file mode 100644
+index 3323621ce3..0000000000
+--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c
++++ /dev/null
+@@ -1,65 +0,0 @@
+-/* Round double to integer away from zero.
+-   Copyright (C) 1997-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+-
+-   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 <math.h>
+-
+-#include <math_private.h>
+-#include <libm-alias-double.h>
+-#include <stdint.h>
+-
+-
+-double
+-__round (double x)
+-{
+-  int64_t i0, j0;
+-
+-  EXTRACT_WORDS64 (i0, x);
+-  j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
+-  if (__glibc_likely (j0 < 52))
+-    {
+-      if (j0 < 0)
+-	{
+-	  i0 &= UINT64_C(0x8000000000000000);
+-	  if (j0 == -1)
+-	    i0 |= UINT64_C(0x3ff0000000000000);
+-	}
+-      else
+-	{
+-	  uint64_t i = UINT64_C(0x000fffffffffffff) >> j0;
+-	  if ((i0 & i) == 0)
+-	    /* X is integral.  */
+-	    return x;
+-
+-	  i0 += UINT64_C(0x0008000000000000) >> j0;
+-	  i0 &= ~i;
+-	}
+-    }
+-  else
+-    {
+-      if (j0 == 0x400)
+-	/* Inf or NaN.  */
+-	return x + x;
+-      else
+-	return x;
+-    }
+-
+-  INSERT_WORDS64 (x, i0);
+-  return x;
+-}
+-libm_alias_double (__round, round)
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-07.patch b/SOURCES/glibc-rh1780204-07.patch
new file mode 100644
index 0000000..13b3c3e
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-07.patch
@@ -0,0 +1,255 @@
+From 735a36828f349419379f15e942bfdf0c532d58eb Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:18 +0100
+Subject: [PATCH 07/28] Use GCC builtins for nearbyint functions if desired.
+
+This patch is using the corresponding GCC builtin for nearbyintf, nearbyint,
+nearbintl and nearbyintf128 if the USE_FUNCTION_BUILTIN macros are defined to one
+in math-use-builtins.h.
+
+This is the case for s390 if build with at least --march=z196 --mzarch.
+Otherwise the generic implementation is used.  The code of the generic
+implementation is not changed.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit ae3577f607b50bf3ce9b0877e43ad2508c9da61b)
+Note: The TWO52 constants are now located in # ! USE_NEARBYINT_BUILTIN
+---
+ sysdeps/generic/math-use-builtins.h         | 29 ++++++++++++
+ sysdeps/ieee754/dbl-64/s_nearbyint.c        | 17 ++++---
+ sysdeps/ieee754/float128/float128_private.h |  4 ++
+ sysdeps/ieee754/flt-32/s_nearbyintf.c       | 17 ++++---
+ sysdeps/ieee754/ldbl-128/s_nearbyintl.c     | 17 ++++---
+ sysdeps/s390/fpu/math-use-builtins.h        | 49 +++++++++++++++++++++
+ 6 files changed, 115 insertions(+), 18 deletions(-)
+ create mode 100644 sysdeps/generic/math-use-builtins.h
+ create mode 100644 sysdeps/s390/fpu/math-use-builtins.h
+
+diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h
+new file mode 100644
+index 0000000000..e12490ed41
+--- /dev/null
++++ b/sysdeps/generic/math-use-builtins.h
+@@ -0,0 +1,29 @@
++/* Using math gcc builtins instead of generic implementation.  Generic version.
++   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/>.  */
++
++#ifndef MATH_USE_BUILTINS_H
++#define MATH_USE_BUILTINS_H	1
++
++/* Define these macros to 1 to use __builtin_xyz instead of the
++   generic implementation.  */
++#define USE_NEARBYINT_BUILTIN 0
++#define USE_NEARBYINTF_BUILTIN 0
++#define USE_NEARBYINTL_BUILTIN 0
++#define USE_NEARBYINTF128_BUILTIN 0
++
++#endif /* math-use-builtins.h */
+diff --git a/sysdeps/ieee754/dbl-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/s_nearbyint.c
+index 903121d456..6b9f44dc8d 100644
+--- a/sysdeps/ieee754/dbl-64/s_nearbyint.c
++++ b/sysdeps/ieee754/dbl-64/s_nearbyint.c
+@@ -29,16 +29,20 @@ static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $";
+ #include <math-barriers.h>
+ #include <math_private.h>
+ #include <libm-alias-double.h>
+-
+-static const double
+-  TWO52[2] = {
+-  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+-};
++#include <math-use-builtins.h>
+ 
+ double
+ __nearbyint (double x)
+ {
++#if USE_NEARBYINT_BUILTIN
++  return __builtin_nearbyint (x);
++#else
++  /* Use generic implementation.  */
++  static const double
++    TWO52[2] = {
++		4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
++		-4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
++  };
+   fenv_t env;
+   int32_t i0, j0, sx;
+   double w, t;
+@@ -72,5 +76,6 @@ __nearbyint (double x)
+   math_force_eval (t);
+   libc_fesetenv (&env);
+   return t;
++#endif /* ! USE_NEARBYINT_BUILTIN  */
+ }
+ libm_alias_double (__nearbyint, nearbyint)
+diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
+index 9dd15601e6..0bf6e8dee2 100644
+--- a/sysdeps/ieee754/float128/float128_private.h
++++ b/sysdeps/ieee754/float128/float128_private.h
+@@ -138,6 +138,9 @@
+ #undef libm_alias_double_ldouble
+ #define libm_alias_double_ldouble(func) libm_alias_float64_float128 (func)
+ 
++#include <math-use-builtins.h>
++#undef USE_NEARBYINTL_BUILTIN
++#define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN
+ 
+ /* IEEE function renames.  */
+ #define __ieee754_acoshl __ieee754_acoshf128
+@@ -339,6 +342,7 @@
+ /* Builtin renames.  */
+ #define __builtin_copysignl __builtin_copysignf128
+ #define __builtin_signbitl __builtin_signbit
++#define __builtin_nearbyintl __builtin_nearbyintf128
+ 
+ /* Get the constant suffix from bits/floatn-compat.h.  */
+ #define L(x) __f128 (x)
+diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c
+index 4dfe491f27..438dcae8cc 100644
+--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c
++++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c
+@@ -20,16 +20,20 @@
+ #include <math-barriers.h>
+ #include <math_private.h>
+ #include <libm-alias-float.h>
+-
+-static const float
+-TWO23[2]={
+-  8.3886080000e+06, /* 0x4b000000 */
+- -8.3886080000e+06, /* 0xcb000000 */
+-};
++#include <math-use-builtins.h>
+ 
+ float
+ __nearbyintf(float x)
+ {
++#if USE_NEARBYINTF_BUILTIN
++  return __builtin_nearbyintf (x);
++#else
++  /* Use generic implementation.  */
++  static const float
++    TWO23[2] = {
++		8.3886080000e+06, /* 0x4b000000 */
++		-8.3886080000e+06, /* 0xcb000000 */
++  };
+ 	fenv_t env;
+ 	int32_t i0,j0,sx;
+ 	float w,t;
+@@ -57,5 +61,6 @@ __nearbyintf(float x)
+ 	math_force_eval (t);
+ 	libc_fesetenvf (&env);
+ 	return t;
++#endif /* ! USE_NEARBYINT_BUILTIN  */
+ }
+ libm_alias_float (__nearbyint, nearbyint)
+diff --git a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
+index f044cb4334..a4ad8e82e5 100644
+--- a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
++++ b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
+@@ -28,15 +28,19 @@
+ #include <math-barriers.h>
+ #include <math_private.h>
+ #include <libm-alias-ldouble.h>
+-
+-static const _Float128
+-TWO112[2]={
+-  L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */
+- L(-5.19229685853482762853049632922009600E+33)  /* 0xC06F000000000000, 0 */
+-};
++#include <math-use-builtins.h>
+ 
+ _Float128 __nearbyintl(_Float128 x)
+ {
++#if USE_NEARBYINTL_BUILTIN
++  return __builtin_nearbyintl (x);
++#else
++  /* Use generic implementation.  */
++  static const _Float128
++    TWO112[2] = {
++		 L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */
++		 L(-5.19229685853482762853049632922009600E+33)  /* 0xC06F000000000000, 0 */
++  };
+ 	fenv_t env;
+ 	int64_t i0,j0,sx;
+ 	uint64_t i1 __attribute__ ((unused));
+@@ -65,5 +69,6 @@ _Float128 __nearbyintl(_Float128 x)
+ 	math_force_eval (t);
+ 	fesetenv (&env);
+ 	return t;
++#endif /* ! USE_NEARBYINTL_BUILTIN  */
+ }
+ libm_alias_ldouble (__nearbyint, nearbyint)
+diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h
+new file mode 100644
+index 0000000000..7abbfb3b50
+--- /dev/null
++++ b/sysdeps/s390/fpu/math-use-builtins.h
+@@ -0,0 +1,49 @@
++/* Using math gcc builtins instead of generic implementation.  s390/s390x version.
++   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/>.  */
++
++#ifndef MATH_USE_BUILTINS_S390_H
++#define MATH_USE_BUILTINS_S390_H	1
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++
++# include <features.h> /* For __GNUC_PREREQ.  */
++
++/* GCC emits the z196 zarch "load fp integer" instructions for these
++   builtins if build with at least --march=z196 -mzarch.  Otherwise a
++   function call to libc is emitted.  */
++# define USE_NEARBYINT_BUILTIN 1
++# define USE_NEARBYINTF_BUILTIN 1
++# define USE_NEARBYINTL_BUILTIN 1
++
++# if __GNUC_PREREQ (8, 0)
++#  define USE_NEARBYINTF128_BUILTIN 1
++# else
++#  define USE_NEARBYINTF128_BUILTIN 0
++# endif
++
++#else
++
++/* Disable the builtins if we do not have the z196 zarch instructions.  */
++# define USE_NEARBYINT_BUILTIN 0
++# define USE_NEARBYINTF_BUILTIN 0
++# define USE_NEARBYINTL_BUILTIN 0
++# define USE_NEARBYINTF128_BUILTIN 0
++
++#endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT  */
++
++#endif /* math-use-builtins.h */
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-08.patch b/SOURCES/glibc-rh1780204-08.patch
new file mode 100644
index 0000000..9dd3a6c
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-08.patch
@@ -0,0 +1,210 @@
+From d37e99de7ab1cd8c3d427f74bf8ceb5774795fe5 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:20 +0100
+Subject: [PATCH 08/28] Use GCC builtins for rint functions if desired.
+
+This patch is using the corresponding GCC builtin for rintf, rint,
+rintl and rintf128 if the USE_FUNCTION_BUILTIN macros are defined to one
+in math-use-builtins.h.
+
+This is the case for s390 if build with at least --march=z196 --mzarch.
+Otherwise the generic implementation is used.  The code of the generic
+implementation is not changed.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit a2a9b004297b777758420c952cb6eea5985d37fe)
+---
+ sysdeps/generic/math-use-builtins.h         |  5 +++++
+ sysdeps/ieee754/dbl-64/s_rint.c             | 17 +++++++++++------
+ sysdeps/ieee754/float128/float128_private.h |  3 +++
+ sysdeps/ieee754/flt-32/s_rintf.c            | 17 +++++++++++------
+ sysdeps/ieee754/ldbl-128/s_rintl.c          | 17 +++++++++++------
+ sysdeps/s390/fpu/math-use-builtins.h        | 11 +++++++++++
+ 6 files changed, 52 insertions(+), 18 deletions(-)
+
+diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h
+index e12490ed41..64b4a4bb5b 100644
+--- a/sysdeps/generic/math-use-builtins.h
++++ b/sysdeps/generic/math-use-builtins.h
+@@ -26,4 +26,9 @@
+ #define USE_NEARBYINTL_BUILTIN 0
+ #define USE_NEARBYINTF128_BUILTIN 0
+ 
++#define USE_RINT_BUILTIN 0
++#define USE_RINTF_BUILTIN 0
++#define USE_RINTL_BUILTIN 0
++#define USE_RINTF128_BUILTIN 0
++
+ #endif /* math-use-builtins.h */
+diff --git a/sysdeps/ieee754/dbl-64/s_rint.c b/sysdeps/ieee754/dbl-64/s_rint.c
+index 7f3dc87b96..5f4ac7c1e3 100644
+--- a/sysdeps/ieee754/dbl-64/s_rint.c
++++ b/sysdeps/ieee754/dbl-64/s_rint.c
+@@ -22,16 +22,20 @@
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-double.h>
+-
+-static const double
+-TWO52[2] = {
+-	    4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+-	    -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+-};
++#include <math-use-builtins.h>
+ 
+ double
+ __rint (double x)
+ {
++#if USE_RINT_BUILTIN
++  return __builtin_rint (x);
++#else
++  /* Use generic implementation.  */
++  static const double
++    TWO52[2] = {
++		4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
++		-4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
++  };
+   int64_t i0, sx;
+   int32_t j0;
+   EXTRACT_WORDS64 (i0, x);
+@@ -58,6 +62,7 @@ __rint (double x)
+     }
+   double w = TWO52[sx] + x;
+   return w - TWO52[sx];
++#endif /* ! USE_RINT_BUILTIN  */
+ }
+ #ifndef __rint
+ libm_alias_double (__rint, rint)
+diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
+index 0bf6e8dee2..b872aefbfd 100644
+--- a/sysdeps/ieee754/float128/float128_private.h
++++ b/sysdeps/ieee754/float128/float128_private.h
+@@ -141,6 +141,8 @@
+ #include <math-use-builtins.h>
+ #undef USE_NEARBYINTL_BUILTIN
+ #define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN
++#undef USE_RINTL_BUILTIN
++#define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN
+ 
+ /* IEEE function renames.  */
+ #define __ieee754_acoshl __ieee754_acoshf128
+@@ -343,6 +345,7 @@
+ #define __builtin_copysignl __builtin_copysignf128
+ #define __builtin_signbitl __builtin_signbit
+ #define __builtin_nearbyintl __builtin_nearbyintf128
++#define __builtin_rintl __builtin_rintf128
+ 
+ /* Get the constant suffix from bits/floatn-compat.h.  */
+ #define L(x) __f128 (x)
+diff --git a/sysdeps/ieee754/flt-32/s_rintf.c b/sysdeps/ieee754/flt-32/s_rintf.c
+index db6f260a0b..a266b1999e 100644
+--- a/sysdeps/ieee754/flt-32/s_rintf.c
++++ b/sysdeps/ieee754/flt-32/s_rintf.c
+@@ -16,16 +16,20 @@
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-float.h>
+-
+-static const float
+-TWO23[2]={
+-  8.3886080000e+06, /* 0x4b000000 */
+- -8.3886080000e+06, /* 0xcb000000 */
+-};
++#include <math-use-builtins.h>
+ 
+ float
+ __rintf(float x)
+ {
++#if USE_RINTF_BUILTIN
++  return __builtin_rintf (x);
++#else
++  /* Use generic implementation.  */
++  static const float
++    TWO23[2] = {
++		8.3886080000e+06, /* 0x4b000000 */
++		-8.3886080000e+06, /* 0xcb000000 */
++  };
+ 	int32_t i0,j0,sx;
+ 	float w,t;
+ 	GET_FLOAT_WORD(i0,x);
+@@ -45,6 +49,7 @@ __rintf(float x)
+ 	}
+ 	w = TWO23[sx]+x;
+ 	return w-TWO23[sx];
++#endif /* ! USE_RINTF_BUILTIN  */
+ }
+ #ifndef __rintf
+ libm_alias_float (__rint, rint)
+diff --git a/sysdeps/ieee754/ldbl-128/s_rintl.c b/sysdeps/ieee754/ldbl-128/s_rintl.c
+index 9e6637a225..f060503066 100644
+--- a/sysdeps/ieee754/ldbl-128/s_rintl.c
++++ b/sysdeps/ieee754/ldbl-128/s_rintl.c
+@@ -30,15 +30,19 @@ static char rcsid[] = "$NetBSD: $";
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-ldouble.h>
+-
+-static const _Float128
+-TWO112[2]={
+-  5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
+- -5.19229685853482762853049632922009600E+33L  /* 0xC06F000000000000, 0 */
+-};
++#include <math-use-builtins.h>
+ 
+ _Float128 __rintl(_Float128 x)
+ {
++#if USE_RINTL_BUILTIN
++  return __builtin_rintl (x);
++#else
++  /* Use generic implementation.  */
++  static const _Float128
++    TWO112[2] = {
++		 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
++		 -5.19229685853482762853049632922009600E+33L  /* 0xC06F000000000000, 0 */
++  };
+ 	int64_t i0,j0,sx;
+ 	uint64_t i1 __attribute__ ((unused));
+ 	_Float128 w,t;
+@@ -59,5 +63,6 @@ _Float128 __rintl(_Float128 x)
+ 	}
+ 	w = TWO112[sx]+x;
+ 	return w-TWO112[sx];
++#endif /* ! USE_RINTL_BUILTIN  */
+ }
+ libm_alias_ldouble (__rint, rint)
+diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h
+index 7abbfb3b50..8b702a6a90 100644
+--- a/sysdeps/s390/fpu/math-use-builtins.h
++++ b/sysdeps/s390/fpu/math-use-builtins.h
+@@ -30,10 +30,16 @@
+ # define USE_NEARBYINTF_BUILTIN 1
+ # define USE_NEARBYINTL_BUILTIN 1
+ 
++# define USE_RINT_BUILTIN 1
++# define USE_RINTF_BUILTIN 1
++# define USE_RINTL_BUILTIN 1
++
+ # if __GNUC_PREREQ (8, 0)
+ #  define USE_NEARBYINTF128_BUILTIN 1
++#  define USE_RINTF128_BUILTIN 1
+ # else
+ #  define USE_NEARBYINTF128_BUILTIN 0
++#  define USE_RINTF128_BUILTIN 0
+ # endif
+ 
+ #else
+@@ -44,6 +50,11 @@
+ # define USE_NEARBYINTL_BUILTIN 0
+ # define USE_NEARBYINTF128_BUILTIN 0
+ 
++# define USE_RINT_BUILTIN 0
++# define USE_RINTF_BUILTIN 0
++# define USE_RINTL_BUILTIN 0
++# define USE_RINTF128_BUILTIN 0
++
+ #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT  */
+ 
+ #endif /* math-use-builtins.h */
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-09.patch b/SOURCES/glibc-rh1780204-09.patch
new file mode 100644
index 0000000..fa6e2b6
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-09.patch
@@ -0,0 +1,182 @@
+From 8353881ede286045dc5bdc00af6407560ca5d05b Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:20 +0100
+Subject: [PATCH 09/28] Use GCC builtins for floor functions if desired.
+
+This patch is using the corresponding GCC builtin for floorf, floor,
+floorl and floorf128 if the USE_FUNCTION_BUILTIN macros are defined to one
+in math-use-builtins.h.
+
+This is the case for s390 if build with at least --march=z196 --mzarch.
+Otherwise the generic implementation is used.  The code of the generic
+implementation is not changed.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 6c1b6a5e8cd91e0e1965509ad91e627e60eb00a3)
+---
+ sysdeps/generic/math-use-builtins.h         |  5 +++++
+ sysdeps/ieee754/dbl-64/s_floor.c            |  6 ++++++
+ sysdeps/ieee754/float128/float128_private.h |  3 +++
+ sysdeps/ieee754/flt-32/s_floorf.c           |  6 ++++++
+ sysdeps/ieee754/ldbl-128/s_floorl.c         |  6 ++++++
+ sysdeps/s390/fpu/math-use-builtins.h        | 11 +++++++++++
+ 6 files changed, 37 insertions(+)
+
+diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h
+index 64b4a4bb5b..e1c5df62e4 100644
+--- a/sysdeps/generic/math-use-builtins.h
++++ b/sysdeps/generic/math-use-builtins.h
+@@ -31,4 +31,9 @@
+ #define USE_RINTL_BUILTIN 0
+ #define USE_RINTF128_BUILTIN 0
+ 
++#define USE_FLOOR_BUILTIN 0
++#define USE_FLOORF_BUILTIN 0
++#define USE_FLOORL_BUILTIN 0
++#define USE_FLOORF128_BUILTIN 0
++
+ #endif /* math-use-builtins.h */
+diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c
+index b551a1aafa..693938b708 100644
+--- a/sysdeps/ieee754/dbl-64/s_floor.c
++++ b/sysdeps/ieee754/dbl-64/s_floor.c
+@@ -34,6 +34,7 @@
+ #include <math_private.h>
+ #include <stdint.h>
+ #include <libm-alias-double.h>
++#include <math-use-builtins.h>
+ 
+ /*
+  * floor(x)
+@@ -45,6 +46,10 @@
+ double
+ __floor (double x)
+ {
++#if USE_FLOOR_BUILTIN
++  return __builtin_floor (x);
++#else
++  /* Use generic implementation.  */
+   int64_t i0;
+   EXTRACT_WORDS64 (i0, x);
+   int32_t j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
+@@ -72,6 +77,7 @@ __floor (double x)
+   else if (j0 == 0x400)
+     return x + x;			/* inf or NaN */
+   return x;
++#endif /* ! USE_FLOOR_BUILTIN  */
+ }
+ #ifndef __floor
+ libm_alias_double (__floor, floor)
+diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
+index b872aefbfd..667030ab06 100644
+--- a/sysdeps/ieee754/float128/float128_private.h
++++ b/sysdeps/ieee754/float128/float128_private.h
+@@ -143,6 +143,8 @@
+ #define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN
+ #undef USE_RINTL_BUILTIN
+ #define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN
++#undef USE_FLOORL_BUILTIN
++#define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN
+ 
+ /* IEEE function renames.  */
+ #define __ieee754_acoshl __ieee754_acoshf128
+@@ -346,6 +348,7 @@
+ #define __builtin_signbitl __builtin_signbit
+ #define __builtin_nearbyintl __builtin_nearbyintf128
+ #define __builtin_rintl __builtin_rintf128
++#define __builtin_floorl __builtin_floorf128
+ 
+ /* Get the constant suffix from bits/floatn-compat.h.  */
+ #define L(x) __f128 (x)
+diff --git a/sysdeps/ieee754/flt-32/s_floorf.c b/sysdeps/ieee754/flt-32/s_floorf.c
+index 12aed343a0..6d37ab90a1 100644
+--- a/sysdeps/ieee754/flt-32/s_floorf.c
++++ b/sysdeps/ieee754/flt-32/s_floorf.c
+@@ -23,10 +23,15 @@
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-float.h>
++#include <math-use-builtins.h>
+ 
+ float
+ __floorf(float x)
+ {
++#if USE_FLOORF_BUILTIN
++  return __builtin_floorf (x);
++#else
++  /* Use generic implementation.  */
+ 	int32_t i0,j0;
+ 	uint32_t i;
+ 	GET_FLOAT_WORD(i0,x);
+@@ -49,6 +54,7 @@ __floorf(float x)
+ 	}
+ 	SET_FLOAT_WORD(x,i0);
+ 	return x;
++#endif /* ! USE_FLOORF_BUILTIN  */
+ }
+ #ifndef __floorf
+ libm_alias_float (__floor, floor)
+diff --git a/sysdeps/ieee754/ldbl-128/s_floorl.c b/sysdeps/ieee754/ldbl-128/s_floorl.c
+index f9c5e014f9..6143fe6ec5 100644
+--- a/sysdeps/ieee754/ldbl-128/s_floorl.c
++++ b/sysdeps/ieee754/ldbl-128/s_floorl.c
+@@ -27,9 +27,14 @@ static char rcsid[] = "$NetBSD: $";
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-ldouble.h>
++#include <math-use-builtins.h>
+ 
+ _Float128 __floorl(_Float128 x)
+ {
++#if USE_FLOORL_BUILTIN
++  return __builtin_floorl (x);
++#else
++  /* Use generic implementation.  */
+ 	int64_t i0,i1,j0;
+ 	uint64_t i,j;
+ 	GET_LDOUBLE_WORDS64(i0,i1,x);
+@@ -64,5 +69,6 @@ _Float128 __floorl(_Float128 x)
+ 	}
+ 	SET_LDOUBLE_WORDS64(x,i0,i1);
+ 	return x;
++#endif /* ! USE_FLOORL_BUILTIN  */
+ }
+ libm_alias_ldouble (__floor, floor)
+diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h
+index 8b702a6a90..c213c16c6f 100644
+--- a/sysdeps/s390/fpu/math-use-builtins.h
++++ b/sysdeps/s390/fpu/math-use-builtins.h
+@@ -34,12 +34,18 @@
+ # define USE_RINTF_BUILTIN 1
+ # define USE_RINTL_BUILTIN 1
+ 
++# define USE_FLOOR_BUILTIN 1
++# define USE_FLOORF_BUILTIN 1
++# define USE_FLOORL_BUILTIN 1
++
+ # if __GNUC_PREREQ (8, 0)
+ #  define USE_NEARBYINTF128_BUILTIN 1
+ #  define USE_RINTF128_BUILTIN 1
++#  define USE_FLOORF128_BUILTIN 1
+ # else
+ #  define USE_NEARBYINTF128_BUILTIN 0
+ #  define USE_RINTF128_BUILTIN 0
++#  define USE_FLOORF128_BUILTIN 0
+ # endif
+ 
+ #else
+@@ -55,6 +61,11 @@
+ # define USE_RINTL_BUILTIN 0
+ # define USE_RINTF128_BUILTIN 0
+ 
++# define USE_FLOOR_BUILTIN 0
++# define USE_FLOORF_BUILTIN 0
++# define USE_FLOORL_BUILTIN 0
++# define USE_FLOORF128_BUILTIN 0
++
+ #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT  */
+ 
+ #endif /* math-use-builtins.h */
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-10.patch b/SOURCES/glibc-rh1780204-10.patch
new file mode 100644
index 0000000..3504976
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-10.patch
@@ -0,0 +1,182 @@
+From 6c5e5f498cd004b3f42d97997898018df8f798a4 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:21 +0100
+Subject: [PATCH 10/28] Use GCC builtins for ceil functions if desired.
+
+This patch is using the corresponding GCC builtin for ceilf, ceil,
+ceill and ceilf128 if the USE_FUNCTION_BUILTIN macros are defined to one
+in math-use-builtins.h.
+
+This is the case for s390 if build with at least --march=z196 --mzarch.
+Otherwise the generic implementation is used.  The code of the generic
+implementation is not changed.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 62560ee84095274bab1050817f42e782df226a17)
+---
+ sysdeps/generic/math-use-builtins.h         |  5 +++++
+ sysdeps/ieee754/dbl-64/s_ceil.c             |  6 ++++++
+ sysdeps/ieee754/float128/float128_private.h |  3 +++
+ sysdeps/ieee754/flt-32/s_ceilf.c            |  7 ++++++-
+ sysdeps/ieee754/ldbl-128/s_ceill.c          |  6 ++++++
+ sysdeps/s390/fpu/math-use-builtins.h        | 11 +++++++++++
+ 6 files changed, 37 insertions(+), 1 deletion(-)
+
+diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h
+index e1c5df62e4..076ec661b0 100644
+--- a/sysdeps/generic/math-use-builtins.h
++++ b/sysdeps/generic/math-use-builtins.h
+@@ -36,4 +36,9 @@
+ #define USE_FLOORL_BUILTIN 0
+ #define USE_FLOORF128_BUILTIN 0
+ 
++#define USE_CEIL_BUILTIN 0
++#define USE_CEILF_BUILTIN 0
++#define USE_CEILL_BUILTIN 0
++#define USE_CEILF128_BUILTIN 0
++
+ #endif /* math-use-builtins.h */
+diff --git a/sysdeps/ieee754/dbl-64/s_ceil.c b/sysdeps/ieee754/dbl-64/s_ceil.c
+index 3becdfc515..ee4a3abc19 100644
+--- a/sysdeps/ieee754/dbl-64/s_ceil.c
++++ b/sysdeps/ieee754/dbl-64/s_ceil.c
+@@ -20,10 +20,15 @@
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-double.h>
++#include <math-use-builtins.h>
+ 
+ double
+ __ceil (double x)
+ {
++#if USE_CEIL_BUILTIN
++  return __builtin_ceil (x);
++#else
++  /* Use generic implementation.  */
+   int64_t i0, i;
+   int32_t j0;
+   EXTRACT_WORDS64 (i0, x);
+@@ -57,6 +62,7 @@ __ceil (double x)
+     }
+   INSERT_WORDS64 (x, i0);
+   return x;
++#endif /* ! USE_CEIL_BUILTIN  */
+ }
+ #ifndef __ceil
+ libm_alias_double (__ceil, ceil)
+diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
+index 667030ab06..19352ca26c 100644
+--- a/sysdeps/ieee754/float128/float128_private.h
++++ b/sysdeps/ieee754/float128/float128_private.h
+@@ -145,6 +145,8 @@
+ #define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN
+ #undef USE_FLOORL_BUILTIN
+ #define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN
++#undef USE_CEILL_BUILTIN
++#define USE_CEILL_BUILTIN USE_CEILF128_BUILTIN
+ 
+ /* IEEE function renames.  */
+ #define __ieee754_acoshl __ieee754_acoshf128
+@@ -349,6 +351,7 @@
+ #define __builtin_nearbyintl __builtin_nearbyintf128
+ #define __builtin_rintl __builtin_rintf128
+ #define __builtin_floorl __builtin_floorf128
++#define __builtin_ceill __builtin_ceilf128
+ 
+ /* Get the constant suffix from bits/floatn-compat.h.  */
+ #define L(x) __f128 (x)
+diff --git a/sysdeps/ieee754/flt-32/s_ceilf.c b/sysdeps/ieee754/flt-32/s_ceilf.c
+index f289ec2341..6cab7bdd62 100644
+--- a/sysdeps/ieee754/flt-32/s_ceilf.c
++++ b/sysdeps/ieee754/flt-32/s_ceilf.c
+@@ -16,11 +16,15 @@
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-float.h>
+-
++#include <math-use-builtins.h>
+ 
+ float
+ __ceilf(float x)
+ {
++#if USE_CEILF_BUILTIN
++  return __builtin_ceilf (x);
++#else
++  /* Use generic implementation.  */
+ 	int32_t i0,j0;
+ 	uint32_t i;
+ 
+@@ -43,6 +47,7 @@ __ceilf(float x)
+ 	}
+ 	SET_FLOAT_WORD(x,i0);
+ 	return x;
++#endif /* ! USE_CEILF_BUILTIN  */
+ }
+ #ifndef __ceilf
+ libm_alias_float (__ceil, ceil)
+diff --git a/sysdeps/ieee754/ldbl-128/s_ceill.c b/sysdeps/ieee754/ldbl-128/s_ceill.c
+index e6aba5f2af..d212d86179 100644
+--- a/sysdeps/ieee754/ldbl-128/s_ceill.c
++++ b/sysdeps/ieee754/ldbl-128/s_ceill.c
+@@ -27,9 +27,14 @@ static char rcsid[] = "$NetBSD: $";
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-ldouble.h>
++#include <math-use-builtins.h>
+ 
+ _Float128 __ceill(_Float128 x)
+ {
++#if USE_CEILL_BUILTIN
++  return __builtin_ceill (x);
++#else
++  /* Use generic implementation.  */
+ 	int64_t i0,i1,j0;
+ 	uint64_t i,j;
+ 	GET_LDOUBLE_WORDS64(i0,i1,x);
+@@ -63,5 +68,6 @@ _Float128 __ceill(_Float128 x)
+ 	}
+ 	SET_LDOUBLE_WORDS64(x,i0,i1);
+ 	return x;
++#endif /* ! USE_CEILL_BUILTIN  */
+ }
+ libm_alias_ldouble (__ceil, ceil)
+diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h
+index c213c16c6f..5435cbb65f 100644
+--- a/sysdeps/s390/fpu/math-use-builtins.h
++++ b/sysdeps/s390/fpu/math-use-builtins.h
+@@ -38,14 +38,20 @@
+ # define USE_FLOORF_BUILTIN 1
+ # define USE_FLOORL_BUILTIN 1
+ 
++# define USE_CEIL_BUILTIN 1
++# define USE_CEILF_BUILTIN 1
++# define USE_CEILL_BUILTIN 1
++
+ # if __GNUC_PREREQ (8, 0)
+ #  define USE_NEARBYINTF128_BUILTIN 1
+ #  define USE_RINTF128_BUILTIN 1
+ #  define USE_FLOORF128_BUILTIN 1
++#  define USE_CEILF128_BUILTIN 1
+ # else
+ #  define USE_NEARBYINTF128_BUILTIN 0
+ #  define USE_RINTF128_BUILTIN 0
+ #  define USE_FLOORF128_BUILTIN 0
++#  define USE_CEILF128_BUILTIN 0
+ # endif
+ 
+ #else
+@@ -66,6 +72,11 @@
+ # define USE_FLOORL_BUILTIN 0
+ # define USE_FLOORF128_BUILTIN 0
+ 
++# define USE_CEIL_BUILTIN 0
++# define USE_CEILF_BUILTIN 0
++# define USE_CEILL_BUILTIN 0
++# define USE_CEILF128_BUILTIN 0
++
+ #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT  */
+ 
+ #endif /* math-use-builtins.h */
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-11.patch b/SOURCES/glibc-rh1780204-11.patch
new file mode 100644
index 0000000..533d478
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-11.patch
@@ -0,0 +1,187 @@
+From abc72a0694c1c3d08354170da343eead8d9afcc1 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:22 +0100
+Subject: [PATCH 11/28] Use GCC builtins for trunc functions if desired.
+
+This patch is using the corresponding GCC builtin for truncf, trunc,
+truncl and truncf128 if the USE_FUNCTION_BUILTIN macros are defined to one
+in math-use-builtins.h.
+
+This is the case for s390 if build with at least --march=z196 --mzarch.
+Otherwise the generic implementation is used.  The code of the generic
+implementation is not changed.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 1ac9c1cf87216bf9f8ac4f7c9754d025d9f2c4ae)
+---
+ sysdeps/generic/math-use-builtins.h         |  5 +++++
+ sysdeps/ieee754/dbl-64/s_trunc.c            |  6 ++++++
+ sysdeps/ieee754/float128/float128_private.h |  3 +++
+ sysdeps/ieee754/flt-32/s_truncf.c           |  6 ++++++
+ sysdeps/ieee754/ldbl-128/s_truncl.c         |  6 ++++++
+ sysdeps/s390/fpu/math-use-builtins.h        | 11 +++++++++++
+ 6 files changed, 37 insertions(+)
+
+diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h
+index 076ec661b0..ab379f45ba 100644
+--- a/sysdeps/generic/math-use-builtins.h
++++ b/sysdeps/generic/math-use-builtins.h
+@@ -41,4 +41,9 @@
+ #define USE_CEILL_BUILTIN 0
+ #define USE_CEILF128_BUILTIN 0
+ 
++#define USE_TRUNC_BUILTIN 0
++#define USE_TRUNCF_BUILTIN 0
++#define USE_TRUNCL_BUILTIN 0
++#define USE_TRUNCF128_BUILTIN 0
++
+ #endif /* math-use-builtins.h */
+diff --git a/sysdeps/ieee754/dbl-64/s_trunc.c b/sysdeps/ieee754/dbl-64/s_trunc.c
+index 38bb33d337..708169c727 100644
+--- a/sysdeps/ieee754/dbl-64/s_trunc.c
++++ b/sysdeps/ieee754/dbl-64/s_trunc.c
+@@ -21,11 +21,16 @@
+ 
+ #include <math_private.h>
+ #include <libm-alias-double.h>
++#include <math-use-builtins.h>
+ 
+ 
+ double
+ __trunc (double x)
+ {
++#if USE_TRUNC_BUILTIN
++  return __builtin_trunc (x);
++#else
++  /* Use generic implementation.  */
+   int64_t i0, j0;
+   int64_t sx;
+ 
+@@ -48,6 +53,7 @@ __trunc (double x)
+     }
+ 
+   return x;
++#endif /* ! USE_TRUNC_BUILTIN  */
+ }
+ #ifndef __trunc
+ libm_alias_double (__trunc, trunc)
+diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
+index 19352ca26c..e248600ec2 100644
+--- a/sysdeps/ieee754/float128/float128_private.h
++++ b/sysdeps/ieee754/float128/float128_private.h
+@@ -147,6 +147,8 @@
+ #define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN
+ #undef USE_CEILL_BUILTIN
+ #define USE_CEILL_BUILTIN USE_CEILF128_BUILTIN
++#undef USE_TRUNCL_BUILTIN
++#define USE_TRUNCL_BUILTIN USE_TRUNCF128_BUILTIN
+ 
+ /* IEEE function renames.  */
+ #define __ieee754_acoshl __ieee754_acoshf128
+@@ -352,6 +354,7 @@
+ #define __builtin_rintl __builtin_rintf128
+ #define __builtin_floorl __builtin_floorf128
+ #define __builtin_ceill __builtin_ceilf128
++#define __builtin_truncl __builtin_truncf128
+ 
+ /* Get the constant suffix from bits/floatn-compat.h.  */
+ #define L(x) __f128 (x)
+diff --git a/sysdeps/ieee754/flt-32/s_truncf.c b/sysdeps/ieee754/flt-32/s_truncf.c
+index 2e1464aeac..71491e5175 100644
+--- a/sysdeps/ieee754/flt-32/s_truncf.c
++++ b/sysdeps/ieee754/flt-32/s_truncf.c
+@@ -21,11 +21,16 @@
+ 
+ #include <math_private.h>
+ #include <libm-alias-float.h>
++#include <math-use-builtins.h>
+ 
+ 
+ float
+ __truncf (float x)
+ {
++#if USE_TRUNCF_BUILTIN
++  return __builtin_truncf (x);
++#else
++  /* Use generic implementation.  */
+   int32_t i0, j0;
+   int sx;
+ 
+@@ -48,6 +53,7 @@ __truncf (float x)
+     }
+ 
+   return x;
++#endif /* ! USE_TRUNCF_BUILTIN  */
+ }
+ #ifndef __truncf
+ libm_alias_float (__trunc, trunc)
+diff --git a/sysdeps/ieee754/ldbl-128/s_truncl.c b/sysdeps/ieee754/ldbl-128/s_truncl.c
+index f858ede3d2..aa49daaf85 100644
+--- a/sysdeps/ieee754/ldbl-128/s_truncl.c
++++ b/sysdeps/ieee754/ldbl-128/s_truncl.c
+@@ -22,11 +22,16 @@
+ 
+ #include <math_private.h>
+ #include <libm-alias-ldouble.h>
++#include <math-use-builtins.h>
+ 
+ 
+ _Float128
+ __truncl (_Float128 x)
+ {
++#if USE_TRUNCL_BUILTIN
++  return __builtin_truncl (x);
++#else
++  /* Use generic implementation.  */
+   int32_t j0;
+   uint64_t i0, i1, sx;
+ 
+@@ -53,5 +58,6 @@ __truncl (_Float128 x)
+     }
+ 
+   return x;
++#endif /* ! USE_TRUNCL_BUILTIN  */
+ }
+ libm_alias_ldouble (__trunc, trunc)
+diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h
+index 5435cbb65f..a39715c612 100644
+--- a/sysdeps/s390/fpu/math-use-builtins.h
++++ b/sysdeps/s390/fpu/math-use-builtins.h
+@@ -42,16 +42,22 @@
+ # define USE_CEILF_BUILTIN 1
+ # define USE_CEILL_BUILTIN 1
+ 
++# define USE_TRUNC_BUILTIN 1
++# define USE_TRUNCF_BUILTIN 1
++# define USE_TRUNCL_BUILTIN 1
++
+ # if __GNUC_PREREQ (8, 0)
+ #  define USE_NEARBYINTF128_BUILTIN 1
+ #  define USE_RINTF128_BUILTIN 1
+ #  define USE_FLOORF128_BUILTIN 1
+ #  define USE_CEILF128_BUILTIN 1
++#  define USE_TRUNCF128_BUILTIN 1
+ # else
+ #  define USE_NEARBYINTF128_BUILTIN 0
+ #  define USE_RINTF128_BUILTIN 0
+ #  define USE_FLOORF128_BUILTIN 0
+ #  define USE_CEILF128_BUILTIN 0
++#  define USE_TRUNCF128_BUILTIN 0
+ # endif
+ 
+ #else
+@@ -77,6 +83,11 @@
+ # define USE_CEILL_BUILTIN 0
+ # define USE_CEILF128_BUILTIN 0
+ 
++# define USE_TRUNC_BUILTIN 0
++# define USE_TRUNCF_BUILTIN 0
++# define USE_TRUNCL_BUILTIN 0
++# define USE_TRUNCF128_BUILTIN 0
++
+ #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT  */
+ 
+ #endif /* math-use-builtins.h */
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-12.patch b/SOURCES/glibc-rh1780204-12.patch
new file mode 100644
index 0000000..3b95873
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-12.patch
@@ -0,0 +1,187 @@
+From f49dd4cc4e295803e517190d1798bd84561d56f4 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:24 +0100
+Subject: [PATCH 12/28] Use GCC builtins for round functions if desired.
+
+This patch is using the corresponding GCC builtin for roundf, round,
+roundl and roundf128 if the USE_FUNCTION_BUILTIN macros are defined to one
+in math-use-builtins.h.
+
+This is the case for s390 if build with at least --march=z196 --mzarch.
+Otherwise the generic implementation is used.  The code of the generic
+implementation is not changed.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit f82996f8159981619ac7ed8a4c1838c2ad72ab61)
+---
+ sysdeps/generic/math-use-builtins.h         |  5 +++++
+ sysdeps/ieee754/dbl-64/s_round.c            |  6 ++++++
+ sysdeps/ieee754/float128/float128_private.h |  3 +++
+ sysdeps/ieee754/flt-32/s_roundf.c           |  6 ++++++
+ sysdeps/ieee754/ldbl-128/s_roundl.c         |  6 ++++++
+ sysdeps/s390/fpu/math-use-builtins.h        | 11 +++++++++++
+ 6 files changed, 37 insertions(+)
+
+diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h
+index ab379f45ba..34ca438a8c 100644
+--- a/sysdeps/generic/math-use-builtins.h
++++ b/sysdeps/generic/math-use-builtins.h
+@@ -46,4 +46,9 @@
+ #define USE_TRUNCL_BUILTIN 0
+ #define USE_TRUNCF128_BUILTIN 0
+ 
++#define USE_ROUND_BUILTIN 0
++#define USE_ROUNDF_BUILTIN 0
++#define USE_ROUNDL_BUILTIN 0
++#define USE_ROUNDF128_BUILTIN 0
++
+ #endif /* math-use-builtins.h */
+diff --git a/sysdeps/ieee754/dbl-64/s_round.c b/sysdeps/ieee754/dbl-64/s_round.c
+index bf9922edca..1f8482adf8 100644
+--- a/sysdeps/ieee754/dbl-64/s_round.c
++++ b/sysdeps/ieee754/dbl-64/s_round.c
+@@ -22,11 +22,16 @@
+ #include <math_private.h>
+ #include <libm-alias-double.h>
+ #include <stdint.h>
++#include <math-use-builtins.h>
+ 
+ 
+ double
+ __round (double x)
+ {
++#if USE_ROUND_BUILTIN
++  return __builtin_round (x);
++#else
++  /* Use generic implementation.  */
+   int64_t i0, j0;
+ 
+   EXTRACT_WORDS64 (i0, x);
+@@ -61,5 +66,6 @@ __round (double x)
+ 
+   INSERT_WORDS64 (x, i0);
+   return x;
++#endif /* ! USE_ROUND_BUILTIN  */
+ }
+ libm_alias_double (__round, round)
+diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
+index e248600ec2..3297a71e44 100644
+--- a/sysdeps/ieee754/float128/float128_private.h
++++ b/sysdeps/ieee754/float128/float128_private.h
+@@ -149,6 +149,8 @@
+ #define USE_CEILL_BUILTIN USE_CEILF128_BUILTIN
+ #undef USE_TRUNCL_BUILTIN
+ #define USE_TRUNCL_BUILTIN USE_TRUNCF128_BUILTIN
++#undef USE_ROUNDL_BUILTIN
++#define USE_ROUNDL_BUILTIN USE_ROUNDF128_BUILTIN
+ 
+ /* IEEE function renames.  */
+ #define __ieee754_acoshl __ieee754_acoshf128
+@@ -355,6 +357,7 @@
+ #define __builtin_floorl __builtin_floorf128
+ #define __builtin_ceill __builtin_ceilf128
+ #define __builtin_truncl __builtin_truncf128
++#define __builtin_roundl __builtin_roundf128
+ 
+ /* Get the constant suffix from bits/floatn-compat.h.  */
+ #define L(x) __f128 (x)
+diff --git a/sysdeps/ieee754/flt-32/s_roundf.c b/sysdeps/ieee754/flt-32/s_roundf.c
+index 7c95125d9c..6fdfbbbade 100644
+--- a/sysdeps/ieee754/flt-32/s_roundf.c
++++ b/sysdeps/ieee754/flt-32/s_roundf.c
+@@ -21,11 +21,16 @@
+ 
+ #include <math_private.h>
+ #include <libm-alias-float.h>
++#include <math-use-builtins.h>
+ 
+ 
+ float
+ __roundf (float x)
+ {
++#if USE_ROUNDF_BUILTIN
++  return __builtin_roundf (x);
++#else
++  /* Use generic implementation.  */
+   int32_t i0, j0;
+ 
+   GET_FLOAT_WORD (i0, x);
+@@ -60,5 +65,6 @@ __roundf (float x)
+ 
+   SET_FLOAT_WORD (x, i0);
+   return x;
++#endif /* ! USE_ROUNDF_BUILTIN  */
+ }
+ libm_alias_float (__round, round)
+diff --git a/sysdeps/ieee754/ldbl-128/s_roundl.c b/sysdeps/ieee754/ldbl-128/s_roundl.c
+index 22789cedf3..564f8ac1b8 100644
+--- a/sysdeps/ieee754/ldbl-128/s_roundl.c
++++ b/sysdeps/ieee754/ldbl-128/s_roundl.c
+@@ -22,11 +22,16 @@
+ 
+ #include <math_private.h>
+ #include <libm-alias-ldouble.h>
++#include <math-use-builtins.h>
+ 
+ 
+ _Float128
+ __roundl (_Float128 x)
+ {
++#if USE_ROUNDL_BUILTIN
++  return __builtin_roundl (x);
++#else
++  /* Use generic implementation.  */
+   int32_t j0;
+   uint64_t i1, i0;
+ 
+@@ -77,5 +82,6 @@ __roundl (_Float128 x)
+ 
+   SET_LDOUBLE_WORDS64 (x, i0, i1);
+   return x;
++#endif /* ! USE_ROUNDL_BUILTIN  */
+ }
+ libm_alias_ldouble (__round, round)
+diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h
+index a39715c612..51cb9f91ab 100644
+--- a/sysdeps/s390/fpu/math-use-builtins.h
++++ b/sysdeps/s390/fpu/math-use-builtins.h
+@@ -46,18 +46,24 @@
+ # define USE_TRUNCF_BUILTIN 1
+ # define USE_TRUNCL_BUILTIN 1
+ 
++# define USE_ROUND_BUILTIN 1
++# define USE_ROUNDF_BUILTIN 1
++# define USE_ROUNDL_BUILTIN 1
++
+ # if __GNUC_PREREQ (8, 0)
+ #  define USE_NEARBYINTF128_BUILTIN 1
+ #  define USE_RINTF128_BUILTIN 1
+ #  define USE_FLOORF128_BUILTIN 1
+ #  define USE_CEILF128_BUILTIN 1
+ #  define USE_TRUNCF128_BUILTIN 1
++#  define USE_ROUNDF128_BUILTIN 1
+ # else
+ #  define USE_NEARBYINTF128_BUILTIN 0
+ #  define USE_RINTF128_BUILTIN 0
+ #  define USE_FLOORF128_BUILTIN 0
+ #  define USE_CEILF128_BUILTIN 0
+ #  define USE_TRUNCF128_BUILTIN 0
++#  define USE_ROUNDF128_BUILTIN 0
+ # endif
+ 
+ #else
+@@ -88,6 +94,11 @@
+ # define USE_TRUNCL_BUILTIN 0
+ # define USE_TRUNCF128_BUILTIN 0
+ 
++# define USE_ROUND_BUILTIN 0
++# define USE_ROUNDF_BUILTIN 0
++# define USE_ROUNDL_BUILTIN 0
++# define USE_ROUNDF128_BUILTIN 0
++
+ #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT  */
+ 
+ #endif /* math-use-builtins.h */
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-13.patch b/SOURCES/glibc-rh1780204-13.patch
new file mode 100644
index 0000000..72ed332
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-13.patch
@@ -0,0 +1,177 @@
+From e93b17fad37a61f7ae9a663c617926b0f510921a Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:24 +0100
+Subject: [PATCH 13/28] Use GCC builtins for copysign functions if desired.
+
+This patch is always using the corresponding GCC builtin for copysignf, copysign,
+and is using the builtin for copysignl, copysignf128 if the USE_FUNCTION_BUILTIN
+macros are defined to one in math-use-builtins.h.
+
+Altough the long double version is enabled by default we still need
+the macro and the alternative implementation as the _Float128 version
+of the builtin is not available with all supported GCC versions.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit f818afdd3b29d7eef2010448457c9f5c16e684cd)
+---
+ sysdeps/generic/math-use-builtins.h         |  9 +++++++++
+ sysdeps/ieee754/dbl-64/s_copysign.c         |  9 ++-------
+ sysdeps/ieee754/float128/float128_private.h |  3 +++
+ sysdeps/ieee754/flt-32/s_copysignf.c        | 12 ++++--------
+ sysdeps/ieee754/ldbl-128/s_copysignl.c      |  6 ++++++
+ sysdeps/s390/fpu/math-use-builtins.h        |  7 +++++++
+ 6 files changed, 31 insertions(+), 15 deletions(-)
+
+diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h
+index 34ca438a8c..770b54ce61 100644
+--- a/sysdeps/generic/math-use-builtins.h
++++ b/sysdeps/generic/math-use-builtins.h
+@@ -19,6 +19,8 @@
+ #ifndef MATH_USE_BUILTINS_H
+ #define MATH_USE_BUILTINS_H	1
+ 
++#include <features.h> /* For __GNUC_PREREQ.  */
++
+ /* Define these macros to 1 to use __builtin_xyz instead of the
+    generic implementation.  */
+ #define USE_NEARBYINT_BUILTIN 0
+@@ -51,4 +53,11 @@
+ #define USE_ROUNDL_BUILTIN 0
+ #define USE_ROUNDF128_BUILTIN 0
+ 
++#define USE_COPYSIGNL_BUILTIN 1
++#if __GNUC_PREREQ (7, 0)
++# define USE_COPYSIGNF128_BUILTIN 1
++#else
++# define USE_COPYSIGNF128_BUILTIN 0
++#endif
++
+ #endif /* math-use-builtins.h */
+diff --git a/sysdeps/ieee754/dbl-64/s_copysign.c b/sysdeps/ieee754/dbl-64/s_copysign.c
+index ab81d732ab..b95f1575d9 100644
+--- a/sysdeps/ieee754/dbl-64/s_copysign.c
++++ b/sysdeps/ieee754/dbl-64/s_copysign.c
+@@ -10,7 +10,7 @@
+  * ====================================================
+  */
+ 
+-#if defined(LIBM_SCCS) && !defined(lint)
++#if defined (LIBM_SCCS) && ! defined (lint)
+ static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $";
+ #endif
+ 
+@@ -21,16 +21,11 @@ static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $
+  */
+ 
+ #include <math.h>
+-#include <math_private.h>
+ #include <libm-alias-double.h>
+ 
+ double
+ __copysign (double x, double y)
+ {
+-  uint32_t hx, hy;
+-  GET_HIGH_WORD (hx, x);
+-  GET_HIGH_WORD (hy, y);
+-  SET_HIGH_WORD (x, (hx & 0x7fffffff) | (hy & 0x80000000));
+-  return x;
++  return __builtin_copysign (x, y);
+ }
+ libm_alias_double (__copysign, copysign)
+diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
+index 3297a71e44..077df0e09f 100644
+--- a/sysdeps/ieee754/float128/float128_private.h
++++ b/sysdeps/ieee754/float128/float128_private.h
+@@ -151,6 +151,8 @@
+ #define USE_TRUNCL_BUILTIN USE_TRUNCF128_BUILTIN
+ #undef USE_ROUNDL_BUILTIN
+ #define USE_ROUNDL_BUILTIN USE_ROUNDF128_BUILTIN
++#undef USE_COPYSIGNL_BUILTIN
++#define USE_COPYSIGNL_BUILTIN USE_COPYSIGNF128_BUILTIN
+ 
+ /* IEEE function renames.  */
+ #define __ieee754_acoshl __ieee754_acoshf128
+@@ -358,6 +360,7 @@
+ #define __builtin_ceill __builtin_ceilf128
+ #define __builtin_truncl __builtin_truncf128
+ #define __builtin_roundl __builtin_roundf128
++#define __builtin_copysignl __builtin_copysignf128
+ 
+ /* Get the constant suffix from bits/floatn-compat.h.  */
+ #define L(x) __f128 (x)
+diff --git a/sysdeps/ieee754/flt-32/s_copysignf.c b/sysdeps/ieee754/flt-32/s_copysignf.c
+index 3c4ac7ce68..0247abd152 100644
+--- a/sysdeps/ieee754/flt-32/s_copysignf.c
++++ b/sysdeps/ieee754/flt-32/s_copysignf.c
+@@ -13,7 +13,7 @@
+  * ====================================================
+  */
+ 
+-#if defined(LIBM_SCCS) && !defined(lint)
++#if defined (LIBM_SCCS) && ! defined (lint)
+ static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4 1995/05/10 20:46:59 jtc Exp $";
+ #endif
+ 
+@@ -24,15 +24,11 @@ static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4 1995/05/10 20:46:59 jtc Exp
+  */
+ 
+ #include <math.h>
+-#include <math_private.h>
+ #include <libm-alias-float.h>
+ 
+-float __copysignf(float x, float y)
++float
++__copysignf (float x, float y)
+ {
+-	uint32_t ix,iy;
+-	GET_FLOAT_WORD(ix,x);
+-	GET_FLOAT_WORD(iy,y);
+-	SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000));
+-        return x;
++  return __builtin_copysignf (x, y);
+ }
+ libm_alias_float (__copysign, copysign)
+diff --git a/sysdeps/ieee754/ldbl-128/s_copysignl.c b/sysdeps/ieee754/ldbl-128/s_copysignl.c
+index d23e0f72ea..4cae8612dc 100644
+--- a/sysdeps/ieee754/ldbl-128/s_copysignl.c
++++ b/sysdeps/ieee754/ldbl-128/s_copysignl.c
+@@ -26,14 +26,20 @@ static char rcsid[] = "$NetBSD: $";
+ #include <math.h>
+ #include <math_private.h>
+ #include <libm-alias-ldouble.h>
++#include <math-use-builtins.h>
+ 
+ _Float128 __copysignl(_Float128 x, _Float128 y)
+ {
++#if USE_COPYSIGNL_BUILTIN
++  return __builtin_copysignl (x, y);
++#else
++  /* Use generic implementation.  */
+ 	uint64_t hx,hy;
+ 	GET_LDOUBLE_MSW64(hx,x);
+ 	GET_LDOUBLE_MSW64(hy,y);
+ 	SET_LDOUBLE_MSW64(x,(hx&0x7fffffffffffffffULL)
+ 			    |(hy&0x8000000000000000ULL));
+         return x;
++#endif /* ! USE_COPYSIGNL_BUILTIN  */
+ }
+ libm_alias_ldouble (__copysign, copysign)
+diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h
+index 51cb9f91ab..4c4aad2ab5 100644
+--- a/sysdeps/s390/fpu/math-use-builtins.h
++++ b/sysdeps/s390/fpu/math-use-builtins.h
+@@ -101,4 +101,11 @@
+ 
+ #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT  */
+ 
++#define USE_COPYSIGNL_BUILTIN 1
++#if __GNUC_PREREQ (7, 0)
++# define USE_COPYSIGNF128_BUILTIN 1
++#else
++# define USE_COPYSIGNF128_BUILTIN 0
++#endif
++
+ #endif /* math-use-builtins.h */
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-14.patch b/SOURCES/glibc-rh1780204-14.patch
new file mode 100644
index 0000000..6e58c11
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-14.patch
@@ -0,0 +1,180 @@
+From bd7c710d3b234a8d3bd77aae358bd7f7a6ce576d Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:25 +0100
+Subject: [PATCH 14/28] Adjust s_nearbyintf.c and s_nearbyintl.c regarding code
+ style.
+
+This patch just adjusts the generic implementation regarding code style.
+No functional change.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 6a3866dae98cccc8cd7a0a4c1fb409dba9192a83)
+---
+ sysdeps/ieee754/flt-32/s_nearbyintf.c   | 60 ++++++++++++-----------
+ sysdeps/ieee754/ldbl-128/s_nearbyintl.c | 63 ++++++++++++++-----------
+ 2 files changed, 68 insertions(+), 55 deletions(-)
+
+diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c
+index 438dcae8cc..5969e3e5b8 100644
+--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c
++++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c
+@@ -23,7 +23,7 @@
+ #include <math-use-builtins.h>
+ 
+ float
+-__nearbyintf(float x)
++__nearbyintf (float x)
+ {
+ #if USE_NEARBYINTF_BUILTIN
+   return __builtin_nearbyintf (x);
+@@ -34,33 +34,39 @@ __nearbyintf(float x)
+ 		8.3886080000e+06, /* 0x4b000000 */
+ 		-8.3886080000e+06, /* 0xcb000000 */
+   };
+-	fenv_t env;
+-	int32_t i0,j0,sx;
+-	float w,t;
+-	GET_FLOAT_WORD(i0,x);
+-	sx = (i0>>31)&1;
+-	j0 = ((i0>>23)&0xff)-0x7f;
+-	if(j0<23) {
+-	    if(j0<0) {
+-		libc_feholdexceptf (&env);
+-		w = TWO23[sx] + math_opt_barrier (x);
+-		t =  w-TWO23[sx];
+-		math_force_eval (t);
+-		libc_fesetenvf (&env);
+-		GET_FLOAT_WORD(i0,t);
+-		SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+-		return t;
+-	    }
+-	} else {
+-	    if(__builtin_expect(j0==0x80, 0)) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
++  fenv_t env;
++  int32_t i0, j0, sx;
++  float w, t;
++  GET_FLOAT_WORD (i0, x);
++  sx = (i0 >> 31) & 1;
++  j0 = ((i0 >> 23) & 0xff) - 0x7f;
++  if (j0 < 23)
++    {
++      if (j0 < 0)
++	{
++	  libc_feholdexceptf (&env);
++	  w = TWO23[sx] + math_opt_barrier (x);
++	  t =  w - TWO23[sx];
++	  math_force_eval (t);
++	  libc_fesetenvf (&env);
++	  GET_FLOAT_WORD (i0, t);
++	  SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31));
++	  return t;
+ 	}
+-	libc_feholdexceptf (&env);
+-	w = TWO23[sx] + math_opt_barrier (x);
+-	t = w-TWO23[sx];
+-	math_force_eval (t);
+-	libc_fesetenvf (&env);
+-	return t;
++    }
++  else
++    {
++      if (__glibc_unlikely (j0 == 0x80))
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++  }
++  libc_feholdexceptf (&env);
++  w = TWO23[sx] + math_opt_barrier (x);
++  t = w - TWO23[sx];
++  math_force_eval (t);
++  libc_fesetenvf (&env);
++  return t;
+ #endif /* ! USE_NEARBYINT_BUILTIN  */
+ }
+ libm_alias_float (__nearbyint, nearbyint)
+diff --git a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
+index a4ad8e82e5..8d26786f78 100644
+--- a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
++++ b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
+@@ -30,7 +30,8 @@
+ #include <libm-alias-ldouble.h>
+ #include <math-use-builtins.h>
+ 
+-_Float128 __nearbyintl(_Float128 x)
++_Float128
++__nearbyintl (_Float128 x)
+ {
+ #if USE_NEARBYINTL_BUILTIN
+   return __builtin_nearbyintl (x);
+@@ -41,34 +42,40 @@ _Float128 __nearbyintl(_Float128 x)
+ 		 L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */
+ 		 L(-5.19229685853482762853049632922009600E+33)  /* 0xC06F000000000000, 0 */
+   };
+-	fenv_t env;
+-	int64_t i0,j0,sx;
+-	uint64_t i1 __attribute__ ((unused));
+-	_Float128 w,t;
+-	GET_LDOUBLE_WORDS64(i0,i1,x);
+-	sx = (((uint64_t)i0)>>63);
+-	j0 = ((i0>>48)&0x7fff)-0x3fff;
+-	if(j0<112) {
+-	    if(j0<0) {
+-		feholdexcept (&env);
+-	        w = TWO112[sx] + math_opt_barrier (x);
+-	        t = w-TWO112[sx];
+-		math_force_eval (t);
+-	        fesetenv (&env);
+-		GET_LDOUBLE_MSW64(i0,t);
+-		SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63));
+-	        return t;
+-	    }
+-	} else {
+-	    if(j0==0x4000) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
++  fenv_t env;
++  int64_t i0, j0, sx;
++  uint64_t i1 __attribute__ ((unused));
++  _Float128 w, t;
++  GET_LDOUBLE_WORDS64 (i0, i1, x);
++  sx = (((uint64_t) i0) >> 63);
++  j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
++  if (j0 < 112)
++    {
++      if (j0 < 0)
++	{
++	  feholdexcept (&env);
++	  w = TWO112[sx] + math_opt_barrier (x);
++	  t = w - TWO112[sx];
++	  math_force_eval (t);
++	  fesetenv (&env);
++	  GET_LDOUBLE_MSW64 (i0, t);
++	  SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63));
++	  return t;
+ 	}
+-	feholdexcept (&env);
+-	w = TWO112[sx] + math_opt_barrier (x);
+-	t = w-TWO112[sx];
+-	math_force_eval (t);
+-	fesetenv (&env);
+-	return t;
++    }
++  else
++    {
++      if (j0 == 0x4000)
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++    }
++  feholdexcept (&env);
++  w = TWO112[sx] + math_opt_barrier (x);
++  t = w - TWO112[sx];
++  math_force_eval (t);
++  fesetenv (&env);
++  return t;
+ #endif /* ! USE_NEARBYINTL_BUILTIN  */
+ }
+ libm_alias_ldouble (__nearbyint, nearbyint)
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-15.patch b/SOURCES/glibc-rh1780204-15.patch
new file mode 100644
index 0000000..47a5661
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-15.patch
@@ -0,0 +1,156 @@
+From ce4f299c02be0a06130b70a62aa79b77385f4326 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:26 +0100
+Subject: [PATCH 15/28] Adjust s_rintf.c and s_rintl.c regarding code style.
+
+This patch just adjusts the generic implementation regarding code style.
+No functional change.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 99b39a83e72f4b58e2f284fd844622df26b3b5fe)
+---
+ sysdeps/ieee754/flt-32/s_rintf.c   | 44 +++++++++++++++------------
+ sysdeps/ieee754/ldbl-128/s_rintl.c | 49 +++++++++++++++++-------------
+ 2 files changed, 53 insertions(+), 40 deletions(-)
+
+diff --git a/sysdeps/ieee754/flt-32/s_rintf.c b/sysdeps/ieee754/flt-32/s_rintf.c
+index a266b1999e..3463a044e1 100644
+--- a/sysdeps/ieee754/flt-32/s_rintf.c
++++ b/sysdeps/ieee754/flt-32/s_rintf.c
+@@ -19,7 +19,7 @@
+ #include <math-use-builtins.h>
+ 
+ float
+-__rintf(float x)
++__rintf (float x)
+ {
+ #if USE_RINTF_BUILTIN
+   return __builtin_rintf (x);
+@@ -30,25 +30,31 @@ __rintf(float x)
+ 		8.3886080000e+06, /* 0x4b000000 */
+ 		-8.3886080000e+06, /* 0xcb000000 */
+   };
+-	int32_t i0,j0,sx;
+-	float w,t;
+-	GET_FLOAT_WORD(i0,x);
+-	sx = (i0>>31)&1;
+-	j0 = ((i0>>23)&0xff)-0x7f;
+-	if(j0<23) {
+-	    if(j0<0) {
+-		w = TWO23[sx]+x;
+-		t =  w-TWO23[sx];
+-		GET_FLOAT_WORD(i0,t);
+-		SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+-		return t;
+-	    }
+-	} else {
+-	    if(j0==0x80) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
++  int32_t i0, j0, sx;
++  float w, t;
++  GET_FLOAT_WORD (i0, x);
++  sx = (i0 >> 31) & 1;
++  j0 = ((i0 >> 23) & 0xff) - 0x7f;
++  if (j0 < 23)
++    {
++      if(j0 < 0)
++	{
++	  w = TWO23[sx] + x;
++	  t =  w - TWO23[sx];
++	  GET_FLOAT_WORD (i0, t);
++	  SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31));
++	  return t;
+ 	}
+-	w = TWO23[sx]+x;
+-	return w-TWO23[sx];
++    }
++  else
++    {
++      if (j0 == 0x80)
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++    }
++  w = TWO23[sx] + x;
++  return w - TWO23[sx];
+ #endif /* ! USE_RINTF_BUILTIN  */
+ }
+ #ifndef __rintf
+diff --git a/sysdeps/ieee754/ldbl-128/s_rintl.c b/sysdeps/ieee754/ldbl-128/s_rintl.c
+index f060503066..260f3aa9b9 100644
+--- a/sysdeps/ieee754/ldbl-128/s_rintl.c
++++ b/sysdeps/ieee754/ldbl-128/s_rintl.c
+@@ -13,7 +13,7 @@
+  * ====================================================
+  */
+ 
+-#if defined(LIBM_SCCS) && !defined(lint)
++#if defined (LIBM_SCCS) && ! defined (lint)
+ static char rcsid[] = "$NetBSD: $";
+ #endif
+ 
+@@ -32,7 +32,8 @@ static char rcsid[] = "$NetBSD: $";
+ #include <libm-alias-ldouble.h>
+ #include <math-use-builtins.h>
+ 
+-_Float128 __rintl(_Float128 x)
++_Float128
++__rintl (_Float128 x)
+ {
+ #if USE_RINTL_BUILTIN
+   return __builtin_rintl (x);
+@@ -43,26 +44,32 @@ _Float128 __rintl(_Float128 x)
+ 		 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
+ 		 -5.19229685853482762853049632922009600E+33L  /* 0xC06F000000000000, 0 */
+   };
+-	int64_t i0,j0,sx;
+-	uint64_t i1 __attribute__ ((unused));
+-	_Float128 w,t;
+-	GET_LDOUBLE_WORDS64(i0,i1,x);
+-	sx = (((uint64_t)i0)>>63);
+-	j0 = ((i0>>48)&0x7fff)-0x3fff;
+-	if(j0<112) {
+-	    if(j0<0) {
+-	        w = TWO112[sx]+x;
+-	        t = w-TWO112[sx];
+-		GET_LDOUBLE_MSW64(i0,t);
+-		SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63));
+-	        return t;
+-	    }
+-	} else {
+-	    if(j0==0x4000) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
++  int64_t i0, j0, sx;
++  uint64_t i1 __attribute__ ((unused));
++  _Float128 w, t;
++  GET_LDOUBLE_WORDS64 (i0, i1, x);
++  sx = (((uint64_t) i0) >> 63);
++  j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
++  if (j0 < 112)
++    {
++      if (j0 < 0)
++	{
++	  w = TWO112[sx] + x;
++	  t = w - TWO112[sx];
++	  GET_LDOUBLE_MSW64 (i0, t);
++	  SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63));
++	  return t;
+ 	}
+-	w = TWO112[sx]+x;
+-	return w-TWO112[sx];
++    }
++  else
++    {
++      if (j0 == 0x4000)
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++    }
++  w = TWO112[sx] + x;
++  return w - TWO112[sx];
+ #endif /* ! USE_RINTL_BUILTIN  */
+ }
+ libm_alias_ldouble (__rint, rint)
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-16.patch b/SOURCES/glibc-rh1780204-16.patch
new file mode 100644
index 0000000..47d84fd
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-16.patch
@@ -0,0 +1,198 @@
+From e96879644e4a9f4304725d1da9cc76b0c685b0b8 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:26 +0100
+Subject: [PATCH 16/28] Adjust s_floorf.c and s_floorl.c regarding code style.
+
+This patch just adjusts the generic implementation regarding code style.
+No functional change.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit d3a0409ab615e133ff3ea27b492de75a607cff4a)
+---
+ sysdeps/ieee754/flt-32/s_floorf.c   | 55 +++++++++++-------
+ sysdeps/ieee754/ldbl-128/s_floorl.c | 89 ++++++++++++++++++-----------
+ 2 files changed, 90 insertions(+), 54 deletions(-)
+
+diff --git a/sysdeps/ieee754/flt-32/s_floorf.c b/sysdeps/ieee754/flt-32/s_floorf.c
+index 6d37ab90a1..c45816e3bd 100644
+--- a/sysdeps/ieee754/flt-32/s_floorf.c
++++ b/sysdeps/ieee754/flt-32/s_floorf.c
+@@ -26,34 +26,45 @@
+ #include <math-use-builtins.h>
+ 
+ float
+-__floorf(float x)
++__floorf (float x)
+ {
+ #if USE_FLOORF_BUILTIN
+   return __builtin_floorf (x);
+ #else
+   /* Use generic implementation.  */
+-	int32_t i0,j0;
+-	uint32_t i;
+-	GET_FLOAT_WORD(i0,x);
+-	j0 = ((i0>>23)&0xff)-0x7f;
+-	if(j0<23) {
+-	    if(j0<0) {
+-		/* return 0*sign(x) if |x|<1 */
+-		if(i0>=0) {i0=0;}
+-		else if((i0&0x7fffffff)!=0)
+-		  { i0=0xbf800000;}
+-	    } else {
+-		i = (0x007fffff)>>j0;
+-		if((i0&i)==0) return x; /* x is integral */
+-		if(i0<0) i0 += (0x00800000)>>j0;
+-		i0 &= (~i);
+-	    }
+-	} else {
+-	    if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */
+-	    else return x;		/* x is integral */
++  int32_t i0, j0;
++  uint32_t i;
++  GET_FLOAT_WORD (i0, x);
++  j0 = ((i0 >> 23) & 0xff) - 0x7f;
++  if (j0 < 23)
++    {
++      if (j0 < 0)
++	{
++	  /* return 0 * sign (x) if |x| < 1  */
++	  if (i0 >= 0)
++	    i0 = 0;
++	  else if ((i0 & 0x7fffffff) != 0)
++	    i0 = 0xbf800000;
+ 	}
+-	SET_FLOAT_WORD(x,i0);
+-	return x;
++      else
++	{
++	  i = (0x007fffff) >> j0;
++	  if ((i0 & i) == 0)
++	    return x;		/* x is integral  */
++	  if (i0 < 0)
++	    i0 += (0x00800000) >> j0;
++	  i0 &= (~i);
++	}
++    }
++  else
++    {
++      if (__glibc_unlikely (j0 == 0x80))
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++    }
++  SET_FLOAT_WORD (x, i0);
++  return x;
+ #endif /* ! USE_FLOORF_BUILTIN  */
+ }
+ #ifndef __floorf
+diff --git a/sysdeps/ieee754/ldbl-128/s_floorl.c b/sysdeps/ieee754/ldbl-128/s_floorl.c
+index 6143fe6ec5..4fc10992c2 100644
+--- a/sysdeps/ieee754/ldbl-128/s_floorl.c
++++ b/sysdeps/ieee754/ldbl-128/s_floorl.c
+@@ -29,46 +29,71 @@ static char rcsid[] = "$NetBSD: $";
+ #include <libm-alias-ldouble.h>
+ #include <math-use-builtins.h>
+ 
+-_Float128 __floorl(_Float128 x)
++_Float128
++__floorl (_Float128 x)
+ {
+ #if USE_FLOORL_BUILTIN
+   return __builtin_floorl (x);
+ #else
+   /* Use generic implementation.  */
+-	int64_t i0,i1,j0;
+-	uint64_t i,j;
+-	GET_LDOUBLE_WORDS64(i0,i1,x);
+-	j0 = ((i0>>48)&0x7fff)-0x3fff;
+-	if(j0<48) {
+-	    if(j0<0) {
+-		/* return 0*sign(x) if |x|<1 */
+-		if(i0>=0) {i0=i1=0;}
+-		else if(((i0&0x7fffffffffffffffLL)|i1)!=0)
+-		    { i0=0xbfff000000000000ULL;i1=0;}
+-	    } else {
+-		i = (0x0000ffffffffffffULL)>>j0;
+-		if(((i0&i)|i1)==0) return x; /* x is integral */
+-		if(i0<0) i0 += (0x0001000000000000LL)>>j0;
+-		i0 &= (~i); i1=0;
++  int64_t i0, i1, j0;
++  uint64_t i, j;
++  GET_LDOUBLE_WORDS64 (i0, i1, x);
++  j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
++  if (j0 < 48)
++    {
++      if (j0 < 0)
++	{
++	  /* return 0 * sign (x) if |x| < 1 */
++	  if (i0 >= 0)
++	    {
++	      i0 = i1 = 0;
+ 	    }
+-	} else if (j0>111) {
+-	    if(j0==0x4000) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
+-	} else {
+-	    i = -1ULL>>(j0-48);
+-	    if((i1&i)==0) return x;	/* x is integral */
+-	    if(i0<0) {
+-		if(j0==48) i0+=1;
+-		else {
+-		    j = i1+(1LL<<(112-j0));
+-		    if(j<i1) i0 +=1 ; 	/* got a carry */
+-		    i1=j;
+-		}
++	  else if (((i0 & 0x7fffffffffffffffLL) | i1) != 0)
++	    {
++	      i0 = 0xbfff000000000000ULL;
++	      i1 = 0;
+ 	    }
+-	    i1 &= (~i);
+ 	}
+-	SET_LDOUBLE_WORDS64(x,i0,i1);
+-	return x;
++      else
++	{
++	  i = (0x0000ffffffffffffULL) >> j0;
++	  if (((i0 & i) | i1) == 0)
++	    return x;		/* x is integral  */
++	  if (i0 < 0)
++	    i0 += (0x0001000000000000LL) >> j0;
++	  i0 &= (~i);
++	  i1 = 0;
++	}
++    }
++  else if (j0 > 111)
++    {
++      if (j0 == 0x4000)
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++    }
++  else
++    {
++      i = -1ULL >> (j0 - 48);
++      if ((i1 & i) == 0)
++	return x;		/* x is integral  */
++      if (i0 < 0)
++	{
++	  if (j0 == 48)
++	    i0 += 1;
++	  else
++	    {
++	      j = i1 + (1LL << (112 - j0));
++	      if (j < i1)
++		i0 += 1 ;	/* got a carry */
++	      i1 = j;
++	    }
++	}
++      i1 &= (~i);
++    }
++  SET_LDOUBLE_WORDS64 (x, i0, i1);
++  return x;
+ #endif /* ! USE_FLOORL_BUILTIN  */
+ }
+ libm_alias_ldouble (__floor, floor)
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-17.patch b/SOURCES/glibc-rh1780204-17.patch
new file mode 100644
index 0000000..c8e447c
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-17.patch
@@ -0,0 +1,207 @@
+From 77b9cf86bba41d44e084337a11bfbf5ee7c98a38 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:27 +0100
+Subject: [PATCH 17/28] Adjust s_ceilf.c and s_ceill.c regarding code style.
+
+This patch just adjusts the generic implementation regarding code style.
+No functional change.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 171d23d7cbce7b6f175a6690e625ccf80b647d23)
+---
+ sysdeps/ieee754/flt-32/s_ceilf.c   | 54 +++++++++++-------
+ sysdeps/ieee754/ldbl-128/s_ceill.c | 91 +++++++++++++++++++-----------
+ 2 files changed, 92 insertions(+), 53 deletions(-)
+
+diff --git a/sysdeps/ieee754/flt-32/s_ceilf.c b/sysdeps/ieee754/flt-32/s_ceilf.c
+index 6cab7bdd62..f60d0ac1f5 100644
+--- a/sysdeps/ieee754/flt-32/s_ceilf.c
++++ b/sysdeps/ieee754/flt-32/s_ceilf.c
+@@ -19,34 +19,46 @@
+ #include <math-use-builtins.h>
+ 
+ float
+-__ceilf(float x)
++__ceilf (float x)
+ {
+ #if USE_CEILF_BUILTIN
+   return __builtin_ceilf (x);
+ #else
+   /* Use generic implementation.  */
+-	int32_t i0,j0;
+-	uint32_t i;
++  int32_t i0, j0;
++  uint32_t i;
+ 
+-	GET_FLOAT_WORD(i0,x);
+-	j0 = ((i0>>23)&0xff)-0x7f;
+-	if(j0<23) {
+-	    if(j0<0) {
+-		/* return 0*sign(x) if |x|<1 */
+-		if(i0<0) {i0=0x80000000;}
+-		else if(i0!=0) { i0=0x3f800000;}
+-	    } else {
+-		i = (0x007fffff)>>j0;
+-		if((i0&i)==0) return x; /* x is integral */
+-		if(i0>0) i0 += (0x00800000)>>j0;
+-		i0 &= (~i);
+-	    }
+-	} else {
+-	    if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */
+-	    else return x;		/* x is integral */
++  GET_FLOAT_WORD (i0, x);
++  j0 = ((i0 >> 23) & 0xff) - 0x7f;
++  if (j0 < 23)
++    {
++      if (j0 < 0)
++	{
++	  /* return 0 * sign (x) if |x| < 1  */
++	  if (i0 < 0)
++	    i0 = 0x80000000;
++	  else if (i0 != 0)
++	    i0 = 0x3f800000;
+ 	}
+-	SET_FLOAT_WORD(x,i0);
+-	return x;
++      else
++	{
++	  i = (0x007fffff) >> j0;
++	  if ((i0 & i) == 0)
++	    return x;		/* x is integral  */
++	  if (i0 > 0)
++	    i0 += (0x00800000) >> j0;
++	  i0 &= (~i);
++	}
++    }
++  else
++    {
++      if (__glibc_unlikely (j0 == 0x80))
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++    }
++  SET_FLOAT_WORD (x, i0);
++  return x;
+ #endif /* ! USE_CEILF_BUILTIN  */
+ }
+ #ifndef __ceilf
+diff --git a/sysdeps/ieee754/ldbl-128/s_ceill.c b/sysdeps/ieee754/ldbl-128/s_ceill.c
+index d212d86179..df75dc3008 100644
+--- a/sysdeps/ieee754/ldbl-128/s_ceill.c
++++ b/sysdeps/ieee754/ldbl-128/s_ceill.c
+@@ -13,7 +13,7 @@
+  * ====================================================
+  */
+ 
+-#if defined(LIBM_SCCS) && !defined(lint)
++#if defined (LIBM_SCCS) && ! defined (lint)
+ static char rcsid[] = "$NetBSD: $";
+ #endif
+ 
+@@ -29,45 +29,72 @@ static char rcsid[] = "$NetBSD: $";
+ #include <libm-alias-ldouble.h>
+ #include <math-use-builtins.h>
+ 
+-_Float128 __ceill(_Float128 x)
++_Float128
++__ceill (_Float128 x)
+ {
+ #if USE_CEILL_BUILTIN
+   return __builtin_ceill (x);
+ #else
+   /* Use generic implementation.  */
+-	int64_t i0,i1,j0;
+-	uint64_t i,j;
+-	GET_LDOUBLE_WORDS64(i0,i1,x);
+-	j0 = ((i0>>48)&0x7fff)-0x3fff;
+-	if(j0<48) {
+-	    if(j0<0) {
+-		/* return 0*sign(x) if |x|<1 */
+-		if(i0<0) {i0=0x8000000000000000ULL;i1=0;}
+-		else if((i0|i1)!=0) { i0=0x3fff000000000000ULL;i1=0;}
+-	    } else {
+-		i = (0x0000ffffffffffffULL)>>j0;
+-		if(((i0&i)|i1)==0) return x; /* x is integral */
+-		if(i0>0) i0 += (0x0001000000000000LL)>>j0;
+-		i0 &= (~i); i1=0;
++  int64_t i0, i1, j0;
++  uint64_t i, j;
++  GET_LDOUBLE_WORDS64 (i0, i1, x);
++  j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
++  if (j0 < 48)
++    {
++      if (j0 < 0)
++	{
++	  /* return 0 * sign (x) if |x| < 1  */
++	  if (i0 < 0)
++	    {
++	      i0 = 0x8000000000000000ULL;
++	      i1 = 0;
+ 	    }
+-	} else if (j0>111) {
+-	    if(j0==0x4000) return x+x;	/* inf or NaN */
+-	    else return x;		/* x is integral */
+-	} else {
+-	    i = -1ULL>>(j0-48);
+-	    if((i1&i)==0) return x;	/* x is integral */
+-	    if(i0>0) {
+-		if(j0==48) i0+=1;
+-		else {
+-		    j = i1+(1LL<<(112-j0));
+-		    if(j<i1) i0 +=1 ; 	/* got a carry */
+-		    i1=j;
+-		}
++	  else if ((i0 | i1) != 0)
++	    {
++	      i0 = 0x3fff000000000000ULL;
++	      i1 = 0;
+ 	    }
+-	    i1 &= (~i);
+ 	}
+-	SET_LDOUBLE_WORDS64(x,i0,i1);
+-	return x;
++      else
++	{
++	  i = (0x0000ffffffffffffULL) >> j0;
++	  if (((i0 & i) | i1) == 0)
++	    return x;		/* x is integral  */
++	  if (i0 > 0)
++	    i0 += (0x0001000000000000LL) >> j0;
++	  i0 &= (~i);
++	  i1 = 0;
++	}
++    }
++  else if (j0 > 111)
++    {
++      if (j0 == 0x4000)
++	return x + x;		/* inf or NaN  */
++      else
++	return x;		/* x is integral  */
++    }
++  else
++    {
++      i = -1ULL >> (j0 - 48);
++      if ((i1 & i) == 0)
++	return x;		/* x is integral  */
++      if (i0 > 0)
++	{
++	  if (j0 == 48)
++	    i0 += 1;
++	  else
++	    {
++	      j = i1 + (1LL << (112 - j0));
++	      if (j < i1)
++		i0 += 1;	/* got a carry  */
++	      i1 = j;
++	    }
++	}
++      i1 &= (~i);
++    }
++  SET_LDOUBLE_WORDS64 (x, i0, i1);
++  return x;
+ #endif /* ! USE_CEILL_BUILTIN  */
+ }
+ libm_alias_ldouble (__ceil, ceil)
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-18.patch b/SOURCES/glibc-rh1780204-18.patch
new file mode 100644
index 0000000..feb6f36
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-18.patch
@@ -0,0 +1,57 @@
+From f6e3f49613f4a31bce8c5f52ae440f9c7b3646fb Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:28 +0100
+Subject: [PATCH 18/28] Adjust s_copysignl.c regarding code style.
+
+This patch just adjusts the generic implementation regarding code style.
+No functional change.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+(cherry picked from commit 1902d5d5ff04771f16b67648789c75a18af06222)
+---
+ sysdeps/ieee754/ldbl-128/s_copysignl.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/sysdeps/ieee754/ldbl-128/s_copysignl.c b/sysdeps/ieee754/ldbl-128/s_copysignl.c
+index 4cae8612dc..9b0e44cf1d 100644
+--- a/sysdeps/ieee754/ldbl-128/s_copysignl.c
++++ b/sysdeps/ieee754/ldbl-128/s_copysignl.c
+@@ -13,7 +13,7 @@
+  * ====================================================
+  */
+ 
+-#if defined(LIBM_SCCS) && !defined(lint)
++#if defined (LIBM_SCCS) && ! defined (lint)
+ static char rcsid[] = "$NetBSD: $";
+ #endif
+ 
+@@ -28,18 +28,19 @@ static char rcsid[] = "$NetBSD: $";
+ #include <libm-alias-ldouble.h>
+ #include <math-use-builtins.h>
+ 
+-_Float128 __copysignl(_Float128 x, _Float128 y)
++_Float128
++__copysignl (_Float128 x, _Float128 y)
+ {
+ #if USE_COPYSIGNL_BUILTIN
+   return __builtin_copysignl (x, y);
+ #else
+   /* Use generic implementation.  */
+-	uint64_t hx,hy;
+-	GET_LDOUBLE_MSW64(hx,x);
+-	GET_LDOUBLE_MSW64(hy,y);
+-	SET_LDOUBLE_MSW64(x,(hx&0x7fffffffffffffffULL)
+-			    |(hy&0x8000000000000000ULL));
+-        return x;
++  uint64_t hx, hy;
++  GET_LDOUBLE_MSW64 (hx, x);
++  GET_LDOUBLE_MSW64 (hy, y);
++  SET_LDOUBLE_MSW64 (x, (hx & 0x7fffffffffffffffULL)
++		     | (hy & 0x8000000000000000ULL));
++  return x;
+ #endif /* ! USE_COPYSIGNL_BUILTIN  */
+ }
+ libm_alias_ldouble (__copysign, copysign)
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-19.patch b/SOURCES/glibc-rh1780204-19.patch
new file mode 100644
index 0000000..bda184c
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-19.patch
@@ -0,0 +1,157 @@
+From 855d045bc26175195dadafc28abf84e7b6613aac Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:28 +0100
+Subject: [PATCH 19/28] S390: Use load-fp-integer instruction for roundeven
+ functions.
+
+If compiled with z196 zarch support, the load-fp-integer instruction
+is used to implement roundeven, roundevenf, roundevenl.
+Otherwise the common-code implementation is used.
+
+(cherry picked from commit 4399b163376b331773e43917dcf56ce68e43e6a0)
+---
+ sysdeps/s390/fpu/s_roundeven.c  | 39 +++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_roundevenf.c | 38 ++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_roundevenl.c | 39 +++++++++++++++++++++++++++++++++
+ 3 files changed, 116 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/s_roundeven.c
+ create mode 100644 sysdeps/s390/fpu/s_roundevenf.c
+ create mode 100644 sysdeps/s390/fpu/s_roundevenl.c
+
+diff --git a/sysdeps/s390/fpu/s_roundeven.c b/sysdeps/s390/fpu/s_roundeven.c
+new file mode 100644
+index 0000000000..95a83a70e8
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_roundeven.c
+@@ -0,0 +1,39 @@
++/* roundeven() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <libm-alias-double.h>
++
++double
++__roundeven (double x)
++{
++  double y;
++  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
++     x to the nearest integer with "ties to even" rounding mode
++     (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("fidbra %0,4,%1,4" : "=f" (y) : "f" (x));
++  return y;
++}
++hidden_def (__roundeven)
++libm_alias_double (__roundeven, roundeven)
++
++#else
++# include <sysdeps/ieee754/dbl-64/s_roundeven.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_roundevenf.c b/sysdeps/s390/fpu/s_roundevenf.c
+new file mode 100644
+index 0000000000..c620a0189c
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_roundevenf.c
+@@ -0,0 +1,38 @@
++/* roundevenf() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <libm-alias-float.h>
++
++float
++__roundevenf (float x)
++{
++  float y;
++  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
++     x to the nearest integer with "ties to even" rounding mode
++     (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("fiebra %0,4,%1,4" : "=f" (y) : "f" (x));
++  return y;
++}
++libm_alias_float (__roundeven, roundeven)
++
++#else
++# include <sysdeps/ieee754/flt-32/s_roundevenf.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_roundevenl.c b/sysdeps/s390/fpu/s_roundevenl.c
+new file mode 100644
+index 0000000000..3481af2665
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_roundevenl.c
+@@ -0,0 +1,39 @@
++/* roundevenl() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <math_private.h>
++# include <libm-alias-ldouble.h>
++
++_Float128
++__roundevenl (_Float128 x)
++{
++  _Float128 y;
++  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
++     x to the nearest integer with "ties to even" rounding mode
++     (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("fixbra %0,4,%1,4" : "=f" (y) : "f" (x));
++  return y;
++}
++libm_alias_ldouble (__roundeven, roundeven)
++
++#else
++# include <sysdeps/ieee754/ldbl-128/s_roundevenl.c>
++#endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-20.patch b/SOURCES/glibc-rh1780204-20.patch
new file mode 100644
index 0000000..4967ce3
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-20.patch
@@ -0,0 +1,207 @@
+From 90e84ac5ac8e774ce0cfd3abc5f7d8834efd2c9b Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:29 +0100
+Subject: [PATCH 20/28] S390: Use convert-to-fixed instruction for lrint
+ functions.
+
+If compiled with z196 zarch support, the convert-to-fixed instruction
+is used to implement lrint, lrintf, lrintl.
+Otherwise the common-code implementation is used.
+
+(cherry picked from commit e3f07622209c1b4436ef364b134dfd2cd4ca9976)
+---
+ sysdeps/s390/fpu/s_lrint.c  | 55 ++++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_lrintf.c | 55 ++++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_lrintl.c | 56 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 166 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/s_lrint.c
+ create mode 100644 sysdeps/s390/fpu/s_lrintf.c
+ create mode 100644 sysdeps/s390/fpu/s_lrintl.c
+
+diff --git a/sysdeps/s390/fpu/s_lrint.c b/sysdeps/s390/fpu/s_lrint.c
+new file mode 100644
+index 0000000000..7be60665b5
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_lrint.c
+@@ -0,0 +1,55 @@
++/* lrint() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <libm-alias-double.h>
++
++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
++   Thus we need different instructions as the target size is encoded there.
++   Note: On s390 this instruction is only used if build with -mzarch.  */
++# ifdef __s390x__
++#  define INSN "cgdbra"
++# else
++#  define INSN "cfdbra"
++# endif
++
++long int
++__lrint (double x)
++{
++  long int y;
++  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
++     according to current rounding mode (M3-field: 0).
++     First convert x with suppressed inexact exception and check if the
++     resulting value is beyond the target limits (indicated by cc=3;
++     Note: a nan is also indicated by cc=3).
++     If the resulting value is within the target limits, redo
++     without suppressing the inexact exception.  */
++  __asm__ (INSN " %0,0,%1,4 \n\t"
++	   "jo 1f \n\t"
++	   INSN " %0,0,%1,0 \n\t"
++	   "1:"
++	   : "=&d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_double (__lrint, lrint)
++
++#else
++# include <sysdeps/ieee754/dbl-64/s_lrint.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_lrintf.c b/sysdeps/s390/fpu/s_lrintf.c
+new file mode 100644
+index 0000000000..d6a2a4081a
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_lrintf.c
+@@ -0,0 +1,55 @@
++/* lrintf() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <libm-alias-float.h>
++
++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
++   Thus we need different instructions as the target size is encoded there.
++   Note: On s390 this instruction is only used if build with -mzarch.  */
++# ifdef __s390x__
++#  define INSN "cgebra"
++# else
++#  define INSN "cfebra"
++# endif
++
++long int
++__lrintf (float x)
++{
++  long int y;
++  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
++     according to current rounding mode (M3-field: 0).
++     First convert x with suppressed inexact exception and check if the
++     resulting value is beyond the target limits (indicated by cc=3;
++     Note: a nan is also indicated by cc=3).
++     If the resulting value is within the target limits, redo
++     without suppressing the inexact exception.  */
++  __asm__ (INSN " %0,0,%1,4 \n\t"
++	   "jo 1f \n\t"
++	   INSN " %0,0,%1,0 \n\t"
++	   "1:"
++	   : "=&d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_float (__lrint, lrint)
++
++#else
++# include <sysdeps/ieee754/flt-32/s_lrintf.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_lrintl.c b/sysdeps/s390/fpu/s_lrintl.c
+new file mode 100644
+index 0000000000..2d386ecff9
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_lrintl.c
+@@ -0,0 +1,56 @@
++/* lrintl() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <math_private.h>
++# include <libm-alias-ldouble.h>
++
++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
++   Thus we need different instructions as the target size is encoded there.
++   Note: On s390 this instruction is only used if build with -mzarch.  */
++# ifdef __s390x__
++#  define INSN "cgxbra"
++# else
++#  define INSN "cfxbra"
++# endif
++
++long int
++__lrintl (_Float128 x)
++{
++  long int y;
++  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
++     according to current rounding mode (M3-field: 0).
++     First convert x with suppressed inexact exception and check if the
++     resulting value is beyond the target limits (indicated by cc=3;
++     Note: a nan is also indicated by cc=3).
++     If the resulting value is within the target limits, redo
++     without suppressing the inexact exception.  */
++  __asm__ (INSN " %0,0,%1,4 \n\t"
++	   "jo 1f \n\t"
++	   INSN " %0,0,%1,0 \n\t"
++	   "1:"
++	   : "=&d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_ldouble (__lrint, lrint)
++
++#else
++# include <sysdeps/ieee754/ldbl-128/s_lrintl.c>
++#endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-21.patch b/SOURCES/glibc-rh1780204-21.patch
new file mode 100644
index 0000000..743e16c
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-21.patch
@@ -0,0 +1,192 @@
+From 429eff12541cc0779c381f84257c8860ece25b12 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:29 +0100
+Subject: [PATCH 21/28] S390: Use convert-to-fixed instruction for llrint
+ functions.
+
+If compiled with z196 zarch support, the convert-to-fixed instruction
+is used to implement llrint, llrintf, llrintl.
+Otherwise the common-code implementation is used.
+
+(cherry picked from commit f10c1654fe13d797d2fd347dc47f72f93c58cf62)
+---
+ sysdeps/s390/fpu/s_llrint.c  | 50 +++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_llrintf.c | 50 +++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_llrintl.c | 51 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 151 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/s_llrint.c
+ create mode 100644 sysdeps/s390/fpu/s_llrintf.c
+ create mode 100644 sysdeps/s390/fpu/s_llrintl.c
+
+diff --git a/sysdeps/s390/fpu/s_llrint.c b/sysdeps/s390/fpu/s_llrint.c
+new file mode 100644
+index 0000000000..edd796ae8c
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_llrint.c
+@@ -0,0 +1,50 @@
++/* llrint() - S390 version.
++   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/>.  */
++
++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++/* We only support s390x as on s390 a long long int refers to a register pair
++   of two 4byte registers instead of a 8byte register which is produced by the
++   instruction.
++   Note: On s390 this instruction would only be used if build with -mzarch.  */
++# include <math.h>
++# include <libm-alias-double.h>
++
++long long int
++__llrint (double x)
++{
++  long long int y;
++  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
++     according to current rounding mode (M3-field: 0).
++     First convert x with suppressed inexact exception and check if the
++     resulting value is beyond the target limits (indicated by cc=3;
++     Note: a nan is also indicated by cc=3).
++     If the resulting value is within the target limits, redo
++     without suppressing the inexact exception.  */
++  __asm__ ("cgdbra %0,0,%1,4 \n\t"
++	   "jo 1f \n\t"
++	   "cgdbra %0,0,%1,0 \n\t"
++	   "1:"
++	   : "=&d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_double (__llrint, llrint)
++
++#else
++# include <sysdeps/ieee754/dbl-64/s_llrint.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_llrintf.c b/sysdeps/s390/fpu/s_llrintf.c
+new file mode 100644
+index 0000000000..3cbe7c581a
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_llrintf.c
+@@ -0,0 +1,50 @@
++/* llrintf() - S390 version.
++   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/>.  */
++
++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++/* We only support s390x as on s390 a long long int refers to a register pair
++   of two 4byte registers instead of a 8byte register which is produced by the
++   instruction.
++   Note: On s390 this instruction would only be used if build with -mzarch.  */
++# include <math.h>
++# include <libm-alias-float.h>
++
++long long int
++__llrintf (float x)
++{
++  long long int y;
++  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
++     according to current rounding mode (M3-field: 0).
++     First convert x with suppressed inexact exception and check if the
++     resulting value is beyond the target limits (indicated by cc=3;
++     Note: a nan is also indicated by cc=3).
++     If the resulting value is within the target limits, redo
++     without suppressing the inexact exception.  */
++  __asm__ ("cgebra %0,0,%1,4 \n\t"
++	   "jo 1f \n\t"
++	   "cgebra %0,0,%1,0 \n\t"
++	   "1:"
++	   : "=&d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_float (__llrint, llrint)
++
++#else
++# include <sysdeps/ieee754/flt-32/s_llrintf.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_llrintl.c b/sysdeps/s390/fpu/s_llrintl.c
+new file mode 100644
+index 0000000000..37eea5914f
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_llrintl.c
+@@ -0,0 +1,51 @@
++/* llrintl() - S390 version.
++   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/>.  */
++
++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++/* We only support s390x as on s390 a long long int refers to a register pair
++   of two 4byte registers instead of a 8byte register which is produced by the
++   instruction.
++   Note: On s390 this instruction would only be used if build with -mzarch.  */
++# include <math.h>
++# include <math_private.h>
++# include <libm-alias-ldouble.h>
++
++long long int
++__llrintl (_Float128 x)
++{
++  long long int y;
++  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
++     according to current rounding mode (M3-field: 0).
++     First convert x with suppressed inexact exception and check if the
++     resulting value is beyond the target limits (indicated by cc=3;
++     Note: a nan is also indicated by cc=3).
++     If the resulting value is within the target limits, redo
++     without suppressing the inexact exception.  */
++  __asm__ ("cgxbra %0,0,%1,4 \n\t"
++	   "jo 1f \n\t"
++	   "cgxbra %0,0,%1,0 \n\t"
++	   "1:"
++	   : "=&d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_ldouble (__llrint, llrint)
++
++#else
++# include <sysdeps/ieee754/ldbl-128/s_llrintl.c>
++#endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-22.patch b/SOURCES/glibc-rh1780204-22.patch
new file mode 100644
index 0000000..db29fa3
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-22.patch
@@ -0,0 +1,183 @@
+From 9f3ee7825b1eae00431ea6477fce8210aaced7db Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:30 +0100
+Subject: [PATCH 22/28] S390: Use convert-to-fixed instruction for lround
+ functions.
+
+If compiled with z196 zarch support, the convert-to-fixed instruction
+is used to implement lround, lroundf, lroundl.
+Otherwise the common-code implementation is used.
+
+(cherry picked from commit 9d9f3527daf65fdca0eb46eaa324b81b8f94d88c)
+---
+ sysdeps/s390/fpu/s_lround.c  | 47 +++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_lroundf.c | 47 +++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_lroundl.c | 48 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 142 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/s_lround.c
+ create mode 100644 sysdeps/s390/fpu/s_lroundf.c
+ create mode 100644 sysdeps/s390/fpu/s_lroundl.c
+
+diff --git a/sysdeps/s390/fpu/s_lround.c b/sysdeps/s390/fpu/s_lround.c
+new file mode 100644
+index 0000000000..9290ec32cd
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_lround.c
+@@ -0,0 +1,47 @@
++/* lround() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <libm-alias-double.h>
++
++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
++   Thus we need different instructions as the target size is encoded there.
++   Note: On s390 this instruction is only used if build with -mzarch.  */
++# ifdef __s390x__
++#  define INSN "cgdbra"
++# else
++#  define INSN "cfdbra"
++# endif
++
++long int
++__lround (double x)
++{
++  long int y;
++  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
++     x to the nearest integer with "ties away from 0" rounding mode
++     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_double (__lround, lround)
++
++#else
++# include <sysdeps/ieee754/dbl-64/s_lround.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_lroundf.c b/sysdeps/s390/fpu/s_lroundf.c
+new file mode 100644
+index 0000000000..097b924c91
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_lroundf.c
+@@ -0,0 +1,47 @@
++/* lroundf() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <libm-alias-float.h>
++
++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
++   Thus we need different instructions as the target size is encoded there.
++   Note: On s390 this instruction is only used if build with -mzarch.  */
++# ifdef __s390x__
++#  define INSN "cgebra"
++# else
++#  define INSN "cfebra"
++# endif
++
++long int
++__lroundf (float x)
++{
++  long int y;
++  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
++     x to the nearest integer with "ties away from 0" rounding mode
++     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_float (__lround, lround)
++
++#else
++# include <sysdeps/ieee754/flt-32/s_lroundf.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_lroundl.c b/sysdeps/s390/fpu/s_lroundl.c
+new file mode 100644
+index 0000000000..0ef77dc667
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_lroundl.c
+@@ -0,0 +1,48 @@
++/* lroundl() - S390 version.
++   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/>.  */
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# include <math.h>
++# include <math_private.h>
++# include <libm-alias-ldouble.h>
++
++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
++   Thus we need different instructions as the target size is encoded there.
++   Note: On s390 this instruction is only used if build with -mzarch.  */
++# ifdef __s390x__
++#  define INSN "cgxbra"
++# else
++#  define INSN "cfxbra"
++# endif
++
++long int
++__lroundl (_Float128 x)
++{
++  long int y;
++  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
++     x to the nearest integer with "ties away from 0" rounding mode
++     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_ldouble (__lround, lround)
++
++#else
++# include <sysdeps/ieee754/ldbl-128/s_lroundl.c>
++#endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-23.patch b/SOURCES/glibc-rh1780204-23.patch
new file mode 100644
index 0000000..bcd8965
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-23.patch
@@ -0,0 +1,168 @@
+From dd8bfb911e89f3ad1da5cfa5618a8c52c62bb095 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:31 +0100
+Subject: [PATCH 23/28] S390: Use convert-to-fixed instruction for llround
+ functions.
+
+If compiled with z196 zarch support, the convert-to-fixed instruction
+is used to implement llround, llroundf, llroundl.
+Otherwise the common-code implementation is used.
+
+(cherry picked from commit 7d42d614fdc2c9d9f6ad46111bd6130501d50460)
+---
+ sysdeps/s390/fpu/s_llround.c  | 42 ++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_llroundf.c | 42 ++++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/s_llroundl.c | 43 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 127 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/s_llround.c
+ create mode 100644 sysdeps/s390/fpu/s_llroundf.c
+ create mode 100644 sysdeps/s390/fpu/s_llroundl.c
+
+diff --git a/sysdeps/s390/fpu/s_llround.c b/sysdeps/s390/fpu/s_llround.c
+new file mode 100644
+index 0000000000..f4a1b21637
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_llround.c
+@@ -0,0 +1,42 @@
++/* llround() - S390 version.
++   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/>.  */
++
++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++/* We only support s390x as on s390 a long long int refers to a register pair
++   of two 4byte registers instead of a 8byte register which is produced by the
++   instruction.
++   Note: On s390 this instruction would only be used if build with -mzarch.  */
++# include <math.h>
++# include <libm-alias-double.h>
++
++long long int
++__llround (double x)
++{
++  long long int y;
++  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
++     x to the nearest integer with "ties away from 0" rounding mode
++     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("cgdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_double (__llround, llround)
++
++#else
++# include <sysdeps/ieee754/dbl-64/s_llround.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_llroundf.c b/sysdeps/s390/fpu/s_llroundf.c
+new file mode 100644
+index 0000000000..d202f4be8c
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_llroundf.c
+@@ -0,0 +1,42 @@
++/* llroundf() - S390 version.
++   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/>.  */
++
++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++/* We only support s390x as on s390 a long long int refers to a register pair
++   of two 4byte registers instead of a 8byte register which is produced by the
++   instruction.
++   Note: On s390 this instruction would only be used if build with -mzarch.  */
++# include <math.h>
++# include <libm-alias-float.h>
++
++long long int
++__llroundf (float x)
++{
++  long long int y;
++  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
++     x to the nearest integer with "ties away from 0" rounding mode
++     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("cgebra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_float (__llround, llround)
++
++#else
++# include <sysdeps/ieee754/flt-32/s_llroundf.c>
++#endif
+diff --git a/sysdeps/s390/fpu/s_llroundl.c b/sysdeps/s390/fpu/s_llroundl.c
+new file mode 100644
+index 0000000000..58976cd5c5
+--- /dev/null
++++ b/sysdeps/s390/fpu/s_llroundl.c
+@@ -0,0 +1,43 @@
++/* llroundl() - S390 version.
++   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/>.  */
++
++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++/* We only support s390x as on s390 a long long int refers to a register pair
++   of two 4byte registers instead of a 8byte register which is produced by the
++   instruction.
++   Note: On s390 this instruction would only be used if build with -mzarch.  */
++# include <math.h>
++# include <math_private.h>
++# include <libm-alias-ldouble.h>
++
++long long int
++__llroundl (_Float128 x)
++{
++  long long int y;
++  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
++     x to the nearest integer with "ties away from 0" rounding mode
++     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("cgxbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
++  return y;
++}
++libm_alias_ldouble (__llround, llround)
++
++#else
++# include <sysdeps/ieee754/ldbl-128/s_llroundl.c>
++#endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-24.patch b/SOURCES/glibc-rh1780204-24.patch
new file mode 100644
index 0000000..21bfd24
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-24.patch
@@ -0,0 +1,70 @@
+From 33f3c934e3023b85c3774ee0482ec4da2a10a3b5 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:32 +0100
+Subject: [PATCH 24/28] S390: Implement math-barriers math_opt_barrier and
+ math_force_eval.
+
+This patch implements the s390 specific math barriers in order
+to omit the store and load from stack if possible.
+
+(cherry picked from commit 433a2ba68cd91842546e0f0d43d65835634d570d)
+---
+ sysdeps/s390/fpu/math-barriers.h | 46 ++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/math-barriers.h
+
+diff --git a/sysdeps/s390/fpu/math-barriers.h b/sysdeps/s390/fpu/math-barriers.h
+new file mode 100644
+index 0000000000..7c3e6b15e0
+--- /dev/null
++++ b/sysdeps/s390/fpu/math-barriers.h
+@@ -0,0 +1,46 @@
++/* Control when floating-point expressions are evaluated.  s390 version.
++   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/>.  */
++
++#ifndef S390_MATH_BARRIERS_H
++#define S390_MATH_BARRIERS_H 1
++
++#ifdef HAVE_S390_VX_GCC_SUPPORT
++# define ASM_CONSTRAINT_VR "v"
++#else
++# define ASM_CONSTRAINT_VR
++#endif
++
++#define math_opt_barrier(x)						\
++  ({ __typeof (x) __x = (x);						\
++    if (__builtin_types_compatible_p (__typeof (x), _Float128))		\
++      __asm__ ("# math_opt_barrier_f128 %0" : "+fm" (__x));		\
++    else								\
++      __asm__ ("# math_opt_barrier %0"					\
++	       : "+f" ASM_CONSTRAINT_VR "m" (__x));			\
++    __x; })
++#define math_force_eval(x)						\
++  ({ __typeof (x) __x = (x);						\
++    if (__builtin_types_compatible_p (__typeof (x), _Float128))		\
++      __asm__ __volatile__ ("# math_force_eval_f128 %0"			\
++			    : : "fm" (__x));				\
++    else								\
++      __asm__ __volatile__ ("# math_force_eval %0"			\
++			    : : "f" ASM_CONSTRAINT_VR "m" (__x));	\
++  })
++
++#endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-25.patch b/SOURCES/glibc-rh1780204-25.patch
new file mode 100644
index 0000000..34353ff
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-25.patch
@@ -0,0 +1,79 @@
+From cf5397eb5b33bab37c16bcb2d1bbddbce1a27de2 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:33 +0100
+Subject: [PATCH 25/28] S390: Implement roundtoint and converttoint and define
+ TOINT_INTRINSICS.
+
+This patch implements roundtoint and convertoint for s390
+by using the load-fp-integer and convert-to-fixed instructions.
+Both functions are using "round to nearest with ties away from zero"
+rounding mode and do not raise inexact exceptions.
+
+(cherry picked from commit 2763d3145a326aa9afa613fe9e1b444cf912a883)
+---
+ sysdeps/s390/fpu/math_private.h | 53 +++++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/math_private.h
+
+diff --git a/sysdeps/s390/fpu/math_private.h b/sysdeps/s390/fpu/math_private.h
+new file mode 100644
+index 0000000000..a1ae91a87c
+--- /dev/null
++++ b/sysdeps/s390/fpu/math_private.h
+@@ -0,0 +1,53 @@
++/* Configure optimized libm functions.  S390 version.
++   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/>.  */
++
++#ifndef S390_MATH_PRIVATE_H
++#define S390_MATH_PRIVATE_H 1
++
++#include <stdint.h>
++#include <math.h>
++
++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
++# define TOINT_INTRINSICS 1
++
++static inline double_t
++roundtoint (double_t x)
++{
++  double_t y;
++  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
++     x to the nearest integer with ties away from zero (M3-field: 1)
++     where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("fidbra %0,1,%1,4" : "=f" (y) : "f" (x));
++  return y;
++}
++
++static inline int32_t
++converttoint (double_t x)
++{
++  int32_t y;
++  /* The z196 zarch "convert to fixed" (cfdbra) instruction is rounding
++     x to the nearest integer with ties away from zero (M3-field: 1)
++     where inexact exceptions are suppressed (M4-field: 4).  */
++  __asm__ ("cfdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
++  return y;
++}
++#endif
++
++#include_next <math_private.h>
++
++#endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-26.patch b/SOURCES/glibc-rh1780204-26.patch
new file mode 100644
index 0000000..0f5a6bc
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-26.patch
@@ -0,0 +1,23 @@
+From 363f9d7a6be5a3b400e3ea3daab583bccfcfa152 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:34 +0100
+Subject: [PATCH 26/28] S390: Use sysdeps/ieee754/dbl-64/wordsize-64 on s390x.
+
+This patch enables the usage of implementations in
+sysdeps/ieee754/dbl-64/wordsize-64 on 64bit s390x.
+
+(cherry picked from commit fcee34cc373daee6aa5320a6e1897cdf2005ab53)
+---
+ sysdeps/s390/s390-64/Implies | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sysdeps/s390/s390-64/Implies b/sysdeps/s390/s390-64/Implies
+index a8cae95f9d..7603c9859c 100644
+--- a/sysdeps/s390/s390-64/Implies
++++ b/sysdeps/s390/s390-64/Implies
+@@ -1 +1,2 @@
+ wordsize-64
++ieee754/dbl-64/wordsize-64
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-27.patch b/SOURCES/glibc-rh1780204-27.patch
new file mode 100644
index 0000000..a90ba6f
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-27.patch
@@ -0,0 +1,294 @@
+From 8e5e36d7ba097b8e110ab45794659156af182f54 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:31 +0100
+Subject: [PATCH 27/28] S390: Implement libc_fe* macros.
+
+This patch provides the s390 specific implementation for
+libc_feholdexcept, libc_fesetround, libc_feholdexcept_setround,
+libc_fetestexcept, libc_fesetenv, libc_feupdateenv_test,
+libc_feupdateenv, libc_feholdsetround_ctx, libc_feresetround_ctx,
+libc_feholdsetround_noex_ctx and libc_feresetround_noex_ctx.
+
+(cherry picked from commit 7c94d036c17dfd352d11e9bf98e5d84122c1f95e)
+Note: glibc-2.28 does not have a generic fenv_private.h.
+Therefore include_next does not work. Instead fenv_private.h needs to
+be included in the s390 specific mathp_private.h just before including
+the generic math_private.h.
+As the s390 specific math_private.h is introduced with the backport of
+commit "S390: Implement roundtoint and converttoint and define TOINT_INTRINSICS.",
+the order of cherry-picking was changed compared to upstream!
+---
+ sysdeps/s390/fpu/fenv_private.h | 248 ++++++++++++++++++++++++++++++++
+ sysdeps/s390/fpu/math_private.h |   1 +
+ 2 files changed, 249 insertions(+)
+ create mode 100644 sysdeps/s390/fpu/fenv_private.h
+
+diff --git a/sysdeps/s390/fpu/fenv_private.h b/sysdeps/s390/fpu/fenv_private.h
+new file mode 100644
+index 0000000000..8899f8f434
+--- /dev/null
++++ b/sysdeps/s390/fpu/fenv_private.h
+@@ -0,0 +1,248 @@
++/* Private floating point rounding and exceptions handling.  390/s390x version.
++   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/>.  */
++
++#ifndef S390_FENV_PRIVATE_H
++#define S390_FENV_PRIVATE_H 1
++
++#include <fenv.h>
++#include <fenv_libc.h>
++#include <fpu_control.h>
++
++static __always_inline void
++libc_feholdexcept_s390 (fenv_t *envp)
++{
++  fpu_control_t fpc, fpc_new;
++
++  /* Store the environment.  */
++  _FPU_GETCW (fpc);
++  envp->__fpc = fpc;
++
++  /* Clear the current exception flags and dxc field.
++     Hold from generating fpu exceptions temporarily.  */
++  fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK);
++
++  /* Only set new environment if it has changed.  */
++  if (fpc_new != fpc)
++    _FPU_SETCW (fpc_new);
++}
++
++#define libc_feholdexcept  libc_feholdexcept_s390
++#define libc_feholdexceptf libc_feholdexcept_s390
++#define libc_feholdexceptl libc_feholdexcept_s390
++
++static __always_inline void
++libc_fesetround_s390 (int round)
++{
++  __asm__ __volatile__ ("srnm 0(%0)" : : "a" (round));
++}
++
++#define libc_fesetround  libc_fesetround_s390
++#define libc_fesetroundf libc_fesetround_s390
++#define libc_fesetroundl libc_fesetround_s390
++
++static __always_inline void
++libc_feholdexcept_setround_s390 (fenv_t *envp, int r)
++{
++  fpu_control_t fpc, fpc_new;
++
++  _FPU_GETCW (fpc);
++  envp->__fpc = fpc;
++
++  /* Clear the current exception flags and dxc field.
++     Hold from generating fpu exceptions temporarily.
++     Reset rounding mode bits.  */
++  fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK
++		    | FPC_RM_MASK);
++
++  /* Set new rounding mode.  */
++  fpc_new |= (r & FPC_RM_MASK);
++
++  /* Only set new environment if it has changed.  */
++  if (fpc_new != fpc)
++    _FPU_SETCW (fpc_new);
++}
++
++#define libc_feholdexcept_setround  libc_feholdexcept_setround_s390
++#define libc_feholdexcept_setroundf libc_feholdexcept_setround_s390
++#define libc_feholdexcept_setroundl libc_feholdexcept_setround_s390
++
++static __always_inline int
++libc_fetestexcept_s390 (int excepts)
++{
++  int res;
++  fexcept_t fpc;
++
++  _FPU_GETCW (fpc);
++
++  /* Get current exceptions.  */
++  res = (fpc >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT;
++  if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0)
++    /* Bits 6, 7 of dxc-byte are zero,
++       thus bits 0-5 of dxc-byte correspond to the flag-bits.
++       Evaluate flags and last dxc-exception-code.  */
++    res |= (fpc >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT;
++
++  return res & excepts;
++}
++
++#define libc_fetestexcept  libc_fetestexcept_s390
++#define libc_fetestexceptf libc_fetestexcept_s390
++#define libc_fetestexceptl libc_fetestexcept_s390
++
++static __always_inline void
++libc_fesetenv_s390 (const fenv_t *envp)
++{
++  _FPU_SETCW (envp->__fpc);
++}
++
++#define libc_fesetenv  libc_fesetenv_s390
++#define libc_fesetenvf libc_fesetenv_s390
++#define libc_fesetenvl libc_fesetenv_s390
++
++static __always_inline int
++libc_feupdateenv_test_s390 (const fenv_t *envp, int ex)
++{
++  /* Get the currently raised exceptions.  */
++  int excepts;
++  fexcept_t fpc_old;
++
++  _FPU_GETCW (fpc_old);
++
++  /* Get current exceptions.  */
++  excepts = (fpc_old >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT;
++  if ((fpc_old & FPC_NOT_FPU_EXCEPTION) == 0)
++    /* Bits 6, 7 of dxc-byte are zero,
++       thus bits 0-5 of dxc-byte correspond to the flag-bits.
++       Evaluate flags and last dxc-exception-code.  */
++    excepts |= (fpc_old >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT;
++
++  /* Merge the currently raised exceptions with those in envp.  */
++  fpu_control_t fpc_new = envp->__fpc;
++  fpc_new |= excepts << FPC_FLAGS_SHIFT;
++
++  /* Install the new fpc from envp.  */
++  if (fpc_new != fpc_old)
++    _FPU_SETCW (fpc_new);
++
++  /* Raise the exceptions if enabled in new fpc.  */
++  if (__glibc_unlikely ((fpc_new >> FPC_EXCEPTION_MASK_SHIFT) & excepts))
++    __feraiseexcept (excepts);
++
++  return excepts & ex;
++}
++
++#define libc_feupdateenv_test  libc_feupdateenv_test_s390
++#define libc_feupdateenv_testf libc_feupdateenv_test_s390
++#define libc_feupdateenv_testl libc_feupdateenv_test_s390
++
++static __always_inline void
++libc_feupdateenv_s390 (const fenv_t *envp)
++{
++  libc_feupdateenv_test_s390 (envp, 0);
++}
++
++#define libc_feupdateenv  libc_feupdateenv_s390
++#define libc_feupdateenvf libc_feupdateenv_s390
++#define libc_feupdateenvl libc_feupdateenv_s390
++
++static __always_inline fenv_t
++libc_handle_user_fenv_s390 (const fenv_t *envp)
++{
++  fenv_t env;
++  if (envp == FE_DFL_ENV)
++    {
++      env.__fpc = _FPU_DEFAULT;
++    }
++  else if (envp == FE_NOMASK_ENV)
++    {
++      env.__fpc = FPC_EXCEPTION_MASK;
++    }
++  else
++    env = (*envp);
++
++  return env;
++}
++
++/* We have support for rounding mode context.  */
++#define HAVE_RM_CTX 1
++
++static __always_inline void
++libc_feholdsetround_s390_ctx (struct rm_ctx *ctx, int r)
++{
++  fpu_control_t fpc;
++  int round;
++
++  _FPU_GETCW (fpc);
++  ctx->env.__fpc = fpc;
++
++  /* Check whether rounding modes are different.  */
++  round = fpc & FPC_RM_MASK;
++
++  /* Set the rounding mode if changed.  */
++  if (__glibc_unlikely (round != r))
++    {
++      ctx->updated_status = true;
++      libc_fesetround_s390 (r);
++    }
++  else
++    ctx->updated_status = false;
++}
++
++#define libc_feholdsetround_ctx		libc_feholdsetround_s390_ctx
++#define libc_feholdsetroundf_ctx	libc_feholdsetround_s390_ctx
++#define libc_feholdsetroundl_ctx	libc_feholdsetround_s390_ctx
++
++static __always_inline void
++libc_feresetround_s390_ctx (struct rm_ctx *ctx)
++{
++  /* Restore the rounding mode if updated.  */
++  if (__glibc_unlikely (ctx->updated_status))
++    {
++      fpu_control_t fpc;
++      _FPU_GETCW (fpc);
++      fpc = ctx->env.__fpc | (fpc & FPC_FLAGS_MASK);
++      _FPU_SETCW (fpc);
++    }
++}
++
++#define libc_feresetround_ctx		libc_feresetround_s390_ctx
++#define libc_feresetroundf_ctx		libc_feresetround_s390_ctx
++#define libc_feresetroundl_ctx		libc_feresetround_s390_ctx
++
++static __always_inline void
++libc_feholdsetround_noex_s390_ctx (struct rm_ctx *ctx, int r)
++{
++  libc_feholdexcept_setround_s390 (&ctx->env, r);
++}
++
++#define libc_feholdsetround_noex_ctx	libc_feholdsetround_noex_s390_ctx
++#define libc_feholdsetround_noexf_ctx	libc_feholdsetround_noex_s390_ctx
++#define libc_feholdsetround_noexl_ctx	libc_feholdsetround_noex_s390_ctx
++
++static __always_inline void
++libc_feresetround_noex_s390_ctx (struct rm_ctx *ctx)
++{
++  /* Restore exception flags and rounding mode.  */
++  libc_fesetenv_s390 (&ctx->env);
++}
++
++#define libc_feresetround_noex_ctx	libc_feresetround_noex_s390_ctx
++#define libc_feresetround_noexf_ctx	libc_feresetround_noex_s390_ctx
++#define libc_feresetround_noexl_ctx	libc_feresetround_noex_s390_ctx
++
++#endif
+diff --git a/sysdeps/s390/fpu/math_private.h b/sysdeps/s390/fpu/math_private.h
+index a1ae91a87c..f3c770d59a 100644
+--- a/sysdeps/s390/fpu/math_private.h
++++ b/sysdeps/s390/fpu/math_private.h
+@@ -48,6 +48,7 @@ converttoint (double_t x)
+ }
+ #endif
+ 
++#include <fenv_private.h>
+ #include_next <math_private.h>
+ 
+ #endif
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1780204-28.patch b/SOURCES/glibc-rh1780204-28.patch
new file mode 100644
index 0000000..d2b165a
--- /dev/null
+++ b/SOURCES/glibc-rh1780204-28.patch
@@ -0,0 +1,317 @@
+From 2ab6ce8252a14e6ef0cfb33046dd565ae15085c2 Mon Sep 17 00:00:00 2001
+From: Stefan Liebler <stli@linux.ibm.com>
+Date: Wed, 11 Dec 2019 15:09:32 +0100
+Subject: [PATCH 28/28] S390: Use libc_fe* macros in fe* functions.
+
+This patch updates the s390 specific functions fegetround,
+fesetround, feholdexcept, fesetenv, feupdateenv, fegetexceptflag,
+fetestexcept, fesetexceptflag, fetestexceptflag.
+Now those functions are using the libc_fe* macros if possible.
+
+Furthermore fegetexceptflag is now returning the exception from
+dxc field shifted to the usual exception-flags.
+Thus a special fetestexceptflag implementation is not needed anymore.
+
+(cherry picked from commit 238adf59db85646ebae47876819bd896dae597bc)
+---
+ sysdeps/s390/fpu/fegetround.c       |  9 ++-------
+ sysdeps/s390/fpu/feholdexcpt.c      | 12 ++---------
+ sysdeps/s390/fpu/fesetenv.c         | 21 +++----------------
+ sysdeps/s390/fpu/fesetround.c       |  9 +++------
+ sysdeps/s390/fpu/fetestexceptflag.c | 31 -----------------------------
+ sysdeps/s390/fpu/feupdateenv.c      | 14 +++----------
+ sysdeps/s390/fpu/fgetexcptflg.c     | 16 ++-------------
+ sysdeps/s390/fpu/fsetexcptflg.c     | 23 ++++++++++-----------
+ sysdeps/s390/fpu/ftestexcept.c      | 16 ++-------------
+ 9 files changed, 27 insertions(+), 124 deletions(-)
+ delete mode 100644 sysdeps/s390/fpu/fetestexceptflag.c
+
+diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c
+index 3c38bc9189..f1be1d12e1 100644
+--- a/sysdeps/s390/fpu/fegetround.c
++++ b/sysdeps/s390/fpu/fegetround.c
+@@ -17,17 +17,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <fenv_libc.h>
+-#include <fpu_control.h>
++#include <get-rounding-mode.h>
+ 
+ int
+ __fegetround (void)
+ {
+-  fexcept_t cw;
+-
+-  _FPU_GETCW (cw);
+-
+-  return cw & FPC_RM_MASK;
++  return get_rounding_mode ();
+ }
+ libm_hidden_def (__fegetround)
+ weak_alias (__fegetround, fegetround)
+diff --git a/sysdeps/s390/fpu/feholdexcpt.c b/sysdeps/s390/fpu/feholdexcpt.c
+index 5daee5675d..48af7ff51b 100644
+--- a/sysdeps/s390/fpu/feholdexcpt.c
++++ b/sysdeps/s390/fpu/feholdexcpt.c
+@@ -17,19 +17,11 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <fenv_libc.h>
+-#include <fpu_control.h>
++#include <fenv_private.h>
+ 
+ int __feholdexcept (fenv_t *envp)
+ {
+-  fexcept_t fpc;
+-  /* Store the environment.  */
+-  __fegetenv (envp);
+-  /* Clear the current sticky bits as more than one exception
+-     may be generated.  */
+-  fpc = envp->__fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK);
+-  /* Hold from generating fpu exceptions temporarily.  */
+-  _FPU_SETCW ((fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT)));
++  libc_feholdexcept_s390 (envp);
+   return 0;
+ }
+ libm_hidden_def (__feholdexcept)
+diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c
+index c6c275d79d..54ba2aa94a 100644
+--- a/sysdeps/s390/fpu/fesetenv.c
++++ b/sysdeps/s390/fpu/fesetenv.c
+@@ -17,28 +17,13 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <fenv_libc.h>
+-#include <fpu_control.h>
+-#include <stddef.h>
+-#include <unistd.h>
++#include <fenv_private.h>
+ 
+ int
+ __fesetenv (const fenv_t *envp)
+ {
+-  fenv_t env;
+-
+-  if (envp == FE_DFL_ENV)
+-    {
+-      env.__fpc = _FPU_DEFAULT;
+-    }
+-  else if (envp == FE_NOMASK_ENV)
+-    {
+-      env.__fpc = FPC_EXCEPTION_MASK;
+-    }
+-  else
+-    env = (*envp);
+-
+-  _FPU_SETCW (env.__fpc);
++  fenv_t env = libc_handle_user_fenv_s390 (envp);
++  libc_fesetenv_s390 (&env);
+ 
+   /* Success.  */
+   return 0;
+diff --git a/sysdeps/s390/fpu/fesetround.c b/sysdeps/s390/fpu/fesetround.c
+index d8a84d2c96..0a7fe2635b 100644
+--- a/sysdeps/s390/fpu/fesetround.c
++++ b/sysdeps/s390/fpu/fesetround.c
+@@ -17,21 +17,18 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <fenv_libc.h>
+-#include <fpu_control.h>
++#include <fenv_private.h>
+ 
+ int
+ __fesetround (int round)
+ {
+-  if ((round|FPC_RM_MASK) != FPC_RM_MASK)
++  if ((round | FPC_RM_MASK) != FPC_RM_MASK)
+     {
+       /* ROUND is not a valid rounding mode.  */
+       return 1;
+     }
+-  __asm__ __volatile__ ("srnm 0(%0)"
+-			:
+-			: "a" (round));
+ 
++  libc_fesetround_s390 (round);
+   return 0;
+ }
+ libm_hidden_def (__fesetround)
+diff --git a/sysdeps/s390/fpu/fetestexceptflag.c b/sysdeps/s390/fpu/fetestexceptflag.c
+deleted file mode 100644
+index 784d356f7b..0000000000
+--- a/sysdeps/s390/fpu/fetestexceptflag.c
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/* Test exception in saved exception state.  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/>.  */
+-
+-#include <fenv.h>
+-#include <fenv_libc.h>
+-
+-int
+-fetestexceptflag (const fexcept_t *flagp, int excepts)
+-{
+-  /* As *flagp is obtained by an earlier call of fegetexceptflag the
+-     bits 0-5 of dxc-byte are either zero or correspond to the
+-     flag-bits.  Evaluate flags and last dxc-exception-code.  */
+-  return (((*flagp >> FPC_FLAGS_SHIFT) | (*flagp >> FPC_DXC_SHIFT))
+-	  & excepts
+-	  & FE_ALL_EXCEPT);
+-}
+diff --git a/sysdeps/s390/fpu/feupdateenv.c b/sysdeps/s390/fpu/feupdateenv.c
+index 4888e1a864..f6b3d7d2de 100644
+--- a/sysdeps/s390/fpu/feupdateenv.c
++++ b/sysdeps/s390/fpu/feupdateenv.c
+@@ -18,21 +18,13 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ 
+-#include <fenv_libc.h>
+-#include <fpu_control.h>
++#include <fenv_private.h>
+ 
+ int
+ __feupdateenv (const fenv_t *envp)
+ {
+-  fexcept_t temp;
+-
+-  _FPU_GETCW (temp);
+-  temp = (temp & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT;
+-
+-  /* Raise the exceptions since the last call to feholdenv  */
+-  /* re install saved environment.  */
+-  __fesetenv (envp);
+-  __feraiseexcept ((int) temp);
++  fenv_t env = libc_handle_user_fenv_s390 (envp);
++  libc_feupdateenv_s390 (&env);
+ 
+   /* Success.  */
+   return 0;
+diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c
+index 2a0f6dc77c..1985b396c9 100644
+--- a/sysdeps/s390/fpu/fgetexcptflg.c
++++ b/sysdeps/s390/fpu/fgetexcptflg.c
+@@ -17,24 +17,12 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <fenv_libc.h>
+-#include <fpu_control.h>
++#include <fenv_private.h>
+ 
+ int
+ fegetexceptflag (fexcept_t *flagp, int excepts)
+ {
+-  fexcept_t temp, newexcepts;
+-
+-  /* Get the current exceptions.  */
+-  _FPU_GETCW (temp);
+-  newexcepts = excepts << FPC_FLAGS_SHIFT;
+-  if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
+-    /* Bits 6, 7 of dxc-byte are zero,
+-       thus bits 0-5 of dxc-byte correspond to the flag-bits.
+-       Evaluate flags and last dxc-exception-code.  */
+-    newexcepts |= excepts << FPC_DXC_SHIFT;
+-
+-  *flagp = temp & newexcepts;
++  *flagp = libc_fetestexcept_s390 (excepts);
+ 
+   /* Success.  */
+   return 0;
+diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c
+index e50684c574..51d258cf17 100644
+--- a/sysdeps/s390/fpu/fsetexcptflg.c
++++ b/sysdeps/s390/fpu/fsetexcptflg.c
+@@ -24,29 +24,26 @@
+ int
+ fesetexceptflag (const fexcept_t *flagp, int excepts)
+ {
+-  fexcept_t temp, newexcepts;
++  fexcept_t fpc, fpc_new;
+ 
+   /* Get the current environment.  We have to do this since we cannot
+      separately set the status word.  */
+-  _FPU_GETCW (temp);
+-  /* Install the new exception bits in the Accrued Exception Byte.  */
+-  excepts = excepts & FE_ALL_EXCEPT;
+-  newexcepts = excepts << FPC_FLAGS_SHIFT;
+-  temp &= ~newexcepts;
+-  if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
++  _FPU_GETCW (fpc);
++
++  /* Clear the current exception bits.  */
++  fpc_new = fpc & ~((excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT);
++  if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0)
+     /* Bits 6, 7 of dxc-byte are zero,
+        thus bits 0-5 of dxc-byte correspond to the flag-bits.
+        Clear given exceptions in dxc-field.  */
+-    temp &= ~(excepts << FPC_DXC_SHIFT);
++    fpc_new &= ~((excepts & FE_ALL_EXCEPT) << FPC_DXC_SHIFT);
+ 
+-  /* Integrate dxc-byte of flagp into flags. The dxc-byte of flagp contains
+-     either an ieee-exception or 0 (see fegetexceptflag).  */
+-  temp |= (*flagp | ((*flagp >> FPC_DXC_SHIFT) << FPC_FLAGS_SHIFT))
+-    & newexcepts;
++  /* Set exceptions from flagp in flags-field.  */
++  fpc_new |= (*flagp & excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT;
+ 
+   /* Store the new status word (along with the rest of the environment.
+      Possibly new exceptions are set but they won't get executed.  */
+-  _FPU_SETCW (temp);
++  _FPU_SETCW (fpc_new);
+ 
+   /* Success.  */
+   return 0;
+diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c
+index 727b9b342d..f2acecc1af 100644
+--- a/sysdeps/s390/fpu/ftestexcept.c
++++ b/sysdeps/s390/fpu/ftestexcept.c
+@@ -17,23 +17,11 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <fenv_libc.h>
+-#include <fpu_control.h>
++#include <fenv_private.h>
+ 
+ int
+ fetestexcept (int excepts)
+ {
+-  fexcept_t temp, res;
+-
+-  /* Get current exceptions.  */
+-  _FPU_GETCW (temp);
+-  res = temp >> FPC_FLAGS_SHIFT;
+-  if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
+-    /* Bits 6, 7 of dxc-byte are zero,
+-       thus bits 0-5 of dxc-byte correspond to the flag-bits.
+-       Evaluate flags and last dxc-exception-code.  */
+-    res |= temp >> FPC_DXC_SHIFT;
+-
+-  return res & excepts & FE_ALL_EXCEPT;
++  return libc_fetestexcept_s390 (excepts);
+ }
+ libm_hidden_def (fetestexcept)
+-- 
+2.18.2
+
diff --git a/SOURCES/glibc-rh1783303-1.patch b/SOURCES/glibc-rh1783303-1.patch
new file mode 100644
index 0000000..89fe806
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-1.patch
@@ -0,0 +1,1188 @@
+commit 6cac323c8dd78668e65aaa29f044cbd33c1a66a5
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Mar 15 18:42:00 2019 +0000
+
+    powerpc: ceil/ceilf refactor
+    
+    This patches consolidates all the powerpc ceil{f} implementations on
+    the generic sysdeps/powerpc/fpu/s_ceil{f}.  The generic implementation
+    uses either the compiler builts for ISA 2.03+ (which generates the frip
+    instruction) or a generic implementation which uses FP only operations.
+    
+    It adds a generic implementation (round_to_integer.h) which is shared
+    with other rounding to integer routines.  The resulting code should be
+    similar in term os performance to previous assembly one.
+    
+    The IFUNC organization for powerpc64 is also change to be enabled only
+    for powerpc64 and not for powerpc64le (since minium ISA of 2.08 does not
+    require the fallback generic implementation).
+    
+    Checked on powerpc-linux-gnu (built without --with-cpu, with
+    --with-cpu=power4 and with --with-cpu=power5+ and --disable-multi-arch),
+    powerpc64-linux-gnu (built without --with-cp and with --with-cpu=power5+
+    and --disable-multi-arch).
+    
+            * sysdeps/powerpc/fpu/fenv_libc.h (__fesetround_inline_nocheck): New
+            function.
+            * sysdeps/powerpc/fpu/round_to_integer.h: New file.
+            * sysdeps/powerpc/fpu/s_ceil.c: Likewise.
+            * sysdeps/powerpc/fpu/s_ceilf.c: Likewise.
+            * sysdeps/powerpc/powerpc32/fpu/s_ceil.S: Remove file.
+            * sysdeps/powerpc/powerpc32/fpu/s_ceilf.S: Likewise.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile
+            (CFLAGS-s_ceil-power5+.c, CFLAGS-s_ceilf-power5+.c): New rule.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S:
+            Remove file.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S:
+            Likewise.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S:
+            Likewise.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S:
+            Likewise.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c:
+            New file.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c:
+            Likewise.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c:
+            Likewise.
+            * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c:
+            Likewise.
+            * sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S: Remove file.
+            * sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S: Likewise.
+            * sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile: New file.
+            * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c:
+            Likewise.
+            * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c:
+            Likewise.
+            * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c: Move to ...
+            * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c: ... here.
+            * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c: New
+            file.
+            * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c:
+            Likewise.
+            * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c: Move to ...
+            * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c: ...
+            * here.
+            * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+            (libm-sysdep_routines): Remove s_ceil-power5+, s_ceil-ppc64,
+            s_ceilf-power5+, and s_ceilf-ppc64.
+            * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S: Remove
+            file.
+            * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S: Likewise.
+            * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S: Likewise.
+            * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S: Likewise.
+            * sysdeps/powerpc/powerpc64/fpu/s_ceil.S: Likewise.
+            * sysdeps/powerpc/powerpc64/fpu/s_ceilf.S: Likewise.
+            * sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S: Likewise.
+            * sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S: Likewise.
+    
+    Reviewed-by: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+Conflicts:
+	sysdeps/powerpc/powerpc32/fpu/s_ceil.S
+	sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
+	sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S
+	sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S
+	sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S
+	sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S
+	sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S
+	sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S
+	sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S
+	sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S
+	sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S
+	sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S
+	sysdeps/powerpc/powerpc64/fpu/s_ceil.S
+	sysdeps/powerpc/powerpc64/fpu/s_ceilf.S
+	sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S
+	sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S
+	  (Removal after the copyright year header change upstream.)
+
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index 4c19d12b0b31c1f9..a0128c66444a3e46 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -98,6 +98,14 @@ __fesetround_inline (int round)
+   return 0;
+ }
+ 
++/* Same as __fesetround_inline, however without runtime check to use DFP
++   mtfsfi syntax (as relax_fenv_state) or if round value is valid.  */
++static inline void
++__fesetround_inline_nocheck (const int round)
++{
++  asm volatile ("mtfsfi 7,%0" : : "i" (round));
++}
++
+ /* Definitions of all the FPSCR bit numbers */
+ enum {
+   FPSCR_FX = 0,    /* exception summary */
+diff --git a/sysdeps/powerpc/fpu/round_to_integer.h b/sysdeps/powerpc/fpu/round_to_integer.h
+new file mode 100644
+index 0000000000000000..c70afbb10f600d81
+--- /dev/null
++++ b/sysdeps/powerpc/fpu/round_to_integer.h
+@@ -0,0 +1,105 @@
++/* Round to integer generic 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 Library General Public License as
++   published by the Free Software Foundation; either version 2 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
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public
++   License along with the GNU C Library; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#ifndef _ROUND_TO_INTEGER_H
++#define _ROUND_TO_INTEGER_H
++
++#include <fenv_private.h>
++
++enum round_mode
++{
++  CEIL
++};
++
++static inline void
++set_fenv_mode (enum round_mode mode)
++{
++  int rmode;
++  switch (mode)
++  {
++  case CEIL:  rmode = FE_UPWARD; break;
++  default:    rmode = FE_TONEAREST; break;
++  }
++  __fesetround_inline_nocheck (rmode);
++}
++
++static inline float
++round_to_integer_float (enum round_mode mode, float x)
++{
++  /* Ensure sNaN input is converted to qNaN.  */
++  if (__glibc_unlikely (isnan (x)))
++    return x + x;
++
++  if (fabs (x) > 0x1p+23)
++    return x;
++
++  float r = x;
++
++  /* Save current FPU rounding mode and inexact state.  */
++  fenv_t fe = fegetenv_register ();
++  set_fenv_mode (mode);
++  if (x > 0.0)
++    {
++      r += 0x1p+23;
++      r -= 0x1p+23;
++      r = fabs (r);
++    }
++  else if (x < 0.0)
++    {
++      r -= 0x1p+23;
++      r += 0x1p+23;
++      r = -fabs (r);
++    }
++  __builtin_mtfsf (0xff, fe);
++
++  return r;
++}
++
++static inline double
++round_to_integer_double (enum round_mode mode, double x)
++{
++  /* Ensure sNaN input is converted to qNaN.  */
++  if (__glibc_unlikely (isnan (x)))
++    return x + x;
++
++  if (fabs (x) > 0x1p+52)
++    return x;
++
++  double r = x;
++
++  /* Save current FPU rounding mode and inexact state.  */
++  fenv_t fe = fegetenv_register ();
++  set_fenv_mode (mode);
++  if (x > 0.0)
++    {
++      r += 0x1p+52;
++      r -= 0x1p+52;
++      r = fabs (r);
++    }
++  else if (x < 0.0)
++    {
++      r -= 0x1p+52;
++      r += 0x1p+52;
++      r = -fabs (r);
++    }
++  __builtin_mtfsf (0xff, fe);
++
++  return r;
++}
++
++#endif
+diff --git a/sysdeps/powerpc/fpu/s_ceil.c b/sysdeps/powerpc/fpu/s_ceil.c
+new file mode 100644
+index 0000000000000000..49008c7af87d6d55
+--- /dev/null
++++ b/sysdeps/powerpc/fpu/s_ceil.c
+@@ -0,0 +1,35 @@
++/* Smallest integral value not less than argument.  PowerPC version.
++   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 Library General Public License as
++   published by the Free Software Foundation; either version 2 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
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public
++   License along with the GNU C Library; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#define NO_MATH_REDIRECT
++#include <math.h>
++#include <libm-alias-double.h>
++#include <round_to_integer.h>
++
++double
++__ceil (double x)
++{
++#ifdef _ARCH_PWR5X
++  return __builtin_ceil (x);
++#else
++  return round_to_integer_double (CEIL, x);
++#endif
++}
++#ifndef __ceil
++libm_alias_double (__ceil, ceil)
++#endif
+diff --git a/sysdeps/powerpc/fpu/s_ceilf.c b/sysdeps/powerpc/fpu/s_ceilf.c
+new file mode 100644
+index 0000000000000000..8c86bf30a34df4cf
+--- /dev/null
++++ b/sysdeps/powerpc/fpu/s_ceilf.c
+@@ -0,0 +1,35 @@
++/* Smallest integral value not less than argument.  PowerPC version.
++   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 Library General Public License as
++   published by the Free Software Foundation; either version 2 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
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public
++   License along with the GNU C Library; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#define NO_MATH_REDIRECT
++#include <math.h>
++#include <libm-alias-float.h>
++#include <round_to_integer.h>
++
++float
++__ceilf (float x)
++{
++#ifdef _ARCH_PWR5X
++  return __builtin_ceilf (x);
++#else
++  return round_to_integer_float (CEIL, x);
++#endif
++}
++#ifndef __ceilf
++libm_alias_float (__ceil, ceil)
++#endif
+diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
+deleted file mode 100644
+index 7f2f97ada1a14a52..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
++++ /dev/null
+@@ -1,76 +0,0 @@
+-/* ceil function.  PowerPC32 version.
+-   Copyright (C) 2004-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 <math_ldbl_opt.h>
+-#include <libm-alias-double.h>
+-
+-	.section	.rodata.cst4,"aM",@progbits,4
+-	.align	2
+-.LC0:	/* 2**52 */
+-	.long 0x59800000
+-
+-	.section	".text"
+-ENTRY (__ceil)
+-#ifdef SHARED
+-	mflr	r11
+-	cfi_register(lr,r11)
+-	SETUP_GOT_ACCESS(r9,got_label)
+-	addis	r9,r9,.LC0-got_label@ha
+-	lfs	fp13,.LC0-got_label@l(r9)
+-	mtlr	r11
+-	cfi_same_value (lr)
+-#else
+-	lis	r9,.LC0@ha
+-	lfs	fp13,.LC0@l(r9)
+-#endif
+-	fabs	fp0,fp1
+-	fsub	fp12,fp13,fp13	/* generate 0.0  */
+-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO52)  */
+-	mffs	fp11		/* Save current FPU rounding mode and
+-				   "inexact" state.  */
+-	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
+-	bnl-	cr7,.L10
+-	mtfsfi	7,2		/* Set rounding mode toward +inf.  */
+-	ble-	cr6,.L4
+-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
+-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
+-	fabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = 0.0; */
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L4:
+-	bge-	cr6,.L9		/* if (x < 0.0)  */
+-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
+-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
+-	fnabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = -0.0; */
+-.L9:
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L10:
+-	/* Ensure sNaN input is converted to qNaN.  */
+-	fcmpu	cr7,fp1,fp1
+-	beqlr	cr7
+-	fadd	fp1,fp1,fp1
+-	blr
+-	END (__ceil)
+-
+-libm_alias_double (__ceil, ceil)
+diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
+deleted file mode 100644
+index 3f5949004fa51baf..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
++++ /dev/null
+@@ -1,76 +0,0 @@
+-/* float ceil function.  PowerPC32 version.
+-   Copyright (C) 2004-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 <libm-alias-float.h>
+-
+-	.section	.rodata.cst4,"aM",@progbits,4
+-	.align	2
+-.LC0:	/* 2**23 */
+-	.long 0x4b000000
+-
+-	.section	".text"
+-ENTRY (__ceilf)
+-#ifdef SHARED
+-	mflr	r11
+-	cfi_register(lr,r11)
+-	SETUP_GOT_ACCESS(r9,got_label)
+-	addis	r9,r9,.LC0-got_label@ha
+-	lfs	fp13,.LC0-got_label@l(r9)
+-	mtlr	r11
+-	cfi_same_value (lr)
+-#else
+-	lis	r9,.LC0@ha
+-	lfs	fp13,.LC0@l(r9)
+-#endif
+-	fabs	fp0,fp1
+-	fsubs	fp12,fp13,fp13	/* generate 0.0  */
+-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO23)  */
+-	mffs	fp11		/* Save current FPU rounding mode and
+-				   "inexact" state.  */
+-	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
+-	bnl-	cr7,.L10
+-	mtfsfi	7,2		/* Set rounding mode toward +inf.  */
+-	ble-	cr6,.L4
+-	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
+-	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
+-	fabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = 0.0; */
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L4:
+-	bge-	cr6,.L9		/* if (x < 0.0)  */
+-	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
+-	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
+-	fnabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = -0.0; */
+-.L9:
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L10:
+-	/* Ensure sNaN input is converted to qNaN.  */
+-	fcmpu	cr7,fp1,fp1
+-	beqlr	cr7
+-	fadds	fp1,fp1,fp1
+-	blr
+-	END (__ceilf)
+-
+-libm_alias_float (__ceil, ceil)
+-
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile
+index 4e85021d50831eb6..cf38e347f2da74e9 100644
+--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile
+@@ -26,6 +26,8 @@ libm-sysdep_routines += s_llrintf-power6 s_llrintf-ppc32 s_llrint-power6 \
+ 			s_logbf-power7 s_logbf-ppc32 e_hypot-power7 \
+ 			e_hypot-ppc32 e_hypotf-power7 e_hypotf-ppc32
+ 
++CFLAGS-s_ceil-power5+.c = -mcpu=power5+
++CFLAGS-s_ceilf-power5+.c = -mcpu=power5+
+ CFLAGS-s_modf-power5+.c = -mcpu=power5+
+ CFLAGS-s_modff-power5+.c = -mcpu=power5+
+ CFLAGS-s_logbl-power7.c = -mcpu=power7
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S
+deleted file mode 100644
+index b8181585a869bd8a..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S
++++ /dev/null
+@@ -1,33 +0,0 @@
+-/* ceil function.  PowerPC32/power5+ version.
+-   Copyright (C) 2013-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 <math_ldbl_opt.h>
+-
+-#undef hidden_def
+-#define hidden_def(name)
+-#undef weak_alias
+-#define weak_alias(name, alias)
+-#undef strong_alias
+-#define strong_alias(name, alias)
+-#undef compat_symbol
+-#define compat_symbol(lib, name, alias, ver)
+-
+-#define __ceil __ceil_power5plus
+-
+-#include <sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c
+new file mode 100644
+index 0000000000000000..87bc66cdb0322c59
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceil __ceil_power5plus
++#include <sysdeps/powerpc/fpu/s_ceil.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S
+deleted file mode 100644
+index cd2bc69b677e76db..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/* ceil function.  PowerPC32 default version.
+-   Copyright (C) 2013-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 <math_ldbl_opt.h>
+-
+-#undef weak_alias
+-#define weak_alias(a,b)
+-#undef strong_alias
+-#define strong_alias(a,b)
+-#undef compat_symbol
+-#define compat_symbol(a,b,c,d)
+-
+-#define __ceil __ceil_ppc32
+-
+-#include <sysdeps/powerpc/powerpc32/fpu/s_ceil.S>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c
+new file mode 100644
+index 0000000000000000..93c098476b915f9d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceil __ceil_ppc32
++#include <sysdeps/powerpc/fpu/s_ceil.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S
+deleted file mode 100644
+index d01aa6e7db3d0b9d..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S
++++ /dev/null
+@@ -1,26 +0,0 @@
+-/* ceilf function.  PowerPC32/power5+ version.
+-   Copyright (C) 2013-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>
+-
+-#undef weak_alias
+-#define weak_alias(name, alias)
+-
+-#define __ceilf __ceilf_power5plus
+-
+-#include <sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c
+new file mode 100644
+index 0000000000000000..a5bfa98535c088a0
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceilf __ceilf_power5plus
++#include <sysdeps/powerpc/fpu/s_ceilf.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S
+deleted file mode 100644
+index 264e032b3b27f9b3..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S
++++ /dev/null
+@@ -1,27 +0,0 @@
+-/* ceilf function.  PowerPC32 default version.
+-   Copyright (C) 2013-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 <math_ldbl_opt.h>
+-
+-#undef weak_alias
+-#define weak_alias(a,b)
+-
+-#define __ceilf __ceilf_ppc32
+-
+-#include <sysdeps/powerpc/powerpc32/fpu/s_ceilf.S>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c
+new file mode 100644
+index 0000000000000000..a4dcdcb4069289d6
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceilf __ceilf_ppc32
++#include <sysdeps/powerpc/fpu/s_ceilf.c>
+diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S
+deleted file mode 100644
+index 356c7a79edf79940..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/* ceil function.  PowerPC32/power5+ version.
+-   Copyright (C) 2006-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 <math_ldbl_opt.h>
+-#include <libm-alias-double.h>
+-
+-	.machine	"power5"
+-EALIGN (__ceil, 4, 0)
+-	frip	fp1, fp1
+-	blr
+-	END (__ceil)
+-
+-libm_alias_double (__ceil, ceil)
+diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S
+deleted file mode 100644
+index a0bcda17fde0c0f6..0000000000000000
+--- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/* ceilf function.  PowerPC32/power5+ version.
+-   Copyright (C) 2006-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 <libm-alias-float.h>
+-
+-	.machine	"power5"
+-EALIGN (__ceilf, 4, 0)
+-	frip	fp1, fp1	/* The rounding instructions are double.  */
+-	frsp	fp1, fp1	/* But we need to set ooverflow for float.  */
+-	blr
+-	END (__ceilf)
+-
+-libm_alias_float (__ceil, ceil)
+-
+diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile
+new file mode 100644
+index 0000000000000000..932c3c7e6c6ad27e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile
+@@ -0,0 +1,9 @@
++ifeq ($(subdir),math)
++libm-sysdep_routines += s_ceil-power5+ \
++			s_ceil-ppc64 \
++			s_ceilf-power5+ \
++			s_ceilf-ppc64
++
++CFLAGS-s_ceil-power5+.c = -mcpu=power5+
++CFLAGS-s_ceilf-power5+.c = -mcpu=power5+
++endif
+diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c
+new file mode 100644
+index 0000000000000000..87bc66cdb0322c59
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceil __ceil_power5plus
++#include <sysdeps/powerpc/fpu/s_ceil.c>
+diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c
+new file mode 100644
+index 0000000000000000..8711ff3229467026
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceil __ceil_ppc64
++#include <sysdeps/powerpc/fpu/s_ceil.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c
+similarity index 95%
+rename from sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c
+rename to sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c
+index 5cde4eb46f26ec82..1abca7ef63d6a852 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c
++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c
+@@ -17,10 +17,8 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <math.h>
+-#include <math_ldbl_opt.h>
+-#include <shlib-compat.h>
+-#include "init-arch.h"
+ #include <libm-alias-double.h>
++#include "init-arch.h"
+ 
+ extern __typeof (__ceil) __ceil_ppc64 attribute_hidden;
+ extern __typeof (__ceil) __ceil_power5plus attribute_hidden;
+diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c
+new file mode 100644
+index 0000000000000000..a5bfa98535c088a0
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceilf __ceilf_power5plus
++#include <sysdeps/powerpc/fpu/s_ceilf.c>
+diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c
+new file mode 100644
+index 0000000000000000..086251dc0937acfa
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c
+@@ -0,0 +1,3 @@
++#include <math.h>
++#define __ceilf __ceilf_ppc64
++#include <sysdeps/powerpc/fpu/s_ceilf.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c
+similarity index 95%
+rename from sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c
+rename to sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c
+index 18697e52b3ac1616..33245968a86ddcf5 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c
++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c
+@@ -17,10 +17,8 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <math.h>
+-#include <math_ldbl_opt.h>
+-#include <shlib-compat.h>
+-#include "init-arch.h"
+ #include <libm-alias-float.h>
++#include "init-arch.h"
+ 
+ extern __typeof (__ceilf) __ceilf_ppc64 attribute_hidden;
+ extern __typeof (__ceilf) __ceilf_power5plus attribute_hidden;
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 73f2f693771027a9..2805e4e0d66f3175 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -14,8 +14,7 @@ sysdep_calls := s_copysign-power6 s_copysign-ppc64 \
+ 
+ sysdep_routines += $(sysdep_calls)
+ libm-sysdep_routines += s_llround-power6x \
+-			s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \
+-			s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \
++			s_llround-power5+ s_llround-ppc64 \
+ 			s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \
+ 			s_floorf-ppc64 s_round-power5+ s_round-ppc64 \
+ 			s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S
+deleted file mode 100644
+index 76651b694c251bb4..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/* ceil function.  PowerPC64/power5+ version.
+-   Copyright (C) 2013-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 <shlib-compat.h>
+-
+-#undef weak_alias
+-#define weak_alias(a,b)
+-#undef strong_alias
+-#define strong_alias(a,b)
+-#undef compat_symbol
+-#define compat_symbol(a,b,c,d)
+-
+-#define __ceil __ceil_power5plus
+-
+-#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S
+deleted file mode 100644
+index c75c66ba3bbf49c8..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/* ceil function.  PowerPC64 default version.
+-   Copyright (C) 2013-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 <shlib-compat.h>
+-
+-#undef weak_alias
+-#define weak_alias(a,b)
+-#undef strong_alias
+-#define strong_alias(a,b)
+-#undef compat_symbol
+-#define compat_symbol(a,b,c,d)
+-
+-#define __ceil __ceil_ppc64
+-
+-#include <sysdeps/powerpc/powerpc64/fpu/s_ceil.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S
+deleted file mode 100644
+index b9c9e14fba6ee134..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S
++++ /dev/null
+@@ -1,24 +0,0 @@
+-/* ceilf function.  PowerPC64/power5+ version.
+-   Copyright (C) 2013-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/>.  */
+-
+-#undef weak_alias
+-#define weak_alias(a,b)
+-
+-#define __ceilf __ceilf_power5plus
+-
+-#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S
+deleted file mode 100644
+index ce5cc49770fdfdee..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S
++++ /dev/null
+@@ -1,24 +0,0 @@
+-/* ceilf function.  PowerPC64 default version.
+-   Copyright (C) 2013-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/>.  */
+-
+-#undef weak_alias
+-#define weak_alias(a,b)
+-
+-#define __ceilf __ceilf_ppc64
+-
+-#include <sysdeps/powerpc/powerpc64/fpu/s_ceilf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S
+deleted file mode 100644
+index 252d94f51ea1a167..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S
++++ /dev/null
+@@ -1,65 +0,0 @@
+-/* ceil function.  PowerPC64 version.
+-   Copyright (C) 2004-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 <math_ldbl_opt.h>
+-#include <libm-alias-double.h>
+-
+-	.section	".toc","aw"
+-.LC0:	/* 2**52 */
+-	.tc FD_43300000_0[TC],0x4330000000000000
+-	.section	".text"
+-
+-ENTRY (__ceil, 4)
+-	CALL_MCOUNT 0
+-	lfd	fp13,.LC0@toc(2)
+-	fabs	fp0,fp1
+-	fsub	fp12,fp13,fp13	/* generate 0.0  */
+-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO52)  */
+-	mffs	fp11		/* Save current FPU rounding mode and
+-				   "inexact" state.  */
+-	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
+-	bnl-	cr7,.L10
+-	mtfsfi	7,2		/* Set rounding mode toward +inf.  */
+-	ble-	cr6,.L4
+-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
+-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
+-	fabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = 0.0; */
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L4:
+-	bge-	cr6,.L9		/* if (x < 0.0)  */
+-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
+-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
+-	fnabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = -0.0; */
+-.L9:
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L10:
+-	/* Ensure sNaN input is converted to qNaN.  */
+-	fcmpu	cr7,fp1,fp1
+-	beqlr	cr7
+-	fadd	fp1,fp1,fp1
+-	blr
+-	END (__ceil)
+-
+-libm_alias_double (__ceil, ceil)
+diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S
+deleted file mode 100644
+index 3c62077c143eeced..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S
++++ /dev/null
+@@ -1,67 +0,0 @@
+-/* float ceil function.  PowerPC64 version.
+-   Copyright (C) 2004-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 <libm-alias-float.h>
+-
+-	.section	".toc","aw"
+-	.p2align 3
+-.LC0:	/* 2**23 */
+-	.long 0x4b000000
+-	.long 0x0
+-	.section	".text"
+-
+-ENTRY (__ceilf, 4)
+-	CALL_MCOUNT 0
+-	lfs	fp13,.LC0@toc(2)
+-	fabs	fp0,fp1
+-	fsubs	fp12,fp13,fp13	/* generate 0.0  */
+-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO23)  */
+-	mffs	fp11		/* Save current FPU rounding mode and
+-				   "inexact" state.  */
+-	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
+-	bnl-	cr7,.L10
+-	mtfsfi	7,2		/* Set rounding mode toward +inf.  */
+-	ble-	cr6,.L4
+-	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
+-	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
+-	fabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = 0.0; */
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L4:
+-	bge-	cr6,.L9		/* if (x < 0.0)  */
+-	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
+-	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
+-	fnabs	fp1,fp1		/* if (x == 0.0)  */
+-				/* x = -0.0; */
+-.L9:
+-	mtfsf	0xff,fp11	/* Restore previous rounding mode and
+-				   "inexact" state.  */
+-	blr
+-.L10:
+-	/* Ensure sNaN input is converted to qNaN.  */
+-	fcmpu	cr7,fp1,fp1
+-	beqlr	cr7
+-	fadds	fp1,fp1,fp1
+-	blr
+-	END (__ceilf)
+-
+-libm_alias_float (__ceil, ceil)
+-
+diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S
+deleted file mode 100644
+index e500932573c07503..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/* ceil function.  PowerPC64/power5+ version.
+-   Copyright (C) 2006-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 <math_ldbl_opt.h>
+-#include <libm-alias-double.h>
+-
+-	.machine	"power5"
+-ENTRY_TOCLESS (__ceil, 4)
+-	CALL_MCOUNT 0
+-	frip	fp1, fp1
+-	blr
+-	END (__ceil)
+-
+-libm_alias_double (__ceil, ceil)
+diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S
+deleted file mode 100644
+index d0b2118c2a3f81be..0000000000000000
+--- a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/* ceilf function.  PowerPC64/power5+ version.
+-   Copyright (C) 2006-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 <libm-alias-float.h>
+-
+-	.machine	"power5"
+-ENTRY_TOCLESS (__ceilf, 4)
+-	CALL_MCOUNT 0
+-	frip	fp1, fp1	/* The rounding instructions are double.  */
+-	frsp	fp1, fp1	/* But we need to set ooverflow for float.  */
+-	blr
+-	END (__ceilf)
+-
+-libm_alias_float (__ceil, ceil)
+-
diff --git a/SOURCES/glibc-rh1783303-10.patch b/SOURCES/glibc-rh1783303-10.patch
new file mode 100644
index 0000000..33663f6
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-10.patch
@@ -0,0 +1,57 @@
+commit 0b3c9e57a41d9f7c26fb6aa45b99f671bef9c7e0
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Tue Aug 20 15:57:35 2019 -0500
+
+    [powerpc] fegetenv_status: simplify instruction generation
+    
+    fegetenv_status() wants to use the lighter weight instruction 'mffsl'
+    for reading the Floating-Point Status and Control Register (FPSCR).
+    It currently will use it directly if compiled '-mcpu=power9', and will
+    perform a runtime check (cpu_supports("arch_3_00")) otherwise.
+    
+    Nicely, it turns out that the 'mffsl' instruction will decode to
+    'mffs' on architectures older than "arch_3_00" because the additional
+    bits set for 'mffsl' are "don't care" for 'mffs'.  'mffs' is a superset
+    of 'mffsl'.
+    
+    So, just generate 'mffsl'.
+
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index b244770d115ea7bb..e8d40ea256b6c5bc 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -36,9 +36,12 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+         ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
+ 
+ /* Equivalent to fegetenv_register, but only returns bits for
+-   status, exception enables, and mode.  */
+-
+-#define fegetenv_status_ISA300()					\
++   status, exception enables, and mode.
++   Nicely, it turns out that the 'mffsl' instruction will decode to
++   'mffs' on architectures older than "power9" because the additional
++   bits set for 'mffsl' are "don't care" for 'mffs'.  'mffs' is a superset
++   of 'mffsl'.  */
++#define fegetenv_status()					\
+   ({register double __fr;						\
+     __asm__ __volatile__ (						\
+       ".machine push; .machine \"power9\"; mffsl %0; .machine pop"	\
+@@ -46,18 +49,6 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+     __fr;								\
+   })
+ 
+-#ifdef _ARCH_PWR9
+-# define fegetenv_status() fegetenv_status_ISA300()
+-#elif defined __BUILTIN_CPU_SUPPORTS__
+-# define fegetenv_status()						\
+-  (__glibc_likely (__builtin_cpu_supports ("arch_3_00"))		\
+-   ? fegetenv_status_ISA300()						\
+-   : fegetenv_register()						\
+-  )
+-#else
+-# define fegetenv_status() fegetenv_register ()
+-#endif
+-
+ /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer.  */
+ #define fesetenv_register(env) \
+ 	do { \
diff --git a/SOURCES/glibc-rh1783303-11.patch b/SOURCES/glibc-rh1783303-11.patch
new file mode 100644
index 0000000..2af4f13
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-11.patch
@@ -0,0 +1,128 @@
+commit f1c56cdff09f650ad721fae026eb6a3651631f3d
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 08:35:16 2019 -0500
+
+    [powerpc] SET_RESTORE_ROUND optimizations and bug fix
+    
+    SET_RESTORE_ROUND brackets a block of code, temporarily setting and
+    restoring the rounding mode and letting everything else, including
+    exceptions generated within the block, pass through.
+    
+    On powerpc, the current code clears the exception enables, which will hide
+    exceptions generated within the block.  This issue was introduced by me
+    in commit e905212627350d54b58426214b5a54ddc852b0c9.
+    
+    Fix this by not clearing exception enable bits in the prologue.
+    
+    Also, since we are no longer changing the enable bits in either the
+    prologue or the epilogue, there is no need to test for entering/exiting
+    non-stop mode.
+    
+    Also, optimize the prologue get/save/set rounding mode operations for
+    POWER9 and later by using 'mffscrn' when possible.
+    
+    Suggested-by: Paul E. Murphy <murphyp@linux.ibm.com>
+    Reviewed-by: Paul E. Murphy <murphyp@linux.ibm.com>
+    Fixes: e905212627350d54b58426214b5a54ddc852b0c9
+    
+    2019-09-19  Paul A. Clarke  <pc@us.ibm.com>
+    
+            * sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_and_set_rn): New.
+            (__fe_mffscrn): New.
+            * sysdeps/powerpc/fpu/fenv_private.h (libc_feholdsetround_ppc_ctx):
+            Do not clear enable bits, remove obsolete code, use
+            fegetenv_and_set_rn.
+            (libc_feresetround_ppc): Remove obsolete code, use
+            fegetenv_and_set_rn.
+
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index e8d40ea256b6c5bc..b10b6a141ded4bfd 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -49,6 +49,38 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+     __fr;								\
+   })
+ 
++#define __fe_mffscrn(rn)						\
++  ({register fenv_union_t __fr;						\
++    if (__builtin_constant_p (rn))					\
++      __asm__ __volatile__ (						\
++        ".machine push; .machine \"power9\"; mffscrni %0,%1; .machine pop" \
++        : "=f" (__fr.fenv) : "i" (rn));					\
++    else								\
++    {									\
++      __fr.l = (rn);							\
++      __asm__ __volatile__ (						\
++        ".machine push; .machine \"power9\"; mffscrn %0,%1; .machine pop" \
++        : "=f" (__fr.fenv) : "f" (__fr.fenv));				\
++    }									\
++    __fr.fenv;								\
++  })
++
++/* Like fegetenv_status, but also sets the rounding mode.  */
++#ifdef _ARCH_PWR9
++#define fegetenv_and_set_rn(rn) __fe_mffscrn (rn)
++#else
++/* 'mffscrn' will decode to 'mffs' on ARCH < 3_00, which is still necessary
++   but not sufficient, because it does not set the rounding mode.
++   Explicitly set the rounding mode when 'mffscrn' actually doesn't.  */
++#define fegetenv_and_set_rn(rn)						\
++  ({register fenv_union_t __fr;						\
++    __fr.fenv = __fe_mffscrn (rn);					\
++    if (__glibc_unlikely (!(GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00)))	\
++      __fesetround_inline (rn);						\
++    __fr.fenv;								\
++  })
++#endif
++
+ /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer.  */
+ #define fesetenv_register(env) \
+ 	do { \
+diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
+index b0149aa243e69f5a..30df92c9a4700dee 100644
+--- a/sysdeps/powerpc/fpu/fenv_private.h
++++ b/sysdeps/powerpc/fpu/fenv_private.h
+@@ -133,16 +133,7 @@ static __always_inline void
+ libc_feresetround_ppc (fenv_t *envp)
+ {
+   fenv_union_t new = { .fenv = *envp };
+-
+-  /* If the old env has no enabled exceptions and the new env has any enabled
+-     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
+-     hardware into "precise mode" and may cause the FPU to run slower on some
+-     hardware.  */
+-  if ((new.l & _FPU_ALL_TRAPS) != 0)
+-    (void) __fe_nomask_env_priv ();
+-
+-  /* Atomically enable and raise (if appropriate) exceptions set in `new'.  */
+-  fesetenv_mode (new.fenv);
++  fegetenv_and_set_rn (new.l & FPSCR_RN_MASK);
+ }
+ 
+ static __always_inline int
+@@ -184,22 +175,10 @@ libc_feupdateenv_ppc (fenv_t *e)
+ static __always_inline void
+ libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r)
+ {
+-  fenv_union_t old, new;
++  fenv_union_t old;
+ 
+-  old.fenv = fegetenv_status ();
+-
+-  new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r;
+-
+-  ctx->env = old.fenv;
+-  if (__glibc_unlikely (new.l != old.l))
+-    {
+-      if ((old.l & _FPU_ALL_TRAPS) != 0)
+-	(void) __fe_mask_env ();
+-      fesetenv_mode (new.fenv);
+-      ctx->updated_status = true;
+-    }
+-  else
+-    ctx->updated_status = false;
++  ctx->env = old.fenv = fegetenv_and_set_rn (r);
++  ctx->updated_status = (r != (old.l & FPSCR_RN_MASK));
+ }
+ 
+ static __always_inline void
diff --git a/SOURCES/glibc-rh1783303-12.patch b/SOURCES/glibc-rh1783303-12.patch
new file mode 100644
index 0000000..5113469
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-12.patch
@@ -0,0 +1,303 @@
+commit e3d85df50b083c9ba68a40f5d45b201cbec4e68b
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 09:13:14 2019 -0500
+
+    [powerpc] fenv_private.h clean up
+    
+    fenv_private.h includes unused functions, magic macro constants, and
+    some replicated common code fragments.
+    
+    Remove unused functions, replace magic constants with constants from
+    fenv_libc.h, and refactor replicated code.
+    
+    Suggested-by: Paul E. Murphy <murphyp@linux.ibm.com>
+    Reviewed-By: Paul E Murphy <murphyp@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c
+index 2a776c72fb5a2b70..bdf55ac62f1ffe4f 100644
+--- a/sysdeps/powerpc/fpu/fedisblxcpt.c
++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c
+@@ -43,8 +43,7 @@ fedisableexcept (int excepts)
+   if (fe.l != curr.l)
+     fesetenv_mode (fe.fenv);
+ 
+-  if (new == 0 && result != 0)
+-    (void)__fe_mask_env ();
++  __TEST_AND_ENTER_NON_STOP (-1ULL, fe.l);
+ 
+   return result;
+ }
+diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c
+index 6f5a828e80965bfa..78ebabed9232c0ad 100644
+--- a/sysdeps/powerpc/fpu/feenablxcpt.c
++++ b/sysdeps/powerpc/fpu/feenablxcpt.c
+@@ -43,8 +43,7 @@ feenableexcept (int excepts)
+   if (fe.l != curr.l)
+     fesetenv_mode (fe.fenv);
+ 
+-  if (new != 0 && result == 0)
+-    (void) __fe_nomask_env_priv ();
++  __TEST_AND_EXIT_NON_STOP (0ULL, fe.l);
+ 
+   return result;
+ }
+diff --git a/sysdeps/powerpc/fpu/feholdexcpt.c b/sysdeps/powerpc/fpu/feholdexcpt.c
+index 8ec3fbff82b22f51..9636ecaa0b600b0d 100644
+--- a/sysdeps/powerpc/fpu/feholdexcpt.c
++++ b/sysdeps/powerpc/fpu/feholdexcpt.c
+@@ -18,7 +18,6 @@
+ 
+ #include <fenv_libc.h>
+ #include <fpu_control.h>
+-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM)
+ 
+ int
+ __feholdexcept (fenv_t *envp)
+@@ -35,11 +34,7 @@ __feholdexcept (fenv_t *envp)
+   if (new.l == old.l)
+     return 0;
+ 
+-  /* If the old env had any enabled exceptions, then mask SIGFPE in the
+-     MSR FE0/FE1 bits.  This may allow the FPU to run faster because it
+-     always takes the default action and can not generate SIGFPE. */
+-  if ((old.l & _FPU_MASK_ALL) != 0)
+-    (void)__fe_mask_env ();
++  __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
+ 
+   /* Put the new state in effect.  */
+   fesetenv_register (new.fenv);
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index b10b6a141ded4bfd..36b639c3939586f6 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -27,6 +27,26 @@ extern const fenv_t *__fe_nomask_env_priv (void);
+ 
+ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+ 
++/* If the old env had any enabled exceptions and the new env has no enabled
++   exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
++   FPU to run faster because it always takes the default action and can not
++   generate SIGFPE.  */
++#define __TEST_AND_ENTER_NON_STOP(old, new) \
++  do { \
++    if (((old) & FPSCR_ENABLES_MASK) != 0 && ((new) & FPSCR_ENABLES_MASK) == 0) \
++      (void) __fe_mask_env (); \
++  } while (0)
++
++/* If the old env has no enabled exceptions and the new env has any enabled
++   exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
++   hardware into "precise mode" and may cause the FPU to run slower on some
++   hardware.  */
++#define __TEST_AND_EXIT_NON_STOP(old, new) \
++  do { \
++    if (((old) & FPSCR_ENABLES_MASK) == 0 && ((new) & FPSCR_ENABLES_MASK) != 0) \
++      (void) __fe_nomask_env_priv (); \
++  } while (0)
++
+ /* The sticky bits in the FPSCR indicating exceptions have occurred.  */
+ #define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID)
+ 
+diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
+index 30df92c9a4700dee..c236d45db2f399a4 100644
+--- a/sysdeps/powerpc/fpu/fenv_private.h
++++ b/sysdeps/powerpc/fpu/fenv_private.h
+@@ -23,73 +23,20 @@
+ #include <fenv_libc.h>
+ #include <fpu_control.h>
+ 
+-/* Mask for the exception enable bits.  */
+-#define _FPU_ALL_TRAPS (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM \
+-                      | _FPU_MASK_XM | _FPU_MASK_IM)
+-
+-/* Mask the rounding mode bits.  */
+-#define _FPU_MASK_RN 0xfffffffffffffffcLL
+-
+-/* Mask everything but the rounding modes and non-IEEE arithmetic flags.  */
+-#define _FPU_MASK_NOT_RN_NI 0xffffffff00000807LL
+-
+-/* Mask restore rounding mode and exception enabled.  */
+-#define _FPU_MASK_TRAPS_RN 0xffffffffffffff00LL
+-
+-/* Mask FP result flags, preserve fraction rounded/inexact bits.  */
+-#define _FPU_MASK_FRAC_INEX_RET_CC 0xfffffffffff80fffLL
+-
+ static __always_inline void
+-__libc_feholdbits_ppc (fenv_t *envp, unsigned long long mask,
+-	unsigned long long bits)
++libc_feholdexcept_setround_ppc (fenv_t *envp, int r)
+ {
+   fenv_union_t old, new;
+ 
+   old.fenv = *envp = fegetenv_register ();
+ 
+-  new.l = (old.l & mask) | bits;
+-
+-  /* If the old env had any enabled exceptions, then mask SIGFPE in the
+-     MSR FE0/FE1 bits.  This may allow the FPU to run faster because it
+-     always takes the default action and can not generate SIGFPE.  */
+-  if ((old.l & _FPU_ALL_TRAPS) != 0)
+-    (void) __fe_mask_env ();
++  __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
+ 
++  /* Clear everything and set the rounding mode.  */
++  new.l = r;
+   fesetenv_register (new.fenv);
+ }
+ 
+-static __always_inline void
+-libc_feholdexcept_ppc (fenv_t *envp)
+-{
+-  __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI, 0LL);
+-}
+-
+-static __always_inline void
+-libc_feholdexcept_setround_ppc (fenv_t *envp, int r)
+-{
+-  __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI & _FPU_MASK_RN, r);
+-}
+-
+-static __always_inline void
+-libc_fesetround_ppc (int r)
+-{
+-  __fesetround_inline (r);
+-}
+-
+-static __always_inline int
+-libc_fetestexcept_ppc (int e)
+-{
+-  fenv_union_t u;
+-  u.fenv = fegetenv_register ();
+-  return u.l & e;
+-}
+-
+-static __always_inline void
+-libc_feholdsetround_ppc (fenv_t *e, int r)
+-{
+-  __libc_feholdbits_ppc (e, _FPU_MASK_TRAPS_RN, r);
+-}
+-
+ static __always_inline unsigned long long
+ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask,
+ 	unsigned long long new_mask)
+@@ -102,19 +49,8 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask,
+   /* Merge bits while masking unwanted bits from new and old env.  */
+   new.l = (old.l & old_mask) | (new.l & new_mask);
+ 
+-  /* If the old env has no enabled exceptions and the new env has any enabled
+-     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
+-     hardware into "precise mode" and may cause the FPU to run slower on some
+-     hardware.  */
+-  if ((old.l & _FPU_ALL_TRAPS) == 0 && (new.l & _FPU_ALL_TRAPS) != 0)
+-    (void) __fe_nomask_env_priv ();
+-
+-  /* If the old env had any enabled exceptions and the new env has no enabled
+-     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+-     FPU to run faster because it always takes the default action and can not
+-     generate SIGFPE.  */
+-  if ((old.l & _FPU_ALL_TRAPS) != 0 && (new.l & _FPU_ALL_TRAPS) == 0)
+-    (void) __fe_mask_env ();
++  __TEST_AND_EXIT_NON_STOP (old.l, new.l);
++  __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+ 
+   /* Atomically enable and raise (if appropriate) exceptions set in `new'.  */
+   fesetenv_register (new.fenv);
+@@ -139,8 +75,8 @@ libc_feresetround_ppc (fenv_t *envp)
+ static __always_inline int
+ libc_feupdateenv_test_ppc (fenv_t *envp, int ex)
+ {
+-  return __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN,
+-				_FPU_MASK_FRAC_INEX_RET_CC) & ex;
++  return __libc_femergeenv_ppc (envp, ~FPSCR_CONTROL_MASK,
++				~FPSCR_STATUS_MASK) & ex;
+ }
+ 
+ static __always_inline void
+@@ -193,8 +129,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r)
+   ctx->env = old.fenv;
+   if (__glibc_unlikely (new.l != old.l))
+     {
+-      if ((old.l & _FPU_ALL_TRAPS) != 0)
+-	(void) __fe_mask_env ();
++      __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
+       fesetenv_register (new.fenv);
+       ctx->updated_status = true;
+     }
+diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c
+index ac927c8f3ada40b4..4eab5045c48105e3 100644
+--- a/sysdeps/powerpc/fpu/fesetenv.c
++++ b/sysdeps/powerpc/fpu/fesetenv.c
+@@ -28,19 +28,8 @@ __fesetenv (const fenv_t *envp)
+   new.fenv = *envp;
+   old.fenv = fegetenv_status ();
+ 
+-  /* If the old env has no enabled exceptions and the new env has any enabled
+-     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
+-     hardware into "precise mode" and may cause the FPU to run slower on some
+-     hardware.  */
+-  if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0)
+-    (void) __fe_nomask_env_priv ();
+-
+-  /* If the old env had any enabled exceptions and the new env has no enabled
+-     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+-     FPU to run faster because it always takes the default action and can not
+-     generate SIGFPE. */
+-  if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0)
+-    (void)__fe_mask_env ();
++  __TEST_AND_EXIT_NON_STOP (old.l, new.l);
++  __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+ 
+   fesetenv_register (new.fenv);
+ 
+diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c
+index 29e088d5ab1c0d93..58ba02c0a1e64c27 100644
+--- a/sysdeps/powerpc/fpu/fesetmode.c
++++ b/sysdeps/powerpc/fpu/fesetmode.c
+@@ -33,11 +33,8 @@ fesetmode (const femode_t *modep)
+   if (old.l == new.l)
+     return 0;
+ 
+-  if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0)
+-    (void) __fe_nomask_env_priv ();
+-
+-  if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0)
+-    (void) __fe_mask_env ();
++  __TEST_AND_EXIT_NON_STOP (old.l, new.l);
++  __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+ 
+   fesetenv_mode (new.fenv);
+   return 0;
+diff --git a/sysdeps/powerpc/fpu/feupdateenv.c b/sysdeps/powerpc/fpu/feupdateenv.c
+index 2dbd1c4e9ec65ed0..fdd15651e0101f9e 100644
+--- a/sysdeps/powerpc/fpu/feupdateenv.c
++++ b/sysdeps/powerpc/fpu/feupdateenv.c
+@@ -20,8 +20,6 @@
+ #include <fenv_libc.h>
+ #include <fpu_control.h>
+ 
+-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM)
+-
+ int
+ __feupdateenv (const fenv_t *envp)
+ {
+@@ -36,19 +34,8 @@ __feupdateenv (const fenv_t *envp)
+      unchanged.  */
+   new.l = (old.l & 0xffffffff1fffff00LL) | (new.l & 0x1ff80fff);
+ 
+-  /* If the old env has no enabled exceptions and the new env has any enabled
+-     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
+-     the hardware into "precise mode" and may cause the FPU to run slower on
+-     some hardware.  */
+-  if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0)
+-    (void) __fe_nomask_env_priv ();
+-
+-  /* If the old env had any enabled exceptions and the new env has no enabled
+-     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+-     FPU to run faster because it always takes the default action and can not
+-     generate SIGFPE. */
+-  if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0)
+-    (void)__fe_mask_env ();
++  __TEST_AND_EXIT_NON_STOP (old.l, new.l);
++  __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+ 
+   /* Atomically enable and raise (if appropriate) exceptions set in `new'. */
+   fesetenv_register (new.fenv);
diff --git a/SOURCES/glibc-rh1783303-13.patch b/SOURCES/glibc-rh1783303-13.patch
new file mode 100644
index 0000000..73d2018
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-13.patch
@@ -0,0 +1,58 @@
+commit 7413c188c77adb26a15cf0e98e0a991d09d73c65
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 11:18:33 2019 -0500
+
+    [powerpc] libc_feupdateenv_test: optimize FPSCR access
+    
+    ROUND_TO_ODD and a couple of other places use libc_feupdateenv_test to
+    restore the rounding mode and exception enables, preserve exception flags,
+    and test whether given exception(s) were generated.
+    
+    If the exception flags haven't changed, then it is sufficient and a bit
+    more efficient to just restore the rounding mode and enables, rather than
+    writing the full Floating-Point Status and Control Register (FPSCR).
+    
+    Reviewed-by: Paul E. Murphy <murphyp@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index 36b639c3939586f6..86ae7fda016abd8b 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -257,6 +257,10 @@ enum {
+   (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK)
+ #define FPSCR_BASIC_EXCEPTIONS_MASK \
+   (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK)
++#define FPSCR_EXCEPTIONS_MASK (FPSCR_BASIC_EXCEPTIONS_MASK| \
++  FPSCR_VXSNAN_MASK|FPSCR_VXISI_MASK|FPSCR_VXIDI_MASK|FPSCR_VXZDZ_MASK| \
++  FPSCR_VXIMZ_MASK|FPSCR_VXVC_MASK|FPSCR_VXSOFT_MASK|FPSCR_VXSQRT_MASK| \
++  FPSCR_VXCVI_MASK)
+ #define FPSCR_FPRF_MASK \
+   (FPSCR_FPRF_C_MASK|FPSCR_FPRF_FL_MASK|FPSCR_FPRF_FG_MASK| \
+    FPSCR_FPRF_FE_MASK|FPSCR_FPRF_FU_MASK)
+diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
+index c236d45db2f399a4..86a3611b3ef41759 100644
+--- a/sysdeps/powerpc/fpu/fenv_private.h
++++ b/sysdeps/powerpc/fpu/fenv_private.h
+@@ -52,8 +52,20 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask,
+   __TEST_AND_EXIT_NON_STOP (old.l, new.l);
+   __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+ 
+-  /* Atomically enable and raise (if appropriate) exceptions set in `new'.  */
+-  fesetenv_register (new.fenv);
++  /* If requesting to keep status, replace control, and merge exceptions,
++     and exceptions haven't changed, we can just set new control instead
++     of the whole FPSCR.  */
++  if ((old_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK))
++      == (FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK) &&
++      (new_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK))
++      == (FPSCR_CONTROL_MASK|FPSCR_EXCEPTIONS_MASK) &&
++      (old.l & FPSCR_EXCEPTIONS_MASK) == (new.l & FPSCR_EXCEPTIONS_MASK))
++  {
++    fesetenv_mode (new.fenv);
++  }
++  else
++    /* Atomically enable and raise (if appropriate) exceptions set in `new'.  */
++    fesetenv_register (new.fenv);
+ 
+   return old.l;
+ }
diff --git a/SOURCES/glibc-rh1783303-14.patch b/SOURCES/glibc-rh1783303-14.patch
new file mode 100644
index 0000000..b0c5e66
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-14.patch
@@ -0,0 +1,56 @@
+commit e68b1151f7460d5fa88c3a567c13f66052da79a7
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 11:39:44 2019 -0500
+
+    [powerpc] __fesetround_inline optimizations
+    
+    On POWER9, use more efficient means to update the 2-bit rounding mode
+    via the 'mffscrn' instruction (instead of two 'mtfsb0/1' instructions
+    or one 'mtfsfi' instruction that modifies 4 bits).
+    
+    Suggested-by: Paul E. Murphy  <murphyp@linux.ibm.com>
+    Reviewed-By: Paul E Murphy <murphyp@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index 86ae7fda016abd8b..c3f541c08440b20e 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -149,7 +149,12 @@ typedef union
+ static inline int
+ __fesetround_inline (int round)
+ {
+-  if ((unsigned int) round < 2)
++#ifdef _ARCH_PWR9
++  __fe_mffscrn (round);
++#else
++  if (__glibc_likely (GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00))
++    __fe_mffscrn (round);
++  else if ((unsigned int) round < 2)
+     {
+        asm volatile ("mtfsb0 30");
+        if ((unsigned int) round == 0)
+@@ -165,7 +170,7 @@ __fesetround_inline (int round)
+        else
+          asm volatile ("mtfsb1 31");
+     }
+-
++#endif
+   return 0;
+ }
+ 
+@@ -174,7 +179,14 @@ __fesetround_inline (int round)
+ static inline void
+ __fesetround_inline_nocheck (const int round)
+ {
+-  asm volatile ("mtfsfi 7,%0" : : "i" (round));
++#ifdef _ARCH_PWR9
++  __fe_mffscrn (round);
++#else
++  if (__glibc_likely (GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00))
++    __fe_mffscrn (round);
++  else
++    asm volatile ("mtfsfi 7,%0" : : "i" (round));
++#endif
+ }
+ 
+ #define FPSCR_MASK(bit) (1 << (31 - (bit)))
diff --git a/SOURCES/glibc-rh1783303-15.patch b/SOURCES/glibc-rh1783303-15.patch
new file mode 100644
index 0000000..47f85db
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-15.patch
@@ -0,0 +1,123 @@
+commit 81ecb0ee4970865cbe5d1da733c4879b999c528f
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 11:58:46 2019 -0500
+
+    [powerpc] Rename fegetenv_status to fegetenv_control
+    
+    fegetenv_status is used variously to retrieve the FPSCR exception enable
+    bits, rounding mode bits, or both.  These are referred to as the control
+    bits in the POWER ISA.  FPSCR status bits are also returned by the
+    'mffs' and 'mffsl' instructions, but they are uniformly ignored by all
+    uses of fegetenv_status.  Change the name to be reflective of its
+    current and expected use.
+    
+    Reviewed-By: Paul E Murphy <murphyp@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c
+index bdf55ac62f1ffe4f..1273987459655585 100644
+--- a/sysdeps/powerpc/fpu/fedisblxcpt.c
++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c
+@@ -26,7 +26,7 @@ fedisableexcept (int excepts)
+   int result, new;
+ 
+   /* Get current exception mask to return.  */
+-  fe.fenv = curr.fenv = fegetenv_status ();
++  fe.fenv = curr.fenv = fegetenv_control ();
+   result = fenv_reg_to_exceptions (fe.l);
+ 
+   if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
+diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c
+index 78ebabed9232c0ad..fa233c305aedd5f6 100644
+--- a/sysdeps/powerpc/fpu/feenablxcpt.c
++++ b/sysdeps/powerpc/fpu/feenablxcpt.c
+@@ -26,7 +26,7 @@ feenableexcept (int excepts)
+   int result, new;
+ 
+   /* Get current exception mask to return.  */
+-  fe.fenv = curr.fenv = fegetenv_status ();
++  fe.fenv = curr.fenv = fegetenv_control ();
+   result = fenv_reg_to_exceptions (fe.l);
+ 
+   if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
+diff --git a/sysdeps/powerpc/fpu/fegetexcept.c b/sysdeps/powerpc/fpu/fegetexcept.c
+index 9d77adea59939ece..6bbf11d9d5df61e5 100644
+--- a/sysdeps/powerpc/fpu/fegetexcept.c
++++ b/sysdeps/powerpc/fpu/fegetexcept.c
+@@ -25,7 +25,7 @@ __fegetexcept (void)
+   fenv_union_t fe;
+   int result = 0;
+ 
+-  fe.fenv = fegetenv_status ();
++  fe.fenv = fegetenv_control ();
+ 
+   if (fe.l & (1 << (31 - FPSCR_XE)))
+       result |= FE_INEXACT;
+diff --git a/sysdeps/powerpc/fpu/fegetmode.c b/sysdeps/powerpc/fpu/fegetmode.c
+index 75493e5f24c8b05b..57d6d5275485ebdc 100644
+--- a/sysdeps/powerpc/fpu/fegetmode.c
++++ b/sysdeps/powerpc/fpu/fegetmode.c
+@@ -21,6 +21,6 @@
+ int
+ fegetmode (femode_t *modep)
+ {
+-  *modep = fegetenv_status ();
++  *modep = fegetenv_control ();
+   return 0;
+ }
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index c3f541c08440b20e..b5c8da1adefe93cb 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -61,7 +61,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+    'mffs' on architectures older than "power9" because the additional
+    bits set for 'mffsl' are "don't care" for 'mffs'.  'mffs' is a superset
+    of 'mffsl'.  */
+-#define fegetenv_status()					\
++#define fegetenv_control()					\
+   ({register double __fr;						\
+     __asm__ __volatile__ (						\
+       ".machine push; .machine \"power9\"; mffsl %0; .machine pop"	\
+@@ -85,7 +85,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+     __fr.fenv;								\
+   })
+ 
+-/* Like fegetenv_status, but also sets the rounding mode.  */
++/* Like fegetenv_control, but also sets the rounding mode.  */
+ #ifdef _ARCH_PWR9
+ #define fegetenv_and_set_rn(rn) __fe_mffscrn (rn)
+ #else
+@@ -116,7 +116,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+ 
+ /* Set the last 2 nibbles of the FPSCR, which contain the
+    exception enables and the rounding mode.
+-   'fegetenv_status' retrieves these bits by reading the FPSCR.  */
++   'fegetenv_control' retrieves these bits by reading the FPSCR.  */
+ #define fesetenv_mode(env) __builtin_mtfsf (0b00000011, (env));
+ 
+ /* This very handy macro:
+diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c
+index 4eab5045c48105e3..252114141cd87f8d 100644
+--- a/sysdeps/powerpc/fpu/fesetenv.c
++++ b/sysdeps/powerpc/fpu/fesetenv.c
+@@ -26,7 +26,7 @@ __fesetenv (const fenv_t *envp)
+ 
+   /* get the currently set exceptions.  */
+   new.fenv = *envp;
+-  old.fenv = fegetenv_status ();
++  old.fenv = fegetenv_control ();
+ 
+   __TEST_AND_EXIT_NON_STOP (old.l, new.l);
+   __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c
+index 58ba02c0a1e64c27..e5938af04cb71ca1 100644
+--- a/sysdeps/powerpc/fpu/fesetmode.c
++++ b/sysdeps/powerpc/fpu/fesetmode.c
+@@ -27,7 +27,7 @@ fesetmode (const femode_t *modep)
+   /* Logic regarding enabled exceptions as in fesetenv.  */
+ 
+   new.fenv = *modep;
+-  old.fenv = fegetenv_status ();
++  old.fenv = fegetenv_control ();
+   new.l = (new.l & ~FPSCR_STATUS_MASK) | (old.l & FPSCR_STATUS_MASK);
+ 
+   if (old.l == new.l)
diff --git a/SOURCES/glibc-rh1783303-16.patch b/SOURCES/glibc-rh1783303-16.patch
new file mode 100644
index 0000000..c60fb39
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-16.patch
@@ -0,0 +1,29 @@
+commit 36c17c7079a5243a890ba43affff326a041775a9
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 11:31:31 2019 -0500
+
+    [powerpc] libc_feholdsetround_noex_ppc_ctx: optimize FPSCR write
+    
+    libc_feholdsetround_noex_ppc_ctx currently performs:
+    1. Read FPSCR, save to context.
+    2. Create new FPSCR value: clear enables and set new rounding mode.
+    3. Write new value to FPSCR.
+    
+    Since other bits just pass through, there is no need to write them.
+    
+    Instead, write just the changed values (enables and rounding mode),
+    which can be a bit more efficient.
+
+diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
+index 86a3611b3ef41759..c88142fe3053580f 100644
+--- a/sysdeps/powerpc/fpu/fenv_private.h
++++ b/sysdeps/powerpc/fpu/fenv_private.h
+@@ -142,7 +142,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r)
+   if (__glibc_unlikely (new.l != old.l))
+     {
+       __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
+-      fesetenv_register (new.fenv);
++      fesetenv_mode (new.fenv);
+       ctx->updated_status = true;
+     }
+   else
diff --git a/SOURCES/glibc-rh1783303-17.patch b/SOURCES/glibc-rh1783303-17.patch
new file mode 100644
index 0000000..2c521cc
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-17.patch
@@ -0,0 +1,84 @@
+commit d7a568af5546e0313abbc04060c8e9b0d3f750b4
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 14:04:45 2019 -0500
+
+    [powerpc] Rename fesetenv_mode to fesetenv_control
+    
+    fesetenv_mode is used variously to write the FPSCR exception enable
+    bits and rounding mode bits.  These are referred to as the control
+    bits in the POWER ISA.  Change the name to be reflective of its
+    current and expected use, and match up well with fegetenv_control.
+
+diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c
+index 1273987459655585..efa9c422fe54f5d8 100644
+--- a/sysdeps/powerpc/fpu/fedisblxcpt.c
++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c
+@@ -41,7 +41,7 @@ fedisableexcept (int excepts)
+   fe.l &= ~new;
+ 
+   if (fe.l != curr.l)
+-    fesetenv_mode (fe.fenv);
++    fesetenv_control (fe.fenv);
+ 
+   __TEST_AND_ENTER_NON_STOP (-1ULL, fe.l);
+ 
+diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c
+index fa233c305aedd5f6..dfcc6fb7bd24b8db 100644
+--- a/sysdeps/powerpc/fpu/feenablxcpt.c
++++ b/sysdeps/powerpc/fpu/feenablxcpt.c
+@@ -41,7 +41,7 @@ feenableexcept (int excepts)
+   fe.l |= new;
+ 
+   if (fe.l != curr.l)
+-    fesetenv_mode (fe.fenv);
++    fesetenv_control (fe.fenv);
+ 
+   __TEST_AND_EXIT_NON_STOP (0ULL, fe.l);
+ 
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index b5c8da1adefe93cb..287fc9f8f70e051c 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -117,7 +117,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+ /* Set the last 2 nibbles of the FPSCR, which contain the
+    exception enables and the rounding mode.
+    'fegetenv_control' retrieves these bits by reading the FPSCR.  */
+-#define fesetenv_mode(env) __builtin_mtfsf (0b00000011, (env));
++#define fesetenv_control(env) __builtin_mtfsf (0b00000011, (env));
+ 
+ /* This very handy macro:
+    - Sets the rounding mode to 'round to nearest';
+diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
+index c88142fe3053580f..666fbfdd9fef7759 100644
+--- a/sysdeps/powerpc/fpu/fenv_private.h
++++ b/sysdeps/powerpc/fpu/fenv_private.h
+@@ -61,7 +61,7 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask,
+       == (FPSCR_CONTROL_MASK|FPSCR_EXCEPTIONS_MASK) &&
+       (old.l & FPSCR_EXCEPTIONS_MASK) == (new.l & FPSCR_EXCEPTIONS_MASK))
+   {
+-    fesetenv_mode (new.fenv);
++    fesetenv_control (new.fenv);
+   }
+   else
+     /* Atomically enable and raise (if appropriate) exceptions set in `new'.  */
+@@ -142,7 +142,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r)
+   if (__glibc_unlikely (new.l != old.l))
+     {
+       __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
+-      fesetenv_mode (new.fenv);
++      fesetenv_control (new.fenv);
+       ctx->updated_status = true;
+     }
+   else
+diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c
+index e5938af04cb71ca1..fdaecb1a6a25a820 100644
+--- a/sysdeps/powerpc/fpu/fesetmode.c
++++ b/sysdeps/powerpc/fpu/fesetmode.c
+@@ -36,6 +36,6 @@ fesetmode (const femode_t *modep)
+   __TEST_AND_EXIT_NON_STOP (old.l, new.l);
+   __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+ 
+-  fesetenv_mode (new.fenv);
++  fesetenv_control (new.fenv);
+   return 0;
+ }
diff --git a/SOURCES/glibc-rh1783303-18.patch b/SOURCES/glibc-rh1783303-18.patch
new file mode 100644
index 0000000..60b6d9d
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-18.patch
@@ -0,0 +1,64 @@
+commit 7b8481b330720d28c019a2e5994492a1923d5daa
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Sep 19 11:11:04 2019 -0500
+
+    [powerpc] No need to enter "Ignore Exceptions Mode"
+    
+    Since at least POWER8, there is no performance advantage to entering
+    "Ignore Exceptions Mode", and doing so conditionally requires
+     - the conditional logic, and
+     - a system call.
+    
+    Make it a no-op for uses within glibc.
+
+diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
+index 666fbfdd9fef7759..e09137e892a8e3f3 100644
+--- a/sysdeps/powerpc/fpu/fenv_private.h
++++ b/sysdeps/powerpc/fpu/fenv_private.h
+@@ -23,6 +23,17 @@
+ #include <fenv_libc.h>
+ #include <fpu_control.h>
+ 
++#ifdef _ARCH_PWR8
++/* There is no performance advantage to non-stop mode.  */
++/* The odd syntax here is to innocuously reference the given variables
++   to prevent warnings about unused variables.  */
++#define __TEST_AND_BEGIN_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0)
++#define __TEST_AND_END_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0)
++#else
++#define __TEST_AND_BEGIN_NON_STOP __TEST_AND_ENTER_NON_STOP
++#define __TEST_AND_END_NON_STOP __TEST_AND_EXIT_NON_STOP
++#endif
++
+ static __always_inline void
+ libc_feholdexcept_setround_ppc (fenv_t *envp, int r)
+ {
+@@ -30,7 +41,7 @@ libc_feholdexcept_setround_ppc (fenv_t *envp, int r)
+ 
+   old.fenv = *envp = fegetenv_register ();
+ 
+-  __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
++  __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL);
+ 
+   /* Clear everything and set the rounding mode.  */
+   new.l = r;
+@@ -49,8 +60,8 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask,
+   /* Merge bits while masking unwanted bits from new and old env.  */
+   new.l = (old.l & old_mask) | (new.l & new_mask);
+ 
+-  __TEST_AND_EXIT_NON_STOP (old.l, new.l);
+-  __TEST_AND_ENTER_NON_STOP (old.l, new.l);
++  __TEST_AND_END_NON_STOP (old.l, new.l);
++  __TEST_AND_BEGIN_NON_STOP (old.l, new.l);
+ 
+   /* If requesting to keep status, replace control, and merge exceptions,
+      and exceptions haven't changed, we can just set new control instead
+@@ -141,7 +152,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r)
+   ctx->env = old.fenv;
+   if (__glibc_unlikely (new.l != old.l))
+     {
+-      __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
++      __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL);
+       fesetenv_control (new.fenv);
+       ctx->updated_status = true;
+     }
diff --git a/SOURCES/glibc-rh1783303-2.patch b/SOURCES/glibc-rh1783303-2.patch
new file mode 100644
index 0000000..616af07
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-2.patch
@@ -0,0 +1,105 @@
+commit de751ebc9efa97ce0115e42bd55fa1beeb614380
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Fri Mar 15 19:04:24 2019 -0400
+
+    [powerpc] get_rounding_mode: utilize faster method to get rounding mode
+    
+    Add support to use 'mffsl' instruction if compiled for POWER9 (or later).
+    
+    Also, mask the result to avoid bleeding unrelated bits into the result of
+    _FPU_GET_RC().
+    
+    Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/fpu/get-rounding-mode.h b/sysdeps/powerpc/fpu/get-rounding-mode.h
+new file mode 100644
+index 0000000000000000..e2fdbbbcce72bd66
+--- /dev/null
++++ b/sysdeps/powerpc/fpu/get-rounding-mode.h
+@@ -0,0 +1,33 @@
++/* Determine floating-point rounding mode within libc.  powerpc64 version.
++   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 _POWERPC64_GET_ROUNDING_MODE_H
++#define _POWERPC64_GET_ROUNDING_MODE_H	1
++
++#include <fenv.h>
++#include <fpu_control.h>
++
++/* Return the floating-point rounding mode.  */
++
++static inline int
++get_rounding_mode (void)
++{
++  return _FPU_GET_RC ();
++}
++
++#endif /* get-rounding-mode.h */
+diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h
+index 9d0698b4fc3eb595..62c478d72ae660cb 100644
+--- a/sysdeps/powerpc/fpu_control.h
++++ b/sysdeps/powerpc/fpu_control.h
+@@ -71,6 +71,8 @@ extern fpu_control_t __fpu_control;
+ # define _FPU_RC_UP      0x02
+ # define _FPU_RC_ZERO    0x01
+ 
++# define _FPU_MASK_RC (_FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO)
++
+ # define _FPU_MASK_NI  0x04 /* non-ieee mode */
+ 
+ /* masking of interrupts */
+@@ -94,15 +96,36 @@ extern fpu_control_t __fpu_control;
+ typedef unsigned int fpu_control_t;
+ 
+ /* Macros for accessing the hardware control word.  */
++# define __FPU_MFFS()						\
++  ({register double __fr;					\
++    __asm__ ("mffs %0" : "=f" (__fr));				\
++    __fr;							\
++  })
++
+ # define _FPU_GETCW(cw)						\
+   ({union { double __d; unsigned long long __ll; } __u;		\
+-    register double __fr;					\
+-    __asm__ ("mffs %0" : "=f" (__fr));				\
+-    __u.__d = __fr;						\
++    __u.__d = __FPU_MFFS();					\
+     (cw) = (fpu_control_t) __u.__ll;				\
+     (fpu_control_t) __u.__ll;					\
+   })
+ 
++#ifdef _ARCH_PWR9
++# define __FPU_MFFSL()						\
++  ({register double __fr;					\
++    __asm__ ("mffsl %0" : "=f" (__fr));				\
++    __fr;							\
++  })
++#else
++# define __FPU_MFFSL() __FPU_MFFS()
++#endif
++    
++# define _FPU_GET_RC()						\
++  ({union { double __d; unsigned long long __ll; } __u;		\
++    __u.__d = __FPU_MFFSL();					\
++    __u.__ll &= _FPU_MASK_RC;					\
++    (fpu_control_t) __u.__ll;					\
++  })
++
+ # define _FPU_SETCW(cw)						\
+   { union { double __d; unsigned long long __ll; } __u;		\
+     register double __fr;					\
diff --git a/SOURCES/glibc-rh1783303-3.patch b/SOURCES/glibc-rh1783303-3.patch
new file mode 100644
index 0000000..b653b49
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-3.patch
@@ -0,0 +1,65 @@
+commit 49bc41b64239c4726f31fa35a1af4f22fb41d51f
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Tue Jun 11 14:37:37 2019 -0500
+
+    [powerpc] add 'volatile' to asm
+    
+    Add 'volatile' keyword to a few asm statements, to force the compiler
+    to generate the instructions therein.
+    
+    Some instances were implicitly volatile, but adding keyword for consistency.
+    
+    2019-06-19  Paul A. Clarke  <pc@us.ibm.com>
+    
+            * sysdeps/powerpc/fpu/fenv_libc.h (relax_fenv_state): Add 'volatile'.
+            * sysdeps/powerpc/fpu/fpu_control.h (__FPU_MFFS): Likewise.
+            (__FPU_MFFSL): Likewise.
+            (_FPU_SETCW): Likewise.
+
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index a0128c66444a3e46..d6945903b525748e 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -57,9 +57,9 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+ #define relax_fenv_state() \
+ 	do { \
+ 	   if (GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \
+-	     asm (".machine push; .machine \"power6\"; " \
++	     asm volatile (".machine push; .machine \"power6\"; " \
+ 		  "mtfsfi 7,0,1; .machine pop"); \
+-	   asm ("mtfsfi 7,0"); \
++	   asm volatile ("mtfsfi 7,0"); \
+ 	} while(0)
+ 
+ /* Set/clear a particular FPSCR bit (for instance,
+diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h
+index 62c478d72ae660cb..90063d77bbbf794f 100644
+--- a/sysdeps/powerpc/fpu_control.h
++++ b/sysdeps/powerpc/fpu_control.h
+@@ -98,7 +98,7 @@ typedef unsigned int fpu_control_t;
+ /* Macros for accessing the hardware control word.  */
+ # define __FPU_MFFS()						\
+   ({register double __fr;					\
+-    __asm__ ("mffs %0" : "=f" (__fr));				\
++    __asm__ __volatile__("mffs %0" : "=f" (__fr));		\
+     __fr;							\
+   })
+ 
+@@ -112,7 +112,7 @@ typedef unsigned int fpu_control_t;
+ #ifdef _ARCH_PWR9
+ # define __FPU_MFFSL()						\
+   ({register double __fr;					\
+-    __asm__ ("mffsl %0" : "=f" (__fr));				\
++    __asm__ __volatile__("mffsl %0" : "=f" (__fr));		\
+     __fr;							\
+   })
+ #else
+@@ -132,7 +132,7 @@ typedef unsigned int fpu_control_t;
+     __u.__ll = 0xfff80000LL << 32; /* This is a QNaN.  */	\
+     __u.__ll |= (cw) & 0xffffffffLL;				\
+     __fr = __u.__d;						\
+-    __asm__ ("mtfsf 255,%0" : : "f" (__fr));			\
++    __asm__ __volatile__("mtfsf 255,%0" : : "f" (__fr));	\
+   }
+ 
+ /* Default control word set at startup.  */
diff --git a/SOURCES/glibc-rh1783303-4.patch b/SOURCES/glibc-rh1783303-4.patch
new file mode 100644
index 0000000..5475305
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-4.patch
@@ -0,0 +1,200 @@
+commit 3db85a9814784a74536a1f0e7b7ddbfef7dc84bb
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Jun 20 11:57:18 2019 -0500
+
+    powerpc: Use faster means to access FPSCR when possible in some cases
+    
+    Using 'mffs' instruction to read the Floating Point Status Control Register
+    (FPSCR) can force a processor flush in some cases, with undesirable
+    performance impact.  If the values of the bits in the FPSCR which force the
+    flush are not needed, an instruction that is new to POWER9 (ISA version 3.0),
+    'mffsl' can be used instead.
+    
+    Cases included:  get_rounding_mode, fegetround, fegetmode, fegetexcept.
+    
+            * sysdeps/powerpc/bits/fenvinline.h (__fegetround): Use
+            __fegetround_ISA300() or __fegetround_ISA2() as appropriate.
+            (__fegetround_ISA300) New.
+            (__fegetround_ISA2) New.
+            * sysdeps/powerpc/fpu_control.h (IS_ISA300): New.
+            (_FPU_MFFS): Move implementation...
+            (_FPU_GETCW): Here.
+            (_FPU_MFFSL): Move implementation....
+            (_FPU_GET_RC_ISA300): Here. New.
+            (_FPU_GET_RC): Use _FPU_GET_RC_ISA300() or _FPU_GETCW() as appropriate.
+            * sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_status_ISA300): New.
+            (fegetenv_status): New.
+            * sysdeps/powerpc/fpu/fegetmode.c (fegetmode): Use fegetenv_status()
+            instead of fegetenv_register().
+            * sysdeps/powerpc/fpu/fegetexcept.c (__fegetexcept): Likewise.
+    
+    Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+
+diff --git a/sysdeps/powerpc/bits/fenvinline.h b/sysdeps/powerpc/bits/fenvinline.h
+index 41316386ba75e903..caec8ead6e17219d 100644
+--- a/sysdeps/powerpc/bits/fenvinline.h
++++ b/sysdeps/powerpc/bits/fenvinline.h
+@@ -18,13 +18,36 @@
+ 
+ #if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_FPRS__
+ 
+-/* Inline definition for fegetround.  */
+-# define __fegetround() \
+-  (__extension__  ({ int __fegetround_result;				      \
+-		     __asm__ __volatile__				      \
+-		       ("mcrfs 7,7 ; mfcr %0"				      \
+-			: "=r"(__fegetround_result) : : "cr7");		      \
+-		     __fegetround_result & 3; }))
++/* Inline definitions for fegetround.  */
++# define __fegetround_ISA300()						\
++  (__extension__  ({							\
++    union { double __d; unsigned long long __ll; } __u;			\
++    __asm__ __volatile__ (						\
++      ".machine push; .machine \"power9\"; mffsl %0; .machine pop"	\
++      : "=f" (__u.__d));						\
++    __u.__ll & 0x0000000000000003LL;					\
++  }))
++
++# define __fegetround_ISA2()						\
++  (__extension__  ({							\
++     int __fegetround_result;						\
++     __asm__ __volatile__ ("mcrfs 7,7 ; mfcr %0"			\
++			   : "=r"(__fegetround_result) : : "cr7");	\
++     __fegetround_result & 3;						\
++  }))
++
++# ifdef _ARCH_PWR9
++#  define __fegetround() __fegetround_ISA300()
++# elif defined __BUILTIN_CPU_SUPPORTS__
++#  define __fegetround()						\
++  (__glibc_likely (__builtin_cpu_supports ("arch_3_00"))		\
++   ? __fegetround_ISA300()						\
++   : __fegetround_ISA2()						\
++  )
++# else
++#  define __fegetround() __fegetround_ISA2()
++# endif
++
+ # define fegetround() __fegetround ()
+ 
+ # ifndef __NO_MATH_INLINES
+diff --git a/sysdeps/powerpc/fpu/fegetexcept.c b/sysdeps/powerpc/fpu/fegetexcept.c
+index a053a32bfe11c0d4..9d77adea59939ece 100644
+--- a/sysdeps/powerpc/fpu/fegetexcept.c
++++ b/sysdeps/powerpc/fpu/fegetexcept.c
+@@ -25,7 +25,7 @@ __fegetexcept (void)
+   fenv_union_t fe;
+   int result = 0;
+ 
+-  fe.fenv = fegetenv_register ();
++  fe.fenv = fegetenv_status ();
+ 
+   if (fe.l & (1 << (31 - FPSCR_XE)))
+       result |= FE_INEXACT;
+diff --git a/sysdeps/powerpc/fpu/fegetmode.c b/sysdeps/powerpc/fpu/fegetmode.c
+index b83dc9f625d2248a..75493e5f24c8b05b 100644
+--- a/sysdeps/powerpc/fpu/fegetmode.c
++++ b/sysdeps/powerpc/fpu/fegetmode.c
+@@ -21,6 +21,6 @@
+ int
+ fegetmode (femode_t *modep)
+ {
+-  *modep = fegetenv_register ();
++  *modep = fegetenv_status ();
+   return 0;
+ }
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index d6945903b525748e..cc00df033da47c1a 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -35,6 +35,27 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+ #define fegetenv_register() \
+         ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
+ 
++/* Equivalent to fegetenv_register, but only returns bits for
++   status, exception enables, and mode.  */
++
++#define fegetenv_status_ISA300()					\
++  ({register double __fr;						\
++    __asm__ __volatile__ (						\
++      ".machine push; .machine \"power9\"; mffsl %0; .machine pop"	\
++      : "=f" (__fr));							\
++    __fr;								\
++  })
++
++#ifdef _ARCH_PWR9
++# define fegetenv_status() fegetenv_status_ISA300()
++#else
++# define fegetenv_status()						\
++  (__glibc_likely (__builtin_cpu_supports ("arch_3_00"))		\
++   ? fegetenv_status_ISA300()						\
++   : fegetenv_register()						\
++  )
++#endif
++
+ /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer.  */
+ #define fesetenv_register(env) \
+ 	do { \
+diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h
+index 90063d77bbbf794f..e0ee622e246c0d61 100644
+--- a/sysdeps/powerpc/fpu_control.h
++++ b/sysdeps/powerpc/fpu_control.h
+@@ -96,35 +96,37 @@ extern fpu_control_t __fpu_control;
+ typedef unsigned int fpu_control_t;
+ 
+ /* Macros for accessing the hardware control word.  */
+-# define __FPU_MFFS()						\
+-  ({register double __fr;					\
+-    __asm__ __volatile__("mffs %0" : "=f" (__fr));		\
+-    __fr;							\
+-  })
+-
+ # define _FPU_GETCW(cw)						\
+   ({union { double __d; unsigned long long __ll; } __u;		\
+-    __u.__d = __FPU_MFFS();					\
++    __asm__ __volatile__("mffs %0" : "=f" (__u.__d));		\
+     (cw) = (fpu_control_t) __u.__ll;				\
+     (fpu_control_t) __u.__ll;					\
+   })
+ 
+-#ifdef _ARCH_PWR9
+-# define __FPU_MFFSL()						\
+-  ({register double __fr;					\
+-    __asm__ __volatile__("mffsl %0" : "=f" (__fr));		\
+-    __fr;							\
++# define _FPU_GET_RC_ISA300()						\
++  ({union { double __d; unsigned long long __ll; } __u;			\
++    __asm__ __volatile__(						\
++      ".machine push; .machine \"power9\"; mffsl %0; .machine pop" 	\
++      : "=f" (__u.__d));						\
++    (fpu_control_t) (__u.__ll & _FPU_MASK_RC);				\
+   })
+-#else
+-# define __FPU_MFFSL() __FPU_MFFS()
+-#endif
+-    
+-# define _FPU_GET_RC()						\
+-  ({union { double __d; unsigned long long __ll; } __u;		\
+-    __u.__d = __FPU_MFFSL();					\
+-    __u.__ll &= _FPU_MASK_RC;					\
+-    (fpu_control_t) __u.__ll;					\
++
++# ifdef _ARCH_PWR9
++#  define _FPU_GET_RC() _FPU_GET_RC_ISA300()
++# elif defined __BUILTIN_CPU_SUPPORTS__
++#  define _FPU_GET_RC()							\
++  ({fpu_control_t __rc;							\
++    __rc = __glibc_likely (__builtin_cpu_supports ("arch_3_00"))	\
++      ? _FPU_GET_RC_ISA300 ()						\
++      : _FPU_GETCW (__rc) & _FPU_MASK_RC;				\
++    __rc;								\
++  })
++# else
++#  define _FPU_GET_RC()						\
++  ({fpu_control_t __rc = _FPU_GETCW (__rc) & _FPU_MASK_RC;	\
++    __rc;							\
+   })
++# endif
+ 
+ # define _FPU_SETCW(cw)						\
+   { union { double __d; unsigned long long __ll; } __u;		\
diff --git a/SOURCES/glibc-rh1783303-5.patch b/SOURCES/glibc-rh1783303-5.patch
new file mode 100644
index 0000000..e8c439e
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-5.patch
@@ -0,0 +1,37 @@
+commit b5232c9f9e6048b8f780d3cbfadbc8e59bb90ce4
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Mon Jul 8 17:06:19 2019 -0500
+
+    [powerpc] fenv_libc.h: protect use of __builtin_cpu_supports
+    
+    Using __builtin_cpu_supports() requires support in GCC and Glibc.
+    My recent patch to fenv_libc.h added an unprotected use of
+    __builtin_cpu_supports().  Compilation of Glibc itself will fail
+    with a sufficiently new GCC and sufficiently old Glibc:
+    
+    ../sysdeps/powerpc/fpu/fegetexcept.c: In function ‘__fegetexcept’:
+    ../sysdeps/powerpc/fpu/fenv_libc.h:52:20: error: builtin ‘__builtin_cpu_supports’ needs GLIBC (2.23 and newer) that exports hardware capability bits [-Werror]
+    
+    Reviewed-by: Florian Weimer <fweimer@redhat.com>
+    Fixes 3db85a9814784a74536a1f0e7b7ddbfef7dc84bb.
+
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index cc00df033da47c1a..9dca6e760cc51946 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -48,12 +48,14 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+ 
+ #ifdef _ARCH_PWR9
+ # define fegetenv_status() fegetenv_status_ISA300()
+-#else
++#elif defined __BUILTIN_CPU_SUPPORTS__
+ # define fegetenv_status()						\
+   (__glibc_likely (__builtin_cpu_supports ("arch_3_00"))		\
+    ? fegetenv_status_ISA300()						\
+    : fegetenv_register()						\
+   )
++#else
++# define fegetenv_status() fegetenv_register ()
+ #endif
+ 
+ /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer.  */
diff --git a/SOURCES/glibc-rh1783303-6.patch b/SOURCES/glibc-rh1783303-6.patch
new file mode 100644
index 0000000..7313bd6
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-6.patch
@@ -0,0 +1,185 @@
+commit cd7ce12a027656ad3cda774454088de5a2c7fbfa
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Fri Jul 12 20:13:58 2019 -0500
+
+    [powerpc] fe{en,dis}ableexcept optimize bit translations
+    
+    The exceptions passed to fe{en,dis}ableexcept() are defined in the ABI
+    as a bitmask, a combination of FE_INVALID, FE_OVERFLOW, etc.
+    Within the functions, these bits must be translated to/from the corresponding
+    enable bits in the Floating Point Status Control Register (FPSCR).
+    This translation is currently done bit-by-bit.  The compiler generates
+    a series of conditional bit operations.  Nicely, the "FE" exception
+    bits are all a uniform offset from the FPSCR enable bits, so the bit-by-bit
+    operation can instead be performed by a shift with appropriate masking.
+
+diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c
+index 2daed44a419301e8..90bc3d12c6d8558c 100644
+--- a/sysdeps/powerpc/fpu/fedisblxcpt.c
++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c
+@@ -33,16 +33,7 @@ fedisableexcept (int excepts)
+     excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;
+ 
+   /* Sets the new exception mask.  */
+-  if (excepts & FE_INEXACT)
+-    fe.l &= ~(1 << (31 - FPSCR_XE));
+-  if (excepts & FE_DIVBYZERO)
+-    fe.l &= ~(1 << (31 - FPSCR_ZE));
+-  if (excepts & FE_UNDERFLOW)
+-    fe.l &= ~(1 << (31 - FPSCR_UE));
+-  if (excepts & FE_OVERFLOW)
+-    fe.l &= ~(1 << (31 - FPSCR_OE));
+-  if (excepts & FE_INVALID)
+-    fe.l &= ~(1 << (31 - FPSCR_VE));
++  fe.l &= ~ fenv_exceptions_to_reg (excepts);
+ 
+   if (fe.l != curr.l)
+     fesetenv_register (fe.fenv);
+diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c
+index 19cfe28e7aa307d4..e029971b9a460c28 100644
+--- a/sysdeps/powerpc/fpu/feenablxcpt.c
++++ b/sysdeps/powerpc/fpu/feenablxcpt.c
+@@ -33,16 +33,7 @@ feenableexcept (int excepts)
+     excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;
+ 
+   /* Sets the new exception mask.  */
+-  if (excepts & FE_INEXACT)
+-    fe.l |= (1 << (31 - FPSCR_XE));
+-  if (excepts & FE_DIVBYZERO)
+-    fe.l |= (1 << (31 - FPSCR_ZE));
+-  if (excepts & FE_UNDERFLOW)
+-    fe.l |= (1 << (31 - FPSCR_UE));
+-  if (excepts & FE_OVERFLOW)
+-    fe.l |= (1 << (31 - FPSCR_OE));
+-  if (excepts & FE_INVALID)
+-    fe.l |= (1 << (31 - FPSCR_VE));
++  fe.l |= fenv_exceptions_to_reg (excepts);
+ 
+   if (fe.l != curr.l)
+     fesetenv_register (fe.fenv);
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index 9dca6e760cc51946..f9634a64d186c076 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -129,60 +129,108 @@ __fesetround_inline_nocheck (const int round)
+   asm volatile ("mtfsfi 7,%0" : : "i" (round));
+ }
+ 
++#define FPSCR_MASK(bit) (1 << (31 - (bit)))
++
+ /* Definitions of all the FPSCR bit numbers */
+ enum {
+   FPSCR_FX = 0,    /* exception summary */
++#define FPSCR_FX_MASK (FPSCR_MASK (FPSCR_FX))
+   FPSCR_FEX,       /* enabled exception summary */
++#define FPSCR_FEX_MASK (FPSCR_MASK FPSCR_FEX))
+   FPSCR_VX,        /* invalid operation summary */
++#define FPSCR_VX_MASK (FPSCR_MASK (FPSCR_VX))
+   FPSCR_OX,        /* overflow */
++#define FPSCR_OX_MASK (FPSCR_MASK (FPSCR_OX))
+   FPSCR_UX,        /* underflow */
++#define FPSCR_UX_MASK (FPSCR_MASK (FPSCR_UX))
+   FPSCR_ZX,        /* zero divide */
++#define FPSCR_ZX_MASK (FPSCR_MASK (FPSCR_ZX))
+   FPSCR_XX,        /* inexact */
++#define FPSCR_XX_MASK (FPSCR_MASK (FPSCR_XX))
+   FPSCR_VXSNAN,    /* invalid operation for sNaN */
++#define FPSCR_VXSNAN_MASK (FPSCR_MASK (FPSCR_VXSNAN))
+   FPSCR_VXISI,     /* invalid operation for Inf-Inf */
++#define FPSCR_VXISI_MASK (FPSCR_MASK (FPSCR_VXISI))
+   FPSCR_VXIDI,     /* invalid operation for Inf/Inf */
++#define FPSCR_VXIDI_MASK (FPSCR_MASK (FPSCR_VXIDI))
+   FPSCR_VXZDZ,     /* invalid operation for 0/0 */
++#define FPSCR_VXZDZ_MASK (FPSCR_MASK (FPSCR_VXZDZ))
+   FPSCR_VXIMZ,     /* invalid operation for Inf*0 */
++#define FPSCR_VXIMZ_MASK (FPSCR_MASK (FPSCR_VXIMZ))
+   FPSCR_VXVC,      /* invalid operation for invalid compare */
++#define FPSCR_VXVC_MASK (FPSCR_MASK (FPSCR_VXVC))
+   FPSCR_FR,        /* fraction rounded [fraction was incremented by round] */
++#define FPSCR_FR_MASK (FPSCR_MASK (FPSCR_FR))
+   FPSCR_FI,        /* fraction inexact */
++#define FPSCR_FI_MASK (FPSCR_MASK (FPSCR_FI))
+   FPSCR_FPRF_C,    /* result class descriptor */
++#define FPSCR_FPRF_C_MASK (FPSCR_MASK (FPSCR_FPRF_C))
+   FPSCR_FPRF_FL,   /* result less than (usually, less than 0) */
++#define FPSCR_FPRF_FL_MASK (FPSCR_MASK (FPSCR_FPRF_FL))
+   FPSCR_FPRF_FG,   /* result greater than */
++#define FPSCR_FPRF_FG_MASK (FPSCR_MASK (FPSCR_FPRF_FG))
+   FPSCR_FPRF_FE,   /* result equal to */
++#define FPSCR_FPRF_FE_MASK (FPSCR_MASK (FPSCR_FPRF_FE))
+   FPSCR_FPRF_FU,   /* result unordered */
++#define FPSCR_FPRF_FU_MASK (FPSCR_MASK (FPSCR_FPRF_FU))
+   FPSCR_20,        /* reserved */
+   FPSCR_VXSOFT,    /* invalid operation set by software */
++#define FPSCR_VXSOFT_MASK (FPSCR_MASK (FPSCR_VXSOFT))
+   FPSCR_VXSQRT,    /* invalid operation for square root */
++#define FPSCR_VXSQRT_MASK (FPSCR_MASK (FPSCR_VXSQRT))
+   FPSCR_VXCVI,     /* invalid operation for invalid integer convert */
++#define FPSCR_VXCVI_MASK (FPSCR_MASK (FPSCR_VXCVI))
+   FPSCR_VE,        /* invalid operation exception enable */
++#define FPSCR_VE_MASK (FPSCR_MASK (FPSCR_VE))
+   FPSCR_OE,        /* overflow exception enable */
++#define FPSCR_OE_MASK (FPSCR_MASK (FPSCR_OE))
+   FPSCR_UE,        /* underflow exception enable */
++#define FPSCR_UE_MASK (FPSCR_MASK (FPSCR_UE))
+   FPSCR_ZE,        /* zero divide exception enable */
++#define FPSCR_ZE_MASK (FPSCR_MASK (FPSCR_ZE))
+   FPSCR_XE,        /* inexact exception enable */
++#define FPSCR_XE_MASK (FPSCR_MASK (FPSCR_XE))
+ #ifdef _ARCH_PWR6
+   FPSCR_29,        /* Reserved in ISA 2.05  */
++#define FPSCR_NI_MASK (FPSCR_MASK (FPSCR_29))
+ #else
+-  FPSCR_NI         /* non-IEEE mode (typically, no denormalised numbers) */
++  FPSCR_NI,        /* non-IEEE mode (typically, no denormalised numbers) */
++#define FPSCR_NI_MASK (FPSCR_MASK (FPSCR_NI))
+ #endif /* _ARCH_PWR6 */
+   /* the remaining two least-significant bits keep the rounding mode */
++  FPSCR_RN_hi,
++#define FPSCR_RN_hi_MASK (FPSCR_MASK (FPSCR_RN_hi))
++  FPSCR_RN_lo
++#define FPSCR_RN_lo_MASK (FPSCR_MASK (FPSCR_RN_lo))
+ };
+ 
++#define FPSCR_RN_MASK (FPSCR_RN_hi_MASK|FPSCR_RN_lo_MASK)
++#define FPSCR_ENABLES_MASK \
++  (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK)
++#define FPSCR_BASIC_EXCEPTIONS_MASK \
++  (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK)
++
++#define FPSCR_CONTROL_MASK (FPSCR_ENABLES_MASK|FPSCR_NI_MASK|FPSCR_RN_MASK)
++
++/* The bits in the FENV(1) ABI for exceptions correspond one-to-one with bits
++   in the FPSCR, albeit shifted to different but corresponding locations.
++   Similarly, the exception indicator bits in the FPSCR correspond one-to-one
++   with the exception enable bits. It is thus possible to map the FENV(1)
++   exceptions directly to the FPSCR enables with a simple mask and shift,
++   and vice versa. */
++#define FPSCR_EXCEPT_TO_ENABLE_SHIFT 22
++
+ static inline int
+ fenv_reg_to_exceptions (unsigned long long l)
+ {
+-  int result = 0;
+-  if (l & (1 << (31 - FPSCR_XE)))
+-    result |= FE_INEXACT;
+-  if (l & (1 << (31 - FPSCR_ZE)))
+-    result |= FE_DIVBYZERO;
+-  if (l & (1 << (31 - FPSCR_UE)))
+-    result |= FE_UNDERFLOW;
+-  if (l & (1 << (31 - FPSCR_OE)))
+-    result |= FE_OVERFLOW;
+-  if (l & (1 << (31 - FPSCR_VE)))
+-    result |= FE_INVALID;
+-  return result;
++  return (((int)l) & FPSCR_ENABLES_MASK) << FPSCR_EXCEPT_TO_ENABLE_SHIFT;
++}
++
++static inline unsigned long long
++fenv_exceptions_to_reg (int excepts)
++{
++  return (unsigned long long)
++    (excepts & FE_ALL_EXCEPT) >> FPSCR_EXCEPT_TO_ENABLE_SHIFT;
+ }
+ 
+ #ifdef _ARCH_PWR6
diff --git a/SOURCES/glibc-rh1783303-7.patch b/SOURCES/glibc-rh1783303-7.patch
new file mode 100644
index 0000000..a74f2eb
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-7.patch
@@ -0,0 +1,174 @@
+commit 3c1766ea10043f2e9625f3cba3bda37c84b32cf0
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Thu Jul 18 19:37:13 2019 -0500
+
+    [powerpc] fe{en,dis}ableexcept, fesetmode: optimize FPSCR accesses
+    
+    Since fe{en,dis}ableexcept() and fesetmode() read-modify-write just the
+    "mode" (exception enable and rounding mode) bits of the Floating Point Status
+    Control Register (FPSCR), the lighter weight 'mffsl' instruction can be used
+    to read the FPSCR (enables and rounding mode), and 'mtfsf 0b00000011' can be
+    used to write just those bits back to the FPSCR.  The net is better performance.
+    
+    In addition, fe{en,dis}ableexcept() read the FPSCR again after writing it, or
+    they determine that it doesn't need to be written because it is not changing.
+    In either case, the local variable holds the current values of the enable
+    bits in the FPSCR.  This local variable can be used instead of again reading
+    the FPSCR.
+    
+    Also, that value of the FPSCR which is read the second time is validated
+    against the requested enables.  Since the write can't fail, this validation
+    step is unnecessary, and can be removed.  Instead, the exceptions to be
+    enabled (or disabled) are transformed into available bits in the FPSCR,
+    then validated after being transformed back, to ensure that all requested
+    bits are actually being set.  For example, FE_INVALID_SQRT can be
+    requested, but cannot actually be set.  This bit is not mapped during the
+    transformations, so a test for that bit being set before and after
+    transformations will show the bit would not be set, and the function will
+    return -1 for failure.
+    
+    Finally, convert the local macros in fesetmode.c to more generally useful
+    macros in fenv_libc.h.
+
+diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c
+index 90bc3d12c6d8558c..2a776c72fb5a2b70 100644
+--- a/sysdeps/powerpc/fpu/fedisblxcpt.c
++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c
+@@ -26,23 +26,25 @@ fedisableexcept (int excepts)
+   int result, new;
+ 
+   /* Get current exception mask to return.  */
+-  fe.fenv = curr.fenv = fegetenv_register ();
++  fe.fenv = curr.fenv = fegetenv_status ();
+   result = fenv_reg_to_exceptions (fe.l);
+ 
+   if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
+     excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;
+ 
++  new = fenv_exceptions_to_reg (excepts);
++
++  if (fenv_reg_to_exceptions (new) != excepts)
++    return -1;
++
+   /* Sets the new exception mask.  */
+-  fe.l &= ~ fenv_exceptions_to_reg (excepts);
++  fe.l &= ~new;
+ 
+   if (fe.l != curr.l)
+-    fesetenv_register (fe.fenv);
++    fesetenv_mode (fe.fenv);
+ 
+-  new = __fegetexcept ();
+   if (new == 0 && result != 0)
+     (void)__fe_mask_env ();
+ 
+-  if ((new & excepts) != 0)
+-    result = -1;
+   return result;
+ }
+diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c
+index e029971b9a460c28..6f5a828e80965bfa 100644
+--- a/sysdeps/powerpc/fpu/feenablxcpt.c
++++ b/sysdeps/powerpc/fpu/feenablxcpt.c
+@@ -26,24 +26,25 @@ feenableexcept (int excepts)
+   int result, new;
+ 
+   /* Get current exception mask to return.  */
+-  fe.fenv = curr.fenv = fegetenv_register ();
++  fe.fenv = curr.fenv = fegetenv_status ();
+   result = fenv_reg_to_exceptions (fe.l);
+ 
+   if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
+     excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;
+ 
++  new = fenv_exceptions_to_reg (excepts);
++
++  if (fenv_reg_to_exceptions (new) != excepts)
++    return -1;
++
+   /* Sets the new exception mask.  */
+-  fe.l |= fenv_exceptions_to_reg (excepts);
++  fe.l |= new;
+ 
+   if (fe.l != curr.l)
+-    fesetenv_register (fe.fenv);
++    fesetenv_mode (fe.fenv);
+ 
+-  new = __fegetexcept ();
+   if (new != 0 && result == 0)
+     (void) __fe_nomask_env_priv ();
+ 
+-  if ((new & excepts) != excepts)
+-    result = -1;
+-
+   return result;
+ }
+diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
+index f9634a64d186c076..b244770d115ea7bb 100644
+--- a/sysdeps/powerpc/fpu/fenv_libc.h
++++ b/sysdeps/powerpc/fpu/fenv_libc.h
+@@ -71,6 +71,11 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
+ 	    asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \
+ 	} while(0)
+ 
++/* Set the last 2 nibbles of the FPSCR, which contain the
++   exception enables and the rounding mode.
++   'fegetenv_status' retrieves these bits by reading the FPSCR.  */
++#define fesetenv_mode(env) __builtin_mtfsf (0b00000011, (env));
++
+ /* This very handy macro:
+    - Sets the rounding mode to 'round to nearest';
+    - Sets the processor into IEEE mode; and
+@@ -209,8 +214,11 @@ enum {
+   (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK)
+ #define FPSCR_BASIC_EXCEPTIONS_MASK \
+   (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK)
+-
++#define FPSCR_FPRF_MASK \
++  (FPSCR_FPRF_C_MASK|FPSCR_FPRF_FL_MASK|FPSCR_FPRF_FG_MASK| \
++   FPSCR_FPRF_FE_MASK|FPSCR_FPRF_FU_MASK)
+ #define FPSCR_CONTROL_MASK (FPSCR_ENABLES_MASK|FPSCR_NI_MASK|FPSCR_RN_MASK)
++#define FPSCR_STATUS_MASK (FPSCR_FR_MASK|FPSCR_FI_MASK|FPSCR_FPRF_MASK)
+ 
+ /* The bits in the FENV(1) ABI for exceptions correspond one-to-one with bits
+    in the FPSCR, albeit shifted to different but corresponding locations.
+diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c
+index 32203a24ff434a32..29e088d5ab1c0d93 100644
+--- a/sysdeps/powerpc/fpu/fesetmode.c
++++ b/sysdeps/powerpc/fpu/fesetmode.c
+@@ -19,11 +19,6 @@
+ #include <fenv_libc.h>
+ #include <fpu_control.h>
+ 
+-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM	\
+-		       | _FPU_MASK_XM | _FPU_MASK_IM)
+-
+-#define FPU_STATUS 0xbffff700ULL
+-
+ int
+ fesetmode (const femode_t *modep)
+ {
+@@ -32,18 +27,18 @@ fesetmode (const femode_t *modep)
+   /* Logic regarding enabled exceptions as in fesetenv.  */
+ 
+   new.fenv = *modep;
+-  old.fenv = fegetenv_register ();
+-  new.l = (new.l & ~FPU_STATUS) | (old.l & FPU_STATUS);
++  old.fenv = fegetenv_status ();
++  new.l = (new.l & ~FPSCR_STATUS_MASK) | (old.l & FPSCR_STATUS_MASK);
+ 
+   if (old.l == new.l)
+     return 0;
+ 
+-  if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0)
++  if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0)
+     (void) __fe_nomask_env_priv ();
+ 
+-  if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0)
++  if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0)
+     (void) __fe_mask_env ();
+ 
+-  fesetenv_register (new.fenv);
++  fesetenv_mode (new.fenv);
+   return 0;
+ }
diff --git a/SOURCES/glibc-rh1783303-8.patch b/SOURCES/glibc-rh1783303-8.patch
new file mode 100644
index 0000000..142e3bb
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-8.patch
@@ -0,0 +1,124 @@
+commit e905212627350d54b58426214b5a54ddc852b0c9
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Fri Aug 2 22:47:57 2019 -0400
+
+    [powerpc] SET_RESTORE_ROUND improvements
+    
+    SET_RESTORE_ROUND uses libc_feholdsetround_ppc_ctx and
+    libc_feresetround_ppc_ctx to bracket a block of code where the floating point
+    rounding mode must be set to a certain value.
+    
+    For the *prologue*, libc_feholdsetround_ppc_ctx is used and performs:
+    1. Read/save FPSCR.
+    2. Create new value for FPSCR with new rounding mode and enables cleared.
+    3. If new value is different than current value,
+       a. If transitioning from a state where some exceptions enabled,
+          enter "ignore exceptions / non-stop" mode.
+       b. Write new value to FPSCR.
+       c. Put a mark on the wall indicating the FPSCR was changed.
+    
+    (1) uses the 'mffs' instruction.  On POWER9, the lighter weight 'mffsl'
+    instruction can be used, but it doesn't return all of the bits in the FPSCR.
+    fegetenv_status uses 'mffsl' on POWER9, 'mffs' otherwise, and can thus be
+    used instead of fegetenv_register.
+    (3b) uses 'mtfsf 0b11111111' to write the entire FPSCR, so it must
+    instead use 'mtfsf 0b00000011' to write just the enables and the mode,
+    because some of the rest of the bits are not valid if 'mffsl' was used.
+    fesetenv_mode uses 'mtfsf 0b00000011' on POWER9, 'mtfsf 0b11111111'
+    otherwise.
+    
+    For the *epilogue*, libc_feresetround_ppc_ctx checks the mark on the wall, then
+    calls libc_feresetround_ppc, which just calls __libc_femergeenv_ppc with
+    parameters such that it performs:
+    1. Retreive saved value of FPSCR, saved in prologue above.
+    2. Read FPSCR.
+    3. Create new value of FPSCR where:
+       - Summary bits and exception indicators = current OR saved.
+       - Rounding mode and enables = saved.
+       - Status bits = current.
+    4. If transitioning from some exceptions enabled to none,
+       enter "ignore exceptions / non-stop" mode.
+    5. If transitioning from no exceptions enabled to some,
+       enter "catch exceptions" mode.
+    6. Write new value to FPSCR.
+    
+    The summary bits are hardwired to the exception indicators, so there is no
+    need to restore any saved summary bits.
+    The exception indicator bits, which are sticky and remain set unless
+    explicitly cleared, would only need to be restored if the code block
+    might explicitly clear any of them.  This is certainly not expected.
+    
+    So, the only bits that need to be restored are the enables and the mode.
+    If it is the case that only those bits are to be restored, there is no need to
+    read the FPSCR.  Steps (2) and (3) are unnecessary, and step (6) only needs to
+    write the bits being restored.
+    
+    We know we are transitioning out of "ignore exceptions" mode, so step (4) is
+    unnecessary, and in step (6), we only need to check the state we are
+    entering.
+
+diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
+index 945ab98018450092..b0149aa243e69f5a 100644
+--- a/sysdeps/powerpc/fpu/fenv_private.h
++++ b/sysdeps/powerpc/fpu/fenv_private.h
+@@ -132,7 +132,17 @@ libc_fesetenv_ppc (const fenv_t *envp)
+ static __always_inline void
+ libc_feresetround_ppc (fenv_t *envp)
+ {
+-  __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, _FPU_MASK_FRAC_INEX_RET_CC);
++  fenv_union_t new = { .fenv = *envp };
++
++  /* If the old env has no enabled exceptions and the new env has any enabled
++     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
++     hardware into "precise mode" and may cause the FPU to run slower on some
++     hardware.  */
++  if ((new.l & _FPU_ALL_TRAPS) != 0)
++    (void) __fe_nomask_env_priv ();
++
++  /* Atomically enable and raise (if appropriate) exceptions set in `new'.  */
++  fesetenv_mode (new.fenv);
+ }
+ 
+ static __always_inline int
+@@ -176,9 +186,30 @@ libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r)
+ {
+   fenv_union_t old, new;
+ 
++  old.fenv = fegetenv_status ();
++
++  new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r;
++
++  ctx->env = old.fenv;
++  if (__glibc_unlikely (new.l != old.l))
++    {
++      if ((old.l & _FPU_ALL_TRAPS) != 0)
++	(void) __fe_mask_env ();
++      fesetenv_mode (new.fenv);
++      ctx->updated_status = true;
++    }
++  else
++    ctx->updated_status = false;
++}
++
++static __always_inline void
++libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r)
++{
++  fenv_union_t old, new;
++
+   old.fenv = fegetenv_register ();
+ 
+-  new.l = (old.l & _FPU_MASK_TRAPS_RN) | r;
++  new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r;
+ 
+   ctx->env = old.fenv;
+   if (__glibc_unlikely (new.l != old.l))
+@@ -218,6 +249,9 @@ libc_feresetround_ppc_ctx (struct rm_ctx *ctx)
+ #define libc_feholdsetround_ctx          libc_feholdsetround_ppc_ctx
+ #define libc_feholdsetroundf_ctx         libc_feholdsetround_ppc_ctx
+ #define libc_feholdsetroundl_ctx         libc_feholdsetround_ppc_ctx
++#define libc_feholdsetround_noex_ctx     libc_feholdsetround_noex_ppc_ctx
++#define libc_feholdsetround_noexf_ctx    libc_feholdsetround_noex_ppc_ctx
++#define libc_feholdsetround_noexl_ctx    libc_feholdsetround_noex_ppc_ctx
+ #define libc_feresetround_ctx            libc_feresetround_ppc_ctx
+ #define libc_feresetroundf_ctx           libc_feresetround_ppc_ctx
+ #define libc_feresetroundl_ctx           libc_feresetround_ppc_ctx
diff --git a/SOURCES/glibc-rh1783303-9.patch b/SOURCES/glibc-rh1783303-9.patch
new file mode 100644
index 0000000..e151082
--- /dev/null
+++ b/SOURCES/glibc-rh1783303-9.patch
@@ -0,0 +1,61 @@
+commit fec2bd2c2d31bc731cf61623e150d047746954bd
+Author: Paul A. Clarke <pc@us.ibm.com>
+Date:   Tue Aug 6 00:13:45 2019 -0400
+
+    [powerpc] fesetenv: optimize FPSCR access
+    
+    fesetenv() reads the current value of the Floating-Point Status and Control
+    Register (FPSCR) to determine the difference between the current state of
+    exception enables and the newly requested state.  All of these bits are also
+    returned by the lighter weight 'mffsl' instruction used by fegetenv_status().
+    Use that instead.
+    
+    Also, remove a local macro _FPU_MASK_ALL in favor of a common macro,
+    FPU_ENABLES_MASK from fenv_libc.h.
+    
+    Finally, use a local variable ('new') in favor of a pointer dereference
+    ('*envp').
+
+diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c
+index ad9fda15b12f15e3..ac927c8f3ada40b4 100644
+--- a/sysdeps/powerpc/fpu/fesetenv.c
++++ b/sysdeps/powerpc/fpu/fesetenv.c
+@@ -19,8 +19,6 @@
+ #include <fenv_libc.h>
+ #include <fpu_control.h>
+ 
+-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM)
+-
+ int
+ __fesetenv (const fenv_t *envp)
+ {
+@@ -28,25 +26,23 @@ __fesetenv (const fenv_t *envp)
+ 
+   /* get the currently set exceptions.  */
+   new.fenv = *envp;
+-  old.fenv = fegetenv_register ();
+-  if (old.l == new.l)
+-    return 0;
++  old.fenv = fegetenv_status ();
+ 
+   /* If the old env has no enabled exceptions and the new env has any enabled
+      exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
+      hardware into "precise mode" and may cause the FPU to run slower on some
+      hardware.  */
+-  if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0)
++  if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0)
+     (void) __fe_nomask_env_priv ();
+ 
+   /* If the old env had any enabled exceptions and the new env has no enabled
+      exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+      FPU to run faster because it always takes the default action and can not
+      generate SIGFPE. */
+-  if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0)
++  if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0)
+     (void)__fe_mask_env ();
+ 
+-  fesetenv_register (*envp);
++  fesetenv_register (new.fenv);
+ 
+   /* Success.  */
+   return 0;
diff --git a/SOURCES/glibc-rh1784519.patch b/SOURCES/glibc-rh1784519.patch
new file mode 100644
index 0000000..c9779d1
--- /dev/null
+++ b/SOURCES/glibc-rh1784519.patch
@@ -0,0 +1,29 @@
+commit 953ceff17a4a15b10cfdd5edc3c8cae4884c8ec3
+Author: Kamlesh Kumar <kamleshbhalui@gmail.com>
+Date:   Thu Dec 5 16:49:00 2019 +0100
+
+    <string.h>: Define __CORRECT_ISO_CPP_STRING_H_PROTO for Clang [BZ #25232]
+    
+    Without the asm redirects, strchr et al. are not const-correct.
+    
+    libc++ has a wrapper header that works with and without
+    __CORRECT_ISO_CPP_STRING_H_PROTO (using a Clang extension).  But when
+    Clang is used with libstdc++ or just C headers, the overloaded functions
+    with the correct types are not declared.
+    
+    This change does not impact current GCC (with libstdc++ or libc++).
+
+diff --git a/string/string.h b/string/string.h
+index 73c22a535a..faf997b972 100644
+--- a/string/string.h
++++ b/string/string.h
+@@ -33,7 +33,8 @@ __BEGIN_DECLS
+ #include <stddef.h>
+ 
+ /* Tell the caller that we provide correct C++ prototypes.  */
+-#if defined __cplusplus && __GNUC_PREREQ (4, 4)
++#if defined __cplusplus && (__GNUC_PREREQ (4, 4) \
++			    || __glibc_clang_prereq (3, 5))
+ # define __CORRECT_ISO_CPP_STRING_H_PROTO
+ #endif
+ 
diff --git a/SOURCES/glibc-rh1784520.patch b/SOURCES/glibc-rh1784520.patch
new file mode 100644
index 0000000..90e9d77
--- /dev/null
+++ b/SOURCES/glibc-rh1784520.patch
@@ -0,0 +1,121 @@
+commit 16554464bcd9d77b07c6ff419dc54f00e394fa50
+Author: DJ Delorie <dj@redhat.com>
+Date:   Tue Dec 3 17:44:36 2019 -0500
+
+    Correct range checking in mallopt/mxfast/tcache [BZ #25194]
+    
+    do_set_tcache_max, do_set_mxfast:
+    Fix two instances of comparing "size_t < 0"
+    Both cases have upper limit, so the "negative value" case
+    is already handled via overflow semantics.
+    
+    do_set_tcache_max, do_set_tcache_count:
+    Fix return value on error.  Note: currently not used.
+    
+    mallopt:
+    pass return value of helper functions to user.  Behavior should
+    only be actually changed for mxfast, where we restore the old
+    (pre-tunables) behavior.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 90825b2aaed53761..00a37f218c0ab3b2 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5111,13 +5111,14 @@ static inline int
+ __always_inline
+ do_set_tcache_max (size_t value)
+ {
+-  if (value >= 0 && value <= MAX_TCACHE_SIZE)
++  if (value <= MAX_TCACHE_SIZE)
+     {
+       LIBC_PROBE (memory_tunable_tcache_max_bytes, 2, value, mp_.tcache_max_bytes);
+       mp_.tcache_max_bytes = value;
+       mp_.tcache_bins = csize2tidx (request2size(value)) + 1;
++      return 1;
+     }
+-  return 1;
++  return 0;
+ }
+ 
+ static inline int
+@@ -5128,8 +5129,9 @@ do_set_tcache_count (size_t value)
+     {
+       LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count);
+       mp_.tcache_count = value;
++      return 1;
+     }
+-  return 1;
++  return 0;
+ }
+ 
+ static inline int
+@@ -5146,7 +5148,7 @@ static inline int
+ __always_inline
+ do_set_mxfast (size_t value)
+ {
+-  if (value >= 0 && value <= MAX_FAST_SIZE)
++  if (value <= MAX_FAST_SIZE)
+     {
+       LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ());
+       set_max_fast (value);
+@@ -5171,18 +5173,24 @@ __libc_mallopt (int param_number, int value)
+      (see definition of set_max_fast).  */
+   malloc_consolidate (av);
+ 
++  /* Many of these helper functions take a size_t.  We do not worry
++     about overflow here, because negative int values will wrap to
++     very large size_t values and the helpers have sufficient range
++     checking for such conversions.  Many of these helpers are also
++     used by the tunables macros in arena.c.  */
++
+   switch (param_number)
+     {
+     case M_MXFAST:
+-      do_set_mxfast (value);
++      res = do_set_mxfast (value);
+       break;
+ 
+     case M_TRIM_THRESHOLD:
+-      do_set_trim_threshold (value);
++      res = do_set_trim_threshold (value);
+       break;
+ 
+     case M_TOP_PAD:
+-      do_set_top_pad (value);
++      res = do_set_top_pad (value);
+       break;
+ 
+     case M_MMAP_THRESHOLD:
+@@ -5190,25 +5198,25 @@ __libc_mallopt (int param_number, int value)
+       break;
+ 
+     case M_MMAP_MAX:
+-      do_set_mmaps_max (value);
++      res = do_set_mmaps_max (value);
+       break;
+ 
+     case M_CHECK_ACTION:
+-      do_set_mallopt_check (value);
++      res = do_set_mallopt_check (value);
+       break;
+ 
+     case M_PERTURB:
+-      do_set_perturb_byte (value);
++      res = do_set_perturb_byte (value);
+       break;
+ 
+     case M_ARENA_TEST:
+       if (value > 0)
+-	do_set_arena_test (value);
++	res = do_set_arena_test (value);
+       break;
+ 
+     case M_ARENA_MAX:
+       if (value > 0)
+-	do_set_arena_max (value);
++	res = do_set_arena_max (value);
+       break;
+     }
+   __libc_lock_unlock (av->mutex);
diff --git a/SOURCES/glibc-rh1784525.patch b/SOURCES/glibc-rh1784525.patch
new file mode 100644
index 0000000..3a5f000
--- /dev/null
+++ b/SOURCES/glibc-rh1784525.patch
@@ -0,0 +1,29 @@
+commit ef21bd2d8c6805c0c186a01f7c5039189f51b8c4
+Author: DJ Delorie <dj@redhat.com>
+Date:   Fri Oct 18 17:15:52 2019 -0400
+
+    loadarchive: guard against locale-archive corruption (Bug #25115)
+    
+    _nl_load_locale_from_archive() checks for a zero size, but
+    divides by both (size) and (size-2).  Extend the check to
+    guard against a size of two or less.
+    
+    Tested by manually corrupting locale-archive and running a program
+    that calls setlocale() with LOCPATH unset (size is typically very
+    large).
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/locale/loadarchive.c b/locale/loadarchive.c
+index 516d30d8d16bd578..b308fd886f44e1fd 100644
+--- a/locale/loadarchive.c
++++ b/locale/loadarchive.c
+@@ -274,7 +274,7 @@ _nl_load_locale_from_archive (int category, const char **namep)
+ 					+ head->namehash_offset);
+ 
+   /* Avoid division by 0 if the file is corrupted.  */
+-  if (__glibc_unlikely (head->namehash_size == 0))
++  if (__glibc_unlikely (head->namehash_size <= 2))
+     goto close_and_out;
+ 
+   idx = hval % head->namehash_size;
diff --git a/SOURCES/glibc-rh1810142-1.patch b/SOURCES/glibc-rh1810142-1.patch
new file mode 100644
index 0000000..4a6d2e9
--- /dev/null
+++ b/SOURCES/glibc-rh1810142-1.patch
@@ -0,0 +1,382 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 11 Feb 2020 12:52:06 +0000 (+0100)
+Subject: Add internal <file_change_detection.h> header file
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=6c80c6e8767b860a5e18e136d04a80be2a8dce15
+
+Add internal <file_change_detection.h> header file
+
+The code started out with bits form resolv/resolv_conf.c, but it
+was enhanced to deal with directories and FIFOs in a more predictable
+manner.  A test case is included as well.
+
+This will be used to implement the /etc/resolv.conf change detection.
+
+This currently lives in a header file only.  Once there are multiple
+users, the implementations should be moved into C files.
+---
+
+diff -rupN a/include/file_change_detection.h b/include/file_change_detection.h
+--- a/include/file_change_detection.h	1969-12-31 19:00:00.000000000 -0500
++++ b/include/file_change_detection.h	2020-03-25 16:57:24.227929816 -0400
+@@ -0,0 +1,140 @@
++/* Detecting file changes using modification times.
++   Copyright (C) 2017-2020 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 <errno.h>
++#include <stdbool.h>
++#include <stddef.h>
++#include <stdio.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++
++/* Items for identifying a particular file version.  Excerpt from
++   struct stat64.  */
++struct file_change_detection
++{
++  /* Special values: 0 if file does not exist.  -1 to force mismatch
++     with the next comparison.  */
++  off64_t size;
++
++  ino64_t ino;
++  struct timespec mtime;
++  struct timespec ctime;
++};
++
++/* Returns true if *LEFT and *RIGHT describe the same version of the
++   same file.  */
++static bool __attribute__ ((unused))
++file_is_unchanged (const struct file_change_detection *left,
++                   const struct file_change_detection *right)
++{
++  if (left->size < 0 || right->size < 0)
++    /* Negative sizes are used as markers and never match.  */
++    return false;
++  else if (left->size == 0 && right->size == 0)
++    /* Both files are empty or do not exist, so they have the same
++       content, no matter what the other fields indicate.  */
++    return true;
++  else
++    return left->size == right->size
++      && left->ino == right->ino
++      && left->mtime.tv_sec == right->mtime.tv_sec
++      && left->mtime.tv_nsec == right->mtime.tv_nsec
++      && left->ctime.tv_sec == right->ctime.tv_sec
++      && left->ctime.tv_nsec == right->ctime.tv_nsec;
++}
++
++/* Extract file change information to *FILE from the stat buffer
++   *ST.  */
++static void __attribute__ ((unused))
++file_change_detection_for_stat (struct file_change_detection *file,
++                                const struct stat64 *st)
++{
++  if (S_ISDIR (st->st_mode))
++    /* Treat as empty file.  */
++    file->size = 0;
++  else if (!S_ISREG (st->st_mode))
++    /* Non-regular files cannot be cached.  */
++    file->size = -1;
++  else
++    {
++      file->size = st->st_size;
++      file->ino = st->st_ino;
++      file->mtime = st->st_mtim;
++      file->ctime = st->st_ctim;
++    }
++}
++
++/* Writes file change information for PATH to *FILE.  Returns true on
++   success.  For benign errors, *FILE is cleared, and true is
++   returned.  For errors indicating resource outages and the like,
++   false is returned.  */
++static bool __attribute__ ((unused))
++file_change_detection_for_path (struct file_change_detection *file,
++                                const char *path)
++{
++  struct stat64 st;
++  if (stat64 (path, &st) != 0)
++    switch (errno)
++      {
++      case EACCES:
++      case EISDIR:
++      case ELOOP:
++      case ENOENT:
++      case ENOTDIR:
++      case EPERM:
++        /* Ignore errors due to file system contents.  Instead, treat
++           the file as empty.  */
++        file->size = 0;
++        return true;
++      default:
++        /* Other errors are fatal.  */
++        return false;
++      }
++  else /* stat64 was successfull.  */
++    {
++      file_change_detection_for_stat (file, &st);
++      return true;
++    }
++}
++
++/* Writes file change information for the stream FP to *FILE.  Returns
++   ture on success, false on failure.  If FP is NULL, treat the file
++   as non-existing.  */
++static bool __attribute__ ((unused))
++file_change_detection_for_fp (struct file_change_detection *file,
++                              FILE *fp)
++{
++  if (fp == NULL)
++    {
++      /* The file does not exist.  */
++      file->size = 0;
++      return true;
++    }
++  else
++    {
++      struct stat64 st;
++      if (fstat64 (__fileno (fp), &st) != 0)
++        /* If we already have a file descriptor, all errors are fatal.  */
++        return false;
++      else
++        {
++          file_change_detection_for_stat (file, &st);
++          return true;
++        }
++    }
++}
+diff -rupN a/io/Makefile b/io/Makefile
+--- a/io/Makefile	2020-03-25 16:55:42.442195992 -0400
++++ b/io/Makefile	2020-03-25 16:58:48.571023810 -0400
+@@ -74,6 +74,7 @@ tests		:= test-utime test-stat test-stat
+ 		   tst-posix_fallocate tst-posix_fallocate64 \
+ 		   tst-fts tst-fts-lfs tst-open-tmpfile \
+ 		   tst-copy_file_range tst-getcwd-abspath \
++		   tst-file_change_detection
+ 
+ # Likewise for statx, but we do not need static linking here.
+ tests-internal += tst-statx
+diff -rupN a/io/tst-file_change_detection.c b/io/tst-file_change_detection.c
+--- a/io/tst-file_change_detection.c	1969-12-31 19:00:00.000000000 -0500
++++ b/io/tst-file_change_detection.c	2020-03-25 16:57:24.242930366 -0400
+@@ -0,0 +1,206 @@
++/* Test for <file_change_detection.c>.
++   Copyright (C) 2020 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/>.  */
++
++/* The header uses the internal __fileno symbol, which is not
++   available outside of libc (even to internal tests).  */
++#define __fileno(fp) fileno (fp)
++
++#include <file_change_detection.h>
++
++#include <array_length.h>
++#include <stdlib.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/temp_file.h>
++#include <support/test-driver.h>
++#include <support/xstdio.h>
++#include <support/xunistd.h>
++#include <unistd.h>
++
++static void
++all_same (struct file_change_detection *array, size_t length)
++{
++  for (size_t i = 0; i < length; ++i)
++    for (size_t j = 0; j < length; ++j)
++      {
++        if (test_verbose > 0)
++          printf ("info: comparing %zu and %zu\n", i, j);
++        TEST_VERIFY (file_is_unchanged (array + i, array + j));
++      }
++}
++
++static void
++all_different (struct file_change_detection *array, size_t length)
++{
++  for (size_t i = 0; i < length; ++i)
++    for (size_t j = 0; j < length; ++j)
++      {
++        if (i == j)
++          continue;
++        if (test_verbose > 0)
++          printf ("info: comparing %zu and %zu\n", i, j);
++        TEST_VERIFY (!file_is_unchanged (array + i, array + j));
++      }
++}
++
++static int
++do_test (void)
++{
++  /* Use a temporary directory with various paths.  */
++  char *tempdir = support_create_temp_directory ("tst-file_change_detection-");
++
++  char *path_dangling = xasprintf ("%s/dangling", tempdir);
++  char *path_does_not_exist = xasprintf ("%s/does-not-exist", tempdir);
++  char *path_empty1 = xasprintf ("%s/empty1", tempdir);
++  char *path_empty2 = xasprintf ("%s/empty2", tempdir);
++  char *path_fifo = xasprintf ("%s/fifo", tempdir);
++  char *path_file1 = xasprintf ("%s/file1", tempdir);
++  char *path_file2 = xasprintf ("%s/file2", tempdir);
++  char *path_loop = xasprintf ("%s/loop", tempdir);
++  char *path_to_empty1 = xasprintf ("%s/to-empty1", tempdir);
++  char *path_to_file1 = xasprintf ("%s/to-file1", tempdir);
++
++  add_temp_file (path_dangling);
++  add_temp_file (path_empty1);
++  add_temp_file (path_empty2);
++  add_temp_file (path_fifo);
++  add_temp_file (path_file1);
++  add_temp_file (path_file2);
++  add_temp_file (path_loop);
++  add_temp_file (path_to_empty1);
++  add_temp_file (path_to_file1);
++
++  xsymlink ("target-does-not-exist", path_dangling);
++  support_write_file_string (path_empty1, "");
++  support_write_file_string (path_empty2, "");
++  TEST_COMPARE (mknod (path_fifo, 0777 | S_IFIFO, 0), 0);
++  support_write_file_string (path_file1, "line\n");
++  support_write_file_string (path_file2, "line\n");
++  xsymlink ("loop", path_loop);
++  xsymlink ("empty1", path_to_empty1);
++  xsymlink ("file1", path_to_file1);
++
++  FILE *fp_file1 = xfopen (path_file1, "r");
++  FILE *fp_file2 = xfopen (path_file2, "r");
++  FILE *fp_empty1 = xfopen (path_empty1, "r");
++  FILE *fp_empty2 = xfopen (path_empty2, "r");
++
++  /* Test for the same (empty) files.  */
++  {
++    struct file_change_detection fcd[10];
++    int i = 0;
++    /* Two empty files always have the same contents.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1));
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty2));
++    /* So does a missing file (which is treated as empty).  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++],
++                                                 path_does_not_exist));
++    /* And a symbolic link loop.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_loop));
++    /* And a dangling symbolic link.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_dangling));
++    /* And a directory.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], tempdir));
++    /* And a symbolic link to an empty file.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_empty1));
++    /* Likewise for access the file via a FILE *.  */
++    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty1));
++    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty2));
++    /* And a NULL FILE * (missing file).  */
++    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], NULL));
++    TEST_COMPARE (i, array_length (fcd));
++
++    all_same (fcd, array_length (fcd));
++  }
++
++  /* Symbolic links are resolved.  */
++  {
++    struct file_change_detection fcd[3];
++    int i = 0;
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1));
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_file1));
++    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_file1));
++    TEST_COMPARE (i, array_length (fcd));
++    all_same (fcd, array_length (fcd));
++  }
++
++  /* Test for different files.  */
++  {
++    struct file_change_detection fcd[5];
++    int i = 0;
++    /* The other files are not empty.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1));
++    /* These two files have the same contents, but have different file
++       identity.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1));
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file2));
++    /* FIFOs are always different, even with themselves.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo));
++    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo));
++    TEST_COMPARE (i, array_length (fcd));
++    all_different (fcd, array_length (fcd));
++
++    /* Replacing the file with its symbolic link does not make a
++       difference.  */
++    TEST_VERIFY (file_change_detection_for_path (&fcd[1], path_to_file1));
++    all_different (fcd, array_length (fcd));
++  }
++
++  /* Wait for a file change.  Depending on file system time stamp
++     resolution, this subtest blocks for a while.  */
++  for (int use_stdio = 0; use_stdio < 2; ++use_stdio)
++    {
++      struct file_change_detection initial;
++      TEST_VERIFY (file_change_detection_for_path (&initial, path_file1));
++      while (true)
++        {
++          support_write_file_string (path_file1, "line\n");
++          struct file_change_detection current;
++          if (use_stdio)
++            TEST_VERIFY (file_change_detection_for_fp (&current, fp_file1));
++          else
++            TEST_VERIFY (file_change_detection_for_path (&current, path_file1));
++          if (!file_is_unchanged (&initial, &current))
++            break;
++          /* Wait for a bit to reduce system load.  */
++          usleep (100 * 1000);
++        }
++    }
++
++  fclose (fp_empty1);
++  fclose (fp_empty2);
++  fclose (fp_file1);
++  fclose (fp_file2);
++
++  free (path_dangling);
++  free (path_does_not_exist);
++  free (path_empty1);
++  free (path_empty2);
++  free (path_fifo);
++  free (path_file1);
++  free (path_file2);
++  free (path_loop);
++  free (path_to_empty1);
++  free (path_to_file1);
++
++  free (tempdir);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1810142-2.patch b/SOURCES/glibc-rh1810142-2.patch
new file mode 100644
index 0000000..cd7b4e4
--- /dev/null
+++ b/SOURCES/glibc-rh1810142-2.patch
@@ -0,0 +1,94 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 21 Jan 2020 15:52:33 +0000 (+0100)
+Subject: resolv: Use <file_change_detection.h> in __resolv_conf_get_current
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=9642b85fd0dfa5731020a3271c08e33e1dc05c85
+
+resolv: Use <file_change_detection.h> in __resolv_conf_get_current
+
+Only minor functional changes (i.e., regarding the handling of
+directories, which are now treated as empty files).
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+---
+
+diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
+index 08c50ef19e..d954ba9a5a 100644
+--- a/resolv/resolv_conf.c
++++ b/resolv/resolv_conf.c
+@@ -24,6 +24,7 @@
+ #include <resolv-internal.h>
+ #include <sys/stat.h>
+ #include <libc-symbols.h>
++#include <file_change_detection.h>
+ 
+ /* _res._u._ext.__glibc_extension_index is used as an index into a
+    struct resolv_conf_array object.  The intent of this construction
+@@ -68,12 +69,8 @@ struct resolv_conf_global
+   /* Cached current configuration object for /etc/resolv.conf.  */
+   struct resolv_conf *conf_current;
+ 
+-  /* These properties of /etc/resolv.conf are used to check if the
+-     configuration needs reloading.  */
+-  struct timespec conf_mtime;
+-  struct timespec conf_ctime;
+-  off64_t conf_size;
+-  ino64_t conf_ino;
++  /* File system identification for /etc/resolv.conf.  */
++  struct file_change_detection file_resolve_conf;
+ };
+ 
+ /* Lazily allocated storage for struct resolv_conf_global.  */
+@@ -123,37 +120,16 @@ conf_decrement (struct resolv_conf *conf)
+ struct resolv_conf *
+ __resolv_conf_get_current (void)
+ {
+-  struct stat64 st;
+-  if (stat64 (_PATH_RESCONF, &st) != 0)
+-    {
+-    switch (errno)
+-      {
+-      case EACCES:
+-      case EISDIR:
+-      case ELOOP:
+-      case ENOENT:
+-      case ENOTDIR:
+-      case EPERM:
+-        /* Ignore errors due to file system contents.  */
+-        memset (&st, 0, sizeof (st));
+-        break;
+-      default:
+-        /* Other errors are fatal.  */
+-        return NULL;
+-      }
+-    }
++  struct file_change_detection initial;
++  if (!file_change_detection_for_path (&initial, _PATH_RESCONF))
++    return NULL;
+ 
+   struct resolv_conf_global *global_copy = get_locked_global ();
+   if (global_copy == NULL)
+     return NULL;
+   struct resolv_conf *conf;
+   if (global_copy->conf_current != NULL
+-      && (global_copy->conf_mtime.tv_sec == st.st_mtim.tv_sec
+-          && global_copy->conf_mtime.tv_nsec == st.st_mtim.tv_nsec
+-          && global_copy->conf_ctime.tv_sec == st.st_ctim.tv_sec
+-          && global_copy->conf_ctime.tv_nsec == st.st_ctim.tv_nsec
+-          && global_copy->conf_ino == st.st_ino
+-          && global_copy->conf_size == st.st_size))
++      && file_is_unchanged (&initial, &global_copy->file_resolve_conf))
+     /* We can reuse the cached configuration object.  */
+     conf = global_copy->conf_current;
+   else
+@@ -171,10 +147,7 @@ __resolv_conf_get_current (void)
+              read could be a newer version of the file, but this does
+              not matter because this will lead to an extraneous reload
+              later.  */
+-          global_copy->conf_mtime = st.st_mtim;
+-          global_copy->conf_ctime = st.st_ctim;
+-          global_copy->conf_ino = st.st_ino;
+-          global_copy->conf_size = st.st_size;
++          global_copy->file_resolve_conf = initial;
+         }
+     }
+ 
diff --git a/SOURCES/glibc-rh1810142-3.patch b/SOURCES/glibc-rh1810142-3.patch
new file mode 100644
index 0000000..e13f74d
--- /dev/null
+++ b/SOURCES/glibc-rh1810142-3.patch
@@ -0,0 +1,46 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 21 Jan 2020 16:11:01 +0000 (+0100)
+Subject: resolv: Fix file handle leak in __resolv_conf_load [BZ #25429]
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=a1a20f029299dc27170912bb9233070c8403444d
+
+resolv: Fix file handle leak in __resolv_conf_load [BZ #25429]
+
+res_vinit_1 did not close the stream on errors, only on success.
+This change moves closing the stream to __resolv_conf_load, for both
+the success and error cases.
+
+Fixes commit 89f187a40fc0ad4e22838526bfe34d73f758b776 ("resolv: Use
+getline for configuration file reading in res_vinit_1") and commit
+3f853f22c87f0b671c0366eb290919719fa56c0e ("resolv: Lift domain search
+list limits [BZ #19569] [BZ #21475]"), where memory allocation was
+introduced into res_vinit_1.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+---
+
+diff --git a/resolv/res_init.c b/resolv/res_init.c
+index 95dce098aa..09345718cd 100644
+--- a/resolv/res_init.c
++++ b/resolv/res_init.c
+@@ -508,7 +508,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+               continue;
+             }
+         }
+-      fclose (fp);
+     }
+   if (__glibc_unlikely (nameserver_list_size (&parser->nameserver_list) == 0))
+     {
+@@ -593,6 +592,13 @@ __resolv_conf_load (struct __res_state *preinit)
+     }
+   resolv_conf_parser_free (&parser);
+ 
++  if (fp != NULL)
++    {
++      int saved_errno = errno;
++      fclose (fp);
++      __set_errno (saved_errno);
++    }
++
+   return conf;
+ }
+ 
diff --git a/SOURCES/glibc-rh1810142-4.patch b/SOURCES/glibc-rh1810142-4.patch
new file mode 100644
index 0000000..3d4ff39
--- /dev/null
+++ b/SOURCES/glibc-rh1810142-4.patch
@@ -0,0 +1,96 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 21 Jan 2020 16:25:39 +0000 (+0100)
+Subject: resolv: Enhance __resolv_conf_load to capture file change data
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=dd0b4df329ff7ff2a656404db271c8ee8379ff9d
+
+resolv: Enhance __resolv_conf_load to capture file change data
+
+The data is captured after reading the file.  This allows callers
+to check the change data against an earlier measurement.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+---
+
+diff --git a/resolv/res_init.c b/resolv/res_init.c
+index 09345718cd..98d84f264d 100644
+--- a/resolv/res_init.c
++++ b/resolv/res_init.c
+@@ -103,6 +103,7 @@
+ #include <inet/net-internal.h>
+ #include <errno.h>
+ #include <resolv_conf.h>
++#include <file_change_detection.h>
+ 
+ static uint32_t net_mask (struct in_addr);
+ 
+@@ -549,7 +550,8 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+ }
+ 
+ struct resolv_conf *
+-__resolv_conf_load (struct __res_state *preinit)
++__resolv_conf_load (struct __res_state *preinit,
++                    struct file_change_detection *change)
+ {
+   /* Ensure that /etc/hosts.conf has been loaded (once).  */
+   _res_hconf_init ();
+@@ -577,7 +579,13 @@ __resolv_conf_load (struct __res_state *preinit)
+   resolv_conf_parser_init (&parser, preinit);
+ 
+   struct resolv_conf *conf = NULL;
+-  if (res_vinit_1 (fp, &parser))
++  bool ok = res_vinit_1 (fp, &parser);
++  if (ok && change != NULL)
++    /* Update the file change information if the configuration was
++       loaded successfully.  */
++    ok = file_change_detection_for_fp (change, fp);
++
++  if (ok)
+     {
+       parser.template.nameserver_list
+         = nameserver_list_begin (&parser.nameserver_list);
+@@ -615,7 +623,7 @@ __res_vinit (res_state statp, int preinit)
+   if (preinit && has_preinit_values (statp))
+     /* For the preinit case, we cannot use the cached configuration
+        because some settings could be different.  */
+-    conf = __resolv_conf_load (statp);
++    conf = __resolv_conf_load (statp, NULL);
+   else
+     conf = __resolv_conf_get_current ();
+   if (conf == NULL)
+diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
+index d954ba9a5a..bdd2ebb909 100644
+--- a/resolv/resolv_conf.c
++++ b/resolv/resolv_conf.c
+@@ -136,7 +136,7 @@ __resolv_conf_get_current (void)
+     {
+       /* Parse configuration while holding the lock.  This avoids
+          duplicate work.  */
+-      conf = __resolv_conf_load (NULL);
++      conf = __resolv_conf_load (NULL, NULL);
+       if (conf != NULL)
+         {
+           if (global_copy->conf_current != NULL)
+diff --git a/resolv/resolv_conf.h b/resolv/resolv_conf.h
+index 01cbff9111..101e14bfe5 100644
+--- a/resolv/resolv_conf.h
++++ b/resolv/resolv_conf.h
+@@ -63,12 +63,16 @@ struct resolv_conf
+    and the struct resolv_context facility.  */
+ 
+ struct __res_state;
++struct file_change_detection;
+ 
+ /* Read /etc/resolv.conf and return a configuration object, or NULL if
+    /etc/resolv.conf cannot be read due to memory allocation errors.
+-   If PREINIT is not NULL, some configuration values are taken from the
+-   struct __res_state object.  */
+-struct resolv_conf *__resolv_conf_load (struct __res_state *preinit)
++   If PREINIT is not NULL, some configuration values are taken from
++   the struct __res_state object.  If CHANGE is not null, file change
++   detection data is written to *CHANGE, based on the state of the
++   file after reading it.  */
++struct resolv_conf *__resolv_conf_load (struct __res_state *preinit,
++                                        struct file_change_detection *change)
+   attribute_hidden __attribute__ ((warn_unused_result));
+ 
+ /* Return a configuration object for the current /etc/resolv.conf
diff --git a/SOURCES/glibc-rh1810142-5.patch b/SOURCES/glibc-rh1810142-5.patch
new file mode 100644
index 0000000..be991b0
--- /dev/null
+++ b/SOURCES/glibc-rh1810142-5.patch
@@ -0,0 +1,52 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 21 Jan 2020 16:38:15 +0000 (+0100)
+Subject: resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420]
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=fa00db0a6eb755837ae5d413515e0da582b304f3
+
+resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420]
+
+__resolv_conf_get_current should only record the initial file
+change data if after verifying that file just read matches the
+original measurement.  Fixes commit aef16cc8a4c670036d45590877
+("resolv: Automatically reload a changed /etc/resolv.conf file
+[BZ #984]").
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+---
+
+diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
+index bdd2ebb909..29a1f4fb94 100644
+--- a/resolv/resolv_conf.c
++++ b/resolv/resolv_conf.c
+@@ -136,18 +136,25 @@ __resolv_conf_get_current (void)
+     {
+       /* Parse configuration while holding the lock.  This avoids
+          duplicate work.  */
+-      conf = __resolv_conf_load (NULL, NULL);
++      struct file_change_detection after_load;
++      conf = __resolv_conf_load (NULL, &after_load);
+       if (conf != NULL)
+         {
+           if (global_copy->conf_current != NULL)
+             conf_decrement (global_copy->conf_current);
+           global_copy->conf_current = conf; /* Takes ownership.  */
+ 
+-          /* Update file modification stamps.  The configuration we
+-             read could be a newer version of the file, but this does
+-             not matter because this will lead to an extraneous reload
+-             later.  */
+-          global_copy->file_resolve_conf = initial;
++          /* Update file change detection data, but only if it matches
++             the initial measurement.  This avoids an ABA race in case
++             /etc/resolv.conf is temporarily replaced while the file
++             is read (after the initial measurement), and restored to
++             the initial version later.  */
++          if (file_is_unchanged (&initial, &after_load))
++            global_copy->file_resolve_conf = after_load;
++          else
++            /* If there is a discrepancy, trigger a reload during the
++               next use.  */
++            global_copy->file_resolve_conf.size = -1;
+         }
+     }
+ 
diff --git a/SOURCES/glibc-rh1810142-6.patch b/SOURCES/glibc-rh1810142-6.patch
new file mode 100644
index 0000000..8d96880
--- /dev/null
+++ b/SOURCES/glibc-rh1810142-6.patch
@@ -0,0 +1,481 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 18 Feb 2020 12:44:48 +0000 (+0100)
+Subject: Move implementation of <file_change_detection.h> into a C file
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=631cf64bc1d8306e011ef39f60b8cb6de91bd271
+
+Move implementation of <file_change_detection.h> into a C file
+
+file_change_detection_for_stat partially initialize
+struct file_change_detection in some cases, when the size member
+alone determines the outcome of all comparisons.  This results
+in maybe-uninitialized compiler warnings in case of sufficiently
+aggressive inlining.
+
+Once the implementation is moved into a separate C file, this kind
+of inlining is no longer possible, so the compiler warnings are gone.
+---
+
+diff --git a/include/file_change_detection.h b/include/file_change_detection.h
+index aaed0a9b6d..767e578555 100644
+--- a/include/file_change_detection.h
++++ b/include/file_change_detection.h
+@@ -16,9 +16,10 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <errno.h>
++#ifndef _FILE_CHANGE_DETECTION_H
++#define _FILE_CHANGE_DETECTION_H
++
+ #include <stdbool.h>
+-#include <stddef.h>
+ #include <stdio.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+@@ -38,103 +39,32 @@ struct file_change_detection
+ 
+ /* Returns true if *LEFT and *RIGHT describe the same version of the
+    same file.  */
+-static bool __attribute__ ((unused))
+-file_is_unchanged (const struct file_change_detection *left,
+-                   const struct file_change_detection *right)
+-{
+-  if (left->size < 0 || right->size < 0)
+-    /* Negative sizes are used as markers and never match.  */
+-    return false;
+-  else if (left->size == 0 && right->size == 0)
+-    /* Both files are empty or do not exist, so they have the same
+-       content, no matter what the other fields indicate.  */
+-    return true;
+-  else
+-    return left->size == right->size
+-      && left->ino == right->ino
+-      && left->mtime.tv_sec == right->mtime.tv_sec
+-      && left->mtime.tv_nsec == right->mtime.tv_nsec
+-      && left->ctime.tv_sec == right->ctime.tv_sec
+-      && left->ctime.tv_nsec == right->ctime.tv_nsec;
+-}
++bool __file_is_unchanged (const struct file_change_detection *left,
++                          const struct file_change_detection *right);
+ 
+ /* Extract file change information to *FILE from the stat buffer
+    *ST.  */
+-static void __attribute__ ((unused))
+-file_change_detection_for_stat (struct file_change_detection *file,
+-                                const struct stat64 *st)
+-{
+-  if (S_ISDIR (st->st_mode))
+-    /* Treat as empty file.  */
+-    file->size = 0;
+-  else if (!S_ISREG (st->st_mode))
+-    /* Non-regular files cannot be cached.  */
+-    file->size = -1;
+-  else
+-    {
+-      file->size = st->st_size;
+-      file->ino = st->st_ino;
+-      file->mtime = st->st_mtim;
+-      file->ctime = st->st_ctim;
+-    }
+-}
++void __file_change_detection_for_stat (struct file_change_detection *file,
++                                       const struct stat64 *st);
+ 
+ /* Writes file change information for PATH to *FILE.  Returns true on
+    success.  For benign errors, *FILE is cleared, and true is
+    returned.  For errors indicating resource outages and the like,
+    false is returned.  */
+-static bool __attribute__ ((unused))
+-file_change_detection_for_path (struct file_change_detection *file,
+-                                const char *path)
+-{
+-  struct stat64 st;
+-  if (stat64 (path, &st) != 0)
+-    switch (errno)
+-      {
+-      case EACCES:
+-      case EISDIR:
+-      case ELOOP:
+-      case ENOENT:
+-      case ENOTDIR:
+-      case EPERM:
+-        /* Ignore errors due to file system contents.  Instead, treat
+-           the file as empty.  */
+-        file->size = 0;
+-        return true;
+-      default:
+-        /* Other errors are fatal.  */
+-        return false;
+-      }
+-  else /* stat64 was successfull.  */
+-    {
+-      file_change_detection_for_stat (file, &st);
+-      return true;
+-    }
+-}
++bool __file_change_detection_for_path (struct file_change_detection *file,
++                                       const char *path);
+ 
+ /* Writes file change information for the stream FP to *FILE.  Returns
+    ture on success, false on failure.  If FP is NULL, treat the file
+    as non-existing.  */
+-static bool __attribute__ ((unused))
+-file_change_detection_for_fp (struct file_change_detection *file,
+-                              FILE *fp)
+-{
+-  if (fp == NULL)
+-    {
+-      /* The file does not exist.  */
+-      file->size = 0;
+-      return true;
+-    }
+-  else
+-    {
+-      struct stat64 st;
+-      if (fstat64 (__fileno (fp), &st) != 0)
+-        /* If we already have a file descriptor, all errors are fatal.  */
+-        return false;
+-      else
+-        {
+-          file_change_detection_for_stat (file, &st);
+-          return true;
+-        }
+-    }
+-}
++bool __file_change_detection_for_fp (struct file_change_detection *file,
++                                     FILE *fp);
++
++#ifndef _ISOMAC
++libc_hidden_proto (__file_is_unchanged)
++libc_hidden_proto (__file_change_detection_for_stat)
++libc_hidden_proto (__file_change_detection_for_path)
++libc_hidden_proto (__file_change_detection_for_fp)
++#endif
++
++#endif /* _FILE_CHANGE_DETECTION_H */
+diff --git a/io/Makefile b/io/Makefile
+index 04c4647dc0..cf380f3516 100644
+--- a/io/Makefile
++++ b/io/Makefile
+@@ -55,7 +55,7 @@ routines :=								\
+ 	posix_fadvise posix_fadvise64					\
+ 	posix_fallocate posix_fallocate64				\
+ 	sendfile sendfile64 copy_file_range 				\
+-	utimensat futimens
++	utimensat futimens file_change_detection
+ 
+ # These routines will be omitted from the libc shared object.
+ # Instead the static object files will be included in a special archive
+diff --git a/io/Versions b/io/Versions
+index f7e5dbe49e..ee468055ff 100644
+--- a/io/Versions
++++ b/io/Versions
+@@ -137,5 +137,9 @@ libc {
+     __fcntl_nocancel;
+     __open64_nocancel;
+     __write_nocancel;
++    __file_is_unchanged;
++    __file_change_detection_for_stat;
++    __file_change_detection_for_path;
++    __file_change_detection_for_fp;
+   }
+ }
+diff --git a/io/file_change_detection.c b/io/file_change_detection.c
+new file mode 100644
+index 0000000000..c6d700ed05
+--- /dev/null
++++ b/io/file_change_detection.c
+@@ -0,0 +1,118 @@
++/* Detecting file changes using modification times.
++   Copyright (C) 2017-2020 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 <file_change_detection.h>
++
++#include <errno.h>
++#include <stddef.h>
++
++bool
++__file_is_unchanged (const struct file_change_detection *left,
++                     const struct file_change_detection *right)
++{
++  if (left->size < 0 || right->size < 0)
++    /* Negative sizes are used as markers and never match.  */
++    return false;
++  else if (left->size == 0 && right->size == 0)
++    /* Both files are empty or do not exist, so they have the same
++       content, no matter what the other fields indicate.  */
++    return true;
++  else
++    return left->size == right->size
++      && left->ino == right->ino
++      && left->mtime.tv_sec == right->mtime.tv_sec
++      && left->mtime.tv_nsec == right->mtime.tv_nsec
++      && left->ctime.tv_sec == right->ctime.tv_sec
++      && left->ctime.tv_nsec == right->ctime.tv_nsec;
++}
++libc_hidden_def (__file_is_unchanged)
++
++void
++__file_change_detection_for_stat (struct file_change_detection *file,
++                                  const struct stat64 *st)
++{
++  if (S_ISDIR (st->st_mode))
++    /* Treat as empty file.  */
++    file->size = 0;
++  else if (!S_ISREG (st->st_mode))
++    /* Non-regular files cannot be cached.  */
++    file->size = -1;
++  else
++    {
++      file->size = st->st_size;
++      file->ino = st->st_ino;
++      file->mtime = st->st_mtim;
++      file->ctime = st->st_ctim;
++    }
++}
++libc_hidden_def (__file_change_detection_for_stat)
++
++bool
++__file_change_detection_for_path (struct file_change_detection *file,
++                                  const char *path)
++{
++  struct stat64 st;
++  if (stat64 (path, &st) != 0)
++    switch (errno)
++      {
++      case EACCES:
++      case EISDIR:
++      case ELOOP:
++      case ENOENT:
++      case ENOTDIR:
++      case EPERM:
++        /* Ignore errors due to file system contents.  Instead, treat
++           the file as empty.  */
++        file->size = 0;
++        return true;
++      default:
++        /* Other errors are fatal.  */
++        return false;
++      }
++  else /* stat64 was successfull.  */
++    {
++      __file_change_detection_for_stat (file, &st);
++      return true;
++    }
++}
++libc_hidden_def (__file_change_detection_for_path)
++
++bool
++__file_change_detection_for_fp (struct file_change_detection *file,
++                                FILE *fp)
++{
++  if (fp == NULL)
++    {
++      /* The file does not exist.  */
++      file->size = 0;
++      return true;
++    }
++  else
++    {
++      struct stat64 st;
++      if (fstat64 (__fileno (fp), &st) != 0)
++        /* If we already have a file descriptor, all errors are fatal.  */
++        return false;
++      else
++        {
++          __file_change_detection_for_stat (file, &st);
++          return true;
++        }
++    }
++}
++libc_hidden_def (__file_change_detection_for_fp)
+diff --git a/io/tst-file_change_detection.c b/io/tst-file_change_detection.c
+index 035dd39c4d..6e00e787b1 100644
+--- a/io/tst-file_change_detection.c
++++ b/io/tst-file_change_detection.c
+@@ -16,10 +16,6 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-/* The header uses the internal __fileno symbol, which is not
+-   available outside of libc (even to internal tests).  */
+-#define __fileno(fp) fileno (fp)
+-
+ #include <file_change_detection.h>
+ 
+ #include <array_length.h>
+@@ -40,7 +36,7 @@ all_same (struct file_change_detection *array, size_t length)
+       {
+         if (test_verbose > 0)
+           printf ("info: comparing %zu and %zu\n", i, j);
+-        TEST_VERIFY (file_is_unchanged (array + i, array + j));
++        TEST_VERIFY (__file_is_unchanged (array + i, array + j));
+       }
+ }
+ 
+@@ -54,7 +50,7 @@ all_different (struct file_change_detection *array, size_t length)
+           continue;
+         if (test_verbose > 0)
+           printf ("info: comparing %zu and %zu\n", i, j);
+-        TEST_VERIFY (!file_is_unchanged (array + i, array + j));
++        TEST_VERIFY (!__file_is_unchanged (array + i, array + j));
+       }
+ }
+ 
+@@ -105,24 +101,24 @@ do_test (void)
+     struct file_change_detection fcd[10];
+     int i = 0;
+     /* Two empty files always have the same contents.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1));
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty2));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty1));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty2));
+     /* So does a missing file (which is treated as empty).  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++],
+-                                                 path_does_not_exist));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++],
++                                                   path_does_not_exist));
+     /* And a symbolic link loop.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_loop));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_loop));
+     /* And a dangling symbolic link.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_dangling));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_dangling));
+     /* And a directory.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], tempdir));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], tempdir));
+     /* And a symbolic link to an empty file.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_empty1));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_to_empty1));
+     /* Likewise for access the file via a FILE *.  */
+-    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty1));
+-    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty2));
++    TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_empty1));
++    TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_empty2));
+     /* And a NULL FILE * (missing file).  */
+-    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], NULL));
++    TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], NULL));
+     TEST_COMPARE (i, array_length (fcd));
+ 
+     all_same (fcd, array_length (fcd));
+@@ -132,9 +128,9 @@ do_test (void)
+   {
+     struct file_change_detection fcd[3];
+     int i = 0;
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1));
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_file1));
+-    TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_file1));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file1));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_to_file1));
++    TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_file1));
+     TEST_COMPARE (i, array_length (fcd));
+     all_same (fcd, array_length (fcd));
+   }
+@@ -144,20 +140,20 @@ do_test (void)
+     struct file_change_detection fcd[5];
+     int i = 0;
+     /* The other files are not empty.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty1));
+     /* These two files have the same contents, but have different file
+        identity.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1));
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file2));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file1));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file2));
+     /* FIFOs are always different, even with themselves.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo));
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_fifo));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_fifo));
+     TEST_COMPARE (i, array_length (fcd));
+     all_different (fcd, array_length (fcd));
+ 
+     /* Replacing the file with its symbolic link does not make a
+        difference.  */
+-    TEST_VERIFY (file_change_detection_for_path (&fcd[1], path_to_file1));
++    TEST_VERIFY (__file_change_detection_for_path (&fcd[1], path_to_file1));
+     all_different (fcd, array_length (fcd));
+   }
+ 
+@@ -166,16 +162,17 @@ do_test (void)
+   for (int use_stdio = 0; use_stdio < 2; ++use_stdio)
+     {
+       struct file_change_detection initial;
+-      TEST_VERIFY (file_change_detection_for_path (&initial, path_file1));
++      TEST_VERIFY (__file_change_detection_for_path (&initial, path_file1));
+       while (true)
+         {
+           support_write_file_string (path_file1, "line\n");
+           struct file_change_detection current;
+           if (use_stdio)
+-            TEST_VERIFY (file_change_detection_for_fp (&current, fp_file1));
++            TEST_VERIFY (__file_change_detection_for_fp (&current, fp_file1));
+           else
+-            TEST_VERIFY (file_change_detection_for_path (&current, path_file1));
+-          if (!file_is_unchanged (&initial, &current))
++            TEST_VERIFY (__file_change_detection_for_path
++                         (&current, path_file1));
++          if (!__file_is_unchanged (&initial, &current))
+             break;
+           /* Wait for a bit to reduce system load.  */
+           usleep (100 * 1000);
+diff --git a/resolv/res_init.c b/resolv/res_init.c
+index 98d84f264d..ee5dfdd391 100644
+--- a/resolv/res_init.c
++++ b/resolv/res_init.c
+@@ -583,7 +583,7 @@ __resolv_conf_load (struct __res_state *preinit,
+   if (ok && change != NULL)
+     /* Update the file change information if the configuration was
+        loaded successfully.  */
+-    ok = file_change_detection_for_fp (change, fp);
++    ok = __file_change_detection_for_fp (change, fp);
+ 
+   if (ok)
+     {
+diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
+index 29a1f4fb94..286149ffad 100644
+--- a/resolv/resolv_conf.c
++++ b/resolv/resolv_conf.c
+@@ -121,7 +121,7 @@ struct resolv_conf *
+ __resolv_conf_get_current (void)
+ {
+   struct file_change_detection initial;
+-  if (!file_change_detection_for_path (&initial, _PATH_RESCONF))
++  if (!__file_change_detection_for_path (&initial, _PATH_RESCONF))
+     return NULL;
+ 
+   struct resolv_conf_global *global_copy = get_locked_global ();
+@@ -129,7 +129,7 @@ __resolv_conf_get_current (void)
+     return NULL;
+   struct resolv_conf *conf;
+   if (global_copy->conf_current != NULL
+-      && file_is_unchanged (&initial, &global_copy->file_resolve_conf))
++      && __file_is_unchanged (&initial, &global_copy->file_resolve_conf))
+     /* We can reuse the cached configuration object.  */
+     conf = global_copy->conf_current;
+   else
+@@ -149,7 +149,7 @@ __resolv_conf_get_current (void)
+              /etc/resolv.conf is temporarily replaced while the file
+              is read (after the initial measurement), and restored to
+              the initial version later.  */
+-          if (file_is_unchanged (&initial, &after_load))
++          if (__file_is_unchanged (&initial, &after_load))
+             global_copy->file_resolve_conf = after_load;
+           else
+             /* If there is a discrepancy, trigger a reload during the
diff --git a/SOURCES/glibc-rh1810146.patch b/SOURCES/glibc-rh1810146.patch
new file mode 100644
index 0000000..da0d6b3
--- /dev/null
+++ b/SOURCES/glibc-rh1810146.patch
@@ -0,0 +1,28 @@
+commit 8b222fa38700422b4da6731806835f0bbf40920d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 20 18:37:13 2020 +0100
+
+    getaddrinfo: Fix resource leak after strdup failure in gethosts [BZ #25425]
+    
+    Filip Ochnik spotted that one of the error jumps in gethosts fails to
+    call __resolv_context_put to release the resolver context.
+    
+    Fixes commit 352f4ff9a268b81ef5d4b2413f582565806e4790 ("resolv:
+    Introduce struct resolv_context [BZ #21668]") and commit
+    964263bb8d650f1681665c55704fb01a8e725621 ("getaddrinfo: Release
+    resolver context on error in gethosts [BZ #21885]").
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 6a5805c9e63a257c..fae3dea81f19dba6 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -292,6 +292,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
+ 	  canonbuf = __strdup (localcanon);				      \
+ 	  if (canonbuf == NULL)						      \
+ 	    {								      \
++	      __resolv_context_put (res_ctx);				      \
+ 	      result = -EAI_SYSTEM;					      \
+ 	      goto free_and_return;					      \
+ 	    }								      \
diff --git a/SOURCES/glibc-rh1810223-1.patch b/SOURCES/glibc-rh1810223-1.patch
new file mode 100644
index 0000000..6771e16
--- /dev/null
+++ b/SOURCES/glibc-rh1810223-1.patch
@@ -0,0 +1,170 @@
+commit 0499a353a6e196f468e7ec554cb13c82011f0e36
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Mar 2 14:24:27 2020 +0100
+
+    elf: Add elf/check-wx-segment, a test for the presence of WX segments
+    
+    Writable, executable segments defeat security hardening.  The
+    existing check for DT_TEXTREL does not catch this.
+    
+    hppa and SPARC currently keep the PLT in an RWX load segment.
+
+# Conflicts:
+#	sysdeps/sparc/Makefile
+
+diff --git a/elf/Makefile b/elf/Makefile
+index f1a16fe8ca594c57..a52d9b1f6a4364a7 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -378,6 +378,7 @@ tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \
+ 		 $(objpfx)tst-rtld-preload.out
+ endif
+ tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \
++		 $(objpfx)check-wx-segment.out \
+ 		 $(objpfx)check-localplt.out $(objpfx)check-initfini.out
+ endif
+ 
+@@ -1148,6 +1149,12 @@ $(objpfx)check-execstack.out: $(..)scripts/check-execstack.awk \
+ 	$(evaluate-test)
+ generated += check-execstack.out
+ 
++$(objpfx)check-wx-segment.out: $(..)scripts/check-wx-segment.py \
++			      $(all-built-dso:=.phdr)
++	$(PYTHON) $^ --xfail="$(check-wx-segment-xfail)" > $@; \
++	$(evaluate-test)
++generated += check-wx-segment.out
++
+ $(objpfx)tst-dlmodcount: $(libdl)
+ $(objpfx)tst-dlmodcount.out: $(test-modules)
+ 
+diff --git a/scripts/check-wx-segment.py b/scripts/check-wx-segment.py
+new file mode 100644
+index 0000000000000000..e1fa79387ce22c4b
+--- /dev/null
++++ b/scripts/check-wx-segment.py
+@@ -0,0 +1,85 @@
++#!/usr/bin/python3
++# Check ELF program headers for WX segments.
++# Copyright (C) 2020 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/>.
++
++"""Check that the program headers do not contain write-exec segments."""
++
++import argparse
++import os.path
++import re
++import sys
++
++# Regular expression to extract the RWE flags field.  The
++# address/offset columns have varying width.
++RE_LOAD = re.compile(
++    r'^  LOAD +(?:0x[0-9a-fA-F]+ +){5}([R ][W ][ E]) +0x[0-9a-fA-F]+\n\Z')
++
++def process_file(path, inp, xfail):
++    """Analyze one input file."""
++
++    errors = 0
++    for line in inp:
++        error = None
++        if line.startswith('  LOAD '):
++            match = RE_LOAD.match(line)
++            if match is None:
++                error = 'Invalid LOAD line'
++            else:
++                flags, = match.groups()
++                if 'W' in flags and 'E' in flags:
++                    if xfail:
++                        print('{}: warning: WX segment (as expected)'.format(
++                            path))
++                    else:
++                        error = 'WX segment'
++
++        if error is not None:
++            print('{}: error: {}: {!r}'.format(path, error, line.strip()))
++            errors += 1
++
++    if xfail and errors == 0:
++        print('{}: warning: missing expected WX segment'.format(path))
++    return errors
++
++
++def main():
++    """The main entry point."""
++    parser = argparse.ArgumentParser(description=__doc__)
++    parser.add_argument('--xfail',
++                        help='Mark input files as XFAILed ("*" for all)',
++                        type=str, default='')
++    parser.add_argument('phdrs',
++                        help='Files containing readelf -Wl output',
++                        nargs='*')
++    opts = parser.parse_args(sys.argv)
++
++    xfails = set(opts.xfail.split(' '))
++    xfails_all = opts.xfail.strip() == '*'
++
++    errors = 0
++    for path in opts.phdrs:
++        xfail = ((os.path.basename(path) + '.phdrs') in xfails
++                 or xfails_all)
++        with open(path) as inp:
++            errors += process_file(path, inp, xfail)
++    if errors > 0:
++        sys.exit(1)
++
++
++if __name__ == '__main__':
++    main()
+diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile
+index 3f0c0964002560f0..a1004e819c9b0c38 100644
+--- a/sysdeps/sparc/Makefile
++++ b/sysdeps/sparc/Makefile
+@@ -16,5 +16,14 @@ CPPFLAGS-crti.S += -fPIC
+ CPPFLAGS-crtn.S += -fPIC
+ endif
+ 
++ifeq ($(subdir),elf)
++
++# Lazy binding on SPARC rewrites the PLT sequence.  See the Solaris
++# Linker and Libraries Guide, section SPARC: Procedure Linkage Table.
++# <https://docs.oracle.com/cd/E19455-01/816-0559/chapter6-1236/index.html>
++test-xfail-check-wx-segment = *
++
++endif # $(subdir) == elf
++
+ # The assembler on SPARC needs the -fPIC flag even when it's assembler code.
+ ASFLAGS-.os += -fPIC
+diff --git a/sysdeps/unix/sysv/linux/hppa/Makefile b/sysdeps/unix/sysv/linux/hppa/Makefile
+index e1637f54f508c007..c89ec8318208205d 100644
+--- a/sysdeps/unix/sysv/linux/hppa/Makefile
++++ b/sysdeps/unix/sysv/linux/hppa/Makefile
+@@ -3,9 +3,14 @@ ifeq ($(subdir),stdlib)
+ gen-as-const-headers += ucontext_i.sym
+ endif
+ 
++ifeq ($(subdir),elf)
+ # Supporting non-executable stacks on HPPA requires changes to both
+ # the Linux kernel and glibc. The kernel currently needs an executable
+ # stack for syscall restarts and signal returns.
+-ifeq ($(subdir),elf)
+ test-xfail-check-execstack = yes
+-endif
++
++# On hppa, the PLT is executable because it contains an executable
++# trampoline used during lazy binding.
++test-xfail-check-wx-segment = *
++
++endif # $(subdir) == elf
diff --git a/SOURCES/glibc-rh1810223-2.patch b/SOURCES/glibc-rh1810223-2.patch
new file mode 100644
index 0000000..4bee60f
--- /dev/null
+++ b/SOURCES/glibc-rh1810223-2.patch
@@ -0,0 +1,49 @@
+commit 279c68ce1336d84d82ce491a4b77086e574ba380
+Author: DJ Delorie <dj@redhat.com>
+Date:   Mon Feb 3 14:57:23 2020 -0500
+
+    Run nptl/tst-pthread-getattr in a container
+    
+    See https://bugzilla.redhat.com/show_bug.cgi?id=1653942
+    
+    This test depends on the kernel's assignment of memory regions, but
+    running under ld.so explicitly changes those assignments, sometimes
+    sufficiently to cause the test to fail (esp with address space
+    randomization).
+    
+    The easiest way to "fix" the test, is to run it the way the user would
+    - without ld.so.  Running it in a container does that.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/nptl/Makefile b/nptl/Makefile
+index b1003cf56b31ddfa..071c53866d14d2fe 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -293,7 +293,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
+ 	tst-exec1 tst-exec2 tst-exec3 tst-exec4 tst-exec5 \
+ 	tst-exit1 tst-exit2 tst-exit3 \
+ 	tst-stdio1 tst-stdio2 \
+-	tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \
++	tst-stack1 tst-stack2 tst-stack3 tst-stack4 \
+ 	tst-pthread-attr-affinity tst-pthread-mutexattr \
+ 	tst-unload \
+ 	tst-dlsym1 \
+@@ -322,6 +322,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
+ 	tst-rwlock-pwn \
+ 	tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall
+ 
++tests-container =  tst-pthread-getattr
++
+ tests-internal := tst-rwlock19 tst-rwlock20 \
+ 		  tst-sem11 tst-sem12 tst-sem13 \
+ 		  tst-barrier5 tst-signal7 tst-mutex8 tst-mutex8-static \
+@@ -633,7 +635,7 @@ ifeq ($(build-shared),yes)
+ $(addprefix $(objpfx), \
+   $(filter-out $(tests-static) $(xtests-static) $(tests-reverse) \
+     $(tests-nolibpthread), \
+-    $(tests) $(tests-internal) $(xtests) $(test-srcs))): \
++    $(tests) $(tests-internal) $(xtests) $(test-srcs) $(tests-container))): \
+ 	$(objpfx)libpthread.so
+ $(objpfx)tst-unload: $(libdl)
+ # $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
diff --git a/SOURCES/glibc-rh1810224-1.patch b/SOURCES/glibc-rh1810224-1.patch
new file mode 100644
index 0000000..a4b671a
--- /dev/null
+++ b/SOURCES/glibc-rh1810224-1.patch
@@ -0,0 +1,28 @@
+commit a331150af65477fc3fa72ab341eed5e0b2daf7f3
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Thu Nov 28 20:32:09 2019 +0000
+
+    Update syscall-names.list for Linux 5.4.
+
+    This patch updates syscall-names.list for Linux 5.4.  There are no new
+    syscalls, so this is just a matter of updating the version number
+    listed in the file.
+
+    Tested with build-many-glibcs.py.
+
+Reworked for RHEL 8.3.0.
+
+diff -Nrup a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+--- a/sysdeps/unix/sysv/linux/syscall-names.list	2020-04-05 20:20:41.471686371 -0400
++++ b/sysdeps/unix/sysv/linux/syscall-names.list	2020-04-05 20:21:56.871912297 -0400
+@@ -22,8 +22,8 @@
+ # names are only used if the installed kernel headers also provide
+ # them.
+ 
+-# The list of system calls is current as of Linux 5.3.
+-kernel 5.3
++# The list of system calls is current as of Linux 5.4.
++kernel 5.4
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
diff --git a/SOURCES/glibc-rh1810224-2.patch b/SOURCES/glibc-rh1810224-2.patch
new file mode 100644
index 0000000..df51b1d
--- /dev/null
+++ b/SOURCES/glibc-rh1810224-2.patch
@@ -0,0 +1,29 @@
+commit 5828bc4523230685ac29a4a882967913255f5666
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Fri Feb 7 13:54:58 2020 +0000
+
+    Update syscall lists for Linux 5.5.
+
+    Linux 5.5 has no new syscalls to add to syscall-names.list, but it
+    does newly enable the clone3 syscall for AArch64.  This patch updates
+    the kernel version listed in syscall-names.list and regenerates the
+    AArch64 arch-syscall.h.
+
+    Tested with build-many-glibcs.py.
+
+Modified to only update syscall-names.list for RHEL 8.3.0.
+
+diff -Nrup a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+--- a/sysdeps/unix/sysv/linux/syscall-names.list	2020-04-06 12:10:47.683272882 -0400
++++ b/sysdeps/unix/sysv/linux/syscall-names.list	2020-04-06 12:12:41.769598687 -0400
+@@ -22,8 +22,8 @@
+ # names are only used if the installed kernel headers also provide
+ # them.
+ 
+-# The list of system calls is current as of Linux 5.4.
+-kernel 5.4
++# The list of system calls is current as of Linux 5.5.
++kernel 5.5
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
diff --git a/SOURCES/glibc-rh1810224-3.patch b/SOURCES/glibc-rh1810224-3.patch
new file mode 100644
index 0000000..2293e42
--- /dev/null
+++ b/SOURCES/glibc-rh1810224-3.patch
@@ -0,0 +1,26 @@
+commit 6cf6a91d05d626698f158078961b3bffcb39ff8c
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Wed Feb 12 13:37:16 2020 +0000
+
+    Rename RWF_WRITE_LIFE_NOT_SET to RWH_WRITE_LIFE_NOT_SET following Linux 5.5.
+    
+    Linux 5.5 renames RWF_WRITE_LIFE_NOT_SET to RWH_WRITE_LIFE_NOT_SET,
+    with the old name kept as an alias.  This patch makes the
+    corresponding change in glibc.
+    
+    Tested for x86_64.
+
+diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
+index 07a889d683..b06488a847 100644
+--- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
++++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
+@@ -290,7 +290,8 @@ struct f_owner_ex
+ 
+ #ifdef __USE_GNU
+ /* Hint values for F_{GET,SET}_RW_HINT.  */
+-# define RWF_WRITE_LIFE_NOT_SET	0
++# define RWH_WRITE_LIFE_NOT_SET	0
++# define RWF_WRITE_LIFE_NOT_SET	RWH_WRITE_LIFE_NOT_SET
+ # define RWH_WRITE_LIFE_NONE	1
+ # define RWH_WRITE_LIFE_SHORT	2
+ # define RWH_WRITE_LIFE_MEDIUM	3
diff --git a/SOURCES/glibc-rh1810224-4.patch b/SOURCES/glibc-rh1810224-4.patch
new file mode 100644
index 0000000..c1205a1
--- /dev/null
+++ b/SOURCES/glibc-rh1810224-4.patch
@@ -0,0 +1,54 @@
+commit e788beaf093bfafecd6b4456b984bd927c18987a
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Fri Apr 3 18:07:55 2020 +0000
+
+    Update syscall lists for Linux 5.6.
+
+    Linux 5.6 has new openat2 and pidfd_getfd syscalls.  This patch adds
+    them to syscall-names.list and regenerates the arch-syscall.h files.
+
+    Tested with build-many-glibcs.py.
+
+Modified to only update syscall-names.list for RHEL 8.3.0.
+Also cleaned up typos in the comments.
+
+diff -Nrup a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+--- a/sysdeps/unix/sysv/linux/syscall-names.list	2020-04-06 12:27:10.519027866 -0400
++++ b/sysdeps/unix/sysv/linux/syscall-names.list	2020-04-06 12:31:53.665812810 -0400
+@@ -16,14 +16,13 @@
+ # License along with the GNU C Library; if not, see
+ # <http://www.gnu.org/licenses/>.
+ 
+-# This file contains the list of system call names names.  It has to
+-# remain in alphabetica order.  Lines which start with # are treated
+-# as comments.  This file can list all potential system calls.  The
+-# names are only used if the installed kernel headers also provide
+-# them.
++# This file contains the list of system call names.  It has to remain in
++# alphabetical order.  Lines which start with # are treated as comments.
++# This file can list all potential system calls.  The names are only
++# used if the installed kernel headers also provide them.
+ 
+-# The list of system calls is current as of Linux 5.5.
+-kernel 5.5
++# The list of system calls is current as of Linux 5.6.
++kernel 5.6
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
+@@ -293,6 +292,7 @@ open
+ open_by_handle_at
+ open_tree
+ openat
++openat2
+ osf_adjtime
+ osf_afs_syscall
+ osf_alt_plock
+@@ -411,6 +411,7 @@ perf_event_open
+ perfctr
+ perfmonctl
+ personality
++pidfd_getfd
+ pidfd_open
+ pidfd_send_signal
+ pipe
diff --git a/SOURCES/glibc-rh1811796-1.patch b/SOURCES/glibc-rh1811796-1.patch
new file mode 100644
index 0000000..a7b711d
--- /dev/null
+++ b/SOURCES/glibc-rh1811796-1.patch
@@ -0,0 +1,113 @@
+commit 9333498794cde1d5cca518badf79533a24114b6f
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Wed Feb 12 23:31:56 2020 +0000
+
+    Avoid ldbl-96 stack corruption from range reduction of pseudo-zero (bug 25487).
+
+    Bug 25487 reports stack corruption in ldbl-96 sinl on a pseudo-zero
+    argument (an representation where all the significand bits, including
+    the explicit high bit, are zero, but the exponent is not zero, which
+    is not a valid representation for the long double type).
+
+    Although this is not a valid long double representation, existing
+    practice in this area (see bug 4586, originally marked invalid but
+    subsequently fixed) is that we still seek to avoid invalid memory
+    accesses as a result, in case of programs that treat arbitrary binary
+    data as long double representations, although the invalid
+    representations of the ldbl-96 format do not need to be consistently
+    handled the same as any particular valid representation.
+
+    This patch makes the range reduction detect pseudo-zero and unnormal
+    representations that would otherwise go to __kernel_rem_pio2, and
+    returns a NaN for them instead of continuing with the range reduction
+    process.  (Pseudo-zero and unnormal representations whose unbiased
+    exponent is less than -1 have already been safely returned from the
+    function before this point without going through the rest of range
+    reduction.)  Pseudo-zero representations would previously result in
+    the value passed to __kernel_rem_pio2 being all-zero, which is
+    definitely unsafe; unnormal representations would previously result in
+    a value passed whose high bit is zero, which might well be unsafe
+    since that is not a form of input expected by __kernel_rem_pio2.
+
+    Tested for x86_64.
+
+Revised for RHEL 8.3.0.
+
+diff -Nrup a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c
+--- a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c	2018-08-01 01:10:47.000000000 -0400
++++ b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c	2020-04-03 13:05:02.609844427 -0400
+@@ -209,6 +209,18 @@ __ieee754_rem_pio2l (long double x, long
+       y[1] = y[0];
+       return 0;
+     }
++  
++  if ((i0 & 0x80000000) == 0)
++    {
++      /* Pseudo-zero and unnormal representations are not valid
++        representations of long double.  We need to avoid stack
++        corruption in __kernel_rem_pio2, which expects input in a
++        particular normal form, but those representations do not need
++        to be consistently handled like any particular floating-point
++        value.  */
++      y[1] = y[0] = __builtin_nanl ("");
++      return 0;
++    }
+ 
+   /* Split the 64 bits of the mantissa into three 24-bit integers
+      stored in a double array.  */
+diff -Nrup a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile
+--- a/sysdeps/ieee754/ldbl-96/Makefile	2018-08-01 01:10:47.000000000 -0400
++++ b/sysdeps/ieee754/ldbl-96/Makefile	2020-04-03 13:03:20.233546734 -0400
+@@ -17,5 +17,6 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ ifeq ($(subdir),math)
+-tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96
++tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo
++CFLAGS-test-sinl-pseudo.c += -fstack-protector-all
+ endif
+diff -Nrup a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c
+--- a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c	1969-12-31 19:00:00.000000000 -0500
++++ b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c	2020-04-03 13:05:37.857952212 -0400
+@@ -0,0 +1,41 @@
++/* Test sinl for pseudo-zeros and unnormals for ldbl-96 (bug 25487).
++   Copyright (C) 2020 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 <math.h>
++#include <math_ldbl.h>
++#include <stdint.h>
++
++static int
++do_test (void)
++{
++  for (int i = 0; i < 64; i++)
++    {
++      uint64_t sig = i == 63 ? 0 : 1ULL << i;
++      long double ld;
++      SET_LDOUBLE_WORDS (ld, 0x4141,
++                        sig >> 32, sig & 0xffffffffULL);
++      /* The requirement is that no stack overflow occurs when the
++        pseudo-zero or unnormal goes through range reduction.  */
++      volatile long double ldr;
++      ldr = sinl (ld);
++      (void) ldr;
++    }
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1811796-2.patch b/SOURCES/glibc-rh1811796-2.patch
new file mode 100644
index 0000000..eae8269
--- /dev/null
+++ b/SOURCES/glibc-rh1811796-2.patch
@@ -0,0 +1,21 @@
+commit c10acd40262486dac597001aecc20ad9d3bd0e4a
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Feb 13 17:01:15 2020 +0100
+
+    math/test-sinl-pseudo: Use stack protector only if available
+    
+    This fixes commit 9333498794cde1d5cca518bad ("Avoid ldbl-96 stack
+    corruption from range reduction of pseudo-zero (bug 25487).").
+
+diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile
+index 318628aed6..6030adf7e7 100644
+--- a/sysdeps/ieee754/ldbl-96/Makefile
++++ b/sysdeps/ieee754/ldbl-96/Makefile
+@@ -18,5 +18,7 @@
+ 
+ ifeq ($(subdir),math)
+ tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo
++ifeq ($(have-ssp),yes)
+ CFLAGS-test-sinl-pseudo.c += -fstack-protector-all
+ endif
++endif # $(subdir) == math
diff --git a/SOURCES/glibc-rh1812756-1.patch b/SOURCES/glibc-rh1812756-1.patch
new file mode 100644
index 0000000..7675c1c
--- /dev/null
+++ b/SOURCES/glibc-rh1812756-1.patch
@@ -0,0 +1,517 @@
+commit eb447b7b4bd6177f876ba9420ad9e048c27bae91
+Author: David Kilroy <David.Kilroy@arm.com>
+Date:   Wed Feb 12 14:28:15 2020 -0300
+
+    elf: Allow dlopen of filter object to work [BZ #16272]
+    
+    There are two fixes that are needed to be able to dlopen filter
+    objects. First _dl_map_object_deps cannot assume that map will be at
+    the beginning of l_searchlist.r_list[], as filtees are inserted before
+    map. Secondly dl_open_worker needs to ensure that filtees get
+    relocated.
+    
+    In _dl_map_object_deps:
+    
+    * avoiding removing relocation dependencies of map by setting
+      l_reserved to 0 and otherwise processing the rest of the search
+      list.
+    
+    * ensure that map remains at the beginning of l_initfini - the list
+      of things that need initialisation (and destruction). Do this by
+      splitting the copy up. This may not be required, but matches the
+      initialization order without dlopen.
+    
+    Modify dl_open_worker to relocate the objects in new->l_inifini.
+    new->l_initfini is constructed in _dl_map_object_deps, and lists the
+    objects that need initialization and destruction. Originally the list
+    of objects in new->l_next are relocated. All of these objects should
+    also be included in new->l_initfini (both lists are populated with
+    dependencies in _dl_map_object_deps). We can't use new->l_prev to pick
+    up filtees, as during a recursive dlopen from an interposed malloc
+    call, l->prev can contain objects that are not ready for relocation.
+    
+    Add tests to verify that symbols resolve to the filtee implementation
+    when auxiliary and filter objects are used, both as a normal link and
+    when dlopen'd.
+    
+    Tested by running the testsuite on x86_64.
+
+# Conflicts:
+#	elf/Makefile
+
+diff --git a/elf/Makefile b/elf/Makefile
+index a52d9b1f6a4364a7..b4b618ce62a9e6df 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -192,7 +192,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
+ 	 tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
+ 	 tst-sonamemove-link tst-sonamemove-dlopen tst-initfinilazyfail \
+-	 tst-dlopenfail tst-dlopenfail-2
++	 tst-dlopenfail tst-dlopenfail-2 \
++	 tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen
+ #	 reldep9
+ tests-internal += loadtest unload unload2 circleload1 \
+ 	 neededtest neededtest2 neededtest3 neededtest4 \
+@@ -302,7 +303,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		tst-sonamemove-runmod1 tst-sonamemove-runmod2 \
+ 		tst-initlazyfailmod tst-finilazyfailmod \
+ 		tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \
+-		tst-dlopenfailmod3
++		tst-dlopenfailmod3 \
++		tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee
+ 
+ ifeq (yes,$(have-mtls-dialect-gnu2))
+ tests += tst-gnu2-tls1
+@@ -1626,3 +1628,15 @@ $(objpfx)tst-dlopen-nodelete-reloc-mod17.so: \
+   $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \
+   $(objpfx)tst-dlopen-nodelete-reloc-mod16.so
+ LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed
++
++LDFLAGS-tst-filterobj-flt.so = -Wl,--filter=$(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-filterobj: $(objpfx)tst-filterobj-flt.so
++$(objpfx)tst-filterobj-dlopen: $(libdl)
++$(objpfx)tst-filterobj.out: $(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-filterobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so
++
++LDFLAGS-tst-filterobj-aux.so = -Wl,--auxiliary=$(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-auxobj: $(objpfx)tst-filterobj-aux.so
++$(objpfx)tst-auxobj-dlopen: $(libdl)
++$(objpfx)tst-auxobj.out: $(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-auxobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so
+diff --git a/elf/dl-deps.c b/elf/dl-deps.c
+index 9d9b1ba7f244348a..50f053a1586efdc3 100644
+--- a/elf/dl-deps.c
++++ b/elf/dl-deps.c
+@@ -485,14 +485,18 @@ _dl_map_object_deps (struct link_map *map,
+ 
+   map->l_searchlist.r_list = &l_initfini[nlist + 1];
+   map->l_searchlist.r_nlist = nlist;
++  unsigned int map_index = UINT_MAX;
+ 
+   for (nlist = 0, runp = known; runp; runp = runp->next)
+     {
+       if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
+ 	/* This can happen when we trace the loading.  */
+ 	--map->l_searchlist.r_nlist;
+-      else
++      else {
++	if (runp->map == map)
++	  map_index = nlist;
+ 	map->l_searchlist.r_list[nlist++] = runp->map;
++      }
+ 
+       /* Now clear all the mark bits we set in the objects on the search list
+ 	 to avoid duplicates, so the next call starts fresh.  */
+@@ -550,13 +554,14 @@ Filters not supported with LD_TRACE_PRELINKING"));
+     }
+ 
+   /* Maybe we can remove some relocation dependencies now.  */
+-  assert (map->l_searchlist.r_list[0] == map);
+   struct link_map_reldeps *l_reldeps = NULL;
+   if (map->l_reldeps != NULL)
+     {
+-      for (i = 1; i < nlist; ++i)
++      for (i = 0; i < nlist; ++i)
+ 	map->l_searchlist.r_list[i]->l_reserved = 1;
+ 
++      /* Avoid removing relocation dependencies of the main binary.  */
++      map->l_reserved = 0;
+       struct link_map **list = &map->l_reldeps->list[0];
+       for (i = 0; i < map->l_reldeps->act; ++i)
+ 	if (list[i]->l_reserved)
+@@ -581,16 +586,30 @@ Filters not supported with LD_TRACE_PRELINKING"));
+ 	      }
+ 	  }
+ 
+-      for (i = 1; i < nlist; ++i)
++      for (i = 0; i < nlist; ++i)
+ 	map->l_searchlist.r_list[i]->l_reserved = 0;
+     }
+ 
+-  /* Sort the initializer list to take dependencies into account.  The binary
+-     itself will always be initialize last.  */
+-  memcpy (l_initfini, map->l_searchlist.r_list,
+-	  nlist * sizeof (struct link_map *));
+-  /* We can skip looking for the binary itself which is at the front of
+-     the search list.  */
++  /* Sort the initializer list to take dependencies into account.  Always
++     initialize the binary itself last.  */
++  assert (map_index < nlist);
++  if (map_index > 0)
++    {
++      /* Copy the binary into position 0.  */
++      l_initfini[0] = map->l_searchlist.r_list[map_index];
++
++      /* Copy the filtees.  */
++      for (i = 0; i < map_index; ++i)
++	l_initfini[i+1] = map->l_searchlist.r_list[i];
++
++      /* Copy the remainder.  */
++      for (i = map_index + 1; i < nlist; ++i)
++	l_initfini[i] = map->l_searchlist.r_list[i];
++    }
++  else
++    memcpy (l_initfini, map->l_searchlist.r_list,
++	    nlist * sizeof (struct link_map *));
++
+   _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
+ 
+   /* Terminate the list of dependencies.  */
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index d834b89754d2b073..d31356f7e17dfb14 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -618,22 +618,25 @@ dl_open_worker (void *a)
+      allows IFUNC relocations to work and it also means copy
+      relocation of dependencies are if necessary overwritten.  */
+   unsigned int nmaps = 0;
+-  struct link_map *l = new;
++  unsigned int j = 0;
++  struct link_map *l = new->l_initfini[0];
+   do
+     {
+       if (! l->l_real->l_relocated)
+ 	++nmaps;
+-      l = l->l_next;
++      l = new->l_initfini[++j];
+     }
+   while (l != NULL);
++  /* Stack allocation is limited by the number of loaded objects.  */
+   struct link_map *maps[nmaps];
+   nmaps = 0;
+-  l = new;
++  j = 0;
++  l = new->l_initfini[0];
+   do
+     {
+       if (! l->l_real->l_relocated)
+ 	maps[nmaps++] = l;
+-      l = l->l_next;
++      l = new->l_initfini[++j];
+     }
+   while (l != NULL);
+   _dl_sort_maps (maps, nmaps, NULL, false);
+diff --git a/elf/tst-auxobj-dlopen.c b/elf/tst-auxobj-dlopen.c
+new file mode 100644
+index 0000000000000000..cb54aba19470a1fe
+--- /dev/null
++++ b/elf/tst-auxobj-dlopen.c
+@@ -0,0 +1,47 @@
++/* Test for BZ#16272, dlopen'ing an auxiliary filter object.
++   Ensure that symbols from the resolve correctly.
++
++   Copyright (C) 2020 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 <stdio.h>
++#include <support/check.h>
++#include <support/xdlfcn.h>
++
++static int do_test (void)
++{
++  void *lib = xdlopen ("tst-filterobj-aux.so", RTLD_LAZY);
++  char *(*fn)(void) = xdlsym (lib, "get_text");
++  const char* text = fn ();
++
++  printf ("%s\n", text);
++
++  /* Verify the text matches what we expect from the filtee */
++  TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++  fn = xdlsym (lib, "get_text2");
++  text = fn ();
++
++  printf ("%s\n", text);
++
++  /* Verify the text matches what we expect from the auxiliary object */
++  TEST_COMPARE_STRING (text, "Hello from auxiliary filter object (PASS)");
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-auxobj.c b/elf/tst-auxobj.c
+new file mode 100644
+index 0000000000000000..bdc7713b04b4a79b
+--- /dev/null
++++ b/elf/tst-auxobj.c
+@@ -0,0 +1,42 @@
++/* Test that symbols from auxiliary filter objects are resolved to the
++   filtee.
++
++   Copyright (C) 2020 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 <stdio.h>
++#include <support/check.h>
++#include "tst-filterobj-filtee.h"
++
++static int do_test (void)
++{
++  const char* text = get_text ();
++  printf ("%s\n", text);
++
++  /* Verify the text matches what we expect from the filtee */
++  TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++  text = get_text2 ();
++  printf ("%s\n", text);
++
++  /* Verify the text matches what we expect from the auxiliary object */
++  TEST_COMPARE_STRING (text, "Hello from auxiliary filter object (PASS)");
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-filterobj-aux.c b/elf/tst-filterobj-aux.c
+new file mode 100644
+index 0000000000000000..0b732f2fb3a69a7f
+--- /dev/null
++++ b/elf/tst-filterobj-aux.c
+@@ -0,0 +1,33 @@
++/* Auxiliary filter object.
++   Contains symbols to be resolved in filtee, and one which doesn't.
++
++   Copyright (C) 2020 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 "tst-filterobj-filtee.h"
++
++/* We never want to see the output of the auxiliary object.  */
++const char *get_text (void)
++{
++  return "Hello from auxiliary filter object (FAIL)";
++}
++
++/* The filtee doesn't implement this symbol, so this should resolve.  */
++const char *get_text2 (void)
++{
++  return "Hello from auxiliary filter object (PASS)";
++}
+diff --git a/elf/tst-filterobj-dlopen.c b/elf/tst-filterobj-dlopen.c
+new file mode 100644
+index 0000000000000000..c5b5072979802b98
+--- /dev/null
++++ b/elf/tst-filterobj-dlopen.c
+@@ -0,0 +1,39 @@
++/* Test for BZ#16272, dlopen'ing a filter object.
++   Ensure that symbols from the filter object resolve to the filtee.
++
++   Copyright (C) 2020 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 <stdio.h>
++#include <support/check.h>
++#include <support/xdlfcn.h>
++
++static int do_test (void)
++{
++  void *lib = xdlopen ("tst-filterobj-flt.so", RTLD_LAZY);
++  char *(*fn)(void) = xdlsym (lib, "get_text");
++  const char* text = fn ();
++
++  printf ("%s\n", text);
++
++  /* Verify the text matches what we expect from the filtee */
++  TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-filterobj-filtee.c b/elf/tst-filterobj-filtee.c
+new file mode 100644
+index 0000000000000000..8fa557cbd251f53c
+--- /dev/null
++++ b/elf/tst-filterobj-filtee.c
+@@ -0,0 +1,27 @@
++/* Filtee for BZ#16272 test.
++   Contains desired symbol implementations.
++
++   Copyright (C) 2020 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 "tst-filterobj-filtee.h"
++
++/* This is the real implementation that wants to be called */
++const char *get_text (void)
++{
++  return "Hello from filtee (PASS)";
++}
+diff --git a/elf/tst-filterobj-filtee.h b/elf/tst-filterobj-filtee.h
+new file mode 100644
+index 0000000000000000..46aee28178b88a77
+--- /dev/null
++++ b/elf/tst-filterobj-filtee.h
+@@ -0,0 +1,24 @@
++/* Filtee header for BZ#16272 test.
++   Contains prototypes for symbols implemented in the filtee.
++
++   Copyright (C) 2020 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/>.  */
++
++const char *get_text (void);
++
++/* For testing auxiliary filter object.  */
++const char *get_text2 (void);
+diff --git a/elf/tst-filterobj-flt.c b/elf/tst-filterobj-flt.c
+new file mode 100644
+index 0000000000000000..5062654be6f14a80
+--- /dev/null
++++ b/elf/tst-filterobj-flt.c
+@@ -0,0 +1,27 @@
++/* Filter object for BZ#16272 test.
++   Contains symbols to be resolved in filtee.
++
++   Copyright (C) 2020 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 "tst-filterobj-filtee.h"
++
++/* We never want to see the output of the filter object */
++const char *get_text (void)
++{
++  return "Hello from filter object (FAIL)";
++}
+diff --git a/elf/tst-filterobj.c b/elf/tst-filterobj.c
+new file mode 100644
+index 0000000000000000..96bfae019ea670bc
+--- /dev/null
++++ b/elf/tst-filterobj.c
+@@ -0,0 +1,36 @@
++/* Test that symbols from filter objects are resolved to the filtee.
++
++   Copyright (C) 2020 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 <stdio.h>
++#include <support/check.h>
++#include "tst-filterobj-filtee.h"
++
++static int do_test (void)
++{
++  const char* text = get_text ();
++
++  printf ("%s\n", text);
++
++  /* Verify the text matches what we expect from the filtee */
++  TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1812756-2.patch b/SOURCES/glibc-rh1812756-2.patch
new file mode 100644
index 0000000..e2df4e4
--- /dev/null
+++ b/SOURCES/glibc-rh1812756-2.patch
@@ -0,0 +1,37 @@
+commit 71bcfa62451dfaa015326d3524f2a0e2d09d80ed
+Author: David Kilroy <David.Kilroy@arm.com>
+Date:   Wed Feb 12 14:30:31 2020 -0300
+
+    elf: avoid redundant sort in dlopen
+    
+    l_initfini is already sorted by dependency in _dl_map_object_deps(),
+    so avoid sorting again in dl_open_worker().
+    
+    Tested by running the testsuite on x86_64.
+
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index d31356f7e17dfb14..980a28c836ca9a7a 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -614,9 +614,10 @@ dl_open_worker (void *a)
+   if (GLRO(dl_lazy))
+     reloc_mode |= mode & RTLD_LAZY;
+ 
+-  /* Sort the objects by dependency for the relocation process.  This
+-     allows IFUNC relocations to work and it also means copy
+-     relocation of dependencies are if necessary overwritten.  */
++  /* Objects must be sorted by dependency for the relocation process.
++     This allows IFUNC relocations to work and it also means copy
++     relocation of dependencies are if necessary overwritten.
++     __dl_map_object_deps has already sorted l_initfini for us.  */
+   unsigned int nmaps = 0;
+   unsigned int j = 0;
+   struct link_map *l = new->l_initfini[0];
+@@ -639,7 +640,6 @@ dl_open_worker (void *a)
+       l = new->l_initfini[++j];
+     }
+   while (l != NULL);
+-  _dl_sort_maps (maps, nmaps, NULL, false);
+ 
+   int relocation_in_progress = 0;
+ 
diff --git a/SOURCES/glibc-rh1812756-3.patch b/SOURCES/glibc-rh1812756-3.patch
new file mode 100644
index 0000000..93e54e2
--- /dev/null
+++ b/SOURCES/glibc-rh1812756-3.patch
@@ -0,0 +1,68 @@
+commit 0a8ce6a0966283b17f373f430929bcadef1ae205
+Author: David Kilroy <David.Kilroy@arm.com>
+Date:   Wed Feb 12 14:31:17 2020 -0300
+
+    elf: avoid stack allocation in dl_open_worker
+    
+    As the sort was removed, there's no need to keep a separate map of
+    links. Instead, when relocating objects iterate over l_initfini
+    directly.
+    
+    This allows us to remove the loop copying l_initfini elements into
+    map. We still need a loop to identify the first and last elements that
+    need relocation.
+    
+    Tested by running the testsuite on x86_64.
+
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index 980a28c836ca9a7a..46a4c1e5a3f8d2dd 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -618,25 +618,18 @@ dl_open_worker (void *a)
+      This allows IFUNC relocations to work and it also means copy
+      relocation of dependencies are if necessary overwritten.
+      __dl_map_object_deps has already sorted l_initfini for us.  */
+-  unsigned int nmaps = 0;
++  unsigned int first = UINT_MAX;
++  unsigned int last = 0;
+   unsigned int j = 0;
+   struct link_map *l = new->l_initfini[0];
+   do
+     {
+       if (! l->l_real->l_relocated)
+-	++nmaps;
+-      l = new->l_initfini[++j];
+-    }
+-  while (l != NULL);
+-  /* Stack allocation is limited by the number of loaded objects.  */
+-  struct link_map *maps[nmaps];
+-  nmaps = 0;
+-  j = 0;
+-  l = new->l_initfini[0];
+-  do
+-    {
+-      if (! l->l_real->l_relocated)
+-	maps[nmaps++] = l;
++	{
++	  if (first == UINT_MAX)
++	    first = j;
++	  last = j + 1;
++	}
+       l = new->l_initfini[++j];
+     }
+   while (l != NULL);
+@@ -651,9 +644,12 @@ dl_open_worker (void *a)
+      them.  However, such relocation dependencies in IFUNC resolvers
+      are undefined anyway, so this is not a problem.  */
+ 
+-  for (unsigned int i = nmaps; i-- > 0; )
++  for (unsigned int i = last; i-- > first; )
+     {
+-      l = maps[i];
++      l = new->l_initfini[i];
++
++      if (l->l_real->l_relocated)
++	continue;
+ 
+       if (! relocation_in_progress)
+ 	{
diff --git a/SOURCES/glibc-rh1813398.patch b/SOURCES/glibc-rh1813398.patch
new file mode 100644
index 0000000..1355dfa
--- /dev/null
+++ b/SOURCES/glibc-rh1813398.patch
@@ -0,0 +1,58 @@
+commit ddc650e9b3dc916eab417ce9f79e67337b05035c
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Wed Feb 19 17:21:46 2020 +0100
+
+    Fix use-after-free in glob when expanding ~user (bug 25414)
+    
+    The value of `end_name' points into the value of `dirname', thus don't
+    deallocate the latter before the last use of the former.
+
+diff --git a/posix/glob.c b/posix/glob.c
+index cba9cd1819..4580cefb9f 100644
+--- a/posix/glob.c
++++ b/posix/glob.c
+@@ -827,31 +827,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
+ 	      {
+ 		size_t home_len = strlen (p->pw_dir);
+ 		size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
+-		char *d;
++		char *d, *newp;
++		bool use_alloca = glob_use_alloca (alloca_used,
++						   home_len + rest_len + 1);
+ 
+-		if (__glibc_unlikely (malloc_dirname))
+-		  free (dirname);
+-		malloc_dirname = 0;
+-
+-		if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
+-		  dirname = alloca_account (home_len + rest_len + 1,
+-					    alloca_used);
++		if (use_alloca)
++		  newp = alloca_account (home_len + rest_len + 1, alloca_used);
+ 		else
+ 		  {
+-		    dirname = malloc (home_len + rest_len + 1);
+-		    if (dirname == NULL)
++		    newp = malloc (home_len + rest_len + 1);
++		    if (newp == NULL)
+ 		      {
+ 			scratch_buffer_free (&pwtmpbuf);
+ 			retval = GLOB_NOSPACE;
+ 			goto out;
+ 		      }
+-		    malloc_dirname = 1;
+ 		  }
+-		d = mempcpy (dirname, p->pw_dir, home_len);
++		d = mempcpy (newp, p->pw_dir, home_len);
+ 		if (end_name != NULL)
+ 		  d = mempcpy (d, end_name, rest_len);
+ 		*d = '\0';
+ 
++		if (__glibc_unlikely (malloc_dirname))
++		  free (dirname);
++		dirname = newp;
++		malloc_dirname = !use_alloca;
++
+ 		dirlen = home_len + rest_len;
+ 		dirname_modified = 1;
+ 	      }
diff --git a/SOURCES/glibc-rh1813399.patch b/SOURCES/glibc-rh1813399.patch
new file mode 100644
index 0000000..16ef72d
--- /dev/null
+++ b/SOURCES/glibc-rh1813399.patch
@@ -0,0 +1,59 @@
+commit d93769405996dfc11d216ddbe415946617b5a494
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Mon Jan 20 17:01:50 2020 +0100
+
+    Fix array overflow in backtrace on PowerPC (bug 25423)
+    
+    When unwinding through a signal frame the backtrace function on PowerPC
+    didn't check array bounds when storing the frame address.  Fixes commit
+    d400dcac5e ("PowerPC: fix backtrace to handle signal trampolines").
+
+diff --git a/debug/tst-backtrace5.c b/debug/tst-backtrace5.c
+index e7ce410845..b2f46160e7 100644
+--- a/debug/tst-backtrace5.c
++++ b/debug/tst-backtrace5.c
+@@ -89,6 +89,18 @@ handle_signal (int signum)
+       }
+   /* Symbol names are not available for static functions, so we do not
+      check do_test.  */
++
++  /* Check that backtrace does not return more than what fits in the array
++     (bug 25423).  */
++  for (int j = 0; j < NUM_FUNCTIONS; j++)
++    {
++      n = backtrace (addresses, j);
++      if (n > j)
++	{
++	  FAIL ();
++	  return;
++	}
++    }
+ }
+ 
+ NO_INLINE int
+diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c
+index 7c2d4726f8..d1456c8ae4 100644
+--- a/sysdeps/powerpc/powerpc32/backtrace.c
++++ b/sysdeps/powerpc/powerpc32/backtrace.c
+@@ -114,6 +114,8 @@ __backtrace (void **array, int size)
+         }
+       if (gregset)
+ 	{
++	  if (count + 1 == size)
++	    break;
+ 	  array[++count] = (void*)((*gregset)[PT_NIP]);
+ 	  current = (void*)((*gregset)[PT_R1]);
+ 	}
+diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c
+index 65c260ab76..8a53a1088f 100644
+--- a/sysdeps/powerpc/powerpc64/backtrace.c
++++ b/sysdeps/powerpc/powerpc64/backtrace.c
+@@ -87,6 +87,8 @@ __backtrace (void **array, int size)
+       if (is_sigtramp_address (current->return_address))
+         {
+ 	  struct signal_frame_64 *sigframe = (struct signal_frame_64*) current;
++	  if (count + 1 == size)
++	    break;
+           array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
+ 	  current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1];
+ 	}
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index d355d29..f9149e6 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -1,6 +1,6 @@
 %define glibcsrcdir glibc-2.28
 %define glibcversion 2.28
-%define glibcrelease 101%{?dist}
+%define glibcrelease 121%{?dist}
 # Pre-release tarballs are pulled in from git using a command that is
 # effectively:
 #
@@ -396,6 +396,84 @@ Patch262: glibc-rh1410154-13.patch
 Patch263: glibc-rh1410154-14.patch
 Patch264: glibc-rh1410154-15.patch
 Patch265: glibc-rh1410154-16.patch
+Patch266: glibc-rh1810142-1.patch
+Patch267: glibc-rh1810142-2.patch
+Patch268: glibc-rh1810142-3.patch
+Patch269: glibc-rh1810142-4.patch
+Patch270: glibc-rh1810142-5.patch
+Patch271: glibc-rh1810142-6.patch
+Patch272: glibc-rh1743445-1.patch
+Patch273: glibc-rh1743445-2.patch
+Patch274: glibc-rh1780204-01.patch
+Patch275: glibc-rh1780204-02.patch
+Patch276: glibc-rh1780204-03.patch
+Patch277: glibc-rh1780204-04.patch
+Patch278: glibc-rh1780204-05.patch
+Patch279: glibc-rh1780204-06.patch
+Patch280: glibc-rh1780204-07.patch
+Patch281: glibc-rh1780204-08.patch
+Patch282: glibc-rh1780204-09.patch
+Patch283: glibc-rh1780204-10.patch
+Patch284: glibc-rh1780204-11.patch
+Patch285: glibc-rh1780204-12.patch
+Patch286: glibc-rh1780204-13.patch
+Patch287: glibc-rh1780204-14.patch
+Patch288: glibc-rh1780204-15.patch
+Patch289: glibc-rh1780204-16.patch
+Patch290: glibc-rh1780204-17.patch
+Patch291: glibc-rh1780204-18.patch
+Patch292: glibc-rh1780204-19.patch
+Patch293: glibc-rh1780204-20.patch
+Patch294: glibc-rh1780204-21.patch
+Patch295: glibc-rh1780204-22.patch
+Patch296: glibc-rh1780204-23.patch
+Patch297: glibc-rh1780204-24.patch
+Patch298: glibc-rh1780204-25.patch
+Patch299: glibc-rh1780204-26.patch
+Patch300: glibc-rh1780204-27.patch
+Patch301: glibc-rh1780204-28.patch
+Patch302: glibc-rh1784519.patch
+Patch303: glibc-rh1775819.patch
+Patch304: glibc-rh1774114.patch
+Patch305: glibc-rh1812756-1.patch
+Patch306: glibc-rh1812756-2.patch
+Patch307: glibc-rh1812756-3.patch
+Patch308: glibc-rh1757354.patch
+Patch309: glibc-rh1784520.patch
+Patch310: glibc-rh1784525.patch
+Patch311: glibc-rh1810146.patch
+Patch312: glibc-rh1810223-1.patch
+Patch313: glibc-rh1810223-2.patch
+Patch314: glibc-rh1811796-1.patch
+Patch315: glibc-rh1811796-2.patch
+Patch316: glibc-rh1813398.patch
+Patch317: glibc-rh1813399.patch
+Patch318: glibc-rh1810224-1.patch
+Patch319: glibc-rh1810224-2.patch
+Patch320: glibc-rh1810224-3.patch
+Patch321: glibc-rh1810224-4.patch
+Patch322: glibc-rh1783303-1.patch
+Patch323: glibc-rh1783303-2.patch
+Patch324: glibc-rh1783303-3.patch
+Patch325: glibc-rh1783303-4.patch
+Patch326: glibc-rh1783303-5.patch
+Patch327: glibc-rh1783303-6.patch
+Patch328: glibc-rh1783303-7.patch
+Patch329: glibc-rh1783303-8.patch
+Patch330: glibc-rh1783303-9.patch
+Patch331: glibc-rh1783303-10.patch
+Patch332: glibc-rh1783303-11.patch
+Patch333: glibc-rh1783303-12.patch
+Patch334: glibc-rh1783303-13.patch
+Patch335: glibc-rh1783303-14.patch
+Patch336: glibc-rh1783303-15.patch
+Patch337: glibc-rh1783303-16.patch
+Patch338: glibc-rh1783303-17.patch
+Patch339: glibc-rh1783303-18.patch
+Patch340: glibc-rh1642150-1.patch
+Patch341: glibc-rh1642150-2.patch
+Patch342: glibc-rh1642150-3.patch
+Patch343: glibc-rh1774115.patch
 
 ##############################################################################
 # Continued list of core "glibc" package information:
@@ -412,6 +490,13 @@ Provides: bundled(gnulib)
 
 Requires(pre): basesystem
 
+%ifarch %{ix86}
+# Automatically install the 32-bit variant if the 64-bit variant has
+# been installed.  This covers the case when glibc.i686 is installed
+# after nss_db.x86_64.  (See below for the other ordering.)
+Recommends: (nss_db(x86-32) if nss_db(x86-64))
+%endif
+
 # This is for building auxiliary programs like memusage, nscd
 # For initial glibc bootstraps it can be commented out
 %if %{without bootstrap}
@@ -803,6 +888,12 @@ performance with LDAP, and may help with DNS as well.
 %package -n nss_db
 Summary: Name Service Switch (NSS) module using hash-indexed files
 Requires: %{name}%{_isa} = %{version}-%{release}
+%ifarch x86_64
+# Automatically install the 32-bit variant if the 64-bit variant has
+# been installed.  This covers the case when glibc.i686 is installed
+# before nss_db.x86_64.  (See above for the other ordering.)
+Recommends: (nss_db(x86-32) if glibc(x86-32))
+%endif
 
 %description -n nss_db
 The nss_db Name Service Switch module uses hash-indexed files in /var/db
@@ -2282,6 +2373,67 @@ fi
 %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
 
 %changelog
+* Wed Apr  8 2020 Florian Weimer <fweimer@redhat.com> - 2.28-121
+- elf: Assign TLS modid later during dlopen (#1774115)
+
+* Wed Apr  8 2020 Florian Weimer <fweimer@redhat.com> - 2.28-120
+- x86-64: Automatically install nss_db.i686 for 32-bit environments (#1807824)
+
+* Tue Apr  7 2020 Florian Weimer <fweimer@redhat.com> - 2.28-119
+- ppc64le: Enable protection key support (#1642150)
+
+* Tue Apr  7 2020 Florian Weimer <fweimer@redhat.com> - 2.28-118
+- ppc64le: floating-point status and exception optimizations (#1783303)
+
+* Fri Apr  3 2020 Patsy Griffin <patsy@redhat.com> - 2.28-117
+- Update to Linux 5.6 syscall-names.list. (#1810224)
+
+* Fri Apr  3 2020 Patsy Griffin <patsy@redhat.com> - 2.28-116
+- CVE-2020-1751: Fix an array overflow in backtrace on PowerPC. (#1813399)
+
+* Fri Apr  3 2020 Patsy Griffin <patsy@redhat.com> - 2.28-115
+- CVE:2020-1752: Fix a use after free in glob when expanding ~user. (#1813398)
+
+* Fri Apr  3 2020 Patsy Griffin <patsy@redhat.com> - 2.28-114
+- CVE-2020-10029: Prevent stack corruption from crafted input in cosl, sinl,
+  sincosl, and tanl function. (#1811796)
+
+* Thu Apr  2 2020 Carlos O'Donell <carlos@redhat.com> - 2.28-113
+- Improve elf/ and nptl/ testsuites (#1810223)
+
+* Thu Apr  2 2020 Carlos O'Donell <carlos@redhat.com> - 2.28-112
+- Fix resource leak in getaddrinfo (#1810146)
+
+* Thu Apr  2 2020 Carlos O'Donell <carlos@redhat.com> - 2.28-111
+- Protect locale archive against corruption (#1784525)
+
+* Thu Apr  2 2020 Carlos O'Donell <carlos@redhat.com> - 2.28-110
+- Properly handle signed vs. unsigned values in mallopt (#1784520)
+
+* Thu Apr  2 2020 Carlos O'Donell <carlos@redhat.com> - 2.28-109
+- Update and harmonize locale names with CLDR (#1757354)
+
+* Thu Apr  2 2020 Carlos O'Donell <carlos@redhat.com> - 2.28-108
+- Fix filter and auxiliary filter implementation (#1812756)
+
+* Thu Apr  2 2020 Carlos O'Donell <carlos@redhat.com> - 2.28-107
+- Handle .dynstr located in separate segment (#1774114)
+
+* Fri Mar 27 2020 Patsy Griffin <patsy@redhat.com> - 2.28-106
+- Disable vtable validation for pre-2.1 interposed handles (#1775819)
+
+* Fri Mar 27 2020 Patsy Griffin <patsy@redhat.com> - 2.28-105
+- Define __CORRECT_ISO_CPP_STRING_H_PROTO for Clang. (#1784519)
+
+* Wed Mar 25 2020 DJ Delorie <dj@redhat.com> - 2.28-104
+- Math library optimizations for IBM Z (#1780204)
+
+* Wed Mar 25 2020 DJ Delorie <dj@redhat.com> - 2.28-103
+- Filter "ignore" autofs mount entries in getmntent (#1743445)
+
+* Wed Mar 25 2020 DJ Delorie <dj@redhat.com> - 2.28-102
+- Fix /etc/resolv.conf reloading defects (#1810142)
+
 * Thu Jan 16 2020 Florian Weimer <fweimer@redhat.com> - 2.28-101
 - ld.so: Reset GL (dl_initfirst) pointer on dlopen failure (#1410154)