diff --git a/SOURCES/glibc-armhfp-ELF_MACHINE_NO_REL-undefined.patch b/SOURCES/glibc-armhfp-ELF_MACHINE_NO_REL-undefined.patch
deleted file mode 100644
index 78d7c4b..0000000
--- a/SOURCES/glibc-armhfp-ELF_MACHINE_NO_REL-undefined.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From patchwork Thu Jul  3 13:26:40 2014
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: ARM: Define ELF_MACHINE_NO_REL
-X-Patchwork-Submitter: Will Newton <will.newton@linaro.org>
-X-Patchwork-Id: 366862
-Message-Id: <1404394000-13429-1-git-send-email-will.newton@linaro.org>
-To: libc-alpha@sourceware.org
-Date: Thu,  3 Jul 2014 14:26:40 +0100
-From: Will Newton <will.newton@linaro.org>
-List-Id: <libc-alpha.sourceware.org>
-
-Fix a -Wundef warning on ARM.
-
-ChangeLog:
-
-2014-07-03  Will Newton  <will.newton@linaro.org>
-
-	* sysdeps/arm/dl-machine.h (ELF_MACHINE_NO_REL): Define.
----
- sysdeps/arm/dl-machine.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
-index c5ffc93..d6b0c52 100644
---- a/sysdeps/arm/dl-machine.h
-+++ b/sysdeps/arm/dl-machine.h
-@@ -296,6 +296,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
- /* ARM never uses Elf32_Rela relocations for the dynamic linker.
-    Prelinked libraries may use Elf32_Rela though.  */
- #define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
-+#define ELF_MACHINE_NO_REL 0
- 
- /* Names of the architecture-specific auditing callback functions.  */
- #define ARCH_LA_PLTENTER arm_gnu_pltenter
diff --git a/SOURCES/glibc-rh1039304-1.patch b/SOURCES/glibc-rh1039304-1.patch
new file mode 100644
index 0000000..f2bbe6e
--- /dev/null
+++ b/SOURCES/glibc-rh1039304-1.patch
@@ -0,0 +1,185 @@
+commit 5c1a69238fcb87ff7f916a5ce7960b2864afb3a1
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Sat Nov 11 11:23:40 2017 +0100
+
+    resolv: Add tst-res_hnok
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 988871086a70b291..b1fd2e2db8736f9b 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -50,6 +50,7 @@ tests += \
+   tst-ns_name \
+   tst-ns_name_compress \
+   tst-res_hconf_reorder \
++  tst-res_hnok \
+   tst-res_use_inet6 \
+   tst-resolv-basic \
+   tst-resolv-edns \
+@@ -182,6 +183,7 @@ $(objpfx)tst-resolv-canonname: \
+ $(objpfx)tst-ns_name: $(objpfx)libresolv.so
+ $(objpfx)tst-ns_name.out: tst-ns_name.data
+ $(objpfx)tst-ns_name_compress: $(objpfx)libresolv.so
++$(objpfx)tst-res_hnok: $(objpfx)libresolv.so
+ 
+ 
+ # This test case uses the deprecated RES_USE_INET6 resolver option.
+diff --git a/resolv/tst-res_hnok.c b/resolv/tst-res_hnok.c
+new file mode 100644
+index 0000000000000000..9c923038218e965c
+--- /dev/null
++++ b/resolv/tst-res_hnok.c
+@@ -0,0 +1,153 @@
++/* Tests for res_hnok and related functions.
++   Copyright (C) 2017 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 <resolv.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/test-driver.h>
++
++/* Bits which indicate which functions are supposed to report
++   success.  */
++enum
++  {
++    hnok = 1,
++    dnok = 2,
++    mailok = 4,
++    ownok = 8,
++    allnomailok = hnok | dnok | ownok,
++    allok = hnok | dnok | mailok | ownok
++  };
++
++/* A string of 60 characters.  */
++#define STRING60 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
++
++/* A string of 63 characters (maximum label length).  */
++#define STRING63 STRING60 "zzz"
++
++/* Combines a test name with the expected results.  */
++struct test_case
++{
++  const char *dn;
++  unsigned int result;          /* Combination of the *ok flags.  */
++};
++
++static const struct test_case tests[] =
++  {
++    { "", allok },
++    { ".", allok },
++    { "www", allnomailok },
++    { "example", allnomailok },
++    { "example.com", allok },
++    { "www.example.com", allok },
++    { "www.example.com.", allok },
++    { "*.example.com", dnok | mailok | ownok },
++    { "-v", dnok },
++    { "-v.example.com", mailok | dnok },
++    { "**.example.com", dnok | mailok },
++    { STRING63, allnomailok },
++    { STRING63 ".example.com", allok },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "z", allok },
++    { "hostmaster@mail.example.com", dnok | mailok },
++    { "with whitespace", 0 },
++    { "with\twhitespace", 0 },
++    { "with\nwhitespace", 0 },
++    { "with.whitespace ", 0 },
++    { "with.whitespace\t", 0 },
++    { "with.whitespace\n", 0 },
++    { "with\\ whitespace", 0 },
++    { "with\\\twhitespace", 0 },
++    { "with\\\nwhitespace", 0 },
++    { "with.whitespace\\ ", 0 },
++    { "with.whitespace\\\t", 0 },
++    { "with.whitespace\\\n", 0 },
++  };
++
++/* Run test case *TEST with FUNC (named FUNCNAME) and report an error
++   if the result does not match the result flag at BIT.  */
++static void
++one_test (const struct test_case *test, const char *funcname,
++          int (*func) (const char *), unsigned int bit)
++{
++  int expected = (test->result & bit) != 0;
++  int actual = func (test->dn);
++  if (actual != expected)
++    {
++      support_record_failure ();
++      printf ("error: %s (\"%s\"): expected=%d, actual=%d\n",
++              funcname, test->dn, expected, actual);
++    }
++}
++
++/* Run 255 tests using all the bytes from 1 to 255, surround the byte
++   with the strings PREFIX and SUFFIX, and check that FUNC (named
++   FUNCNAME) accepts only those bytes listed in ACCEPTED.  */
++static void
++one_char (const char *prefix, const char *accepted, const char *suffix,
++          const char *funcname, int (*func) (const char *))
++{
++  for (int ch = 1; ch <= 255; ++ch)
++    {
++      char dn[1024];
++      snprintf (dn, sizeof (dn), "%s%c%s", prefix, ch, suffix);
++      int expected = strchr (accepted, ch) != NULL;
++      int actual = func (dn);
++      if (actual != expected)
++        {
++          support_record_failure ();
++          printf ("error: %s (\"%s\"): expected=%d, actual=%d\n",
++                  funcname, dn, expected, actual);
++        }
++    }
++}
++
++static int
++do_test (void)
++{
++  for (const struct test_case *test = tests; test < array_end (tests); ++test)
++    {
++      if (test_verbose)
++        printf ("info: testing domain name [[[%s]]] (0x%x)\n",
++                test->dn, test->result);
++      one_test (test, "res_hnok", res_hnok, hnok);
++      one_test (test, "res_dnok", res_dnok, dnok);
++      one_test (test, "res_mailok", res_mailok, mailok);
++      one_test (test, "res_ownok", res_ownok, ownok);
++    }
++
++  one_char
++    ("", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.",
++     "", "res_hnok", res_hnok);
++  one_char
++    ("middle",
++     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
++     "suffix", "res_hnok", res_hnok);
++  one_char
++    ("middle",
++     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_"
++     "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~",
++     "suffix.example", "res_mailok", res_mailok);
++  one_char
++    ("mailbox.middle",
++     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
++     "suffix.example", "res_mailok", res_mailok);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1039304-2.patch b/SOURCES/glibc-rh1039304-2.patch
new file mode 100644
index 0000000..7bea4a3
--- /dev/null
+++ b/SOURCES/glibc-rh1039304-2.patch
@@ -0,0 +1,235 @@
+commit e2a9fca8101443076235a8dbcfceaa2d96bf4801
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Sat Nov 11 11:33:32 2017 +0100
+
+    resolv: Add tst-ns_name_pton
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index b1fd2e2db8736f9b..0130a09db2d69451 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -49,6 +49,7 @@ tests += \
+   tst-bug18665-tcp \
+   tst-ns_name \
+   tst-ns_name_compress \
++  tst-ns_name_pton \
+   tst-res_hconf_reorder \
+   tst-res_hnok \
+   tst-res_use_inet6 \
+@@ -183,6 +184,7 @@ $(objpfx)tst-resolv-canonname: \
+ $(objpfx)tst-ns_name: $(objpfx)libresolv.so
+ $(objpfx)tst-ns_name.out: tst-ns_name.data
+ $(objpfx)tst-ns_name_compress: $(objpfx)libresolv.so
++$(objpfx)tst-ns_name_pton: $(objpfx)libresolv.so
+ $(objpfx)tst-res_hnok: $(objpfx)libresolv.so
+ 
+ 
+diff --git a/resolv/tst-ns_name_pton.c b/resolv/tst-ns_name_pton.c
+new file mode 100644
+index 0000000000000000..879d97c9d3816210
+--- /dev/null
++++ b/resolv/tst-ns_name_pton.c
+@@ -0,0 +1,203 @@
++/* Tests for ns_name_pton.
++   Copyright (C) 2017 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <arpa/nameser.h>
++#include <array_length.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/test-driver.h>
++
++/* Bits which indicate which functions are supposed to report
++   success.  */
++enum
++  {
++    hnok = 1,
++    dnok = 2,
++    mailok = 4,
++    ownok = 8,
++    allnomailok = hnok | dnok | ownok,
++    allok = hnok | dnok | mailok | ownok
++  };
++
++/* A string of 60 characters.  */
++#define STRING60 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
++
++/* A string of 63 characters (maximum label length).  */
++#define STRING63 STRING60 "zzz"
++
++/* A string of 60 bytes (non-ASCII).  */
++#define STRING60OCT \
++  "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
++  "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
++  "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
++  "\377\377\377\377\377\377\377\377\377"
++
++/* A string of 63 bytes (non-ASCII).  */
++#define STRING63OCT STRING60OCT "\377\377\377"
++
++/* A string of 60 bytes (non-ASCII, quoted decimal).  */
++#define STRING60DEC \
++  "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
++  "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
++  "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
++  "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
++  "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
++  "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255"
++
++/* A string of 63 bytes (non-ASCII, quoted decimal).  */
++#define STRING63DEC STRING60DEC "\\255\\255\\255"
++
++/* Combines a test name with the expected results.  */
++struct test_case
++{
++  const char *dn;
++  const char *back; /* Expected test result converted using ns_name_ntop.  */
++  bool fully_qualified; /* True if the domain name has a trailing dot.  */
++};
++
++static const struct test_case tests[] =
++  {
++    { "", ".", false },
++    { ".", ".", true },
++    { "..", NULL, },
++    { "www", "www", false },
++    { "www.", "www", true },
++    { "www\\.", "www\\.", false },
++    { ".www", NULL, },
++    { ".www\\.", NULL, },
++    { "example.com", "example.com", false },
++    { "example.com.", "example.com", true },
++    { ".example.com", NULL, },
++    { ".example.com.", NULL, },
++    { "example\\.com", "example\\.com", false },
++    { "example\\.com.", "example\\.com", true },
++    { "example..", NULL, },
++    { "example..com", NULL, },
++    { "example..com", NULL, },
++    { "\\0", NULL, },
++    { "\\00", NULL, },
++    { "\\000", "\\000", false },
++    { "\\1", NULL, },
++    { "\\01", NULL, },
++    { "\\001", "\\001", false },
++    { "\\1x", NULL, },
++    { "\\01x", NULL, },
++    { "\\001x", "\\001x", false },
++    { "\\256", NULL, },
++    { "\\0641", "\\@1", false },
++    { "\\0011", "\\0011", false },
++    { STRING63, STRING63, false },
++    { STRING63 ".", STRING63, true },
++    { STRING63 "z", NULL, },
++    { STRING63 "\\.", NULL, },
++    { STRING60 "zz\\.", STRING60 "zz\\.", false },
++    { STRING60 "zz\\..", STRING60 "zz\\.", true },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "z",
++      STRING63 "." STRING63 "." STRING63 "." STRING60 "z", false },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "z.",
++      STRING63 "." STRING63 "." STRING63 "." STRING60 "z", true },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "zz", NULL, },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "zzz", NULL, },
++    { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT "\377",
++      STRING63DEC "." STRING63DEC "." STRING63DEC "." STRING60DEC "\\255",
++      false },
++    { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT "\377.",
++      STRING63DEC "." STRING63DEC "." STRING63DEC "." STRING60DEC "\\255",
++      true },
++    { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
++      "\377\377", NULL, },
++    { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
++      "\377\377\377", NULL, },
++  };
++
++static int
++do_test (void)
++{
++  unsigned char *wire = xmalloc (NS_MAXCDNAME);
++  char *text = xmalloc (NS_MAXDNAME);
++  for (const struct test_case *test = tests; test < array_end (tests); ++test)
++    {
++      if (test_verbose)
++        printf ("info: testing domain name [[[%s]]]\n", test->dn);
++      int ret = ns_name_pton (test->dn, wire, NS_MAXCDNAME);
++      if (ret == -1)
++        {
++          if (test->back != NULL)
++            {
++              support_record_failure ();
++              printf ("error: unexpected decoding failure for [[%s]]\n",
++                      test->dn);
++            }
++          /* Otherwise, we have an expected decoding failure.  */
++          continue;
++        }
++
++      if (ret < -1 || ret > 1)
++        {
++          support_record_failure ();
++          printf ("error: invalid return value %d for [[%s]]\n",
++                  ret, test->dn);
++          continue;
++        }
++
++      int ret2 = ns_name_ntop (wire, text, NS_MAXDNAME);
++
++      if (ret2 < 0)
++        {
++          support_record_failure ();
++          printf ("error: failure to convert back [[%s]]\n", test->dn);
++        }
++
++      if (test->back == NULL)
++        {
++          support_record_failure ();
++          printf ("error: unexpected success converting [[%s]]\n", test->dn);
++          if (ret2 >= 1)
++            printf ("error:   result converts back to [[%s]]\n", test->dn);
++          continue;
++        }
++
++      if (strcmp (text, test->back) != 0)
++        {
++          support_record_failure ();
++          printf ("error: back-conversion of [[%s]] did not match\n",
++                  test->dn);
++          printf ("error:   expected: [[%s]]\n", test->back);
++          printf ("error:     actual: [[%s]]\n", text);
++        }
++
++      if (ret != test->fully_qualified)
++        {
++          support_record_failure ();
++          printf ("error: invalid fully-qualified status for [[%s]]\n",
++                  test->dn);
++          printf ("error:   expected: %d\n", (int) test->fully_qualified);
++          printf ("error:     actual: %d\n", ret);
++        }
++    }
++
++  free (text);
++  free (wire);
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1039304-3.patch b/SOURCES/glibc-rh1039304-3.patch
new file mode 100644
index 0000000..d39d4d2
--- /dev/null
+++ b/SOURCES/glibc-rh1039304-3.patch
@@ -0,0 +1,40 @@
+commit 9e0ad3049dbae88d615bfb038e53bf365a39a634
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Sat Nov 11 11:41:45 2017 +0100
+
+    resolv: ns_name_pton should report trailing \ as error [BZ #22413]
+
+diff --git a/resolv/ns_name.c b/resolv/ns_name.c
+index 08a75e2fe0b4edd6..73213fee2dca530b 100644
+--- a/resolv/ns_name.c
++++ b/resolv/ns_name.c
+@@ -222,6 +222,11 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
+ 		}
+ 		*bp++ = (u_char)c;
+ 	}
++	if (escaped) {
++		/* Trailing backslash.  */
++		__set_errno (EMSGSIZE);
++		return -1;
++	}
+ 	c = (bp - label - 1);
+ 	if ((c & NS_CMPRSFLGS) != 0) {		/*%< Label too big. */
+ 		__set_errno (EMSGSIZE);
+diff --git a/resolv/tst-ns_name_pton.c b/resolv/tst-ns_name_pton.c
+index 879d97c9d3816210..73bdb05e08e405dc 100644
+--- a/resolv/tst-ns_name_pton.c
++++ b/resolv/tst-ns_name_pton.c
+@@ -127,6 +127,13 @@ static const struct test_case tests[] =
+       "\377\377", NULL, },
+     { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
+       "\377\377\377", NULL, },
++    { "\\", NULL, },
++    { "\\\\", "\\\\", false },
++    { "\\\\.", "\\\\", true },
++    { "\\\\\\", NULL, },
++    { "a\\", NULL, },
++    { "a.\\", NULL, },
++    { "a.b\\", NULL, },
+   };
+ 
+ static int
diff --git a/SOURCES/glibc-rh1039304-4.patch b/SOURCES/glibc-rh1039304-4.patch
new file mode 100644
index 0000000..e67eab1
--- /dev/null
+++ b/SOURCES/glibc-rh1039304-4.patch
@@ -0,0 +1,322 @@
+commit c0a25aa92b612786f4e45292c4aee1d7d47123f8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Sat Nov 11 11:51:08 2017 +0100
+
+    resolv: More precise checks in res_hnok, res_dnok [BZ #22409] [BZ #22412]
+    
+    res_hnok rejected some host names used on the Internet, such as
+    www-.example.com.  res_hnok and res_dnok failed to perform basic syntax
+    checking on DNS domain names.
+    
+    Also fix res_mailok, res_ownok.
+
+diff --git a/resolv/res_comp.c b/resolv/res_comp.c
+index ffb2ed59147d3680..79760e891f607daa 100644
+--- a/resolv/res_comp.c
++++ b/resolv/res_comp.c
+@@ -1,3 +1,21 @@
++/* Domain name processing functions.
++   Copyright (C) 1995-2017 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
+ /*
+  * Copyright (c) 1985, 1993
+  *    The Regents of the University of California.  All rights reserved.
+@@ -121,110 +139,118 @@ dn_skipname(const u_char *ptr, const u_char *eom) {
+ }
+ libresolv_hidden_def (dn_skipname)
+ 
+-/*
+- * Verify that a domain name uses an acceptable character set.
+- */
++/* Return true if the string consists of printable ASCII characters
++   only.  */
++static bool
++printable_string (const char *dn)
++{
++  while (true)
++    {
++      char ch = *dn;
++      if (ch == '\0')
++	return true;
++      if (ch <= ' ' || ch > '~')
++	return false;
++      ++dn;
++    }
++}
+ 
+-/*
+- * Note the conspicuous absence of ctype macros in these definitions.  On
+- * non-ASCII hosts, we can't depend on string literals or ctype macros to
+- * tell us anything about network-format data.  The rest of the BIND system
+- * is not careful about this, but for some reason, we're doing it right here.
+- */
+-#define PERIOD 0x2e
+-#define	hyphenchar(c) ((c) == 0x2d)
+-#define	underscorechar(c) ((c) == 0x5f)
+-#define bslashchar(c) ((c) == 0x5c)
+-#define periodchar(c) ((c) == PERIOD)
+-#define asterchar(c) ((c) == 0x2a)
+-#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
+-		   || ((c) >= 0x61 && (c) <= 0x7a))
+-#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+-
+-#define borderchar(c) (alphachar(c) || digitchar(c))
+-#define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c))
+-#define	domainchar(c) ((c) > 0x20 && (c) < 0x7f)
++/* Return true if DN points to a name consisting only of [0-9a-zA-Z_-]
++   characters.  DN must be in DNS wire format, without
++   compression.  */
++static bool
++binary_hnok (const unsigned char *dn)
++{
++  while (true)
++    {
++      size_t label_length = *dn;
++      if (label_length == 0)
++	break;
++      ++dn;
++      const unsigned char *label_end = dn + label_length;
++      do
++	{
++	  unsigned char ch = *dn;
++	  if (!(('0' <= ch && ch <= '9')
++		|| ('A' <= ch && ch <= 'Z')
++		|| ('a' <= ch && ch <= 'z')
++		|| ch == '-' || ch == '_'))
++	    return false;
++	  ++dn;
++	}
++      while (dn < label_end);
++    }
++  return true;
++}
++
++/* Return true if the binary domain name has a first labels which
++   starts with '-'.  */
++static inline bool
++binary_leading_dash (const unsigned char *dn)
++{
++  return dn[0] > 0 && dn[1] == '-';
++}
+ 
++/* Return 1 if res_hnok is a valid host name.  Labels must only
++   contain [0-9a-zA-Z_-] characters, and the name must not start with
++   a '-'.  The latter is to avoid confusion with program options.  */
+ int
+-res_hnok(const char *dn) {
+-	int pch = PERIOD, ch = *dn++;
+-
+-	while (ch != '\0') {
+-		int nch = *dn++;
+-
+-		if (periodchar(ch)) {
+-			(void)NULL;
+-		} else if (periodchar(pch)) {
+-			if (!borderchar(ch))
+-				return (0);
+-		} else if (periodchar(nch) || nch == '\0') {
+-			if (!borderchar(ch))
+-				return (0);
+-		} else {
+-			if (!middlechar(ch))
+-				return (0);
+-		}
+-		pch = ch, ch = nch;
+-	}
+-	return (1);
++res_hnok (const char *dn)
++{
++  unsigned char buf[NS_MAXCDNAME];
++  if (!printable_string (dn)
++      || ns_name_pton (dn, buf, sizeof (buf)) < 0
++      || binary_leading_dash (buf))
++    return 0;
++  return binary_hnok (buf);
+ }
+ libresolv_hidden_def (res_hnok)
+ 
+-/*
+- * hostname-like (A, MX, WKS) owners can have "*" as their first label
+- * but must otherwise be as a host name.
+- */
++/* Hostname-like (A, MX, WKS) owners can have "*" as their first label
++   but must otherwise be as a host name.  */
+ int
+-res_ownok(const char *dn) {
+-	if (asterchar(dn[0])) {
+-		if (periodchar(dn[1]))
+-			return (res_hnok(dn+2));
+-		if (dn[1] == '\0')
+-			return (1);
+-	}
+-	return (res_hnok(dn));
++res_ownok (const char *dn)
++{
++  unsigned char buf[NS_MAXCDNAME];
++  if (!printable_string (dn)
++      || ns_name_pton (dn, buf, sizeof (buf)) < 0
++      || binary_leading_dash (buf))
++    return 0;
++  if (buf[0] == 1 && buf [1] == '*')
++    /* Skip over the leading "*." part.  */
++    return binary_hnok (buf + 2);
++  else
++    return binary_hnok (buf);
+ }
+ 
+-/*
+- * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+- * label, but the rest of the name has to look like a host name.
+- */
++/* SOA RNAMEs and RP RNAMEs can have any byte in their first label,
++   but the rest of the name has to look like a host name.  */
+ int
+-res_mailok(const char *dn) {
+-	int ch, escaped = 0;
+-
+-	/* "." is a valid missing representation */
+-	if (*dn == '\0')
+-		return (1);
+-
+-	/* otherwise <label>.<hostname> */
+-	while ((ch = *dn++) != '\0') {
+-		if (!domainchar(ch))
+-			return (0);
+-		if (!escaped && periodchar(ch))
+-			break;
+-		if (escaped)
+-			escaped = 0;
+-		else if (bslashchar(ch))
+-			escaped = 1;
+-	}
+-	if (periodchar(ch))
+-		return (res_hnok(dn));
+-	return (0);
++res_mailok (const char *dn)
++{
++  unsigned char buf[NS_MAXCDNAME];
++  if (!printable_string (dn)
++      || ns_name_pton (dn, buf, sizeof (buf)) < 0)
++    return 0;
++  unsigned char label_length = buf[0];
++  /* "." is a valid missing representation */
++  if (label_length == 0)
++    return 1;
++  /* Skip over the first label.  */
++  unsigned char *tail = buf + 1 + label_length;
++  if (*tail == 0)
++    /* More than one label is required (except for ".").  */
++    return 0;
++  return binary_hnok (tail);
+ }
+ 
+-/*
+- * This function is quite liberal, since RFC 1034's character sets are only
+- * recommendations.
+- */
++/* Return 1 if DN is a syntactically valid domain name.  Empty names
++   are accepted.  */
+ int
+-res_dnok(const char *dn) {
+-	int ch;
+-
+-	while ((ch = *dn++) != '\0')
+-		if (!domainchar(ch))
+-			return (0);
+-	return (1);
++res_dnok (const char *dn)
++{
++  unsigned char buf[NS_MAXCDNAME];
++  return printable_string (dn) && ns_name_pton (dn, buf, sizeof (buf)) >= 0;
+ }
+ libresolv_hidden_def (res_dnok)
+ 
+diff --git a/resolv/tst-res_hnok.c b/resolv/tst-res_hnok.c
+index 9c923038218e965c..314477a2ce2661c0 100644
+--- a/resolv/tst-res_hnok.c
++++ b/resolv/tst-res_hnok.c
+@@ -51,19 +51,31 @@ static const struct test_case tests[] =
+   {
+     { "", allok },
+     { ".", allok },
++    { "..", 0 },
+     { "www", allnomailok },
++    { "www.", allnomailok },
+     { "example", allnomailok },
+     { "example.com", allok },
+     { "www.example.com", allok },
+     { "www.example.com.", allok },
++    { "www-.example.com.", allok },
++    { "www.-example.com.", allok },
+     { "*.example.com", dnok | mailok | ownok },
+     { "-v", dnok },
+     { "-v.example.com", mailok | dnok },
+     { "**.example.com", dnok | mailok },
++    { "www.example.com\\", 0 },
+     { STRING63, allnomailok },
++    { STRING63 ".", allnomailok },
++    { STRING63 "\\.", 0 },
++    { STRING63 "z", 0 },
+     { STRING63 ".example.com", allok },
+     { STRING63 "." STRING63 "." STRING63 "." STRING60 "z", allok },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "z.", allok },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "zz", 0 },
++    { STRING63 "." STRING63 "." STRING63 "." STRING60 "zzz", 0 },
+     { "hostmaster@mail.example.com", dnok | mailok },
++    { "hostmaster\\@mail.example.com", dnok | mailok },
+     { "with whitespace", 0 },
+     { "with\twhitespace", 0 },
+     { "with\nwhitespace", 0 },
+@@ -116,6 +128,12 @@ one_char (const char *prefix, const char *accepted, const char *suffix,
+     }
+ }
+ 
++#define LETTERSDIGITS \
++  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
++
++#define PRINTABLE \
++  "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~"
++
+ static int
+ do_test (void)
+ {
+@@ -131,20 +149,18 @@ do_test (void)
+     }
+ 
+   one_char
+-    ("", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.",
+-     "", "res_hnok", res_hnok);
++    ("", LETTERSDIGITS "._", "", "res_hnok", res_hnok);
+   one_char
+     ("middle",
+-     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
++     LETTERSDIGITS ".-_\\", /* "middle\\suffix" == "middlesuffix", so good.  */
+      "suffix", "res_hnok", res_hnok);
+   one_char
+     ("middle",
+-     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_"
+-     "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~",
++     LETTERSDIGITS ".-_" PRINTABLE,
+      "suffix.example", "res_mailok", res_mailok);
+   one_char
+     ("mailbox.middle",
+-     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
++     LETTERSDIGITS ".-_\\",
+      "suffix.example", "res_mailok", res_mailok);
+ 
+   return 0;
diff --git a/SOURCES/glibc-rh1163509-1.patch b/SOURCES/glibc-rh1163509-1.patch
new file mode 100644
index 0000000..c8cd366
--- /dev/null
+++ b/SOURCES/glibc-rh1163509-1.patch
@@ -0,0 +1,834 @@
+Note: The __pthread_once definition in the new unified implementation in
+this patch has been edited. The original version of the patch had an old
+style declaration that was causing a -Werror=old-style-definition failure.
+
+commit 36875b06e0ed7f137190b9228bef553adfc338ba
+Author: Torvald Riegel <triegel@redhat.com>
+Date:   Wed May 8 16:35:10 2013 +0200
+
+    Fixed and unified pthread_once.
+    
+    [BZ #15215] This unifies various pthread_once architecture-specific
+    implementations which were using the same algorithm with slightly different
+    implementations.  It also adds missing memory barriers that are required for
+    correctness.
+
+diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
+new file mode 100644
+index 0000000000000000..2684b660958361d4
+--- /dev/null
++++ b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
+@@ -0,0 +1,129 @@
++/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
++
++   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 "pthreadP.h"
++#include <lowlevellock.h>
++#include <atomic.h>
++
++
++unsigned long int __fork_generation attribute_hidden;
++
++
++static void
++clear_once_control (void *arg)
++{
++  pthread_once_t *once_control = (pthread_once_t *) arg;
++
++  /* Reset to the uninitialized state here.  We don't need a stronger memory
++     order because we do not need to make any other of our writes visible to
++     other threads that see this value: This function will be called if we
++     get interrupted (see __pthread_once), so all we need to relay to other
++     threads is the state being reset again.  */
++  *once_control = 0;
++  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
++}
++
++
++/* This is similar to a lock implementation, but we distinguish between three
++   states: not yet initialized (0), initialization finished (2), and
++   initialization in progress (__fork_generation | 1).  If in the first state,
++   threads will try to run the initialization by moving to the second state;
++   the first thread to do so via a CAS on once_control runs init_routine,
++   other threads block.
++   When forking the process, some threads can be interrupted during the second
++   state; they won't be present in the forked child, so we need to restart
++   initialization in the child.  To distinguish an in-progress initialization
++   from an interrupted initialization (in which case we need to reclaim the
++   lock), we look at the fork generation that's part of the second state: We
++   can reclaim iff it differs from the current fork generation.
++   XXX: This algorithm has an ABA issue on the fork generation: If an
++   initialization is interrupted, we then fork 2^30 times (30 bits of
++   once_control are used for the fork generation), and try to initialize
++   again, we can deadlock because we can't distinguish the in-progress and
++   interrupted cases anymore.  */
++int
++__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
++{
++  while (1)
++    {
++      int oldval, val, newval;
++
++      /* We need acquire memory order for this load because if the value
++         signals that initialization has finished, we need to be see any
++         data modifications done during initialization.  */
++      val = *once_control;
++      atomic_read_barrier();
++      do
++	{
++	  /* Check if the initialization has already been done.  */
++	  if (__glibc_likely ((val & 2) != 0))
++	    return 0;
++
++	  oldval = val;
++	  /* We try to set the state to in-progress and having the current
++	     fork generation.  We don't need atomic accesses for the fork
++	     generation because it's immutable in a particular process, and
++	     forked child processes start with a single thread that modified
++	     the generation.  */
++	  newval = __fork_generation | 1;
++	  /* We need acquire memory order here for the same reason as for the
++	     load from once_control above.  */
++	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
++						     oldval);
++	}
++      while (__glibc_unlikely (val != oldval));
++
++      /* Check if another thread already runs the initializer.	*/
++      if ((oldval & 1) != 0)
++	{
++	  /* Check whether the initializer execution was interrupted by a
++	     fork.  We know that for both values, bit 0 is set and bit 1 is
++	     not.  */
++	  if (oldval == newval)
++	    {
++	      /* Same generation, some other thread was faster. Wait.  */
++	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
++	      continue;
++	    }
++	}
++
++      /* This thread is the first here.  Do the initialization.
++	 Register a cleanup handler so that in case the thread gets
++	 interrupted the initialization can be restarted.  */
++      pthread_cleanup_push (clear_once_control, once_control);
++
++      init_routine ();
++
++      pthread_cleanup_pop (0);
++
++
++      /* Mark *once_control as having finished the initialization.  We need
++         release memory order here because we need to synchronize with other
++         threads that want to use the initialized data.  */
++      atomic_write_barrier();
++      *once_control = 2;
++
++      /* Wake up all other threads.  */
++      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
++      break;
++    }
++
++  return 0;
++}
++weak_alias (__pthread_once, pthread_once)
++hidden_def (__pthread_once)
+diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
+deleted file mode 100644
+index a2111756374174f2..0000000000000000
+--- a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
++++ /dev/null
+@@ -1,93 +0,0 @@
+-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-
+-int
+-__pthread_once (once_control, init_routine)
+-     pthread_once_t *once_control;
+-     void (*init_routine) (void);
+-{
+-  while (1)
+-    {
+-      int oldval, val, newval;
+-
+-      val = *once_control;
+-      do
+-	{
+-	  /* Check if the initialized has already been done.  */
+-	  if ((val & 2) != 0)
+-	    return 0;
+-
+-	  oldval = val;
+-	  newval = (oldval & 3) | __fork_generation | 1;
+-	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+-						     oldval);
+-	}
+-      while (__builtin_expect (val != oldval, 0));
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
+-	{
+-	  /* Check whether the initializer execution was interrupted
+-	     by a fork.	 */
+-	  if (((oldval ^ newval) & -4) == 0)
+-	    {
+-	      /* Same generation, some other thread was faster. Wait.  */
+-	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+-	      continue;
+-	    }
+-	}
+-
+-      /* This thread is the first here.  Do the initialization.
+-	 Register a cleanup handler so that in case the thread gets
+-	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
+-
+-      init_routine ();
+-
+-      pthread_cleanup_pop (0);
+-
+-
+-      /* Add one to *once_control.  */
+-      atomic_increment (once_control);
+-
+-      /* Wake up all other threads.  */
+-      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-      break;
+-    }
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/aarch64/nptl/pthread_once.c
+deleted file mode 100644
+index 0897e1e004ef3278..0000000000000000
+--- a/sysdeps/unix/sysv/linux/aarch64/nptl/pthread_once.c
++++ /dev/null
+@@ -1,90 +0,0 @@
+-/* Copyright (C) 2004-2012 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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-int
+-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+-{
+-  for (;;)
+-    {
+-      int oldval;
+-      int newval;
+-
+-      /* Pseudo code:
+-	 newval = __fork_generation | 1;
+-	 oldval = *once_control;
+-	 if ((oldval & 2) == 0)
+-	   *once_control = newval;
+-	 Do this atomically.
+-      */
+-      do
+-	{
+-	  newval = __fork_generation | 1;
+-	  oldval = *once_control;
+-	  if (oldval & 2)
+-	    break;
+-	} while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
+-
+-      /* Check if the initializer has already been done.  */
+-      if ((oldval & 2) != 0)
+-	return 0;
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) == 0)
+-	break;
+-
+-      /* Check whether the initializer execution was interrupted by a fork.  */
+-      if (oldval != newval)
+-	break;
+-
+-      /* Same generation, some other thread was faster. Wait.  */
+-      lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+-    }
+-
+-  /* This thread is the first here.  Do the initialization.
+-     Register a cleanup handler so that in case the thread gets
+-     interrupted the initialization can be restarted.  */
+-  pthread_cleanup_push (clear_once_control, once_control);
+-
+-  init_routine ();
+-
+-  pthread_cleanup_pop (0);
+-
+-  /* Say that the initialisation is done.  */
+-  *once_control = __fork_generation | 2;
+-
+-  /* Wake up all other threads.  */
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c
+deleted file mode 100644
+index 0c03f1c816a2fad5..0000000000000000
+--- a/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c
++++ /dev/null
+@@ -1,89 +0,0 @@
+-/* Copyright (C) 2004-2012 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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-int
+-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+-{
+-  for (;;)
+-    {
+-      int oldval;
+-      int newval;
+-
+-      /* Pseudo code:
+-	 newval = __fork_generation | 1;
+-	 oldval = *once_control;
+-	 if ((oldval & 2) == 0)
+-	   *once_control = newval;
+-	 Do this atomically.
+-      */
+-      do
+-	{
+-	  newval = __fork_generation | 1;
+-	  oldval = *once_control;
+-	  if (oldval & 2)
+-	    break;
+-	} while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
+-
+-      /* Check if the initializer has already been done.  */
+-      if ((oldval & 2) != 0)
+-	return 0;
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) == 0)
+-	break;
+-
+-      /* Check whether the initializer execution was interrupted by a fork.  */
+-      if (oldval != newval)
+-	break;
+-
+-      /* Same generation, some other thread was faster. Wait.  */
+-      lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+-    }
+-
+-  /* This thread is the first here.  Do the initialization.
+-     Register a cleanup handler so that in case the thread gets
+-     interrupted the initialization can be restarted.  */
+-  pthread_cleanup_push (clear_once_control, once_control);
+-
+-  init_routine ();
+-
+-  pthread_cleanup_pop (0);
+-
+-  /* Say that the initialisation is done.  */
+-  *once_control = __fork_generation | 2;
+-
+-  /* Wake up all other threads.  */
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/ia64/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/ia64/nptl/pthread_once.c
+deleted file mode 100644
+index 7730935dfec85ae6..0000000000000000
+--- a/sysdeps/unix/sysv/linux/ia64/nptl/pthread_once.c
++++ /dev/null
+@@ -1,93 +0,0 @@
+-/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-
+-int
+-__pthread_once (once_control, init_routine)
+-     pthread_once_t *once_control;
+-     void (*init_routine) (void);
+-{
+-  while (1)
+-    {
+-      int oldval, val, newval;
+-
+-      val = *once_control;
+-      do
+-	{
+-	  /* Check if the initialized has already been done.  */
+-	  if ((val & 2) != 0)
+-	    return 0;
+-
+-	  oldval = val;
+-	  newval = (oldval & 3) | __fork_generation | 1;
+-	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+-						     oldval);
+-	}
+-      while (__builtin_expect (val != oldval, 0));
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
+-	{
+-	  /* Check whether the initializer execution was interrupted
+-	     by a fork.	 */
+-	  if (((oldval ^ newval) & -4) == 0)
+-	    {
+-	      /* Same generation, some other thread was faster. Wait.  */
+-	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+-	      continue;
+-	    }
+-	}
+-
+-      /* This thread is the first here.  Do the initialization.
+-	 Register a cleanup handler so that in case the thread gets
+-	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
+-
+-      init_routine ();
+-
+-      pthread_cleanup_pop (0);
+-
+-
+-      /* Add one to *once_control.  */
+-      atomic_increment (once_control);
+-
+-      /* Wake up all other threads.  */
+-      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-      break;
+-    }
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/m68k/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/m68k/nptl/pthread_once.c
+deleted file mode 100644
+index 8d81db602eee601f..0000000000000000
+--- a/sysdeps/unix/sysv/linux/m68k/nptl/pthread_once.c
++++ /dev/null
+@@ -1,90 +0,0 @@
+-/* Copyright (C) 2010-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-int
+-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+-{
+-  for (;;)
+-    {
+-      int oldval;
+-      int newval;
+-
+-      /* Pseudo code:
+-	 newval = __fork_generation | 1;
+-	 oldval = *once_control;
+-	 if ((oldval & 2) == 0)
+-	   *once_control = newval;
+-	 Do this atomically.
+-      */
+-      do
+-	{
+-	  newval = __fork_generation | 1;
+-	  oldval = *once_control;
+-	  if (oldval & 2)
+-	    break;
+-	} while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
+-
+-      /* Check if the initializer has already been done.  */
+-      if ((oldval & 2) != 0)
+-	return 0;
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) == 0)
+-	break;
+-
+-      /* Check whether the initializer execution was interrupted by a fork.  */
+-      if (oldval != newval)
+-	break;
+-
+-      /* Same generation, some other thread was faster. Wait.  */
+-      lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+-    }
+-
+-  /* This thread is the first here.  Do the initialization.
+-     Register a cleanup handler so that in case the thread gets
+-     interrupted the initialization can be restarted.  */
+-  pthread_cleanup_push (clear_once_control, once_control);
+-
+-  init_routine ();
+-
+-  pthread_cleanup_pop (0);
+-
+-  /* Say that the initialisation is done.  */
+-  *once_control = __fork_generation | 2;
+-
+-  /* Wake up all other threads.  */
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c
+deleted file mode 100644
+index 308da8bbce0c3800..0000000000000000
+--- a/sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c
++++ /dev/null
+@@ -1,93 +0,0 @@
+-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-
+-int
+-__pthread_once (once_control, init_routine)
+-     pthread_once_t *once_control;
+-     void (*init_routine) (void);
+-{
+-  while (1)
+-    {
+-      int oldval, val, newval;
+-
+-      val = *once_control;
+-      do
+-	{
+-	  /* Check if the initialized has already been done.  */
+-	  if ((val & 2) != 0)
+-	    return 0;
+-
+-	  oldval = val;
+-	  newval = (oldval & 3) | __fork_generation | 1;
+-	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+-						     oldval);
+-	}
+-      while (__builtin_expect (val != oldval, 0));
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
+-	{
+-	  /* Check whether the initializer execution was interrupted
+-	     by a fork.	 */
+-	  if (((oldval ^ newval) & -4) == 0)
+-	    {
+-	      /* Same generation, some other thread was faster. Wait.  */
+-	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+-	      continue;
+-	    }
+-	}
+-
+-      /* This thread is the first here.  Do the initialization.
+-	 Register a cleanup handler so that in case the thread gets
+-	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
+-
+-      init_routine ();
+-
+-      pthread_cleanup_pop (0);
+-
+-
+-      /* Add one to *once_control.  */
+-      atomic_increment (once_control);
+-
+-      /* Wake up all other threads.  */
+-      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-      break;
+-    }
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c
+deleted file mode 100644
+index 93ac29b24c440b2c..0000000000000000
+--- a/sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c
++++ /dev/null
+@@ -1,94 +0,0 @@
+-/* Copyright (C) 2011-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+-   Based on work contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+-
+-   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 <nptl/pthreadP.h>
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-
+-int
+-__pthread_once (once_control, init_routine)
+-     pthread_once_t *once_control;
+-     void (*init_routine) (void);
+-{
+-  while (1)
+-    {
+-      int oldval, val, newval;
+-
+-      val = *once_control;
+-      do
+-	{
+-	  /* Check if the initialized has already been done.  */
+-	  if ((val & 2) != 0)
+-	    return 0;
+-
+-	  oldval = val;
+-	  newval = (oldval & 3) | __fork_generation | 1;
+-	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+-						     oldval);
+-	}
+-      while (__builtin_expect (val != oldval, 0));
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
+-	{
+-	  /* Check whether the initializer execution was interrupted
+-	     by a fork.	 */
+-	  if (((oldval ^ newval) & -4) == 0)
+-	    {
+-	      /* Same generation, some other thread was faster. Wait.  */
+-	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+-	      continue;
+-	    }
+-	}
+-
+-      /* This thread is the first here.  Do the initialization.
+-	 Register a cleanup handler so that in case the thread gets
+-	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
+-
+-      init_routine ();
+-
+-      pthread_cleanup_pop (0);
+-
+-
+-      /* Add one to *once_control.  */
+-      atomic_increment (once_control);
+-
+-      /* Wake up all other threads.  */
+-      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-      break;
+-    }
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
diff --git a/SOURCES/glibc-rh1163509-2.patch b/SOURCES/glibc-rh1163509-2.patch
new file mode 100644
index 0000000..78284d0
--- /dev/null
+++ b/SOURCES/glibc-rh1163509-2.patch
@@ -0,0 +1,294 @@
+This patch is based on the below upstream commit.
+It only includes relevant pthread_once bits.
+
+commit 08192659bbeae149e7cb1f4c43547257f7099bb0
+Author: Roland McGrath <roland@hack.frob.com>
+Date:   Mon Jul 7 09:28:38 2014 -0700
+
+    Get rid of nptl/sysdeps/ entirely!
+
+diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
+index ed1ea3498c397e5c..10c01d6023508e3c 100644
+--- a/nptl/pthread_once.c
++++ b/nptl/pthread_once.c
+@@ -1,6 +1,6 @@
+-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
++/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
++   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+@@ -9,7 +9,7 @@
+ 
+    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
++   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
+@@ -18,37 +18,114 @@
+ 
+ #include "pthreadP.h"
+ #include <lowlevellock.h>
++#include <atomic.h>
+ 
+ 
++unsigned long int __fork_generation attribute_hidden;
+ 
+-static int once_lock = LLL_LOCK_INITIALIZER;
+ 
++static void
++clear_once_control (void *arg)
++{
++  pthread_once_t *once_control = (pthread_once_t *) arg;
++
++  /* Reset to the uninitialized state here.  We don't need a stronger memory
++     order because we do not need to make any other of our writes visible to
++     other threads that see this value: This function will be called if we
++     get interrupted (see __pthread_once), so all we need to relay to other
++     threads is the state being reset again.  */
++  *once_control = 0;
++  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
++}
+ 
++
++/* This is similar to a lock implementation, but we distinguish between three
++   states: not yet initialized (0), initialization finished (2), and
++   initialization in progress (__fork_generation | 1).  If in the first state,
++   threads will try to run the initialization by moving to the second state;
++   the first thread to do so via a CAS on once_control runs init_routine,
++   other threads block.
++   When forking the process, some threads can be interrupted during the second
++   state; they won't be present in the forked child, so we need to restart
++   initialization in the child.  To distinguish an in-progress initialization
++   from an interrupted initialization (in which case we need to reclaim the
++   lock), we look at the fork generation that's part of the second state: We
++   can reclaim iff it differs from the current fork generation.
++   XXX: This algorithm has an ABA issue on the fork generation: If an
++   initialization is interrupted, we then fork 2^30 times (30 bits of
++   once_control are used for the fork generation), and try to initialize
++   again, we can deadlock because we can't distinguish the in-progress and
++   interrupted cases anymore.  */
+ int
+ __pthread_once (once_control, init_routine)
+      pthread_once_t *once_control;
+      void (*init_routine) (void);
+ {
+-  /* XXX Depending on whether the LOCK_IN_ONCE_T is defined use a
+-     global lock variable or one which is part of the pthread_once_t
+-     object.  */
+-  if (*once_control == PTHREAD_ONCE_INIT)
++  while (1)
+     {
+-      lll_lock (once_lock, LLL_PRIVATE);
++      int oldval, val, newval;
+ 
+-      /* XXX This implementation is not complete.  It doesn't take
+-	 cancelation and fork into account.  */
+-      if (*once_control == PTHREAD_ONCE_INIT)
++      /* We need acquire memory order for this load because if the value
++         signals that initialization has finished, we need to be see any
++         data modifications done during initialization.  */
++      val = *once_control;
++      atomic_read_barrier();
++      do
+ 	{
+-	  init_routine ();
++	  /* Check if the initialization has already been done.  */
++	  if (__glibc_likely ((val & 2) != 0))
++	    return 0;
++
++	  oldval = val;
++	  /* We try to set the state to in-progress and having the current
++	     fork generation.  We don't need atomic accesses for the fork
++	     generation because it's immutable in a particular process, and
++	     forked child processes start with a single thread that modified
++	     the generation.  */
++	  newval = __fork_generation | 1;
++	  /* We need acquire memory order here for the same reason as for the
++	     load from once_control above.  */
++	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
++						     oldval);
++	}
++      while (__glibc_unlikely (val != oldval));
+ 
+-	  *once_control = !PTHREAD_ONCE_INIT;
++      /* Check if another thread already runs the initializer.	*/
++      if ((oldval & 1) != 0)
++	{
++	  /* Check whether the initializer execution was interrupted by a
++	     fork.  We know that for both values, bit 0 is set and bit 1 is
++	     not.  */
++	  if (oldval == newval)
++	    {
++	      /* Same generation, some other thread was faster. Wait.  */
++	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
++	      continue;
++	    }
+ 	}
+ 
+-      lll_unlock (once_lock, LLL_PRIVATE);
++      /* This thread is the first here.  Do the initialization.
++	 Register a cleanup handler so that in case the thread gets
++	 interrupted the initialization can be restarted.  */
++      pthread_cleanup_push (clear_once_control, once_control);
++
++      init_routine ();
++
++      pthread_cleanup_pop (0);
++
++
++      /* Mark *once_control as having finished the initialization.  We need
++         release memory order here because we need to synchronize with other
++         threads that want to use the initialized data.  */
++      atomic_write_barrier();
++      *once_control = 2;
++
++      /* Wake up all other threads.  */
++      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
++      break;
+     }
+ 
+   return 0;
+ }
+-strong_alias (__pthread_once, pthread_once)
++weak_alias (__pthread_once, pthread_once)
+ hidden_def (__pthread_once)
+diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
+deleted file mode 100644
+index 2684b660958361d4..0000000000000000
+--- a/nptl/sysdeps/unix/sysv/linux/pthread_once.c
++++ /dev/null
+@@ -1,129 +0,0 @@
+-/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-#include <atomic.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  /* Reset to the uninitialized state here.  We don't need a stronger memory
+-     order because we do not need to make any other of our writes visible to
+-     other threads that see this value: This function will be called if we
+-     get interrupted (see __pthread_once), so all we need to relay to other
+-     threads is the state being reset again.  */
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-
+-/* This is similar to a lock implementation, but we distinguish between three
+-   states: not yet initialized (0), initialization finished (2), and
+-   initialization in progress (__fork_generation | 1).  If in the first state,
+-   threads will try to run the initialization by moving to the second state;
+-   the first thread to do so via a CAS on once_control runs init_routine,
+-   other threads block.
+-   When forking the process, some threads can be interrupted during the second
+-   state; they won't be present in the forked child, so we need to restart
+-   initialization in the child.  To distinguish an in-progress initialization
+-   from an interrupted initialization (in which case we need to reclaim the
+-   lock), we look at the fork generation that's part of the second state: We
+-   can reclaim iff it differs from the current fork generation.
+-   XXX: This algorithm has an ABA issue on the fork generation: If an
+-   initialization is interrupted, we then fork 2^30 times (30 bits of
+-   once_control are used for the fork generation), and try to initialize
+-   again, we can deadlock because we can't distinguish the in-progress and
+-   interrupted cases anymore.  */
+-int
+-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+-{
+-  while (1)
+-    {
+-      int oldval, val, newval;
+-
+-      /* We need acquire memory order for this load because if the value
+-         signals that initialization has finished, we need to be see any
+-         data modifications done during initialization.  */
+-      val = *once_control;
+-      atomic_read_barrier();
+-      do
+-	{
+-	  /* Check if the initialization has already been done.  */
+-	  if (__glibc_likely ((val & 2) != 0))
+-	    return 0;
+-
+-	  oldval = val;
+-	  /* We try to set the state to in-progress and having the current
+-	     fork generation.  We don't need atomic accesses for the fork
+-	     generation because it's immutable in a particular process, and
+-	     forked child processes start with a single thread that modified
+-	     the generation.  */
+-	  newval = __fork_generation | 1;
+-	  /* We need acquire memory order here for the same reason as for the
+-	     load from once_control above.  */
+-	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+-						     oldval);
+-	}
+-      while (__glibc_unlikely (val != oldval));
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
+-	{
+-	  /* Check whether the initializer execution was interrupted by a
+-	     fork.  We know that for both values, bit 0 is set and bit 1 is
+-	     not.  */
+-	  if (oldval == newval)
+-	    {
+-	      /* Same generation, some other thread was faster. Wait.  */
+-	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+-	      continue;
+-	    }
+-	}
+-
+-      /* This thread is the first here.  Do the initialization.
+-	 Register a cleanup handler so that in case the thread gets
+-	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
+-
+-      init_routine ();
+-
+-      pthread_cleanup_pop (0);
+-
+-
+-      /* Mark *once_control as having finished the initialization.  We need
+-         release memory order here because we need to synchronize with other
+-         threads that want to use the initialized data.  */
+-      atomic_write_barrier();
+-      *once_control = 2;
+-
+-      /* Wake up all other threads.  */
+-      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-      break;
+-    }
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
diff --git a/SOURCES/glibc-rh1163509-3.patch b/SOURCES/glibc-rh1163509-3.patch
new file mode 100644
index 0000000..17b2c93
--- /dev/null
+++ b/SOURCES/glibc-rh1163509-3.patch
@@ -0,0 +1,108 @@
+commit 63668b7084ac26865136e59fdf17781f9f49bd99
+Author: Torvald Riegel <triegel@redhat.com>
+Date:   Fri Oct 11 18:58:04 2013 +0300
+
+    pthread_once: Clean up constants.
+    
+    [BZ #15215] This just gives a name to the integer constants being used.
+
+diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
+index dda1032d5aa95234..1a842e06bff82479 100644
+--- a/nptl/pthreadP.h
++++ b/nptl/pthreadP.h
+@@ -159,6 +159,12 @@ enum
+ #define FUTEX_TID_MASK		0x3fffffff
+ 
+ 
++/* pthread_once definitions.  See __pthread_once for how these are used.  */
++#define __PTHREAD_ONCE_INPROGRESS	1
++#define __PTHREAD_ONCE_DONE		2
++#define __PTHREAD_ONCE_FORK_GEN_INCR	4
++
++
+ /* Internal variables.  */
+ 
+ 
+diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
+index 10c01d6023508e3c..595bd7e298003e00 100644
+--- a/nptl/pthread_once.c
++++ b/nptl/pthread_once.c
+@@ -40,8 +40,11 @@ clear_once_control (void *arg)
+ 
+ 
+ /* This is similar to a lock implementation, but we distinguish between three
+-   states: not yet initialized (0), initialization finished (2), and
+-   initialization in progress (__fork_generation | 1).  If in the first state,
++   states: not yet initialized (0), initialization in progress
++   (__fork_generation | __PTHREAD_ONCE_INPROGRESS), and initialization
++   finished (__PTHREAD_ONCE_DONE); __fork_generation does not use the bits
++   that are used for __PTHREAD_ONCE_INPROGRESS and __PTHREAD_ONCE_DONE (which
++   is what __PTHREAD_ONCE_FORK_GEN_INCR is used for).  If in the first state,
+    threads will try to run the initialization by moving to the second state;
+    the first thread to do so via a CAS on once_control runs init_routine,
+    other threads block.
+@@ -66,14 +69,14 @@ __pthread_once (once_control, init_routine)
+       int oldval, val, newval;
+ 
+       /* We need acquire memory order for this load because if the value
+-         signals that initialization has finished, we need to be see any
++         signals that initialization has finished, we need to see any
+          data modifications done during initialization.  */
+       val = *once_control;
+       atomic_read_barrier();
+       do
+ 	{
+ 	  /* Check if the initialization has already been done.  */
+-	  if (__glibc_likely ((val & 2) != 0))
++	  if (__glibc_likely ((val & __PTHREAD_ONCE_DONE) != 0))
+ 	    return 0;
+ 
+ 	  oldval = val;
+@@ -82,7 +85,7 @@ __pthread_once (once_control, init_routine)
+ 	     generation because it's immutable in a particular process, and
+ 	     forked child processes start with a single thread that modified
+ 	     the generation.  */
+-	  newval = __fork_generation | 1;
++	  newval = __fork_generation | __PTHREAD_ONCE_INPROGRESS;
+ 	  /* We need acquire memory order here for the same reason as for the
+ 	     load from once_control above.  */
+ 	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+@@ -91,11 +94,11 @@ __pthread_once (once_control, init_routine)
+       while (__glibc_unlikely (val != oldval));
+ 
+       /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
++      if ((oldval & __PTHREAD_ONCE_INPROGRESS) != 0)
+ 	{
+ 	  /* Check whether the initializer execution was interrupted by a
+-	     fork.  We know that for both values, bit 0 is set and bit 1 is
+-	     not.  */
++	     fork.  We know that for both values, __PTHREAD_ONCE_INPROGRESS
++	     is set and __PTHREAD_ONCE_DONE is not.  */
+ 	  if (oldval == newval)
+ 	    {
+ 	      /* Same generation, some other thread was faster. Wait.  */
+@@ -118,7 +121,7 @@ __pthread_once (once_control, init_routine)
+          release memory order here because we need to synchronize with other
+          threads that want to use the initialized data.  */
+       atomic_write_barrier();
+-      *once_control = 2;
++      *once_control = __PTHREAD_ONCE_DONE;
+ 
+       /* Wake up all other threads.  */
+       lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
+index 0635bfdb6cdf0aa8..8c197cb8e4347959 100644
+--- a/nptl/sysdeps/unix/sysv/linux/fork.c
++++ b/nptl/sysdeps/unix/sysv/linux/fork.c
+@@ -146,8 +146,9 @@ __libc_fork (void)
+ 
+       assert (THREAD_GETMEM (self, tid) != ppid);
+ 
++      /* See __pthread_once.  */
+       if (__fork_generation_pointer != NULL)
+-	*__fork_generation_pointer += 4;
++	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
+ 
+       /* Adjust the PID field for the new process.  */
+       THREAD_SETMEM (self, pid, THREAD_GETMEM (self, tid));
diff --git a/SOURCES/glibc-rh1163509-4.patch b/SOURCES/glibc-rh1163509-4.patch
new file mode 100644
index 0000000..641face
--- /dev/null
+++ b/SOURCES/glibc-rh1163509-4.patch
@@ -0,0 +1,443 @@
+This patch is based on the below upstream commit.
+File deletions were altered to reflect file renames.
+
+commit f50277c19df0937ea9691ab7e7c642ecd3ed3d94
+Author: Torvald Riegel <triegel@redhat.com>
+Date:   Sun Oct 19 21:59:26 2014 +0200
+
+    pthread_once: Add fast path and remove x86 variants.
+
+diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
+index 595bd7e298003e00..2afb79c01fe0a61e 100644
+--- a/nptl/pthread_once.c
++++ b/nptl/pthread_once.c
+@@ -58,11 +58,13 @@ clear_once_control (void *arg)
+    initialization is interrupted, we then fork 2^30 times (30 bits of
+    once_control are used for the fork generation), and try to initialize
+    again, we can deadlock because we can't distinguish the in-progress and
+-   interrupted cases anymore.  */
+-int
+-__pthread_once (once_control, init_routine)
+-     pthread_once_t *once_control;
+-     void (*init_routine) (void);
++   interrupted cases anymore.
++   XXX: We split out this slow path because current compilers do not generate
++   as efficient code when the fast path in __pthread_once below is not in a
++   separate function.  */
++static int
++__attribute__ ((noinline))
++__pthread_once_slow (pthread_once_t *once_control, void (*init_routine) (void))
+ {
+   while (1)
+     {
+@@ -72,7 +74,7 @@ __pthread_once (once_control, init_routine)
+          signals that initialization has finished, we need to see any
+          data modifications done during initialization.  */
+       val = *once_control;
+-      atomic_read_barrier();
++      atomic_read_barrier ();
+       do
+ 	{
+ 	  /* Check if the initialization has already been done.  */
+@@ -130,5 +132,18 @@ __pthread_once (once_control, init_routine)
+ 
+   return 0;
+ }
++
++int
++__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
++{
++  /* Fast path.  See __pthread_once_slow.  */
++  int val;
++  val = *once_control;
++  atomic_read_barrier ();
++  if (__glibc_likely ((val & __PTHREAD_ONCE_DONE) != 0))
++    return 0;
++  else
++    return __pthread_once_slow (once_control, init_routine);
++}
+ weak_alias (__pthread_once, pthread_once)
+ hidden_def (__pthread_once)
+diff --git a/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
+deleted file mode 100644
+index ca3b860a7f6f95ae..0000000000000000
+--- a/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
++++ /dev/null
+@@ -1,178 +0,0 @@
+-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+-
+-   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 <unwindbuf.h>
+-#include <sysdep.h>
+-#include <kernel-features.h>
+-#include <lowlevellock.h>
+-
+-
+-	.comm	__fork_generation, 4, 4
+-
+-	.text
+-
+-
+-	.globl	__pthread_once
+-	.type	__pthread_once,@function
+-	.align	16
+-	cfi_startproc
+-__pthread_once:
+-	movl	4(%esp), %ecx
+-	testl	$2, (%ecx)
+-	jz	1f
+-	xorl	%eax, %eax
+-	ret
+-
+-1:	pushl	%ebx
+-	cfi_adjust_cfa_offset (4)
+-	cfi_rel_offset (3, 0)
+-	pushl	%esi
+-	cfi_adjust_cfa_offset (4)
+-	cfi_rel_offset (6, 0)
+-	movl	%ecx, %ebx
+-	xorl	%esi, %esi
+-
+-	/* Not yet initialized or initialization in progress.
+-	   Get the fork generation counter now.  */
+-6:	movl	(%ebx), %eax
+-#ifdef PIC
+-	LOAD_PIC_REG(cx)
+-#endif
+-
+-5:	movl	%eax, %edx
+-
+-	testl	$2, %eax
+-	jnz	4f
+-
+-	andl	$3, %edx
+-#ifdef PIC
+-	orl	__fork_generation@GOTOFF(%ecx), %edx
+-#else
+-	orl	__fork_generation, %edx
+-#endif
+-	orl	$1, %edx
+-
+-	LOCK
+-	cmpxchgl %edx, (%ebx)
+-	jnz	5b
+-
+-	/* Check whether another thread already runs the initializer.  */
+-	testl	$1, %eax
+-	jz	3f	/* No -> do it.  */
+-
+-	/* Check whether the initializer execution was interrupted
+-	   by a fork.  */
+-	xorl	%edx, %eax
+-	testl	$0xfffffffc, %eax
+-	jnz	3f	/* Different for generation -> run initializer.  */
+-
+-	/* Somebody else got here first.  Wait.  */
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	movl	$FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %ecx
+-#else
+-# if FUTEX_WAIT == 0
+-	movl	%gs:PRIVATE_FUTEX, %ecx
+-# else
+-	movl	$FUTEX_WAIT, %ecx
+-	orl	%gs:PRIVATE_FUTEX, %ecx
+-# endif
+-#endif
+-	movl	$SYS_futex, %eax
+-	ENTER_KERNEL
+-	jmp	6b
+-
+-3:	/* Call the initializer function after setting up the
+-	   cancellation handler.  Note that it is not possible here
+-	   to use the unwind-based cleanup handling.  This would require
+-	   that the user-provided function and all the code it calls
+-	   is compiled with exceptions.  Unfortunately this cannot be
+-	   guaranteed.  */
+-	subl	$UNWINDBUFSIZE+8, %esp
+-	cfi_adjust_cfa_offset (UNWINDBUFSIZE+8)
+-	movl	%ecx, %ebx		/* PIC register value.  */
+-
+-	leal	8+UWJMPBUF(%esp), %eax
+-	movl	$0, 4(%esp)
+-	movl	%eax, (%esp)
+-	call	__sigsetjmp@PLT
+-	testl	%eax, %eax
+-	jne	7f
+-
+-	leal	8(%esp), %eax
+-	call	HIDDEN_JUMPTARGET(__pthread_register_cancel)
+-
+-	/* Call the user-provided initialization function.  */
+-	call	*24+UNWINDBUFSIZE(%esp)
+-
+-	/* Pop the cleanup handler.  */
+-	leal	8(%esp), %eax
+-	call	HIDDEN_JUMPTARGET(__pthread_unregister_cancel)
+-	addl	$UNWINDBUFSIZE+8, %esp
+-	cfi_adjust_cfa_offset (-UNWINDBUFSIZE-8)
+-
+-	/* Sucessful run of the initializer.  Signal that we are done.  */
+-	movl	12(%esp), %ebx
+-	LOCK
+-	addl	$1, (%ebx)
+-
+-	/* Wake up all other threads.  */
+-	movl	$0x7fffffff, %edx
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
+-#else
+-	movl	$FUTEX_WAKE, %ecx
+-	orl	%gs:PRIVATE_FUTEX, %ecx
+-#endif
+-	movl	$SYS_futex, %eax
+-	ENTER_KERNEL
+-
+-4:	popl	%esi
+-	cfi_adjust_cfa_offset (-4)
+-	cfi_restore (6)
+-	popl	%ebx
+-	cfi_adjust_cfa_offset (-4)
+-	cfi_restore (3)
+-	xorl	%eax, %eax
+-	ret
+-
+-7:	/* __sigsetjmp returned for the second time.  */
+-	movl	20+UNWINDBUFSIZE(%esp), %ebx
+-	cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
+-	cfi_offset (3, -8)
+-	cfi_offset (6, -12)
+-	movl	$0, (%ebx)
+-
+-	movl	$0x7fffffff, %edx
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
+-#else
+-	movl	$FUTEX_WAKE, %ecx
+-	orl	%gs:PRIVATE_FUTEX, %ecx
+-#endif
+-	movl	$SYS_futex, %eax
+-	ENTER_KERNEL
+-
+-	leal	8(%esp), %eax
+-	call	HIDDEN_JUMPTARGET (__pthread_unwind_next)
+-	/* NOTREACHED */
+-	hlt
+-	cfi_endproc
+-	.size	__pthread_once,.-__pthread_once
+-
+-hidden_def (__pthread_once)
+-strong_alias (__pthread_once, pthread_once)
+diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
+deleted file mode 100644
+index 7f5c0810fa16b987..0000000000000000
+--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
++++ /dev/null
+@@ -1,193 +0,0 @@
+-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+-
+-   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 <kernel-features.h>
+-#include <tcb-offsets.h>
+-#include <lowlevellock.h>
+-
+-
+-	.comm	__fork_generation, 4, 4
+-
+-	.text
+-
+-
+-	.globl	__pthread_once
+-	.type	__pthread_once,@function
+-	.align	16
+-__pthread_once:
+-.LSTARTCODE:
+-	cfi_startproc
+-#ifdef SHARED
+-	cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
+-			DW.ref.__gcc_personality_v0)
+-	cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
+-#else
+-	cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
+-	cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
+-#endif
+-	testl	$2, (%rdi)
+-	jz	1f
+-	xorl	%eax, %eax
+-	retq
+-
+-	/* Preserve the function pointer.  */
+-1:	pushq	%rsi
+-	cfi_adjust_cfa_offset(8)
+-	xorq	%r10, %r10
+-
+-	/* Not yet initialized or initialization in progress.
+-	   Get the fork generation counter now.  */
+-6:	movl	(%rdi), %eax
+-
+-5:	movl	%eax, %edx
+-
+-	testl	$2, %eax
+-	jnz	4f
+-
+-	andl	$3, %edx
+-	orl	__fork_generation(%rip), %edx
+-	orl	$1, %edx
+-
+-	LOCK
+-	cmpxchgl %edx, (%rdi)
+-	jnz	5b
+-
+-	/* Check whether another thread already runs the initializer.  */
+-	testl	$1, %eax
+-	jz	3f	/* No -> do it.  */
+-
+-	/* Check whether the initializer execution was interrupted
+-	   by a fork.  */
+-	xorl	%edx, %eax
+-	testl	$0xfffffffc, %eax
+-	jnz	3f	/* Different for generation -> run initializer.  */
+-
+-	/* Somebody else got here first.  Wait.  */
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	movl	$FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %esi
+-#else
+-# if FUTEX_WAIT == 0
+-	movl	%fs:PRIVATE_FUTEX, %esi
+-# else
+-	movl	$FUTEX_WAIT, %esi
+-	orl	%fs:PRIVATE_FUTEX, %esi
+-# endif
+-#endif
+-	movl	$SYS_futex, %eax
+-	syscall
+-	jmp	6b
+-
+-	/* Preserve the pointer to the control variable.  */
+-3:	pushq	%rdi
+-	cfi_adjust_cfa_offset(8)
+-	pushq	%rdi
+-	cfi_adjust_cfa_offset(8)
+-
+-.LcleanupSTART:
+-	callq	*16(%rsp)
+-.LcleanupEND:
+-
+-	/* Get the control variable address back.  */
+-	popq	%rdi
+-	cfi_adjust_cfa_offset(-8)
+-
+-	/* Sucessful run of the initializer.  Signal that we are done.  */
+-	LOCK
+-	incl	(%rdi)
+-
+-	addq	$8, %rsp
+-	cfi_adjust_cfa_offset(-8)
+-
+-	/* Wake up all other threads.  */
+-	movl	$0x7fffffff, %edx
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+-#else
+-	movl	$FUTEX_WAKE, %esi
+-	orl	%fs:PRIVATE_FUTEX, %esi
+-#endif
+-	movl	$SYS_futex, %eax
+-	syscall
+-
+-4:	addq	$8, %rsp
+-	cfi_adjust_cfa_offset(-8)
+-	xorl	%eax, %eax
+-	retq
+-	.size	__pthread_once,.-__pthread_once
+-
+-
+-hidden_def (__pthread_once)
+-strong_alias (__pthread_once, pthread_once)
+-
+-
+-	.type	clear_once_control,@function
+-	.align	16
+-clear_once_control:
+-	cfi_adjust_cfa_offset(3 * 8)
+-	movq	(%rsp), %rdi
+-	movq	%rax, %r8
+-	movl	$0, (%rdi)
+-
+-	movl	$0x7fffffff, %edx
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+-#else
+-	movl	$FUTEX_WAKE, %esi
+-	orl	%fs:PRIVATE_FUTEX, %esi
+-#endif
+-	movl	$SYS_futex, %eax
+-	syscall
+-
+-	movq	%r8, %rdi
+-.LcallUR:
+-	call	_Unwind_Resume@PLT
+-	hlt
+-.LENDCODE:
+-	cfi_endproc
+-	.size	clear_once_control,.-clear_once_control
+-
+-
+-	.section .gcc_except_table,"a",@progbits
+-.LexceptSTART:
+-	.byte	DW_EH_PE_omit			# @LPStart format
+-	.byte	DW_EH_PE_omit			# @TType format
+-	.byte	DW_EH_PE_uleb128		# call-site format
+-	.uleb128 .Lcstend-.Lcstbegin
+-.Lcstbegin:
+-	.uleb128 .LcleanupSTART-.LSTARTCODE
+-	.uleb128 .LcleanupEND-.LcleanupSTART
+-	.uleb128 clear_once_control-.LSTARTCODE
+-	.uleb128  0
+-	.uleb128 .LcallUR-.LSTARTCODE
+-	.uleb128 .LENDCODE-.LcallUR
+-	.uleb128 0
+-	.uleb128  0
+-.Lcstend:
+-
+-
+-#ifdef SHARED
+-	.hidden	DW.ref.__gcc_personality_v0
+-	.weak	DW.ref.__gcc_personality_v0
+-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+-	.align	LP_SIZE
+-	.type	DW.ref.__gcc_personality_v0, @object
+-	.size	DW.ref.__gcc_personality_v0, LP_SIZE
+-DW.ref.__gcc_personality_v0:
+-	ASM_ADDR __gcc_personality_v0
+-#endif
diff --git a/SOURCES/glibc-rh1163509-5.patch b/SOURCES/glibc-rh1163509-5.patch
new file mode 100644
index 0000000..cc314ec
--- /dev/null
+++ b/SOURCES/glibc-rh1163509-5.patch
@@ -0,0 +1,720 @@
+This patch removes the following remaining architecture specific
+pthread_once implementations:
+
+- alpha, hppa, sh: Not used in RHEL.
+
+- s390: Was first moved, then renamed upstream by the following commits:
+
+  commit 52ae23b4bfa09fa1f42e3f659aaa057d1176d06b
+  Author: Roland McGrath <roland@hack.frob.com>
+  Date:   Thu Jun 26 09:31:11 2014 -0700
+
+      Move remaining S390 code out of nptl/.
+
+  commit bc89c0fc70ba952f78fc27fc261ec209be0a6732
+  Author: Torvald Riegel <triegel@redhat.com>
+  Date:   Mon Dec 8 18:32:14 2014 +0100
+
+      Remove custom pthread_once implementation on s390.
+
+- powerpc: Was removed upstream by the following commit:
+
+  commit 75ffb047f6ee2a545da8cf69dba9a979ca6271ce
+  Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+  Date:   Sun Apr 13 18:13:42 2014 -0500
+
+      PowerPC: Sync pthread_once with default implementation
+
+diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
+deleted file mode 100644
+index 52ab53f0a912d107..0000000000000000
+--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
++++ /dev/null
+@@ -1,110 +0,0 @@
+-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  __asm __volatile (__lll_rel_instr);
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-
+-int
+-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+-{
+-  for (;;)
+-    {
+-      int oldval;
+-      int newval;
+-      int tmp;
+-
+-      /* Pseudo code:
+-	 newval = __fork_generation | 1;
+-	 oldval = *once_control;
+-	 if ((oldval & 2) == 0)
+-	   *once_control = newval;
+-	 Do this atomically with an acquire barrier.
+-      */
+-      newval = __fork_generation | 1;
+-      __asm __volatile ("1:	lwarx	%0,0,%3" MUTEX_HINT_ACQ "\n"
+-			"	andi.	%1,%0,2\n"
+-			"	bne	2f\n"
+-			"	stwcx.	%4,0,%3\n"
+-			"	bne	1b\n"
+-			"2:	" __lll_acq_instr
+-			: "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
+-			: "r" (once_control), "r" (newval), "m" (*once_control)
+-			: "cr0");
+-
+-      /* Check if the initializer has already been done.  */
+-      if ((oldval & 2) != 0)
+-	return 0;
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) == 0)
+-	break;
+-
+-      /* Check whether the initializer execution was interrupted by a fork.  */
+-      if (oldval != newval)
+-	break;
+-
+-      /* Same generation, some other thread was faster. Wait.  */
+-      lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+-    }
+-
+-
+-  /* This thread is the first here.  Do the initialization.
+-     Register a cleanup handler so that in case the thread gets
+-     interrupted the initialization can be restarted.  */
+-  pthread_cleanup_push (clear_once_control, once_control);
+-
+-  init_routine ();
+-
+-  pthread_cleanup_pop (0);
+-
+-
+-  /* Add one to *once_control to take the bottom 2 bits from 01 to 10.
+-     A release barrier is needed to ensure memory written by init_routine
+-     is seen in other threads before *once_control changes.  */
+-  int tmp;
+-  __asm __volatile (__lll_rel_instr "\n"
+-		    "1:	lwarx	%0,0,%2" MUTEX_HINT_REL "\n"
+-		    "	addi	%0,%0,1\n"
+-		    "	stwcx.	%0,0,%2\n"
+-		    "	bne-	1b"
+-		    : "=&b" (tmp), "=m" (*once_control)
+-		    : "r" (once_control), "m" (*once_control)
+-		    : "cr0");
+-
+-  /* Wake up all other threads.  */
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
+deleted file mode 100644
+index 4bce7fec13ea3bb2..0000000000000000
+--- a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
++++ /dev/null
+@@ -1,108 +0,0 @@
+-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-
+-int
+-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+-{
+-  while (1)
+-    {
+-      int oldval;
+-      int newval;
+-
+-      /* Pseudo code:
+-	   oldval = *once_control;
+-	   if ((oldval & 2) == 0)
+-	    {
+-	      newval = (oldval & 3) | __fork_generation | 1;
+-	      *once_control = newval;
+-	    }
+-	 Do this atomically.  */
+-      __asm __volatile ("   l	 %1,%0\n"
+-			"0: lhi	 %2,2\n"
+-			"   tml	 %1,2\n"
+-			"   jnz	 1f\n"
+-			"   nr	 %2,%1\n"
+-			"   ahi	 %2,1\n"
+-			"   o	 %2,%3\n"
+-			"   cs	 %1,%2,%0\n"
+-			"   jl	 0b\n"
+-			"1:"
+-			: "=Q" (*once_control), "=&d" (oldval), "=&d" (newval)
+-			: "m" (__fork_generation), "m" (*once_control)
+-			: "cc" );
+-      /* Check if the initialized has already been done.  */
+-      if ((oldval & 2) != 0)
+-	  break;
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
+-	{
+-	  /* Check whether the initializer execution was interrupted
+-	     by a fork.	 */
+-	  if (((oldval ^ newval) & -4) == 0)
+-	    {
+-	      /* Same generation, some other thread was faster. Wait.  */
+-	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
+-	      continue;
+-	    }
+-	}
+-
+-      /* This thread is the first here.  Do the initialization.
+-	 Register a cleanup handler so that in case the thread gets
+-	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
+-
+-      init_routine ();
+-
+-      pthread_cleanup_pop (0);
+-
+-
+-      /* Add one to *once_control.  */
+-      __asm __volatile ("   l	 %1,%0\n"
+-			"0: lr	 %2,%1\n"
+-			"   ahi	 %2,1\n"
+-			"   cs	 %1,%2,%0\n"
+-			"   jl	 0b\n"
+-			: "=Q" (*once_control), "=&d" (oldval), "=&d" (newval)
+-			: "m" (*once_control) : "cc" );
+-
+-      /* Wake up all other threads.  */
+-      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-      break;
+-    }
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
+deleted file mode 100644
+index 62b92d8b103ded65..0000000000000000
+--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
++++ /dev/null
+@@ -1,257 +0,0 @@
+-/* Copyright (C) 2003-2012 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 <unwindbuf.h>
+-#include <sysdep.h>
+-#include <kernel-features.h>
+-#include <lowlevellock.h>
+-#include "lowlevel-atomic.h"
+-
+-
+-	.comm	__fork_generation, 4, 4
+-
+-	.text
+-	.globl	__pthread_once
+-	.type	__pthread_once,@function
+-	.align	5
+-	cfi_startproc
+-__pthread_once:
+-	mov.l	@r4, r0
+-	tst	#2, r0
+-	bt	1f
+-	rts
+-	 mov	#0, r0
+-
+-1:
+-	mov.l	r12, @-r15
+-	cfi_adjust_cfa_offset (4)
+-	cfi_rel_offset (r12, 0)
+-	mov.l	r9, @-r15
+-	cfi_adjust_cfa_offset (4)
+-	cfi_rel_offset (r9, 0)
+-	mov.l	r8, @-r15
+-	cfi_adjust_cfa_offset (4)
+-	cfi_rel_offset (r8, 0)
+-	sts.l	pr, @-r15
+-	cfi_adjust_cfa_offset (4)
+-	cfi_rel_offset (pr, 0)
+-	mov	r5, r8
+-	mov	r4, r9
+-
+-	/* Not yet initialized or initialization in progress.
+-	   Get the fork generation counter now.  */
+-6:
+-	mov.l	@r4, r1
+-	mova	.Lgot, r0
+-	mov.l	.Lgot, r12
+-	add	r0, r12
+-
+-5:
+-	mov	r1, r0
+-
+-	tst	#2, r0
+-	bf	4f
+-
+-	and	#3, r0
+-	mov.l	.Lfgen, r2
+-#ifdef PIC
+-	add	r12, r2
+-#endif
+-	mov.l	@r2, r3
+-	or	r3, r0	
+-	or	#1, r0
+-	mov	r0, r3
+-	mov	r1, r5
+-
+-	CMPXCHG (r5, @r4, r3, r2)
+-	bf	5b
+-
+-	/* Check whether another thread already runs the initializer.  */
+-	mov	r2, r0
+-	tst	#1, r0
+-	bt	3f	/* No -> do it.  */
+-
+-	/* Check whether the initializer execution was interrupted
+-	   by a fork.  */
+-	xor	r3, r0
+-	mov	#-4, r1	/* -4 = 0xfffffffc */
+-	tst	r1, r0
+-	bf	3f	/* Different for generation -> run initializer.  */
+-
+-	/* Somebody else got here first.  Wait.  */
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5
+-	extu.b	r5, r5
+-#else
+-	stc	gbr, r1
+-	mov.w	.Lpfoff, r2
+-	add	r2, r1
+-	mov.l	@r1, r5
+-# if FUTEX_WAIT != 0
+-	mov	#FUTEX_WAIT, r0
+-	or	r0, r5
+-# endif
+-#endif
+-	mov	r3, r6
+-	mov	#0, r7
+-	mov	#SYS_futex, r3
+-	extu.b	r3, r3
+-	trapa	#0x14
+-	SYSCALL_INST_PAD
+-	bra	6b
+-	 nop
+-
+-	.align	2
+-.Lgot:
+-	.long	_GLOBAL_OFFSET_TABLE_
+-#ifdef PIC
+-.Lfgen:	
+-	.long	__fork_generation@GOTOFF
+-#else
+-.Lfgen:	
+-	.long	__fork_generation
+-#endif
+-
+-3:
+-	/* Call the initializer function after setting up the
+-	   cancellation handler.  Note that it is not possible here
+-	   to use the unwind-based cleanup handling.  This would require
+-	   that the user-provided function and all the code it calls
+-	   is compiled with exceptions.  Unfortunately this cannot be
+-	   guaranteed.  */
+-	add	#-UNWINDBUFSIZE, r15
+-	cfi_adjust_cfa_offset (UNWINDBUFSIZE)
+-
+-	mov.l	.Lsigsetjmp, r1
+-	mov	#UWJMPBUF, r4
+-	add	r15, r4
+-	bsrf	r1
+-	 mov	#0, r5
+-.Lsigsetjmp0:
+-	tst	r0, r0
+-	bf	7f
+-
+-	mov.l	.Lcpush, r1
+-	bsrf	r1
+-	 mov	r15, r4
+-.Lcpush0:
+-
+-	/* Call the user-provided initialization function.  */
+-	jsr	@r8
+-	 nop
+-
+-	/* Pop the cleanup handler.  */
+-	mov.l	.Lcpop, r1
+-	bsrf	r1
+-	 mov	r15, r4
+-.Lcpop0:
+-
+-	add	#UNWINDBUFSIZE, r15
+-	cfi_adjust_cfa_offset (-UNWINDBUFSIZE)
+-
+-	/* Sucessful run of the initializer.  Signal that we are done.  */
+-	INC (@r9, r2)
+-	/* Wake up all other threads.  */
+-	mov	r9, r4
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+-	extu.b	r5, r5
+-#else
+-	stc	gbr, r1
+-	mov.w	.Lpfoff, r2
+-	add	r2, r1
+-	mov.l	@r1, r5
+-	mov	#FUTEX_WAKE, r0
+-	or	r0, r5
+-#endif
+-	mov	#-1, r6
+-	shlr	r6		/* r6 = 0x7fffffff */
+-	mov	#0, r7
+-	mov	#SYS_futex, r3
+-	extu.b	r3, r3
+-	trapa	#0x14
+-	SYSCALL_INST_PAD
+-
+-4:
+-	lds.l	@r15+, pr
+-	cfi_adjust_cfa_offset (-4)
+-	cfi_restore (pr)
+-	mov.l	@r15+, r8
+-	cfi_adjust_cfa_offset (-4)
+-	cfi_restore (r8)
+-	mov.l	@r15+, r9
+-	cfi_adjust_cfa_offset (-4)
+-	cfi_restore (r9)
+-	mov.l	@r15+, r12
+-	cfi_adjust_cfa_offset (-4)
+-	cfi_restore (r12)
+-	rts
+-	 mov	#0, r0
+-
+-7:
+-	/* __sigsetjmp returned for the second time.  */
+-	cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
+-	cfi_offset (r12, -4)
+-	cfi_offset (r9, -8)
+-	cfi_offset (r8, -12)
+-	cfi_offset (pr, -16)
+-	mov	#0, r7
+-	mov.l	r7, @r9
+-	mov	r9, r4
+-#ifdef __ASSUME_PRIVATE_FUTEX
+-	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+-#else
+-	stc	gbr, r1
+-	mov.w	.Lpfoff, r2
+-	add	r2, r1
+-	mov.l	@r1, r5
+-	mov	#FUTEX_WAKE, r0
+-	or	r0, r5
+-#endif
+-	extu.b	r5, r5
+-	mov	#-1, r6
+-	shlr	r6		/* r6 = 0x7fffffff */
+-	mov	#SYS_futex, r3
+-	extu.b	r3, r3
+-	trapa	#0x14
+-	SYSCALL_INST_PAD
+-
+-	mov.l	.Lunext, r1
+-	bsrf	r1
+-	 mov	r15, r4
+-.Lunext0:
+-	/* NOTREACHED */
+-	sleep
+-	cfi_endproc
+-
+-#ifndef __ASSUME_PRIVATE_FUTEX
+-.Lpfoff:
+-	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+-#endif
+-	.align	2
+-.Lsigsetjmp:
+-	.long	__sigsetjmp@PLT-(.Lsigsetjmp0-.)
+-.Lcpush:
+-	.long	HIDDEN_JUMPTARGET(__pthread_register_cancel)-.Lcpush0
+-.Lcpop:
+-	.long	HIDDEN_JUMPTARGET(__pthread_unregister_cancel)-.Lcpop0
+-.Lunext:
+-	.long	HIDDEN_JUMPTARGET(__pthread_unwind_next)-.Lunext0
+-	.size	__pthread_once,.-__pthread_once
+-
+-hidden_def (__pthread_once)
+-strong_alias (__pthread_once, pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/alpha/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/alpha/nptl/pthread_once.c
+deleted file mode 100644
+index c342e0a7a0965086..0000000000000000
+--- a/sysdeps/unix/sysv/linux/alpha/nptl/pthread_once.c
++++ /dev/null
+@@ -1,95 +0,0 @@
+-/* Copyright (C) 2003-2012 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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-}
+-
+-int
+-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+-{
+-  for (;;)
+-    {
+-      int oldval;
+-      int newval;
+-      int tmp;
+-
+-      /* Pseudo code:
+-	 newval = __fork_generation | 1;
+-	 oldval = *once_control;
+-	 if ((oldval & 2) == 0)
+-	   *once_control = newval;
+-	 Do this atomically.
+-      */
+-      newval = __fork_generation | 1;
+-      __asm __volatile (
+-		"1:	ldl_l	%0, %2\n"
+-		"	and	%0, 2, %1\n"
+-		"	bne	%1, 2f\n"
+-		"	mov	%3, %1\n"
+-		"	stl_c	%1, %2\n"
+-		"	beq	%1, 1b\n"
+-		"2:	mb"
+-		: "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
+-		: "r" (newval), "m" (*once_control));
+-
+-      /* Check if the initializer has already been done.  */
+-      if ((oldval & 2) != 0)
+-	return 0;
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) == 0)
+-	break;
+-
+-      /* Check whether the initializer execution was interrupted by a fork.  */
+-      if (oldval != newval)
+-	break;
+-
+-      /* Same generation, some other thread was faster. Wait.  */
+-      lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+-    }
+-
+-  /* This thread is the first here.  Do the initialization.
+-     Register a cleanup handler so that in case the thread gets
+-     interrupted the initialization can be restarted.  */
+-  pthread_cleanup_push (clear_once_control, once_control);
+-
+-  init_routine ();
+-
+-  pthread_cleanup_pop (0);
+-
+-  /* Add one to *once_control to take the bottom 2 bits from 01 to 10.  */
+-  atomic_increment (once_control);
+-
+-  /* Wake up all other threads.  */
+-  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
+diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c
+deleted file mode 100644
+index b920ebb22c10a569..0000000000000000
+--- a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c
++++ /dev/null
+@@ -1,93 +0,0 @@
+-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+-
+-   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 "pthreadP.h"
+-#include <lowlevellock.h>
+-
+-
+-unsigned long int __fork_generation attribute_hidden;
+-
+-
+-static void
+-clear_once_control (void *arg)
+-{
+-  pthread_once_t *once_control = (pthread_once_t *) arg;
+-
+-  *once_control = 0;
+-  lll_private_futex_wake (once_control, INT_MAX);
+-}
+-
+-
+-int
+-__pthread_once (once_control, init_routine)
+-     pthread_once_t *once_control;
+-     void (*init_routine) (void);
+-{
+-  while (1)
+-    {
+-      int oldval, val, newval;
+-
+-      val = *once_control;
+-      do
+-	{
+-	  /* Check if the initialized has already been done.  */
+-	  if ((val & 2) != 0)
+-	    return 0;
+-
+-	  oldval = val;
+-	  newval = (oldval & 3) | __fork_generation | 1;
+-	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
+-						     oldval);
+-	}
+-      while (__builtin_expect (val != oldval, 0));
+-
+-      /* Check if another thread already runs the initializer.	*/
+-      if ((oldval & 1) != 0)
+-	{
+-	  /* Check whether the initializer execution was interrupted
+-	     by a fork.	 */
+-	  if (((oldval ^ newval) & -4) == 0)
+-	    {
+-	      /* Same generation, some other thread was faster. Wait.  */
+-	      lll_private_futex_wait (once_control, newval);
+-	      continue;
+-	    }
+-	}
+-
+-      /* This thread is the first here.  Do the initialization.
+-	 Register a cleanup handler so that in case the thread gets
+-	 interrupted the initialization can be restarted.  */
+-      pthread_cleanup_push (clear_once_control, once_control);
+-
+-      init_routine ();
+-
+-      pthread_cleanup_pop (0);
+-
+-
+-      /* Add one to *once_control.  */
+-      atomic_increment (once_control);
+-
+-      /* Wake up all other threads.  */
+-      lll_private_futex_wake (once_control, INT_MAX);
+-      break;
+-    }
+-
+-  return 0;
+-}
+-weak_alias (__pthread_once, pthread_once)
+-hidden_def (__pthread_once)
diff --git a/SOURCES/glibc-rh1256317-armhfp-build-issue.patch b/SOURCES/glibc-rh1256317-armhfp-build-issue.patch
deleted file mode 100644
index aa6e7fe..0000000
--- a/SOURCES/glibc-rh1256317-armhfp-build-issue.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/sysdeps/unix/arm/sysdep.S	2016-11-05 11:44:45.561945344 +0100
-+++ b/sysdeps/unix/arm/sysdep.S	2016-11-05 11:44:19.542069815 +0100
-@@ -37,7 +37,7 @@
- 	moveq r0, $EAGAIN	/* Yes; translate it to EAGAIN.  */
- #endif
- 
--#ifndef IS_IN_rtld
-+#if !IS_IN (rtld)
- 	mov ip, lr
- 	cfi_register (lr, ip)
- 	mov r1, r0
diff --git a/SOURCES/glibc-rh1418978-1.patch b/SOURCES/glibc-rh1418978-1.patch
index c57c652..466a62e 100644
--- a/SOURCES/glibc-rh1418978-1.patch
+++ b/SOURCES/glibc-rh1418978-1.patch
@@ -1,19 +1,25 @@
 This patch creates the contents of the support/ directory up to this
 upstream commit on the master branch:
 
-commit 401311cfba71b61d93d23aa17e5c9ac5fb047d48
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Mon Jan 8 14:33:17 2018 +0100
+commit 00c86a37d1b63044e3169d1f2ebec23447c73f79
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Nov 7 11:09:02 2018 -0200
 
-    resolv: Support binary labels in test framework
+    support: Fix printf format for TEST_COMPARE_STRING
     
-    The old implementation based on hsearch_r used an ad-hoc C string
-    encoding and produced an incorrect format on the wire for domain
-    names which contained bytes which needed escaping when printed.
+    Fix the following on 32 bits targets:
     
-    This commit switches to ns_name_pton for the wire format conversion
-    (now that we have separate tests for it) and uses a tsearch tree
-    with a suitable comparison function to locate compression targets.
+    support_test_compare_string.c: In function ‘support_test_compare_string’:
+    support_test_compare_string.c:80:37: error: format ‘%lu’ expects argument of
+    type ‘long unsigned int’, but argument 2 has type ‘size_t’ {aka ‘unsigned int’}
+    [-Werror=format=]
+             printf ("  string length: %lu bytes\n", left_length);
+                                       ~~^           ~~~~~~~~~~~
+                                       %u
+    Checked on arm-linux-gnueabihf.
+    
+            * support/support_test_compare_string.c
+            (support_test_compare_string): Fix printf format.
 
 diff --git a/scripts/backport-support.sh b/scripts/backport-support.sh
 new file mode 100644
@@ -133,10 +139,10 @@ index 0000000000..4057e42d3c
 +command_$command
 diff --git a/support/Makefile b/support/Makefile
 new file mode 100644
-index 0000000000..1bda81e55e
+index 0000000000..2b663fbbfa
 --- /dev/null
 +++ b/support/Makefile
-@@ -0,0 +1,171 @@
+@@ -0,0 +1,219 @@
 +# Makefile for support library, used only at build and test time
 +# Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +# This file is part of the GNU C Library.
@@ -164,6 +170,7 @@ index 0000000000..1bda81e55e
 +extra-libs-noinstall := $(extra-libs)
 +
 +libsupport-routines = \
++  blob_repeat \
 +  check \
 +  check_addrinfo \
 +  check_dns_packet \
@@ -182,6 +189,8 @@ index 0000000000..1bda81e55e
 +  support_capture_subprocess \
 +  support_capture_subprocess_check \
 +  support_chroot \
++  support_copy_file_range \
++  support_descriptor_supports_holes \
 +  support_enter_mount_namespace \
 +  support_enter_network_namespace \
 +  support_format_address_family \
@@ -191,10 +200,15 @@ index 0000000000..1bda81e55e
 +  support_format_hostent \
 +  support_format_netent \
 +  support_isolate_in_subprocess \
++  support_openpty \
++  support_paths \
++  support_quote_blob \
 +  support_record_failure \
 +  support_run_diff \
 +  support_shared_allocate \
++  support_test_compare_blob \
 +  support_test_compare_failure \
++  support_test_compare_string \
 +  support_write_file_string \
 +  support_test_main \
 +  support_test_verify_impl \
@@ -208,6 +222,7 @@ index 0000000000..1bda81e55e
 +  xchroot \
 +  xclose \
 +  xconnect \
++  xcopy_file_range \
 +  xdlfcn \
 +  xdup2 \
 +  xfclose \
@@ -220,6 +235,7 @@ index 0000000000..1bda81e55e
 +  xmalloc \
 +  xmemstream \
 +  xmkdir \
++  xmkdirp \
 +  xmmap \
 +  xmprotect \
 +  xmunmap \
@@ -234,6 +250,9 @@ index 0000000000..1bda81e55e
 +  xpthread_barrier_destroy \
 +  xpthread_barrier_init \
 +  xpthread_barrier_wait \
++  xpthread_barrierattr_destroy \
++  xpthread_barrierattr_init \
++  xpthread_barrierattr_setpshared \
 +  xpthread_cancel \
 +  xpthread_check_return \
 +  xpthread_cond_wait \
@@ -272,6 +291,7 @@ index 0000000000..1bda81e55e
 +  xsocket \
 +  xstrdup \
 +  xstrndup \
++  xsymlink \
 +  xsysconf \
 +  xunlink \
 +  xwaitpid \
@@ -284,13 +304,47 @@ index 0000000000..1bda81e55e
 +libsupport-inhibit-o += .o
 +endif
 +
++CFLAGS-support_paths.c = \
++		-DSRCDIR_PATH=\"`cd .. ; pwd`\" \
++		-DOBJDIR_PATH=\"`cd $(objpfx)/..; pwd`\" \
++		-DOBJDIR_ELF_LDSO_PATH=\"`cd $(objpfx)/..; pwd`/elf/$(rtld-installed-name)\" \
++		-DINSTDIR_PATH=\"$(prefix)\" \
++		-DLIBDIR_PATH=\"$(libdir)\"
++
++ifeq (,$(CXX))
++LINKS_DSO_PROGRAM = links-dso-program-c
++else
++LINKS_DSO_PROGRAM = links-dso-program
++LDLIBS-links-dso-program = -lstdc++ -lgcc -lgcc_s $(libunwind)
++endif
++
++LDLIBS-test-container = $(libsupport)
++
++others += test-container
++others-noinstall += test-container
++
++others += shell-container echo-container true-container
++others-noinstall += shell-container echo-container true-container
++
++others += $(LINKS_DSO_PROGRAM)
++others-noinstall += $(LINKS_DSO_PROGRAM)
++
++$(objpfx)test-container : $(libsupport)
++$(objpfx)shell-container : $(libsupport)
++$(objpfx)echo-container : $(libsupport)
++$(objpfx)true-container : $(libsupport)
++
 +tests = \
 +  README-testing \
 +  tst-support-namespace \
++  tst-support_blob_repeat \
 +  tst-support_capture_subprocess \
 +  tst-support_format_dns_packet \
++  tst-support_quote_blob \
 +  tst-support_record_failure \
 +  tst-test_compare \
++  tst-test_compare_blob \
++  tst-test_compare_string \
 +  tst-xreadlink \
 +
 +ifeq ($(run-built-tests),yes)
@@ -368,6 +422,344 @@ index 0000000000..9d289c3020
 +/* This file references do_test above and contains the definition of
 +   the main function.  */
 +#include <support/test-driver.c>
+diff --git a/support/blob_repeat.c b/support/blob_repeat.c
+new file mode 100644
+index 0000000000..16c1e448b9
+--- /dev/null
++++ b/support/blob_repeat.c
+@@ -0,0 +1,282 @@
++/* Repeating a memory blob, with alias mapping optimization.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <fcntl.h>
++#include <stdbool.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/blob_repeat.h>
++#include <support/check.h>
++#include <support/test-driver.h>
++#include <support/support.h>
++#include <support/xunistd.h>
++#include <sys/mman.h>
++#include <unistd.h>
++#include <wchar.h>
++
++/* Small allocations should use malloc directly instead of the mmap
++   optimization because mappings carry a lot of overhead.  */
++static const size_t maximum_small_size = 4 * 1024 * 1024;
++
++/* Internal helper for fill.  */
++static void
++fill0 (char *target, const char *element, size_t element_size,
++       size_t count)
++{
++  while (count > 0)
++    {
++      memcpy (target, element, element_size);
++      target += element_size;
++      --count;
++    }
++}
++
++/* Fill the buffer at TARGET with COUNT copies of the ELEMENT_SIZE
++   bytes starting at ELEMENT.  */
++static void
++fill (char *target, const char *element, size_t element_size,
++      size_t count)
++{
++  if (element_size == 0 || count == 0)
++    return;
++  else if (element_size == 1)
++    memset (target, element[0], count);
++  else if (element_size == sizeof (wchar_t))
++    {
++      wchar_t wc;
++      memcpy (&wc, element, sizeof (wc));
++      wmemset ((wchar_t *) target, wc, count);
++    }
++  else if (element_size < 1024 && count > 4096)
++    {
++      /* Use larger copies for really small element sizes.  */
++      char buffer[8192];
++      size_t buffer_count = sizeof (buffer) / element_size;
++      fill0 (buffer, element, element_size, buffer_count);
++      while (count > 0)
++        {
++          size_t copy_count = buffer_count;
++          if (copy_count > count)
++            copy_count = count;
++          size_t copy_bytes = copy_count * element_size;
++          memcpy (target, buffer, copy_bytes);
++          target += copy_bytes;
++          count -= copy_count;
++        }
++    }
++  else
++    fill0 (target, element, element_size, count);
++}
++
++/* Use malloc instead of mmap for small allocations and unusual size
++   combinations.  */
++static struct support_blob_repeat
++allocate_malloc (size_t total_size, const void *element, size_t element_size,
++                 size_t count)
++{
++  void *buffer = malloc (total_size);
++  if (buffer == NULL)
++    return (struct support_blob_repeat) { 0 };
++  fill (buffer, element, element_size, count);
++  return (struct support_blob_repeat)
++    {
++      .start = buffer,
++      .size = total_size,
++      .use_malloc = true
++    };
++}
++
++/* Return the least common multiple of PAGE_SIZE and ELEMENT_SIZE,
++   avoiding overflow.  This assumes that PAGE_SIZE is a power of
++   two.  */
++static size_t
++minimum_stride_size (size_t page_size, size_t element_size)
++{
++  TEST_VERIFY_EXIT (page_size > 0);
++  TEST_VERIFY_EXIT (element_size > 0);
++
++  /* Compute the number of trailing zeros common to both sizes.  */
++  unsigned int common_zeros = __builtin_ctzll (page_size | element_size);
++
++  /* In the product, this power of two appears twice, but in the least
++     common multiple, it appears only once.  Therefore, shift one
++     factor.  */
++  size_t multiple;
++  if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
++                              &multiple))
++    return 0;
++  return multiple;
++}
++
++/* Allocations larger than maximum_small_size potentially use mmap
++   with alias mappings.  */
++static struct support_blob_repeat
++allocate_big (size_t total_size, const void *element, size_t element_size,
++              size_t count)
++{
++  unsigned long page_size = xsysconf (_SC_PAGESIZE);
++  size_t stride_size = minimum_stride_size (page_size, element_size);
++  if (stride_size == 0)
++    {
++      errno = EOVERFLOW;
++      return (struct support_blob_repeat) { 0 };
++    }
++
++  /* Ensure that the stride size is at least maximum_small_size.  This
++     is necessary to reduce the number of distinct mappings.  */
++  if (stride_size < maximum_small_size)
++    stride_size
++      = ((maximum_small_size + stride_size - 1) / stride_size) * stride_size;
++
++  if (stride_size > total_size)
++    /* The mmap optimization would not save anything.  */
++    return allocate_malloc (total_size, element, element_size, count);
++
++  /* Reserve the memory region.  If we cannot create the mapping,
++     there is no reason to set up the backing file.  */
++  void *target = mmap (NULL, total_size, PROT_NONE,
++                       MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
++  if (target == MAP_FAILED)
++    return (struct support_blob_repeat) { 0 };
++
++  /* Create the backing file for the repeated mapping.  Call mkstemp
++     directly to remove the resources backing the temporary file
++     immediately, once support_blob_repeat_free is called.  Using
++     create_temp_file would result in a warning during post-test
++     cleanup.  */
++  int fd;
++  {
++    char *temppath = xasprintf ("%s/support_blob_repeat-XXXXXX", test_dir);
++    fd = mkstemp (temppath);
++    if (fd < 0)
++      FAIL_EXIT1 ("mkstemp (\"%s\"): %m", temppath);
++    xunlink (temppath);
++    free (temppath);
++  }
++
++  /* Make sure that there is backing storage, so that the fill
++     operation will not fault.  */
++  if (posix_fallocate (fd, 0, stride_size) != 0)
++    FAIL_EXIT1 ("posix_fallocate (%zu): %m", stride_size);
++
++  /* The stride size must still be a multiple of the page size and
++     element size.  */
++  TEST_VERIFY_EXIT ((stride_size % page_size) == 0);
++  TEST_VERIFY_EXIT ((stride_size % element_size) == 0);
++
++  /* Fill the backing store.  */
++  {
++    void *ptr = mmap (target, stride_size, PROT_READ | PROT_WRITE,
++                      MAP_FIXED | MAP_FILE | MAP_SHARED, fd, 0);
++    if (ptr == MAP_FAILED)
++      {
++        int saved_errno = errno;
++        xmunmap (target, total_size);
++        xclose (fd);
++        errno = saved_errno;
++        return (struct support_blob_repeat) { 0 };
++      }
++    if (ptr != target)
++      FAIL_EXIT1 ("mapping of %zu bytes moved from %p to %p",
++                  stride_size, target, ptr);
++
++    /* Write the repeating data.  */
++    fill (target, element, element_size, stride_size / element_size);
++
++    /* Return to a PROT_NONE mapping, just to be on the safe side.  */
++    ptr = mmap (target, stride_size, PROT_NONE,
++                MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
++    if (ptr == MAP_FAILED)
++      FAIL_EXIT1 ("Failed to reinstate PROT_NONE mapping: %m");
++    if (ptr != target)
++      FAIL_EXIT1 ("PROT_NONE mapping of %zu bytes moved from %p to %p",
++                  stride_size, target, ptr);
++  }
++
++  /* Create the alias mappings.  */
++  {
++    size_t remaining_size = total_size;
++    char *current = target;
++    int flags = MAP_FIXED | MAP_FILE | MAP_PRIVATE;
++#ifdef MAP_NORESERVE
++    flags |= MAP_NORESERVE;
++#endif
++    while (remaining_size > 0)
++      {
++        size_t to_map = stride_size;
++        if (to_map > remaining_size)
++          to_map = remaining_size;
++        void *ptr = mmap (current, to_map, PROT_READ | PROT_WRITE,
++                          flags, fd, 0);
++        if (ptr == MAP_FAILED)
++          {
++            int saved_errno = errno;
++            xmunmap (target, total_size);
++            xclose (fd);
++            errno = saved_errno;
++            return (struct support_blob_repeat) { 0 };
++          }
++        if (ptr != current)
++          FAIL_EXIT1 ("MAP_PRIVATE mapping of %zu bytes moved from %p to %p",
++                      to_map, target, ptr);
++        remaining_size -= to_map;
++        current += to_map;
++      }
++  }
++
++  xclose (fd);
++
++  return (struct support_blob_repeat)
++    {
++      .start = target,
++      .size = total_size,
++      .use_malloc = false
++    };
++}
++
++struct support_blob_repeat
++support_blob_repeat_allocate (const void *element, size_t element_size,
++                              size_t count)
++{
++  size_t total_size;
++  if (__builtin_mul_overflow (element_size, count, &total_size))
++    {
++      errno = EOVERFLOW;
++      return (struct support_blob_repeat) { 0 };
++    }
++  if (total_size <= maximum_small_size)
++    return allocate_malloc (total_size, element, element_size, count);
++  else
++    return allocate_big (total_size, element, element_size, count);
++}
++
++void
++support_blob_repeat_free (struct support_blob_repeat *blob)
++{
++  if (blob->size > 0)
++    {
++      int saved_errno = errno;
++      if (blob->use_malloc)
++        free (blob->start);
++      else
++        xmunmap (blob->start, blob->size);
++      errno = saved_errno;
++    }
++  *blob = (struct support_blob_repeat) { 0 };
++}
+diff --git a/support/blob_repeat.h b/support/blob_repeat.h
+new file mode 100644
+index 0000000000..8e9d7ff5f1
+--- /dev/null
++++ b/support/blob_repeat.h
+@@ -0,0 +1,44 @@
++/* Repeating a memory blob, with alias mapping optimization.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#ifndef SUPPORT_BLOB_REPEAT_H
++#define SUPPORT_BLOB_REPEAT_H
++
++#include <stdbool.h>
++#include <stddef.h>
++
++struct support_blob_repeat
++{
++  void *start;
++  size_t size;
++  bool use_malloc;
++};
++
++/* Return an allocation of COUNT elements, each of ELEMENT_SIZE bytes,
++   initialized with the bytes starting at ELEMENT.  The memory is
++   writable (and thus counts towards the commit charge).  In case of
++   on error, all members of the return struct are zero-initialized,
++   and errno is set accordingly.  */
++struct support_blob_repeat support_blob_repeat_allocate (const void *element,
++                                                         size_t element_size,
++                                                         size_t count);
++
++/* Deallocate the blob created by support_blob_repeat_allocate.  */
++void support_blob_repeat_free (struct support_blob_repeat *);
++
++#endif /* SUPPORT_BLOB_REPEAT_H */
 diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
 new file mode 100644
 index 0000000000..b0886ba1d1
@@ -437,10 +829,10 @@ index 0000000000..b0886ba1d1
 +#endif /* SUPPORT_CAPTURE_SUBPROCESS_H */
 diff --git a/support/check.c b/support/check.c
 new file mode 100644
-index 0000000000..688ed569ac
+index 0000000000..78f2b3cde1
 --- /dev/null
 +++ b/support/check.c
-@@ -0,0 +1,57 @@
+@@ -0,0 +1,60 @@
 +/* Support code for reporting test results.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -461,6 +853,7 @@ index 0000000000..688ed569ac
 +
 +#include <support/check.h>
 +
++#include <errno.h>
 +#include <stdarg.h>
 +#include <stdio.h>
 +#include <stdlib.h>
@@ -469,9 +862,11 @@ index 0000000000..688ed569ac
 +static void
 +print_failure (const char *file, int line, const char *format, va_list ap)
 +{
++  int saved_errno = errno;
 +  printf ("error: %s:%d: ", file, line);
 +  vprintf (format, ap);
 +  puts ("");
++  errno = saved_errno;
 +}
 +
 +int
@@ -500,10 +895,10 @@ index 0000000000..688ed569ac
 +}
 diff --git a/support/check.h b/support/check.h
 new file mode 100644
-index 0000000000..2192f38941
+index 0000000000..e6765289f2
 --- /dev/null
 +++ b/support/check.h
-@@ -0,0 +1,153 @@
+@@ -0,0 +1,188 @@
 +/* Functionality for reporting test results.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -570,6 +965,8 @@ index 0000000000..2192f38941
 +        (1, __FILE__, __LINE__, #expr);                         \
 +  })
 +
++
++
 +int support_print_failure_impl (const char *file, int line,
 +                                const char *format, ...)
 +  __attribute__ ((nonnull (1), format (printf, 3, 4)));
@@ -647,6 +1044,39 @@ index 0000000000..2192f38941
 +                                   int right_size);
 +
 +
++/* Compare [LEFT, LEFT + LEFT_LENGTH) with [RIGHT, RIGHT +
++   RIGHT_LENGTH) and report a test failure if the arrays are
++   different.  LEFT_LENGTH and RIGHT_LENGTH are measured in bytes.  If
++   the length is null, the corresponding pointer is ignored (i.e., it
++   can be NULL).  The blobs should be reasonably short because on
++   mismatch, both are printed.  */
++#define TEST_COMPARE_BLOB(left, left_length, right, right_length)       \
++  (support_test_compare_blob (left, left_length, right, right_length,   \
++                              __FILE__, __LINE__,                       \
++                              #left, #left_length, #right, #right_length))
++
++void support_test_compare_blob (const void *left,
++                                unsigned long int left_length,
++                                const void *right,
++                                unsigned long int right_length,
++                                const char *file, int line,
++                                const char *left_exp, const char *left_len_exp,
++                                const char *right_exp,
++                                const char *right_len_exp);
++
++/* Compare the strings LEFT and RIGHT and report a test failure if
++   they are different.  Also report failure if one of the arguments is
++   a null pointer and the other is not.  The strings should be
++   reasonably short because on mismatch, both are printed.  */
++#define TEST_COMPARE_STRING(left, right)                         \
++  (support_test_compare_string (left, right, __FILE__, __LINE__, \
++                                #left, #right))
++
++void support_test_compare_string (const char *left, const char *right,
++                                  const char *file, int line,
++                                  const char *left_expr,
++                                  const char *right_expr);
++
 +/* Internal function called by the test driver.  */
 +int support_report_failure (int status)
 +  __attribute__ ((weak, warn_unused_result));
@@ -962,6 +1392,46 @@ index 0000000000..2780d9a6fe
 +  /* Restore the original signal mask.  */
 +  xpthread_sigmask (SIG_SETMASK, &old_set, NULL);
 +}
+diff --git a/support/echo-container.c b/support/echo-container.c
+new file mode 100644
+index 0000000000..e4d48df957
+--- /dev/null
++++ b/support/echo-container.c
+@@ -0,0 +1,34 @@
++/* Minimal /bin/echo for in-container use.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++
++int
++main (int argc, const char **argv)
++{
++  int i;
++
++  for (i = 1; i < argc; i++)
++    {
++      if (i > 1)
++	putchar (' ');
++      fputs (argv[i], stdout);
++    }
++  putchar ('\n');
++  return 0;
++}
 diff --git a/support/format_nss.h b/support/format_nss.h
 new file mode 100644
 index 0000000000..e55354e788
@@ -1053,6 +1523,38 @@ index 0000000000..450333ad38
 +    }
 +  setenv ("LIBC_FATAL_STDERR_", "1", 1);
 +}
+diff --git a/support/links-dso-program-c.c b/support/links-dso-program-c.c
+new file mode 100644
+index 0000000000..d28a28a0d0
+--- /dev/null
++++ b/support/links-dso-program-c.c
+@@ -0,0 +1,9 @@
++#include <stdio.h>
++
++int
++main (int argc, char **argv)
++{
++  /* Complexity to keep gcc from optimizing this away.  */
++  printf ("This is a test %s.\n", argc > 1 ? argv[1] : "null");
++  return 0;
++}
+diff --git a/support/links-dso-program.cc b/support/links-dso-program.cc
+new file mode 100644
+index 0000000000..dba6976c06
+--- /dev/null
++++ b/support/links-dso-program.cc
+@@ -0,0 +1,11 @@
++#include <iostream>
++
++using namespace std;
++
++int
++main (int argc, char **argv)
++{
++  /* Complexity to keep gcc from optimizing this away.  */
++  cout << (argc > 1 ? argv[1] : "null");
++  return 0;
++}
 diff --git a/support/namespace.h b/support/namespace.h
 new file mode 100644
 index 0000000000..3c3842a49b
@@ -2855,14 +3357,14 @@ index 0000000000..c2dacbb179
 +  sigaction (SIGABRT, &sa, NULL);
 +  ignore_stderr ();
 +}
-diff --git a/support/support-xfstat.c b/support/support-xfstat.c
+diff --git a/support/shell-container.c b/support/shell-container.c
 new file mode 100644
-index 0000000000..f69253af09
+index 0000000000..9bd90d3f60
 --- /dev/null
-+++ b/support/support-xfstat.c
-@@ -0,0 +1,28 @@
-+/* fstat64 with error checking.
-+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++++ b/support/shell-container.c
+@@ -0,0 +1,395 @@
++/* Minimal /bin/sh for in-container use.
++   Copyright (C) 2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
 +
 +   The GNU C Library is free software; you can redistribute it and/or
@@ -2879,58 +3381,459 @@ index 0000000000..f69253af09
 +   License along with the GNU C Library; if not, see
 +   <http://www.gnu.org/licenses/>.  */
 +
-+#include <support/check.h>
-+#include <support/xunistd.h>
++#define _FILE_OFFSET_BITS 64
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sched.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <dirent.h>
++#include <string.h>
 +#include <sys/stat.h>
++#include <sys/fcntl.h>
++#include <sys/file.h>
++#include <sys/wait.h>
++#include <stdarg.h>
++#include <sys/sysmacros.h>
++#include <ctype.h>
++#include <utime.h>
++#include <errno.h>
++#include <error.h>
 +
-+void
-+xfstat (int fd, struct stat64 *result)
-+{
-+  if (fstat64 (fd, result) != 0)
-+    FAIL_EXIT1 ("fstat64 (%d): %m", fd);
-+}
-diff --git a/support/support-xstat.c b/support/support-xstat.c
-new file mode 100644
-index 0000000000..fc10c6dcb7
---- /dev/null
-+++ b/support/support-xstat.c
-@@ -0,0 +1,30 @@
-+/* stat64 with error checking.
-+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
++#include <support/support.h>
 +
-+   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.
++/* Design considerations
 +
-+   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.
++ General rule: optimize for developer time, not run time.
 +
-+   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/>.  */
++ Specifically:
 +
-+/* NB: Non-standard file name to avoid sysdeps override for xstat.  */
++ * Don't worry about slow algorithms
++ * Don't worry about free'ing memory
++ * Don't implement anything the testsuite doesn't need.
++ * Line and argument counts are limited, see below.
 +
-+#include <support/check.h>
-+#include <support/xunistd.h>
-+#include <sys/stat.h>
++*/
 +
-+void
-+xstat (const char *path, struct stat64 *result)
++#define MAX_ARG_COUNT 100
++#define MAX_LINE_LENGTH 1000
++
++/* Debugging is enabled via --debug, which must be the first argument.  */
++static int debug_mode = 0;
++#define dprintf if (debug_mode) fprintf
++
++/* Emulate the "/bin/true" command.  Arguments are ignored.  */
++static int
++true_func (char **argv)
 +{
-+  if (stat64 (path, result) != 0)
-+    FAIL_EXIT1 ("stat64 (\"%s\"): %m", path);
++  return 0;
++}
++
++/* Emulate the "/bin/echo" command.  Options are ignored, arguments
++   are printed to stdout.  */
++static int
++echo_func (char **argv)
++{
++  int i;
++
++  for (i = 0; argv[i]; i++)
++    {
++      if (i > 0)
++	putchar (' ');
++      fputs (argv[i], stdout);
++    }
++  putchar ('\n');
++
++  return 0;
++}
++
++/* Emulate the "/bin/cp" command.  Options are ignored.  Only copies
++   one source file to one destination file.  Directory destinations
++   are not supported.  */
++static int
++copy_func (char **argv)
++{
++  char *sname = argv[0];
++  char *dname = argv[1];
++  int sfd, dfd;
++  struct stat st;
++
++  sfd = open (sname, O_RDONLY);
++  if (sfd < 0)
++    {
++      fprintf (stderr, "cp: unable to open %s for reading: %s\n",
++	       sname, strerror (errno));
++      return 1;
++    }
++
++  if (fstat (sfd, &st) < 0)
++    {
++      fprintf (stderr, "cp: unable to fstat %s: %s\n",
++	       sname, strerror (errno));
++      return 1;
++    }
++
++  dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
++  if (dfd < 0)
++    {
++      fprintf (stderr, "cp: unable to open %s for writing: %s\n",
++	       dname, strerror (errno));
++      return 1;
++    }
++
++  if (support_copy_file_range (sfd, 0, dfd, 0, st.st_size, 0) != st.st_size)
++    {
++      fprintf (stderr, "cp: cannot copy file %s to %s: %s\n",
++	       sname, dname, strerror (errno));
++      return 1;
++    }
++
++  close (sfd);
++  close (dfd);
++
++  chmod (dname, st.st_mode & 0777);
++
++  return 0;
++
++}
++
++/* This is a list of all the built-in commands we understand.  */
++static struct {
++  const char *name;
++  int (*func) (char **argv);
++} builtin_funcs[] = {
++  { "true", true_func },
++  { "echo", echo_func },
++  { "cp", copy_func },
++  { NULL, NULL }
++};
++
++/* Run one tokenized command.  argv[0] is the command.  argv is
++   NULL-terminated.  */
++static void
++run_command_array (char **argv)
++{
++  int i, j;
++  pid_t pid;
++  int status;
++  int (*builtin_func) (char **args);
++
++  if (argv[0] == NULL)
++    return;
++
++  builtin_func = NULL;
++
++  int new_stdin = 0;
++  int new_stdout = 1;
++  int new_stderr = 2;
++
++  dprintf (stderr, "run_command_array starting\n");
++  for (i = 0; argv[i]; i++)
++    dprintf (stderr, "   argv [%d] `%s'\n", i, argv[i]);
++
++  for (j = i = 0; argv[i]; i++)
++    {
++      if (strcmp (argv[i], "<") == 0 && argv[i + 1])
++	{
++	  new_stdin = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777);
++	  ++i;
++	  continue;
++	}
++      if (strcmp (argv[i], ">") == 0 && argv[i + 1])
++	{
++	  new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777);
++	  ++i;
++	  continue;
++	}
++      if (strcmp (argv[i], ">>") == 0 && argv[i + 1])
++	{
++	  new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_APPEND, 0777);
++	  ++i;
++	  continue;
++	}
++      if (strcmp (argv[i], "2>") == 0 && argv[i + 1])
++	{
++	  new_stderr = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777);
++	  ++i;
++	  continue;
++	}
++      argv[j++] = argv[i];
++    }
++  argv[j] = NULL;
++
++
++  for (i = 0; builtin_funcs[i].name != NULL; i++)
++    if (strcmp (argv[0], builtin_funcs[i].name) == 0)
++       builtin_func = builtin_funcs[i].func;
++
++  dprintf (stderr, "builtin %p argv0 `%s'\n", builtin_func, argv[0]);
++
++  pid = fork ();
++  if (pid < 0)
++    {
++      fprintf (stderr, "sh: fork failed\n");
++      exit (1);
++    }
++
++  if (pid == 0)
++    {
++      if (new_stdin != 0)
++	{
++	  dup2 (new_stdin, 0);
++	  close (new_stdin);
++	}
++      if (new_stdout != 1)
++	{
++	  dup2 (new_stdout, 1);
++	  close (new_stdout);
++	}
++      if (new_stderr != 2)
++	{
++	  dup2 (new_stderr, 2);
++	  close (new_stdout);
++	}
++
++      if (builtin_func != NULL)
++	exit (builtin_func (argv + 1));
++
++      execvp (argv[0], argv);
++
++      fprintf (stderr, "sh: execing %s failed: %s",
++	       argv[0], strerror (errno));
++      exit (1);
++    }
++
++  waitpid (pid, &status, 0);
++
++  dprintf (stderr, "exiting run_command_array\n");
++
++  if (WIFEXITED (status))
++    {
++      int rv = WEXITSTATUS (status);
++      if (rv)
++	exit (rv);
++    }
++  else
++    exit (1);
++}
++
++/* Run one command-as-a-string, by tokenizing it.  Limited to
++   MAX_ARG_COUNT arguments.  Simple substitution is done of $1 to $9
++   (as whole separate tokens) from iargs[].  Quoted strings work if
++   the quotes wrap whole tokens; i.e. "foo bar" but not foo" bar".  */
++static void
++run_command_string (const char *cmdline, const char **iargs)
++{
++  char *args[MAX_ARG_COUNT+1];
++  int ap = 0;
++  const char *start, *end;
++  int nargs;
++
++  for (nargs = 0; iargs[nargs] != NULL; ++nargs)
++    ;
++
++  dprintf (stderr, "run_command_string starting: '%s'\n", cmdline);
++
++  while (ap < MAX_ARG_COUNT)
++    {
++      /* If the argument is quoted, this is the quote character, else NUL.  */
++      int in_quote = 0;
++
++      /* Skip whitespace up to the next token.  */
++      while (*cmdline && isspace (*cmdline))
++	cmdline ++;
++      if (*cmdline == 0)
++	break;
++
++      start = cmdline;
++      /* Check for quoted argument.  */
++      in_quote = (*cmdline == '\'' || *cmdline == '"') ? *cmdline : 0;
++
++      /* Skip to end of token; either by whitespace or matching quote.  */
++      dprintf (stderr, "in_quote %d\n", in_quote);
++      while (*cmdline
++	     && (!isspace (*cmdline) || in_quote))
++	{
++	  if (*cmdline == in_quote
++	      && cmdline != start)
++	    in_quote = 0;
++	  dprintf (stderr, "[%c]%d ", *cmdline, in_quote);
++	  cmdline ++;
++	}
++      dprintf (stderr, "\n");
++
++      /* Allocate space for this token and store it in args[].  */
++      end = cmdline;
++      dprintf (stderr, "start<%s> end<%s>\n", start, end);
++      args[ap] = (char *) xmalloc (end - start + 1);
++      memcpy (args[ap], start, end - start);
++      args[ap][end - start] = 0;
++
++      /* Strip off quotes, if found.  */
++      dprintf (stderr, "args[%d] = <%s>\n", ap, args[ap]);
++      if (args[ap][0] == '\''
++	  && args[ap][strlen (args[ap])-1] == '\'')
++	{
++	  args[ap][strlen (args[ap])-1] = 0;
++	  args[ap] ++;
++	}
++
++      else if (args[ap][0] == '"'
++	  && args[ap][strlen (args[ap])-1] == '"')
++	{
++	  args[ap][strlen (args[ap])-1] = 0;
++	  args[ap] ++;
++	}
++
++      /* Replace positional parameters like $4.  */
++      else if (args[ap][0] == '$'
++	       && isdigit (args[ap][1])
++	       && args[ap][2] == 0)
++	{
++	  int a = args[ap][1] - '1';
++	  if (0 <= a && a < nargs)
++	    args[ap] = strdup (iargs[a]);
++	}
++
++      ap ++;
++
++      if (*cmdline == 0)
++	break;
++    }
++
++  /* Lastly, NULL terminate the array and run it.  */
++  args[ap] = NULL;
++  run_command_array (args);
++}
++
++/* Run a script by reading lines and passing them to the above
++   function.  */
++static void
++run_script (const char *filename, const char **args)
++{
++  char line[MAX_LINE_LENGTH + 1];
++  dprintf (stderr, "run_script starting: '%s'\n", filename);
++  FILE *f = fopen (filename, "r");
++  if (f == NULL)
++    {
++      fprintf (stderr, "sh: %s: %s\n", filename, strerror (errno));
++      exit (1);
++    }
++  while (fgets (line, sizeof (line), f) != NULL)
++    {
++      if (line[0] == '#')
++	{
++	  dprintf (stderr, "comment: %s\n", line);
++	  continue;
++	}
++      run_command_string (line, args);
++    }
++  fclose (f);
++}
++
++int
++main (int argc, const char **argv)
++{
++  int i;
++
++  if (strcmp (argv[1], "--debug") == 0)
++    {
++      debug_mode = 1;
++      --argc;
++      ++argv;
++    }
++
++  dprintf (stderr, "container-sh starting:\n");
++  for (i = 0; i < argc; i++)
++    dprintf (stderr, "  argv[%d] is `%s'\n", i, argv[i]);
++
++  if (strcmp (argv[1], "-c") == 0)
++    run_command_string (argv[2], argv+3);
++  else
++    run_script (argv[1], argv+2);
++
++  dprintf (stderr, "normal exit 0\n");
++  return 0;
++}
+diff --git a/support/support-xfstat.c b/support/support-xfstat.c
+new file mode 100644
+index 0000000000..f69253af09
+--- /dev/null
++++ b/support/support-xfstat.c
+@@ -0,0 +1,28 @@
++/* fstat64 with error checking.
++   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/check.h>
++#include <support/xunistd.h>
++#include <sys/stat.h>
++
++void
++xfstat (int fd, struct stat64 *result)
++{
++  if (fstat64 (fd, result) != 0)
++    FAIL_EXIT1 ("fstat64 (%d): %m", fd);
++}
+diff --git a/support/support-xstat.c b/support/support-xstat.c
+new file mode 100644
+index 0000000000..fc10c6dcb7
+--- /dev/null
++++ b/support/support-xstat.c
+@@ -0,0 +1,30 @@
++/* stat64 with error checking.
++   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* NB: Non-standard file name to avoid sysdeps override for xstat.  */
++
++#include <support/check.h>
++#include <support/xunistd.h>
++#include <sys/stat.h>
++
++void
++xstat (const char *path, struct stat64 *result)
++{
++  if (stat64 (path, result) != 0)
++    FAIL_EXIT1 ("stat64 (\"%s\"): %m", path);
 +}
 diff --git a/support/support.h b/support/support.h
 new file mode 100644
-index 0000000000..bc5827ed87
+index 0000000000..9418cd11ef
 --- /dev/null
 +++ b/support/support.h
-@@ -0,0 +1,75 @@
+@@ -0,0 +1,108 @@
 +/* Common extra functions.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -2958,6 +3861,10 @@ index 0000000000..bc5827ed87
 +
 +#include <stddef.h>
 +#include <sys/cdefs.h>
++/* For mode_t.  */
++#include <sys/stat.h>
++/* For ssize_t and off64_t.  */
++#include <sys/types.h>
 +
 +__BEGIN_DECLS
 +
@@ -2992,6 +3899,18 @@ index 0000000000..bc5827ed87
 +   process on error.  */
 +void support_write_file_string (const char *path, const char *contents);
 +
++/* Quote the contents of the byte array starting at BLOB, of LENGTH
++   bytes, in such a way that the result string can be included in a C
++   literal (in single/double quotes, without putting the quotes into
++   the result).  */
++char *support_quote_blob (const void *blob, size_t length);
++
++/* Returns non-zero if the file descriptor is a regular file on a file
++   system which supports holes (that is, seeking and writing does not
++   allocate storage for the range of zeros).  FD must refer to a
++   regular file open for writing, and initially empty.  */
++int support_descriptor_supports_holes (int fd);
++
 +/* Error-checking wrapper functions which terminate the process on
 +   error.  */
 +
@@ -3003,6 +3922,23 @@ index 0000000000..bc5827ed87
 +char *xstrdup (const char *);
 +char *xstrndup (const char *, size_t);
 +
++/* These point to the TOP of the source/build tree, not your (or
++   support's) subdirectory.  */
++extern const char support_srcdir_root[];
++extern const char support_objdir_root[];
++
++/* Corresponds to the path to the runtime linker used by the testsuite,
++   e.g. OBJDIR_PATH/elf/ld-linux-x86-64.so.2  */
++extern const char support_objdir_elf_ldso[];
++
++/* Corresponds to the --prefix= passed to configure.  */
++extern const char support_install_prefix[];
++/* Corresponds to the install's lib/ or lib64/ directory.  */
++extern const char support_libdir_prefix[];
++
++extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
++					size_t, unsigned int);
++
 +__END_DECLS
 +
 +#endif /* SUPPORT_H */
@@ -3459,14 +4395,14 @@ index 0000000000..6356b1af6c
 +  free (chroot->path_host_conf);
 +  free (chroot);
 +}
-diff --git a/support/support_enter_mount_namespace.c b/support/support_enter_mount_namespace.c
+diff --git a/support/support_copy_file_range.c b/support/support_copy_file_range.c
 new file mode 100644
-index 0000000000..ba68e990f2
+index 0000000000..9a1e39773e
 --- /dev/null
-+++ b/support/support_enter_mount_namespace.c
-@@ -0,0 +1,47 @@
-+/* Enter a mount namespace.
-+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++++ b/support/support_copy_file_range.c
+@@ -0,0 +1,143 @@
++/* Simplified copy_file_range with cross-device copy.
++   Copyright (C) 2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
 +
 +   The GNU C Library is free software; you can redistribute it and/or
@@ -3483,39 +4419,281 @@ index 0000000000..ba68e990f2
 +   License along with the GNU C Library; if not, see
 +   <http://www.gnu.org/licenses/>.  */
 +
-+#include <support/namespace.h>
-+
-+#include <sched.h>
-+#include <stdio.h>
-+#ifdef CLONE_NEWNS
-+# include <sys/mount.h>
-+#endif /* CLONE_NEWNS */
++#include <errno.h>
++#include <fcntl.h>
++#include <inttypes.h>
++#include <limits.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <unistd.h>
++#include <support/support.h>
 +
-+bool
-+support_enter_mount_namespace (void)
++ssize_t
++support_copy_file_range (int infd, __off64_t *pinoff,
++			 int outfd, __off64_t *poutoff,
++			 size_t length, unsigned int flags)
 +{
-+#ifdef CLONE_NEWNS
-+  if (unshare (CLONE_NEWNS) == 0)
++  if (flags != 0)
 +    {
-+      /* On some systems, / is marked as MS_SHARED, which means that
-+         mounts within the namespace leak to the rest of the system,
-+         which is not what we want.  */
-+      if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0)
-+        {
-+          printf ("warning: making the mount namespace private failed: %m\n");
-+          return false;
-+        }
-+      return true;
++      errno = EINVAL;
++      return -1;
 +    }
-+  else
-+    printf ("warning: unshare (CLONE_NEWNS) failed: %m\n");
-+#endif /* CLONE_NEWNS */
-+  return false;
-+}
-diff --git a/support/support_enter_network_namespace.c b/support/support_enter_network_namespace.c
-new file mode 100644
-index 0000000000..1d874df885
---- /dev/null
++
++  struct stat64 instat;
++  struct stat64 outstat;
++  if (fstat64 (infd, &instat) != 0 || fstat64 (outfd, &outstat) != 0)
++    return -1;
++  if (S_ISDIR (instat.st_mode) || S_ISDIR (outstat.st_mode))
++    {
++      errno = EISDIR;
++      return -1;
++    }
++  if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode))
++    {
++      /* We need a regular input file so that the we can seek
++	 backwards in case of a write failure.  */
++      errno = EINVAL;
++      return -1;
++    }
++
++  /* The output descriptor must not have O_APPEND set.  */
++  if (fcntl (outfd, F_GETFL) & O_APPEND)
++    {
++      errno = EBADF;
++      return -1;
++    }
++
++  /* Avoid an overflow in the result.  */
++  if (length > SSIZE_MAX)
++    length = SSIZE_MAX;
++
++  /* Main copying loop.  The buffer size is arbitrary and is a
++     trade-off between stack size consumption, cache usage, and
++     amortization of system call overhead.  */
++  size_t copied = 0;
++  char buf[8192];
++  while (length > 0)
++    {
++      size_t to_read = length;
++      if (to_read > sizeof (buf))
++	to_read = sizeof (buf);
++
++      /* Fill the buffer.  */
++      ssize_t read_count;
++      if (pinoff == NULL)
++	read_count = read (infd, buf, to_read);
++      else
++	read_count = pread64 (infd, buf, to_read, *pinoff);
++      if (read_count == 0)
++	/* End of file reached prematurely.  */
++	return copied;
++      if (read_count < 0)
++	{
++	  if (copied > 0)
++	    /* Report the number of bytes copied so far.  */
++	    return copied;
++	  return -1;
++	}
++      if (pinoff != NULL)
++	*pinoff += read_count;
++
++      /* Write the buffer part which was read to the destination.  */
++      char *end = buf + read_count;
++      for (char *p = buf; p < end; )
++	{
++	  ssize_t write_count;
++	  if (poutoff == NULL)
++	    write_count = write (outfd, p, end - p);
++	  else
++	    write_count = pwrite64 (outfd, p, end - p, *poutoff);
++	  if (write_count < 0)
++	    {
++	      /* Adjust the input read position to match what we have
++		 written, so that the caller can pick up after the
++		 error.  */
++	      size_t written = p - buf;
++	      /* NB: This needs to be signed so that we can form the
++		 negative value below.  */
++	      ssize_t overread = read_count - written;
++	      if (pinoff == NULL)
++		{
++		  if (overread > 0)
++		    {
++		      /* We are on an error recovery path, so we
++			 cannot deal with failure here.  */
++		      int save_errno = errno;
++		      (void) lseek64 (infd, -overread, SEEK_CUR);
++		      errno = save_errno;
++		    }
++		}
++	      else /* pinoff != NULL */
++		*pinoff -= overread;
++
++	      if (copied + written > 0)
++		/* Report the number of bytes copied so far.  */
++		return copied + written;
++	      return -1;
++	    }
++	  p += write_count;
++	  if (poutoff != NULL)
++	    *poutoff += write_count;
++	} /* Write loop.  */
++
++      copied += read_count;
++      length -= read_count;
++    }
++  return copied;
++}
+diff --git a/support/support_descriptor_supports_holes.c b/support/support_descriptor_supports_holes.c
+new file mode 100644
+index 0000000000..c7099ca67c
+--- /dev/null
++++ b/support/support_descriptor_supports_holes.c
+@@ -0,0 +1,87 @@
++/* Test for file system hole support.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdbool.h>
++#include <support.h>
++#include <support/check.h>
++#include <sys/stat.h>
++#include <xunistd.h>
++
++int
++support_descriptor_supports_holes (int fd)
++{
++  enum
++    {
++      /* Write offset for the enlarged file.  This value is arbitrary
++         and hopefully large enough to trigger the creation of holes.
++         We cannot use the file system block size as a reference here
++         because it is incorrect for network file systems.  */
++      write_offset = 16 * 1024 * 1024,
++
++      /* Our write may add this number of additional blocks (see
++         block_limit below).  */
++      block_headroom = 8,
++    };
++
++  struct stat64 st;
++  xfstat (fd, &st);
++  if (!S_ISREG (st.st_mode))
++    FAIL_EXIT1 ("descriptor %d does not refer to a regular file", fd);
++  if (st.st_size != 0)
++    FAIL_EXIT1 ("descriptor %d does not refer to an empty file", fd);
++  if (st.st_blocks > block_headroom)
++    FAIL_EXIT1 ("descriptor %d refers to a pre-allocated file (%lld blocks)",
++                fd, (long long int) st.st_blocks);
++
++  /* Write a single byte at the start of the file to compute the block
++     usage for a single byte.  */
++  xlseek (fd, 0, SEEK_SET);
++  char b = '@';
++  xwrite (fd, &b, 1);
++  /* Attempt to bypass delayed allocation.  */
++  TEST_COMPARE (fsync (fd), 0);
++  xfstat (fd, &st);
++
++  /* This limit is arbitrary.  The file system needs to store
++     somewhere that data exists at the write offset, and this may
++     moderately increase the number of blocks used by the file, in
++     proportion to the initial block count, but not in proportion to
++     the write offset.  */
++  unsigned long long int block_limit = 2 * st.st_blocks + block_headroom;
++
++  /* Write a single byte at 16 megabytes.  */
++  xlseek (fd, write_offset, SEEK_SET);
++  xwrite (fd, &b, 1);
++  /* Attempt to bypass delayed allocation.  */
++  TEST_COMPARE (fsync (fd), 0);
++  xfstat (fd, &st);
++  bool supports_holes = st.st_blocks <= block_limit;
++
++  /* Also check that extending the file does not fill up holes.  */
++  xftruncate (fd, 2 * write_offset);
++  /* Attempt to bypass delayed allocation.  */
++  TEST_COMPARE (fsync (fd), 0);
++  xfstat (fd, &st);
++  supports_holes = supports_holes && st.st_blocks <= block_limit;
++
++  /* Return to a zero-length file.  */
++  xftruncate (fd, 0);
++  xlseek (fd, 0, SEEK_SET);
++
++  return supports_holes;
++}
+diff --git a/support/support_enter_mount_namespace.c b/support/support_enter_mount_namespace.c
+new file mode 100644
+index 0000000000..ba68e990f2
+--- /dev/null
++++ b/support/support_enter_mount_namespace.c
+@@ -0,0 +1,47 @@
++/* Enter a mount namespace.
++   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/namespace.h>
++
++#include <sched.h>
++#include <stdio.h>
++#ifdef CLONE_NEWNS
++# include <sys/mount.h>
++#endif /* CLONE_NEWNS */
++
++bool
++support_enter_mount_namespace (void)
++{
++#ifdef CLONE_NEWNS
++  if (unshare (CLONE_NEWNS) == 0)
++    {
++      /* On some systems, / is marked as MS_SHARED, which means that
++         mounts within the namespace leak to the rest of the system,
++         which is not what we want.  */
++      if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0)
++        {
++          printf ("warning: making the mount namespace private failed: %m\n");
++          return false;
++        }
++      return true;
++    }
++  else
++    printf ("warning: unshare (CLONE_NEWNS) failed: %m\n");
++#endif /* CLONE_NEWNS */
++  return false;
++}
+diff --git a/support/support_enter_network_namespace.c b/support/support_enter_network_namespace.c
+new file mode 100644
+index 0000000000..1d874df885
+--- /dev/null
 +++ b/support/support_enter_network_namespace.c
 @@ -0,0 +1,75 @@
 +/* Enter a network namespace.
@@ -3636,10 +4814,10 @@ index 0000000000..2acb9afffd
 +}
 diff --git a/support/support_format_addrinfo.c b/support/support_format_addrinfo.c
 new file mode 100644
-index 0000000000..c5e00e516a
+index 0000000000..60d2cc40f6
 --- /dev/null
 +++ b/support/support_format_addrinfo.c
-@@ -0,0 +1,240 @@
+@@ -0,0 +1,242 @@
 +/* Convert struct addrinfo values to a string.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -3709,8 +4887,6 @@ index 0000000000..c5e00e516a
 +      FLAG (AI_ADDRCONFIG);
 +      FLAG (AI_IDN);
 +      FLAG (AI_CANONIDN);
-+      FLAG (AI_IDN_ALLOW_UNASSIGNED);
-+      FLAG (AI_IDN_USE_STD3_ASCII_RULES);
 +      FLAG (AI_NUMERICSERV);
 +#undef FLAG
 +      int remaining = ai->ai_flags & ~flags_printed;
@@ -3862,7 +5038,11 @@ index 0000000000..c5e00e516a
 +  xopen_memstream (&mem);
 +  if (ret != 0)
 +    {
-+      fprintf (mem.out, "error: %s\n", gai_strerror (ret));
++      const char *errmsg = gai_strerror (ret);
++      if (strcmp (errmsg, "Unknown error") == 0)
++        fprintf (mem.out, "error: Unknown error %d\n", ret);
++      else
++        fprintf (mem.out, "error: %s\n", errmsg);
 +      if (ret == EAI_SYSTEM)
 +        {
 +          errno = errno_copy;
@@ -4351,6 +5531,275 @@ index 0000000000..25edc00385
 +  if (status != 0)
 +    FAIL_EXIT1 ("child process exited with status %d", status);
 +}
+diff --git a/support/support_openpty.c b/support/support_openpty.c
+new file mode 100644
+index 0000000000..ac779ab91e
+--- /dev/null
++++ b/support/support_openpty.c
+@@ -0,0 +1,109 @@
++/* Open a pseudoterminal.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/tty.h>
++#include <support/check.h>
++#include <support/support.h>
++
++#include <errno.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <fcntl.h>
++#include <termios.h>
++#include <sys/ioctl.h>
++#include <unistd.h>
++
++/* As ptsname, but allocates space for an appropriately-sized string
++   using malloc.  */
++static char *
++xptsname (int fd)
++{
++  int rv;
++  size_t buf_len = 128;
++  char *buf = xmalloc (buf_len);
++  for (;;)
++    {
++      rv = ptsname_r (fd, buf, buf_len);
++      if (rv)
++        FAIL_EXIT1 ("ptsname_r: %s", strerror (errno));
++
++      if (memchr (buf, '\0', buf_len))
++        return buf; /* ptsname succeeded and the buffer was not truncated */
++
++      buf_len *= 2;
++      buf = xrealloc (buf, buf_len);
++    }
++}
++
++void
++support_openpty (int *a_outer, int *a_inner, char **a_name,
++                 const struct termios *termp,
++                 const struct winsize *winp)
++{
++  int outer = -1, inner = -1;
++  char *namebuf = 0;
++
++  outer = posix_openpt (O_RDWR | O_NOCTTY);
++  if (outer == -1)
++    FAIL_EXIT1 ("posix_openpt: %s", strerror (errno));
++
++  if (grantpt (outer))
++    FAIL_EXIT1 ("grantpt: %s", strerror (errno));
++
++  if (unlockpt (outer))
++    FAIL_EXIT1 ("unlockpt: %s", strerror (errno));
++
++
++#ifdef TIOCGPTPEER
++  inner = ioctl (outer, TIOCGPTPEER, O_RDWR | O_NOCTTY);
++#endif
++  if (inner == -1)
++    {
++      /* The kernel might not support TIOCGPTPEER, fall back to open
++         by name.  */
++      namebuf = xptsname (outer);
++      inner = open (namebuf, O_RDWR | O_NOCTTY);
++      if (inner == -1)
++        FAIL_EXIT1 ("%s: %s", namebuf, strerror (errno));
++    }
++
++  if (termp)
++    {
++      if (tcsetattr (inner, TCSAFLUSH, termp))
++        FAIL_EXIT1 ("tcsetattr: %s", strerror (errno));
++    }
++#ifdef TIOCSWINSZ
++  if (winp)
++    {
++      if (ioctl (inner, TIOCSWINSZ, winp))
++        FAIL_EXIT1 ("TIOCSWINSZ: %s", strerror (errno));
++    }
++#endif
++
++  if (a_name)
++    {
++      if (!namebuf)
++        namebuf = xptsname (outer);
++      *a_name = namebuf;
++    }
++  else
++    free (namebuf);
++  *a_outer = outer;
++  *a_inner = inner;
++}
+diff --git a/support/support_paths.c b/support/support_paths.c
+new file mode 100644
+index 0000000000..6d0beb102c
+--- /dev/null
++++ b/support/support_paths.c
+@@ -0,0 +1,59 @@
++/* Various paths that might be needed.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/support.h>
++#include <support/check.h>
++
++/* The idea here is to make various makefile-level paths available to
++   support programs, as canonicalized absolute paths.  */
++
++/* These point to the TOP of the source/build tree, not your (or
++   support's) subdirectory.  */
++#ifdef SRCDIR_PATH
++const char support_srcdir_root[] = SRCDIR_PATH;
++#else
++# error please -DSRCDIR_PATH=something in the Makefile
++#endif
++
++#ifdef OBJDIR_PATH
++const char support_objdir_root[] = OBJDIR_PATH;
++#else
++# error please -DOBJDIR_PATH=something in the Makefile
++#endif
++
++#ifdef OBJDIR_ELF_LDSO_PATH
++/* Corresponds to the path to the runtime linker used by the testsuite,
++   e.g. OBJDIR_PATH/elf/ld-linux-x86-64.so.2  */
++const char support_objdir_elf_ldso[] = OBJDIR_ELF_LDSO_PATH;
++#else
++# error please -DOBJDIR_ELF_LDSO_PATH=something in the Makefile
++#endif
++
++#ifdef INSTDIR_PATH
++/* Corresponds to the --prefix= passed to configure.  */
++const char support_install_prefix[] = INSTDIR_PATH;
++#else
++# error please -DINSTDIR_PATH=something in the Makefile
++#endif
++
++#ifdef LIBDIR_PATH
++/* Corresponds to the install's lib/ or lib64/ directory.  */
++const char support_libdir_prefix[] = LIBDIR_PATH;
++#else
++# error please -DLIBDIR_PATH=something in the Makefile
++#endif
+diff --git a/support/support_quote_blob.c b/support/support_quote_blob.c
+new file mode 100644
+index 0000000000..d6a678d8d6
+--- /dev/null
++++ b/support/support_quote_blob.c
+@@ -0,0 +1,83 @@
++/* Quote a blob so that it can be used in C literals.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/support.h>
++#include <support/xmemstream.h>
++
++char *
++support_quote_blob (const void *blob, size_t length)
++{
++  struct xmemstream out;
++  xopen_memstream (&out);
++
++  const unsigned char *p = blob;
++  for (size_t i = 0; i < length; ++i)
++    {
++      unsigned char ch = p[i];
++
++      /* Use C backslash escapes for those control characters for
++         which they are defined.  */
++      switch (ch)
++        {
++          case '\a':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked ('a', out.out);
++            break;
++          case '\b':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked ('b', out.out);
++            break;
++          case '\f':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked ('f', out.out);
++            break;
++          case '\n':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked ('n', out.out);
++            break;
++          case '\r':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked ('r', out.out);
++            break;
++          case '\t':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked ('t', out.out);
++            break;
++          case '\v':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked ('v', out.out);
++            break;
++          case '\\':
++          case '\'':
++          case '\"':
++            putc_unlocked ('\\', out.out);
++            putc_unlocked (ch, out.out);
++            break;
++        default:
++          if (ch < ' ' || ch > '~')
++            /* Use octal sequences because they are fixed width,
++               unlike hexadecimal sequences.  */
++            fprintf (out.out, "\\%03o", ch);
++          else
++            putc_unlocked (ch, out.out);
++        }
++    }
++
++  xfclose_memstream (&out);
++  return out.buffer;
++}
 diff --git a/support/support_record_failure.c b/support/support_record_failure.c
 new file mode 100644
 index 0000000000..356798f556
@@ -4608,14 +6057,14 @@ index 0000000000..8ab43c4b38
 +  struct header *header = data - offsetof (struct header, data);
 +  xmunmap (header, header->total_size);
 +}
-diff --git a/support/support_test_compare_failure.c b/support/support_test_compare_failure.c
+diff --git a/support/support_test_compare_blob.c b/support/support_test_compare_blob.c
 new file mode 100644
-index 0000000000..e5596fd121
+index 0000000000..c5e63d1b93
 --- /dev/null
-+++ b/support/support_test_compare_failure.c
-@@ -0,0 +1,55 @@
-+/* Reporting a numeric comparison failure.
-+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++++ b/support/support_test_compare_blob.c
+@@ -0,0 +1,76 @@
++/* Check two binary blobs for equality.
++   Copyright (C) 2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
 +
 +   The GNU C Library is free software; you can redistribute it and/or
@@ -4633,18 +6082,101 @@ index 0000000000..e5596fd121
 +   <http://www.gnu.org/licenses/>.  */
 +
 +#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
 +#include <support/check.h>
++#include <support/support.h>
++#include <support/xmemstream.h>
 +
 +static void
-+report (const char *which, const char *expr, long long value, int positive,
-+        int size)
++report_length (const char *what, unsigned long int length, const char *expr)
 +{
-+  printf ("  %s: ", which);
-+  if (positive)
-+    printf ("%llu", (unsigned long long) value);
-+  else
-+    printf ("%lld", value);
-+  unsigned long long mask
++  printf ("  %s %lu bytes (from %s)\n", what, length, expr);
++}
++
++static void
++report_blob (const char *what, const unsigned char *blob,
++             unsigned long int length, const char *expr)
++{
++  if (length > 0)
++    {
++      printf ("  %s (evaluated from %s):\n", what, expr);
++      char *quoted = support_quote_blob (blob, length);
++      printf ("      \"%s\"\n", quoted);
++      free (quoted);
++
++      fputs ("     ", stdout);
++      for (unsigned long i = 0; i < length; ++i)
++        printf (" %02X", blob[i]);
++      putc ('\n', stdout);
++    }
++}
++
++void
++support_test_compare_blob (const void *left, unsigned long int left_length,
++                           const void *right, unsigned long int right_length,
++                           const char *file, int line,
++                           const char *left_expr, const char *left_len_expr,
++                           const char *right_expr, const char *right_len_expr)
++{
++  /* No differences are possible if both lengths are null.  */
++  if (left_length == 0 && right_length == 0)
++    return;
++
++  if (left_length != right_length || left == NULL || right == NULL
++      || memcmp (left, right, left_length) != 0)
++    {
++      support_record_failure ();
++      printf ("%s:%d: error: blob comparison failed\n", file, line);
++      if (left_length == right_length)
++        printf ("  blob length: %lu bytes\n", left_length);
++      else
++        {
++          report_length ("left length: ", left_length, left_len_expr);
++          report_length ("right length:", right_length, right_len_expr);
++        }
++      report_blob ("left", left, left_length, left_expr);
++      report_blob ("right", right, right_length, right_expr);
++    }
++}
+diff --git a/support/support_test_compare_failure.c b/support/support_test_compare_failure.c
+new file mode 100644
+index 0000000000..8eb51c439d
+--- /dev/null
++++ b/support/support_test_compare_failure.c
+@@ -0,0 +1,58 @@
++/* Reporting a numeric comparison failure.
++   Copyright (C) 2017-2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <stdio.h>
++#include <support/check.h>
++
++static void
++report (const char *which, const char *expr, long long value, int positive,
++        int size)
++{
++  printf ("  %s: ", which);
++  if (positive)
++    printf ("%llu", (unsigned long long) value);
++  else
++    printf ("%lld", value);
++  unsigned long long mask
 +    = (~0ULL) >> (8 * (sizeof (unsigned long long) - size));
 +  printf (" (0x%llx); from: %s\n", (unsigned long long) value & mask, expr);
 +}
@@ -4660,6 +6192,7 @@ index 0000000000..e5596fd121
 +                              int right_positive,
 +                              int right_size)
 +{
++  int saved_errno = errno;
 +  support_record_failure ();
 +  if (left_size != right_size)
 +    printf ("%s:%d: numeric comparison failure (widths %d and %d)\n",
@@ -4668,13 +6201,111 @@ index 0000000000..e5596fd121
 +    printf ("%s:%d: numeric comparison failure\n", file, line);
 +  report (" left", left_expr, left_value, left_positive, left_size);
 +  report ("right", right_expr, right_value, right_positive, right_size);
++  errno = saved_errno;
++}
+diff --git a/support/support_test_compare_string.c b/support/support_test_compare_string.c
+new file mode 100644
+index 0000000000..a76ba8eda7
+--- /dev/null
++++ b/support/support_test_compare_string.c
+@@ -0,0 +1,91 @@
++/* Check two strings for equality.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/xmemstream.h>
++
++static void
++report_length (const char *what, const char *str, size_t length)
++{
++  if (str == NULL)
++    printf ("  %s string: NULL\n", what);
++  else
++    printf ("  %s string: %zu bytes\n", what, length);
++}
++
++static void
++report_string (const char *what, const unsigned char *blob,
++               size_t length, const char *expr)
++{
++  if (length > 0)
++    {
++      printf ("  %s (evaluated from %s):\n", what, expr);
++      char *quoted = support_quote_blob (blob, length);
++      printf ("      \"%s\"\n", quoted);
++      free (quoted);
++
++      fputs ("     ", stdout);
++      for (size_t i = 0; i < length; ++i)
++        printf (" %02X", blob[i]);
++      putc ('\n', stdout);
++    }
++}
++
++static size_t
++string_length_or_zero (const char *str)
++{
++  if (str == NULL)
++    return 0;
++  else
++    return strlen (str);
++}
++
++void
++support_test_compare_string (const char *left, const char *right,
++                             const char *file, int line,
++                             const char *left_expr, const char *right_expr)
++{
++  /* Two null pointers are accepted.  */
++  if (left == NULL && right == NULL)
++    return;
++
++  size_t left_length = string_length_or_zero (left);
++  size_t right_length = string_length_or_zero (right);
++
++  if (left_length != right_length || left == NULL || right == NULL
++      || memcmp (left, right, left_length) != 0)
++    {
++      support_record_failure ();
++      printf ("%s:%d: error: blob comparison failed\n", file, line);
++      if (left_length == right_length && right != NULL && left != NULL)
++        printf ("  string length: %zu bytes\n", left_length);
++      else
++        {
++          report_length ("left", left, left_length);
++          report_length ("right", right, right_length);
++        }
++      report_string ("left", (const unsigned char *) left,
++                     left_length, left_expr);
++      report_string ("right", (const unsigned char *) right,
++                     right_length, right_expr);
++    }
 +}
 diff --git a/support/support_test_main.c b/support/support_test_main.c
 new file mode 100644
-index 0000000000..396385729b
+index 0000000000..23429779ac
 --- /dev/null
 +++ b/support/support_test_main.c
-@@ -0,0 +1,424 @@
+@@ -0,0 +1,425 @@
 +/* Main worker function for the test driver.
 +   Copyright (C) 1998-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -4947,7 +6578,8 @@ index 0000000000..396385729b
 +    timeout =  DEFAULT_TIMEOUT;
 +
 +  /* Make sure we see all message, even those on stdout.  */
-+  setvbuf (stdout, NULL, _IONBF, 0);
++  if (!config->no_setvbuf)
++    setvbuf (stdout, NULL, _IONBF, 0);
 +
 +  /* Make sure temporary files are deleted.  */
 +  if (support_delete_temp_files != NULL)
@@ -5101,10 +6733,10 @@ index 0000000000..396385729b
 +}
 diff --git a/support/support_test_verify_impl.c b/support/support_test_verify_impl.c
 new file mode 100644
-index 0000000000..80311a8265
+index 0000000000..5ff5555a6a
 --- /dev/null
 +++ b/support/support_test_verify_impl.c
-@@ -0,0 +1,37 @@
+@@ -0,0 +1,40 @@
 +/* Implementation of the TEST_VERIFY and TEST_VERIFY_EXIT macros.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -5125,14 +6757,17 @@ index 0000000000..80311a8265
 +
 +#include <support/check.h>
 +
++#include <errno.h>
 +#include <stdio.h>
 +#include <stdlib.h>
 +
 +void
 +support_test_verify_impl (const char *file, int line, const char *expr)
 +{
++  int saved_errno = errno;
 +  support_record_failure ();
 +  printf ("error: %s:%d: not true: %s\n", file, line, expr);
++  errno = saved_errno;
 +}
 +
 +void
@@ -5406,29 +7041,1023 @@ index 0000000000..c7795cc577
 +
 +__BEGIN_DECLS
 +
-+/* Schedule a temporary file for deletion on exit.  */
-+void add_temp_file (const char *name);
++/* Schedule a temporary file for deletion on exit.  */
++void add_temp_file (const char *name);
++
++/* Create a temporary file.  Return the opened file descriptor on
++   success, or -1 on failure.  Write the file name to *FILENAME if
++   FILENAME is not NULL.  In this case, the caller is expected to free
++   *FILENAME.  */
++int create_temp_file (const char *base, char **filename);
++
++/* Create a temporary directory and schedule it for deletion.  BASE is
++   used as a prefix for the unique directory name, which the function
++   returns.  The caller should free this string.  */
++char *support_create_temp_directory (const char *base);
++
++__END_DECLS
++
++#endif /* SUPPORT_TEMP_FILE_H */
+diff --git a/support/test-container.c b/support/test-container.c
+new file mode 100644
+index 0000000000..b58f0f7b3d
+--- /dev/null
++++ b/support/test-container.c
+@@ -0,0 +1,988 @@
++/* Run a test case in an isolated namespace.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#define _FILE_OFFSET_BITS 64
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sched.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <dirent.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <sys/fcntl.h>
++#include <sys/file.h>
++#include <sys/wait.h>
++#include <stdarg.h>
++#include <sys/sysmacros.h>
++#include <ctype.h>
++#include <utime.h>
++#include <errno.h>
++#include <error.h>
++#include <libc-pointer-arith.h>
++
++#ifdef __linux__
++#include <sys/mount.h>
++#endif
++
++#include <support/support.h>
++#include <support/xunistd.h>
++#include "check.h"
++#include "test-driver.h"
++
++#ifndef __linux__
++#define mount(s,t,fs,f,d) no_mount()
++int no_mount (void)
++{
++  FAIL_UNSUPPORTED("mount not supported; port needed");
++}
++#endif
++
++int verbose = 0;
++
++/* Running a test in a container is tricky.  There are two main
++   categories of things to do:
++
++   1. "Once" actions, like setting up the container and doing an
++      install into it.
++
++   2. "Per-test" actions, like copying in support files and
++      configuring the container.
++
++
++   "Once" actions:
++
++   * mkdir $buildroot/testroot.pristine/
++   * install into it
++   * rsync to $buildroot/testroot.root/
++
++   "Per-test" actions:
++   * maybe rsync to $buildroot/testroot.root/
++   * copy support files and test binary
++   * chroot/unshare
++   * set up any mounts (like /proc)
++
++   Magic files:
++
++   For test $srcdir/foo/mytest.c we look for $srcdir/foo/mytest.root
++   and, if found...
++
++   * mytest.root/ is rsync'd into container
++   * mytest.root/preclean.req causes fresh rsync (with delete) before
++     test if present
++   * mytest.root/mytset.script has a list of "commands" to run:
++       syntax:
++         # comment
++         mv FILE FILE
++	 cp FILE FILE
++	 rm FILE
++	 FILE must start with $B/, $S/, $I/, $L/, or /
++	  (expands to build dir, source dir, install dir, library dir
++	   (in container), or container's root)
++   * mytest.root/postclean.req causes fresh rsync (with delete) after
++     test if present
++
++   Note that $srcdir/foo/mytest.script may be used instead of a
++   $srcdir/foo/mytest.root/mytest.script in the sysroot template, if
++   there is no other reason for a sysroot.
++
++   Design goals:
++
++   * independent of other packages which may not be installed (like
++     rsync or Docker, or even "cp")
++
++   * Simple, easy to review code (i.e. prefer simple naive code over
++     complex efficient code)
++
++   * The current implementation ist parallel-make-safe, but only in
++     that it uses a lock to prevent parallel access to the testroot.  */
++
++
++/* Utility Functions */
++
++/* Like xunlink, but it's OK if the file already doesn't exist.  */
++void
++maybe_xunlink (const char *path)
++{
++  int rv = unlink (path);
++  if (rv < 0 && errno != ENOENT)
++    FAIL_EXIT1 ("unlink (\"%s\"): %m", path);
++}
++
++/* Like xmkdir, but it's OK if the directory already exists.  */
++void
++maybe_xmkdir (const char *path, mode_t mode)
++{
++  struct stat st;
++
++  if (stat (path, &st) == 0
++      && S_ISDIR (st.st_mode))
++    return;
++  xmkdir (path, mode);
++}
++
++/* Temporarily concatenate multiple strings into one.  Allows up to 10
++   temporary results; use strdup () if you need them to be
++   permanent.  */
++static char *
++concat (const char *str, ...)
++{
++  /* Assume initialized to NULL/zero.  */
++  static char *bufs[10];
++  static size_t buflens[10];
++  static int bufn = 0;
++  int n;
++  size_t len;
++  va_list ap, ap2;
++  char *cp;
++  char *next;
++
++  va_start (ap, str);
++  va_copy (ap2, ap);
++
++  n = bufn;
++  bufn = (bufn + 1) % 10;
++  len = strlen (str);
++
++  while ((next = va_arg (ap, char *)) != NULL)
++    len = len + strlen (next);
++
++  va_end (ap);
++
++  if (bufs[n] == NULL)
++    {
++      bufs[n] = xmalloc (len + 1); /* NUL */
++      buflens[n] = len + 1;
++    }
++  else if (buflens[n] < len + 1)
++    {
++      bufs[n] = xrealloc (bufs[n], len + 1); /* NUL */
++      buflens[n] = len + 1;
++    }
++
++  strcpy (bufs[n], str);
++  cp = strchr (bufs[n], '\0');
++  while ((next = va_arg (ap2, char *)) != NULL)
++    {
++      strcpy (cp, next);
++      cp = strchr (cp, '\0');
++    }
++  *cp = 0;
++  va_end (ap2);
++
++  return bufs[n];
++}
++
++/* Try to mount SRC onto DEST.  */
++static void
++trymount (const char *src, const char *dest)
++{
++  if (mount (src, dest, "", MS_BIND, NULL) < 0)
++    FAIL_EXIT1 ("can't mount %s onto %s\n", src, dest);
++}
++
++/* Special case of above for devices like /dev/zero where we have to
++   mount a device over a device, not a directory over a directory.  */
++static void
++devmount (const char *new_root_path, const char *which)
++{
++  int fd;
++  fd = open (concat (new_root_path, "/dev/", which, NULL),
++	     O_CREAT | O_TRUNC | O_RDWR, 0777);
++  xclose (fd);
++
++  trymount (concat ("/dev/", which, NULL),
++	    concat (new_root_path, "/dev/", which, NULL));
++}
++
++/* Returns true if the string "looks like" an environement variable
++   being set.  */
++static int
++is_env_setting (const char *a)
++{
++  int count_name = 0;
++
++  while (*a)
++    {
++      if (isalnum (*a) || *a == '_')
++	++count_name;
++      else if (*a == '=' && count_name > 0)
++	return 1;
++      else
++	return 0;
++      ++a;
++    }
++  return 0;
++}
++
++/* Break the_line into words and store in the_words.  Max nwords,
++   returns actual count.  */
++static int
++tokenize (char *the_line, char **the_words, int nwords)
++{
++  int rv = 0;
++
++  while (nwords > 0)
++    {
++      /* Skip leading whitespace, if any.  */
++      while (*the_line && isspace (*the_line))
++	++the_line;
++
++      /* End of line?  */
++      if (*the_line == 0)
++	return rv;
++
++      /* THE_LINE points to a non-whitespace character, so we have a
++	 word.  */
++      *the_words = the_line;
++      ++the_words;
++      nwords--;
++      ++rv;
++
++      /* Skip leading whitespace, if any.  */
++      while (*the_line && ! isspace (*the_line))
++	++the_line;
++
++      /* We now point at the trailing NUL *or* some whitespace.  */
++      if (*the_line == 0)
++	return rv;
++
++      /* It was whitespace, skip and keep tokenizing.  */
++      *the_line++ = 0;
++    }
++
++  /* We get here if we filled the words buffer.  */
++  return rv;
++}
++
++
++/* Mini-RSYNC implementation.  Optimize later.      */
++
++/* A few routines for an "rsync buffer" which stores the paths we're
++   working on.  We continuously grow and shrink the paths in each
++   buffer so there's lot of re-use.  */
++
++/* We rely on "initialized to zero" to set these up.  */
++typedef struct
++{
++  char *buf;
++  size_t len;
++  size_t size;
++} path_buf;
++
++static path_buf spath, dpath;
++
++static void
++r_setup (char *path, path_buf * pb)
++{
++  size_t len = strlen (path);
++  if (pb->buf == NULL || pb->size < len + 1)
++    {
++      /* Round up.  This is an arbitrary number, just to keep from
++	 reallocing too often.  */
++      size_t sz = ALIGN_UP (len + 1, 512);
++      if (pb->buf == NULL)
++	pb->buf = (char *) xmalloc (sz);
++      else
++	pb->buf = (char *) xrealloc (pb->buf, sz);
++      if (pb->buf == NULL)
++	FAIL_EXIT1 ("Out of memory while rsyncing\n");
++
++      pb->size = sz;
++    }
++  strcpy (pb->buf, path);
++  pb->len = len;
++}
++
++static void
++r_append (const char *path, path_buf * pb)
++{
++  size_t len = strlen (path) + pb->len;
++  if (pb->size < len + 1)
++    {
++      /* Round up */
++      size_t sz = ALIGN_UP (len + 1, 512);
++      pb->buf = (char *) xrealloc (pb->buf, sz);
++      if (pb->buf == NULL)
++	FAIL_EXIT1 ("Out of memory while rsyncing\n");
++
++      pb->size = sz;
++    }
++  strcpy (pb->buf + pb->len, path);
++  pb->len = len;
++}
++
++static int
++file_exists (char *path)
++{
++  struct stat st;
++  if (lstat (path, &st) == 0)
++    return 1;
++  return 0;
++}
++
++static void
++recursive_remove (char *path)
++{
++  pid_t child;
++  int status;
++
++  child = fork ();
++
++  switch (child) {
++  case -1:
++    FAIL_EXIT1 ("Unable to fork");
++  case 0:
++    /* Child.  */
++    execlp ("rm", "rm", "-rf", path, NULL);
++  default:
++    /* Parent.  */
++    waitpid (child, &status, 0);
++    /* "rm" would have already printed a suitable error message.  */
++    if (! WIFEXITED (status)
++	|| WEXITSTATUS (status) != 0)
++      exit (1);
++
++    break;
++  }
++}
++
++/* Used for both rsync and the mytest.script "cp" command.  */
++static void
++copy_one_file (const char *sname, const char *dname)
++{
++  int sfd, dfd;
++  struct stat st;
++  struct utimbuf times;
++
++  sfd = open (sname, O_RDONLY);
++  if (sfd < 0)
++    FAIL_EXIT1 ("unable to open %s for reading\n", sname);
++
++  if (fstat (sfd, &st) < 0)
++    FAIL_EXIT1 ("unable to fstat %s\n", sname);
++
++  dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
++  if (dfd < 0)
++    FAIL_EXIT1 ("unable to open %s for writing\n", dname);
++
++  xcopy_file_range (sfd, 0, dfd, 0, st.st_size, 0);
++
++  xclose (sfd);
++  xclose (dfd);
++
++  if (chmod (dname, st.st_mode & 0777) < 0)
++    FAIL_EXIT1 ("chmod %s: %s\n", dname, strerror (errno));
++
++  times.actime = st.st_atime;
++  times.modtime = st.st_mtime;
++  if (utime (dname, &times) < 0)
++    FAIL_EXIT1 ("utime %s: %s\n", dname, strerror (errno));
++}
++
++/* We don't check *everything* about the two files to see if a copy is
++   needed, just the minimum to make sure we get the latest copy.  */
++static int
++need_sync (char *ap, char *bp, struct stat *a, struct stat *b)
++{
++  if ((a->st_mode & S_IFMT) != (b->st_mode & S_IFMT))
++    return 1;
++
++  if (S_ISLNK (a->st_mode))
++    {
++      int rv;
++      char *al, *bl;
++
++      if (a->st_size != b->st_size)
++	return 1;
++
++      al = xreadlink (ap);
++      bl = xreadlink (bp);
++      rv = strcmp (al, bl);
++      free (al);
++      free (bl);
++      if (rv == 0)
++	return 0; /* links are same */
++      return 1; /* links differ */
++    }
++
++  if (verbose)
++    {
++      if (a->st_size != b->st_size)
++	printf ("SIZE\n");
++      if ((a->st_mode & 0777) != (b->st_mode & 0777))
++	printf ("MODE\n");
++      if (a->st_mtime != b->st_mtime)
++	printf ("TIME\n");
++    }
++
++  if (a->st_size == b->st_size
++      && ((a->st_mode & 0777) == (b->st_mode & 0777))
++      && a->st_mtime == b->st_mtime)
++    return 0;
++
++  return 1;
++}
++
++static void
++rsync_1 (path_buf * src, path_buf * dest, int and_delete)
++{
++  DIR *dir;
++  struct dirent *de;
++  struct stat s, d;
++
++  r_append ("/", src);
++  r_append ("/", dest);
++
++  if (verbose)
++    printf ("sync %s to %s %s\n", src->buf, dest->buf,
++	    and_delete ? "and delete" : "");
++
++  size_t staillen = src->len;
++
++  size_t dtaillen = dest->len;
++
++  dir = opendir (src->buf);
++
++  while ((de = readdir (dir)) != NULL)
++    {
++      if (strcmp (de->d_name, ".") == 0
++	  || strcmp (de->d_name, "..") == 0)
++	continue;
++
++      src->len = staillen;
++      r_append (de->d_name, src);
++      dest->len = dtaillen;
++      r_append (de->d_name, dest);
++
++      s.st_mode = ~0;
++      d.st_mode = ~0;
++
++      if (lstat (src->buf, &s) != 0)
++	FAIL_EXIT1 ("%s obtained by readdir, but stat failed.\n", src->buf);
++
++      /* It's OK if this one fails, since we know the file might be
++	 missing.  */
++      lstat (dest->buf, &d);
++
++      if (! need_sync (src->buf, dest->buf, &s, &d))
++	{
++	  if (S_ISDIR (s.st_mode))
++	    rsync_1 (src, dest, and_delete);
++	  continue;
++	}
++
++      if (d.st_mode != ~0)
++	switch (d.st_mode & S_IFMT)
++	  {
++	  case S_IFDIR:
++	    if (!S_ISDIR (s.st_mode))
++	      {
++		if (verbose)
++		  printf ("-D %s\n", dest->buf);
++		recursive_remove (dest->buf);
++	      }
++	    break;
++
++	  default:
++	    if (verbose)
++	      printf ("-F %s\n", dest->buf);
++	    maybe_xunlink (dest->buf);
++	    break;
++	  }
++
++      switch (s.st_mode & S_IFMT)
++	{
++	case S_IFREG:
++	  if (verbose)
++	    printf ("+F %s\n", dest->buf);
++	  copy_one_file (src->buf, dest->buf);
++	  break;
++
++	case S_IFDIR:
++	  if (verbose)
++	    printf ("+D %s\n", dest->buf);
++	  maybe_xmkdir (dest->buf, (s.st_mode & 0777) | 0700);
++	  rsync_1 (src, dest, and_delete);
++	  break;
++
++	case S_IFLNK:
++	  {
++	    char *lp;
++	    if (verbose)
++	      printf ("+L %s\n", dest->buf);
++	    lp = xreadlink (src->buf);
++	    xsymlink (lp, dest->buf);
++	    free (lp);
++	    break;
++	  }
++
++	default:
++	  break;
++	}
++    }
++
++  closedir (dir);
++  src->len = staillen;
++  src->buf[staillen] = 0;
++  dest->len = dtaillen;
++  dest->buf[dtaillen] = 0;
++
++  if (!and_delete)
++    return;
++
++  /* The rest of this function removes any files/directories in DEST
++     that do not exist in SRC.  This is triggered as part of a
++     preclean or postsclean step.  */
++
++  dir = opendir (dest->buf);
++
++  while ((de = readdir (dir)) != NULL)
++    {
++      if (strcmp (de->d_name, ".") == 0
++	  || strcmp (de->d_name, "..") == 0)
++	continue;
++
++      src->len = staillen;
++      r_append (de->d_name, src);
++      dest->len = dtaillen;
++      r_append (de->d_name, dest);
++
++      s.st_mode = ~0;
++      d.st_mode = ~0;
++
++      lstat (src->buf, &s);
++
++      if (lstat (dest->buf, &d) != 0)
++	FAIL_EXIT1 ("%s obtained by readdir, but stat failed.\n", dest->buf);
++
++      if (s.st_mode == ~0)
++	{
++	  /* dest exists and src doesn't, clean it.  */
++	  switch (d.st_mode & S_IFMT)
++	    {
++	    case S_IFDIR:
++	      if (!S_ISDIR (s.st_mode))
++		{
++		  if (verbose)
++		    printf ("-D %s\n", dest->buf);
++		  recursive_remove (dest->buf);
++		}
++	      break;
++
++	    default:
++	      if (verbose)
++		printf ("-F %s\n", dest->buf);
++	      maybe_xunlink (dest->buf);
++	      break;
++	    }
++	}
++    }
++
++  closedir (dir);
++}
++
++static void
++rsync (char *src, char *dest, int and_delete)
++{
++  r_setup (src, &spath);
++  r_setup (dest, &dpath);
++
++  rsync_1 (&spath, &dpath, and_delete);
++}
++
++
++int
++main (int argc, char **argv)
++{
++  pid_t child;
++  char *pristine_root_path;
++  char *new_root_path;
++  char *new_cwd_path;
++  char *new_objdir_path;
++  char *new_srcdir_path;
++  char **new_child_proc;
++  char *command_root;
++  char *command_base;
++  char *command_basename;
++  char *so_base;
++  int do_postclean = 0;
++
++  uid_t original_uid;
++  gid_t original_gid;
++  int UMAP;
++  int GMAP;
++  /* Used for "%lld %lld 1" so need not be large.  */
++  char tmp[100];
++  struct stat st;
++  int lock_fd;
++
++  setbuf (stdout, NULL);
++
++  /* The command line we're expecting looks like this:
++     env <set some vars> ld.so <library path> test-binary
++
++     We need to peel off any "env" or "ld.so" portion of the command
++     line, and keep track of which env vars we should preserve and
++     which we drop.  */
++
++  if (argc < 2)
++    {
++      fprintf (stderr, "Usage: containerize <program to run> <args...>\n");
++      exit (1);
++    }
++
++  if (strcmp (argv[1], "-v") == 0)
++    {
++      verbose = 1;
++      ++argv;
++      --argc;
++    }
++
++  if (strcmp (argv[1], "env") == 0)
++    {
++      ++argv;
++      --argc;
++      while (is_env_setting (argv[1]))
++	{
++	  /* If there are variables we do NOT want to propogate, this
++	     is where the test for them goes.  */
++	    {
++	      /* Need to keep these.  Note that putenv stores a
++	         pointer to our argv.  */
++	      putenv (argv[1]);
++	    }
++	  ++argv;
++	  --argc;
++	}
++    }
++
++  if (strcmp (argv[1], support_objdir_elf_ldso) == 0)
++    {
++      ++argv;
++      --argc;
++      while (argv[1][0] == '-')
++	{
++	  if (strcmp (argv[1], "--library-path") == 0)
++	    {
++	      ++argv;
++	      --argc;
++	    }
++	  ++argv;
++	  --argc;
++	}
++    }
++
++  pristine_root_path = strdup (concat (support_objdir_root,
++				       "/testroot.pristine", NULL));
++  new_root_path = strdup (concat (support_objdir_root,
++				  "/testroot.root", NULL));
++  new_cwd_path = get_current_dir_name ();
++  new_child_proc = argv + 1;
++
++  lock_fd = open (concat (pristine_root_path, "/lock.fd", NULL),
++		 O_CREAT | O_TRUNC | O_RDWR, 0666);
++  if (lock_fd < 0)
++    FAIL_EXIT1 ("Cannot create testroot lock.\n");
++
++  while (flock (lock_fd, LOCK_EX) != 0)
++    {
++      if (errno != EINTR)
++	FAIL_EXIT1 ("Cannot lock testroot.\n");
++    }
++
++  xmkdirp (new_root_path, 0755);
++
++  /* We look for extra setup info in a subdir in the same spot as the
++     test, with the same name but a ".root" extension.  This is that
++     directory.  We try to look in the source tree if the path we're
++     given refers to the build tree, but we rely on the path to be
++     absolute.  This is what the glibc makefiles do.  */
++  command_root = concat (argv[1], ".root", NULL);
++  if (strncmp (command_root, support_objdir_root,
++	       strlen (support_objdir_root)) == 0
++      && command_root[strlen (support_objdir_root)] == '/')
++    command_root = concat (support_srcdir_root,
++			   argv[1] + strlen (support_objdir_root),
++			   ".root", NULL);
++  command_root = strdup (command_root);
++
++  /* This cuts off the ".root" we appended above.  */
++  command_base = strdup (command_root);
++  command_base[strlen (command_base) - 5] = 0;
++
++  /* This is the basename of the test we're running.  */
++  command_basename = strrchr (command_base, '/');
++  if (command_basename == NULL)
++    command_basename = command_base;
++  else
++    ++command_basename;
++
++  /* Shared object base directory.  */
++  so_base = strdup (argv[1]);
++  if (strrchr (so_base, '/') != NULL)
++    strrchr (so_base, '/')[1] = 0;
++
++  if (file_exists (concat (command_root, "/postclean.req", NULL)))
++    do_postclean = 1;
++
++  rsync (pristine_root_path, new_root_path,
++	 file_exists (concat (command_root, "/preclean.req", NULL)));
++
++  if (stat (command_root, &st) >= 0
++      && S_ISDIR (st.st_mode))
++    rsync (command_root, new_root_path, 0);
++
++  new_objdir_path = strdup (concat (new_root_path,
++				    support_objdir_root, NULL));
++  new_srcdir_path = strdup (concat (new_root_path,
++				    support_srcdir_root, NULL));
++
++  /* new_cwd_path starts with '/' so no "/" needed between the two.  */
++  xmkdirp (concat (new_root_path, new_cwd_path, NULL), 0755);
++  xmkdirp (new_srcdir_path, 0755);
++  xmkdirp (new_objdir_path, 0755);
++
++  original_uid = getuid ();
++  original_gid = getgid ();
++
++  /* Handle the cp/mv/rm "script" here.  */
++  {
++    char *the_line = NULL;
++    size_t line_len = 0;
++    char *fname = concat (command_root, "/",
++			  command_basename, ".script", NULL);
++    char *the_words[3];
++    FILE *f = fopen (fname, "r");
++
++    if (verbose && f)
++      fprintf (stderr, "running %s\n", fname);
++
++    if (f == NULL)
++      {
++	/* Try foo.script instead of foo.root/foo.script, as a shortcut.  */
++	fname = concat (command_base, ".script", NULL);
++	f = fopen (fname, "r");
++	if (verbose && f)
++	  fprintf (stderr, "running %s\n", fname);
++      }
++
++    /* Note that we do NOT look for a Makefile-generated foo.script in
++       the build directory.  If that is ever needed, this is the place
++       to add it.  */
++
++    /* This is where we "interpret" the mini-script which is <test>.script.  */
++    if (f != NULL)
++      {
++	while (getline (&the_line, &line_len, f) > 0)
++	  {
++	    int nt = tokenize (the_line, the_words, 3);
++	    int i;
++
++	    for (i = 1; i < nt; ++i)
++	      {
++		if (memcmp (the_words[i], "$B/", 3) == 0)
++		  the_words[i] = concat (support_objdir_root,
++					 the_words[i] + 2, NULL);
++		else if (memcmp (the_words[i], "$S/", 3) == 0)
++		  the_words[i] = concat (support_srcdir_root,
++					 the_words[i] + 2, NULL);
++		else if (memcmp (the_words[i], "$I/", 3) == 0)
++		  the_words[i] = concat (new_root_path,
++					 support_install_prefix,
++					 the_words[i] + 2, NULL);
++		else if (memcmp (the_words[i], "$L/", 3) == 0)
++		  the_words[i] = concat (new_root_path,
++					 support_libdir_prefix,
++					 the_words[i] + 2, NULL);
++		else if (the_words[i][0] == '/')
++		  the_words[i] = concat (new_root_path,
++					 the_words[i], NULL);
++	      }
++
++	    if (nt == 3 && the_words[2][strlen (the_words[2]) - 1] == '/')
++	      {
++		char *r = strrchr (the_words[1], '/');
++		if (r)
++		  the_words[2] = concat (the_words[2], r + 1, NULL);
++		else
++		  the_words[2] = concat (the_words[2], the_words[1], NULL);
++	      }
++
++	    if (nt == 2 && strcmp (the_words[0], "so") == 0)
++	      {
++		the_words[2] = concat (new_root_path, support_libdir_prefix,
++				       "/", the_words[1], NULL);
++		the_words[1] = concat (so_base, the_words[1], NULL);
++		copy_one_file (the_words[1], the_words[2]);
++	      }
++	    else if (nt == 3 && strcmp (the_words[0], "cp") == 0)
++	      {
++		copy_one_file (the_words[1], the_words[2]);
++	      }
++	    else if (nt == 3 && strcmp (the_words[0], "mv") == 0)
++	      {
++		if (rename (the_words[1], the_words[2]) < 0)
++		  FAIL_EXIT1 ("rename %s -> %s: %s", the_words[1],
++			      the_words[2], strerror (errno));
++	      }
++	    else if (nt == 3 && strcmp (the_words[0], "chmod") == 0)
++	      {
++		long int m;
++		m = strtol (the_words[1], NULL, 0);
++		if (chmod (the_words[2], m) < 0)
++		    FAIL_EXIT1 ("chmod %s: %s\n",
++				the_words[2], strerror (errno));
++
++	      }
++	    else if (nt == 2 && strcmp (the_words[0], "rm") == 0)
++	      {
++		maybe_xunlink (the_words[1]);
++	      }
++	    else if (nt > 0 && the_words[0][0] != '#')
++	      {
++		printf ("\033[31minvalid [%s]\033[0m\n", the_words[0]);
++	      }
++	  }
++	fclose (f);
++      }
++  }
++
++#ifdef CLONE_NEWNS
++  /* The unshare here gives us our own spaces and capabilities.  */
++  if (unshare (CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS) < 0)
++    {
++      /* Older kernels may not support all the options, or security
++	 policy may block this call.  */
++      if (errno == EINVAL || errno == EPERM)
++	FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (errno));
++      else
++	FAIL_EXIT1 ("unable to unshare user/fs: %s", strerror (errno));
++    }
++#else
++  /* Some targets may not support unshare at all.  */
++  FAIL_UNSUPPORTED ("unshare support missing");
++#endif
++
++  /* Some systems, by default, all mounts leak out of the namespace.  */
++  if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0)
++    FAIL_EXIT1 ("could not create a private mount namespace\n");
++
++  trymount (support_srcdir_root, new_srcdir_path);
++  trymount (support_objdir_root, new_objdir_path);
++
++  xmkdirp (concat (new_root_path, "/dev", NULL), 0755);
++  devmount (new_root_path, "null");
++  devmount (new_root_path, "zero");
++  devmount (new_root_path, "urandom");
++
++  /* We're done with the "old" root, switch to the new one.  */
++  if (chroot (new_root_path) < 0)
++    FAIL_EXIT1 ("Can't chroot to %s - ", new_root_path);
++
++  if (chdir (new_cwd_path) < 0)
++    FAIL_EXIT1 ("Can't cd to new %s - ", new_cwd_path);
++
++  /* To complete the containerization, we need to fork () at least
++     once.  We can't exec, nor can we somehow link the new child to
++     our parent.  So we run the child and propogate it's exit status
++     up.  */
++  child = fork ();
++  if (child < 0)
++    FAIL_EXIT1 ("Unable to fork");
++  else if (child > 0)
++    {
++      /* Parent.  */
++      int status;
++      waitpid (child, &status, 0);
++
++      /* There's a bit of magic here, since the buildroot is mounted
++	 in our space, the paths are still valid, and since the mounts
++	 aren't recursive, it sees *only* the built root, not anything
++	 we would normally se if we rsync'd to "/" like mounted /dev
++	 files.  */
++      if (do_postclean)
++	  rsync (pristine_root_path, new_root_path, 1);
++
++      if (WIFEXITED (status))
++	exit (WEXITSTATUS (status));
++
++      if (WIFSIGNALED (status))
++	{
++	  printf ("%%SIGNALLED%%\n");
++	  exit (77);
++	}
++
++      printf ("%%EXITERROR%%\n");
++      exit (78);
++    }
++
++  /* The rest is the child process, which is now PID 1 and "in" the
++     new root.  */
++
++  maybe_xmkdir ("/tmp", 0755);
++
++  /* Now that we're pid 1 (effectively "root") we can mount /proc  */
++  maybe_xmkdir ("/proc", 0777);
++  if (mount ("proc", "/proc", "proc", 0, NULL) < 0)
++    FAIL_EXIT1 ("Unable to mount /proc: ");
++
++  /* We map our original UID to the same UID in the container so we
++     can own our own files normally.  */
++  UMAP = open ("/proc/self/uid_map", O_WRONLY);
++  if (UMAP < 0)
++    FAIL_EXIT1 ("can't write to /proc/self/uid_map\n");
++
++  sprintf (tmp, "%lld %lld 1\n",
++	   (long long) original_uid, (long long) original_uid);
++  write (UMAP, tmp, strlen (tmp));
++  xclose (UMAP);
++
++  /* We must disable setgroups () before we can map our groups, else we
++     get EPERM.  */
++  GMAP = open ("/proc/self/setgroups", O_WRONLY);
++  if (GMAP >= 0)
++    {
++      /* We support kernels old enough to not have this.  */
++      write (GMAP, "deny\n", 5);
++      xclose (GMAP);
++    }
++
++  /* We map our original GID to the same GID in the container so we
++     can own our own files normally.  */
++  GMAP = open ("/proc/self/gid_map", O_WRONLY);
++  if (GMAP < 0)
++    FAIL_EXIT1 ("can't write to /proc/self/gid_map\n");
 +
-+/* Create a temporary file.  Return the opened file descriptor on
-+   success, or -1 on failure.  Write the file name to *FILENAME if
-+   FILENAME is not NULL.  In this case, the caller is expected to free
-+   *FILENAME.  */
-+int create_temp_file (const char *base, char **filename);
++  sprintf (tmp, "%lld %lld 1\n",
++	   (long long) original_gid, (long long) original_gid);
++  write (GMAP, tmp, strlen (tmp));
++  xclose (GMAP);
 +
-+/* Create a temporary directory and schedule it for deletion.  BASE is
-+   used as a prefix for the unique directory name, which the function
-+   returns.  The caller should free this string.  */
-+char *support_create_temp_directory (const char *base);
++  /* Now run the child.  */
++  execvp (new_child_proc[0], new_child_proc);
 +
-+__END_DECLS
++  /* Or don't run the child?  */
++  FAIL_EXIT1 ("Unable to exec %s\n", new_child_proc[0]);
 +
-+#endif /* SUPPORT_TEMP_FILE_H */
++  /* Because gcc won't know error () never returns...  */
++  exit (EXIT_UNSUPPORTED);
++}
 diff --git a/support/test-driver.c b/support/test-driver.c
 new file mode 100644
-index 0000000000..09c8783e4f
+index 0000000000..9798f16227
 --- /dev/null
 +++ b/support/test-driver.c
-@@ -0,0 +1,165 @@
+@@ -0,0 +1,169 @@
 +/* Main function for test programs.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -5571,6 +8200,10 @@ index 0000000000..09c8783e4f
 +  test_config.no_mallopt = 1;
 +#endif
 +
++#ifdef TEST_NO_SETVBUF
++  test_config.no_setvbuf = 1;
++#endif
++
 +#ifdef TIMEOUT
 +  test_config.timeout = TIMEOUT;
 +#endif
@@ -5596,10 +8229,10 @@ index 0000000000..09c8783e4f
 +}
 diff --git a/support/test-driver.h b/support/test-driver.h
 new file mode 100644
-index 0000000000..1708d68d60
+index 0000000000..549179b254
 --- /dev/null
 +++ b/support/test-driver.h
-@@ -0,0 +1,75 @@
+@@ -0,0 +1,76 @@
 +/* Interfaces for the test driver.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -5637,6 +8270,7 @@ index 0000000000..1708d68d60
 +  int expected_status;   /* Expected exit status.  */
 +  int expected_signal;   /* If non-zero, expect termination by signal.  */
 +  char no_mallopt;       /* Boolean flag to disable mallopt.  */
++  char no_setvbuf;       /* Boolean flag to disable setvbuf.  */
 +  const char *optstring; /* Short command line options.  */
 +};
 +
@@ -5675,6 +8309,38 @@ index 0000000000..1708d68d60
 +__END_DECLS
 +
 +#endif /* SUPPORT_TEST_DRIVER_H */
+diff --git a/support/true-container.c b/support/true-container.c
+new file mode 100644
+index 0000000000..57dc57e252
+--- /dev/null
++++ b/support/true-container.c
+@@ -0,0 +1,26 @@
++/* Minimal /bin/true for in-container use.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* Implements the in-container /bin/true, which always returns true
++   (0).  */
++
++int
++main (void)
++{
++  return 0;
++}
 diff --git a/support/tst-support-namespace.c b/support/tst-support-namespace.c
 new file mode 100644
 index 0000000000..e20423c4a3
@@ -5795,6 +8461,97 @@ index 0000000000..e20423c4a3
 +}
 +
 +#include <support/test-driver.c>
+diff --git a/support/tst-support_blob_repeat.c b/support/tst-support_blob_repeat.c
+new file mode 100644
+index 0000000000..1978c14488
+--- /dev/null
++++ b/support/tst-support_blob_repeat.c
+@@ -0,0 +1,85 @@
++/* Tests for <support/blob_repeat.h>
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <support/blob_repeat.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  struct support_blob_repeat repeat
++    = support_blob_repeat_allocate ("5", 1, 5);
++  TEST_COMPARE_BLOB (repeat.start, repeat.size, "55555", 5);
++  support_blob_repeat_free (&repeat);
++
++  repeat = support_blob_repeat_allocate ("ABC", 3, 3);
++  TEST_COMPARE_BLOB (repeat.start, repeat.size, "ABCABCABC", 9);
++  support_blob_repeat_free (&repeat);
++
++  repeat = support_blob_repeat_allocate ("abc", 4, 3);
++  TEST_COMPARE_BLOB (repeat.start, repeat.size, "abc\0abc\0abc", 12);
++  support_blob_repeat_free (&repeat);
++
++  size_t gigabyte = 1U << 30;
++  repeat = support_blob_repeat_allocate ("X", 1, gigabyte + 1);
++  if (repeat.start == NULL)
++    puts ("warning: not enough memory for 1 GiB mapping");
++  else
++    {
++      TEST_COMPARE (repeat.size, gigabyte + 1);
++      {
++        unsigned char *p = repeat.start;
++        for (size_t i = 0; i < gigabyte + 1; ++i)
++          if (p[i] != 'X')
++            FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
++
++        /* Check that there is no sharing across the mapping.  */
++        p[0] = 'Y';
++        p[1U << 24] = 'Z';
++        for (size_t i = 0; i < gigabyte + 1; ++i)
++          if (i == 0)
++            TEST_COMPARE (p[i], 'Y');
++          else if (i == 1U << 24)
++            TEST_COMPARE (p[i], 'Z');
++          else if (p[i] != 'X')
++            FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
++      }
++    }
++  support_blob_repeat_free (&repeat);
++
++  repeat = support_blob_repeat_allocate ("012345678", 9, 10 * 1000 * 1000);
++  if (repeat.start == NULL)
++    puts ("warning: not enough memory for large mapping");
++  else
++    {
++      unsigned char *p = repeat.start;
++      for (int i = 0; i < 10 * 1000 * 1000; ++i)
++        for (int j = 0; j <= 8; ++j)
++          if (p[i * 9 + j] != '0' + j)
++            {
++              printf ("error: element %d index %d\n", i, j);
++              TEST_COMPARE (p[i * 9 + j], '0' + j);
++            }
++    }
++  support_blob_repeat_free (&repeat);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
 diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c
 new file mode 100644
 index 0000000000..a685256091
@@ -6096,6 +8853,73 @@ index 0000000000..b1135eebc6
 +}
 +
 +#include <support/test-driver.c>
+diff --git a/support/tst-support_quote_blob.c b/support/tst-support_quote_blob.c
+new file mode 100644
+index 0000000000..5467a190a6
+--- /dev/null
++++ b/support/tst-support_quote_blob.c
+@@ -0,0 +1,61 @@
++/* Test the support_quote_blob function.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/check.h>
++#include <support/support.h>
++#include <string.h>
++#include <stdlib.h>
++
++static int
++do_test (void)
++{
++  /* Check handling of the empty blob, both with and without trailing
++     NUL byte.  */
++  char *p = support_quote_blob ("", 0);
++  TEST_COMPARE (strlen (p), 0);
++  free (p);
++  p = support_quote_blob ("X", 0);
++  TEST_COMPARE (strlen (p), 0);
++  free (p);
++
++  /* Check escaping of backslash-escaped characters, and lack of
++     escaping for other shell meta-characters.  */
++  p = support_quote_blob ("$()*?`@[]{}~\'\"X", 14);
++  TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\""), 0);
++  free (p);
++
++  /* Check lack of escaping for letters and digits.  */
++#define LETTERS_AND_DIGTS                       \
++  "abcdefghijklmnopqrstuvwxyz"                  \
++  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"                  \
++  "0123456789"
++  p = support_quote_blob (LETTERS_AND_DIGTS "@", 2 * 26 + 10);
++  TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS), 0);
++  free (p);
++
++  /* Check escaping of control characters and other non-printable
++     characters.  */
++  p = support_quote_blob ("\r\n\t\a\b\f\v\1\177\200\377\0@", 14);
++  TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
++                        "\\177\\200\\377\\000@\\000"), 0);
++  free (p);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
 diff --git a/support/tst-support_record_failure-2.sh b/support/tst-support_record_failure-2.sh
 new file mode 100644
 index 0000000000..09cd96290a
@@ -6380,47 +9204,264 @@ index 0000000000..123ba1bc3c
 +  unsigned long long int u63 : 63;
 +};
 +
-+/* Functions which return signed sizes are common, so test that these
-+   results can readily checked using TEST_COMPARE.  */
++/* Functions which return signed sizes are common, so test that these
++   results can readily checked using TEST_COMPARE.  */
++
++static int
++return_ssize_t (void)
++{
++  return 4;
++}
++
++static int
++return_int (void)
++{
++  return 4;
++}
++
++
++static int
++do_test (void)
++{
++  /* This should succeed.  */
++  TEST_COMPARE (1, 1);
++  TEST_COMPARE (2LL, 2U);
++  {
++    char i8 = 3;
++    unsigned short u16 = 3;
++    TEST_COMPARE (i8, u16);
++  }
++  TEST_COMPARE (return_ssize_t (), sizeof (char[4]));
++  TEST_COMPARE (return_int (), sizeof (char[4]));
++
++  struct bitfield bitfield = { 0 };
++  TEST_COMPARE (bitfield.i2, bitfield.i3);
++  TEST_COMPARE (bitfield.u2, bitfield.u3);
++  TEST_COMPARE (bitfield.u2, bitfield.i3);
++  TEST_COMPARE (bitfield.u3, bitfield.i3);
++  TEST_COMPARE (bitfield.i2, bitfield.u3);
++  TEST_COMPARE (bitfield.i3, bitfield.u2);
++  TEST_COMPARE (bitfield.i63, bitfield.i63);
++  TEST_COMPARE (bitfield.u63, bitfield.u63);
++  TEST_COMPARE (bitfield.i31, bitfield.i63);
++  TEST_COMPARE (bitfield.i63, bitfield.i31);
++
++  struct support_capture_subprocess proc = support_capture_subprocess
++    (&subprocess, NULL);
++
++  /* Discard the reported error.  */
++  support_record_failure_reset ();
++
++  puts ("info: *** subprocess output starts ***");
++  fputs (proc.out.buffer, stdout);
++  puts ("info: *** subprocess output ends ***");
++
++  TEST_VERIFY
++    (strcmp (proc.out.buffer,
++             "tst-test_compare.c:28: numeric comparison failure\n"
++             "   left: 1 (0x1); from: ch\n"
++             "  right: -1 (0xffffffff); from: -1\n"
++             "tst-test_compare.c:29: numeric comparison failure\n"
++             "   left: 2 (0x2); from: 2LL\n"
++             "  right: -2 (0xfffffffffffffffe); from: -2LL\n"
++             "tst-test_compare.c:30: numeric comparison failure"
++             " (widths 64 and 32)\n"
++             "   left: 3 (0x3); from: 3LL\n"
++             "  right: -3 (0xfffffffd); from: (short) -3\n") == 0);
++
++  /* Check that there is no output on standard error.  */
++  support_capture_subprocess_check (&proc, "TEST_COMPARE", 0, sc_allow_stdout);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/support/tst-test_compare_blob.c b/support/tst-test_compare_blob.c
+new file mode 100644
+index 0000000000..aa8643e182
+--- /dev/null
++++ b/support/tst-test_compare_blob.c
+@@ -0,0 +1,125 @@
++/* Basic test for the TEST_COMPARE_BLOB macro.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <string.h>
++#include <support/check.h>
++#include <support/capture_subprocess.h>
++
++static void
++subprocess (void *closure)
++{
++  /* These tests should fail.  They were chosen to cover differences
++     in length (with the same contents), single-bit mismatches, and
++     mismatching null pointers.  */
++  TEST_COMPARE_BLOB ("", 0, "", 1);    /* Line 29.  */
++  TEST_COMPARE_BLOB ("X", 1, "", 1);   /* Line 30.  */
++  TEST_COMPARE_BLOB ("abcd", 3, "abcd", 4); /* Line 31.  */
++  TEST_COMPARE_BLOB ("abcd", 4, "abcD", 4); /* Line 32.  */
++  TEST_COMPARE_BLOB ("abcd", 4, NULL, 0); /* Line 33.  */
++  TEST_COMPARE_BLOB (NULL, 0, "abcd", 4); /* Line 34.  */
++}
++
++/* Same contents, different addresses.  */
++char buffer_abc_1[] = "abc";
++char buffer_abc_2[] = "abc";
++
++static int
++do_test (void)
++{
++  /* This should succeed.  Even if the pointers and array contents are
++     different, zero-length inputs are not different.  */
++  TEST_COMPARE_BLOB ("", 0, "", 0);
++  TEST_COMPARE_BLOB ("", 0, buffer_abc_1, 0);
++  TEST_COMPARE_BLOB (buffer_abc_1, 0, "", 0);
++  TEST_COMPARE_BLOB (NULL, 0, "", 0);
++  TEST_COMPARE_BLOB ("", 0, NULL, 0);
++  TEST_COMPARE_BLOB (NULL, 0, NULL, 0);
++
++  /* Check equality of blobs containing a single NUL byte.  */
++  TEST_COMPARE_BLOB ("", 1, "", 1);
++  TEST_COMPARE_BLOB ("", 1, &buffer_abc_1[3], 1);
++
++  /* Check equality of blobs of varying lengths.  */
++  for (size_t i = 0; i <= sizeof (buffer_abc_1); ++i)
++    TEST_COMPARE_BLOB (buffer_abc_1, i, buffer_abc_2, i);
++
++  struct support_capture_subprocess proc = support_capture_subprocess
++    (&subprocess, NULL);
++
++  /* Discard the reported error.  */
++  support_record_failure_reset ();
++
++  puts ("info: *** subprocess output starts ***");
++  fputs (proc.out.buffer, stdout);
++  puts ("info: *** subprocess output ends ***");
++
++  TEST_VERIFY
++    (strcmp (proc.out.buffer,
++"tst-test_compare_blob.c:29: error: blob comparison failed\n"
++"  left length:  0 bytes (from 0)\n"
++"  right length: 1 bytes (from 1)\n"
++"  right (evaluated from \"\"):\n"
++"      \"\\000\"\n"
++"      00\n"
++"tst-test_compare_blob.c:30: error: blob comparison failed\n"
++"  blob length: 1 bytes\n"
++"  left (evaluated from \"X\"):\n"
++"      \"X\"\n"
++"      58\n"
++"  right (evaluated from \"\"):\n"
++"      \"\\000\"\n"
++"      00\n"
++"tst-test_compare_blob.c:31: error: blob comparison failed\n"
++"  left length:  3 bytes (from 3)\n"
++"  right length: 4 bytes (from 4)\n"
++"  left (evaluated from \"abcd\"):\n"
++"      \"abc\"\n"
++"      61 62 63\n"
++"  right (evaluated from \"abcd\"):\n"
++"      \"abcd\"\n"
++"      61 62 63 64\n"
++"tst-test_compare_blob.c:32: error: blob comparison failed\n"
++"  blob length: 4 bytes\n"
++"  left (evaluated from \"abcd\"):\n"
++"      \"abcd\"\n"
++"      61 62 63 64\n"
++"  right (evaluated from \"abcD\"):\n"
++"      \"abcD\"\n"
++"      61 62 63 44\n"
++"tst-test_compare_blob.c:33: error: blob comparison failed\n"
++"  left length:  4 bytes (from 4)\n"
++"  right length: 0 bytes (from 0)\n"
++"  left (evaluated from \"abcd\"):\n"
++"      \"abcd\"\n"
++"      61 62 63 64\n"
++"tst-test_compare_blob.c:34: error: blob comparison failed\n"
++"  left length:  0 bytes (from 0)\n"
++"  right length: 4 bytes (from 4)\n"
++"  right (evaluated from \"abcd\"):\n"
++"      \"abcd\"\n"
++"      61 62 63 64\n"
++             ) == 0);
++
++  /* Check that there is no output on standard error.  */
++  support_capture_subprocess_check (&proc, "TEST_COMPARE_BLOB",
++                                    0, sc_allow_stdout);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/support/tst-test_compare_string.c b/support/tst-test_compare_string.c
+new file mode 100644
+index 0000000000..2a4b258587
+--- /dev/null
++++ b/support/tst-test_compare_string.c
+@@ -0,0 +1,107 @@
++/* Basic test for the TEST_COMPARE_STRING macro.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
 +
-+static int
-+return_ssize_t (void)
-+{
-+  return 4;
-+}
++#include <string.h>
++#include <support/check.h>
++#include <support/capture_subprocess.h>
 +
-+static int
-+return_int (void)
++static void
++subprocess (void *closure)
 +{
-+  return 4;
++  /* These tests should fail.  They were chosen to cover differences
++     in length (with the same contents), single-bit mismatches, and
++     mismatching null pointers.  */
++  TEST_COMPARE_STRING ("", NULL);             /* Line 29.  */
++  TEST_COMPARE_STRING ("X", "");              /* Line 30.  */
++  TEST_COMPARE_STRING (NULL, "X");            /* Line 31.  */
++  TEST_COMPARE_STRING ("abcd", "abcD");       /* Line 32.  */
++  TEST_COMPARE_STRING ("abcd", NULL);         /* Line 33.  */
++  TEST_COMPARE_STRING (NULL, "abcd");         /* Line 34.  */
 +}
 +
++/* Same contents, different addresses.  */
++char buffer_abc_1[] = "abc";
++char buffer_abc_2[] = "abc";
 +
 +static int
 +do_test (void)
 +{
-+  /* This should succeed.  */
-+  TEST_COMPARE (1, 1);
-+  TEST_COMPARE (2LL, 2U);
-+  {
-+    char i8 = 3;
-+    unsigned short u16 = 3;
-+    TEST_COMPARE (i8, u16);
-+  }
-+  TEST_COMPARE (return_ssize_t (), sizeof (char[4]));
-+  TEST_COMPARE (return_int (), sizeof (char[4]));
-+
-+  struct bitfield bitfield = { 0 };
-+  TEST_COMPARE (bitfield.i2, bitfield.i3);
-+  TEST_COMPARE (bitfield.u2, bitfield.u3);
-+  TEST_COMPARE (bitfield.u2, bitfield.i3);
-+  TEST_COMPARE (bitfield.u3, bitfield.i3);
-+  TEST_COMPARE (bitfield.i2, bitfield.u3);
-+  TEST_COMPARE (bitfield.i3, bitfield.u2);
-+  TEST_COMPARE (bitfield.i63, bitfield.i63);
-+  TEST_COMPARE (bitfield.u63, bitfield.u63);
-+  TEST_COMPARE (bitfield.i31, bitfield.i63);
-+  TEST_COMPARE (bitfield.i63, bitfield.i31);
++  /* This should succeed.  Even if the pointers and array contents are
++     different, zero-length inputs are not different.  */
++  TEST_COMPARE_STRING (NULL, NULL);
++  TEST_COMPARE_STRING ("", "");
++  TEST_COMPARE_STRING (buffer_abc_1, buffer_abc_2);
++  TEST_COMPARE_STRING (buffer_abc_1, "abc");
 +
 +  struct support_capture_subprocess proc = support_capture_subprocess
 +    (&subprocess, NULL);
@@ -6434,19 +9475,46 @@ index 0000000000..123ba1bc3c
 +
 +  TEST_VERIFY
 +    (strcmp (proc.out.buffer,
-+             "tst-test_compare.c:28: numeric comparison failure\n"
-+             "   left: 1 (0x1); from: ch\n"
-+             "  right: -1 (0xffffffff); from: -1\n"
-+             "tst-test_compare.c:29: numeric comparison failure\n"
-+             "   left: 2 (0x2); from: 2LL\n"
-+             "  right: -2 (0xfffffffffffffffe); from: -2LL\n"
-+             "tst-test_compare.c:30: numeric comparison failure"
-+             " (widths 64 and 32)\n"
-+             "   left: 3 (0x3); from: 3LL\n"
-+             "  right: -3 (0xfffffffd); from: (short) -3\n") == 0);
++"tst-test_compare_string.c:29: error: blob comparison failed\n"
++"  left string: 0 bytes\n"
++"  right string: NULL\n"
++"tst-test_compare_string.c:30: error: blob comparison failed\n"
++"  left string: 1 bytes\n"
++"  right string: 0 bytes\n"
++"  left (evaluated from \"X\"):\n"
++"      \"X\"\n"
++"      58\n"
++"tst-test_compare_string.c:31: error: blob comparison failed\n"
++"  left string: NULL\n"
++"  right string: 1 bytes\n"
++"  right (evaluated from \"X\"):\n"
++"      \"X\"\n"
++"      58\n"
++"tst-test_compare_string.c:32: error: blob comparison failed\n"
++"  string length: 4 bytes\n"
++"  left (evaluated from \"abcd\"):\n"
++"      \"abcd\"\n"
++"      61 62 63 64\n"
++"  right (evaluated from \"abcD\"):\n"
++"      \"abcD\"\n"
++"      61 62 63 44\n"
++"tst-test_compare_string.c:33: error: blob comparison failed\n"
++"  left string: 4 bytes\n"
++"  right string: NULL\n"
++"  left (evaluated from \"abcd\"):\n"
++"      \"abcd\"\n"
++"      61 62 63 64\n"
++"tst-test_compare_string.c:34: error: blob comparison failed\n"
++"  left string: NULL\n"
++"  right string: 4 bytes\n"
++"  right (evaluated from \"abcd\"):\n"
++"      \"abcd\"\n"
++"      61 62 63 64\n"
++             ) == 0);
 +
 +  /* Check that there is no output on standard error.  */
-+  support_capture_subprocess_check (&proc, "TEST_COMPARE", 0, sc_allow_stdout);
++  support_capture_subprocess_check (&proc, "TEST_COMPARE_STRING",
++                                    0, sc_allow_stdout);
 +
 +  return 0;
 +}
@@ -6530,12 +9598,63 @@ index 0000000000..b142207228
 +}
 +
 +#include <support/test-driver.c>
+diff --git a/support/tty.h b/support/tty.h
+new file mode 100644
+index 0000000000..1d37c42279
+--- /dev/null
++++ b/support/tty.h
+@@ -0,0 +1,45 @@
++/* Support functions related to (pseudo)terminals.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#ifndef _SUPPORT_TTY_H
++#define _SUPPORT_TTY_H 1
++
++struct termios;
++struct winsize;
++
++/** Open a pseudoterminal pair.  The outer fd is written to the address
++    A_OUTER and the inner fd to A_INNER.
++
++    If A_NAME is not NULL, it will be set to point to a string naming
++    the /dev/pts/NNN device corresponding to the inner fd; space for
++    this string is allocated with malloc and should be freed by the
++    caller when no longer needed.  (This is different from the libutil
++    function 'openpty'.)
++
++    If TERMP is not NULL, the terminal parameters will be initialized
++    according to the termios structure it points to.
++
++    If WINP is not NULL, the terminal window size will be set
++    accordingly.
++
++    Terminates the process on failure (like xmalloc).  */
++extern void support_openpty (int *a_outer, int *a_inner, char **a_name,
++                             const struct termios *termp,
++                             const struct winsize *winp);
++
++#endif
 diff --git a/support/write_message.c b/support/write_message.c
 new file mode 100644
-index 0000000000..9d0f267a2f
+index 0000000000..a3e2f90535
 --- /dev/null
 +++ b/support/write_message.c
-@@ -0,0 +1,29 @@
+@@ -0,0 +1,32 @@
 +/* Write a message to standard output.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -6556,14 +9675,17 @@ index 0000000000..9d0f267a2f
 +
 +#include <support/support.h>
 +
++#include <errno.h>
 +#include <string.h>
 +#include <unistd.h>
 +
 +void
 +write_message (const char *message)
 +{
++  int saved_errno = errno;
 +  ssize_t unused __attribute__ ((unused));
 +  unused = write (STDOUT_FILENO, message, strlen (message));
++  errno = saved_errno;
 +}
 diff --git a/support/xaccept.c b/support/xaccept.c
 new file mode 100644
@@ -6863,6 +9985,44 @@ index 0000000000..341805d80d
 +  if (connect (fd, sa, sa_len) != 0)
 +    FAIL_EXIT1 ("connect (%d), family %d: %m", fd, sa->sa_family);
 +}
+diff --git a/support/xcopy_file_range.c b/support/xcopy_file_range.c
+new file mode 100644
+index 0000000000..b3501a4d5e
+--- /dev/null
++++ b/support/xcopy_file_range.c
+@@ -0,0 +1,32 @@
++/* copy_file_range with error checking.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/support.h>
++#include <support/xunistd.h>
++#include <support/check.h>
++
++ssize_t
++xcopy_file_range (int infd, off64_t *pinoff, int outfd, off64_t *poutoff,
++		  size_t length, unsigned int flags)
++{
++  ssize_t status = support_copy_file_range (infd, pinoff, outfd,
++					    poutoff, length, flags);
++  if (status == -1)
++    FAIL_EXIT1 ("cannot copy file: %m\n");
++  return status;
++}
 diff --git a/support/xdlfcn.c b/support/xdlfcn.c
 new file mode 100644
 index 0000000000..f34bb059c0
@@ -7433,6 +10593,78 @@ index 0000000000..7e67f783de
 +  if (mkdir (path, mode) != 0)
 +    FAIL_EXIT1 ("mkdir (\"%s\", 0%o): %m", path, mode);
 +}
+diff --git a/support/xmkdirp.c b/support/xmkdirp.c
+new file mode 100644
+index 0000000000..fada0452ea
+--- /dev/null
++++ b/support/xmkdirp.c
+@@ -0,0 +1,66 @@
++/* Error-checking replacement for "mkdir -p".
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/support.h>
++#include <support/check.h>
++#include <support/xunistd.h>
++
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++
++/* Equivalent of "mkdir -p".  Any failures cause FAIL_EXIT1 so no
++   return code is needed.  */
++
++void
++xmkdirp (const char *path, mode_t mode)
++{
++  struct stat s;
++  const char *slash_p;
++  int rv;
++
++  if (path[0] == 0)
++    return;
++
++  if (stat (path, &s) == 0)
++    {
++      if (S_ISDIR (s.st_mode))
++	return;
++      errno = EEXIST;
++      FAIL_EXIT1 ("mkdir_p (\"%s\", 0%o): %m", path, mode);
++    }
++
++  slash_p = strrchr (path, '/');
++  if (slash_p != NULL)
++    {
++      while (slash_p > path && slash_p[-1] == '/')
++	--slash_p;
++      if (slash_p > path)
++	{
++	  char *parent = xstrndup (path, slash_p - path);
++	  xmkdirp (parent, mode);
++	  free (parent);
++	}
++    }
++
++  rv = mkdir (path, mode);
++  if (rv != 0)
++    FAIL_EXIT1 ("mkdir_p (\"%s\", 0%o): %m", path, mode);
++
++  return;
++}
 diff --git a/support/xmmap.c b/support/xmmap.c
 new file mode 100644
 index 0000000000..d580c07013
@@ -7905,6 +11137,102 @@ index 0000000000..61690c5e7c
 +    xpthread_check_return ("pthread_barrier_wait", ret);
 +  return ret == PTHREAD_BARRIER_SERIAL_THREAD;
 +}
+diff --git a/support/xpthread_barrierattr_destroy.c b/support/xpthread_barrierattr_destroy.c
+new file mode 100644
+index 0000000000..3e471f9a81
+--- /dev/null
++++ b/support/xpthread_barrierattr_destroy.c
+@@ -0,0 +1,26 @@
++/* pthread_barrierattr_destroy with error checking.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/xthread.h>
++
++void
++xpthread_barrierattr_destroy (pthread_barrierattr_t *attr)
++{
++  xpthread_check_return ("pthread_barrierattr_destroy",
++                         pthread_barrierattr_destroy (attr));
++}
+diff --git a/support/xpthread_barrierattr_init.c b/support/xpthread_barrierattr_init.c
+new file mode 100644
+index 0000000000..4ee14e78f3
+--- /dev/null
++++ b/support/xpthread_barrierattr_init.c
+@@ -0,0 +1,26 @@
++/* pthread_barrierattr_init with error checking.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/xthread.h>
++
++void
++xpthread_barrierattr_init (pthread_barrierattr_t *attr)
++{
++  xpthread_check_return ("pthread_barrierattr_init",
++                         pthread_barrierattr_init (attr));
++}
+diff --git a/support/xpthread_barrierattr_setpshared.c b/support/xpthread_barrierattr_setpshared.c
+new file mode 100644
+index 0000000000..90b2c5bec6
+--- /dev/null
++++ b/support/xpthread_barrierattr_setpshared.c
+@@ -0,0 +1,26 @@
++/* pthread_barrierattr_setpshared with error checking.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/xthread.h>
++
++void
++xpthread_barrierattr_setpshared (pthread_barrierattr_t *attr, int pshared)
++{
++  xpthread_check_return ("pthread_barrierattr_setpshared",
++                         pthread_barrierattr_setpshared (attr, pshared));
++}
 diff --git a/support/xpthread_cancel.c b/support/xpthread_cancel.c
 new file mode 100644
 index 0000000000..26e864ea3e
@@ -9330,6 +12658,41 @@ index 0000000000..e85fddd439
 +    oom_error ("strndup", length);
 +  return p;
 +}
+diff --git a/support/xsymlink.c b/support/xsymlink.c
+new file mode 100644
+index 0000000000..0f3edf640a
+--- /dev/null
++++ b/support/xsymlink.c
+@@ -0,0 +1,29 @@
++/* Error-checking replacement for "symlink".
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/support.h>
++#include <support/check.h>
++
++#include <unistd.h>
++
++void
++xsymlink (const char *target, const char *linkpath)
++{
++  if (symlink (target, linkpath) < 0)
++    FAIL_EXIT1 ("symlink (\"%s\", \"%s\")", target, linkpath);
++}
 diff --git a/support/xsysconf.c b/support/xsysconf.c
 new file mode 100644
 index 0000000000..afefc2d098
@@ -9374,10 +12737,10 @@ index 0000000000..afefc2d098
 +}
 diff --git a/support/xthread.h b/support/xthread.h
 new file mode 100644
-index 0000000000..79358e7c99
+index 0000000000..623f5ad0ac
 --- /dev/null
 +++ b/support/xthread.h
-@@ -0,0 +1,87 @@
+@@ -0,0 +1,90 @@
 +/* Support functionality for using threads.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -9421,6 +12784,9 @@ index 0000000000..79358e7c99
 +void xpthread_barrier_init (pthread_barrier_t *barrier,
 +                            pthread_barrierattr_t *attr, unsigned int count);
 +void xpthread_barrier_destroy (pthread_barrier_t *barrier);
++void xpthread_barrierattr_destroy (pthread_barrierattr_t *);
++void xpthread_barrierattr_init (pthread_barrierattr_t *);
++void xpthread_barrierattr_setpshared (pthread_barrierattr_t *, int pshared);
 +void xpthread_mutexattr_destroy (pthread_mutexattr_t *);
 +void xpthread_mutexattr_init (pthread_mutexattr_t *);
 +void xpthread_mutexattr_setprotocol (pthread_mutexattr_t *, int);
@@ -9467,10 +12833,10 @@ index 0000000000..79358e7c99
 +#endif /* SUPPORT_THREAD_H */
 diff --git a/support/xunistd.h b/support/xunistd.h
 new file mode 100644
-index 0000000000..5fe5dae818
+index 0000000000..f99f362cb4
 --- /dev/null
 +++ b/support/xunistd.h
-@@ -0,0 +1,65 @@
+@@ -0,0 +1,72 @@
 +/* POSIX-specific extra functions.
 +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -9516,6 +12882,10 @@ index 0000000000..5fe5dae818
 +long xsysconf (int name);
 +long long xlseek (int fd, long long offset, int whence);
 +void xftruncate (int fd, long long length);
++void xsymlink (const char *target, const char *linkpath);
++
++/* Equivalent of "mkdir -p".  */
++void xmkdirp (const char *, mode_t);
 +
 +/* Read the link at PATH.  The caller should free the returned string
 +   with free.  */
@@ -9533,6 +12903,9 @@ index 0000000000..5fe5dae818
 +void xmprotect (void *addr, size_t length, int prot);
 +void xmunmap (void *addr, size_t length);
 +
++ssize_t xcopy_file_range(int fd_in, loff_t *off_in, int fd_out,
++			 loff_t *off_out, size_t len, unsigned int flags);
++
 +__END_DECLS
 +
 +#endif /* SUPPORT_XUNISTD_H */
diff --git a/SOURCES/glibc-rh1418978-1a.patch b/SOURCES/glibc-rh1418978-1a.patch
new file mode 100644
index 0000000..6d41e32
--- /dev/null
+++ b/SOURCES/glibc-rh1418978-1a.patch
@@ -0,0 +1,54 @@
+Backporting changes to the support/ subdirectory.
+
+This is kept separate from glibc-rh1418978-1.patch to simplify rebases
+of the support/ subdirectory.  Changes here should be restricted to
+things that absolutely cannot be upstreamed at this point (such as
+support for older compilers).
+
+diff --git a/support/blob_repeat.c b/support/blob_repeat.c
+index 16c1e448b990e386..a2d5e0cbd736f998 100644
+--- a/support/blob_repeat.c
++++ b/support/blob_repeat.c
+@@ -30,6 +30,9 @@
+ #include <unistd.h>
+ #include <wchar.h>
+ 
++/* For check_mul_overflow_size_t.  */
++#include <malloc/malloc-internal.h>
++
+ /* Small allocations should use malloc directly instead of the mmap
+    optimization because mappings carry a lot of overhead.  */
+ static const size_t maximum_small_size = 4 * 1024 * 1024;
+@@ -118,8 +121,8 @@ minimum_stride_size (size_t page_size, size_t element_size)
+      common multiple, it appears only once.  Therefore, shift one
+      factor.  */
+   size_t multiple;
+-  if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
+-                              &multiple))
++  if (check_mul_overflow_size_t (page_size >> common_zeros, element_size,
++                                 &multiple))
+     return 0;
+   return multiple;
+ }
+@@ -255,7 +258,7 @@ support_blob_repeat_allocate (const void *element, size_t element_size,
+                               size_t count)
+ {
+   size_t total_size;
+-  if (__builtin_mul_overflow (element_size, count, &total_size))
++  if (check_mul_overflow_size_t (element_size, count, &total_size))
+     {
+       errno = EOVERFLOW;
+       return (struct support_blob_repeat) { 0 };
+diff --git a/support/links-dso-program.cc b/support/links-dso-program.cc
+index dba6976c0609a332..8ff3155dd7fcd757 100644
+--- a/support/links-dso-program.cc
++++ b/support/links-dso-program.cc
+@@ -1,3 +1,8 @@
++/* Change for backporting: The build system does not define _ISOMAC
++   for us because the tests-internal changes have not been
++   backported.  */
++#define _ISOMAC 1
++
+ #include <iostream>
+ 
+ using namespace std;
diff --git a/SOURCES/glibc-rh1427734-1.patch b/SOURCES/glibc-rh1427734-1.patch
new file mode 100644
index 0000000..c9e569f
--- /dev/null
+++ b/SOURCES/glibc-rh1427734-1.patch
@@ -0,0 +1,318 @@
+The commit included in this patch only incidentally fixes the problem
+reported in bug 1427734: In each of the IBM9xx character sets referenced in
+this patch, the removal of the "break" statement means that the subsequent
+increment of "inptr" is executed instead of being skipped. This allows
+conversion to progress instead of hanging.
+
+commit 692de4b3960dc90bdcfb871513ee4d81d314cf69
+Author: Martin Sebor <msebor@redhat.com>
+Date:   Fri Jan 15 11:25:13 2016 -0700
+
+    Have iconv accept redundant escape sequences in IBM900, IBM903, IBM905,
+    IBM907, and IBM909.
+    
+    Patch for bug #17197 changes the encoder to avoid generating redundant
+    shift sequences.  However, those sequences may already be present in
+    data encododed by prior versions of the encoder.  This change modifies
+    the decoder to also avoid rejecting redundant shift sequences.
+    
+            [BZ #19432]
+            * iconvdata/Makefile: Add bug-iconv11.
+            * iconvdata/bug-iconv11.c: New test.
+            * iconvdata/ibm930.c: Do not reject redundant shift sequences.
+            * iconvdata/ibm933.c: Same.
+            * iconvdata/ibm935.c: Same.
+            * iconvdata/ibm937.c: Same.
+            * iconvdata/ibm939.c: Same.
+
+# Conflicts:
+#	iconvdata/Makefile
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index 0ec67554ca4c29ea..c4e6c510d7abc055 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -68,7 +68,7 @@ include ../Makeconfig
+ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+ 	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
+-	bug-iconv10 bug-iconv12
++	bug-iconv10 bug-iconv11 bug-iconv12
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+diff --git a/iconvdata/bug-iconv11.c b/iconvdata/bug-iconv11.c
+new file mode 100644
+index 0000000000000000..6cdc07d79883454d
+--- /dev/null
++++ b/iconvdata/bug-iconv11.c
+@@ -0,0 +1,114 @@
++/* bug 19432: iconv rejects redundant escape sequences in IBM903,
++              IBM905, IBM907, and IBM909
++
++   Copyright (C) 2016 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 <iconv.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++
++// The longest test input sequence.
++#define MAXINBYTES    8
++#define MAXOUTBYTES   (MAXINBYTES * MB_LEN_MAX)
++
++/* Verify that a conversion of the INPUT sequence consisting of
++   INBYTESLEFT bytes in the encoding specified by the codeset
++   named by FROM_SET is successful.
++   Return 0 on success, non-zero on iconv() failure.  */
++
++static int
++test_ibm93x (const char *from_set, const char *input, size_t inbytesleft)
++{
++  const char to_set[] = "UTF-8";
++  iconv_t cd = iconv_open (to_set, from_set);
++  if (cd == (iconv_t) -1)
++    {
++      printf ("iconv_open(\"%s\", \"%s\"): %s\n",
++              from_set, to_set, strerror (errno));
++      return 1;
++    }
++
++  char output [MAXOUTBYTES];
++  size_t outbytesleft = sizeof output;
++
++  char *inbuf = (char*)input;
++  char *outbuf = output;
++
++  printf ("iconv(cd, %p, %zu, %p, %zu)\n",
++          inbuf, inbytesleft, outbuf, outbytesleft);
++
++  errno = 0;
++  size_t ret = iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
++  printf ("  ==> %td: %s\n"
++          "  inbuf%+td, inbytesleft=%zu, outbuf%+td, outbytesleft=%zu\n",
++          ret, strerror (errno),
++          inbuf - input, inbytesleft, outbuf - output, outbytesleft);
++
++  // Return 0 on success, non-zero on iconv() failure.
++  return ret == (size_t)-1 || errno;
++}
++
++static int
++do_test (void)
++{
++  // State-dependent encodings to exercise.
++  static const char* const to_code[] = {
++    "IBM930", "IBM933", "IBM935", "IBM937", "IBM939"
++  };
++
++  static const size_t ncodesets = sizeof to_code / sizeof *to_code;
++
++  static const struct {
++    char txt[MAXINBYTES];
++    size_t len;
++  } input[] = {
++#define DATA(s) { s, sizeof s - 1 }
++    /* <SI>: denotes the shift-in 1-byte escape sequence, changing
++             the encoder from a sigle-byte encoding to multibyte
++       <SO>: denotes the shift-out 1-byte escape sequence, switching
++             the encoder from a multibyte to a single-byte state  */
++
++    DATA ("\x0e"),               // <SI> (not redundant)
++    DATA ("\x0f"),               // <S0> (redundant with initial state)
++    DATA ("\x0e\x0e"),           // <SI><SI>
++    DATA ("\x0e\x0f\x0f"),       // <SI><SO><SO>
++    DATA ("\x0f\x0f"),           // <SO><SO>
++    DATA ("\x0f\x0e\x0e"),       // <SO><SI><SI>
++    DATA ("\x0e\x0f\xc7\x0f"),   // <SI><SO><G><SO>
++    DATA ("\xc7\x0f")            // <G><SO> (redundant with initial state)
++  };
++
++  static const size_t ninputs = sizeof input / sizeof *input;
++
++  int ret = 0;
++
++  size_t i, j;
++
++  /* Iterate over the IBM93x codesets above and exercise each with
++     the input sequences above.  */
++  for (i = 0; i != ncodesets; ++i)
++    for (j = 0; j != ninputs; ++j)
++      ret += test_ibm93x (to_code [i], input [i].txt, input [i].len);
++
++  return ret;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/iconvdata/ibm930.c b/iconvdata/ibm930.c
+index 636141114f506985..88413ccfbabfdc35 100644
+--- a/iconvdata/ibm930.c
++++ b/iconvdata/ibm930.c
+@@ -105,24 +105,14 @@ enum
+ 									      \
+     if (__builtin_expect (ch, 0) == SO)					      \
+       {									      \
+-	/* Shift OUT, change to DBCS converter.  */			      \
+-	if (curcs == db)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift OUT, change to DBCS converter (redundant escape okay).  */   \
+ 	curcs = db;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+       }									      \
+     else if (__builtin_expect (ch, 0) == SI)				      \
+       {									      \
+-	/* Shift IN, change to SBCS converter */			      \
+-	if (curcs == sb)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift IN, change to SBCS converter (redundant escape okay).  */    \
+ 	curcs = sb;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
+index 8b9e5780a36a454a..335d385551fee86e 100644
+--- a/iconvdata/ibm933.c
++++ b/iconvdata/ibm933.c
+@@ -104,24 +104,14 @@ enum
+ 									      \
+     if (__builtin_expect (ch, 0) == SO)					      \
+       {									      \
+-	/* Shift OUT, change to DBCS converter.  */			      \
+-	if (curcs == db)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift OUT, change to DBCS converter (redundant escape okay).  */   \
+ 	curcs = db;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+       }									      \
+     else if (__builtin_expect (ch, 0) == SI)				      \
+       {									      \
+-	/* Shift IN, change to SBCS converter.  */			      \
+-	if (curcs == sb)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift IN, change to SBCS converter (redundant escape okay).  */    \
+ 	curcs = sb;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+diff --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
+index 4e2d99ab56d7f0d2..520d28a4e9a690fc 100644
+--- a/iconvdata/ibm935.c
++++ b/iconvdata/ibm935.c
+@@ -104,24 +104,14 @@ enum
+ 									      \
+     if (__builtin_expect(ch, 0) == SO)					      \
+       {									      \
+-	/* Shift OUT, change to DBCS converter.  */			      \
+-	if (curcs == db)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift OUT, change to DBCS converter (redundant escape okay).  */   \
+ 	curcs = db;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+       }									      \
+     else if (__builtin_expect (ch, 0) == SI)				      \
+       {									      \
+-	/* Shift IN, change to SBCS converter.  */			      \
+-	if (curcs == sb)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift IN, change to SBCS converter (redundant escape okay).  */    \
+ 	curcs = sb;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+diff --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
+index 1e468871b783e78d..64563bb8bf0441ff 100644
+--- a/iconvdata/ibm937.c
++++ b/iconvdata/ibm937.c
+@@ -104,24 +104,14 @@ enum
+ 									      \
+     if (__builtin_expect (ch, 0) == SO)					      \
+       {									      \
+-	/* Shift OUT, change to DBCS converter.  */			      \
+-	if (curcs == db)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift OUT, change to DBCS converter (redundant escape okay).  */   \
+ 	curcs = db;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+       }									      \
+     else if (__builtin_expect (ch, 0) == SI)				      \
+       {									      \
+-	/* Shift IN, change to SBCS converter.  */			      \
+-	if (curcs == sb)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift IN, change to SBCS converter (redundant escape okay).  */    \
+ 	curcs = sb;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+diff --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
+index 2060b0c329df0c86..4f73e2e55c94972d 100644
+--- a/iconvdata/ibm939.c
++++ b/iconvdata/ibm939.c
+@@ -104,24 +104,14 @@ enum
+ 									      \
+     if (__builtin_expect (ch, 0) == SO)					      \
+       {									      \
+-	/* Shift OUT, change to DBCS converter.  */			      \
+-	if (curcs == db)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift OUT, change to DBCS converter (redundant escape okay).  */   \
+ 	curcs = db;							      \
+ 	++inptr;							      \
+ 	continue;							      \
+       }									      \
+     else if (__builtin_expect (ch, 0) == SI)				      \
+       {									      \
+-	/* Shift IN, change to SBCS converter.  */			      \
+-	if (curcs == sb)						      \
+-	  {								      \
+-	    result = __GCONV_ILLEGAL_INPUT;				      \
+-	    break;							      \
+-	  }								      \
++	/* Shift IN, change to SBCS converter (redundant escape okay).  */    \
+ 	curcs = sb;							      \
+ 	++inptr;							      \
+ 	continue;							      \
diff --git a/SOURCES/glibc-rh1427734-2.patch b/SOURCES/glibc-rh1427734-2.patch
new file mode 100644
index 0000000..eaa39ad
--- /dev/null
+++ b/SOURCES/glibc-rh1427734-2.patch
@@ -0,0 +1,34 @@
+commit ab9f6255ab4e7aa353ec1b61b4f332bf00cea4d0
+Author: Stefan Liebler <stli@linux.vnet.ibm.com>
+Date:   Wed Jan 20 08:32:37 2016 +0100
+
+    S390: Fix build error in iconvdata/bug-iconv11.c.
+    
+    This fixes the following build error on S390 31bit while building the test
+    iconvdata/bug-iconv11.c with gcc 5.3:
+    bug-iconv11.c: In function ‘test_ibm93x’:
+    bug-iconv11.c:59:11: error: format ‘%td’ expects argument of type ‘ptrdiff_t’, but argument 2 has type ‘size_t {aka long unsigned int}’ [-Werror=format=]
+       printf ("  ==> %td: %s\n"
+               ^
+    cc1: all warnings being treated as errors
+    
+    This patch uses %zu format specifier for argument size_t ret instead of %td.
+    
+    ChangeLog:
+    
+            * iconvdata/bug-iconv11.c (test_ibm93x):
+            Use %zu printf format specifier for size_t argument.
+
+diff --git a/iconvdata/bug-iconv11.c b/iconvdata/bug-iconv11.c
+index 6cdc07d79883454d..5b9d9a36af0b4bcf 100644
+--- a/iconvdata/bug-iconv11.c
++++ b/iconvdata/bug-iconv11.c
+@@ -56,7 +56,7 @@ test_ibm93x (const char *from_set, const char *input, size_t inbytesleft)
+ 
+   errno = 0;
+   size_t ret = iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+-  printf ("  ==> %td: %s\n"
++  printf ("  ==> %zu: %s\n"
+           "  inbuf%+td, inbytesleft=%zu, outbuf%+td, outbytesleft=%zu\n",
+           ret, strerror (errno),
+           inbuf - input, inbytesleft, outbuf - output, outbytesleft);
diff --git a/SOURCES/glibc-rh1439165-syscall-names.patch b/SOURCES/glibc-rh1439165-syscall-names.patch
index 247e3f2..6bc2372 100644
--- a/SOURCES/glibc-rh1439165-syscall-names.patch
+++ b/SOURCES/glibc-rh1439165-syscall-names.patch
@@ -1,5 +1,6 @@
 This patch contains the sysdeps/unix/sysv/linux/syscall-names.list file
-from upstream and is continuously updated for new kernel versions.
+from upstream for Linux 4.13, and forms the baseline, subsequent changes
+are cherry picked from upstream.
 
 diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
 new file mode 100644
diff --git a/SOURCES/glibc-rh1439165.patch b/SOURCES/glibc-rh1439165.patch
index bb2ee65..624d448 100644
--- a/SOURCES/glibc-rh1439165.patch
+++ b/SOURCES/glibc-rh1439165.patch
@@ -3,8 +3,8 @@ Posted upstream at:
   https://sourceware.org/ml/libc-alpha/2017-04/msg00082.html
 
 sysdeps/unix/sysv/linux/syscall-names.list is stored as a separate patch
-(glibc-rh1439165-syscall-names.patch) in the source RPM for easier
-updates.
+(glibc-rh1439165-syscall-names.patch) in the source RPM, and is the
+baseline for subsequent changes.
 
 Author: Florian Weimer <fweimer@redhat.com>
 
diff --git a/SOURCES/glibc-rh1443872-2.patch b/SOURCES/glibc-rh1443872-2.patch
new file mode 100644
index 0000000..c7717f7
--- /dev/null
+++ b/SOURCES/glibc-rh1443872-2.patch
@@ -0,0 +1,40 @@
+Add missing newlines to __libc_fatal error messages.  This was
+implemented upstream in commits a6e8926f8d49a213a9abb1a61f6af964f612ab7f
+("[BZ #20271] Add newlines in __libc_fatal calls.") and
+36f30c104fe3addd4d864e276202c6b934f825b7
+("__netlink_assert_response: Add more __libc_fatal newlines [BZ #20271]").
+
+diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
+index b570e93db840fec1..434b50d20b67d130 100644
+--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
++++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
+@@ -73,12 +73,12 @@ __netlink_assert_response (int fd, ssize_t result)
+           char message[200];
+           if (family < 0)
+             __snprintf (message, sizeof (message),
+-                        "Unexpected error %d on netlink descriptor %d",
++                        "Unexpected error %d on netlink descriptor %d\n",
+                         error_code, fd);
+           else
+             __snprintf (message, sizeof (message),
+                         "Unexpected error %d on netlink descriptor %d"
+-                        " (address family %d)",
++                        " (address family %d)\n",
+                         error_code, fd, family);
+           __libc_fatal (message);
+         }
+@@ -93,12 +93,12 @@ __netlink_assert_response (int fd, ssize_t result)
+       if (family < 0)
+           __snprintf (message, sizeof (message),
+                       "Unexpected netlink response of size %zd"
+-                      " on descriptor %d",
++                      " on descriptor %d\n",
+                       result, fd);
+       else
+           __snprintf (message, sizeof (message),
+                       "Unexpected netlink response of size %zd"
+-                      " on descriptor %d (address family %d)",
++                      " on descriptor %d (address family %d)\n",
+                       result, fd, family);
+       __libc_fatal (message);
+     }
diff --git a/SOURCES/glibc-rh1443872.patch b/SOURCES/glibc-rh1443872.patch
new file mode 100644
index 0000000..6027304
--- /dev/null
+++ b/SOURCES/glibc-rh1443872.patch
@@ -0,0 +1,250 @@
+commit 2eecc8afd02d8c65cf098cbae4de87f332dc21bd
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Nov 9 12:48:41 2015 +0100
+
+    Terminate process on invalid netlink response from kernel [BZ #12926]
+    
+    The recvmsg system calls for netlink sockets have been particularly
+    prone to picking up unrelated data after a file descriptor race
+    (where the descriptor is closed and reopened concurrently in a
+    multi-threaded process, as the result of a file descriptor
+    management issue elsewhere).  This commit adds additional error
+    checking and aborts the process if a datagram of unexpected length
+    (without the netlink header) is received, or an error code which
+    cannot happen due to the way the netlink socket is used.
+    
+            [BZ #12926]
+            Terminate process on invalid netlink response.
+            * sysdeps/unix/sysv/linux/netlinkaccess.h
+            (__netlink_assert_response): Declare.
+            * sysdeps/unix/sysv/linux/netlink_assert_response.c: New file.
+            * sysdeps/unix/sysv/linux/Makefile [$(subdir) == inet]
+            (sysdep_routines): Add netlink_assert_response.
+            * sysdeps/unix/sysv/linux/check_native.c (__check_native): Call
+            __netlink_assert_response.
+            * sysdeps/unix/sysv/linux/check_pf.c (make_request): Likewise.
+            * sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Likewise.
+            * sysdeps/unix/sysv/linux/Versions (GLIBC_PRIVATE): Add
+            __netlink_assert_response.
+
+Conflicts:
+	sysdeps/unix/sysv/linux/check_pf.c
+	  Upstream commit fda389c8f0311dd5786be91a7b54b9f935fcafa1
+          ("Fix infinite loop in check_pf (BZ #12926)") was not backported
+	  before and is superseded by the upstream commit backported here.
+	sysdeps/unix/sysv/linux/netlinkaccess.h
+          Missing backport of e054f494306530720114b321b3d97ca2f397cbbb
+          ("Add #include <stdint.h> for uint[32|64]_t usage (except
+	  installed headers)").
+
+diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
+index 95cff0ef651e74a9..bb69b985e6df7fb1 100644
+--- a/sysdeps/unix/sysv/linux/Makefile
++++ b/sysdeps/unix/sysv/linux/Makefile
+@@ -114,6 +114,7 @@ sysdep_headers += netinet/if_fddi.h netinet/if_tr.h \
+ 		  netipx/ipx.h netash/ash.h netax25/ax25.h netatalk/at.h \
+ 		  netrom/netrom.h netpacket/packet.h netrose/rose.h \
+ 		  neteconet/ec.h netiucv/iucv.h
++sysdep_routines += netlink_assert_response
+ endif
+ 
+ # Don't compile the ctype glue code, since there is no old non-GNU C library.
+diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
+index 16bb28159099c5fa..202ffccc2908ddcc 100644
+--- a/sysdeps/unix/sysv/linux/Versions
++++ b/sysdeps/unix/sysv/linux/Versions
+@@ -169,5 +169,7 @@ libc {
+   GLIBC_PRIVATE {
+     # functions used in other libraries
+     __syscall_rt_sigqueueinfo;
++    # functions used by nscd
++    __netlink_assert_response;
+   }
+ }
+diff --git a/sysdeps/unix/sysv/linux/check_native.c b/sysdeps/unix/sysv/linux/check_native.c
+index 4968a07a0f8c7932..319b46762aeaf3b6 100644
+--- a/sysdeps/unix/sysv/linux/check_native.c
++++ b/sysdeps/unix/sysv/linux/check_native.c
+@@ -35,6 +35,7 @@
+ 
+ #include <not-cancel.h>
+ 
++#include "netlinkaccess.h"
+ 
+ void
+ __check_native (uint32_t a1_index, int *a1_native,
+@@ -117,6 +118,7 @@ __check_native (uint32_t a1_index, int *a1_native,
+ 	};
+ 
+       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
++      __netlink_assert_response (fd, read_len);
+       if (read_len < 0)
+ 	goto out_fail;
+ 
+diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
+index d33e1b497d8ba9c7..6b28a735a14f1498 100644
+--- a/sysdeps/unix/sysv/linux/check_pf.c
++++ b/sysdeps/unix/sysv/linux/check_pf.c
+@@ -36,6 +36,7 @@
+ #include <atomic.h>
+ #include <nscd/nscd-client.h>
+ 
++#include "netlinkaccess.h"
+ 
+ #ifndef IFA_F_HOMEADDRESS
+ # define IFA_F_HOMEADDRESS 0
+@@ -178,6 +179,7 @@ make_request (int fd, pid_t pid)
+ 	};
+ 
+       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
++      __netlink_assert_response (fd, read_len);
+       if (read_len < 0)
+ 	goto out_fail;
+ 
+diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
+index 179653103e057b79..c87e594e30a314fe 100644
+--- a/sysdeps/unix/sysv/linux/ifaddrs.c
++++ b/sysdeps/unix/sysv/linux/ifaddrs.c
+@@ -169,6 +169,7 @@ __netlink_request (struct netlink_handle *h, int type)
+ 	};
+ 
+       read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
++      __netlink_assert_response (h->fd, read_len);
+       if (read_len < 0)
+ 	goto out_fail;
+ 
+diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
+new file mode 100644
+index 0000000000000000..b570e93db840fec1
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
+@@ -0,0 +1,106 @@
++/* Check recvmsg results for netlink sockets.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <fcntl.h>
++#include <stdio.h>
++#include <sys/socket.h>
++
++#include "netlinkaccess.h"
++
++static int
++get_address_family (int fd)
++{
++  struct sockaddr_storage sa;
++  socklen_t sa_len = sizeof (sa);
++  if (__getsockname (fd, (struct sockaddr *) &sa, &sa_len) < 0)
++    return -1;
++  /* Check that the socket family number is preserved despite in-band
++     signaling.  */
++  _Static_assert (sizeof (sa.ss_family) < sizeof (int), "address family size");
++  _Static_assert (0 < (__typeof__ (sa.ss_family)) -1,
++                  "address family unsigned");
++  return sa.ss_family;
++}
++
++void
++internal_function
++__netlink_assert_response (int fd, ssize_t result)
++{
++  if (result < 0)
++    {
++      /* Check if the error is unexpected.  */
++      bool terminate = false;
++      int error_code = errno;
++      int family = get_address_family (fd);
++      if (family != AF_NETLINK)
++        /* If the address family does not match (or getsockname
++           failed), report the original error.  */
++        terminate = true;
++      else if (error_code == EBADF
++          || error_code == ENOTCONN
++          || error_code == ENOTSOCK
++          || error_code == ECONNREFUSED)
++        /* These errors indicate that the descriptor is not a
++           connected socket.  */
++        terminate = true;
++      else if (error_code == EAGAIN || error_code == EWOULDBLOCK)
++        {
++          /* The kernel might return EAGAIN for other reasons than a
++             non-blocking socket.  But if the socket is not blocking,
++             it is not ours, so report the error.  */
++          int mode = __fcntl (fd, F_GETFL, 0);
++          if (mode < 0 || (mode & O_NONBLOCK) != 0)
++            terminate = true;
++        }
++      if (terminate)
++        {
++          char message[200];
++          if (family < 0)
++            __snprintf (message, sizeof (message),
++                        "Unexpected error %d on netlink descriptor %d",
++                        error_code, fd);
++          else
++            __snprintf (message, sizeof (message),
++                        "Unexpected error %d on netlink descriptor %d"
++                        " (address family %d)",
++                        error_code, fd, family);
++          __libc_fatal (message);
++        }
++      else
++        /* Restore orignal errno value.  */
++        __set_errno (error_code);
++    }
++  else if (result < sizeof (struct nlmsghdr))
++    {
++      char message[200];
++      int family = get_address_family (fd);
++      if (family < 0)
++          __snprintf (message, sizeof (message),
++                      "Unexpected netlink response of size %zd"
++                      " on descriptor %d",
++                      result, fd);
++      else
++          __snprintf (message, sizeof (message),
++                      "Unexpected netlink response of size %zd"
++                      " on descriptor %d (address family %d)",
++                      result, fd, family);
++      __libc_fatal (message);
++    }
++}
++libc_hidden_def (__netlink_assert_response)
+diff --git a/sysdeps/unix/sysv/linux/netlinkaccess.h b/sysdeps/unix/sysv/linux/netlinkaccess.h
+index 6cd8a882640d2486..33dc4e12cd464681 100644
+--- a/sysdeps/unix/sysv/linux/netlinkaccess.h
++++ b/sysdeps/unix/sysv/linux/netlinkaccess.h
+@@ -18,6 +18,7 @@
+ #ifndef _NETLINKACCESS_H
+ #define _NETLINKACCESS_H 1
+ 
++#include <sys/types.h>
+ #include <asm/types.h>
+ #include <linux/netlink.h>
+ #include <linux/rtnetlink.h>
+@@ -49,5 +50,10 @@ extern void __netlink_close (struct netlink_handle *h);
+ extern void __netlink_free_handle (struct netlink_handle *h);
+ extern int __netlink_request (struct netlink_handle *h, int type);
+ 
++/* Terminate the process if RESULT is an invalid recvmsg result for
++   the netlink socket FD.  */
++void __netlink_assert_response (int fd, ssize_t result)
++  internal_function;
++libc_hidden_proto (__netlink_assert_response)
+ 
+ #endif /* netlinkaccess.h */
diff --git a/SOURCES/glibc-rh1457479-3.patch b/SOURCES/glibc-rh1457479-3.patch
index bb86e24..e8710fd 100644
--- a/SOURCES/glibc-rh1457479-3.patch
+++ b/SOURCES/glibc-rh1457479-3.patch
@@ -1,3 +1,7 @@
+Note; the test is known to fail on the RHEL 7.7 kernel - the patch
+fixes PT_GETREGS (which we want) but adds PTRACE_SINGLEBLOCK (which we
+don't support yet).  So, the test case was not included.  - DJ
+
 commit b08a6a0dea63742313ed3d9577c1e2d83436b196
 Author: Stefan Liebler <stli@linux.vnet.ibm.com>
 Date:   Mon Jun 19 16:27:25 2017 +0200
diff --git a/SOURCES/glibc-rh1472832.patch b/SOURCES/glibc-rh1472832.patch
new file mode 100644
index 0000000..3d9e01e
--- /dev/null
+++ b/SOURCES/glibc-rh1472832.patch
@@ -0,0 +1,38 @@
+commit c1f86a33ca32e26a9d6e29fc961e5ecb5e2e5eb4
+Author: Daniel Alvarez <dalvarez@redhat.com>
+Date:   Fri Jun 29 09:44:55 2018 +0200
+
+    getifaddrs: Don't return ifa entries with NULL names [BZ #21812]
+    
+    A lookup operation in map_newlink could turn into an insert because of
+    holes in the interface part of the map.  This leads to incorrectly set
+    the name of the interface to NULL when the interface is not present
+    for the address being processed (most likely because the interface was
+    added between the RTM_GETLINK and RTM_GETADDR calls to the kernel).
+    When such changes are detected by the kernel, it'll mark the dump as
+    "inconsistent" by setting NLM_F_DUMP_INTR flag on the next netlink
+    message.
+    
+    This patch checks this condition and retries the whole operation.
+    Hopes are that next time the interface corresponding to the address
+    entry is present in the list and correct name is returned.
+
+diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
+index c87e594e30a314fe..b1329dc4d4c63529 100644
+--- a/sysdeps/unix/sysv/linux/ifaddrs.c
++++ b/sysdeps/unix/sysv/linux/ifaddrs.c
+@@ -369,6 +369,14 @@ getifaddrs_internal (struct ifaddrs **ifap)
+ 	  if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
+ 	    continue;
+ 
++	  /* If the dump got interrupted, we can't rely on the results
++	     so try again. */
++	  if (nlh->nlmsg_flags & NLM_F_DUMP_INTR)
++	    {
++	      result = -EAGAIN;
++	      goto exit_free;
++	    }
++
+ 	  if (nlh->nlmsg_type == NLMSG_DONE)
+ 	    break;		/* ok */
+ 
diff --git a/SOURCES/glibc-rh1488370.patch b/SOURCES/glibc-rh1488370.patch
new file mode 100644
index 0000000..4ecebda
--- /dev/null
+++ b/SOURCES/glibc-rh1488370.patch
@@ -0,0 +1,61 @@
+Partial backport of the following Fedora Rawhide patches:
+    
+commit a747c093bbee95a3bdf1d7ef052bd248c95fadc5
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Jun 1 12:05:26 2018 +0200
+    
+    Modernise nsswitch.conf defaults (#1581809)
+    
+(backported the line which adds sss description).
+    
+commit 82a97343d6405772541d754aeb4bab79612bd839
+Author: Carlos O'Donell <carlos@redhat.com>
+Date:   Thu Feb 7 17:15:12 2019 -0500
+    
+    Add warnings and notes to /etc/nsswitch.conf and /etc/nscd.conf.
+    
+(backported fully with adjustments for releng/nsswitch.conf).
+
+diff --git a/nscd/nscd.conf b/nscd/nscd.conf
+index 3730835c50a349c4..d7c0ee590466b0d4 100644
+--- a/nscd/nscd.conf
++++ b/nscd/nscd.conf
+@@ -3,6 +3,9 @@
+ #
+ # An example Name Service Cache config file.  This file is needed by nscd.
+ #
++# WARNING: Running nscd with a secondary caching service like sssd may lead to
++#          unexpected behaviour, especially with how long entries are cached.
++#
+ # Legal entries are:
+ #
+ #	logfile			<file>
+@@ -22,7 +25,12 @@
+ #       suggested-size		<service> <prime number>
+ #	check-files		<service> <yes|no>
+ #	persistent		<service> <yes|no>
++#
+ #	shared			<service> <yes|no>
++#	NOTE: Setting 'shared' to a value of 'yes' will accelerate the lookup
++#	      with the help of the client, but these lookups will not be
++#	      counted as cache hits i.e. 'nscd -g' may show '0%'.
++#
+ #	max-db-size		<service> <number bytes>
+ #	auto-propagate		<service> <yes|no>
+ #
+diff --git a/releng/nsswitch.conf b/releng/nsswitch.conf
+index 0a02e5717d906387..4b120bf9e6f94e5f 100644
+--- a/releng/nsswitch.conf
++++ b/releng/nsswitch.conf
+@@ -19,8 +19,11 @@
+ #	db			Use the local database (.db) files
+ #	compat			Use NIS on compat mode
+ #	hesiod			Use Hesiod for user lookups
++#	sss			Use sssd (System Security Services Daemon)
+ #	[NOTFOUND=return]	Stop searching if not found so far
+ #
++# WARNING: Running nscd with a secondary caching service like sssd may lead to
++# 	   unexpected behaviour, especially with how long entries are cached.
+ 
+ # To use db, put the "db" in front of "files" for entries you want to be
+ # looked up first in the databases
diff --git a/SOURCES/glibc-rh1555189-1.patch b/SOURCES/glibc-rh1555189-1.patch
new file mode 100644
index 0000000..772b293
--- /dev/null
+++ b/SOURCES/glibc-rh1555189-1.patch
@@ -0,0 +1,35 @@
+This patch replaces the era block in ja_JP with the non-escaped
+version.  It is a partial backport of commit
+a259f5d388d6195da958b2d147d17c2e2d16b857 ("Replaced unicode sequences
+in the ASCII printable range"), containing only the changes to this
+part of the localedata/locales/ja_JP file.
+
+diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
+index 54e55b1b52e90f29..594df82f05a23719 100644
+--- a/localedata/locales/ja_JP
++++ b/localedata/locales/ja_JP
+@@ -14942,15 +14942,15 @@ am_pm	"<U5348><U524D>";"<U5348><U5F8C>"
+ 
+ t_fmt_ampm "<U0025><U0070><U0025><U0049><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
+ 
+-era	"<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
+-	"<U002B><U003A><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0038><U003A><U0031><U0039><U0038><U0039><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U5143><U5E74>";/
+-	"<U002B><U003A><U0032><U003A><U0031><U0039><U0032><U0037><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0037><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
+-	"<U002B><U003A><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0035><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U5143><U5E74>";/
+-	"<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0034><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
+-	"<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0033><U0030><U003A><U0031><U0039><U0031><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U5143><U5E74>";/
+-	"<U002B><U003A><U0036><U003A><U0031><U0038><U0037><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0032><U0039><U003A><U660E><U6CBB><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
+-	"<U002B><U003A><U0031><U003A><U0030><U0030><U0030><U0031><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0038><U0037><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U897F><U66A6><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
+-	"<U002B><U003A><U0031><U003A><U002D><U0030><U0030><U0030><U0031><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U002D><U002A><U003A><U7D00><U5143><U524D><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>"
++era	"+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
++	"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
++	"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
++	"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
++	"+:2:1913//01//01:1926//12//24:<U5927><U6B63>:%EC%Ey<U5E74>";/
++	"+:2:1912//07//30:1912//12//31:<U5927><U6B63>:%EC<U5143><U5E74>";/
++	"+:6:1873//01//01:1912//07//29:<U660E><U6CBB>:%EC%Ey<U5E74>";/
++	"+:1:0001//01//01:1872//12//31:<U897F><U66A6>:%EC%Ey<U5E74>";/
++	"+:1:-0001//12//31:-*:<U7D00><U5143><U524D>:%EC%Ey<U5E74>"
+ 
+ era_d_fmt	"<U0025><U0045><U0059><U0025><U006d><U6708><U0025><U0064><U65E5>"
+ 
diff --git a/SOURCES/glibc-rh1555189-2.patch b/SOURCES/glibc-rh1555189-2.patch
new file mode 100644
index 0000000..f9cbc16
--- /dev/null
+++ b/SOURCES/glibc-rh1555189-2.patch
@@ -0,0 +1,24 @@
+Patch by Hanataka Shinya <hanataka.shinya@gmail.com> from
+<https://sourceware.org/bugzilla/show_bug.cgi?id=24405>.  Confirmed by TAMUKI
+Shoichi's patch in
+<https://sourceware.org/ml/libc-alpha/2019-04/msg00005.html>.
+
+The official announcement by the Japanese Prime Minister in
+<https://www.kantei.go.jp/jp/tyoukanpress/201904/1_a.html> uses U+4EE4 U+548C
+as well.
+
+diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
+index 594df82f05a23719..40cb5795fea730a5 100644
+--- a/localedata/locales/ja_JP
++++ b/localedata/locales/ja_JP
+@@ -14942,7 +14942,9 @@ am_pm	"<U5348><U524D>";"<U5348><U5F8C>"
+ 
+ t_fmt_ampm "<U0025><U0070><U0025><U0049><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
+ 
+-era	"+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
++era	"+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
++	"+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
++	"+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
+ 	"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
+ 	"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
+ 	"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
diff --git a/SOURCES/glibc-rh1579354.patch b/SOURCES/glibc-rh1579354.patch
new file mode 100644
index 0000000..e0182ce
--- /dev/null
+++ b/SOURCES/glibc-rh1579354.patch
@@ -0,0 +1,57 @@
+commit 583a27d525ae189bdfaa6784021b92a9a1dae12e
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Apr 9 10:08:07 2018 +0200
+
+    resolv: Fully initialize struct mmsghdr in send_dg [BZ #23037]
+
+diff --git a/resolv/res_send.c b/resolv/res_send.c
+index 478d542419566574..05c7ba511b0383c1 100644
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -1154,25 +1154,27 @@ send_dg(res_state statp,
+ 		if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL
+ 		    && !single_request)
+ 		  {
+-		    struct iovec iov[2];
+-		    struct mmsghdr reqs[2];
+-		    reqs[0].msg_hdr.msg_name = NULL;
+-		    reqs[0].msg_hdr.msg_namelen = 0;
+-		    reqs[0].msg_hdr.msg_iov = &iov[0];
+-		    reqs[0].msg_hdr.msg_iovlen = 1;
+-		    iov[0].iov_base = (void *) buf;
+-		    iov[0].iov_len = buflen;
+-		    reqs[0].msg_hdr.msg_control = NULL;
+-		    reqs[0].msg_hdr.msg_controllen = 0;
+-
+-		    reqs[1].msg_hdr.msg_name = NULL;
+-		    reqs[1].msg_hdr.msg_namelen = 0;
+-		    reqs[1].msg_hdr.msg_iov = &iov[1];
+-		    reqs[1].msg_hdr.msg_iovlen = 1;
+-		    iov[1].iov_base = (void *) buf2;
+-		    iov[1].iov_len = buflen2;
+-		    reqs[1].msg_hdr.msg_control = NULL;
+-		    reqs[1].msg_hdr.msg_controllen = 0;
++		    struct iovec iov =
++		      { .iov_base = (void *) buf, .iov_len = buflen };
++		    struct iovec iov2 =
++		      { .iov_base = (void *) buf2, .iov_len = buflen2 };
++		    struct mmsghdr reqs[2] =
++		      {
++			{
++			  .msg_hdr =
++			    {
++			      .msg_iov = &iov,
++			      .msg_iovlen = 1,
++			    },
++			},
++			{
++			  .msg_hdr =
++			    {
++			      .msg_iov = &iov2,
++			      .msg_iovlen = 1,
++			    }
++			},
++		      };
+ 
+ 		    int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
+ 		    if (__glibc_likely (ndg == 2))
diff --git a/SOURCES/glibc-rh1579730-1.patch b/SOURCES/glibc-rh1579730-1.patch
new file mode 100644
index 0000000..16a13ce
--- /dev/null
+++ b/SOURCES/glibc-rh1579730-1.patch
@@ -0,0 +1,308 @@
+commit 68448be208ee06e76665918b37b0a57e3e00c8b4
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Nov 17 16:04:29 2017 -0200
+
+    i386: Fix i386 sigaction sa_restorer initialization (BZ#21269)
+    
+    This patch fixes the i386 sa_restorer field initialization for sigaction
+    syscall for kernel with vDSO.  As described in bug report, i386 Linux
+    (and compat on x86_64) interprets SA_RESTORER clear with nonzero
+    sa_restorer as a request for stack switching if the SS segment is 'funny'.
+    This means that anything that tries to mix glibc's signal handling with
+    segmentation (for instance through modify_ldt syscall) is randomly broken
+    depending on what values lands in sa_restorer.
+    
+    The testcase added  is based on Linux test tools/testing/selftests/x86/ldt_gdt.c,
+    more specifically in do_multicpu_tests function.  The main changes are:
+    
+      - C11 atomics instead of plain access.
+    
+      - Remove x86_64 support which simplifies the syscall handling and fallbacks.
+    
+      - Replicate only the test required to trigger the issue.
+    
+    Checked on i686-linux-gnu.
+    
+            [BZ #21269]
+            * sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269.
+            * sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear
+            sa_restorer for vDSO case.
+            * sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file.
+
+(Adjusted for conflicted in sysdeps/unix/sysv/linux/i386/Makefile due
+different context around the addition of the new test.)
+
+diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
+index acc30219e8dc965f..78e2101682d8d996 100644
+--- a/sysdeps/unix/sysv/linux/i386/Makefile
++++ b/sysdeps/unix/sysv/linux/i386/Makefile
+@@ -3,6 +3,9 @@ default-abi := 32
+ 
+ ifeq ($(subdir),misc)
+ sysdep_routines += ioperm iopl vm86 call_pselect6 call_fallocate
++
++tests += tst-bz21269
++$(objpfx)tst-bz21269: $(shared-thread-library)
+ endif
+ 
+ ifeq ($(subdir),elf)
+diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c
+index 414ef759a97363c4..f10e1363865c3d18 100644
+--- a/sysdeps/unix/sysv/linux/i386/sigaction.c
++++ b/sysdeps/unix/sysv/linux/i386/sigaction.c
+@@ -44,7 +44,6 @@ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
+ #endif
+ extern void restore (void) asm ("__restore") attribute_hidden;
+ 
+-
+ /* If ACT is not NULL, change the action for SIG to *ACT.
+    If OACT is not NULL, put the old action for SIG in *OACT.  */
+ int
+@@ -67,6 +66,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+ 	  kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
+ 			      ? &restore_rt : &restore);
+ 	}
++      else
++	kact.sa_restorer = NULL;
+     }
+ 
+   /* XXX The size argument hopefully will have to be changed to the
+diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+new file mode 100644
+index 0000000000000000..353e36507dce92ea
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+@@ -0,0 +1,233 @@
++/* Test for i386 sigaction sa_restorer handling (BZ#21269)
++   Copyright (C) 2017 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This is based on Linux test tools/testing/selftests/x86/ldt_gdt.c,
++   more specifically in do_multicpu_tests function.  The main changes
++   are:
++
++   - C11 atomics instead of plain access.
++   - Remove x86_64 support which simplifies the syscall handling
++     and fallbacks.
++   - Replicate only the test required to trigger the issue for the
++     BZ#21269.  */
++
++#include <stdatomic.h>
++
++#include <asm/ldt.h>
++#include <linux/futex.h>
++
++#include <setjmp.h>
++#include <signal.h>
++#include <errno.h>
++#include <sys/syscall.h>
++#include <sys/mman.h>
++
++#include <support/xunistd.h>
++#include <support/check.h>
++#include <support/xthread.h>
++
++static int
++xset_thread_area (struct user_desc *u_info)
++{
++  long ret = syscall (SYS_set_thread_area, u_info);
++  TEST_VERIFY_EXIT (ret == 0);
++  return ret;
++}
++
++static void
++xmodify_ldt (int func, const void *ptr, unsigned long bytecount)
++{
++  TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0);
++}
++
++static int
++futex (int *uaddr, int futex_op, int val, void *timeout, int *uaddr2,
++	int val3)
++{
++  return syscall (SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
++}
++
++static void
++xsethandler (int sig, void (*handler)(int, siginfo_t *, void *), int flags)
++{
++  struct sigaction sa = { 0 };
++  sa.sa_sigaction = handler;
++  sa.sa_flags = SA_SIGINFO | flags;
++  TEST_VERIFY_EXIT (sigemptyset (&sa.sa_mask) == 0);
++  TEST_VERIFY_EXIT (sigaction (sig, &sa, 0) == 0);
++}
++
++static jmp_buf jmpbuf;
++
++static void
++sigsegv_handler (int sig, siginfo_t *info, void *ctx_void)
++{
++  siglongjmp (jmpbuf, 1);
++}
++
++/* Points to an array of 1024 ints, each holding its own index.  */
++static const unsigned int *counter_page;
++static struct user_desc *low_user_desc;
++static struct user_desc *low_user_desc_clear; /* Used to delete GDT entry.  */
++static int gdt_entry_num;
++
++static void
++setup_counter_page (void)
++{
++  long page_size = sysconf (_SC_PAGE_SIZE);
++  TEST_VERIFY_EXIT (page_size > 0);
++  unsigned int *page = xmmap (NULL, page_size, PROT_READ | PROT_WRITE,
++			      MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1);
++  for (int i = 0; i < (page_size / sizeof (unsigned int)); i++)
++    page[i] = i;
++  counter_page = page;
++}
++
++static void
++setup_low_user_desc (void)
++{
++  low_user_desc = xmmap (NULL, 2 * sizeof (struct user_desc),
++			 PROT_READ | PROT_WRITE,
++			 MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1);
++
++  low_user_desc->entry_number    = -1;
++  low_user_desc->base_addr       = (unsigned long) &counter_page[1];
++  low_user_desc->limit           = 0xffff;
++  low_user_desc->seg_32bit       = 1;
++  low_user_desc->contents        = 0;
++  low_user_desc->read_exec_only  = 0;
++  low_user_desc->limit_in_pages  = 1;
++  low_user_desc->seg_not_present = 0;
++  low_user_desc->useable         = 0;
++
++  xset_thread_area (low_user_desc);
++
++  low_user_desc_clear = low_user_desc + 1;
++  low_user_desc_clear->entry_number = gdt_entry_num;
++  low_user_desc_clear->read_exec_only = 1;
++  low_user_desc_clear->seg_not_present = 1;
++}
++
++/* Possible values of futex:
++   0: thread is idle.
++   1: thread armed.
++   2: thread should clear LDT entry 0.
++   3: thread should exit.  */
++static atomic_uint ftx;
++
++static void *
++threadproc (void *ctx)
++{
++  while (1)
++    {
++      futex ((int *) &ftx, FUTEX_WAIT, 1, NULL, NULL, 0);
++      while (atomic_load (&ftx) != 2)
++	{
++	  if (atomic_load (&ftx) >= 3)
++	    return NULL;
++	}
++
++      /* clear LDT entry 0.  */
++      const struct user_desc desc = { 0 };
++      xmodify_ldt (1, &desc, sizeof (desc));
++
++      /* If ftx == 2, set it to zero,  If ftx == 100, quit.  */
++      if (atomic_fetch_add (&ftx, -2) != 2)
++	return NULL;
++    }
++}
++
++
++/* As described in testcase, for historical reasons x86_32 Linux (and compat
++   on x86_64) interprets SA_RESTORER clear with nonzero sa_restorer as a
++   request for stack switching if the SS segment is 'funny' (this is default
++   scenario for vDSO system).  This means that anything that tries to mix
++   signal handling with segmentation should explicit clear the sa_restorer.
++
++   This testcase check if sigaction in fact does it by changing the local
++   descriptor table (LDT) through the modify_ldt syscall and triggering
++   a synchronous segfault on iret fault by trying to install an invalid
++   segment.  With a correct zeroed sa_restorer it should not trigger an
++   'real' SEGSEGV and allows the siglongjmp in signal handler.  */
++
++static int
++do_test (void)
++{
++  setup_counter_page ();
++  setup_low_user_desc ();
++
++  pthread_t thread;
++  unsigned short orig_ss;
++
++  xsethandler (SIGSEGV, sigsegv_handler, 0);
++  /* 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults.  */
++  xsethandler (SIGILL, sigsegv_handler, 0);
++
++  thread = xpthread_create (0, threadproc, 0);
++
++  asm volatile ("mov %%ss, %0" : "=rm" (orig_ss));
++
++  for (int i = 0; i < 5; i++)
++    {
++      if (sigsetjmp (jmpbuf, 1) != 0)
++	continue;
++
++      /* Make sure the thread is ready after the last test. */
++      while (atomic_load (&ftx) != 0)
++	;
++
++      struct user_desc desc = {
++	.entry_number       = 0,
++	.base_addr          = 0,
++	.limit              = 0xffff,
++	.seg_32bit          = 1,
++	.contents           = 0,
++	.read_exec_only     = 0,
++	.limit_in_pages     = 1,
++	.seg_not_present    = 0,
++	.useable            = 0
++      };
++
++      xmodify_ldt (0x11, &desc, sizeof (desc));
++
++      /* Arm the thread.  */
++      ftx = 1;
++      futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
++
++      asm volatile ("mov %0, %%ss" : : "r" (0x7));
++
++      /* Fire up thread modify_ldt call.  */
++      atomic_store (&ftx, 2);
++
++      while (atomic_load (&ftx) != 0)
++	;
++
++      /* On success, modify_ldt will segfault us synchronously and we will
++	 escape via siglongjmp.  */
++      support_record_failure ();
++    }
++
++  atomic_store (&ftx, 100);
++  futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
++
++  xpthread_join (thread);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1579730-2.patch b/SOURCES/glibc-rh1579730-2.patch
new file mode 100644
index 0000000..fbf93f8
--- /dev/null
+++ b/SOURCES/glibc-rh1579730-2.patch
@@ -0,0 +1,22 @@
+commit 4d76d3e59d31aa690f148fc0c95cc0c581aed3e8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Mar 29 11:42:24 2018 +0200
+
+    Linux i386: tst-bz21269 triggers SIGBUS on some kernels
+    
+    In addition to SIGSEGV and SIGILL, SIGBUS is also a possible signal
+    generated by the kernel.
+
+diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+index 353e36507dce92ea..6ee3fc62be0d3312 100644
+--- a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
++++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+@@ -177,6 +177,8 @@ do_test (void)
+   xsethandler (SIGSEGV, sigsegv_handler, 0);
+   /* 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults.  */
+   xsethandler (SIGILL, sigsegv_handler, 0);
++  /* Some kernels send SIGBUS instead.  */
++  xsethandler (SIGBUS, sigsegv_handler, 0);
+ 
+   thread = xpthread_create (0, threadproc, 0);
+ 
diff --git a/SOURCES/glibc-rh1579730-3.patch b/SOURCES/glibc-rh1579730-3.patch
new file mode 100644
index 0000000..e051406
--- /dev/null
+++ b/SOURCES/glibc-rh1579730-3.patch
@@ -0,0 +1,131 @@
+Port sysdeps/unix/sysv/linux/i386/tst-bz21269.c to __atomic builtins
+
+The upstream test uses <stdatomic.h>, which is not supported in the
+Red Hat Enterprise Linux 7 system compiler.
+
+The port uses __ATOMIC_SEQ_CST for consistency with the upstream test;
+such as trong memory ordering is not actually required here.
+
+Furthermore, it is necessary to change the SYS_ system call constants
+to __NR_ constants.  Downstream builts the test with internal headers,
+and those only have the __NR_ constants from the kernel.
+
+The initializer of sa in xsethandler was replaced with a memset, to
+avoid a warning about missing braces in an initializer (something that
+later GCC versions do not warn about).
+
+diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+index 6ee3fc62be0d3312..f58395cedc6972c4 100644
+--- a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
++++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
+@@ -26,8 +26,6 @@
+    - Replicate only the test required to trigger the issue for the
+      BZ#21269.  */
+ 
+-#include <stdatomic.h>
+-
+ #include <asm/ldt.h>
+ #include <linux/futex.h>
+ 
+@@ -36,6 +34,7 @@
+ #include <errno.h>
+ #include <sys/syscall.h>
+ #include <sys/mman.h>
++#include <string.h>
+ 
+ #include <support/xunistd.h>
+ #include <support/check.h>
+@@ -44,7 +43,7 @@
+ static int
+ xset_thread_area (struct user_desc *u_info)
+ {
+-  long ret = syscall (SYS_set_thread_area, u_info);
++  long ret = syscall (__NR_set_thread_area, u_info);
+   TEST_VERIFY_EXIT (ret == 0);
+   return ret;
+ }
+@@ -52,20 +51,21 @@ xset_thread_area (struct user_desc *u_info)
+ static void
+ xmodify_ldt (int func, const void *ptr, unsigned long bytecount)
+ {
+-  TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0);
++  TEST_VERIFY_EXIT (syscall (__NR_modify_ldt, 1, ptr, bytecount) == 0);
+ }
+ 
+ static int
+ futex (int *uaddr, int futex_op, int val, void *timeout, int *uaddr2,
+ 	int val3)
+ {
+-  return syscall (SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
++  return syscall (__NR_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
+ }
+ 
+ static void
+ xsethandler (int sig, void (*handler)(int, siginfo_t *, void *), int flags)
+ {
+-  struct sigaction sa = { 0 };
++  struct sigaction sa;
++  memset (&sa, 0, sizeof (sa));
+   sa.sa_sigaction = handler;
+   sa.sa_flags = SA_SIGINFO | flags;
+   TEST_VERIFY_EXIT (sigemptyset (&sa.sa_mask) == 0);
+@@ -128,7 +128,7 @@ setup_low_user_desc (void)
+    1: thread armed.
+    2: thread should clear LDT entry 0.
+    3: thread should exit.  */
+-static atomic_uint ftx;
++static unsigned int ftx;
+ 
+ static void *
+ threadproc (void *ctx)
+@@ -136,9 +136,9 @@ threadproc (void *ctx)
+   while (1)
+     {
+       futex ((int *) &ftx, FUTEX_WAIT, 1, NULL, NULL, 0);
+-      while (atomic_load (&ftx) != 2)
++      while (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) != 2)
+ 	{
+-	  if (atomic_load (&ftx) >= 3)
++	  if (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) >= 3)
+ 	    return NULL;
+ 	}
+ 
+@@ -147,7 +147,7 @@ threadproc (void *ctx)
+       xmodify_ldt (1, &desc, sizeof (desc));
+ 
+       /* If ftx == 2, set it to zero,  If ftx == 100, quit.  */
+-      if (atomic_fetch_add (&ftx, -2) != 2)
++      if (__atomic_fetch_add (&ftx, -2, __ATOMIC_SEQ_CST) != 2)
+ 	return NULL;
+     }
+ }
+@@ -190,7 +190,7 @@ do_test (void)
+ 	continue;
+ 
+       /* Make sure the thread is ready after the last test. */
+-      while (atomic_load (&ftx) != 0)
++      while (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) != 0)
+ 	;
+ 
+       struct user_desc desc = {
+@@ -214,9 +214,9 @@ do_test (void)
+       asm volatile ("mov %0, %%ss" : : "r" (0x7));
+ 
+       /* Fire up thread modify_ldt call.  */
+-      atomic_store (&ftx, 2);
++      __atomic_store_n (&ftx, 2, __ATOMIC_SEQ_CST);
+ 
+-      while (atomic_load (&ftx) != 0)
++      while (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) != 0)
+ 	;
+ 
+       /* On success, modify_ldt will segfault us synchronously and we will
+@@ -224,7 +224,7 @@ do_test (void)
+       support_record_failure ();
+     }
+ 
+-  atomic_store (&ftx, 100);
++  __atomic_store_n (&ftx, 100, __ATOMIC_SEQ_CST);
+   futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
+ 
+   xpthread_join (thread);
diff --git a/SOURCES/glibc-rh1579739-2.patch b/SOURCES/glibc-rh1579739-2.patch
new file mode 100644
index 0000000..72ea53e
--- /dev/null
+++ b/SOURCES/glibc-rh1579739-2.patch
@@ -0,0 +1,66 @@
+commit c259196b5005812aa3294dbf4eeca29b266a4522
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Mar 1 18:53:03 2019 +0100
+
+    elf/tst-big-note: Improve accuracy of test [BZ #20419]
+    
+    It is possible that the link editor injects an allocated ABI tag note
+    before the artificial, allocated large note in the test.  Note parsing
+    in open_verify stops when the first ABI tag note is encountered, so if
+    the ABI tag note comes first, the problematic code is not actually
+    exercised.
+    
+    Also tweak the artificial note so that it is a syntactically valid
+    4-byte aligned note, in case the link editor tries to parse notes and
+    process them.
+    
+    Improves the testing part of commit 0065aaaaae51cd60210ec3a7e13.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+(Minor adjustment for Makefile conflict.)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index b46b3a0e3542a06f..2b2662d5cf96c437 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -244,8 +244,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
+ # We need this variable to be sure the test modules get the right CPPFLAGS.
+ test-extras += $(modules-names)
+ 
+-# filtmod1.so has a special rule
+-modules-names-nobuild := filtmod1
++# filtmod1.so, tst-big-note-lib.so have special rules.
++modules-names-nobuild := filtmod1 tst-big-note-lib
+ 
+ ifneq (no,$(multi-arch))
+ tests-static += ifuncmain1static ifuncmain1picstatic \
+@@ -1239,3 +1239,8 @@ $(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
+ LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
+ 
+ $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
++# Avoid creating an ABI tag note, which may come before the
++# artificial, large note in tst-big-note-lib.o and invalidate the
++# test.
++$(objpfx)tst-big-note-lib.so: $(objpfx)tst-big-note-lib.o
++	$(LINK.o) -shared -o $@ $(LDFLAGS.so) $<
+diff --git a/elf/tst-big-note-lib.S b/elf/tst-big-note-lib.S
+index 6b514a03cc686141..c97590ccb05e9b2e 100644
+--- a/elf/tst-big-note-lib.S
++++ b/elf/tst-big-note-lib.S
+@@ -20,7 +20,13 @@
+    On a typical Linux system with 8MiB "ulimit -s", that was enough
+    to trigger stack overflow in open_verify.  */
+ 
++#define NOTE_SIZE 8*1024*1024
++
+ .pushsection .note.big,"a"
+-.balign 4
+-.fill 8*1024*1024, 1, 0
++	.balign 4
++	.long 5 		/* n_namesz.  Length of "GLIBC".  */
++	.long NOTE_SIZE		/* n_descsz.  */
++	.long 0			/* n_type.  */
++	.ascii "GLIBC\0\0\0"	/* Name and alignment to four bytes.  */
++	.fill NOTE_SIZE, 1, 0
+ .popsection
diff --git a/SOURCES/glibc-rh1579739.patch b/SOURCES/glibc-rh1579739.patch
new file mode 100644
index 0000000..f6811d5
--- /dev/null
+++ b/SOURCES/glibc-rh1579739.patch
@@ -0,0 +1,162 @@
+commit 0065aaaaae51cd60210ec3a7e13dddd8e01ffe2c
+Author: Paul Pluzhnikov <ppluzhnikov@google.com>
+Date:   Sat May 5 18:08:27 2018 -0700
+
+    Fix BZ 20419.  A PT_NOTE in a binary could be arbitratily large, so using
+    alloca for it may cause stack overflow.  If the note is larger than
+    __MAX_ALLOCA_CUTOFF, use dynamically allocated memory to read it in.
+    
+    2018-05-05  Paul Pluzhnikov  <ppluzhnikov@google.com>
+    
+            [BZ #20419]
+            * elf/dl-load.c (open_verify): Fix stack overflow.
+            * elf/Makefile (tst-big-note): New test.
+            * elf/tst-big-note-lib.S: New.
+            * elf/tst-big-note.c: New.
+
+Minor textual conflicts and elf/Makefile due to continued upstream
+development.
+
+diff --git a/elf/Makefile b/elf/Makefile
+index dea66ca1c12e5c29..b46b3a0e3542a06f 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -151,7 +151,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
+ 	 tst-stackguard1 tst-addr1 tst-thrlock \
+ 	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
+-	 tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1
++	 tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1 \
++	 tst-big-note
+ #	 reldep9
+ test-srcs = tst-pathopt
+ selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
+@@ -223,7 +224,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
+ 		tst-array5dep \
+ 		tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
+-		tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12
++		tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
++		tst-big-note-lib
++
+ ifeq (yesyes,$(have-fpie)$(build-shared))
+ modules-names += tst-piemod1
+ tests += tst-pie1
+@@ -1234,3 +1237,5 @@ $(objpfx)tst-audit12: $(libdl)
+ tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so
+ $(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
+ LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
++
++$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 7466b686244e55b2..013efdb3814700d3 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1744,6 +1744,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+       ElfW(Ehdr) *ehdr;
+       ElfW(Phdr) *phdr, *ph;
+       ElfW(Word) *abi_note;
++      ElfW(Word) *abi_note_malloced = NULL;
+       unsigned int osversion;
+       size_t maplength;
+ 
+@@ -1889,10 +1890,25 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+ 	      abi_note = (void *) (fbp->buf + ph->p_offset);
+ 	    else
+ 	      {
+-		abi_note = alloca (size);
++		/* Note: __libc_use_alloca is not usable here, because
++		   thread info may not have been set up yet.  */
++		if (size < __MAX_ALLOCA_CUTOFF)
++		  abi_note = alloca (size);
++		else
++		  {
++		    /* There could be multiple PT_NOTEs.  */
++		    abi_note_malloced = realloc (abi_note_malloced, size);
++		    if (abi_note_malloced == NULL)
++		      goto read_error;
++
++		    abi_note = abi_note_malloced;
++		  }
+ 		__lseek (fd, ph->p_offset, SEEK_SET);
+ 		if (__libc_read (fd, (void *) abi_note, size) != size)
+-		  goto read_error;
++		  {
++		    free (abi_note_malloced);
++		    goto read_error;
++		  }
+ 	      }
+ 
+ 	    while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
+@@ -1928,6 +1944,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+ 
+ 	    break;
+ 	  }
++      free (abi_note_malloced);
+     }
+ 
+   return fd;
+diff --git a/elf/tst-big-note-lib.S b/elf/tst-big-note-lib.S
+new file mode 100644
+index 0000000000000000..6b514a03cc686141
+--- /dev/null
++++ b/elf/tst-big-note-lib.S
+@@ -0,0 +1,26 @@
++/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This creates a .so with 8MiB PT_NOTE segment.
++   On a typical Linux system with 8MiB "ulimit -s", that was enough
++   to trigger stack overflow in open_verify.  */
++
++.pushsection .note.big,"a"
++.balign 4
++.fill 8*1024*1024, 1, 0
++.popsection
+diff --git a/elf/tst-big-note.c b/elf/tst-big-note.c
+new file mode 100644
+index 0000000000000000..fcd2b0ed82cc1667
+--- /dev/null
++++ b/elf/tst-big-note.c
+@@ -0,0 +1,26 @@
++/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This file must be run from within a directory called "elf".  */
++
++int main (int argc, char *argv[])
++{
++  /* Nothing to do here: merely linking against tst-big-note-lib.so triggers
++     the bug.  */
++  return 0;
++}
diff --git a/SOURCES/glibc-rh1591268.patch b/SOURCES/glibc-rh1591268.patch
new file mode 100644
index 0000000..3dc8bd6
--- /dev/null
+++ b/SOURCES/glibc-rh1591268.patch
@@ -0,0 +1,38 @@
+From 14beef7575099f6373f9a45b4656f1e3675f7372 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 14 Jun 2018 22:34:09 +0200
+Subject: [PATCH] localedata: Make IBM273 compatible with ISO-8859-1 [BZ
+ #23290]
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+---
+ ChangeLog                  | 8 ++++++++
+ iconvdata/ibm273.c         | 2 +-
+ localedata/charmaps/IBM273 | 2 +-
+ 3 files changed, 10 insertions(+), 2 deletions(-)
+
+Index: b/iconvdata/ibm273.c
+===================================================================
+--- a/iconvdata/ibm273.c
++++ b/iconvdata/ibm273.c
+@@ -23,6 +23,6 @@
+ #define TABLES <ibm273.h>
+ 
+ #define CHARSET_NAME	"IBM273//"
+-#define HAS_HOLES	1	/* Not all 256 character are defined.  */
++#define HAS_HOLES	0
+ 
+ #include <8bit-gap.c>
+Index: b/localedata/charmaps/IBM273
+===================================================================
+--- a/localedata/charmaps/IBM273
++++ b/localedata/charmaps/IBM273
+@@ -194,7 +194,7 @@ CHARMAP
+ <U00BE>     /xb9         VULGAR FRACTION THREE QUARTERS
+ <U00AC>     /xba         NOT SIGN
+ <U007C>     /xbb         VERTICAL LINE
+-<U203E>     /xbc         OVERLINE
++<U00AF>     /xbc         MACRON
+ <U00A8>     /xbd         DIAERESIS
+ <U00B4>     /xbe         ACUTE ACCENT
+ <U00D7>     /xbf         MULTIPLICATION SIGN
diff --git a/SOURCES/glibc-rh1592475-1.patch b/SOURCES/glibc-rh1592475-1.patch
new file mode 100644
index 0000000..e1785dc
--- /dev/null
+++ b/SOURCES/glibc-rh1592475-1.patch
@@ -0,0 +1,194 @@
+From f2857da7cdb65bfad75ee30981f5b2fde5bbb1dc Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Mon, 18 Jun 2018 13:37:57 +0000
+Subject: [PATCH] Add SHM_STAT_ANY from Linux 4.17 to bits/shm.h.
+
+Linux 4.17 adds a SHM_STAT_ANY constant (ipcs command).  This patch
+adds it to the relevant bits/shm.h headers.
+
+Tested for x86_64.
+
+	* sysdeps/unix/sysv/linux/alpha/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): New macro.
+	* sysdeps/unix/sysv/linux/arm/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/generic/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/hppa/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/ia64/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/mips/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/sh/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/x86/bits/shm.h [__USE_MISC]
+	(SHM_STAT_ANY): Likewise.
+---
+ ChangeLog                                  | 25 ++++++++++++++++++++++
+ sysdeps/unix/sysv/linux/alpha/bits/shm.h   |  1 +
+ sysdeps/unix/sysv/linux/arm/bits/shm.h     |  1 +
+ sysdeps/unix/sysv/linux/bits/shm.h         |  1 +
+ sysdeps/unix/sysv/linux/generic/bits/shm.h |  1 +
+ sysdeps/unix/sysv/linux/hppa/bits/shm.h    |  1 +
+ sysdeps/unix/sysv/linux/ia64/bits/shm.h    |  1 +
+ sysdeps/unix/sysv/linux/mips/bits/shm.h    |  1 +
+ sysdeps/unix/sysv/linux/powerpc/bits/shm.h |  1 +
+ sysdeps/unix/sysv/linux/s390/bits/shm.h    |  1 +
+ sysdeps/unix/sysv/linux/sh/bits/shm.h      |  1 +
+ sysdeps/unix/sysv/linux/sparc/bits/shm.h   |  1 +
+ sysdeps/unix/sysv/linux/x86/bits/shm.h     |  1 +
+ 13 files changed, 37 insertions(+)
+
+Index: b/sysdeps/unix/sysv/linux/alpha/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/alpha/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/alpha/bits/shm.h
+@@ -65,6 +65,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/arm/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/arm/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/arm/bits/shm.h
+@@ -69,6 +69,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/bits/shm.h
+@@ -68,6 +68,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/generic/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/generic/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/generic/bits/shm.h
+@@ -76,6 +76,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/hppa/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
+@@ -73,6 +73,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/ia64/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/ia64/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/ia64/bits/shm.h
+@@ -61,6 +61,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/mips/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/mips/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/shm.h
+@@ -62,6 +62,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT	13
+ # define SHM_INFO	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
+@@ -78,6 +78,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT      13
+ # define SHM_INFO      14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST      01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/s390/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/s390/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/shm.h
+@@ -75,6 +75,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT	13
+ # define SHM_INFO	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/sh/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/sh/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/sh/bits/shm.h
+@@ -66,6 +66,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/sparc/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/sparc/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/shm.h
+@@ -76,6 +76,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
+Index: b/sysdeps/unix/sysv/linux/x86/bits/shm.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/x86/bits/shm.h
++++ b/sysdeps/unix/sysv/linux/x86/bits/shm.h
+@@ -74,6 +74,7 @@ struct shmid_ds
+ /* ipcs ctl commands */
+ # define SHM_STAT 	13
+ # define SHM_INFO 	14
++# define SHM_STAT_ANY	15
+ 
+ /* shm_mode upper byte flags */
+ # define SHM_DEST	01000	/* segment will be destroyed on last detach */
diff --git a/SOURCES/glibc-rh1592475-2.patch b/SOURCES/glibc-rh1592475-2.patch
new file mode 100644
index 0000000..7b6fc50
--- /dev/null
+++ b/SOURCES/glibc-rh1592475-2.patch
@@ -0,0 +1,164 @@
+From 176c7fee517c11f628aed4ef4b9457e47fa976a1 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Mon, 18 Jun 2018 13:36:41 +0000
+Subject: [PATCH] Add SEM_STAT_ANY from Linux 4.17 to bits/sem.h.
+
+Linux 4.17 adds a SEM_STAT_ANY constant (ipcs command).  This patch
+adds it to the relevant bits/sem.h headers.
+
+Tested for x86_64.
+
+	* sysdeps/unix/sysv/linux/alpha/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): New macro.
+	* sysdeps/unix/sysv/linux/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/generic/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/hppa/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/ia64/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/mips/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/x86/bits/sem.h [__USE_MISC]
+	(SEM_STAT_ANY): Likewise.
+---
+ ChangeLog                                  | 21 +++++++++++++++++++++
+ sysdeps/unix/sysv/linux/alpha/bits/sem.h   |  1 +
+ sysdeps/unix/sysv/linux/bits/sem.h         |  1 +
+ sysdeps/unix/sysv/linux/generic/bits/sem.h |  1 +
+ sysdeps/unix/sysv/linux/hppa/bits/sem.h    |  1 +
+ sysdeps/unix/sysv/linux/ia64/bits/sem.h    |  1 +
+ sysdeps/unix/sysv/linux/mips/bits/sem.h    |  1 +
+ sysdeps/unix/sysv/linux/powerpc/bits/sem.h |  1 +
+ sysdeps/unix/sysv/linux/s390/bits/sem.h    |  1 +
+ sysdeps/unix/sysv/linux/sparc/bits/sem.h   |  1 +
+ sysdeps/unix/sysv/linux/x86/bits/sem.h     |  1 +
+ 11 files changed, 31 insertions(+)
+
+Index: b/sysdeps/unix/sysv/linux/alpha/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/alpha/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/alpha/bits/sem.h
+@@ -66,6 +66,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/bits/sem.h
+@@ -68,6 +68,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/generic/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/generic/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/generic/bits/sem.h
+@@ -74,6 +74,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/hppa/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/hppa/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/sem.h
+@@ -73,6 +73,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/ia64/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/ia64/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/ia64/bits/sem.h
+@@ -68,6 +68,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/mips/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/mips/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/sem.h
+@@ -66,6 +66,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
+@@ -73,6 +73,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/s390/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/s390/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/sem.h
+@@ -73,6 +73,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct	seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/sparc/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/sparc/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/sem.h
+@@ -73,6 +73,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
+Index: b/sysdeps/unix/sysv/linux/x86/bits/sem.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/x86/bits/sem.h
++++ b/sysdeps/unix/sysv/linux/x86/bits/sem.h
+@@ -68,6 +68,7 @@ struct semid_ds
+ /* ipcs ctl cmds */
+ # define SEM_STAT 18
+ # define SEM_INFO 19
++# define SEM_STAT_ANY 20
+ 
+ struct  seminfo
+ {
diff --git a/SOURCES/glibc-rh1592475-3.patch b/SOURCES/glibc-rh1592475-3.patch
new file mode 100644
index 0000000..4a7fab5
--- /dev/null
+++ b/SOURCES/glibc-rh1592475-3.patch
@@ -0,0 +1,164 @@
+From 86bf0019ed9c0d1e19916448454c3f7df0479ac6 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Mon, 18 Jun 2018 13:34:52 +0000
+Subject: [PATCH] Add MSG_STAT_ANY from Linux 4.17 to bits/msq.h.
+
+Linux 4.17 adds a MSG_STAT_ANY constant (ipcs command).  This patch
+adds it to the relevant bits/msq.h headers.
+
+Tested for x86_64.
+
+	* sysdeps/unix/sysv/linux/alpha/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): New macro.
+	* sysdeps/unix/sysv/linux/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/generic/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/hppa/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/ia64/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/mips/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+	* sysdeps/unix/sysv/linux/x86/bits/msq.h [__USE_MISC]
+	(MSG_STAT_ANY): Likewise.
+---
+ ChangeLog                                  | 21 +++++++++++++++++++++
+ sysdeps/unix/sysv/linux/alpha/bits/msq.h   |  1 +
+ sysdeps/unix/sysv/linux/bits/msq.h         |  1 +
+ sysdeps/unix/sysv/linux/generic/bits/msq.h |  1 +
+ sysdeps/unix/sysv/linux/hppa/bits/msq.h    |  1 +
+ sysdeps/unix/sysv/linux/ia64/bits/msq.h    |  1 +
+ sysdeps/unix/sysv/linux/mips/bits/msq.h    |  1 +
+ sysdeps/unix/sysv/linux/powerpc/bits/msq.h |  1 +
+ sysdeps/unix/sysv/linux/s390/bits/msq.h    |  1 +
+ sysdeps/unix/sysv/linux/sparc/bits/msq.h   |  1 +
+ sysdeps/unix/sysv/linux/x86/bits/msq.h     |  1 +
+ 11 files changed, 31 insertions(+)
+
+Index: b/sysdeps/unix/sysv/linux/alpha/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/alpha/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/alpha/bits/msq.h
+@@ -56,6 +56,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/bits/msq.h
+@@ -59,6 +59,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/generic/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/generic/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/generic/bits/msq.h
+@@ -66,6 +66,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/hppa/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/hppa/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/hppa/bits/msq.h
+@@ -66,6 +66,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/ia64/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/ia64/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/ia64/bits/msq.h
+@@ -51,6 +51,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/mips/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/mips/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/mips/bits/msq.h
+@@ -74,6 +74,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
+@@ -65,6 +65,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/s390/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/s390/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/s390/bits/msq.h
+@@ -66,6 +66,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/sparc/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/sparc/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/sparc/bits/msq.h
+@@ -66,6 +66,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
+Index: b/sysdeps/unix/sysv/linux/x86/bits/msq.h
+===================================================================
+--- a/sysdeps/unix/sysv/linux/x86/bits/msq.h
++++ b/sysdeps/unix/sysv/linux/x86/bits/msq.h
+@@ -64,6 +64,7 @@ struct msqid_ds
+ /* ipcs ctl commands */
+ # define MSG_STAT 11
+ # define MSG_INFO 12
++# define MSG_STAT_ANY 13
+ 
+ /* buffer for msgctl calls IPC_INFO, MSG_INFO */
+ struct msginfo
diff --git a/SOURCES/glibc-rh1595191-1.patch b/SOURCES/glibc-rh1595191-1.patch
new file mode 100644
index 0000000..62a85d7
--- /dev/null
+++ b/SOURCES/glibc-rh1595191-1.patch
@@ -0,0 +1,230 @@
+commit 0262507918cfad7223bf81b8f162b7adc7a2af01
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Jun 1 10:43:06 2018 +0200
+
+    libio: Avoid _allocate_buffer, _free_buffer function pointers [BZ #23236]
+    
+    These unmangled function pointers reside on the heap and could
+    be targeted by exploit writers, effectively bypassing libio vtable
+    validation.  Instead, we ignore these pointers and always call
+    malloc or free.
+    
+    In theory, this is a backwards-incompatible change, but using the
+    global heap instead of the user-supplied callback functions should
+    have little application impact.  (The old libstdc++ implementation
+    exposed this functionality via a public, undocumented constructor
+    in its strstreambuf class.)
+    
+    (cherry picked from commit 4e8a6346cd3da2d88bbad745a1769260d36f2783)
+
+Backported from the upstream release/2.26/master branch.
+
+diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c
+index a8ca32bad57b4d13..113354749ccf8d9a 100644
+--- a/debug/vasprintf_chk.c
++++ b/debug/vasprintf_chk.c
+@@ -55,8 +55,8 @@ __vasprintf_chk (char **result_ptr, int flags, const char *format,
+   _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
+   _IO_str_init_static_internal (&sf, string, init_string_size, string);
+   sf._sbf._f._flags &= ~_IO_USER_BUF;
+-  sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+-  sf._s._free_buffer = (_IO_free_type) free;
++  sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
++  sf._s._free_buffer_unused = (_IO_free_type) free;
+ 
+   /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
+      can only come from read-only format strings.  */
+diff --git a/libio/memstream.c b/libio/memstream.c
+index e18a7756b297c9f4..9a51331e525c3468 100644
+--- a/libio/memstream.c
++++ b/libio/memstream.c
+@@ -87,8 +87,8 @@ open_memstream (char **bufloc, _IO_size_t *sizeloc)
+   _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps;
+   _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
+   new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
+-  new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+-  new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
++  new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
++  new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
+ 
+   new_f->fp.bufloc = bufloc;
+   new_f->fp.sizeloc = sizeloc;
+diff --git a/libio/strfile.h b/libio/strfile.h
+index 4ea7548f9fa92638..9cd8e7c466616b52 100644
+--- a/libio/strfile.h
++++ b/libio/strfile.h
+@@ -34,8 +34,11 @@ typedef void (*_IO_free_type) (void*);
+ 
+ struct _IO_str_fields
+ {
+-  _IO_alloc_type _allocate_buffer;
+-  _IO_free_type _free_buffer;
++  /* These members are preserved for ABI compatibility.  The glibc
++     implementation always calls malloc/free for user buffers if
++     _IO_USER_BUF or _IO_FLAGS2_USER_WBUF are not set.  */
++  _IO_alloc_type _allocate_buffer_unused;
++  _IO_free_type _free_buffer_unused;
+ };
+ 
+ /* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type,
+@@ -55,10 +58,6 @@ typedef struct _IO_strfile_
+   struct _IO_str_fields _s;
+ } _IO_strfile;
+ 
+-/* dynamic: set when the array object is allocated (or reallocated)  as
+-   necessary to hold a character sequence that can change in length. */
+-#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0)
+-
+ /* frozen: set when the program has requested that the array object not
+    be altered, reallocated, or freed. */
+ #define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF)
+diff --git a/libio/strops.c b/libio/strops.c
+index fdd113a60811e593..129a0f6aeca818fd 100644
+--- a/libio/strops.c
++++ b/libio/strops.c
+@@ -61,7 +61,7 @@ _IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size,
+       fp->_IO_read_end = end;
+     }
+   /* A null _allocate_buffer function flags the strfile as being static. */
+-  sf->_s._allocate_buffer = (_IO_alloc_type) 0;
++  sf->_s._allocate_buffer_unused = (_IO_alloc_type) 0;
+ }
+ 
+ void
+@@ -103,8 +103,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
+ 	  _IO_size_t new_size = 2 * old_blen + 100;
+ 	  if (new_size < old_blen)
+ 	    return EOF;
+-	  new_buf
+-	    = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
++	  new_buf = malloc (new_size);
+ 	  if (new_buf == NULL)
+ 	    {
+ 	      /*	  __ferror(fp) = 1; */
+@@ -113,7 +112,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
+ 	  if (old_buf)
+ 	    {
+ 	      memcpy (new_buf, old_buf, old_blen);
+-	      (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
++	      free (old_buf);
+ 	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
+ 	      fp->_IO_buf_base = NULL;
+ 	    }
+@@ -182,15 +181,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
+ 
+   _IO_size_t newsize = offset + 100;
+   char *oldbuf = fp->_IO_buf_base;
+-  char *newbuf
+-    = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize);
++  char *newbuf = malloc (newsize);
+   if (newbuf == NULL)
+     return 1;
+ 
+   if (oldbuf != NULL)
+     {
+       memcpy (newbuf, oldbuf, _IO_blen (fp));
+-      (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
++      free (oldbuf);
+       /* Make sure _IO_setb won't try to delete
+ 	 _IO_buf_base. */
+       fp->_IO_buf_base = NULL;
+@@ -317,7 +315,7 @@ void
+ _IO_str_finish (_IO_FILE *fp, int dummy)
+ {
+   if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+-    (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
++    free (fp->_IO_buf_base);
+   fp->_IO_buf_base = NULL;
+ 
+   _IO_default_finish (fp, 0);
+diff --git a/libio/vasprintf.c b/libio/vasprintf.c
+index 282c86fff0a7ae0e..867ef4fe4ca4ec56 100644
+--- a/libio/vasprintf.c
++++ b/libio/vasprintf.c
+@@ -54,8 +54,8 @@ _IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args)
+   _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
+   _IO_str_init_static_internal (&sf, string, init_string_size, string);
+   sf._sbf._f._flags &= ~_IO_USER_BUF;
+-  sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+-  sf._s._free_buffer = (_IO_free_type) free;
++  sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
++  sf._s._free_buffer_unused = (_IO_free_type) free;
+   ret = _IO_vfprintf (&sf._sbf._f, format, args);
+   if (ret < 0)
+     {
+diff --git a/libio/wmemstream.c b/libio/wmemstream.c
+index bd6d1798b1685fe9..3a9a681c80a321a7 100644
+--- a/libio/wmemstream.c
++++ b/libio/wmemstream.c
+@@ -90,8 +90,8 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc)
+   _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
+ 			_IO_BUFSIZ / sizeof (wchar_t), buf);
+   new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF;
+-  new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+-  new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
++  new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
++  new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
+ 
+   new_f->fp.bufloc = bufloc;
+   new_f->fp.sizeloc = sizeloc;
+diff --git a/libio/wstrops.c b/libio/wstrops.c
+index 7a9a33ab8763b8ff..a31d0e23341b2aad 100644
+--- a/libio/wstrops.c
++++ b/libio/wstrops.c
+@@ -63,7 +63,7 @@ _IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size,
+       fp->_wide_data->_IO_read_end = end;
+     }
+   /* A null _allocate_buffer function flags the strfile as being static. */
+-  (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
++  (((_IO_strfile *) fp)->_s._allocate_buffer_unused) = (_IO_alloc_type)0;
+ }
+ 
+ _IO_wint_t
+@@ -95,9 +95,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
+ 	      || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
+ 	    return EOF;
+ 
+-	  new_buf
+-	    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
+-									* sizeof (wchar_t));
++	  new_buf = malloc (new_size * sizeof (wchar_t));
+ 	  if (new_buf == NULL)
+ 	    {
+ 	      /*	  __ferror(fp) = 1; */
+@@ -106,7 +104,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
+ 	  if (old_buf)
+ 	    {
+ 	      __wmemcpy (new_buf, old_buf, old_wblen);
+-	      (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
++	      free (old_buf);
+ 	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
+ 	      fp->_wide_data->_IO_buf_base = NULL;
+ 	    }
+@@ -186,16 +184,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
+     return 1;
+ 
+   wchar_t *oldbuf = wd->_IO_buf_base;
+-  wchar_t *newbuf
+-    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
+-								* sizeof (wchar_t));
++  wchar_t *newbuf = malloc (newsize * sizeof (wchar_t));
+   if (newbuf == NULL)
+     return 1;
+ 
+   if (oldbuf != NULL)
+     {
+       __wmemcpy (newbuf, oldbuf, _IO_wblen (fp));
+-      (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
++      free (oldbuf);
+       /* Make sure _IO_setb won't try to delete
+ 	 _IO_buf_base. */
+       wd->_IO_buf_base = NULL;
+@@ -326,7 +322,7 @@ void
+ _IO_wstr_finish (_IO_FILE *fp, int dummy)
+ {
+   if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
+-    (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base);
++    free (fp->_wide_data->_IO_buf_base);
+   fp->_wide_data->_IO_buf_base = NULL;
+ 
+   _IO_wdefault_finish (fp, 0);
diff --git a/SOURCES/glibc-rh1595191-2.patch b/SOURCES/glibc-rh1595191-2.patch
new file mode 100644
index 0000000..17b6030
--- /dev/null
+++ b/SOURCES/glibc-rh1595191-2.patch
@@ -0,0 +1,34 @@
+commit 3bb748257405e94e13de76573a4e9da1cfd961d0
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Jul 3 15:54:49 2018 +0200
+
+    libio: Disable vtable validation in case of interposition [BZ #23313]
+    
+    (cherry picked from commit c402355dfa7807b8e0adb27c009135a7e2b9f1b0)
+
+Backported from the upstream release/2.26/master branch.
+
+diff --git a/libio/vtables.c b/libio/vtables.c
+index e364ea03edbfa75b..d6478e4bab9050ce 100644
+--- a/libio/vtables.c
++++ b/libio/vtables.c
+@@ -68,3 +68,19 @@ _IO_vtable_check (void)
+ 
+   __libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n");
+ }
++
++/* Some variants of libstdc++ interpose _IO_2_1_stdin_ etc. and
++   install their own vtables directly, without calling _IO_init or
++   other functions.  Detect this by looking at the vtables values
++   during startup, and disable vtable validation in this case.  */
++#ifdef SHARED
++__attribute__ ((constructor))
++static void
++check_stdfiles_vtables (void)
++{
++  if (_IO_2_1_stdin_.vtable != &_IO_file_jumps
++      || _IO_2_1_stdout_.vtable != &_IO_file_jumps
++      || _IO_2_1_stderr_.vtable != &_IO_file_jumps)
++    IO_set_accept_foreign_vtables (&_IO_vtable_check);
++}
++#endif
diff --git a/SOURCES/glibc-rh1595191-3.patch b/SOURCES/glibc-rh1595191-3.patch
new file mode 100644
index 0000000..ab88533
--- /dev/null
+++ b/SOURCES/glibc-rh1595191-3.patch
@@ -0,0 +1,624 @@
+commit 44927211651adde42bbd431ef5ebe568186125e5
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Jul 3 17:57:14 2018 +0200
+
+    libio: Add tst-vtables, tst-vtables-interposed
+    
+    (cherry picked from commit 29055464a03c72762969a2e8734d0d05d4d70e58)
+    
+    Some adjustments were needed for a tricky multi-inclusion issue related
+    to libioP.h.
+
+Backported from the upsteam release/2.26/master branch, adjusted for
+lack of tests-internal support downstream.
+
+diff --git a/libio/Makefile b/libio/Makefile
+index 0cef96141209fe99..1e923da42e45c492 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -61,7 +61,9 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
+ 	bug-memstream1 bug-wmemstream1 \
+ 	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
+ 	tst-fwrite-error tst-ftell-active-handler \
+-	tst-ftell-append
++	tst-ftell-append \
++	tst-vtables tst-vtables-interposed
++
+ ifeq (yes,$(build-shared))
+ # Add test-fopenloc only if shared library is enabled since it depends on
+ # shared localedata objects.
+diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c
+new file mode 100644
+index 0000000000000000..dc8d89c195b95b8d
+--- /dev/null
++++ b/libio/tst-vtables-common.c
+@@ -0,0 +1,511 @@
++/* Test for libio vtables and their validation.  Common code.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This test provides some coverage for how various stdio functions
++   use the vtables in FILE * objects.  The focus is mostly on which
++   functions call which methods, not so much on validating data
++   processing.  An initial series of tests check that custom vtables
++   do not work without activation through _IO_init.
++
++   Note: libio vtables are deprecated feature.  Do not use this test
++   as a documentation source for writing custom vtables.  See
++   fopencookie for a different way of creating custom stdio
++   streams.  */
++
++#include <stdbool.h>
++#include <string.h>
++#include <support/capture_subprocess.h>
++#include <support/check.h>
++#include <support/namespace.h>
++#include <support/support.h>
++#include <support/test-driver.h>
++#include <support/xunistd.h>
++
++/* Data shared between the test subprocess and the test driver in the
++   parent.  Note that *shared is reset at the start of the check_call
++   function.  */
++struct shared
++{
++  /* Expected file pointer for method calls.  */
++  FILE *fp;
++
++  /* If true, assume that a call to _IO_init is needed to enable
++     custom vtables.  */
++  bool initially_disabled;
++
++  /* Requested return value for the methods which have one.  */
++  int return_value;
++
++  /* A value (usually a character) recorded by some of the methods
++     below.  */
++  int value;
++
++  /* Likewise, for some data.  */
++  char buffer[16];
++  size_t buffer_length;
++
++  /* Total number of method calls.  */
++  unsigned int calls;
++
++  /* Individual method call counts.  */
++  unsigned int calls_finish;
++  unsigned int calls_overflow;
++  unsigned int calls_underflow;
++  unsigned int calls_uflow;
++  unsigned int calls_pbackfail;
++  unsigned int calls_xsputn;
++  unsigned int calls_xsgetn;
++  unsigned int calls_seekoff;
++  unsigned int calls_seekpos;
++  unsigned int calls_setbuf;
++  unsigned int calls_sync;
++  unsigned int calls_doallocate;
++  unsigned int calls_read;
++  unsigned int calls_write;
++  unsigned int calls_seek;
++  unsigned int calls_close;
++  unsigned int calls_stat;
++  unsigned int calls_showmanyc;
++  unsigned int calls_imbue;
++} *shared;
++
++/* Method implementations which increment the counters in *shared.  */
++
++static void
++log_method (FILE *fp, const char *name)
++{
++  if (test_verbose > 0)
++    printf ("info: %s (%p) called\n", name, fp);
++}
++
++static void
++method_finish (FILE *fp, int dummy)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_finish;
++}
++
++static int
++method_overflow (FILE *fp, int ch)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_overflow;
++  shared->value = ch;
++  return shared->return_value;
++}
++
++static int
++method_underflow (FILE *fp)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_underflow;
++  return shared->return_value;
++}
++
++static int
++method_uflow (FILE *fp)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_uflow;
++  return shared->return_value;
++}
++
++static int
++method_pbackfail (FILE *fp, int ch)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_pbackfail;
++  shared->value = ch;
++  return shared->return_value;
++}
++
++static size_t
++method_xsputn (FILE *fp, const void *data, size_t n)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_xsputn;
++
++  size_t to_copy = n;
++  if (n > sizeof (shared->buffer))
++    to_copy = sizeof (shared->buffer);
++  memcpy (shared->buffer, data, to_copy);
++  shared->buffer_length = to_copy;
++  return to_copy;
++}
++
++static size_t
++method_xsgetn (FILE *fp, void *data, size_t n)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_xsgetn;
++  return 0;
++}
++
++static off64_t
++method_seekoff (FILE *fp, off64_t offset, int dir, int mode)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_seekoff;
++  return shared->return_value;
++}
++
++static off64_t
++method_seekpos (FILE *fp, off64_t offset, int mode)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_seekpos;
++  return shared->return_value;
++}
++
++static FILE *
++method_setbuf (FILE *fp, char *buffer, ssize_t length)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_setbuf;
++  return fp;
++}
++
++static int
++method_sync (FILE *fp)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_sync;
++  return shared->return_value;
++}
++
++static int
++method_doallocate (FILE *fp)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_doallocate;
++  return shared->return_value;
++}
++
++static ssize_t
++method_read (FILE *fp, void *data, ssize_t length)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_read;
++  return shared->return_value;
++}
++
++static ssize_t
++method_write (FILE *fp, const void *data, ssize_t length)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_write;
++  return shared->return_value;
++}
++
++static off64_t
++method_seek (FILE *fp, off64_t offset, int mode)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_seek;
++  return shared->return_value;
++}
++
++static int
++method_close (FILE *fp)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_close;
++  return shared->return_value;
++}
++
++static int
++method_stat (FILE *fp, void *buffer)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_stat;
++  return shared->return_value;
++}
++
++static int
++method_showmanyc (FILE *fp)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_showmanyc;
++  return shared->return_value;
++}
++
++static void
++method_imbue (FILE *fp, void *locale)
++{
++  log_method (fp, __func__);
++  TEST_VERIFY (fp == shared->fp);
++  ++shared->calls;
++  ++shared->calls_imbue;
++}
++
++/* Our custom vtable.  */
++
++static const struct _IO_jump_t jumps =
++{
++  JUMP_INIT_DUMMY,
++  JUMP_INIT (finish, method_finish),
++  JUMP_INIT (overflow, method_overflow),
++  JUMP_INIT (underflow, method_underflow),
++  JUMP_INIT (uflow, method_uflow),
++  JUMP_INIT (pbackfail, method_pbackfail),
++  JUMP_INIT (xsputn, method_xsputn),
++  JUMP_INIT (xsgetn, method_xsgetn),
++  JUMP_INIT (seekoff, method_seekoff),
++  JUMP_INIT (seekpos, method_seekpos),
++  JUMP_INIT (setbuf, method_setbuf),
++  JUMP_INIT (sync, method_sync),
++  JUMP_INIT (doallocate, method_doallocate),
++  JUMP_INIT (read, method_read),
++  JUMP_INIT (write, method_write),
++  JUMP_INIT (seek, method_seek),
++  JUMP_INIT (close, method_close),
++  JUMP_INIT (stat, method_stat),
++  JUMP_INIT (showmanyc, method_showmanyc),
++  JUMP_INIT (imbue, method_imbue)
++};
++
++/* Our file implementation.  */
++
++struct my_file
++{
++  FILE f;
++  const struct _IO_jump_t *vtable;
++};
++
++struct my_file
++my_file_create (void)
++{
++  return (struct my_file)
++    {
++      /* Disable locking, so that we do not have to set up a lock
++         pointer.  */
++      .f._flags =  _IO_USER_LOCK,
++
++      /* Copy the offset from the an initialized handle, instead of
++         figuring it out from scratch.  */
++      .f._vtable_offset = stdin->_vtable_offset,
++
++      .vtable = &jumps,
++    };
++}
++
++/* Initial tests which do not enable vtable compatibility.  */
++
++/* Inhibit GCC optimization of fprintf.  */
++typedef int (*fprintf_type) (FILE *, const char *, ...);
++static const volatile fprintf_type fprintf_ptr = &fprintf;
++
++static void
++without_compatibility_fprintf (void *closure)
++{
++  /* This call should abort.  */
++  fprintf_ptr (shared->fp, " ");
++  _exit (1);
++}
++
++static void
++without_compatibility_fputc (void *closure)
++{
++  /* This call should abort.  */
++  fputc (' ', shared->fp);
++  _exit (1);
++}
++
++static void
++without_compatibility_fgetc (void *closure)
++{
++  /* This call should abort.  */
++  fgetc (shared->fp);
++  _exit (1);
++}
++
++static void
++without_compatibility_fflush (void *closure)
++{
++  /* This call should abort.  */
++  fflush (shared->fp);
++  _exit (1);
++}
++
++/* Exit status after abnormal termination.  */
++static int termination_status;
++
++static void
++init_termination_status (void)
++{
++  pid_t pid = xfork ();
++  if (pid == 0)
++    abort ();
++  xwaitpid (pid, &termination_status, 0);
++
++  TEST_VERIFY (WIFSIGNALED (termination_status));
++  TEST_COMPARE (WTERMSIG (termination_status), SIGABRT);
++}
++
++static void
++check_for_termination (const char *name, void (*callback) (void *))
++{
++  struct my_file file = my_file_create ();
++  shared->fp = &file.f;
++  shared->return_value = -1;
++  shared->calls = 0;
++  struct support_capture_subprocess proc
++    = support_capture_subprocess (callback, NULL);
++  support_capture_subprocess_check (&proc, name, termination_status,
++                                    sc_allow_stderr);
++  const char *message
++    = "Fatal error: glibc detected an invalid stdio handle\n";
++  TEST_COMPARE_BLOB (proc.err.buffer, proc.err.length,
++                     message, strlen (message));
++  TEST_COMPARE (shared->calls, 0);
++  support_capture_subprocess_free (&proc);
++}
++
++/* The test with vtable validation disabled.  */
++
++/* This function does not have a prototype in libioP.h to prevent
++   accidental use from within the library (which would disable vtable
++   verification).  */
++void _IO_init (FILE *fp, int flags);
++
++static void
++with_compatibility_fprintf (void *closure)
++{
++  TEST_COMPARE (fprintf_ptr (shared->fp, "A%sCD", "B"), 4);
++  TEST_COMPARE (shared->calls, 3);
++  TEST_COMPARE (shared->calls_xsputn, 3);
++  TEST_COMPARE_BLOB (shared->buffer, shared->buffer_length,
++                     "CD", 2);
++}
++
++static void
++with_compatibility_fputc (void *closure)
++{
++  shared->return_value = '@';
++  TEST_COMPARE (fputc ('@', shared->fp), '@');
++  TEST_COMPARE (shared->calls, 1);
++  TEST_COMPARE (shared->calls_overflow, 1);
++  TEST_COMPARE (shared->value, '@');
++}
++
++static void
++with_compatibility_fgetc (void *closure)
++{
++  shared->return_value = 'X';
++  TEST_COMPARE (fgetc (shared->fp), 'X');
++  TEST_COMPARE (shared->calls, 1);
++  TEST_COMPARE (shared->calls_uflow, 1);
++}
++
++static void
++with_compatibility_fflush (void *closure)
++{
++  TEST_COMPARE (fflush (shared->fp), 0);
++  TEST_COMPARE (shared->calls, 1);
++  TEST_COMPARE (shared->calls_sync, 1);
++}
++
++/* Call CALLBACK in a subprocess, after setting up a custom file
++   object and updating shared->fp.  */
++static void
++check_call (const char *name, void (*callback) (void *),
++            bool initially_disabled)
++{
++  *shared = (struct shared)
++    {
++     .initially_disabled = initially_disabled,
++    };
++
++  /* Set up a custom file object.  */
++  struct my_file file = my_file_create ();
++  shared->fp = &file.f;
++  if (shared->initially_disabled)
++    _IO_init (shared->fp, file.f._flags);
++
++  if (test_verbose > 0)
++    printf ("info: calling test %s\n", name);
++  support_isolate_in_subprocess (callback, NULL);
++}
++
++/* Run the tests.  INITIALLY_DISABLED indicates whether custom vtables
++   are disabled when the test starts.  */
++static int
++run_tests (bool initially_disabled)
++{
++  /* The test relies on fatal error messages being printed to standard
++     error.  */
++  setenv ("LIBC_FATAL_STDERR_", "1", 1);
++
++  shared = support_shared_allocate (sizeof (*shared));
++  shared->initially_disabled = initially_disabled;
++  init_termination_status ();
++
++  if (initially_disabled)
++    {
++      check_for_termination ("fprintf", without_compatibility_fprintf);
++      check_for_termination ("fputc", without_compatibility_fputc);
++      check_for_termination ("fgetc", without_compatibility_fgetc);
++      check_for_termination ("fflush", without_compatibility_fflush);
++    }
++
++  check_call ("fprintf", with_compatibility_fprintf, initially_disabled);
++  check_call ("fputc", with_compatibility_fputc, initially_disabled);
++  check_call ("fgetc", with_compatibility_fgetc, initially_disabled);
++  check_call ("fflush", with_compatibility_fflush, initially_disabled);
++
++  support_shared_free (shared);
++  shared = NULL;
++
++  return 0;
++}
+diff --git a/libio/tst-vtables-interposed.c b/libio/tst-vtables-interposed.c
+new file mode 100644
+index 0000000000000000..c8f4e8c7c386af39
+--- /dev/null
++++ b/libio/tst-vtables-interposed.c
+@@ -0,0 +1,37 @@
++/* Test for libio vtables and their validation.  Enabled through interposition.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* Provide an interposed definition of the standard file handles with
++   our own vtable.  stdout/stdin/stderr will not work as a result, but
++   a succesful test does not print anything, so this is fine.  */
++static const struct _IO_jump_t jumps;
++#define _IO_file_jumps jumps
++#include "stdfiles.c"
++
++#include "tst-vtables-common.c"
++
++static int
++do_test (void)
++{
++  return run_tests (false);
++}
++
++/* Calling setvbuf in the test driver is not supported with our
++   interposed file handles.  */
++#define TEST_NO_SETVBUF
++#include <support/test-driver.c>
+diff --git a/libio/tst-vtables.c b/libio/tst-vtables.c
+new file mode 100644
+index 0000000000000000..f16acf5d23b0fff6
+--- /dev/null
++++ b/libio/tst-vtables.c
+@@ -0,0 +1,29 @@
++/* Test for libio vtables and their validation.  Initially disabled case.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include "libioP.h"
++
++#include "tst-vtables-common.c"
++
++static int
++do_test (void)
++{
++  return run_tests (true);
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1595191-4.patch b/SOURCES/glibc-rh1595191-4.patch
new file mode 100644
index 0000000..9e9d95b
--- /dev/null
+++ b/SOURCES/glibc-rh1595191-4.patch
@@ -0,0 +1,24 @@
+commit 2d1c89a5d7c872a1109768f50e2508cf9a4b0348
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Jun 20 09:45:19 2018 +0200
+
+    libio: Avoid ptrdiff_t overflow in IO_validate_vtable
+    
+    If the candidate pointer is sufficiently far away from
+    __start___libc_IO_vtables, the result might not fit into ptrdiff_t.
+
+diff --git a/libio/libioP.h b/libio/libioP.h
+index b60244ac5fc3d908..f1576381500ffc85 100644
+--- a/libio/libioP.h
++++ b/libio/libioP.h
+@@ -957,8 +957,8 @@ IO_validate_vtable (const struct _IO_jump_t *vtable)
+   /* Fast path: The vtable pointer is within the __libc_IO_vtables
+      section.  */
+   uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;
+-  const char *ptr = (const char *) vtable;
+-  uintptr_t offset = ptr - __start___libc_IO_vtables;
++  uintptr_t ptr = (uintptr_t) vtable;
++  uintptr_t offset = ptr - (uintptr_t) __start___libc_IO_vtables;
+   if (__glibc_unlikely (offset >= section_length))
+     /* The vtable pointer is not in the expected section.  Use the
+        slow path, which will terminate the process if necessary.  */
diff --git a/SOURCES/glibc-rh1609067.patch b/SOURCES/glibc-rh1609067.patch
new file mode 100644
index 0000000..e10b503
--- /dev/null
+++ b/SOURCES/glibc-rh1609067.patch
@@ -0,0 +1,65 @@
+commit b04acb2651e0aaf615de50e9138cddfd5c24021f
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Tue Jul 30 11:58:45 2013 +0200
+
+    Fix race conditions in pldd that may leave the process stopped after detaching
+    
+    Fixes bug 15804
+
+diff --git a/elf/pldd.c b/elf/pldd.c
+index 684aff4..75f7812 100644
+--- a/elf/pldd.c
++++ b/elf/pldd.c
+@@ -34,6 +34,7 @@
+ #include <unistd.h>
+ #include <sys/ptrace.h>
+ #include <sys/stat.h>
++#include <sys/wait.h>
+ 
+ #include <ldsodefs.h>
+ #include <version.h>
+@@ -82,6 +83,7 @@ static char *exe;
+ 
+ /* Local functions.  */
+ static int get_process_info (int dfd, long int pid);
++static void wait_for_ptrace_stop (long int pid);
+ 
+ 
+ int
+@@ -170,6 +172,8 @@ main (int argc, char *argv[])
+ 		 tid);
+ 	}
+ 
++      wait_for_ptrace_stop (tid);
++
+       struct thread_list *newp = alloca (sizeof (*newp));
+       newp->tid = tid;
+       newp->next = thread_list;
+@@ -194,6 +198,27 @@ main (int argc, char *argv[])
+ }
+ 
+ 
++/* Wait for PID to enter ptrace-stop state after being attached.  */
++static void
++wait_for_ptrace_stop (long int pid)
++{
++  int status;
++
++  /* While waiting for SIGSTOP being delivered to the tracee we have to
++     reinject any other pending signal.  Ignore all other errors.  */
++  while (waitpid (pid, &status, __WALL) == pid && WIFSTOPPED (status))
++    {
++      /* The STOP signal should not be delivered to the tracee.  */
++      if (WSTOPSIG (status) == SIGSTOP)
++	return;
++      if (ptrace (PTRACE_CONT, pid, NULL,
++		  (void *) (uintptr_t) WSTOPSIG (status)))
++	/* The only possible error is that the process died.  */
++	return;
++    }
++}
++
++
+ /* Handle program arguments.  */
+ static error_t
+ parse_opt (int key, char *arg, struct argp_state *state)
diff --git a/SOURCES/glibc-rh1630440-1.patch b/SOURCES/glibc-rh1630440-1.patch
new file mode 100644
index 0000000..971c251
--- /dev/null
+++ b/SOURCES/glibc-rh1630440-1.patch
@@ -0,0 +1,486 @@
+commit e5d262effe3a87164308a3f37e61b32d0348692a
+Author: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+Date:   Fri Nov 30 18:05:32 2018 -0200
+
+    Fix _dl_profile_fixup data-dependency issue (Bug 23690)
+    
+    There is a data-dependency between the fields of struct l_reloc_result
+    and the field used as the initialization guard. Users of the guard
+    expect writes to the structure to be observable when they also observe
+    the guard initialized. The solution for this problem is to use an acquire
+    and release load and store to ensure previous writes to the structure are
+    observable if the guard is initialized.
+    
+    The previous implementation used DL_FIXUP_VALUE_ADDR (l_reloc_result->addr)
+    as the initialization guard, making it impossible for some architectures
+    to load and store it atomically, i.e. hppa and ia64, due to its larger size.
+    
+    This commit adds an unsigned int to l_reloc_result to be used as the new
+    initialization guard of the struct, making it possible to load and store
+    it atomically in all architectures. The fix ensures that the values
+    observed in l_reloc_result are consistent and do not lead to crashes.
+    The algorithm is documented in the code in elf/dl-runtime.c
+    (_dl_profile_fixup). Not all data races have been eliminated.
+    
+    Tested with build-many-glibcs and on powerpc, powerpc64, and powerpc64le.
+    
+            [BZ #23690]
+            * elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
+            modification order when accessing reloc_result->addr.
+            * include/link.h (reloc_result): Add field init.
+            * nptl/Makefile (tests): Add tst-audit-threads.
+            (modules-names): Add tst-audit-threads-mod1 and
+            tst-audit-threads-mod2.
+            Add rules to build tst-audit-threads.
+            * nptl/tst-audit-threads-mod1.c: New file.
+            * nptl/tst-audit-threads-mod2.c: Likewise.
+            * nptl/tst-audit-threads.c: Likewise.
+            * nptl/tst-audit-threads.h: Likewise.
+    
+    Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+(elf/dl-runtime.c adjusted here for lack of __builtin_expect cleanup,
+nptl/Makefile for the usual test-related conflicts.)
+
+diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
+index a42e3c4924e067ba..3678a98c98d726f3 100644
+--- a/elf/dl-runtime.c
++++ b/elf/dl-runtime.c
+@@ -183,10 +183,36 @@ _dl_profile_fixup (
+   /* This is the address in the array where we store the result of previous
+      relocations.  */
+   struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
+-  DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
+ 
+-  DL_FIXUP_VALUE_TYPE value = *resultp;
+-  if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
++ /* CONCURRENCY NOTES:
++
++  Multiple threads may be calling the same PLT sequence and with
++  LD_AUDIT enabled they will be calling into _dl_profile_fixup to
++  update the reloc_result with the result of the lazy resolution.
++  The reloc_result guard variable is reloc_init, and we use
++  acquire/release loads and store to it to ensure that the results of
++  the structure are consistent with the loaded value of the guard.
++  This does not fix all of the data races that occur when two or more
++  threads read reloc_result->reloc_init with a value of zero and read
++  and write to that reloc_result concurrently.  The expectation is
++  generally that while this is a data race it works because the
++  threads write the same values.  Until the data races are fixed
++  there is a potential for problems to arise from these data races.
++  The reloc result updates should happen in parallel but there should
++  be an atomic RMW which does the final update to the real result
++  entry (see bug 23790).
++
++  The following code uses reloc_result->init set to 0 to indicate if it is
++  the first time this object is being relocated, otherwise 1 which
++  indicates the object has already been relocated.
++
++  Reading/Writing from/to reloc_result->reloc_init must not happen
++  before previous writes to reloc_result complete as they could
++  end-up with an incomplete struct.  */
++  DL_FIXUP_VALUE_TYPE value;
++  unsigned int init = atomic_load_acquire (&reloc_result->init);
++
++  if (init == 0)
+     {
+       /* This is the first time we have to relocate this object.  */
+       const ElfW(Sym) *const symtab
+@@ -347,20 +373,32 @@ _dl_profile_fixup (
+ #endif
+ 
+       /* Store the result for later runs.  */
+-      if (__builtin_expect (! GLRO(dl_bind_not), 1))
+-	*resultp = value;
++      if (__glibc_likely (! GLRO(dl_bind_not)))
++	{
++	  reloc_result->addr = value;
++	  /* Guarantee all previous writes complete before
++	     init is updated.  See CONCURRENCY NOTES earlier  */
++	  atomic_store_release (&reloc_result->init, 1);
++	}
++      init = 1;
+     }
++  else
++    value = reloc_result->addr;
+ 
+   /* By default we do not call the pltexit function.  */
+   long int framesize = -1;
+ 
++
+ #ifdef SHARED
+   /* Auditing checkpoint: report the PLT entering and allow the
+      auditors to change the value.  */
+-  if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
++  if (GLRO(dl_naudit) > 0
+       /* Don't do anything if no auditor wants to intercept this call.  */
+       && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
+     {
++      /* Sanity check:  DL_FIXUP_VALUE_CODE_ADDR (value) should have been
++	 initialized earlier in this function or in another thread.  */
++      assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
+       ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
+ 						l_info[DT_SYMTAB])
+ 			   + reloc_result->boundndx);
+diff --git a/include/link.h b/include/link.h
+index d7590640aa9285e5..22d020d833ae3a7c 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -206,6 +206,10 @@ struct link_map
+       unsigned int boundndx;
+       uint32_t enterexit;
+       unsigned int flags;
++      /* CONCURRENCY NOTE: This is used to guard the concurrent initialization
++	 of the relocation result across multiple threads.  See the more
++	 detailed notes in elf/dl-runtime.c.  */
++      unsigned int init;
+     } *l_reloc_result;
+ 
+     /* Pointer to the version information if available.  */
+diff --git a/nptl/Makefile b/nptl/Makefile
+index cf47a6f097916766..1b9639f3566a63fd 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -298,7 +298,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
+ endif
+ ifeq ($(build-shared),yes)
+ tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1 tst-fini1 \
+-	 tst-stackguard1
++	 tst-stackguard1 tst-audit-threads
+ tests-nolibpthread += tst-fini1
+ ifeq ($(have-z-execstack),yes)
+ tests += tst-execstack
+@@ -309,7 +309,7 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
+ 		tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
+ 		tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
+ 		tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
+-		tst-join7mod
++		tst-join7mod tst-audit-threads-mod1 tst-audit-threads-mod2
+ extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
+ test-extras += $(modules-names) tst-cleanup4aux
+ test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
+@@ -627,6 +627,14 @@ $(objpfx)tst-oddstacklimit.out: $(objpfx)tst-oddstacklimit $(objpfx)tst-basic1
+ 	$(run-program-prefix) $< --command '$(host-built-program-cmd)' > $@
+ endif
+ 
++# Protect against a build using -Wl,-z,now.
++LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy
++LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy
++LDFLAGS-tst-audit-threads = -Wl,-z,lazy
++$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so
++$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so
++tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so
++
+ # The tests here better do not run in parallel
+ ifneq ($(filter %tests,$(MAKECMDGOALS)),)
+ .NOTPARALLEL:
+diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c
+new file mode 100644
+index 0000000000000000..615d5ee5121962df
+--- /dev/null
++++ b/nptl/tst-audit-threads-mod1.c
+@@ -0,0 +1,74 @@
++/* Dummy audit library for test-audit-threads.
++
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <elf.h>
++#include <link.h>
++#include <stdio.h>
++#include <assert.h>
++#include <string.h>
++
++/* We must use a dummy LD_AUDIT module to force the dynamic loader to
++   *not* update the real PLT, and instead use a cached value for the
++   lazy resolution result.  It is the update of that cached value that
++   we are testing for correctness by doing this.  */
++
++/* Library to be audited.  */
++#define LIB "tst-audit-threads-mod2.so"
++/* CALLNUM is the number of retNum functions.  */
++#define CALLNUM 7999
++
++#define CONCATX(a, b) __CONCAT (a, b)
++
++static int previous = 0;
++
++unsigned int
++la_version (unsigned int ver)
++{
++  return 1;
++}
++
++unsigned int
++la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
++{
++  return LA_FLG_BINDTO | LA_FLG_BINDFROM;
++}
++
++uintptr_t
++CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym,
++					unsigned int ndx,
++					uintptr_t *refcook,
++					uintptr_t *defcook,
++					unsigned int *flags,
++					const char *symname)
++{
++  const char * retnum = "retNum";
++  char * num = strstr (symname, retnum);
++  int n;
++  /* Validate if the symbols are getting called in the correct order.
++     This code is here to verify binutils does not optimize out the PLT
++     entries that require the symbol binding.  */
++  if (num != NULL)
++    {
++      n = atoi (num);
++      assert (n >= previous);
++      assert (n <= CALLNUM);
++      previous = n;
++    }
++  return sym->st_value;
++}
+diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c
+new file mode 100644
+index 0000000000000000..f9817dd3dc7f4910
+--- /dev/null
++++ b/nptl/tst-audit-threads-mod2.c
+@@ -0,0 +1,22 @@
++/* Shared object with a huge number of functions for test-audit-threads.
++
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* Define all the retNumN functions in a library.  */
++#define definenum
++#include "tst-audit-threads.h"
+diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
+new file mode 100644
+index 0000000000000000..e4bf433bd85f3715
+--- /dev/null
++++ b/nptl/tst-audit-threads.c
+@@ -0,0 +1,97 @@
++/* Test multi-threading using LD_AUDIT.
++
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a
++   library with a huge number of functions in order to validate lazy symbol
++   binding with an audit library.  We use one thread per CPU to test that
++   concurrent lazy resolution does not have any defects which would cause
++   the process to fail.  We use an LD_AUDIT library to force the testing of
++   the relocation resolution caching code in the dynamic loader i.e.
++   _dl_runtime_profile and _dl_profile_fixup.  */
++
++#include <support/xthread.h>
++#include <strings.h>
++#include <stdlib.h>
++#include <sys/sysinfo.h>
++
++static int do_test (void);
++
++/* This test usually takes less than 3s to run.  However, there are cases that
++   take up to 30s.  */
++#define TIMEOUT 60
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
++
++/* Declare the functions we are going to call.  */
++#define externnum
++#include "tst-audit-threads.h"
++#undef externnum
++
++int num_threads;
++pthread_barrier_t barrier;
++
++void
++sync_all (int num)
++{
++  pthread_barrier_wait (&barrier);
++}
++
++void
++call_all_ret_nums (void)
++{
++  /* Call each function one at a time from all threads.  */
++#define callnum
++#include "tst-audit-threads.h"
++#undef callnum
++}
++
++void *
++thread_main (void *unused)
++{
++  call_all_ret_nums ();
++  return NULL;
++}
++
++#define STR2(X) #X
++#define STR(X) STR2(X)
++
++static int
++do_test (void)
++{
++  int i;
++  pthread_t *threads;
++
++  num_threads = get_nprocs ();
++  if (num_threads <= 1)
++    num_threads = 2;
++
++  /* Used to synchronize all the threads after calling each retNumN.  */
++  xpthread_barrier_init (&barrier, NULL, num_threads);
++
++  threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
++  for (i = 0; i < num_threads; i++)
++    threads[i] = xpthread_create(NULL, thread_main, NULL);
++
++  for (i = 0; i < num_threads; i++)
++    xpthread_join(threads[i]);
++
++  free (threads);
++
++  return 0;
++}
+diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h
+new file mode 100644
+index 0000000000000000..1c9ecc08dfcd3e65
+--- /dev/null
++++ b/nptl/tst-audit-threads.h
+@@ -0,0 +1,92 @@
++/* Helper header for test-audit-threads.
++
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* We use this helper to create a large number of functions, all of
++   which will be resolved lazily and thus have their PLT updated.
++   This is done to provide enough functions that we can statistically
++   observe a thread vs. PLT resolution failure if one exists.  */
++
++#define CONCAT(a, b) a ## b
++#define NUM(x, y) CONCAT (x, y)
++
++#define FUNC10(x)	\
++  FUNC (NUM (x, 0));	\
++  FUNC (NUM (x, 1));	\
++  FUNC (NUM (x, 2));	\
++  FUNC (NUM (x, 3));	\
++  FUNC (NUM (x, 4));	\
++  FUNC (NUM (x, 5));	\
++  FUNC (NUM (x, 6));	\
++  FUNC (NUM (x, 7));	\
++  FUNC (NUM (x, 8));	\
++  FUNC (NUM (x, 9))
++
++#define FUNC100(x)	\
++  FUNC10 (NUM (x, 0));	\
++  FUNC10 (NUM (x, 1));	\
++  FUNC10 (NUM (x, 2));	\
++  FUNC10 (NUM (x, 3));	\
++  FUNC10 (NUM (x, 4));	\
++  FUNC10 (NUM (x, 5));	\
++  FUNC10 (NUM (x, 6));	\
++  FUNC10 (NUM (x, 7));	\
++  FUNC10 (NUM (x, 8));	\
++  FUNC10 (NUM (x, 9))
++
++#define FUNC1000(x)		\
++  FUNC100 (NUM (x, 0));		\
++  FUNC100 (NUM (x, 1));		\
++  FUNC100 (NUM (x, 2));		\
++  FUNC100 (NUM (x, 3));		\
++  FUNC100 (NUM (x, 4));		\
++  FUNC100 (NUM (x, 5));		\
++  FUNC100 (NUM (x, 6));		\
++  FUNC100 (NUM (x, 7));		\
++  FUNC100 (NUM (x, 8));		\
++  FUNC100 (NUM (x, 9))
++
++#define FUNC7000()	\
++  FUNC1000 (1);		\
++  FUNC1000 (2);		\
++  FUNC1000 (3);		\
++  FUNC1000 (4);		\
++  FUNC1000 (5);		\
++  FUNC1000 (6);		\
++  FUNC1000 (7);
++
++#ifdef FUNC
++# undef FUNC
++#endif
++
++#ifdef externnum
++# define FUNC(x) extern int CONCAT (retNum, x) (void)
++#endif
++
++#ifdef definenum
++# define FUNC(x) int CONCAT (retNum, x) (void) { return x; }
++#endif
++
++#ifdef callnum
++# define FUNC(x) CONCAT (retNum, x) (); sync_all (x)
++#endif
++
++/* A value of 7000 functions is chosen as an arbitrarily large
++   number of functions that will allow us enough attempts to
++   verify lazy resolution operation.  */
++FUNC7000 ();
diff --git a/SOURCES/glibc-rh1630440-2.patch b/SOURCES/glibc-rh1630440-2.patch
new file mode 100644
index 0000000..e2bf37b
--- /dev/null
+++ b/SOURCES/glibc-rh1630440-2.patch
@@ -0,0 +1,48 @@
+nptl/tst-audit-threads: Switch to <support/test-driver.c>
+
+The downstream version of test-skeleton.c does not include
+<support/support.h> for backwards compatibility reasons, leading to a
+compilation failure:
+
+tst-audit-threads.c: In function 'do_test':
+tst-audit-threads.c:87:3: error: implicit declaration of function 'xcalloc' [-Werror=implicit-function-declaration]
+   threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
+   ^
+tst-audit-threads.c:87:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
+   threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
+             ^
+
+diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
+index e4bf433bd85f3715..42742d51e4bc06a3 100644
+--- a/nptl/tst-audit-threads.c
++++ b/nptl/tst-audit-threads.c
+@@ -25,19 +25,12 @@
+    the relocation resolution caching code in the dynamic loader i.e.
+    _dl_runtime_profile and _dl_profile_fixup.  */
+ 
++#include <support/support.h>
+ #include <support/xthread.h>
+ #include <strings.h>
+ #include <stdlib.h>
+ #include <sys/sysinfo.h>
+ 
+-static int do_test (void);
+-
+-/* This test usually takes less than 3s to run.  However, there are cases that
+-   take up to 30s.  */
+-#define TIMEOUT 60
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
+-
+ /* Declare the functions we are going to call.  */
+ #define externnum
+ #include "tst-audit-threads.h"
+@@ -95,3 +88,8 @@ do_test (void)
+ 
+   return 0;
+ }
++
++/* This test usually takes less than 3s to run.  However, there are cases that
++   take up to 30s.  */
++#define TIMEOUT 60
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1639524.patch b/SOURCES/glibc-rh1639524.patch
new file mode 100644
index 0000000..9302219
--- /dev/null
+++ b/SOURCES/glibc-rh1639524.patch
@@ -0,0 +1,74 @@
+Note: the context of this patch differs from upstream slightly,
+to accomodate the lack of ILP32 in RHEL.
+
+commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date:   Wed Sep 27 16:55:14 2017 +0100
+
+    aarch64: Disable lazy symbol binding of TLSDESC
+    
+    Always do TLS descriptor initialization at load time during relocation
+    processing to avoid barriers at every TLS access. In non-dlopened shared
+    libraries the overhead of tls access vs static global access is > 3x
+    bigger when lazy initialization is used (_dl_tlsdesc_return_lazy)
+    compared to bind-now (_dl_tlsdesc_return) so the barriers dominate tls
+    access performance.
+    
+    TLSDESC relocs are in DT_JMPREL which are processed at load time using
+    elf_machine_lazy_rel which is only supposed to do lightweight
+    initialization using the DT_TLSDESC_PLT trampoline (the trampoline code
+    jumps to the entry point in DT_TLSDESC_GOT which does the lazy tlsdesc
+    initialization at runtime).  This patch changes elf_machine_lazy_rel
+    in aarch64 to do the symbol binding and initialization as if DF_BIND_NOW
+    was set, so the non-lazy code path of elf/do-rel.h was replicated.
+    
+    The static linker could be changed to emit TLSDESC relocs in DT_REL*,
+    which are processed non-lazily, but the goal of this patch is to always
+    guarantee bind-now semantics, even if the binary was produced with an
+    old linker, so the barriers can be dropped in tls descriptor functions.
+    
+    After this change the synchronizing ldar instructions can be dropped
+    as well as the lazy initialization machinery including the DT_TLSDESC_GOT
+    setup.
+    
+    I believe this should be done on all targets, including ones where no
+    barrier is needed for lazy initialization.  There is very little gain in
+    optimizing for large number of symbolic tlsdesc relocations which is an
+    extremely uncommon case.  And currently the tlsdesc entries are only
+    readonly protected with -z now and some hardennings against writable
+    JUMPSLOT relocs don't work for TLSDESC so they are a security hazard.
+    (But to fix that the static linker has to be changed.)
+    
+    	* sysdeps/aarch64/dl-machine.h (elf_machine_lazy_rel): Do symbol
+    	binding and initialization non-lazily for R_AARCH64_TLSDESC.
+
+diff -rup a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
+--- a/sysdeps/aarch64/dl-machine.h	2018-10-16 12:07:31.588149003 -0400
++++ b/sysdeps/aarch64/dl-machine.h	2018-10-16 12:18:46.214078837 -0400
+@@ -376,12 +376,21 @@ elf_machine_lazy_rel (struct link_map *m
+     }
+   else if (__builtin_expect (r_type == R_AARCH64_TLSDESC, 1))
+     {
+-      struct tlsdesc volatile *td =
+-	(struct tlsdesc volatile *)reloc_addr;
++      const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
++      const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]);
++      const ElfW (Sym) *sym = &symtab[symndx];
++      const struct r_found_version *version = NULL;
+ 
+-      td->arg = (void*)reloc;
+-      td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
+-			  + map->l_addr);
++      if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
++	{
++	  const ElfW (Half) *vernum =
++	    (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
++	  version = &map->l_versions[vernum[symndx] & 0x7fff];
++	}
++
++      /* Always initialize TLS descriptors completely, because lazy
++	 initialization requires synchronization at every TLS access.  */
++      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
+     }
+   else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE))
+     {
diff --git a/SOURCES/glibc-rh1641981.patch b/SOURCES/glibc-rh1641981.patch
new file mode 100644
index 0000000..48cea45
--- /dev/null
+++ b/SOURCES/glibc-rh1641981.patch
@@ -0,0 +1,41 @@
+commit c3d8dc45c9df199b8334599a6cbd98c9950dba62
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Thu Oct 11 15:18:40 2018 -0300
+
+    x86: Fix Haswell strong flags (BZ#23709)
+    
+    Th commit 'Disable TSX on some Haswell processors.' (2702856bf4) changed the
+    default flags for Haswell models.  Previously, new models were handled by the
+    default switch path, which assumed a Core i3/i5/i7 if AVX is available. After
+    the patch, Haswell models (0x3f, 0x3c, 0x45, 0x46) do not set the flags
+    Fast_Rep_String, Fast_Unaligned_Load, Fast_Unaligned_Copy, and
+    Prefer_PMINUB_for_stringop (only the TSX one).
+    
+    This patch fixes it by disentangle the TSX flag handling from the memory
+    optimization ones.  The strstr case cited on patch now selects the
+    __strstr_sse2_unaligned as expected for the Haswell cpu.
+    
+    Checked on x86_64-linux-gnu.
+    
+            [BZ #23709]
+            * sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
+            independently of other flags.
+
+diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
+index 0667e486959a8a91..d134ef3a92cbc83d 100644
+--- a/sysdeps/x86/cpu-features.c
++++ b/sysdeps/x86/cpu-features.c
+@@ -133,7 +133,13 @@ init_cpu_features (struct cpu_features *cpu_features)
+ 		    | bit_Fast_Unaligned_Load
+ 		    | bit_Prefer_PMINUB_for_stringop);
+ 	      break;
++	    }
+ 
++	 /* Disable TSX on some Haswell processors to avoid TSX on kernels that
++	    weren't updated with the latest microcode package (which disables
++	    broken feature by default).  */
++	 switch (model)
++	    {
+ 	    case 0x3f:
+ 	      /* Xeon E7 v3 with stepping >= 4 has working TSX.  */
+ 	      if (stepping >= 4)
diff --git a/SOURCES/glibc-rh1646373.patch b/SOURCES/glibc-rh1646373.patch
new file mode 100644
index 0000000..a6c6c7b
--- /dev/null
+++ b/SOURCES/glibc-rh1646373.patch
@@ -0,0 +1,32 @@
+commit bd3b0fbae33a9a4cc5e2daf049443d5cf03d4251
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Mon Nov 5 12:47:30 2018 +0100
+
+    libanl: properly cleanup if first helper thread creation failed (bug 22927)
+
+2018-11-05  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #22927]
+	* resolv/gai_misc.c (__gai_enqueue_request): Don't crash if
+	creating the first helper thread failed.
+
+[Note from DJ - hard to test; must force second calloc() call in
+getaddrinfo_a() to return NULL/ENOMEM]
+
+diff -rup a/resolv/gai_misc.c b/resolv/gai_misc.c
+--- a/resolv/gai_misc.c	2012-12-24 22:02:13.000000000 -0500
++++ b/resolv/gai_misc.c	2019-01-22 16:19:30.514199534 -0500
+@@ -264,8 +264,11 @@ __gai_enqueue_request (struct gaicb *gai
+ 	      /* We cannot create a thread in the moment and there is
+ 		 also no thread running.  This is a problem.  `errno' is
+ 		 set to EAGAIN if this is only a temporary problem.  */
+-	      assert (lastp->next == newp);
+-	      lastp->next = NULL;
++	      assert (requests == newp || lastp->next == newp);
++	      if (lastp != NULL)
++		lastp->next = NULL;
++	      else
++		requests = NULL;
+ 	      requests_tail = lastp;
+ 
+ 	      newp->next = freelist;
diff --git a/SOURCES/glibc-rh1647490-1.patch b/SOURCES/glibc-rh1647490-1.patch
new file mode 100644
index 0000000..cf3ade5
--- /dev/null
+++ b/SOURCES/glibc-rh1647490-1.patch
@@ -0,0 +1,80 @@
+commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523
+Author: Paul Pluzhnikov <ppluzhnikov@kazbek.mtv.corp.google.com>
+Date:   Fri Aug 24 18:08:51 2018 -0700
+
+    Fix BZ#23400 (creating temporary files in source tree), and undefined behavior in test.
+
+diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
+index e7837f98c19fc4bf..d1aa69106ccf6ac5 100644
+--- a/stdlib/test-bz22786.c
++++ b/stdlib/test-bz22786.c
+@@ -26,28 +26,20 @@
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/temp_file.h>
+ #include <support/test-driver.h>
+ #include <libc-diag.h>
+ 
+ static int
+ do_test (void)
+ {
+-  const char dir[] = "bz22786";
+-  const char lnk[] = "bz22786/symlink";
++  const char *dir = support_create_temp_directory ("bz22786.");
++  const char *lnk = xasprintf ("%s/symlink", dir);
++  const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
+ 
+-  rmdir (dir);
+-  if (mkdir (dir, 0755) != 0 && errno != EEXIST)
+-    {
+-      printf ("mkdir %s: %m\n", dir);
+-      return EXIT_FAILURE;
+-    }
+-  if (symlink (".", lnk) != 0 && errno != EEXIST)
+-    {
+-      printf ("symlink (%s, %s): %m\n", dir, lnk);
+-      return EXIT_FAILURE;
+-    }
+-
+-  const size_t path_len = (size_t) INT_MAX + 1;
++  TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
+ 
+   DIAG_PUSH_NEEDS_COMMENT;
+ #if __GNUC_PREREQ (7, 0)
+@@ -55,20 +47,14 @@ do_test (void)
+      allocation to succeed for the test to work.  */
+   DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+ #endif
+-  char *path = malloc (path_len);
++  char *path = xmalloc (path_len);
+   DIAG_POP_NEEDS_COMMENT;
+ 
+-  if (path == NULL)
+-    {
+-      printf ("malloc (%zu): %m\n", path_len);
+-      return EXIT_UNSUPPORTED;
+-    }
+-
+-  /* Construct very long path = "bz22786/symlink/aaaa....."  */
+-  char *p = mempcpy (path, lnk, sizeof (lnk) - 1);
++  /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....."  */
++  char *p = mempcpy (path, lnk, strlen (lnk));
+   *(p++) = '/';
+-  memset (p, 'a', path_len - (path - p) - 2);
+-  p[path_len - (path - p) - 1] = '\0';
++  memset (p, 'a', path_len - (p - path) - 2);
++  p[path_len - (p - path) - 1] = '\0';
+ 
+   /* This call crashes before the fix for bz22786 on 32-bit platforms.  */
+   p = realpath (path, NULL);
+@@ -81,7 +67,6 @@ do_test (void)
+ 
+   /* Cleanup.  */
+   unlink (lnk);
+-  rmdir (dir);
+ 
+   return 0;
+ }
diff --git a/SOURCES/glibc-rh1647490-2.patch b/SOURCES/glibc-rh1647490-2.patch
new file mode 100644
index 0000000..8ad2241
--- /dev/null
+++ b/SOURCES/glibc-rh1647490-2.patch
@@ -0,0 +1,55 @@
+commit 3bad2358d67d371497079bba4f8eca9c0096f4e2
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Thu Aug 30 08:44:32 2018 +0200
+
+    Test stdlib/test-bz22786 exits now with unsupported if malloc fails.
+    
+    The test tries to allocate more than 2^31 bytes which will always fail on s390
+    as it has maximum 2^31bit of memory.
+    Before commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523, this test returned
+    unsupported if malloc fails.  This patch re enables this behaviour.
+    
+    Furthermore support_delete_temp_files() failed to remove the temp directory
+    in this case as it is not empty due to the created symlink.
+    Thus the creation of the symlink is moved behind malloc.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    
+    ChangeLog:
+    
+            * stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
+            if malloc fails.
+
+diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
+index d1aa69106ccf6ac5..777bf9180f4b5022 100644
+--- a/stdlib/test-bz22786.c
++++ b/stdlib/test-bz22786.c
+@@ -39,16 +39,25 @@ do_test (void)
+   const char *lnk = xasprintf ("%s/symlink", dir);
+   const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
+ 
+-  TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
+-
+   DIAG_PUSH_NEEDS_COMMENT;
+ #if __GNUC_PREREQ (7, 0)
+   /* GCC 7 warns about too-large allocations; here we need such
+      allocation to succeed for the test to work.  */
+   DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+ #endif
+-  char *path = xmalloc (path_len);
++  char *path = malloc (path_len);
+   DIAG_POP_NEEDS_COMMENT;
++  if (path == NULL)
++    {
++      printf ("malloc (%zu): %m\n", path_len);
++      /* On 31-bit s390 the malloc will always fail as we do not have
++	 so much memory, and we want to mark the test unsupported.
++	 Likewise on systems with little physical memory the test will
++	 fail and should be unsupported.  */
++      return EXIT_UNSUPPORTED;
++    }
++
++  TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
+ 
+   /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....."  */
+   char *p = mempcpy (path, lnk, strlen (lnk));
diff --git a/SOURCES/glibc-rh1647490-3.patch b/SOURCES/glibc-rh1647490-3.patch
new file mode 100644
index 0000000..7f68b16
--- /dev/null
+++ b/SOURCES/glibc-rh1647490-3.patch
@@ -0,0 +1,64 @@
+commit f5e7e95921847bd83186bfe621fc2b48c4de5477
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Oct 30 13:11:47 2018 +0100
+
+    stdlib/test-bz22786: Avoid spurious test failures using alias mappings
+    
+    On systems without enough random-access memory, stdlib/test-bz22786
+    will go deeply into swap and time out, even with a substantial
+    TIMEOUTFACTOR.  This commit adds a facility to construct repeating
+    strings with alias mappings, so that the requirement for physical
+    memory, and uses it in stdlib/test-bz22786.
+
+Adjusted here for the support/ backport in glibc-rh1418978-1.patch.
+
+diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
+index 777bf9180f4b5022..bb1e04f2debe9042 100644
+--- a/stdlib/test-bz22786.c
++++ b/stdlib/test-bz22786.c
+@@ -26,6 +26,7 @@
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
++#include <support/blob_repeat.h>
+ #include <support/check.h>
+ #include <support/support.h>
+ #include <support/temp_file.h>
+@@ -39,17 +40,12 @@ do_test (void)
+   const char *lnk = xasprintf ("%s/symlink", dir);
+   const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
+ 
+-  DIAG_PUSH_NEEDS_COMMENT;
+-#if __GNUC_PREREQ (7, 0)
+-  /* GCC 7 warns about too-large allocations; here we need such
+-     allocation to succeed for the test to work.  */
+-  DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+-#endif
+-  char *path = malloc (path_len);
+-  DIAG_POP_NEEDS_COMMENT;
++  struct support_blob_repeat repeat
++    = support_blob_repeat_allocate ("a", 1, path_len);
++  char *path = repeat.start;
+   if (path == NULL)
+     {
+-      printf ("malloc (%zu): %m\n", path_len);
++      printf ("Repeated allocation (%zu bytes): %m\n", path_len);
+       /* On 31-bit s390 the malloc will always fail as we do not have
+ 	 so much memory, and we want to mark the test unsupported.
+ 	 Likewise on systems with little physical memory the test will
+@@ -62,7 +58,6 @@ do_test (void)
+   /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....."  */
+   char *p = mempcpy (path, lnk, strlen (lnk));
+   *(p++) = '/';
+-  memset (p, 'a', path_len - (p - path) - 2);
+   p[path_len - (p - path) - 1] = '\0';
+ 
+   /* This call crashes before the fix for bz22786 on 32-bit platforms.  */
+@@ -76,6 +71,7 @@ do_test (void)
+ 
+   /* Cleanup.  */
+   unlink (lnk);
++  support_blob_repeat_free (&repeat);
+ 
+   return 0;
+ }
diff --git a/SOURCES/glibc-rh1647490-4.patch b/SOURCES/glibc-rh1647490-4.patch
new file mode 100644
index 0000000..77866a1
--- /dev/null
+++ b/SOURCES/glibc-rh1647490-4.patch
@@ -0,0 +1,51 @@
+commit 07da99aad93c9364acb7efdab47c27ba698f6313
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Oct 30 13:55:01 2018 +0100
+
+    stdlib/tst-strtod-overflow: Switch to support_blob_repeat
+    
+    This is another test with an avoidable large memory allocation.
+
+diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
+index 6c5b2828551dd580..fd1be79f3f58c64b 100644
+--- a/stdlib/tst-strtod-overflow.c
++++ b/stdlib/tst-strtod-overflow.c
+@@ -19,6 +19,8 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <support/blob_repeat.h>
++#include <support/test-driver.h>
+ 
+ #define EXPONENT "e-2147483649"
+ #define SIZE 214748364
+@@ -26,21 +28,23 @@
+ static int
+ do_test (void)
+ {
+-  char *p = malloc (1 + SIZE + sizeof (EXPONENT));
+-  if (p == NULL)
++  struct support_blob_repeat repeat = support_blob_repeat_allocate
++    ("0", 1, 1 + SIZE + sizeof (EXPONENT));
++  if (repeat.size == 0)
+     {
+-      puts ("malloc failed, cannot test for overflow");
+-      return 0;
++      puts ("warning: memory allocation failed, cannot test for overflow");
++      return EXIT_UNSUPPORTED;
+     }
++  char *p = repeat.start;
+   p[0] = '1';
+-  memset (p + 1, '0', SIZE);
+   memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT));
+   double d = strtod (p, NULL);
+   if (d != 0)
+     {
+-      printf ("strtod returned wrong value: %a\n", d);
++      printf ("error: strtod returned wrong value: %a\n", d);
+       return 1;
+     }
++  support_blob_repeat_free (&repeat);
+   return 0;
+ }
+ 
diff --git a/SOURCES/glibc-rh1647490-5.patch b/SOURCES/glibc-rh1647490-5.patch
new file mode 100644
index 0000000..ea8509f
--- /dev/null
+++ b/SOURCES/glibc-rh1647490-5.patch
@@ -0,0 +1,30 @@
+commit 60708030536df82616c16aa2f14f533c4362b969
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Oct 30 13:56:40 2018 +0100
+
+    stdlib/test-bz22786: Avoid memory leaks in the test itself
+
+diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
+index bb1e04f2debe9042..8035e8a394e7d034 100644
+--- a/stdlib/test-bz22786.c
++++ b/stdlib/test-bz22786.c
+@@ -36,8 +36,8 @@
+ static int
+ do_test (void)
+ {
+-  const char *dir = support_create_temp_directory ("bz22786.");
+-  const char *lnk = xasprintf ("%s/symlink", dir);
++  char *dir = support_create_temp_directory ("bz22786.");
++  char *lnk = xasprintf ("%s/symlink", dir);
+   const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
+ 
+   struct support_blob_repeat repeat
+@@ -72,6 +72,8 @@ do_test (void)
+   /* Cleanup.  */
+   unlink (lnk);
+   support_blob_repeat_free (&repeat);
++  free (lnk);
++  free (dir);
+ 
+   return 0;
+ }
diff --git a/SOURCES/glibc-rh1647490-6.patch b/SOURCES/glibc-rh1647490-6.patch
new file mode 100644
index 0000000..7ae5a66
--- /dev/null
+++ b/SOURCES/glibc-rh1647490-6.patch
@@ -0,0 +1,27 @@
+Use <support/test-driver.c> in stdlib/tst-strtod-overflow.c
+
+This downstream-only patch is needed because test-skeleton.c contains
+a copy of the old test skeleton (unlike upstream), resulting in the
+following error:
+
+In file included from tst-strtod-overflow.c:53:0:
+../test-skeleton.c:65:20: error: static declaration of 'test_dir' follows non-static declaration
+ static const char *test_dir;
+                    ^
+In file included from tst-strtod-overflow.c:23:0:
+../support/test-driver.h:65:20: note: previous declaration of 'test_dir' was here
+ extern const char *test_dir;
+                    ^
+
+diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
+index fd1be79f3f58c64b..2b30947d9a9fa03a 100644
+--- a/stdlib/tst-strtod-overflow.c
++++ b/stdlib/tst-strtod-overflow.c
+@@ -48,6 +48,4 @@ do_test (void)
+   return 0;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#define TIMEOUT 5
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1657015-1.patch b/SOURCES/glibc-rh1657015-1.patch
new file mode 100644
index 0000000..cec18d7
--- /dev/null
+++ b/SOURCES/glibc-rh1657015-1.patch
@@ -0,0 +1,41 @@
+Update kernel version in syscall-names.list to 4.17.
+
+As far as I can tell, Linux 4.17 does not add any new syscalls; this
+patch updates the version number in syscall-names.list to reflect that
+it's still current for 4.17.
+
+Tested for x86_64-linux-gnu with build-many-glibcs.py.
+
+	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+	version to 4.17.
+
+(cherry picked from commit 0e0577c93fcdd8922ca83763400f74ca10e46019)
+
+diff --git a/ChangeLog b/ChangeLog
+index 77c3dae5b015ecad..77aa2a8cf78e568f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++2018-06-05  Joseph Myers  <joseph@codesourcery.com>
++
++	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
++	version to 4.17.
++
+ 2012-12-21  David S. Miller  <davem@davemloft.net>
+ 
+ 	* po/hr.po: Update from translation team.
+diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+index fab3ff2328373a1f..5306d538e6448163 100644
+--- a/sysdeps/unix/sysv/linux/syscall-names.list
++++ b/sysdeps/unix/sysv/linux/syscall-names.list
+@@ -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 4.16.
+-kernel 4.16
++# The list of system calls is current as of Linux 4.17.
++kernel 4.17
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
diff --git a/SOURCES/glibc-rh1657015-2.patch b/SOURCES/glibc-rh1657015-2.patch
new file mode 100644
index 0000000..ced8bd8
--- /dev/null
+++ b/SOURCES/glibc-rh1657015-2.patch
@@ -0,0 +1,61 @@
+Update syscall-names.list for Linux 4.18.
+
+This patch updates sysdeps/unix/sysv/linux/syscall-names.list for
+Linux 4.18.  The io_pgetevents and rseq syscalls are added to the
+kernel on various architectures, so need to be mentioned in this file.
+
+Tested with build-many-glibcs.py.
+
+	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+	version to 4.18.
+	(io_pgetevents): New syscall.
+	(rseq): Likewise.
+
+(cherry picked from commit 17b26500f9bb926d85e86821d014f7c1bb88043c)
+
+diff --git a/ChangeLog b/ChangeLog
+index 77aa2a8cf78e568f..3ccca34563e5b71f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++2018-08-13  Joseph Myers  <joseph@codesourcery.com>
++
++	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
++	version to 4.18.
++	(io_pgetevents): New syscall.
++	(rseq): Likewise.
++
+ 2018-06-05  Joseph Myers  <joseph@codesourcery.com>
+ 
+ 	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+index 5306d538e6448163..9982a6334d46ae62 100644
+--- a/sysdeps/unix/sysv/linux/syscall-names.list
++++ b/sysdeps/unix/sysv/linux/syscall-names.list
+@@ -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 4.17.
+-kernel 4.17
++# The list of system calls is current as of Linux 4.18.
++kernel 4.18
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
+@@ -186,6 +186,7 @@ inotify_rm_watch
+ io_cancel
+ io_destroy
+ io_getevents
++io_pgetevents
+ io_setup
+ io_submit
+ ioctl
+@@ -431,6 +432,7 @@ renameat2
+ request_key
+ restart_syscall
+ rmdir
++rseq
+ rt_sigaction
+ rt_sigpending
+ rt_sigprocmask
diff --git a/SOURCES/glibc-rh1657015-3.patch b/SOURCES/glibc-rh1657015-3.patch
new file mode 100644
index 0000000..df258a9
--- /dev/null
+++ b/SOURCES/glibc-rh1657015-3.patch
@@ -0,0 +1,41 @@
+Update kernel version in syscall-names.list to 4.19.
+
+Linux 4.19 does not add any new syscalls (some existing ones are added
+to more architectures); this patch updates the version number in
+syscall-names.list to reflect that it's still current for 4.19.
+
+Tested with build-many-glibcs.py.
+
+	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+	version to 4.19.
+
+(cherry picked from commit 029ad711b8ad4cf0e5d98e0c138a35a23a376a74)
+
+diff --git a/ChangeLog b/ChangeLog
+index 3ccca34563e5b71f..30a5bed6b09efcef 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++2018-10-22  Joseph Myers  <joseph@codesourcery.com>
++
++	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
++	version to 4.19.
++
+ 2018-08-13  Joseph Myers  <joseph@codesourcery.com>
+ 
+ 	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+index 9982a6334d46ae62..f88001c9c38d5fc7 100644
+--- a/sysdeps/unix/sysv/linux/syscall-names.list
++++ b/sysdeps/unix/sysv/linux/syscall-names.list
+@@ -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 4.18.
+-kernel 4.18
++# The list of system calls is current as of Linux 4.19.
++kernel 4.19
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
diff --git a/SOURCES/glibc-rh1657015-4.patch b/SOURCES/glibc-rh1657015-4.patch
new file mode 100644
index 0000000..c4f98dc
--- /dev/null
+++ b/SOURCES/glibc-rh1657015-4.patch
@@ -0,0 +1,52 @@
+Update syscall-names.list for Linux 4.20.
+
+This patch updates sysdeps/unix/sysv/linux/syscall-names.list for
+Linux 4.20.  Although there are no new syscalls, the
+riscv_flush_icache syscall has moved to asm/unistd.h (previously in
+asm/syscalls.h) and so now needs to be added to the list.
+
+Tested with build-many-glibcs.py.
+
+	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+	version to 4.20.
+	(riscv_flush_icache): New syscall.
+
+(cherry picked from commit 47ad5e1a2a3ab8eeda491454cbef3b1c5239dc02)
+
+diff --git a/ChangeLog b/ChangeLog
+index 30a5bed6b09efcef..0f4f95193ff07d45 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++2019-01-01  Joseph Myers  <joseph@codesourcery.com>
++
++	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
++	version to 4.20.
++	(riscv_flush_icache): New syscall.
++
+ 2018-10-22  Joseph Myers  <joseph@codesourcery.com>
+ 
+ 	* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+index f88001c9c38d5fc7..d623dc1d9af027be 100644
+--- a/sysdeps/unix/sysv/linux/syscall-names.list
++++ b/sysdeps/unix/sysv/linux/syscall-names.list
+@@ -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 4.19.
+-kernel 4.19
++# The list of system calls is current as of Linux 4.20.
++kernel 4.20
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
+@@ -431,6 +431,7 @@ renameat
+ renameat2
+ request_key
+ restart_syscall
++riscv_flush_icache
+ rmdir
+ rseq
+ rt_sigaction
diff --git a/SOURCES/glibc-rh1661242-1.patch b/SOURCES/glibc-rh1661242-1.patch
deleted file mode 100644
index 971c251..0000000
--- a/SOURCES/glibc-rh1661242-1.patch
+++ /dev/null
@@ -1,486 +0,0 @@
-commit e5d262effe3a87164308a3f37e61b32d0348692a
-Author: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
-Date:   Fri Nov 30 18:05:32 2018 -0200
-
-    Fix _dl_profile_fixup data-dependency issue (Bug 23690)
-    
-    There is a data-dependency between the fields of struct l_reloc_result
-    and the field used as the initialization guard. Users of the guard
-    expect writes to the structure to be observable when they also observe
-    the guard initialized. The solution for this problem is to use an acquire
-    and release load and store to ensure previous writes to the structure are
-    observable if the guard is initialized.
-    
-    The previous implementation used DL_FIXUP_VALUE_ADDR (l_reloc_result->addr)
-    as the initialization guard, making it impossible for some architectures
-    to load and store it atomically, i.e. hppa and ia64, due to its larger size.
-    
-    This commit adds an unsigned int to l_reloc_result to be used as the new
-    initialization guard of the struct, making it possible to load and store
-    it atomically in all architectures. The fix ensures that the values
-    observed in l_reloc_result are consistent and do not lead to crashes.
-    The algorithm is documented in the code in elf/dl-runtime.c
-    (_dl_profile_fixup). Not all data races have been eliminated.
-    
-    Tested with build-many-glibcs and on powerpc, powerpc64, and powerpc64le.
-    
-            [BZ #23690]
-            * elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
-            modification order when accessing reloc_result->addr.
-            * include/link.h (reloc_result): Add field init.
-            * nptl/Makefile (tests): Add tst-audit-threads.
-            (modules-names): Add tst-audit-threads-mod1 and
-            tst-audit-threads-mod2.
-            Add rules to build tst-audit-threads.
-            * nptl/tst-audit-threads-mod1.c: New file.
-            * nptl/tst-audit-threads-mod2.c: Likewise.
-            * nptl/tst-audit-threads.c: Likewise.
-            * nptl/tst-audit-threads.h: Likewise.
-    
-    Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
-    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
-
-(elf/dl-runtime.c adjusted here for lack of __builtin_expect cleanup,
-nptl/Makefile for the usual test-related conflicts.)
-
-diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
-index a42e3c4924e067ba..3678a98c98d726f3 100644
---- a/elf/dl-runtime.c
-+++ b/elf/dl-runtime.c
-@@ -183,10 +183,36 @@ _dl_profile_fixup (
-   /* This is the address in the array where we store the result of previous
-      relocations.  */
-   struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
--  DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
- 
--  DL_FIXUP_VALUE_TYPE value = *resultp;
--  if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
-+ /* CONCURRENCY NOTES:
-+
-+  Multiple threads may be calling the same PLT sequence and with
-+  LD_AUDIT enabled they will be calling into _dl_profile_fixup to
-+  update the reloc_result with the result of the lazy resolution.
-+  The reloc_result guard variable is reloc_init, and we use
-+  acquire/release loads and store to it to ensure that the results of
-+  the structure are consistent with the loaded value of the guard.
-+  This does not fix all of the data races that occur when two or more
-+  threads read reloc_result->reloc_init with a value of zero and read
-+  and write to that reloc_result concurrently.  The expectation is
-+  generally that while this is a data race it works because the
-+  threads write the same values.  Until the data races are fixed
-+  there is a potential for problems to arise from these data races.
-+  The reloc result updates should happen in parallel but there should
-+  be an atomic RMW which does the final update to the real result
-+  entry (see bug 23790).
-+
-+  The following code uses reloc_result->init set to 0 to indicate if it is
-+  the first time this object is being relocated, otherwise 1 which
-+  indicates the object has already been relocated.
-+
-+  Reading/Writing from/to reloc_result->reloc_init must not happen
-+  before previous writes to reloc_result complete as they could
-+  end-up with an incomplete struct.  */
-+  DL_FIXUP_VALUE_TYPE value;
-+  unsigned int init = atomic_load_acquire (&reloc_result->init);
-+
-+  if (init == 0)
-     {
-       /* This is the first time we have to relocate this object.  */
-       const ElfW(Sym) *const symtab
-@@ -347,20 +373,32 @@ _dl_profile_fixup (
- #endif
- 
-       /* Store the result for later runs.  */
--      if (__builtin_expect (! GLRO(dl_bind_not), 1))
--	*resultp = value;
-+      if (__glibc_likely (! GLRO(dl_bind_not)))
-+	{
-+	  reloc_result->addr = value;
-+	  /* Guarantee all previous writes complete before
-+	     init is updated.  See CONCURRENCY NOTES earlier  */
-+	  atomic_store_release (&reloc_result->init, 1);
-+	}
-+      init = 1;
-     }
-+  else
-+    value = reloc_result->addr;
- 
-   /* By default we do not call the pltexit function.  */
-   long int framesize = -1;
- 
-+
- #ifdef SHARED
-   /* Auditing checkpoint: report the PLT entering and allow the
-      auditors to change the value.  */
--  if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
-+  if (GLRO(dl_naudit) > 0
-       /* Don't do anything if no auditor wants to intercept this call.  */
-       && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
-     {
-+      /* Sanity check:  DL_FIXUP_VALUE_CODE_ADDR (value) should have been
-+	 initialized earlier in this function or in another thread.  */
-+      assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
-       ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
- 						l_info[DT_SYMTAB])
- 			   + reloc_result->boundndx);
-diff --git a/include/link.h b/include/link.h
-index d7590640aa9285e5..22d020d833ae3a7c 100644
---- a/include/link.h
-+++ b/include/link.h
-@@ -206,6 +206,10 @@ struct link_map
-       unsigned int boundndx;
-       uint32_t enterexit;
-       unsigned int flags;
-+      /* CONCURRENCY NOTE: This is used to guard the concurrent initialization
-+	 of the relocation result across multiple threads.  See the more
-+	 detailed notes in elf/dl-runtime.c.  */
-+      unsigned int init;
-     } *l_reloc_result;
- 
-     /* Pointer to the version information if available.  */
-diff --git a/nptl/Makefile b/nptl/Makefile
-index cf47a6f097916766..1b9639f3566a63fd 100644
---- a/nptl/Makefile
-+++ b/nptl/Makefile
-@@ -298,7 +298,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
- endif
- ifeq ($(build-shared),yes)
- tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1 tst-fini1 \
--	 tst-stackguard1
-+	 tst-stackguard1 tst-audit-threads
- tests-nolibpthread += tst-fini1
- ifeq ($(have-z-execstack),yes)
- tests += tst-execstack
-@@ -309,7 +309,7 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
- 		tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
- 		tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
- 		tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
--		tst-join7mod
-+		tst-join7mod tst-audit-threads-mod1 tst-audit-threads-mod2
- extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
- test-extras += $(modules-names) tst-cleanup4aux
- test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
-@@ -627,6 +627,14 @@ $(objpfx)tst-oddstacklimit.out: $(objpfx)tst-oddstacklimit $(objpfx)tst-basic1
- 	$(run-program-prefix) $< --command '$(host-built-program-cmd)' > $@
- endif
- 
-+# Protect against a build using -Wl,-z,now.
-+LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy
-+LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy
-+LDFLAGS-tst-audit-threads = -Wl,-z,lazy
-+$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so
-+$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so
-+tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so
-+
- # The tests here better do not run in parallel
- ifneq ($(filter %tests,$(MAKECMDGOALS)),)
- .NOTPARALLEL:
-diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c
-new file mode 100644
-index 0000000000000000..615d5ee5121962df
---- /dev/null
-+++ b/nptl/tst-audit-threads-mod1.c
-@@ -0,0 +1,74 @@
-+/* Dummy audit library for test-audit-threads.
-+
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include <elf.h>
-+#include <link.h>
-+#include <stdio.h>
-+#include <assert.h>
-+#include <string.h>
-+
-+/* We must use a dummy LD_AUDIT module to force the dynamic loader to
-+   *not* update the real PLT, and instead use a cached value for the
-+   lazy resolution result.  It is the update of that cached value that
-+   we are testing for correctness by doing this.  */
-+
-+/* Library to be audited.  */
-+#define LIB "tst-audit-threads-mod2.so"
-+/* CALLNUM is the number of retNum functions.  */
-+#define CALLNUM 7999
-+
-+#define CONCATX(a, b) __CONCAT (a, b)
-+
-+static int previous = 0;
-+
-+unsigned int
-+la_version (unsigned int ver)
-+{
-+  return 1;
-+}
-+
-+unsigned int
-+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
-+{
-+  return LA_FLG_BINDTO | LA_FLG_BINDFROM;
-+}
-+
-+uintptr_t
-+CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym,
-+					unsigned int ndx,
-+					uintptr_t *refcook,
-+					uintptr_t *defcook,
-+					unsigned int *flags,
-+					const char *symname)
-+{
-+  const char * retnum = "retNum";
-+  char * num = strstr (symname, retnum);
-+  int n;
-+  /* Validate if the symbols are getting called in the correct order.
-+     This code is here to verify binutils does not optimize out the PLT
-+     entries that require the symbol binding.  */
-+  if (num != NULL)
-+    {
-+      n = atoi (num);
-+      assert (n >= previous);
-+      assert (n <= CALLNUM);
-+      previous = n;
-+    }
-+  return sym->st_value;
-+}
-diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c
-new file mode 100644
-index 0000000000000000..f9817dd3dc7f4910
---- /dev/null
-+++ b/nptl/tst-audit-threads-mod2.c
-@@ -0,0 +1,22 @@
-+/* Shared object with a huge number of functions for test-audit-threads.
-+
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+/* Define all the retNumN functions in a library.  */
-+#define definenum
-+#include "tst-audit-threads.h"
-diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
-new file mode 100644
-index 0000000000000000..e4bf433bd85f3715
---- /dev/null
-+++ b/nptl/tst-audit-threads.c
-@@ -0,0 +1,97 @@
-+/* Test multi-threading using LD_AUDIT.
-+
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a
-+   library with a huge number of functions in order to validate lazy symbol
-+   binding with an audit library.  We use one thread per CPU to test that
-+   concurrent lazy resolution does not have any defects which would cause
-+   the process to fail.  We use an LD_AUDIT library to force the testing of
-+   the relocation resolution caching code in the dynamic loader i.e.
-+   _dl_runtime_profile and _dl_profile_fixup.  */
-+
-+#include <support/xthread.h>
-+#include <strings.h>
-+#include <stdlib.h>
-+#include <sys/sysinfo.h>
-+
-+static int do_test (void);
-+
-+/* This test usually takes less than 3s to run.  However, there are cases that
-+   take up to 30s.  */
-+#define TIMEOUT 60
-+#define TEST_FUNCTION do_test ()
-+#include "../test-skeleton.c"
-+
-+/* Declare the functions we are going to call.  */
-+#define externnum
-+#include "tst-audit-threads.h"
-+#undef externnum
-+
-+int num_threads;
-+pthread_barrier_t barrier;
-+
-+void
-+sync_all (int num)
-+{
-+  pthread_barrier_wait (&barrier);
-+}
-+
-+void
-+call_all_ret_nums (void)
-+{
-+  /* Call each function one at a time from all threads.  */
-+#define callnum
-+#include "tst-audit-threads.h"
-+#undef callnum
-+}
-+
-+void *
-+thread_main (void *unused)
-+{
-+  call_all_ret_nums ();
-+  return NULL;
-+}
-+
-+#define STR2(X) #X
-+#define STR(X) STR2(X)
-+
-+static int
-+do_test (void)
-+{
-+  int i;
-+  pthread_t *threads;
-+
-+  num_threads = get_nprocs ();
-+  if (num_threads <= 1)
-+    num_threads = 2;
-+
-+  /* Used to synchronize all the threads after calling each retNumN.  */
-+  xpthread_barrier_init (&barrier, NULL, num_threads);
-+
-+  threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
-+  for (i = 0; i < num_threads; i++)
-+    threads[i] = xpthread_create(NULL, thread_main, NULL);
-+
-+  for (i = 0; i < num_threads; i++)
-+    xpthread_join(threads[i]);
-+
-+  free (threads);
-+
-+  return 0;
-+}
-diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h
-new file mode 100644
-index 0000000000000000..1c9ecc08dfcd3e65
---- /dev/null
-+++ b/nptl/tst-audit-threads.h
-@@ -0,0 +1,92 @@
-+/* Helper header for test-audit-threads.
-+
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+/* We use this helper to create a large number of functions, all of
-+   which will be resolved lazily and thus have their PLT updated.
-+   This is done to provide enough functions that we can statistically
-+   observe a thread vs. PLT resolution failure if one exists.  */
-+
-+#define CONCAT(a, b) a ## b
-+#define NUM(x, y) CONCAT (x, y)
-+
-+#define FUNC10(x)	\
-+  FUNC (NUM (x, 0));	\
-+  FUNC (NUM (x, 1));	\
-+  FUNC (NUM (x, 2));	\
-+  FUNC (NUM (x, 3));	\
-+  FUNC (NUM (x, 4));	\
-+  FUNC (NUM (x, 5));	\
-+  FUNC (NUM (x, 6));	\
-+  FUNC (NUM (x, 7));	\
-+  FUNC (NUM (x, 8));	\
-+  FUNC (NUM (x, 9))
-+
-+#define FUNC100(x)	\
-+  FUNC10 (NUM (x, 0));	\
-+  FUNC10 (NUM (x, 1));	\
-+  FUNC10 (NUM (x, 2));	\
-+  FUNC10 (NUM (x, 3));	\
-+  FUNC10 (NUM (x, 4));	\
-+  FUNC10 (NUM (x, 5));	\
-+  FUNC10 (NUM (x, 6));	\
-+  FUNC10 (NUM (x, 7));	\
-+  FUNC10 (NUM (x, 8));	\
-+  FUNC10 (NUM (x, 9))
-+
-+#define FUNC1000(x)		\
-+  FUNC100 (NUM (x, 0));		\
-+  FUNC100 (NUM (x, 1));		\
-+  FUNC100 (NUM (x, 2));		\
-+  FUNC100 (NUM (x, 3));		\
-+  FUNC100 (NUM (x, 4));		\
-+  FUNC100 (NUM (x, 5));		\
-+  FUNC100 (NUM (x, 6));		\
-+  FUNC100 (NUM (x, 7));		\
-+  FUNC100 (NUM (x, 8));		\
-+  FUNC100 (NUM (x, 9))
-+
-+#define FUNC7000()	\
-+  FUNC1000 (1);		\
-+  FUNC1000 (2);		\
-+  FUNC1000 (3);		\
-+  FUNC1000 (4);		\
-+  FUNC1000 (5);		\
-+  FUNC1000 (6);		\
-+  FUNC1000 (7);
-+
-+#ifdef FUNC
-+# undef FUNC
-+#endif
-+
-+#ifdef externnum
-+# define FUNC(x) extern int CONCAT (retNum, x) (void)
-+#endif
-+
-+#ifdef definenum
-+# define FUNC(x) int CONCAT (retNum, x) (void) { return x; }
-+#endif
-+
-+#ifdef callnum
-+# define FUNC(x) CONCAT (retNum, x) (); sync_all (x)
-+#endif
-+
-+/* A value of 7000 functions is chosen as an arbitrarily large
-+   number of functions that will allow us enough attempts to
-+   verify lazy resolution operation.  */
-+FUNC7000 ();
diff --git a/SOURCES/glibc-rh1661242-2.patch b/SOURCES/glibc-rh1661242-2.patch
deleted file mode 100644
index e2bf37b..0000000
--- a/SOURCES/glibc-rh1661242-2.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-nptl/tst-audit-threads: Switch to <support/test-driver.c>
-
-The downstream version of test-skeleton.c does not include
-<support/support.h> for backwards compatibility reasons, leading to a
-compilation failure:
-
-tst-audit-threads.c: In function 'do_test':
-tst-audit-threads.c:87:3: error: implicit declaration of function 'xcalloc' [-Werror=implicit-function-declaration]
-   threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
-   ^
-tst-audit-threads.c:87:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
-   threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
-             ^
-
-diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
-index e4bf433bd85f3715..42742d51e4bc06a3 100644
---- a/nptl/tst-audit-threads.c
-+++ b/nptl/tst-audit-threads.c
-@@ -25,19 +25,12 @@
-    the relocation resolution caching code in the dynamic loader i.e.
-    _dl_runtime_profile and _dl_profile_fixup.  */
- 
-+#include <support/support.h>
- #include <support/xthread.h>
- #include <strings.h>
- #include <stdlib.h>
- #include <sys/sysinfo.h>
- 
--static int do_test (void);
--
--/* This test usually takes less than 3s to run.  However, there are cases that
--   take up to 30s.  */
--#define TIMEOUT 60
--#define TEST_FUNCTION do_test ()
--#include "../test-skeleton.c"
--
- /* Declare the functions we are going to call.  */
- #define externnum
- #include "tst-audit-threads.h"
-@@ -95,3 +88,8 @@ do_test (void)
- 
-   return 0;
- }
-+
-+/* This test usually takes less than 3s to run.  However, there are cases that
-+   take up to 30s.  */
-+#define TIMEOUT 60
-+#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1661244.patch b/SOURCES/glibc-rh1661244.patch
deleted file mode 100644
index 05ae724..0000000
--- a/SOURCES/glibc-rh1661244.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-Note: the context of this patch differs from upstream slightly,
-to accomodate the lack of ILP32 in RHEL.
-
-commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67
-Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
-Date:   Wed Sep 27 16:55:14 2017 +0100
-
-    aarch64: Disable lazy symbol binding of TLSDESC
-    
-    Always do TLS descriptor initialization at load time during relocation
-    processing to avoid barriers at every TLS access. In non-dlopened shared
-    libraries the overhead of tls access vs static global access is > 3x
-    bigger when lazy initialization is used (_dl_tlsdesc_return_lazy)
-    compared to bind-now (_dl_tlsdesc_return) so the barriers dominate tls
-    access performance.
-    
-    TLSDESC relocs are in DT_JMPREL which are processed at load time using
-    elf_machine_lazy_rel which is only supposed to do lightweight
-    initialization using the DT_TLSDESC_PLT trampoline (the trampoline code
-    jumps to the entry point in DT_TLSDESC_GOT which does the lazy tlsdesc
-    initialization at runtime).  This patch changes elf_machine_lazy_rel
-    in aarch64 to do the symbol binding and initialization as if DF_BIND_NOW
-    was set, so the non-lazy code path of elf/do-rel.h was replicated.
-    
-    The static linker could be changed to emit TLSDESC relocs in DT_REL*,
-    which are processed non-lazily, but the goal of this patch is to always
-    guarantee bind-now semantics, even if the binary was produced with an
-    old linker, so the barriers can be dropped in tls descriptor functions.
-    
-    After this change the synchronizing ldar instructions can be dropped
-    as well as the lazy initialization machinery including the DT_TLSDESC_GOT
-    setup.
-    
-    I believe this should be done on all targets, including ones where no
-    barrier is needed for lazy initialization.  There is very little gain in
-    optimizing for large number of symbolic tlsdesc relocations which is an
-    extremely uncommon case.  And currently the tlsdesc entries are only
-    readonly protected with -z now and some hardennings against writable
-    JUMPSLOT relocs don't work for TLSDESC so they are a security hazard.
-    (But to fix that the static linker has to be changed.)
-    
-    	* sysdeps/aarch64/dl-machine.h (elf_machine_lazy_rel): Do symbol
-    	binding and initialization non-lazily for R_AARCH64_TLSDESC.
-
-diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
-index 4faf818b710d6ed7..185402f6dc550dc1 100644
---- a/sysdeps/aarch64/dl-machine.h
-+++ b/sysdeps/aarch64/dl-machine.h
-@@ -376,12 +376,21 @@ elf_machine_lazy_rel (struct link_map *map,
-     }
-   else if (__builtin_expect (r_type == R_AARCH64_TLSDESC, 1))
-     {
--      struct tlsdesc volatile *td =
--	(struct tlsdesc volatile *)reloc_addr;
-+      const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
-+      const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]);
-+      const ElfW (Sym) *sym = &symtab[symndx];
-+      const struct r_found_version *version = NULL;
- 
--      td->arg = (void*)reloc;
--      td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
--			  + map->l_addr);
-+      if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
-+	{
-+	  const ElfW (Half) *vernum =
-+	    (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
-+	  version = &map->l_versions[vernum[symndx] & 0x7fff];
-+	}
-+
-+      /* Always initialize TLS descriptors completely, because lazy
-+	 initialization requires synchronization at every TLS access.  */
-+      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
-     }
-   else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE))
-     {
diff --git a/SOURCES/glibc-rh1662842.patch b/SOURCES/glibc-rh1662842.patch
new file mode 100644
index 0000000..58be2be
--- /dev/null
+++ b/SOURCES/glibc-rh1662842.patch
@@ -0,0 +1,68 @@
+commit b50dd3bc8cbb1efe85399b03d7e6c0310c2ead84
+Author: Florian Weimer <fw@deneb.enyo.de>
+Date:   Mon Dec 31 22:04:36 2018 +0100
+
+    malloc: Always call memcpy in _int_realloc [BZ #24027]
+    
+    This commit removes the custom memcpy implementation from _int_realloc
+    for small chunk sizes.  The ncopies variable has the wrong type, and
+    an integer wraparound could cause the existing code to copy too few
+    elements (leaving the new memory region mostly uninitialized).
+    Therefore, removing this code fixes bug 24027.
+
+diff -rup a/malloc/malloc.c b/malloc/malloc.c
+--- a/malloc/malloc.c	2019-03-26 14:12:59.364333388 -0400
++++ b/malloc/malloc.c	2019-03-26 14:17:17.373475418 -0400
+@@ -4214,11 +4214,6 @@ _int_realloc(mstate av, mchunkptr oldp,
+   mchunkptr        bck;             /* misc temp for linking */
+   mchunkptr        fwd;             /* misc temp for linking */
+ 
+-  unsigned long    copysize;        /* bytes to copy */
+-  unsigned int     ncopies;         /* INTERNAL_SIZE_T words to copy */
+-  INTERNAL_SIZE_T* s;               /* copy source */
+-  INTERNAL_SIZE_T* d;               /* copy destination */
+-
+   const char *errstr = NULL;
+ 
+   /* oldmem size */
+@@ -4291,39 +4286,7 @@ _int_realloc(mstate av, mchunkptr oldp,
+ 	newp = oldp;
+       }
+       else {
+-	/*
+-	  Unroll copy of <= 36 bytes (72 if 8byte sizes)
+-	  We know that contents have an odd number of
+-	  INTERNAL_SIZE_T-sized words; minimally 3.
+-	*/
+-
+-	copysize = oldsize - SIZE_SZ;
+-	s = (INTERNAL_SIZE_T*)(chunk2mem(oldp));
+-	d = (INTERNAL_SIZE_T*)(newmem);
+-	ncopies = copysize / sizeof(INTERNAL_SIZE_T);
+-	assert(ncopies >= 3);
+-
+-	if (ncopies > 9)
+-	  MALLOC_COPY(d, s, copysize);
+-
+-	else {
+-	  *(d+0) = *(s+0);
+-	  *(d+1) = *(s+1);
+-	  *(d+2) = *(s+2);
+-	  if (ncopies > 4) {
+-	    *(d+3) = *(s+3);
+-	    *(d+4) = *(s+4);
+-	    if (ncopies > 6) {
+-	      *(d+5) = *(s+5);
+-	      *(d+6) = *(s+6);
+-	      if (ncopies > 8) {
+-		*(d+7) = *(s+7);
+-		*(d+8) = *(s+8);
+-	      }
+-	    }
+-	  }
+-	}
+-
++	memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ);
+ 	_int_free(av, oldp, 1);
+ 	check_inuse_chunk(av, newp);
+ 	return chunk2mem(newp);
diff --git a/SOURCES/glibc-rh1673465-1.patch b/SOURCES/glibc-rh1673465-1.patch
new file mode 100644
index 0000000..b548f3c
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-1.patch
@@ -0,0 +1,48 @@
+commit c94a5688fb1228a862b2d4a3f1239cdc0e3349e5
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Nov 2 12:14:01 2017 +0100
+
+    <array_length.h>: New array_length and array_end macros
+
+diff --git a/include/array_length.h b/include/array_length.h
+new file mode 100644
+index 0000000000000000..cb4a8b2a56bca3ad
+--- /dev/null
++++ b/include/array_length.h
+@@ -0,0 +1,36 @@
++/* The array_length and array_end macros.
++   Copyright (C) 2017 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 _ARRAY_LENGTH_H
++#define _ARRAY_LENGTH_H
++
++/* array_length (VAR) is the number of elements in the array VAR.  VAR
++   must evaluate to an array, not a pointer.  */
++#define array_length(var)                                               \
++  __extension__ ({                                                      \
++    _Static_assert (!__builtin_types_compatible_p                       \
++                    (__typeof (var), __typeof (&(var)[0])),             \
++                    "argument must be an array");                       \
++    sizeof (var) / sizeof ((var)[0]);                                   \
++  })
++
++/* array_end (VAR) is a pointer one past the end of the array VAR.
++   VAR must evaluate to an array, not a pointer.  */
++#define array_end(var) (&(var)[array_length (var)])
++
++#endif /* _ARRAY_LENGTH_H */
diff --git a/SOURCES/glibc-rh1673465-2.patch b/SOURCES/glibc-rh1673465-2.patch
new file mode 100644
index 0000000..5c4cbab
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-2.patch
@@ -0,0 +1,34 @@
+commit 8311c83f91a3127ccd2fe684e25bc60c5178d23b
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Feb 7 09:03:02 2019 +0100
+
+    array_length: Make usable as a constant expression
+    
+    Do not use a statement expression in array_length, so that
+    array_length can be used at file scope and as a constant expression.
+    Instead, put the _Static_assert into a struct (as a declaration),
+    and nest this in the expression using a sizeof expression.
+
+diff --git a/include/array_length.h b/include/array_length.h
+index cb4a8b2a56bca3ad..ccb253c1dc1641cf 100644
+--- a/include/array_length.h
++++ b/include/array_length.h
+@@ -22,12 +22,12 @@
+ /* array_length (VAR) is the number of elements in the array VAR.  VAR
+    must evaluate to an array, not a pointer.  */
+ #define array_length(var)                                               \
+-  __extension__ ({                                                      \
+-    _Static_assert (!__builtin_types_compatible_p                       \
+-                    (__typeof (var), __typeof (&(var)[0])),             \
+-                    "argument must be an array");                       \
+-    sizeof (var) / sizeof ((var)[0]);                                   \
+-  })
++  (sizeof (var) / sizeof ((var)[0])                                     \
++   + 0 * sizeof (struct {                                               \
++       _Static_assert (!__builtin_types_compatible_p                    \
++                       (__typeof (var), __typeof (&(var)[0])),          \
++                       "argument must be an array");                    \
++   }))
+ 
+ /* array_end (VAR) is a pointer one past the end of the array VAR.
+    VAR must evaluate to an array, not a pointer.  */
diff --git a/SOURCES/glibc-rh1673465-3.patch b/SOURCES/glibc-rh1673465-3.patch
new file mode 100644
index 0000000..5e8faa2
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-3.patch
@@ -0,0 +1,142 @@
+commit c74a91deaa5de416237c02bbb3e41bda76ca4c7b
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Nov 27 21:35:56 2018 +0100
+
+    support: Implement support_quote_string
+    
+    Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+
+diff --git a/support/Makefile b/support/Makefile
+index 2b663fbbfa334ea2..a2536980d1d5a89b 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -58,6 +58,7 @@ libsupport-routines = \
+   support_openpty \
+   support_paths \
+   support_quote_blob \
++  support_quote_string \
+   support_record_failure \
+   support_run_diff \
+   support_shared_allocate \
+@@ -196,6 +197,7 @@ tests = \
+   tst-support_capture_subprocess \
+   tst-support_format_dns_packet \
+   tst-support_quote_blob \
++  tst-support_quote_string \
+   tst-support_record_failure \
+   tst-test_compare \
+   tst-test_compare_blob \
+diff --git a/support/support.h b/support/support.h
+index 9418cd11ef6e684d..835e7173eb566355 100644
+--- a/support/support.h
++++ b/support/support.h
+@@ -69,6 +69,11 @@ void support_write_file_string (const char *path, const char *contents);
+    the result).  */
+ char *support_quote_blob (const void *blob, size_t length);
+ 
++/* Quote the contents of the at STR, in such a way that the result
++   string can be included in a C literal (in single/double quotes,
++   without putting the quotes into the result).  */
++char *support_quote_string (const char *str);
++
+ /* Returns non-zero if the file descriptor is a regular file on a file
+    system which supports holes (that is, seeking and writing does not
+    allocate storage for the range of zeros).  FD must refer to a
+diff --git a/support/support_quote_string.c b/support/support_quote_string.c
+new file mode 100644
+index 0000000000000000..d324371b133a4d66
+--- /dev/null
++++ b/support/support_quote_string.c
+@@ -0,0 +1,26 @@
++/* Quote a string so that it can be used in C literals.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <string.h>
++#include <support/support.h>
++
++char *
++support_quote_string (const char *str)
++{
++  return support_quote_blob (str, strlen (str));
++}
+diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c
+new file mode 100644
+index 0000000000000000..3c004759b76e21d7
+--- /dev/null
++++ b/support/tst-support_quote_string.c
+@@ -0,0 +1,60 @@
++/* Test the support_quote_string function.
++   Copyright (C) 2018 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <support/check.h>
++#include <support/support.h>
++#include <string.h>
++#include <stdlib.h>
++
++static int
++do_test (void)
++{
++  char *p = support_quote_string ("");
++  TEST_COMPARE (strlen (p), 0);
++  free (p);
++  p = support_quote_string ("X");
++  TEST_COMPARE (strlen (p), 1);
++  TEST_COMPARE (p[0], 'X');
++  free (p);
++
++  /* Check escaping of backslash-escaped characters, and lack of
++     escaping for other shell meta-characters.  */
++  p = support_quote_string ("$()*?`@[]{}~\'\"X");
++  TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0);
++  free (p);
++
++  /* Check lack of escaping for letters and digits.  */
++#define LETTERS_AND_DIGTS                       \
++  "abcdefghijklmnopqrstuvwxyz"                  \
++  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"                  \
++  "0123456789"
++  p = support_quote_string (LETTERS_AND_DIGTS "@");
++  TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0);
++  free (p);
++
++  /* Check escaping of control characters and other non-printable
++     characters.  */
++  p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@");
++  TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
++                        "\\177\\200\\377@"), 0);
++  free (p);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1673465-4.patch b/SOURCES/glibc-rh1673465-4.patch
new file mode 100644
index 0000000..5842b08
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-4.patch
@@ -0,0 +1,221 @@
+commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 21 08:59:42 2019 +0100
+
+    resolv: Reformat inet_addr, inet_aton to GNU style
+
+diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
+index 022f7ea0841b6bae..32f58b0e13598b32 100644
+--- a/resolv/inet_addr.c
++++ b/resolv/inet_addr.c
+@@ -1,3 +1,21 @@
++/* Legacy IPv4 text-to-address functions.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
+ /*
+  * Copyright (c) 1983, 1990, 1993
+  *    The Regents of the University of California.  All rights reserved.
+@@ -78,105 +96,97 @@
+ #include <limits.h>
+ #include <errno.h>
+ 
+-/*
+- * Ascii internet address interpretation routine.
+- * The value returned is in network order.
+- */
++/* ASCII IPv4 Internet address interpretation routine.  The value
++   returned is in network order.  */
+ in_addr_t
+-__inet_addr(const char *cp) {
+-	struct in_addr val;
++__inet_addr (const char *cp)
++{
++  struct in_addr val;
+ 
+-	if (__inet_aton(cp, &val))
+-		return (val.s_addr);
+-	return (INADDR_NONE);
++  if (__inet_aton (cp, &val))
++    return val.s_addr;
++  return INADDR_NONE;
+ }
+ weak_alias (__inet_addr, inet_addr)
+ 
+-/*
+- * Check whether "cp" is a valid ascii representation
+- * of an Internet address and convert to a binary address.
+- * Returns 1 if the address is valid, 0 if not.
+- * This replaces inet_addr, the return value from which
+- * cannot distinguish between failure and a local broadcast address.
+- */
++/* Check whether "cp" is a valid ASCII representation of an IPv4
++   Internet address and convert it to a binary address.  Returns 1 if
++   the address is valid, 0 if not.  This replaces inet_addr, the
++   return value from which cannot distinguish between failure and a
++   local broadcast address.  */
+ int
+-__inet_aton(const char *cp, struct in_addr *addr)
++__inet_aton (const char *cp, struct in_addr *addr)
+ {
+-	static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
+-	in_addr_t val;
+-	char c;
+-	union iaddr {
+-	  uint8_t bytes[4];
+-	  uint32_t word;
+-	} res;
+-	uint8_t *pp = res.bytes;
+-	int digit;
+-
+-	int saved_errno = errno;
+-	__set_errno (0);
+-
+-	res.word = 0;
+-
+-	c = *cp;
+-	for (;;) {
+-		/*
+-		 * Collect number up to ``.''.
+-		 * Values are specified as for C:
+-		 * 0x=hex, 0=octal, isdigit=decimal.
+-		 */
+-		if (!isdigit(c))
+-			goto ret_0;
+-		{
+-			char *endp;
+-			unsigned long ul = strtoul (cp, (char **) &endp, 0);
+-			if (ul == ULONG_MAX && errno == ERANGE)
+-				goto ret_0;
+-			if (ul > 0xfffffffful)
+-				goto ret_0;
+-			val = ul;
+-			digit = cp != endp;
+-			cp = endp;
+-		}
+-		c = *cp;
+-		if (c == '.') {
+-			/*
+-			 * Internet format:
+-			 *	a.b.c.d
+-			 *	a.b.c	(with c treated as 16 bits)
+-			 *	a.b	(with b treated as 24 bits)
+-			 */
+-			if (pp > res.bytes + 2 || val > 0xff)
+-				goto ret_0;
+-			*pp++ = val;
+-			c = *++cp;
+-		} else
+-			break;
+-	}
+-	/*
+-	 * Check for trailing characters.
+-	 */
+-	if (c != '\0' && (!isascii(c) || !isspace(c)))
+-		goto ret_0;
+-	/*
+-	 * Did we get a valid digit?
+-	 */
+-	if (!digit)
+-		goto ret_0;
+-
+-	/* Check whether the last part is in its limits depending on
+-	   the number of parts in total.  */
+-	if (val > max[pp - res.bytes])
++  static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
++  in_addr_t val;
++  char c;
++  union iaddr
++  {
++    uint8_t bytes[4];
++    uint32_t word;
++  } res;
++  uint8_t *pp = res.bytes;
++  int digit;
++
++  int saved_errno = errno;
++  __set_errno (0);
++
++  res.word = 0;
++
++  c = *cp;
++  for (;;)
++    {
++      /* Collect number up to ``.''.  Values are specified as for C:
++	 0x=hex, 0=octal, isdigit=decimal.  */
++      if (!isdigit (c))
++	goto ret_0;
++      {
++	char *endp;
++	unsigned long ul = strtoul (cp, &endp, 0);
++	if (ul == ULONG_MAX && errno == ERANGE)
+ 	  goto ret_0;
+-
+-	if (addr != NULL)
+-		addr->s_addr = res.word | htonl (val);
+-
+-	__set_errno (saved_errno);
+-	return (1);
+-
+-ret_0:
+-	__set_errno (saved_errno);
+-	return (0);
++	if (ul > 0xfffffffful)
++	  goto ret_0;
++	val = ul;
++	digit = cp != endp;
++	cp = endp;
++      }
++      c = *cp;
++      if (c == '.')
++	{
++	  /* Internet format:
++	     a.b.c.d
++	     a.b.c	(with c treated as 16 bits)
++	     a.b	(with b treated as 24 bits).  */
++	  if (pp > res.bytes + 2 || val > 0xff)
++	    goto ret_0;
++	  *pp++ = val;
++	  c = *++cp;
++	}
++      else
++	break;
++    }
++  /* Check for trailing characters.  */
++  if (c != '\0' && (!isascii (c) || !isspace (c)))
++    goto ret_0;
++  /*  Did we get a valid digit?  */
++  if (!digit)
++    goto ret_0;
++
++  /* Check whether the last part is in its limits depending on the
++     number of parts in total.  */
++  if (val > max[pp - res.bytes])
++    goto ret_0;
++
++  if (addr != NULL)
++    addr->s_addr = res.word | htonl (val);
++
++  __set_errno (saved_errno);
++  return 1;
++
++ ret_0:
++  __set_errno (saved_errno);
++  return 0;
+ }
+ weak_alias (__inet_aton, inet_aton)
+ libc_hidden_def (__inet_aton)
diff --git a/SOURCES/glibc-rh1673465-5.patch b/SOURCES/glibc-rh1673465-5.patch
new file mode 100644
index 0000000..6177dd1
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-5.patch
@@ -0,0 +1,80 @@
+commit 6ca53a2453598804a2559a548a08424fca96434a
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 21 09:26:41 2019 +0100
+
+    resolv: Do not send queries for non-host-names in nss_dns [BZ #24112]
+    
+    Before this commit, nss_dns would send a query which did not contain a
+    host name as the query name (such as invalid\032name.example.com) and
+    then reject the answer in getanswer_r and gaih_getanswer_slice, using
+    a check based on res_hnok.  With this commit, no query is sent, and a
+    host-not-found error is returned to NSS without network interaction.
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index 1e85e4f08ffc8600..e697d9103797341b 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -273,11 +273,26 @@ gethostbyname3_context (struct resolv_context *ctx,
+   return status;
+ }
+ 
++/* Verify that the name looks like a host name.  There is no point in
++   sending a query which will not produce a usable name in the
++   response.  */
++static enum nss_status
++check_name (const char *name, int *h_errnop)
++{
++  if (res_hnok (name))
++    return NSS_STATUS_SUCCESS;
++  *h_errnop = HOST_NOT_FOUND;
++  return NSS_STATUS_NOTFOUND;
++}
++
+ enum nss_status
+ _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
+ 			   char *buffer, size_t buflen, int *errnop,
+ 			   int *h_errnop)
+ {
++  enum nss_status status = check_name (name, h_errnop);
++  if (status != NSS_STATUS_SUCCESS)
++    return status;
+   return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop,
+ 				    h_errnop, NULL, NULL);
+ }
+@@ -288,6 +303,9 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
+ 			  char *buffer, size_t buflen, int *errnop,
+ 			  int *h_errnop)
+ {
++  enum nss_status status = check_name (name, h_errnop);
++  if (status != NSS_STATUS_SUCCESS)
++    return status;
+   struct resolv_context *ctx = __resolv_context_get ();
+   if (ctx == NULL)
+     {
+@@ -295,7 +313,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
+       *h_errnop = NETDB_INTERNAL;
+       return NSS_STATUS_UNAVAIL;
+     }
+-  enum nss_status status = NSS_STATUS_NOTFOUND;
++  status = NSS_STATUS_NOTFOUND;
+   if (res_use_inet6 ())
+     status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer,
+ 				     buflen, errnop, h_errnop, NULL, NULL);
+@@ -312,6 +330,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+ 			   char *buffer, size_t buflen, int *errnop,
+ 			   int *herrnop, int32_t *ttlp)
+ {
++  enum nss_status status = check_name (name, herrnop);
++  if (status != NSS_STATUS_SUCCESS)
++    return status;
+   struct resolv_context *ctx = __resolv_context_get ();
+   if (ctx == NULL)
+     {
+@@ -346,7 +367,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+   int ans2p_malloced = 0;
+ 
+   int olderr = errno;
+-  enum nss_status status;
+   int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
+ 				host_buffer.buf->buf, 2048, &host_buffer.ptr,
+ 				&ans2p, &nans2p, &resplen2, &ans2p_malloced);
diff --git a/SOURCES/glibc-rh1673465-6.patch b/SOURCES/glibc-rh1673465-6.patch
new file mode 100644
index 0000000..78aa0c8
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-6.patch
@@ -0,0 +1,698 @@
+commit 108bc4049f8ae82710aec26a92ffdb4b439c83fd
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Jan 21 21:26:03 2019 +0100
+
+    CVE-2016-10739: getaddrinfo: Fully parse IPv4 address strings [BZ #20018]
+    
+    The IPv4 address parser in the getaddrinfo function is changed so that
+    it does not ignore trailing whitespace and all characters after it.
+    For backwards compatibility, the getaddrinfo function still recognizes
+    legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8
+    (octal).
+    
+    This commit does not change the behavior of inet_addr and inet_aton.
+    gethostbyname already had additional sanity checks (but is switched
+    over to the new __inet_aton_exact function for completeness as well).
+    
+    To avoid sending the problematic query names over DNS, commit
+    6ca53a2453598804a2559a548a08424fca96434a ("resolv: Do not send queries
+    for non-host-names in nss_dns [BZ #24112]") is needed.
+
+diff --git a/include/arpa/inet.h b/include/arpa/inet.h
+index c3f28f2baaa2ed66..19aec74275069a45 100644
+--- a/include/arpa/inet.h
++++ b/include/arpa/inet.h
+@@ -1,10 +1,10 @@
+ #include <inet/arpa/inet.h>
+ 
+ #ifndef _ISOMAC
+-extern int __inet_aton (const char *__cp, struct in_addr *__inp);
+-libc_hidden_proto (__inet_aton)
++/* Variant of inet_aton which rejects trailing garbage.  */
++extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp);
++libc_hidden_proto (__inet_aton_exact)
+ 
+-libc_hidden_proto (inet_aton)
+ libc_hidden_proto (inet_ntop)
+ libc_hidden_proto (inet_pton)
+ extern __typeof (inet_pton) __inet_pton;
+diff --git a/nscd/gai.c b/nscd/gai.c
+index 018b449339813df5..dbe878fcf699dbc1 100644
+--- a/nscd/gai.c
++++ b/nscd/gai.c
+@@ -20,7 +20,6 @@
+ 
+ /* This file uses the getaddrinfo code but it compiles it without NSCD
+    support.  We just need a few symbol renames.  */
+-#define __inet_aton inet_aton
+ #define __ioctl ioctl
+ #define __getsockname getsockname
+ #define __socket socket
+diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c
+index 2ab75e469eca1589..958a12d063f1e3e6 100644
+--- a/nscd/gethstbynm3_r.c
++++ b/nscd/gethstbynm3_r.c
+@@ -38,8 +38,6 @@
+ #define HAVE_LOOKUP_BUFFER	1
+ #define HAVE_AF			1
+ 
+-#define __inet_aton inet_aton
+-
+ /* We are nscd, so we don't want to be talking to ourselves.  */
+ #undef	USE_NSCD
+ 
+diff --git a/nss/digits_dots.c b/nss/digits_dots.c
+index 0c1fa97e3977a81e..5f7e5b5fb120c387 100644
+--- a/nss/digits_dots.c
++++ b/nss/digits_dots.c
+@@ -29,7 +29,6 @@
+ #include "nsswitch.h"
+ 
+ #ifdef USE_NSCD
+-# define inet_aton __inet_aton
+ # include <nscd/nscd_proto.h>
+ #endif
+ 
+@@ -160,7 +159,7 @@ __nss_hostname_digits_dots_context (struct resolv_context *ctx,
+ 		     255.255.255.255?  The test below will succeed
+ 		     spuriously... ???  */
+ 		  if (af == AF_INET)
+-		    ok = __inet_aton (name, (struct in_addr *) host_addr);
++		    ok = __inet_aton_exact (name, (struct in_addr *) host_addr);
+ 		  else
+ 		    {
+ 		      assert (af == AF_INET6);
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 1124897ce5f9610b..988871086a70b291 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -34,6 +34,9 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
+ tests = tst-aton tst-leaks tst-inet_ntop
+ xtests = tst-leaks2
+ 
++tests-internal += tst-inet_aton_exact
++
++
+ generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
+ 
+ extra-libs := libresolv libnss_dns
+@@ -51,8 +54,10 @@ tests += \
+   tst-resolv-basic \
+   tst-resolv-edns \
+   tst-resolv-network \
++  tst-resolv-nondecimal \
+   tst-resolv-res_init-multi \
+   tst-resolv-search \
++  tst-resolv-trailing \
+ 
+ # These tests need libdl.
+ ifeq (yes,$(build-shared))
+@@ -164,9 +169,11 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
+   $(shared-thread-library)
+ $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \
+   $(shared-thread-library)
++$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-threads: \
+   $(libdl) $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-canonname: \
+diff --git a/resolv/Versions b/resolv/Versions
+index b05778d9654aa0f2..9a82704af75f789b 100644
+--- a/resolv/Versions
++++ b/resolv/Versions
+@@ -27,6 +27,7 @@ libc {
+     __h_errno; __resp;
+ 
+     __res_iclose;
++    __inet_aton_exact;
+     __inet_pton_length;
+     __resolv_context_get;
+     __resolv_context_get_preinit;
+diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
+index 32f58b0e13598b32..41b6166a5bd5a44b 100644
+--- a/resolv/inet_addr.c
++++ b/resolv/inet_addr.c
+@@ -96,26 +96,14 @@
+ #include <limits.h>
+ #include <errno.h>
+ 
+-/* ASCII IPv4 Internet address interpretation routine.  The value
+-   returned is in network order.  */
+-in_addr_t
+-__inet_addr (const char *cp)
+-{
+-  struct in_addr val;
+-
+-  if (__inet_aton (cp, &val))
+-    return val.s_addr;
+-  return INADDR_NONE;
+-}
+-weak_alias (__inet_addr, inet_addr)
+-
+ /* Check whether "cp" is a valid ASCII representation of an IPv4
+    Internet address and convert it to a binary address.  Returns 1 if
+    the address is valid, 0 if not.  This replaces inet_addr, the
+    return value from which cannot distinguish between failure and a
+-   local broadcast address.  */
+-int
+-__inet_aton (const char *cp, struct in_addr *addr)
++   local broadcast address.  Write a pointer to the first
++   non-converted character to *endp.  */
++static int
++inet_aton_end (const char *cp, struct in_addr *addr, const char **endp)
+ {
+   static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
+   in_addr_t val;
+@@ -180,6 +168,7 @@ __inet_aton (const char *cp, struct in_addr *addr)
+ 
+   if (addr != NULL)
+     addr->s_addr = res.word | htonl (val);
++  *endp = cp;
+ 
+   __set_errno (saved_errno);
+   return 1;
+@@ -188,6 +177,41 @@ __inet_aton (const char *cp, struct in_addr *addr)
+   __set_errno (saved_errno);
+   return 0;
+ }
+-weak_alias (__inet_aton, inet_aton)
+-libc_hidden_def (__inet_aton)
+-libc_hidden_weak (inet_aton)
++
++int
++__inet_aton_exact (const char *cp, struct in_addr *addr)
++{
++  struct in_addr val;
++  const char *endp;
++  /* Check that inet_aton_end parsed the entire string.  */
++  if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0)
++    {
++      *addr = val;
++      return 1;
++    }
++  else
++    return 0;
++}
++libc_hidden_def (__inet_aton_exact)
++
++/* inet_aton ignores trailing garbage.  */
++int
++__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr)
++{
++  const char *endp;
++  return  inet_aton_end (cp, addr, &endp);
++}
++weak_alias (__inet_aton_ignore_trailing, inet_aton)
++
++/* ASCII IPv4 Internet address interpretation routine.  The value
++   returned is in network order.  */
++in_addr_t
++__inet_addr (const char *cp)
++{
++  struct in_addr val;
++  const char *endp;
++  if (inet_aton_end (cp, &val, &endp))
++    return val.s_addr;
++  return INADDR_NONE;
++}
++weak_alias (__inet_addr, inet_addr)
+diff --git a/resolv/res_init.c b/resolv/res_init.c
+index c29bc4e9b99b6bee..9ea9c01d1029ba5f 100644
+--- a/resolv/res_init.c
++++ b/resolv/res_init.c
+@@ -399,8 +399,16 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+               cp = parser->buffer + sizeof ("nameserver") - 1;
+               while (*cp == ' ' || *cp == '\t')
+                 cp++;
++
++              /* Ignore trailing contents on the name server line.  */
++              {
++                char *el;
++                if ((el = strpbrk (cp, " \t\n")) != NULL)
++                  *el = '\0';
++              }
++
+               struct sockaddr *sa;
+-              if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a))
++              if ((*cp != '\0') && (*cp != '\n') && __inet_aton_exact (cp, &a))
+                 {
+                   sa = allocate_address_v4 (a, NAMESERVER_PORT);
+                   if (sa == NULL)
+@@ -410,9 +418,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+                 {
+                   struct in6_addr a6;
+                   char *el;
+-
+-                  if ((el = strpbrk (cp, " \t\n")) != NULL)
+-                    *el = '\0';
+                   if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL)
+                     *el = '\0';
+                   if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0))
+@@ -472,7 +477,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+                   char separator = *cp;
+                   *cp = 0;
+                   struct resolv_sortlist_entry e;
+-                  if (__inet_aton (net, &a))
++                  if (__inet_aton_exact (net, &a))
+                     {
+                       e.addr = a;
+                       if (is_sort_mask (separator))
+@@ -484,7 +489,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
+                             cp++;
+                           separator = *cp;
+                           *cp = 0;
+-                          if (__inet_aton (net, &a))
++                          if (__inet_aton_exact (net, &a))
+                             e.mask = a.s_addr;
+                           else
+                             e.mask = net_mask (e.addr);
+diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c
+index 08110a007af909ff..eb734d7758d6ed87 100644
+--- a/resolv/tst-aton.c
++++ b/resolv/tst-aton.c
+@@ -1,11 +1,29 @@
++/* Test legacy IPv4 text-to-address function inet_aton.
++   Copyright (C) 1998-2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <array_length.h>
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ 
+-
+-static struct tests
++static const struct tests
+ {
+   const char *input;
+   int valid;
+@@ -16,6 +34,7 @@ static struct tests
+   { "-1", 0, 0 },
+   { "256", 1, 0x00000100 },
+   { "256.", 0, 0 },
++  { "255a", 0, 0 },
+   { "256a", 0, 0 },
+   { "0x100", 1, 0x00000100 },
+   { "0200.0x123456", 1, 0x80123456 },
+@@ -40,7 +59,12 @@ static struct tests
+   { "1.2.256.4", 0, 0 },
+   { "1.2.3.0x100", 0, 0 },
+   { "323543357756889", 0, 0 },
+-  { "10.1.2.3.4", 0, 0},
++  { "10.1.2.3.4", 0, 0 },
++  { "192.0.2.1", 1, 0xc0000201 },
++  { "192.0.2.2\nX", 1, 0xc0000202 },
++  { "192.0.2.3 Y", 1, 0xc0000203 },
++  { "192.0.2.3Z", 0, 0 },
++  { "192.000.002.010", 1, 0xc0000208 },
+ };
+ 
+ 
+@@ -50,7 +74,7 @@ do_test (void)
+   int result = 0;
+   size_t cnt;
+ 
+-  for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt)
++  for (cnt = 0; cnt < array_length (tests); ++cnt)
+     {
+       struct in_addr addr;
+ 
+@@ -73,5 +97,4 @@ do_test (void)
+   return result;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c
+new file mode 100644
+index 0000000000000000..0fdfa3d6aa9aef91
+--- /dev/null
++++ b/resolv/tst-inet_aton_exact.c
+@@ -0,0 +1,47 @@
++/* Test internal legacy IPv4 text-to-address function __inet_aton_exact.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <arpa/inet.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  struct in_addr addr = { };
++
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.1", &addr), 1);
++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000201);
++
++  TEST_COMPARE (__inet_aton_exact ("192.000.002.010", &addr), 1);
++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000208);
++  TEST_COMPARE (__inet_aton_exact ("0xC0000234", &addr), 1);
++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000234);
++
++  /* Trailing content is not accepted.  */
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.2X", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.3 Y", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.4\nZ", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.5\tT", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.6 Y", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.7\n", &addr), 0);
++  TEST_COMPARE (__inet_aton_exact ("192.0.2.8\t", &addr), 0);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-nondecimal.c b/resolv/tst-resolv-nondecimal.c
+new file mode 100644
+index 0000000000000000..a0df6f332ae8faf7
+--- /dev/null
++++ b/resolv/tst-resolv-nondecimal.c
+@@ -0,0 +1,139 @@
++/* Test name resolution behavior for octal, hexadecimal IPv4 addresses.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <netdb.h>
++#include <stdlib.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  /* The tests are not supposed send any DNS queries.  */
++  FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
++}
++
++static void
++run_query_addrinfo (const char *query, const char *address)
++{
++  char *quoted_query = support_quote_string (query);
++
++  struct addrinfo *ai;
++  struct addrinfo hints =
++    {
++     .ai_socktype = SOCK_STREAM,
++     .ai_protocol = IPPROTO_TCP,
++    };
++
++  char *context = xasprintf ("getaddrinfo \"%s\" AF_INET", quoted_query);
++  char *expected = xasprintf ("address: STREAM/TCP %s 80\n", address);
++  hints.ai_family = AF_INET;
++  int ret = getaddrinfo (query, "80", &hints, &ai);
++  check_addrinfo (context, ai, ret, expected);
++  if (ret == 0)
++    freeaddrinfo (ai);
++  free (context);
++
++  context = xasprintf ("getaddrinfo \"%s\" AF_UNSPEC", quoted_query);
++  hints.ai_family = AF_UNSPEC;
++  ret = getaddrinfo (query, "80", &hints, &ai);
++  check_addrinfo (context, ai, ret, expected);
++  if (ret == 0)
++    freeaddrinfo (ai);
++  free (expected);
++  free (context);
++
++  context = xasprintf ("getaddrinfo \"%s\" AF_INET6", quoted_query);
++  expected = xasprintf ("flags: AI_V4MAPPED\n"
++                        "address: STREAM/TCP ::ffff:%s 80\n",
++                        address);
++  hints.ai_family = AF_INET6;
++  hints.ai_flags = AI_V4MAPPED;
++  ret = getaddrinfo (query, "80", &hints, &ai);
++  check_addrinfo (context, ai, ret, expected);
++  if (ret == 0)
++    freeaddrinfo (ai);
++  free (expected);
++  free (context);
++
++  free (quoted_query);
++}
++
++static void
++run_query (const char *query, const char *address)
++{
++  char *quoted_query = support_quote_string (query);
++  char *context = xasprintf ("gethostbyname (\"%s\")", quoted_query);
++  char *expected = xasprintf ("name: %s\n"
++                              "address: %s\n", query, address);
++  check_hostent (context, gethostbyname (query), expected);
++  free (context);
++
++  context = xasprintf ("gethostbyname_r \"%s\"", quoted_query);
++  struct hostent storage;
++  char buf[4096];
++  struct hostent *e = NULL;
++  TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
++                                 &e, &h_errno), 0);
++  check_hostent (context, e, expected);
++  free (context);
++
++  context = xasprintf ("gethostbyname2 (\"%s\", AF_INET)", quoted_query);
++  check_hostent (context, gethostbyname2 (query, AF_INET), expected);
++  free (context);
++
++  context = xasprintf ("gethostbyname2_r \"%s\" AF_INET", quoted_query);
++  e = NULL;
++  TEST_COMPARE (gethostbyname2_r (query, AF_INET, &storage, buf, sizeof (buf),
++                                  &e, &h_errno), 0);
++  check_hostent (context, e, expected);
++  free (context);
++  free (expected);
++
++  free (quoted_query);
++
++  /* The gethostbyname tests are always valid for getaddrinfo, but not
++     vice versa.  */
++  run_query_addrinfo (query, address);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *aux = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response,
++     });
++
++  run_query ("192.000.002.010", "192.0.2.8");
++
++  /* Hexadecimal numbers are not accepted by gethostbyname.  */
++  run_query_addrinfo ("0xc0000210", "192.0.2.16");
++  run_query_addrinfo ("192.0x234", "192.0.2.52");
++
++  resolv_test_end (aux);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-trailing.c b/resolv/tst-resolv-trailing.c
+new file mode 100644
+index 0000000000000000..7504bdae572ed8d0
+--- /dev/null
++++ b/resolv/tst-resolv-trailing.c
+@@ -0,0 +1,136 @@
++/* Test name resolution behavior with trailing characters.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <array_length.h>
++#include <netdb.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  /* The tests are not supposed send any DNS queries.  */
++  FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *aux = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response,
++     });
++
++  static const char *const queries[] =
++    {
++     "192.0.2.1 ",
++     "192.0.2.2\t",
++     "192.0.2.3\n",
++     "192.0.2.4 X",
++     "192.0.2.5\tY",
++     "192.0.2.6\nZ",
++     "192.0.2. ",
++     "192.0.2.\t",
++     "192.0.2.\n",
++     "192.0.2. X",
++     "192.0.2.\tY",
++     "192.0.2.\nZ",
++     "2001:db8::1 ",
++     "2001:db8::2\t",
++     "2001:db8::3\n",
++     "2001:db8::4 X",
++     "2001:db8::5\tY",
++     "2001:db8::6\nZ",
++    };
++  for (size_t query_idx = 0; query_idx < array_length (queries); ++query_idx)
++    {
++      const char *query = queries[query_idx];
++      struct hostent storage;
++      char buf[4096];
++      struct hostent *e;
++
++      h_errno = 0;
++      TEST_VERIFY (gethostbyname (query) == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      e = NULL;
++      TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
++                                     &e, &h_errno), 0);
++      TEST_VERIFY (e == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      TEST_VERIFY (gethostbyname2 (query, AF_INET) == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      e = NULL;
++      TEST_COMPARE (gethostbyname2_r (query, AF_INET,
++                                      &storage, buf, sizeof (buf),
++                                     &e, &h_errno), 0);
++      TEST_VERIFY (e == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      TEST_VERIFY (gethostbyname2 (query, AF_INET6) == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      h_errno = 0;
++      e = NULL;
++      TEST_COMPARE (gethostbyname2_r (query, AF_INET6,
++                                      &storage, buf, sizeof (buf),
++                                     &e, &h_errno), 0);
++      TEST_VERIFY (e == NULL);
++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
++
++      static const int gai_flags[] =
++        {
++         0,
++         AI_ADDRCONFIG,
++         AI_NUMERICHOST,
++         AI_IDN,
++         AI_IDN | AI_NUMERICHOST,
++         AI_V4MAPPED,
++         AI_V4MAPPED | AI_NUMERICHOST,
++        };
++      for (size_t gai_flags_idx; gai_flags_idx < array_length (gai_flags);
++             ++gai_flags_idx)
++        {
++          struct addrinfo hints = { .ai_flags = gai_flags[gai_flags_idx], };
++          struct addrinfo *ai;
++          hints.ai_family = AF_INET;
++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
++          hints.ai_family = AF_INET6;
++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
++          hints.ai_family = AF_UNSPEC;
++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
++        }
++    };
++
++  resolv_test_end (aux);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 2c4b6d6793a4c3a9..52f1b590f00c518e 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -508,7 +508,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
+ 	}
+ #endif
+ 
+-      if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
++      if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
+ 	{
+ 	  if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
+ 	    at->family = AF_INET;
diff --git a/SOURCES/glibc-rh1673465-7.patch b/SOURCES/glibc-rh1673465-7.patch
new file mode 100644
index 0000000..ea20dbc
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-7.patch
@@ -0,0 +1,81 @@
+commit c533244b8e00ae701583ec50aeb43377d292452d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Feb 4 20:07:18 2019 +0100
+
+    nscd: Do not use __inet_aton_exact@GLIBC_PRIVATE [BZ #20018]
+    
+    This commit avoids referencing the __inet_aton_exact@GLIBC_PRIVATE
+    symbol from nscd.  In master, the separately-compiled getaddrinfo
+    implementation in nscd needs it, however such an internal ABI change
+    is not desirable on a release branch if it can be avoided.
+
+(Note: This commit was backported from the release/2.28/master branch.)
+
+diff --git a/nscd/Makefile b/nscd/Makefile
+index 2dc98d3a3347f998..62f38fa824527e0a 100644
+--- a/nscd/Makefile
++++ b/nscd/Makefile
+@@ -36,7 +36,7 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
+ 		getsrvbynm_r getsrvbypt_r servicescache \
+ 		dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
+ 		xmalloc xstrdup aicache initgrcache gai res_hconf \
+-		netgroupcache
++		netgroupcache nscd-inet_addr
+ 
+ ifeq ($(build-nscd)$(have-thread-library),yesyes)
+ 
+diff --git a/nscd/gai.c b/nscd/gai.c
+index dbe878fcf699dbc1..e7443904b4514836 100644
+--- a/nscd/gai.c
++++ b/nscd/gai.c
+@@ -32,6 +32,12 @@
+ /* nscd uses 1MB or 2MB thread stacks.  */
+ #define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF)
+ 
++/* We do not want to export __inet_aton_exact.  Get the prototype and
++   change its visibility to hidden.  */
++#include <arpa/inet.h>
++__typeof__ (__inet_aton_exact) __inet_aton_exact
++  __attribute__ ((visibility ("hidden")));
++
+ /* We are nscd, so we don't want to be talking to ourselves.  */
+ #undef  USE_NSCD
+ 
+diff --git a/nscd/nscd-inet_addr.c b/nscd/nscd-inet_addr.c
+new file mode 100644
+index 0000000000000000..f366b9567d914f99
+--- /dev/null
++++ b/nscd/nscd-inet_addr.c
+@@ -0,0 +1,32 @@
++/* Legacy IPv4 text-to-address functions.  Version for nscd.
++   Copyright (C) 2019 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <arpa/inet.h>
++
++/* We do not want to export __inet_aton_exact.  Get the prototype and
++   change the visibility to hidden.  */
++#include <arpa/inet.h>
++__typeof__ (__inet_aton_exact) __inet_aton_exact
++  __attribute__ ((visibility ("hidden")));
++
++/* Do not provide definitions of the public symbols exported from
++   libc.  */
++#undef weak_alias
++#define weak_alias(from, to)
++
++#include <resolv/inet_addr.c>
diff --git a/SOURCES/glibc-rh1673465-8.patch b/SOURCES/glibc-rh1673465-8.patch
new file mode 100644
index 0000000..51954e1
--- /dev/null
+++ b/SOURCES/glibc-rh1673465-8.patch
@@ -0,0 +1,16 @@
+Adjust resolv/tst-inet_aton_exact to use tests instead of tests-internal.
+Downstream, tests-internal is currently ignored.
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 0130a09db2d69451..033c3c651f0deb1b 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -34,7 +34,7 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
+ tests = tst-aton tst-leaks tst-inet_ntop
+ xtests = tst-leaks2
+ 
+-tests-internal += tst-inet_aton_exact
++tests += tst-inet_aton_exact
+ 
+ 
+ generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
diff --git a/SOURCES/glibc-rh1684874-1.patch b/SOURCES/glibc-rh1684874-1.patch
new file mode 100644
index 0000000..2f1fc76
--- /dev/null
+++ b/SOURCES/glibc-rh1684874-1.patch
@@ -0,0 +1,54 @@
+commit 7c70f2272edd4efcc4525f1bbb50e92de1a27a57
+Author: Mike Frysinger <vapier@gentoo.org>
+Date:   Thu Jan 30 18:56:56 2014 -0500
+
+    linux: bits/in.h: sync with latest kernel headers
+    
+    This pulls in the latest defines for {g,s}etsockopt.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    Signed-off-by: Mike Frysinger <vapier@gentoo.org>
+
+diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
+index 022082da1c0ca9f7..ac07d17d0e9dc9c9 100644
+--- a/sysdeps/unix/sysv/linux/bits/in.h
++++ b/sysdeps/unix/sysv/linux/bits/in.h
+@@ -98,13 +98,37 @@
+ #define IP_RECVORIGDSTADDR   IP_ORIGDSTADDR
+ 
+ #define IP_MINTTL       21
+-
++#define IP_NODEFRAG     22
+ 
+ /* IP_MTU_DISCOVER arguments.  */
+ #define IP_PMTUDISC_DONT   0	/* Never send DF frames.  */
+ #define IP_PMTUDISC_WANT   1	/* Use per route hints.  */
+ #define IP_PMTUDISC_DO     2	/* Always DF.  */
+ #define IP_PMTUDISC_PROBE  3	/* Ignore dst pmtu.  */
++/* Always use interface mtu (ignores dst pmtu) but don't set DF flag.
++   Also incoming ICMP frag_needed notifications will be ignored on
++   this socket to prevent accepting spoofed ones.  */
++#define IP_PMTUDISC_INTERFACE           4
++
++#define IP_MULTICAST_IF			32
++#define IP_MULTICAST_TTL 		33
++#define IP_MULTICAST_LOOP 		34
++#define IP_ADD_MEMBERSHIP		35
++#define IP_DROP_MEMBERSHIP		36
++#define IP_UNBLOCK_SOURCE		37
++#define IP_BLOCK_SOURCE			38
++#define IP_ADD_SOURCE_MEMBERSHIP	39
++#define IP_DROP_SOURCE_MEMBERSHIP	40
++#define IP_MSFILTER			41
++#define MCAST_JOIN_GROUP		42
++#define MCAST_BLOCK_SOURCE		43
++#define MCAST_UNBLOCK_SOURCE		44
++#define MCAST_LEAVE_GROUP		45
++#define MCAST_JOIN_SOURCE_GROUP		46
++#define MCAST_LEAVE_SOURCE_GROUP	47
++#define MCAST_MSFILTER			48
++#define IP_MULTICAST_ALL		49
++#define IP_UNICAST_IF			50
+ 
+ /* To select the IP level.  */
+ #define SOL_IP	0
diff --git a/SOURCES/glibc-rh1684874-2.patch b/SOURCES/glibc-rh1684874-2.patch
new file mode 100644
index 0000000..7264d5b
--- /dev/null
+++ b/SOURCES/glibc-rh1684874-2.patch
@@ -0,0 +1,49 @@
+commit 76e5216e317f39da2bc5bf905721cd9554ee6d09
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Mon Jun 23 15:48:42 2014 +0000
+
+    Update headers for Linux 3.15.
+    
+    This patch updates glibc headers for changes / new definitions in
+    Linux 3.15.  In the course of my review I noticed that
+    IPV6_PMTUDISC_INTERFACE was absent from glibc despite the inclusion of
+    IP_PMTUDISC_INTERFACE; I added it along with IP_PMTUDISC_OMIT and
+    IPV6_PMTUDISC_OMIT.  I did not add FALLOC_FL_NO_HIDE_STALE given the
+    kernel header comment that it is reserved.
+    
+    Tested x86_64.
+    
+            * sysdeps/unix/sysv/linux/bits/fcntl-linux.h [__USE_GNU]
+            (FALLOC_FL_COLLAPSE_RANGE): New macro.
+            [__USE_GNU] (FALLOC_FL_ZERO_RANGE): Likewise.
+            * sysdeps/unix/sysv/linux/bits/in.h (IP_PMTUDISC_OMIT): Likewise.
+            (IPV6_PMTUDISC_INTERFACE): Likewise.
+            (IPV6_PMTUDISC_OMIT): Likewise.
+
+Only the sysdeps/unix/sysv/linux/bits/in.h part is backported in this
+patch.  The sysdeps/unix/sysv/linux/bits/fcntl-linux.h part was
+completely superseded by glibc-rh1476120.patch, which uses
+<linux/falloc.h> in favor of duplicated constants.
+
+diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
+index ac07d17d0e9dc9c9..23046d3b5a6b0d91 100644
+--- a/sysdeps/unix/sysv/linux/bits/in.h
++++ b/sysdeps/unix/sysv/linux/bits/in.h
+@@ -109,6 +109,8 @@
+    Also incoming ICMP frag_needed notifications will be ignored on
+    this socket to prevent accepting spoofed ones.  */
+ #define IP_PMTUDISC_INTERFACE           4
++/* Like IP_PMTUDISC_INTERFACE but allow packets to be fragmented.  */
++#define IP_PMTUDISC_OMIT		5
+ 
+ #define IP_MULTICAST_IF			32
+ #define IP_MULTICAST_TTL 		33
+@@ -224,6 +226,8 @@ struct in_pktinfo
+ #define IPV6_PMTUDISC_WANT	1	/* Use per route hints.  */
+ #define IPV6_PMTUDISC_DO	2	/* Always DF.  */
+ #define IPV6_PMTUDISC_PROBE	3	/* Ignore dst pmtu.  */
++#define IPV6_PMTUDISC_INTERFACE	4	/* See IP_PMTUDISC_INTERFACE.  */
++#define IPV6_PMTUDISC_OMIT	5	/* See IP_PMTUDISC_OMIT.  */
+ 
+ /* Socket level values for IPv6.  */
+ #define SOL_IPV6        41
diff --git a/SOURCES/glibc-rh1693152-1.patch b/SOURCES/glibc-rh1693152-1.patch
deleted file mode 100644
index 772b293..0000000
--- a/SOURCES/glibc-rh1693152-1.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-This patch replaces the era block in ja_JP with the non-escaped
-version.  It is a partial backport of commit
-a259f5d388d6195da958b2d147d17c2e2d16b857 ("Replaced unicode sequences
-in the ASCII printable range"), containing only the changes to this
-part of the localedata/locales/ja_JP file.
-
-diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
-index 54e55b1b52e90f29..594df82f05a23719 100644
---- a/localedata/locales/ja_JP
-+++ b/localedata/locales/ja_JP
-@@ -14942,15 +14942,15 @@ am_pm	"<U5348><U524D>";"<U5348><U5F8C>"
- 
- t_fmt_ampm "<U0025><U0070><U0025><U0049><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
- 
--era	"<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
--	"<U002B><U003A><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0038><U003A><U0031><U0039><U0038><U0039><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U5143><U5E74>";/
--	"<U002B><U003A><U0032><U003A><U0031><U0039><U0032><U0037><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0037><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
--	"<U002B><U003A><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0035><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U5143><U5E74>";/
--	"<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0034><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
--	"<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0033><U0030><U003A><U0031><U0039><U0031><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U5143><U5E74>";/
--	"<U002B><U003A><U0036><U003A><U0031><U0038><U0037><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0032><U0039><U003A><U660E><U6CBB><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
--	"<U002B><U003A><U0031><U003A><U0030><U0030><U0030><U0031><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0038><U0037><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U897F><U66A6><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
--	"<U002B><U003A><U0031><U003A><U002D><U0030><U0030><U0030><U0031><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U002D><U002A><U003A><U7D00><U5143><U524D><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>"
-+era	"+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
-+	"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
-+	"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
-+	"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
-+	"+:2:1913//01//01:1926//12//24:<U5927><U6B63>:%EC%Ey<U5E74>";/
-+	"+:2:1912//07//30:1912//12//31:<U5927><U6B63>:%EC<U5143><U5E74>";/
-+	"+:6:1873//01//01:1912//07//29:<U660E><U6CBB>:%EC%Ey<U5E74>";/
-+	"+:1:0001//01//01:1872//12//31:<U897F><U66A6>:%EC%Ey<U5E74>";/
-+	"+:1:-0001//12//31:-*:<U7D00><U5143><U524D>:%EC%Ey<U5E74>"
- 
- era_d_fmt	"<U0025><U0045><U0059><U0025><U006d><U6708><U0025><U0064><U65E5>"
- 
diff --git a/SOURCES/glibc-rh1693152-2.patch b/SOURCES/glibc-rh1693152-2.patch
deleted file mode 100644
index f9cbc16..0000000
--- a/SOURCES/glibc-rh1693152-2.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-Patch by Hanataka Shinya <hanataka.shinya@gmail.com> from
-<https://sourceware.org/bugzilla/show_bug.cgi?id=24405>.  Confirmed by TAMUKI
-Shoichi's patch in
-<https://sourceware.org/ml/libc-alpha/2019-04/msg00005.html>.
-
-The official announcement by the Japanese Prime Minister in
-<https://www.kantei.go.jp/jp/tyoukanpress/201904/1_a.html> uses U+4EE4 U+548C
-as well.
-
-diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
-index 594df82f05a23719..40cb5795fea730a5 100644
---- a/localedata/locales/ja_JP
-+++ b/localedata/locales/ja_JP
-@@ -14942,7 +14942,9 @@ am_pm	"<U5348><U524D>";"<U5348><U5F8C>"
- 
- t_fmt_ampm "<U0025><U0070><U0025><U0049><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
- 
--era	"+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
-+era	"+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
-+	"+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
-+	"+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
- 	"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
- 	"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
- 	"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
diff --git a/SOURCES/glibc-rh1705899-1.patch b/SOURCES/glibc-rh1705899-1.patch
deleted file mode 100644
index 9955c76..0000000
--- a/SOURCES/glibc-rh1705899-1.patch
+++ /dev/null
@@ -1,466 +0,0 @@
-commit 2afece36f6006844e87d7cb2fcb1ad8b220b2623
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Wed May 16 17:00:35 2018 +0200
-
-    support: Add TEST_COMPARE_BLOB, support_quote_blob
-    
-    The declaration of support_test_compare_blob uses unsigned long int,
-    to avoid including <stddef.h>.
-    
-    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
-
-(Adjusted for minor conflict in support/Makefile.)
-
-diff --git a/support/Makefile b/support/Makefile
-index 1bda81e55e519a57..fb9f4291d72156df 100644
---- a/support/Makefile
-+++ b/support/Makefile
-@@ -52,9 +52,11 @@ libsupport-routines = \
-   support_format_hostent \
-   support_format_netent \
-   support_isolate_in_subprocess \
-+  support_quote_blob \
-   support_record_failure \
-   support_run_diff \
-   support_shared_allocate \
-+  support_test_compare_blob \
-   support_test_compare_failure \
-   support_write_file_string \
-   support_test_main \
-@@ -150,8 +152,10 @@ tests = \
-   tst-support-namespace \
-   tst-support_capture_subprocess \
-   tst-support_format_dns_packet \
-+  tst-support_quote_blob \
-   tst-support_record_failure \
-   tst-test_compare \
-+  tst-test_compare_blob \
-   tst-xreadlink \
- 
- ifeq ($(run-built-tests),yes)
-diff --git a/support/check.h b/support/check.h
-index 2192f38941af2515..b3a4645e9255e90d 100644
---- a/support/check.h
-+++ b/support/check.h
-@@ -64,6 +64,8 @@ __BEGIN_DECLS
-         (1, __FILE__, __LINE__, #expr);                         \
-   })
- 
-+
-+
- int support_print_failure_impl (const char *file, int line,
-                                 const char *format, ...)
-   __attribute__ ((nonnull (1), format (printf, 3, 4)));
-@@ -141,6 +143,26 @@ void support_test_compare_failure (const char *file, int line,
-                                    int right_size);
- 
- 
-+/* Compare [LEFT, LEFT + LEFT_LENGTH) with [RIGHT, RIGHT +
-+   RIGHT_LENGTH) and report a test failure if the arrays are
-+   different.  LEFT_LENGTH and RIGHT_LENGTH are measured in bytes.  If
-+   the length is null, the corresponding pointer is ignored (i.e., it
-+   can be NULL).  The blobs should be reasonably short because on
-+   mismatch, both are printed.  */
-+#define TEST_COMPARE_BLOB(left, left_length, right, right_length)       \
-+  (support_test_compare_blob (left, left_length, right, right_length,   \
-+                              __FILE__, __LINE__,                       \
-+                              #left, #left_length, #right, #right_length))
-+
-+void support_test_compare_blob (const void *left,
-+                                unsigned long int left_length,
-+                                const void *right,
-+                                unsigned long int right_length,
-+                                const char *file, int line,
-+                                const char *left_exp, const char *left_len_exp,
-+                                const char *right_exp,
-+                                const char *right_len_exp);
-+
- /* Internal function called by the test driver.  */
- int support_report_failure (int status)
-   __attribute__ ((weak, warn_unused_result));
-diff --git a/support/support.h b/support/support.h
-index bc5827ed87d0d96c..b61fe0735c9204de 100644
---- a/support/support.h
-+++ b/support/support.h
-@@ -59,6 +59,12 @@ void support_shared_free (void *);
-    process on error.  */
- void support_write_file_string (const char *path, const char *contents);
- 
-+/* Quote the contents of the byte array starting at BLOB, of LENGTH
-+   bytes, in such a way that the result string can be included in a C
-+   literal (in single/double quotes, without putting the quotes into
-+   the result).  */
-+char *support_quote_blob (const void *blob, size_t length);
-+
- /* Error-checking wrapper functions which terminate the process on
-    error.  */
- 
-diff --git a/support/support_quote_blob.c b/support/support_quote_blob.c
-new file mode 100644
-index 0000000000000000..d6a678d8d69160a8
---- /dev/null
-+++ b/support/support_quote_blob.c
-@@ -0,0 +1,83 @@
-+/* Quote a blob so that it can be used in C literals.
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include <support/support.h>
-+#include <support/xmemstream.h>
-+
-+char *
-+support_quote_blob (const void *blob, size_t length)
-+{
-+  struct xmemstream out;
-+  xopen_memstream (&out);
-+
-+  const unsigned char *p = blob;
-+  for (size_t i = 0; i < length; ++i)
-+    {
-+      unsigned char ch = p[i];
-+
-+      /* Use C backslash escapes for those control characters for
-+         which they are defined.  */
-+      switch (ch)
-+        {
-+          case '\a':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked ('a', out.out);
-+            break;
-+          case '\b':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked ('b', out.out);
-+            break;
-+          case '\f':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked ('f', out.out);
-+            break;
-+          case '\n':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked ('n', out.out);
-+            break;
-+          case '\r':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked ('r', out.out);
-+            break;
-+          case '\t':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked ('t', out.out);
-+            break;
-+          case '\v':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked ('v', out.out);
-+            break;
-+          case '\\':
-+          case '\'':
-+          case '\"':
-+            putc_unlocked ('\\', out.out);
-+            putc_unlocked (ch, out.out);
-+            break;
-+        default:
-+          if (ch < ' ' || ch > '~')
-+            /* Use octal sequences because they are fixed width,
-+               unlike hexadecimal sequences.  */
-+            fprintf (out.out, "\\%03o", ch);
-+          else
-+            putc_unlocked (ch, out.out);
-+        }
-+    }
-+
-+  xfclose_memstream (&out);
-+  return out.buffer;
-+}
-diff --git a/support/support_test_compare_blob.c b/support/support_test_compare_blob.c
-new file mode 100644
-index 0000000000000000..c5e63d1b9327c9fe
---- /dev/null
-+++ b/support/support_test_compare_blob.c
-@@ -0,0 +1,76 @@
-+/* Check two binary blobs for equality.
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <support/check.h>
-+#include <support/support.h>
-+#include <support/xmemstream.h>
-+
-+static void
-+report_length (const char *what, unsigned long int length, const char *expr)
-+{
-+  printf ("  %s %lu bytes (from %s)\n", what, length, expr);
-+}
-+
-+static void
-+report_blob (const char *what, const unsigned char *blob,
-+             unsigned long int length, const char *expr)
-+{
-+  if (length > 0)
-+    {
-+      printf ("  %s (evaluated from %s):\n", what, expr);
-+      char *quoted = support_quote_blob (blob, length);
-+      printf ("      \"%s\"\n", quoted);
-+      free (quoted);
-+
-+      fputs ("     ", stdout);
-+      for (unsigned long i = 0; i < length; ++i)
-+        printf (" %02X", blob[i]);
-+      putc ('\n', stdout);
-+    }
-+}
-+
-+void
-+support_test_compare_blob (const void *left, unsigned long int left_length,
-+                           const void *right, unsigned long int right_length,
-+                           const char *file, int line,
-+                           const char *left_expr, const char *left_len_expr,
-+                           const char *right_expr, const char *right_len_expr)
-+{
-+  /* No differences are possible if both lengths are null.  */
-+  if (left_length == 0 && right_length == 0)
-+    return;
-+
-+  if (left_length != right_length || left == NULL || right == NULL
-+      || memcmp (left, right, left_length) != 0)
-+    {
-+      support_record_failure ();
-+      printf ("%s:%d: error: blob comparison failed\n", file, line);
-+      if (left_length == right_length)
-+        printf ("  blob length: %lu bytes\n", left_length);
-+      else
-+        {
-+          report_length ("left length: ", left_length, left_len_expr);
-+          report_length ("right length:", right_length, right_len_expr);
-+        }
-+      report_blob ("left", left, left_length, left_expr);
-+      report_blob ("right", right, right_length, right_expr);
-+    }
-+}
-diff --git a/support/tst-support_quote_blob.c b/support/tst-support_quote_blob.c
-new file mode 100644
-index 0000000000000000..5467a190a6e0725c
---- /dev/null
-+++ b/support/tst-support_quote_blob.c
-@@ -0,0 +1,61 @@
-+/* Test the support_quote_blob function.
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include <support/check.h>
-+#include <support/support.h>
-+#include <string.h>
-+#include <stdlib.h>
-+
-+static int
-+do_test (void)
-+{
-+  /* Check handling of the empty blob, both with and without trailing
-+     NUL byte.  */
-+  char *p = support_quote_blob ("", 0);
-+  TEST_COMPARE (strlen (p), 0);
-+  free (p);
-+  p = support_quote_blob ("X", 0);
-+  TEST_COMPARE (strlen (p), 0);
-+  free (p);
-+
-+  /* Check escaping of backslash-escaped characters, and lack of
-+     escaping for other shell meta-characters.  */
-+  p = support_quote_blob ("$()*?`@[]{}~\'\"X", 14);
-+  TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\""), 0);
-+  free (p);
-+
-+  /* Check lack of escaping for letters and digits.  */
-+#define LETTERS_AND_DIGTS                       \
-+  "abcdefghijklmnopqrstuvwxyz"                  \
-+  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"                  \
-+  "0123456789"
-+  p = support_quote_blob (LETTERS_AND_DIGTS "@", 2 * 26 + 10);
-+  TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS), 0);
-+  free (p);
-+
-+  /* Check escaping of control characters and other non-printable
-+     characters.  */
-+  p = support_quote_blob ("\r\n\t\a\b\f\v\1\177\200\377\0@", 14);
-+  TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
-+                        "\\177\\200\\377\\000@\\000"), 0);
-+  free (p);
-+
-+  return 0;
-+}
-+
-+#include <support/test-driver.c>
-diff --git a/support/tst-test_compare_blob.c b/support/tst-test_compare_blob.c
-new file mode 100644
-index 0000000000000000..aa8643e18227da85
---- /dev/null
-+++ b/support/tst-test_compare_blob.c
-@@ -0,0 +1,125 @@
-+/* Basic test for the TEST_COMPARE_BLOB macro.
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include <string.h>
-+#include <support/check.h>
-+#include <support/capture_subprocess.h>
-+
-+static void
-+subprocess (void *closure)
-+{
-+  /* These tests should fail.  They were chosen to cover differences
-+     in length (with the same contents), single-bit mismatches, and
-+     mismatching null pointers.  */
-+  TEST_COMPARE_BLOB ("", 0, "", 1);    /* Line 29.  */
-+  TEST_COMPARE_BLOB ("X", 1, "", 1);   /* Line 30.  */
-+  TEST_COMPARE_BLOB ("abcd", 3, "abcd", 4); /* Line 31.  */
-+  TEST_COMPARE_BLOB ("abcd", 4, "abcD", 4); /* Line 32.  */
-+  TEST_COMPARE_BLOB ("abcd", 4, NULL, 0); /* Line 33.  */
-+  TEST_COMPARE_BLOB (NULL, 0, "abcd", 4); /* Line 34.  */
-+}
-+
-+/* Same contents, different addresses.  */
-+char buffer_abc_1[] = "abc";
-+char buffer_abc_2[] = "abc";
-+
-+static int
-+do_test (void)
-+{
-+  /* This should succeed.  Even if the pointers and array contents are
-+     different, zero-length inputs are not different.  */
-+  TEST_COMPARE_BLOB ("", 0, "", 0);
-+  TEST_COMPARE_BLOB ("", 0, buffer_abc_1, 0);
-+  TEST_COMPARE_BLOB (buffer_abc_1, 0, "", 0);
-+  TEST_COMPARE_BLOB (NULL, 0, "", 0);
-+  TEST_COMPARE_BLOB ("", 0, NULL, 0);
-+  TEST_COMPARE_BLOB (NULL, 0, NULL, 0);
-+
-+  /* Check equality of blobs containing a single NUL byte.  */
-+  TEST_COMPARE_BLOB ("", 1, "", 1);
-+  TEST_COMPARE_BLOB ("", 1, &buffer_abc_1[3], 1);
-+
-+  /* Check equality of blobs of varying lengths.  */
-+  for (size_t i = 0; i <= sizeof (buffer_abc_1); ++i)
-+    TEST_COMPARE_BLOB (buffer_abc_1, i, buffer_abc_2, i);
-+
-+  struct support_capture_subprocess proc = support_capture_subprocess
-+    (&subprocess, NULL);
-+
-+  /* Discard the reported error.  */
-+  support_record_failure_reset ();
-+
-+  puts ("info: *** subprocess output starts ***");
-+  fputs (proc.out.buffer, stdout);
-+  puts ("info: *** subprocess output ends ***");
-+
-+  TEST_VERIFY
-+    (strcmp (proc.out.buffer,
-+"tst-test_compare_blob.c:29: error: blob comparison failed\n"
-+"  left length:  0 bytes (from 0)\n"
-+"  right length: 1 bytes (from 1)\n"
-+"  right (evaluated from \"\"):\n"
-+"      \"\\000\"\n"
-+"      00\n"
-+"tst-test_compare_blob.c:30: error: blob comparison failed\n"
-+"  blob length: 1 bytes\n"
-+"  left (evaluated from \"X\"):\n"
-+"      \"X\"\n"
-+"      58\n"
-+"  right (evaluated from \"\"):\n"
-+"      \"\\000\"\n"
-+"      00\n"
-+"tst-test_compare_blob.c:31: error: blob comparison failed\n"
-+"  left length:  3 bytes (from 3)\n"
-+"  right length: 4 bytes (from 4)\n"
-+"  left (evaluated from \"abcd\"):\n"
-+"      \"abc\"\n"
-+"      61 62 63\n"
-+"  right (evaluated from \"abcd\"):\n"
-+"      \"abcd\"\n"
-+"      61 62 63 64\n"
-+"tst-test_compare_blob.c:32: error: blob comparison failed\n"
-+"  blob length: 4 bytes\n"
-+"  left (evaluated from \"abcd\"):\n"
-+"      \"abcd\"\n"
-+"      61 62 63 64\n"
-+"  right (evaluated from \"abcD\"):\n"
-+"      \"abcD\"\n"
-+"      61 62 63 44\n"
-+"tst-test_compare_blob.c:33: error: blob comparison failed\n"
-+"  left length:  4 bytes (from 4)\n"
-+"  right length: 0 bytes (from 0)\n"
-+"  left (evaluated from \"abcd\"):\n"
-+"      \"abcd\"\n"
-+"      61 62 63 64\n"
-+"tst-test_compare_blob.c:34: error: blob comparison failed\n"
-+"  left length:  0 bytes (from 0)\n"
-+"  right length: 4 bytes (from 4)\n"
-+"  right (evaluated from \"abcd\"):\n"
-+"      \"abcd\"\n"
-+"      61 62 63 64\n"
-+             ) == 0);
-+
-+  /* Check that there is no output on standard error.  */
-+  support_capture_subprocess_check (&proc, "TEST_COMPARE_BLOB",
-+                                    0, sc_allow_stdout);
-+
-+  return 0;
-+}
-+
-+#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1705899-2.patch b/SOURCES/glibc-rh1705899-2.patch
deleted file mode 100644
index 5e0e669..0000000
--- a/SOURCES/glibc-rh1705899-2.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-commit 5c0202af4b3d588c04bcec7baf05706b21cd7416
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Tue Jun 26 12:05:21 2018 +0200
-
-    support: Add TEST_NO_SETVBUF
-    
-    This is sometimes needed for testing stdio streams, where the
-    setvbuf call in the test driver could interfere with the test.
-
-diff --git a/support/support_test_main.c b/support/support_test_main.c
-index 396385729b6809ad..23429779aca85613 100644
---- a/support/support_test_main.c
-+++ b/support/support_test_main.c
-@@ -270,7 +270,8 @@ support_test_main (int argc, char **argv, const struct test_config *config)
-     timeout =  DEFAULT_TIMEOUT;
- 
-   /* Make sure we see all message, even those on stdout.  */
--  setvbuf (stdout, NULL, _IONBF, 0);
-+  if (!config->no_setvbuf)
-+    setvbuf (stdout, NULL, _IONBF, 0);
- 
-   /* Make sure temporary files are deleted.  */
-   if (support_delete_temp_files != NULL)
-diff --git a/support/test-driver.c b/support/test-driver.c
-index 09c8783e4f54d809..9798f16227b9d467 100644
---- a/support/test-driver.c
-+++ b/support/test-driver.c
-@@ -140,6 +140,10 @@ main (int argc, char **argv)
-   test_config.no_mallopt = 1;
- #endif
- 
-+#ifdef TEST_NO_SETVBUF
-+  test_config.no_setvbuf = 1;
-+#endif
-+
- #ifdef TIMEOUT
-   test_config.timeout = TIMEOUT;
- #endif
-diff --git a/support/test-driver.h b/support/test-driver.h
-index 1708d68d608ee4a4..549179b254946390 100644
---- a/support/test-driver.h
-+++ b/support/test-driver.h
-@@ -35,6 +35,7 @@ struct test_config
-   int expected_status;   /* Expected exit status.  */
-   int expected_signal;   /* If non-zero, expect termination by signal.  */
-   char no_mallopt;       /* Boolean flag to disable mallopt.  */
-+  char no_setvbuf;       /* Boolean flag to disable setvbuf.  */
-   const char *optstring; /* Short command line options.  */
- };
- 
diff --git a/SOURCES/glibc-rh1705899-3.patch b/SOURCES/glibc-rh1705899-3.patch
deleted file mode 100644
index 3e3fa24..0000000
--- a/SOURCES/glibc-rh1705899-3.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-commit 0262507918cfad7223bf81b8f162b7adc7a2af01
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Fri Jun 1 10:43:06 2018 +0200
-
-    libio: Avoid _allocate_buffer, _free_buffer function pointers [BZ #23236]
-
-    These unmangled function pointers reside on the heap and could
-    be targeted by exploit writers, effectively bypassing libio vtable
-    validation.  Instead, we ignore these pointers and always call
-    malloc or free.
-
-    In theory, this is a backwards-incompatible change, but using the
-    global heap instead of the user-supplied callback functions should
-    have little application impact.  (The old libstdc++ implementation
-    exposed this functionality via a public, undocumented constructor
-    in its strstreambuf class.)
-
-    (cherry picked from commit 4e8a6346cd3da2d88bbad745a1769260d36f2783)
-
-Backported from the upstream release/2.27/master branch.
-
-diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c
-index a8ca32bad57b4d13..113354749ccf8d9a 100644
---- a/debug/vasprintf_chk.c
-+++ b/debug/vasprintf_chk.c
-@@ -55,8 +55,8 @@ __vasprintf_chk (char **result_ptr, int flags, const char *format,
-   _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
-   _IO_str_init_static_internal (&sf, string, init_string_size, string);
-   sf._sbf._f._flags &= ~_IO_USER_BUF;
--  sf._s._allocate_buffer = (_IO_alloc_type) malloc;
--  sf._s._free_buffer = (_IO_free_type) free;
-+  sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
-+  sf._s._free_buffer_unused = (_IO_free_type) free;
- 
-   /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
-      can only come from read-only format strings.  */
-diff --git a/libio/memstream.c b/libio/memstream.c
-index e18a7756b297c9f4..9a51331e525c3468 100644
---- a/libio/memstream.c
-+++ b/libio/memstream.c
-@@ -87,8 +87,8 @@ open_memstream (char **bufloc, _IO_size_t *sizeloc)
-   _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps;
-   _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
-   new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
--  new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
--  new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
-+  new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
-+  new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
- 
-   new_f->fp.bufloc = bufloc;
-   new_f->fp.sizeloc = sizeloc;
-diff --git a/libio/strfile.h b/libio/strfile.h
-index 4ea7548f9fa92638..9cd8e7c466616b52 100644
---- a/libio/strfile.h
-+++ b/libio/strfile.h
-@@ -34,8 +34,11 @@ typedef void (*_IO_free_type) (void*);
- 
- struct _IO_str_fields
- {
--  _IO_alloc_type _allocate_buffer;
--  _IO_free_type _free_buffer;
-+  /* These members are preserved for ABI compatibility.  The glibc
-+     implementation always calls malloc/free for user buffers if
-+     _IO_USER_BUF or _IO_FLAGS2_USER_WBUF are not set.  */
-+  _IO_alloc_type _allocate_buffer_unused;
-+  _IO_free_type _free_buffer_unused;
- };
- 
- /* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type,
-@@ -55,10 +58,6 @@ typedef struct _IO_strfile_
-   struct _IO_str_fields _s;
- } _IO_strfile;
- 
--/* dynamic: set when the array object is allocated (or reallocated)  as
--   necessary to hold a character sequence that can change in length. */
--#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0)
--
- /* frozen: set when the program has requested that the array object not
-    be altered, reallocated, or freed. */
- #define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF)
-diff --git a/libio/strops.c b/libio/strops.c
-index fdd113a60811e593..129a0f6aeca818fd 100644
---- a/libio/strops.c
-+++ b/libio/strops.c
-@@ -61,7 +61,7 @@ _IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size,
-       fp->_IO_read_end = end;
-     }
-   /* A null _allocate_buffer function flags the strfile as being static. */
--  sf->_s._allocate_buffer = (_IO_alloc_type) 0;
-+  sf->_s._allocate_buffer_unused = (_IO_alloc_type) 0;
- }
- 
- void
-@@ -103,8 +103,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
- 	  _IO_size_t new_size = 2 * old_blen + 100;
- 	  if (new_size < old_blen)
- 	    return EOF;
--	  new_buf
--	    = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
-+	  new_buf = malloc (new_size);
- 	  if (new_buf == NULL)
- 	    {
- 	      /*	  __ferror(fp) = 1; */
-@@ -113,7 +112,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
- 	  if (old_buf)
- 	    {
- 	      memcpy (new_buf, old_buf, old_blen);
--	      (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
-+	      free (old_buf);
- 	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
- 	      fp->_IO_buf_base = NULL;
- 	    }
-@@ -182,15 +181,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
- 
-   _IO_size_t newsize = offset + 100;
-   char *oldbuf = fp->_IO_buf_base;
--  char *newbuf
--    = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize);
-+  char *newbuf = malloc (newsize);
-   if (newbuf == NULL)
-     return 1;
- 
-   if (oldbuf != NULL)
-     {
-       memcpy (newbuf, oldbuf, _IO_blen (fp));
--      (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
-+      free (oldbuf);
-       /* Make sure _IO_setb won't try to delete
- 	 _IO_buf_base. */
-       fp->_IO_buf_base = NULL;
-@@ -317,7 +315,7 @@ void
- _IO_str_finish (_IO_FILE *fp, int dummy)
- {
-   if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
--    (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
-+    free (fp->_IO_buf_base);
-   fp->_IO_buf_base = NULL;
- 
-   _IO_default_finish (fp, 0);
-diff --git a/libio/vasprintf.c b/libio/vasprintf.c
-index 282c86fff0a7ae0e..867ef4fe4ca4ec56 100644
---- a/libio/vasprintf.c
-+++ b/libio/vasprintf.c
-@@ -54,8 +54,8 @@ _IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args)
-   _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
-   _IO_str_init_static_internal (&sf, string, init_string_size, string);
-   sf._sbf._f._flags &= ~_IO_USER_BUF;
--  sf._s._allocate_buffer = (_IO_alloc_type) malloc;
--  sf._s._free_buffer = (_IO_free_type) free;
-+  sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
-+  sf._s._free_buffer_unused = (_IO_free_type) free;
-   ret = _IO_vfprintf (&sf._sbf._f, format, args);
-   if (ret < 0)
-     {
-diff --git a/libio/wmemstream.c b/libio/wmemstream.c
-index bd6d1798b1685fe9..3a9a681c80a321a7 100644
---- a/libio/wmemstream.c
-+++ b/libio/wmemstream.c
-@@ -90,8 +90,8 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc)
-   _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
- 			_IO_BUFSIZ / sizeof (wchar_t), buf);
-   new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF;
--  new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
--  new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
-+  new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
-+  new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
- 
-   new_f->fp.bufloc = bufloc;
-   new_f->fp.sizeloc = sizeloc;
-diff --git a/libio/wstrops.c b/libio/wstrops.c
-index 7a9a33ab8763b8ff..a31d0e23341b2aad 100644
---- a/libio/wstrops.c
-+++ b/libio/wstrops.c
-@@ -63,7 +63,7 @@ _IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size,
-       fp->_wide_data->_IO_read_end = end;
-     }
-   /* A null _allocate_buffer function flags the strfile as being static. */
--  (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
-+  (((_IO_strfile *) fp)->_s._allocate_buffer_unused) = (_IO_alloc_type)0;
- }
- 
- _IO_wint_t
-@@ -95,9 +95,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
- 	      || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
- 	    return EOF;
- 
--	  new_buf
--	    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
--									* sizeof (wchar_t));
-+	  new_buf = malloc (new_size * sizeof (wchar_t));
- 	  if (new_buf == NULL)
- 	    {
- 	      /*	  __ferror(fp) = 1; */
-@@ -106,7 +104,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
- 	  if (old_buf)
- 	    {
- 	      __wmemcpy (new_buf, old_buf, old_wblen);
--	      (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
-+	      free (old_buf);
- 	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
- 	      fp->_wide_data->_IO_buf_base = NULL;
- 	    }
-@@ -186,16 +184,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
-     return 1;
- 
-   wchar_t *oldbuf = wd->_IO_buf_base;
--  wchar_t *newbuf
--    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
--								* sizeof (wchar_t));
-+  wchar_t *newbuf = malloc (newsize * sizeof (wchar_t));
-   if (newbuf == NULL)
-     return 1;
- 
-   if (oldbuf != NULL)
-     {
-       __wmemcpy (newbuf, oldbuf, _IO_wblen (fp));
--      (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
-+      free (oldbuf);
-       /* Make sure _IO_setb won't try to delete
- 	 _IO_buf_base. */
-       wd->_IO_buf_base = NULL;
-@@ -326,7 +322,7 @@ void
- _IO_wstr_finish (_IO_FILE *fp, int dummy)
- {
-   if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
--    (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base);
-+    free (fp->_wide_data->_IO_buf_base);
-   fp->_wide_data->_IO_buf_base = NULL;
- 
-   _IO_wdefault_finish (fp, 0);
diff --git a/SOURCES/glibc-rh1705899-4.patch b/SOURCES/glibc-rh1705899-4.patch
deleted file mode 100644
index 80c7606..0000000
--- a/SOURCES/glibc-rh1705899-4.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-commit 3bb748257405e94e13de76573a4e9da1cfd961d0
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Tue Jul 3 15:54:49 2018 +0200
-
-    libio: Disable vtable validation in case of interposition [BZ #23313]
-
-    (cherry picked from commit c402355dfa7807b8e0adb27c009135a7e2b9f1b0)
-
-Backported from the upstream release/2.27/master branch.
-
-diff --git a/libio/vtables.c b/libio/vtables.c
-index e364ea03edbfa75b..d6478e4bab9050ce 100644
---- a/libio/vtables.c
-+++ b/libio/vtables.c
-@@ -68,3 +68,19 @@ _IO_vtable_check (void)
- 
-   __libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n");
- }
-+
-+/* Some variants of libstdc++ interpose _IO_2_1_stdin_ etc. and
-+   install their own vtables directly, without calling _IO_init or
-+   other functions.  Detect this by looking at the vtables values
-+   during startup, and disable vtable validation in this case.  */
-+#ifdef SHARED
-+__attribute__ ((constructor))
-+static void
-+check_stdfiles_vtables (void)
-+{
-+  if (_IO_2_1_stdin_.vtable != &_IO_file_jumps
-+      || _IO_2_1_stdout_.vtable != &_IO_file_jumps
-+      || _IO_2_1_stderr_.vtable != &_IO_file_jumps)
-+    IO_set_accept_foreign_vtables (&_IO_vtable_check);
-+}
-+#endif
diff --git a/SOURCES/glibc-rh1705899-5.patch b/SOURCES/glibc-rh1705899-5.patch
deleted file mode 100644
index 1500ba3..0000000
--- a/SOURCES/glibc-rh1705899-5.patch
+++ /dev/null
@@ -1,624 +0,0 @@
-commit 44927211651adde42bbd431ef5ebe568186125e5
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Tue Jul 3 17:57:14 2018 +0200
-
-    libio: Add tst-vtables, tst-vtables-interposed
-
-    (cherry picked from commit 29055464a03c72762969a2e8734d0d05d4d70e58)
-
-    Some adjustments were needed for a tricky multi-inclusion issue related
-    to libioP.h.
-
-Backported from the upsteam release/2.27/master branch, adjusted for
-lack of tests-internal support downstream.
-
-diff --git a/libio/Makefile b/libio/Makefile
-index 0cef96141209fe99..1e923da42e45c492 100644
---- a/libio/Makefile
-+++ b/libio/Makefile
-@@ -61,7 +61,9 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
- 	bug-memstream1 bug-wmemstream1 \
- 	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
- 	tst-fwrite-error tst-ftell-active-handler \
--	tst-ftell-append
-+	tst-ftell-append \
-+	tst-vtables tst-vtables-interposed
-+
- ifeq (yes,$(build-shared))
- # Add test-fopenloc only if shared library is enabled since it depends on
- # shared localedata objects.
-diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c
-new file mode 100644
-index 0000000000000000..dc8d89c195b95b8d
---- /dev/null
-+++ b/libio/tst-vtables-common.c
-@@ -0,0 +1,511 @@
-+/* Test for libio vtables and their validation.  Common code.
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+/* This test provides some coverage for how various stdio functions
-+   use the vtables in FILE * objects.  The focus is mostly on which
-+   functions call which methods, not so much on validating data
-+   processing.  An initial series of tests check that custom vtables
-+   do not work without activation through _IO_init.
-+
-+   Note: libio vtables are deprecated feature.  Do not use this test
-+   as a documentation source for writing custom vtables.  See
-+   fopencookie for a different way of creating custom stdio
-+   streams.  */
-+
-+#include <stdbool.h>
-+#include <string.h>
-+#include <support/capture_subprocess.h>
-+#include <support/check.h>
-+#include <support/namespace.h>
-+#include <support/support.h>
-+#include <support/test-driver.h>
-+#include <support/xunistd.h>
-+
-+/* Data shared between the test subprocess and the test driver in the
-+   parent.  Note that *shared is reset at the start of the check_call
-+   function.  */
-+struct shared
-+{
-+  /* Expected file pointer for method calls.  */
-+  FILE *fp;
-+
-+  /* If true, assume that a call to _IO_init is needed to enable
-+     custom vtables.  */
-+  bool initially_disabled;
-+
-+  /* Requested return value for the methods which have one.  */
-+  int return_value;
-+
-+  /* A value (usually a character) recorded by some of the methods
-+     below.  */
-+  int value;
-+
-+  /* Likewise, for some data.  */
-+  char buffer[16];
-+  size_t buffer_length;
-+
-+  /* Total number of method calls.  */
-+  unsigned int calls;
-+
-+  /* Individual method call counts.  */
-+  unsigned int calls_finish;
-+  unsigned int calls_overflow;
-+  unsigned int calls_underflow;
-+  unsigned int calls_uflow;
-+  unsigned int calls_pbackfail;
-+  unsigned int calls_xsputn;
-+  unsigned int calls_xsgetn;
-+  unsigned int calls_seekoff;
-+  unsigned int calls_seekpos;
-+  unsigned int calls_setbuf;
-+  unsigned int calls_sync;
-+  unsigned int calls_doallocate;
-+  unsigned int calls_read;
-+  unsigned int calls_write;
-+  unsigned int calls_seek;
-+  unsigned int calls_close;
-+  unsigned int calls_stat;
-+  unsigned int calls_showmanyc;
-+  unsigned int calls_imbue;
-+} *shared;
-+
-+/* Method implementations which increment the counters in *shared.  */
-+
-+static void
-+log_method (FILE *fp, const char *name)
-+{
-+  if (test_verbose > 0)
-+    printf ("info: %s (%p) called\n", name, fp);
-+}
-+
-+static void
-+method_finish (FILE *fp, int dummy)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_finish;
-+}
-+
-+static int
-+method_overflow (FILE *fp, int ch)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_overflow;
-+  shared->value = ch;
-+  return shared->return_value;
-+}
-+
-+static int
-+method_underflow (FILE *fp)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_underflow;
-+  return shared->return_value;
-+}
-+
-+static int
-+method_uflow (FILE *fp)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_uflow;
-+  return shared->return_value;
-+}
-+
-+static int
-+method_pbackfail (FILE *fp, int ch)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_pbackfail;
-+  shared->value = ch;
-+  return shared->return_value;
-+}
-+
-+static size_t
-+method_xsputn (FILE *fp, const void *data, size_t n)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_xsputn;
-+
-+  size_t to_copy = n;
-+  if (n > sizeof (shared->buffer))
-+    to_copy = sizeof (shared->buffer);
-+  memcpy (shared->buffer, data, to_copy);
-+  shared->buffer_length = to_copy;
-+  return to_copy;
-+}
-+
-+static size_t
-+method_xsgetn (FILE *fp, void *data, size_t n)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_xsgetn;
-+  return 0;
-+}
-+
-+static off64_t
-+method_seekoff (FILE *fp, off64_t offset, int dir, int mode)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_seekoff;
-+  return shared->return_value;
-+}
-+
-+static off64_t
-+method_seekpos (FILE *fp, off64_t offset, int mode)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_seekpos;
-+  return shared->return_value;
-+}
-+
-+static FILE *
-+method_setbuf (FILE *fp, char *buffer, ssize_t length)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_setbuf;
-+  return fp;
-+}
-+
-+static int
-+method_sync (FILE *fp)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_sync;
-+  return shared->return_value;
-+}
-+
-+static int
-+method_doallocate (FILE *fp)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_doallocate;
-+  return shared->return_value;
-+}
-+
-+static ssize_t
-+method_read (FILE *fp, void *data, ssize_t length)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_read;
-+  return shared->return_value;
-+}
-+
-+static ssize_t
-+method_write (FILE *fp, const void *data, ssize_t length)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_write;
-+  return shared->return_value;
-+}
-+
-+static off64_t
-+method_seek (FILE *fp, off64_t offset, int mode)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_seek;
-+  return shared->return_value;
-+}
-+
-+static int
-+method_close (FILE *fp)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_close;
-+  return shared->return_value;
-+}
-+
-+static int
-+method_stat (FILE *fp, void *buffer)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_stat;
-+  return shared->return_value;
-+}
-+
-+static int
-+method_showmanyc (FILE *fp)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_showmanyc;
-+  return shared->return_value;
-+}
-+
-+static void
-+method_imbue (FILE *fp, void *locale)
-+{
-+  log_method (fp, __func__);
-+  TEST_VERIFY (fp == shared->fp);
-+  ++shared->calls;
-+  ++shared->calls_imbue;
-+}
-+
-+/* Our custom vtable.  */
-+
-+static const struct _IO_jump_t jumps =
-+{
-+  JUMP_INIT_DUMMY,
-+  JUMP_INIT (finish, method_finish),
-+  JUMP_INIT (overflow, method_overflow),
-+  JUMP_INIT (underflow, method_underflow),
-+  JUMP_INIT (uflow, method_uflow),
-+  JUMP_INIT (pbackfail, method_pbackfail),
-+  JUMP_INIT (xsputn, method_xsputn),
-+  JUMP_INIT (xsgetn, method_xsgetn),
-+  JUMP_INIT (seekoff, method_seekoff),
-+  JUMP_INIT (seekpos, method_seekpos),
-+  JUMP_INIT (setbuf, method_setbuf),
-+  JUMP_INIT (sync, method_sync),
-+  JUMP_INIT (doallocate, method_doallocate),
-+  JUMP_INIT (read, method_read),
-+  JUMP_INIT (write, method_write),
-+  JUMP_INIT (seek, method_seek),
-+  JUMP_INIT (close, method_close),
-+  JUMP_INIT (stat, method_stat),
-+  JUMP_INIT (showmanyc, method_showmanyc),
-+  JUMP_INIT (imbue, method_imbue)
-+};
-+
-+/* Our file implementation.  */
-+
-+struct my_file
-+{
-+  FILE f;
-+  const struct _IO_jump_t *vtable;
-+};
-+
-+struct my_file
-+my_file_create (void)
-+{
-+  return (struct my_file)
-+    {
-+      /* Disable locking, so that we do not have to set up a lock
-+         pointer.  */
-+      .f._flags =  _IO_USER_LOCK,
-+
-+      /* Copy the offset from the an initialized handle, instead of
-+         figuring it out from scratch.  */
-+      .f._vtable_offset = stdin->_vtable_offset,
-+
-+      .vtable = &jumps,
-+    };
-+}
-+
-+/* Initial tests which do not enable vtable compatibility.  */
-+
-+/* Inhibit GCC optimization of fprintf.  */
-+typedef int (*fprintf_type) (FILE *, const char *, ...);
-+static const volatile fprintf_type fprintf_ptr = &fprintf;
-+
-+static void
-+without_compatibility_fprintf (void *closure)
-+{
-+  /* This call should abort.  */
-+  fprintf_ptr (shared->fp, " ");
-+  _exit (1);
-+}
-+
-+static void
-+without_compatibility_fputc (void *closure)
-+{
-+  /* This call should abort.  */
-+  fputc (' ', shared->fp);
-+  _exit (1);
-+}
-+
-+static void
-+without_compatibility_fgetc (void *closure)
-+{
-+  /* This call should abort.  */
-+  fgetc (shared->fp);
-+  _exit (1);
-+}
-+
-+static void
-+without_compatibility_fflush (void *closure)
-+{
-+  /* This call should abort.  */
-+  fflush (shared->fp);
-+  _exit (1);
-+}
-+
-+/* Exit status after abnormal termination.  */
-+static int termination_status;
-+
-+static void
-+init_termination_status (void)
-+{
-+  pid_t pid = xfork ();
-+  if (pid == 0)
-+    abort ();
-+  xwaitpid (pid, &termination_status, 0);
-+
-+  TEST_VERIFY (WIFSIGNALED (termination_status));
-+  TEST_COMPARE (WTERMSIG (termination_status), SIGABRT);
-+}
-+
-+static void
-+check_for_termination (const char *name, void (*callback) (void *))
-+{
-+  struct my_file file = my_file_create ();
-+  shared->fp = &file.f;
-+  shared->return_value = -1;
-+  shared->calls = 0;
-+  struct support_capture_subprocess proc
-+    = support_capture_subprocess (callback, NULL);
-+  support_capture_subprocess_check (&proc, name, termination_status,
-+                                    sc_allow_stderr);
-+  const char *message
-+    = "Fatal error: glibc detected an invalid stdio handle\n";
-+  TEST_COMPARE_BLOB (proc.err.buffer, proc.err.length,
-+                     message, strlen (message));
-+  TEST_COMPARE (shared->calls, 0);
-+  support_capture_subprocess_free (&proc);
-+}
-+
-+/* The test with vtable validation disabled.  */
-+
-+/* This function does not have a prototype in libioP.h to prevent
-+   accidental use from within the library (which would disable vtable
-+   verification).  */
-+void _IO_init (FILE *fp, int flags);
-+
-+static void
-+with_compatibility_fprintf (void *closure)
-+{
-+  TEST_COMPARE (fprintf_ptr (shared->fp, "A%sCD", "B"), 4);
-+  TEST_COMPARE (shared->calls, 3);
-+  TEST_COMPARE (shared->calls_xsputn, 3);
-+  TEST_COMPARE_BLOB (shared->buffer, shared->buffer_length,
-+                     "CD", 2);
-+}
-+
-+static void
-+with_compatibility_fputc (void *closure)
-+{
-+  shared->return_value = '@';
-+  TEST_COMPARE (fputc ('@', shared->fp), '@');
-+  TEST_COMPARE (shared->calls, 1);
-+  TEST_COMPARE (shared->calls_overflow, 1);
-+  TEST_COMPARE (shared->value, '@');
-+}
-+
-+static void
-+with_compatibility_fgetc (void *closure)
-+{
-+  shared->return_value = 'X';
-+  TEST_COMPARE (fgetc (shared->fp), 'X');
-+  TEST_COMPARE (shared->calls, 1);
-+  TEST_COMPARE (shared->calls_uflow, 1);
-+}
-+
-+static void
-+with_compatibility_fflush (void *closure)
-+{
-+  TEST_COMPARE (fflush (shared->fp), 0);
-+  TEST_COMPARE (shared->calls, 1);
-+  TEST_COMPARE (shared->calls_sync, 1);
-+}
-+
-+/* Call CALLBACK in a subprocess, after setting up a custom file
-+   object and updating shared->fp.  */
-+static void
-+check_call (const char *name, void (*callback) (void *),
-+            bool initially_disabled)
-+{
-+  *shared = (struct shared)
-+    {
-+     .initially_disabled = initially_disabled,
-+    };
-+
-+  /* Set up a custom file object.  */
-+  struct my_file file = my_file_create ();
-+  shared->fp = &file.f;
-+  if (shared->initially_disabled)
-+    _IO_init (shared->fp, file.f._flags);
-+
-+  if (test_verbose > 0)
-+    printf ("info: calling test %s\n", name);
-+  support_isolate_in_subprocess (callback, NULL);
-+}
-+
-+/* Run the tests.  INITIALLY_DISABLED indicates whether custom vtables
-+   are disabled when the test starts.  */
-+static int
-+run_tests (bool initially_disabled)
-+{
-+  /* The test relies on fatal error messages being printed to standard
-+     error.  */
-+  setenv ("LIBC_FATAL_STDERR_", "1", 1);
-+
-+  shared = support_shared_allocate (sizeof (*shared));
-+  shared->initially_disabled = initially_disabled;
-+  init_termination_status ();
-+
-+  if (initially_disabled)
-+    {
-+      check_for_termination ("fprintf", without_compatibility_fprintf);
-+      check_for_termination ("fputc", without_compatibility_fputc);
-+      check_for_termination ("fgetc", without_compatibility_fgetc);
-+      check_for_termination ("fflush", without_compatibility_fflush);
-+    }
-+
-+  check_call ("fprintf", with_compatibility_fprintf, initially_disabled);
-+  check_call ("fputc", with_compatibility_fputc, initially_disabled);
-+  check_call ("fgetc", with_compatibility_fgetc, initially_disabled);
-+  check_call ("fflush", with_compatibility_fflush, initially_disabled);
-+
-+  support_shared_free (shared);
-+  shared = NULL;
-+
-+  return 0;
-+}
-diff --git a/libio/tst-vtables-interposed.c b/libio/tst-vtables-interposed.c
-new file mode 100644
-index 0000000000000000..c8f4e8c7c386af39
---- /dev/null
-+++ b/libio/tst-vtables-interposed.c
-@@ -0,0 +1,37 @@
-+/* Test for libio vtables and their validation.  Enabled through interposition.
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+/* Provide an interposed definition of the standard file handles with
-+   our own vtable.  stdout/stdin/stderr will not work as a result, but
-+   a succesful test does not print anything, so this is fine.  */
-+static const struct _IO_jump_t jumps;
-+#define _IO_file_jumps jumps
-+#include "stdfiles.c"
-+
-+#include "tst-vtables-common.c"
-+
-+static int
-+do_test (void)
-+{
-+  return run_tests (false);
-+}
-+
-+/* Calling setvbuf in the test driver is not supported with our
-+   interposed file handles.  */
-+#define TEST_NO_SETVBUF
-+#include <support/test-driver.c>
-diff --git a/libio/tst-vtables.c b/libio/tst-vtables.c
-new file mode 100644
-index 0000000000000000..f16acf5d23b0fff6
---- /dev/null
-+++ b/libio/tst-vtables.c
-@@ -0,0 +1,29 @@
-+/* Test for libio vtables and their validation.  Initially disabled case.
-+   Copyright (C) 2018 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
-+
-+#include "libioP.h"
-+
-+#include "tst-vtables-common.c"
-+
-+static int
-+do_test (void)
-+{
-+  return run_tests (true);
-+}
-+
-+#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1705899-6.patch b/SOURCES/glibc-rh1705899-6.patch
deleted file mode 100644
index 4ff1252..0000000
--- a/SOURCES/glibc-rh1705899-6.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-commit 2d1c89a5d7c872a1109768f50e2508cf9a4b0348
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Wed Jun 20 09:45:19 2018 +0200
-
-    libio: Avoid ptrdiff_t overflow in IO_validate_vtable
-
-    If the candidate pointer is sufficiently far away from
-    __start___libc_IO_vtables, the result might not fit into ptrdiff_t.
-
-diff --git a/libio/libioP.h b/libio/libioP.h
-index b60244ac5fc3d908..f1576381500ffc85 100644
---- a/libio/libioP.h
-+++ b/libio/libioP.h
-@@ -957,8 +957,8 @@ IO_validate_vtable (const struct _IO_jump_t *vtable)
-   /* Fast path: The vtable pointer is within the __libc_IO_vtables
-      section.  */
-   uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;
--  const char *ptr = (const char *) vtable;
--  uintptr_t offset = ptr - __start___libc_IO_vtables;
-+  uintptr_t ptr = (uintptr_t) vtable;
-+  uintptr_t offset = ptr - (uintptr_t) __start___libc_IO_vtables;
-   if (__glibc_unlikely (offset >= section_length))
-     /* The vtable pointer is not in the expected section.  Use the
-        slow path, which will terminate the process if necessary.  */
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index 5e9fe6c..ebf161b 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -1,6 +1,6 @@
 %define glibcsrcdir glibc-2.17-c758a686
 %define glibcversion 2.17
-%define glibcrelease 260%{?dist}.6
+%define glibcrelease 292%{?dist}
 ##############################################################################
 # We support the following options:
 # --with/--without,
@@ -258,11 +258,6 @@ Patch0068: glibc-rh1349982.patch
 
 # These changes were brought forward from RHEL 6 for compatibility
 Patch0069: glibc-rh1448107.patch
-
-# Armhfp build issue
-Patch9998: glibc-armhfp-ELF_MACHINE_NO_REL-undefined.patch
-Patch9999: glibc-rh1256317-armhfp-build-issue.patch
-
 ##############################################################################
 #
 # Patches from upstream
@@ -942,6 +937,7 @@ Patch1757: glibc-rh1337242.patch
 Patch17580: glibc-rh1418978-max_align_t.patch
 Patch1758: glibc-rh1418978-0.patch
 Patch1759: glibc-rh1418978-1.patch
+Patch2752: glibc-rh1418978-1a.patch
 Patch1760: glibc-rh1418978-2-1.patch
 Patch1761: glibc-rh1418978-2-2.patch
 Patch1762: glibc-rh1418978-2-3.patch
@@ -1164,6 +1160,10 @@ Patch1900: glibc-rh1534635.patch
 Patch1901: glibc-rh1529982.patch
 
 Patch1902: glibc-rh1523119-compat-symbols.patch
+
+# RHBZ #1609067: Backfort of upstream [#15804] - fix race condition in pldd
+Patch1903: glibc-rh1609067.patch
+
 Patch2500: glibc-rh1505492-nscd_stat.patch
 Patch2501: glibc-rh1564638.patch
 Patch2502: glibc-rh1566623.patch
@@ -1422,17 +1422,63 @@ Patch2748: glibc-rh1401665-2.patch
 Patch2749: glibc-rh1401665-3.patch
 Patch2750: glibc-rh1401665-4.patch
 Patch2751: glibc-rh1401665-5.patch
-Patch2752: glibc-rh1661244.patch
-Patch2753: glibc-rh1661242-1.patch
-Patch2754: glibc-rh1661242-2.patch
-Patch2755: glibc-rh1693152-1.patch
-Patch2756: glibc-rh1693152-2.patch
-Patch2757: glibc-rh1705899-1.patch
-Patch2758: glibc-rh1705899-2.patch
-Patch2759: glibc-rh1705899-3.patch
-Patch2760: glibc-rh1705899-4.patch
-Patch2761: glibc-rh1705899-5.patch
-Patch2762: glibc-rh1705899-6.patch
+Patch2753: glibc-rh1595191-1.patch
+Patch2754: glibc-rh1595191-2.patch
+Patch2755: glibc-rh1595191-3.patch
+Patch2756: glibc-rh1595191-4.patch
+Patch2757: glibc-rh1647490-1.patch
+Patch2758: glibc-rh1647490-2.patch
+Patch2759: glibc-rh1647490-3.patch
+Patch2760: glibc-rh1647490-4.patch
+Patch2761: glibc-rh1647490-5.patch
+Patch2762: glibc-rh1639524.patch
+Patch2763: glibc-rh1647490-6.patch
+Patch2764: glibc-rh1579730-1.patch
+Patch2765: glibc-rh1579730-2.patch
+Patch2766: glibc-rh1579730-3.patch
+Patch2767: glibc-rh1630440-1.patch
+Patch2768: glibc-rh1630440-2.patch
+Patch2769: glibc-rh1646373.patch
+Patch2770: glibc-rh1591268.patch
+Patch2771: glibc-rh1592475-1.patch
+Patch2772: glibc-rh1592475-2.patch
+Patch2773: glibc-rh1592475-3.patch
+Patch2774: glibc-rh1657015-1.patch
+Patch2775: glibc-rh1657015-2.patch
+Patch2776: glibc-rh1657015-3.patch
+Patch2777: glibc-rh1657015-4.patch
+Patch2778: glibc-rh1673465-1.patch
+Patch2779: glibc-rh1673465-2.patch
+Patch2780: glibc-rh1673465-3.patch
+Patch2781: glibc-rh1673465-4.patch
+Patch2782: glibc-rh1673465-5.patch
+Patch2783: glibc-rh1673465-6.patch
+Patch2784: glibc-rh1673465-7.patch
+Patch2785: glibc-rh1039304-1.patch
+Patch2786: glibc-rh1039304-2.patch
+Patch2787: glibc-rh1039304-3.patch
+Patch2788: glibc-rh1039304-4.patch
+Patch2789: glibc-rh1443872.patch
+Patch2790: glibc-rh1472832.patch
+Patch2791: glibc-rh1673465-8.patch
+Patch2792: glibc-rh1443872-2.patch
+Patch2793: glibc-rh1579354.patch
+Patch2794: glibc-rh1579739.patch
+Patch2795: glibc-rh1641981.patch
+Patch2796: glibc-rh1579739-2.patch
+Patch2797: glibc-rh1684874-1.patch
+Patch2798: glibc-rh1684874-2.patch
+Patch2799: glibc-rh1488370.patch
+Patch2800: glibc-rh1662842.patch
+Patch2801: glibc-rh1163509-1.patch
+Patch2802: glibc-rh1163509-2.patch
+Patch2803: glibc-rh1163509-3.patch
+Patch2804: glibc-rh1163509-4.patch
+Patch2805: glibc-rh1163509-5.patch
+Patch2806: glibc-rh1555189-1.patch
+Patch2807: glibc-rh1555189-2.patch
+Patch2808: glibc-rh1427734-1.patch
+Patch2809: glibc-rh1427734-2.patch
 
 ##############################################################################
 #
@@ -1634,6 +1680,9 @@ BuildRequires: systemd
 # the required semantics.
 BuildRequires: gcc >= 4.8.5-25
 
+# This RPM version introduced --g-libs.
+BuildRequires: rpm-build >= 4.11.3-38.el7
+
 %define enablekernel 2.6.32
 Conflicts: kernel < %{enablekernel}
 %define target %{_target_cpu}-redhat-linux
@@ -2397,6 +2446,7 @@ package or when debugging this package.
 %patch17580 -p1
 %patch1758 -p1
 %patch1759 -p1
+%patch2752 -p1
 %patch1760 -p1
 %patch1761 -p1
 %patch1762 -p1
@@ -2577,6 +2627,7 @@ package or when debugging this package.
 %patch1900 -p1
 %patch1901 -p1
 %patch1902 -p1
+%patch1903 -p1
 %patch2500 -p1
 %patch2501 -p1
 %patch2502 -p1
@@ -2833,7 +2884,6 @@ package or when debugging this package.
 %patch2749 -p1
 %patch2750 -p1
 %patch2751 -p1
-%patch2752 -p1
 %patch2753 -p1
 %patch2754 -p1
 %patch2755 -p1
@@ -2844,11 +2894,53 @@ package or when debugging this package.
 %patch2760 -p1
 %patch2761 -p1
 %patch2762 -p1
-
-%ifarch %{arm}
-%patch9998 -p1
-%patch9999 -p1
-%endif
+%patch2763 -p1
+%patch2764 -p1
+%patch2765 -p1
+%patch2766 -p1
+%patch2767 -p1
+%patch2768 -p1
+%patch2769 -p1
+%patch2770 -p1
+%patch2771 -p1
+%patch2772 -p1
+%patch2773 -p1
+%patch2774 -p1
+%patch2775 -p1
+%patch2776 -p1
+%patch2777 -p1
+%patch2778 -p1
+%patch2779 -p1
+%patch2780 -p1
+%patch2781 -p1
+%patch2782 -p1
+%patch2783 -p1
+%patch2784 -p1
+%patch2785 -p1
+%patch2786 -p1
+%patch2787 -p1
+%patch2788 -p1
+%patch2789 -p1
+%patch2790 -p1
+%patch2791 -p1
+%patch2792 -p1
+%patch2793 -p1
+%patch2794 -p1
+%patch2795 -p1
+%patch2796 -p1
+%patch2797 -p1
+%patch2798 -p1
+%patch2799 -p1
+%patch2800 -p1
+%patch2801 -p1
+%patch2802 -p1
+%patch2803 -p1
+%patch2804 -p1
+%patch2805 -p1
+%patch2806 -p1
+%patch2807 -p1
+%patch2808 -p1
+%patch2809 -p1
 
 ##############################################################################
 # %%prep - Additional prep required...
@@ -2889,6 +2981,9 @@ touch `find . -name configure`
 # Ensure *-kw.h files are current to prevent regenerating them.
 touch locale/programs/*-kw.h
 
+# RHBZ #1640764: Ensure plural.c is current to prevent regenerating it (bison)
+touch intl/plural.c
+
 ##############################################################################
 # Build glibc...
 ##############################################################################
@@ -3725,7 +3820,7 @@ ls -l $RPM_BUILD_ROOT/usr/bin/getconf
 ls -l $RPM_BUILD_ROOT/usr/libexec/getconf
 eu-readelf -hS $RPM_BUILD_ROOT/usr/bin/getconf $RPM_BUILD_ROOT/usr/libexec/getconf/*
 
-find_debuginfo_args='--strict-build-id -g'
+find_debuginfo_args='--strict-build-id --g-libs'
 %ifarch %{debuginfocommonarches}
 find_debuginfo_args="$find_debuginfo_args \
   -l common.filelist -l utils.filelist -l nscd.filelist \
@@ -4012,20 +4107,102 @@ rm -f *.filelist*
 %endif
 
 %changelog
-* Fri May  3 2019 Florian Weimer <fweimer@redhat.com> - 2.17-260.6
-- Backport libio vtable validation improvements (#1705899)
+* Tue Apr 30 2019 Arjun Shankar <arjun@redhat.com> - 2.17-292
+- Avoid iconv hang on invalid multi-byte sequences (#1427734)
+
+* Tue Apr 30 2019 Florian Weimer <fweimer@redhat.com> - 2.17-291
+- Use versioned Obsoletes: for nss_db (#1703565)
+
+* Mon Apr  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-290
+- Adjust to find-debuginfo.sh changes (#1661508)
+
+* Mon Apr  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-289
+- ja_JP: Add new Japanese Era name (#1555189)
+
+* Wed Mar 27 2019 Arjun Shankar <arjun@redhat.com> - 2.17-288
+- Unify and improve pthread_once implementation for all architectures (#1163509)
+
+* Tue Mar 26 2019 DJ Delorie <dj@redhat.com> - 2.17.287
+- malloc: Always call memcpy in _int_realloc (#1662842)
+
+* Wed Mar 20 2019 Carlos O'Donell <carlos@redhat.com> - 2.17-286
+- Update comments in nscd.conf and nsswitch.conf (#1488370)
+
+* Tue Mar 19 2019 Arjun Shankar <arjun@redhat.com> - 2.17-285
+- intl: Ensure plural.c is current to prevent regenerating it (#1640764)
+
+* Tue Mar  5 2019 Florian Weimer <fweimer@redhat.com> - 2.17-284
+- Update <netinet/in.h> to include IP*_PMTUDISC_OMIT and others (#1684874)
+
+* Fri Mar  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-283
+- elf: Adjust the big PT_NOTE test to exercise the bug in more cases (#1579739)
+
+* Fri Mar  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-282
+- x86: Fix incorrect selection of string functions (#1641981)
+
+* Fri Mar  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-281
+- elf: Avoid stack overflow with large PT_NOTE segments (#1579739)
+
+* Fri Mar  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-280
+- resolv: Fully initialize sendmmsg argument data (#1579354)
+
+* Fri Mar  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-279
+- Improve formatting of Netlink error messages (#1443872)
+
+* Fri Mar  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-278
+- Run resolv/tst-inet_aton_exact test (#1673465)
+
+* Thu Feb 28 2019 Florian Weimer <fweimer@redhat.com> - 2.17-277
+- getifaddrs could return interfaces with ifa_name set to NULL (#1472832)
+
+* Thu Feb 28 2019 Florian Weimer <fweimer@redhat.com> - 2.17-276
+- Terminate process on invalid netlink response from kernel (#1443872)
+
+* Thu Feb 28 2019 Florian Weimer <fweimer@redhat.com> - 2.17-275
+- resolv: Support host names with trailing dashes (#1039304)
+
+* Thu Feb 28 2019 Florian Weimer <fweimer@redhat.com> - 2.17-274
+- CVE-2016-10739: Reject trailing characters in getaddrinfo (#1673465)
+
+* Thu Feb 28 2019 Carlos O'Donell <carlos@redhat.com> - 2.17-273
+- Update syscall list for Linux 4.20 (#1657015)
+
+* Wed Feb 20 2019 Arjun Shankar <arjun@redhat.com> - 2.17-272
+- glibc-headers: Add ipc STAT_ANY constants (#1592475)
+
+* Wed Feb 13 2019 Arjun Shankar <arjun@redhat.com> - 2.17-271
+- localedata: Make IBM273 compatible with ISO-8859-1 (#1591268)
+
+* Mon Jan 28 2019 Patsy Griffin Franklin <pfrankli@redhat.com> - 2.17-270
+- Fix pldd race condition that may leave the process stopped after
+  detaching. (#1609067)
+
+* Tue Jan 22 2019 DJ Delorie <dj@redhat.com> - 2.17-269
+- libanl: properly cleanup if first helper thread creation failed (#1646373)
+
+* Mon Jan 21 2019 DJ Delorie <dj@redhat.com> - 2.17-268
+- Add note about missing test case for BZ1457479 (#1635325)
+
+* Thu Dec 20 2018 Florian Weimer <fweimer@redhat.com> - 2.17-267
+- elf: Fix data race in _dl_profile_fixup (#1630440)
+
+* Wed Dec 19 2018 Florian Weimer <fweimer@redhat.com> - 2.17-266
+- Fix i386 sigaction sa_restorer initialization (#1579730)
+
+* Wed Dec 19 2018 Florian Weimer <fweimer@redhat.com> - 2.17-265
+- Fix compilation error in stdlib/tst-strtod-overflow.c (#1647490)
 
-* Tue Apr 30 2019 Florian Weimer <fweimer@redhat.com> - 2.17-260.5
-- Use versioned Obsoletes: for nss_db (#1704593)
+* Thu Dec 13 2018 DJ Delorie <dj@redhat.com> - 2.17-264
+- aarch64: Disable lazy symbol binding of TLSDESC (#1639524)
 
-* Mon Apr  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-260.4
-- ja_JP: Add new Japanese Era name (#1693152)
+* Fri Nov  9 2018 Florian Weimer <fweimer@redhat.com> - 2.17-263
+- Reduce RAM requirements for stdlib/test-bz22786 (#1647490)
 
-* Thu Jan  3 2019 Florian Weimer <fweimer@redhat.com> - 2.17-260.3
-- elf: Fix data race in _dl_profile_fixup (#1661242)
+* Wed Nov  7 2018 Florian Weimer <fweimer@redhat.com> - 2.17-262
+- libio vtable validation improvements (#1595191)
 
-* Thu Dec 20 2018 Florian Weimer <fweimer@redhat.com> - 2.17-260.1
-- aarch64: Disable lazy symbol binding of TLSDESC (#1661244)
+* Wed Nov  7 2018 Florian Weimer <fweimer@redhat.com> - 2.17-261
+- Update support/ to the most recent upstream version (#1595191)
 
 * Wed Jun 27 2018 Patsy Franklin <pfrankli@redhat.com> - 2.17-260
 - Update glibc-rh1560641.patch to initialize pad outside