summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Avoid-ldbl-96-stack-corruption-from-range-reduction-.patch126
-rw-r--r--Disable-warnings-due-to-deprecated-libselinux-symbol.patch104
-rw-r--r--Fix-CVE-2020-27618-iconv-Accept-redundant-shift-sequences.patch56
-rw-r--r--Fix-CVE-2020-6096-001.patch189
-rw-r--r--Fix-CVE-2020-6096-002.patch107
-rw-r--r--Fix-avx2-strncmp-offset-compare-condition-check-BZ-2.patch52
-rw-r--r--Fix-double-free-in-__printf_fp_l-bug-26214.patch36
-rw-r--r--Fix-memory-leak-in-__printf_fp_l-bug-26215.patch87
-rw-r--r--Fix-strtod-multiple-precision-division-bug-bug-26137.patch3646
-rw-r--r--Fix-use-after-free-in-glob-when-expanding-user-bug-2.patch63
-rw-r--r--Handle-SEM_STAT_ANY-the-same-way-as-SEM_STAT-so-that.patch41
-rw-r--r--LanguageList196
-rw-r--r--LicenseList26
-rw-r--r--Reset-converter-state-after-second-wchar_t-output-Bu.patch251
-rw-r--r--bench.mk77
-rw-r--r--build-extra-libpthreadcond-so.patch4935
-rw-r--r--delete-no-hard-link-to-avoid-all_language-package-to.patch26
-rw-r--r--elf-Allow-dlopen-of-filter-object-to-work-BZ-16272.patch537
-rw-r--r--glibc-1070416.patch38
-rw-r--r--glibc-bench-compare153
-rw-r--r--glibc-c-utf8-locale.patch286
-rw-r--r--glibc.spec1329
-rw-r--r--nptl-Don-t-madvise-user-provided-stack.patch41
-rw-r--r--nptl-wait-for-pending-setxid-request-also-in-detache.patch52
-rw-r--r--nscd.conf1
-rw-r--r--nsswitch.conf56
-rw-r--r--remove-country-selection-from-tzselect.patch151
-rw-r--r--rtld-Avoid-using-up-static-TLS-surplus-for-optimizat.patch586
-rw-r--r--sources1
-rw-r--r--turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch25
-rw-r--r--x86-64-Use-RDX_LP-on-__x86_shared_non_temporal_thres.patch50
-rw-r--r--x86_64-Use-xmmN-with-vpxor-to-clear-a-vector-registe.patch43
33 files changed, 13368 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..7f6520c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/glibc-2.31.tar.xz
diff --git a/Avoid-ldbl-96-stack-corruption-from-range-reduction-.patch b/Avoid-ldbl-96-stack-corruption-from-range-reduction-.patch
new file mode 100644
index 0000000..09522fa
--- /dev/null
+++ b/Avoid-ldbl-96-stack-corruption-from-range-reduction-.patch
@@ -0,0 +1,126 @@
+From 9f997ceca28f0634ad78a1ca95b84265f7801ff4 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Wed, 12 Feb 2020 23:31:56 +0000
+Subject: [PATCH] Avoid ldbl-96 stack corruption from range reduction of
+ pseudo-zero (bug 25487).
+
+Bug 25487 reports stack corruption in ldbl-96 sinl on a pseudo-zero
+argument (an representation where all the significand bits, including
+the explicit high bit, are zero, but the exponent is not zero, which
+is not a valid representation for the long double type).
+
+Although this is not a valid long double representation, existing
+practice in this area (see bug 4586, originally marked invalid but
+subsequently fixed) is that we still seek to avoid invalid memory
+accesses as a result, in case of programs that treat arbitrary binary
+data as long double representations, although the invalid
+representations of the ldbl-96 format do not need to be consistently
+handled the same as any particular valid representation.
+
+This patch makes the range reduction detect pseudo-zero and unnormal
+representations that would otherwise go to __kernel_rem_pio2, and
+returns a NaN for them instead of continuing with the range reduction
+process. (Pseudo-zero and unnormal representations whose unbiased
+exponent is less than -1 have already been safely returned from the
+function before this point without going through the rest of range
+reduction.) Pseudo-zero representations would previously result in
+the value passed to __kernel_rem_pio2 being all-zero, which is
+definitely unsafe; unnormal representations would previously result in
+a value passed whose high bit is zero, which might well be unsafe
+since that is not a form of input expected by __kernel_rem_pio2.
+
+Tested for x86_64.
+
+(cherry picked from commit 9333498794cde1d5cca518badf79533a24114b6f)
+---
+ sysdeps/ieee754/ldbl-96/Makefile | 3 ++-
+ sysdeps/ieee754/ldbl-96/e_rem_pio2l.c | 12 +++++++++
+ sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c | 41 ++++++++++++++++++++++++++++++
+ 4 files changed, 60 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c
+
+diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile
+index 995e90d..318628a 100644
+--- a/sysdeps/ieee754/ldbl-96/Makefile
++++ b/sysdeps/ieee754/ldbl-96/Makefile
+@@ -17,5 +17,6 @@
+ # <https://www.gnu.org/licenses/>.
+
+ ifeq ($(subdir),math)
+-tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96
++tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo
++CFLAGS-test-sinl-pseudo.c += -fstack-protector-all
+ endif
+diff --git a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c
+index 5f74232..bcdf201 100644
+--- a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c
++++ b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c
+@@ -210,6 +210,18 @@ __ieee754_rem_pio2l (long double x, long double *y)
+ return 0;
+ }
+
++ if ((i0 & 0x80000000) == 0)
++ {
++ /* Pseudo-zero and unnormal representations are not valid
++ representations of long double. We need to avoid stack
++ corruption in __kernel_rem_pio2, which expects input in a
++ particular normal form, but those representations do not need
++ to be consistently handled like any particular floating-point
++ value. */
++ y[1] = y[0] = __builtin_nanl ("");
++ return 0;
++ }
++
+ /* Split the 64 bits of the mantissa into three 24-bit integers
+ stored in a double array. */
+ exp = j0 - 23;
+diff --git a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c
+new file mode 100644
+index 0000000..f59b977
+--- /dev/null
++++ b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c
+@@ -0,0 +1,41 @@
++/* Test sinl for pseudo-zeros and unnormals for ldbl-96 (bug 25487).
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <math.h>
++#include <math_ldbl.h>
++#include <stdint.h>
++
++static int
++do_test (void)
++{
++ for (int i = 0; i < 64; i++)
++ {
++ uint64_t sig = i == 63 ? 0 : 1ULL << i;
++ long double ld;
++ SET_LDOUBLE_WORDS (ld, 0x4141,
++ sig >> 32, sig & 0xffffffffULL);
++ /* The requirement is that no stack overflow occurs when the
++ pseudo-zero or unnormal goes through range reduction. */
++ volatile long double ldr;
++ ldr = sinl (ld);
++ (void) ldr;
++ }
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.7.4
+
diff --git a/Disable-warnings-due-to-deprecated-libselinux-symbol.patch b/Disable-warnings-due-to-deprecated-libselinux-symbol.patch
new file mode 100644
index 0000000..25e6d57
--- /dev/null
+++ b/Disable-warnings-due-to-deprecated-libselinux-symbol.patch
@@ -0,0 +1,104 @@
+From 04726be814c6fd6d9cf974e15d684dd3ac1a180e Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Thu, 23 Jul 2020 12:20:38 +0200
+Subject: [PATCH] Disable warnings due to deprecated libselinux symbols used by
+ nss and nscd
+
+The SELinux API deprecated several symbols in its 3.1 release, including
+security_context_t, matchpathcon, avc_init, and sidput, which are used in
+makedb and nscd. While the usage of these should eventually be replaced by
+newer interfaces, this commit disables GCC warnings due to the use of the
+above symbols.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+---
+ nscd/selinux.c | 15 +++++++++++++++
+ nss/makedb.c | 9 +++++++++
+ 2 files changed, 24 insertions(+)
+
+diff --git a/nscd/selinux.c b/nscd/selinux.c
+index a4ea8008e2..1ebf924826 100644
+--- a/nscd/selinux.c
++++ b/nscd/selinux.c
+@@ -33,6 +33,7 @@
+ #ifdef HAVE_LIBAUDIT
+ # include <libaudit.h>
+ #endif
++#include <libc-diag.h>
+
+ #include "dbg_log.h"
+ #include "selinux.h"
+@@ -320,6 +321,12 @@ avc_free_lock (void *lock)
+ }
+
+
++/* avc_init (along with several other symbols) was marked as deprecated by the
++ SELinux API starting from version 3.1. We use it here, but should
++ eventually switch to the newer API. */
++DIAG_PUSH_NEEDS_COMMENT
++DIAG_IGNORE_NEEDS_COMMENT (10, "-Wdeprecated-declarations");
++
+ /* Initialize the user space access vector cache (AVC) for NSCD along with
+ log/thread/lock callbacks. */
+ void
+@@ -335,7 +342,14 @@ nscd_avc_init (void)
+ audit_init ();
+ #endif
+ }
++DIAG_POP_NEEDS_COMMENT
++
+
++/* security_context_t and sidput (along with several other symbols) were marked
++ as deprecated by the SELinux API starting from version 3.1. We use them
++ here, but should eventually switch to the newer API. */
++DIAG_PUSH_NEEDS_COMMENT
++DIAG_IGNORE_NEEDS_COMMENT (10, "-Wdeprecated-declarations");
+
+ /* Check the permission from the caller (via getpeercon) to nscd.
+ Returns 0 if access is allowed, 1 if denied, and -1 on error.
+@@ -422,6 +436,7 @@ out:
+
+ return rc;
+ }
++DIAG_POP_NEEDS_COMMENT
+
+
+ /* Wrapper to get AVC statistics. */
+diff --git a/nss/makedb.c b/nss/makedb.c
+index 8e389a1683..8e1e8ec9ad 100644
+--- a/nss/makedb.c
++++ b/nss/makedb.c
+@@ -38,6 +38,7 @@
+ #include <sys/stat.h>
+ #include <sys/uio.h>
+ #include "nss_db/nss_db.h"
++#include <libc-diag.h>
+
+ /* Get libc version number. */
+ #include "../version.h"
+@@ -841,6 +842,13 @@ print_database (int fd)
+
+
+ #ifdef HAVE_SELINUX
++
++/* security_context_t and matchpathcon (along with several other symbols) were
++ marked as deprecated by the SELinux API starting from version 3.1. We use
++ them here, but should eventually switch to the newer API. */
++DIAG_PUSH_NEEDS_COMMENT
++DIAG_IGNORE_NEEDS_COMMENT (10, "-Wdeprecated-declarations");
++
+ static void
+ set_file_creation_context (const char *outname, mode_t mode)
+ {
+@@ -870,6 +878,7 @@ set_file_creation_context (const char *outname, mode_t mode)
+ freecon (ctx);
+ }
+ }
++DIAG_POP_NEEDS_COMMENT
+
+ static void
+ reset_file_creation_context (void)
+--
+2.23.0
+
diff --git a/Fix-CVE-2020-27618-iconv-Accept-redundant-shift-sequences.patch b/Fix-CVE-2020-27618-iconv-Accept-redundant-shift-sequences.patch
new file mode 100644
index 0000000..c26139f
--- /dev/null
+++ b/Fix-CVE-2020-27618-iconv-Accept-redundant-shift-sequences.patch
@@ -0,0 +1,56 @@
+From 9a99c682144bdbd40792ebf822fe9264e0376fb5 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Wed, 4 Nov 2020 12:19:38 +0100
+Subject: [PATCH] iconv: Accept redundant shift sequences in IBM1364 [BZ
+ #26224]
+
+The IBM1364, IBM1371, IBM1388, IBM1390 and IBM1399 character sets
+share converter logic (iconvdata/ibm1364.c) which would reject
+redundant shift sequences when processing input in these character
+sets. This led to a hang in the iconv program (CVE-2020-27618).
+
+This commit adjusts the converter to ignore redundant shift sequences
+and adds test cases for iconv_prog hangs that would be triggered upon
+their rejection. This brings the implementation in line with other
+converters that also ignore redundant shift sequences (e.g. IBM930
+etc., fixed in commit 692de4b3960d).
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+---
+ iconvdata/ibm1364.c | 14 ++------------
+ 1 files changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
+index 49e7267ab45..521f0825b7f 100644
+--- a/iconvdata/ibm1364.c
++++ b/iconvdata/ibm1364.c
+@@ -158,24 +158,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; \
+ } \
+ 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; \
+--
+2.25.1
+
diff --git a/Fix-CVE-2020-6096-001.patch b/Fix-CVE-2020-6096-001.patch
new file mode 100644
index 0000000..d3a3d67
--- /dev/null
+++ b/Fix-CVE-2020-6096-001.patch
@@ -0,0 +1,189 @@
+From 79a4fa341b8a89cb03f84564fd72abaa1a2db394 Mon Sep 17 00:00:00 2001
+From: Evgeny Eremin <e.eremin@omprussia.ru>
+Date: Wed, 8 Jul 2020 14:18:19 +0200
+Subject: [PATCH] arm: CVE-2020-6096: fix memcpy and memmove for negative
+ length [BZ #25620]
+
+Unsigned branch instructions could be used for r2 to fix the wrong
+behavior when a negative length is passed to memcpy and memmove.
+This commit fixes the generic arm implementation of memcpy amd memmove.
+---
+ sysdeps/arm/memcpy.S | 24 ++++++++++--------------
+ sysdeps/arm/memmove.S | 24 ++++++++++--------------
+ 2 files changed, 20 insertions(+), 28 deletions(-)
+
+diff --git a/sysdeps/arm/memcpy.S b/sysdeps/arm/memcpy.S
+index 510e8adaf2..bcfbc51d99 100644
+--- a/sysdeps/arm/memcpy.S
++++ b/sysdeps/arm/memcpy.S
+@@ -68,7 +68,7 @@ ENTRY(memcpy)
+ cfi_remember_state
+
+ subs r2, r2, #4
+- blt 8f
++ blo 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #0] )
+ bne 9f
+@@ -82,7 +82,7 @@ ENTRY(memcpy)
+ cfi_rel_offset (r6, 4)
+ cfi_rel_offset (r7, 8)
+ cfi_rel_offset (r8, 12)
+- blt 5f
++ blo 5f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb r3, ip, #32 )
+@@ -98,9 +98,9 @@ ENTRY(memcpy)
+ #endif
+
+ PLD( pld [r1, #0] )
+-2: PLD( subs r2, r2, #96 )
++2: PLD( cmp r2, #96 )
+ PLD( pld [r1, #28] )
+- PLD( blt 4f )
++ PLD( blo 4f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+@@ -108,9 +108,7 @@ ENTRY(memcpy)
+ 4: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ subs r2, r2, #32
+ stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+- bge 3b
+- PLD( cmn r2, #96 )
+- PLD( bge 4b )
++ bhs 3b
+
+ 5: ands ip, r2, #28
+ rsb ip, ip, #32
+@@ -222,7 +220,7 @@ ENTRY(memcpy)
+ strbge r4, [r0], #1
+ subs r2, r2, ip
+ strb lr, [r0], #1
+- blt 8b
++ blo 8b
+ ands ip, r1, #3
+ beq 1b
+
+@@ -236,7 +234,7 @@ ENTRY(memcpy)
+ .macro forward_copy_shift pull push
+
+ subs r2, r2, #28
+- blt 14f
++ blo 14f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb ip, ip, #32 )
+@@ -253,9 +251,9 @@ ENTRY(memcpy)
+ cfi_rel_offset (r10, 16)
+
+ PLD( pld [r1, #0] )
+- PLD( subs r2, r2, #96 )
++ PLD( cmp r2, #96 )
+ PLD( pld [r1, #28] )
+- PLD( blt 13f )
++ PLD( blo 13f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+@@ -280,9 +278,7 @@ ENTRY(memcpy)
+ mov ip, ip, PULL #\pull
+ orr ip, ip, lr, PUSH #\push
+ stmia r0!, {r3, r4, r5, r6, r7, r8, r10, ip}
+- bge 12b
+- PLD( cmn r2, #96 )
+- PLD( bge 13b )
++ bhs 12b
+
+ pop {r5 - r8, r10}
+ cfi_adjust_cfa_offset (-20)
+diff --git a/sysdeps/arm/memmove.S b/sysdeps/arm/memmove.S
+index 954037ef3a..0d07b76ee6 100644
+--- a/sysdeps/arm/memmove.S
++++ b/sysdeps/arm/memmove.S
+@@ -85,7 +85,7 @@ ENTRY(memmove)
+ add r1, r1, r2
+ add r0, r0, r2
+ subs r2, r2, #4
+- blt 8f
++ blo 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #-4] )
+ bne 9f
+@@ -99,7 +99,7 @@ ENTRY(memmove)
+ cfi_rel_offset (r6, 4)
+ cfi_rel_offset (r7, 8)
+ cfi_rel_offset (r8, 12)
+- blt 5f
++ blo 5f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( sbcsne r4, ip, r2 ) @ C is always set here
+@@ -114,9 +114,9 @@ ENTRY(memmove)
+ #endif
+
+ PLD( pld [r1, #-4] )
+-2: PLD( subs r2, r2, #96 )
++2: PLD( cmp r2, #96 )
+ PLD( pld [r1, #-32] )
+- PLD( blt 4f )
++ PLD( blo 4f )
+ PLD( pld [r1, #-64] )
+ PLD( pld [r1, #-96] )
+
+@@ -124,9 +124,7 @@ ENTRY(memmove)
+ 4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ subs r2, r2, #32
+ stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+- bge 3b
+- PLD( cmn r2, #96 )
+- PLD( bge 4b )
++ bhs 3b
+
+ 5: ands ip, r2, #28
+ rsb ip, ip, #32
+@@ -237,7 +235,7 @@ ENTRY(memmove)
+ strbge r4, [r0, #-1]!
+ subs r2, r2, ip
+ strb lr, [r0, #-1]!
+- blt 8b
++ blo 8b
+ ands ip, r1, #3
+ beq 1b
+
+@@ -251,7 +249,7 @@ ENTRY(memmove)
+ .macro backward_copy_shift push pull
+
+ subs r2, r2, #28
+- blt 14f
++ blo 14f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb ip, ip, #32 )
+@@ -268,9 +266,9 @@ ENTRY(memmove)
+ cfi_rel_offset (r10, 16)
+
+ PLD( pld [r1, #-4] )
+- PLD( subs r2, r2, #96 )
++ PLD( cmp r2, #96 )
+ PLD( pld [r1, #-32] )
+- PLD( blt 13f )
++ PLD( blo 13f )
+ PLD( pld [r1, #-64] )
+ PLD( pld [r1, #-96] )
+
+@@ -295,9 +293,7 @@ ENTRY(memmove)
+ mov r4, r4, PUSH #\push
+ orr r4, r4, r3, PULL #\pull
+ stmdb r0!, {r4 - r8, r10, ip, lr}
+- bge 12b
+- PLD( cmn r2, #96 )
+- PLD( bge 13b )
++ bhs 12b
+
+ pop {r5 - r8, r10}
+ cfi_adjust_cfa_offset (-20)
+--
+2.19.1
+
diff --git a/Fix-CVE-2020-6096-002.patch b/Fix-CVE-2020-6096-002.patch
new file mode 100644
index 0000000..3d65fae
--- /dev/null
+++ b/Fix-CVE-2020-6096-002.patch
@@ -0,0 +1,107 @@
+From beea361050728138b82c57dda0c4810402d342b9 Mon Sep 17 00:00:00 2001
+From: Alexander Anisimov <a.anisimov@omprussia.ru>
+Date: Wed, 8 Jul 2020 14:18:31 +0200
+Subject: [PATCH] arm: CVE-2020-6096: Fix multiarch memcpy for negative length
+ [BZ #25620]
+
+Unsigned branch instructions could be used for r2 to fix the wrong
+behavior when a negative length is passed to memcpy.
+This commit fixes the armv7 version.
+---
+ sysdeps/arm/armv7/multiarch/memcpy_impl.S | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/sysdeps/arm/armv7/multiarch/memcpy_impl.S b/sysdeps/arm/armv7/multiarch/memcpy_impl.S
+index bf4ac7077f..379bb56fc9 100644
+--- a/sysdeps/arm/armv7/multiarch/memcpy_impl.S
++++ b/sysdeps/arm/armv7/multiarch/memcpy_impl.S
+@@ -268,7 +268,7 @@ ENTRY(memcpy)
+
+ mov dst, dstin /* Preserve dstin, we need to return it. */
+ cmp count, #64
+- bge .Lcpy_not_short
++ bhs .Lcpy_not_short
+ /* Deal with small copies quickly by dropping straight into the
+ exit block. */
+
+@@ -351,10 +351,10 @@ ENTRY(memcpy)
+
+ 1:
+ subs tmp2, count, #64 /* Use tmp2 for count. */
+- blt .Ltail63aligned
++ blo .Ltail63aligned
+
+ cmp tmp2, #512
+- bge .Lcpy_body_long
++ bhs .Lcpy_body_long
+
+ .Lcpy_body_medium: /* Count in tmp2. */
+ #ifdef USE_VFP
+@@ -378,7 +378,7 @@ ENTRY(memcpy)
+ add src, src, #64
+ vstr d1, [dst, #56]
+ add dst, dst, #64
+- bge 1b
++ bhs 1b
+ tst tmp2, #0x3f
+ beq .Ldone
+
+@@ -412,7 +412,7 @@ ENTRY(memcpy)
+ ldrd A_l, A_h, [src, #64]!
+ strd A_l, A_h, [dst, #64]!
+ subs tmp2, tmp2, #64
+- bge 1b
++ bhs 1b
+ tst tmp2, #0x3f
+ bne 1f
+ ldr tmp2,[sp], #FRAME_SIZE
+@@ -482,7 +482,7 @@ ENTRY(memcpy)
+ add src, src, #32
+
+ subs tmp2, tmp2, #prefetch_lines * 64 * 2
+- blt 2f
++ blo 2f
+ 1:
+ cpy_line_vfp d3, 0
+ cpy_line_vfp d4, 64
+@@ -494,7 +494,7 @@ ENTRY(memcpy)
+ add dst, dst, #2 * 64
+ add src, src, #2 * 64
+ subs tmp2, tmp2, #prefetch_lines * 64
+- bge 1b
++ bhs 1b
+
+ 2:
+ cpy_tail_vfp d3, 0
+@@ -615,8 +615,8 @@ ENTRY(memcpy)
+ 1:
+ pld [src, #(3 * 64)]
+ subs count, count, #64
+- ldrmi tmp2, [sp], #FRAME_SIZE
+- bmi .Ltail63unaligned
++ ldrlo tmp2, [sp], #FRAME_SIZE
++ blo .Ltail63unaligned
+ pld [src, #(4 * 64)]
+
+ #ifdef USE_NEON
+@@ -633,7 +633,7 @@ ENTRY(memcpy)
+ neon_load_multi d0-d3, src
+ neon_load_multi d4-d7, src
+ subs count, count, #64
+- bmi 2f
++ blo 2f
+ 1:
+ pld [src, #(4 * 64)]
+ neon_store_multi d0-d3, dst
+@@ -641,7 +641,7 @@ ENTRY(memcpy)
+ neon_store_multi d4-d7, dst
+ neon_load_multi d4-d7, src
+ subs count, count, #64
+- bpl 1b
++ bhs 1b
+ 2:
+ neon_store_multi d0-d3, dst
+ neon_store_multi d4-d7, dst
+--
+2.19.1
+
diff --git a/Fix-avx2-strncmp-offset-compare-condition-check-BZ-2.patch b/Fix-avx2-strncmp-offset-compare-condition-check-BZ-2.patch
new file mode 100644
index 0000000..a613744
--- /dev/null
+++ b/Fix-avx2-strncmp-offset-compare-condition-check-BZ-2.patch
@@ -0,0 +1,52 @@
+From 75870237ff3bb363447b03f4b0af100227570910 Mon Sep 17 00:00:00 2001
+From: Sunil K Pandey <skpgkp1@gmail.com>
+Date: Fri, 12 Jun 2020 08:57:16 -0700
+Subject: [PATCH] Fix avx2 strncmp offset compare condition check [BZ #25933]
+
+strcmp-avx2.S: In avx2 strncmp function, strings are compared in
+chunks of 4 vector size(i.e. 32x4=128 byte for avx2). After first 4
+vector size comparison, code must check whether it already passed
+the given offset. This patch implement avx2 offset check condition
+for strncmp function, if both string compare same for first 4 vector
+size.
+---
+ sysdeps/x86_64/multiarch/strcmp-avx2.S | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
+index 5f88a68262..d42b04b54f 100644
+--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
+@@ -591,7 +591,14 @@ L(loop_cross_page_2_vec):
+ movl $(PAGE_SIZE / (VEC_SIZE * 4) - 1), %esi
+
+ testq %rdi, %rdi
++# ifdef USE_AS_STRNCMP
++ /* At this point, if %rdi value is 0, it already tested
++ VEC_SIZE*4+%r10 byte starting from %rax. This label
++ checks whether strncmp maximum offset reached or not. */
++ je L(string_nbyte_offset_check)
++# else
+ je L(back_to_loop)
++# endif
+ tzcntq %rdi, %rcx
+ addq %r10, %rcx
+ /* Adjust for number of bytes skipped. */
+@@ -627,6 +634,14 @@ L(loop_cross_page_2_vec):
+ VZEROUPPER
+ ret
+
++# ifdef USE_AS_STRNCMP
++L(string_nbyte_offset_check):
++ leaq (VEC_SIZE * 4)(%r10), %r10
++ cmpq %r10, %r11
++ jbe L(zero)
++ jmp L(back_to_loop)
++# endif
++
+ .p2align 4
+ L(cross_page_loop):
+ /* Check one byte/dword at a time. */
+--
+2.19.1
+
diff --git a/Fix-double-free-in-__printf_fp_l-bug-26214.patch b/Fix-double-free-in-__printf_fp_l-bug-26214.patch
new file mode 100644
index 0000000..996179e
--- /dev/null
+++ b/Fix-double-free-in-__printf_fp_l-bug-26214.patch
@@ -0,0 +1,36 @@
+From ede56038e50235cd1ca7de3602c9491d3b84b49b Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Thu, 9 Jul 2020 21:51:49 +0000
+Subject: [PATCH] Fix double free in __printf_fp_l (bug 26214).
+
+__printf_fp_l has a double free bug in the case where it allocates
+memory with malloc internally, then has an I/O error while outputting
+trailing padding and tries to free that already-freed memory when the
+error occurs. This patch fixes this by setting the relevant pointer
+to NULL after the first free (the only free of this pointer that isn't
+immediately followed by returning from the function).
+
+note that this patch is parts of the origin one.
+
+Tested for x86_64 and x86.
+---
+ stdio-common/printf_fp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
+index 66ab59ba..c310eb8e 100644
+--- a/stdio-common/printf_fp.c
++++ b/stdio-common/printf_fp.c
+@@ -1250,6 +1250,9 @@ __printf_fp_l (FILE *fp, locale_t loc,
+ {
+ free (buffer);
+ free (wbuffer);
++ /* Avoid a double free if the subsequent PADN encounters an
++ I/O error. */
++ wbuffer = NULL;
+ }
+ }
+
+--
+2.23.0
+
diff --git a/Fix-memory-leak-in-__printf_fp_l-bug-26215.patch b/Fix-memory-leak-in-__printf_fp_l-bug-26215.patch
new file mode 100644
index 0000000..d888746
--- /dev/null
+++ b/Fix-memory-leak-in-__printf_fp_l-bug-26215.patch
@@ -0,0 +1,87 @@
+From 90663e9c814a919fa1fb41a878c06ef2fae58ed2 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Thu, 9 Jul 2020 21:52:24 +0000
+Subject: [PATCH] Fix memory leak in __printf_fp_l (bug 26215).
+
+__printf_fp_l has a memory leak in the case of some I/O errors, where
+both buffer and wbuffer have been malloced but the handling of I/O
+errors only frees wbuffer. This patch fixes this by moving the
+declaration of buffer to an outer scope and ensuring that it is freed
+when wbuffer is freed.
+
+note that this patch is parts of the origin one.
+
+Tested for x86_64 and x86.
+---
+ stdio-common/printf_fp.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
+index c310eb8e..b88e9cc6 100644
+--- a/stdio-common/printf_fp.c
++++ b/stdio-common/printf_fp.c
+@@ -72,7 +72,10 @@
+ if (putc (outc, fp) == EOF) \
+ { \
+ if (buffer_malloced) \
+- free (wbuffer); \
++ { \
++ free (buffer); \
++ free (wbuffer); \
++ } \
+ return -1; \
+ } \
+ ++done; \
+@@ -87,7 +90,10 @@
+ if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen) \
+ { \
+ if (buffer_malloced) \
+- free (wbuffer); \
++ { \
++ free (buffer); \
++ free (wbuffer); \
++ } \
+ return -1; \
+ } \
+ ptr += outlen; \
+@@ -110,7 +116,10 @@
+ if (PAD (fp, ch, len) != len) \
+ { \
+ if (buffer_malloced) \
+- free (wbuffer); \
++ { \
++ free (buffer); \
++ free (wbuffer); \
++ } \
+ return -1; \
+ } \
+ done += len; \
+@@ -259,7 +268,8 @@ __printf_fp_l (FILE *fp, locale_t loc,
+
+ /* Buffer in which we produce the output. */
+ wchar_t *wbuffer = NULL;
+- /* Flag whether wbuffer is malloc'ed or not. */
++ char *buffer = NULL;
++ /* Flag whether wbuffer and buffer are malloc'ed or not. */
+ int buffer_malloced = 0;
+
+ p.expsign = 0;
+@@ -1172,7 +1182,6 @@ __printf_fp_l (FILE *fp, locale_t loc,
+ PADN ('0', width);
+
+ {
+- char *buffer = NULL;
+ char *buffer_end = NULL;
+ char *cp = NULL;
+ char *tmpptr;
+@@ -1252,6 +1261,7 @@ __printf_fp_l (FILE *fp, locale_t loc,
+ free (wbuffer);
+ /* Avoid a double free if the subsequent PADN encounters an
+ I/O error. */
++ buffer = NULL;
+ wbuffer = NULL;
+ }
+ }
+--
+2.23.0
+
diff --git a/Fix-strtod-multiple-precision-division-bug-bug-26137.patch b/Fix-strtod-multiple-precision-division-bug-bug-26137.patch
new file mode 100644
index 0000000..43bcf34
--- /dev/null
+++ b/Fix-strtod-multiple-precision-division-bug-bug-26137.patch
@@ -0,0 +1,3646 @@
+From 09555b9721d090f7917f8221be2613a4d6a9b0f6 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Tue, 30 Jun 2020 23:04:06 +0000
+Subject: [PATCH] Fix strtod multiple-precision division bug (bug 26137).
+
+Bug 26137 reports spurious "inexact" exceptions from strtod, on 32-bit
+systems only, for a decimal argument that is exactly 1 + 2^-32. In
+fact the same issue also appears for 1 + 2^-64 and 1 + 2^-96 as
+arguments to strtof128 on 32-bit systems, and 1 + 2^-64 as an argument
+to strtof128 on 64-bit systems. In FE_DOWNWARD or FE_TOWARDZERO mode,
+the return value is also incorrect.
+
+The problem is in the multiple-precision division logic used in the
+case of dividing by a denominator that occupies at least three GMP
+limbs. There was a comment "The division does not work if the upper
+limb of the two-limb mumerator is greater than the denominator.", but
+in fact there were problems for the case of equality (that is, where
+the high limbs are equal, offset by some multiple of the GMP limb
+size) as well. In such cases, the code used "quot = ~(mp_limb_t) 0;"
+(with subsequent correction if that is an overestimate), because
+udiv_qrnnd does not support the case of equality, but it's possible
+for the shifted numerator to be greater than or equal to the
+denominator, in which case that is an underestimate. To avoid that,
+this patch changes the ">" condition to ">=", meaning the first
+division is done with a zero high word.
+
+The tests added are all 1 + 2^-n for n from 1 to 113 except for those
+that were already present in tst-strtod-round-data.
+
+Tested for x86_64 and x86.
+---
+ stdlib/strtod_l.c | 4 +-
+ stdlib/tst-strtod-round-data | 110 +
+ stdlib/tst-strtod-round-data.h | 3465 ++++++++++++++++++++++++++++++++
+ 3 files changed, 3577 insertions(+), 2 deletions(-)
+
+diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
+index a3836fc12e..158da787a2 100644
+--- a/stdlib/strtod_l.c
++++ b/stdlib/strtod_l.c
+@@ -1648,8 +1648,8 @@ ____STRTOF_INTERNAL (const STRING_TYPE *nptr, STRING_TYPE **endptr, int group,
+ d1 = den[densize - 2];
+
+ /* The division does not work if the upper limb of the two-limb
+- numerator is greater than the denominator. */
+- if (__mpn_cmp (num, &den[densize - numsize], numsize) > 0)
++ numerator is greater or equal to than the denominator. */
++ if (__mpn_cmp (num, &den[densize - numsize], numsize) >= 0)
+ num[numsize++] = 0;
+
+ if (numsize < densize)
+diff --git a/stdlib/tst-strtod-round-data b/stdlib/tst-strtod-round-data
+index 8a898ddb0e..84ab705709 100644
+--- a/stdlib/tst-strtod-round-data
++++ b/stdlib/tst-strtod-round-data
+@@ -155,3 +155,113 @@
+ -179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215
+ -1189731495357231765085759326628007130763444687096510237472674821233261358180483686904488595472612039915115437484839309258897667381308687426274524698341565006080871634366004897522143251619531446845952345709482135847036647464830984784714280967845614138476044338404886122905286855313236158695999885790106357018120815363320780964323712757164290613406875202417365323950267880089067517372270610835647545755780793431622213451903817859630690311343850657539360649645193283178291767658965405285113556134369793281725888015908414675289832538063419234888599898980623114025121674472051872439321323198402942705341366951274739014593816898288994445173400364617928377138074411345791848573595077170437644191743889644885377684738322240608239079061399475675334739784016491742621485229014847672335977897158397334226349734811441653077758250988926030894789604676153104257260141806823027588003441951455327701598071281589597169413965608439504983171255062282026626200048042149808200002060993433681237623857880627479727072877482838438705048034164633337013385405998040701908662387301605018188262573723766279240798931717708807901740265407930976419648877869604017517691938687988088008944251258826969688364194133945780157844364946052713655454906327187428531895100278695119323496808703630436193927592692344820812834297364478686862064169042458555136532055050508189891866846863799917647547291371573500701015197559097453040033031520683518216494195636696077748110598284901343611469214274121810495077979275556645164983850062051066517084647369464036640569339464837172183352956873912042640003611618789278195710052094562761306703551840330110645101995435167626688669627763820604342480357906415354212732946756073006907088870496125050068156659252761297664065498347492661798824062312210409274584565587264846417650160123175874034726261957289081466197651553830744424709698634753627770356227126145052549125229448040149114795681359875968512808575244271871455454084894986155020794806980939215658055319165641681105966454159951476908583129721503298816585142073061480888021769818338417129396878371459575846052583142928447249703698548125295775920936450022651427249949580708203966082847550921891152133321048011973883636577825533325988852156325439335021315312134081390451021255363707903495916963125924201167877190108935255914539488216897117943269373608639074472792751116715127106396425081353553137213552890539802602978645319795100976432939091924660228878912900654210118287298298707382159717184569540515403029173307292454391789568674219640761451173600617752186991913366837033887201582071625868247133104513315097274713442728340606642890406496636104443217752811227470029162858093727701049646499540220983981932786613204254226464243689610107429923197638681545837561773535568984536053627234424277105760924864023781629665526314910906960488073475217005121136311870439925762508666032566213750416695719919674223210606724721373471234021613540712188239909701971943944347480314217903886317767779921539892177334344368907550318800833546852344370327089284147501640589448482001254237386680074457341910933774891959681016516069106149905572425810895586938833067490204900368624166301968553005687040285095450484840073528643826570403767157286512380255109954518857013476588189300004138849715883139866071547574816476727635116435462804401112711392529180570794193422686818353212799068972247697191474268157912195973794192807298886952361100880264258801320928040011928153970801130741339550003299015924978259936974358726286143980520112454369271114083747919007803406596321353417004068869443405472140675963640997405009225803505672726465095506267339268892424364561897661906898424186770491035344080399248327097911712881140170384182058601614758284200750183500329358499691864066590539660709069537381601887679046657759654588001937117771344698326428792622894338016112445533539447087462049763409147542099248815521395929388007711172017894897793706604273480985161028815458787911160979113422433557549170905442026397275695283207305331845419990749347810524006194197200591652147867193696254337864981603833146354201700628817947177518115217674352016511172347727727075220056177748218928597158346744541337107358427757919660562583883823262178961691787226118865632764934288772405859754877759869235530653929937901193611669007472354746360764601872442031379944139824366828698790212922996174192728625891720057612509349100482545964152046477925114446500732164109099345259799455690095576788686397487061948854749024863607921857834205793797188834779656273479112388585706424836379072355410286787018527401653934219888361061949671961055068686961468019035629749424086587195041004404915266476272761070511568387063401264136517237211409916458796347624949215904533937210937520465798300175408017538862312719042361037129338896586028150046596078872444365564480545689033575955702988396719744528212984142578483954005084264327730840985420021409069485412320805268520094146798876110414583170390473982488899228091818213934288295679717369943152460447027290669964066815
+ +0x.80000000000000000000000000000001p1025
++1.5
++1.25
++1.125
++1.0625
++1.03125
++1.015625
++1.0078125
++1.00390625
++1.001953125
++1.0009765625
++1.00048828125
++1.000244140625
++1.0001220703125
++1.00006103515625
++1.000030517578125
++1.0000152587890625
++1.00000762939453125
++1.000003814697265625
++1.0000019073486328125
++1.00000095367431640625
++1.000000476837158203125
++1.0000000298023223876953125
++1.00000001490116119384765625
++1.000000007450580596923828125
++1.0000000037252902984619140625
++1.00000000186264514923095703125
++1.000000000931322574615478515625
++1.0000000004656612873077392578125
++1.00000000023283064365386962890625
++1.000000000116415321826934814453125
++1.0000000000582076609134674072265625
++1.00000000002910383045673370361328125
++1.000000000014551915228366851806640625
++1.0000000000072759576141834259033203125
++1.00000000000363797880709171295166015625
++1.000000000001818989403545856475830078125
++1.0000000000009094947017729282379150390625
++1.00000000000045474735088646411895751953125
++1.000000000000227373675443232059478759765625
++1.0000000000001136868377216160297393798828125
++1.00000000000005684341886080801486968994140625
++1.000000000000028421709430404007434844970703125
++1.0000000000000142108547152020037174224853515625
++1.00000000000000710542735760100185871124267578125
++1.000000000000003552713678800500929355621337890625
++1.0000000000000017763568394002504646778106689453125
++1.00000000000000088817841970012523233890533447265625
++1.000000000000000444089209850062616169452667236328125
++1.0000000000000002220446049250313080847263336181640625
++1.00000000000000011102230246251565404236316680908203125
++1.000000000000000055511151231257827021181583404541015625
++1.0000000000000000277555756156289135105907917022705078125
++1.00000000000000001387778780781445675529539585113525390625
++1.000000000000000006938893903907228377647697925567626953125
++1.0000000000000000034694469519536141888238489627838134765625
++1.00000000000000000173472347597680709441192448139190673828125
++1.000000000000000000867361737988403547205962240695953369140625
++1.0000000000000000004336808689942017736029811203479766845703125
++1.00000000000000000021684043449710088680149056017398834228515625
++1.000000000000000000108420217248550443400745280086994171142578125
++1.0000000000000000000542101086242752217003726400434970855712890625
++1.00000000000000000002710505431213761085018632002174854278564453125
++1.000000000000000000013552527156068805425093160010874271392822265625
++1.0000000000000000000067762635780344027125465800054371356964111328125
++1.00000000000000000000338813178901720135627329000271856784820556640625
++1.000000000000000000001694065894508600678136645001359283924102783203125
++1.0000000000000000000008470329472543003390683225006796419620513916015625
++1.00000000000000000000042351647362715016953416125033982098102569580078125
++1.000000000000000000000211758236813575084767080625169910490512847900390625
++1.0000000000000000000001058791184067875423835403125849552452564239501953125
++1.00000000000000000000005293955920339377119177015629247762262821197509765625
++1.000000000000000000000026469779601696885595885078146238811314105987548828125
++1.0000000000000000000000132348898008484427979425390731194056570529937744140625
++1.00000000000000000000000661744490042422139897126953655970282852649688720703125
++1.000000000000000000000003308722450212110699485634768279851414263248443603515625
++1.0000000000000000000000016543612251060553497428173841399257071316242218017578125
++1.00000000000000000000000082718061255302767487140869206996285356581211090087890625
++1.000000000000000000000000413590306276513837435704346034981426782906055450439453125
++1.0000000000000000000000002067951531382569187178521730174907133914530277252197265625
++1.00000000000000000000000010339757656912845935892608650874535669572651386260986328125
++1.000000000000000000000000051698788284564229679463043254372678347863256931304931640625
++1.0000000000000000000000000258493941422821148397315216271863391739316284656524658203125
++1.00000000000000000000000001292469707114105741986576081359316958696581423282623291015625
++1.000000000000000000000000006462348535570528709932880406796584793482907116413116455078125
++1.0000000000000000000000000032311742677852643549664402033982923967414535582065582275390625
++1.00000000000000000000000000161558713389263217748322010169914619837072677910327911376953125
++1.000000000000000000000000000807793566946316088741610050849573099185363389551639556884765625
++1.0000000000000000000000000004038967834731580443708050254247865495926816947758197784423828125
++1.00000000000000000000000000020194839173657902218540251271239327479634084738790988922119140625
++1.000000000000000000000000000100974195868289511092701256356196637398170423693954944610595703125
++1.0000000000000000000000000000504870979341447555463506281780983186990852118469774723052978515625
++1.00000000000000000000000000002524354896707237777317531408904915934954260592348873615264892578125
++1.000000000000000000000000000012621774483536188886587657044524579674771302961744368076324462890625
++1.0000000000000000000000000000063108872417680944432938285222622898373856514808721840381622314453125
++1.00000000000000000000000000000315544362088404722164691426113114491869282574043609201908111572265625
++1.000000000000000000000000000001577721810442023610823457130565572459346412870218046009540557861328125
++1.0000000000000000000000000000007888609052210118054117285652827862296732064351090230047702789306640625
++1.00000000000000000000000000000039443045261050590270586428264139311483660321755451150238513946533203125
++1.000000000000000000000000000000197215226305252951352932141320696557418301608777255751192569732666015625
++1.0000000000000000000000000000000986076131526264756764660706603482787091508043886278755962848663330078125
++1.00000000000000000000000000000004930380657631323783823303533017413935457540219431393779814243316650390625
++1.000000000000000000000000000000024651903288156618919116517665087069677287701097156968899071216583251953125
++1.0000000000000000000000000000000123259516440783094595582588325435348386438505485784844495356082916259765625
++1.00000000000000000000000000000000616297582203915472977912941627176741932192527428924222476780414581298828125
++1.000000000000000000000000000000003081487911019577364889564708135883709660962637144621112383902072906494140625
++1.0000000000000000000000000000000015407439555097886824447823540679418548304813185723105561919510364532470703125
++1.00000000000000000000000000000000077037197775489434122239117703397092741524065928615527809597551822662353515625
++1.000000000000000000000000000000000385185988877447170611195588516985463707620329643077639047987759113311767578125
++1.0000000000000000000000000000000001925929944387235853055977942584927318538101648215388195239938795566558837890625
++1.00000000000000000000000000000000009629649721936179265279889712924636592690508241076940976199693977832794189453125
+diff --git a/stdlib/tst-strtod-round-data.h b/stdlib/tst-strtod-round-data.h
+index 5ac25f7b29..8899d15f9b 100644
+--- a/stdlib/tst-strtod-round-data.h
++++ b/stdlib/tst-strtod-round-data.h
+@@ -11972,4 +11972,3469 @@ static const struct test tests[] = {
+ 0x1p+1024, false,
+ 0x1p+1024, false,
+ 0x1.0000000000000000000000000001p+1024, false),
++ TEST ("1.5",
++ true,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ true,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ true,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ true,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ true,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ true,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false,
++ 0x1.8p+0, false),
++ TEST ("1.25",
++ true,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ true,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ true,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ true,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ true,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ true,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false,
++ 0x1.4p+0, false),
++ TEST ("1.125",
++ true,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ true,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ true,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ true,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ true,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ true,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false,
++ 0x1.2p+0, false),
++ TEST ("1.0625",
++ true,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ true,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ true,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ true,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ true,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ true,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false,
++ 0x1.1p+0, false),
++ TEST ("1.03125",
++ true,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ true,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ true,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ true,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ true,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ true,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false,
++ 0x1.08p+0, false),
++ TEST ("1.015625",
++ true,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ true,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ true,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ true,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ true,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ true,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false,
++ 0x1.04p+0, false),
++ TEST ("1.0078125",
++ true,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ true,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ true,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ true,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ true,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ true,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false,
++ 0x1.02p+0, false),
++ TEST ("1.00390625",
++ true,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ true,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ true,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ true,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ true,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ true,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false,
++ 0x1.01p+0, false),
++ TEST ("1.001953125",
++ true,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ true,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ true,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ true,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ true,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ true,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false,
++ 0x1.008p+0, false),
++ TEST ("1.0009765625",
++ true,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ true,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ true,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ true,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ true,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ true,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false,
++ 0x1.004p+0, false),
++ TEST ("1.00048828125",
++ true,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ true,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ true,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ true,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ true,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ true,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false,
++ 0x1.002p+0, false),
++ TEST ("1.000244140625",
++ true,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ true,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ true,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ true,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ true,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ true,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false,
++ 0x1.001p+0, false),
++ TEST ("1.0001220703125",
++ true,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ true,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ true,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ true,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ true,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ true,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false,
++ 0x1.0008p+0, false),
++ TEST ("1.00006103515625",
++ true,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ true,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ true,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ true,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ true,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ true,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false,
++ 0x1.0004p+0, false),
++ TEST ("1.000030517578125",
++ true,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ true,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ true,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ true,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ true,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ true,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false,
++ 0x1.0002p+0, false),
++ TEST ("1.0000152587890625",
++ true,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ true,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ true,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ true,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ true,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ true,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false,
++ 0x1.0001p+0, false),
++ TEST ("1.00000762939453125",
++ true,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ true,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ true,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ true,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ true,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ true,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false,
++ 0x1.00008p+0, false),
++ TEST ("1.000003814697265625",
++ true,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ true,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ true,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ true,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ true,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ true,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false,
++ 0x1.00004p+0, false),
++ TEST ("1.0000019073486328125",
++ true,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ true,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ true,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ true,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ true,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ true,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false,
++ 0x1.00002p+0, false),
++ TEST ("1.00000095367431640625",
++ true,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ true,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ true,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ true,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ true,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ true,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false,
++ 0x1.00001p+0, false),
++ TEST ("1.000000476837158203125",
++ true,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ true,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ true,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ true,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ true,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ true,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false,
++ 0x1.000008p+0, false),
++ TEST ("1.0000000298023223876953125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ true,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ true,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ true,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ true,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false,
++ 0x1.0000008p+0, false),
++ TEST ("1.00000001490116119384765625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ true,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ true,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ true,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ true,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false,
++ 0x1.0000004p+0, false),
++ TEST ("1.000000007450580596923828125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ true,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ true,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ true,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ true,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false,
++ 0x1.0000002p+0, false),
++ TEST ("1.0000000037252902984619140625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ true,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ true,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ true,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ true,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false,
++ 0x1.0000001p+0, false),
++ TEST ("1.00000000186264514923095703125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ true,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ true,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ true,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ true,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false,
++ 0x1.00000008p+0, false),
++ TEST ("1.000000000931322574615478515625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ true,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ true,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ true,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ true,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false,
++ 0x1.00000004p+0, false),
++ TEST ("1.0000000004656612873077392578125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ true,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ true,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ true,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ true,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false,
++ 0x1.00000002p+0, false),
++ TEST ("1.00000000023283064365386962890625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ true,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ true,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ true,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ true,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false,
++ 0x1.00000001p+0, false),
++ TEST ("1.000000000116415321826934814453125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ true,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ true,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ true,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ true,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false,
++ 0x1.000000008p+0, false),
++ TEST ("1.0000000000582076609134674072265625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ true,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ true,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ true,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ true,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false,
++ 0x1.000000004p+0, false),
++ TEST ("1.00000000002910383045673370361328125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ true,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ true,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ true,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ true,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false,
++ 0x1.000000002p+0, false),
++ TEST ("1.000000000014551915228366851806640625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ true,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ true,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ true,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ true,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false,
++ 0x1.000000001p+0, false),
++ TEST ("1.0000000000072759576141834259033203125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ true,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ true,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ true,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ true,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false,
++ 0x1.0000000008p+0, false),
++ TEST ("1.00000000000363797880709171295166015625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ true,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ true,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ true,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ true,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false,
++ 0x1.0000000004p+0, false),
++ TEST ("1.000000000001818989403545856475830078125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ true,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ true,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ true,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ true,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false,
++ 0x1.0000000002p+0, false),
++ TEST ("1.0000000000009094947017729282379150390625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ true,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ true,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ true,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ true,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false,
++ 0x1.0000000001p+0, false),
++ TEST ("1.00000000000045474735088646411895751953125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ true,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ true,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ true,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ true,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false,
++ 0x1.00000000008p+0, false),
++ TEST ("1.000000000000227373675443232059478759765625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ true,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ true,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ true,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ true,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false,
++ 0x1.00000000004p+0, false),
++ TEST ("1.0000000000001136868377216160297393798828125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ true,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ true,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ true,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ true,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false,
++ 0x1.00000000002p+0, false),
++ TEST ("1.00000000000005684341886080801486968994140625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ true,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ true,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ true,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ true,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false,
++ 0x1.00000000001p+0, false),
++ TEST ("1.000000000000028421709430404007434844970703125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ true,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ true,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ true,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ true,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false,
++ 0x1.000000000008p+0, false),
++ TEST ("1.0000000000000142108547152020037174224853515625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ true,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ true,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ true,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ true,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false,
++ 0x1.000000000004p+0, false),
++ TEST ("1.00000000000000710542735760100185871124267578125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ true,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ true,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ true,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ true,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false,
++ 0x1.000000000002p+0, false),
++ TEST ("1.000000000000003552713678800500929355621337890625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ true,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ true,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ true,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ true,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false,
++ 0x1.000000000001p+0, false),
++ TEST ("1.0000000000000017763568394002504646778106689453125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ true,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ true,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ true,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ true,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false,
++ 0x1.0000000000008p+0, false),
++ TEST ("1.00000000000000088817841970012523233890533447265625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ true,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ true,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ true,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ true,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false,
++ 0x1.0000000000004p+0, false),
++ TEST ("1.000000000000000444089209850062616169452667236328125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ true,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ true,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ true,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ true,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false,
++ 0x1.0000000000002p+0, false),
++ TEST ("1.0000000000000002220446049250313080847263336181640625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ true,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false,
++ 0x1.0000000000001p+0, false),
++ TEST ("1.00000000000000011102230246251565404236316680908203125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ true,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ true,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ true,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false,
++ 0x1.00000000000008p+0, false),
++ TEST ("1.000000000000000055511151231257827021181583404541015625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ true,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ true,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ true,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false,
++ 0x1.00000000000004p+0, false),
++ TEST ("1.0000000000000000277555756156289135105907917022705078125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ true,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ true,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ true,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false,
++ 0x1.00000000000002p+0, false),
++ TEST ("1.00000000000000001387778780781445675529539585113525390625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ true,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ true,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ true,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false,
++ 0x1.00000000000001p+0, false),
++ TEST ("1.000000000000000006938893903907228377647697925567626953125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ true,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ true,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ true,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false,
++ 0x1.000000000000008p+0, false),
++ TEST ("1.0000000000000000034694469519536141888238489627838134765625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ true,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ true,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ true,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false,
++ 0x1.000000000000004p+0, false),
++ TEST ("1.0000000000000000017347234759768070944119244813919067382812"
++ "5",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ true,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ true,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ true,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false,
++ 0x1.000000000000002p+0, false),
++ TEST ("1.0000000000000000008673617379884035472059622406959533691406"
++ "25",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ true,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ true,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ true,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false,
++ 0x1.000000000000001p+0, false),
++ TEST ("1.0000000000000000004336808689942017736029811203479766845703"
++ "125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ true,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ true,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ true,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false,
++ 0x1.0000000000000008p+0, false),
++ TEST ("1.0000000000000000002168404344971008868014905601739883422851"
++ "5625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ true,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ true,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ true,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false,
++ 0x1.0000000000000004p+0, false),
++ TEST ("1.0000000000000000001084202172485504434007452800869941711425"
++ "78125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ true,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false,
++ 0x1.0000000000000002p+0, false),
++ TEST ("1.0000000000000000000542101086242752217003726400434970855712"
++ "890625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000001p+0, false,
++ 0x1.0000000000000001p+0, false,
++ 0x1.0000000000000001p+0, false,
++ 0x1.0000000000000001p+0, false,
++ true,
++ 0x1.0000000000000001p+0, false,
++ 0x1.0000000000000001p+0, false,
++ 0x1.0000000000000001p+0, false,
++ 0x1.0000000000000001p+0, false),
++ TEST ("1.0000000000000000000271050543121376108501863200217485427856"
++ "4453125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000008p+0, false,
++ 0x1.00000000000000008p+0, false,
++ 0x1.00000000000000008p+0, false,
++ 0x1.00000000000000008p+0, false,
++ true,
++ 0x1.00000000000000008p+0, false,
++ 0x1.00000000000000008p+0, false,
++ 0x1.00000000000000008p+0, false,
++ 0x1.00000000000000008p+0, false),
++ TEST ("1.0000000000000000000135525271560688054250931600108742713928"
++ "22265625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000004p+0, false,
++ 0x1.00000000000000004p+0, false,
++ 0x1.00000000000000004p+0, false,
++ 0x1.00000000000000004p+0, false,
++ true,
++ 0x1.00000000000000004p+0, false,
++ 0x1.00000000000000004p+0, false,
++ 0x1.00000000000000004p+0, false,
++ 0x1.00000000000000004p+0, false),
++ TEST ("1.0000000000000000000067762635780344027125465800054371356964"
++ "111328125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000002p+0, false,
++ 0x1.00000000000000002p+0, false,
++ 0x1.00000000000000002p+0, false,
++ 0x1.00000000000000002p+0, false,
++ true,
++ 0x1.00000000000000002p+0, false,
++ 0x1.00000000000000002p+0, false,
++ 0x1.00000000000000002p+0, false,
++ 0x1.00000000000000002p+0, false),
++ TEST ("1.0000000000000000000033881317890172013562732900027185678482"
++ "0556640625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000001p+0, false,
++ 0x1.00000000000000001p+0, false,
++ 0x1.00000000000000001p+0, false,
++ 0x1.00000000000000001p+0, false,
++ true,
++ 0x1.00000000000000001p+0, false,
++ 0x1.00000000000000001p+0, false,
++ 0x1.00000000000000001p+0, false,
++ 0x1.00000000000000001p+0, false),
++ TEST ("1.0000000000000000000016940658945086006781366450013592839241"
++ "02783203125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000008p+0, false,
++ 0x1.000000000000000008p+0, false,
++ 0x1.000000000000000008p+0, false,
++ 0x1.000000000000000008p+0, false,
++ true,
++ 0x1.000000000000000008p+0, false,
++ 0x1.000000000000000008p+0, false,
++ 0x1.000000000000000008p+0, false,
++ 0x1.000000000000000008p+0, false),
++ TEST ("1.0000000000000000000008470329472543003390683225006796419620"
++ "513916015625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000004p+0, false,
++ 0x1.000000000000000004p+0, false,
++ 0x1.000000000000000004p+0, false,
++ 0x1.000000000000000004p+0, false,
++ true,
++ 0x1.000000000000000004p+0, false,
++ 0x1.000000000000000004p+0, false,
++ 0x1.000000000000000004p+0, false,
++ 0x1.000000000000000004p+0, false),
++ TEST ("1.0000000000000000000004235164736271501695341612503398209810"
++ "2569580078125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000002p+0, false,
++ 0x1.000000000000000002p+0, false,
++ 0x1.000000000000000002p+0, false,
++ 0x1.000000000000000002p+0, false,
++ true,
++ 0x1.000000000000000002p+0, false,
++ 0x1.000000000000000002p+0, false,
++ 0x1.000000000000000002p+0, false,
++ 0x1.000000000000000002p+0, false),
++ TEST ("1.0000000000000000000002117582368135750847670806251699104905"
++ "12847900390625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000001p+0, false,
++ 0x1.000000000000000001p+0, false,
++ 0x1.000000000000000001p+0, false,
++ 0x1.000000000000000001p+0, false,
++ true,
++ 0x1.000000000000000001p+0, false,
++ 0x1.000000000000000001p+0, false,
++ 0x1.000000000000000001p+0, false,
++ 0x1.000000000000000001p+0, false),
++ TEST ("1.0000000000000000000001058791184067875423835403125849552452"
++ "564239501953125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000008p+0, false,
++ 0x1.0000000000000000008p+0, false,
++ 0x1.0000000000000000008p+0, false,
++ 0x1.0000000000000000008p+0, false,
++ true,
++ 0x1.0000000000000000008p+0, false,
++ 0x1.0000000000000000008p+0, false,
++ 0x1.0000000000000000008p+0, false,
++ 0x1.0000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000529395592033937711917701562924776226"
++ "2821197509765625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000004p+0, false,
++ 0x1.0000000000000000004p+0, false,
++ 0x1.0000000000000000004p+0, false,
++ 0x1.0000000000000000004p+0, false,
++ true,
++ 0x1.0000000000000000004p+0, false,
++ 0x1.0000000000000000004p+0, false,
++ 0x1.0000000000000000004p+0, false,
++ 0x1.0000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000264697796016968855958850781462388113"
++ "14105987548828125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000002p+0, false,
++ 0x1.0000000000000000002p+0, false,
++ 0x1.0000000000000000002p+0, false,
++ 0x1.0000000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000002p+0, false,
++ 0x1.0000000000000000002p+0, false,
++ 0x1.0000000000000000002p+0, false,
++ 0x1.0000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000132348898008484427979425390731194056"
++ "570529937744140625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000001p+0, false,
++ 0x1.0000000000000000001p+0, false,
++ 0x1.0000000000000000001p+0, false,
++ 0x1.0000000000000000001p+0, false,
++ true,
++ 0x1.0000000000000000001p+0, false,
++ 0x1.0000000000000000001p+0, false,
++ 0x1.0000000000000000001p+0, false,
++ 0x1.0000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000066174449004242213989712695365597028"
++ "2852649688720703125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000008p+0, false,
++ 0x1.00000000000000000008p+0, false,
++ 0x1.00000000000000000008p+0, false,
++ 0x1.00000000000000000008p+0, false,
++ true,
++ 0x1.00000000000000000008p+0, false,
++ 0x1.00000000000000000008p+0, false,
++ 0x1.00000000000000000008p+0, false,
++ 0x1.00000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000033087224502121106994856347682798514"
++ "14263248443603515625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000004p+0, false,
++ 0x1.00000000000000000004p+0, false,
++ 0x1.00000000000000000004p+0, false,
++ 0x1.00000000000000000004p+0, false,
++ true,
++ 0x1.00000000000000000004p+0, false,
++ 0x1.00000000000000000004p+0, false,
++ 0x1.00000000000000000004p+0, false,
++ 0x1.00000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000016543612251060553497428173841399257"
++ "071316242218017578125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000002p+0, false,
++ 0x1.00000000000000000002p+0, false,
++ 0x1.00000000000000000002p+0, false,
++ 0x1.00000000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000002p+0, false,
++ 0x1.00000000000000000002p+0, false,
++ 0x1.00000000000000000002p+0, false,
++ 0x1.00000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000008271806125530276748714086920699628"
++ "5356581211090087890625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000001p+0, false,
++ 0x1.00000000000000000001p+0, false,
++ 0x1.00000000000000000001p+0, false,
++ 0x1.00000000000000000001p+0, false,
++ true,
++ 0x1.00000000000000000001p+0, false,
++ 0x1.00000000000000000001p+0, false,
++ 0x1.00000000000000000001p+0, false,
++ 0x1.00000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000004135903062765138374357043460349814"
++ "26782906055450439453125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000008p+0, false,
++ 0x1.000000000000000000008p+0, false,
++ 0x1.000000000000000000008p+0, false,
++ 0x1.000000000000000000008p+0, false,
++ true,
++ 0x1.000000000000000000008p+0, false,
++ 0x1.000000000000000000008p+0, false,
++ 0x1.000000000000000000008p+0, false,
++ 0x1.000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000002067951531382569187178521730174907"
++ "133914530277252197265625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000004p+0, false,
++ 0x1.000000000000000000004p+0, false,
++ 0x1.000000000000000000004p+0, false,
++ 0x1.000000000000000000004p+0, false,
++ true,
++ 0x1.000000000000000000004p+0, false,
++ 0x1.000000000000000000004p+0, false,
++ 0x1.000000000000000000004p+0, false,
++ 0x1.000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000001033975765691284593589260865087453"
++ "5669572651386260986328125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000002p+0, false,
++ 0x1.000000000000000000002p+0, false,
++ 0x1.000000000000000000002p+0, false,
++ 0x1.000000000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000002p+0, false,
++ 0x1.000000000000000000002p+0, false,
++ 0x1.000000000000000000002p+0, false,
++ 0x1.000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000516987882845642296794630432543726"
++ "78347863256931304931640625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000001p+0, false,
++ 0x1.000000000000000000001p+0, false,
++ 0x1.000000000000000000001p+0, false,
++ 0x1.000000000000000000001p+0, false,
++ true,
++ 0x1.000000000000000000001p+0, false,
++ 0x1.000000000000000000001p+0, false,
++ 0x1.000000000000000000001p+0, false,
++ 0x1.000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000258493941422821148397315216271863"
++ "391739316284656524658203125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000008p+0, false,
++ 0x1.0000000000000000000008p+0, false,
++ 0x1.0000000000000000000008p+0, false,
++ 0x1.0000000000000000000008p+0, false,
++ true,
++ 0x1.0000000000000000000008p+0, false,
++ 0x1.0000000000000000000008p+0, false,
++ 0x1.0000000000000000000008p+0, false,
++ 0x1.0000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000000129246970711410574198657608135931"
++ "6958696581423282623291015625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000004p+0, false,
++ 0x1.0000000000000000000004p+0, false,
++ 0x1.0000000000000000000004p+0, false,
++ 0x1.0000000000000000000004p+0, false,
++ true,
++ 0x1.0000000000000000000004p+0, false,
++ 0x1.0000000000000000000004p+0, false,
++ 0x1.0000000000000000000004p+0, false,
++ 0x1.0000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000000064623485355705287099328804067965"
++ "84793482907116413116455078125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000002p+0, false,
++ 0x1.0000000000000000000002p+0, false,
++ 0x1.0000000000000000000002p+0, false,
++ 0x1.0000000000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000002p+0, false,
++ 0x1.0000000000000000000002p+0, false,
++ 0x1.0000000000000000000002p+0, false,
++ 0x1.0000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000032311742677852643549664402033982"
++ "923967414535582065582275390625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000001p+0, false,
++ 0x1.0000000000000000000001p+0, false,
++ 0x1.0000000000000000000001p+0, false,
++ 0x1.0000000000000000000001p+0, false,
++ true,
++ 0x1.0000000000000000000001p+0, false,
++ 0x1.0000000000000000000001p+0, false,
++ 0x1.0000000000000000000001p+0, false,
++ 0x1.0000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000016155871338926321774832201016991"
++ "4619837072677910327911376953125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000008p+0, false,
++ 0x1.00000000000000000000008p+0, false,
++ 0x1.00000000000000000000008p+0, false,
++ 0x1.00000000000000000000008p+0, false,
++ true,
++ 0x1.00000000000000000000008p+0, false,
++ 0x1.00000000000000000000008p+0, false,
++ 0x1.00000000000000000000008p+0, false,
++ 0x1.00000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000000008077935669463160887416100508495"
++ "73099185363389551639556884765625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000004p+0, false,
++ 0x1.00000000000000000000004p+0, false,
++ 0x1.00000000000000000000004p+0, false,
++ 0x1.00000000000000000000004p+0, false,
++ true,
++ 0x1.00000000000000000000004p+0, false,
++ 0x1.00000000000000000000004p+0, false,
++ 0x1.00000000000000000000004p+0, false,
++ 0x1.00000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000000004038967834731580443708050254247"
++ "865495926816947758197784423828125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000002p+0, false,
++ 0x1.00000000000000000000002p+0, false,
++ 0x1.00000000000000000000002p+0, false,
++ 0x1.00000000000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000002p+0, false,
++ 0x1.00000000000000000000002p+0, false,
++ 0x1.00000000000000000000002p+0, false,
++ 0x1.00000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000002019483917365790221854025127123"
++ "9327479634084738790988922119140625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000001p+0, false,
++ 0x1.00000000000000000000001p+0, false,
++ 0x1.00000000000000000000001p+0, false,
++ 0x1.00000000000000000000001p+0, false,
++ true,
++ 0x1.00000000000000000000001p+0, false,
++ 0x1.00000000000000000000001p+0, false,
++ 0x1.00000000000000000000001p+0, false,
++ 0x1.00000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000001009741958682895110927012563561"
++ "96637398170423693954944610595703125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000000008p+0, false,
++ 0x1.000000000000000000000008p+0, false,
++ 0x1.000000000000000000000008p+0, false,
++ 0x1.000000000000000000000008p+0, false,
++ true,
++ 0x1.000000000000000000000008p+0, false,
++ 0x1.000000000000000000000008p+0, false,
++ 0x1.000000000000000000000008p+0, false,
++ 0x1.000000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000000000504870979341447555463506281780"
++ "983186990852118469774723052978515625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000000004p+0, false,
++ 0x1.000000000000000000000004p+0, false,
++ 0x1.000000000000000000000004p+0, false,
++ 0x1.000000000000000000000004p+0, false,
++ true,
++ 0x1.000000000000000000000004p+0, false,
++ 0x1.000000000000000000000004p+0, false,
++ 0x1.000000000000000000000004p+0, false,
++ 0x1.000000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000000000252435489670723777731753140890"
++ "4915934954260592348873615264892578125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000000002p+0, false,
++ 0x1.000000000000000000000002p+0, false,
++ 0x1.000000000000000000000002p+0, false,
++ 0x1.000000000000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000000002p+0, false,
++ 0x1.000000000000000000000002p+0, false,
++ 0x1.000000000000000000000002p+0, false,
++ 0x1.000000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000000126217744835361888865876570445"
++ "24579674771302961744368076324462890625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000000001p+0, false,
++ 0x1.000000000000000000000001p+0, false,
++ 0x1.000000000000000000000001p+0, false,
++ 0x1.000000000000000000000001p+0, false,
++ true,
++ 0x1.000000000000000000000001p+0, false,
++ 0x1.000000000000000000000001p+0, false,
++ 0x1.000000000000000000000001p+0, false,
++ 0x1.000000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000000063108872417680944432938285222"
++ "622898373856514808721840381622314453125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000008p+0, false,
++ true,
++ 0x1.0000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000000000031554436208840472216469142611"
++ "3114491869282574043609201908111572265625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000004p+0, false,
++ true,
++ 0x1.0000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000000000015777218104420236108234571305"
++ "65572459346412870218046009540557861328125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000000007888609052210118054117285652"
++ "827862296732064351090230047702789306640625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.0000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000001p+0, false,
++ true,
++ 0x1.0000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000000003944304526105059027058642826"
++ "4139311483660321755451150238513946533203125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000000008p+0, false,
++ 0x1.00000000000000000000000008p+0, false,
++ 0x1.00000000000000000000000008p+0, false,
++ 0x1.00000000000000000000000008p+0, false,
++ true,
++ 0x1.00000000000000000000000008p+0, false,
++ 0x1.00000000000000000000000008p+0, false,
++ 0x1.00000000000000000000000008p+0, false,
++ 0x1.00000000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000000000001972152263052529513529321413"
++ "20696557418301608777255751192569732666015625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000000004p+0, false,
++ 0x1.00000000000000000000000004p+0, false,
++ 0x1.00000000000000000000000004p+0, false,
++ 0x1.00000000000000000000000004p+0, false,
++ true,
++ 0x1.00000000000000000000000004p+0, false,
++ 0x1.00000000000000000000000004p+0, false,
++ 0x1.00000000000000000000000004p+0, false,
++ 0x1.00000000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000000000000986076131526264756764660706"
++ "603482787091508043886278755962848663330078125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000000002p+0, false,
++ 0x1.00000000000000000000000002p+0, false,
++ 0x1.00000000000000000000000002p+0, false,
++ 0x1.00000000000000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000000002p+0, false,
++ 0x1.00000000000000000000000002p+0, false,
++ 0x1.00000000000000000000000002p+0, false,
++ 0x1.00000000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000000000493038065763132378382330353"
++ "3017413935457540219431393779814243316650390625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.00000000000000000000000001p+0, false,
++ 0x1.00000000000000000000000001p+0, false,
++ 0x1.00000000000000000000000001p+0, false,
++ 0x1.00000000000000000000000001p+0, false,
++ true,
++ 0x1.00000000000000000000000001p+0, false,
++ 0x1.00000000000000000000000001p+0, false,
++ 0x1.00000000000000000000000001p+0, false,
++ 0x1.00000000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000000000246519032881566189191165176"
++ "65087069677287701097156968899071216583251953125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ true,
++ 0x1.000000000000000000000000008p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.000000000000000000000000008p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ 0x1.000000000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000000000000123259516440783094595582588"
++ "325435348386438505485784844495356082916259765625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.000000000000000000000000004p+0, false,
++ 0x1.000000000000000000000000004p+0, false,
++ 0x1.000000000000000000000000004p+0, false,
++ 0x1.000000000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000000000000061629758220391547297791294"
++ "1627176741932192527428924222476780414581298828125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.000000000000000000000000002p+0, false,
++ 0x1.000000000000000000000000002p+0, false,
++ 0x1.000000000000000000000000002p+0, false,
++ 0x1.000000000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000000000030814879110195773648895647"
++ "08135883709660962637144621112383902072906494140625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.000000000000000000000000001p+0, false,
++ 0x1.000000000000000000000000001p+0, false,
++ 0x1.000000000000000000000000001p+0, false,
++ 0x1.000000000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000000000015407439555097886824447823"
++ "540679418548304813185723105561919510364532470703125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.0000000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000000008p+0, false,
++ 0x1.0000000000000000000000000008p+0, false),
++ TEST ("1.0000000000000000000000000000000007703719777548943412223911"
++ "7703397092741524065928615527809597551822662353515625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.0000000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000000004p+0, false,
++ 0x1.0000000000000000000000000004p+0, false),
++ TEST ("1.0000000000000000000000000000000003851859888774471706111955"
++ "88516985463707620329643077639047987759113311767578125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.0000000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000000002p+0, false,
++ 0x1.0000000000000000000000000002p+0, false),
++ TEST ("1.0000000000000000000000000000000001925929944387235853055977"
++ "942584927318538101648215388195239938795566558837890625",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ true,
++ 0x1.0000000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000000001p+0, false,
++ 0x1.0000000000000000000000000001p+0, false),
++ TEST ("1.0000000000000000000000000000000000962964972193617926527988"
++ "9712924636592690508241076940976199693977832794189453125",
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000001p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000002p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.000000000000000000000000008p+0, false,
++ false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1p+0, false,
++ 0x1.0000000000000000000000000001p+0, false),
+ };
+--
+2.19.1
+
diff --git a/Fix-use-after-free-in-glob-when-expanding-user-bug-2.patch b/Fix-use-after-free-in-glob-when-expanding-user-bug-2.patch
new file mode 100644
index 0000000..0156323
--- /dev/null
+++ b/Fix-use-after-free-in-glob-when-expanding-user-bug-2.patch
@@ -0,0 +1,63 @@
+From ddc650e9b3dc916eab417ce9f79e67337b05035c Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Wed, 19 Feb 2020 17:21:46 +0100
+Subject: [PATCH] Fix use-after-free in glob when expanding ~user (bug 25414)
+
+The value of `end_name' points into the value of `dirname', thus don't
+deallocate the latter before the last use of the former.
+---
+ posix/glob.c | 25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/posix/glob.c b/posix/glob.c
+index cba9cd18198..4580cefb9fa 100644
+--- a/posix/glob.c
++++ b/posix/glob.c
+@@ -827,31 +827,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
+ {
+ size_t home_len = strlen (p->pw_dir);
+ size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
+- char *d;
++ char *d, *newp;
++ bool use_alloca = glob_use_alloca (alloca_used,
++ home_len + rest_len + 1);
+
+- if (__glibc_unlikely (malloc_dirname))
+- free (dirname);
+- malloc_dirname = 0;
+-
+- if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
+- dirname = alloca_account (home_len + rest_len + 1,
+- alloca_used);
++ if (use_alloca)
++ newp = alloca_account (home_len + rest_len + 1, alloca_used);
+ else
+ {
+- dirname = malloc (home_len + rest_len + 1);
+- if (dirname == NULL)
++ newp = malloc (home_len + rest_len + 1);
++ if (newp == NULL)
+ {
+ scratch_buffer_free (&pwtmpbuf);
+ retval = GLOB_NOSPACE;
+ goto out;
+ }
+- malloc_dirname = 1;
+ }
+- d = mempcpy (dirname, p->pw_dir, home_len);
++ d = mempcpy (newp, p->pw_dir, home_len);
+ if (end_name != NULL)
+ d = mempcpy (d, end_name, rest_len);
+ *d = '\0';
+
++ if (__glibc_unlikely (malloc_dirname))
++ free (dirname);
++ dirname = newp;
++ malloc_dirname = !use_alloca;
++
+ dirlen = home_len + rest_len;
+ dirname_modified = 1;
+ }
+--
+2.19.1
+
diff --git a/Handle-SEM_STAT_ANY-the-same-way-as-SEM_STAT-so-that.patch b/Handle-SEM_STAT_ANY-the-same-way-as-SEM_STAT-so-that.patch
new file mode 100644
index 0000000..f03cb35
--- /dev/null
+++ b/Handle-SEM_STAT_ANY-the-same-way-as-SEM_STAT-so-that.patch
@@ -0,0 +1,41 @@
+From 574500a108be1d2a6a0dc97a075c9e98371aba Tue Sep 29 17:10:20 2020
+From: Dmitry V. Levin <ldv@altlinux.org>
+Date: Tue, 29 Sep 2020 17:10:20 +0800
+Subject: [PATCH] Handle SEM_STAT_ANY the same way as SEM_STAT so that the
+ buffer argument of SEM_STAT_ANY is properly passed to the kernel and back.
+
+---
+ sysdeps/unix/sysv/linux/semctl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
+index 0c3eb093..15ed333b 100644
+--- a/sysdeps/unix/sysv/linux/semctl.c
++++ b/sysdeps/unix/sysv/linux/semctl.c
+@@ -72,6 +72,7 @@ __new_semctl (int semid, int semnum, int cmd, ...)
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+@@ -127,6 +128,7 @@ __semctl_mode16 (int semid, int semnum, int cmd, ...)
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+@@ -160,6 +162,7 @@ __old_semctl (int semid, int semnum, int cmd, ...)
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
++ case SEM_STAT_ANY:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+--
+2.23.0
+
diff --git a/LanguageList b/LanguageList
new file mode 100644
index 0000000..7ae6391
--- /dev/null
+++ b/LanguageList
@@ -0,0 +1,196 @@
+glibc-langpack-aa
+glibc-langpack-af
+glibc-langpack-agr
+glibc-langpack-ak
+glibc-langpack-am
+glibc-langpack-an
+glibc-langpack-anp
+glibc-langpack-ar
+glibc-langpack-as
+glibc-langpack-ast
+glibc-langpack-ayc
+glibc-langpack-az
+glibc-langpack-be
+glibc-langpack-bem
+glibc-langpack-ber
+glibc-langpack-bg
+glibc-langpack-bhb
+glibc-langpack-bho
+glibc-langpack-bi
+glibc-langpack-bn
+glibc-langpack-bo
+glibc-langpack-br
+glibc-langpack-brx
+glibc-langpack-bs
+glibc-langpack-byn
+glibc-langpack-ca
+glibc-langpack-ce
+glibc-langpack-chr
+glibc-langpack-cmn
+glibc-langpack-crh
+glibc-langpack-cs
+glibc-langpack-csb
+glibc-langpack-cv
+glibc-langpack-cy
+glibc-langpack-da
+glibc-langpack-de
+glibc-langpack-doi
+glibc-langpack-dsb
+glibc-langpack-dv
+glibc-langpack-dz
+glibc-langpack-el
+glibc-langpack-en
+glibc-langpack-eo
+glibc-langpack-es
+glibc-langpack-et
+glibc-langpack-eu
+glibc-langpack-fa
+glibc-langpack-ff
+glibc-langpack-fi
+glibc-langpack-fil
+glibc-langpack-fo
+glibc-langpack-fr
+glibc-langpack-fur
+glibc-langpack-fy
+glibc-langpack-ga
+glibc-langpack-gd
+glibc-langpack-gez
+glibc-langpack-gl
+glibc-langpack-gu
+glibc-langpack-gv
+glibc-langpack-ha
+glibc-langpack-hak
+glibc-langpack-he
+glibc-langpack-hi
+glibc-langpack-hif
+glibc-langpack-hne
+glibc-langpack-hr
+glibc-langpack-hsb
+glibc-langpack-ht
+glibc-langpack-hu
+glibc-langpack-hy
+glibc-langpack-ia
+glibc-langpack-id
+glibc-langpack-ig
+glibc-langpack-ik
+glibc-langpack-is
+glibc-langpack-it
+glibc-langpack-iu
+glibc-langpack-ja
+glibc-langpack-ka
+glibc-langpack-kab
+glibc-langpack-kk
+glibc-langpack-kl
+glibc-langpack-km
+glibc-langpack-kn
+glibc-langpack-ko
+glibc-langpack-kok
+glibc-langpack-ks
+glibc-langpack-ku
+glibc-langpack-kw
+glibc-langpack-ky
+glibc-langpack-lb
+glibc-langpack-lg
+glibc-langpack-li
+glibc-langpack-lij
+glibc-langpack-ln
+glibc-langpack-lo
+glibc-langpack-lt
+glibc-langpack-lv
+glibc-langpack-lzh
+glibc-langpack-mag
+glibc-langpack-mai
+glibc-langpack-mfe
+glibc-langpack-mg
+glibc-langpack-mhr
+glibc-langpack-mi
+glibc-langpack-miq
+glibc-langpack-mjw
+glibc-langpack-mk
+glibc-langpack-ml
+glibc-langpack-mn
+glibc-langpack-mni
+glibc-langpack-mr
+glibc-langpack-ms
+glibc-langpack-mt
+glibc-langpack-my
+glibc-langpack-nan
+glibc-langpack-nb
+glibc-langpack-nds
+glibc-langpack-ne
+glibc-langpack-nhn
+glibc-langpack-niu
+glibc-langpack-nl
+glibc-langpack-nn
+glibc-langpack-nr
+glibc-langpack-nso
+glibc-langpack-oc
+glibc-langpack-om
+glibc-langpack-or
+glibc-langpack-os
+glibc-langpack-pa
+glibc-langpack-pap
+glibc-langpack-pl
+glibc-langpack-ps
+glibc-langpack-pt
+glibc-langpack-quz
+glibc-langpack-raj
+glibc-langpack-ro
+glibc-langpack-ru
+glibc-langpack-rw
+glibc-langpack-sa
+glibc-langpack-sah
+glibc-langpack-sat
+glibc-langpack-sc
+glibc-langpack-sd
+glibc-langpack-se
+glibc-langpack-sgs
+glibc-langpack-shn
+glibc-langpack-shs
+glibc-langpack-si
+glibc-langpack-sid
+glibc-langpack-sk
+glibc-langpack-sl
+glibc-langpack-sm
+glibc-langpack-so
+glibc-langpack-sq
+glibc-langpack-sr
+glibc-langpack-ss
+glibc-langpack-st
+glibc-langpack-sv
+glibc-langpack-sw
+glibc-langpack-szl
+glibc-langpack-ta
+glibc-langpack-tcy
+glibc-langpack-te
+glibc-langpack-tg
+glibc-langpack-th
+glibc-langpack-the
+glibc-langpack-ti
+glibc-langpack-tig
+glibc-langpack-tk
+glibc-langpack-tl
+glibc-langpack-tn
+glibc-langpack-to
+glibc-langpack-tpi
+glibc-langpack-tr
+glibc-langpack-ts
+glibc-langpack-tt
+glibc-langpack-ug
+glibc-langpack-uk
+glibc-langpack-unm
+glibc-langpack-ur
+glibc-langpack-uz
+glibc-langpack-ve
+glibc-langpack-vi
+glibc-langpack-wa
+glibc-langpack-wae
+glibc-langpack-wal
+glibc-langpack-wo
+glibc-langpack-xh
+glibc-langpack-yi
+glibc-langpack-yo
+glibc-langpack-yue
+glibc-langpack-yuw
+glibc-langpack-zh
+glibc-langpack-zu
diff --git a/LicenseList b/LicenseList
new file mode 100644
index 0000000..bcffe7a
--- /dev/null
+++ b/LicenseList
@@ -0,0 +1,26 @@
+In general, GPLv2+ is used by programs, LGPLv2+ is used for
+libraries.
+
+LGPLv2+ with exceptions is used for things that are linked directly
+into dynamically linked programs and shared libraries (e.g. crt
+files, lib*_nonshared.a). Historically, this exception also applies
+to parts of libio.
+
+GPLv2+ with exceptions is used for parts of the Arm unwinder.
+
+GFDL is used for the documentation.
+
+Some other licenses are used in various places (BSD, Inner-Net,
+ISC, Public Domain).
+
+HSRL and FSFAP are only used in test cases, which currently do not
+ship in binary RPMs, so they are not listed here. MIT is used for
+scripts/install-sh, which does not ship, either.
+
+GPLv3+ is used by manual/texinfo.tex, which we do not use.
+
+LGPLv3+ is used by some Hurd code, which we do not build.
+
+LGPLv2 is used in one place (time/timespec_get.c, by mistake), but
+it is not actually compiled, so it does not matter for libraries.
+
diff --git a/Reset-converter-state-after-second-wchar_t-output-Bu.patch b/Reset-converter-state-after-second-wchar_t-output-Bu.patch
new file mode 100644
index 0000000..b616737
--- /dev/null
+++ b/Reset-converter-state-after-second-wchar_t-output-Bu.patch
@@ -0,0 +1,251 @@
+From c580e6466d6da8262820cdbad19f32c5546226cf Mon Sep 17 00:00:00 2001
+From: Carlos O'Donell <carlos@redhat.com>
+Date: Fri, 27 Mar 2020 17:03:36 -0400
+Subject: [PATCH] Reset converter state after second wchar_t output (Bug 25734)
+
+An input BIG5-HKSCS character may be converted into at most 2 wchar_t
+characters. After outputting the second whcar_t character (which was
+saved in the converter state) we must reset the state. If we fail
+to reset the state we will be stuck continually copying that
+character to the output even if we have further input to consider.
+
+We add a new test case that covers the 4 BIG5-HKSCS characters
+that may become 2 wchar_t characters.
+
+Reviewed-by: Tom Honermann <tom@honermann.net>
+---
+ iconvdata/Makefile | 17 ++-
+ iconvdata/big5hkscs.c | 3 +
+ iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c | 160 ++++++++++++++++++++++
+ 3 files changed, 176 insertions(+), 4 deletions(-)
+ create mode 100644 iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index c83962f351b..4ec2741cdce 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -73,7 +73,7 @@ modules.so := $(addsuffix .so, $(modules))
+ 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-iconv11 bug-iconv12
++ bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -275,16 +275,21 @@ endif
+ endif
+ endif
+
+-include ../Rules
+-
+ ifeq ($(run-built-tests),yes)
+-LOCALES := de_DE.UTF-8
++LOCALES := \
++ de_DE.UTF-8 \
++ zh_HK.BIG5-HKSCS \
++ $(NULL)
++
+ include ../gen-locales.mk
+
+ $(objpfx)bug-iconv6.out: $(gen-locales)
+ $(objpfx)tst-iconv7.out: $(gen-locales)
++$(objpfx)tst-iconv-big5-hkscs-to-2ucs4.out: $(gen-locales)
+ endif
+
++include ../Rules
++
+ # Set libof-* for each routine.
+ cpp-srcs-left := $(modules) $(generated-modules) $(libJIS-routines) \
+ $(libKSC-routines) $(libGB-routines) $(libCNS-routines) \
+@@ -340,3 +345,7 @@ tst-tables-clean:
+
+ $(objpfx)gconv-modules: gconv-modules
+ cat $(sysdeps-gconv-modules) $^ > $@
++
++# Test requires BIG5HKSCS.
++$(objpfx)tst-iconv-big5-hkscs-to-2ucs4.out: $(objpfx)gconv-modules \
++ $(addprefix $(objpfx),$(modules.so))
+diff --git a/iconvdata/big5hkscs.c b/iconvdata/big5hkscs.c
+index 01fcfeba76b..ef325119b18 100644
+--- a/iconvdata/big5hkscs.c
++++ b/iconvdata/big5hkscs.c
+@@ -17895,6 +17895,9 @@ static struct
+ else \
+ ++inptr; \
+ } \
++ else \
++ /* Clear the queue and proceed to output the saved character. */ \
++ *statep = 0; \
+ \
+ put32 (outptr, ch); \
+ outptr += 4; \
+diff --git a/iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c b/iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c
+new file mode 100644
+index 00000000000..8389adebf27
+--- /dev/null
++++ b/iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c
+@@ -0,0 +1,160 @@
++/* Verify the BIG5HKSCS outputs that generate 2 wchar_t's (Bug 25734).
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <string.h>
++#include <locale.h>
++#include <wchar.h>
++#include <support/check.h>
++#include <support/support.h>
++
++/* A few BIG5-HKSCS characters map in two unicode code points.
++ They are:
++ /x88/x62 => <U00CA><U0304>
++ /x88/x64 => <U00CA><U030C>
++ /x88/xa3 => <U00EA><U0304>
++ /x88/xa5 => <U00EA><U030C>
++ Each of these is special cased in iconvdata/big5hkscs.c.
++ This test ensures that we correctly reset the shift state after
++ outputting any of these characters. We do this by converting
++ each them followed by converting an ASCII character. If we fail
++ to reset the shift state (bug 25734) then we'll see the last
++ character in the queue output again. */
++
++/* Each test has name, input bytes, and expected wide character
++ output. */
++struct testdata {
++ const char *name;
++ const char input[3];
++ wchar_t expected[3];
++};
++
++/* In BIG5-HKSCS (2008) there are 4 characters that generate multiple
++ wide characters. */
++struct testdata tests[4] = {
++ /* <H-8862>X => <U+00CA><U+0304>X */
++ { "<H-8862>", "\x88\x62\x58", { 0x00CA, 0x0304, 0x0058 } },
++ /* <H-8864>X => <U+00CA><U+030C>X */
++ { "<H-8864>", "\x88\x64\x58", { 0x00CA, 0x030C, 0x0058 } },
++ /* <H-88A3>X => <U+00EA><U+0304>X */
++ { "<H-88A3>", "\x88\xa3\x58", { 0x00EA, 0x0304, 0x0058 } },
++ /* <H-88A5>X => <U+00EA><U+030C>X */
++ { "<H-88A5>", "\x88\xa5\x58", { 0x00EA, 0x030C, 0x0058 } }
++};
++
++/* Each test is of the form:
++ - Translate first code sequence (two bytes)
++ - Translate second (zero bytes)
++ - Translate the third (one byte). */
++static int
++check_conversion (struct testdata test)
++{
++ int err = 0;
++ wchar_t wc;
++ mbstate_t st;
++ size_t ret;
++ const char *mbs = test.input;
++ int consumed = 0;
++ /* Input is always 3 bytes long. */
++ int inlen = 3;
++
++ memset (&st, 0, sizeof (st));
++ /* First conversion: Consumes first 2 bytes. */
++ ret = mbrtowc (&wc, mbs, inlen - consumed, &st);
++ if (ret != 2)
++ {
++ printf ("error: First conversion consumed only %zd bytes.\n", ret);
++ err++;
++ }
++ /* Advance the two consumed bytes. */
++ mbs += ret;
++ consumed += ret;
++ if (wc != test.expected[0])
++ {
++ printf ("error: Result of first conversion was wrong.\n");
++ err++;
++ }
++ /* Second conversion: Consumes 0 bytes. */
++ ret = mbrtowc (&wc, mbs, inlen - consumed, &st);
++ if (ret != 0)
++ {
++ printf ("error: Second conversion consumed only %zd bytes.\n", ret);
++ err++;
++ }
++ /* Advance the zero consumed bytes. */
++ mbs += ret;
++ consumed += ret;
++ if (wc != test.expected[1])
++ {
++ printf ("error: Result of second conversion was wrong.\n");
++ err++;
++ }
++ /* After the second conversion the state of the converter should be
++ in the initial state. It is in the initial state because the two
++ input BIG5-HKSCS bytes have been consumed and the 2 wchar_t's have
++ been output. */
++ if (mbsinit (&st) == 0)
++ {
++ printf ("error: Converter not in initial state.\n");
++ err++;
++ }
++ /* Third conversion: Consumes 1 byte (it's an ASCII character). */
++ ret = mbrtowc (&wc, mbs, inlen - consumed, &st);
++ if (ret != 1)
++ {
++ printf ("error: Third conversion consumed only %zd bytes.\n", ret);
++ err++;
++ }
++ /* Advance the one byte. */
++ mbs += ret;
++ consumed += ret;
++ if (wc != test.expected[2])
++ {
++ printf ("error: Result of third conversion was wrong.\n");
++ err++;
++ }
++ /* Return 0 if we saw no errors. */
++ return err;
++}
++
++static int
++do_test (void)
++{
++ int err = 0;
++ int ret;
++ /* Testing BIG5-HKSCS. */
++ setlocale (LC_ALL, "zh_HK.BIG5-HKSCS");
++
++ /* Run all the special conversions. */
++ for (int i = 0; i < (sizeof (tests) / sizeof (struct testdata)); i++)
++ {
++ printf ("Running test for %s\n", tests[i].name);
++ ret = check_conversion (tests[i]);
++ if (ret > 0)
++ printf ("Test %s failed.\n", tests[i].name);
++ err += ret;
++ }
++
++ /* Fail if any conversion had an error. */
++ if (err > 0)
++ FAIL_EXIT1 ("One or more conversions failed.");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.19.1
+
diff --git a/bench.mk b/bench.mk
new file mode 100644
index 0000000..dfe46bd
--- /dev/null
+++ b/bench.mk
@@ -0,0 +1,77 @@
+objpfx = $(prefix)/$(ver)/usr/libexec/glibc-benchtests/
+
+bench-math := acos acosh asin asinh atan atanh cos cosh exp exp2 ffs ffsll \
+ log log2 modf pow rint sin sincos sinh sqrt tan tanh
+
+bench-pthread := pthread_once
+
+bench := $(bench-math) $(bench-pthread)
+
+run-bench := $(prefix)/$(ver)/lib64/ld-linux-x86-64.so.2 --library-path $(prefix)/$(ver)/lib64 $${run}
+
+# String function benchmarks.
+string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \
+ mempcpy memset rawmemchr stpcpy stpncpy strcasecmp strcasestr \
+ strcat strchr strchrnul strcmp strcpy strcspn strlen \
+ strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \
+ strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok
+string-bench-all := $(string-bench)
+
+stdlib-bench := strtod
+
+benchset := $(string-bench-all) $(stdlib-bench)
+
+bench-malloc := malloc-thread
+
+binaries-bench := $(addprefix $(objpfx)bench-,$(bench))
+binaries-benchset := $(addprefix $(objpfx)bench-,$(benchset))
+binaries-bench-malloc := $(addprefix $(objpfx)bench-,$(bench-malloc))
+
+DETAILED_OPT :=
+
+ifdef DETAILED
+ DETAILED_OPT := -d
+endif
+
+bench: bench-set bench-func bench-malloc
+
+bench-set: $(binaries-benchset)
+ for run in $^; do \
+ outfile=$(prefix)/$$(basename $${run}.$(ver).out); \
+ echo "Running $${run}"; \
+ $(run-bench) > $${outfile}.tmp; \
+ mv $${outfile}{.tmp,}; \
+ done
+
+bench-malloc: $(binaries-bench-malloc)
+ run=$(objpfx)bench-malloc-thread; \
+ outfile=$(prefix)/$$(basename $${run}.$(ver).out); \
+ for thr in 1 8 16 32; do \
+ echo "Running $${run} $${thr}"; \
+ $(run-bench) $${thr} > $${outfile}.tmp; \
+ mv $${outfile}{.tmp,}; \
+ done
+
+# Build and execute the benchmark functions. This target generates JSON
+# formatted bench.out. Each of the programs produce independent JSON output,
+# so one could even execute them individually and process it using any JSON
+# capable language or tool.
+bench-func: $(binaries-bench)
+ { echo "{\"timing_type\": \"hp-timing\","; \
+ echo " \"functions\": {"; \
+ for run in $^; do \
+ if ! [ "x$${run}" = "x$<" ]; then \
+ echo ","; \
+ fi; \
+ echo "Running $${run}" >&2; \
+ $(run-bench) $(DETAILED_OPT); \
+ done; \
+ echo; \
+ echo " }"; \
+ echo "}"; } > $(prefix)/bench.$(ver).out-tmp; \
+ if [ -f $(prefix)/bench.$(ver).out ]; then \
+ mv -f $(prefix)/bench.$(ver).out{,.old}; \
+ fi; \
+ mv -f $(prefix)/bench.$(ver).out{-tmp,}
+# scripts/validate_benchout.py bench.out \
+# scripts/benchout.schema.json
diff --git a/build-extra-libpthreadcond-so.patch b/build-extra-libpthreadcond-so.patch
new file mode 100644
index 0000000..8d80f07
--- /dev/null
+++ b/build-extra-libpthreadcond-so.patch
@@ -0,0 +1,4935 @@
+From 808cf7c45e187c1889867ac83d047abfdf81c7a3 Mon Sep 17 00:00:00 2001
+From: root <root@localhost.localdomain>
+Date: Fri, 14 Aug 2020 17:41:59 +0800
+Subject: [PATCH] performance degradation in multi-core scenarios, here is an
+ extra libpthreadcond.so using old version of the function. you can use it by
+ adding LD_PRELOAD=./libpthreadcond.so in front of your program (eg:
+ LD_PRELOAD=./libpthreadcond.so ./test). use with-libpthreadcond to compile
+ it. warning:2.17 version does not meet the posix standard, you should pay
+ attention when using it.
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=ed19993b5b0d05d62cc883571519a67dae481a14
+
+
+diff --git a/nptl_2_17/Makefile b/nptl_2_17/Makefile
+new file mode 100644
+index 00000000..4c30c5f1
+--- /dev/null
++++ b/nptl_2_17/Makefile
+@@ -0,0 +1,52 @@
++include libpthreadcond_config
++subdir=libpthreadcond
++objdir=../$(build_dir)/
++
++
++ifdef subdir
++.. := ../
++endif
++
++objpfx := $(patsubst %//,%/,$(objdir)/$(subdir)/)
++common-objpfx = $(objdir)/
++common-objdir = $(objdir)
++
++sysdep_dir := $(..)sysdeps
++export sysdep_dir := $(sysdep_dir)
++
++include $(common-objpfx)soversions.mk
++include $(common-objpfx)config.make
++
++uses-callbacks = -fexceptions
++
++sysdirs := $(foreach D,$(config-sysdirs),$(firstword $(filter /%,$D) $(..)$D))
++
+++sysdep_dirs = $(sysdirs)
+++sysdep_dirs := $(objdir) $(+sysdep_dirs)
++
+++sysdep-includes := $(foreach dir,$(+sysdep_dirs), $(addprefix -I,$(wildcard $(dir)/include) $(dir)))
++
++compile_obj = vars_2_17.os pthread_cond_wait_2_17.os pthread_cond_timedwait_2_17.os pthread_cond_signal_2_17.os pthread_cond_broadcast_2_17.os pthread_cond_init_2_17.os pthread_cond_destroy_2_17.os cleanup_compat_2_17.os unwind_2_17.os cancellation_2_17.os pthread_mutex_cond_lock_2_17.os pthread_mutex_lock_2_17.os pthread_mutex_unlock_2_17.os pthread_condattr_getclock_2_17.os pthread_condattr_getpshared_2_17.os pthread_condattr_init_2_17.os pthread_condattr_setclock_2_17.os tpp_2_17.os
++compile_obj_dir = $(foreach n,$(compile_obj),../$(build_dir)/nptl/$(n))
++
++exist_obj = lowlevellock.os lll_timedlock_wait.os pthread_mutex_conf.os
++ifeq (x86_64, $(arch))
++exist_obj += elision-lock.os elision-unlock.os elision-timed.os elision-trylock.os
++endif
++
++exist_obj_dir = $(foreach n,$(exist_obj),../$(build_dir)/nptl/$(n))
++
++CFLAGS = -c -std=gnu11 -fgnu89-inline -g -O2 -Wall -Wwrite-strings -Wundef -Werror -fmerge-all-constants -frounding-math -fno-stack-protector -Wstrict-prototypes -Wold-style-definition -fmath-errno -fPIC -ftls-model=initial-exec -DPIC -DSHARED -DTOP_NAMESPACE=glibc
++
++Headers = -I../include -I../$(build_dir)/nptl $(+sysdep-includes) -I../nptl_2_17 -I../nptl -I../libio -I../. -D_LIBC_REENTRANT -include ../$(build_dir)/libc-modules.h -include include/libc-symbols.h
++
++all: libpthreadcond.so
++
++libpthreadcond.so : $(compile_obj) libpthreadcond_pic.a
++ gcc -shared -static-libgcc -Wl,-O1 -Wl,-z,defs -Wl,-dynamic-linker=/usr/local/lib/$(ld.so-version) -B../$(build_dir)/csu/ -Wl,--version-script=libpthreadcond-$(arch).map -Wl,-soname=libpthreadcond.so.0 -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -L../$(build_dir) -L../$(build_dir)/math -L../$(build_dir)/elf -L../$(build_dir)/dlfcn -L../$(build_dir)/nss -L../$(build_dir)/nis -L../$(build_dir)/rt -L../$(build_dir)/resolv -L../$(build_dir)/mathvec -L../$(build_dir)/support -L../$(build_dir)/crypt -L../$(build_dir)/nptl -Wl,-rpath-link=../$(build_dir):../$(build_dir)/math:../$(build_dir)/elf:../$(build_dir)/dlfcn:../$(build_dir)/nss:../$(build_dir)/nis:../$(build_dir)/rt:../$(build_dir)/resolv:../$(build_dir)/mathvec:../$(build_dir)/support:../$(build_dir)/crypt:../$(build_dir)/nptl -o ../$(build_dir)/nptl/libpthreadcond.so ../$(build_dir)/csu/abi-note.o -Wl,--whole-archive ../$(build_dir)/nptl/libpthreadcond_pic.a -Wl,--no-whole-archive -Wl,--start-group ../$(build_dir)/libc.so ../$(build_dir)/libc_nonshared.a -Wl,--as-needed ../$(build_dir)/elf/ld.so -Wl,--no-as-needed -Wl,--end-group
++
++libpthreadcond_pic.a : $(compile_obj_dir) $(exist_obj_dir)
++ ar cruv ../$(build_dir)/nptl/$@ $^
++
++$(compile_obj) : %.os : %.c
++ gcc $< $(CFLAGS) $(Headers) -o ../$(build_dir)/nptl/$@ -MD -MP -MF ../$(build_dir)/nptl/$@.dt -MT ../$(build_dir)/nptl/$@
+diff --git a/nptl_2_17/bits/pthreadtypes_2_17.h b/nptl_2_17/bits/pthreadtypes_2_17.h
+new file mode 100644
+index 00000000..f501ea4c
+--- /dev/null
++++ b/nptl_2_17/bits/pthreadtypes_2_17.h
+@@ -0,0 +1,121 @@
++/* Declaration of common pthread types for all architectures.
++ Copyright (C) 2017-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#ifndef _BITS_PTHREADTYPES_COMMON_H
++# define _BITS_PTHREADTYPES_COMMON_H 1
++
++/* For internal mutex and condition variable definitions. */
++#include <bits/thread-shared-types_2_17.h>
++
++/* Thread identifiers. The structure of the attribute type is not
++ exposed on purpose. */
++typedef unsigned long int pthread_t;
++
++
++/* Data structures for mutex handling. The structure of the attribute
++ type is not exposed on purpose. */
++typedef union
++{
++ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
++ int __align;
++} pthread_mutexattr_t;
++
++
++/* Data structure for condition variable handling. The structure of
++ the attribute type is not exposed on purpose. */
++typedef union
++{
++ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
++ int __align;
++} pthread_condattr_t;
++
++
++/* Keys for thread-specific data */
++typedef unsigned int pthread_key_t;
++
++
++/* Once-only execution */
++typedef int __ONCE_ALIGNMENT pthread_once_t;
++
++
++union pthread_attr_t
++{
++ char __size[__SIZEOF_PTHREAD_ATTR_T];
++ long int __align;
++};
++#ifndef __have_pthread_attr_t
++typedef union pthread_attr_t pthread_attr_t;
++# define __have_pthread_attr_t 1
++#endif
++
++
++typedef union
++{
++ struct __pthread_mutex_s __data;
++ char __size[__SIZEOF_PTHREAD_MUTEX_T];
++ long int __align;
++} pthread_mutex_t;
++
++
++typedef union
++{
++ struct __pthread_cond_s __data;
++ char __size[__SIZEOF_PTHREAD_COND_T];
++ __extension__ long long int __align;
++} pthread_cond_t;
++
++
++#if defined __USE_UNIX98 || defined __USE_XOPEN2K
++/* Data structure for reader-writer lock variable handling. The
++ structure of the attribute type is deliberately not exposed. */
++typedef union
++{
++ struct __pthread_rwlock_arch_t __data;
++ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
++ long int __align;
++} pthread_rwlock_t;
++
++typedef union
++{
++ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
++ long int __align;
++} pthread_rwlockattr_t;
++#endif
++
++
++#ifdef __USE_XOPEN2K
++/* POSIX spinlock data type. */
++typedef volatile int pthread_spinlock_t;
++
++
++/* POSIX barriers data type. The structure of the type is
++ deliberately not exposed. */
++typedef union
++{
++ char __size[__SIZEOF_PTHREAD_BARRIER_T];
++ long int __align;
++} pthread_barrier_t;
++
++typedef union
++{
++ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
++ int __align;
++} pthread_barrierattr_t;
++#endif
++
++#endif
+diff --git a/nptl_2_17/bits/thread-shared-types_2_17.h b/nptl_2_17/bits/thread-shared-types_2_17.h
+new file mode 100644
+index 00000000..50e86261
+--- /dev/null
++++ b/nptl_2_17/bits/thread-shared-types_2_17.h
+@@ -0,0 +1,104 @@
++/* Common threading primitives definitions for both POSIX and C11.
++ Copyright (C) 2017-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#ifndef _THREAD_SHARED_TYPES_H
++#define _THREAD_SHARED_TYPES_H 1
++
++/* Arch-specific definitions. Each architecture must define the following
++ macros to define the expected sizes of pthread data types:
++
++ __SIZEOF_PTHREAD_ATTR_T - size of pthread_attr_t.
++ __SIZEOF_PTHREAD_MUTEX_T - size of pthread_mutex_t.
++ __SIZEOF_PTHREAD_MUTEXATTR_T - size of pthread_mutexattr_t.
++ __SIZEOF_PTHREAD_COND_T - size of pthread_cond_t.
++ __SIZEOF_PTHREAD_CONDATTR_T - size of pthread_condattr_t.
++ __SIZEOF_PTHREAD_RWLOCK_T - size of pthread_rwlock_t.
++ __SIZEOF_PTHREAD_RWLOCKATTR_T - size of pthread_rwlockattr_t.
++ __SIZEOF_PTHREAD_BARRIER_T - size of pthread_barrier_t.
++ __SIZEOF_PTHREAD_BARRIERATTR_T - size of pthread_barrierattr_t.
++
++ The additional macro defines any constraint for the lock alignment
++ inside the thread structures:
++
++ __LOCK_ALIGNMENT - for internal lock/futex usage.
++
++ Same idea but for the once locking primitive:
++
++ __ONCE_ALIGNMENT - for pthread_once_t/once_flag definition. */
++
++#include <bits/pthreadtypes-arch.h>
++
++
++/* Common definition of pthread_mutex_t. */
++
++typedef struct __pthread_internal_list
++{
++ struct __pthread_internal_list *__prev;
++ struct __pthread_internal_list *__next;
++} __pthread_list_t;
++
++typedef struct __pthread_internal_slist
++{
++ struct __pthread_internal_slist *__next;
++} __pthread_slist_t;
++
++/* Arch-specific mutex definitions. A generic implementation is provided
++ by sysdeps/nptl/bits/struct_mutex.h. If required, an architecture
++ can override it by defining:
++
++ 1. struct __pthread_mutex_s (used on both pthread_mutex_t and mtx_t
++ definition). It should contains at least the internal members
++ defined in the generic version.
++
++ 2. __LOCK_ALIGNMENT for any extra attribute for internal lock used with
++ atomic operations.
++
++ 3. The macro __PTHREAD_MUTEX_INITIALIZER used for static initialization.
++ It should initialize the mutex internal flag. */
++
++#include <bits/struct_mutex.h>
++
++/* Arch-sepecific read-write lock definitions. A generic implementation is
++ provided by struct_rwlock.h. If required, an architecture can override it
++ by defining:
++
++ 1. struct __pthread_rwlock_arch_t (used on pthread_rwlock_t definition).
++ It should contain at least the internal members defined in the
++ generic version.
++
++ 2. The macro __PTHREAD_RWLOCK_INITIALIZER used for static initialization.
++ It should initialize the rwlock internal type. */
++
++#include <bits/struct_rwlock.h>
++
++
++/* Common definition of pthread_cond_t. */
++
++struct __pthread_cond_s
++{
++ int __lock;
++ unsigned int __futex;
++ __extension__ unsigned long long int __total_seq;
++ __extension__ unsigned long long int __wakeup_seq;
++ __extension__ unsigned long long int __woken_seq;
++ void *__mutex;
++ unsigned int __nwaiters;
++ unsigned int __broadcast_seq;
++};
++
++#endif /* _THREAD_SHARED_TYPES_H */
+diff --git a/nptl_2_17/build_libpthreadcondso.sh b/nptl_2_17/build_libpthreadcondso.sh
+new file mode 100644
+index 00000000..6997277b
+--- /dev/null
++++ b/nptl_2_17/build_libpthreadcondso.sh
+@@ -0,0 +1,9 @@
++#!/bin/sh
++build_arch=$1
++build_dir=$2
++config_dir=libpthreadcond_config
++
++echo arch=${build_arch} > ${config_dir}
++echo build_dir=${build_dir} >> ${config_dir}
++make
++rm -rf ${config_dir}
+diff --git a/nptl_2_17/cancellation_2_17.c b/nptl_2_17/cancellation_2_17.c
+new file mode 100644
+index 00000000..644d83bf
+--- /dev/null
++++ b/nptl_2_17/cancellation_2_17.c
+@@ -0,0 +1,104 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++#include <setjmp.h>
++#include <stdlib.h>
++#include <futex-internal.h>
++
++
++/* The next two functions are similar to pthread_setcanceltype() but
++ more specialized for the use in the cancelable functions like write().
++ They do not need to check parameters etc. These functions must be
++ AS-safe, with the exception of the actual cancellation, because they
++ are called by wrappers around AS-safe functions like write().*/
++int
++attribute_hidden
++__pthread_enable_asynccancel (void)
++{
++ struct pthread *self = THREAD_SELF;
++ int oldval = THREAD_GETMEM (self, cancelhandling);
++
++ while (1)
++ {
++ int newval = oldval | CANCELTYPE_BITMASK;
++
++ if (newval == oldval)
++ break;
++
++ int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
++ oldval);
++ if (__glibc_likely (curval == oldval))
++ {
++ if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
++ {
++ THREAD_SETMEM (self, result, PTHREAD_CANCELED);
++ __do_cancel ();
++ }
++
++ break;
++ }
++
++ /* Prepare the next round. */
++ oldval = curval;
++ }
++
++ return oldval;
++}
++
++/* See the comment for __pthread_enable_asynccancel regarding
++ the AS-safety of this function. */
++void
++attribute_hidden
++__pthread_disable_asynccancel (int oldtype)
++{
++ /* If asynchronous cancellation was enabled before we do not have
++ anything to do. */
++ if (oldtype & CANCELTYPE_BITMASK)
++ return;
++
++ struct pthread *self = THREAD_SELF;
++ int newval;
++
++ int oldval = THREAD_GETMEM (self, cancelhandling);
++
++ while (1)
++ {
++ newval = oldval & ~CANCELTYPE_BITMASK;
++
++ int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
++ oldval);
++ if (__glibc_likely (curval == oldval))
++ break;
++
++ /* Prepare the next round. */
++ oldval = curval;
++ }
++
++ /* We cannot return when we are being canceled. Upon return the
++ thread might be things which would have to be undone. The
++ following loop should loop until the cancellation signal is
++ delivered. */
++ while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
++ == CANCELING_BITMASK, 0))
++ {
++ futex_wait_simple ((unsigned int *) &self->cancelhandling, newval,
++ FUTEX_PRIVATE);
++ newval = THREAD_GETMEM (self, cancelhandling);
++ }
++}
+diff --git a/nptl_2_17/cleanup_compat_2_17.c b/nptl_2_17/cleanup_compat_2_17.c
+new file mode 100644
+index 00000000..ccc55836
+--- /dev/null
++++ b/nptl_2_17/cleanup_compat_2_17.c
+@@ -0,0 +1,50 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdlib.h>
++#include "pthreadP_2_17.h"
++
++
++void
++_pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
++ void (*routine) (void *), void *arg)
++{
++ struct pthread *self = THREAD_SELF;
++
++ buffer->__routine = routine;
++ buffer->__arg = arg;
++ buffer->__prev = THREAD_GETMEM (self, cleanup);
++
++ THREAD_SETMEM (self, cleanup, buffer);
++}
++strong_alias (_pthread_cleanup_push, __pthread_cleanup_push)
++
++
++void
++_pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer, int execute)
++{
++ struct pthread *self __attribute ((unused)) = THREAD_SELF;
++
++ THREAD_SETMEM (self, cleanup, buffer->__prev);
++
++ /* If necessary call the cleanup routine after we removed the
++ current cleanup block from the list. */
++ if (execute)
++ buffer->__routine (buffer->__arg);
++}
++strong_alias (_pthread_cleanup_pop, __pthread_cleanup_pop)
+diff --git a/nptl_2_17/libpthreadcond-aarch64.map b/nptl_2_17/libpthreadcond-aarch64.map
+new file mode 100644
+index 00000000..d970af06
+--- /dev/null
++++ b/nptl_2_17/libpthreadcond-aarch64.map
+@@ -0,0 +1,8 @@
++GLIBC_2.17 {
++ global:
++ pthread_cond_init; pthread_cond_destroy;
++ pthread_cond_signal; pthread_cond_broadcast;
++ pthread_cond_wait; pthread_cond_timedwait;
++ local:
++ *;
++};
+diff --git a/nptl_2_17/libpthreadcond-x86_64.map b/nptl_2_17/libpthreadcond-x86_64.map
+new file mode 100644
+index 00000000..d7f23322
+--- /dev/null
++++ b/nptl_2_17/libpthreadcond-x86_64.map
+@@ -0,0 +1,8 @@
++GLIBC_2.3.2 {
++ global:
++ pthread_cond_init; pthread_cond_destroy;
++ pthread_cond_signal; pthread_cond_broadcast;
++ pthread_cond_wait; pthread_cond_timedwait;
++ local:
++ *;
++};
+diff --git a/nptl_2_17/pthreadP_2_17.h b/nptl_2_17/pthreadP_2_17.h
+new file mode 100644
+index 00000000..e195221a
+--- /dev/null
++++ b/nptl_2_17/pthreadP_2_17.h
+@@ -0,0 +1,620 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#ifndef _PTHREADP_H
++#define _PTHREADP_H 1
++
++#include <pthread_2_17.h>
++#include <setjmp.h>
++#include <stdbool.h>
++#include <sys/syscall.h>
++#include "descr.h"
++#include <tls.h>
++#include <lowlevellock.h>
++#include <stackinfo.h>
++#include <internaltypes.h>
++#include <pthread-functions.h>
++#include <atomic.h>
++#include <kernel-features.h>
++#include <errno.h>
++#include <internal-signals.h>
++#include "pthread_mutex_conf.h"
++
++
++/* Atomic operations on TLS memory. */
++#ifndef THREAD_ATOMIC_CMPXCHG_VAL
++# define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, new, old) \
++ atomic_compare_and_exchange_val_acq (&(descr)->member, new, old)
++#endif
++
++#ifndef THREAD_ATOMIC_BIT_SET
++# define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
++ atomic_bit_set (&(descr)->member, bit)
++#endif
++
++
++static inline short max_adaptive_count (void)
++{
++#if HAVE_TUNABLES
++ return __mutex_aconf.spin_count;
++#else
++ return DEFAULT_ADAPTIVE_COUNT;
++#endif
++}
++
++
++/* Magic cookie representing robust mutex with dead owner. */
++#define PTHREAD_MUTEX_INCONSISTENT INT_MAX
++/* Magic cookie representing not recoverable robust mutex. */
++#define PTHREAD_MUTEX_NOTRECOVERABLE (INT_MAX - 1)
++
++#define COND_NWAITERS_SHIFT 1
++
++/* Internal mutex type value. */
++enum
++{
++ PTHREAD_MUTEX_KIND_MASK_NP = 3,
++
++ PTHREAD_MUTEX_ELISION_NP = 256,
++ PTHREAD_MUTEX_NO_ELISION_NP = 512,
++
++ PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
++ PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
++ = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP,
++ PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP
++ = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
++ PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
++ = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
++ PTHREAD_MUTEX_PRIO_INHERIT_NP = 32,
++ PTHREAD_MUTEX_PI_NORMAL_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_NORMAL,
++ PTHREAD_MUTEX_PI_RECURSIVE_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
++ PTHREAD_MUTEX_PI_ERRORCHECK_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
++ PTHREAD_MUTEX_PI_ADAPTIVE_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
++ PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP,
++ PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_RECURSIVE_NP,
++ PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP,
++ PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP
++ = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP,
++ PTHREAD_MUTEX_PRIO_PROTECT_NP = 64,
++ PTHREAD_MUTEX_PP_NORMAL_NP
++ = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_NORMAL,
++ PTHREAD_MUTEX_PP_RECURSIVE_NP
++ = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
++ PTHREAD_MUTEX_PP_ERRORCHECK_NP
++ = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
++ PTHREAD_MUTEX_PP_ADAPTIVE_NP
++ = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
++ PTHREAD_MUTEX_ELISION_FLAGS_NP
++ = PTHREAD_MUTEX_ELISION_NP | PTHREAD_MUTEX_NO_ELISION_NP,
++
++ PTHREAD_MUTEX_TIMED_ELISION_NP =
++ PTHREAD_MUTEX_TIMED_NP | PTHREAD_MUTEX_ELISION_NP,
++ PTHREAD_MUTEX_TIMED_NO_ELISION_NP =
++ PTHREAD_MUTEX_TIMED_NP | PTHREAD_MUTEX_NO_ELISION_NP,
++};
++#define PTHREAD_MUTEX_PSHARED_BIT 128
++
++/* See concurrency notes regarding __kind in struct __pthread_mutex_s
++ in sysdeps/nptl/bits/thread-shared-types.h. */
++#define PTHREAD_MUTEX_TYPE(m) \
++ (atomic_load_relaxed (&((m)->__data.__kind)) & 127)
++/* Don't include NO_ELISION, as that type is always the same
++ as the underlying lock type. */
++#define PTHREAD_MUTEX_TYPE_ELISION(m) \
++ (atomic_load_relaxed (&((m)->__data.__kind)) \
++ & (127 | PTHREAD_MUTEX_ELISION_NP))
++
++#if LLL_PRIVATE == 0 && LLL_SHARED == 128
++# define PTHREAD_MUTEX_PSHARED(m) \
++ (atomic_load_relaxed (&((m)->__data.__kind)) & 128)
++#else
++# define PTHREAD_MUTEX_PSHARED(m) \
++ ((atomic_load_relaxed (&((m)->__data.__kind)) & 128) \
++ ? LLL_SHARED : LLL_PRIVATE)
++#endif
++
++/* The kernel when waking robust mutexes on exit never uses
++ FUTEX_PRIVATE_FLAG FUTEX_WAKE. */
++#define PTHREAD_ROBUST_MUTEX_PSHARED(m) LLL_SHARED
++
++/* Ceiling in __data.__lock. __data.__lock is signed, so don't
++ use the MSB bit in there, but in the mask also include that bit,
++ so that the compiler can optimize & PTHREAD_MUTEX_PRIO_CEILING_MASK
++ masking if the value is then shifted down by
++ PTHREAD_MUTEX_PRIO_CEILING_SHIFT. */
++#define PTHREAD_MUTEX_PRIO_CEILING_SHIFT 19
++#define PTHREAD_MUTEX_PRIO_CEILING_MASK 0xfff80000
++
++
++/* Flags in mutex attr. */
++#define PTHREAD_MUTEXATTR_PROTOCOL_SHIFT 28
++#define PTHREAD_MUTEXATTR_PROTOCOL_MASK 0x30000000
++#define PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT 12
++#define PTHREAD_MUTEXATTR_PRIO_CEILING_MASK 0x00fff000
++#define PTHREAD_MUTEXATTR_FLAG_ROBUST 0x40000000
++#define PTHREAD_MUTEXATTR_FLAG_PSHARED 0x80000000
++#define PTHREAD_MUTEXATTR_FLAG_BITS \
++ (PTHREAD_MUTEXATTR_FLAG_ROBUST | PTHREAD_MUTEXATTR_FLAG_PSHARED \
++ | PTHREAD_MUTEXATTR_PROTOCOL_MASK | PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
++
++
++/* For the following, see pthread_rwlock_common.c. */
++#define PTHREAD_RWLOCK_WRPHASE 1
++#define PTHREAD_RWLOCK_WRLOCKED 2
++#define PTHREAD_RWLOCK_RWAITING 4
++#define PTHREAD_RWLOCK_READER_SHIFT 3
++#define PTHREAD_RWLOCK_READER_OVERFLOW ((unsigned int) 1 \
++ << (sizeof (unsigned int) * 8 - 1))
++#define PTHREAD_RWLOCK_WRHANDOVER ((unsigned int) 1 \
++ << (sizeof (unsigned int) * 8 - 1))
++#define PTHREAD_RWLOCK_FUTEX_USED 2
++
++
++/* Bits used in robust mutex implementation. */
++#define FUTEX_WAITERS 0x80000000
++#define FUTEX_OWNER_DIED 0x40000000
++#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
++
++/* Attribute to indicate thread creation was issued from C11 thrd_create. */
++#define ATTR_C11_THREAD ((void*)(uintptr_t)-1)
++
++#if 0
++/* Condition variable definitions. See __pthread_cond_wait_common.
++ Need to be defined here so there is one place from which
++ nptl_lock_constants can grab them. */
++#define __PTHREAD_COND_CLOCK_MONOTONIC_MASK 2
++#define __PTHREAD_COND_SHARED_MASK 1
++#endif
++
++/* Internal variables. */
++
++
++/* Default pthread attributes. */
++extern struct pthread_attr __default_pthread_attr attribute_hidden;
++extern int __default_pthread_attr_lock attribute_hidden;
++
++/* Size and alignment of static TLS block. */
++extern size_t __static_tls_size attribute_hidden;
++extern size_t __static_tls_align_m1 attribute_hidden;
++
++/* Flag whether the machine is SMP or not. */
++extern int __is_smp attribute_hidden;
++
++/* Thread descriptor handling. */
++extern list_t __stack_user;
++hidden_proto (__stack_user)
++
++/* Attribute handling. */
++extern struct pthread_attr *__attr_list attribute_hidden;
++extern int __attr_list_lock attribute_hidden;
++
++/* Concurrency handling. */
++extern int __concurrency_level attribute_hidden;
++
++/* Thread-local data key handling. */
++extern struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX];
++hidden_proto (__pthread_keys)
++
++/* Number of threads running. */
++extern unsigned int __nptl_nthreads attribute_hidden;
++
++#ifndef __ASSUME_SET_ROBUST_LIST
++/* Negative if we do not have the system call and we can use it. */
++extern int __set_robust_list_avail attribute_hidden;
++#endif
++
++/* Thread Priority Protection. */
++extern int __sched_fifo_min_prio attribute_hidden;
++extern int __sched_fifo_max_prio attribute_hidden;
++extern void __init_sched_fifo_prio (void) attribute_hidden;
++extern int __pthread_tpp_change_priority (int prev_prio, int new_prio)
++ attribute_hidden;
++extern int __pthread_current_priority (void) attribute_hidden;
++
++/* The library can run in debugging mode where it performs a lot more
++ tests. */
++extern int __pthread_debug attribute_hidden;
++/** For now disable debugging support. */
++#if 0
++# define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
++# define INVALID_TD_P(pd) (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
++# define INVALID_NOT_TERMINATED_TD_P(pd) INVALID_TD_P (pd)
++#else
++# define DEBUGGING_P 0
++/* Simplified test. This will not catch all invalid descriptors but
++ is better than nothing. And if the test triggers the thread
++ descriptor is guaranteed to be invalid. */
++# define INVALID_TD_P(pd) __builtin_expect ((pd)->tid <= 0, 0)
++# define INVALID_NOT_TERMINATED_TD_P(pd) __builtin_expect ((pd)->tid < 0, 0)
++#endif
++
++
++/* Cancellation test. */
++#define CANCELLATION_P(self) \
++ do { \
++ int cancelhandling = THREAD_GETMEM (self, cancelhandling); \
++ if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \
++ { \
++ THREAD_SETMEM (self, result, PTHREAD_CANCELED); \
++ __do_cancel (); \
++ } \
++ } while (0)
++
++
++extern void __pthread_unwind (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute __attribute ((__noreturn__))
++ ;
++extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute __attribute ((__noreturn__))
++#ifndef SHARED
++ weak_function
++#endif
++ ;
++extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute;
++extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute;
++hidden_proto (__pthread_unwind)
++hidden_proto (__pthread_unwind_next)
++hidden_proto (__pthread_register_cancel)
++hidden_proto (__pthread_unregister_cancel)
++# ifdef SHARED
++extern void attribute_hidden pthread_cancel_init (void);
++# endif
++extern void __nptl_unwind_freeres (void) attribute_hidden;
++
++/* Called when a thread reacts on a cancellation request. */
++static inline void
++__attribute ((noreturn, always_inline))
++__do_cancel (void)
++{
++ struct pthread *self = THREAD_SELF;
++
++ /* Make sure we get no more cancellations. */
++ THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
++
++ __pthread_unwind ((__pthread_unwind_buf_t *)
++ THREAD_GETMEM (self, cleanup_jmp_buf));
++}
++
++
++/* Internal prototypes. */
++
++/* Thread list handling. */
++extern struct pthread *__find_in_stack_list (struct pthread *pd)
++ attribute_hidden;
++
++/* Deallocate a thread's stack after optionally making sure the thread
++ descriptor is still valid. */
++extern void __free_tcb (struct pthread *pd) attribute_hidden;
++
++/* Free allocated stack. */
++extern void __deallocate_stack (struct pthread *pd) attribute_hidden;
++
++/* Mark all the stacks except for the current one as available. This
++ function also re-initializes the lock for the stack cache. */
++extern void __reclaim_stacks (void) attribute_hidden;
++
++/* Make all threads's stacks executable. */
++extern int __make_stacks_executable (void **stack_endp) attribute_hidden;
++
++/* longjmp handling. */
++extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
++hidden_proto (__pthread_cleanup_upto)
++
++
++/* Functions with versioned interfaces. */
++extern int __pthread_create_2_1 (pthread_t *newthread,
++ const pthread_attr_t *attr,
++ void *(*start_routine) (void *), void *arg);
++extern int __pthread_create_2_0 (pthread_t *newthread,
++ const pthread_attr_t *attr,
++ void *(*start_routine) (void *), void *arg);
++extern int __pthread_attr_init_2_1 (pthread_attr_t *attr);
++extern int __pthread_attr_init_2_0 (pthread_attr_t *attr);
++
++
++/* Event handlers for libthread_db interface. */
++extern void __nptl_create_event (void);
++extern void __nptl_death_event (void);
++hidden_proto (__nptl_create_event)
++hidden_proto (__nptl_death_event)
++
++/* Register the generation counter in the libpthread with the libc. */
++#ifdef TLS_MULTIPLE_THREADS_IN_TCB
++extern void __libc_pthread_init (unsigned long int *ptr,
++ void (*reclaim) (void),
++ const struct pthread_functions *functions);
++#else
++extern int *__libc_pthread_init (unsigned long int *ptr,
++ void (*reclaim) (void),
++ const struct pthread_functions *functions);
++
++/* Variable set to a nonzero value either if more than one thread runs or ran,
++ or if a single-threaded process is trying to cancel itself. See
++ nptl/descr.h for more context on the single-threaded process case. */
++extern int __pthread_multiple_threads attribute_hidden;
++/* Pointer to the corresponding variable in libc. */
++extern int *__libc_multiple_threads_ptr attribute_hidden;
++#endif
++
++extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
++
++extern size_t __pthread_get_minstack (const pthread_attr_t *attr);
++
++/* Namespace save aliases. */
++extern int __pthread_getschedparam (pthread_t thread_id, int *policy,
++ struct sched_param *param);
++extern int __pthread_setschedparam (pthread_t thread_id, int policy,
++ const struct sched_param *param);
++extern int __pthread_setcancelstate (int state, int *oldstate);
++extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
++ const pthread_mutexattr_t *__mutexattr);
++extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
++extern int __pthread_mutex_trylock (pthread_mutex_t *_mutex);
++extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
++extern int __pthread_mutex_timedlock (pthread_mutex_t *__mutex,
++ const struct timespec *__abstime);
++extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
++ attribute_hidden;
++extern void __pthread_mutex_cond_lock_adjust (pthread_mutex_t *__mutex)
++ attribute_hidden;
++extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
++extern int __pthread_mutex_unlock_usercnt (pthread_mutex_t *__mutex,
++ int __decr) attribute_hidden;
++extern int __pthread_mutexattr_init (pthread_mutexattr_t *attr);
++extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *attr);
++extern int __pthread_mutexattr_settype (pthread_mutexattr_t *attr, int kind);
++extern int __pthread_attr_destroy (pthread_attr_t *attr);
++extern int __pthread_attr_getdetachstate (const pthread_attr_t *attr,
++ int *detachstate);
++extern int __pthread_attr_setdetachstate (pthread_attr_t *attr,
++ int detachstate);
++extern int __pthread_attr_getinheritsched (const pthread_attr_t *attr,
++ int *inherit);
++extern int __pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit);
++extern int __pthread_attr_getschedparam (const pthread_attr_t *attr,
++ struct sched_param *param);
++extern int __pthread_attr_setschedparam (pthread_attr_t *attr,
++ const struct sched_param *param);
++extern int __pthread_attr_getschedpolicy (const pthread_attr_t *attr,
++ int *policy);
++extern int __pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
++extern int __pthread_attr_getscope (const pthread_attr_t *attr, int *scope);
++extern int __pthread_attr_setscope (pthread_attr_t *attr, int scope);
++extern int __pthread_attr_getstackaddr (const pthread_attr_t *__restrict
++ __attr, void **__restrict __stackaddr);
++extern int __pthread_attr_setstackaddr (pthread_attr_t *__attr,
++ void *__stackaddr);
++extern int __pthread_attr_getstacksize (const pthread_attr_t *__restrict
++ __attr,
++ size_t *__restrict __stacksize);
++extern int __pthread_attr_setstacksize (pthread_attr_t *__attr,
++ size_t __stacksize);
++extern int __pthread_attr_getstack (const pthread_attr_t *__restrict __attr,
++ void **__restrict __stackaddr,
++ size_t *__restrict __stacksize);
++extern int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
++ size_t __stacksize);
++extern int __pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
++ const pthread_rwlockattr_t *__restrict
++ __attr);
++extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
++extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
++extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
++extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
++extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
++extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
++extern int __pthread_cond_broadcast (pthread_cond_t *cond);
++extern int __pthread_cond_destroy (pthread_cond_t *cond);
++extern int __pthread_cond_init (pthread_cond_t *cond,
++ const pthread_condattr_t *cond_attr);
++extern int __pthread_cond_signal (pthread_cond_t *cond);
++extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
++extern int __pthread_cond_timedwait (pthread_cond_t *cond,
++ pthread_mutex_t *mutex,
++ const struct timespec *abstime);
++extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
++extern int __pthread_condattr_init (pthread_condattr_t *attr);
++extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));
++extern int __pthread_key_delete (pthread_key_t key);
++extern void *__pthread_getspecific (pthread_key_t key);
++extern int __pthread_setspecific (pthread_key_t key, const void *value);
++extern int __pthread_once (pthread_once_t *once_control,
++ void (*init_routine) (void));
++extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void),
++ void (*child) (void));
++extern pthread_t __pthread_self (void);
++extern int __pthread_equal (pthread_t thread1, pthread_t thread2);
++extern int __pthread_detach (pthread_t th);
++extern int __pthread_cancel (pthread_t th);
++extern int __pthread_kill (pthread_t threadid, int signo);
++extern void __pthread_exit (void *value) __attribute__ ((__noreturn__));
++extern int __pthread_join (pthread_t threadid, void **thread_return);
++extern int __pthread_setcanceltype (int type, int *oldtype);
++extern int __pthread_enable_asynccancel (void) attribute_hidden;
++extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
++extern void __pthread_testcancel (void);
++extern int __pthread_clockjoin_ex (pthread_t, void **, clockid_t,
++ const struct timespec *, bool)
++ attribute_hidden;
++
++
++hidden_proto (__pthread_mutex_init)
++hidden_proto (__pthread_mutex_destroy)
++hidden_proto (__pthread_mutex_lock)
++hidden_proto (__pthread_mutex_trylock)
++hidden_proto (__pthread_mutex_unlock)
++hidden_proto (__pthread_rwlock_rdlock)
++hidden_proto (__pthread_rwlock_wrlock)
++hidden_proto (__pthread_rwlock_unlock)
++hidden_proto (__pthread_key_create)
++hidden_proto (__pthread_getspecific)
++hidden_proto (__pthread_setspecific)
++hidden_proto (__pthread_once)
++hidden_proto (__pthread_setcancelstate)
++hidden_proto (__pthread_testcancel)
++hidden_proto (__pthread_mutexattr_init)
++hidden_proto (__pthread_mutexattr_settype)
++
++extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond);
++extern int __pthread_cond_destroy_2_0 (pthread_cond_2_0_t *cond);
++extern int __pthread_cond_init_2_0 (pthread_cond_2_0_t *cond,
++ const pthread_condattr_t *cond_attr);
++extern int __pthread_cond_signal_2_0 (pthread_cond_2_0_t *cond);
++extern int __pthread_cond_timedwait_2_0 (pthread_cond_2_0_t *cond,
++ pthread_mutex_t *mutex,
++ const struct timespec *abstime);
++extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond,
++ pthread_mutex_t *mutex);
++
++extern int __pthread_getaffinity_np (pthread_t th, size_t cpusetsize,
++ cpu_set_t *cpuset);
++
++/* Special versions which use non-exported functions. */
++extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
++ void (*routine) (void *), void *arg)
++ attribute_hidden;
++
++/* Replace cleanup macros defined in <pthread.h> with internal
++ versions that don't depend on unwind info and better support
++ cancellation. */
++# undef pthread_cleanup_push
++# define pthread_cleanup_push(routine,arg) \
++ { struct _pthread_cleanup_buffer _buffer; \
++ __pthread_cleanup_push (&_buffer, (routine), (arg));
++
++extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
++ int execute) attribute_hidden;
++# undef pthread_cleanup_pop
++# define pthread_cleanup_pop(execute) \
++ __pthread_cleanup_pop (&_buffer, (execute)); }
++
++extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
++ void (*routine) (void *), void *arg);
++extern void __pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
++ int execute);
++
++/* Old cleanup interfaces, still used in libc.so. */
++extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
++ void (*routine) (void *), void *arg);
++extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
++ int execute);
++extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
++ void (*routine) (void *), void *arg);
++extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
++ int execute);
++
++extern void __nptl_deallocate_tsd (void) attribute_hidden;
++
++extern void __nptl_setxid_error (struct xid_command *cmdp, int error)
++ attribute_hidden;
++extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
++#ifndef SHARED
++extern void __nptl_set_robust (struct pthread *self);
++#endif
++
++extern void __nptl_stacks_freeres (void) attribute_hidden;
++extern void __shm_directory_freeres (void) attribute_hidden;
++
++extern void __wait_lookup_done (void) attribute_hidden;
++
++#ifdef SHARED
++# define PTHREAD_STATIC_FN_REQUIRE(name)
++#else
++# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
++#endif
++
++/* Test if the mutex is suitable for the FUTEX_WAIT_REQUEUE_PI operation. */
++#if (defined lll_futex_wait_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++# define USE_REQUEUE_PI(mut) \
++ ((mut) && (mut) != (void *) ~0l \
++ && (((mut)->__data.__kind \
++ & (PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP)) \
++ == PTHREAD_MUTEX_PRIO_INHERIT_NP))
++#else
++# define USE_REQUEUE_PI(mut) 0
++#endif
++
++/* Returns 0 if POL is a valid scheduling policy. */
++static inline int
++check_sched_policy_attr (int pol)
++{
++ if (pol == SCHED_OTHER || pol == SCHED_FIFO || pol == SCHED_RR)
++ return 0;
++
++ return EINVAL;
++}
++
++/* Returns 0 if PR is within the accepted range of priority values for
++ the scheduling policy POL or EINVAL otherwise. */
++static inline int
++check_sched_priority_attr (int pr, int pol)
++{
++ int min = __sched_get_priority_min (pol);
++ int max = __sched_get_priority_max (pol);
++
++ if (min >= 0 && max >= 0 && pr >= min && pr <= max)
++ return 0;
++
++ return EINVAL;
++}
++
++/* Returns 0 if ST is a valid stack size for a thread stack and EINVAL
++ otherwise. */
++static inline int
++check_stacksize_attr (size_t st)
++{
++ if (st >= PTHREAD_STACK_MIN)
++ return 0;
++
++ return EINVAL;
++}
++
++#define ASSERT_TYPE_SIZE(type, size) \
++ _Static_assert (sizeof (type) == size, \
++ "sizeof (" #type ") != " #size)
++
++#define ASSERT_PTHREAD_INTERNAL_SIZE(type, internal) \
++ _Static_assert (sizeof ((type) { { 0 } }).__size >= sizeof (internal),\
++ "sizeof (" #type ".__size) < sizeof (" #internal ")")
++
++#define ASSERT_PTHREAD_STRING(x) __STRING (x)
++#define ASSERT_PTHREAD_INTERNAL_OFFSET(type, member, offset) \
++ _Static_assert (offsetof (type, member) == offset, \
++ "offset of " #member " field of " #type " != " \
++ ASSERT_PTHREAD_STRING (offset))
++#define ASSERT_PTHREAD_INTERNAL_MEMBER_SIZE(type, member, mtype) \
++ _Static_assert (sizeof (((type) { 0 }).member) != 8, \
++ "sizeof (" #type "." #member ") != sizeof (" #mtype "))")
++
++#endif /* pthreadP.h */
+diff --git a/nptl_2_17/pthread_2_17.h b/nptl_2_17/pthread_2_17.h
+new file mode 100644
+index 00000000..3954770a
+--- /dev/null
++++ b/nptl_2_17/pthread_2_17.h
+@@ -0,0 +1,1173 @@
++/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#ifndef _PTHREAD_H
++#define _PTHREAD_H 1
++
++#include <features.h>
++#include <sched.h>
++#include <time.h>
++
++#include <bits/endian.h>
++#include <bits/pthreadtypes_2_17.h>
++#include <bits/setjmp.h>
++#include <bits/wordsize.h>
++#include <bits/types/struct_timespec.h>
++
++
++/* Detach state. */
++enum
++{
++ PTHREAD_CREATE_JOINABLE,
++#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
++ PTHREAD_CREATE_DETACHED
++#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
++};
++
++
++/* Mutex types. */
++enum
++{
++ PTHREAD_MUTEX_TIMED_NP,
++ PTHREAD_MUTEX_RECURSIVE_NP,
++ PTHREAD_MUTEX_ERRORCHECK_NP,
++ PTHREAD_MUTEX_ADAPTIVE_NP
++#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
++ ,
++ PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
++ PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
++ PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
++ PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
++#endif
++#ifdef __USE_GNU
++ /* For compatibility. */
++ , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
++#endif
++};
++
++
++#ifdef __USE_XOPEN2K
++/* Robust mutex or not flags. */
++enum
++{
++ PTHREAD_MUTEX_STALLED,
++ PTHREAD_MUTEX_STALLED_NP = PTHREAD_MUTEX_STALLED,
++ PTHREAD_MUTEX_ROBUST,
++ PTHREAD_MUTEX_ROBUST_NP = PTHREAD_MUTEX_ROBUST
++};
++#endif
++
++
++#if defined __USE_POSIX199506 || defined __USE_UNIX98
++/* Mutex protocols. */
++enum
++{
++ PTHREAD_PRIO_NONE,
++ PTHREAD_PRIO_INHERIT,
++ PTHREAD_PRIO_PROTECT
++};
++#endif
++
++
++#define PTHREAD_MUTEX_INITIALIZER \
++ { { __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_TIMED_NP) } }
++#ifdef __USE_GNU
++# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
++ { { __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_RECURSIVE_NP) } }
++# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
++ { { __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_ERRORCHECK_NP) } }
++# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
++ { { __PTHREAD_MUTEX_INITIALIZER (PTHREAD_MUTEX_ADAPTIVE_NP) } }
++#endif
++
++
++/* Read-write lock types. */
++#if defined __USE_UNIX98 || defined __USE_XOPEN2K
++enum
++{
++ PTHREAD_RWLOCK_PREFER_READER_NP,
++ PTHREAD_RWLOCK_PREFER_WRITER_NP,
++ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
++ PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP
++};
++
++
++/* Read-write lock initializers. */
++# define PTHREAD_RWLOCK_INITIALIZER \
++ { { __PTHREAD_RWLOCK_INITIALIZER (PTHREAD_RWLOCK_DEFAULT_NP) } }
++# ifdef __USE_GNU
++# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
++ { { __PTHREAD_RWLOCK_INITIALIZER (PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) } }
++# endif
++#endif /* Unix98 or XOpen2K */
++
++
++/* Scheduler inheritance. */
++enum
++{
++ PTHREAD_INHERIT_SCHED,
++#define PTHREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED
++ PTHREAD_EXPLICIT_SCHED
++#define PTHREAD_EXPLICIT_SCHED PTHREAD_EXPLICIT_SCHED
++};
++
++
++/* Scope handling. */
++enum
++{
++ PTHREAD_SCOPE_SYSTEM,
++#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM
++ PTHREAD_SCOPE_PROCESS
++#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS
++};
++
++
++/* Process shared or private flag. */
++enum
++{
++ PTHREAD_PROCESS_PRIVATE,
++#define PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
++ PTHREAD_PROCESS_SHARED
++#define PTHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
++};
++
++
++
++/* Conditional variable handling. */
++#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }
++
++
++/* Cleanup buffers */
++struct _pthread_cleanup_buffer
++{
++ void (*__routine) (void *); /* Function to call. */
++ void *__arg; /* Its argument. */
++ int __canceltype; /* Saved cancellation type. */
++ struct _pthread_cleanup_buffer *__prev; /* Chaining of cleanup functions. */
++};
++
++/* Cancellation */
++enum
++{
++ PTHREAD_CANCEL_ENABLE,
++#define PTHREAD_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE
++ PTHREAD_CANCEL_DISABLE
++#define PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE
++};
++enum
++{
++ PTHREAD_CANCEL_DEFERRED,
++#define PTHREAD_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED
++ PTHREAD_CANCEL_ASYNCHRONOUS
++#define PTHREAD_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS
++};
++#define PTHREAD_CANCELED ((void *) -1)
++
++
++/* Single execution handling. */
++#define PTHREAD_ONCE_INIT 0
++
++
++#ifdef __USE_XOPEN2K
++/* Value returned by 'pthread_barrier_wait' for one of the threads after
++ the required number of threads have called this function.
++ -1 is distinct from 0 and all errno constants */
++# define PTHREAD_BARRIER_SERIAL_THREAD -1
++#endif
++
++
++__BEGIN_DECLS
++
++/* Create a new thread, starting with execution of START-ROUTINE
++ getting passed ARG. Creation attributed come from ATTR. The new
++ handle is stored in *NEWTHREAD. */
++extern int pthread_create (pthread_t *__restrict __newthread,
++ const pthread_attr_t *__restrict __attr,
++ void *(*__start_routine) (void *),
++ void *__restrict __arg) __THROWNL __nonnull ((1, 3));
++
++/* Terminate calling thread.
++
++ The registered cleanup handlers are called via exception handling
++ so we cannot mark this function with __THROW.*/
++extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__));
++
++/* Make calling thread wait for termination of the thread TH. The
++ exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN
++ is not NULL.
++
++ This function is a cancellation point and therefore not marked with
++ __THROW. */
++extern int pthread_join (pthread_t __th, void **__thread_return);
++
++#ifdef __USE_GNU
++/* Check whether thread TH has terminated. If yes return the status of
++ the thread in *THREAD_RETURN, if THREAD_RETURN is not NULL. */
++extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW;
++
++/* Make calling thread wait for termination of the thread TH, but only
++ until TIMEOUT. The exit status of the thread is stored in
++ *THREAD_RETURN, if THREAD_RETURN is not NULL.
++
++ This function is a cancellation point and therefore not marked with
++ __THROW. */
++extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return,
++ const struct timespec *__abstime);
++
++/* Make calling thread wait for termination of the thread TH, but only
++ until TIMEOUT measured against the clock specified by CLOCKID. The
++ exit status of the thread is stored in *THREAD_RETURN, if
++ THREAD_RETURN is not NULL.
++
++ This function is a cancellation point and therefore not marked with
++ __THROW. */
++extern int pthread_clockjoin_np (pthread_t __th, void **__thread_return,
++ clockid_t __clockid,
++ const struct timespec *__abstime);
++#endif
++
++/* Indicate that the thread TH is never to be joined with PTHREAD_JOIN.
++ The resources of TH will therefore be freed immediately when it
++ terminates, instead of waiting for another thread to perform PTHREAD_JOIN
++ on it. */
++extern int pthread_detach (pthread_t __th) __THROW;
++
++
++/* Obtain the identifier of the current thread. */
++extern pthread_t pthread_self (void) __THROW __attribute__ ((__const__));
++
++/* Compare two thread identifiers. */
++extern int pthread_equal (pthread_t __thread1, pthread_t __thread2)
++ __THROW __attribute__ ((__const__));
++
++
++/* Thread attribute handling. */
++
++/* Initialize thread attribute *ATTR with default attributes
++ (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER,
++ no user-provided stack). */
++extern int pthread_attr_init (pthread_attr_t *__attr) __THROW __nonnull ((1));
++
++/* Destroy thread attribute *ATTR. */
++extern int pthread_attr_destroy (pthread_attr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Get detach state attribute. */
++extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr,
++ int *__detachstate)
++ __THROW __nonnull ((1, 2));
++
++/* Set detach state attribute. */
++extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
++ int __detachstate)
++ __THROW __nonnull ((1));
++
++
++/* Get the size of the guard area created for stack overflow protection. */
++extern int pthread_attr_getguardsize (const pthread_attr_t *__attr,
++ size_t *__guardsize)
++ __THROW __nonnull ((1, 2));
++
++/* Set the size of the guard area created for stack overflow protection. */
++extern int pthread_attr_setguardsize (pthread_attr_t *__attr,
++ size_t __guardsize)
++ __THROW __nonnull ((1));
++
++
++/* Return in *PARAM the scheduling parameters of *ATTR. */
++extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr,
++ struct sched_param *__restrict __param)
++ __THROW __nonnull ((1, 2));
++
++/* Set scheduling parameters (priority, etc) in *ATTR according to PARAM. */
++extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
++ const struct sched_param *__restrict
++ __param) __THROW __nonnull ((1, 2));
++
++/* Return in *POLICY the scheduling policy of *ATTR. */
++extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict
++ __attr, int *__restrict __policy)
++ __THROW __nonnull ((1, 2));
++
++/* Set scheduling policy in *ATTR according to POLICY. */
++extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy)
++ __THROW __nonnull ((1));
++
++/* Return in *INHERIT the scheduling inheritance mode of *ATTR. */
++extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict
++ __attr, int *__restrict __inherit)
++ __THROW __nonnull ((1, 2));
++
++/* Set scheduling inheritance mode in *ATTR according to INHERIT. */
++extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
++ int __inherit)
++ __THROW __nonnull ((1));
++
++
++/* Return in *SCOPE the scheduling contention scope of *ATTR. */
++extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr,
++ int *__restrict __scope)
++ __THROW __nonnull ((1, 2));
++
++/* Set scheduling contention scope in *ATTR according to SCOPE. */
++extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope)
++ __THROW __nonnull ((1));
++
++/* Return the previously set address for the stack. */
++extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict
++ __attr, void **__restrict __stackaddr)
++ __THROW __nonnull ((1, 2)) __attribute_deprecated__;
++
++/* Set the starting address of the stack of the thread to be created.
++ Depending on whether the stack grows up or down the value must either
++ be higher or lower than all the address in the memory block. The
++ minimal size of the block must be PTHREAD_STACK_MIN. */
++extern int pthread_attr_setstackaddr (pthread_attr_t *__attr,
++ void *__stackaddr)
++ __THROW __nonnull ((1)) __attribute_deprecated__;
++
++/* Return the currently used minimal stack size. */
++extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict
++ __attr, size_t *__restrict __stacksize)
++ __THROW __nonnull ((1, 2));
++
++/* Add information about the minimum stack size needed for the thread
++ to be started. This size must never be less than PTHREAD_STACK_MIN
++ and must also not exceed the system limits. */
++extern int pthread_attr_setstacksize (pthread_attr_t *__attr,
++ size_t __stacksize)
++ __THROW __nonnull ((1));
++
++#ifdef __USE_XOPEN2K
++/* Return the previously set address for the stack. */
++extern int pthread_attr_getstack (const pthread_attr_t *__restrict __attr,
++ void **__restrict __stackaddr,
++ size_t *__restrict __stacksize)
++ __THROW __nonnull ((1, 2, 3));
++
++/* The following two interfaces are intended to replace the last two. They
++ require setting the address as well as the size since only setting the
++ address will make the implementation on some architectures impossible. */
++extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
++ size_t __stacksize) __THROW __nonnull ((1));
++#endif
++
++#ifdef __USE_GNU
++/* Thread created with attribute ATTR will be limited to run only on
++ the processors represented in CPUSET. */
++extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr,
++ size_t __cpusetsize,
++ const cpu_set_t *__cpuset)
++ __THROW __nonnull ((1, 3));
++
++/* Get bit set in CPUSET representing the processors threads created with
++ ATTR can run on. */
++extern int pthread_attr_getaffinity_np (const pthread_attr_t *__attr,
++ size_t __cpusetsize,
++ cpu_set_t *__cpuset)
++ __THROW __nonnull ((1, 3));
++
++/* Get the default attributes used by pthread_create in this process. */
++extern int pthread_getattr_default_np (pthread_attr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Set the default attributes to be used by pthread_create in this
++ process. */
++extern int pthread_setattr_default_np (const pthread_attr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Initialize thread attribute *ATTR with attributes corresponding to the
++ already running thread TH. It shall be called on uninitialized ATTR
++ and destroyed with pthread_attr_destroy when no longer needed. */
++extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr)
++ __THROW __nonnull ((2));
++#endif
++
++
++/* Functions for scheduling control. */
++
++/* Set the scheduling parameters for TARGET_THREAD according to POLICY
++ and *PARAM. */
++extern int pthread_setschedparam (pthread_t __target_thread, int __policy,
++ const struct sched_param *__param)
++ __THROW __nonnull ((3));
++
++/* Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. */
++extern int pthread_getschedparam (pthread_t __target_thread,
++ int *__restrict __policy,
++ struct sched_param *__restrict __param)
++ __THROW __nonnull ((2, 3));
++
++/* Set the scheduling priority for TARGET_THREAD. */
++extern int pthread_setschedprio (pthread_t __target_thread, int __prio)
++ __THROW;
++
++
++#ifdef __USE_GNU
++/* Get thread name visible in the kernel and its interfaces. */
++extern int pthread_getname_np (pthread_t __target_thread, char *__buf,
++ size_t __buflen)
++ __THROW __nonnull ((2));
++
++/* Set thread name visible in the kernel and its interfaces. */
++extern int pthread_setname_np (pthread_t __target_thread, const char *__name)
++ __THROW __nonnull ((2));
++#endif
++
++
++#ifdef __USE_UNIX98
++/* Determine level of concurrency. */
++extern int pthread_getconcurrency (void) __THROW;
++
++/* Set new concurrency level to LEVEL. */
++extern int pthread_setconcurrency (int __level) __THROW;
++#endif
++
++#ifdef __USE_GNU
++/* Yield the processor to another thread or process.
++ This function is similar to the POSIX `sched_yield' function but
++ might be differently implemented in the case of a m-on-n thread
++ implementation. */
++extern int pthread_yield (void) __THROW;
++
++
++/* Limit specified thread TH to run only on the processors represented
++ in CPUSET. */
++extern int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize,
++ const cpu_set_t *__cpuset)
++ __THROW __nonnull ((3));
++
++/* Get bit set in CPUSET representing the processors TH can run on. */
++extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize,
++ cpu_set_t *__cpuset)
++ __THROW __nonnull ((3));
++#endif
++
++
++/* Functions for handling initialization. */
++
++/* Guarantee that the initialization function INIT_ROUTINE will be called
++ only once, even if pthread_once is executed several times with the
++ same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or
++ extern variable initialized to PTHREAD_ONCE_INIT.
++
++ The initialization functions might throw exception which is why
++ this function is not marked with __THROW. */
++extern int pthread_once (pthread_once_t *__once_control,
++ void (*__init_routine) (void)) __nonnull ((1, 2));
++
++
++/* Functions for handling cancellation.
++
++ Note that these functions are explicitly not marked to not throw an
++ exception in C++ code. If cancellation is implemented by unwinding
++ this is necessary to have the compiler generate the unwind information. */
++
++/* Set cancelability state of current thread to STATE, returning old
++ state in *OLDSTATE if OLDSTATE is not NULL. */
++extern int pthread_setcancelstate (int __state, int *__oldstate);
++
++/* Set cancellation state of current thread to TYPE, returning the old
++ type in *OLDTYPE if OLDTYPE is not NULL. */
++extern int pthread_setcanceltype (int __type, int *__oldtype);
++
++/* Cancel THREAD immediately or at the next possibility. */
++extern int pthread_cancel (pthread_t __th);
++
++/* Test for pending cancellation for the current thread and terminate
++ the thread as per pthread_exit(PTHREAD_CANCELED) if it has been
++ cancelled. */
++extern void pthread_testcancel (void);
++
++
++/* Cancellation handling with integration into exception handling. */
++
++typedef struct
++{
++ struct
++ {
++ __jmp_buf __cancel_jmp_buf;
++ int __mask_was_saved;
++ } __cancel_jmp_buf[1];
++ void *__pad[4];
++} __pthread_unwind_buf_t __attribute__ ((__aligned__));
++
++/* No special attributes by default. */
++#ifndef __cleanup_fct_attribute
++# define __cleanup_fct_attribute
++#endif
++
++
++/* Structure to hold the cleanup handler information. */
++struct __pthread_cleanup_frame
++{
++ void (*__cancel_routine) (void *);
++ void *__cancel_arg;
++ int __do_it;
++ int __cancel_type;
++};
++
++#if defined __GNUC__ && defined __EXCEPTIONS
++# ifdef __cplusplus
++/* Class to handle cancellation handler invocation. */
++class __pthread_cleanup_class
++{
++ void (*__cancel_routine) (void *);
++ void *__cancel_arg;
++ int __do_it;
++ int __cancel_type;
++
++ public:
++ __pthread_cleanup_class (void (*__fct) (void *), void *__arg)
++ : __cancel_routine (__fct), __cancel_arg (__arg), __do_it (1) { }
++ ~__pthread_cleanup_class () { if (__do_it) __cancel_routine (__cancel_arg); }
++ void __setdoit (int __newval) { __do_it = __newval; }
++ void __defer () { pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED,
++ &__cancel_type); }
++ void __restore () const { pthread_setcanceltype (__cancel_type, 0); }
++};
++
++/* Install a cleanup handler: ROUTINE will be called with arguments ARG
++ when the thread is canceled or calls pthread_exit. ROUTINE will also
++ be called with arguments ARG when the matching pthread_cleanup_pop
++ is executed with non-zero EXECUTE argument.
++
++ pthread_cleanup_push and pthread_cleanup_pop are macros and must always
++ be used in matching pairs at the same nesting level of braces. */
++# define pthread_cleanup_push(routine, arg) \
++ do { \
++ __pthread_cleanup_class __clframe (routine, arg)
++
++/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
++ If EXECUTE is non-zero, the handler function is called. */
++# define pthread_cleanup_pop(execute) \
++ __clframe.__setdoit (execute); \
++ } while (0)
++
++# ifdef __USE_GNU
++/* Install a cleanup handler as pthread_cleanup_push does, but also
++ saves the current cancellation type and sets it to deferred
++ cancellation. */
++# define pthread_cleanup_push_defer_np(routine, arg) \
++ do { \
++ __pthread_cleanup_class __clframe (routine, arg); \
++ __clframe.__defer ()
++
++/* Remove a cleanup handler as pthread_cleanup_pop does, but also
++ restores the cancellation type that was in effect when the matching
++ pthread_cleanup_push_defer was called. */
++# define pthread_cleanup_pop_restore_np(execute) \
++ __clframe.__restore (); \
++ __clframe.__setdoit (execute); \
++ } while (0)
++# endif
++# else
++/* Function called to call the cleanup handler. As an extern inline
++ function the compiler is free to decide inlining the change when
++ needed or fall back on the copy which must exist somewhere
++ else. */
++__extern_inline void
++__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
++{
++ if (__frame->__do_it)
++ __frame->__cancel_routine (__frame->__cancel_arg);
++}
++
++/* Install a cleanup handler: ROUTINE will be called with arguments ARG
++ when the thread is canceled or calls pthread_exit. ROUTINE will also
++ be called with arguments ARG when the matching pthread_cleanup_pop
++ is executed with non-zero EXECUTE argument.
++
++ pthread_cleanup_push and pthread_cleanup_pop are macros and must always
++ be used in matching pairs at the same nesting level of braces. */
++# define pthread_cleanup_push(routine, arg) \
++ do { \
++ struct __pthread_cleanup_frame __clframe \
++ __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) \
++ = { .__cancel_routine = (routine), .__cancel_arg = (arg), \
++ .__do_it = 1 };
++
++/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
++ If EXECUTE is non-zero, the handler function is called. */
++# define pthread_cleanup_pop(execute) \
++ __clframe.__do_it = (execute); \
++ } while (0)
++
++# ifdef __USE_GNU
++/* Install a cleanup handler as pthread_cleanup_push does, but also
++ saves the current cancellation type and sets it to deferred
++ cancellation. */
++# define pthread_cleanup_push_defer_np(routine, arg) \
++ do { \
++ struct __pthread_cleanup_frame __clframe \
++ __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) \
++ = { .__cancel_routine = (routine), .__cancel_arg = (arg), \
++ .__do_it = 1 }; \
++ (void) pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, \
++ &__clframe.__cancel_type)
++
++/* Remove a cleanup handler as pthread_cleanup_pop does, but also
++ restores the cancellation type that was in effect when the matching
++ pthread_cleanup_push_defer was called. */
++# define pthread_cleanup_pop_restore_np(execute) \
++ (void) pthread_setcanceltype (__clframe.__cancel_type, NULL); \
++ __clframe.__do_it = (execute); \
++ } while (0)
++# endif
++# endif
++#else
++/* Install a cleanup handler: ROUTINE will be called with arguments ARG
++ when the thread is canceled or calls pthread_exit. ROUTINE will also
++ be called with arguments ARG when the matching pthread_cleanup_pop
++ is executed with non-zero EXECUTE argument.
++
++ pthread_cleanup_push and pthread_cleanup_pop are macros and must always
++ be used in matching pairs at the same nesting level of braces. */
++# define pthread_cleanup_push(routine, arg) \
++ do { \
++ __pthread_unwind_buf_t __cancel_buf; \
++ void (*__cancel_routine) (void *) = (routine); \
++ void *__cancel_arg = (arg); \
++ int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
++ __cancel_buf.__cancel_jmp_buf, 0); \
++ if (__glibc_unlikely (__not_first_call)) \
++ { \
++ __cancel_routine (__cancel_arg); \
++ __pthread_unwind_next (&__cancel_buf); \
++ /* NOTREACHED */ \
++ } \
++ \
++ __pthread_register_cancel (&__cancel_buf); \
++ do {
++extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute;
++
++/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
++ If EXECUTE is non-zero, the handler function is called. */
++# define pthread_cleanup_pop(execute) \
++ do { } while (0);/* Empty to allow label before pthread_cleanup_pop. */\
++ } while (0); \
++ __pthread_unregister_cancel (&__cancel_buf); \
++ if (execute) \
++ __cancel_routine (__cancel_arg); \
++ } while (0)
++extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute;
++
++# ifdef __USE_GNU
++/* Install a cleanup handler as pthread_cleanup_push does, but also
++ saves the current cancellation type and sets it to deferred
++ cancellation. */
++# define pthread_cleanup_push_defer_np(routine, arg) \
++ do { \
++ __pthread_unwind_buf_t __cancel_buf; \
++ void (*__cancel_routine) (void *) = (routine); \
++ void *__cancel_arg = (arg); \
++ int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
++ __cancel_buf.__cancel_jmp_buf, 0); \
++ if (__glibc_unlikely (__not_first_call)) \
++ { \
++ __cancel_routine (__cancel_arg); \
++ __pthread_unwind_next (&__cancel_buf); \
++ /* NOTREACHED */ \
++ } \
++ \
++ __pthread_register_cancel_defer (&__cancel_buf); \
++ do {
++extern void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute;
++
++/* Remove a cleanup handler as pthread_cleanup_pop does, but also
++ restores the cancellation type that was in effect when the matching
++ pthread_cleanup_push_defer was called. */
++# define pthread_cleanup_pop_restore_np(execute) \
++ do { } while (0);/* Empty to allow label before pthread_cleanup_pop. */\
++ } while (0); \
++ __pthread_unregister_cancel_restore (&__cancel_buf); \
++ if (execute) \
++ __cancel_routine (__cancel_arg); \
++ } while (0)
++extern void __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute;
++# endif
++
++/* Internal interface to initiate cleanup. */
++extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
++ __cleanup_fct_attribute __attribute__ ((__noreturn__))
++# ifndef SHARED
++ __attribute__ ((__weak__))
++# endif
++ ;
++#endif
++
++/* Function used in the macros. */
++struct __jmp_buf_tag;
++extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROWNL;
++
++
++/* Mutex handling. */
++
++/* Initialize a mutex. */
++extern int pthread_mutex_init (pthread_mutex_t *__mutex,
++ const pthread_mutexattr_t *__mutexattr)
++ __THROW __nonnull ((1));
++
++/* Destroy a mutex. */
++extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
++ __THROW __nonnull ((1));
++
++/* Try locking a mutex. */
++extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
++ __THROWNL __nonnull ((1));
++
++/* Lock a mutex. */
++extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
++ __THROWNL __nonnull ((1));
++
++#ifdef __USE_XOPEN2K
++/* Wait until lock becomes available, or specified time passes. */
++extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
++ const struct timespec *__restrict
++ __abstime) __THROWNL __nonnull ((1, 2));
++#endif
++
++#ifdef __USE_GNU
++extern int pthread_mutex_clocklock (pthread_mutex_t *__restrict __mutex,
++ clockid_t __clockid,
++ const struct timespec *__restrict
++ __abstime) __THROWNL __nonnull ((1, 3));
++#endif
++
++/* Unlock a mutex. */
++extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
++ __THROWNL __nonnull ((1));
++
++
++/* Get the priority ceiling of MUTEX. */
++extern int pthread_mutex_getprioceiling (const pthread_mutex_t *
++ __restrict __mutex,
++ int *__restrict __prioceiling)
++ __THROW __nonnull ((1, 2));
++
++/* Set the priority ceiling of MUTEX to PRIOCEILING, return old
++ priority ceiling value in *OLD_CEILING. */
++extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex,
++ int __prioceiling,
++ int *__restrict __old_ceiling)
++ __THROW __nonnull ((1, 3));
++
++
++#ifdef __USE_XOPEN2K8
++/* Declare the state protected by MUTEX as consistent. */
++extern int pthread_mutex_consistent (pthread_mutex_t *__mutex)
++ __THROW __nonnull ((1));
++# ifdef __USE_GNU
++extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex)
++ __THROW __nonnull ((1));
++# endif
++#endif
++
++
++/* Functions for handling mutex attributes. */
++
++/* Initialize mutex attribute object ATTR with default attributes
++ (kind is PTHREAD_MUTEX_TIMED_NP). */
++extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Destroy mutex attribute object ATTR. */
++extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Get the process-shared flag of the mutex attribute ATTR. */
++extern int pthread_mutexattr_getpshared (const pthread_mutexattr_t *
++ __restrict __attr,
++ int *__restrict __pshared)
++ __THROW __nonnull ((1, 2));
++
++/* Set the process-shared flag of the mutex attribute ATTR. */
++extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
++ int __pshared)
++ __THROW __nonnull ((1));
++
++#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
++/* Return in *KIND the mutex kind attribute in *ATTR. */
++extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict
++ __attr, int *__restrict __kind)
++ __THROW __nonnull ((1, 2));
++
++/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
++ PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
++ PTHREAD_MUTEX_DEFAULT). */
++extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
++ __THROW __nonnull ((1));
++#endif
++
++/* Return in *PROTOCOL the mutex protocol attribute in *ATTR. */
++extern int pthread_mutexattr_getprotocol (const pthread_mutexattr_t *
++ __restrict __attr,
++ int *__restrict __protocol)
++ __THROW __nonnull ((1, 2));
++
++/* Set the mutex protocol attribute in *ATTR to PROTOCOL (either
++ PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, or PTHREAD_PRIO_PROTECT). */
++extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
++ int __protocol)
++ __THROW __nonnull ((1));
++
++/* Return in *PRIOCEILING the mutex prioceiling attribute in *ATTR. */
++extern int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *
++ __restrict __attr,
++ int *__restrict __prioceiling)
++ __THROW __nonnull ((1, 2));
++
++/* Set the mutex prioceiling attribute in *ATTR to PRIOCEILING. */
++extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr,
++ int __prioceiling)
++ __THROW __nonnull ((1));
++
++#ifdef __USE_XOPEN2K
++/* Get the robustness flag of the mutex attribute ATTR. */
++extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr,
++ int *__robustness)
++ __THROW __nonnull ((1, 2));
++# ifdef __USE_GNU
++extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr,
++ int *__robustness)
++ __THROW __nonnull ((1, 2));
++# endif
++
++/* Set the robustness flag of the mutex attribute ATTR. */
++extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
++ int __robustness)
++ __THROW __nonnull ((1));
++# ifdef __USE_GNU
++extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
++ int __robustness)
++ __THROW __nonnull ((1));
++# endif
++#endif
++
++
++#if defined __USE_UNIX98 || defined __USE_XOPEN2K
++/* Functions for handling read-write locks. */
++
++/* Initialize read-write lock RWLOCK using attributes ATTR, or use
++ the default values if later is NULL. */
++extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
++ const pthread_rwlockattr_t *__restrict
++ __attr) __THROW __nonnull ((1));
++
++/* Destroy read-write lock RWLOCK. */
++extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
++ __THROW __nonnull ((1));
++
++/* Acquire read lock for RWLOCK. */
++extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
++ __THROWNL __nonnull ((1));
++
++/* Try to acquire read lock for RWLOCK. */
++extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
++ __THROWNL __nonnull ((1));
++
++# ifdef __USE_XOPEN2K
++/* Try to acquire read lock for RWLOCK or return after specfied time. */
++extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
++ const struct timespec *__restrict
++ __abstime) __THROWNL __nonnull ((1, 2));
++# endif
++
++# ifdef __USE_GNU
++extern int pthread_rwlock_clockrdlock (pthread_rwlock_t *__restrict __rwlock,
++ clockid_t __clockid,
++ const struct timespec *__restrict
++ __abstime) __THROWNL __nonnull ((1, 3));
++# endif
++
++/* Acquire write lock for RWLOCK. */
++extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
++ __THROWNL __nonnull ((1));
++
++/* Try to acquire write lock for RWLOCK. */
++extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
++ __THROWNL __nonnull ((1));
++
++# ifdef __USE_XOPEN2K
++/* Try to acquire write lock for RWLOCK or return after specfied time. */
++extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
++ const struct timespec *__restrict
++ __abstime) __THROWNL __nonnull ((1, 2));
++# endif
++
++# ifdef __USE_GNU
++extern int pthread_rwlock_clockwrlock (pthread_rwlock_t *__restrict __rwlock,
++ clockid_t __clockid,
++ const struct timespec *__restrict
++ __abstime) __THROWNL __nonnull ((1, 3));
++# endif
++
++/* Unlock RWLOCK. */
++extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
++ __THROWNL __nonnull ((1));
++
++
++/* Functions for handling read-write lock attributes. */
++
++/* Initialize attribute object ATTR with default values. */
++extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Destroy attribute object ATTR. */
++extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Return current setting of process-shared attribute of ATTR in PSHARED. */
++extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *
++ __restrict __attr,
++ int *__restrict __pshared)
++ __THROW __nonnull ((1, 2));
++
++/* Set process-shared attribute of ATTR to PSHARED. */
++extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr,
++ int __pshared)
++ __THROW __nonnull ((1));
++
++/* Return current setting of reader/writer preference. */
++extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *
++ __restrict __attr,
++ int *__restrict __pref)
++ __THROW __nonnull ((1, 2));
++
++/* Set reader/write preference. */
++extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
++ int __pref) __THROW __nonnull ((1));
++#endif
++
++
++/* Functions for handling conditional variables. */
++
++/* Initialize condition variable COND using attributes ATTR, or use
++ the default values if later is NULL. */
++extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
++ const pthread_condattr_t *__restrict __cond_attr)
++ __THROW __nonnull ((1));
++
++/* Destroy condition variable COND. */
++extern int pthread_cond_destroy (pthread_cond_t *__cond)
++ __THROW __nonnull ((1));
++
++/* Wake up one thread waiting for condition variable COND. */
++extern int pthread_cond_signal (pthread_cond_t *__cond)
++ __THROWNL __nonnull ((1));
++
++/* Wake up all threads waiting for condition variables COND. */
++extern int pthread_cond_broadcast (pthread_cond_t *__cond)
++ __THROWNL __nonnull ((1));
++
++/* Wait for condition variable COND to be signaled or broadcast.
++ MUTEX is assumed to be locked before.
++
++ This function is a cancellation point and therefore not marked with
++ __THROW. */
++extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
++ pthread_mutex_t *__restrict __mutex)
++ __nonnull ((1, 2));
++
++/* Wait for condition variable COND to be signaled or broadcast until
++ ABSTIME. MUTEX is assumed to be locked before. ABSTIME is an
++ absolute time specification; zero is the beginning of the epoch
++ (00:00:00 GMT, January 1, 1970).
++
++ This function is a cancellation point and therefore not marked with
++ __THROW. */
++extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
++ pthread_mutex_t *__restrict __mutex,
++ const struct timespec *__restrict __abstime)
++ __nonnull ((1, 2, 3));
++
++# ifdef __USE_GNU
++/* Wait for condition variable COND to be signaled or broadcast until
++ ABSTIME measured by the specified clock. MUTEX is assumed to be
++ locked before. CLOCK is the clock to use. ABSTIME is an absolute
++ time specification against CLOCK's epoch.
++
++ This function is a cancellation point and therefore not marked with
++ __THROW. */
++extern int pthread_cond_clockwait (pthread_cond_t *__restrict __cond,
++ pthread_mutex_t *__restrict __mutex,
++ __clockid_t __clock_id,
++ const struct timespec *__restrict __abstime)
++ __nonnull ((1, 2, 4));
++# endif
++
++/* Functions for handling condition variable attributes. */
++
++/* Initialize condition variable attribute ATTR. */
++extern int pthread_condattr_init (pthread_condattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Destroy condition variable attribute ATTR. */
++extern int pthread_condattr_destroy (pthread_condattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Get the process-shared flag of the condition variable attribute ATTR. */
++extern int pthread_condattr_getpshared (const pthread_condattr_t *
++ __restrict __attr,
++ int *__restrict __pshared)
++ __THROW __nonnull ((1, 2));
++
++/* Set the process-shared flag of the condition variable attribute ATTR. */
++extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
++ int __pshared) __THROW __nonnull ((1));
++
++#ifdef __USE_XOPEN2K
++/* Get the clock selected for the condition variable attribute ATTR. */
++extern int pthread_condattr_getclock (const pthread_condattr_t *
++ __restrict __attr,
++ __clockid_t *__restrict __clock_id)
++ __THROW __nonnull ((1, 2));
++
++/* Set the clock selected for the condition variable attribute ATTR. */
++extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
++ __clockid_t __clock_id)
++ __THROW __nonnull ((1));
++#endif
++
++
++#ifdef __USE_XOPEN2K
++/* Functions to handle spinlocks. */
++
++/* Initialize the spinlock LOCK. If PSHARED is nonzero the spinlock can
++ be shared between different processes. */
++extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
++ __THROW __nonnull ((1));
++
++/* Destroy the spinlock LOCK. */
++extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
++ __THROW __nonnull ((1));
++
++/* Wait until spinlock LOCK is retrieved. */
++extern int pthread_spin_lock (pthread_spinlock_t *__lock)
++ __THROWNL __nonnull ((1));
++
++/* Try to lock spinlock LOCK. */
++extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
++ __THROWNL __nonnull ((1));
++
++/* Release spinlock LOCK. */
++extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
++ __THROWNL __nonnull ((1));
++
++
++/* Functions to handle barriers. */
++
++/* Initialize BARRIER with the attributes in ATTR. The barrier is
++ opened when COUNT waiters arrived. */
++extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier,
++ const pthread_barrierattr_t *__restrict
++ __attr, unsigned int __count)
++ __THROW __nonnull ((1));
++
++/* Destroy a previously dynamically initialized barrier BARRIER. */
++extern int pthread_barrier_destroy (pthread_barrier_t *__barrier)
++ __THROW __nonnull ((1));
++
++/* Wait on barrier BARRIER. */
++extern int pthread_barrier_wait (pthread_barrier_t *__barrier)
++ __THROWNL __nonnull ((1));
++
++
++/* Initialize barrier attribute ATTR. */
++extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Destroy previously dynamically initialized barrier attribute ATTR. */
++extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr)
++ __THROW __nonnull ((1));
++
++/* Get the process-shared flag of the barrier attribute ATTR. */
++extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *
++ __restrict __attr,
++ int *__restrict __pshared)
++ __THROW __nonnull ((1, 2));
++
++/* Set the process-shared flag of the barrier attribute ATTR. */
++extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
++ int __pshared)
++ __THROW __nonnull ((1));
++#endif
++
++
++/* Functions for handling thread-specific data. */
++
++/* Create a key value identifying a location in the thread-specific
++ data area. Each thread maintains a distinct thread-specific data
++ area. DESTR_FUNCTION, if non-NULL, is called with the value
++ associated to that key when the key is destroyed.
++ DESTR_FUNCTION is not called if the value associated is NULL when
++ the key is destroyed. */
++extern int pthread_key_create (pthread_key_t *__key,
++ void (*__destr_function) (void *))
++ __THROW __nonnull ((1));
++
++/* Destroy KEY. */
++extern int pthread_key_delete (pthread_key_t __key) __THROW;
++
++/* Return current value of the thread-specific data slot identified by KEY. */
++extern void *pthread_getspecific (pthread_key_t __key) __THROW;
++
++/* Store POINTER in the thread-specific data slot identified by KEY. */
++extern int pthread_setspecific (pthread_key_t __key,
++ const void *__pointer) __THROW ;
++
++
++#ifdef __USE_XOPEN2K
++/* Get ID of CPU-time clock for thread THREAD_ID. */
++extern int pthread_getcpuclockid (pthread_t __thread_id,
++ __clockid_t *__clock_id)
++ __THROW __nonnull ((2));
++#endif
++
++
++/* Install handlers to be called when a new process is created with FORK.
++ The PREPARE handler is called in the parent process just before performing
++ FORK. The PARENT handler is called in the parent process just after FORK.
++ The CHILD handler is called in the child process. Each of the three
++ handlers can be NULL, meaning that no handler needs to be called at that
++ point.
++ PTHREAD_ATFORK can be called several times, in which case the PREPARE
++ handlers are called in LIFO order (last added with PTHREAD_ATFORK,
++ first called before FORK), and the PARENT and CHILD handlers are called
++ in FIFO (first added, first called). */
++
++extern int pthread_atfork (void (*__prepare) (void),
++ void (*__parent) (void),
++ void (*__child) (void)) __THROW;
++
++
++#ifdef __USE_EXTERN_INLINES
++/* Optimizations. */
++__extern_inline int
++__NTH (pthread_equal (pthread_t __thread1, pthread_t __thread2))
++{
++ return __thread1 == __thread2;
++}
++#endif
++
++__END_DECLS
++
++#endif /* pthread.h */
+diff --git a/nptl_2_17/pthread_cond_broadcast_2_17.c b/nptl_2_17/pthread_cond_broadcast_2_17.c
+new file mode 100644
+index 00000000..e1d5f332
+--- /dev/null
++++ b/nptl_2_17/pthread_cond_broadcast_2_17.c
+@@ -0,0 +1,94 @@
++/* Copyright (C) 2003-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <pthread_2_17.h>
++#include <pthreadP_2_17.h>
++#include <endian.h>
++#include <errno.h>
++#include <sysdep.h>
++#include <lowlevellock.h>
++#include <stap-probe.h>
++#include <atomic.h>
++
++#include <shlib-compat.h>
++
++#include <kernel-features.h>
++
++int
++__pthread_cond_broadcast (pthread_cond_t *cond)
++{
++ LIBC_PROBE (cond_broadcast, 1, cond);
++
++ int pshared = (cond->__data.__mutex == (void *) ~0l)
++ ? LLL_SHARED : LLL_PRIVATE;
++ /* Make sure we are alone. */
++ lll_lock (cond->__data.__lock, pshared);
++
++ /* Are there any waiters to be woken? */
++ if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
++
++ {
++ /* Yes. Mark them all as woken. */
++ cond->__data.__wakeup_seq = cond->__data.__total_seq;
++ cond->__data.__woken_seq = cond->__data.__total_seq;
++ cond->__data.__futex = (unsigned int) cond->__data.__total_seq * 2;
++ int futex_val = cond->__data.__futex;
++ /* Signal that a broadcast happened. */
++ ++cond->__data.__broadcast_seq;
++
++ /* We are done. */
++ lll_unlock (cond->__data.__lock, pshared);
++
++ /* Wake everybody. */
++ pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
++
++ /* Do not use requeue for pshared condvars. */
++ if (mut == (void *) ~0l
++ || PTHREAD_MUTEX_PSHARED (mut) & PTHREAD_MUTEX_PSHARED_BIT)
++ goto wake_all;
++
++#if (defined lll_futex_cmp_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ if (USE_REQUEUE_PI (mut))
++ {
++ if (lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, INT_MAX,
++ &mut->__data.__lock, futex_val,
++ LLL_PRIVATE) == 0)
++ return 0;
++ }
++ else
++#endif
++ /* lll_futex_requeue returns 0 for success and non-zero
++ for errors. */
++ if (!__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
++ INT_MAX, &mut->__data.__lock,
++ futex_val, LLL_PRIVATE), 0))
++ return 0;
++
++wake_all:
++ lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
++ return 0;
++ }
++ /* We are done. */
++ lll_unlock (cond->__data.__lock, pshared);
++
++ return 0;
++}
++
++versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
++ GLIBC_2_3_2);
+diff --git a/nptl_2_17/pthread_cond_destroy_2_17.c b/nptl_2_17/pthread_cond_destroy_2_17.c
+new file mode 100644
+index 00000000..62c8ae72
+--- /dev/null
++++ b/nptl_2_17/pthread_cond_destroy_2_17.c
+@@ -0,0 +1,85 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++#include <errno.h>
++#include <shlib-compat.h>
++#include <stap-probe.h>
++int
++__pthread_cond_destroy (pthread_cond_t *cond)
++{
++ int pshared = (cond->__data.__mutex == (void *) ~0l)
++ ? LLL_SHARED : LLL_PRIVATE;
++
++ LIBC_PROBE (cond_destroy, 1, cond);
++
++ /* Make sure we are alone. */
++ lll_lock (cond->__data.__lock, pshared);
++
++ if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
++ {
++ /* If there are still some waiters which have not been
++ woken up, this is an application bug. */
++ lll_unlock (cond->__data.__lock, pshared);
++ return EBUSY;
++ }
++
++ /* Tell pthread_cond_*wait that this condvar is being destroyed. */
++ cond->__data.__total_seq = -1ULL;
++
++ /* If there are waiters which have been already signalled or
++ broadcasted, but still are using the pthread_cond_t structure,
++ pthread_cond_destroy needs to wait for them. */
++ unsigned int nwaiters = cond->__data.__nwaiters;
++
++ if (nwaiters >= (1 << COND_NWAITERS_SHIFT))
++
++ {
++ /* Wake everybody on the associated mutex in case there are
++ threads that have been requeued to it.
++ Without this, pthread_cond_destroy could block potentially
++ for a long time or forever, as it would depend on other
++ thread's using the mutex.
++ When all threads waiting on the mutex are woken up, pthread_cond_wait
++ only waits for threads to acquire and release the internal
++ condvar lock. */
++ if (cond->__data.__mutex != NULL
++ && cond->__data.__mutex != (void *) ~0l)
++ {
++ pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
++ lll_futex_wake (&mut->__data.__lock, INT_MAX,
++ PTHREAD_MUTEX_PSHARED (mut));
++ }
++
++ do
++ {
++ lll_unlock (cond->__data.__lock, pshared);
++
++ lll_futex_wait (&cond->__data.__nwaiters, nwaiters, pshared);
++
++ lll_lock (cond->__data.__lock, pshared);
++
++ nwaiters = cond->__data.__nwaiters;
++ }
++ while (nwaiters >= (1 << COND_NWAITERS_SHIFT));
++ }
++
++ return 0;
++}
++versioned_symbol (libpthread, __pthread_cond_destroy,
++ pthread_cond_destroy, GLIBC_2_3_2);
+diff --git a/nptl_2_17/pthread_cond_init_2_17.c b/nptl_2_17/pthread_cond_init_2_17.c
+new file mode 100644
+index 00000000..7acaa86b
+--- /dev/null
++++ b/nptl_2_17/pthread_cond_init_2_17.c
+@@ -0,0 +1,50 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++#include <shlib-compat.h>
++#include <stap-probe.h>
++
++
++int
++__pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
++{
++ ASSERT_TYPE_SIZE (pthread_cond_t, __SIZEOF_PTHREAD_COND_T);
++
++ struct pthread_condattr *icond_attr = (struct pthread_condattr *) cond_attr;
++
++ cond->__data.__lock = LLL_LOCK_INITIALIZER;
++ cond->__data.__futex = 0;
++ cond->__data.__nwaiters = (icond_attr != NULL
++ ? ((icond_attr->value >> 1)
++ & ((1 << COND_NWAITERS_SHIFT) - 1))
++ : CLOCK_REALTIME);
++ cond->__data.__total_seq = 0;
++ cond->__data.__wakeup_seq = 0;
++ cond->__data.__woken_seq = 0;
++ cond->__data.__mutex = (icond_attr == NULL || (icond_attr->value & 1) == 0
++ ? NULL : (void *) ~0l);
++ cond->__data.__broadcast_seq = 0;
++
++
++ LIBC_PROBE (cond_init, 2, cond, cond_attr);
++
++ return 0;
++}
++versioned_symbol (libpthread, __pthread_cond_init,
++ pthread_cond_init, GLIBC_2_3_2);
+diff --git a/nptl_2_17/pthread_cond_signal_2_17.c b/nptl_2_17/pthread_cond_signal_2_17.c
+new file mode 100644
+index 00000000..a8053d33
+--- /dev/null
++++ b/nptl_2_17/pthread_cond_signal_2_17.c
+@@ -0,0 +1,82 @@
++/* Copyright (C) 2003-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <pthread_2_17.h>
++#include <pthreadP_2_17.h>
++#include <endian.h>
++#include <errno.h>
++#include <sysdep.h>
++#include <lowlevellock.h>
++
++#include <shlib-compat.h>
++#include <kernel-features.h>
++#include <stap-probe.h>
++
++
++int
++__pthread_cond_signal (pthread_cond_t *cond)
++{
++ int pshared = (cond->__data.__mutex == (void *) ~0l)
++ ? LLL_SHARED : LLL_PRIVATE;
++
++ LIBC_PROBE (cond_signal, 1, cond);
++
++ /* Make sure we are alone. */
++ lll_lock (cond->__data.__lock, pshared);
++
++ /* Are there any waiters to be woken? */
++ if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
++ {
++ /* Yes. Mark one of them as woken. */
++ ++cond->__data.__wakeup_seq;
++ ++cond->__data.__futex;
++
++#if (defined lll_futex_cmp_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ pthread_mutex_t *mut = cond->__data.__mutex;
++
++ if (USE_REQUEUE_PI (mut)
++ /* This can only really fail with a ENOSYS, since nobody can modify
++ futex while we have the cond_lock. */
++ && lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, 0,
++ &mut->__data.__lock,
++ cond->__data.__futex, pshared) == 0)
++ {
++ lll_unlock (cond->__data.__lock, pshared);
++ return 0;
++ }
++ else
++#endif
++ /* Wake one. */
++ if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex,
++ 1, 1,
++ &cond->__data.__lock,
++ pshared), 0))
++ return 0;
++
++ /* Fallback if neither of them work. */
++ lll_futex_wake (&cond->__data.__futex, 1, pshared);
++ }
++/* We are done. */
++ lll_unlock (cond->__data.__lock, pshared);
++
++ return 0;
++}
++
++versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
++ GLIBC_2_3_2);
+diff --git a/nptl_2_17/pthread_cond_timedwait_2_17.c b/nptl_2_17/pthread_cond_timedwait_2_17.c
+new file mode 100644
+index 00000000..965d51a1
+--- /dev/null
++++ b/nptl_2_17/pthread_cond_timedwait_2_17.c
+@@ -0,0 +1,268 @@
++/* Copyright (C) 2003-2016 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 <pthread_2_17.h>
++#include <pthreadP_2_17.h>
++#include <endian.h>
++#include <errno.h>
++#include <sysdep.h>
++#include <lowlevellock.h>
++#include <sys/time.h>
++#include <kernel-features.h>
++
++#include <shlib-compat.h>
++
++#ifndef HAVE_CLOCK_GETTIME_VSYSCALL
++# undef INTERNAL_VSYSCALL
++# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
++# undef INLINE_VSYSCALL
++# define INLINE_VSYSCALL INLINE_SYSCALL
++#else
++# include <libc-vdso.h>
++#endif
++
++/* Cleanup handler, defined in pthread_cond_wait.c. */
++extern void __condvar_cleanup (void *arg)
++ __attribute__ ((visibility ("hidden")));
++
++struct _condvar_cleanup_buffer
++{
++ int oldtype;
++ pthread_cond_t *cond;
++ pthread_mutex_t *mutex;
++ unsigned int bc_seq;
++};
++
++int
++__pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
++ const struct timespec *abstime)
++{
++ struct _pthread_cleanup_buffer buffer;
++ struct _condvar_cleanup_buffer cbuffer;
++ int result = 0;
++
++ /* Catch invalid parameters. */
++ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
++ return EINVAL;
++
++ int pshared = (cond->__data.__mutex == (void *) ~0l)
++ ? LLL_SHARED : LLL_PRIVATE;
++
++#if (defined lll_futex_timed_wait_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ int pi_flag = 0;
++#endif
++
++ /* Make sure we are alone. */
++ lll_lock (cond->__data.__lock, pshared);
++
++ /* Now we can release the mutex. */
++ int err = __pthread_mutex_unlock_usercnt (mutex, 0);
++ if (err)
++ {
++ lll_unlock (cond->__data.__lock, pshared);
++ return err;
++ }
++
++ /* We have one new user of the condvar. */
++ ++cond->__data.__total_seq;
++ ++cond->__data.__futex;
++ cond->__data.__nwaiters += 1 << COND_NWAITERS_SHIFT;
++
++ /* Work around the fact that the kernel rejects negative timeout values
++ despite them being valid. */
++ if (__glibc_unlikely (abstime->tv_sec < 0))
++ goto timeout;
++
++ /* Remember the mutex we are using here. If there is already a
++ different address store this is a bad user bug. Do not store
++ anything for pshared condvars. */
++ if (cond->__data.__mutex != (void *) ~0l)
++ cond->__data.__mutex = mutex;
++
++ /* Prepare structure passed to cancellation handler. */
++ cbuffer.cond = cond;
++ cbuffer.mutex = mutex;
++
++ /* Before we block we enable cancellation. Therefore we have to
++ install a cancellation handler. */
++ __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
++
++ /* The current values of the wakeup counter. The "woken" counter
++ must exceed this value. */
++ unsigned long long int val;
++ unsigned long long int seq;
++ val = seq = cond->__data.__wakeup_seq;
++ /* Remember the broadcast counter. */
++ cbuffer.bc_seq = cond->__data.__broadcast_seq;
++
++ while (1)
++ {
++#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
++ || !defined lll_futex_timed_wait_bitset)
++ struct timespec rt;
++ {
++# ifdef __NR_clock_gettime
++ INTERNAL_SYSCALL_DECL (err);
++ (void) INTERNAL_VSYSCALL (clock_gettime, err, 2,
++ (cond->__data.__nwaiters
++ & ((1 << COND_NWAITERS_SHIFT) - 1)),
++ &rt);
++ /* Convert the absolute timeout value to a relative timeout. */
++ rt.tv_sec = abstime->tv_sec - rt.tv_sec;
++ rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
++# else
++ /* Get the current time. So far we support only one clock. */
++ struct timeval tv;
++ (void) __gettimeofday (&tv, NULL);
++
++ /* Convert the absolute timeout value to a relative timeout. */
++ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
++ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
++# endif
++ }
++ if (rt.tv_nsec < 0)
++ {
++ rt.tv_nsec += 1000000000;
++ --rt.tv_sec;
++ }
++ /* Did we already time out? */
++ if (__glibc_unlikely (rt.tv_sec < 0))
++ {
++ if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
++ goto bc_out;
++
++ goto timeout;
++ }
++#endif
++
++ unsigned int futex_val = cond->__data.__futex;
++
++ /* Prepare to wait. Release the condvar futex. */
++ lll_unlock (cond->__data.__lock, pshared);
++
++ /* Enable asynchronous cancellation. Required by the standard. */
++ cbuffer.oldtype = __pthread_enable_asynccancel ();
++
++/* REQUEUE_PI was implemented after FUTEX_CLOCK_REALTIME, so it is sufficient
++ to check just the former. */
++#if (defined lll_futex_timed_wait_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ /* If pi_flag remained 1 then it means that we had the lock and the mutex
++ but a spurious waker raced ahead of us. Give back the mutex before
++ going into wait again. */
++ if (pi_flag)
++ {
++ __pthread_mutex_cond_lock_adjust (mutex);
++ __pthread_mutex_unlock_usercnt (mutex, 0);
++ }
++ pi_flag = USE_REQUEUE_PI (mutex);
++
++ if (pi_flag)
++ {
++ unsigned int clockbit = (cond->__data.__nwaiters & 1
++ ? 0 : FUTEX_CLOCK_REALTIME);
++ err = lll_futex_timed_wait_requeue_pi (&cond->__data.__futex,
++ futex_val, abstime, clockbit,
++ &mutex->__data.__lock,
++ pshared);
++ pi_flag = (err == 0);
++ }
++ else
++#endif
++
++ {
++#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
++ || !defined lll_futex_timed_wait_bitset)
++ /* Wait until woken by signal or broadcast. */
++ err = lll_futex_timed_wait (&cond->__data.__futex,
++ futex_val, &rt, pshared);
++#else
++ unsigned int clockbit = (cond->__data.__nwaiters & 1
++ ? 0 : FUTEX_CLOCK_REALTIME);
++ err = lll_futex_timed_wait_bitset (&cond->__data.__futex, futex_val,
++ abstime, clockbit, pshared);
++#endif
++ }
++
++ /* Disable asynchronous cancellation. */
++ __pthread_disable_asynccancel (cbuffer.oldtype);
++
++ /* We are going to look at shared data again, so get the lock. */
++ lll_lock (cond->__data.__lock, pshared);
++
++ /* If a broadcast happened, we are done. */
++ if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
++ goto bc_out;
++
++ /* Check whether we are eligible for wakeup. */
++ val = cond->__data.__wakeup_seq;
++ if (val != seq && cond->__data.__woken_seq != val)
++ break;
++
++ /* Not woken yet. Maybe the time expired? */
++ if (__glibc_unlikely (err == -ETIMEDOUT))
++ {
++ timeout:
++ /* Yep. Adjust the counters. */
++ ++cond->__data.__wakeup_seq;
++ ++cond->__data.__futex;
++
++ /* The error value. */
++ result = ETIMEDOUT;
++ break;
++ }
++ }
++
++ /* Another thread woken up. */
++ ++cond->__data.__woken_seq;
++
++ bc_out:
++
++ cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
++
++ /* If pthread_cond_destroy was called on this variable already,
++ notify the pthread_cond_destroy caller all waiters have left
++ and it can be successfully destroyed. */
++ if (cond->__data.__total_seq == -1ULL
++ && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
++ lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
++
++ /* We are done with the condvar. */
++ lll_unlock (cond->__data.__lock, pshared);
++
++ /* The cancellation handling is back to normal, remove the handler. */
++ __pthread_cleanup_pop (&buffer, 0);
++
++ /* Get the mutex before returning. */
++#if (defined lll_futex_timed_wait_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ if (pi_flag)
++ {
++ __pthread_mutex_cond_lock_adjust (mutex);
++ err = 0;
++ }
++ else
++#endif
++ err = __pthread_mutex_cond_lock (mutex);
++
++ return err ?: result;
++}
++
++versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
++ GLIBC_2_3_2);
+diff --git a/nptl_2_17/pthread_cond_wait_2_17.c b/nptl_2_17/pthread_cond_wait_2_17.c
+new file mode 100644
+index 00000000..ecd404ad
+--- /dev/null
++++ b/nptl_2_17/pthread_cond_wait_2_17.c
+@@ -0,0 +1,231 @@
++/* Copyright (C) 2003-2018 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 <pthread_2_17.h>
++#include <pthreadP_2_17.h>
++#include <endian.h>
++#include <errno.h>
++#include <sysdep.h>
++#include <lowlevellock.h>
++#include <kernel-features.h>
++#include <shlib-compat.h>
++#include <stap-probe.h>
++
++struct _condvar_cleanup_buffer
++{
++ int oldtype;
++ pthread_cond_t *cond;
++ pthread_mutex_t *mutex;
++ unsigned int bc_seq;
++};
++
++void
++__attribute__ ((visibility ("hidden")))
++__condvar_cleanup (void *arg)
++{
++ struct _condvar_cleanup_buffer *cbuffer =
++ (struct _condvar_cleanup_buffer *) arg;
++ unsigned int destroying;
++ int pshared = (cbuffer->cond->__data.__mutex == (void *) ~0l)
++ ? LLL_SHARED : LLL_PRIVATE;
++
++ /* We are going to modify shared data. */
++ lll_lock (cbuffer->cond->__data.__lock, pshared);
++
++ if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
++ {
++ /* This thread is not waiting anymore. Adjust the sequence counters
++ * appropriately. We do not increment WAKEUP_SEQ if this would
++ * bump it over the value of TOTAL_SEQ. This can happen if a thread
++ * was woken and then canceled. */
++ if (cbuffer->cond->__data.__wakeup_seq
++ < cbuffer->cond->__data.__total_seq)
++ {
++ ++cbuffer->cond->__data.__wakeup_seq;
++ ++cbuffer->cond->__data.__futex;
++ }
++ ++cbuffer->cond->__data.__woken_seq;
++ }
++
++ cbuffer->cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
++
++ /* If pthread_cond_destroy was called on this variable already,
++ * notify the pthread_cond_destroy caller all waiters have left
++ * and it can be successfully destroyed. */
++ destroying = 0;
++ if (cbuffer->cond->__data.__total_seq == -1ULL
++ && cbuffer->cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
++ {
++ lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1, pshared);
++ destroying = 1;
++ }
++
++ /* We are done. */
++ lll_unlock (cbuffer->cond->__data.__lock, pshared);
++
++ /* Wake everybody to make sure no condvar signal gets lost. */
++ if (! destroying)
++ lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared);
++
++ /* Get the mutex before returning unless asynchronous cancellation
++ * is in effect. We don't try to get the mutex if we already own it. */
++ if (!(USE_REQUEUE_PI (cbuffer->mutex))
++ || ((cbuffer->mutex->__data.__lock & FUTEX_TID_MASK)
++ != THREAD_GETMEM (THREAD_SELF, tid)))
++ {
++ __pthread_mutex_cond_lock (cbuffer->mutex);
++ }
++ else
++ __pthread_mutex_cond_lock_adjust (cbuffer->mutex);
++}
++
++int
++__pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
++{
++struct _pthread_cleanup_buffer buffer;
++ struct _condvar_cleanup_buffer cbuffer;
++ int err;
++ int pshared = (cond->__data.__mutex == (void *) ~0l)
++ ? LLL_SHARED : LLL_PRIVATE;
++
++#if (defined lll_futex_wait_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ int pi_flag = 0;
++#endif
++
++ LIBC_PROBE (cond_wait, 2, cond, mutex);
++ /* Make sure we are alone. */
++ lll_lock (cond->__data.__lock, pshared);
++
++ /* Now we can release the mutex. */
++ err = __pthread_mutex_unlock_usercnt (mutex, 0);
++ if (__glibc_unlikely (err))
++ {
++ lll_unlock (cond->__data.__lock, pshared);
++ return err;
++ }
++ /* We have one new user of the condvar. */
++ ++cond->__data.__total_seq;
++ ++cond->__data.__futex;
++ cond->__data.__nwaiters += 1 << COND_NWAITERS_SHIFT;
++
++ /* Remember the mutex we are using here. If there is already a
++ * different address store this is a bad user bug. Do not store
++ * anything for pshared condvars. */
++ if (cond->__data.__mutex != (void *) ~0l)
++ cond->__data.__mutex = mutex;
++
++ /* Prepare structure passed to cancellation handler. */
++ cbuffer.cond = cond;
++ cbuffer.mutex = mutex;
++
++ /* Before we block we enable cancellation. Therefore we have to
++ * install a cancellation handler. */
++ __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
++
++ /* The current values of the wakeup counter. The "woken" counter
++ * must exceed this value. */
++ unsigned long long int val;
++ unsigned long long int seq;
++ val = seq = cond->__data.__wakeup_seq;
++ /* Remember the broadcast counter. */
++ cbuffer.bc_seq = cond->__data.__broadcast_seq;
++
++ do
++ {
++ unsigned int futex_val = cond->__data.__futex;
++ /* Prepare to wait. Release the condvar futex. */
++ lll_unlock (cond->__data.__lock, pshared);
++
++ /* Enable asynchronous cancellation. Required by the standard. */
++ cbuffer.oldtype = __pthread_enable_asynccancel ();
++
++#if (defined lll_futex_wait_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ /* If pi_flag remained 1 then it means that we had the lock and the mutex
++ but a spurious waker raced ahead of us. Give back the mutex before
++ going into wait again. */
++ if (pi_flag)
++ {
++ __pthread_mutex_cond_lock_adjust (mutex);
++ __pthread_mutex_unlock_usercnt (mutex, 0);
++ }
++ pi_flag = USE_REQUEUE_PI (mutex);
++
++ if (pi_flag)
++ {
++ err = lll_futex_wait_requeue_pi (&cond->__data.__futex,
++ futex_val, &mutex->__data.__lock,
++ pshared);
++
++ pi_flag = (err == 0);
++ }
++ else
++#endif
++ /* Wait until woken by signal or broadcast. */
++ lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
++
++ /* Disable asynchronous cancellation. */
++ __pthread_disable_asynccancel (cbuffer.oldtype);
++
++ /* We are going to look at shared data again, so get the lock. */
++ lll_lock (cond->__data.__lock, pshared);
++
++ /* If a broadcast happened, we are done. */
++ if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
++ goto bc_out;
++
++ /* Check whether we are eligible for wakeup. */
++ val = cond->__data.__wakeup_seq;
++ }
++ while (val == seq || cond->__data.__woken_seq == val);
++
++ /* Another thread woken up. */
++ ++cond->__data.__woken_seq;
++
++bc_out:
++ cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
++
++ /* If pthread_cond_destroy was called on this varaible already,
++ notify the pthread_cond_destroy caller all waiters have left
++ and it can be successfully destroyed. */
++ if (cond->__data.__total_seq == -1ULL
++ && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
++ lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
++
++ /* We are done with the condvar. */
++ lll_unlock (cond->__data.__lock, pshared);
++
++ /* The cancellation handling is back to normal, remove the handler. */
++ __pthread_cleanup_pop (&buffer, 0);
++
++ /* Get the mutex before returning. Not needed for PI. */
++#if (defined lll_futex_wait_requeue_pi \
++ && defined __ASSUME_REQUEUE_PI)
++ if (pi_flag)
++ {
++ __pthread_mutex_cond_lock_adjust (mutex);
++ return 0;
++ }
++ else
++#endif
++ return __pthread_mutex_cond_lock (mutex);
++}
++
++versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
++ GLIBC_2_3_2);
+diff --git a/nptl_2_17/pthread_condattr_getclock_2_17.c b/nptl_2_17/pthread_condattr_getclock_2_17.c
+new file mode 100644
+index 00000000..e07b349e
+--- /dev/null
++++ b/nptl_2_17/pthread_condattr_getclock_2_17.c
+@@ -0,0 +1,28 @@
++/* Copyright (C) 2003-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ulrich Drepper <drepper@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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++
++
++int
++pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t *clock_id)
++{
++ *clock_id = (((((const struct pthread_condattr *) attr)->value) >> 1)
++ & ((1 << COND_NWAITERS_SHIFT) - 1));
++ return 0;
++}
+diff --git a/nptl_2_17/pthread_condattr_getpshared_2_17.c b/nptl_2_17/pthread_condattr_getpshared_2_17.c
+new file mode 100644
+index 00000000..8f4fe2bf
+--- /dev/null
++++ b/nptl_2_17/pthread_condattr_getpshared_2_17.c
+@@ -0,0 +1,28 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++
++
++int
++pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
++{
++ *pshared = ((const struct pthread_condattr *) attr)->value & 1;
++
++ return 0;
++}
+diff --git a/nptl_2_17/pthread_condattr_init_2_17.c b/nptl_2_17/pthread_condattr_init_2_17.c
+new file mode 100644
+index 00000000..d90ba1e8
+--- /dev/null
++++ b/nptl_2_17/pthread_condattr_init_2_17.c
+@@ -0,0 +1,34 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include <string.h>
++#include "pthreadP_2_17.h"
++
++
++int
++__pthread_condattr_init (pthread_condattr_t *attr)
++{
++ ASSERT_TYPE_SIZE (pthread_condattr_t, __SIZEOF_PTHREAD_CONDATTR_T);
++ ASSERT_PTHREAD_INTERNAL_SIZE (pthread_condattr_t,
++ struct pthread_condattr);
++
++ memset (attr, '\0', sizeof (*attr));
++
++ return 0;
++}
++strong_alias (__pthread_condattr_init, pthread_condattr_init)
+diff --git a/nptl_2_17/pthread_condattr_setclock_2_17.c b/nptl_2_17/pthread_condattr_setclock_2_17.c
+new file mode 100644
+index 00000000..5d91f17b
+--- /dev/null
++++ b/nptl_2_17/pthread_condattr_setclock_2_17.c
+@@ -0,0 +1,45 @@
++/* Copyright (C) 2003-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ulrich Drepper <drepper@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
++ <https://www.gnu.org/licenses/>. */
++
++#include <assert.h>
++#include <errno.h>
++#include <stdbool.h>
++#include <time.h>
++#include <sysdep.h>
++#include "pthreadP_2_17.h"
++
++
++int
++pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
++{
++ /* Only a few clocks are allowed. */
++ if (clock_id != CLOCK_MONOTONIC && clock_id != CLOCK_REALTIME)
++ /* If more clocks are allowed some day the storing of the clock ID
++ in the pthread_cond_t structure needs to be adjusted. */
++ return EINVAL;
++
++ /* Make sure the value fits in the bits we reserved. */
++ assert (clock_id < (1 << COND_NWAITERS_SHIFT));
++
++ int *valuep = &((struct pthread_condattr *) attr)->value;
++
++ *valuep = ((*valuep & ~(((1 << COND_NWAITERS_SHIFT) - 1) << 1))
++ | (clock_id << 1));
++
++ return 0;
++}
+diff --git a/nptl_2_17/pthread_mutex_cond_lock_2_17.c b/nptl_2_17/pthread_mutex_cond_lock_2_17.c
+new file mode 100644
+index 00000000..2f077130
+--- /dev/null
++++ b/nptl_2_17/pthread_mutex_cond_lock_2_17.c
+@@ -0,0 +1,21 @@
++#include <pthreadP.h>
++
++#define LLL_MUTEX_LOCK(mutex) \
++ lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
++
++/* Not actually elided so far. Needed? */
++#define LLL_MUTEX_LOCK_ELISION(mutex) \
++ ({ lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); 0; })
++
++#define LLL_MUTEX_TRYLOCK(mutex) \
++ lll_cond_trylock ((mutex)->__data.__lock)
++#define LLL_MUTEX_TRYLOCK_ELISION(mutex) LLL_MUTEX_TRYLOCK(mutex)
++
++/* We need to assume that there are other threads blocked on the futex.
++ See __pthread_mutex_lock_full for further details. */
++#define LLL_ROBUST_MUTEX_LOCK_MODIFIER FUTEX_WAITERS
++#define __pthread_mutex_lock __pthread_mutex_cond_lock
++#define __pthread_mutex_lock_full __pthread_mutex_cond_lock_full
++#define NO_INCR
++
++#include <nptl/pthread_mutex_lock.c>
+diff --git a/nptl_2_17/pthread_mutex_lock_2_17.c b/nptl_2_17/pthread_mutex_lock_2_17.c
+new file mode 100644
+index 00000000..73ee0842
+--- /dev/null
++++ b/nptl_2_17/pthread_mutex_lock_2_17.c
+@@ -0,0 +1,628 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++#include <assert.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/param.h>
++#include <not-cancel.h>
++#include <atomic.h>
++#include <futex-internal.h>
++#include <stap-probe.h>
++
++#ifndef lll_lock_elision
++#define lll_lock_elision(lock, try_lock, private) ({ \
++ lll_lock (lock, private); 0; })
++#endif
++
++#ifndef lll_trylock_elision
++#define lll_trylock_elision(a,t) lll_trylock(a)
++#endif
++
++/* Some of the following definitions differ when pthread_mutex_cond_lock.c
++ includes this file. */
++#ifndef LLL_MUTEX_LOCK
++# define LLL_MUTEX_LOCK(mutex) \
++ lll_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
++# define LLL_MUTEX_TRYLOCK(mutex) \
++ lll_trylock ((mutex)->__data.__lock)
++# define LLL_ROBUST_MUTEX_LOCK_MODIFIER 0
++# define LLL_MUTEX_LOCK_ELISION(mutex) \
++ lll_lock_elision ((mutex)->__data.__lock, (mutex)->__data.__elision, \
++ PTHREAD_MUTEX_PSHARED (mutex))
++# define LLL_MUTEX_TRYLOCK_ELISION(mutex) \
++ lll_trylock_elision((mutex)->__data.__lock, (mutex)->__data.__elision, \
++ PTHREAD_MUTEX_PSHARED (mutex))
++#endif
++
++#ifndef FORCE_ELISION
++#define FORCE_ELISION(m, s)
++#endif
++
++static int __pthread_mutex_lock_full (pthread_mutex_t *mutex)
++ __attribute_noinline__;
++
++int
++__pthread_mutex_lock (pthread_mutex_t *mutex)
++{
++ /* See concurrency notes regarding mutex type which is loaded from __kind
++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
++ unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
++
++ LIBC_PROBE (mutex_entry, 1, mutex);
++
++ if (__builtin_expect (type & ~(PTHREAD_MUTEX_KIND_MASK_NP
++ | PTHREAD_MUTEX_ELISION_FLAGS_NP), 0))
++ return __pthread_mutex_lock_full (mutex);
++
++ if (__glibc_likely (type == PTHREAD_MUTEX_TIMED_NP))
++ {
++ FORCE_ELISION (mutex, goto elision);
++ simple:
++ /* Normal mutex. */
++ LLL_MUTEX_LOCK (mutex);
++ assert (mutex->__data.__owner == 0);
++ }
++#ifdef HAVE_ELISION
++ else if (__glibc_likely (type == PTHREAD_MUTEX_TIMED_ELISION_NP))
++ {
++ elision: __attribute__((unused))
++ /* This case can never happen on a system without elision,
++ as the mutex type initialization functions will not
++ allow to set the elision flags. */
++ /* Don't record owner or users for elision case. This is a
++ tail call. */
++ return LLL_MUTEX_LOCK_ELISION (mutex);
++ }
++#endif
++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
++ == PTHREAD_MUTEX_RECURSIVE_NP, 1))
++ {
++ /* Recursive mutex. */
++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
++
++ /* Check whether we already hold the mutex. */
++ if (mutex->__data.__owner == id)
++ {
++ /* Just bump the counter. */
++ if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
++ /* Overflow of the counter. */
++ return EAGAIN;
++
++ ++mutex->__data.__count;
++
++ return 0;
++ }
++
++ /* We have to get the mutex. */
++ LLL_MUTEX_LOCK (mutex);
++
++ assert (mutex->__data.__owner == 0);
++ mutex->__data.__count = 1;
++ }
++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
++ == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
++ {
++ if (! __is_smp)
++ goto simple;
++
++ if (LLL_MUTEX_TRYLOCK (mutex) != 0)
++ {
++ int cnt = 0;
++ int max_cnt = MIN (DEFAULT_ADAPTIVE_COUNT,
++ mutex->__data.__spins * 2 + 10);
++ do
++ {
++ if (cnt++ >= max_cnt)
++ {
++ LLL_MUTEX_LOCK (mutex);
++ break;
++ }
++ atomic_spin_nop ();
++ }
++ while (LLL_MUTEX_TRYLOCK (mutex) != 0);
++
++ mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
++ }
++ assert (mutex->__data.__owner == 0);
++ }
++ else
++ {
++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
++ assert (PTHREAD_MUTEX_TYPE (mutex) == PTHREAD_MUTEX_ERRORCHECK_NP);
++ /* Check whether we already hold the mutex. */
++ if (__glibc_unlikely (mutex->__data.__owner == id))
++ return EDEADLK;
++ goto simple;
++ }
++
++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
++
++ /* Record the ownership. */
++ mutex->__data.__owner = id;
++#ifndef NO_INCR
++ ++mutex->__data.__nusers;
++#endif
++
++ LIBC_PROBE (mutex_acquired, 1, mutex);
++
++ return 0;
++}
++
++static int
++__pthread_mutex_lock_full (pthread_mutex_t *mutex)
++{
++ int oldval;
++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
++
++ switch (PTHREAD_MUTEX_TYPE (mutex))
++ {
++ case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
++ case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
++ case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
++ case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++ &mutex->__data.__list.__next);
++ /* We need to set op_pending before starting the operation. Also
++ see comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++
++ oldval = mutex->__data.__lock;
++ /* This is set to FUTEX_WAITERS iff we might have shared the
++ FUTEX_WAITERS flag with other threads, and therefore need to keep it
++ set to avoid lost wake-ups. We have the same requirement in the
++ simple mutex algorithm.
++ We start with value zero for a normal mutex, and FUTEX_WAITERS if we
++ are building the special case mutexes for use from within condition
++ variables. */
++ unsigned int assume_other_futex_waiters = LLL_ROBUST_MUTEX_LOCK_MODIFIER;
++ while (1)
++ {
++ /* Try to acquire the lock through a CAS from 0 (not acquired) to
++ our TID | assume_other_futex_waiters. */
++ if (__glibc_likely (oldval == 0))
++ {
++ oldval
++ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
++ id | assume_other_futex_waiters, 0);
++ if (__glibc_likely (oldval == 0))
++ break;
++ }
++
++ if ((oldval & FUTEX_OWNER_DIED) != 0)
++ {
++ /* The previous owner died. Try locking the mutex. */
++ int newval = id;
++#ifdef NO_INCR
++ /* We are not taking assume_other_futex_waiters into accoount
++ here simply because we'll set FUTEX_WAITERS anyway. */
++ newval |= FUTEX_WAITERS;
++#else
++ newval |= (oldval & FUTEX_WAITERS) | assume_other_futex_waiters;
++#endif
++
++ newval
++ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
++ newval, oldval);
++
++ if (newval != oldval)
++ {
++ oldval = newval;
++ continue;
++ }
++
++ /* We got the mutex. */
++ mutex->__data.__count = 1;
++ /* But it is inconsistent unless marked otherwise. */
++ mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
++
++ /* We must not enqueue the mutex before we have acquired it.
++ Also see comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++ ENQUEUE_MUTEX (mutex);
++ /* We need to clear op_pending after we enqueue the mutex. */
++ __asm ("" ::: "memory");
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++
++ /* Note that we deliberately exit here. If we fall
++ through to the end of the function __nusers would be
++ incremented which is not correct because the old
++ owner has to be discounted. If we are not supposed
++ to increment __nusers we actually have to decrement
++ it here. */
++#ifdef NO_INCR
++ --mutex->__data.__nusers;
++#endif
++
++ return EOWNERDEAD;
++ }
++
++ /* Check whether we already hold the mutex. */
++ if (__glibc_unlikely ((oldval & FUTEX_TID_MASK) == id))
++ {
++ int kind = PTHREAD_MUTEX_TYPE (mutex);
++ if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
++ {
++ /* We do not need to ensure ordering wrt another memory
++ access. Also see comments at ENQUEUE_MUTEX. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++ NULL);
++ return EDEADLK;
++ }
++
++ if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
++ {
++ /* We do not need to ensure ordering wrt another memory
++ access. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++ NULL);
++
++ /* Just bump the counter. */
++ if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
++ /* Overflow of the counter. */
++ return EAGAIN;
++
++ ++mutex->__data.__count;
++
++ return 0;
++ }
++ }
++
++ /* We cannot acquire the mutex nor has its owner died. Thus, try
++ to block using futexes. Set FUTEX_WAITERS if necessary so that
++ other threads are aware that there are potentially threads
++ blocked on the futex. Restart if oldval changed in the
++ meantime. */
++ if ((oldval & FUTEX_WAITERS) == 0)
++ {
++ if (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
++ oldval | FUTEX_WAITERS,
++ oldval)
++ != 0)
++ {
++ oldval = mutex->__data.__lock;
++ continue;
++ }
++ oldval |= FUTEX_WAITERS;
++ }
++
++ /* It is now possible that we share the FUTEX_WAITERS flag with
++ another thread; therefore, update assume_other_futex_waiters so
++ that we do not forget about this when handling other cases
++ above and thus do not cause lost wake-ups. */
++ assume_other_futex_waiters |= FUTEX_WAITERS;
++
++ /* Block using the futex and reload current lock value. */
++ lll_futex_wait (&mutex->__data.__lock, oldval,
++ PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
++ oldval = mutex->__data.__lock;
++ }
++
++ /* We have acquired the mutex; check if it is still consistent. */
++ if (__builtin_expect (mutex->__data.__owner
++ == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
++ {
++ /* This mutex is now not recoverable. */
++ mutex->__data.__count = 0;
++ int private = PTHREAD_ROBUST_MUTEX_PSHARED (mutex);
++ lll_unlock (mutex->__data.__lock, private);
++ /* FIXME This violates the mutex destruction requirements. See
++ __pthread_mutex_unlock_full. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++ return ENOTRECOVERABLE;
++ }
++
++ mutex->__data.__count = 1;
++ /* We must not enqueue the mutex before we have acquired it.
++ Also see comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++ ENQUEUE_MUTEX (mutex);
++ /* We need to clear op_pending after we enqueue the mutex. */
++ __asm ("" ::: "memory");
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++ break;
++
++ /* The PI support requires the Linux futex system call. If that's not
++ available, pthread_mutex_init should never have allowed the type to
++ be set. So it will get the default case for an invalid type. */
++#ifdef __NR_futex
++ case PTHREAD_MUTEX_PI_RECURSIVE_NP:
++ case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
++ case PTHREAD_MUTEX_PI_NORMAL_NP:
++ case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
++ case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
++ case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
++ case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
++ case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
++ {
++ int kind, robust;
++ {
++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
++ in sysdeps/nptl/bits/thread-shared-types.h. */
++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
++ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
++ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
++ }
++
++ if (robust)
++ {
++ /* Note: robust PI futexes are signaled by setting bit 0. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++ (void *) (((uintptr_t) &mutex->__data.__list.__next)
++ | 1));
++ /* We need to set op_pending before starting the operation. Also
++ see comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++ }
++
++ oldval = mutex->__data.__lock;
++
++ /* Check whether we already hold the mutex. */
++ if (__glibc_unlikely ((oldval & FUTEX_TID_MASK) == id))
++ {
++ if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
++ {
++ /* We do not need to ensure ordering wrt another memory
++ access. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++ return EDEADLK;
++ }
++
++ if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
++ {
++ /* We do not need to ensure ordering wrt another memory
++ access. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++
++ /* Just bump the counter. */
++ if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
++ /* Overflow of the counter. */
++ return EAGAIN;
++
++ ++mutex->__data.__count;
++
++ return 0;
++ }
++ }
++
++ int newval = id;
++# ifdef NO_INCR
++ newval |= FUTEX_WAITERS;
++# endif
++ oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
++ newval, 0);
++
++ if (oldval != 0)
++ {
++ /* The mutex is locked. The kernel will now take care of
++ everything. */
++ int private = (robust
++ ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
++ : PTHREAD_MUTEX_PSHARED (mutex));
++ int e = futex_lock_pi ((unsigned int *) &mutex->__data.__lock,
++ NULL, private);
++ if (e == ESRCH || e == EDEADLK)
++ {
++ assert (e != EDEADLK
++ || (kind != PTHREAD_MUTEX_ERRORCHECK_NP
++ && kind != PTHREAD_MUTEX_RECURSIVE_NP));
++ /* ESRCH can happen only for non-robust PI mutexes where
++ the owner of the lock died. */
++ assert (e != ESRCH || !robust);
++
++ /* Delay the thread indefinitely. */
++ while (1)
++ lll_timedwait (&(int){0}, 0, 0 /* ignored */, NULL,
++ private);
++ }
++
++ oldval = mutex->__data.__lock;
++
++ assert (robust || (oldval & FUTEX_OWNER_DIED) == 0);
++ }
++
++ if (__glibc_unlikely (oldval & FUTEX_OWNER_DIED))
++ {
++ atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
++
++ /* We got the mutex. */
++ mutex->__data.__count = 1;
++ /* But it is inconsistent unless marked otherwise. */
++ mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
++
++ /* We must not enqueue the mutex before we have acquired it.
++ Also see comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++ ENQUEUE_MUTEX_PI (mutex);
++ /* We need to clear op_pending after we enqueue the mutex. */
++ __asm ("" ::: "memory");
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++
++ /* Note that we deliberately exit here. If we fall
++ through to the end of the function __nusers would be
++ incremented which is not correct because the old owner
++ has to be discounted. If we are not supposed to
++ increment __nusers we actually have to decrement it here. */
++# ifdef NO_INCR
++ --mutex->__data.__nusers;
++# endif
++
++ return EOWNERDEAD;
++ }
++
++ if (robust
++ && __builtin_expect (mutex->__data.__owner
++ == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
++ {
++ /* This mutex is now not recoverable. */
++ mutex->__data.__count = 0;
++
++ futex_unlock_pi ((unsigned int *) &mutex->__data.__lock,
++ PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
++
++ /* To the kernel, this will be visible after the kernel has
++ acquired the mutex in the syscall. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++ return ENOTRECOVERABLE;
++ }
++
++ mutex->__data.__count = 1;
++ if (robust)
++ {
++ /* We must not enqueue the mutex before we have acquired it.
++ Also see comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++ ENQUEUE_MUTEX_PI (mutex);
++ /* We need to clear op_pending after we enqueue the mutex. */
++ __asm ("" ::: "memory");
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++ }
++ }
++ break;
++#endif /* __NR_futex. */
++
++ case PTHREAD_MUTEX_PP_RECURSIVE_NP:
++ case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
++ case PTHREAD_MUTEX_PP_NORMAL_NP:
++ case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
++ {
++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
++ in sysdeps/nptl/bits/thread-shared-types.h. */
++ int kind = atomic_load_relaxed (&(mutex->__data.__kind))
++ & PTHREAD_MUTEX_KIND_MASK_NP;
++
++ oldval = mutex->__data.__lock;
++
++ /* Check whether we already hold the mutex. */
++ if (mutex->__data.__owner == id)
++ {
++ if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
++ return EDEADLK;
++
++ if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
++ {
++ /* Just bump the counter. */
++ if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
++ /* Overflow of the counter. */
++ return EAGAIN;
++
++ ++mutex->__data.__count;
++
++ return 0;
++ }
++ }
++
++ int oldprio = -1, ceilval;
++ do
++ {
++ int ceiling = (oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK)
++ >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
++
++ if (__pthread_current_priority () > ceiling)
++ {
++ if (oldprio != -1)
++ __pthread_tpp_change_priority (oldprio, -1);
++ return EINVAL;
++ }
++
++ int retval = __pthread_tpp_change_priority (oldprio, ceiling);
++ if (retval)
++ return retval;
++
++ ceilval = ceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
++ oldprio = ceiling;
++
++ oldval
++ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
++#ifdef NO_INCR
++ ceilval | 2,
++#else
++ ceilval | 1,
++#endif
++ ceilval);
++
++ if (oldval == ceilval)
++ break;
++
++ do
++ {
++ oldval
++ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
++ ceilval | 2,
++ ceilval | 1);
++
++ if ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval)
++ break;
++
++ if (oldval != ceilval)
++ lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
++ PTHREAD_MUTEX_PSHARED (mutex));
++ }
++ while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
++ ceilval | 2, ceilval)
++ != ceilval);
++ }
++ while ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval);
++
++ assert (mutex->__data.__owner == 0);
++ mutex->__data.__count = 1;
++ }
++ break;
++
++ default:
++ /* Correct code cannot set any other type. */
++ return EINVAL;
++ }
++
++ /* Record the ownership. */
++ mutex->__data.__owner = id;
++#ifndef NO_INCR
++ ++mutex->__data.__nusers;
++#endif
++
++ LIBC_PROBE (mutex_acquired, 1, mutex);
++
++ return 0;
++}
++#ifndef __pthread_mutex_lock
++weak_alias (__pthread_mutex_lock, pthread_mutex_lock)
++hidden_def (__pthread_mutex_lock)
++#endif
++
++
++#ifdef NO_INCR
++void
++__pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex)
++{
++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
++ in sysdeps/nptl/bits/thread-shared-types.h. */
++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
++ assert ((mutex_kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
++ assert ((mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
++ assert ((mutex_kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
++
++ /* Record the ownership. */
++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
++ mutex->__data.__owner = id;
++
++ if (mutex_kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
++ ++mutex->__data.__count;
++}
++#endif
+diff --git a/nptl_2_17/pthread_mutex_unlock_2_17.c b/nptl_2_17/pthread_mutex_unlock_2_17.c
+new file mode 100644
+index 00000000..18ba158e
+--- /dev/null
++++ b/nptl_2_17/pthread_mutex_unlock_2_17.c
+@@ -0,0 +1,360 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++#include <assert.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <lowlevellock.h>
++#include <stap-probe.h>
++#include <futex-internal.h>
++
++#ifndef lll_unlock_elision
++#define lll_unlock_elision(a,b,c) ({ lll_unlock (a,c); 0; })
++#endif
++
++static int
++__pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
++ __attribute_noinline__;
++
++int
++attribute_hidden
++__pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr)
++{
++ /* See concurrency notes regarding mutex type which is loaded from __kind
++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
++ int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
++ if (__builtin_expect (type
++ & ~(PTHREAD_MUTEX_KIND_MASK_NP
++ |PTHREAD_MUTEX_ELISION_FLAGS_NP), 0))
++ return __pthread_mutex_unlock_full (mutex, decr);
++
++ if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
++ == PTHREAD_MUTEX_TIMED_NP)
++ {
++ /* Always reset the owner field. */
++ normal:
++ mutex->__data.__owner = 0;
++ if (decr)
++ /* One less user. */
++ --mutex->__data.__nusers;
++
++ /* Unlock. */
++ lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
++
++ LIBC_PROBE (mutex_release, 1, mutex);
++
++ return 0;
++ }
++ else if (__glibc_likely (type == PTHREAD_MUTEX_TIMED_ELISION_NP))
++ {
++ /* Don't reset the owner/users fields for elision. */
++ return lll_unlock_elision (mutex->__data.__lock, mutex->__data.__elision,
++ PTHREAD_MUTEX_PSHARED (mutex));
++ }
++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
++ == PTHREAD_MUTEX_RECURSIVE_NP, 1))
++ {
++ /* Recursive mutex. */
++ if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
++ return EPERM;
++
++ if (--mutex->__data.__count != 0)
++ /* We still hold the mutex. */
++ return 0;
++ goto normal;
++ }
++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
++ == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
++ goto normal;
++ else
++ {
++ /* Error checking mutex. */
++ assert (type == PTHREAD_MUTEX_ERRORCHECK_NP);
++ if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
++ || ! lll_islocked (mutex->__data.__lock))
++ return EPERM;
++ goto normal;
++ }
++}
++
++
++static int
++__pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
++{
++ int newowner = 0;
++ int private;
++
++ switch (PTHREAD_MUTEX_TYPE (mutex))
++ {
++ case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
++ /* Recursive mutex. */
++ if ((mutex->__data.__lock & FUTEX_TID_MASK)
++ == THREAD_GETMEM (THREAD_SELF, tid)
++ && __builtin_expect (mutex->__data.__owner
++ == PTHREAD_MUTEX_INCONSISTENT, 0))
++ {
++ if (--mutex->__data.__count != 0)
++ /* We still hold the mutex. */
++ return ENOTRECOVERABLE;
++
++ goto notrecoverable;
++ }
++
++ if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
++ return EPERM;
++
++ if (--mutex->__data.__count != 0)
++ /* We still hold the mutex. */
++ return 0;
++
++ goto robust;
++
++ case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
++ case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
++ case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
++ if ((mutex->__data.__lock & FUTEX_TID_MASK)
++ != THREAD_GETMEM (THREAD_SELF, tid)
++ || ! lll_islocked (mutex->__data.__lock))
++ return EPERM;
++
++ /* If the previous owner died and the caller did not succeed in
++ making the state consistent, mark the mutex as unrecoverable
++ and make all waiters. */
++ if (__builtin_expect (mutex->__data.__owner
++ == PTHREAD_MUTEX_INCONSISTENT, 0))
++ notrecoverable:
++ newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
++
++ robust:
++ /* Remove mutex from the list. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++ &mutex->__data.__list.__next);
++ /* We must set op_pending before we dequeue the mutex. Also see
++ comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++ DEQUEUE_MUTEX (mutex);
++
++ mutex->__data.__owner = newowner;
++ if (decr)
++ /* One less user. */
++ --mutex->__data.__nusers;
++
++ /* Unlock by setting the lock to 0 (not acquired); if the lock had
++ FUTEX_WAITERS set previously, then wake any waiters.
++ The unlock operation must be the last access to the mutex to not
++ violate the mutex destruction requirements (see __lll_unlock). */
++ private = PTHREAD_ROBUST_MUTEX_PSHARED (mutex);
++ if (__glibc_unlikely ((atomic_exchange_rel (&mutex->__data.__lock, 0)
++ & FUTEX_WAITERS) != 0))
++ lll_futex_wake (&mutex->__data.__lock, 1, private);
++
++ /* We must clear op_pending after we release the mutex.
++ FIXME However, this violates the mutex destruction requirements
++ because another thread could acquire the mutex, destroy it, and
++ reuse the memory for something else; then, if this thread crashes,
++ and the memory happens to have a value equal to the TID, the kernel
++ will believe it is still related to the mutex (which has been
++ destroyed already) and will modify some other random object. */
++ __asm ("" ::: "memory");
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++ break;
++
++ /* The PI support requires the Linux futex system call. If that's not
++ available, pthread_mutex_init should never have allowed the type to
++ be set. So it will get the default case for an invalid type. */
++#ifdef __NR_futex
++ case PTHREAD_MUTEX_PI_RECURSIVE_NP:
++ /* Recursive mutex. */
++ if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
++ return EPERM;
++
++ if (--mutex->__data.__count != 0)
++ /* We still hold the mutex. */
++ return 0;
++ goto continue_pi_non_robust;
++
++ case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
++ /* Recursive mutex. */
++ if ((mutex->__data.__lock & FUTEX_TID_MASK)
++ == THREAD_GETMEM (THREAD_SELF, tid)
++ && __builtin_expect (mutex->__data.__owner
++ == PTHREAD_MUTEX_INCONSISTENT, 0))
++ {
++ if (--mutex->__data.__count != 0)
++ /* We still hold the mutex. */
++ return ENOTRECOVERABLE;
++
++ goto pi_notrecoverable;
++ }
++
++ if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
++ return EPERM;
++
++ if (--mutex->__data.__count != 0)
++ /* We still hold the mutex. */
++ return 0;
++
++ goto continue_pi_robust;
++
++ case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
++ case PTHREAD_MUTEX_PI_NORMAL_NP:
++ case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
++ case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
++ case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
++ case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
++ if ((mutex->__data.__lock & FUTEX_TID_MASK)
++ != THREAD_GETMEM (THREAD_SELF, tid)
++ || ! lll_islocked (mutex->__data.__lock))
++ return EPERM;
++
++ /* If the previous owner died and the caller did not succeed in
++ making the state consistent, mark the mutex as unrecoverable
++ and make all waiters. */
++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
++ in sysdeps/nptl/bits/thread-shared-types.h. */
++ if ((atomic_load_relaxed (&(mutex->__data.__kind))
++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
++ && __builtin_expect (mutex->__data.__owner
++ == PTHREAD_MUTEX_INCONSISTENT, 0))
++ pi_notrecoverable:
++ newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
++
++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
++ in sysdeps/nptl/bits/thread-shared-types.h. */
++ if ((atomic_load_relaxed (&(mutex->__data.__kind))
++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
++ {
++ continue_pi_robust:
++ /* Remove mutex from the list.
++ Note: robust PI futexes are signaled by setting bit 0. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++ (void *) (((uintptr_t) &mutex->__data.__list.__next)
++ | 1));
++ /* We must set op_pending before we dequeue the mutex. Also see
++ comments at ENQUEUE_MUTEX. */
++ __asm ("" ::: "memory");
++ DEQUEUE_MUTEX (mutex);
++ }
++
++ continue_pi_non_robust:
++ mutex->__data.__owner = newowner;
++ if (decr)
++ /* One less user. */
++ --mutex->__data.__nusers;
++
++ /* Unlock. Load all necessary mutex data before releasing the mutex
++ to not violate the mutex destruction requirements (see
++ lll_unlock). */
++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
++ in sysdeps/nptl/bits/thread-shared-types.h. */
++ int robust = atomic_load_relaxed (&(mutex->__data.__kind))
++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
++ private = (robust
++ ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
++ : PTHREAD_MUTEX_PSHARED (mutex));
++ /* Unlock the mutex using a CAS unless there are futex waiters or our
++ TID is not the value of __lock anymore, in which case we let the
++ kernel take care of the situation. Use release MO in the CAS to
++ synchronize with acquire MO in lock acquisitions. */
++ int l = atomic_load_relaxed (&mutex->__data.__lock);
++ do
++ {
++ if (((l & FUTEX_WAITERS) != 0)
++ || (l != THREAD_GETMEM (THREAD_SELF, tid)))
++ {
++ futex_unlock_pi ((unsigned int *) &mutex->__data.__lock,
++ private);
++ break;
++ }
++ }
++ while (!atomic_compare_exchange_weak_release (&mutex->__data.__lock,
++ &l, 0));
++
++ /* This happens after the kernel releases the mutex but violates the
++ mutex destruction requirements; see comments in the code handling
++ PTHREAD_MUTEX_ROBUST_NORMAL_NP. */
++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
++ break;
++#endif /* __NR_futex. */
++
++ case PTHREAD_MUTEX_PP_RECURSIVE_NP:
++ /* Recursive mutex. */
++ if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
++ return EPERM;
++
++ if (--mutex->__data.__count != 0)
++ /* We still hold the mutex. */
++ return 0;
++ goto pp;
++
++ case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
++ /* Error checking mutex. */
++ if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
++ || (mutex->__data.__lock & ~ PTHREAD_MUTEX_PRIO_CEILING_MASK) == 0)
++ return EPERM;
++ /* FALLTHROUGH */
++
++ case PTHREAD_MUTEX_PP_NORMAL_NP:
++ case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
++ /* Always reset the owner field. */
++ pp:
++ mutex->__data.__owner = 0;
++
++ if (decr)
++ /* One less user. */
++ --mutex->__data.__nusers;
++
++ /* Unlock. Use release MO in the CAS to synchronize with acquire MO in
++ lock acquisitions. */
++ int newval;
++ int oldval = atomic_load_relaxed (&mutex->__data.__lock);
++ do
++ {
++ newval = oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK;
++ }
++ while (!atomic_compare_exchange_weak_release (&mutex->__data.__lock,
++ &oldval, newval));
++
++ if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
++ lll_futex_wake (&mutex->__data.__lock, 1,
++ PTHREAD_MUTEX_PSHARED (mutex));
++
++ int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
++
++ LIBC_PROBE (mutex_release, 1, mutex);
++
++ return __pthread_tpp_change_priority (oldprio, -1);
++
++ default:
++ /* Correct code cannot set any other type. */
++ return EINVAL;
++ }
++
++ LIBC_PROBE (mutex_release, 1, mutex);
++ return 0;
++}
++
++
++int
++__pthread_mutex_unlock (pthread_mutex_t *mutex)
++{
++ return __pthread_mutex_unlock_usercnt (mutex, 1);
++}
++weak_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
++hidden_def (__pthread_mutex_unlock)
+diff --git a/nptl_2_17/pthreadtypes_2_17.h b/nptl_2_17/pthreadtypes_2_17.h
+new file mode 100644
+index 00000000..0483e44a
+--- /dev/null
++++ b/nptl_2_17/pthreadtypes_2_17.h
+@@ -0,0 +1,179 @@
++/* Copyright (C) 2002-2020 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
++ <https://www.gnu.org/licenses/>. */
++
++#ifndef _INTERNALTYPES_H
++#define _INTERNALTYPES_H 1
++
++#include <stdint.h>
++#include <atomic.h>
++#include <endian.h>
++
++
++struct pthread_attr
++{
++ /* Scheduler parameters and priority. */
++ struct sched_param schedparam;
++ int schedpolicy;
++ /* Various flags like detachstate, scope, etc. */
++ int flags;
++ /* Size of guard area. */
++ size_t guardsize;
++ /* Stack handling. */
++ void *stackaddr;
++ size_t stacksize;
++ /* Affinity map. */
++ cpu_set_t *cpuset;
++ size_t cpusetsize;
++};
++
++#define ATTR_FLAG_DETACHSTATE 0x0001
++#define ATTR_FLAG_NOTINHERITSCHED 0x0002
++#define ATTR_FLAG_SCOPEPROCESS 0x0004
++#define ATTR_FLAG_STACKADDR 0x0008
++#define ATTR_FLAG_OLDATTR 0x0010
++#define ATTR_FLAG_SCHED_SET 0x0020
++#define ATTR_FLAG_POLICY_SET 0x0040
++
++
++/* Mutex attribute data structure. */
++struct pthread_mutexattr
++{
++ /* Identifier for the kind of mutex.
++
++ Bit 31 is set if the mutex is to be shared between processes.
++
++ Bit 0 to 30 contain one of the PTHREAD_MUTEX_ values to identify
++ the type of the mutex. */
++ int mutexkind;
++};
++
++
++/* Conditional variable attribute data structure. */
++struct pthread_condattr
++{
++ /* Combination of values:
++
++ Bit 0 : flag whether conditional variable will be
++ sharable between processes.
++ Bit 1-COND_CLOCK_BITS: Clock ID. COND_CLOCK_BITS is the number of bits
++ needed to represent the ID of the clock. */
++ int value;
++};
++#define COND_CLOCK_BITS 1
++#define COND_NWAITERS_SHIFT 1
++
++/* Read-write lock variable attribute data structure. */
++struct pthread_rwlockattr
++{
++ int lockkind;
++ int pshared;
++};
++
++
++/* Barrier data structure. See pthread_barrier_wait for a description
++ of how these fields are used. */
++struct pthread_barrier
++{
++ unsigned int in;
++ unsigned int current_round;
++ unsigned int count;
++ int shared;
++ unsigned int out;
++};
++/* See pthread_barrier_wait for a description. */
++#define BARRIER_IN_THRESHOLD (UINT_MAX/2)
++
++
++/* Barrier variable attribute data structure. */
++struct pthread_barrierattr
++{
++ int pshared;
++};
++
++
++/* Thread-local data handling. */
++struct pthread_key_struct
++{
++ /* Sequence numbers. Even numbers indicated vacant entries. Note
++ that zero is even. We use uintptr_t to not require padding on
++ 32- and 64-bit machines. On 64-bit machines it helps to avoid
++ wrapping, too. */
++ uintptr_t seq;
++
++ /* Destructor for the data. */
++ void (*destr) (void *);
++};
++
++/* Check whether an entry is unused. */
++#define KEY_UNUSED(p) (((p) & 1) == 0)
++/* Check whether a key is usable. We cannot reuse an allocated key if
++ the sequence counter would overflow after the next destroy call.
++ This would mean that we potentially free memory for a key with the
++ same sequence. This is *very* unlikely to happen, A program would
++ have to create and destroy a key 2^31 times (on 32-bit platforms,
++ on 64-bit platforms that would be 2^63). If it should happen we
++ simply don't use this specific key anymore. */
++#define KEY_USABLE(p) (((uintptr_t) (p)) < ((uintptr_t) ((p) + 2)))
++
++
++/* Handling of read-write lock data. */
++// XXX For now there is only one flag. Maybe more in future.
++#define RWLOCK_RECURSIVE(rwlock) ((rwlock)->__data.__flags != 0)
++
++
++/* Semaphore variable structure. */
++struct new_sem
++{
++#if __HAVE_64B_ATOMICS
++ /* The data field holds both value (in the least-significant 32 bits) and
++ nwaiters. */
++# if __BYTE_ORDER == __LITTLE_ENDIAN
++# define SEM_VALUE_OFFSET 0
++# elif __BYTE_ORDER == __BIG_ENDIAN
++# define SEM_VALUE_OFFSET 1
++# else
++# error Unsupported byte order.
++# endif
++# define SEM_NWAITERS_SHIFT 32
++# define SEM_VALUE_MASK (~(unsigned int)0)
++ uint64_t data;
++ int private;
++ int pad;
++#else
++# define SEM_VALUE_SHIFT 1
++# define SEM_NWAITERS_MASK ((unsigned int)1)
++ unsigned int value;
++ int private;
++ int pad;
++ unsigned int nwaiters;
++#endif
++};
++
++struct old_sem
++{
++ unsigned int value;
++};
++
++
++/* Compatibility type for old conditional variable interfaces. */
++typedef struct
++{
++ pthread_cond_t *cond;
++} pthread_cond_2_0_t;
++
++#endif /* internaltypes.h */
+diff --git a/nptl_2_17/tpp_2_17.c b/nptl_2_17/tpp_2_17.c
+new file mode 100644
+index 00000000..56357ea3
+--- /dev/null
++++ b/nptl_2_17/tpp_2_17.c
+@@ -0,0 +1,195 @@
++/* Thread Priority Protect helpers.
++ Copyright (C) 2006-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <assert.h>
++#include <atomic.h>
++#include <errno.h>
++#include <pthreadP.h>
++#include <sched.h>
++#include <stdlib.h>
++#include <atomic.h>
++
++
++int __sched_fifo_min_prio = -1;
++int __sched_fifo_max_prio = -1;
++
++/* We only want to initialize __sched_fifo_min_prio and __sched_fifo_max_prio
++ once. The standard solution would be similar to pthread_once, but then
++ readers would need to use an acquire fence. In this specific case,
++ initialization is comprised of just idempotent writes to two variables
++ that have an initial value of -1. Therefore, we can treat each variable as
++ a separate, at-least-once initialized value. This enables using just
++ relaxed MO loads and stores, but requires that consumers check for
++ initialization of each value that is to be used; see
++ __pthread_tpp_change_priority for an example.
++ */
++void
++__init_sched_fifo_prio (void)
++{
++ atomic_store_relaxed (&__sched_fifo_max_prio,
++ __sched_get_priority_max (SCHED_FIFO));
++ atomic_store_relaxed (&__sched_fifo_min_prio,
++ __sched_get_priority_min (SCHED_FIFO));
++}
++
++int
++__pthread_tpp_change_priority (int previous_prio, int new_prio)
++{
++ struct pthread *self = THREAD_SELF;
++ struct priority_protection_data *tpp = THREAD_GETMEM (self, tpp);
++ int fifo_min_prio = atomic_load_relaxed (&__sched_fifo_min_prio);
++ int fifo_max_prio = atomic_load_relaxed (&__sched_fifo_max_prio);
++
++ if (tpp == NULL)
++ {
++ /* See __init_sched_fifo_prio. We need both the min and max prio,
++ so need to check both, and run initialization if either one is
++ not initialized. The memory model's write-read coherence rule
++ makes this work. */
++ if (fifo_min_prio == -1 || fifo_max_prio == -1)
++ {
++ __init_sched_fifo_prio ();
++ fifo_min_prio = atomic_load_relaxed (&__sched_fifo_min_prio);
++ fifo_max_prio = atomic_load_relaxed (&__sched_fifo_max_prio);
++ }
++
++ size_t size = sizeof *tpp;
++ size += (fifo_max_prio - fifo_min_prio + 1)
++ * sizeof (tpp->priomap[0]);
++ tpp = calloc (size, 1);
++ if (tpp == NULL)
++ return ENOMEM;
++ tpp->priomax = fifo_min_prio - 1;
++ THREAD_SETMEM (self, tpp, tpp);
++ }
++
++ assert (new_prio == -1
++ || (new_prio >= fifo_min_prio
++ && new_prio <= fifo_max_prio));
++ assert (previous_prio == -1
++ || (previous_prio >= fifo_min_prio
++ && previous_prio <= fifo_max_prio));
++
++ int priomax = tpp->priomax;
++ int newpriomax = priomax;
++ if (new_prio != -1)
++ {
++ if (tpp->priomap[new_prio - fifo_min_prio] + 1 == 0)
++ return EAGAIN;
++ ++tpp->priomap[new_prio - fifo_min_prio];
++ if (new_prio > priomax)
++ newpriomax = new_prio;
++ }
++
++ if (previous_prio != -1)
++ {
++ if (--tpp->priomap[previous_prio - fifo_min_prio] == 0
++ && priomax == previous_prio
++ && previous_prio > new_prio)
++ {
++ int i;
++ for (i = previous_prio - 1; i >= fifo_min_prio; --i)
++ if (tpp->priomap[i - fifo_min_prio])
++ break;
++ newpriomax = i;
++ }
++ }
++
++ if (priomax == newpriomax)
++ return 0;
++
++ /* See CREATE THREAD NOTES in nptl/pthread_create.c. */
++ lll_lock (self->lock, LLL_PRIVATE);
++
++ tpp->priomax = newpriomax;
++
++ int result = 0;
++
++ if ((self->flags & ATTR_FLAG_SCHED_SET) == 0)
++ {
++ if (__sched_getparam (self->tid, &self->schedparam) != 0)
++ result = errno;
++ else
++ self->flags |= ATTR_FLAG_SCHED_SET;
++ }
++
++ if ((self->flags & ATTR_FLAG_POLICY_SET) == 0)
++ {
++ self->schedpolicy = __sched_getscheduler (self->tid);
++ if (self->schedpolicy == -1)
++ result = errno;
++ else
++ self->flags |= ATTR_FLAG_POLICY_SET;
++ }
++
++ if (result == 0)
++ {
++ struct sched_param sp = self->schedparam;
++ if (sp.sched_priority < newpriomax || sp.sched_priority < priomax)
++ {
++ if (sp.sched_priority < newpriomax)
++ sp.sched_priority = newpriomax;
++
++ if (__sched_setscheduler (self->tid, self->schedpolicy, &sp) < 0)
++ result = errno;
++ }
++ }
++
++ lll_unlock (self->lock, LLL_PRIVATE);
++
++ return result;
++}
++
++int
++__pthread_current_priority (void)
++{
++ struct pthread *self = THREAD_SELF;
++ if ((self->flags & (ATTR_FLAG_POLICY_SET | ATTR_FLAG_SCHED_SET))
++ == (ATTR_FLAG_POLICY_SET | ATTR_FLAG_SCHED_SET))
++ return self->schedparam.sched_priority;
++
++ int result = 0;
++
++ /* See CREATE THREAD NOTES in nptl/pthread_create.c. */
++ lll_lock (self->lock, LLL_PRIVATE);
++
++ if ((self->flags & ATTR_FLAG_SCHED_SET) == 0)
++ {
++ if (__sched_getparam (self->tid, &self->schedparam) != 0)
++ result = -1;
++ else
++ self->flags |= ATTR_FLAG_SCHED_SET;
++ }
++
++ if ((self->flags & ATTR_FLAG_POLICY_SET) == 0)
++ {
++ self->schedpolicy = __sched_getscheduler (self->tid);
++ if (self->schedpolicy == -1)
++ result = -1;
++ else
++ self->flags |= ATTR_FLAG_POLICY_SET;
++ }
++
++ if (result != -1)
++ result = self->schedparam.sched_priority;
++
++ lll_unlock (self->lock, LLL_PRIVATE);
++
++ return result;
++}
+diff --git a/nptl_2_17/unwind_2_17.c b/nptl_2_17/unwind_2_17.c
+new file mode 100644
+index 00000000..1534540c
+--- /dev/null
++++ b/nptl_2_17/unwind_2_17.c
+@@ -0,0 +1,138 @@
++/* Copyright (C) 2003-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ulrich Drepper <drepper@redhat.com>
++ and Richard Henderson <rth@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
++ <https://www.gnu.org/licenses/>. */
++
++#include "pthreadP_2_17.h"
++#include <setjmp.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <jmpbuf-unwind.h>
++
++#ifdef _STACK_GROWS_DOWN
++# define FRAME_LEFT(frame, other, adj) \
++ ((uintptr_t) frame - adj >= (uintptr_t) other - adj)
++#elif _STACK_GROWS_UP
++# define FRAME_LEFT(frame, other, adj) \
++ ((uintptr_t) frame - adj <= (uintptr_t) other - adj)
++#else
++# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
++#endif
++
++static _Unwind_Reason_Code
++unwind_stop (int version, _Unwind_Action actions,
++ _Unwind_Exception_Class exc_class,
++ struct _Unwind_Exception *exc_obj,
++ struct _Unwind_Context *context, void *stop_parameter)
++{
++ struct pthread_unwind_buf *buf = stop_parameter;
++ struct pthread *self = THREAD_SELF;
++ struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup);
++ int do_longjump = 0;
++
++ /* Adjust all pointers used in comparisons, so that top of thread's
++ stack is at the top of address space. Without that, things break
++ if stack is allocated above the main stack. */
++ uintptr_t adj = (uintptr_t) self->stackblock + self->stackblock_size;
++
++ /* Do longjmp if we're at "end of stack", aka "end of unwind data".
++ We assume there are only C frame without unwind data in between
++ here and the jmp_buf target. Otherwise simply note that the CFA
++ of a function is NOT within it's stack frame; it's the SP of the
++ previous frame. */
++ if ((actions & _UA_END_OF_STACK)
++ || ! _JMPBUF_CFA_UNWINDS_ADJ (buf->cancel_jmp_buf[0].jmp_buf, context,
++ adj))
++ do_longjump = 1;
++
++ if (__glibc_unlikely (curp != NULL))
++ {
++ /* Handle the compatibility stuff. Execute all handlers
++ registered with the old method which would be unwound by this
++ step. */
++ struct _pthread_cleanup_buffer *oldp = buf->priv.data.cleanup;
++ void *cfa = (void *) (_Unwind_Ptr) _Unwind_GetCFA (context);
++
++ if (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp, adj)))
++ {
++ do
++ {
++ /* Pointer to the next element. */
++ struct _pthread_cleanup_buffer *nextp = curp->__prev;
++
++ /* Call the handler. */
++ curp->__routine (curp->__arg);
++
++ /* To the next. */
++ curp = nextp;
++ }
++ while (curp != oldp
++ && (do_longjump || FRAME_LEFT (cfa, curp, adj)));
++
++ /* Mark the current element as handled. */
++ THREAD_SETMEM (self, cleanup, curp);
++ }
++ }
++
++ if (do_longjump)
++ __libc_unwind_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1);
++
++ return _URC_NO_REASON;
++}
++
++
++static void
++unwind_cleanup (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc)
++{
++ /* When we get here a C++ catch block didn't rethrow the object. We
++ cannot handle this case and therefore abort. */
++ __libc_fatal ("FATAL: exception not rethrown\n");
++}
++
++
++void
++__cleanup_fct_attribute __attribute ((noreturn))
++__pthread_unwind (__pthread_unwind_buf_t *buf)
++{
++ struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
++ struct pthread *self = THREAD_SELF;
++
++ /* This is not a catchable exception, so don't provide any details about
++ the exception type. We do need to initialize the field though. */
++ THREAD_SETMEM (self, exc.exception_class, 0);
++ THREAD_SETMEM (self, exc.exception_cleanup, &unwind_cleanup);
++
++ _Unwind_ForcedUnwind (&self->exc, unwind_stop, ibuf);
++ /* NOTREACHED */
++
++ /* We better do not get here. */
++ abort ();
++}
++hidden_def (__pthread_unwind)
++
++
++void
++__cleanup_fct_attribute __attribute ((noreturn))
++__pthread_unwind_next (__pthread_unwind_buf_t *buf)
++{
++ struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
++
++ __pthread_unwind ((__pthread_unwind_buf_t *) ibuf->priv.data.prev);
++}
++hidden_def (__pthread_unwind_next)
+diff --git a/nptl_2_17/vars_2_17.c b/nptl_2_17/vars_2_17.c
+new file mode 100644
+index 00000000..295d7e33
+--- /dev/null
++++ b/nptl_2_17/vars_2_17.c
+@@ -0,0 +1,43 @@
++/* Copyright (C) 2004-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <pthreadP_2_17.h>
++#include <stdlib.h>
++#include <tls.h>
++#include <unistd.h>
++
++/* Default thread attributes for the case when the user does not
++ provide any. */
++struct pthread_attr __default_pthread_attr attribute_hidden;
++
++/* Mutex protecting __default_pthread_attr. */
++int __default_pthread_attr_lock = LLL_LOCK_INITIALIZER;
++
++/* Flag whether the machine is SMP or not. */
++int __is_smp attribute_hidden;
++
++#ifndef TLS_MULTIPLE_THREADS_IN_TCB
++/* Variable set to a nonzero value either if more than one thread runs or ran,
++ or if a single-threaded process is trying to cancel itself. See
++ nptl/descr.h for more context on the single-threaded process case. */
++int __pthread_multiple_threads attribute_hidden;
++#endif
++
++/* Table of the key information. */
++struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX]
++ __attribute__ ((nocommon));
++hidden_data_def (__pthread_keys)
+--
+2.23.0
+
diff --git a/delete-no-hard-link-to-avoid-all_language-package-to.patch b/delete-no-hard-link-to-avoid-all_language-package-to.patch
new file mode 100644
index 0000000..1ccebcc
--- /dev/null
+++ b/delete-no-hard-link-to-avoid-all_language-package-to.patch
@@ -0,0 +1,26 @@
+From ba6891f0633d394a59d14f0a54090fa1b6260c16 Mon Sep 17 00:00:00 2001
+From: buque <wuxu.wu@hotmail.com>
+Date: Wed, 15 Jul 2020 15:09:54 +0800
+Subject: [PATCH] delete --no-hard-link to avoid all_language package too
+ large.
+
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/localedata/Makefile b/localedata/Makefile
+index b8a3b67..c78d0fe 100644
+--- a/localedata/Makefile
++++ b/localedata/Makefile
+@@ -444,7 +444,7 @@ $(INSTALL-SUPPORTED-LOCALE-ARCHIVE): install-locales-dir
+ $(build-one-locale)
+
+ $(INSTALL-SUPPORTED-LOCALE-FILES): install-locales-dir
+- @flags="-c --no-archive --no-hard-links"; \
++ @flags="-c --no-archive"; \
+ $(build-one-locale)
+
+ tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
+--
+2.25.1
+
diff --git a/elf-Allow-dlopen-of-filter-object-to-work-BZ-16272.patch b/elf-Allow-dlopen-of-filter-object-to-work-BZ-16272.patch
new file mode 100644
index 0000000..cea541d
--- /dev/null
+++ b/elf-Allow-dlopen-of-filter-object-to-work-BZ-16272.patch
@@ -0,0 +1,537 @@
+From eb447b7b4bd6177f876ba9420ad9e048c27bae91 Mon Sep 17 00:00:00 2001
+From: David Kilroy <David.Kilroy@arm.com>
+Date: Wed, 12 Feb 2020 14:28:15 -0300
+Subject: [PATCH] elf: Allow dlopen of filter object to work [BZ #16272]
+
+There are two fixes that are needed to be able to dlopen filter
+objects. First _dl_map_object_deps cannot assume that map will be at
+the beginning of l_searchlist.r_list[], as filtees are inserted before
+map. Secondly dl_open_worker needs to ensure that filtees get
+relocated.
+
+In _dl_map_object_deps:
+
+* avoiding removing relocation dependencies of map by setting
+ l_reserved to 0 and otherwise processing the rest of the search
+ list.
+
+* ensure that map remains at the beginning of l_initfini - the list
+ of things that need initialisation (and destruction). Do this by
+ splitting the copy up. This may not be required, but matches the
+ initialization order without dlopen.
+
+Modify dl_open_worker to relocate the objects in new->l_inifini.
+new->l_initfini is constructed in _dl_map_object_deps, and lists the
+objects that need initialization and destruction. Originally the list
+of objects in new->l_next are relocated. All of these objects should
+also be included in new->l_initfini (both lists are populated with
+dependencies in _dl_map_object_deps). We can't use new->l_prev to pick
+up filtees, as during a recursive dlopen from an interposed malloc
+call, l->prev can contain objects that are not ready for relocation.
+
+Add tests to verify that symbols resolve to the filtee implementation
+when auxiliary and filter objects are used, both as a normal link and
+when dlopen'd.
+
+Tested by running the testsuite on x86_64.
+---
+ elf/Makefile | 18 ++++++++++++++++--
+ elf/dl-deps.c | 39 ++++++++++++++++++++++++++++----------
+ elf/dl-open.c | 11 +++++++----
+ elf/tst-auxobj-dlopen.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
+ elf/tst-auxobj.c | 42 +++++++++++++++++++++++++++++++++++++++++
+ elf/tst-filterobj-aux.c | 33 ++++++++++++++++++++++++++++++++
+ elf/tst-filterobj-dlopen.c | 39 ++++++++++++++++++++++++++++++++++++++
+ elf/tst-filterobj-filtee.c | 27 ++++++++++++++++++++++++++
+ elf/tst-filterobj-filtee.h | 24 +++++++++++++++++++++++
+ elf/tst-filterobj-flt.c | 27 ++++++++++++++++++++++++++
+ elf/tst-filterobj.c | 36 +++++++++++++++++++++++++++++++++++
+ 11 files changed, 327 insertions(+), 16 deletions(-)
+ create mode 100644 elf/tst-auxobj-dlopen.c
+ create mode 100644 elf/tst-auxobj.c
+ create mode 100644 elf/tst-filterobj-aux.c
+ create mode 100644 elf/tst-filterobj-dlopen.c
+ create mode 100644 elf/tst-filterobj-filtee.c
+ create mode 100644 elf/tst-filterobj-filtee.h
+ create mode 100644 elf/tst-filterobj-flt.c
+ create mode 100644 elf/tst-filterobj.c
+
+diff --git a/elf/Makefile b/elf/Makefile
+index f440488..2053c9d 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -202,7 +202,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
+ tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \
+ tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \
+ tst-dlopenfail-2 \
+- tst-tls-ie tst-tls-ie-dlmopen
++ tst-tls-ie tst-tls-ie-dlmopen \
++ tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen
+ # reldep9
+ tests-internal += loadtest unload unload2 circleload1 \
+ neededtest neededtest2 neededtest3 neededtest4 \
+@@ -316,7 +317,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ tst-dlopenfailmod3 tst-ldconfig-ld-mod \
+ tst-tls-ie-mod0 tst-tls-ie-mod1 tst-tls-ie-mod2 \
+ tst-tls-ie-mod3 tst-tls-ie-mod4 tst-tls-ie-mod5 \
+- tst-tls-ie-mod6
++ tst-tls-ie-mod6 \
++ tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee
+ # Most modules build with _ISOMAC defined, but those filtered out
+ # depend on internal headers.
+ modules-names-tests = $(filter-out ifuncmod% tst-libc_dlvsym-dso tst-tlsmod%,\
+@@ -1723,3 +1725,15 @@ $(objpfx)tst-tls-ie-dlmopen.out: \
+ $(objpfx)tst-tls-ie-mod4.so \
+ $(objpfx)tst-tls-ie-mod5.so \
+ $(objpfx)tst-tls-ie-mod6.so
++
++LDFLAGS-tst-filterobj-flt.so = -Wl,--filter=$(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-filterobj: $(objpfx)tst-filterobj-flt.so
++$(objpfx)tst-filterobj-dlopen: $(libdl)
++$(objpfx)tst-filterobj.out: $(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-filterobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so
++
++LDFLAGS-tst-filterobj-aux.so = -Wl,--auxiliary=$(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-auxobj: $(objpfx)tst-filterobj-aux.so
++$(objpfx)tst-auxobj-dlopen: $(libdl)
++$(objpfx)tst-auxobj.out: $(objpfx)tst-filterobj-filtee.so
++$(objpfx)tst-auxobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so
+diff --git a/elf/dl-deps.c b/elf/dl-deps.c
+index 5103a8a..0730ea9 100644
+--- a/elf/dl-deps.c
++++ b/elf/dl-deps.c
+@@ -485,14 +485,18 @@ _dl_map_object_deps (struct link_map *map,
+
+ map->l_searchlist.r_list = &l_initfini[nlist + 1];
+ map->l_searchlist.r_nlist = nlist;
++ unsigned int map_index = UINT_MAX;
+
+ for (nlist = 0, runp = known; runp; runp = runp->next)
+ {
+ if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
+ /* This can happen when we trace the loading. */
+ --map->l_searchlist.r_nlist;
+- else
++ else {
++ if (runp->map == map)
++ map_index = nlist;
+ map->l_searchlist.r_list[nlist++] = runp->map;
++ }
+
+ /* Now clear all the mark bits we set in the objects on the search list
+ to avoid duplicates, so the next call starts fresh. */
+@@ -550,13 +554,14 @@ Filters not supported with LD_TRACE_PRELINKING"));
+ }
+
+ /* Maybe we can remove some relocation dependencies now. */
+- assert (map->l_searchlist.r_list[0] == map);
+ struct link_map_reldeps *l_reldeps = NULL;
+ if (map->l_reldeps != NULL)
+ {
+- for (i = 1; i < nlist; ++i)
++ for (i = 0; i < nlist; ++i)
+ map->l_searchlist.r_list[i]->l_reserved = 1;
+
++ /* Avoid removing relocation dependencies of the main binary. */
++ map->l_reserved = 0;
+ struct link_map **list = &map->l_reldeps->list[0];
+ for (i = 0; i < map->l_reldeps->act; ++i)
+ if (list[i]->l_reserved)
+@@ -581,16 +586,30 @@ Filters not supported with LD_TRACE_PRELINKING"));
+ }
+ }
+
+- for (i = 1; i < nlist; ++i)
++ for (i = 0; i < nlist; ++i)
+ map->l_searchlist.r_list[i]->l_reserved = 0;
+ }
+
+- /* Sort the initializer list to take dependencies into account. The binary
+- itself will always be initialize last. */
+- memcpy (l_initfini, map->l_searchlist.r_list,
+- nlist * sizeof (struct link_map *));
+- /* We can skip looking for the binary itself which is at the front of
+- the search list. */
++ /* Sort the initializer list to take dependencies into account. Always
++ initialize the binary itself last. */
++ assert (map_index < nlist);
++ if (map_index > 0)
++ {
++ /* Copy the binary into position 0. */
++ l_initfini[0] = map->l_searchlist.r_list[map_index];
++
++ /* Copy the filtees. */
++ for (i = 0; i < map_index; ++i)
++ l_initfini[i+1] = map->l_searchlist.r_list[i];
++
++ /* Copy the remainder. */
++ for (i = map_index + 1; i < nlist; ++i)
++ l_initfini[i] = map->l_searchlist.r_list[i];
++ }
++ else
++ memcpy (l_initfini, map->l_searchlist.r_list,
++ nlist * sizeof (struct link_map *));
++
+ _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
+
+ /* Terminate the list of dependencies. */
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index 623c975..ecb2ba9 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -621,22 +621,25 @@ dl_open_worker (void *a)
+ allows IFUNC relocations to work and it also means copy
+ relocation of dependencies are if necessary overwritten. */
+ unsigned int nmaps = 0;
+- struct link_map *l = new;
++ unsigned int j = 0;
++ struct link_map *l = new->l_initfini[0];
+ do
+ {
+ if (! l->l_real->l_relocated)
+ ++nmaps;
+- l = l->l_next;
++ l = new->l_initfini[++j];
+ }
+ while (l != NULL);
++ /* Stack allocation is limited by the number of loaded objects. */
+ struct link_map *maps[nmaps];
+ nmaps = 0;
+- l = new;
++ j = 0;
++ l = new->l_initfini[0];
+ do
+ {
+ if (! l->l_real->l_relocated)
+ maps[nmaps++] = l;
+- l = l->l_next;
++ l = new->l_initfini[++j];
+ }
+ while (l != NULL);
+ _dl_sort_maps (maps, nmaps, NULL, false);
+diff --git a/elf/tst-auxobj-dlopen.c b/elf/tst-auxobj-dlopen.c
+new file mode 100644
+index 0000000..cb54aba
+--- /dev/null
++++ b/elf/tst-auxobj-dlopen.c
+@@ -0,0 +1,47 @@
++/* Test for BZ#16272, dlopen'ing an auxiliary filter object.
++ Ensure that symbols from the resolve correctly.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <support/check.h>
++#include <support/xdlfcn.h>
++
++static int do_test (void)
++{
++ void *lib = xdlopen ("tst-filterobj-aux.so", RTLD_LAZY);
++ char *(*fn)(void) = xdlsym (lib, "get_text");
++ const char* text = fn ();
++
++ printf ("%s\n", text);
++
++ /* Verify the text matches what we expect from the filtee */
++ TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++ fn = xdlsym (lib, "get_text2");
++ text = fn ();
++
++ printf ("%s\n", text);
++
++ /* Verify the text matches what we expect from the auxiliary object */
++ TEST_COMPARE_STRING (text, "Hello from auxiliary filter object (PASS)");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-auxobj.c b/elf/tst-auxobj.c
+new file mode 100644
+index 0000000..bdc7713
+--- /dev/null
++++ b/elf/tst-auxobj.c
+@@ -0,0 +1,42 @@
++/* Test that symbols from auxiliary filter objects are resolved to the
++ filtee.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <support/check.h>
++#include "tst-filterobj-filtee.h"
++
++static int do_test (void)
++{
++ const char* text = get_text ();
++ printf ("%s\n", text);
++
++ /* Verify the text matches what we expect from the filtee */
++ TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++ text = get_text2 ();
++ printf ("%s\n", text);
++
++ /* Verify the text matches what we expect from the auxiliary object */
++ TEST_COMPARE_STRING (text, "Hello from auxiliary filter object (PASS)");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-filterobj-aux.c b/elf/tst-filterobj-aux.c
+new file mode 100644
+index 0000000..0b732f2
+--- /dev/null
++++ b/elf/tst-filterobj-aux.c
+@@ -0,0 +1,33 @@
++/* Auxiliary filter object.
++ Contains symbols to be resolved in filtee, and one which doesn't.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include "tst-filterobj-filtee.h"
++
++/* We never want to see the output of the auxiliary object. */
++const char *get_text (void)
++{
++ return "Hello from auxiliary filter object (FAIL)";
++}
++
++/* The filtee doesn't implement this symbol, so this should resolve. */
++const char *get_text2 (void)
++{
++ return "Hello from auxiliary filter object (PASS)";
++}
+diff --git a/elf/tst-filterobj-dlopen.c b/elf/tst-filterobj-dlopen.c
+new file mode 100644
+index 0000000..c5b5072
+--- /dev/null
++++ b/elf/tst-filterobj-dlopen.c
+@@ -0,0 +1,39 @@
++/* Test for BZ#16272, dlopen'ing a filter object.
++ Ensure that symbols from the filter object resolve to the filtee.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <support/check.h>
++#include <support/xdlfcn.h>
++
++static int do_test (void)
++{
++ void *lib = xdlopen ("tst-filterobj-flt.so", RTLD_LAZY);
++ char *(*fn)(void) = xdlsym (lib, "get_text");
++ const char* text = fn ();
++
++ printf ("%s\n", text);
++
++ /* Verify the text matches what we expect from the filtee */
++ TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-filterobj-filtee.c b/elf/tst-filterobj-filtee.c
+new file mode 100644
+index 0000000..8fa557c
+--- /dev/null
++++ b/elf/tst-filterobj-filtee.c
+@@ -0,0 +1,27 @@
++/* Filtee for BZ#16272 test.
++ Contains desired symbol implementations.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include "tst-filterobj-filtee.h"
++
++/* This is the real implementation that wants to be called */
++const char *get_text (void)
++{
++ return "Hello from filtee (PASS)";
++}
+diff --git a/elf/tst-filterobj-filtee.h b/elf/tst-filterobj-filtee.h
+new file mode 100644
+index 0000000..46aee28
+--- /dev/null
++++ b/elf/tst-filterobj-filtee.h
+@@ -0,0 +1,24 @@
++/* Filtee header for BZ#16272 test.
++ Contains prototypes for symbols implemented in the filtee.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++const char *get_text (void);
++
++/* For testing auxiliary filter object. */
++const char *get_text2 (void);
+diff --git a/elf/tst-filterobj-flt.c b/elf/tst-filterobj-flt.c
+new file mode 100644
+index 0000000..5062654
+--- /dev/null
++++ b/elf/tst-filterobj-flt.c
+@@ -0,0 +1,27 @@
++/* Filter object for BZ#16272 test.
++ Contains symbols to be resolved in filtee.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include "tst-filterobj-filtee.h"
++
++/* We never want to see the output of the filter object */
++const char *get_text (void)
++{
++ return "Hello from filter object (FAIL)";
++}
+diff --git a/elf/tst-filterobj.c b/elf/tst-filterobj.c
+new file mode 100644
+index 0000000..96bfae0
+--- /dev/null
++++ b/elf/tst-filterobj.c
+@@ -0,0 +1,36 @@
++/* Test that symbols from filter objects are resolved to the filtee.
++
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <support/check.h>
++#include "tst-filterobj-filtee.h"
++
++static int do_test (void)
++{
++ const char* text = get_text ();
++
++ printf ("%s\n", text);
++
++ /* Verify the text matches what we expect from the filtee */
++ TEST_COMPARE_STRING (text, "Hello from filtee (PASS)");
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+1.8.3.1
+
diff --git a/glibc-1070416.patch b/glibc-1070416.patch
new file mode 100644
index 0000000..0975e0f
--- /dev/null
+++ b/glibc-1070416.patch
@@ -0,0 +1,38 @@
+Short description: Add syslog.target dependency.
+Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
+Origin: PATCH
+Bug-Fedora: #1070416
+Upstream status: not-needed
+
+Fedora-specific changes to the nscd.service file.
+See also: glibc-nscd-sysconfig.patch.
+
+--- a/nscd/nscd.service
++++ b/nscd/nscd.service
+@@ -2,6 +2,7 @@
+
+ [Unit]
+ Description=Name Service Cache Daemon
++After=syslog.target
+
+ [Service]
+ Type=forking
+@@ -17,3 +18,4 @@
+
+ [Install]
+ WantedBy=multi-user.target
++Also=nscd.socket
+diff --git a/nscd/nscd.socket b/nscd/nscd.socket
+new file mode 100644
+index 0000000..7e512d5
+--- /dev/null
++++ b/nscd/nscd.socket
+@@ -0,0 +1,8 @@
++[Unit]
++Description=Name Service Cache Daemon Socket
++
++[Socket]
++ListenDatagram=/var/run/nscd/socket
++
++[Install]
++WantedBy=sockets.target
diff --git a/glibc-bench-compare b/glibc-bench-compare
new file mode 100644
index 0000000..84e3aba
--- /dev/null
+++ b/glibc-bench-compare
@@ -0,0 +1,153 @@
+#!/usr/bin/bash
+# This script can be invoked as follows:
+#
+# glibc-bench-compare [options] <BUILD> [BUILD]
+#
+# Options may be one of the following:
+#
+# -t The BUILD arguments are task ids and not a version-release string
+# -a ARCH Do comparison for ARCH architecture
+#
+# If any of the above options are given, both BUILD arguments must be given.
+# Otherwise, if only one BUILD is specified, then it is compared against the
+# installed glibc.
+
+# Silence the pushd/popd messages
+pushd() {
+ command pushd "$@" > /dev/null 2>&1
+}
+
+popd() {
+ command popd "$@" > /dev/null 2>&1
+}
+
+# Clean up any downloaded files before we exit
+trap "rm -rf /tmp/glibc-bench-compare.$BASHPID.*" EXIT
+
+task=0
+arch=$(uname -i)
+options=0
+path=0
+installed=
+
+# Look for any commandline options
+while getopts ":tpa:" opt; do
+ case $opt in
+ p)
+ path=1
+ ;;
+ t)
+ task=1
+ options=1
+ echo "Not implemented."
+ exit 1
+ ;;
+ a)
+ arch=$OPTARG
+ options=1
+ ;;
+ *)
+ ;;
+ esac
+done
+
+# Done, now shift all option arguments out.
+shift $((OPTIND-1))
+
+if [ $# -gt 2 ] || [ $# -eq 0 ] || [ $# -lt 2 -a $options -eq 1 ]; then
+ echo "Usage: $0 [OPTIONS] <old> [new]"
+ echo
+ echo "OPTIONS:"
+ echo -e "\t-t\tCompare two brew tasks"
+ echo -e "\t-a ARCH\tGet rpms for the ARCH architecture"
+ echo -e "\t-p\tCompare built rpms in two paths."
+ echo -e "\t\tThis minimally needs glibc, glibc-common and glibc-benchtests"
+ exit 1
+fi
+
+if [ -z $2 ]; then
+ new="$1"
+ old=$(rpm --queryformat "%{VERSION}-%{RELEASE}\n" -q glibc | head -1)
+ installed=$old
+else
+ new="$2"
+ old="$1"
+fi
+
+decompress_rpms() {
+ # We were given a path to the rpms. Figure out the version-release and
+ # decompress the rpms.
+ if [ -n $1 ]; then
+ vr=$(rpm --queryformat="%{VERSION}-%{RELEASE}" -qp $1/glibc-2*.rpm | head -1)
+ mkdir $vr && pushd $vr
+ fi
+
+ for r in $1*.rpm; do
+ ( rpm2cpio $r | cpio -di ) > /dev/null
+ done
+
+ if [ -n $1 ]; then
+ popd
+ echo $vr
+ fi
+}
+
+# Get rpms for a build and decompress them
+get_build() {
+ echo "Processing build $1"
+ mkdir $1 && pushd $1
+ brew buildinfo "glibc-$1" |
+ sed -n -e "s|/mnt/koji\(.\+$arch.\+\)|http://kojipkgs.fedoraproject.org\1|p" |
+ while read url; do
+ echo "Downloading $url"
+ wget -q $url
+ done
+ decompress_rpms
+
+ echo "Removing rpms"
+ rm -f $1/*.rpm
+
+ popd
+}
+
+# Run benchmarks for a build
+run_bench() {
+ if [ -z $1 ]; then
+ make DETAILED=1 ver=$installed prefix= -f /usr/libexec/glibc-benchtests/bench.mk bench
+ else
+ make DETAILED=1 ver=$1 prefix=$PWD -f $1/usr/libexec/glibc-benchtests/bench.mk bench
+ fi
+}
+
+# Get absolute paths if needed, since we will change into the working directory
+# next.
+if [ $path -eq 1 ]; then
+ old_path=$(realpath $old)/
+ new_path=$(realpath $new)/
+fi
+
+tmpdir=$(mktemp -p /tmp -d glibc-bench-compare.$$.XXXX)
+pushd $tmpdir
+
+# Get both builds.
+if [ $path -eq 0 ]; then
+ if [ -z $installed ]; then
+ get_build $old
+ fi
+ get_build $new
+else
+ old=$(decompress_rpms $old_path)
+ new=$(decompress_rpms $new_path)
+fi
+
+# make bench for each of those.
+if [ -z $installed ]; then
+ run_bench $old
+else
+ run_bench
+fi
+run_bench $new
+
+# Now run the comparison script.
+$old/usr/libexec/glibc-benchtests/compare_bench.py $old/usr/libexec/glibc-benchtests/benchout.schema.json \
+ bench.$old.out bench.$new.out
diff --git a/glibc-c-utf8-locale.patch b/glibc-c-utf8-locale.patch
new file mode 100644
index 0000000..a4cf357
--- /dev/null
+++ b/glibc-c-utf8-locale.patch
@@ -0,0 +1,286 @@
+Short description: Add C.UTF-8 support.
+Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
+Origin: PATCH
+Upstream status: not-submitted
+
+This patch needs to upstream as part of Carlos O'Donell
+<carlos@redhat.com>'s work on enabling upstream C.UTF-8 support. This
+work is currently blocked on cleaning up the test results to prove that
+full code-point sorting is working as intended.
+
+Note that this patch does not provide full code-point sorting as
+expected.
+
+This patch needs to upstream as soon as possible since it would be nice
+to have this in F29 and fixed.
+
+From 2eda7b462b415105f5a05c1323372d4e39d46439 Mon Sep 17 00:00:00 2001
+From: Mike FABIAN <mfabian@redhat.com>
+Date: Mon, 10 Aug 2015 15:58:12 +0200
+Subject: [PATCH] Add a C.UTF-8 locale
+
+---
+ localedata/SUPPORTED | 1 +
+ localedata/locales/C | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 239 insertions(+)
+ create mode 100644 localedata/locales/C
+
+diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED
+index 8ca023e..2a78391 100644
+--- a/localedata/SUPPORTED
++++ b/localedata/SUPPORTED
+@@ -1,6 +1,7 @@
+ # This file names the currently supported and somewhat tested locales.
+ # If you have any additions please file a glibc bug report.
+ SUPPORTED-LOCALES=\
++C.UTF-8/UTF-8 \
+ aa_DJ.UTF-8/UTF-8 \
+ aa_DJ/ISO-8859-1 \
+ aa_ER/UTF-8 \
+diff --git a/localedata/locales/C b/localedata/locales/C
+new file mode 100644
+index 0000000..fdf460e
+--- /dev/null
++++ b/localedata/locales/C
+@@ -0,0 +1,238 @@
++escape_char /
++comment_char %
++% Locale for C locale in UTF-8
++
++LC_IDENTIFICATION
++title "C locale"
++source ""
++address ""
++contact ""
++email "mfabian@redhat.com"
++tel ""
++fax ""
++language "C"
++territory ""
++revision "1.0"
++date "2015-08-10"
++%
++category "i18n:2012";LC_IDENTIFICATION
++category "i18n:2012";LC_CTYPE
++category "i18n:2012";LC_COLLATE
++category "i18n:2012";LC_TIME
++category "i18n:2012";LC_NUMERIC
++category "i18n:2012";LC_MONETARY
++category "i18n:2012";LC_MESSAGES
++category "i18n:2012";LC_PAPER
++category "i18n:2012";LC_NAME
++category "i18n:2012";LC_ADDRESS
++category "i18n:2012";LC_TELEPHONE
++category "i18n:2012";LC_MEASUREMENT
++END LC_IDENTIFICATION
++
++LC_CTYPE
++copy "i18n"
++
++translit_start
++include "translit_combining";""
++translit_end
++
++END LC_CTYPE
++
++LC_COLLATE
++order_start forward
++<U0000>
++..
++<UFFFF>
++<U00010000>
++..
++<U0001FFFF>
++<U00020000>
++..
++<U0002FFFF>
++<U000E0000>
++..
++<U000EFFFF>
++<U000F0000>
++..
++<U000FFFFF>
++<U00100000>
++..
++<U0010FFFF>
++UNDEFINED
++order_end
++END LC_COLLATE
++
++LC_MONETARY
++% This is the 14652 i18n fdcc-set definition for
++% the LC_MONETARY category
++% (except for the int_curr_symbol and currency_symbol, they are empty in
++% the 14652 i18n fdcc-set definition and also empty in
++% glibc/locale/C-monetary.c. But localedef complains in that case).
++%
++% Using "USD" for int_curr_symbol. But maybe "XXX" would be better?
++% XXX is "No currency" (https://en.wikipedia.org/wiki/ISO_4217)
++int_curr_symbol "<U0055><U0053><U0044><U0020>"
++% Using "$" for currency_symbol. But maybe <U00A4> would be better?
++% U+00A4 is the "generic currency symbol"
++% (https://en.wikipedia.org/wiki/Currency_sign_%28typography%29)
++currency_symbol "<U0024>"
++mon_decimal_point "<U002E>"
++mon_thousands_sep ""
++mon_grouping -1
++positive_sign ""
++negative_sign "<U002D>"
++int_frac_digits -1
++frac_digits -1
++p_cs_precedes -1
++int_p_sep_by_space -1
++p_sep_by_space -1
++n_cs_precedes -1
++int_n_sep_by_space -1
++n_sep_by_space -1
++p_sign_posn -1
++n_sign_posn -1
++%
++END LC_MONETARY
++
++LC_NUMERIC
++% This is the POSIX Locale definition for
++% the LC_NUMERIC category.
++%
++decimal_point "<U002E>"
++thousands_sep ""
++grouping -1
++END LC_NUMERIC
++
++LC_TIME
++% This is the POSIX Locale definition for
++% the LC_TIME category.
++%
++% Abbreviated weekday names (%a)
++abday "<U0053><U0075><U006E>";"<U004D><U006F><U006E>";/
++ "<U0054><U0075><U0065>";"<U0057><U0065><U0064>";/
++ "<U0054><U0068><U0075>";"<U0046><U0072><U0069>";/
++ "<U0053><U0061><U0074>"
++
++% Full weekday names (%A)
++day "<U0053><U0075><U006E><U0064><U0061><U0079>";/
++ "<U004D><U006F><U006E><U0064><U0061><U0079>";/
++ "<U0054><U0075><U0065><U0073><U0064><U0061><U0079>";/
++ "<U0057><U0065><U0064><U006E><U0065><U0073><U0064><U0061><U0079>";/
++ "<U0054><U0068><U0075><U0072><U0073><U0064><U0061><U0079>";/
++ "<U0046><U0072><U0069><U0064><U0061><U0079>";/
++ "<U0053><U0061><U0074><U0075><U0072><U0064><U0061><U0079>"
++
++% Abbreviated month names (%b)
++abmon "<U004A><U0061><U006E>";"<U0046><U0065><U0062>";/
++ "<U004D><U0061><U0072>";"<U0041><U0070><U0072>";/
++ "<U004D><U0061><U0079>";"<U004A><U0075><U006E>";/
++ "<U004A><U0075><U006C>";"<U0041><U0075><U0067>";/
++ "<U0053><U0065><U0070>";"<U004F><U0063><U0074>";/
++ "<U004E><U006F><U0076>";"<U0044><U0065><U0063>"
++
++% Full month names (%B)
++mon "<U004A><U0061><U006E><U0075><U0061><U0072><U0079>";/
++ "<U0046><U0065><U0062><U0072><U0075><U0061><U0072><U0079>";/
++ "<U004D><U0061><U0072><U0063><U0068>";/
++ "<U0041><U0070><U0072><U0069><U006C>";/
++ "<U004D><U0061><U0079>";/
++ "<U004A><U0075><U006E><U0065>";/
++ "<U004A><U0075><U006C><U0079>";/
++ "<U0041><U0075><U0067><U0075><U0073><U0074>";/
++ "<U0053><U0065><U0070><U0074><U0065><U006D><U0062><U0065><U0072>";/
++ "<U004F><U0063><U0074><U006F><U0062><U0065><U0072>";/
++ "<U004E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
++ "<U0044><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
++
++% Week description, consists of three fields:
++% 1. Number of days in a week.
++% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday).
++% 3. The weekday number to be contained in the first week of the year.
++%
++% ISO 8601 conforming applications should use the values 7, 19971201 (a
++% Monday), and 4 (Thursday), respectively.
++week 7;19971201;4
++first_weekday 1
++first_workday 1
++
++% Appropriate date and time representation (%c)
++% "%a %b %e %H:%M:%S %Y"
++d_t_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0059>"
++
++% Appropriate date representation (%x)
++% "%m/%d/%y"
++d_fmt "<U0025><U006D><U002F><U0025><U0064><U002F><U0025><U0079>"
++
++% Appropriate time representation (%X)
++% "%H:%M:%S"
++t_fmt "<U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053>"
++
++% Appropriate AM/PM time representation (%r)
++% "%I:%M:%S %p"
++t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0070>"
++
++% Equivalent of AM/PM (%p) "AM"/"PM"
++%
++am_pm "<U0041><U004D>";"<U0050><U004D>"
++
++% Appropriate date representation (date(1)) "%a %b %e %H:%M:%S %Z %Y"
++date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U0020><U0025><U0059>"
++END LC_TIME
++
++LC_MESSAGES
++% This is the POSIX Locale definition for
++% the LC_NUMERIC category.
++%
++yesexpr "<U005E><U005B><U0079><U0059><U005D>"
++noexpr "<U005E><U005B><U006E><U004E><U005D>"
++yesstr "<U0059><U0065><U0073>"
++nostr "<U004E><U006F>"
++END LC_MESSAGES
++
++LC_PAPER
++% This is the ISO/IEC 14652 "i18n" definition for
++% the LC_PAPER category.
++% (A4 paper, this is also used in the built in C/POSIX
++% locale in glibc/locale/C-paper.c)
++height 297
++width 210
++END LC_PAPER
++
++LC_NAME
++% This is the ISO/IEC 14652 "i18n" definition for
++% the LC_NAME category.
++% "%p%t%g%t%m%t%f"
++% (also used in the built in C/POSIX locale in glibc/locale/C-name.c)
++name_fmt "<U0025><U0070><U0025><U0074><U0025><U0067><U0025><U0074>/
++<U0025><U006D><U0025><U0074><U0025><U0066>"
++END LC_NAME
++
++LC_ADDRESS
++% This is the ISO/IEC 14652 "i18n" definition for
++% the LC_ADDRESS category.
++% "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"
++% (also used in the built in C/POSIX locale in glibc/locale/C-address.c)
++postal_fmt "<U0025><U0061><U0025><U004E><U0025><U0066><U0025><U004E>/
++<U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0073>/
++<U0020><U0025><U0068><U0020><U0025><U0065><U0020><U0025><U0072><U0025>/
++<U004E><U0025><U0043><U002D><U0025><U007A><U0020><U0025><U0054><U0025>/
++<U004E><U0025><U0063><U0025><U004E>"
++END LC_ADDRESS
++
++LC_TELEPHONE
++% This is the ISO/IEC 14652 "i18n" definition for
++% the LC_TELEPHONE category.
++% "+%c %a %l"
++tel_int_fmt "<U002B><U0025><U0063><U0020><U0025><U0061><U0020><U0025>/
++<U006C>"
++% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c)
++END LC_TELEPHONE
++
++LC_MEASUREMENT
++% This is the ISO/IEC 14652 "i18n" definition for
++% the LC_MEASUREMENT category.
++% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c)
++%metric
++measurement 1
++END LC_MEASUREMENT
++
+--
+2.4.3
+
diff --git a/glibc.spec b/glibc.spec
new file mode 100644
index 0000000..83d20b0
--- /dev/null
+++ b/glibc.spec
@@ -0,0 +1,1329 @@
+%global __filter_GLIBC_PRIVATE 1
+
+%define rpm_ver_major %(eval "echo `rpm -q rpm |cut -d '-' -f2 |cut -d. -f1`")
+%define rpm_ver_minor %(eval "echo `rpm -q rpm |cut -d '-' -f2 |cut -d. -f2`")
+%define rpm_version_ge_412 %(eval "if [ %{rpm_ver_major} -gt 4 -o %{rpm_ver_major} -eq 4 -a %{rpm_ver_minor} -ge 12 ]; then echo 1; else echo 0; fi")
+%define gcc_version %(eval "echo `gcc --version |head -1 |awk '{print $3}' |awk -F '.' '{print $1}'`")
+##############################################################################
+# We support the following options:
+# --with/--without,
+# * testsuite
+# - Running the testsuite. It must run for production builds.
+# - Default: Always run the testsuite.
+# * benchtests
+# - Running and building benchmark subpackage.
+# - Default: Always build the benchtests.
+# * bootstrap
+# - Bootstrapping the package.
+# - Default: Not bootstrapping.
+# * werror
+# - Build with -Werror
+# - Default: Enable using -Werror
+# * docs
+# - Build with documentation and the required dependencies.
+# - Default: Always build documentation.
+# * valgrind
+# - Run smoke tests with valgrind to verify dynamic loader.
+# - Default: Always run valgrind tests if there is architecture support.
+##############################################################################
+%bcond_without testsuite
+%bcond_without benchtests
+%bcond_with bootstrap
+%bcond_without werror
+%bcond_without docs
+%bcond_with libpthreadcond
+
+%ifarch %{valgrind_arches}
+%bcond_without valgrind
+%else
+%bcond_with valgrind
+%endif
+
+%if %{with bootstrap}
+%undefine with_benchtests
+%undefine with_werror
+%undefine with_docs
+%undefine with_valgrind
+%endif
+
+%define enablekernel 3.2
+%define target %{_target_cpu}-%{_vendor}-linux
+%ifarch %{arm}
+%define target %{_target_cpu}-%{_vendor}-linuxeabi
+%endif
+%define x86_arches %{ix86} x86_64
+%define all_license LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ and GPLv2+ with exceptions and BSD and Inner-Net and ISC and Public Domain and GFDL
+%define GCC gcc
+%define GXX g++
+##############################################################################
+# glibc - The GNU C Library (glibc) core package.
+##############################################################################
+Name: glibc
+Version: 2.31
+Release: 10
+Summary: The GNU libc libraries
+License: %{all_license}
+URL: http://www.gnu.org/software/glibc/
+
+Source0: https://ftp.gnu.org/gnu/glibc/%{name}-%{version}.tar.xz
+Source1: nscd.conf
+Source2: nsswitch.conf
+Source3: bench.mk
+Source4: glibc-bench-compare
+Source5: LanguageList
+Source6: LicenseList
+
+Patch0: glibc-1070416.patch
+Patch1: glibc-c-utf8-locale.patch
+
+Patch6000: Fix-use-after-free-in-glob-when-expanding-user-bug-2.patch
+Patch6001: Avoid-ldbl-96-stack-corruption-from-range-reduction-.patch
+Patch6002: Reset-converter-state-after-second-wchar_t-output-Bu.patch
+Patch6003: Fix-avx2-strncmp-offset-compare-condition-check-BZ-2.patch
+Patch6004: nptl-wait-for-pending-setxid-request-also-in-detache.patch
+Patch6005: x86-64-Use-RDX_LP-on-__x86_shared_non_temporal_thres.patch
+Patch6006: x86_64-Use-xmmN-with-vpxor-to-clear-a-vector-registe.patch
+Patch6007: nptl-Don-t-madvise-user-provided-stack.patch
+Patch6008: turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch
+Patch6009: Fix-strtod-multiple-precision-division-bug-bug-26137.patch
+Patch6010: Fix-double-free-in-__printf_fp_l-bug-26214.patch
+Patch6011: Fix-memory-leak-in-__printf_fp_l-bug-26215.patch
+Patch6012: Fix-CVE-2020-6096-001.patch
+Patch6013: Fix-CVE-2020-6096-002.patch
+Patch6014: Disable-warnings-due-to-deprecated-libselinux-symbol.patch
+Patch6015: rtld-Avoid-using-up-static-TLS-surplus-for-optimizat.patch
+Patch6016: Fix-CVE-2020-27618-iconv-Accept-redundant-shift-sequences.patch
+Patch6017: elf-Allow-dlopen-of-filter-object-to-work-BZ-16272.patch
+Patch6018: Handle-SEM_STAT_ANY-the-same-way-as-SEM_STAT-so-that.patch
+
+Patch9000: delete-no-hard-link-to-avoid-all_language-package-to.patch
+Patch9001: build-extra-libpthreadcond-so.patch
+Patch9002: remove-country-selection-from-tzselect.patch
+
+Provides: ldconfig rtld(GNU_HASH) bundled(gnulib)
+
+BuildRequires: audit-libs-devel >= 1.1.3, sed >= 3.95, libcap-devel, gettext
+BuildRequires: procps-ng, util-linux, gawk, systemtap-sdt-devel, systemd, python3
+BuildRequires: make >= 4.0, bison >= 2.7, binutils >= 2.30-17, gcc >= 7.2.1-6
+BuildRequires: m4 gcc_secure gdb
+
+%if %{without bootstrap}
+BuildRequires: gd-devel libpng-devel zlib-devel
+%endif
+
+%if %{with docs}
+BuildRequires: texinfo >= 5.0
+%endif
+
+%if %{without bootstrap}
+BuildRequires: libselinux-devel >= 1.33.4-3
+%endif
+
+%if %{with valgrind}
+BuildRequires: valgrind
+%endif
+
+%if 0%{?_enable_debug_packages}
+BuildRequires: elfutils >= 0.72 rpm >= 4.2-0.56
+%endif
+
+%if %{without bootstrap}
+%if %{with testsuite}
+BuildRequires: gcc-c++ libstdc++-static glibc-devel libidn2
+%endif
+%endif
+
+Requires: glibc-common = %{version}-%{release}
+Requires: glibc-langpack = %{version}-%{release}
+Requires: basesystem
+
+%description
+The GNU C Library project provides the core libraries for the GNU system and
+GNU/Linux systems, as well as many other systems that use Linux as the kernel.
+These libraries provide critical APIs including ISO C11, POSIX.1-2008, BSD,
+OS-specific APIs and more. These APIs include such foundational facilities as
+open, read, write, malloc, printf, getaddrinfo, dlopen, pthread_create, crypt,
+ login, exit and more.
+
+##############################################################################
+# glibc "common" sub-package
+##############################################################################
+%package common
+Summary: Common binaries and locale data for glibc
+Provides: glibc-langpack = %{version}-%{release}
+
+Provides: glibc-langpack-en = %{version}-%{release}
+Provides: glibc-langpack-en%{?_isa} = %{version}-%{release}
+Provides: glibc-langpack-zh = %{version}-%{release}
+Provides: glibc-langpack-zh%{?_isa} = %{version}-%{release}
+
+Requires: %{name} = %{version}-%{release}
+Requires: tzdata >= 2003a
+
+%description common
+The glibc-common package includes common binaries for the GNU libc
+libraries and national language (locale) support. Besides, zh_CN and
+en_US are included.
+
+%transfiletriggerin common -P 2000000 -- /lib /usr/lib /lib64 /usr/lib64
+/sbin/ldconfig
+%end
+
+%transfiletriggerpostun common -P 2000000 -- /lib /usr/lib /lib64 /usr/lib64
+/sbin/ldconfig
+%end
+
+%undefine __brp_ldconfig
+
+##############################################################################
+# glibc "all-langpacks" sub-package
+##############################################################################
+%package all-langpacks
+Summary: All language packs for %{name}.
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
+Provides: %{name}-langpack = %{version}-%{release}
+Obsoletes: %{name}-minimal-langpack = 2.28
+
+%{lua:
+-- List the Symbol provided by all-langpacks
+lang_provides = {}
+for line in io.lines(rpm.expand("%{SOURCE5}")) do
+ print(rpm.expand([[
+Provides:]]..line..[[ = %{version}-%{release}
+Obsoletes:]]..line..[[ = 2.28
+]]))
+end
+}
+
+%description all-langpacks
+The glibc-all-langpacks provides all the glibc-langpacks. Every entry
+includes the basic information required to support the corresponding
+language in your applications.
+
+##############################################################################
+# glibc "locale-source" sub-package
+##############################################################################
+%package locale-source
+Summary: The sources package of locales
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
+
+%description locale-source
+The locale-source package contains all language packs which are built custom
+locales
+
+##############################################################################
+# glibc "devel" sub-package
+##############################################################################
+%package devel
+Summary: The devel for %{name}
+Requires: %{name} = %{version}-%{release}
+Requires: libgcc%{_isa}
+Requires(pre): info
+Requires(pre): kernel-headers
+Requires(pre): coreutils
+Requires: kernel-headers >= 3.2
+%if 0%{rpm_version_ge_412}
+Requires: libxcrypt-devel%{_isa} >= 4.0.0
+Requires: libxcrypt-static%{?_isa} >= 4.0.0
+%endif
+BuildRequires: kernel-headers >= 3.2
+
+Provides: %{name}-static = %{version}-%{release}
+Provides: %{name}-static%{_isa} = %{version}-%{release}
+Provides: %{name}-headers = %{version}-%{release}
+Provides: %{name}-headers(%{_target_cpu})
+Provides: %{name}-headers%{_isa} = %{version}-%{release}
+
+Obsoletes: %{name}-static = 2.28
+Obsoletes: %{name}-headers = 2.28
+
+%description devel
+The glibc-devel package contains the object files necessary for developing
+programs which use the standard C libraries. Besides, it contains the
+headers. Thus, it is necessory to install glibc-devel if you ned develop programs.
+
+##############################################################################
+# glibc "nscd" sub-package
+##############################################################################
+%package -n nscd
+Summary: Name caching service daemon.
+Requires: %{name} = %{version}-%{release}
+%if %{without bootstrap}
+Requires: libselinux >= 1.17.10-1
+%endif
+Requires: audit-libs >= 1.1.3
+Requires(pre): shadow-utils, coreutils
+Requires: systemd
+Requires(postun): shadow-utils
+
+%description -n nscd
+The nscd package is able to daemon caches name service lookups and improve
+the performance with LDAP.
+
+##############################################################################
+# nss modules sub-package
+##############################################################################
+%package -n nss_modules
+Summary: Name Service Switch module using hash-indexed files and Hesiod
+Requires: %{name}%{_isa} = %{version}-%{release}
+Provides: nss_db = %{version}-%{release}
+Provides: nss_db%{_isa} = %{version}-%{release}
+Provides: nss_hesiod = %{version}-%{release}
+Provides: nss_hesiod%{_isa} = %{version}-%{release}
+Obsoletes: nss_db = 2.28, nss_hesiod = 2.28
+
+%description -n nss_modules
+This package contains nss_db and nss_hesiod. The former uses hash-indexed files
+to speed up user, group, service, host name, and other NSS-based lookups.The
+latter uses the Domain Name System (DNS) as a source for user, group, and service
+information to follow the Hesiod convention of Project Athena.
+
+##############################################################################
+# nss-devel sub-package
+##############################################################################
+%package nss-devel
+Summary: The devel for directly linking NSS service modules
+Requires: nss_db%{_isa} = %{version}-%{release}
+Requires: nss_hesiod%{_isa} = %{version}-%{release}
+
+%description nss-devel
+This package contains the necessary devel files to compile applications and
+libraries which directly link against NSS modules supplied by glibc. This
+package is rarely used, and in most cases use the glibc-devel package instead.
+
+##############################################################################
+# libnsl subpackage
+##############################################################################
+%package -n libnsl
+Summary: Public client interface for NIS(YP) and NIS+
+Requires: %{name}%{_isa} = %{version}-%{release}
+
+%description -n libnsl
+The libnsl package contains the public client interface for NIS(YP) and NIS+.
+It replaces the NIS library that used to be in glibc.
+
+##############################################################################
+# glibc benchtests sub-package
+##############################################################################
+%if %{with benchtests}
+
+%package benchtests
+Summary: Build benchmarking binaries and scripts for %{name}
+
+%description benchtests
+This package provides built benchmark binaries and scripts which will be used
+to run microbenchmark tests on the system.
+%endif
+
+##############################################################################
+# glibc debugutils sub-package
+##############################################################################
+%package debugutils
+Summary: debug files for %{name}
+Requires: %{name} = %{version}-%{release}
+Provides: %{name}-utils = %{version}-%{release}
+Provides: %{name}-utils%{_isa} = %{version}-%{release}
+
+Obsoletes: %{name}-utils = 2.28
+
+%description debugutils
+This package provides memusage, a memory usage profiler, mtrace, a memory leak
+tracer and xtrace, a function call tracer, all of which is not necessory for you.
+
+##############################################################################
+# glibc debuginfo sub-package
+##############################################################################
+%if 0%{?_enable_debug_packages}
+%define debug_package %{nil}
+%define __debug_install_post %{nil}
+%global __debug_package 1
+
+%undefine _debugsource_packages
+%undefine _debuginfo_subpackages
+%undefine _unique_debug_names
+%undefine _unique_debug_srcs
+
+%package debuginfo
+Summary: Debug information for %{name}
+AutoReqProv: no
+
+%description debuginfo
+This package provides debug information for package %{name}.
+Debug information is useful when developing applications that use this
+package or when debugging this package.
+
+%package debugsource
+Summary: Debug source for %{name}
+AutoReqProv: no
+
+%description debugsource
+This package provides debug sources for package %{name}.
+Debug sources are useful when developing applications that use this
+package or when debugging this package.
+
+%endif # 0%{?_enable_debug_packages}
+
+##############################################################################
+# glibc help sub-package
+##############################################################################
+%package help
+Summary: The doc and man for %{name}
+Buildarch: noarch
+Requires: man info
+
+%description help
+This package provides al doc and man files of %{name}
+
+##############################################################################
+# Prepare for the build.
+##############################################################################
+%prep
+%autosetup -n %{name}-%{version} -p1
+
+chmod +x benchtests/scripts/*.py scripts/pylint
+
+find . -type f -size 0 -o -name "*.orig" -exec rm -f {} \;
+
+touch `find . -name configure`
+
+touch locale/programs/*-kw.h
+
+##############################################################################
+# Build glibc...
+##############################################################################
+%build
+
+BuildFlags="-O2 -g"
+BuildFlags="$BuildFlags -DNDEBUG"
+reference=" \
+ "-Wp,-D_GLIBCXX_ASSERTIONS" \
+ "-fasynchronous-unwind-tables" \
+ "-fstack-clash-protection" \
+ "-funwind-tables" \
+ "-m31" \
+ "-m32" \
+ "-m64" \
+ "-march=haswell" \
+ "-march=i686" \
+ "-march=x86-64" \
+ "-march=z13" \
+ "-march=z14" \
+ "-march=zEC12" \
+ "-mfpmath=sse" \
+ "-msse2" \
+ "-mstackrealign" \
+ "-mtune=generic" \
+ "-mtune=z13" \
+ "-mtune=z14" \
+ "-mtune=zEC12" \
+ "-specs=/usr/lib/rpm/%{_vendor}/%{_vendor}-annobin-cc1" "
+
+for flag in $RPM_OPT_FLAGS $RPM_LD_FLAGS ; do
+ if echo "$reference" | grep -q -F " $flag " ; then
+ BuildFlags="$BuildFlags $flag"
+ fi
+done
+
+%define glibc_make_flags_as ASFLAGS="-g -Wa,--generate-missing-build-notes=yes"
+%define glibc_make_flags %{glibc_make_flags_as}
+
+EnableKernel="--enable-kernel=%{enablekernel}"
+
+builddir=build-%{target}
+rm -rf $builddir
+mkdir $builddir
+pushd $builddir
+../configure CC="%GCC" CXX="%GXX" CFLAGS="$BuildFlags" \
+ --prefix=%{_prefix} \
+ --with-headers=%{_prefix}/include $EnableKernel \
+ --with-nonshared-cflags=-Wp,-D_FORTIFY_SOURCE=2 \
+ --enable-bind-now \
+ --build=%{target} \
+ --enable-stack-protector=strong \
+%ifarch %{x86_arches}
+%if 0%{?gcc_version} >= 8
+ --enable-static-pie \
+ --enable-cet \
+%endif
+%endif
+ --enable-tunables \
+ --enable-systemtap \
+%ifarch %{ix86}
+ --disable-multi-arch \
+%endif
+%if %{without werror}
+ --disable-werror \
+%endif
+ --disable-profile \
+%if %{with bootstrap}
+ --without-selinux \
+%endif
+%if 0%{rpm_version_ge_412}
+ --disable-crypt \
+%endif
+ ||
+ { cat config.log; false; }
+
+make %{?_smp_mflags} -O -r %{glibc_make_flags}
+popd
+
+##############################################################################
+# Build libpthreadcond
+##############################################################################
+%if %{with libpthreadcond}
+ cd nptl_2_17
+ sh build_libpthreadcondso.sh %{_target_cpu} $builddir
+ cd ..
+%endif
+
+##############################################################################
+# Install glibc...
+##############################################################################
+%install
+chmod 644 sysdeps/gnu/errlist.c
+
+%ifarch riscv64
+for d in $RPM_BUILD_ROOT%{_libdir} $RPM_BUILD_ROOT/%{_lib}; do
+ mkdir -p $d
+ (cd $d && ln -sf . lp64d)
+done
+%endif
+
+make -j1 install_root=$RPM_BUILD_ROOT install -C build-%{target}
+
+%if %{with libpthreadcond}
+ cp build-%{target}/nptl/libpthreadcond.so $RPM_BUILD_ROOT%{_libdir}
+%endif
+
+pushd build-%{target}
+
+# notice: we can't use parallel compilation because the localedata will use "localedef" command
+# to create locales such as LC_CTYPE, LC_TIME etc, and this command will create a file,
+# or create a hard link if there already has a output file who's input is the same,
+# so when we use parallel compilation, it will lead to different results, and this will cause BEP inconsistence.
+make -j1 install_root=$RPM_BUILD_ROOT \
+ install-locale-files -C ../localedata objdir=`pwd`
+popd
+
+rm -f $RPM_BUILD_ROOT/%{_libdir}/libNoVersion*
+rm -f $RPM_BUILD_ROOT/%{_lib}/libNoVersion*
+rm -f $RPM_BUILD_ROOT/%{_lib}/libnss1-*
+rm -f $RPM_BUILD_ROOT/%{_lib}/libnss-*.so.1
+rm -f $RPM_BUILD_ROOT/{usr/,}sbin/sln
+
+mkdir -p $RPM_BUILD_ROOT/var/cache/ldconfig
+truncate -s 0 $RPM_BUILD_ROOT/var/cache/ldconfig/aux-cache
+
+$RPM_BUILD_ROOT/sbin/ldconfig -N -r $RPM_BUILD_ROOT
+
+# Install info files
+%if %{with docs}
+# Move the info files if glibc installed them into the wrong location.
+if [ -d $RPM_BUILD_ROOT%{_prefix}/info -a "%{_infodir}" != "%{_prefix}/info" ]; then
+ mkdir -p $RPM_BUILD_ROOT%{_infodir}
+ mv -f $RPM_BUILD_ROOT%{_prefix}/info/* $RPM_BUILD_ROOT%{_infodir}
+ rm -rf $RPM_BUILD_ROOT%{_prefix}/info
+fi
+
+# Compress all of the info files.
+gzip -9nvf $RPM_BUILD_ROOT%{_infodir}/libc*
+
+%else
+rm -f $RPM_BUILD_ROOT%{_infodir}/dir
+rm -f $RPM_BUILD_ROOT%{_infodir}/libc.info*
+%endif
+
+# Create all-packages libc.lang
+olddir=`pwd`
+pushd $RPM_BUILD_ROOT%{_prefix}/lib/locale
+rm -f locale-archive
+$olddir/build-%{target}/elf/ld.so \
+ --library-path $olddir/build-%{target}/ \
+ $olddir/build-%{target}/locale/localedef \
+ --alias-file=$olddir/intl/locale.alias \
+ --prefix $RPM_BUILD_ROOT --add-to-archive \
+ eo *_*
+%{find_lang} libc
+popd
+mv $RPM_BUILD_ROOT%{_prefix}/lib/locale/libc.lang .
+
+# Install configuration files for services
+install -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT/etc/nsswitch.conf
+
+mkdir -p $RPM_BUILD_ROOT/etc/default
+install -p -m 644 nis/nss $RPM_BUILD_ROOT/etc/default/nss
+
+# This is for ncsd - in glibc 2.2
+install -m 644 nscd/nscd.conf $RPM_BUILD_ROOT/etc
+mkdir -p $RPM_BUILD_ROOT%{_tmpfilesdir}
+install -m 644 %{SOURCE1} %{buildroot}%{_tmpfilesdir}
+mkdir -p $RPM_BUILD_ROOT/lib/systemd/system
+install -m 644 nscd/nscd.service nscd/nscd.socket $RPM_BUILD_ROOT/lib/systemd/system
+
+# Include ld.so.conf
+echo 'include ld.so.conf.d/*.conf' > $RPM_BUILD_ROOT/etc/ld.so.conf
+truncate -s 0 $RPM_BUILD_ROOT/etc/ld.so.cache
+chmod 644 $RPM_BUILD_ROOT/etc/ld.so.conf
+mkdir -p $RPM_BUILD_ROOT/etc/ld.so.conf.d
+mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
+truncate -s 0 $RPM_BUILD_ROOT/etc/sysconfig/nscd
+truncate -s 0 $RPM_BUILD_ROOT/etc/gai.conf
+
+# Include %{_libdir}/gconv/gconv-modules.cache
+truncate -s 0 $RPM_BUILD_ROOT%{_libdir}/gconv/gconv-modules.cache
+chmod 644 $RPM_BUILD_ROOT%{_libdir}/gconv/gconv-modules.cache
+
+# Install debug copies of unstripped static libraries
+%if 0%{?_enable_debug_packages}
+mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/debug%{_libdir}
+cp -a $RPM_BUILD_ROOT%{_libdir}/*.a \
+ $RPM_BUILD_ROOT%{_prefix}/lib/debug%{_libdir}/
+rm -f $RPM_BUILD_ROOT%{_prefix}/lib/debug%{_libdir}/*_p.a
+%endif
+
+# Remove any zoneinfo files; they are maintained by tzdata.
+rm -rf $RPM_BUILD_ROOT%{_prefix}/share/zoneinfo
+
+touch -r %{SOURCE0} $RPM_BUILD_ROOT/etc/ld.so.conf
+touch -r sunrpc/etc.rpc $RPM_BUILD_ROOT/etc/rpc
+
+# Lastly copy some additional documentation for the packages.
+rm -rf documentation
+mkdir documentation
+cp timezone/README documentation/README.timezone
+cp posix/gai.conf documentation/
+
+%if %{with benchtests}
+# Build benchmark binaries. Ignore the output of the benchmark runs.
+pushd build-%{target}
+make BENCH_DURATION=1 bench-build
+popd
+
+# Copy over benchmark binaries.
+mkdir -p $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests
+cp $(find build-%{target}/benchtests -type f -executable) $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests/
+
+#makefile.
+for b in %{SOURCE3} %{SOURCE4}; do
+ cp $b $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests/
+done
+
+#comparison scripts.
+for i in benchout.schema.json compare_bench.py import_bench.py validate_benchout.py; do
+ cp benchtests/scripts/$i $RPM_BUILD_ROOT%{_prefix}/libexec/glibc-benchtests/
+done
+
+%if 0%{?_enable_debug_packages}
+pushd locale
+ln -s programs/*.gperf .
+popd
+
+pushd iconv
+ln -s ../locale/programs/charmap-kw.gperf .
+popd
+
+%if %{with docs}
+rm -f $RPM_BUILD_ROOT%{_infodir}/dir
+%endif
+
+mkdir -p $RPM_BUILD_ROOT/var/{db,run}/nscd
+touch $RPM_BUILD_ROOT/var/{db,run}/nscd/{passwd,group,hosts,services}
+touch $RPM_BUILD_ROOT/var/run/nscd/{socket,nscd.pid}
+
+mkdir -p $RPM_BUILD_ROOT%{_libdir}
+mv -f $RPM_BUILD_ROOT/%{_lib}/lib{pcprofile,memusage}.so \
+ $RPM_BUILD_ROOT%{_libdir}
+
+# Strip all of the installed object files.
+strip -g $RPM_BUILD_ROOT%{_libdir}/*.o
+
+# Rebuild libpthread.a using --whole-archive to ensure all of libpthread
+# is included in a static link.
+pushd $RPM_BUILD_ROOT%{_prefix}/%{_lib}/
+%GCC -r -nostdlib -o libpthread.o -Wl,--whole-archive ./libpthread.a
+rm libpthread.a
+ar rcs libpthread.a libpthread.o
+rm libpthread.o
+popd
+
+for i in $RPM_BUILD_ROOT%{_prefix}/bin/{xtrace,memusage}; do
+%if %{with bootstrap}
+ test -w $i || continue
+%endif
+ sed -e 's~=/%{_lib}/libpcprofile.so~=%{_libdir}/libpcprofile.so~' \
+ -e 's~=/%{_lib}/libmemusage.so~=%{_libdir}/libmemusage.so~' \
+ -e 's~='\''/\\\$LIB/libpcprofile.so~='\''%{_prefix}/\\$LIB/libpcprofile.so~' \
+ -e 's~='\''/\\\$LIB/libmemusage.so~='\''%{_prefix}/\\$LIB/libmemusage.so~' \
+ -i $i
+done
+
+touch master.filelist
+touch glibc.filelist
+touch common.filelist
+touch devel.filelist
+touch nscd.filelist
+touch nss_modules.filelist
+touch nss-devel.filelist
+touch libnsl.filelist
+touch debugutils.filelist
+touch benchtests.filelist
+touch debuginfo.filelist
+
+{
+ find $RPM_BUILD_ROOT \( -type f -o -type l \) \
+ \( \
+ -name etc -printf "%%%%config " -o \
+ -name gconv-modules \
+ -printf "%%%%verify(not md5 size mtime) %%%%config(noreplace) " -o \
+ -name gconv-modules.cache \
+ -printf "%%%%verify(not md5 size mtime) " \
+ , \
+ ! -path "*/lib/debug/*" -printf "/%%P\n" \)
+
+ find $RPM_BUILD_ROOT -type d \
+ \( -path '*%{_prefix}/share/locale' -prune -o \
+ \( -path '*%{_prefix}/share/*' \
+%if %{with docs}
+ ! -path '*%{_infodir}' -o \
+%endif
+ -path "*%{_prefix}/include/*" \
+ \) -printf "%%%%dir /%%P\n" \)
+} | {
+ sed -e '\,.*/share/locale/\([^/_]\+\).*/LC_MESSAGES/.*\.mo,d' \
+ -e '\,.*/share/i18n/locales/.*,d' \
+ -e '\,.*/share/i18n/charmaps/.*,d' \
+ -e '\,.*/etc/\(localtime\|nsswitch.conf\|ld\.so\.conf\|ld\.so\.cache\|default\|rpc\|gai\.conf\),d' \
+ -e '\,.*/%{_libdir}/lib\(pcprofile\|memusage\)\.so,d' \
+ -e '\,.*/bin/\(memusage\|mtrace\|xtrace\|pcprofiledump\),d'
+} | sort > master.filelist
+
+chmod 0444 master.filelist
+
+##############################################################################
+# glibc - The GNU C Library (glibc) core package.
+##############################################################################
+cat master.filelist \
+ | grep -v \
+ -e '%{_infodir}' \
+ -e '%{_libdir}/lib.*_p.a' \
+ -e '%{_prefix}/include' \
+ -e '%{_libdir}/lib.*\.a' \
+ -e '%{_libdir}/.*\.o' \
+ -e '%{_libdir}/lib.*\.so' \
+ -e 'nscd' \
+ -e '%{_prefix}/bin' \
+ -e '%{_prefix}/lib/locale' \
+ -e '%{_prefix}/sbin/[^i]' \
+ -e '%{_prefix}/share' \
+ -e '/var/db/Makefile' \
+ -e '/libnss_.*\.so[0-9.]*$' \
+ -e '/libnsl' \
+ -e 'glibc-benchtests' \
+ -e 'aux-cache' \
+ > glibc.filelist
+
+for module in compat files dns; do
+ cat master.filelist \
+ | grep -E \
+ -e "/libnss_$module(\.so\.[0-9.]+|-[0-9.]+\.so)$" \
+ >> glibc.filelist
+done
+grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist >> glibc.filelist
+
+%if %{with libpthreadcond}
+ echo "%{_libdir}/libpthreadcond.so" >> glibc.filelist
+%endif
+
+##############################################################################
+# glibc "common" sub-package
+##############################################################################
+grep '%{_prefix}/bin' master.filelist > common.filelist
+grep '%{_prefix}/sbin' master.filelist \
+ | grep -v '%{_prefix}/sbin/iconvconfig' \
+ | grep -v 'nscd' >> common.filelist
+
+grep '%{_prefix}/share' master.filelist \
+ | grep -v \
+ -e '%{_prefix}/share/info/libc.info.*' \
+ -e '%%dir %{prefix}/share/info' \
+ -e '%%dir %{prefix}/share' \
+ >> common.filelist
+
+###############################################################################
+# glibc "devel" sub-package
+###############################################################################
+%if %{with docs}
+grep '%{_infodir}' master.filelist | grep -v '%{_infodir}/dir' > devel.filelist
+%endif
+
+grep '%{_libdir}/lib.*\.a' master.filelist \
+ | grep '/lib\(\(c\|pthread\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\)\.a$' \
+ >> devel.filelist
+
+grep '%{_libdir}/.*\.o' < master.filelist >> devel.filelist
+grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist
+
+sed -i -e '\,libmemusage.so,d' \
+ -e '\,libpcprofile.so,d' \
+ -e '\,/libnss_[a-z]*\.so$,d' \
+ devel.filelist
+
+grep '%{_prefix}/include' < master.filelist >> devel.filelist
+
+grep '%{_libdir}/lib.*\.a' < master.filelist \
+ | grep -v '/lib\(\(c\|pthread\|nldbl\|mvec\)_nonshared\|g\|ieee\|mcheck\)\.a$' \
+ >> devel.filelist
+
+
+##############################################################################
+# glibc "nscd" sub-package
+##############################################################################
+echo '%{_prefix}/sbin/nscd' > nscd.filelist
+
+##############################################################################
+# nss modules sub-package
+##############################################################################
+grep -E "/libnss_(db|hesiod)(\.so\.[0-9.]+|-[0-9.]+\.so)$" \
+master.filelist > nss_modules.filelist
+
+##############################################################################
+# nss-devel sub-package
+##############################################################################
+grep '/libnss_[a-z]*\.so$' master.filelist > nss-devel.filelist
+
+##############################################################################
+# libnsl subpackage
+##############################################################################
+grep '/libnsl-[0-9.]*.so$' master.filelist > libnsl.filelist
+test $(wc -l < libnsl.filelist) -eq 1
+
+##############################################################################
+# glibc debugutils sub-package
+##############################################################################
+cat > debugutils.filelist <<EOF
+%if %{without bootstrap}
+%{_prefix}/bin/memusage
+%{_prefix}/bin/memusagestat
+%endif
+%{_prefix}/bin/mtrace
+%{_prefix}/bin/pcprofiledump
+%{_prefix}/bin/xtrace
+EOF
+
+##############################################################################
+# glibc benchtests sub-package
+##############################################################################
+find build-%{target}/benchtests -type f -executable | while read b; do
+ echo "%{_prefix}/libexec/glibc-benchtests/$(basename $b)"
+done > benchtests.filelist
+# ... and the makefile.
+for b in %{SOURCE3} %{SOURCE4}; do
+ echo "%{_prefix}/libexec/glibc-benchtests/$(basename $b)" >> benchtests.filelist
+done
+# ... and finally, the comparison scripts.
+echo "%{_prefix}/libexec/glibc-benchtests/benchout.schema.json" >> benchtests.filelist
+echo "%{_prefix}/libexec/glibc-benchtests/compare_bench.py*" >> benchtests.filelist
+echo "%{_prefix}/libexec/glibc-benchtests/import_bench.py*" >> benchtests.filelist
+echo "%{_prefix}/libexec/glibc-benchtests/validate_benchout.py*" >> benchtests.filelist
+%endif # 0%{?_enable_debug_packages}
+
+##############################################################################
+# glibc debuginfo sub-package
+##############################################################################
+touch debuginfo_additional.filelist
+find_debuginfo_args='--strict-build-id -i'
+%ifarch %{x86_arches}
+find_debuginfo_args="$find_debuginfo_args \
+ -l common.filelist \
+ -l debugutils.filelist \
+ -l nscd.filelist \
+ -p '.*/(sbin|libexec)/.*' \
+ -o debuginfo_additional.filelist \
+ -l nss_modules.filelist \
+ -l libnsl.filelist \
+ -l glibc.filelist \
+%if %{with benchtests}
+ -l benchtests.filelist
+%endif
+ "
+%endif
+
+/usr/lib/rpm/find-debuginfo.sh $find_debuginfo_args -o debuginfo.filelist
+
+%ifarch %{x86_arches}
+sed -i '\#^$RPM_BUILD_ROOT%{_prefix}/src/debug/#d' debuginfo_additional.filelist
+cat debuginfo_additional.filelist >> debuginfo.filelist
+find $RPM_BUILD_ROOT%{_prefix}/src/debug \
+ \( -type d -printf '%%%%dir ' \) , \
+ -printf '%{_prefix}/src/debug/%%P\n' >> debuginfo.filelist
+
+add_dir=%{_prefix}/lib/debug%{_libdir}
+find $RPM_BUILD_ROOT$add_dir -name "*.a" -printf "$add_dir/%%P\n" >> debuginfo.filelist
+%endif # %{x86_arches}
+
+remove_dir="%{_prefix}/src/debug"
+remove_dir="$remove_dir $(echo %{_prefix}/lib/debug{,/%{_lib},/bin,/sbin})"
+remove_dir="$remove_dir $(echo %{_prefix}/lib/debug%{_prefix}{,/%{_lib},/libexec,/bin,/sbin})"
+
+for d in $(echo $remove_dir | sed 's/ /\n/g'); do
+ sed -i "\|^%%dir $d/\?$|d" debuginfo.filelist
+done
+
+%endif # %{with benchtests}
+##############################################################################
+# Run the glibc testsuite
+##############################################################################
+%check
+%if %{with testsuite}
+# Increase timeouts
+export TIMEOUTFACTOR=16
+parent=$$
+echo ====================TESTING=========================
+
+# Default libraries.
+pushd build-%{target}
+make %{?_smp_mflags} -O check |& tee rpmbuild.check.log >&2
+test -n tests.sum
+if ! grep -q '^Summary of test results:$' rpmbuild.check.log ; then
+ echo "FAIL: test suite build of target: $(basename "$(pwd)")" >& 2
+ exit 1
+fi
+set +x
+grep -v ^PASS: tests.sum > rpmbuild.tests.sum.not-passing || true
+if test -n rpmbuild.tests.sum.not-passing ; then
+ echo ===================FAILED TESTS===================== >&2
+ echo "Target: $(basename "$(pwd)")" >& 2
+ cat rpmbuild.tests.sum.not-passing >&2
+ while read failed_code failed_test ; do
+ for suffix in out test-result ; do
+ if test -e "$failed_test.$suffix"; then
+ echo >&2
+ echo "=====$failed_code $failed_test.$suffix=====" >&2
+ cat -- "$failed_test.$suffix" >&2
+ echo >&2
+ fi
+ done
+ done <rpmbuild.tests.sum.not-passing
+fi
+
+# Unconditonally dump differences in the system call list.
+echo "* System call consistency checks:" >&2
+cat misc/tst-syscall-list.out >&2
+set -x
+popd
+
+echo ====================TESTING END=====================
+PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p'
+echo ====================PLT RELOCS LD.SO================
+readelf -Wr $RPM_BUILD_ROOT/%{_lib}/ld-*.so | sed -n -e "$PLTCMD"
+echo ====================PLT RELOCS LIBC.SO==============
+readelf -Wr $RPM_BUILD_ROOT/%{_lib}/libc-*.so | sed -n -e "$PLTCMD"
+echo ====================PLT RELOCS END==================
+
+pushd build-%{target}
+LD_SHOW_AUXV=1 elf/ld.so --library-path .:elf:nptl:dlfcn /bin/true
+
+%if %{with valgrind}
+elf/ld.so --library-path .:elf:nptl:dlfcn \
+ /usr/bin/valgrind --error-exitcode=1 \
+ elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/true
+%endif
+popd
+
+%endif # %{run_glibc_tests}
+
+##############################################################################
+# Install and uninstall scripts
+##############################################################################
+%pre -p <lua>
+-- Check that the running kernel is new enough
+required = '%{enablekernel}'
+rel = posix.uname("%r")
+if rpm.vercmp(rel, required) < 0 then
+ error("FATAL: kernel too old", 0)
+end
+
+%post -p <lua>
+-- We use lua's posix.exec because there may be no shell that we can
+-- run during glibc upgrade.
+function post_exec (program, ...)
+ local pid = posix.fork ()
+ if pid == 0 then
+ assert (posix.exec (program, ...))
+ elseif pid > 0 then
+ posix.wait (pid)
+ end
+end
+
+-- (1) Remove multilib libraries from previous installs.
+-- In order to support in-place upgrades, we must immediately remove
+-- obsolete platform directories after installing a new glibc
+-- version. RPM only deletes files removed by updates near the end
+-- of the transaction. If we did not remove the obsolete platform
+-- directories here, they may be preferred by the dynamic linker
+-- during the execution of subsequent RPM scriptlets, likely
+-- resulting in process startup failures.
+
+-- Full set of libraries glibc may install.
+install_libs = { "anl", "BrokenLocale", "c", "dl", "m", "mvec",
+ "nss_compat", "nss_db", "nss_dns", "nss_files",
+ "nss_hesiod", "pthread", "resolv", "rt", "SegFault",
+ "thread_db", "util" }
+
+-- We are going to remove these libraries. Generally speaking we remove
+-- all core libraries in the multilib directory.
+-- We employ a tight match where X.Y is in [2.0,9.9*], so we would
+-- match "libc-2.0.so" and so on up to "libc-9.9*".
+remove_regexps = {}
+for i = 1, #install_libs do
+ remove_regexps[i] = ("lib" .. install_libs[i]
+ .. "%%-[2-9]%%.[0-9]+%%.so$")
+end
+
+-- Two exceptions:
+remove_regexps[#install_libs + 1] = "libthread_db%%-1%%.0%%.so"
+remove_regexps[#install_libs + 2] = "libSegFault%%.so"
+
+-- We are going to search these directories.
+local remove_dirs = { "%{_libdir}/i686",
+ "%{_libdir}/i686/nosegneg" }
+
+-- Walk all the directories with files we need to remove...
+for _, rdir in ipairs (remove_dirs) do
+ if posix.access (rdir) then
+ -- If the directory exists we look at all the files...
+ local remove_files = posix.files (rdir)
+ for rfile in remove_files do
+ for _, rregexp in ipairs (remove_regexps) do
+ -- Does it match the regexp?
+ local dso = string.match (rfile, rregexp)
+ if (dso ~= nil) then
+ -- Removing file...
+ os.remove (rdir .. '/' .. rfile)
+ end
+ end
+ end
+ end
+end
+
+-- (2) Update /etc/ld.so.conf
+-- Next we update /etc/ld.so.conf to ensure that it starts with
+-- a literal "include ld.so.conf.d/*.conf".
+
+local ldsoconf = "/etc/ld.so.conf"
+local ldsoconf_tmp = "/etc/glibc_post_upgrade.ld.so.conf"
+
+if posix.access (ldsoconf) then
+
+ -- We must have a "include ld.so.conf.d/*.conf" line.
+ local have_include = false
+ for line in io.lines (ldsoconf) do
+ -- This must match, and we don't ignore whitespace.
+ if string.match (line, "^include ld.so.conf.d/%%*%%.conf$") ~= nil then
+ have_include = true
+ end
+ end
+
+ if not have_include then
+ -- Insert "include ld.so.conf.d/*.conf" line at the start of the
+ -- file. We only support one of these post upgrades running at
+ -- a time (temporary file name is fixed).
+ local tmp_fd = io.open (ldsoconf_tmp, "w")
+ if tmp_fd ~= nil then
+ tmp_fd:write ("include ld.so.conf.d/*.conf\n")
+ for line in io.lines (ldsoconf) do
+ tmp_fd:write (line .. "\n")
+ end
+ tmp_fd:close ()
+ local res = os.rename (ldsoconf_tmp, ldsoconf)
+ if res == nil then
+ io.stdout:write ("Error: Unable to update configuration file (rename).\n")
+ end
+ else
+ io.stdout:write ("Error: Unable to update configuration file (open).\n")
+ end
+ end
+end
+
+-- (3) Rebuild ld.so.cache early.
+-- If the format of the cache changes then we need to rebuild
+-- the cache early to avoid any problems running binaries with
+-- the new glibc.
+
+-- Note: We use _prefix because Fedora's UsrMove says so.
+post_exec ("%{_prefix}/sbin/ldconfig")
+
+-- (4) Update gconv modules cache.
+-- If the /usr/lib/gconv/gconv-modules.cache exists, then update it
+-- with the latest set of modules that were just installed.
+-- We assume that the cache is in _libdir/gconv and called
+-- "gconv-modules.cache".
+local iconv_dir = "%{_libdir}/gconv"
+local iconv_cache = iconv_dir .. "/gconv-modules.cache"
+if (posix.utime (iconv_cache) == 0) then
+ post_exec ("%{_prefix}/sbin/iconvconfig",
+ "-o", iconv_cache,
+ "--nostdlib",
+ iconv_dir)
+else
+ io.stdout:write ("Error: Missing " .. iconv_cache .. " file.\n")
+end
+
+%pre devel
+# this used to be a link and it is causing nightmares now
+if [ -L %{_prefix}/include/scsi ] ; then
+ rm -f %{_prefix}/include/scsi
+fi
+
+%pre -n nscd
+getent group nscd >/dev/null || /usr/sbin/groupadd -g 28 -r nscd
+getent passwd nscd >/dev/null ||
+ /usr/sbin/useradd -M -o -r -d / -s /sbin/nologin \
+ -c "NSCD Daemon" -u 28 -g nscd nscd
+
+%post -n nscd
+%systemd_post nscd.service
+
+%preun -n nscd
+%systemd_preun nscd.service
+
+%postun -n nscd
+if test $1 = 0; then
+ /usr/sbin/userdel nscd > /dev/null 2>&1 || :
+fi
+%systemd_postun_with_restart nscd.service
+
+##############################################################################
+# Files list
+##############################################################################
+%files -f glibc.filelist
+%dir %{_prefix}/%{_lib}/audit
+%verify(not md5 size mtime) %config(noreplace) /etc/nsswitch.conf
+%verify(not md5 size mtime) %config(noreplace) /etc/ld.so.conf
+%verify(not md5 size mtime) %config(noreplace) /etc/rpc
+%dir /etc/ld.so.conf.d
+%dir %{_prefix}/libexec/getconf
+%dir %{_libdir}/gconv
+%dir %attr(0700,root,root) /var/cache/ldconfig
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/cache/ldconfig/aux-cache
+%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/ld.so.cache
+%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/gai.conf
+%{!?_licensedir:%global license %%doc}
+%license COPYING COPYING.LIB LICENSES
+
+%files -f common.filelist common
+%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %config(missingok,noreplace) %{_prefix}/lib/locale/locale-archive
+%dir %{_prefix}/lib/locale
+%dir %{_prefix}/lib/locale/C.utf8
+%{_prefix}/lib/locale/C.utf8/*
+%{_prefix}/lib/locale/zh_CN.utf8
+%{_prefix}/lib/locale/en_US.utf8
+%{_prefix}/share/locale/zh_CN
+%{_prefix}/share/locale/en_GB
+%dir %attr(755,root,root) /etc/default
+%verify(not md5 size mtime) %config(noreplace) /etc/default/nss
+
+%files -f libc.lang all-langpacks
+%{_prefix}/lib/locale
+%exclude %{_prefix}/lib/locale/locale-archive
+%exclude %{_prefix}/lib/locale/C.utf8
+%exclude %{_prefix}/lib/locale/zh_CN.utf8
+%exclude %{_prefix}/lib/locale/en_US.utf8
+%exclude %{_prefix}/share/locale/zh_CN
+%exclude %{_prefix}/share/locale/en_GB
+
+%files locale-source
+%dir %{_prefix}/share/i18n/locales
+%{_prefix}/share/i18n/locales/*
+%dir %{_prefix}/share/i18n/charmaps
+%{_prefix}/share/i18n/charmaps/*
+
+%files -f devel.filelist devel
+
+%files -f nscd.filelist -n nscd
+%config(noreplace) /etc/nscd.conf
+%dir %attr(0755,root,root) /var/run/nscd
+%dir %attr(0755,root,root) /var/db/nscd
+/lib/systemd/system/nscd.service
+/lib/systemd/system/nscd.socket
+%{_tmpfilesdir}/nscd.conf
+%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/nscd.pid
+%attr(0666,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/socket
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/passwd
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/group
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/hosts
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/run/nscd/services
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/passwd
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/group
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/hosts
+%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/db/nscd/services
+%ghost %config(missingok,noreplace) /etc/sysconfig/nscd
+
+%files -f nss_modules.filelist -n nss_modules
+/var/db/Makefile
+
+%files -f nss-devel.filelist nss-devel
+
+%files -f libnsl.filelist -n libnsl
+/%{_lib}/libnsl.so.1
+
+%files -f debugutils.filelist debugutils
+
+%if %{with benchtests}
+%files -f benchtests.filelist benchtests
+%endif
+
+%if 0%{?_enable_debug_packages}
+%files -f debuginfo.filelist debuginfo
+
+%files debugsource
+%endif
+
+
+%files help
+#Doc of glibc package
+%doc README NEWS INSTALL elf/rtld-debugger-interface.txt
+#Doc of common sub-package
+%doc documentation/README.timezone
+%doc documentation/gai.conf
+#Doc of nss_modules sub-package
+%doc hesiod/README.hesiod
+
+%changelog
+* Sat Mar 20 2021 xuhuijie <xuhuijie@huawei.com> - 2.31-10
+- semctl: SEM_STAT_ANY fails to pass the buffer specified by
+ the caller to the kernel [BZ #26637]
+ https://sourceware.org/bugzilla/show_bug.cgi?id=26637
+
+* Tue Jan 26 2021 shanzhikun <shanzhikun@huawei.com> - 2.31-9
+- elf: Allow dlopen of filter object to work [BZ #16272]
+ https://sourceware.org/bugzilla/show_bug.cgi?id=16272
+
+* Fri Jan 8 2021 Wang Shuo<wangshuo_1994@foxmail.com> - 2.31-8
+- Replace "openEuler" by %{_vendor} for versatility
+
+* Tue Nov 10 2020 liusirui <liusirui@huawei.com> - 2.31-7
+- Fix CVE-2020-27618, iconv accept redundant shift sequences in IBM1364 [BZ #26224]
+ https://sourceware.org/bugzilla/show_bug.cgi?id=26224
+
+* Tue Sep 15 2020 shanzhikun<shanzhikun@huawei.com> - 2.31-6
+- rtld: Avoid using up static TLS surplus for optimizations [BZ #25051].
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=ffb17e7ba3a5ba9632cee97330b325072fbe41dd
+
+* Fri Sep 4 2020 MarsChan<chenmingmin@huawei.com> - 2.31-5
+- For political reasons, remove country selection from tzselect.ksh
+
+* Fri Aug 14 2020 Xu Huijie<546391727@qq.com> - 2.31-4
+- since the new version of the pthread_cond_wait()
+ function has performance degradation in multi-core
+ scenarios, here is an extra libpthreadcond.so using
+ old version of the function. you can use it by adding
+ LD_PRELOAD=./libpthreadcond.so in front of your program
+ (eg: LD_PRELOAD=./libpthreadcond.so ./test).
+ use with-libpthreadcond to compile it.
+ warning:2.17 version pthread_cond_wait() does not meet
+ the posix standard, you should pay attention when using
+ it.
+
+* Fri Jul 24 2020 Wang Shuo<wangshuo_1994@foxmail.com> - 2.31-3
+- backport patch to disable warnings due to deprecated libselinux
+- symbols used by nss and nscd
+
+* Fri Jul 24 2020 Wang Shuo<wangshuo_1994@foxmail.com> - 2.31-2
+- fix CVE-2020-6096
+- fix bugzilla 26137, 26214 and 26215
+
+* Thu Jul 9 2020 wuxu<wuxu.wu@hotmail.com> - 2.31-1
+- upgrade glibc to 2.31-1
+- delete build-locale-archive command
+- delete nsswitch.conf file
+- replace glibc_post_upgrade function with lua
+- remove sys/sysctl.h header file
+- delete stime, ftime function
+
+* Tue Jul 7 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-45
+- disable rpc, it has been splited to libnss and libtirpc
+- disable parallel compilation
+
+* Tue Jul 7 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-44
+- backup to version 40
+
+* Mon Jul 6 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-43
+- disable rpc, it has been splited to libnss and libtirpc
+- disable parallel compilation
+
+* Mon Jul 6 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-42
+- add zh and en to LanguageList
+
+* Thu Jul 2 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-41
+- add filelist to improve the scalability
+- backport many patch for bugfix
+
+* Sat May 30 2020 liqingqing<liqignqing3@huawei.com> - 2.28-40
+- Fix array overflow in backtrace on PowerPC (bug 25423)
+
+* Thu May 28 2020 jdkboy<guoge1@huawei.com> - 2.28-39
+- Disable compilation warnings temporarily
+
+* Tue Apr 28 2020 liqingqing<liqignqing3@huawei.com> - 2.28-38
+- Avoid ldbl-96 stack corruption from range reduction of pseudo-zero (bug 25487)
+
+* Thu Apr 16 2020 wangbin<wangbin224@huawei.com> - 2.28-37
+- backport Kunpeng patches
+
+* Thu Mar 19 2020 yuxiangyang<yuxiangyang4@huawei.com> - 2.28-36
+- fix build src.rpm error
+
+* Fri Mar 13 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-35
+- exclude conflict files about rpc
+
+* Fri Mar 13 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-34
+- enable obsolete rpc
+
+* Tue Mar 10 2020 liqingqing<liqingqing3@huawei.com> - 2.28-33
+- fix use after free in glob when expanding user bug
+
+* Wed Feb 26 2020 Wang Shuo<wangshuo47@huawei.com> - 2.28-32
+- remove aditional require for debugutils package
+
+* Tue Jan 7 2020 Wang Shuo <wangshuo47@huawei.com> - 2.28-31
+- Fix compile macro
+
+* Mon Jan 6 2020 Wang Shuo <wangshuo47@huawei.com> - 2.28-30
+- add obsoletes symbol for language
+
+* Fri Dec 20 2019 liqingqing <liqingqing3@huawei.com> - 2.28-29
+- remove country selection from tzselect
+- fix some bugs https://sourceware.org/git/?p=glibc.git;a=commit;h=1df872fd74f730bcae3df201a229195445d2e18a
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=823624bdc47f1f80109c9c52dee7939b9386d708
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=bc10e22c90e42613bd5dafb77b80a9ea1759dd1b
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=6c29942cbf059aca47fd4bbd852ea42c9d46b71f
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=31effacee2fc1b327bedc9a5fcb4b83f227c6539
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=5b06f538c5aee0389ed034f60d90a8884d6d54de
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=57ada43c905eec7ba28fe60a08b93a52d88e26c1
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=e0e4c321c3145b6ac0e8f6e894f87790cf9437ce
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=182a3746b8cc28784718c8ea27346e97d1423945
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=02d8b5ab1c89bcef2627d2b621bfb35b573852c2
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=f59a54ab0c2dcaf9ee946df2bfee9d4be81f09b8
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=fefa21790b5081e5d04662a240e2efd18603ef86
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=2bd81b60d6ffdf7e0d22006d69f4b812b1c80513
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=a55541fd1c4774d483c2d2b4bd17bcb9faac62e7
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=b6d2c4475d5abc05dd009575b90556bdd3c78ad0
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=8a80ee5e2bab17a1f8e1e78fab5c33ac7efa8b29
+ https://sourceware.org/git/?p=glibc.git;a=commit;h=c0fd3244e71db39cef1e2d1d8ba12bb8b7375ce4
+- fix CVE-2016-10739 CVE-2019-19126 CVE-2019-6488
+- add pie compile option for debug/Makefile and remove -static for build-locale-archive
+
+* Fri Dec 20 2019 liusirui <liusirui@huawei.com> - 2.28-28
+- Fix null pointer in mtrace
+
+* Thu Nov 21 2019 mengxian <mengxian@huawei.com> - 2.28-27
+- In x86, configure static pie and cet only with gcc 8 or above
+
+* Wed Nov 13 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.28-26
+- Optimized instructions for Kunpeng processor
+
+* Fri Jan 18 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.28-25
+- Package init
diff --git a/nptl-Don-t-madvise-user-provided-stack.patch b/nptl-Don-t-madvise-user-provided-stack.patch
new file mode 100644
index 0000000..41937de
--- /dev/null
+++ b/nptl-Don-t-madvise-user-provided-stack.patch
@@ -0,0 +1,41 @@
+From 087942251f26d5fd5802b8d14e47d460263a0c4d Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date: Wed, 24 Jun 2020 07:47:15 +0100
+Subject: [PATCH] nptl: Don't madvise user provided stack
+
+User provided stack should not be released nor madvised at
+thread exit because it's owned by the user.
+
+If the memory is shared or file based then MADV_DONTNEED
+can have unwanted effects. With memory tagging on aarch64
+linux the tags are dropped and thus it may invalidate
+pointers.
+
+Tested on aarch64-linux-gnu with MTE, it fixes
+
+FAIL: nptl/tst-stack3
+FAIL: nptl/tst-stack3-mem
+
+---
+ nptl/pthread_create.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
+index 179f07a1..00931c19 100644
+--- a/nptl/pthread_create.c
++++ b/nptl/pthread_create.c
+@@ -564,8 +564,9 @@ START_THREAD_DEFN
+ }
+ #endif
+
+- advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
+- pd->guardsize);
++ if (!pd->user_stack)
++ advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
++ pd->guardsize);
+
+ if (__glibc_unlikely (pd->cancelhandling & SETXID_BITMASK))
+ {
+--
+2.19.1
+
diff --git a/nptl-wait-for-pending-setxid-request-also-in-detache.patch b/nptl-wait-for-pending-setxid-request-also-in-detache.patch
new file mode 100644
index 0000000..604e0b7
--- /dev/null
+++ b/nptl-wait-for-pending-setxid-request-also-in-detache.patch
@@ -0,0 +1,52 @@
+From 4cab20fa49b3ea3e3454fdc4f13bf3828d8efd19 Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Thu, 7 May 2020 15:50:09 +0200
+Subject: [PATCH] nptl: wait for pending setxid request also in detached thread
+ (bug 25942)
+
+There is a race between __nptl_setxid and exiting detached thread, which
+causes a deadlock on stack_cache_lock. The deadlock happens in this
+state:
+
+T1: setgroups -> __nptl_setxid (holding stack_cache_lock, waiting on cmdp->cntr == 0)
+T2 (detached, exiting): start_thread -> __deallocate_stack (waiting on stack_cache_lock)
+more threads waiting on stack_cache_lock in pthread_create
+
+For non-detached threads, start_thread waits for its own setxid handler to
+finish before exiting. Do this for detached threads as well.
+---
+ nptl/pthread_create.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
+index afd379e89a..a43089065c 100644
+--- a/nptl/pthread_create.c
++++ b/nptl/pthread_create.c
+@@ -567,11 +567,7 @@ START_THREAD_DEFN
+ advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
+ pd->guardsize);
+
+- /* If the thread is detached free the TCB. */
+- if (IS_DETACHED (pd))
+- /* Free the TCB. */
+- __free_tcb (pd);
+- else if (__glibc_unlikely (pd->cancelhandling & SETXID_BITMASK))
++ if (__glibc_unlikely (pd->cancelhandling & SETXID_BITMASK))
+ {
+ /* Some other thread might call any of the setXid functions and expect
+ us to reply. In this case wait until we did that. */
+@@ -587,6 +583,11 @@ START_THREAD_DEFN
+ pd->setxid_futex = 0;
+ }
+
++ /* If the thread is detached free the TCB. */
++ if (IS_DETACHED (pd))
++ /* Free the TCB. */
++ __free_tcb (pd);
++
+ /* We cannot call '_exit' here. '_exit' will terminate the process.
+
+ The 'exit' implementation in the kernel will signal when the
+--
+2.19.1
+
diff --git a/nscd.conf b/nscd.conf
new file mode 100644
index 0000000..8a24a78
--- /dev/null
+++ b/nscd.conf
@@ -0,0 +1 @@
+d /run/nscd 0755 root root
diff --git a/nsswitch.conf b/nsswitch.conf
new file mode 100644
index 0000000..b49a3b2
--- /dev/null
+++ b/nsswitch.conf
@@ -0,0 +1,56 @@
+#
+# /etc/nsswitch.conf
+#
+# An example Name Service Switch config file. This file should be
+# sorted with the most-used services at the beginning.
+#
+# The entry '[NOTFOUND=return]' means that the search for an
+# entry should stop if the search in the previous entry turned
+# up nothing. Note that if the search failed due to some other reason
+# (like no NIS server responding) then the search continues with the
+# next entry.
+#
+# Valid entries include:
+#
+# nisplus Use NIS+ (NIS version 3)
+# nis Use NIS (NIS version 2), also called YP
+# dns Use DNS (Domain Name Service)
+# files Use the local files in /etc
+# db Use the pre-processed /var/db files
+# compat Use /etc files plus *_compat pseudo-databases
+# hesiod Use Hesiod (DNS) for user lookups
+# sss Use sssd (System Security Services Daemon)
+# [NOTFOUND=return] Stop searching if not found so far
+#
+# 'sssd' performs its own 'files'-based caching, so it should
+# generally come before 'files'.
+
+# To use 'db', install the nss_db package, and put the 'db' in front
+# of 'files' for entries you want to be looked up first in the
+# databases, like this:
+#
+# passwd: db files
+# shadow: db files
+# group: db files
+
+passwd: sss files
+shadow: files sss
+group: sss files
+
+hosts: files dns myhostname
+
+bootparams: files
+
+ethers: files
+netmasks: files
+networks: files
+protocols: files
+rpc: files
+services: files sss
+
+netgroup: sss
+
+publickey: files
+
+automount: files sss
+aliases: files
diff --git a/remove-country-selection-from-tzselect.patch b/remove-country-selection-from-tzselect.patch
new file mode 100644
index 0000000..5b00087
--- /dev/null
+++ b/remove-country-selection-from-tzselect.patch
@@ -0,0 +1,151 @@
+From dff0000cc458d6d4993b821f2badcf31ea28062e Mon Sep 17 00:00:00 2001
+From: MarsChan <cmm8293@163.com>
+Date: Sun, 6 Sep 2020 09:42:44 +0800
+Subject: [PATCH] remove country selection from tzselect.ksh
+
+---
+ timezone/tzselect.ksh | 98 +++++++++----------------------------------
+ 1 file changed, 20 insertions(+), 78 deletions(-)
+
+diff --git a/timezone/tzselect.ksh b/timezone/tzselect.ksh
+index 18fce27e..7e31798c 100755
+--- a/timezone/tzselect.ksh
++++ b/timezone/tzselect.ksh
+@@ -51,7 +51,7 @@ say() {
+
+ coord=
+ location_limit=10
+-zonetabtype=zone1970
++zonetabtype=zone
+
+ usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT]
+ Select a timezone interactively.
+@@ -398,94 +398,37 @@ while
+ '`
+ ;;
+ *)
+- # Get list of names of countries in the continent or ocean.
+- countries=`$AWK \
++ # Get list of regions in the continent or ocean.
++ timezones=`$AWK \
+ -v continent="$continent" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ BEGIN { FS = "\t" }
+ /^#/ { next }
+ $3 ~ ("^" continent "/") {
+- ncc = split($1, cc, /,/)
++ ncc = split($3, cc, /,/)
+ for (i = 1; i <= ncc; i++)
+ if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
+ }
+ END {
+- while (getline <TZ_COUNTRY_TABLE) {
+- if ($0 !~ /^#/) cc_name[$1] = $2
+- }
+ for (i = 1; i <= ccs; i++) {
+- country = cc_list[i]
+- if (cc_name[country]) {
+- country = cc_name[country]
+- }
+- print country
++ print cc_list[i]
+ }
+ }
+ ' <"$TZ_ZONE_TABLE" | sort -f`
+-
+-
+- # If there's more than one country, ask the user which one.
+- case $countries in
+- *"$newline"*)
+- echo >&2 'Please select a country' \
+- 'whose clocks agree with yours.'
+- doselect $countries
+- country=$select_result;;
+- *)
+- country=$countries
+- esac
+-
+-
+- # Get list of timezones in the country.
+- regions=`$AWK \
+- -v country="$country" \
+- -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+- '
+- BEGIN {
+- FS = "\t"
+- cc = country
+- while (getline <TZ_COUNTRY_TABLE) {
+- if ($0 !~ /^#/ && country == $2) {
+- cc = $1
+- break
+- }
+- }
+- }
+- /^#/ { next }
+- $1 ~ cc { print $4 }
+- ' <"$TZ_ZONE_TABLE"`
+-
+-
+- # If there's more than one region, ask the user which one.
+- case $regions in
+- *"$newline"*)
+- echo >&2 'Please select one of the following timezones.'
+- doselect $regions
+- region=$select_result;;
+- *)
+- region=$regions
+- esac
++ regions=[]
++ index=0
++ for item in $timezones; do
++ regions[$index]=`echo $item | awk -F '/' '{print $2}'`
++ index=$(($index+1))
++ done
++ echo >&2 'Please select a timezone' \
++ 'whose clocks agree with yours.'
++ doselect ${regions[@]}
++ region=$select_result
+
+ # Determine TZ from country and region.
+- TZ=`$AWK \
+- -v country="$country" \
+- -v region="$region" \
+- -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+- '
+- BEGIN {
+- FS = "\t"
+- cc = country
+- while (getline <TZ_COUNTRY_TABLE) {
+- if ($0 !~ /^#/ && country == $2) {
+- cc = $1
+- break
+- }
+- }
+- }
+- /^#/ { next }
+- $1 ~ cc && $4 == region { print $3 }
+- ' <"$TZ_ZONE_TABLE"`
++ TZ=$continent/$region
+ esac
+
+ # Make sure the corresponding zoneinfo file exists.
+@@ -523,11 +466,10 @@ Universal Time is now: $UTdate."
+ echo >&2 ""
+ echo >&2 "The following information has been given:"
+ echo >&2 ""
+- case $country%$region%$coord in
+- ?*%?*%) say >&2 " $country$newline $region";;
+- ?*%%) say >&2 " $country";;
+- %?*%?*) say >&2 " coord $coord$newline $region";;
+- %%?*) say >&2 " coord $coord";;
++ case $region%$coord in
++ ?*%) say >&2 " $region";;
++ ?*%?*) say >&2 " coord $coord$newline $region";;
++ %?*) say >&2 " coord $coord";;
+ *) say >&2 " TZ='$TZ'"
+ esac
+ say >&2 ""
+--
+2.24.3 (Apple Git-128)
+
diff --git a/rtld-Avoid-using-up-static-TLS-surplus-for-optimizat.patch b/rtld-Avoid-using-up-static-TLS-surplus-for-optimizat.patch
new file mode 100644
index 0000000..d70be0b
--- /dev/null
+++ b/rtld-Avoid-using-up-static-TLS-surplus-for-optimizat.patch
@@ -0,0 +1,586 @@
+From ffb17e7ba3a5ba9632cee97330b325072fbe41dd Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date: Wed, 10 Jun 2020 13:40:40 +0100
+Subject: [PATCH] rtld: Avoid using up static TLS surplus for optimizations [BZ
+ #25051]
+
+On some targets static TLS surplus area can be used opportunistically
+for dynamically loaded modules such that the TLS access then becomes
+faster (TLSDESC and powerpc TLS optimization). However we don't want
+all surplus TLS to be used for this optimization because dynamically
+loaded modules with initial-exec model TLS can only use surplus TLS.
+
+The new contract for surplus static TLS use is:
+
+- libc.so can have up to 192 bytes of IE TLS,
+- other system libraries together can have up to 144 bytes of IE TLS.
+- Some "optional" static TLS is available for opportunistic use.
+
+The optional TLS is now tunable: rtld.optional_static_tls, so users
+can directly affect the allocated static TLS size. (Note that module
+unloading with dlclose does not reclaim static TLS. After the optional
+TLS runs out, TLS access is no longer optimized to use static TLS.)
+
+The default setting of rtld.optional_static_tls is 512 so the surplus
+TLS is 3*192 + 4*144 + 512 = 1664 by default, the same as before.
+
+Fixes BZ #25051.
+
+Tested on aarch64-linux-gnu and x86_64-linux-gnu.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+---
+ csu/libc-tls.c | 3 ++
+ elf/Makefile | 29 +++++++++++-
+ elf/dl-reloc.c | 37 +++++++++++----
+ elf/dl-tls.c | 9 ++--
+ elf/dl-tunables.list | 5 ++
+ elf/dynamic-link.h | 5 +-
+ elf/tst-tls-ie-dlmopen.c | 112 +++++++++++++++++++++++++++++++++++++++++++++
+ elf/tst-tls-ie-mod.h | 40 ++++++++++++++++
+ elf/tst-tls-ie-mod0.c | 4 ++
+ elf/tst-tls-ie-mod1.c | 4 ++
+ elf/tst-tls-ie-mod2.c | 4 ++
+ elf/tst-tls-ie-mod3.c | 4 ++
+ elf/tst-tls-ie-mod4.c | 4 ++
+ elf/tst-tls-ie-mod5.c | 4 ++
+ elf/tst-tls-ie-mod6.c | 4 ++
+ elf/tst-tls-ie.c | 111 ++++++++++++++++++++++++++++++++++++++++++++
+ manual/tunables.texi | 17 +++++++
+ sysdeps/generic/ldsodefs.h | 3 ++
+ 18 files changed, 382 insertions(+), 17 deletions(-)
+ create mode 100644 elf/tst-tls-ie-dlmopen.c
+ create mode 100644 elf/tst-tls-ie-mod.h
+ create mode 100644 elf/tst-tls-ie-mod0.c
+ create mode 100644 elf/tst-tls-ie-mod1.c
+ create mode 100644 elf/tst-tls-ie-mod2.c
+ create mode 100644 elf/tst-tls-ie-mod3.c
+ create mode 100644 elf/tst-tls-ie-mod4.c
+ create mode 100644 elf/tst-tls-ie-mod5.c
+ create mode 100644 elf/tst-tls-ie-mod6.c
+ create mode 100644 elf/tst-tls-ie.c
+
+diff --git a/csu/libc-tls.c b/csu/libc-tls.c
+index 28a7944..1b68d71 100644
+--- a/csu/libc-tls.c
++++ b/csu/libc-tls.c
+@@ -59,6 +59,9 @@ size_t _dl_tls_static_size = 2048;
+ size_t _dl_tls_static_used;
+ /* Alignment requirement of the static TLS block. */
+ size_t _dl_tls_static_align;
++/* Remaining amount of static TLS that may be used for optimizing
++ dynamic TLS access (e.g. with TLSDESC). */
++size_t _dl_tls_static_optional = 512;
+
+ /* Generation counter for the dtv. */
+ size_t _dl_tls_generation;
+diff --git a/elf/Makefile b/elf/Makefile
+index 632a4d8..f440488 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -201,7 +201,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
+ tst-unwind-ctor tst-unwind-main tst-audit13 \
+ tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \
+ tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \
+- tst-dlopenfail-2
++ tst-dlopenfail-2 \
++ tst-tls-ie tst-tls-ie-dlmopen
+ # reldep9
+ tests-internal += loadtest unload unload2 circleload1 \
+ neededtest neededtest2 neededtest3 neededtest4 \
+@@ -312,7 +313,10 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \
+ tst-initlazyfailmod tst-finilazyfailmod \
+ tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \
+- tst-dlopenfailmod3 tst-ldconfig-ld-mod
++ tst-dlopenfailmod3 tst-ldconfig-ld-mod \
++ tst-tls-ie-mod0 tst-tls-ie-mod1 tst-tls-ie-mod2 \
++ tst-tls-ie-mod3 tst-tls-ie-mod4 tst-tls-ie-mod5 \
++ tst-tls-ie-mod6
+ # Most modules build with _ISOMAC defined, but those filtered out
+ # depend on internal headers.
+ modules-names-tests = $(filter-out ifuncmod% tst-libc_dlvsym-dso tst-tlsmod%,\
+@@ -1699,3 +1703,23 @@ LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed
+
+ $(objpfx)tst-ldconfig-ld_so_conf-update.out: $(objpfx)tst-ldconfig-ld-mod.so
+ $(objpfx)tst-ldconfig-ld_so_conf-update: $(libdl)
++
++$(objpfx)tst-tls-ie: $(libdl) $(shared-thread-library)
++$(objpfx)tst-tls-ie.out: \
++ $(objpfx)tst-tls-ie-mod0.so \
++ $(objpfx)tst-tls-ie-mod1.so \
++ $(objpfx)tst-tls-ie-mod2.so \
++ $(objpfx)tst-tls-ie-mod3.so \
++ $(objpfx)tst-tls-ie-mod4.so \
++ $(objpfx)tst-tls-ie-mod5.so \
++ $(objpfx)tst-tls-ie-mod6.so
++
++$(objpfx)tst-tls-ie-dlmopen: $(libdl) $(shared-thread-library)
++$(objpfx)tst-tls-ie-dlmopen.out: \
++ $(objpfx)tst-tls-ie-mod0.so \
++ $(objpfx)tst-tls-ie-mod1.so \
++ $(objpfx)tst-tls-ie-mod2.so \
++ $(objpfx)tst-tls-ie-mod3.so \
++ $(objpfx)tst-tls-ie-mod4.so \
++ $(objpfx)tst-tls-ie-mod5.so \
++ $(objpfx)tst-tls-ie-mod6.so
+diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
+index ffcc84d..6d32e49 100644
+--- a/elf/dl-reloc.c
++++ b/elf/dl-reloc.c
+@@ -39,13 +39,16 @@
+ /* We are trying to perform a static TLS relocation in MAP, but it was
+ dynamically loaded. This can only work if there is enough surplus in
+ the static TLS area already allocated for each running thread. If this
+- object's TLS segment is too big to fit, we fail. If it fits,
+- we set MAP->l_tls_offset and return.
+- This function intentionally does not return any value but signals error
+- directly, as static TLS should be rare and code handling it should
+- not be inlined as much as possible. */
++ object's TLS segment is too big to fit, we fail with -1. If it fits,
++ we set MAP->l_tls_offset and return 0.
++ A portion of the surplus static TLS can be optionally used to optimize
++ dynamic TLS access (with TLSDESC or powerpc TLS optimizations).
++ If OPTIONAL is true then TLS is allocated for such optimization and
++ the caller must have a fallback in case the optional portion of surplus
++ TLS runs out. If OPTIONAL is false then the entire surplus TLS area is
++ considered and the allocation only fails if that runs out. */
+ int
+-_dl_try_allocate_static_tls (struct link_map *map)
++_dl_try_allocate_static_tls (struct link_map *map, bool optional)
+ {
+ /* If we've already used the variable with dynamic access, or if the
+ alignment requirements are too high, fail. */
+@@ -68,8 +71,14 @@ _dl_try_allocate_static_tls (struct link_map *map)
+
+ size_t n = (freebytes - blsize) / map->l_tls_align;
+
+- size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
+- - map->l_tls_firstbyte_offset);
++ /* Account optional static TLS surplus usage. */
++ size_t use = freebytes - n * map->l_tls_align - map->l_tls_firstbyte_offset;
++ if (optional && use > GL(dl_tls_static_optional))
++ goto fail;
++ else if (optional)
++ GL(dl_tls_static_optional) -= use;
++
++ size_t offset = GL(dl_tls_static_used) + use;
+
+ map->l_tls_offset = GL(dl_tls_static_used) = offset;
+ #elif TLS_DTV_AT_TP
+@@ -83,6 +92,13 @@ _dl_try_allocate_static_tls (struct link_map *map)
+ if (used > GL(dl_tls_static_size))
+ goto fail;
+
++ /* Account optional static TLS surplus usage. */
++ size_t use = used - GL(dl_tls_static_used);
++ if (optional && use > GL(dl_tls_static_optional))
++ goto fail;
++ else if (optional)
++ GL(dl_tls_static_optional) -= use;
++
+ map->l_tls_offset = offset;
+ map->l_tls_firstbyte_offset = GL(dl_tls_static_used);
+ GL(dl_tls_static_used) = used;
+@@ -110,12 +126,15 @@ _dl_try_allocate_static_tls (struct link_map *map)
+ return 0;
+ }
+
++/* This function intentionally does not return any value but signals error
++ directly, as static TLS should be rare and code handling it should
++ not be inlined as much as possible. */
+ void
+ __attribute_noinline__
+ _dl_allocate_static_tls (struct link_map *map)
+ {
+ if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
+- || _dl_try_allocate_static_tls (map))
++ || _dl_try_allocate_static_tls (map, false))
+ {
+ _dl_signal_error (0, map->l_name, NULL, N_("\
+ cannot allocate memory in static TLS block"));
+diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
+index bb7a66f..6727233 100644
+--- a/elf/dynamic-link.h
++++ b/elf/dynamic-link.h
+@@ -40,9 +40,10 @@
+ (__builtin_expect ((sym_map)->l_tls_offset \
+ != FORCED_DYNAMIC_TLS_OFFSET, 1) \
+ && (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET, 1) \
+- || _dl_try_allocate_static_tls (sym_map) == 0))
++ || _dl_try_allocate_static_tls (sym_map, true) == 0))
+
+-int _dl_try_allocate_static_tls (struct link_map *map) attribute_hidden;
++int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
++ attribute_hidden;
+
+ #include <elf.h>
+
+diff --git a/elf/tst-tls-ie-dlmopen.c b/elf/tst-tls-ie-dlmopen.c
+new file mode 100644
+index 0000000..c7b5c68
+--- /dev/null
++++ b/elf/tst-tls-ie-dlmopen.c
+@@ -0,0 +1,112 @@
++/* Test dlopen of modules with initial-exec TLS after dlmopen.
++ Copyright (C) 2016-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++/* This test tries to check that surplus static TLS is not used up for
++ dynamic TLS optimizations and 4*144 = 576 bytes of static TLS is
++ still available for dlopening modules with initial-exec TLS after 3
++ new dlmopen namespaces are created. It depends on rtld.nns=4 and
++ rtld.optional_static_tls=512 tunable settings. */
++
++#include <errno.h>
++#include <pthread.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++static int do_test (void);
++#include <support/xthread.h>
++#include <support/xdlfcn.h>
++#include <support/check.h>
++#include <support/test-driver.c>
++
++/* Have some big TLS in the main exe: should not use surplus TLS. */
++__thread char maintls[1000];
++
++static pthread_barrier_t barrier;
++
++/* Forces multi-threaded behaviour. */
++static void *
++blocked_thread_func (void *closure)
++{
++ xpthread_barrier_wait (&barrier);
++ /* TLS load and access tests run here in the main thread. */
++ xpthread_barrier_wait (&barrier);
++ return NULL;
++}
++
++static void *
++load_and_access (Lmid_t lmid, const char *mod, const char *func)
++{
++ /* Load module with TLS. */
++ void *p = xdlmopen (lmid, mod, RTLD_NOW);
++ /* Access the TLS variable to ensure it is allocated. */
++ void (*f) (void) = (void (*) (void))xdlsym (p, func);
++ f ();
++ return p;
++}
++
++static int
++do_test (void)
++{
++ void *mods[5];
++
++ {
++ int ret = pthread_barrier_init (&barrier, NULL, 2);
++ if (ret != 0)
++ {
++ errno = ret;
++ printf ("error: pthread_barrier_init: %m\n");
++ exit (1);
++ }
++ }
++
++ pthread_t blocked_thread = xpthread_create (NULL, blocked_thread_func, NULL);
++ xpthread_barrier_wait (&barrier);
++
++ printf ("maintls[%zu]:\t %p .. %p\n",
++ sizeof maintls, maintls, maintls + sizeof maintls);
++ memset (maintls, 1, sizeof maintls);
++
++ /* Load modules with dynamic TLS (use surplus static TLS for libc
++ in new namespaces and may be for TLS optimizations too). */
++ mods[0] = load_and_access (LM_ID_BASE, "tst-tls-ie-mod0.so", "access0");
++ mods[1] = load_and_access (LM_ID_NEWLM, "tst-tls-ie-mod1.so", "access1");
++ mods[2] = load_and_access (LM_ID_NEWLM, "tst-tls-ie-mod2.so", "access2");
++ mods[3] = load_and_access (LM_ID_NEWLM, "tst-tls-ie-mod3.so", "access3");
++ /* Load modules with initial-exec TLS (can only use surplus static TLS). */
++ mods[4] = load_and_access (LM_ID_BASE, "tst-tls-ie-mod6.so", "access6");
++
++ /* Here 576 bytes + 3 * libc use of surplus static TLS is in use so less
++ than 1024 bytes are available (exact number depends on TLS optimizations
++ and the libc TLS use). */
++ printf ("The next dlmopen should fail...\n");
++ void *p = dlmopen (LM_ID_BASE, "tst-tls-ie-mod4.so", RTLD_NOW);
++ if (p != NULL)
++ FAIL_EXIT1 ("error: expected dlmopen to fail because there is "
++ "not enough surplus static TLS.\n");
++ printf ("...OK failed with: %s.\n", dlerror ());
++
++ xpthread_barrier_wait (&barrier);
++ xpthread_join (blocked_thread);
++
++ /* Close the modules. */
++ for (int i = 0; i < 5; ++i)
++ xdlclose (mods[i]);
++
++ return 0;
++}
+diff --git a/elf/tst-tls-ie-mod.h b/elf/tst-tls-ie-mod.h
+new file mode 100644
+index 0000000..46b362a
+--- /dev/null
++++ b/elf/tst-tls-ie-mod.h
+@@ -0,0 +1,40 @@
++/* Module with specified TLS size and model.
++ Copyright (C) 2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++/* This file is parameterized by macros N, SIZE and MODEL. */
++
++#include <stdio.h>
++#include <string.h>
++
++#define CONCATX(x, y) x ## y
++#define CONCAT(x, y) CONCATX (x, y)
++#define STRX(x) #x
++#define STR(x) STRX (x)
++
++#define VAR CONCAT (var, N)
++
++__attribute__ ((aligned (8), tls_model (MODEL)))
++__thread char VAR[SIZE];
++
++void
++CONCAT (access, N) (void)
++{
++ printf (STR (VAR) "[%d]:\t %p .. %p " MODEL "\n", SIZE, VAR, VAR + SIZE);
++ fflush (stdout);
++ memset (VAR, 1, SIZE);
++}
+diff --git a/elf/tst-tls-ie-mod0.c b/elf/tst-tls-ie-mod0.c
+new file mode 100644
+index 0000000..2450686
+--- /dev/null
++++ b/elf/tst-tls-ie-mod0.c
+@@ -0,0 +1,4 @@
++#define N 0
++#define SIZE 480
++#define MODEL "global-dynamic"
++#include "tst-tls-ie-mod.h"
+diff --git a/elf/tst-tls-ie-mod1.c b/elf/tst-tls-ie-mod1.c
+new file mode 100644
+index 0000000..849ff91
+--- /dev/null
++++ b/elf/tst-tls-ie-mod1.c
+@@ -0,0 +1,4 @@
++#define N 1
++#define SIZE 120
++#define MODEL "global-dynamic"
++#include "tst-tls-ie-mod.h"
+diff --git a/elf/tst-tls-ie-mod2.c b/elf/tst-tls-ie-mod2.c
+new file mode 100644
+index 0000000..23915ab
+--- /dev/null
++++ b/elf/tst-tls-ie-mod2.c
+@@ -0,0 +1,4 @@
++#define N 2
++#define SIZE 24
++#define MODEL "global-dynamic"
++#include "tst-tls-ie-mod.h"
+diff --git a/elf/tst-tls-ie-mod3.c b/elf/tst-tls-ie-mod3.c
+new file mode 100644
+index 0000000..5395f84
+--- /dev/null
++++ b/elf/tst-tls-ie-mod3.c
+@@ -0,0 +1,4 @@
++#define N 3
++#define SIZE 16
++#define MODEL "global-dynamic"
++#include "tst-tls-ie-mod.h"
+diff --git a/elf/tst-tls-ie-mod4.c b/elf/tst-tls-ie-mod4.c
+new file mode 100644
+index 0000000..93ac2ea
+--- /dev/null
++++ b/elf/tst-tls-ie-mod4.c
+@@ -0,0 +1,4 @@
++#define N 4
++#define SIZE 1024
++#define MODEL "initial-exec"
++#include "tst-tls-ie-mod.h"
+diff --git a/elf/tst-tls-ie-mod5.c b/elf/tst-tls-ie-mod5.c
+new file mode 100644
+index 0000000..84b3fd2
+--- /dev/null
++++ b/elf/tst-tls-ie-mod5.c
+@@ -0,0 +1,4 @@
++#define N 5
++#define SIZE 128
++#define MODEL "initial-exec"
++#include "tst-tls-ie-mod.h"
+diff --git a/elf/tst-tls-ie-mod6.c b/elf/tst-tls-ie-mod6.c
+new file mode 100644
+index 0000000..c736bf0
+--- /dev/null
++++ b/elf/tst-tls-ie-mod6.c
+@@ -0,0 +1,4 @@
++#define N 6
++#define SIZE 576
++#define MODEL "initial-exec"
++#include "tst-tls-ie-mod.h"
+diff --git a/elf/tst-tls-ie.c b/elf/tst-tls-ie.c
+new file mode 100644
+index 0000000..2dc0894
+--- /dev/null
++++ b/elf/tst-tls-ie.c
+@@ -0,0 +1,111 @@
++/* Test dlopen of modules with initial-exec TLS.
++ Copyright (C) 2016-2020 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++/* This test tries to check that surplus static TLS is not used up for
++ dynamic TLS optimizations and 3*192 + 4*144 = 1152 bytes of static
++ TLS is available for dlopening modules with initial-exec TLS. It
++ depends on rtld.nns=4 and rtld.optional_static_tls=512 tunable setting. */
++
++#include <errno.h>
++#include <pthread.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++static int do_test (void);
++#include <support/xthread.h>
++#include <support/xdlfcn.h>
++#include <support/check.h>
++#include <support/test-driver.c>
++
++/* Have some big TLS in the main exe: should not use surplus TLS. */
++__thread char maintls[1000];
++
++static pthread_barrier_t barrier;
++
++/* Forces multi-threaded behaviour. */
++static void *
++blocked_thread_func (void *closure)
++{
++ xpthread_barrier_wait (&barrier);
++ /* TLS load and access tests run here in the main thread. */
++ xpthread_barrier_wait (&barrier);
++ return NULL;
++}
++
++static void *
++load_and_access (const char *mod, const char *func)
++{
++ /* Load module with TLS. */
++ void *p = xdlopen (mod, RTLD_NOW);
++ /* Access the TLS variable to ensure it is allocated. */
++ void (*f) (void) = (void (*) (void))xdlsym (p, func);
++ f ();
++ return p;
++}
++
++static int
++do_test (void)
++{
++ void *mods[6];
++
++ {
++ int ret = pthread_barrier_init (&barrier, NULL, 2);
++ if (ret != 0)
++ {
++ errno = ret;
++ printf ("error: pthread_barrier_init: %m\n");
++ exit (1);
++ }
++ }
++
++ pthread_t blocked_thread = xpthread_create (NULL, blocked_thread_func, NULL);
++ xpthread_barrier_wait (&barrier);
++
++ printf ("maintls[%zu]:\t %p .. %p\n",
++ sizeof maintls, maintls, maintls + sizeof maintls);
++ memset (maintls, 1, sizeof maintls);
++
++ /* Load modules with dynamic TLS (may use surplus static TLS
++ opportunistically). */
++ mods[0] = load_and_access ("tst-tls-ie-mod0.so", "access0");
++ mods[1] = load_and_access ("tst-tls-ie-mod1.so", "access1");
++ mods[2] = load_and_access ("tst-tls-ie-mod2.so", "access2");
++ mods[3] = load_and_access ("tst-tls-ie-mod3.so", "access3");
++ /* Load modules with initial-exec TLS (can only use surplus static TLS). */
++ mods[4] = load_and_access ("tst-tls-ie-mod4.so", "access4");
++ mods[5] = load_and_access ("tst-tls-ie-mod5.so", "access5");
++
++ /* Here 1152 bytes of surplus static TLS is in use and at most 512 bytes
++ are available (depending on TLS optimizations). */
++ printf ("The next dlopen should fail...\n");
++ void *p = dlopen ("tst-tls-ie-mod6.so", RTLD_NOW);
++ if (p != NULL)
++ FAIL_EXIT1 ("error: expected dlopen to fail because there is "
++ "not enough surplus static TLS.\n");
++ printf ("...OK failed with: %s.\n", dlerror ());
++
++ xpthread_barrier_wait (&barrier);
++ xpthread_join (blocked_thread);
++
++ /* Close the modules. */
++ for (int i = 0; i < 6; ++i)
++ xdlclose (mods[i]);
++
++ return 0;
++}
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index eb3ef5b..ba114ab 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -442,6 +442,9 @@ struct rtld_global
+ EXTERN size_t _dl_tls_static_used;
+ /* Alignment requirement of the static TLS block. */
+ EXTERN size_t _dl_tls_static_align;
++ /* Remaining amount of static TLS that may be used for optimizing
++ dynamic TLS access (e.g. with TLSDESC). */
++ EXTERN size_t _dl_tls_static_optional;
+
+ /* Number of additional entries in the slotinfo array of each slotinfo
+ list element. A large number makes it almost certain take we never
+--
+1.8.3.1
+
diff --git a/sources b/sources
new file mode 100644
index 0000000..9694bad
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+78a720f17412f3c3282be5a6f3363ec6 glibc-2.31.tar.xz
diff --git a/turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch b/turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch
new file mode 100644
index 0000000..5b766cf
--- /dev/null
+++ b/turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch
@@ -0,0 +1,25 @@
+From 44314a556239a7524b5a6451025737c1bdbb1cd0 Mon Sep 17 00:00:00 2001
+From: Wang Shuo <wangshuo47@huawei.com>
+Date: Thu, 21 May 2020 11:23:06 +0800
+Subject: [PATCH] turn REP_STOSB_THRESHOLD from 2k to 1M
+
+---
+ sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
+index dcd63c92..92c08eed 100644
+--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
++++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
+@@ -65,7 +65,7 @@
+ Enhanced REP STOSB. Since the stored value is fixed, larger register
+ size has minimal impact on threshold. */
+ #ifndef REP_STOSB_THRESHOLD
+-# define REP_STOSB_THRESHOLD 2048
++# define REP_STOSB_THRESHOLD 1048576
+ #endif
+
+ #ifndef SECTION
+--
+2.19.1
+
diff --git a/x86-64-Use-RDX_LP-on-__x86_shared_non_temporal_thres.patch b/x86-64-Use-RDX_LP-on-__x86_shared_non_temporal_thres.patch
new file mode 100644
index 0000000..82f8476
--- /dev/null
+++ b/x86-64-Use-RDX_LP-on-__x86_shared_non_temporal_thres.patch
@@ -0,0 +1,50 @@
+From 55c7bcc71b84123d5d4bd2814366a6b05fcf8ebd Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Sat, 9 May 2020 12:04:23 -0700
+Subject: [PATCH] x86-64: Use RDX_LP on __x86_shared_non_temporal_threshold [BZ
+ #25966]
+
+Since __x86_shared_non_temporal_threshold is defined as
+
+long int __x86_shared_non_temporal_threshold;
+
+and long int is 4 bytes for x32, use RDX_LP to compare against
+__x86_shared_non_temporal_threshold in assembly code.
+---
+ sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
+index c763b7d871..74953245aa 100644
+--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
++++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
+@@ -244,7 +244,7 @@ L(return):
+ ret
+
+ L(movsb):
+- cmpq __x86_shared_non_temporal_threshold(%rip), %rdx
++ cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP
+ jae L(more_8x_vec)
+ cmpq %rsi, %rdi
+ jb 1f
+@@ -402,7 +402,7 @@ L(more_8x_vec):
+ addq %r8, %rdx
+ #if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
+ /* Check non-temporal store threshold. */
+- cmpq __x86_shared_non_temporal_threshold(%rip), %rdx
++ cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP
+ ja L(large_forward)
+ #endif
+ L(loop_4x_vec_forward):
+@@ -454,7 +454,7 @@ L(more_8x_vec_backward):
+ subq %r8, %rdx
+ #if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
+ /* Check non-temporal store threshold. */
+- cmpq __x86_shared_non_temporal_threshold(%rip), %rdx
++ cmp __x86_shared_non_temporal_threshold(%rip), %RDX_LP
+ ja L(large_backward)
+ #endif
+ L(loop_4x_vec_backward):
+--
+2.19.1
+
diff --git a/x86_64-Use-xmmN-with-vpxor-to-clear-a-vector-registe.patch b/x86_64-Use-xmmN-with-vpxor-to-clear-a-vector-registe.patch
new file mode 100644
index 0000000..a308561
--- /dev/null
+++ b/x86_64-Use-xmmN-with-vpxor-to-clear-a-vector-registe.patch
@@ -0,0 +1,43 @@
+From a35a59036ebae3efcdf5e8167610e0656fca9770 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Thu, 11 Jun 2020 12:41:18 -0700
+Subject: [PATCH] x86_64: Use %xmmN with vpxor to clear a vector register
+
+Since "vpxor %xmmN, %xmmN, %xmmN" clears the whole vector register, use
+%xmmN, instead of %ymmN, with vpxor to clear a vector register.
+---
+ sysdeps/x86_64/multiarch/strcmp-avx2.S | 4 ++--
+ sysdeps/x86_64/multiarch/strrchr-avx2.S | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
+index 48d03a9f46..5f88a68262 100644
+--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
++++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
+@@ -91,8 +91,8 @@ ENTRY (STRCMP)
+ # endif
+ movl %edi, %eax
+ xorl %edx, %edx
+- /* Make %ymm7 all zeros in this function. */
+- vpxor %ymm7, %ymm7, %ymm7
++ /* Make %xmm7 (%ymm7) all zeros in this function. */
++ vpxor %xmm7, %xmm7, %xmm7
+ orl %esi, %eax
+ andl $(PAGE_SIZE - 1), %eax
+ cmpl $(PAGE_SIZE - (VEC_SIZE * 4)), %eax
+diff --git a/sysdeps/x86_64/multiarch/strrchr-avx2.S b/sysdeps/x86_64/multiarch/strrchr-avx2.S
+index 23077b4c45..146bdd51d0 100644
+--- a/sysdeps/x86_64/multiarch/strrchr-avx2.S
++++ b/sysdeps/x86_64/multiarch/strrchr-avx2.S
+@@ -44,7 +44,7 @@ ENTRY (STRRCHR)
+ movl %edi, %ecx
+ /* Broadcast CHAR to YMM4. */
+ VPBROADCAST %xmm4, %ymm4
+- vpxor %ymm0, %ymm0, %ymm0
++ vpxor %xmm0, %xmm0, %xmm0
+
+ /* Check if we may cross page boundary with one vector load. */
+ andl $(2 * VEC_SIZE - 1), %ecx
+--
+2.19.1
+