From 7c04899d471d84139c1b0bb85e29813494c09d9c Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 24 2020 03:12:19 +0000 Subject: import glibc-2.28-121.el8 --- diff --git a/SOURCES/glibc-rh1642150-1.patch b/SOURCES/glibc-rh1642150-1.patch new file mode 100644 index 0000000..381ad0b --- /dev/null +++ b/SOURCES/glibc-rh1642150-1.patch @@ -0,0 +1,176 @@ +commit a803367bab167f5ec4fde1f0d0ec447707c29520 +Author: Florian Weimer +Date: Fri Feb 14 20:55:39 2020 +0100 + + powerpc64: Add memory protection key support [BZ #23202] + + The 32-bit protection key behavior is somewhat unclear on 32-bit powerpc, + so this change is restricted to the 64-bit variants. + + Flag translation is needed because of hardware differences between the + POWER implementation (read and write flags) and the Intel implementation + (write and read+write flags). + +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h +new file mode 100644 +index 0000000000000000..623b073d5a585d51 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h +@@ -0,0 +1,55 @@ ++/* Helper functions for manipulating memory protection keys, for powerpc64. ++ Copyright (C) 2017-2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _ARCH_PKEY_H ++#define _ARCH_PKEY_H ++ ++/* Read and write access bits in the AMR register. Needs to be ++ translated from and to PKEY_DISABLE_* flags. */ ++#define PKEY_AMR_READ 1UL ++#define PKEY_AMR_WRITE 2UL ++ ++/* Return the value of the AMR register. */ ++static inline unsigned long int ++pkey_read (void) ++{ ++ unsigned long int result; ++ __asm__ volatile ("mfspr %0, 13" : "=r" (result)); ++ return result; ++} ++ ++/* Overwrite the AMR register with VALUE. */ ++static inline void ++pkey_write (unsigned long int value) ++{ ++ __asm__ volatile ("mtspr 13, %0" : : "r" (value)); ++} ++ ++/* Number of the largest supported key. This depends on the width of ++ the AMR register. */ ++#define PKEY_MAX (sizeof (unsigned long int) * 8 / 2 - 1) ++_Static_assert (PKEY_MAX == 15 || PKEY_MAX == 31, "PKEY_MAX value"); ++ ++/* Translate key number into AMR index position. */ ++static inline int ++pkey_index (int key) ++{ ++ return 2 * (PKEY_MAX - key); ++} ++ ++#endif /* _ARCH_PKEY_H */ +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c +new file mode 100644 +index 0000000000000000..856ba061b90eabd2 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c +@@ -0,0 +1,42 @@ ++/* Reading the per-thread memory protection key, powerpc64 version. ++ Copyright (C) 2017-2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++pkey_get (int key) ++{ ++ if (key < 0 || key > PKEY_MAX) ++ { ++ __set_errno (EINVAL); ++ return -1; ++ } ++ unsigned int index = pkey_index (key); ++ unsigned long int amr = pkey_read (); ++ unsigned int bits = (amr >> index) & 3; ++ ++ /* Translate from AMR values. PKEY_AMR_READ standing alone is not ++ currently representable. */ ++ if (bits & PKEY_AMR_READ) ++ return PKEY_DISABLE_ACCESS; ++ else if (bits == PKEY_AMR_WRITE) ++ return PKEY_DISABLE_WRITE; ++ return 0; ++} +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c +new file mode 100644 +index 0000000000000000..20b372ee2983abd5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c +@@ -0,0 +1,48 @@ ++/* Changing the per-thread memory protection key, powerpc64 version. ++ Copyright (C) 2017-2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++pkey_set (int key, unsigned int rights) ++{ ++ if (key < 0 || key > PKEY_MAX || rights > 3) ++ { ++ __set_errno (EINVAL); ++ return -1; ++ } ++ ++ /* Translate to AMR bit values. */ ++ unsigned long int bits; ++ if (rights & PKEY_DISABLE_ACCESS) ++ /* The PKEY_DISABLE_WRITE bit does not matter. */ ++ bits = PKEY_AMR_READ | PKEY_AMR_WRITE; ++ else if (rights == PKEY_DISABLE_WRITE) ++ bits = PKEY_AMR_WRITE; ++ else ++ bits = 0; ++ ++ unsigned int index = pkey_index (key); ++ unsigned long int mask = 3UL << index; ++ unsigned long int amr = pkey_read (); ++ amr = (amr & ~mask) | (bits << index); ++ pkey_write (amr); ++ return 0; ++} diff --git a/SOURCES/glibc-rh1642150-2.patch b/SOURCES/glibc-rh1642150-2.patch new file mode 100644 index 0000000..129ed9d --- /dev/null +++ b/SOURCES/glibc-rh1642150-2.patch @@ -0,0 +1,53 @@ +commit 8d42bf859a289944749d9f978c076cd318119867 +Author: Lucas A. M. Magalhaes +Date: Mon Feb 17 09:09:52 2020 -0300 + + Fix tst-pkey expectations on pkey_get [BZ #23202] + + From the GNU C Library manual, the pkey_set can receive a combination of + PKEY_DISABLE_WRITE and PKEY_DISABLE_ACCESS. However PKEY_DISABLE_ACCESS + is more restrictive than PKEY_DISABLE_WRITE and includes its behavior. + + The test expects that after setting + (PKEY_DISABLE_WRITE|PKEY_DISABLE_ACCESS) pkey_get should return the + same. This may not be true as PKEY_DISABLE_ACCESS will succeed in + describing the state of the key in this case. + + The pkey behavior during signal handling is different between x86 and + POWER. This change make the test compatible with both architectures. + + Reviewed-by: Tulio Magno Quites Machado Filho + +diff --git a/sysdeps/unix/sysv/linux/tst-pkey.c b/sysdeps/unix/sysv/linux/tst-pkey.c +index 5f721d4444490945..600b6f0098def773 100644 +--- a/sysdeps/unix/sysv/linux/tst-pkey.c ++++ b/sysdeps/unix/sysv/linux/tst-pkey.c +@@ -37,7 +37,7 @@ static pthread_barrier_t barrier; + + /* The keys used for testing. These have been allocated with access + rights set based on their array index. */ +-enum { key_count = 4 }; ++enum { key_count = 3 }; + static int keys[key_count]; + static volatile int *pages[key_count]; + +@@ -111,14 +111,16 @@ check_page_access (int page, bool write) + } + + static volatile sig_atomic_t sigusr1_handler_ran; +- +-/* Used to check that access is revoked in signal handlers. */ ++/* Used to check the behavior in signal handlers. In x86 all access are ++ revoked during signal handling. In PowerPC the key permissions are ++ inherited by the interrupted thread. This test accept both approaches. */ + static void + sigusr1_handler (int signum) + { + TEST_COMPARE (signum, SIGUSR1); + for (int i = 0; i < key_count; ++i) +- TEST_COMPARE (pkey_get (keys[i]), PKEY_DISABLE_ACCESS); ++ TEST_VERIFY (pkey_get (keys[i]) == PKEY_DISABLE_ACCESS ++ || pkey_get (keys[i]) == i); + sigusr1_handler_ran = 1; + } + diff --git a/SOURCES/glibc-rh1642150-3.patch b/SOURCES/glibc-rh1642150-3.patch new file mode 100644 index 0000000..84a2191 --- /dev/null +++ b/SOURCES/glibc-rh1642150-3.patch @@ -0,0 +1,46 @@ +commit 70ba28f7ab2923d4e36ffc9d5d2e32357353b25c +Author: Lucas A. M. Magalhaes +Date: Thu Jan 16 10:39:12 2020 -0300 + + Fix tst-pkey.c pkey_alloc return checks and manual + + This test was failing in some powerpc systems as it was not checking + for ENOSPC return. + + As said on the Linux man-pages and can be observed by the implementation + at mm/mprotect.c in the Linux Kernel source. The syscall pkey_alloc can + return EINVAL or ENOSPC. ENOSPC will indicate either that all keys are + in use or that the kernel does not support pkeys. + + Reviewed-by: Gabriel F. T. Gomes + +diff --git a/manual/memory.texi b/manual/memory.texi +index a1435aad1acd3239..4731a38bcc5701e0 100644 +--- a/manual/memory.texi ++++ b/manual/memory.texi +@@ -3289,6 +3289,10 @@ in which memory protection keys are disabled. + + @item ENOSPC + All available protection keys already have been allocated. ++ ++The system does not implement memory protection keys or runs in a mode ++in which memory protection keys are disabled. ++ + @end table + @end deftypefun + +diff --git a/sysdeps/unix/sysv/linux/tst-pkey.c b/sysdeps/unix/sysv/linux/tst-pkey.c +index 600b6f0098def773..40d7e9f24dec3e57 100644 +--- a/sysdeps/unix/sysv/linux/tst-pkey.c ++++ b/sysdeps/unix/sysv/linux/tst-pkey.c +@@ -199,6 +199,10 @@ do_test (void) + if (errno == EINVAL) + FAIL_UNSUPPORTED + ("CPU does not support memory protection keys: %m"); ++ if (errno == ENOSPC) ++ FAIL_UNSUPPORTED ++ ("no keys available or kernel does not support memory" ++ " protection keys"); + FAIL_EXIT1 ("pkey_alloc: %m"); + } + TEST_COMPARE (pkey_get (keys[0]), 0); diff --git a/SOURCES/glibc-rh1743445-1.patch b/SOURCES/glibc-rh1743445-1.patch new file mode 100644 index 0000000..759879a --- /dev/null +++ b/SOURCES/glibc-rh1743445-1.patch @@ -0,0 +1,151 @@ +From: Ian Kent +Date: Mon, 2 Sep 2019 11:26:14 +0000 (+0200) +Subject: Use autofs "ignore" mount hint in getmntent_r/getmntent +X-Git-Tag: changelog-ends-here~75 +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=08b7e9988272113ca5640cf5e115ea51449fb392 + +Use autofs "ignore" mount hint in getmntent_r/getmntent + +Historically autofs mounts were not included in mount table +listings. This is the case in other SysV autofs implementations +and was also the case with Linux autofs. + +But now that /etc/mtab is a symlink to the proc filesystem +mount table the autofs mount entries appear in the mount table +on Linux. + +Prior to the symlinking of /etc/mtab mount table it was +sufficient to call mount(2) and simply not update /etc/mtab +to exclude autofs mounts from mount listings. + +Also, with the symlinking of /etc/mtab we have seen a shift in +usage toward using the proc mount tables directly. + +But the autofs mount entries need to be retained when coming +from the proc file system for applications that need them +(largely autofs file system users themselves) so filtering out +these entries within the kernel itself can't be done. So it +needs be done in user space. + +There are three reasons to omit the autofs mount entries. + +One is that certain types of auto-mounts have an autofs mount +for every entry in their autofs mount map and these maps can +be quite large. This leads to mount table listings containing +a lot of unnecessary entries. + +Also, this change in behaviour between autofs implementations +can cause problems for applications that use getmntent(3) in +other OS implementations as well as Linux. + +Lastly, there's very little that user space can do with autofs +mount entries since this must be left to the autofs mount owner, +typically the automount daemon. But it can also lead to attempts +to access automount managed paths resulting mounts being triggered +when they aren't needed or mounts staying mounted for much longer +thay they need be. While the point of this change ins't to help +with these problems (and it can be quite a problem) it may be +a welcome side effect. + +So the Linux autofs file system has been modified to accept a +pseudo mount option of "ignore" (as is used in other OS +implementations) so that user space can use this as a hint to +skip autofs entries on reading the mount table. + +The Linux autofs automount daemon used getmntent(3) itself and +has been modified to use the proc file system directly so that +it can "ignore" mount option. + +The use of this mount option is opt-in and a configuration +option has been added which defaults to not use this option +so if there are applications that need these entries, other +than autofs itself, they can be retained. Also, since this +filtering is based on an added mount option earlier versions +of Linux autofs iand other autofs file system users will not +use the option and so won't be affected by the change. +--- + +diff --git a/misc/mntent_r.c b/misc/mntent_r.c +index 5d88c45c6f..d90e8d7087 100644 +--- a/misc/mntent_r.c ++++ b/misc/mntent_r.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -112,26 +113,18 @@ decode_name (char *buf) + return buf; + } + +- +-/* Read one mount table entry from STREAM. Returns a pointer to storage +- reused on the next call, or null for EOF or error (use feof/ferror to +- check). */ +-struct mntent * +-__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) ++static bool ++get_mnt_entry (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) + { + char *cp; + char *head; + +- flockfile (stream); + do + { + char *end_ptr; + + if (__fgets_unlocked (buffer, bufsiz, stream) == NULL) +- { +- funlockfile (stream); +- return NULL; +- } ++ return false; + + end_ptr = strchr (buffer, '\n'); + if (end_ptr != NULL) /* chop newline */ +@@ -181,9 +174,40 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) + case 2: + break; + } ++ ++ return true; ++} ++ ++/* Read one mount table entry from STREAM. Returns a pointer to storage ++ reused on the next call, or null for EOF or error (use feof/ferror to ++ check). */ ++struct mntent * ++__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) ++{ ++ struct mntent *result; ++ ++ flockfile (stream); ++ while (true) ++ if (get_mnt_entry (stream, mp, buffer, bufsiz)) ++ { ++ /* If the file system is autofs look for a mount option hint ++ ("ignore") to skip the entry. */ ++ if (strcmp (mp->mnt_type, "autofs") == 0 && __hasmntopt (mp, "ignore")) ++ memset (mp, 0, sizeof (*mp)); ++ else ++ { ++ result = mp; ++ break; ++ } ++ } ++ else ++ { ++ result = NULL; ++ break; ++ } + funlockfile (stream); + +- return mp; ++ return result; + } + libc_hidden_def (__getmntent_r) + weak_alias (__getmntent_r, getmntent_r) diff --git a/SOURCES/glibc-rh1743445-2.patch b/SOURCES/glibc-rh1743445-2.patch new file mode 100644 index 0000000..a14fe60 --- /dev/null +++ b/SOURCES/glibc-rh1743445-2.patch @@ -0,0 +1,169 @@ +From: Florian Weimer +Date: Mon, 2 Sep 2019 10:40:38 +0000 (+0200) +Subject: Add misc/tst-mntent-autofs, testing autofs "ignore" filtering +X-Git-Tag: changelog-ends-here~74 +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=9a1e7257a4292d3aea45c8317df3956f4331d8ce + +Add misc/tst-mntent-autofs, testing autofs "ignore" filtering +--- + +diff -rup a/misc/Makefile b/misc/Makefile +--- a/misc/Makefile 2020-03-25 18:30:42.275895917 -0400 ++++ b/misc/Makefile 2020-03-25 18:37:55.527738814 -0400 +@@ -84,7 +84,8 @@ tests := tst-dirname tst-tsearch tst-fds + tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \ + tst-mntent-blank-corrupt tst-mntent-blank-passno bug18240 \ + tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \ +- tst-preadvwritev2 tst-preadvwritev64v2 ++ tst-preadvwritev2 tst-preadvwritev64v2 \ ++ tst-mntent-autofs + + # Tests which need libdl. + ifeq (yes,$(build-shared)) +diff --git a/misc/tst-mntent-autofs.c b/misc/tst-mntent-autofs.c +new file mode 100644 +index 0000000000..bf4d4e73b4 +--- /dev/null ++++ b/misc/tst-mntent-autofs.c +@@ -0,0 +1,141 @@ ++/* Test autofs "ignore" filtering for getment_r. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct test_case ++{ ++ const char *line; ++ struct ++ { ++ /* Like struct mntent, but with const pointers. */ ++ const char *mnt_fsname; ++ const char *mnt_dir; ++ const char *mnt_type; ++ const char *mnt_opts; ++ int mnt_freq; ++ int mnt_passno; ++ } expected; ++}; ++ ++static struct test_case test_cases[] = ++ { ++ { "/etc/auto.direct /mnt/auto/1 autofs defaults 0 0", ++ { "/etc/auto.direct", "/mnt/auto/1", "autofs", "defaults", 0, 0 } }, ++ ++ /* These entries are filtered out. */ ++ { "/etc/auto.2 /mnt/auto/2 autofs ignore 0 0", { NULL, } }, ++ { "/etc/auto.3 /mnt/auto/3 autofs ignore,other 1 2", { NULL, } }, ++ { "/etc/auto.4 /mnt/auto/4 autofs other,ignore 3 4", { NULL, } }, ++ { "/etc/auto.5 /mnt/auto/5 autofs opt1,ignore,opt2 5 6", { NULL, } }, ++ ++ /* Dummy entry to make the desynchronization more obvious. */ ++ { "/dev/sda1 / xfs defaults 0 0", ++ { "/dev/sda1", "/", "xfs", "defaults", 0, 0 } }, ++ ++ /* These are not filtered because the file system is not autofs. */ ++ { "/etc/auto.direct /mnt/auto/6 autofs1 ignore 0 0", ++ { "/etc/auto.direct", "/mnt/auto/6", "autofs1", "ignore", 0, 0 } }, ++ { "/etc/auto.direct /mnt/auto/7 autofs1 ignore,other 0 0", ++ { "/etc/auto.direct", "/mnt/auto/7", "autofs1", "ignore,other", 0, 0 } }, ++ { "/etc/auto.direct /mnt/auto/8 autofs1 other,ignore 0 0", ++ { "/etc/auto.direct", "/mnt/auto/8", "autofs1", "other,ignore", 0, 0 } }, ++ { "/etc/auto.direct /mnt/auto/9 autofs1 opt1,ignore,opt2 0 0", ++ { "/etc/auto.direct", "/mnt/auto/9", "autofs1", "opt1,ignore,opt2", } }, ++ ++ /* These are not filtered because the string "ignore" is not an ++ option name. */ ++ { "/etc/auto.direct /mnt/auto/10 autofs noignore 1 2", ++ { "/etc/auto.direct", "/mnt/auto/10", "autofs", "noignore", 1, 2 } }, ++ { "/etc/auto.direct /mnt/auto/11 autofs noignore,other 0 0", ++ { "/etc/auto.direct", "/mnt/auto/11", "autofs", "noignore,other", } }, ++ { "/etc/auto.direct /mnt/auto/12 autofs other,noignore 0 0", ++ { "/etc/auto.direct", "/mnt/auto/12", "autofs", "other,noignore", } }, ++ { "/etc/auto.direct /mnt/auto/13 autofs errors=ignore 0 0", ++ { "/etc/auto.direct", "/mnt/auto/13", "autofs", "errors=ignore", } }, ++ { "/etc/auto.direct /mnt/auto/14 autofs errors=ignore,other 0 0", ++ { "/etc/auto.direct", "/mnt/auto/14", "autofs", ++ "errors=ignore,other", } }, ++ { "/etc/auto.direct /mnt/auto/15 autofs other,errors=ignore 0 0", ++ { "/etc/auto.direct", "/mnt/auto/15", "autofs", ++ "other,errors=ignore", } }, ++ ++ /* These are not filtered because the string is escaped. '\151' ++ is 'i', but it is not actually decoded by the parser. */ ++ { "/etc/auto.\\151gnore /mnt/auto/16 autofs \\151gnore 0 0", ++ { "/etc/auto.\\151gnore", "/mnt/auto/16", "autofs", ++ "\\151gnore", } }, ++ }; ++ ++static int ++do_test (void) ++{ ++ char *path; ++ xclose (create_temp_file ("tst-mntent-autofs-", &path)); ++ ++ /* Write the test file. */ ++ FILE *fp = xfopen (path, "w"); ++ for (size_t i = 0; i < array_length (test_cases); ++i) ++ fprintf (fp, "%s\n", test_cases[i].line); ++ xfclose (fp); ++ ++ /* Open the test file again, this time for parsing. */ ++ fp = setmntent (path, "r"); ++ TEST_VERIFY_EXIT (fp != NULL); ++ char buffer[512]; ++ struct mntent me; ++ ++ for (size_t i = 0; i < array_length (test_cases); ++i) ++ { ++ if (test_cases[i].expected.mnt_type == NULL) ++ continue; ++ ++ memset (buffer, 0xcc, sizeof (buffer)); ++ memset (&me, 0xcc, sizeof (me)); ++ struct mntent *pme = getmntent_r (fp, &me, buffer, sizeof (buffer)); ++ TEST_VERIFY_EXIT (pme != NULL); ++ TEST_VERIFY (pme == &me); ++ TEST_COMPARE_STRING (test_cases[i].expected.mnt_fsname, me.mnt_fsname); ++ TEST_COMPARE_STRING (test_cases[i].expected.mnt_dir, me.mnt_dir); ++ TEST_COMPARE_STRING (test_cases[i].expected.mnt_type, me.mnt_type); ++ TEST_COMPARE_STRING (test_cases[i].expected.mnt_opts, me.mnt_opts); ++ TEST_COMPARE (test_cases[i].expected.mnt_freq, me.mnt_freq); ++ TEST_COMPARE (test_cases[i].expected.mnt_passno, me.mnt_passno); ++ } ++ ++ TEST_VERIFY (getmntent_r (fp, &me, buffer, sizeof (buffer)) == NULL); ++ ++ TEST_COMPARE (feof (fp), 1); ++ TEST_COMPARE (ferror (fp), 0); ++ errno = 0; ++ TEST_COMPARE (endmntent (fp), 1); ++ TEST_COMPARE (errno, 0); ++ free (path); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1757354.patch b/SOURCES/glibc-rh1757354.patch new file mode 100644 index 0000000..d159b26 --- /dev/null +++ b/SOURCES/glibc-rh1757354.patch @@ -0,0 +1,1163 @@ +commit 8e42fc6811ba94a01e194d46572c3cf803b3aae0 +Author: Mike FABIAN +Date: Tue Sep 17 17:20:32 2019 +0200 + + Sync "language", "lang_name", "territory", "country_name" with CLDR/langtable + + Sync these values with CLDR and langtable as much as possible. Add + missing values. + + If possible, take the values from CLDR, if CLDR does not have it, + take it from langtable. The values from langtable which are not from + CLDR are from Wikipedia or native speakers. + +diff --git a/localedata/locales/az_AZ b/localedata/locales/az_AZ +index 6fe8839f25cc7450..3c0db0be3de1e6d3 100644 +--- a/localedata/locales/az_AZ ++++ b/localedata/locales/az_AZ +@@ -243,7 +243,7 @@ country_ab3 "AZE" + country_num 031 + country_car "AZ" + % Azərbaycanca +-lang_name "azrbaycan dili" ++lang_name "azrbaycan" + lang_ab "az" + lang_term "aze" + lang_lib "aze" +diff --git a/localedata/locales/be_BY@latin b/localedata/locales/be_BY@latin +index 43b13cc27812aaa0..fef339f6247a0eb6 100644 +--- a/localedata/locales/be_BY@latin ++++ b/localedata/locales/be_BY@latin +@@ -156,7 +156,7 @@ country_ab2 "BY" + country_ab3 "BLR" + country_num 112 + country_car "BY" +-lang_name "biearuskaja mova" ++lang_name "biearuskaja" + lang_ab "be" + lang_term "bel" + lang_lib "bel" +diff --git a/localedata/locales/ber_DZ b/localedata/locales/ber_DZ +index 79f3d289b1ee771c..4fa1bdfff94b9efd 100644 +--- a/localedata/locales/ber_DZ ++++ b/localedata/locales/ber_DZ +@@ -8,7 +8,7 @@ escape_char / + % exempt you from the conditions of the license if your use would + % otherwise be governed by that license. + +-% Amazigh Language Locale for Algeria (latin) ++% Berber Language Locale for Algeria (latin) + % Source: + % Contact: Pablo Saratxaga + % Email: +@@ -20,14 +20,14 @@ escape_char / + % Users: general + + LC_IDENTIFICATION +-title "Amazigh language locale for Algeria (latin)" ++title "Berber language locale for Algeria (latin)" + source "" + address "" + contact "Pablo Saratxaga" + email "pablo@mandrakesoft.com" + tel "" + fax "" +-language "Amazigh" ++language "Berber" + territory "Algeria" + revision "0.1" + date "2002-04-16" +@@ -253,14 +253,15 @@ LC_ADDRESS + % This is the ISO_IEC TR14652 Locale definition for the + % LC_ADDRESS + postal_fmt "%z%c%T%s%b%e%r" ++country_name "Lezzayer" + %country_post "" + country_ab2 "DZ" + country_ab3 "DZA" + country_num 012 + %country_isbn "" + country_car "DZ" +-% ⵜⴰⵎⴰⵣⵉⵖⵜ +-lang_name "" ++% Tamaziɣt ++lang_name "Tamazit" + %lang_ab + lang_term "ber" + lang_lib "ber" +diff --git a/localedata/locales/ber_MA b/localedata/locales/ber_MA +index b9bd64868cda3412..5d19354ad65069eb 100644 +--- a/localedata/locales/ber_MA ++++ b/localedata/locales/ber_MA +@@ -8,7 +8,7 @@ escape_char / + % exempt you from the conditions of the license if your use would + % otherwise be governed by that license. + +-% Amazigh Language Locale for Morocco (tifinagh) ++% Berber Language Locale for Morocco (tifinagh) + % Source: + % Contact: Pablo Saratxaga + % Email: +@@ -20,14 +20,14 @@ escape_char / + % Users: general + + LC_IDENTIFICATION +-title "Amazigh language locale for Morocco (tifinagh)" ++title "Berber language locale for Morocco (tifinagh)" + source "" + address "" + contact "Pablo Saratxaga" + email "pablo@mandrakesoft.com" + tel "" + fax "" +-language "Amazigh" ++language "Berber" + territory "Morocco" + revision "0.1" + date "2002-06-26" +@@ -204,6 +204,8 @@ LC_ADDRESS + % This is the ISO_IEC TR14652 Locale definition for the + % LC_ADDRESS + postal_fmt "%z%c%T%s%b%e%r" ++% https://en.wikipedia.org/wiki/Morocco ⵜⴰⴳⵍⴷⵉⵜ ⵏ ⵍⵎⵖⵔⵉⴱ ++country_name " " + %country_post "" + country_ab2 "MA" + country_ab3 "MAR" +@@ -211,7 +213,7 @@ country_num 504 + %country_isbn "" + country_car "MA" + % ⵜⴰⵎⴰⵣⵉⵖⵜ +-lang_name "" ++lang_name "" + % lang_ab + lang_term "ber" + lang_lib "ber" +diff --git a/localedata/locales/bhb_IN b/localedata/locales/bhb_IN +index 549974de2cfd4843..80d590d068582de6 100644 +--- a/localedata/locales/bhb_IN ++++ b/localedata/locales/bhb_IN +@@ -145,11 +145,13 @@ LC_ADDRESS + % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category + % generated by IBM Basic CountryPack Transformer. + postal_fmt "%z%c%T%s%b%e%r" ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_car "IND" + country_num 356 +-lang_name "bhili" ++% भीली ++lang_name "" + lang_ab "" + lang_term "bhb" + lang_lib "bhb" +diff --git a/localedata/locales/bho_IN b/localedata/locales/bho_IN +index 99a91c2553ecdeae..4a0f25d6aceaa023 100644 +--- a/localedata/locales/bho_IN ++++ b/localedata/locales/bho_IN +@@ -147,6 +147,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%z%c%T%s%b%e%r" ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 +diff --git a/localedata/locales/chr_US b/localedata/locales/chr_US +index 290d1b24551dd3ba..86868c02e9ae2e1c 100644 +--- a/localedata/locales/chr_US ++++ b/localedata/locales/chr_US +@@ -113,7 +113,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N" +-country_name "" ++country_name "" + country_post "USA" + country_ab2 "US" + country_ab3 "USA" +diff --git a/localedata/locales/crh_UA b/localedata/locales/crh_UA +index b2ac8c66d78521b0..86281a27db1cc64d 100644 +--- a/localedata/locales/crh_UA ++++ b/localedata/locales/crh_UA +@@ -198,8 +198,8 @@ country_ab2 "UA" + country_ab3 "UKR" + country_num 804 + country_car "UA" +-% Qırımtatarca +-lang_name "Qrmtatarca" ++% qırımtatar tili ++lang_name "qrmtatar tili" + lang_term "crh" + lang_lib "crh" + END LC_ADDRESS +diff --git a/localedata/locales/csb_PL b/localedata/locales/csb_PL +index c8572f8fc54853b3..662dcefa15a2cae3 100644 +--- a/localedata/locales/csb_PL ++++ b/localedata/locales/csb_PL +@@ -210,6 +210,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" ++country_name "Plsk" + country_ab2 "PL" + country_ab3 "POL" + country_num 616 +diff --git a/localedata/locales/doi_IN b/localedata/locales/doi_IN +index 0428ae50a9bf60e8..df9dfc6e2a428abb 100644 +--- a/localedata/locales/doi_IN ++++ b/localedata/locales/doi_IN +@@ -156,6 +156,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%z%c%T%s%b%e%r" ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 +diff --git a/localedata/locales/dv_MV b/localedata/locales/dv_MV +index 0d7842f39f7edf85..ab78fa5ce33cfe0e 100644 +--- a/localedata/locales/dv_MV ++++ b/localedata/locales/dv_MV +@@ -182,9 +182,8 @@ country_ab2 "MV" + country_ab3 "MDV" + country_num 462 + country_car "MV" +-% lang_name FIXME +-% Cannot represent Dhivehi in Thaana script +-% http://en.wikipedia.org/wiki/Maldivian_language ++% ދިވެހި ++lang_name "" + lang_ab "dv" + lang_term "div" + lang_lib "div" +diff --git a/localedata/locales/eo b/localedata/locales/eo +index 33a81033e23caadd..b2ad5758004b67d8 100644 +--- a/localedata/locales/eo ++++ b/localedata/locales/eo +@@ -206,7 +206,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%%z %T%N%c%N" +-lang_name "Esperanto" ++lang_name "esperanto" + lang_ab "eo" + lang_term "epo" + END LC_ADDRESS +diff --git a/localedata/locales/hak_TW b/localedata/locales/hak_TW +index f62937e91b634416..87f2a00489d1574e 100644 +--- a/localedata/locales/hak_TW ++++ b/localedata/locales/hak_TW +@@ -187,8 +187,8 @@ country_ab3 "TWN" + country_num 158 + country_car "RC" + country_isbn 957 +-% 漢語客家語 +-lang_name "" ++% 客家語 ++lang_name "" + lang_term "hak" + lang_lib "hak" + END LC_ADDRESS +diff --git a/localedata/locales/hif_FJ b/localedata/locales/hif_FJ +index 5433bb4a2a54636e..a6868b791025c8f4 100644 +--- a/localedata/locales/hif_FJ ++++ b/localedata/locales/hif_FJ +@@ -176,7 +176,8 @@ country_car "FJI" + country_num 242 + % https://en.wikipedia.org/wiki/ISO_3166-1_numeric + % https://en.wikipedia.org/wiki/Fiji_Hindi +-lang_name "Fiji Baat" ++% फ़िजी बात ++lang_name "" + % iso-639-1 + lang_ab "" + % iso-639-3 +diff --git a/localedata/locales/hne_IN b/localedata/locales/hne_IN +index 7abec636304b9e67..d8b83610165a6844 100644 +--- a/localedata/locales/hne_IN ++++ b/localedata/locales/hne_IN +@@ -154,6 +154,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%z%c%T%s%b%e%r" ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 +diff --git a/localedata/locales/ia_FR b/localedata/locales/ia_FR +index f3fbf213a3f7f267..4ce7c7fe4a416541 100644 +--- a/localedata/locales/ia_FR ++++ b/localedata/locales/ia_FR +@@ -127,7 +127,7 @@ country_ab3 "FRA" + country_num 250 + country_isbn "979-10" + country_car "F" +-lang_name "Interlingua" ++lang_name "interlingua" + lang_ab "ia" + lang_term "ina" + lang_lib "ina" +diff --git a/localedata/locales/id_ID b/localedata/locales/id_ID +index 3ddd8d07daed6697..92ff81df23b059a0 100644 +--- a/localedata/locales/id_ID ++++ b/localedata/locales/id_ID +@@ -155,7 +155,7 @@ country_ab2 "ID" + country_ab3 "IDN" + country_num 360 + country_car "RI" +-lang_name "Bahasa Indonesia" ++lang_name "Indonesia" + lang_ab "id" + lang_term "ind" + lang_lib "ind" +diff --git a/localedata/locales/ig_NG b/localedata/locales/ig_NG +index bddd2ccde523dca8..113294a0f58ab576 100644 +--- a/localedata/locales/ig_NG ++++ b/localedata/locales/ig_NG +@@ -321,11 +321,11 @@ LC_ADDRESS + % "end of line + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" + +-% Country name in Igbo - "Nigeria" +-country_name "Nigeria" ++% Country name in Igbo - "Naịjịrịa" ++country_name "Najra" + +-% Language name in Igbo - "Igbo" +-lang_name "Igbo" ++% Language name in Igbo - "Asụsụ Igbo" ++lang_name "Ass Igbo" + + % CEPT MAILCODES are suggested + % Alternatively use the code found on your countries postal item tracking number +diff --git a/localedata/locales/kab_DZ b/localedata/locales/kab_DZ +index a165f53f01370c94..ef572357c22615f7 100644 +--- a/localedata/locales/kab_DZ ++++ b/localedata/locales/kab_DZ +@@ -154,7 +154,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" +-country_name "Zzayer" ++country_name "Lezzayer" + country_ab2 "DZ" + country_ab3 "DZA" + country_num 012 +diff --git a/localedata/locales/ks_IN b/localedata/locales/ks_IN +index 6992a5536887d9f6..e1efea342d4b55a0 100644 +--- a/localedata/locales/ks_IN ++++ b/localedata/locales/ks_IN +@@ -167,7 +167,7 @@ LC_ADDRESS + % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category + % generated by IBM Basic CountryPack Transformer. + postal_fmt "%z%c%T%s%b%e%r" +-country_name "" ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 +diff --git a/localedata/locales/ku_TR b/localedata/locales/ku_TR +index 595cdb14bc9ef29d..f6a8925608ea046d 100644 +--- a/localedata/locales/ku_TR ++++ b/localedata/locales/ku_TR +@@ -182,14 +182,14 @@ END LC_NAME + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" + % TODO +-country_name "Turkey" ++country_name "Tirkiye" + country_post "TR" + country_ab2 "TR" + country_ab3 "TUR" + country_num 792 + country_isbn 975 + country_car "TR" +-lang_name "kurdi" ++lang_name "kurd" + lang_ab "ku" + lang_term "kur" + lang_lib "kur" +diff --git a/localedata/locales/mag_IN b/localedata/locales/mag_IN +index b8f65f70e26f4481..c86d9ba075ef2577 100644 +--- a/localedata/locales/mag_IN ++++ b/localedata/locales/mag_IN +@@ -152,6 +152,7 @@ END LC_NAME + LC_ADDRESS + + postal_fmt "%z%c%T%s%b%e%r" ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 +diff --git a/localedata/locales/mfe_MU b/localedata/locales/mfe_MU +index 7415e9250fb78d50..7fabc5f80d9ae5e5 100644 +--- a/localedata/locales/mfe_MU ++++ b/localedata/locales/mfe_MU +@@ -170,7 +170,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%h%s%N%T" +-country_name "Mauritius" ++country_name "Moris" + country_ab2 "MU" + country_ab3 "MUS" + country_num 480 +diff --git a/localedata/locales/mhr_RU b/localedata/locales/mhr_RU +index 85ac21b35af25c87..02bec3e9aed6fddc 100644 +--- a/localedata/locales/mhr_RU ++++ b/localedata/locales/mhr_RU +@@ -159,6 +159,8 @@ country_ab2 "RU" + country_ab3 "RUS" + country_num 643 + country_car "RUS" ++% марий йылме ++lang_name " " + lang_term "mhr" + lang_lib "mhr" + END LC_ADDRESS +diff --git a/localedata/locales/mi_NZ b/localedata/locales/mi_NZ +index 782f02359cb096d4..d08bc249427581c2 100644 +--- a/localedata/locales/mi_NZ ++++ b/localedata/locales/mi_NZ +@@ -157,7 +157,7 @@ country_ab2 "NZ" + country_ab3 "NZL" + country_num 554 + country_car "NZ" +-lang_name "Te Reo" ++lang_name "Mori" + lang_ab "mi" + lang_term "mri" + lang_lib "mao" +diff --git a/localedata/locales/ms_MY b/localedata/locales/ms_MY +index 66b5dd98e99e5da3..8ffe9156b6e3d022 100644 +--- a/localedata/locales/ms_MY ++++ b/localedata/locales/ms_MY +@@ -184,7 +184,7 @@ country_ab3 "MYS" + country_num 458 + country_car "MAL" + % Bahasa Melayu +-lang_name "Bahasa Melayu" ++lang_name "Melayu" + lang_ab "ms" + lang_term "msa" + lang_lib "may" +diff --git a/localedata/locales/my_MM b/localedata/locales/my_MM +index d612e5305aff7e2b..846363223883723b 100644 +--- a/localedata/locales/my_MM ++++ b/localedata/locales/my_MM +@@ -309,7 +309,8 @@ country_ab2 "MM" + country_num 104 + country_car "MYA" + lang_ab "my" +-lang_name "" ++% မြန်မာ ++lang_name "" + lang_term "mya" + lang_lib "bur" + END LC_ADDRESS +diff --git a/localedata/locales/nan_TW b/localedata/locales/nan_TW +index f5bc5d1642c2ce9b..53884e02ffd16d2c 100644 +--- a/localedata/locales/nan_TW ++++ b/localedata/locales/nan_TW +@@ -188,8 +188,8 @@ country_ab3 "TWN" + country_num 158 + country_car "RC" + country_isbn 957 +-% 漢語閩南語 +-lang_name "" ++% 閩南語 ++lang_name "" + lang_term "nan" + lang_lib "nan" + END LC_ADDRESS +diff --git a/localedata/locales/nan_TW@latin b/localedata/locales/nan_TW@latin +index d4579a4cdf032d4c..104f4152a98b37ab 100644 +--- a/localedata/locales/nan_TW@latin ++++ b/localedata/locales/nan_TW@latin +@@ -165,8 +165,8 @@ country_ab3 "TWN" + country_num 158 + country_car "RC" + country_isbn 957 +-%lang_name "Bân-lâm-gú, Hō-ló-oē" +-lang_name "Bn-lm-g, H-l-o" ++%lang_name "Bân-lâm-gú" ++lang_name "Bn-lm-g" + lang_term "nan" + lang_lib "nan" + END LC_ADDRESS +diff --git a/localedata/locales/nds_DE b/localedata/locales/nds_DE +index 232f9e4455ca74cc..d6200b7972b6b820 100644 +--- a/localedata/locales/nds_DE ++++ b/localedata/locales/nds_DE +@@ -45,7 +45,7 @@ country_ab3 "DEU" + country_car "D" + country_num 276 + country_isbn "3" +-lang_name "Neddersassisch" ++lang_name "Neddersasssch" + %lang_ab + lang_term "nds" + lang_lib "nds" +diff --git a/localedata/locales/nds_NL b/localedata/locales/nds_NL +index 8c8bebd93530938f..9fd50fb6256d3823 100644 +--- a/localedata/locales/nds_NL ++++ b/localedata/locales/nds_NL +@@ -44,7 +44,7 @@ country_ab3 "NLD" + country_car "NL" + country_num 528 + country_isbn "3" +-lang_name "Neddersassisch" ++lang_name "Neddersasssch" + %lang_ab + lang_term "nds" + lang_lib "nds" +diff --git a/localedata/locales/nhn_MX b/localedata/locales/nhn_MX +index 88a89765e88f060b..2dbfcb3c6572cd0c 100644 +--- a/localedata/locales/nhn_MX ++++ b/localedata/locales/nhn_MX +@@ -133,11 +133,12 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" ++country_name "Mexihco" + country_ab2 "MX" + country_ab3 "MEX" + country_num 484 + country_car "MEX" +-lang_name "Tlaxcala-Puebla Nahuatl" ++lang_name "Tlahco nhuatlahtlli" + lang_term "nhn" + lang_lib "nhn" + END LC_ADDRESS +diff --git a/localedata/locales/niu_NU b/localedata/locales/niu_NU +index 553c5d9edcddfc86..387e109109fc0374 100644 +--- a/localedata/locales/niu_NU ++++ b/localedata/locales/niu_NU +@@ -163,10 +163,12 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" ++country_name "Niu" + country_post "NU" + country_ab2 "NU" + country_ab3 "NIU" + country_num 570 ++lang_name "ko e vagahau Niu" + lang_term "niu" + lang_lib "niu" + END LC_ADDRESS +diff --git a/localedata/locales/niu_NZ b/localedata/locales/niu_NZ +index 560101b447c22251..2eba7d2630f8a46d 100644 +--- a/localedata/locales/niu_NZ ++++ b/localedata/locales/niu_NZ +@@ -99,6 +99,7 @@ country_ab2 "NZ" + country_ab3 "NZL" + country_num 554 + country_car "NZ" ++lang_name "ko e vagahau Niu" + lang_term "niu" + lang_lib "niu" + END LC_ADDRESS +diff --git a/localedata/locales/nr_ZA b/localedata/locales/nr_ZA +index 7de6420a6b52977e..f64434fadbad4e69 100644 +--- a/localedata/locales/nr_ZA ++++ b/localedata/locales/nr_ZA +@@ -225,7 +225,7 @@ country_car "ZA" + country_num 710 + + % Language name in Southern Ndebele +-lang_name "IsiNdebele" ++lang_name "isiNdebele" + + % ISO 639 two and three letter language names + % see http://www.loc.gov/standards/iso639-2/englangn.html +diff --git a/localedata/locales/oc_FR b/localedata/locales/oc_FR +index 707927ee2662ac91..a106f8d1c1152959 100644 +--- a/localedata/locales/oc_FR ++++ b/localedata/locales/oc_FR +@@ -44,7 +44,7 @@ country_ab3 "FRA" + country_num 250 + country_isbn "979-10" + country_car "F" +-lang_name "Occitan" ++lang_name "occitan" + lang_ab "oc" + lang_term "oci" + lang_lib "oci" +diff --git a/localedata/locales/or_IN b/localedata/locales/or_IN +index ef28b58895c342b6..2e4975e7b710b592 100644 +--- a/localedata/locales/or_IN ++++ b/localedata/locales/or_IN +@@ -20,7 +20,7 @@ contact "" + email "bug-glibc@gnu.org" + tel "" + fax "" +-language "Oriya" ++language "Odia" + territory "India" + revision "1.0" + date "2006-05-25" +diff --git a/localedata/locales/pa_PK b/localedata/locales/pa_PK +index 1f49bdc90d7ce637..0a584114b8f06590 100644 +--- a/localedata/locales/pa_PK ++++ b/localedata/locales/pa_PK +@@ -173,7 +173,7 @@ END LC_NAME + LC_ADDRESS + % FIXME + postal_fmt "%a%N%f%N%d%N%b%N%h %s %e %r%N%T %z%N%c%N" +-country_name "" ++country_name "" + country_ab2 "PK" + country_ab3 "PAK" + country_num 586 +diff --git a/localedata/locales/ps_AF b/localedata/locales/ps_AF +index 66f560ef4406be61..23dc86dcf1c1453b 100644 +--- a/localedata/locales/ps_AF ++++ b/localedata/locales/ps_AF +@@ -308,8 +308,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" +-country_name "/ +-" ++country_name "" + country_post "AF" + country_ab2 "AF" + country_ab3 "AFG" +diff --git a/localedata/locales/quz_PE b/localedata/locales/quz_PE +index f6b1956b937100df..9ed890cbb0e6c762 100644 +--- a/localedata/locales/quz_PE ++++ b/localedata/locales/quz_PE +@@ -10,7 +10,7 @@ escape_char / + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % +-% Quechua (Cusco-Collao) language locale for Peru ++% Cusco Quechua language locale for Peru + % + % Prepared and contributed to glibc by Chris Leonard + % and Amos Batto +@@ -25,14 +25,14 @@ escape_char / + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + LC_IDENTIFICATION +-title "Quechua (Cusco-Collao) locale for Peru" ++title "Cusco Quechua locale for Peru" + source "Sugar Labs // OLPC" + address "" + contact "sugarlabs.org" + email "libc-alpha@sourceware.org" + tel "" + fax "" +-language "Quechua (Cusco-Collao)" ++language "Cusco Quechua" + territory "Peru" + revision "1.0" + date "2013-08-24" +@@ -144,7 +144,7 @@ country_ab2 "PE" + country_ab3 "PER" + country_num 604 + country_car "PE" +-lang_name "Quechua (Cusco)" ++lang_name "Qusqu runasimi" + lang_term "quz" + lang_lib "quz" + END LC_ADDRESS +diff --git a/localedata/locales/raj_IN b/localedata/locales/raj_IN +index ece080223e8de94b..ce009e406ab5c332 100644 +--- a/localedata/locales/raj_IN ++++ b/localedata/locales/raj_IN +@@ -158,7 +158,16 @@ name_ms "" + END LC_NAME + + LC_ADDRESS +-copy "hi_IN" ++postal_fmt "%z%c%T%s%b%e%r" ++country_name "" ++country_ab2 "IN" ++country_ab3 "IND" ++country_num 356 ++country_car "IND" ++% राजस्थानी ++lang_name "" ++lang_term "raj" ++lang_lib "raj" + END LC_ADDRESS + + LC_TELEPHONE +diff --git a/localedata/locales/rw_RW b/localedata/locales/rw_RW +index e0bc763c5a484c15..31cb4673dfa4a3aa 100644 +--- a/localedata/locales/rw_RW ++++ b/localedata/locales/rw_RW +@@ -132,7 +132,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" +-country_name "Rwanda" ++country_name "U Rwanda" + country_ab2 "RW" + country_ab3 "RWA" + country_num 646 +diff --git a/localedata/locales/sah_RU b/localedata/locales/sah_RU +index 80f67219c39cceb2..2b5a4b7bd660fb6e 100644 +--- a/localedata/locales/sah_RU ++++ b/localedata/locales/sah_RU +@@ -1,7 +1,7 @@ + escape_char / + comment_char % + +-% Yakut (Sakha) locale for Russian Federation ++% Sakha (Yakut) locale for Russian Federation + % Source: Valery Timiriliyev + % Email: timiriliyev@gmail.com + % Tel: +@@ -13,14 +13,14 @@ comment_char % + % Users: general + + LC_IDENTIFICATION +-title "Yakut (Sakha) locale for Russian Federation" ++title "Sakha (Yakut) locale for Russian Federation" + source "Valery Timiriliyev" + address "" + contact "Valery Timiriliyev" + email "timiriliyev@gmail.com" + tel "" + fax "" +-language "Yakut" ++language "Sakha" + territory "Russian Federation" + revision "1.1.0" + date "2018-07-06" +@@ -264,11 +264,11 @@ END LC_NAME + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" + +-% Россия +-country_name "" ++% Арассыыйа ++country_name "" + +-% Саха тыла +-lang_name " " ++% саха тыла ++lang_name "" + + % UN Geneve 1949:68 Distinguishing signs of vehicles in international traffic + % RUS +diff --git a/localedata/locales/sat_IN b/localedata/locales/sat_IN +index 134eb8a572c836a7..e1775a4072ff7d9c 100644 +--- a/localedata/locales/sat_IN ++++ b/localedata/locales/sat_IN +@@ -158,12 +158,13 @@ END LC_NAME + LC_ADDRESS + + postal_fmt "%z%c%T%s%b%e%r" ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 + country_car "IND" +-% Satār +-lang_name "Satr" ++% ᱥᱟᱱᱛᱟᱲᱤ ++lang_name "" + lang_term "sat" + lang_lib "sat" + END LC_ADDRESS +diff --git a/localedata/locales/sc_IT b/localedata/locales/sc_IT +index 1488744575dae32a..32626404d2956e8c 100644 +--- a/localedata/locales/sc_IT ++++ b/localedata/locales/sc_IT +@@ -144,7 +144,7 @@ country_ab3 "ITA" + country_num 380 + country_isbn "978-88,979-12" + country_car "I" +-lang_name "Sardu" ++lang_name "sardu" + lang_ab "sc" + lang_term "srd" + lang_lib "srd" +diff --git a/localedata/locales/sd_IN b/localedata/locales/sd_IN +index 66aa0e254cefe0d7..64c5366c31dcd818 100644 +--- a/localedata/locales/sd_IN ++++ b/localedata/locales/sd_IN +@@ -164,12 +164,14 @@ LC_ADDRESS + % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category + % generated by IBM Basic CountryPack Transformer. + postal_fmt "%z%c%T%s%b%e%r" +-% https://sd.wikipedia.org/wiki/%DA%80%D8%A7%D8%B1%D8%AA : "ڀارت" +-country_name "" ++% From cldr: انڊيا ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 + country_car "IND" ++% سنڌي ++lang_name "" + lang_ab "sd" + lang_term "snd" + lang_lib "snd" +diff --git a/localedata/locales/sd_IN@devanagari b/localedata/locales/sd_IN@devanagari +index b1ce87df93f9c3d6..97357e08559ea64f 100644 +--- a/localedata/locales/sd_IN@devanagari ++++ b/localedata/locales/sd_IN@devanagari +@@ -167,6 +167,8 @@ country_ab2 "IN" + country_ab3 "IND" + country_num 356 + country_car "IND" ++% सिन्धी ++lang_name "" + lang_ab "sd" + lang_term "snd" + lang_lib "snd" +diff --git a/localedata/locales/shn_MM b/localedata/locales/shn_MM +index 4212c50ec5ae0066..a837f5fb394b1bb5 100644 +--- a/localedata/locales/shn_MM ++++ b/localedata/locales/shn_MM +@@ -281,7 +281,8 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%a%N%d%N%f%N%b%N%h%t%r%t%e%t%s%N%T%t%z%N%c%N" +-country_name "" ++% https://shn.wikipedia.org/wiki/%E1%80%99%E1%80%AD%E1%80%B0%E1%80%84%E1%80%BA%E1%80%B8%E1%80%99%E1%81%A2%E1%81%BC%E1%80%BA%E1%82%88 မိူင်းမၢၼ်ႈ ++country_name "" + country_post "Myanmar" + country_ab2 "MM" + country_num 104 +diff --git a/localedata/locales/shs_CA b/localedata/locales/shs_CA +index a5b675a316945608..ab48d600ef72ba75 100644 +--- a/localedata/locales/shs_CA ++++ b/localedata/locales/shs_CA +@@ -8,7 +8,7 @@ escape_char / + % exempt you from the conditions of the license if your use would + % otherwise be governed by that license. + +-% Secwepemctsin (Shuswap) language locale for Canada ++% Shuswap language locale for Canada + % sorting according to CAN/CSA-Z243.4.1-1992 + % Source: Neskie Manuel + % Address: 745 Ska-Hiish Dr +@@ -25,14 +25,14 @@ escape_char / + % Users: general + + LC_IDENTIFICATION +-title "Secwepemctsin locale for Canada" ++title "Shuswap locale for Canada" + source "Neskie Manuel" + address "745 Ska-Hiish Dr, Chase BC V0E 1M3" + contact "" + email "bug-glibc-locales@gnu.org" + tel "" + fax "" +-language "Secwepemctsin" ++language "Shuswap" + territory "Canada" + revision "1.0" + date "2008-01-15" +@@ -155,7 +155,7 @@ country_ab2 "CA" + country_ab3 "CAN" + country_num 124 + country_car "CDN" +-lang_name "Secwepemctsin" ++lang_name "Secwepemctsn" + lang_term "shs" + lang_lib "shs" + END LC_ADDRESS +diff --git a/localedata/locales/sm_WS b/localedata/locales/sm_WS +index 6058fbdc38283bb2..2823005c0635b6cf 100644 +--- a/localedata/locales/sm_WS ++++ b/localedata/locales/sm_WS +@@ -159,7 +159,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N" +-country_name "Samoa" ++country_name "Smoa" + country_post "%a %N %f %N %d %N %b %N %h %s %e %/ + r %N %T, %c %N" + % http://laendercode.net/en/2-letter-list.html +diff --git a/localedata/locales/ss_ZA b/localedata/locales/ss_ZA +index 7532a1940b3556f9..8e08a85f461aed9b 100644 +--- a/localedata/locales/ss_ZA ++++ b/localedata/locales/ss_ZA +@@ -228,7 +228,7 @@ country_car "ZA" + % country_isbn "" + + % Language name in Swati +-lang_name "SiSwati" ++lang_name "siSwati" + + % ISO 639 two and three letter language names + % see http://www.loc.gov/standards/iso639-2/englangn.html +diff --git a/localedata/locales/szl_PL b/localedata/locales/szl_PL +index 8d5de2112e54b7ad..88f1df4e905c5bdf 100644 +--- a/localedata/locales/szl_PL ++++ b/localedata/locales/szl_PL +@@ -188,6 +188,7 @@ END LC_NAME + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" ++country_name "Polska" + country_ab2 "PL" + country_ab3 "POL" + country_num 616 +diff --git a/localedata/locales/te_IN b/localedata/locales/te_IN +index fb5bb21b09ae0647..cb1b1109690b20bb 100644 +--- a/localedata/locales/te_IN ++++ b/localedata/locales/te_IN +@@ -177,7 +177,7 @@ LC_ADDRESS + % generated by IBM Basic CountryPack Transformer. + + postal_fmt "%a%N%d%N%f%N%r%t%e%N%h%t%b%N%s%t%N%T%t%z%N%S%N%c" +-country_name " " ++country_name "" + country_ab2 "IN" + country_ab3 "IND" + country_num 356 +diff --git a/localedata/locales/tg_TJ b/localedata/locales/tg_TJ +index 35dfca4574d4b5b9..6d1e4d8ab339501f 100644 +--- a/localedata/locales/tg_TJ ++++ b/localedata/locales/tg_TJ +@@ -222,6 +222,8 @@ country_ab2 "TJ" + country_ab3 "TJK" + country_num 762 + country_car "TJ" ++% тоҷикӣ ++lang_name "" + lang_ab "tg" + lang_term "tgk" + lang_lib "tgk" +diff --git a/localedata/locales/the_NP b/localedata/locales/the_NP +index 993e62fbfc5cea64..296e9970885ee490 100644 +--- a/localedata/locales/the_NP ++++ b/localedata/locales/the_NP +@@ -162,10 +162,14 @@ LC_ADDRESS + postal_fmt "%z%c%T%s%b%e%r" + lang_term "the" + lang_lib "the" ++% नेपाल ++country_name "" + country_ab2 "NP" + country_ab3 "NPL" + country_num 524 + country_car "NEP" ++% थारु ++lang_name "" + END LC_ADDRESS + + +diff --git a/localedata/locales/tk_TM b/localedata/locales/tk_TM +index 410afaf6c76c920b..e29ae20408763196 100644 +--- a/localedata/locales/tk_TM ++++ b/localedata/locales/tk_TM +@@ -399,7 +399,7 @@ country_num 795 + country_ab2 "TM" + country_ab3 "TKM" + % Türkmençe +-lang_name "trkmene" ++lang_name "trkmen dili" + lang_term "tuk" + lang_lib "tuk" + lang_ab "tk" +diff --git a/localedata/locales/tl_PH b/localedata/locales/tl_PH +index 40fd71d96095be12..03b8350749ab2c0a 100644 +--- a/localedata/locales/tl_PH ++++ b/localedata/locales/tl_PH +@@ -138,6 +138,7 @@ country_ab2 "PH" + country_ab3 "PHL" + country_num 608 + country_car "RP" ++lang_name "Tagalog" + lang_ab "tl" + lang_term "tgl" + lang_lib "tgl" +diff --git a/localedata/locales/to_TO b/localedata/locales/to_TO +index 7abe8685df8488cf..403a1219126bb189 100644 +--- a/localedata/locales/to_TO ++++ b/localedata/locales/to_TO +@@ -169,7 +169,7 @@ country_ab3 "TON" + country_car "TON" + country_num 776 + % Tongan +-lang_name "Tonga" ++lang_name "lea fakatonga" + % https://en.wikipedia.org/wiki/Tongan_language + lang_ab "to" + lang_term "ton" +diff --git a/localedata/locales/tpi_PG b/localedata/locales/tpi_PG +index 3315c27633ba58c6..885481974c8b531b 100644 +--- a/localedata/locales/tpi_PG ++++ b/localedata/locales/tpi_PG +@@ -172,7 +172,8 @@ END LC_NAME + LC_ADDRESS + % http://www.addressexamples.com/papua-new-guinea-address-format/ + postal_fmt "%a%s%z%C" +-country_name "Papua New Guinea" ++% https://tpi.wikipedia.org/wiki/Papua_Niugini ++country_name "Papua Niugini" + country_post "" + country_ab2 "PG" + country_ab3 "PNG" +@@ -180,7 +181,7 @@ country_car "PNG" + % https://en.wikipedia.org/wiki/ISO_3166-1_numeric + country_num 598 + % Tok Pisin +-lang_name "Tok Pisin" ++lang_name "Tok Pisin" + % https://en.wikipedia.org/wiki/Tok_Pisin + lang_ab "" + lang_term "tpi" +diff --git a/localedata/locales/tt_RU@iqtelif b/localedata/locales/tt_RU@iqtelif +index d4737c888e41352b..b52b1299946f372f 100644 +--- a/localedata/locales/tt_RU@iqtelif ++++ b/localedata/locales/tt_RU@iqtelif +@@ -155,10 +155,12 @@ END LC_MEASUREMENT + + LC_ADDRESS + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" ++country_name "Urs Patahlq" + country_ab2 "RU" + country_ab3 "RUS" + country_num 643 + country_car "RUS" ++lang_name "tatar tele" + lang_ab "tt" + lang_term "tat" + lang_lib "tat" +diff --git a/localedata/locales/ug_CN b/localedata/locales/ug_CN +index 1ba583c588e074d2..acb8b68239c4a653 100644 +--- a/localedata/locales/ug_CN ++++ b/localedata/locales/ug_CN +@@ -195,6 +195,8 @@ country_ab3 "CHN" + country_num 156 + country_car "CHN" + country_isbn 7 ++% ئۇيغۇرچە ++lang_name "" + lang_ab "ug" + lang_term "uig" + lang_lib "uig" +diff --git a/localedata/locales/unm_US b/localedata/locales/unm_US +index 1e62c60443b83ec6..ef458e22dc195809 100644 +--- a/localedata/locales/unm_US ++++ b/localedata/locales/unm_US +@@ -139,7 +139,7 @@ country_ab3 "USA" + country_num 840 + country_car "USA" + country_isbn 0 +-% lang_name "" ++lang_name "Lenape" + % lang_ab "" + lang_term "unm" + lang_lib "unm" +diff --git a/localedata/locales/wa_BE b/localedata/locales/wa_BE +index e97493089eb287b0..afec10f41c8b1612 100644 +--- a/localedata/locales/wa_BE ++++ b/localedata/locales/wa_BE +@@ -44,7 +44,7 @@ country_ab3 "BEL" + country_num 056 + country_isbn "2" + country_car "B" +-lang_name "Walon" ++lang_name "walon" + lang_ab "wa" + lang_term "wln" + lang_lib "wln" +diff --git a/localedata/locales/wo_SN b/localedata/locales/wo_SN +index 47263d2eab6db94e..20190925034c9ab4 100644 +--- a/localedata/locales/wo_SN ++++ b/localedata/locales/wo_SN +@@ -161,6 +161,7 @@ country_ab2 "SN" + country_ab3 "SEN" + country_num 686 + country_car "SN" ++lang_name "Wolof" + lang_ab "wo" + lang_term "wol" + lang_lib "wol" +diff --git a/localedata/locales/xh_ZA b/localedata/locales/xh_ZA +index 4564137e851b0cda..327f7250987aaa57 100644 +--- a/localedata/locales/xh_ZA ++++ b/localedata/locales/xh_ZA +@@ -209,13 +209,13 @@ END LC_NAME + + LC_ADDRESS + % https://xh.wikipedia.org/wiki/UMzantsi_Afrika +-country_name "UMzantsi Afrika" ++country_name "uMzantsi Afrika" + % + % Abbreviated country postal name + country_post "ZA" + % + % Language name in Sotho +-lang_name "IsiXhosa" ++lang_name "isiXhosa" + + % UN Geneve 1949:68 Distinguishing signs of vehicles in international traffic + % http://www.unece.org/trans/conventn/disting-signs-5-2001.pdf +diff --git a/localedata/locales/yo_NG b/localedata/locales/yo_NG +index ec72d078bb7eab6d..a3102270bf0fd38b 100644 +--- a/localedata/locales/yo_NG ++++ b/localedata/locales/yo_NG +@@ -271,8 +271,8 @@ LC_ADDRESS + % "country designation for the keyword", + % "end of line + postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" +- +-country_name "Orlde Njr" ++% https://yo.wikipedia.org/wiki/N%C3%A0%C3%ACj%C3%ADr%C3%AD%C3%A0 and CLDR: Orilẹ̀-èdè Nàìjíríà ++country_name "Orild Njr" + + % Language name in Yoruba - "Yorùbá" + lang_name "d Yorb" +diff --git a/localedata/locales/yuw_PG b/localedata/locales/yuw_PG +index 0cb3cadf4ae485a1..55e787a5cdfc559f 100644 +--- a/localedata/locales/yuw_PG ++++ b/localedata/locales/yuw_PG +@@ -16,7 +16,7 @@ contact "Hannah Sarvasy" + email "nungon.localization@gmail.com" + tel "" + fax "" +-language "Yau/Nungon" ++language "Yau" + territory "Papua New Guinea" + revision "1.0" + date "2016-12-07" +@@ -133,8 +133,8 @@ country_ab2 "PG" + country_ab3 "PNG" + % ISO 3166-1 numeric code for PNG + country_num 598 +-% Yau/Nungon +-lang_name "Yau/Nungon" ++% See: https://en.wikipedia.org/wiki/Yau_language, the endonym seems to be Uruwa ++lang_name "Uruwa" + country_car "PNG" + lang_ab "" + lang_term "yuw" +diff --git a/localedata/locales/zh_HK b/localedata/locales/zh_HK +index c130878f3d6e0ace..e8097d6ed0704670 100644 +--- a/localedata/locales/zh_HK ++++ b/localedata/locales/zh_HK +@@ -178,6 +178,7 @@ country_ab2 "HK" + country_ab3 "HKG" + country_num 344 + country_car "HK" ++lang_name "" + lang_ab "zh" + lang_term "zho" + lang_lib "chi" +diff --git a/localedata/locales/zh_SG b/localedata/locales/zh_SG +index 2427cd3ead3583dc..472843c7f77b8ed6 100644 +--- a/localedata/locales/zh_SG ++++ b/localedata/locales/zh_SG +@@ -175,6 +175,7 @@ country_ab3 "SGP" + country_num 702 + % SGP + country_car "SGP" ++lang_name "" + lang_ab "zh" + lang_term "zho" + lang_lib "chi" diff --git a/SOURCES/glibc-rh1774114.patch b/SOURCES/glibc-rh1774114.patch new file mode 100644 index 0000000..bdee317 --- /dev/null +++ b/SOURCES/glibc-rh1774114.patch @@ -0,0 +1,85 @@ +commit 58e8f5fd2ba47b6dc47fd4d0a35e4175c7c87aaa +Author: Andreas Schwab +Date: Wed Oct 9 17:46:47 2019 +0200 + + ldconfig: handle .dynstr located in separate segment (bug 25087) + + To determine the load offset of the DT_STRTAB section search for the + segment containing it, instead of using the load offset of the first + segment. + +diff --git a/elf/readelflib.c b/elf/readelflib.c +index 5a1e2dc2dfa36599..8774e779f5abbfbb 100644 +--- a/elf/readelflib.c ++++ b/elf/readelflib.c +@@ -45,7 +45,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag, + { + int i; + unsigned int j; +- ElfW(Addr) loadaddr; + unsigned int dynamic_addr; + size_t dynamic_size; + char *program_interpreter; +@@ -87,7 +86,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag, + libc5/libc6. */ + *flag = FLAG_ELF; + +- loadaddr = -1; + dynamic_addr = 0; + dynamic_size = 0; + program_interpreter = NULL; +@@ -98,11 +96,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag, + + switch (segment->p_type) + { +- case PT_LOAD: +- if (loadaddr == (ElfW(Addr)) -1) +- loadaddr = segment->p_vaddr - segment->p_offset; +- break; +- + case PT_DYNAMIC: + if (dynamic_addr) + error (0, 0, _("more than one dynamic segment\n")); +@@ -176,11 +169,6 @@ process_elf_file (const char *file_name, const char *lib, int *flag, + } + + } +- if (loadaddr == (ElfW(Addr)) -1) +- { +- /* Very strange. */ +- loadaddr = 0; +- } + + /* Now we can read the dynamic sections. */ + if (dynamic_size == 0) +@@ -197,7 +185,29 @@ process_elf_file (const char *file_name, const char *lib, int *flag, + check_ptr (dyn_entry); + if (dyn_entry->d_tag == DT_STRTAB) + { +- dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); ++ /* Find the file offset of the segment containing the dynamic ++ string table. */ ++ ElfW(Off) loadoff = -1; ++ for (i = 0, segment = elf_pheader; ++ i < elf_header->e_phnum; i++, segment++) ++ { ++ if (segment->p_type == PT_LOAD ++ && dyn_entry->d_un.d_val >= segment->p_vaddr ++ && (dyn_entry->d_un.d_val - segment->p_vaddr ++ < segment->p_filesz)) ++ { ++ loadoff = segment->p_vaddr - segment->p_offset; ++ break; ++ } ++ } ++ if (loadoff == (ElfW(Off)) -1) ++ { ++ /* Very strange. */ ++ loadoff = 0; ++ } ++ ++ dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val ++ - loadoff); + check_ptr (dynamic_strings); + break; + } diff --git a/SOURCES/glibc-rh1774115.patch b/SOURCES/glibc-rh1774115.patch new file mode 100644 index 0000000..a660644 --- /dev/null +++ b/SOURCES/glibc-rh1774115.patch @@ -0,0 +1,103 @@ +Partial backport without the new tst-dlopen-aout-pie test. The test +fails because the a self-dlopen of a PIE binary succeeds, as commit +23d2e5faf0bca6d9b31bef4aa162b95ee64cbfc6 ("elf: Self-dlopen failure +with explict loader invocation [BZ #24900]") has not been backported. + +commit 77523d5e43cb5721c23855eb6045b0607a3b30a0 +Author: Florian Weimer +Date: Fri Oct 4 21:23:51 2019 +0200 + + elf: Assign TLS modid later during dlopen [BZ #24930] + + Commit a42faf59d6d9f82e5293a9ebcc26d9c9e562b12b ("Fix BZ #16634.") + attempted to fix a TLS modid consistency issue by adding additional + checks to the open_verify function. However, this is fragile + because open_verify cannot reliably predict whether + _dl_map_object_from_fd will later fail in the more complex cases + (such as memory allocation failures). Therefore, this commit + assigns the TLS modid as late as possible. At that point, the link + map pointer will eventually be passed to _dl_close, which will undo + the TLS modid assignment. + + Reviewed-by: Gabriel F. T. Gomes + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index bb839ef70ff46f37..b190b28e32e47391 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1134,27 +1134,21 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, + offset. We will adjust it later. */ + l->l_tls_initimage = (void *) ph->p_vaddr; + +- /* If not loading the initial set of shared libraries, +- check whether we should permit loading a TLS segment. */ +- if (__glibc_likely (l->l_type == lt_library) +- /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did +- not set up TLS data structures, so don't use them now. */ +- || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL)) +- { +- /* Assign the next available module ID. */ +- l->l_tls_modid = _dl_next_tls_modid (); +- break; +- } ++ /* l->l_tls_modid is assigned below, once there is no ++ possibility for failure. */ + ++ if (l->l_type != lt_library ++ && GL(dl_tls_dtv_slotinfo_list) == NULL) ++ { + #ifdef SHARED +- /* We are loading the executable itself when the dynamic +- linker was executed directly. The setup will happen +- later. Otherwise, the TLS data structures are already +- initialized, and we assigned a TLS modid above. */ +- assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0); ++ /* We are loading the executable itself when the dynamic ++ linker was executed directly. The setup will happen ++ later. */ ++ assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0); + #else +- assert (false && "TLS not initialized in static application"); ++ assert (false && "TLS not initialized in static application"); + #endif ++ } + break; + + case PT_GNU_STACK: +@@ -1395,6 +1389,18 @@ cannot enable executable stack as shared object requires"); + add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB]) + + l->l_info[DT_SONAME]->d_un.d_val)); + ++ /* _dl_close can only eventually undo the module ID assignment (via ++ remove_slotinfo) if this function returns a pointer to a link ++ map. Therefore, delay this step until all possibilities for ++ failure have been excluded. */ ++ if (l->l_tls_blocksize > 0 ++ && (__glibc_likely (l->l_type == lt_library) ++ /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did ++ not set up TLS data structures, so don't use them now. */ ++ || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL))) ++ /* Assign the next available module ID. */ ++ l->l_tls_modid = _dl_next_tls_modid (); ++ + #ifdef DL_AFTER_LOAD + DL_AFTER_LOAD (l); + #endif +@@ -1662,17 +1668,6 @@ open_verify (const char *name, int fd, + errstring = N_("only ET_DYN and ET_EXEC can be loaded"); + goto call_lose; + } +- else if (__glibc_unlikely (ehdr->e_type == ET_EXEC +- && (mode & __RTLD_OPENEXEC) == 0)) +- { +- /* BZ #16634. It is an error to dlopen ET_EXEC (unless +- __RTLD_OPENEXEC is explicitly set). We return error here +- so that code in _dl_map_object_from_fd does not try to set +- l_tls_modid for this module. */ +- +- errstring = N_("cannot dynamically load executable"); +- goto call_lose; +- } + else if (__glibc_unlikely (ehdr->e_phentsize != sizeof (ElfW(Phdr)))) + { + errstring = N_("ELF file's phentsize not the expected size"); diff --git a/SOURCES/glibc-rh1775819.patch b/SOURCES/glibc-rh1775819.patch new file mode 100644 index 0000000..a9e6338 --- /dev/null +++ b/SOURCES/glibc-rh1775819.patch @@ -0,0 +1,33 @@ +commit f55e312bcd6582b5ff68fdcc1781c7017796dc91 +Author: Florian Weimer +Date: Thu Nov 28 14:42:11 2019 +0100 + + libio: Disable vtable validation for pre-2.1 interposed handles [BZ #25203] + + Commit c402355dfa7807b8e0adb27c009135a7e2b9f1b0 ("libio: Disable + vtable validation in case of interposition [BZ #23313]") only covered + the interposable glibc 2.1 handles, in libio/stdfiles.c. The + parallel code in libio/oldstdfiles.c needs similar detection logic. + + Fixes (again) commit db3476aff19b75c4fdefbe65fcd5f0a90588ba51 + ("libio: Implement vtable verification [BZ #20191]"). + + Change-Id: Ief6f9f17e91d1f7263421c56a7dc018f4f595c21 + (cherry picked from commit cb61630ed712d033f54295f776967532d3f4b46a) + +diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c +index f3dda89004..9fe809bd68 100644 +--- a/libio/oldstdfiles.c ++++ b/libio/oldstdfiles.c +@@ -87,6 +87,11 @@ _IO_check_libio (void) + stdout->_vtable_offset = stderr->_vtable_offset = + ((int) sizeof (struct _IO_FILE) + - (int) sizeof (struct _IO_FILE_complete)); ++ ++ if (_IO_stdin_.vtable != &_IO_old_file_jumps ++ || _IO_stdout_.vtable != &_IO_old_file_jumps ++ || _IO_stderr_.vtable != &_IO_old_file_jumps) ++ IO_set_accept_foreign_vtables (&_IO_vtable_check); + } + } + diff --git a/SOURCES/glibc-rh1780204-01.patch b/SOURCES/glibc-rh1780204-01.patch new file mode 100644 index 0000000..33a1752 --- /dev/null +++ b/SOURCES/glibc-rh1780204-01.patch @@ -0,0 +1,48 @@ +From 34e75eb497941f829115e6e8f34e899575f4e342 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Fri, 18 Oct 2019 14:57:14 +0200 +Subject: [PATCH 01/28] S390: Add new s390 platform z15. + +The new IBM z15 is added to platform string array. +The macro _DL_PLATFORMS_COUNT is incremented. + +(cherry picked from commit 2901743568452403849be7295c8732faa7732339) +--- + sysdeps/s390/dl-procinfo.c | 4 ++-- + sysdeps/s390/dl-procinfo.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index 6ea220a171..6d76d7d008 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -63,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[19][9] + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_platforms + #else +-PROCINFO_CLASS const char _dl_s390_platforms[9][7] ++PROCINFO_CLASS const char _dl_s390_platforms[10][7] + #endif + #ifndef PROCINFO_DECL + = { +- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14" ++ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index d03c69fffd..b367bbe8ce 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -23,7 +23,7 @@ + + #define _DL_HWCAP_COUNT 19 + +-#define _DL_PLATFORMS_COUNT 9 ++#define _DL_PLATFORMS_COUNT 10 + + /* The kernel provides up to 32 capability bits with elf_hwcap. */ + #define _DL_FIRST_PLATFORM 32 +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-02.patch b/SOURCES/glibc-rh1780204-02.patch new file mode 100644 index 0000000..e9d2ea3 --- /dev/null +++ b/SOURCES/glibc-rh1780204-02.patch @@ -0,0 +1,159 @@ +From 73f98d03d2cde34255c0a39ef18902bffdce0185 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:14 +0100 +Subject: [PATCH 02/28] Always use wordsize-64 version of s_rint.c. + +This patch replaces s_rint.c in sysdeps/dbl-64 with the one in +sysdeps/dbl-64/wordsize-64 and removes the latter one. +The code is not changed except changes in code style. + +Also adjusted the include path in x86_64 file. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit ab48bdd098a675dddb360faafc497a61c4bd4334) +--- + sysdeps/ieee754/dbl-64/s_rint.c | 32 ++++++------ + sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c | 57 --------------------- + sysdeps/x86_64/fpu/multiarch/s_rint-c.c | 2 +- + 3 files changed, 17 insertions(+), 74 deletions(-) + delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c + +diff --git a/sysdeps/ieee754/dbl-64/s_rint.c b/sysdeps/ieee754/dbl-64/s_rint.c +index cb0f5ca298..7f3dc87b96 100644 +--- a/sysdeps/ieee754/dbl-64/s_rint.c ++++ b/sysdeps/ieee754/dbl-64/s_rint.c +@@ -1,4 +1,3 @@ +-/* @(#)s_rint.c 5.1 93/09/24 */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +@@ -25,38 +24,39 @@ + #include + + static const double +- TWO52[2] = { +- 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ +- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ ++TWO52[2] = { ++ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ ++ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ + }; + + double + __rint (double x) + { +- int32_t i0, j0, sx; +- double w, t; +- GET_HIGH_WORD (i0, x); +- sx = (i0 >> 31) & 1; +- j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; ++ int64_t i0, sx; ++ int32_t j0; ++ EXTRACT_WORDS64 (i0, x); ++ sx = (i0 >> 63) & 1; ++ j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; + if (j0 < 52) + { + if (j0 < 0) + { +- w = TWO52[sx] + x; +- t = w - TWO52[sx]; +- GET_HIGH_WORD (i0, t); +- SET_HIGH_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); ++ double w = TWO52[sx] + x; ++ double t = w - TWO52[sx]; ++ EXTRACT_WORDS64 (i0, t); ++ INSERT_WORDS64 (t, (i0 & UINT64_C (0x7fffffffffffffff)) ++ | (sx << 63)); + return t; + } + } + else + { + if (j0 == 0x400) +- return x + x; /* inf or NaN */ ++ return x + x; /* inf or NaN */ + else +- return x; /* x is integral */ ++ return x; /* x is integral */ + } +- w = TWO52[sx] + x; ++ double w = TWO52[sx] + x; + return w - TWO52[sx]; + } + #ifndef __rint +diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c +deleted file mode 100644 +index 622e479c5f..0000000000 +--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c ++++ /dev/null +@@ -1,57 +0,0 @@ +-/* +- * ==================================================== +- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +- * +- * Developed at SunPro, a Sun Microsystems, Inc. business. +- * Permission to use, copy, modify, and distribute this +- * software is freely granted, provided that this notice +- * is preserved. +- * ==================================================== +- */ +- +-/* +- * rint(x) +- * Return x rounded to integral value according to the prevailing +- * rounding mode. +- * Method: +- * Using floating addition. +- * Exception: +- * Inexact flag raised if x not equal to rint(x). +- */ +- +-#include +-#include +-#include +- +-static const double +-TWO52[2]={ +- 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ +- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +-}; +- +-double +-__rint(double x) +-{ +- int64_t i0,sx; +- int32_t j0; +- EXTRACT_WORDS64(i0,x); +- sx = (i0>>63)&1; +- j0 = ((i0>>52)&0x7ff)-0x3ff; +- if(j0<52) { +- if(j0<0) { +- double w = TWO52[sx]+x; +- double t = w-TWO52[sx]; +- EXTRACT_WORDS64(i0,t); +- INSERT_WORDS64(t,(i0&UINT64_C(0x7fffffffffffffff))|(sx<<63)); +- return t; +- } +- } else { +- if(j0==0x400) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ +- } +- double w = TWO52[sx]+x; +- return w-TWO52[sx]; +-} +-#ifndef __rint +-libm_alias_double (__rint, rint) +-#endif +diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-c.c b/sysdeps/x86_64/fpu/multiarch/s_rint-c.c +index 162a630ff9..b010150f52 100644 +--- a/sysdeps/x86_64/fpu/multiarch/s_rint-c.c ++++ b/sysdeps/x86_64/fpu/multiarch/s_rint-c.c +@@ -1,3 +1,3 @@ + #undef __rint + #define __rint __rint_c +-#include ++#include +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-03.patch b/SOURCES/glibc-rh1780204-03.patch new file mode 100644 index 0000000..1e5d46f --- /dev/null +++ b/SOURCES/glibc-rh1780204-03.patch @@ -0,0 +1,257 @@ +From 7741c9c7f566d09f57db45df9377ac497f6232a5 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:15 +0100 +Subject: [PATCH 03/28] Always use wordsize-64 version of s_floor.c. + +This patch replaces s_floor.c in sysdeps/dbl-64 with the one in +sysdeps/dbl-64/wordsize-64 and removes the latter one. +The code is not changed except changes in code style. + +Also adjusted the include path in x86_64 and sparc64 files. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 95b0c2c431510013eb2f7385fc078ee2498f83bf) +Note: glibc 2.28 had no NO_MATH_REDIRECT in wordsize-64 version. +--- + sysdeps/ieee754/dbl-64/s_floor.c | 92 +++++++++---------- + sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c | 71 -------------- + .../sparc64/fpu/multiarch/s_floor-generic.c | 2 +- + .../sparc64/fpu/multiarch/s_floor-vis3.c | 2 +- + sysdeps/x86_64/fpu/multiarch/s_floor-c.c | 2 +- + 5 files changed, 45 insertions(+), 124 deletions(-) + delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c + +diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c +index f27c6f3ad2..b551a1aafa 100644 +--- a/sysdeps/ieee754/dbl-64/s_floor.c ++++ b/sysdeps/ieee754/dbl-64/s_floor.c +@@ -1,4 +1,24 @@ +-/* @(#)s_floor.c 5.1 93/09/24 */ ++/* Round double to integer away from zero. ++ Copyright (C) 2011-2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Ulrich Drepper , 2011. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Based on a version which carries the following copyright: */ ++ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +@@ -10,6 +30,11 @@ + * ==================================================== + */ + ++#include ++#include ++#include ++#include ++ + /* + * floor(x) + * Return x rounded toward -inf to integral value +@@ -17,68 +42,35 @@ + * Bit twiddling. + */ + +-#include +-#include +-#include +- + double + __floor (double x) + { +- int32_t i0, i1, j0; +- uint32_t i, j; +- EXTRACT_WORDS (i0, i1, x); +- j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; +- if (j0 < 20) ++ int64_t i0; ++ EXTRACT_WORDS64 (i0, x); ++ int32_t j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; ++ if (__glibc_likely (j0 < 52)) + { + if (j0 < 0) + { +- /* return 0*sign(x) if |x|<1 */ ++ /* return 0 * sign (x) if |x| < 1 */ + if (i0 >= 0) +- { +- i0 = i1 = 0; +- } +- else if (((i0 & 0x7fffffff) | i1) != 0) +- { +- i0 = 0xbff00000; i1 = 0; +- } ++ i0 = 0; ++ else if ((i0 & 0x7fffffffffffffffl) != 0) ++ i0 = 0xbff0000000000000l; + } + else + { +- i = (0x000fffff) >> j0; +- if (((i0 & i) | i1) == 0) +- return x; /* x is integral */ ++ uint64_t i = 0x000fffffffffffffl >> j0; ++ if ((i0 & i) == 0) ++ return x; /* x is integral */ + if (i0 < 0) +- i0 += (0x00100000) >> j0; +- i0 &= (~i); i1 = 0; +- } +- } +- else if (j0 > 51) +- { +- if (j0 == 0x400) +- return x + x; /* inf or NaN */ +- else +- return x; /* x is integral */ +- } +- else +- { +- i = ((uint32_t) (0xffffffff)) >> (j0 - 20); +- if ((i1 & i) == 0) +- return x; /* x is integral */ +- if (i0 < 0) +- { +- if (j0 == 20) +- i0 += 1; +- else +- { +- j = i1 + (1 << (52 - j0)); +- if (j < i1) +- i0 += 1; /* got a carry */ +- i1 = j; +- } ++ i0 += 0x0010000000000000l >> j0; ++ i0 &= ~i; + } +- i1 &= (~i); ++ INSERT_WORDS64 (x, i0); + } +- INSERT_WORDS (x, i0, i1); ++ else if (j0 == 0x400) ++ return x + x; /* inf or NaN */ + return x; + } + #ifndef __floor +diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c +deleted file mode 100644 +index f7e0a77ec3..0000000000 +--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c ++++ /dev/null +@@ -1,71 +0,0 @@ +-/* Round double to integer away from zero. +- Copyright (C) 2011-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2011. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* Based on a version which carries the following copyright: */ +- +-/* +- * ==================================================== +- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +- * +- * Developed at SunPro, a Sun Microsystems, Inc. business. +- * Permission to use, copy, modify, and distribute this +- * software is freely granted, provided that this notice +- * is preserved. +- * ==================================================== +- */ +- +-#include +-#include +-#include +-#include +- +-/* +- * floor(x) +- * Return x rounded toward -inf to integral value +- * Method: +- * Bit twiddling. +- */ +- +- +-double +-__floor (double x) +-{ +- int64_t i0; +- EXTRACT_WORDS64(i0,x); +- int32_t j0 = ((i0>>52)&0x7ff)-0x3ff; +- if(__builtin_expect(j0<52, 1)) { +- if(j0<0) { +- /* return 0*sign(x) if |x|<1 */ +- if(i0>=0) {i0=0;} +- else if((i0&0x7fffffffffffffffl)!=0) +- { i0=0xbff0000000000000l;} +- } else { +- uint64_t i = (0x000fffffffffffffl)>>j0; +- if((i0&i)==0) return x; /* x is integral */ +- if(i0<0) i0 += (0x0010000000000000l)>>j0; +- i0 &= (~i); +- } +- INSERT_WORDS64(x,i0); +- } else if (j0==0x400) +- return x+x; /* inf or NaN */ +- return x; +-} +-#ifndef __floor +-libm_alias_double (__floor, floor) +-#endif +diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c +index 0f3361a9fb..c92b600df1 100644 +--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c ++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c +@@ -1,2 +1,2 @@ + #define __floor __floor_generic +-#include ++#include +diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c +index d9974161b0..35564b9139 100644 +--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c ++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c +@@ -20,4 +20,4 @@ + + #define __floor __floor_vis3 + +-#include ++#include +diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c b/sysdeps/x86_64/fpu/multiarch/s_floor-c.c +index 68733b69ef..002d12247e 100644 +--- a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c ++++ b/sysdeps/x86_64/fpu/multiarch/s_floor-c.c +@@ -1,3 +1,3 @@ + #undef __floor + #define __floor __floor_c +-#include ++#include +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-04.patch b/SOURCES/glibc-rh1780204-04.patch new file mode 100644 index 0000000..e447d66 --- /dev/null +++ b/SOURCES/glibc-rh1780204-04.patch @@ -0,0 +1,192 @@ +From d3833cb69c7ff42ac8df68ed7b646c98c3a32eb8 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:16 +0100 +Subject: [PATCH 04/28] Always use wordsize-64 version of s_ceil.c. + +This patch replaces s_ceil.c in sysdeps/dbl-64 with the one in +sysdeps/dbl-64/wordsize-64 and removes the latter one. +The code is not changed except changes in code style. + +Also adjusted the include path in x86_64 and sparc64 files. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 9f234eafe8698fd9a441ca2309a299d0bd771156) +--- + sysdeps/ieee754/dbl-64/s_ceil.c | 59 ++++++------------- + sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c | 51 ---------------- + .../sparc64/fpu/multiarch/s_ceil-generic.c | 2 +- + .../sparc/sparc64/fpu/multiarch/s_ceil-vis3.c | 2 +- + sysdeps/x86_64/fpu/multiarch/s_ceil-c.c | 2 +- + 5 files changed, 21 insertions(+), 95 deletions(-) + delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c + +diff --git a/sysdeps/ieee754/dbl-64/s_ceil.c b/sysdeps/ieee754/dbl-64/s_ceil.c +index 5a7434c737..3becdfc515 100644 +--- a/sysdeps/ieee754/dbl-64/s_ceil.c ++++ b/sysdeps/ieee754/dbl-64/s_ceil.c +@@ -24,61 +24,38 @@ + double + __ceil (double x) + { +- int32_t i0, i1, j0; +- uint32_t i, j; +- EXTRACT_WORDS (i0, i1, x); +- j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; +- if (j0 < 20) ++ int64_t i0, i; ++ int32_t j0; ++ EXTRACT_WORDS64 (i0, x); ++ j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; ++ if (j0 <= 51) + { + if (j0 < 0) + { +- /* return 0*sign(x) if |x|<1 */ ++ /* return 0 * sign(x) if |x| < 1 */ + if (i0 < 0) +- { +- i0 = 0x80000000; i1 = 0; +- } +- else if ((i0 | i1) != 0) +- { +- i0 = 0x3ff00000; i1 = 0; +- } ++ i0 = INT64_C (0x8000000000000000); ++ else if (i0 != 0) ++ i0 = INT64_C (0x3ff0000000000000); + } + else + { +- i = (0x000fffff) >> j0; +- if (((i0 & i) | i1) == 0) +- return x; /* x is integral */ ++ i = INT64_C (0x000fffffffffffff) >> j0; ++ if ((i0 & i) == 0) ++ return x; /* x is integral */ + if (i0 > 0) +- i0 += (0x00100000) >> j0; +- i0 &= (~i); i1 = 0; ++ i0 += UINT64_C (0x0010000000000000) >> j0; ++ i0 &= ~i; + } + } +- else if (j0 > 51) ++ else + { + if (j0 == 0x400) +- return x + x; /* inf or NaN */ ++ return x + x; /* inf or NaN */ + else +- return x; /* x is integral */ +- } +- else +- { +- i = ((uint32_t) (0xffffffff)) >> (j0 - 20); +- if ((i1 & i) == 0) +- return x; /* x is integral */ +- if (i0 > 0) +- { +- if (j0 == 20) +- i0 += 1; +- else +- { +- j = i1 + (1 << (52 - j0)); +- if (j < i1) +- i0 += 1; /* got a carry */ +- i1 = j; +- } +- } +- i1 &= (~i); ++ return x; /* x is integral */ + } +- INSERT_WORDS (x, i0, i1); ++ INSERT_WORDS64 (x, i0); + return x; + } + #ifndef __ceil +diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c +deleted file mode 100644 +index b99829d2b0..0000000000 +--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c ++++ /dev/null +@@ -1,51 +0,0 @@ +-/* @(#)s_ceil.c 5.1 93/09/24 */ +-/* +- * ==================================================== +- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +- * +- * Developed at SunPro, a Sun Microsystems, Inc. business. +- * Permission to use, copy, modify, and distribute this +- * software is freely granted, provided that this notice +- * is preserved. +- * ==================================================== +- */ +- +-/* +- * ceil(x) +- * Return x rounded toward -inf to integral value +- * Method: +- * Bit twiddling. +- */ +- +-#include +-#include +-#include +- +-double +-__ceil(double x) +-{ +- int64_t i0,i; +- int32_t j0; +- EXTRACT_WORDS64(i0,x); +- j0 = ((i0>>52)&0x7ff)-0x3ff; +- if(j0<=51) { +- if(j0<0) { +- /* return 0*sign(x) if |x|<1 */ +- if(i0<0) {i0=INT64_C(0x8000000000000000);} +- else if(i0!=0) { i0=INT64_C(0x3ff0000000000000);} +- } else { +- i = INT64_C(0x000fffffffffffff)>>j0; +- if((i0&i)==0) return x; /* x is integral */ +- if(i0>0) i0 += UINT64_C(0x0010000000000000)>>j0; +- i0 &= (~i); +- } +- } else { +- if(j0==0x400) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ +- } +- INSERT_WORDS64(x,i0); +- return x; +-} +-#ifndef __ceil +-libm_alias_double (__ceil, ceil) +-#endif +diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c +index febea745e1..80f68b6766 100644 +--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c ++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c +@@ -1,2 +1,2 @@ + #define __ceil __ceil_generic +-#include ++#include +diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c +index a03a0090f0..59822e0f8c 100644 +--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c ++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c +@@ -20,4 +20,4 @@ + + #define __ceil __ceil_vis3 + +-#include ++#include +diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c b/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c +index 6a5ea3ff27..ada28baa1a 100644 +--- a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c ++++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c +@@ -1,2 +1,2 @@ + #define __ceil __ceil_c +-#include ++#include +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-05.patch b/SOURCES/glibc-rh1780204-05.patch new file mode 100644 index 0000000..3c139a2 --- /dev/null +++ b/SOURCES/glibc-rh1780204-05.patch @@ -0,0 +1,157 @@ +From e8f1c08a49d313b210ed4104c20646c105bab6a4 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:17 +0100 +Subject: [PATCH 05/28] Always use wordsize-64 version of s_trunc.c. + +This patch replaces s_trunc.c in sysdeps/dbl-64 with the one in +sysdeps/dbl-64/wordsize-64 and removes the latter one. +The code is not changed except changes in code style. + +Also adjusted the include path in x86_64 and sparc64 files. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 1c94bf0f0a50ce66c808e2ea9b7e417785798b73) +--- + sysdeps/ieee754/dbl-64/s_trunc.c | 25 ++++----- + sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c | 54 ------------------- + .../sparc64/fpu/multiarch/s_trunc-generic.c | 2 +- + .../sparc64/fpu/multiarch/s_trunc-vis3.c | 2 +- + sysdeps/x86_64/fpu/multiarch/s_trunc-c.c | 2 +- + 5 files changed, 13 insertions(+), 72 deletions(-) + delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c + +diff --git a/sysdeps/ieee754/dbl-64/s_trunc.c b/sysdeps/ieee754/dbl-64/s_trunc.c +index 6ffabb410a..38bb33d337 100644 +--- a/sysdeps/ieee754/dbl-64/s_trunc.c ++++ b/sysdeps/ieee754/dbl-64/s_trunc.c +@@ -26,31 +26,26 @@ + double + __trunc (double x) + { +- int32_t i0, j0; +- uint32_t i1; +- int sx; +- +- EXTRACT_WORDS (i0, i1, x); +- sx = i0 & 0x80000000; +- j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; +- if (j0 < 20) ++ int64_t i0, j0; ++ int64_t sx; ++ ++ EXTRACT_WORDS64 (i0, x); ++ sx = i0 & UINT64_C (0x8000000000000000); ++ j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; ++ if (j0 < 52) + { + if (j0 < 0) + /* The magnitude of the number is < 1 so the result is +-0. */ +- INSERT_WORDS (x, sx, 0); ++ INSERT_WORDS64 (x, sx); + else +- INSERT_WORDS (x, sx | (i0 & ~(0x000fffff >> j0)), 0); ++ INSERT_WORDS64 (x, sx | (i0 & ~(UINT64_C (0x000fffffffffffff) >> j0))); + } +- else if (j0 > 51) ++ else + { + if (j0 == 0x400) + /* x is inf or NaN. */ + return x + x; + } +- else +- { +- INSERT_WORDS (x, i0, i1 & ~(0xffffffffu >> (j0 - 20))); +- } + + return x; + } +diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c +deleted file mode 100644 +index 19a09b894e..0000000000 +--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* Truncate argument to nearest integral value not larger than the argument. +- Copyright (C) 1997-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 1997. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-#include +-#include +- +- +-double +-__trunc (double x) +-{ +- int64_t i0, j0; +- int64_t sx; +- +- EXTRACT_WORDS64 (i0, x); +- sx = i0 & UINT64_C(0x8000000000000000); +- j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; +- if (j0 < 52) +- { +- if (j0 < 0) +- /* The magnitude of the number is < 1 so the result is +-0. */ +- INSERT_WORDS64 (x, sx); +- else +- INSERT_WORDS64 (x, sx | (i0 & ~(UINT64_C(0x000fffffffffffff) >> j0))); +- } +- else +- { +- if (j0 == 0x400) +- /* x is inf or NaN. */ +- return x + x; +- } +- +- return x; +-} +-#ifndef __trunc +-libm_alias_double (__trunc, trunc) +-#endif +diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c +index 00abd2a643..c198ebb3d5 100644 +--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c ++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c +@@ -1,2 +1,2 @@ + #define __trunc __trunc_generic +-#include ++#include +diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c +index a89916ba89..766bb22629 100644 +--- a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c ++++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c +@@ -20,4 +20,4 @@ + + #define __trunc __trunc_vis3 + +-#include ++#include +diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c b/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c +index 6204ae3c77..8aa499fbb8 100644 +--- a/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c ++++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c +@@ -1,2 +1,2 @@ + #define __trunc __trunc_c +-#include ++#include +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-06.patch b/SOURCES/glibc-rh1780204-06.patch new file mode 100644 index 0000000..b0d1765 --- /dev/null +++ b/SOURCES/glibc-rh1780204-06.patch @@ -0,0 +1,167 @@ +From 577943dac79a5657bdfe51e06e289eb2473c3d2e Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:17 +0100 +Subject: [PATCH 06/28] Always use wordsize-64 version of s_round.c. + +This patch replaces s_round.c in sysdeps/dbl-64 with the one in +sysdeps/dbl-64/wordsize-64 and removes the latter one. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 36e9acbd5cb2c330c0d53195db4a0ee31f2c3097) +--- + sysdeps/ieee754/dbl-64/s_round.c | 39 ++++-------- + sysdeps/ieee754/dbl-64/wordsize-64/s_round.c | 65 -------------------- + 2 files changed, 12 insertions(+), 92 deletions(-) + delete mode 100644 sysdeps/ieee754/dbl-64/wordsize-64/s_round.c + +diff --git a/sysdeps/ieee754/dbl-64/s_round.c b/sysdeps/ieee754/dbl-64/s_round.c +index fa9e83196e..bf9922edca 100644 +--- a/sysdeps/ieee754/dbl-64/s_round.c ++++ b/sysdeps/ieee754/dbl-64/s_round.c +@@ -21,38 +21,36 @@ + + #include + #include ++#include + + + double + __round (double x) + { +- int32_t i0, j0; +- uint32_t i1; ++ int64_t i0, j0; + +- EXTRACT_WORDS (i0, i1, x); +- j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; +- if (j0 < 20) ++ EXTRACT_WORDS64 (i0, x); ++ j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; ++ if (__glibc_likely (j0 < 52)) + { + if (j0 < 0) + { +- i0 &= 0x80000000; ++ i0 &= UINT64_C (0x8000000000000000); + if (j0 == -1) +- i0 |= 0x3ff00000; +- i1 = 0; ++ i0 |= UINT64_C (0x3ff0000000000000); + } + else + { +- uint32_t i = 0x000fffff >> j0; +- if (((i0 & i) | i1) == 0) ++ uint64_t i = UINT64_C (0x000fffffffffffff) >> j0; ++ if ((i0 & i) == 0) + /* X is integral. */ + return x; + +- i0 += 0x00080000 >> j0; ++ i0 += UINT64_C (0x0008000000000000) >> j0; + i0 &= ~i; +- i1 = 0; + } + } +- else if (j0 > 51) ++ else + { + if (j0 == 0x400) + /* Inf or NaN. */ +@@ -60,21 +58,8 @@ __round (double x) + else + return x; + } +- else +- { +- uint32_t i = 0xffffffff >> (j0 - 20); +- if ((i1 & i) == 0) +- /* X is integral. */ +- return x; +- +- uint32_t j = i1 + (1 << (51 - j0)); +- if (j < i1) +- i0 += 1; +- i1 = j; +- i1 &= ~i; +- } + +- INSERT_WORDS (x, i0, i1); ++ INSERT_WORDS64 (x, i0); + return x; + } + libm_alias_double (__round, round) +diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c +deleted file mode 100644 +index 3323621ce3..0000000000 +--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c ++++ /dev/null +@@ -1,65 +0,0 @@ +-/* Round double to integer away from zero. +- Copyright (C) 1997-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 1997. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-#include +-#include +-#include +- +- +-double +-__round (double x) +-{ +- int64_t i0, j0; +- +- EXTRACT_WORDS64 (i0, x); +- j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; +- if (__glibc_likely (j0 < 52)) +- { +- if (j0 < 0) +- { +- i0 &= UINT64_C(0x8000000000000000); +- if (j0 == -1) +- i0 |= UINT64_C(0x3ff0000000000000); +- } +- else +- { +- uint64_t i = UINT64_C(0x000fffffffffffff) >> j0; +- if ((i0 & i) == 0) +- /* X is integral. */ +- return x; +- +- i0 += UINT64_C(0x0008000000000000) >> j0; +- i0 &= ~i; +- } +- } +- else +- { +- if (j0 == 0x400) +- /* Inf or NaN. */ +- return x + x; +- else +- return x; +- } +- +- INSERT_WORDS64 (x, i0); +- return x; +-} +-libm_alias_double (__round, round) +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-07.patch b/SOURCES/glibc-rh1780204-07.patch new file mode 100644 index 0000000..13b3c3e --- /dev/null +++ b/SOURCES/glibc-rh1780204-07.patch @@ -0,0 +1,255 @@ +From 735a36828f349419379f15e942bfdf0c532d58eb Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:18 +0100 +Subject: [PATCH 07/28] Use GCC builtins for nearbyint functions if desired. + +This patch is using the corresponding GCC builtin for nearbyintf, nearbyint, +nearbintl and nearbyintf128 if the USE_FUNCTION_BUILTIN macros are defined to one +in math-use-builtins.h. + +This is the case for s390 if build with at least --march=z196 --mzarch. +Otherwise the generic implementation is used. The code of the generic +implementation is not changed. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit ae3577f607b50bf3ce9b0877e43ad2508c9da61b) +Note: The TWO52 constants are now located in # ! USE_NEARBYINT_BUILTIN +--- + sysdeps/generic/math-use-builtins.h | 29 ++++++++++++ + sysdeps/ieee754/dbl-64/s_nearbyint.c | 17 ++++--- + sysdeps/ieee754/float128/float128_private.h | 4 ++ + sysdeps/ieee754/flt-32/s_nearbyintf.c | 17 ++++--- + sysdeps/ieee754/ldbl-128/s_nearbyintl.c | 17 ++++--- + sysdeps/s390/fpu/math-use-builtins.h | 49 +++++++++++++++++++++ + 6 files changed, 115 insertions(+), 18 deletions(-) + create mode 100644 sysdeps/generic/math-use-builtins.h + create mode 100644 sysdeps/s390/fpu/math-use-builtins.h + +diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h +new file mode 100644 +index 0000000000..e12490ed41 +--- /dev/null ++++ b/sysdeps/generic/math-use-builtins.h +@@ -0,0 +1,29 @@ ++/* Using math gcc builtins instead of generic implementation. Generic version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef MATH_USE_BUILTINS_H ++#define MATH_USE_BUILTINS_H 1 ++ ++/* Define these macros to 1 to use __builtin_xyz instead of the ++ generic implementation. */ ++#define USE_NEARBYINT_BUILTIN 0 ++#define USE_NEARBYINTF_BUILTIN 0 ++#define USE_NEARBYINTL_BUILTIN 0 ++#define USE_NEARBYINTF128_BUILTIN 0 ++ ++#endif /* math-use-builtins.h */ +diff --git a/sysdeps/ieee754/dbl-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/s_nearbyint.c +index 903121d456..6b9f44dc8d 100644 +--- a/sysdeps/ieee754/dbl-64/s_nearbyint.c ++++ b/sysdeps/ieee754/dbl-64/s_nearbyint.c +@@ -29,16 +29,20 @@ static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; + #include + #include + #include +- +-static const double +- TWO52[2] = { +- 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ +- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +-}; ++#include + + double + __nearbyint (double x) + { ++#if USE_NEARBYINT_BUILTIN ++ return __builtin_nearbyint (x); ++#else ++ /* Use generic implementation. */ ++ static const double ++ TWO52[2] = { ++ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ ++ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ ++ }; + fenv_t env; + int32_t i0, j0, sx; + double w, t; +@@ -72,5 +76,6 @@ __nearbyint (double x) + math_force_eval (t); + libc_fesetenv (&env); + return t; ++#endif /* ! USE_NEARBYINT_BUILTIN */ + } + libm_alias_double (__nearbyint, nearbyint) +diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h +index 9dd15601e6..0bf6e8dee2 100644 +--- a/sysdeps/ieee754/float128/float128_private.h ++++ b/sysdeps/ieee754/float128/float128_private.h +@@ -138,6 +138,9 @@ + #undef libm_alias_double_ldouble + #define libm_alias_double_ldouble(func) libm_alias_float64_float128 (func) + ++#include ++#undef USE_NEARBYINTL_BUILTIN ++#define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN + + /* IEEE function renames. */ + #define __ieee754_acoshl __ieee754_acoshf128 +@@ -339,6 +342,7 @@ + /* Builtin renames. */ + #define __builtin_copysignl __builtin_copysignf128 + #define __builtin_signbitl __builtin_signbit ++#define __builtin_nearbyintl __builtin_nearbyintf128 + + /* Get the constant suffix from bits/floatn-compat.h. */ + #define L(x) __f128 (x) +diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c +index 4dfe491f27..438dcae8cc 100644 +--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c ++++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c +@@ -20,16 +20,20 @@ + #include + #include + #include +- +-static const float +-TWO23[2]={ +- 8.3886080000e+06, /* 0x4b000000 */ +- -8.3886080000e+06, /* 0xcb000000 */ +-}; ++#include + + float + __nearbyintf(float x) + { ++#if USE_NEARBYINTF_BUILTIN ++ return __builtin_nearbyintf (x); ++#else ++ /* Use generic implementation. */ ++ static const float ++ TWO23[2] = { ++ 8.3886080000e+06, /* 0x4b000000 */ ++ -8.3886080000e+06, /* 0xcb000000 */ ++ }; + fenv_t env; + int32_t i0,j0,sx; + float w,t; +@@ -57,5 +61,6 @@ __nearbyintf(float x) + math_force_eval (t); + libc_fesetenvf (&env); + return t; ++#endif /* ! USE_NEARBYINT_BUILTIN */ + } + libm_alias_float (__nearbyint, nearbyint) +diff --git a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c +index f044cb4334..a4ad8e82e5 100644 +--- a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c ++++ b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c +@@ -28,15 +28,19 @@ + #include + #include + #include +- +-static const _Float128 +-TWO112[2]={ +- L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */ +- L(-5.19229685853482762853049632922009600E+33) /* 0xC06F000000000000, 0 */ +-}; ++#include + + _Float128 __nearbyintl(_Float128 x) + { ++#if USE_NEARBYINTL_BUILTIN ++ return __builtin_nearbyintl (x); ++#else ++ /* Use generic implementation. */ ++ static const _Float128 ++ TWO112[2] = { ++ L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */ ++ L(-5.19229685853482762853049632922009600E+33) /* 0xC06F000000000000, 0 */ ++ }; + fenv_t env; + int64_t i0,j0,sx; + uint64_t i1 __attribute__ ((unused)); +@@ -65,5 +69,6 @@ _Float128 __nearbyintl(_Float128 x) + math_force_eval (t); + fesetenv (&env); + return t; ++#endif /* ! USE_NEARBYINTL_BUILTIN */ + } + libm_alias_ldouble (__nearbyint, nearbyint) +diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h +new file mode 100644 +index 0000000000..7abbfb3b50 +--- /dev/null ++++ b/sysdeps/s390/fpu/math-use-builtins.h +@@ -0,0 +1,49 @@ ++/* Using math gcc builtins instead of generic implementation. s390/s390x version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef MATH_USE_BUILTINS_S390_H ++#define MATH_USE_BUILTINS_S390_H 1 ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++ ++# include /* For __GNUC_PREREQ. */ ++ ++/* GCC emits the z196 zarch "load fp integer" instructions for these ++ builtins if build with at least --march=z196 -mzarch. Otherwise a ++ function call to libc is emitted. */ ++# define USE_NEARBYINT_BUILTIN 1 ++# define USE_NEARBYINTF_BUILTIN 1 ++# define USE_NEARBYINTL_BUILTIN 1 ++ ++# if __GNUC_PREREQ (8, 0) ++# define USE_NEARBYINTF128_BUILTIN 1 ++# else ++# define USE_NEARBYINTF128_BUILTIN 0 ++# endif ++ ++#else ++ ++/* Disable the builtins if we do not have the z196 zarch instructions. */ ++# define USE_NEARBYINT_BUILTIN 0 ++# define USE_NEARBYINTF_BUILTIN 0 ++# define USE_NEARBYINTL_BUILTIN 0 ++# define USE_NEARBYINTF128_BUILTIN 0 ++ ++#endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ ++ ++#endif /* math-use-builtins.h */ +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-08.patch b/SOURCES/glibc-rh1780204-08.patch new file mode 100644 index 0000000..9dd3a6c --- /dev/null +++ b/SOURCES/glibc-rh1780204-08.patch @@ -0,0 +1,210 @@ +From d37e99de7ab1cd8c3d427f74bf8ceb5774795fe5 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:20 +0100 +Subject: [PATCH 08/28] Use GCC builtins for rint functions if desired. + +This patch is using the corresponding GCC builtin for rintf, rint, +rintl and rintf128 if the USE_FUNCTION_BUILTIN macros are defined to one +in math-use-builtins.h. + +This is the case for s390 if build with at least --march=z196 --mzarch. +Otherwise the generic implementation is used. The code of the generic +implementation is not changed. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit a2a9b004297b777758420c952cb6eea5985d37fe) +--- + sysdeps/generic/math-use-builtins.h | 5 +++++ + sysdeps/ieee754/dbl-64/s_rint.c | 17 +++++++++++------ + sysdeps/ieee754/float128/float128_private.h | 3 +++ + sysdeps/ieee754/flt-32/s_rintf.c | 17 +++++++++++------ + sysdeps/ieee754/ldbl-128/s_rintl.c | 17 +++++++++++------ + sysdeps/s390/fpu/math-use-builtins.h | 11 +++++++++++ + 6 files changed, 52 insertions(+), 18 deletions(-) + +diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h +index e12490ed41..64b4a4bb5b 100644 +--- a/sysdeps/generic/math-use-builtins.h ++++ b/sysdeps/generic/math-use-builtins.h +@@ -26,4 +26,9 @@ + #define USE_NEARBYINTL_BUILTIN 0 + #define USE_NEARBYINTF128_BUILTIN 0 + ++#define USE_RINT_BUILTIN 0 ++#define USE_RINTF_BUILTIN 0 ++#define USE_RINTL_BUILTIN 0 ++#define USE_RINTF128_BUILTIN 0 ++ + #endif /* math-use-builtins.h */ +diff --git a/sysdeps/ieee754/dbl-64/s_rint.c b/sysdeps/ieee754/dbl-64/s_rint.c +index 7f3dc87b96..5f4ac7c1e3 100644 +--- a/sysdeps/ieee754/dbl-64/s_rint.c ++++ b/sysdeps/ieee754/dbl-64/s_rint.c +@@ -22,16 +22,20 @@ + #include + #include + #include +- +-static const double +-TWO52[2] = { +- 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ +- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +-}; ++#include + + double + __rint (double x) + { ++#if USE_RINT_BUILTIN ++ return __builtin_rint (x); ++#else ++ /* Use generic implementation. */ ++ static const double ++ TWO52[2] = { ++ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ ++ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ ++ }; + int64_t i0, sx; + int32_t j0; + EXTRACT_WORDS64 (i0, x); +@@ -58,6 +62,7 @@ __rint (double x) + } + double w = TWO52[sx] + x; + return w - TWO52[sx]; ++#endif /* ! USE_RINT_BUILTIN */ + } + #ifndef __rint + libm_alias_double (__rint, rint) +diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h +index 0bf6e8dee2..b872aefbfd 100644 +--- a/sysdeps/ieee754/float128/float128_private.h ++++ b/sysdeps/ieee754/float128/float128_private.h +@@ -141,6 +141,8 @@ + #include + #undef USE_NEARBYINTL_BUILTIN + #define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN ++#undef USE_RINTL_BUILTIN ++#define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN + + /* IEEE function renames. */ + #define __ieee754_acoshl __ieee754_acoshf128 +@@ -343,6 +345,7 @@ + #define __builtin_copysignl __builtin_copysignf128 + #define __builtin_signbitl __builtin_signbit + #define __builtin_nearbyintl __builtin_nearbyintf128 ++#define __builtin_rintl __builtin_rintf128 + + /* Get the constant suffix from bits/floatn-compat.h. */ + #define L(x) __f128 (x) +diff --git a/sysdeps/ieee754/flt-32/s_rintf.c b/sysdeps/ieee754/flt-32/s_rintf.c +index db6f260a0b..a266b1999e 100644 +--- a/sysdeps/ieee754/flt-32/s_rintf.c ++++ b/sysdeps/ieee754/flt-32/s_rintf.c +@@ -16,16 +16,20 @@ + #include + #include + #include +- +-static const float +-TWO23[2]={ +- 8.3886080000e+06, /* 0x4b000000 */ +- -8.3886080000e+06, /* 0xcb000000 */ +-}; ++#include + + float + __rintf(float x) + { ++#if USE_RINTF_BUILTIN ++ return __builtin_rintf (x); ++#else ++ /* Use generic implementation. */ ++ static const float ++ TWO23[2] = { ++ 8.3886080000e+06, /* 0x4b000000 */ ++ -8.3886080000e+06, /* 0xcb000000 */ ++ }; + int32_t i0,j0,sx; + float w,t; + GET_FLOAT_WORD(i0,x); +@@ -45,6 +49,7 @@ __rintf(float x) + } + w = TWO23[sx]+x; + return w-TWO23[sx]; ++#endif /* ! USE_RINTF_BUILTIN */ + } + #ifndef __rintf + libm_alias_float (__rint, rint) +diff --git a/sysdeps/ieee754/ldbl-128/s_rintl.c b/sysdeps/ieee754/ldbl-128/s_rintl.c +index 9e6637a225..f060503066 100644 +--- a/sysdeps/ieee754/ldbl-128/s_rintl.c ++++ b/sysdeps/ieee754/ldbl-128/s_rintl.c +@@ -30,15 +30,19 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + #include +- +-static const _Float128 +-TWO112[2]={ +- 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */ +- -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */ +-}; ++#include + + _Float128 __rintl(_Float128 x) + { ++#if USE_RINTL_BUILTIN ++ return __builtin_rintl (x); ++#else ++ /* Use generic implementation. */ ++ static const _Float128 ++ TWO112[2] = { ++ 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */ ++ -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */ ++ }; + int64_t i0,j0,sx; + uint64_t i1 __attribute__ ((unused)); + _Float128 w,t; +@@ -59,5 +63,6 @@ _Float128 __rintl(_Float128 x) + } + w = TWO112[sx]+x; + return w-TWO112[sx]; ++#endif /* ! USE_RINTL_BUILTIN */ + } + libm_alias_ldouble (__rint, rint) +diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h +index 7abbfb3b50..8b702a6a90 100644 +--- a/sysdeps/s390/fpu/math-use-builtins.h ++++ b/sysdeps/s390/fpu/math-use-builtins.h +@@ -30,10 +30,16 @@ + # define USE_NEARBYINTF_BUILTIN 1 + # define USE_NEARBYINTL_BUILTIN 1 + ++# define USE_RINT_BUILTIN 1 ++# define USE_RINTF_BUILTIN 1 ++# define USE_RINTL_BUILTIN 1 ++ + # if __GNUC_PREREQ (8, 0) + # define USE_NEARBYINTF128_BUILTIN 1 ++# define USE_RINTF128_BUILTIN 1 + # else + # define USE_NEARBYINTF128_BUILTIN 0 ++# define USE_RINTF128_BUILTIN 0 + # endif + + #else +@@ -44,6 +50,11 @@ + # define USE_NEARBYINTL_BUILTIN 0 + # define USE_NEARBYINTF128_BUILTIN 0 + ++# define USE_RINT_BUILTIN 0 ++# define USE_RINTF_BUILTIN 0 ++# define USE_RINTL_BUILTIN 0 ++# define USE_RINTF128_BUILTIN 0 ++ + #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ + + #endif /* math-use-builtins.h */ +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-09.patch b/SOURCES/glibc-rh1780204-09.patch new file mode 100644 index 0000000..fa6e2b6 --- /dev/null +++ b/SOURCES/glibc-rh1780204-09.patch @@ -0,0 +1,182 @@ +From 8353881ede286045dc5bdc00af6407560ca5d05b Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:20 +0100 +Subject: [PATCH 09/28] Use GCC builtins for floor functions if desired. + +This patch is using the corresponding GCC builtin for floorf, floor, +floorl and floorf128 if the USE_FUNCTION_BUILTIN macros are defined to one +in math-use-builtins.h. + +This is the case for s390 if build with at least --march=z196 --mzarch. +Otherwise the generic implementation is used. The code of the generic +implementation is not changed. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 6c1b6a5e8cd91e0e1965509ad91e627e60eb00a3) +--- + sysdeps/generic/math-use-builtins.h | 5 +++++ + sysdeps/ieee754/dbl-64/s_floor.c | 6 ++++++ + sysdeps/ieee754/float128/float128_private.h | 3 +++ + sysdeps/ieee754/flt-32/s_floorf.c | 6 ++++++ + sysdeps/ieee754/ldbl-128/s_floorl.c | 6 ++++++ + sysdeps/s390/fpu/math-use-builtins.h | 11 +++++++++++ + 6 files changed, 37 insertions(+) + +diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h +index 64b4a4bb5b..e1c5df62e4 100644 +--- a/sysdeps/generic/math-use-builtins.h ++++ b/sysdeps/generic/math-use-builtins.h +@@ -31,4 +31,9 @@ + #define USE_RINTL_BUILTIN 0 + #define USE_RINTF128_BUILTIN 0 + ++#define USE_FLOOR_BUILTIN 0 ++#define USE_FLOORF_BUILTIN 0 ++#define USE_FLOORL_BUILTIN 0 ++#define USE_FLOORF128_BUILTIN 0 ++ + #endif /* math-use-builtins.h */ +diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c +index b551a1aafa..693938b708 100644 +--- a/sysdeps/ieee754/dbl-64/s_floor.c ++++ b/sysdeps/ieee754/dbl-64/s_floor.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + /* + * floor(x) +@@ -45,6 +46,10 @@ + double + __floor (double x) + { ++#if USE_FLOOR_BUILTIN ++ return __builtin_floor (x); ++#else ++ /* Use generic implementation. */ + int64_t i0; + EXTRACT_WORDS64 (i0, x); + int32_t j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; +@@ -72,6 +77,7 @@ __floor (double x) + else if (j0 == 0x400) + return x + x; /* inf or NaN */ + return x; ++#endif /* ! USE_FLOOR_BUILTIN */ + } + #ifndef __floor + libm_alias_double (__floor, floor) +diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h +index b872aefbfd..667030ab06 100644 +--- a/sysdeps/ieee754/float128/float128_private.h ++++ b/sysdeps/ieee754/float128/float128_private.h +@@ -143,6 +143,8 @@ + #define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN + #undef USE_RINTL_BUILTIN + #define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN ++#undef USE_FLOORL_BUILTIN ++#define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN + + /* IEEE function renames. */ + #define __ieee754_acoshl __ieee754_acoshf128 +@@ -346,6 +348,7 @@ + #define __builtin_signbitl __builtin_signbit + #define __builtin_nearbyintl __builtin_nearbyintf128 + #define __builtin_rintl __builtin_rintf128 ++#define __builtin_floorl __builtin_floorf128 + + /* Get the constant suffix from bits/floatn-compat.h. */ + #define L(x) __f128 (x) +diff --git a/sysdeps/ieee754/flt-32/s_floorf.c b/sysdeps/ieee754/flt-32/s_floorf.c +index 12aed343a0..6d37ab90a1 100644 +--- a/sysdeps/ieee754/flt-32/s_floorf.c ++++ b/sysdeps/ieee754/flt-32/s_floorf.c +@@ -23,10 +23,15 @@ + #include + #include + #include ++#include + + float + __floorf(float x) + { ++#if USE_FLOORF_BUILTIN ++ return __builtin_floorf (x); ++#else ++ /* Use generic implementation. */ + int32_t i0,j0; + uint32_t i; + GET_FLOAT_WORD(i0,x); +@@ -49,6 +54,7 @@ __floorf(float x) + } + SET_FLOAT_WORD(x,i0); + return x; ++#endif /* ! USE_FLOORF_BUILTIN */ + } + #ifndef __floorf + libm_alias_float (__floor, floor) +diff --git a/sysdeps/ieee754/ldbl-128/s_floorl.c b/sysdeps/ieee754/ldbl-128/s_floorl.c +index f9c5e014f9..6143fe6ec5 100644 +--- a/sysdeps/ieee754/ldbl-128/s_floorl.c ++++ b/sysdeps/ieee754/ldbl-128/s_floorl.c +@@ -27,9 +27,14 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + #include ++#include + + _Float128 __floorl(_Float128 x) + { ++#if USE_FLOORL_BUILTIN ++ return __builtin_floorl (x); ++#else ++ /* Use generic implementation. */ + int64_t i0,i1,j0; + uint64_t i,j; + GET_LDOUBLE_WORDS64(i0,i1,x); +@@ -64,5 +69,6 @@ _Float128 __floorl(_Float128 x) + } + SET_LDOUBLE_WORDS64(x,i0,i1); + return x; ++#endif /* ! USE_FLOORL_BUILTIN */ + } + libm_alias_ldouble (__floor, floor) +diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h +index 8b702a6a90..c213c16c6f 100644 +--- a/sysdeps/s390/fpu/math-use-builtins.h ++++ b/sysdeps/s390/fpu/math-use-builtins.h +@@ -34,12 +34,18 @@ + # define USE_RINTF_BUILTIN 1 + # define USE_RINTL_BUILTIN 1 + ++# define USE_FLOOR_BUILTIN 1 ++# define USE_FLOORF_BUILTIN 1 ++# define USE_FLOORL_BUILTIN 1 ++ + # if __GNUC_PREREQ (8, 0) + # define USE_NEARBYINTF128_BUILTIN 1 + # define USE_RINTF128_BUILTIN 1 ++# define USE_FLOORF128_BUILTIN 1 + # else + # define USE_NEARBYINTF128_BUILTIN 0 + # define USE_RINTF128_BUILTIN 0 ++# define USE_FLOORF128_BUILTIN 0 + # endif + + #else +@@ -55,6 +61,11 @@ + # define USE_RINTL_BUILTIN 0 + # define USE_RINTF128_BUILTIN 0 + ++# define USE_FLOOR_BUILTIN 0 ++# define USE_FLOORF_BUILTIN 0 ++# define USE_FLOORL_BUILTIN 0 ++# define USE_FLOORF128_BUILTIN 0 ++ + #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ + + #endif /* math-use-builtins.h */ +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-10.patch b/SOURCES/glibc-rh1780204-10.patch new file mode 100644 index 0000000..3504976 --- /dev/null +++ b/SOURCES/glibc-rh1780204-10.patch @@ -0,0 +1,182 @@ +From 6c5e5f498cd004b3f42d97997898018df8f798a4 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:21 +0100 +Subject: [PATCH 10/28] Use GCC builtins for ceil functions if desired. + +This patch is using the corresponding GCC builtin for ceilf, ceil, +ceill and ceilf128 if the USE_FUNCTION_BUILTIN macros are defined to one +in math-use-builtins.h. + +This is the case for s390 if build with at least --march=z196 --mzarch. +Otherwise the generic implementation is used. The code of the generic +implementation is not changed. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 62560ee84095274bab1050817f42e782df226a17) +--- + sysdeps/generic/math-use-builtins.h | 5 +++++ + sysdeps/ieee754/dbl-64/s_ceil.c | 6 ++++++ + sysdeps/ieee754/float128/float128_private.h | 3 +++ + sysdeps/ieee754/flt-32/s_ceilf.c | 7 ++++++- + sysdeps/ieee754/ldbl-128/s_ceill.c | 6 ++++++ + sysdeps/s390/fpu/math-use-builtins.h | 11 +++++++++++ + 6 files changed, 37 insertions(+), 1 deletion(-) + +diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h +index e1c5df62e4..076ec661b0 100644 +--- a/sysdeps/generic/math-use-builtins.h ++++ b/sysdeps/generic/math-use-builtins.h +@@ -36,4 +36,9 @@ + #define USE_FLOORL_BUILTIN 0 + #define USE_FLOORF128_BUILTIN 0 + ++#define USE_CEIL_BUILTIN 0 ++#define USE_CEILF_BUILTIN 0 ++#define USE_CEILL_BUILTIN 0 ++#define USE_CEILF128_BUILTIN 0 ++ + #endif /* math-use-builtins.h */ +diff --git a/sysdeps/ieee754/dbl-64/s_ceil.c b/sysdeps/ieee754/dbl-64/s_ceil.c +index 3becdfc515..ee4a3abc19 100644 +--- a/sysdeps/ieee754/dbl-64/s_ceil.c ++++ b/sysdeps/ieee754/dbl-64/s_ceil.c +@@ -20,10 +20,15 @@ + #include + #include + #include ++#include + + double + __ceil (double x) + { ++#if USE_CEIL_BUILTIN ++ return __builtin_ceil (x); ++#else ++ /* Use generic implementation. */ + int64_t i0, i; + int32_t j0; + EXTRACT_WORDS64 (i0, x); +@@ -57,6 +62,7 @@ __ceil (double x) + } + INSERT_WORDS64 (x, i0); + return x; ++#endif /* ! USE_CEIL_BUILTIN */ + } + #ifndef __ceil + libm_alias_double (__ceil, ceil) +diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h +index 667030ab06..19352ca26c 100644 +--- a/sysdeps/ieee754/float128/float128_private.h ++++ b/sysdeps/ieee754/float128/float128_private.h +@@ -145,6 +145,8 @@ + #define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN + #undef USE_FLOORL_BUILTIN + #define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN ++#undef USE_CEILL_BUILTIN ++#define USE_CEILL_BUILTIN USE_CEILF128_BUILTIN + + /* IEEE function renames. */ + #define __ieee754_acoshl __ieee754_acoshf128 +@@ -349,6 +351,7 @@ + #define __builtin_nearbyintl __builtin_nearbyintf128 + #define __builtin_rintl __builtin_rintf128 + #define __builtin_floorl __builtin_floorf128 ++#define __builtin_ceill __builtin_ceilf128 + + /* Get the constant suffix from bits/floatn-compat.h. */ + #define L(x) __f128 (x) +diff --git a/sysdeps/ieee754/flt-32/s_ceilf.c b/sysdeps/ieee754/flt-32/s_ceilf.c +index f289ec2341..6cab7bdd62 100644 +--- a/sysdeps/ieee754/flt-32/s_ceilf.c ++++ b/sysdeps/ieee754/flt-32/s_ceilf.c +@@ -16,11 +16,15 @@ + #include + #include + #include +- ++#include + + float + __ceilf(float x) + { ++#if USE_CEILF_BUILTIN ++ return __builtin_ceilf (x); ++#else ++ /* Use generic implementation. */ + int32_t i0,j0; + uint32_t i; + +@@ -43,6 +47,7 @@ __ceilf(float x) + } + SET_FLOAT_WORD(x,i0); + return x; ++#endif /* ! USE_CEILF_BUILTIN */ + } + #ifndef __ceilf + libm_alias_float (__ceil, ceil) +diff --git a/sysdeps/ieee754/ldbl-128/s_ceill.c b/sysdeps/ieee754/ldbl-128/s_ceill.c +index e6aba5f2af..d212d86179 100644 +--- a/sysdeps/ieee754/ldbl-128/s_ceill.c ++++ b/sysdeps/ieee754/ldbl-128/s_ceill.c +@@ -27,9 +27,14 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + #include ++#include + + _Float128 __ceill(_Float128 x) + { ++#if USE_CEILL_BUILTIN ++ return __builtin_ceill (x); ++#else ++ /* Use generic implementation. */ + int64_t i0,i1,j0; + uint64_t i,j; + GET_LDOUBLE_WORDS64(i0,i1,x); +@@ -63,5 +68,6 @@ _Float128 __ceill(_Float128 x) + } + SET_LDOUBLE_WORDS64(x,i0,i1); + return x; ++#endif /* ! USE_CEILL_BUILTIN */ + } + libm_alias_ldouble (__ceil, ceil) +diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h +index c213c16c6f..5435cbb65f 100644 +--- a/sysdeps/s390/fpu/math-use-builtins.h ++++ b/sysdeps/s390/fpu/math-use-builtins.h +@@ -38,14 +38,20 @@ + # define USE_FLOORF_BUILTIN 1 + # define USE_FLOORL_BUILTIN 1 + ++# define USE_CEIL_BUILTIN 1 ++# define USE_CEILF_BUILTIN 1 ++# define USE_CEILL_BUILTIN 1 ++ + # if __GNUC_PREREQ (8, 0) + # define USE_NEARBYINTF128_BUILTIN 1 + # define USE_RINTF128_BUILTIN 1 + # define USE_FLOORF128_BUILTIN 1 ++# define USE_CEILF128_BUILTIN 1 + # else + # define USE_NEARBYINTF128_BUILTIN 0 + # define USE_RINTF128_BUILTIN 0 + # define USE_FLOORF128_BUILTIN 0 ++# define USE_CEILF128_BUILTIN 0 + # endif + + #else +@@ -66,6 +72,11 @@ + # define USE_FLOORL_BUILTIN 0 + # define USE_FLOORF128_BUILTIN 0 + ++# define USE_CEIL_BUILTIN 0 ++# define USE_CEILF_BUILTIN 0 ++# define USE_CEILL_BUILTIN 0 ++# define USE_CEILF128_BUILTIN 0 ++ + #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ + + #endif /* math-use-builtins.h */ +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-11.patch b/SOURCES/glibc-rh1780204-11.patch new file mode 100644 index 0000000..533d478 --- /dev/null +++ b/SOURCES/glibc-rh1780204-11.patch @@ -0,0 +1,187 @@ +From abc72a0694c1c3d08354170da343eead8d9afcc1 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:22 +0100 +Subject: [PATCH 11/28] Use GCC builtins for trunc functions if desired. + +This patch is using the corresponding GCC builtin for truncf, trunc, +truncl and truncf128 if the USE_FUNCTION_BUILTIN macros are defined to one +in math-use-builtins.h. + +This is the case for s390 if build with at least --march=z196 --mzarch. +Otherwise the generic implementation is used. The code of the generic +implementation is not changed. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 1ac9c1cf87216bf9f8ac4f7c9754d025d9f2c4ae) +--- + sysdeps/generic/math-use-builtins.h | 5 +++++ + sysdeps/ieee754/dbl-64/s_trunc.c | 6 ++++++ + sysdeps/ieee754/float128/float128_private.h | 3 +++ + sysdeps/ieee754/flt-32/s_truncf.c | 6 ++++++ + sysdeps/ieee754/ldbl-128/s_truncl.c | 6 ++++++ + sysdeps/s390/fpu/math-use-builtins.h | 11 +++++++++++ + 6 files changed, 37 insertions(+) + +diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h +index 076ec661b0..ab379f45ba 100644 +--- a/sysdeps/generic/math-use-builtins.h ++++ b/sysdeps/generic/math-use-builtins.h +@@ -41,4 +41,9 @@ + #define USE_CEILL_BUILTIN 0 + #define USE_CEILF128_BUILTIN 0 + ++#define USE_TRUNC_BUILTIN 0 ++#define USE_TRUNCF_BUILTIN 0 ++#define USE_TRUNCL_BUILTIN 0 ++#define USE_TRUNCF128_BUILTIN 0 ++ + #endif /* math-use-builtins.h */ +diff --git a/sysdeps/ieee754/dbl-64/s_trunc.c b/sysdeps/ieee754/dbl-64/s_trunc.c +index 38bb33d337..708169c727 100644 +--- a/sysdeps/ieee754/dbl-64/s_trunc.c ++++ b/sysdeps/ieee754/dbl-64/s_trunc.c +@@ -21,11 +21,16 @@ + + #include + #include ++#include + + + double + __trunc (double x) + { ++#if USE_TRUNC_BUILTIN ++ return __builtin_trunc (x); ++#else ++ /* Use generic implementation. */ + int64_t i0, j0; + int64_t sx; + +@@ -48,6 +53,7 @@ __trunc (double x) + } + + return x; ++#endif /* ! USE_TRUNC_BUILTIN */ + } + #ifndef __trunc + libm_alias_double (__trunc, trunc) +diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h +index 19352ca26c..e248600ec2 100644 +--- a/sysdeps/ieee754/float128/float128_private.h ++++ b/sysdeps/ieee754/float128/float128_private.h +@@ -147,6 +147,8 @@ + #define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN + #undef USE_CEILL_BUILTIN + #define USE_CEILL_BUILTIN USE_CEILF128_BUILTIN ++#undef USE_TRUNCL_BUILTIN ++#define USE_TRUNCL_BUILTIN USE_TRUNCF128_BUILTIN + + /* IEEE function renames. */ + #define __ieee754_acoshl __ieee754_acoshf128 +@@ -352,6 +354,7 @@ + #define __builtin_rintl __builtin_rintf128 + #define __builtin_floorl __builtin_floorf128 + #define __builtin_ceill __builtin_ceilf128 ++#define __builtin_truncl __builtin_truncf128 + + /* Get the constant suffix from bits/floatn-compat.h. */ + #define L(x) __f128 (x) +diff --git a/sysdeps/ieee754/flt-32/s_truncf.c b/sysdeps/ieee754/flt-32/s_truncf.c +index 2e1464aeac..71491e5175 100644 +--- a/sysdeps/ieee754/flt-32/s_truncf.c ++++ b/sysdeps/ieee754/flt-32/s_truncf.c +@@ -21,11 +21,16 @@ + + #include + #include ++#include + + + float + __truncf (float x) + { ++#if USE_TRUNCF_BUILTIN ++ return __builtin_truncf (x); ++#else ++ /* Use generic implementation. */ + int32_t i0, j0; + int sx; + +@@ -48,6 +53,7 @@ __truncf (float x) + } + + return x; ++#endif /* ! USE_TRUNCF_BUILTIN */ + } + #ifndef __truncf + libm_alias_float (__trunc, trunc) +diff --git a/sysdeps/ieee754/ldbl-128/s_truncl.c b/sysdeps/ieee754/ldbl-128/s_truncl.c +index f858ede3d2..aa49daaf85 100644 +--- a/sysdeps/ieee754/ldbl-128/s_truncl.c ++++ b/sysdeps/ieee754/ldbl-128/s_truncl.c +@@ -22,11 +22,16 @@ + + #include + #include ++#include + + + _Float128 + __truncl (_Float128 x) + { ++#if USE_TRUNCL_BUILTIN ++ return __builtin_truncl (x); ++#else ++ /* Use generic implementation. */ + int32_t j0; + uint64_t i0, i1, sx; + +@@ -53,5 +58,6 @@ __truncl (_Float128 x) + } + + return x; ++#endif /* ! USE_TRUNCL_BUILTIN */ + } + libm_alias_ldouble (__trunc, trunc) +diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h +index 5435cbb65f..a39715c612 100644 +--- a/sysdeps/s390/fpu/math-use-builtins.h ++++ b/sysdeps/s390/fpu/math-use-builtins.h +@@ -42,16 +42,22 @@ + # define USE_CEILF_BUILTIN 1 + # define USE_CEILL_BUILTIN 1 + ++# define USE_TRUNC_BUILTIN 1 ++# define USE_TRUNCF_BUILTIN 1 ++# define USE_TRUNCL_BUILTIN 1 ++ + # if __GNUC_PREREQ (8, 0) + # define USE_NEARBYINTF128_BUILTIN 1 + # define USE_RINTF128_BUILTIN 1 + # define USE_FLOORF128_BUILTIN 1 + # define USE_CEILF128_BUILTIN 1 ++# define USE_TRUNCF128_BUILTIN 1 + # else + # define USE_NEARBYINTF128_BUILTIN 0 + # define USE_RINTF128_BUILTIN 0 + # define USE_FLOORF128_BUILTIN 0 + # define USE_CEILF128_BUILTIN 0 ++# define USE_TRUNCF128_BUILTIN 0 + # endif + + #else +@@ -77,6 +83,11 @@ + # define USE_CEILL_BUILTIN 0 + # define USE_CEILF128_BUILTIN 0 + ++# define USE_TRUNC_BUILTIN 0 ++# define USE_TRUNCF_BUILTIN 0 ++# define USE_TRUNCL_BUILTIN 0 ++# define USE_TRUNCF128_BUILTIN 0 ++ + #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ + + #endif /* math-use-builtins.h */ +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-12.patch b/SOURCES/glibc-rh1780204-12.patch new file mode 100644 index 0000000..3b95873 --- /dev/null +++ b/SOURCES/glibc-rh1780204-12.patch @@ -0,0 +1,187 @@ +From f49dd4cc4e295803e517190d1798bd84561d56f4 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:24 +0100 +Subject: [PATCH 12/28] Use GCC builtins for round functions if desired. + +This patch is using the corresponding GCC builtin for roundf, round, +roundl and roundf128 if the USE_FUNCTION_BUILTIN macros are defined to one +in math-use-builtins.h. + +This is the case for s390 if build with at least --march=z196 --mzarch. +Otherwise the generic implementation is used. The code of the generic +implementation is not changed. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit f82996f8159981619ac7ed8a4c1838c2ad72ab61) +--- + sysdeps/generic/math-use-builtins.h | 5 +++++ + sysdeps/ieee754/dbl-64/s_round.c | 6 ++++++ + sysdeps/ieee754/float128/float128_private.h | 3 +++ + sysdeps/ieee754/flt-32/s_roundf.c | 6 ++++++ + sysdeps/ieee754/ldbl-128/s_roundl.c | 6 ++++++ + sysdeps/s390/fpu/math-use-builtins.h | 11 +++++++++++ + 6 files changed, 37 insertions(+) + +diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h +index ab379f45ba..34ca438a8c 100644 +--- a/sysdeps/generic/math-use-builtins.h ++++ b/sysdeps/generic/math-use-builtins.h +@@ -46,4 +46,9 @@ + #define USE_TRUNCL_BUILTIN 0 + #define USE_TRUNCF128_BUILTIN 0 + ++#define USE_ROUND_BUILTIN 0 ++#define USE_ROUNDF_BUILTIN 0 ++#define USE_ROUNDL_BUILTIN 0 ++#define USE_ROUNDF128_BUILTIN 0 ++ + #endif /* math-use-builtins.h */ +diff --git a/sysdeps/ieee754/dbl-64/s_round.c b/sysdeps/ieee754/dbl-64/s_round.c +index bf9922edca..1f8482adf8 100644 +--- a/sysdeps/ieee754/dbl-64/s_round.c ++++ b/sysdeps/ieee754/dbl-64/s_round.c +@@ -22,11 +22,16 @@ + #include + #include + #include ++#include + + + double + __round (double x) + { ++#if USE_ROUND_BUILTIN ++ return __builtin_round (x); ++#else ++ /* Use generic implementation. */ + int64_t i0, j0; + + EXTRACT_WORDS64 (i0, x); +@@ -61,5 +66,6 @@ __round (double x) + + INSERT_WORDS64 (x, i0); + return x; ++#endif /* ! USE_ROUND_BUILTIN */ + } + libm_alias_double (__round, round) +diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h +index e248600ec2..3297a71e44 100644 +--- a/sysdeps/ieee754/float128/float128_private.h ++++ b/sysdeps/ieee754/float128/float128_private.h +@@ -149,6 +149,8 @@ + #define USE_CEILL_BUILTIN USE_CEILF128_BUILTIN + #undef USE_TRUNCL_BUILTIN + #define USE_TRUNCL_BUILTIN USE_TRUNCF128_BUILTIN ++#undef USE_ROUNDL_BUILTIN ++#define USE_ROUNDL_BUILTIN USE_ROUNDF128_BUILTIN + + /* IEEE function renames. */ + #define __ieee754_acoshl __ieee754_acoshf128 +@@ -355,6 +357,7 @@ + #define __builtin_floorl __builtin_floorf128 + #define __builtin_ceill __builtin_ceilf128 + #define __builtin_truncl __builtin_truncf128 ++#define __builtin_roundl __builtin_roundf128 + + /* Get the constant suffix from bits/floatn-compat.h. */ + #define L(x) __f128 (x) +diff --git a/sysdeps/ieee754/flt-32/s_roundf.c b/sysdeps/ieee754/flt-32/s_roundf.c +index 7c95125d9c..6fdfbbbade 100644 +--- a/sysdeps/ieee754/flt-32/s_roundf.c ++++ b/sysdeps/ieee754/flt-32/s_roundf.c +@@ -21,11 +21,16 @@ + + #include + #include ++#include + + + float + __roundf (float x) + { ++#if USE_ROUNDF_BUILTIN ++ return __builtin_roundf (x); ++#else ++ /* Use generic implementation. */ + int32_t i0, j0; + + GET_FLOAT_WORD (i0, x); +@@ -60,5 +65,6 @@ __roundf (float x) + + SET_FLOAT_WORD (x, i0); + return x; ++#endif /* ! USE_ROUNDF_BUILTIN */ + } + libm_alias_float (__round, round) +diff --git a/sysdeps/ieee754/ldbl-128/s_roundl.c b/sysdeps/ieee754/ldbl-128/s_roundl.c +index 22789cedf3..564f8ac1b8 100644 +--- a/sysdeps/ieee754/ldbl-128/s_roundl.c ++++ b/sysdeps/ieee754/ldbl-128/s_roundl.c +@@ -22,11 +22,16 @@ + + #include + #include ++#include + + + _Float128 + __roundl (_Float128 x) + { ++#if USE_ROUNDL_BUILTIN ++ return __builtin_roundl (x); ++#else ++ /* Use generic implementation. */ + int32_t j0; + uint64_t i1, i0; + +@@ -77,5 +82,6 @@ __roundl (_Float128 x) + + SET_LDOUBLE_WORDS64 (x, i0, i1); + return x; ++#endif /* ! USE_ROUNDL_BUILTIN */ + } + libm_alias_ldouble (__round, round) +diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h +index a39715c612..51cb9f91ab 100644 +--- a/sysdeps/s390/fpu/math-use-builtins.h ++++ b/sysdeps/s390/fpu/math-use-builtins.h +@@ -46,18 +46,24 @@ + # define USE_TRUNCF_BUILTIN 1 + # define USE_TRUNCL_BUILTIN 1 + ++# define USE_ROUND_BUILTIN 1 ++# define USE_ROUNDF_BUILTIN 1 ++# define USE_ROUNDL_BUILTIN 1 ++ + # if __GNUC_PREREQ (8, 0) + # define USE_NEARBYINTF128_BUILTIN 1 + # define USE_RINTF128_BUILTIN 1 + # define USE_FLOORF128_BUILTIN 1 + # define USE_CEILF128_BUILTIN 1 + # define USE_TRUNCF128_BUILTIN 1 ++# define USE_ROUNDF128_BUILTIN 1 + # else + # define USE_NEARBYINTF128_BUILTIN 0 + # define USE_RINTF128_BUILTIN 0 + # define USE_FLOORF128_BUILTIN 0 + # define USE_CEILF128_BUILTIN 0 + # define USE_TRUNCF128_BUILTIN 0 ++# define USE_ROUNDF128_BUILTIN 0 + # endif + + #else +@@ -88,6 +94,11 @@ + # define USE_TRUNCL_BUILTIN 0 + # define USE_TRUNCF128_BUILTIN 0 + ++# define USE_ROUND_BUILTIN 0 ++# define USE_ROUNDF_BUILTIN 0 ++# define USE_ROUNDL_BUILTIN 0 ++# define USE_ROUNDF128_BUILTIN 0 ++ + #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ + + #endif /* math-use-builtins.h */ +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-13.patch b/SOURCES/glibc-rh1780204-13.patch new file mode 100644 index 0000000..72ed332 --- /dev/null +++ b/SOURCES/glibc-rh1780204-13.patch @@ -0,0 +1,177 @@ +From e93b17fad37a61f7ae9a663c617926b0f510921a Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:24 +0100 +Subject: [PATCH 13/28] Use GCC builtins for copysign functions if desired. + +This patch is always using the corresponding GCC builtin for copysignf, copysign, +and is using the builtin for copysignl, copysignf128 if the USE_FUNCTION_BUILTIN +macros are defined to one in math-use-builtins.h. + +Altough the long double version is enabled by default we still need +the macro and the alternative implementation as the _Float128 version +of the builtin is not available with all supported GCC versions. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit f818afdd3b29d7eef2010448457c9f5c16e684cd) +--- + sysdeps/generic/math-use-builtins.h | 9 +++++++++ + sysdeps/ieee754/dbl-64/s_copysign.c | 9 ++------- + sysdeps/ieee754/float128/float128_private.h | 3 +++ + sysdeps/ieee754/flt-32/s_copysignf.c | 12 ++++-------- + sysdeps/ieee754/ldbl-128/s_copysignl.c | 6 ++++++ + sysdeps/s390/fpu/math-use-builtins.h | 7 +++++++ + 6 files changed, 31 insertions(+), 15 deletions(-) + +diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h +index 34ca438a8c..770b54ce61 100644 +--- a/sysdeps/generic/math-use-builtins.h ++++ b/sysdeps/generic/math-use-builtins.h +@@ -19,6 +19,8 @@ + #ifndef MATH_USE_BUILTINS_H + #define MATH_USE_BUILTINS_H 1 + ++#include /* For __GNUC_PREREQ. */ ++ + /* Define these macros to 1 to use __builtin_xyz instead of the + generic implementation. */ + #define USE_NEARBYINT_BUILTIN 0 +@@ -51,4 +53,11 @@ + #define USE_ROUNDL_BUILTIN 0 + #define USE_ROUNDF128_BUILTIN 0 + ++#define USE_COPYSIGNL_BUILTIN 1 ++#if __GNUC_PREREQ (7, 0) ++# define USE_COPYSIGNF128_BUILTIN 1 ++#else ++# define USE_COPYSIGNF128_BUILTIN 0 ++#endif ++ + #endif /* math-use-builtins.h */ +diff --git a/sysdeps/ieee754/dbl-64/s_copysign.c b/sysdeps/ieee754/dbl-64/s_copysign.c +index ab81d732ab..b95f1575d9 100644 +--- a/sysdeps/ieee754/dbl-64/s_copysign.c ++++ b/sysdeps/ieee754/dbl-64/s_copysign.c +@@ -10,7 +10,7 @@ + * ==================================================== + */ + +-#if defined(LIBM_SCCS) && !defined(lint) ++#if defined (LIBM_SCCS) && ! defined (lint) + static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $"; + #endif + +@@ -21,16 +21,11 @@ static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $ + */ + + #include +-#include + #include + + double + __copysign (double x, double y) + { +- uint32_t hx, hy; +- GET_HIGH_WORD (hx, x); +- GET_HIGH_WORD (hy, y); +- SET_HIGH_WORD (x, (hx & 0x7fffffff) | (hy & 0x80000000)); +- return x; ++ return __builtin_copysign (x, y); + } + libm_alias_double (__copysign, copysign) +diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h +index 3297a71e44..077df0e09f 100644 +--- a/sysdeps/ieee754/float128/float128_private.h ++++ b/sysdeps/ieee754/float128/float128_private.h +@@ -151,6 +151,8 @@ + #define USE_TRUNCL_BUILTIN USE_TRUNCF128_BUILTIN + #undef USE_ROUNDL_BUILTIN + #define USE_ROUNDL_BUILTIN USE_ROUNDF128_BUILTIN ++#undef USE_COPYSIGNL_BUILTIN ++#define USE_COPYSIGNL_BUILTIN USE_COPYSIGNF128_BUILTIN + + /* IEEE function renames. */ + #define __ieee754_acoshl __ieee754_acoshf128 +@@ -358,6 +360,7 @@ + #define __builtin_ceill __builtin_ceilf128 + #define __builtin_truncl __builtin_truncf128 + #define __builtin_roundl __builtin_roundf128 ++#define __builtin_copysignl __builtin_copysignf128 + + /* Get the constant suffix from bits/floatn-compat.h. */ + #define L(x) __f128 (x) +diff --git a/sysdeps/ieee754/flt-32/s_copysignf.c b/sysdeps/ieee754/flt-32/s_copysignf.c +index 3c4ac7ce68..0247abd152 100644 +--- a/sysdeps/ieee754/flt-32/s_copysignf.c ++++ b/sysdeps/ieee754/flt-32/s_copysignf.c +@@ -13,7 +13,7 @@ + * ==================================================== + */ + +-#if defined(LIBM_SCCS) && !defined(lint) ++#if defined (LIBM_SCCS) && ! defined (lint) + static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4 1995/05/10 20:46:59 jtc Exp $"; + #endif + +@@ -24,15 +24,11 @@ static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4 1995/05/10 20:46:59 jtc Exp + */ + + #include +-#include + #include + +-float __copysignf(float x, float y) ++float ++__copysignf (float x, float y) + { +- uint32_t ix,iy; +- GET_FLOAT_WORD(ix,x); +- GET_FLOAT_WORD(iy,y); +- SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000)); +- return x; ++ return __builtin_copysignf (x, y); + } + libm_alias_float (__copysign, copysign) +diff --git a/sysdeps/ieee754/ldbl-128/s_copysignl.c b/sysdeps/ieee754/ldbl-128/s_copysignl.c +index d23e0f72ea..4cae8612dc 100644 +--- a/sysdeps/ieee754/ldbl-128/s_copysignl.c ++++ b/sysdeps/ieee754/ldbl-128/s_copysignl.c +@@ -26,14 +26,20 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + #include ++#include + + _Float128 __copysignl(_Float128 x, _Float128 y) + { ++#if USE_COPYSIGNL_BUILTIN ++ return __builtin_copysignl (x, y); ++#else ++ /* Use generic implementation. */ + uint64_t hx,hy; + GET_LDOUBLE_MSW64(hx,x); + GET_LDOUBLE_MSW64(hy,y); + SET_LDOUBLE_MSW64(x,(hx&0x7fffffffffffffffULL) + |(hy&0x8000000000000000ULL)); + return x; ++#endif /* ! USE_COPYSIGNL_BUILTIN */ + } + libm_alias_ldouble (__copysign, copysign) +diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h +index 51cb9f91ab..4c4aad2ab5 100644 +--- a/sysdeps/s390/fpu/math-use-builtins.h ++++ b/sysdeps/s390/fpu/math-use-builtins.h +@@ -101,4 +101,11 @@ + + #endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ + ++#define USE_COPYSIGNL_BUILTIN 1 ++#if __GNUC_PREREQ (7, 0) ++# define USE_COPYSIGNF128_BUILTIN 1 ++#else ++# define USE_COPYSIGNF128_BUILTIN 0 ++#endif ++ + #endif /* math-use-builtins.h */ +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-14.patch b/SOURCES/glibc-rh1780204-14.patch new file mode 100644 index 0000000..6e58c11 --- /dev/null +++ b/SOURCES/glibc-rh1780204-14.patch @@ -0,0 +1,180 @@ +From bd7c710d3b234a8d3bd77aae358bd7f7a6ce576d Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:25 +0100 +Subject: [PATCH 14/28] Adjust s_nearbyintf.c and s_nearbyintl.c regarding code + style. + +This patch just adjusts the generic implementation regarding code style. +No functional change. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 6a3866dae98cccc8cd7a0a4c1fb409dba9192a83) +--- + sysdeps/ieee754/flt-32/s_nearbyintf.c | 60 ++++++++++++----------- + sysdeps/ieee754/ldbl-128/s_nearbyintl.c | 63 ++++++++++++++----------- + 2 files changed, 68 insertions(+), 55 deletions(-) + +diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c +index 438dcae8cc..5969e3e5b8 100644 +--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c ++++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c +@@ -23,7 +23,7 @@ + #include + + float +-__nearbyintf(float x) ++__nearbyintf (float x) + { + #if USE_NEARBYINTF_BUILTIN + return __builtin_nearbyintf (x); +@@ -34,33 +34,39 @@ __nearbyintf(float x) + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ + }; +- fenv_t env; +- int32_t i0,j0,sx; +- float w,t; +- GET_FLOAT_WORD(i0,x); +- sx = (i0>>31)&1; +- j0 = ((i0>>23)&0xff)-0x7f; +- if(j0<23) { +- if(j0<0) { +- libc_feholdexceptf (&env); +- w = TWO23[sx] + math_opt_barrier (x); +- t = w-TWO23[sx]; +- math_force_eval (t); +- libc_fesetenvf (&env); +- GET_FLOAT_WORD(i0,t); +- SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); +- return t; +- } +- } else { +- if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ ++ fenv_t env; ++ int32_t i0, j0, sx; ++ float w, t; ++ GET_FLOAT_WORD (i0, x); ++ sx = (i0 >> 31) & 1; ++ j0 = ((i0 >> 23) & 0xff) - 0x7f; ++ if (j0 < 23) ++ { ++ if (j0 < 0) ++ { ++ libc_feholdexceptf (&env); ++ w = TWO23[sx] + math_opt_barrier (x); ++ t = w - TWO23[sx]; ++ math_force_eval (t); ++ libc_fesetenvf (&env); ++ GET_FLOAT_WORD (i0, t); ++ SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); ++ return t; + } +- libc_feholdexceptf (&env); +- w = TWO23[sx] + math_opt_barrier (x); +- t = w-TWO23[sx]; +- math_force_eval (t); +- libc_fesetenvf (&env); +- return t; ++ } ++ else ++ { ++ if (__glibc_unlikely (j0 == 0x80)) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ libc_feholdexceptf (&env); ++ w = TWO23[sx] + math_opt_barrier (x); ++ t = w - TWO23[sx]; ++ math_force_eval (t); ++ libc_fesetenvf (&env); ++ return t; + #endif /* ! USE_NEARBYINT_BUILTIN */ + } + libm_alias_float (__nearbyint, nearbyint) +diff --git a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c +index a4ad8e82e5..8d26786f78 100644 +--- a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c ++++ b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c +@@ -30,7 +30,8 @@ + #include + #include + +-_Float128 __nearbyintl(_Float128 x) ++_Float128 ++__nearbyintl (_Float128 x) + { + #if USE_NEARBYINTL_BUILTIN + return __builtin_nearbyintl (x); +@@ -41,34 +42,40 @@ _Float128 __nearbyintl(_Float128 x) + L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */ + L(-5.19229685853482762853049632922009600E+33) /* 0xC06F000000000000, 0 */ + }; +- fenv_t env; +- int64_t i0,j0,sx; +- uint64_t i1 __attribute__ ((unused)); +- _Float128 w,t; +- GET_LDOUBLE_WORDS64(i0,i1,x); +- sx = (((uint64_t)i0)>>63); +- j0 = ((i0>>48)&0x7fff)-0x3fff; +- if(j0<112) { +- if(j0<0) { +- feholdexcept (&env); +- w = TWO112[sx] + math_opt_barrier (x); +- t = w-TWO112[sx]; +- math_force_eval (t); +- fesetenv (&env); +- GET_LDOUBLE_MSW64(i0,t); +- SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63)); +- return t; +- } +- } else { +- if(j0==0x4000) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ ++ fenv_t env; ++ int64_t i0, j0, sx; ++ uint64_t i1 __attribute__ ((unused)); ++ _Float128 w, t; ++ GET_LDOUBLE_WORDS64 (i0, i1, x); ++ sx = (((uint64_t) i0) >> 63); ++ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; ++ if (j0 < 112) ++ { ++ if (j0 < 0) ++ { ++ feholdexcept (&env); ++ w = TWO112[sx] + math_opt_barrier (x); ++ t = w - TWO112[sx]; ++ math_force_eval (t); ++ fesetenv (&env); ++ GET_LDOUBLE_MSW64 (i0, t); ++ SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63)); ++ return t; + } +- feholdexcept (&env); +- w = TWO112[sx] + math_opt_barrier (x); +- t = w-TWO112[sx]; +- math_force_eval (t); +- fesetenv (&env); +- return t; ++ } ++ else ++ { ++ if (j0 == 0x4000) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ feholdexcept (&env); ++ w = TWO112[sx] + math_opt_barrier (x); ++ t = w - TWO112[sx]; ++ math_force_eval (t); ++ fesetenv (&env); ++ return t; + #endif /* ! USE_NEARBYINTL_BUILTIN */ + } + libm_alias_ldouble (__nearbyint, nearbyint) +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-15.patch b/SOURCES/glibc-rh1780204-15.patch new file mode 100644 index 0000000..47a5661 --- /dev/null +++ b/SOURCES/glibc-rh1780204-15.patch @@ -0,0 +1,156 @@ +From ce4f299c02be0a06130b70a62aa79b77385f4326 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:26 +0100 +Subject: [PATCH 15/28] Adjust s_rintf.c and s_rintl.c regarding code style. + +This patch just adjusts the generic implementation regarding code style. +No functional change. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 99b39a83e72f4b58e2f284fd844622df26b3b5fe) +--- + sysdeps/ieee754/flt-32/s_rintf.c | 44 +++++++++++++++------------ + sysdeps/ieee754/ldbl-128/s_rintl.c | 49 +++++++++++++++++------------- + 2 files changed, 53 insertions(+), 40 deletions(-) + +diff --git a/sysdeps/ieee754/flt-32/s_rintf.c b/sysdeps/ieee754/flt-32/s_rintf.c +index a266b1999e..3463a044e1 100644 +--- a/sysdeps/ieee754/flt-32/s_rintf.c ++++ b/sysdeps/ieee754/flt-32/s_rintf.c +@@ -19,7 +19,7 @@ + #include + + float +-__rintf(float x) ++__rintf (float x) + { + #if USE_RINTF_BUILTIN + return __builtin_rintf (x); +@@ -30,25 +30,31 @@ __rintf(float x) + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ + }; +- int32_t i0,j0,sx; +- float w,t; +- GET_FLOAT_WORD(i0,x); +- sx = (i0>>31)&1; +- j0 = ((i0>>23)&0xff)-0x7f; +- if(j0<23) { +- if(j0<0) { +- w = TWO23[sx]+x; +- t = w-TWO23[sx]; +- GET_FLOAT_WORD(i0,t); +- SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); +- return t; +- } +- } else { +- if(j0==0x80) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ ++ int32_t i0, j0, sx; ++ float w, t; ++ GET_FLOAT_WORD (i0, x); ++ sx = (i0 >> 31) & 1; ++ j0 = ((i0 >> 23) & 0xff) - 0x7f; ++ if (j0 < 23) ++ { ++ if(j0 < 0) ++ { ++ w = TWO23[sx] + x; ++ t = w - TWO23[sx]; ++ GET_FLOAT_WORD (i0, t); ++ SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); ++ return t; + } +- w = TWO23[sx]+x; +- return w-TWO23[sx]; ++ } ++ else ++ { ++ if (j0 == 0x80) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ w = TWO23[sx] + x; ++ return w - TWO23[sx]; + #endif /* ! USE_RINTF_BUILTIN */ + } + #ifndef __rintf +diff --git a/sysdeps/ieee754/ldbl-128/s_rintl.c b/sysdeps/ieee754/ldbl-128/s_rintl.c +index f060503066..260f3aa9b9 100644 +--- a/sysdeps/ieee754/ldbl-128/s_rintl.c ++++ b/sysdeps/ieee754/ldbl-128/s_rintl.c +@@ -13,7 +13,7 @@ + * ==================================================== + */ + +-#if defined(LIBM_SCCS) && !defined(lint) ++#if defined (LIBM_SCCS) && ! defined (lint) + static char rcsid[] = "$NetBSD: $"; + #endif + +@@ -32,7 +32,8 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + +-_Float128 __rintl(_Float128 x) ++_Float128 ++__rintl (_Float128 x) + { + #if USE_RINTL_BUILTIN + return __builtin_rintl (x); +@@ -43,26 +44,32 @@ _Float128 __rintl(_Float128 x) + 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */ + -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */ + }; +- int64_t i0,j0,sx; +- uint64_t i1 __attribute__ ((unused)); +- _Float128 w,t; +- GET_LDOUBLE_WORDS64(i0,i1,x); +- sx = (((uint64_t)i0)>>63); +- j0 = ((i0>>48)&0x7fff)-0x3fff; +- if(j0<112) { +- if(j0<0) { +- w = TWO112[sx]+x; +- t = w-TWO112[sx]; +- GET_LDOUBLE_MSW64(i0,t); +- SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63)); +- return t; +- } +- } else { +- if(j0==0x4000) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ ++ int64_t i0, j0, sx; ++ uint64_t i1 __attribute__ ((unused)); ++ _Float128 w, t; ++ GET_LDOUBLE_WORDS64 (i0, i1, x); ++ sx = (((uint64_t) i0) >> 63); ++ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; ++ if (j0 < 112) ++ { ++ if (j0 < 0) ++ { ++ w = TWO112[sx] + x; ++ t = w - TWO112[sx]; ++ GET_LDOUBLE_MSW64 (i0, t); ++ SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63)); ++ return t; + } +- w = TWO112[sx]+x; +- return w-TWO112[sx]; ++ } ++ else ++ { ++ if (j0 == 0x4000) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ w = TWO112[sx] + x; ++ return w - TWO112[sx]; + #endif /* ! USE_RINTL_BUILTIN */ + } + libm_alias_ldouble (__rint, rint) +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-16.patch b/SOURCES/glibc-rh1780204-16.patch new file mode 100644 index 0000000..47d84fd --- /dev/null +++ b/SOURCES/glibc-rh1780204-16.patch @@ -0,0 +1,198 @@ +From e96879644e4a9f4304725d1da9cc76b0c685b0b8 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:26 +0100 +Subject: [PATCH 16/28] Adjust s_floorf.c and s_floorl.c regarding code style. + +This patch just adjusts the generic implementation regarding code style. +No functional change. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit d3a0409ab615e133ff3ea27b492de75a607cff4a) +--- + sysdeps/ieee754/flt-32/s_floorf.c | 55 +++++++++++------- + sysdeps/ieee754/ldbl-128/s_floorl.c | 89 ++++++++++++++++++----------- + 2 files changed, 90 insertions(+), 54 deletions(-) + +diff --git a/sysdeps/ieee754/flt-32/s_floorf.c b/sysdeps/ieee754/flt-32/s_floorf.c +index 6d37ab90a1..c45816e3bd 100644 +--- a/sysdeps/ieee754/flt-32/s_floorf.c ++++ b/sysdeps/ieee754/flt-32/s_floorf.c +@@ -26,34 +26,45 @@ + #include + + float +-__floorf(float x) ++__floorf (float x) + { + #if USE_FLOORF_BUILTIN + return __builtin_floorf (x); + #else + /* Use generic implementation. */ +- int32_t i0,j0; +- uint32_t i; +- GET_FLOAT_WORD(i0,x); +- j0 = ((i0>>23)&0xff)-0x7f; +- if(j0<23) { +- if(j0<0) { +- /* return 0*sign(x) if |x|<1 */ +- if(i0>=0) {i0=0;} +- else if((i0&0x7fffffff)!=0) +- { i0=0xbf800000;} +- } else { +- i = (0x007fffff)>>j0; +- if((i0&i)==0) return x; /* x is integral */ +- if(i0<0) i0 += (0x00800000)>>j0; +- i0 &= (~i); +- } +- } else { +- if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ ++ int32_t i0, j0; ++ uint32_t i; ++ GET_FLOAT_WORD (i0, x); ++ j0 = ((i0 >> 23) & 0xff) - 0x7f; ++ if (j0 < 23) ++ { ++ if (j0 < 0) ++ { ++ /* return 0 * sign (x) if |x| < 1 */ ++ if (i0 >= 0) ++ i0 = 0; ++ else if ((i0 & 0x7fffffff) != 0) ++ i0 = 0xbf800000; + } +- SET_FLOAT_WORD(x,i0); +- return x; ++ else ++ { ++ i = (0x007fffff) >> j0; ++ if ((i0 & i) == 0) ++ return x; /* x is integral */ ++ if (i0 < 0) ++ i0 += (0x00800000) >> j0; ++ i0 &= (~i); ++ } ++ } ++ else ++ { ++ if (__glibc_unlikely (j0 == 0x80)) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ SET_FLOAT_WORD (x, i0); ++ return x; + #endif /* ! USE_FLOORF_BUILTIN */ + } + #ifndef __floorf +diff --git a/sysdeps/ieee754/ldbl-128/s_floorl.c b/sysdeps/ieee754/ldbl-128/s_floorl.c +index 6143fe6ec5..4fc10992c2 100644 +--- a/sysdeps/ieee754/ldbl-128/s_floorl.c ++++ b/sysdeps/ieee754/ldbl-128/s_floorl.c +@@ -29,46 +29,71 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + +-_Float128 __floorl(_Float128 x) ++_Float128 ++__floorl (_Float128 x) + { + #if USE_FLOORL_BUILTIN + return __builtin_floorl (x); + #else + /* Use generic implementation. */ +- int64_t i0,i1,j0; +- uint64_t i,j; +- GET_LDOUBLE_WORDS64(i0,i1,x); +- j0 = ((i0>>48)&0x7fff)-0x3fff; +- if(j0<48) { +- if(j0<0) { +- /* return 0*sign(x) if |x|<1 */ +- if(i0>=0) {i0=i1=0;} +- else if(((i0&0x7fffffffffffffffLL)|i1)!=0) +- { i0=0xbfff000000000000ULL;i1=0;} +- } else { +- i = (0x0000ffffffffffffULL)>>j0; +- if(((i0&i)|i1)==0) return x; /* x is integral */ +- if(i0<0) i0 += (0x0001000000000000LL)>>j0; +- i0 &= (~i); i1=0; ++ int64_t i0, i1, j0; ++ uint64_t i, j; ++ GET_LDOUBLE_WORDS64 (i0, i1, x); ++ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; ++ if (j0 < 48) ++ { ++ if (j0 < 0) ++ { ++ /* return 0 * sign (x) if |x| < 1 */ ++ if (i0 >= 0) ++ { ++ i0 = i1 = 0; + } +- } else if (j0>111) { +- if(j0==0x4000) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ +- } else { +- i = -1ULL>>(j0-48); +- if((i1&i)==0) return x; /* x is integral */ +- if(i0<0) { +- if(j0==48) i0+=1; +- else { +- j = i1+(1LL<<(112-j0)); +- if(j> j0; ++ if (((i0 & i) | i1) == 0) ++ return x; /* x is integral */ ++ if (i0 < 0) ++ i0 += (0x0001000000000000LL) >> j0; ++ i0 &= (~i); ++ i1 = 0; ++ } ++ } ++ else if (j0 > 111) ++ { ++ if (j0 == 0x4000) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ else ++ { ++ i = -1ULL >> (j0 - 48); ++ if ((i1 & i) == 0) ++ return x; /* x is integral */ ++ if (i0 < 0) ++ { ++ if (j0 == 48) ++ i0 += 1; ++ else ++ { ++ j = i1 + (1LL << (112 - j0)); ++ if (j < i1) ++ i0 += 1 ; /* got a carry */ ++ i1 = j; ++ } ++ } ++ i1 &= (~i); ++ } ++ SET_LDOUBLE_WORDS64 (x, i0, i1); ++ return x; + #endif /* ! USE_FLOORL_BUILTIN */ + } + libm_alias_ldouble (__floor, floor) +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-17.patch b/SOURCES/glibc-rh1780204-17.patch new file mode 100644 index 0000000..c8e447c --- /dev/null +++ b/SOURCES/glibc-rh1780204-17.patch @@ -0,0 +1,207 @@ +From 77b9cf86bba41d44e084337a11bfbf5ee7c98a38 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:27 +0100 +Subject: [PATCH 17/28] Adjust s_ceilf.c and s_ceill.c regarding code style. + +This patch just adjusts the generic implementation regarding code style. +No functional change. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 171d23d7cbce7b6f175a6690e625ccf80b647d23) +--- + sysdeps/ieee754/flt-32/s_ceilf.c | 54 +++++++++++------- + sysdeps/ieee754/ldbl-128/s_ceill.c | 91 +++++++++++++++++++----------- + 2 files changed, 92 insertions(+), 53 deletions(-) + +diff --git a/sysdeps/ieee754/flt-32/s_ceilf.c b/sysdeps/ieee754/flt-32/s_ceilf.c +index 6cab7bdd62..f60d0ac1f5 100644 +--- a/sysdeps/ieee754/flt-32/s_ceilf.c ++++ b/sysdeps/ieee754/flt-32/s_ceilf.c +@@ -19,34 +19,46 @@ + #include + + float +-__ceilf(float x) ++__ceilf (float x) + { + #if USE_CEILF_BUILTIN + return __builtin_ceilf (x); + #else + /* Use generic implementation. */ +- int32_t i0,j0; +- uint32_t i; ++ int32_t i0, j0; ++ uint32_t i; + +- GET_FLOAT_WORD(i0,x); +- j0 = ((i0>>23)&0xff)-0x7f; +- if(j0<23) { +- if(j0<0) { +- /* return 0*sign(x) if |x|<1 */ +- if(i0<0) {i0=0x80000000;} +- else if(i0!=0) { i0=0x3f800000;} +- } else { +- i = (0x007fffff)>>j0; +- if((i0&i)==0) return x; /* x is integral */ +- if(i0>0) i0 += (0x00800000)>>j0; +- i0 &= (~i); +- } +- } else { +- if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ ++ GET_FLOAT_WORD (i0, x); ++ j0 = ((i0 >> 23) & 0xff) - 0x7f; ++ if (j0 < 23) ++ { ++ if (j0 < 0) ++ { ++ /* return 0 * sign (x) if |x| < 1 */ ++ if (i0 < 0) ++ i0 = 0x80000000; ++ else if (i0 != 0) ++ i0 = 0x3f800000; + } +- SET_FLOAT_WORD(x,i0); +- return x; ++ else ++ { ++ i = (0x007fffff) >> j0; ++ if ((i0 & i) == 0) ++ return x; /* x is integral */ ++ if (i0 > 0) ++ i0 += (0x00800000) >> j0; ++ i0 &= (~i); ++ } ++ } ++ else ++ { ++ if (__glibc_unlikely (j0 == 0x80)) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ SET_FLOAT_WORD (x, i0); ++ return x; + #endif /* ! USE_CEILF_BUILTIN */ + } + #ifndef __ceilf +diff --git a/sysdeps/ieee754/ldbl-128/s_ceill.c b/sysdeps/ieee754/ldbl-128/s_ceill.c +index d212d86179..df75dc3008 100644 +--- a/sysdeps/ieee754/ldbl-128/s_ceill.c ++++ b/sysdeps/ieee754/ldbl-128/s_ceill.c +@@ -13,7 +13,7 @@ + * ==================================================== + */ + +-#if defined(LIBM_SCCS) && !defined(lint) ++#if defined (LIBM_SCCS) && ! defined (lint) + static char rcsid[] = "$NetBSD: $"; + #endif + +@@ -29,45 +29,72 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + +-_Float128 __ceill(_Float128 x) ++_Float128 ++__ceill (_Float128 x) + { + #if USE_CEILL_BUILTIN + return __builtin_ceill (x); + #else + /* Use generic implementation. */ +- int64_t i0,i1,j0; +- uint64_t i,j; +- GET_LDOUBLE_WORDS64(i0,i1,x); +- j0 = ((i0>>48)&0x7fff)-0x3fff; +- if(j0<48) { +- if(j0<0) { +- /* return 0*sign(x) if |x|<1 */ +- if(i0<0) {i0=0x8000000000000000ULL;i1=0;} +- else if((i0|i1)!=0) { i0=0x3fff000000000000ULL;i1=0;} +- } else { +- i = (0x0000ffffffffffffULL)>>j0; +- if(((i0&i)|i1)==0) return x; /* x is integral */ +- if(i0>0) i0 += (0x0001000000000000LL)>>j0; +- i0 &= (~i); i1=0; ++ int64_t i0, i1, j0; ++ uint64_t i, j; ++ GET_LDOUBLE_WORDS64 (i0, i1, x); ++ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; ++ if (j0 < 48) ++ { ++ if (j0 < 0) ++ { ++ /* return 0 * sign (x) if |x| < 1 */ ++ if (i0 < 0) ++ { ++ i0 = 0x8000000000000000ULL; ++ i1 = 0; + } +- } else if (j0>111) { +- if(j0==0x4000) return x+x; /* inf or NaN */ +- else return x; /* x is integral */ +- } else { +- i = -1ULL>>(j0-48); +- if((i1&i)==0) return x; /* x is integral */ +- if(i0>0) { +- if(j0==48) i0+=1; +- else { +- j = i1+(1LL<<(112-j0)); +- if(j> j0; ++ if (((i0 & i) | i1) == 0) ++ return x; /* x is integral */ ++ if (i0 > 0) ++ i0 += (0x0001000000000000LL) >> j0; ++ i0 &= (~i); ++ i1 = 0; ++ } ++ } ++ else if (j0 > 111) ++ { ++ if (j0 == 0x4000) ++ return x + x; /* inf or NaN */ ++ else ++ return x; /* x is integral */ ++ } ++ else ++ { ++ i = -1ULL >> (j0 - 48); ++ if ((i1 & i) == 0) ++ return x; /* x is integral */ ++ if (i0 > 0) ++ { ++ if (j0 == 48) ++ i0 += 1; ++ else ++ { ++ j = i1 + (1LL << (112 - j0)); ++ if (j < i1) ++ i0 += 1; /* got a carry */ ++ i1 = j; ++ } ++ } ++ i1 &= (~i); ++ } ++ SET_LDOUBLE_WORDS64 (x, i0, i1); ++ return x; + #endif /* ! USE_CEILL_BUILTIN */ + } + libm_alias_ldouble (__ceil, ceil) +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-18.patch b/SOURCES/glibc-rh1780204-18.patch new file mode 100644 index 0000000..feb6f36 --- /dev/null +++ b/SOURCES/glibc-rh1780204-18.patch @@ -0,0 +1,57 @@ +From f6e3f49613f4a31bce8c5f52ae440f9c7b3646fb Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:28 +0100 +Subject: [PATCH 18/28] Adjust s_copysignl.c regarding code style. + +This patch just adjusts the generic implementation regarding code style. +No functional change. + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 1902d5d5ff04771f16b67648789c75a18af06222) +--- + sysdeps/ieee754/ldbl-128/s_copysignl.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/sysdeps/ieee754/ldbl-128/s_copysignl.c b/sysdeps/ieee754/ldbl-128/s_copysignl.c +index 4cae8612dc..9b0e44cf1d 100644 +--- a/sysdeps/ieee754/ldbl-128/s_copysignl.c ++++ b/sysdeps/ieee754/ldbl-128/s_copysignl.c +@@ -13,7 +13,7 @@ + * ==================================================== + */ + +-#if defined(LIBM_SCCS) && !defined(lint) ++#if defined (LIBM_SCCS) && ! defined (lint) + static char rcsid[] = "$NetBSD: $"; + #endif + +@@ -28,18 +28,19 @@ static char rcsid[] = "$NetBSD: $"; + #include + #include + +-_Float128 __copysignl(_Float128 x, _Float128 y) ++_Float128 ++__copysignl (_Float128 x, _Float128 y) + { + #if USE_COPYSIGNL_BUILTIN + return __builtin_copysignl (x, y); + #else + /* Use generic implementation. */ +- uint64_t hx,hy; +- GET_LDOUBLE_MSW64(hx,x); +- GET_LDOUBLE_MSW64(hy,y); +- SET_LDOUBLE_MSW64(x,(hx&0x7fffffffffffffffULL) +- |(hy&0x8000000000000000ULL)); +- return x; ++ uint64_t hx, hy; ++ GET_LDOUBLE_MSW64 (hx, x); ++ GET_LDOUBLE_MSW64 (hy, y); ++ SET_LDOUBLE_MSW64 (x, (hx & 0x7fffffffffffffffULL) ++ | (hy & 0x8000000000000000ULL)); ++ return x; + #endif /* ! USE_COPYSIGNL_BUILTIN */ + } + libm_alias_ldouble (__copysign, copysign) +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-19.patch b/SOURCES/glibc-rh1780204-19.patch new file mode 100644 index 0000000..bda184c --- /dev/null +++ b/SOURCES/glibc-rh1780204-19.patch @@ -0,0 +1,157 @@ +From 855d045bc26175195dadafc28abf84e7b6613aac Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:28 +0100 +Subject: [PATCH 19/28] S390: Use load-fp-integer instruction for roundeven + functions. + +If compiled with z196 zarch support, the load-fp-integer instruction +is used to implement roundeven, roundevenf, roundevenl. +Otherwise the common-code implementation is used. + +(cherry picked from commit 4399b163376b331773e43917dcf56ce68e43e6a0) +--- + sysdeps/s390/fpu/s_roundeven.c | 39 +++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_roundevenf.c | 38 ++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_roundevenl.c | 39 +++++++++++++++++++++++++++++++++ + 3 files changed, 116 insertions(+) + create mode 100644 sysdeps/s390/fpu/s_roundeven.c + create mode 100644 sysdeps/s390/fpu/s_roundevenf.c + create mode 100644 sysdeps/s390/fpu/s_roundevenl.c + +diff --git a/sysdeps/s390/fpu/s_roundeven.c b/sysdeps/s390/fpu/s_roundeven.c +new file mode 100644 +index 0000000000..95a83a70e8 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_roundeven.c +@@ -0,0 +1,39 @@ ++/* roundeven() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++ ++double ++__roundeven (double x) ++{ ++ double y; ++ /* The z196 zarch "load fp integer" (fidbra) instruction is rounding ++ x to the nearest integer with "ties to even" rounding mode ++ (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("fidbra %0,4,%1,4" : "=f" (y) : "f" (x)); ++ return y; ++} ++hidden_def (__roundeven) ++libm_alias_double (__roundeven, roundeven) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_roundevenf.c b/sysdeps/s390/fpu/s_roundevenf.c +new file mode 100644 +index 0000000000..c620a0189c +--- /dev/null ++++ b/sysdeps/s390/fpu/s_roundevenf.c +@@ -0,0 +1,38 @@ ++/* roundevenf() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++ ++float ++__roundevenf (float x) ++{ ++ float y; ++ /* The z196 zarch "load fp integer" (fiebra) instruction is rounding ++ x to the nearest integer with "ties to even" rounding mode ++ (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("fiebra %0,4,%1,4" : "=f" (y) : "f" (x)); ++ return y; ++} ++libm_alias_float (__roundeven, roundeven) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_roundevenl.c b/sysdeps/s390/fpu/s_roundevenl.c +new file mode 100644 +index 0000000000..3481af2665 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_roundevenl.c +@@ -0,0 +1,39 @@ ++/* roundevenl() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++# include ++ ++_Float128 ++__roundevenl (_Float128 x) ++{ ++ _Float128 y; ++ /* The z196 zarch "load fp integer" (fixbra) instruction is rounding ++ x to the nearest integer with "ties to even" rounding mode ++ (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("fixbra %0,4,%1,4" : "=f" (y) : "f" (x)); ++ return y; ++} ++libm_alias_ldouble (__roundeven, roundeven) ++ ++#else ++# include ++#endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-20.patch b/SOURCES/glibc-rh1780204-20.patch new file mode 100644 index 0000000..4967ce3 --- /dev/null +++ b/SOURCES/glibc-rh1780204-20.patch @@ -0,0 +1,207 @@ +From 90e84ac5ac8e774ce0cfd3abc5f7d8834efd2c9b Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:29 +0100 +Subject: [PATCH 20/28] S390: Use convert-to-fixed instruction for lrint + functions. + +If compiled with z196 zarch support, the convert-to-fixed instruction +is used to implement lrint, lrintf, lrintl. +Otherwise the common-code implementation is used. + +(cherry picked from commit e3f07622209c1b4436ef364b134dfd2cd4ca9976) +--- + sysdeps/s390/fpu/s_lrint.c | 55 ++++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_lrintf.c | 55 ++++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_lrintl.c | 56 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 166 insertions(+) + create mode 100644 sysdeps/s390/fpu/s_lrint.c + create mode 100644 sysdeps/s390/fpu/s_lrintf.c + create mode 100644 sysdeps/s390/fpu/s_lrintl.c + +diff --git a/sysdeps/s390/fpu/s_lrint.c b/sysdeps/s390/fpu/s_lrint.c +new file mode 100644 +index 0000000000..7be60665b5 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_lrint.c +@@ -0,0 +1,55 @@ ++/* lrint() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++ ++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). ++ Thus we need different instructions as the target size is encoded there. ++ Note: On s390 this instruction is only used if build with -mzarch. */ ++# ifdef __s390x__ ++# define INSN "cgdbra" ++# else ++# define INSN "cfdbra" ++# endif ++ ++long int ++__lrint (double x) ++{ ++ long int y; ++ /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding ++ according to current rounding mode (M3-field: 0). ++ First convert x with suppressed inexact exception and check if the ++ resulting value is beyond the target limits (indicated by cc=3; ++ Note: a nan is also indicated by cc=3). ++ If the resulting value is within the target limits, redo ++ without suppressing the inexact exception. */ ++ __asm__ (INSN " %0,0,%1,4 \n\t" ++ "jo 1f \n\t" ++ INSN " %0,0,%1,0 \n\t" ++ "1:" ++ : "=&d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_double (__lrint, lrint) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_lrintf.c b/sysdeps/s390/fpu/s_lrintf.c +new file mode 100644 +index 0000000000..d6a2a4081a +--- /dev/null ++++ b/sysdeps/s390/fpu/s_lrintf.c +@@ -0,0 +1,55 @@ ++/* lrintf() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++ ++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). ++ Thus we need different instructions as the target size is encoded there. ++ Note: On s390 this instruction is only used if build with -mzarch. */ ++# ifdef __s390x__ ++# define INSN "cgebra" ++# else ++# define INSN "cfebra" ++# endif ++ ++long int ++__lrintf (float x) ++{ ++ long int y; ++ /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding ++ according to current rounding mode (M3-field: 0). ++ First convert x with suppressed inexact exception and check if the ++ resulting value is beyond the target limits (indicated by cc=3; ++ Note: a nan is also indicated by cc=3). ++ If the resulting value is within the target limits, redo ++ without suppressing the inexact exception. */ ++ __asm__ (INSN " %0,0,%1,4 \n\t" ++ "jo 1f \n\t" ++ INSN " %0,0,%1,0 \n\t" ++ "1:" ++ : "=&d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_float (__lrint, lrint) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_lrintl.c b/sysdeps/s390/fpu/s_lrintl.c +new file mode 100644 +index 0000000000..2d386ecff9 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_lrintl.c +@@ -0,0 +1,56 @@ ++/* lrintl() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++# include ++ ++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). ++ Thus we need different instructions as the target size is encoded there. ++ Note: On s390 this instruction is only used if build with -mzarch. */ ++# ifdef __s390x__ ++# define INSN "cgxbra" ++# else ++# define INSN "cfxbra" ++# endif ++ ++long int ++__lrintl (_Float128 x) ++{ ++ long int y; ++ /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding ++ according to current rounding mode (M3-field: 0). ++ First convert x with suppressed inexact exception and check if the ++ resulting value is beyond the target limits (indicated by cc=3; ++ Note: a nan is also indicated by cc=3). ++ If the resulting value is within the target limits, redo ++ without suppressing the inexact exception. */ ++ __asm__ (INSN " %0,0,%1,4 \n\t" ++ "jo 1f \n\t" ++ INSN " %0,0,%1,0 \n\t" ++ "1:" ++ : "=&d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_ldouble (__lrint, lrint) ++ ++#else ++# include ++#endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-21.patch b/SOURCES/glibc-rh1780204-21.patch new file mode 100644 index 0000000..743e16c --- /dev/null +++ b/SOURCES/glibc-rh1780204-21.patch @@ -0,0 +1,192 @@ +From 429eff12541cc0779c381f84257c8860ece25b12 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:29 +0100 +Subject: [PATCH 21/28] S390: Use convert-to-fixed instruction for llrint + functions. + +If compiled with z196 zarch support, the convert-to-fixed instruction +is used to implement llrint, llrintf, llrintl. +Otherwise the common-code implementation is used. + +(cherry picked from commit f10c1654fe13d797d2fd347dc47f72f93c58cf62) +--- + sysdeps/s390/fpu/s_llrint.c | 50 +++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_llrintf.c | 50 +++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_llrintl.c | 51 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 151 insertions(+) + create mode 100644 sysdeps/s390/fpu/s_llrint.c + create mode 100644 sysdeps/s390/fpu/s_llrintf.c + create mode 100644 sysdeps/s390/fpu/s_llrintl.c + +diff --git a/sysdeps/s390/fpu/s_llrint.c b/sysdeps/s390/fpu/s_llrint.c +new file mode 100644 +index 0000000000..edd796ae8c +--- /dev/null ++++ b/sysdeps/s390/fpu/s_llrint.c +@@ -0,0 +1,50 @@ ++/* llrint() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++/* We only support s390x as on s390 a long long int refers to a register pair ++ of two 4byte registers instead of a 8byte register which is produced by the ++ instruction. ++ Note: On s390 this instruction would only be used if build with -mzarch. */ ++# include ++# include ++ ++long long int ++__llrint (double x) ++{ ++ long long int y; ++ /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding ++ according to current rounding mode (M3-field: 0). ++ First convert x with suppressed inexact exception and check if the ++ resulting value is beyond the target limits (indicated by cc=3; ++ Note: a nan is also indicated by cc=3). ++ If the resulting value is within the target limits, redo ++ without suppressing the inexact exception. */ ++ __asm__ ("cgdbra %0,0,%1,4 \n\t" ++ "jo 1f \n\t" ++ "cgdbra %0,0,%1,0 \n\t" ++ "1:" ++ : "=&d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_double (__llrint, llrint) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_llrintf.c b/sysdeps/s390/fpu/s_llrintf.c +new file mode 100644 +index 0000000000..3cbe7c581a +--- /dev/null ++++ b/sysdeps/s390/fpu/s_llrintf.c +@@ -0,0 +1,50 @@ ++/* llrintf() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++/* We only support s390x as on s390 a long long int refers to a register pair ++ of two 4byte registers instead of a 8byte register which is produced by the ++ instruction. ++ Note: On s390 this instruction would only be used if build with -mzarch. */ ++# include ++# include ++ ++long long int ++__llrintf (float x) ++{ ++ long long int y; ++ /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding ++ according to current rounding mode (M3-field: 0). ++ First convert x with suppressed inexact exception and check if the ++ resulting value is beyond the target limits (indicated by cc=3; ++ Note: a nan is also indicated by cc=3). ++ If the resulting value is within the target limits, redo ++ without suppressing the inexact exception. */ ++ __asm__ ("cgebra %0,0,%1,4 \n\t" ++ "jo 1f \n\t" ++ "cgebra %0,0,%1,0 \n\t" ++ "1:" ++ : "=&d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_float (__llrint, llrint) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_llrintl.c b/sysdeps/s390/fpu/s_llrintl.c +new file mode 100644 +index 0000000000..37eea5914f +--- /dev/null ++++ b/sysdeps/s390/fpu/s_llrintl.c +@@ -0,0 +1,51 @@ ++/* llrintl() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++/* We only support s390x as on s390 a long long int refers to a register pair ++ of two 4byte registers instead of a 8byte register which is produced by the ++ instruction. ++ Note: On s390 this instruction would only be used if build with -mzarch. */ ++# include ++# include ++# include ++ ++long long int ++__llrintl (_Float128 x) ++{ ++ long long int y; ++ /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding ++ according to current rounding mode (M3-field: 0). ++ First convert x with suppressed inexact exception and check if the ++ resulting value is beyond the target limits (indicated by cc=3; ++ Note: a nan is also indicated by cc=3). ++ If the resulting value is within the target limits, redo ++ without suppressing the inexact exception. */ ++ __asm__ ("cgxbra %0,0,%1,4 \n\t" ++ "jo 1f \n\t" ++ "cgxbra %0,0,%1,0 \n\t" ++ "1:" ++ : "=&d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_ldouble (__llrint, llrint) ++ ++#else ++# include ++#endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-22.patch b/SOURCES/glibc-rh1780204-22.patch new file mode 100644 index 0000000..db29fa3 --- /dev/null +++ b/SOURCES/glibc-rh1780204-22.patch @@ -0,0 +1,183 @@ +From 9f3ee7825b1eae00431ea6477fce8210aaced7db Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:30 +0100 +Subject: [PATCH 22/28] S390: Use convert-to-fixed instruction for lround + functions. + +If compiled with z196 zarch support, the convert-to-fixed instruction +is used to implement lround, lroundf, lroundl. +Otherwise the common-code implementation is used. + +(cherry picked from commit 9d9f3527daf65fdca0eb46eaa324b81b8f94d88c) +--- + sysdeps/s390/fpu/s_lround.c | 47 +++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_lroundf.c | 47 +++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_lroundl.c | 48 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 142 insertions(+) + create mode 100644 sysdeps/s390/fpu/s_lround.c + create mode 100644 sysdeps/s390/fpu/s_lroundf.c + create mode 100644 sysdeps/s390/fpu/s_lroundl.c + +diff --git a/sysdeps/s390/fpu/s_lround.c b/sysdeps/s390/fpu/s_lround.c +new file mode 100644 +index 0000000000..9290ec32cd +--- /dev/null ++++ b/sysdeps/s390/fpu/s_lround.c +@@ -0,0 +1,47 @@ ++/* lround() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++ ++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). ++ Thus we need different instructions as the target size is encoded there. ++ Note: On s390 this instruction is only used if build with -mzarch. */ ++# ifdef __s390x__ ++# define INSN "cgdbra" ++# else ++# define INSN "cfdbra" ++# endif ++ ++long int ++__lround (double x) ++{ ++ long int y; ++ /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding ++ x to the nearest integer with "ties away from 0" rounding mode ++ (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_double (__lround, lround) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_lroundf.c b/sysdeps/s390/fpu/s_lroundf.c +new file mode 100644 +index 0000000000..097b924c91 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_lroundf.c +@@ -0,0 +1,47 @@ ++/* lroundf() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++ ++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). ++ Thus we need different instructions as the target size is encoded there. ++ Note: On s390 this instruction is only used if build with -mzarch. */ ++# ifdef __s390x__ ++# define INSN "cgebra" ++# else ++# define INSN "cfebra" ++# endif ++ ++long int ++__lroundf (float x) ++{ ++ long int y; ++ /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding ++ x to the nearest integer with "ties away from 0" rounding mode ++ (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_float (__lround, lround) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_lroundl.c b/sysdeps/s390/fpu/s_lroundl.c +new file mode 100644 +index 0000000000..0ef77dc667 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_lroundl.c +@@ -0,0 +1,48 @@ ++/* lroundl() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# include ++# include ++# include ++ ++/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). ++ Thus we need different instructions as the target size is encoded there. ++ Note: On s390 this instruction is only used if build with -mzarch. */ ++# ifdef __s390x__ ++# define INSN "cgxbra" ++# else ++# define INSN "cfxbra" ++# endif ++ ++long int ++__lroundl (_Float128 x) ++{ ++ long int y; ++ /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding ++ x to the nearest integer with "ties away from 0" rounding mode ++ (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_ldouble (__lround, lround) ++ ++#else ++# include ++#endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-23.patch b/SOURCES/glibc-rh1780204-23.patch new file mode 100644 index 0000000..bcd8965 --- /dev/null +++ b/SOURCES/glibc-rh1780204-23.patch @@ -0,0 +1,168 @@ +From dd8bfb911e89f3ad1da5cfa5618a8c52c62bb095 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:31 +0100 +Subject: [PATCH 23/28] S390: Use convert-to-fixed instruction for llround + functions. + +If compiled with z196 zarch support, the convert-to-fixed instruction +is used to implement llround, llroundf, llroundl. +Otherwise the common-code implementation is used. + +(cherry picked from commit 7d42d614fdc2c9d9f6ad46111bd6130501d50460) +--- + sysdeps/s390/fpu/s_llround.c | 42 ++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_llroundf.c | 42 ++++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/s_llroundl.c | 43 +++++++++++++++++++++++++++++++++++ + 3 files changed, 127 insertions(+) + create mode 100644 sysdeps/s390/fpu/s_llround.c + create mode 100644 sysdeps/s390/fpu/s_llroundf.c + create mode 100644 sysdeps/s390/fpu/s_llroundl.c + +diff --git a/sysdeps/s390/fpu/s_llround.c b/sysdeps/s390/fpu/s_llround.c +new file mode 100644 +index 0000000000..f4a1b21637 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_llround.c +@@ -0,0 +1,42 @@ ++/* llround() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++/* We only support s390x as on s390 a long long int refers to a register pair ++ of two 4byte registers instead of a 8byte register which is produced by the ++ instruction. ++ Note: On s390 this instruction would only be used if build with -mzarch. */ ++# include ++# include ++ ++long long int ++__llround (double x) ++{ ++ long long int y; ++ /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding ++ x to the nearest integer with "ties away from 0" rounding mode ++ (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("cgdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_double (__llround, llround) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_llroundf.c b/sysdeps/s390/fpu/s_llroundf.c +new file mode 100644 +index 0000000000..d202f4be8c +--- /dev/null ++++ b/sysdeps/s390/fpu/s_llroundf.c +@@ -0,0 +1,42 @@ ++/* llroundf() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++/* We only support s390x as on s390 a long long int refers to a register pair ++ of two 4byte registers instead of a 8byte register which is produced by the ++ instruction. ++ Note: On s390 this instruction would only be used if build with -mzarch. */ ++# include ++# include ++ ++long long int ++__llroundf (float x) ++{ ++ long long int y; ++ /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding ++ x to the nearest integer with "ties away from 0" rounding mode ++ (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("cgebra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_float (__llround, llround) ++ ++#else ++# include ++#endif +diff --git a/sysdeps/s390/fpu/s_llroundl.c b/sysdeps/s390/fpu/s_llroundl.c +new file mode 100644 +index 0000000000..58976cd5c5 +--- /dev/null ++++ b/sysdeps/s390/fpu/s_llroundl.c +@@ -0,0 +1,43 @@ ++/* llroundl() - S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++/* We only support s390x as on s390 a long long int refers to a register pair ++ of two 4byte registers instead of a 8byte register which is produced by the ++ instruction. ++ Note: On s390 this instruction would only be used if build with -mzarch. */ ++# include ++# include ++# include ++ ++long long int ++__llroundl (_Float128 x) ++{ ++ long long int y; ++ /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding ++ x to the nearest integer with "ties away from 0" rounding mode ++ (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("cgxbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); ++ return y; ++} ++libm_alias_ldouble (__llround, llround) ++ ++#else ++# include ++#endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-24.patch b/SOURCES/glibc-rh1780204-24.patch new file mode 100644 index 0000000..21bfd24 --- /dev/null +++ b/SOURCES/glibc-rh1780204-24.patch @@ -0,0 +1,70 @@ +From 33f3c934e3023b85c3774ee0482ec4da2a10a3b5 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:32 +0100 +Subject: [PATCH 24/28] S390: Implement math-barriers math_opt_barrier and + math_force_eval. + +This patch implements the s390 specific math barriers in order +to omit the store and load from stack if possible. + +(cherry picked from commit 433a2ba68cd91842546e0f0d43d65835634d570d) +--- + sysdeps/s390/fpu/math-barriers.h | 46 ++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + create mode 100644 sysdeps/s390/fpu/math-barriers.h + +diff --git a/sysdeps/s390/fpu/math-barriers.h b/sysdeps/s390/fpu/math-barriers.h +new file mode 100644 +index 0000000000..7c3e6b15e0 +--- /dev/null ++++ b/sysdeps/s390/fpu/math-barriers.h +@@ -0,0 +1,46 @@ ++/* Control when floating-point expressions are evaluated. s390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef S390_MATH_BARRIERS_H ++#define S390_MATH_BARRIERS_H 1 ++ ++#ifdef HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CONSTRAINT_VR "v" ++#else ++# define ASM_CONSTRAINT_VR ++#endif ++ ++#define math_opt_barrier(x) \ ++ ({ __typeof (x) __x = (x); \ ++ if (__builtin_types_compatible_p (__typeof (x), _Float128)) \ ++ __asm__ ("# math_opt_barrier_f128 %0" : "+fm" (__x)); \ ++ else \ ++ __asm__ ("# math_opt_barrier %0" \ ++ : "+f" ASM_CONSTRAINT_VR "m" (__x)); \ ++ __x; }) ++#define math_force_eval(x) \ ++ ({ __typeof (x) __x = (x); \ ++ if (__builtin_types_compatible_p (__typeof (x), _Float128)) \ ++ __asm__ __volatile__ ("# math_force_eval_f128 %0" \ ++ : : "fm" (__x)); \ ++ else \ ++ __asm__ __volatile__ ("# math_force_eval %0" \ ++ : : "f" ASM_CONSTRAINT_VR "m" (__x)); \ ++ }) ++ ++#endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-25.patch b/SOURCES/glibc-rh1780204-25.patch new file mode 100644 index 0000000..34353ff --- /dev/null +++ b/SOURCES/glibc-rh1780204-25.patch @@ -0,0 +1,79 @@ +From cf5397eb5b33bab37c16bcb2d1bbddbce1a27de2 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:33 +0100 +Subject: [PATCH 25/28] S390: Implement roundtoint and converttoint and define + TOINT_INTRINSICS. + +This patch implements roundtoint and convertoint for s390 +by using the load-fp-integer and convert-to-fixed instructions. +Both functions are using "round to nearest with ties away from zero" +rounding mode and do not raise inexact exceptions. + +(cherry picked from commit 2763d3145a326aa9afa613fe9e1b444cf912a883) +--- + sysdeps/s390/fpu/math_private.h | 53 +++++++++++++++++++++++++++++++++ + 1 file changed, 53 insertions(+) + create mode 100644 sysdeps/s390/fpu/math_private.h + +diff --git a/sysdeps/s390/fpu/math_private.h b/sysdeps/s390/fpu/math_private.h +new file mode 100644 +index 0000000000..a1ae91a87c +--- /dev/null ++++ b/sysdeps/s390/fpu/math_private.h +@@ -0,0 +1,53 @@ ++/* Configure optimized libm functions. S390 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef S390_MATH_PRIVATE_H ++#define S390_MATH_PRIVATE_H 1 ++ ++#include ++#include ++ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define TOINT_INTRINSICS 1 ++ ++static inline double_t ++roundtoint (double_t x) ++{ ++ double_t y; ++ /* The z196 zarch "load fp integer" (fidbra) instruction is rounding ++ x to the nearest integer with ties away from zero (M3-field: 1) ++ where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("fidbra %0,1,%1,4" : "=f" (y) : "f" (x)); ++ return y; ++} ++ ++static inline int32_t ++converttoint (double_t x) ++{ ++ int32_t y; ++ /* The z196 zarch "convert to fixed" (cfdbra) instruction is rounding ++ x to the nearest integer with ties away from zero (M3-field: 1) ++ where inexact exceptions are suppressed (M4-field: 4). */ ++ __asm__ ("cfdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); ++ return y; ++} ++#endif ++ ++#include_next ++ ++#endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-26.patch b/SOURCES/glibc-rh1780204-26.patch new file mode 100644 index 0000000..0f5a6bc --- /dev/null +++ b/SOURCES/glibc-rh1780204-26.patch @@ -0,0 +1,23 @@ +From 363f9d7a6be5a3b400e3ea3daab583bccfcfa152 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:34 +0100 +Subject: [PATCH 26/28] S390: Use sysdeps/ieee754/dbl-64/wordsize-64 on s390x. + +This patch enables the usage of implementations in +sysdeps/ieee754/dbl-64/wordsize-64 on 64bit s390x. + +(cherry picked from commit fcee34cc373daee6aa5320a6e1897cdf2005ab53) +--- + sysdeps/s390/s390-64/Implies | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sysdeps/s390/s390-64/Implies b/sysdeps/s390/s390-64/Implies +index a8cae95f9d..7603c9859c 100644 +--- a/sysdeps/s390/s390-64/Implies ++++ b/sysdeps/s390/s390-64/Implies +@@ -1 +1,2 @@ + wordsize-64 ++ieee754/dbl-64/wordsize-64 +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-27.patch b/SOURCES/glibc-rh1780204-27.patch new file mode 100644 index 0000000..a90ba6f --- /dev/null +++ b/SOURCES/glibc-rh1780204-27.patch @@ -0,0 +1,294 @@ +From 8e5e36d7ba097b8e110ab45794659156af182f54 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:31 +0100 +Subject: [PATCH 27/28] S390: Implement libc_fe* macros. + +This patch provides the s390 specific implementation for +libc_feholdexcept, libc_fesetround, libc_feholdexcept_setround, +libc_fetestexcept, libc_fesetenv, libc_feupdateenv_test, +libc_feupdateenv, libc_feholdsetround_ctx, libc_feresetround_ctx, +libc_feholdsetround_noex_ctx and libc_feresetround_noex_ctx. + +(cherry picked from commit 7c94d036c17dfd352d11e9bf98e5d84122c1f95e) +Note: glibc-2.28 does not have a generic fenv_private.h. +Therefore include_next does not work. Instead fenv_private.h needs to +be included in the s390 specific mathp_private.h just before including +the generic math_private.h. +As the s390 specific math_private.h is introduced with the backport of +commit "S390: Implement roundtoint and converttoint and define TOINT_INTRINSICS.", +the order of cherry-picking was changed compared to upstream! +--- + sysdeps/s390/fpu/fenv_private.h | 248 ++++++++++++++++++++++++++++++++ + sysdeps/s390/fpu/math_private.h | 1 + + 2 files changed, 249 insertions(+) + create mode 100644 sysdeps/s390/fpu/fenv_private.h + +diff --git a/sysdeps/s390/fpu/fenv_private.h b/sysdeps/s390/fpu/fenv_private.h +new file mode 100644 +index 0000000000..8899f8f434 +--- /dev/null ++++ b/sysdeps/s390/fpu/fenv_private.h +@@ -0,0 +1,248 @@ ++/* Private floating point rounding and exceptions handling. 390/s390x version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef S390_FENV_PRIVATE_H ++#define S390_FENV_PRIVATE_H 1 ++ ++#include ++#include ++#include ++ ++static __always_inline void ++libc_feholdexcept_s390 (fenv_t *envp) ++{ ++ fpu_control_t fpc, fpc_new; ++ ++ /* Store the environment. */ ++ _FPU_GETCW (fpc); ++ envp->__fpc = fpc; ++ ++ /* Clear the current exception flags and dxc field. ++ Hold from generating fpu exceptions temporarily. */ ++ fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK); ++ ++ /* Only set new environment if it has changed. */ ++ if (fpc_new != fpc) ++ _FPU_SETCW (fpc_new); ++} ++ ++#define libc_feholdexcept libc_feholdexcept_s390 ++#define libc_feholdexceptf libc_feholdexcept_s390 ++#define libc_feholdexceptl libc_feholdexcept_s390 ++ ++static __always_inline void ++libc_fesetround_s390 (int round) ++{ ++ __asm__ __volatile__ ("srnm 0(%0)" : : "a" (round)); ++} ++ ++#define libc_fesetround libc_fesetround_s390 ++#define libc_fesetroundf libc_fesetround_s390 ++#define libc_fesetroundl libc_fesetround_s390 ++ ++static __always_inline void ++libc_feholdexcept_setround_s390 (fenv_t *envp, int r) ++{ ++ fpu_control_t fpc, fpc_new; ++ ++ _FPU_GETCW (fpc); ++ envp->__fpc = fpc; ++ ++ /* Clear the current exception flags and dxc field. ++ Hold from generating fpu exceptions temporarily. ++ Reset rounding mode bits. */ ++ fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK ++ | FPC_RM_MASK); ++ ++ /* Set new rounding mode. */ ++ fpc_new |= (r & FPC_RM_MASK); ++ ++ /* Only set new environment if it has changed. */ ++ if (fpc_new != fpc) ++ _FPU_SETCW (fpc_new); ++} ++ ++#define libc_feholdexcept_setround libc_feholdexcept_setround_s390 ++#define libc_feholdexcept_setroundf libc_feholdexcept_setround_s390 ++#define libc_feholdexcept_setroundl libc_feholdexcept_setround_s390 ++ ++static __always_inline int ++libc_fetestexcept_s390 (int excepts) ++{ ++ int res; ++ fexcept_t fpc; ++ ++ _FPU_GETCW (fpc); ++ ++ /* Get current exceptions. */ ++ res = (fpc >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT; ++ if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0) ++ /* Bits 6, 7 of dxc-byte are zero, ++ thus bits 0-5 of dxc-byte correspond to the flag-bits. ++ Evaluate flags and last dxc-exception-code. */ ++ res |= (fpc >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT; ++ ++ return res & excepts; ++} ++ ++#define libc_fetestexcept libc_fetestexcept_s390 ++#define libc_fetestexceptf libc_fetestexcept_s390 ++#define libc_fetestexceptl libc_fetestexcept_s390 ++ ++static __always_inline void ++libc_fesetenv_s390 (const fenv_t *envp) ++{ ++ _FPU_SETCW (envp->__fpc); ++} ++ ++#define libc_fesetenv libc_fesetenv_s390 ++#define libc_fesetenvf libc_fesetenv_s390 ++#define libc_fesetenvl libc_fesetenv_s390 ++ ++static __always_inline int ++libc_feupdateenv_test_s390 (const fenv_t *envp, int ex) ++{ ++ /* Get the currently raised exceptions. */ ++ int excepts; ++ fexcept_t fpc_old; ++ ++ _FPU_GETCW (fpc_old); ++ ++ /* Get current exceptions. */ ++ excepts = (fpc_old >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT; ++ if ((fpc_old & FPC_NOT_FPU_EXCEPTION) == 0) ++ /* Bits 6, 7 of dxc-byte are zero, ++ thus bits 0-5 of dxc-byte correspond to the flag-bits. ++ Evaluate flags and last dxc-exception-code. */ ++ excepts |= (fpc_old >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT; ++ ++ /* Merge the currently raised exceptions with those in envp. */ ++ fpu_control_t fpc_new = envp->__fpc; ++ fpc_new |= excepts << FPC_FLAGS_SHIFT; ++ ++ /* Install the new fpc from envp. */ ++ if (fpc_new != fpc_old) ++ _FPU_SETCW (fpc_new); ++ ++ /* Raise the exceptions if enabled in new fpc. */ ++ if (__glibc_unlikely ((fpc_new >> FPC_EXCEPTION_MASK_SHIFT) & excepts)) ++ __feraiseexcept (excepts); ++ ++ return excepts & ex; ++} ++ ++#define libc_feupdateenv_test libc_feupdateenv_test_s390 ++#define libc_feupdateenv_testf libc_feupdateenv_test_s390 ++#define libc_feupdateenv_testl libc_feupdateenv_test_s390 ++ ++static __always_inline void ++libc_feupdateenv_s390 (const fenv_t *envp) ++{ ++ libc_feupdateenv_test_s390 (envp, 0); ++} ++ ++#define libc_feupdateenv libc_feupdateenv_s390 ++#define libc_feupdateenvf libc_feupdateenv_s390 ++#define libc_feupdateenvl libc_feupdateenv_s390 ++ ++static __always_inline fenv_t ++libc_handle_user_fenv_s390 (const fenv_t *envp) ++{ ++ fenv_t env; ++ if (envp == FE_DFL_ENV) ++ { ++ env.__fpc = _FPU_DEFAULT; ++ } ++ else if (envp == FE_NOMASK_ENV) ++ { ++ env.__fpc = FPC_EXCEPTION_MASK; ++ } ++ else ++ env = (*envp); ++ ++ return env; ++} ++ ++/* We have support for rounding mode context. */ ++#define HAVE_RM_CTX 1 ++ ++static __always_inline void ++libc_feholdsetround_s390_ctx (struct rm_ctx *ctx, int r) ++{ ++ fpu_control_t fpc; ++ int round; ++ ++ _FPU_GETCW (fpc); ++ ctx->env.__fpc = fpc; ++ ++ /* Check whether rounding modes are different. */ ++ round = fpc & FPC_RM_MASK; ++ ++ /* Set the rounding mode if changed. */ ++ if (__glibc_unlikely (round != r)) ++ { ++ ctx->updated_status = true; ++ libc_fesetround_s390 (r); ++ } ++ else ++ ctx->updated_status = false; ++} ++ ++#define libc_feholdsetround_ctx libc_feholdsetround_s390_ctx ++#define libc_feholdsetroundf_ctx libc_feholdsetround_s390_ctx ++#define libc_feholdsetroundl_ctx libc_feholdsetround_s390_ctx ++ ++static __always_inline void ++libc_feresetround_s390_ctx (struct rm_ctx *ctx) ++{ ++ /* Restore the rounding mode if updated. */ ++ if (__glibc_unlikely (ctx->updated_status)) ++ { ++ fpu_control_t fpc; ++ _FPU_GETCW (fpc); ++ fpc = ctx->env.__fpc | (fpc & FPC_FLAGS_MASK); ++ _FPU_SETCW (fpc); ++ } ++} ++ ++#define libc_feresetround_ctx libc_feresetround_s390_ctx ++#define libc_feresetroundf_ctx libc_feresetround_s390_ctx ++#define libc_feresetroundl_ctx libc_feresetround_s390_ctx ++ ++static __always_inline void ++libc_feholdsetround_noex_s390_ctx (struct rm_ctx *ctx, int r) ++{ ++ libc_feholdexcept_setround_s390 (&ctx->env, r); ++} ++ ++#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_s390_ctx ++#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_s390_ctx ++#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_s390_ctx ++ ++static __always_inline void ++libc_feresetround_noex_s390_ctx (struct rm_ctx *ctx) ++{ ++ /* Restore exception flags and rounding mode. */ ++ libc_fesetenv_s390 (&ctx->env); ++} ++ ++#define libc_feresetround_noex_ctx libc_feresetround_noex_s390_ctx ++#define libc_feresetround_noexf_ctx libc_feresetround_noex_s390_ctx ++#define libc_feresetround_noexl_ctx libc_feresetround_noex_s390_ctx ++ ++#endif +diff --git a/sysdeps/s390/fpu/math_private.h b/sysdeps/s390/fpu/math_private.h +index a1ae91a87c..f3c770d59a 100644 +--- a/sysdeps/s390/fpu/math_private.h ++++ b/sysdeps/s390/fpu/math_private.h +@@ -48,6 +48,7 @@ converttoint (double_t x) + } + #endif + ++#include + #include_next + + #endif +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1780204-28.patch b/SOURCES/glibc-rh1780204-28.patch new file mode 100644 index 0000000..d2b165a --- /dev/null +++ b/SOURCES/glibc-rh1780204-28.patch @@ -0,0 +1,317 @@ +From 2ab6ce8252a14e6ef0cfb33046dd565ae15085c2 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 11 Dec 2019 15:09:32 +0100 +Subject: [PATCH 28/28] S390: Use libc_fe* macros in fe* functions. + +This patch updates the s390 specific functions fegetround, +fesetround, feholdexcept, fesetenv, feupdateenv, fegetexceptflag, +fetestexcept, fesetexceptflag, fetestexceptflag. +Now those functions are using the libc_fe* macros if possible. + +Furthermore fegetexceptflag is now returning the exception from +dxc field shifted to the usual exception-flags. +Thus a special fetestexceptflag implementation is not needed anymore. + +(cherry picked from commit 238adf59db85646ebae47876819bd896dae597bc) +--- + sysdeps/s390/fpu/fegetround.c | 9 ++------- + sysdeps/s390/fpu/feholdexcpt.c | 12 ++--------- + sysdeps/s390/fpu/fesetenv.c | 21 +++---------------- + sysdeps/s390/fpu/fesetround.c | 9 +++------ + sysdeps/s390/fpu/fetestexceptflag.c | 31 ----------------------------- + sysdeps/s390/fpu/feupdateenv.c | 14 +++---------- + sysdeps/s390/fpu/fgetexcptflg.c | 16 ++------------- + sysdeps/s390/fpu/fsetexcptflg.c | 23 ++++++++++----------- + sysdeps/s390/fpu/ftestexcept.c | 16 ++------------- + 9 files changed, 27 insertions(+), 124 deletions(-) + delete mode 100644 sysdeps/s390/fpu/fetestexceptflag.c + +diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c +index 3c38bc9189..f1be1d12e1 100644 +--- a/sysdeps/s390/fpu/fegetround.c ++++ b/sysdeps/s390/fpu/fegetround.c +@@ -17,17 +17,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include ++#include + + int + __fegetround (void) + { +- fexcept_t cw; +- +- _FPU_GETCW (cw); +- +- return cw & FPC_RM_MASK; ++ return get_rounding_mode (); + } + libm_hidden_def (__fegetround) + weak_alias (__fegetround, fegetround) +diff --git a/sysdeps/s390/fpu/feholdexcpt.c b/sysdeps/s390/fpu/feholdexcpt.c +index 5daee5675d..48af7ff51b 100644 +--- a/sysdeps/s390/fpu/feholdexcpt.c ++++ b/sysdeps/s390/fpu/feholdexcpt.c +@@ -17,19 +17,11 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include ++#include + + int __feholdexcept (fenv_t *envp) + { +- fexcept_t fpc; +- /* Store the environment. */ +- __fegetenv (envp); +- /* Clear the current sticky bits as more than one exception +- may be generated. */ +- fpc = envp->__fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK); +- /* Hold from generating fpu exceptions temporarily. */ +- _FPU_SETCW ((fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT))); ++ libc_feholdexcept_s390 (envp); + return 0; + } + libm_hidden_def (__feholdexcept) +diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c +index c6c275d79d..54ba2aa94a 100644 +--- a/sysdeps/s390/fpu/fesetenv.c ++++ b/sysdeps/s390/fpu/fesetenv.c +@@ -17,28 +17,13 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include +-#include +-#include ++#include + + int + __fesetenv (const fenv_t *envp) + { +- fenv_t env; +- +- if (envp == FE_DFL_ENV) +- { +- env.__fpc = _FPU_DEFAULT; +- } +- else if (envp == FE_NOMASK_ENV) +- { +- env.__fpc = FPC_EXCEPTION_MASK; +- } +- else +- env = (*envp); +- +- _FPU_SETCW (env.__fpc); ++ fenv_t env = libc_handle_user_fenv_s390 (envp); ++ libc_fesetenv_s390 (&env); + + /* Success. */ + return 0; +diff --git a/sysdeps/s390/fpu/fesetround.c b/sysdeps/s390/fpu/fesetround.c +index d8a84d2c96..0a7fe2635b 100644 +--- a/sysdeps/s390/fpu/fesetround.c ++++ b/sysdeps/s390/fpu/fesetround.c +@@ -17,21 +17,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include ++#include + + int + __fesetround (int round) + { +- if ((round|FPC_RM_MASK) != FPC_RM_MASK) ++ if ((round | FPC_RM_MASK) != FPC_RM_MASK) + { + /* ROUND is not a valid rounding mode. */ + return 1; + } +- __asm__ __volatile__ ("srnm 0(%0)" +- : +- : "a" (round)); + ++ libc_fesetround_s390 (round); + return 0; + } + libm_hidden_def (__fesetround) +diff --git a/sysdeps/s390/fpu/fetestexceptflag.c b/sysdeps/s390/fpu/fetestexceptflag.c +deleted file mode 100644 +index 784d356f7b..0000000000 +--- a/sysdeps/s390/fpu/fetestexceptflag.c ++++ /dev/null +@@ -1,31 +0,0 @@ +-/* Test exception in saved exception state. S/390 version. +- Copyright (C) 2016-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +-int +-fetestexceptflag (const fexcept_t *flagp, int excepts) +-{ +- /* As *flagp is obtained by an earlier call of fegetexceptflag the +- bits 0-5 of dxc-byte are either zero or correspond to the +- flag-bits. Evaluate flags and last dxc-exception-code. */ +- return (((*flagp >> FPC_FLAGS_SHIFT) | (*flagp >> FPC_DXC_SHIFT)) +- & excepts +- & FE_ALL_EXCEPT); +-} +diff --git a/sysdeps/s390/fpu/feupdateenv.c b/sysdeps/s390/fpu/feupdateenv.c +index 4888e1a864..f6b3d7d2de 100644 +--- a/sysdeps/s390/fpu/feupdateenv.c ++++ b/sysdeps/s390/fpu/feupdateenv.c +@@ -18,21 +18,13 @@ + . */ + + +-#include +-#include ++#include + + int + __feupdateenv (const fenv_t *envp) + { +- fexcept_t temp; +- +- _FPU_GETCW (temp); +- temp = (temp & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT; +- +- /* Raise the exceptions since the last call to feholdenv */ +- /* re install saved environment. */ +- __fesetenv (envp); +- __feraiseexcept ((int) temp); ++ fenv_t env = libc_handle_user_fenv_s390 (envp); ++ libc_feupdateenv_s390 (&env); + + /* Success. */ + return 0; +diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c +index 2a0f6dc77c..1985b396c9 100644 +--- a/sysdeps/s390/fpu/fgetexcptflg.c ++++ b/sysdeps/s390/fpu/fgetexcptflg.c +@@ -17,24 +17,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include ++#include + + int + fegetexceptflag (fexcept_t *flagp, int excepts) + { +- fexcept_t temp, newexcepts; +- +- /* Get the current exceptions. */ +- _FPU_GETCW (temp); +- newexcepts = excepts << FPC_FLAGS_SHIFT; +- if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) +- /* Bits 6, 7 of dxc-byte are zero, +- thus bits 0-5 of dxc-byte correspond to the flag-bits. +- Evaluate flags and last dxc-exception-code. */ +- newexcepts |= excepts << FPC_DXC_SHIFT; +- +- *flagp = temp & newexcepts; ++ *flagp = libc_fetestexcept_s390 (excepts); + + /* Success. */ + return 0; +diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c +index e50684c574..51d258cf17 100644 +--- a/sysdeps/s390/fpu/fsetexcptflg.c ++++ b/sysdeps/s390/fpu/fsetexcptflg.c +@@ -24,29 +24,26 @@ + int + fesetexceptflag (const fexcept_t *flagp, int excepts) + { +- fexcept_t temp, newexcepts; ++ fexcept_t fpc, fpc_new; + + /* Get the current environment. We have to do this since we cannot + separately set the status word. */ +- _FPU_GETCW (temp); +- /* Install the new exception bits in the Accrued Exception Byte. */ +- excepts = excepts & FE_ALL_EXCEPT; +- newexcepts = excepts << FPC_FLAGS_SHIFT; +- temp &= ~newexcepts; +- if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) ++ _FPU_GETCW (fpc); ++ ++ /* Clear the current exception bits. */ ++ fpc_new = fpc & ~((excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT); ++ if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0) + /* Bits 6, 7 of dxc-byte are zero, + thus bits 0-5 of dxc-byte correspond to the flag-bits. + Clear given exceptions in dxc-field. */ +- temp &= ~(excepts << FPC_DXC_SHIFT); ++ fpc_new &= ~((excepts & FE_ALL_EXCEPT) << FPC_DXC_SHIFT); + +- /* Integrate dxc-byte of flagp into flags. The dxc-byte of flagp contains +- either an ieee-exception or 0 (see fegetexceptflag). */ +- temp |= (*flagp | ((*flagp >> FPC_DXC_SHIFT) << FPC_FLAGS_SHIFT)) +- & newexcepts; ++ /* Set exceptions from flagp in flags-field. */ ++ fpc_new |= (*flagp & excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT; + + /* Store the new status word (along with the rest of the environment. + Possibly new exceptions are set but they won't get executed. */ +- _FPU_SETCW (temp); ++ _FPU_SETCW (fpc_new); + + /* Success. */ + return 0; +diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c +index 727b9b342d..f2acecc1af 100644 +--- a/sysdeps/s390/fpu/ftestexcept.c ++++ b/sysdeps/s390/fpu/ftestexcept.c +@@ -17,23 +17,11 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include ++#include + + int + fetestexcept (int excepts) + { +- fexcept_t temp, res; +- +- /* Get current exceptions. */ +- _FPU_GETCW (temp); +- res = temp >> FPC_FLAGS_SHIFT; +- if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) +- /* Bits 6, 7 of dxc-byte are zero, +- thus bits 0-5 of dxc-byte correspond to the flag-bits. +- Evaluate flags and last dxc-exception-code. */ +- res |= temp >> FPC_DXC_SHIFT; +- +- return res & excepts & FE_ALL_EXCEPT; ++ return libc_fetestexcept_s390 (excepts); + } + libm_hidden_def (fetestexcept) +-- +2.18.2 + diff --git a/SOURCES/glibc-rh1783303-1.patch b/SOURCES/glibc-rh1783303-1.patch new file mode 100644 index 0000000..89fe806 --- /dev/null +++ b/SOURCES/glibc-rh1783303-1.patch @@ -0,0 +1,1188 @@ +commit 6cac323c8dd78668e65aaa29f044cbd33c1a66a5 +Author: Adhemerval Zanella +Date: Fri Mar 15 18:42:00 2019 +0000 + + powerpc: ceil/ceilf refactor + + This patches consolidates all the powerpc ceil{f} implementations on + the generic sysdeps/powerpc/fpu/s_ceil{f}. The generic implementation + uses either the compiler builts for ISA 2.03+ (which generates the frip + instruction) or a generic implementation which uses FP only operations. + + It adds a generic implementation (round_to_integer.h) which is shared + with other rounding to integer routines. The resulting code should be + similar in term os performance to previous assembly one. + + The IFUNC organization for powerpc64 is also change to be enabled only + for powerpc64 and not for powerpc64le (since minium ISA of 2.08 does not + require the fallback generic implementation). + + Checked on powerpc-linux-gnu (built without --with-cpu, with + --with-cpu=power4 and with --with-cpu=power5+ and --disable-multi-arch), + powerpc64-linux-gnu (built without --with-cp and with --with-cpu=power5+ + and --disable-multi-arch). + + * sysdeps/powerpc/fpu/fenv_libc.h (__fesetround_inline_nocheck): New + function. + * sysdeps/powerpc/fpu/round_to_integer.h: New file. + * sysdeps/powerpc/fpu/s_ceil.c: Likewise. + * sysdeps/powerpc/fpu/s_ceilf.c: Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_ceil.S: Remove file. + * sysdeps/powerpc/powerpc32/fpu/s_ceilf.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile + (CFLAGS-s_ceil-power5+.c, CFLAGS-s_ceilf-power5+.c): New rule. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S: + Remove file. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S: + Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S: + Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S: + Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c: + New file. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c: + Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c: + Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c: + Likewise. + * sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S: Remove file. + * sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S: Likewise. + * sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile: New file. + * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c: + Likewise. + * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c: + Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c: Move to ... + * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c: ... here. + * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c: New + file. + * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c: + Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c: Move to ... + * sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c: ... + * here. + * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile + (libm-sysdep_routines): Remove s_ceil-power5+, s_ceil-ppc64, + s_ceilf-power5+, and s_ceilf-ppc64. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S: Remove + file. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S: Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_ceil.S: Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_ceilf.S: Likewise. + * sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S: Likewise. + * sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S: Likewise. + + Reviewed-by: Gabriel F. T. Gomes + +Conflicts: + sysdeps/powerpc/powerpc32/fpu/s_ceil.S + sysdeps/powerpc/powerpc32/fpu/s_ceilf.S + sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S + sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S + sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S + sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S + sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S + sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S + sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S + sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S + sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S + sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S + sysdeps/powerpc/powerpc64/fpu/s_ceil.S + sysdeps/powerpc/powerpc64/fpu/s_ceilf.S + sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S + sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S + (Removal after the copyright year header change upstream.) + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index 4c19d12b0b31c1f9..a0128c66444a3e46 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -98,6 +98,14 @@ __fesetround_inline (int round) + return 0; + } + ++/* Same as __fesetround_inline, however without runtime check to use DFP ++ mtfsfi syntax (as relax_fenv_state) or if round value is valid. */ ++static inline void ++__fesetround_inline_nocheck (const int round) ++{ ++ asm volatile ("mtfsfi 7,%0" : : "i" (round)); ++} ++ + /* Definitions of all the FPSCR bit numbers */ + enum { + FPSCR_FX = 0, /* exception summary */ +diff --git a/sysdeps/powerpc/fpu/round_to_integer.h b/sysdeps/powerpc/fpu/round_to_integer.h +new file mode 100644 +index 0000000000000000..c70afbb10f600d81 +--- /dev/null ++++ b/sysdeps/powerpc/fpu/round_to_integer.h +@@ -0,0 +1,105 @@ ++/* Round to integer generic implementation. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#ifndef _ROUND_TO_INTEGER_H ++#define _ROUND_TO_INTEGER_H ++ ++#include ++ ++enum round_mode ++{ ++ CEIL ++}; ++ ++static inline void ++set_fenv_mode (enum round_mode mode) ++{ ++ int rmode; ++ switch (mode) ++ { ++ case CEIL: rmode = FE_UPWARD; break; ++ default: rmode = FE_TONEAREST; break; ++ } ++ __fesetround_inline_nocheck (rmode); ++} ++ ++static inline float ++round_to_integer_float (enum round_mode mode, float x) ++{ ++ /* Ensure sNaN input is converted to qNaN. */ ++ if (__glibc_unlikely (isnan (x))) ++ return x + x; ++ ++ if (fabs (x) > 0x1p+23) ++ return x; ++ ++ float r = x; ++ ++ /* Save current FPU rounding mode and inexact state. */ ++ fenv_t fe = fegetenv_register (); ++ set_fenv_mode (mode); ++ if (x > 0.0) ++ { ++ r += 0x1p+23; ++ r -= 0x1p+23; ++ r = fabs (r); ++ } ++ else if (x < 0.0) ++ { ++ r -= 0x1p+23; ++ r += 0x1p+23; ++ r = -fabs (r); ++ } ++ __builtin_mtfsf (0xff, fe); ++ ++ return r; ++} ++ ++static inline double ++round_to_integer_double (enum round_mode mode, double x) ++{ ++ /* Ensure sNaN input is converted to qNaN. */ ++ if (__glibc_unlikely (isnan (x))) ++ return x + x; ++ ++ if (fabs (x) > 0x1p+52) ++ return x; ++ ++ double r = x; ++ ++ /* Save current FPU rounding mode and inexact state. */ ++ fenv_t fe = fegetenv_register (); ++ set_fenv_mode (mode); ++ if (x > 0.0) ++ { ++ r += 0x1p+52; ++ r -= 0x1p+52; ++ r = fabs (r); ++ } ++ else if (x < 0.0) ++ { ++ r -= 0x1p+52; ++ r += 0x1p+52; ++ r = -fabs (r); ++ } ++ __builtin_mtfsf (0xff, fe); ++ ++ return r; ++} ++ ++#endif +diff --git a/sysdeps/powerpc/fpu/s_ceil.c b/sysdeps/powerpc/fpu/s_ceil.c +new file mode 100644 +index 0000000000000000..49008c7af87d6d55 +--- /dev/null ++++ b/sysdeps/powerpc/fpu/s_ceil.c +@@ -0,0 +1,35 @@ ++/* Smallest integral value not less than argument. PowerPC version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#define NO_MATH_REDIRECT ++#include ++#include ++#include ++ ++double ++__ceil (double x) ++{ ++#ifdef _ARCH_PWR5X ++ return __builtin_ceil (x); ++#else ++ return round_to_integer_double (CEIL, x); ++#endif ++} ++#ifndef __ceil ++libm_alias_double (__ceil, ceil) ++#endif +diff --git a/sysdeps/powerpc/fpu/s_ceilf.c b/sysdeps/powerpc/fpu/s_ceilf.c +new file mode 100644 +index 0000000000000000..8c86bf30a34df4cf +--- /dev/null ++++ b/sysdeps/powerpc/fpu/s_ceilf.c +@@ -0,0 +1,35 @@ ++/* Smallest integral value not less than argument. PowerPC version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#define NO_MATH_REDIRECT ++#include ++#include ++#include ++ ++float ++__ceilf (float x) ++{ ++#ifdef _ARCH_PWR5X ++ return __builtin_ceilf (x); ++#else ++ return round_to_integer_float (CEIL, x); ++#endif ++} ++#ifndef __ceilf ++libm_alias_float (__ceil, ceil) ++#endif +diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S +deleted file mode 100644 +index 7f2f97ada1a14a52..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S ++++ /dev/null +@@ -1,76 +0,0 @@ +-/* ceil function. PowerPC32 version. +- Copyright (C) 2004-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +- +- .section .rodata.cst4,"aM",@progbits,4 +- .align 2 +-.LC0: /* 2**52 */ +- .long 0x59800000 +- +- .section ".text" +-ENTRY (__ceil) +-#ifdef SHARED +- mflr r11 +- cfi_register(lr,r11) +- SETUP_GOT_ACCESS(r9,got_label) +- addis r9,r9,.LC0-got_label@ha +- lfs fp13,.LC0-got_label@l(r9) +- mtlr r11 +- cfi_same_value (lr) +-#else +- lis r9,.LC0@ha +- lfs fp13,.LC0@l(r9) +-#endif +- fabs fp0,fp1 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- mffs fp11 /* Save current FPU rounding mode and +- "inexact" state. */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L10 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- ble- cr6,.L4 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) */ +- /* x = 0.0; */ +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L4: +- bge- cr6,.L9 /* if (x < 0.0) */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fnabs fp1,fp1 /* if (x == 0.0) */ +- /* x = -0.0; */ +-.L9: +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L10: +- /* Ensure sNaN input is converted to qNaN. */ +- fcmpu cr7,fp1,fp1 +- beqlr cr7 +- fadd fp1,fp1,fp1 +- blr +- END (__ceil) +- +-libm_alias_double (__ceil, ceil) +diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S +deleted file mode 100644 +index 3f5949004fa51baf..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S ++++ /dev/null +@@ -1,76 +0,0 @@ +-/* float ceil function. PowerPC32 version. +- Copyright (C) 2004-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .section .rodata.cst4,"aM",@progbits,4 +- .align 2 +-.LC0: /* 2**23 */ +- .long 0x4b000000 +- +- .section ".text" +-ENTRY (__ceilf) +-#ifdef SHARED +- mflr r11 +- cfi_register(lr,r11) +- SETUP_GOT_ACCESS(r9,got_label) +- addis r9,r9,.LC0-got_label@ha +- lfs fp13,.LC0-got_label@l(r9) +- mtlr r11 +- cfi_same_value (lr) +-#else +- lis r9,.LC0@ha +- lfs fp13,.LC0@l(r9) +-#endif +- fabs fp0,fp1 +- fsubs fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ +- mffs fp11 /* Save current FPU rounding mode and +- "inexact" state. */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L10 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- ble- cr6,.L4 +- fadds fp1,fp1,fp13 /* x+= TWO23; */ +- fsubs fp1,fp1,fp13 /* x-= TWO23; */ +- fabs fp1,fp1 /* if (x == 0.0) */ +- /* x = 0.0; */ +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L4: +- bge- cr6,.L9 /* if (x < 0.0) */ +- fsubs fp1,fp1,fp13 /* x-= TWO23; */ +- fadds fp1,fp1,fp13 /* x+= TWO23; */ +- fnabs fp1,fp1 /* if (x == 0.0) */ +- /* x = -0.0; */ +-.L9: +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L10: +- /* Ensure sNaN input is converted to qNaN. */ +- fcmpu cr7,fp1,fp1 +- beqlr cr7 +- fadds fp1,fp1,fp1 +- blr +- END (__ceilf) +- +-libm_alias_float (__ceil, ceil) +- +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile +index 4e85021d50831eb6..cf38e347f2da74e9 100644 +--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile +@@ -26,6 +26,8 @@ libm-sysdep_routines += s_llrintf-power6 s_llrintf-ppc32 s_llrint-power6 \ + s_logbf-power7 s_logbf-ppc32 e_hypot-power7 \ + e_hypot-ppc32 e_hypotf-power7 e_hypotf-ppc32 + ++CFLAGS-s_ceil-power5+.c = -mcpu=power5+ ++CFLAGS-s_ceilf-power5+.c = -mcpu=power5+ + CFLAGS-s_modf-power5+.c = -mcpu=power5+ + CFLAGS-s_modff-power5+.c = -mcpu=power5+ + CFLAGS-s_logbl-power7.c = -mcpu=power7 +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S +deleted file mode 100644 +index b8181585a869bd8a..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S ++++ /dev/null +@@ -1,33 +0,0 @@ +-/* ceil function. PowerPC32/power5+ version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +-#undef hidden_def +-#define hidden_def(name) +-#undef weak_alias +-#define weak_alias(name, alias) +-#undef strong_alias +-#define strong_alias(name, alias) +-#undef compat_symbol +-#define compat_symbol(lib, name, alias, ver) +- +-#define __ceil __ceil_power5plus +- +-#include +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c +new file mode 100644 +index 0000000000000000..87bc66cdb0322c59 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceil __ceil_power5plus ++#include +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S +deleted file mode 100644 +index cd2bc69b677e76db..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S ++++ /dev/null +@@ -1,31 +0,0 @@ +-/* ceil function. PowerPC32 default version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +-#undef weak_alias +-#define weak_alias(a,b) +-#undef strong_alias +-#define strong_alias(a,b) +-#undef compat_symbol +-#define compat_symbol(a,b,c,d) +- +-#define __ceil __ceil_ppc32 +- +-#include +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c +new file mode 100644 +index 0000000000000000..93c098476b915f9d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceil __ceil_ppc32 ++#include +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S +deleted file mode 100644 +index d01aa6e7db3d0b9d..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* ceilf function. PowerPC32/power5+ version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-#undef weak_alias +-#define weak_alias(name, alias) +- +-#define __ceilf __ceilf_power5plus +- +-#include +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c +new file mode 100644 +index 0000000000000000..a5bfa98535c088a0 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceilf __ceilf_power5plus ++#include +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S +deleted file mode 100644 +index 264e032b3b27f9b3..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S ++++ /dev/null +@@ -1,27 +0,0 @@ +-/* ceilf function. PowerPC32 default version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +-#undef weak_alias +-#define weak_alias(a,b) +- +-#define __ceilf __ceilf_ppc32 +- +-#include +diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c +new file mode 100644 +index 0000000000000000..a4dcdcb4069289d6 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceilf __ceilf_ppc32 ++#include +diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S +deleted file mode 100644 +index 356c7a79edf79940..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S ++++ /dev/null +@@ -1,29 +0,0 @@ +-/* ceil function. PowerPC32/power5+ version. +- Copyright (C) 2006-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +- +- .machine "power5" +-EALIGN (__ceil, 4, 0) +- frip fp1, fp1 +- blr +- END (__ceil) +- +-libm_alias_double (__ceil, ceil) +diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S +deleted file mode 100644 +index a0bcda17fde0c0f6..0000000000000000 +--- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* ceilf function. PowerPC32/power5+ version. +- Copyright (C) 2006-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .machine "power5" +-EALIGN (__ceilf, 4, 0) +- frip fp1, fp1 /* The rounding instructions are double. */ +- frsp fp1, fp1 /* But we need to set ooverflow for float. */ +- blr +- END (__ceilf) +- +-libm_alias_float (__ceil, ceil) +- +diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile +new file mode 100644 +index 0000000000000000..932c3c7e6c6ad27e +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile +@@ -0,0 +1,9 @@ ++ifeq ($(subdir),math) ++libm-sysdep_routines += s_ceil-power5+ \ ++ s_ceil-ppc64 \ ++ s_ceilf-power5+ \ ++ s_ceilf-ppc64 ++ ++CFLAGS-s_ceil-power5+.c = -mcpu=power5+ ++CFLAGS-s_ceilf-power5+.c = -mcpu=power5+ ++endif +diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c +new file mode 100644 +index 0000000000000000..87bc66cdb0322c59 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceil __ceil_power5plus ++#include +diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c +new file mode 100644 +index 0000000000000000..8711ff3229467026 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceil __ceil_ppc64 ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c +similarity index 95% +rename from sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c +rename to sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c +index 5cde4eb46f26ec82..1abca7ef63d6a852 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c ++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c +@@ -17,10 +17,8 @@ + . */ + + #include +-#include +-#include +-#include "init-arch.h" + #include ++#include "init-arch.h" + + extern __typeof (__ceil) __ceil_ppc64 attribute_hidden; + extern __typeof (__ceil) __ceil_power5plus attribute_hidden; +diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c +new file mode 100644 +index 0000000000000000..a5bfa98535c088a0 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceilf __ceilf_power5plus ++#include +diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c +new file mode 100644 +index 0000000000000000..086251dc0937acfa +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c +@@ -0,0 +1,3 @@ ++#include ++#define __ceilf __ceilf_ppc64 ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c +similarity index 95% +rename from sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c +rename to sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c +index 18697e52b3ac1616..33245968a86ddcf5 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c ++++ b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c +@@ -17,10 +17,8 @@ + . */ + + #include +-#include +-#include +-#include "init-arch.h" + #include ++#include "init-arch.h" + + extern __typeof (__ceilf) __ceilf_ppc64 attribute_hidden; + extern __typeof (__ceilf) __ceilf_power5plus attribute_hidden; +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 73f2f693771027a9..2805e4e0d66f3175 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -14,8 +14,7 @@ sysdep_calls := s_copysign-power6 s_copysign-ppc64 \ + + sysdep_routines += $(sysdep_calls) + libm-sysdep_routines += s_llround-power6x \ +- s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \ +- s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \ ++ s_llround-power5+ s_llround-ppc64 \ + s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \ + s_floorf-ppc64 s_round-power5+ s_round-ppc64 \ + s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \ +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S +deleted file mode 100644 +index 76651b694c251bb4..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* ceil function. PowerPC64/power5+ version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-#undef weak_alias +-#define weak_alias(a,b) +-#undef strong_alias +-#define strong_alias(a,b) +-#undef compat_symbol +-#define compat_symbol(a,b,c,d) +- +-#define __ceil __ceil_power5plus +- +-#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S +deleted file mode 100644 +index c75c66ba3bbf49c8..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* ceil function. PowerPC64 default version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-#undef weak_alias +-#define weak_alias(a,b) +-#undef strong_alias +-#define strong_alias(a,b) +-#undef compat_symbol +-#define compat_symbol(a,b,c,d) +- +-#define __ceil __ceil_ppc64 +- +-#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S +deleted file mode 100644 +index b9c9e14fba6ee134..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S ++++ /dev/null +@@ -1,24 +0,0 @@ +-/* ceilf function. PowerPC64/power5+ version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#undef weak_alias +-#define weak_alias(a,b) +- +-#define __ceilf __ceilf_power5plus +- +-#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S +deleted file mode 100644 +index ce5cc49770fdfdee..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S ++++ /dev/null +@@ -1,24 +0,0 @@ +-/* ceilf function. PowerPC64 default version. +- Copyright (C) 2013-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#undef weak_alias +-#define weak_alias(a,b) +- +-#define __ceilf __ceilf_ppc64 +- +-#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S +deleted file mode 100644 +index 252d94f51ea1a167..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S ++++ /dev/null +@@ -1,65 +0,0 @@ +-/* ceil function. PowerPC64 version. +- Copyright (C) 2004-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +- .section ".text" +- +-ENTRY (__ceil, 4) +- CALL_MCOUNT 0 +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- mffs fp11 /* Save current FPU rounding mode and +- "inexact" state. */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L10 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- ble- cr6,.L4 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) */ +- /* x = 0.0; */ +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L4: +- bge- cr6,.L9 /* if (x < 0.0) */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fnabs fp1,fp1 /* if (x == 0.0) */ +- /* x = -0.0; */ +-.L9: +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L10: +- /* Ensure sNaN input is converted to qNaN. */ +- fcmpu cr7,fp1,fp1 +- beqlr cr7 +- fadd fp1,fp1,fp1 +- blr +- END (__ceil) +- +-libm_alias_double (__ceil, ceil) +diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S +deleted file mode 100644 +index 3c62077c143eeced..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* float ceil function. PowerPC64 version. +- Copyright (C) 2004-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +- .p2align 3 +-.LC0: /* 2**23 */ +- .long 0x4b000000 +- .long 0x0 +- .section ".text" +- +-ENTRY (__ceilf, 4) +- CALL_MCOUNT 0 +- lfs fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fsubs fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ +- mffs fp11 /* Save current FPU rounding mode and +- "inexact" state. */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L10 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- ble- cr6,.L4 +- fadds fp1,fp1,fp13 /* x+= TWO23; */ +- fsubs fp1,fp1,fp13 /* x-= TWO23; */ +- fabs fp1,fp1 /* if (x == 0.0) */ +- /* x = 0.0; */ +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L4: +- bge- cr6,.L9 /* if (x < 0.0) */ +- fsubs fp1,fp1,fp13 /* x-= TWO23; */ +- fadds fp1,fp1,fp13 /* x+= TWO23; */ +- fnabs fp1,fp1 /* if (x == 0.0) */ +- /* x = -0.0; */ +-.L9: +- mtfsf 0xff,fp11 /* Restore previous rounding mode and +- "inexact" state. */ +- blr +-.L10: +- /* Ensure sNaN input is converted to qNaN. */ +- fcmpu cr7,fp1,fp1 +- beqlr cr7 +- fadds fp1,fp1,fp1 +- blr +- END (__ceilf) +- +-libm_alias_float (__ceil, ceil) +- +diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S +deleted file mode 100644 +index e500932573c07503..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* ceil function. PowerPC64/power5+ version. +- Copyright (C) 2006-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +- +- .machine "power5" +-ENTRY_TOCLESS (__ceil, 4) +- CALL_MCOUNT 0 +- frip fp1, fp1 +- blr +- END (__ceil) +- +-libm_alias_double (__ceil, ceil) +diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S +deleted file mode 100644 +index d0b2118c2a3f81be..0000000000000000 +--- a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S ++++ /dev/null +@@ -1,31 +0,0 @@ +-/* ceilf function. PowerPC64/power5+ version. +- Copyright (C) 2006-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .machine "power5" +-ENTRY_TOCLESS (__ceilf, 4) +- CALL_MCOUNT 0 +- frip fp1, fp1 /* The rounding instructions are double. */ +- frsp fp1, fp1 /* But we need to set ooverflow for float. */ +- blr +- END (__ceilf) +- +-libm_alias_float (__ceil, ceil) +- diff --git a/SOURCES/glibc-rh1783303-10.patch b/SOURCES/glibc-rh1783303-10.patch new file mode 100644 index 0000000..33663f6 --- /dev/null +++ b/SOURCES/glibc-rh1783303-10.patch @@ -0,0 +1,57 @@ +commit 0b3c9e57a41d9f7c26fb6aa45b99f671bef9c7e0 +Author: Paul A. Clarke +Date: Tue Aug 20 15:57:35 2019 -0500 + + [powerpc] fegetenv_status: simplify instruction generation + + fegetenv_status() wants to use the lighter weight instruction 'mffsl' + for reading the Floating-Point Status and Control Register (FPSCR). + It currently will use it directly if compiled '-mcpu=power9', and will + perform a runtime check (cpu_supports("arch_3_00")) otherwise. + + Nicely, it turns out that the 'mffsl' instruction will decode to + 'mffs' on architectures older than "arch_3_00" because the additional + bits set for 'mffsl' are "don't care" for 'mffs'. 'mffs' is a superset + of 'mffsl'. + + So, just generate 'mffsl'. + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index b244770d115ea7bb..e8d40ea256b6c5bc 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -36,9 +36,12 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; }) + + /* Equivalent to fegetenv_register, but only returns bits for +- status, exception enables, and mode. */ +- +-#define fegetenv_status_ISA300() \ ++ status, exception enables, and mode. ++ Nicely, it turns out that the 'mffsl' instruction will decode to ++ 'mffs' on architectures older than "power9" because the additional ++ bits set for 'mffsl' are "don't care" for 'mffs'. 'mffs' is a superset ++ of 'mffsl'. */ ++#define fegetenv_status() \ + ({register double __fr; \ + __asm__ __volatile__ ( \ + ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ +@@ -46,18 +49,6 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + __fr; \ + }) + +-#ifdef _ARCH_PWR9 +-# define fegetenv_status() fegetenv_status_ISA300() +-#elif defined __BUILTIN_CPU_SUPPORTS__ +-# define fegetenv_status() \ +- (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ +- ? fegetenv_status_ISA300() \ +- : fegetenv_register() \ +- ) +-#else +-# define fegetenv_status() fegetenv_register () +-#endif +- + /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ + #define fesetenv_register(env) \ + do { \ diff --git a/SOURCES/glibc-rh1783303-11.patch b/SOURCES/glibc-rh1783303-11.patch new file mode 100644 index 0000000..2af4f13 --- /dev/null +++ b/SOURCES/glibc-rh1783303-11.patch @@ -0,0 +1,128 @@ +commit f1c56cdff09f650ad721fae026eb6a3651631f3d +Author: Paul A. Clarke +Date: Thu Sep 19 08:35:16 2019 -0500 + + [powerpc] SET_RESTORE_ROUND optimizations and bug fix + + SET_RESTORE_ROUND brackets a block of code, temporarily setting and + restoring the rounding mode and letting everything else, including + exceptions generated within the block, pass through. + + On powerpc, the current code clears the exception enables, which will hide + exceptions generated within the block. This issue was introduced by me + in commit e905212627350d54b58426214b5a54ddc852b0c9. + + Fix this by not clearing exception enable bits in the prologue. + + Also, since we are no longer changing the enable bits in either the + prologue or the epilogue, there is no need to test for entering/exiting + non-stop mode. + + Also, optimize the prologue get/save/set rounding mode operations for + POWER9 and later by using 'mffscrn' when possible. + + Suggested-by: Paul E. Murphy + Reviewed-by: Paul E. Murphy + Fixes: e905212627350d54b58426214b5a54ddc852b0c9 + + 2019-09-19 Paul A. Clarke + + * sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_and_set_rn): New. + (__fe_mffscrn): New. + * sysdeps/powerpc/fpu/fenv_private.h (libc_feholdsetround_ppc_ctx): + Do not clear enable bits, remove obsolete code, use + fegetenv_and_set_rn. + (libc_feresetround_ppc): Remove obsolete code, use + fegetenv_and_set_rn. + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index e8d40ea256b6c5bc..b10b6a141ded4bfd 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -49,6 +49,38 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + __fr; \ + }) + ++#define __fe_mffscrn(rn) \ ++ ({register fenv_union_t __fr; \ ++ if (__builtin_constant_p (rn)) \ ++ __asm__ __volatile__ ( \ ++ ".machine push; .machine \"power9\"; mffscrni %0,%1; .machine pop" \ ++ : "=f" (__fr.fenv) : "i" (rn)); \ ++ else \ ++ { \ ++ __fr.l = (rn); \ ++ __asm__ __volatile__ ( \ ++ ".machine push; .machine \"power9\"; mffscrn %0,%1; .machine pop" \ ++ : "=f" (__fr.fenv) : "f" (__fr.fenv)); \ ++ } \ ++ __fr.fenv; \ ++ }) ++ ++/* Like fegetenv_status, but also sets the rounding mode. */ ++#ifdef _ARCH_PWR9 ++#define fegetenv_and_set_rn(rn) __fe_mffscrn (rn) ++#else ++/* 'mffscrn' will decode to 'mffs' on ARCH < 3_00, which is still necessary ++ but not sufficient, because it does not set the rounding mode. ++ Explicitly set the rounding mode when 'mffscrn' actually doesn't. */ ++#define fegetenv_and_set_rn(rn) \ ++ ({register fenv_union_t __fr; \ ++ __fr.fenv = __fe_mffscrn (rn); \ ++ if (__glibc_unlikely (!(GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00))) \ ++ __fesetround_inline (rn); \ ++ __fr.fenv; \ ++ }) ++#endif ++ + /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ + #define fesetenv_register(env) \ + do { \ +diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h +index b0149aa243e69f5a..30df92c9a4700dee 100644 +--- a/sysdeps/powerpc/fpu/fenv_private.h ++++ b/sysdeps/powerpc/fpu/fenv_private.h +@@ -133,16 +133,7 @@ static __always_inline void + libc_feresetround_ppc (fenv_t *envp) + { + fenv_union_t new = { .fenv = *envp }; +- +- /* If the old env has no enabled exceptions and the new env has any enabled +- exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the +- hardware into "precise mode" and may cause the FPU to run slower on some +- hardware. */ +- if ((new.l & _FPU_ALL_TRAPS) != 0) +- (void) __fe_nomask_env_priv (); +- +- /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ +- fesetenv_mode (new.fenv); ++ fegetenv_and_set_rn (new.l & FPSCR_RN_MASK); + } + + static __always_inline int +@@ -184,22 +175,10 @@ libc_feupdateenv_ppc (fenv_t *e) + static __always_inline void + libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r) + { +- fenv_union_t old, new; ++ fenv_union_t old; + +- old.fenv = fegetenv_status (); +- +- new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r; +- +- ctx->env = old.fenv; +- if (__glibc_unlikely (new.l != old.l)) +- { +- if ((old.l & _FPU_ALL_TRAPS) != 0) +- (void) __fe_mask_env (); +- fesetenv_mode (new.fenv); +- ctx->updated_status = true; +- } +- else +- ctx->updated_status = false; ++ ctx->env = old.fenv = fegetenv_and_set_rn (r); ++ ctx->updated_status = (r != (old.l & FPSCR_RN_MASK)); + } + + static __always_inline void diff --git a/SOURCES/glibc-rh1783303-12.patch b/SOURCES/glibc-rh1783303-12.patch new file mode 100644 index 0000000..5113469 --- /dev/null +++ b/SOURCES/glibc-rh1783303-12.patch @@ -0,0 +1,303 @@ +commit e3d85df50b083c9ba68a40f5d45b201cbec4e68b +Author: Paul A. Clarke +Date: Thu Sep 19 09:13:14 2019 -0500 + + [powerpc] fenv_private.h clean up + + fenv_private.h includes unused functions, magic macro constants, and + some replicated common code fragments. + + Remove unused functions, replace magic constants with constants from + fenv_libc.h, and refactor replicated code. + + Suggested-by: Paul E. Murphy + Reviewed-By: Paul E Murphy + +diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c +index 2a776c72fb5a2b70..bdf55ac62f1ffe4f 100644 +--- a/sysdeps/powerpc/fpu/fedisblxcpt.c ++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c +@@ -43,8 +43,7 @@ fedisableexcept (int excepts) + if (fe.l != curr.l) + fesetenv_mode (fe.fenv); + +- if (new == 0 && result != 0) +- (void)__fe_mask_env (); ++ __TEST_AND_ENTER_NON_STOP (-1ULL, fe.l); + + return result; + } +diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c +index 6f5a828e80965bfa..78ebabed9232c0ad 100644 +--- a/sysdeps/powerpc/fpu/feenablxcpt.c ++++ b/sysdeps/powerpc/fpu/feenablxcpt.c +@@ -43,8 +43,7 @@ feenableexcept (int excepts) + if (fe.l != curr.l) + fesetenv_mode (fe.fenv); + +- if (new != 0 && result == 0) +- (void) __fe_nomask_env_priv (); ++ __TEST_AND_EXIT_NON_STOP (0ULL, fe.l); + + return result; + } +diff --git a/sysdeps/powerpc/fpu/feholdexcpt.c b/sysdeps/powerpc/fpu/feholdexcpt.c +index 8ec3fbff82b22f51..9636ecaa0b600b0d 100644 +--- a/sysdeps/powerpc/fpu/feholdexcpt.c ++++ b/sysdeps/powerpc/fpu/feholdexcpt.c +@@ -18,7 +18,6 @@ + + #include + #include +-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) + + int + __feholdexcept (fenv_t *envp) +@@ -35,11 +34,7 @@ __feholdexcept (fenv_t *envp) + if (new.l == old.l) + return 0; + +- /* If the old env had any enabled exceptions, then mask SIGFPE in the +- MSR FE0/FE1 bits. This may allow the FPU to run faster because it +- always takes the default action and can not generate SIGFPE. */ +- if ((old.l & _FPU_MASK_ALL) != 0) +- (void)__fe_mask_env (); ++ __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); + + /* Put the new state in effect. */ + fesetenv_register (new.fenv); +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index b10b6a141ded4bfd..36b639c3939586f6 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -27,6 +27,26 @@ extern const fenv_t *__fe_nomask_env_priv (void); + + extern const fenv_t *__fe_mask_env (void) attribute_hidden; + ++/* If the old env had any enabled exceptions and the new env has no enabled ++ exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the ++ FPU to run faster because it always takes the default action and can not ++ generate SIGFPE. */ ++#define __TEST_AND_ENTER_NON_STOP(old, new) \ ++ do { \ ++ if (((old) & FPSCR_ENABLES_MASK) != 0 && ((new) & FPSCR_ENABLES_MASK) == 0) \ ++ (void) __fe_mask_env (); \ ++ } while (0) ++ ++/* If the old env has no enabled exceptions and the new env has any enabled ++ exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the ++ hardware into "precise mode" and may cause the FPU to run slower on some ++ hardware. */ ++#define __TEST_AND_EXIT_NON_STOP(old, new) \ ++ do { \ ++ if (((old) & FPSCR_ENABLES_MASK) == 0 && ((new) & FPSCR_ENABLES_MASK) != 0) \ ++ (void) __fe_nomask_env_priv (); \ ++ } while (0) ++ + /* The sticky bits in the FPSCR indicating exceptions have occurred. */ + #define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID) + +diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h +index 30df92c9a4700dee..c236d45db2f399a4 100644 +--- a/sysdeps/powerpc/fpu/fenv_private.h ++++ b/sysdeps/powerpc/fpu/fenv_private.h +@@ -23,73 +23,20 @@ + #include + #include + +-/* Mask for the exception enable bits. */ +-#define _FPU_ALL_TRAPS (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM \ +- | _FPU_MASK_XM | _FPU_MASK_IM) +- +-/* Mask the rounding mode bits. */ +-#define _FPU_MASK_RN 0xfffffffffffffffcLL +- +-/* Mask everything but the rounding modes and non-IEEE arithmetic flags. */ +-#define _FPU_MASK_NOT_RN_NI 0xffffffff00000807LL +- +-/* Mask restore rounding mode and exception enabled. */ +-#define _FPU_MASK_TRAPS_RN 0xffffffffffffff00LL +- +-/* Mask FP result flags, preserve fraction rounded/inexact bits. */ +-#define _FPU_MASK_FRAC_INEX_RET_CC 0xfffffffffff80fffLL +- + static __always_inline void +-__libc_feholdbits_ppc (fenv_t *envp, unsigned long long mask, +- unsigned long long bits) ++libc_feholdexcept_setround_ppc (fenv_t *envp, int r) + { + fenv_union_t old, new; + + old.fenv = *envp = fegetenv_register (); + +- new.l = (old.l & mask) | bits; +- +- /* If the old env had any enabled exceptions, then mask SIGFPE in the +- MSR FE0/FE1 bits. This may allow the FPU to run faster because it +- always takes the default action and can not generate SIGFPE. */ +- if ((old.l & _FPU_ALL_TRAPS) != 0) +- (void) __fe_mask_env (); ++ __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); + ++ /* Clear everything and set the rounding mode. */ ++ new.l = r; + fesetenv_register (new.fenv); + } + +-static __always_inline void +-libc_feholdexcept_ppc (fenv_t *envp) +-{ +- __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI, 0LL); +-} +- +-static __always_inline void +-libc_feholdexcept_setround_ppc (fenv_t *envp, int r) +-{ +- __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI & _FPU_MASK_RN, r); +-} +- +-static __always_inline void +-libc_fesetround_ppc (int r) +-{ +- __fesetround_inline (r); +-} +- +-static __always_inline int +-libc_fetestexcept_ppc (int e) +-{ +- fenv_union_t u; +- u.fenv = fegetenv_register (); +- return u.l & e; +-} +- +-static __always_inline void +-libc_feholdsetround_ppc (fenv_t *e, int r) +-{ +- __libc_feholdbits_ppc (e, _FPU_MASK_TRAPS_RN, r); +-} +- + static __always_inline unsigned long long + __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, + unsigned long long new_mask) +@@ -102,19 +49,8 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, + /* Merge bits while masking unwanted bits from new and old env. */ + new.l = (old.l & old_mask) | (new.l & new_mask); + +- /* If the old env has no enabled exceptions and the new env has any enabled +- exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the +- hardware into "precise mode" and may cause the FPU to run slower on some +- hardware. */ +- if ((old.l & _FPU_ALL_TRAPS) == 0 && (new.l & _FPU_ALL_TRAPS) != 0) +- (void) __fe_nomask_env_priv (); +- +- /* If the old env had any enabled exceptions and the new env has no enabled +- exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the +- FPU to run faster because it always takes the default action and can not +- generate SIGFPE. */ +- if ((old.l & _FPU_ALL_TRAPS) != 0 && (new.l & _FPU_ALL_TRAPS) == 0) +- (void) __fe_mask_env (); ++ __TEST_AND_EXIT_NON_STOP (old.l, new.l); ++ __TEST_AND_ENTER_NON_STOP (old.l, new.l); + + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ + fesetenv_register (new.fenv); +@@ -139,8 +75,8 @@ libc_feresetround_ppc (fenv_t *envp) + static __always_inline int + libc_feupdateenv_test_ppc (fenv_t *envp, int ex) + { +- return __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, +- _FPU_MASK_FRAC_INEX_RET_CC) & ex; ++ return __libc_femergeenv_ppc (envp, ~FPSCR_CONTROL_MASK, ++ ~FPSCR_STATUS_MASK) & ex; + } + + static __always_inline void +@@ -193,8 +129,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r) + ctx->env = old.fenv; + if (__glibc_unlikely (new.l != old.l)) + { +- if ((old.l & _FPU_ALL_TRAPS) != 0) +- (void) __fe_mask_env (); ++ __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); + fesetenv_register (new.fenv); + ctx->updated_status = true; + } +diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c +index ac927c8f3ada40b4..4eab5045c48105e3 100644 +--- a/sysdeps/powerpc/fpu/fesetenv.c ++++ b/sysdeps/powerpc/fpu/fesetenv.c +@@ -28,19 +28,8 @@ __fesetenv (const fenv_t *envp) + new.fenv = *envp; + old.fenv = fegetenv_status (); + +- /* If the old env has no enabled exceptions and the new env has any enabled +- exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the +- hardware into "precise mode" and may cause the FPU to run slower on some +- hardware. */ +- if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0) +- (void) __fe_nomask_env_priv (); +- +- /* If the old env had any enabled exceptions and the new env has no enabled +- exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the +- FPU to run faster because it always takes the default action and can not +- generate SIGFPE. */ +- if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0) +- (void)__fe_mask_env (); ++ __TEST_AND_EXIT_NON_STOP (old.l, new.l); ++ __TEST_AND_ENTER_NON_STOP (old.l, new.l); + + fesetenv_register (new.fenv); + +diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c +index 29e088d5ab1c0d93..58ba02c0a1e64c27 100644 +--- a/sysdeps/powerpc/fpu/fesetmode.c ++++ b/sysdeps/powerpc/fpu/fesetmode.c +@@ -33,11 +33,8 @@ fesetmode (const femode_t *modep) + if (old.l == new.l) + return 0; + +- if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0) +- (void) __fe_nomask_env_priv (); +- +- if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0) +- (void) __fe_mask_env (); ++ __TEST_AND_EXIT_NON_STOP (old.l, new.l); ++ __TEST_AND_ENTER_NON_STOP (old.l, new.l); + + fesetenv_mode (new.fenv); + return 0; +diff --git a/sysdeps/powerpc/fpu/feupdateenv.c b/sysdeps/powerpc/fpu/feupdateenv.c +index 2dbd1c4e9ec65ed0..fdd15651e0101f9e 100644 +--- a/sysdeps/powerpc/fpu/feupdateenv.c ++++ b/sysdeps/powerpc/fpu/feupdateenv.c +@@ -20,8 +20,6 @@ + #include + #include + +-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) +- + int + __feupdateenv (const fenv_t *envp) + { +@@ -36,19 +34,8 @@ __feupdateenv (const fenv_t *envp) + unchanged. */ + new.l = (old.l & 0xffffffff1fffff00LL) | (new.l & 0x1ff80fff); + +- /* If the old env has no enabled exceptions and the new env has any enabled +- exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put +- the hardware into "precise mode" and may cause the FPU to run slower on +- some hardware. */ +- if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) +- (void) __fe_nomask_env_priv (); +- +- /* If the old env had any enabled exceptions and the new env has no enabled +- exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the +- FPU to run faster because it always takes the default action and can not +- generate SIGFPE. */ +- if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) +- (void)__fe_mask_env (); ++ __TEST_AND_EXIT_NON_STOP (old.l, new.l); ++ __TEST_AND_ENTER_NON_STOP (old.l, new.l); + + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ + fesetenv_register (new.fenv); diff --git a/SOURCES/glibc-rh1783303-13.patch b/SOURCES/glibc-rh1783303-13.patch new file mode 100644 index 0000000..73d2018 --- /dev/null +++ b/SOURCES/glibc-rh1783303-13.patch @@ -0,0 +1,58 @@ +commit 7413c188c77adb26a15cf0e98e0a991d09d73c65 +Author: Paul A. Clarke +Date: Thu Sep 19 11:18:33 2019 -0500 + + [powerpc] libc_feupdateenv_test: optimize FPSCR access + + ROUND_TO_ODD and a couple of other places use libc_feupdateenv_test to + restore the rounding mode and exception enables, preserve exception flags, + and test whether given exception(s) were generated. + + If the exception flags haven't changed, then it is sufficient and a bit + more efficient to just restore the rounding mode and enables, rather than + writing the full Floating-Point Status and Control Register (FPSCR). + + Reviewed-by: Paul E. Murphy + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index 36b639c3939586f6..86ae7fda016abd8b 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -257,6 +257,10 @@ enum { + (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK) + #define FPSCR_BASIC_EXCEPTIONS_MASK \ + (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK) ++#define FPSCR_EXCEPTIONS_MASK (FPSCR_BASIC_EXCEPTIONS_MASK| \ ++ FPSCR_VXSNAN_MASK|FPSCR_VXISI_MASK|FPSCR_VXIDI_MASK|FPSCR_VXZDZ_MASK| \ ++ FPSCR_VXIMZ_MASK|FPSCR_VXVC_MASK|FPSCR_VXSOFT_MASK|FPSCR_VXSQRT_MASK| \ ++ FPSCR_VXCVI_MASK) + #define FPSCR_FPRF_MASK \ + (FPSCR_FPRF_C_MASK|FPSCR_FPRF_FL_MASK|FPSCR_FPRF_FG_MASK| \ + FPSCR_FPRF_FE_MASK|FPSCR_FPRF_FU_MASK) +diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h +index c236d45db2f399a4..86a3611b3ef41759 100644 +--- a/sysdeps/powerpc/fpu/fenv_private.h ++++ b/sysdeps/powerpc/fpu/fenv_private.h +@@ -52,8 +52,20 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, + __TEST_AND_EXIT_NON_STOP (old.l, new.l); + __TEST_AND_ENTER_NON_STOP (old.l, new.l); + +- /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ +- fesetenv_register (new.fenv); ++ /* If requesting to keep status, replace control, and merge exceptions, ++ and exceptions haven't changed, we can just set new control instead ++ of the whole FPSCR. */ ++ if ((old_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK)) ++ == (FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK) && ++ (new_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK)) ++ == (FPSCR_CONTROL_MASK|FPSCR_EXCEPTIONS_MASK) && ++ (old.l & FPSCR_EXCEPTIONS_MASK) == (new.l & FPSCR_EXCEPTIONS_MASK)) ++ { ++ fesetenv_mode (new.fenv); ++ } ++ else ++ /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ ++ fesetenv_register (new.fenv); + + return old.l; + } diff --git a/SOURCES/glibc-rh1783303-14.patch b/SOURCES/glibc-rh1783303-14.patch new file mode 100644 index 0000000..b0c5e66 --- /dev/null +++ b/SOURCES/glibc-rh1783303-14.patch @@ -0,0 +1,56 @@ +commit e68b1151f7460d5fa88c3a567c13f66052da79a7 +Author: Paul A. Clarke +Date: Thu Sep 19 11:39:44 2019 -0500 + + [powerpc] __fesetround_inline optimizations + + On POWER9, use more efficient means to update the 2-bit rounding mode + via the 'mffscrn' instruction (instead of two 'mtfsb0/1' instructions + or one 'mtfsfi' instruction that modifies 4 bits). + + Suggested-by: Paul E. Murphy + Reviewed-By: Paul E Murphy + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index 86ae7fda016abd8b..c3f541c08440b20e 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -149,7 +149,12 @@ typedef union + static inline int + __fesetround_inline (int round) + { +- if ((unsigned int) round < 2) ++#ifdef _ARCH_PWR9 ++ __fe_mffscrn (round); ++#else ++ if (__glibc_likely (GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00)) ++ __fe_mffscrn (round); ++ else if ((unsigned int) round < 2) + { + asm volatile ("mtfsb0 30"); + if ((unsigned int) round == 0) +@@ -165,7 +170,7 @@ __fesetround_inline (int round) + else + asm volatile ("mtfsb1 31"); + } +- ++#endif + return 0; + } + +@@ -174,7 +179,14 @@ __fesetround_inline (int round) + static inline void + __fesetround_inline_nocheck (const int round) + { +- asm volatile ("mtfsfi 7,%0" : : "i" (round)); ++#ifdef _ARCH_PWR9 ++ __fe_mffscrn (round); ++#else ++ if (__glibc_likely (GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00)) ++ __fe_mffscrn (round); ++ else ++ asm volatile ("mtfsfi 7,%0" : : "i" (round)); ++#endif + } + + #define FPSCR_MASK(bit) (1 << (31 - (bit))) diff --git a/SOURCES/glibc-rh1783303-15.patch b/SOURCES/glibc-rh1783303-15.patch new file mode 100644 index 0000000..47f85db --- /dev/null +++ b/SOURCES/glibc-rh1783303-15.patch @@ -0,0 +1,123 @@ +commit 81ecb0ee4970865cbe5d1da733c4879b999c528f +Author: Paul A. Clarke +Date: Thu Sep 19 11:58:46 2019 -0500 + + [powerpc] Rename fegetenv_status to fegetenv_control + + fegetenv_status is used variously to retrieve the FPSCR exception enable + bits, rounding mode bits, or both. These are referred to as the control + bits in the POWER ISA. FPSCR status bits are also returned by the + 'mffs' and 'mffsl' instructions, but they are uniformly ignored by all + uses of fegetenv_status. Change the name to be reflective of its + current and expected use. + + Reviewed-By: Paul E Murphy + +diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c +index bdf55ac62f1ffe4f..1273987459655585 100644 +--- a/sysdeps/powerpc/fpu/fedisblxcpt.c ++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c +@@ -26,7 +26,7 @@ fedisableexcept (int excepts) + int result, new; + + /* Get current exception mask to return. */ +- fe.fenv = curr.fenv = fegetenv_status (); ++ fe.fenv = curr.fenv = fegetenv_control (); + result = fenv_reg_to_exceptions (fe.l); + + if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) +diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c +index 78ebabed9232c0ad..fa233c305aedd5f6 100644 +--- a/sysdeps/powerpc/fpu/feenablxcpt.c ++++ b/sysdeps/powerpc/fpu/feenablxcpt.c +@@ -26,7 +26,7 @@ feenableexcept (int excepts) + int result, new; + + /* Get current exception mask to return. */ +- fe.fenv = curr.fenv = fegetenv_status (); ++ fe.fenv = curr.fenv = fegetenv_control (); + result = fenv_reg_to_exceptions (fe.l); + + if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) +diff --git a/sysdeps/powerpc/fpu/fegetexcept.c b/sysdeps/powerpc/fpu/fegetexcept.c +index 9d77adea59939ece..6bbf11d9d5df61e5 100644 +--- a/sysdeps/powerpc/fpu/fegetexcept.c ++++ b/sysdeps/powerpc/fpu/fegetexcept.c +@@ -25,7 +25,7 @@ __fegetexcept (void) + fenv_union_t fe; + int result = 0; + +- fe.fenv = fegetenv_status (); ++ fe.fenv = fegetenv_control (); + + if (fe.l & (1 << (31 - FPSCR_XE))) + result |= FE_INEXACT; +diff --git a/sysdeps/powerpc/fpu/fegetmode.c b/sysdeps/powerpc/fpu/fegetmode.c +index 75493e5f24c8b05b..57d6d5275485ebdc 100644 +--- a/sysdeps/powerpc/fpu/fegetmode.c ++++ b/sysdeps/powerpc/fpu/fegetmode.c +@@ -21,6 +21,6 @@ + int + fegetmode (femode_t *modep) + { +- *modep = fegetenv_status (); ++ *modep = fegetenv_control (); + return 0; + } +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index c3f541c08440b20e..b5c8da1adefe93cb 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -61,7 +61,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + 'mffs' on architectures older than "power9" because the additional + bits set for 'mffsl' are "don't care" for 'mffs'. 'mffs' is a superset + of 'mffsl'. */ +-#define fegetenv_status() \ ++#define fegetenv_control() \ + ({register double __fr; \ + __asm__ __volatile__ ( \ + ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ +@@ -85,7 +85,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + __fr.fenv; \ + }) + +-/* Like fegetenv_status, but also sets the rounding mode. */ ++/* Like fegetenv_control, but also sets the rounding mode. */ + #ifdef _ARCH_PWR9 + #define fegetenv_and_set_rn(rn) __fe_mffscrn (rn) + #else +@@ -116,7 +116,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + + /* Set the last 2 nibbles of the FPSCR, which contain the + exception enables and the rounding mode. +- 'fegetenv_status' retrieves these bits by reading the FPSCR. */ ++ 'fegetenv_control' retrieves these bits by reading the FPSCR. */ + #define fesetenv_mode(env) __builtin_mtfsf (0b00000011, (env)); + + /* This very handy macro: +diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c +index 4eab5045c48105e3..252114141cd87f8d 100644 +--- a/sysdeps/powerpc/fpu/fesetenv.c ++++ b/sysdeps/powerpc/fpu/fesetenv.c +@@ -26,7 +26,7 @@ __fesetenv (const fenv_t *envp) + + /* get the currently set exceptions. */ + new.fenv = *envp; +- old.fenv = fegetenv_status (); ++ old.fenv = fegetenv_control (); + + __TEST_AND_EXIT_NON_STOP (old.l, new.l); + __TEST_AND_ENTER_NON_STOP (old.l, new.l); +diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c +index 58ba02c0a1e64c27..e5938af04cb71ca1 100644 +--- a/sysdeps/powerpc/fpu/fesetmode.c ++++ b/sysdeps/powerpc/fpu/fesetmode.c +@@ -27,7 +27,7 @@ fesetmode (const femode_t *modep) + /* Logic regarding enabled exceptions as in fesetenv. */ + + new.fenv = *modep; +- old.fenv = fegetenv_status (); ++ old.fenv = fegetenv_control (); + new.l = (new.l & ~FPSCR_STATUS_MASK) | (old.l & FPSCR_STATUS_MASK); + + if (old.l == new.l) diff --git a/SOURCES/glibc-rh1783303-16.patch b/SOURCES/glibc-rh1783303-16.patch new file mode 100644 index 0000000..c60fb39 --- /dev/null +++ b/SOURCES/glibc-rh1783303-16.patch @@ -0,0 +1,29 @@ +commit 36c17c7079a5243a890ba43affff326a041775a9 +Author: Paul A. Clarke +Date: Thu Sep 19 11:31:31 2019 -0500 + + [powerpc] libc_feholdsetround_noex_ppc_ctx: optimize FPSCR write + + libc_feholdsetround_noex_ppc_ctx currently performs: + 1. Read FPSCR, save to context. + 2. Create new FPSCR value: clear enables and set new rounding mode. + 3. Write new value to FPSCR. + + Since other bits just pass through, there is no need to write them. + + Instead, write just the changed values (enables and rounding mode), + which can be a bit more efficient. + +diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h +index 86a3611b3ef41759..c88142fe3053580f 100644 +--- a/sysdeps/powerpc/fpu/fenv_private.h ++++ b/sysdeps/powerpc/fpu/fenv_private.h +@@ -142,7 +142,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r) + if (__glibc_unlikely (new.l != old.l)) + { + __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); +- fesetenv_register (new.fenv); ++ fesetenv_mode (new.fenv); + ctx->updated_status = true; + } + else diff --git a/SOURCES/glibc-rh1783303-17.patch b/SOURCES/glibc-rh1783303-17.patch new file mode 100644 index 0000000..2c521cc --- /dev/null +++ b/SOURCES/glibc-rh1783303-17.patch @@ -0,0 +1,84 @@ +commit d7a568af5546e0313abbc04060c8e9b0d3f750b4 +Author: Paul A. Clarke +Date: Thu Sep 19 14:04:45 2019 -0500 + + [powerpc] Rename fesetenv_mode to fesetenv_control + + fesetenv_mode is used variously to write the FPSCR exception enable + bits and rounding mode bits. These are referred to as the control + bits in the POWER ISA. Change the name to be reflective of its + current and expected use, and match up well with fegetenv_control. + +diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c +index 1273987459655585..efa9c422fe54f5d8 100644 +--- a/sysdeps/powerpc/fpu/fedisblxcpt.c ++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c +@@ -41,7 +41,7 @@ fedisableexcept (int excepts) + fe.l &= ~new; + + if (fe.l != curr.l) +- fesetenv_mode (fe.fenv); ++ fesetenv_control (fe.fenv); + + __TEST_AND_ENTER_NON_STOP (-1ULL, fe.l); + +diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c +index fa233c305aedd5f6..dfcc6fb7bd24b8db 100644 +--- a/sysdeps/powerpc/fpu/feenablxcpt.c ++++ b/sysdeps/powerpc/fpu/feenablxcpt.c +@@ -41,7 +41,7 @@ feenableexcept (int excepts) + fe.l |= new; + + if (fe.l != curr.l) +- fesetenv_mode (fe.fenv); ++ fesetenv_control (fe.fenv); + + __TEST_AND_EXIT_NON_STOP (0ULL, fe.l); + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index b5c8da1adefe93cb..287fc9f8f70e051c 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -117,7 +117,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + /* Set the last 2 nibbles of the FPSCR, which contain the + exception enables and the rounding mode. + 'fegetenv_control' retrieves these bits by reading the FPSCR. */ +-#define fesetenv_mode(env) __builtin_mtfsf (0b00000011, (env)); ++#define fesetenv_control(env) __builtin_mtfsf (0b00000011, (env)); + + /* This very handy macro: + - Sets the rounding mode to 'round to nearest'; +diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h +index c88142fe3053580f..666fbfdd9fef7759 100644 +--- a/sysdeps/powerpc/fpu/fenv_private.h ++++ b/sysdeps/powerpc/fpu/fenv_private.h +@@ -61,7 +61,7 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, + == (FPSCR_CONTROL_MASK|FPSCR_EXCEPTIONS_MASK) && + (old.l & FPSCR_EXCEPTIONS_MASK) == (new.l & FPSCR_EXCEPTIONS_MASK)) + { +- fesetenv_mode (new.fenv); ++ fesetenv_control (new.fenv); + } + else + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ +@@ -142,7 +142,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r) + if (__glibc_unlikely (new.l != old.l)) + { + __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); +- fesetenv_mode (new.fenv); ++ fesetenv_control (new.fenv); + ctx->updated_status = true; + } + else +diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c +index e5938af04cb71ca1..fdaecb1a6a25a820 100644 +--- a/sysdeps/powerpc/fpu/fesetmode.c ++++ b/sysdeps/powerpc/fpu/fesetmode.c +@@ -36,6 +36,6 @@ fesetmode (const femode_t *modep) + __TEST_AND_EXIT_NON_STOP (old.l, new.l); + __TEST_AND_ENTER_NON_STOP (old.l, new.l); + +- fesetenv_mode (new.fenv); ++ fesetenv_control (new.fenv); + return 0; + } diff --git a/SOURCES/glibc-rh1783303-18.patch b/SOURCES/glibc-rh1783303-18.patch new file mode 100644 index 0000000..60b6d9d --- /dev/null +++ b/SOURCES/glibc-rh1783303-18.patch @@ -0,0 +1,64 @@ +commit 7b8481b330720d28c019a2e5994492a1923d5daa +Author: Paul A. Clarke +Date: Thu Sep 19 11:11:04 2019 -0500 + + [powerpc] No need to enter "Ignore Exceptions Mode" + + Since at least POWER8, there is no performance advantage to entering + "Ignore Exceptions Mode", and doing so conditionally requires + - the conditional logic, and + - a system call. + + Make it a no-op for uses within glibc. + +diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h +index 666fbfdd9fef7759..e09137e892a8e3f3 100644 +--- a/sysdeps/powerpc/fpu/fenv_private.h ++++ b/sysdeps/powerpc/fpu/fenv_private.h +@@ -23,6 +23,17 @@ + #include + #include + ++#ifdef _ARCH_PWR8 ++/* There is no performance advantage to non-stop mode. */ ++/* The odd syntax here is to innocuously reference the given variables ++ to prevent warnings about unused variables. */ ++#define __TEST_AND_BEGIN_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0) ++#define __TEST_AND_END_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0) ++#else ++#define __TEST_AND_BEGIN_NON_STOP __TEST_AND_ENTER_NON_STOP ++#define __TEST_AND_END_NON_STOP __TEST_AND_EXIT_NON_STOP ++#endif ++ + static __always_inline void + libc_feholdexcept_setround_ppc (fenv_t *envp, int r) + { +@@ -30,7 +41,7 @@ libc_feholdexcept_setround_ppc (fenv_t *envp, int r) + + old.fenv = *envp = fegetenv_register (); + +- __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); ++ __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL); + + /* Clear everything and set the rounding mode. */ + new.l = r; +@@ -49,8 +60,8 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, + /* Merge bits while masking unwanted bits from new and old env. */ + new.l = (old.l & old_mask) | (new.l & new_mask); + +- __TEST_AND_EXIT_NON_STOP (old.l, new.l); +- __TEST_AND_ENTER_NON_STOP (old.l, new.l); ++ __TEST_AND_END_NON_STOP (old.l, new.l); ++ __TEST_AND_BEGIN_NON_STOP (old.l, new.l); + + /* If requesting to keep status, replace control, and merge exceptions, + and exceptions haven't changed, we can just set new control instead +@@ -141,7 +152,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r) + ctx->env = old.fenv; + if (__glibc_unlikely (new.l != old.l)) + { +- __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); ++ __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL); + fesetenv_control (new.fenv); + ctx->updated_status = true; + } diff --git a/SOURCES/glibc-rh1783303-2.patch b/SOURCES/glibc-rh1783303-2.patch new file mode 100644 index 0000000..616af07 --- /dev/null +++ b/SOURCES/glibc-rh1783303-2.patch @@ -0,0 +1,105 @@ +commit de751ebc9efa97ce0115e42bd55fa1beeb614380 +Author: Paul A. Clarke +Date: Fri Mar 15 19:04:24 2019 -0400 + + [powerpc] get_rounding_mode: utilize faster method to get rounding mode + + Add support to use 'mffsl' instruction if compiled for POWER9 (or later). + + Also, mask the result to avoid bleeding unrelated bits into the result of + _FPU_GET_RC(). + + Reviewed-by: Tulio Magno Quites Machado Filho + +diff --git a/sysdeps/powerpc/fpu/get-rounding-mode.h b/sysdeps/powerpc/fpu/get-rounding-mode.h +new file mode 100644 +index 0000000000000000..e2fdbbbcce72bd66 +--- /dev/null ++++ b/sysdeps/powerpc/fpu/get-rounding-mode.h +@@ -0,0 +1,33 @@ ++/* Determine floating-point rounding mode within libc. powerpc64 version. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _POWERPC64_GET_ROUNDING_MODE_H ++#define _POWERPC64_GET_ROUNDING_MODE_H 1 ++ ++#include ++#include ++ ++/* Return the floating-point rounding mode. */ ++ ++static inline int ++get_rounding_mode (void) ++{ ++ return _FPU_GET_RC (); ++} ++ ++#endif /* get-rounding-mode.h */ +diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h +index 9d0698b4fc3eb595..62c478d72ae660cb 100644 +--- a/sysdeps/powerpc/fpu_control.h ++++ b/sysdeps/powerpc/fpu_control.h +@@ -71,6 +71,8 @@ extern fpu_control_t __fpu_control; + # define _FPU_RC_UP 0x02 + # define _FPU_RC_ZERO 0x01 + ++# define _FPU_MASK_RC (_FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO) ++ + # define _FPU_MASK_NI 0x04 /* non-ieee mode */ + + /* masking of interrupts */ +@@ -94,15 +96,36 @@ extern fpu_control_t __fpu_control; + typedef unsigned int fpu_control_t; + + /* Macros for accessing the hardware control word. */ ++# define __FPU_MFFS() \ ++ ({register double __fr; \ ++ __asm__ ("mffs %0" : "=f" (__fr)); \ ++ __fr; \ ++ }) ++ + # define _FPU_GETCW(cw) \ + ({union { double __d; unsigned long long __ll; } __u; \ +- register double __fr; \ +- __asm__ ("mffs %0" : "=f" (__fr)); \ +- __u.__d = __fr; \ ++ __u.__d = __FPU_MFFS(); \ + (cw) = (fpu_control_t) __u.__ll; \ + (fpu_control_t) __u.__ll; \ + }) + ++#ifdef _ARCH_PWR9 ++# define __FPU_MFFSL() \ ++ ({register double __fr; \ ++ __asm__ ("mffsl %0" : "=f" (__fr)); \ ++ __fr; \ ++ }) ++#else ++# define __FPU_MFFSL() __FPU_MFFS() ++#endif ++ ++# define _FPU_GET_RC() \ ++ ({union { double __d; unsigned long long __ll; } __u; \ ++ __u.__d = __FPU_MFFSL(); \ ++ __u.__ll &= _FPU_MASK_RC; \ ++ (fpu_control_t) __u.__ll; \ ++ }) ++ + # define _FPU_SETCW(cw) \ + { union { double __d; unsigned long long __ll; } __u; \ + register double __fr; \ diff --git a/SOURCES/glibc-rh1783303-3.patch b/SOURCES/glibc-rh1783303-3.patch new file mode 100644 index 0000000..b653b49 --- /dev/null +++ b/SOURCES/glibc-rh1783303-3.patch @@ -0,0 +1,65 @@ +commit 49bc41b64239c4726f31fa35a1af4f22fb41d51f +Author: Paul A. Clarke +Date: Tue Jun 11 14:37:37 2019 -0500 + + [powerpc] add 'volatile' to asm + + Add 'volatile' keyword to a few asm statements, to force the compiler + to generate the instructions therein. + + Some instances were implicitly volatile, but adding keyword for consistency. + + 2019-06-19 Paul A. Clarke + + * sysdeps/powerpc/fpu/fenv_libc.h (relax_fenv_state): Add 'volatile'. + * sysdeps/powerpc/fpu/fpu_control.h (__FPU_MFFS): Likewise. + (__FPU_MFFSL): Likewise. + (_FPU_SETCW): Likewise. + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index a0128c66444a3e46..d6945903b525748e 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -57,9 +57,9 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + #define relax_fenv_state() \ + do { \ + if (GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \ +- asm (".machine push; .machine \"power6\"; " \ ++ asm volatile (".machine push; .machine \"power6\"; " \ + "mtfsfi 7,0,1; .machine pop"); \ +- asm ("mtfsfi 7,0"); \ ++ asm volatile ("mtfsfi 7,0"); \ + } while(0) + + /* Set/clear a particular FPSCR bit (for instance, +diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h +index 62c478d72ae660cb..90063d77bbbf794f 100644 +--- a/sysdeps/powerpc/fpu_control.h ++++ b/sysdeps/powerpc/fpu_control.h +@@ -98,7 +98,7 @@ typedef unsigned int fpu_control_t; + /* Macros for accessing the hardware control word. */ + # define __FPU_MFFS() \ + ({register double __fr; \ +- __asm__ ("mffs %0" : "=f" (__fr)); \ ++ __asm__ __volatile__("mffs %0" : "=f" (__fr)); \ + __fr; \ + }) + +@@ -112,7 +112,7 @@ typedef unsigned int fpu_control_t; + #ifdef _ARCH_PWR9 + # define __FPU_MFFSL() \ + ({register double __fr; \ +- __asm__ ("mffsl %0" : "=f" (__fr)); \ ++ __asm__ __volatile__("mffsl %0" : "=f" (__fr)); \ + __fr; \ + }) + #else +@@ -132,7 +132,7 @@ typedef unsigned int fpu_control_t; + __u.__ll = 0xfff80000LL << 32; /* This is a QNaN. */ \ + __u.__ll |= (cw) & 0xffffffffLL; \ + __fr = __u.__d; \ +- __asm__ ("mtfsf 255,%0" : : "f" (__fr)); \ ++ __asm__ __volatile__("mtfsf 255,%0" : : "f" (__fr)); \ + } + + /* Default control word set at startup. */ diff --git a/SOURCES/glibc-rh1783303-4.patch b/SOURCES/glibc-rh1783303-4.patch new file mode 100644 index 0000000..5475305 --- /dev/null +++ b/SOURCES/glibc-rh1783303-4.patch @@ -0,0 +1,200 @@ +commit 3db85a9814784a74536a1f0e7b7ddbfef7dc84bb +Author: Paul A. Clarke +Date: Thu Jun 20 11:57:18 2019 -0500 + + powerpc: Use faster means to access FPSCR when possible in some cases + + Using 'mffs' instruction to read the Floating Point Status Control Register + (FPSCR) can force a processor flush in some cases, with undesirable + performance impact. If the values of the bits in the FPSCR which force the + flush are not needed, an instruction that is new to POWER9 (ISA version 3.0), + 'mffsl' can be used instead. + + Cases included: get_rounding_mode, fegetround, fegetmode, fegetexcept. + + * sysdeps/powerpc/bits/fenvinline.h (__fegetround): Use + __fegetround_ISA300() or __fegetround_ISA2() as appropriate. + (__fegetround_ISA300) New. + (__fegetround_ISA2) New. + * sysdeps/powerpc/fpu_control.h (IS_ISA300): New. + (_FPU_MFFS): Move implementation... + (_FPU_GETCW): Here. + (_FPU_MFFSL): Move implementation.... + (_FPU_GET_RC_ISA300): Here. New. + (_FPU_GET_RC): Use _FPU_GET_RC_ISA300() or _FPU_GETCW() as appropriate. + * sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_status_ISA300): New. + (fegetenv_status): New. + * sysdeps/powerpc/fpu/fegetmode.c (fegetmode): Use fegetenv_status() + instead of fegetenv_register(). + * sysdeps/powerpc/fpu/fegetexcept.c (__fegetexcept): Likewise. + + Reviewed-by: Tulio Magno Quites Machado Filho + +diff --git a/sysdeps/powerpc/bits/fenvinline.h b/sysdeps/powerpc/bits/fenvinline.h +index 41316386ba75e903..caec8ead6e17219d 100644 +--- a/sysdeps/powerpc/bits/fenvinline.h ++++ b/sysdeps/powerpc/bits/fenvinline.h +@@ -18,13 +18,36 @@ + + #if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_FPRS__ + +-/* Inline definition for fegetround. */ +-# define __fegetround() \ +- (__extension__ ({ int __fegetround_result; \ +- __asm__ __volatile__ \ +- ("mcrfs 7,7 ; mfcr %0" \ +- : "=r"(__fegetround_result) : : "cr7"); \ +- __fegetround_result & 3; })) ++/* Inline definitions for fegetround. */ ++# define __fegetround_ISA300() \ ++ (__extension__ ({ \ ++ union { double __d; unsigned long long __ll; } __u; \ ++ __asm__ __volatile__ ( \ ++ ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ ++ : "=f" (__u.__d)); \ ++ __u.__ll & 0x0000000000000003LL; \ ++ })) ++ ++# define __fegetround_ISA2() \ ++ (__extension__ ({ \ ++ int __fegetround_result; \ ++ __asm__ __volatile__ ("mcrfs 7,7 ; mfcr %0" \ ++ : "=r"(__fegetround_result) : : "cr7"); \ ++ __fegetround_result & 3; \ ++ })) ++ ++# ifdef _ARCH_PWR9 ++# define __fegetround() __fegetround_ISA300() ++# elif defined __BUILTIN_CPU_SUPPORTS__ ++# define __fegetround() \ ++ (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ ++ ? __fegetround_ISA300() \ ++ : __fegetround_ISA2() \ ++ ) ++# else ++# define __fegetround() __fegetround_ISA2() ++# endif ++ + # define fegetround() __fegetround () + + # ifndef __NO_MATH_INLINES +diff --git a/sysdeps/powerpc/fpu/fegetexcept.c b/sysdeps/powerpc/fpu/fegetexcept.c +index a053a32bfe11c0d4..9d77adea59939ece 100644 +--- a/sysdeps/powerpc/fpu/fegetexcept.c ++++ b/sysdeps/powerpc/fpu/fegetexcept.c +@@ -25,7 +25,7 @@ __fegetexcept (void) + fenv_union_t fe; + int result = 0; + +- fe.fenv = fegetenv_register (); ++ fe.fenv = fegetenv_status (); + + if (fe.l & (1 << (31 - FPSCR_XE))) + result |= FE_INEXACT; +diff --git a/sysdeps/powerpc/fpu/fegetmode.c b/sysdeps/powerpc/fpu/fegetmode.c +index b83dc9f625d2248a..75493e5f24c8b05b 100644 +--- a/sysdeps/powerpc/fpu/fegetmode.c ++++ b/sysdeps/powerpc/fpu/fegetmode.c +@@ -21,6 +21,6 @@ + int + fegetmode (femode_t *modep) + { +- *modep = fegetenv_register (); ++ *modep = fegetenv_status (); + return 0; + } +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index d6945903b525748e..cc00df033da47c1a 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -35,6 +35,27 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + #define fegetenv_register() \ + ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; }) + ++/* Equivalent to fegetenv_register, but only returns bits for ++ status, exception enables, and mode. */ ++ ++#define fegetenv_status_ISA300() \ ++ ({register double __fr; \ ++ __asm__ __volatile__ ( \ ++ ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ ++ : "=f" (__fr)); \ ++ __fr; \ ++ }) ++ ++#ifdef _ARCH_PWR9 ++# define fegetenv_status() fegetenv_status_ISA300() ++#else ++# define fegetenv_status() \ ++ (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ ++ ? fegetenv_status_ISA300() \ ++ : fegetenv_register() \ ++ ) ++#endif ++ + /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ + #define fesetenv_register(env) \ + do { \ +diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h +index 90063d77bbbf794f..e0ee622e246c0d61 100644 +--- a/sysdeps/powerpc/fpu_control.h ++++ b/sysdeps/powerpc/fpu_control.h +@@ -96,35 +96,37 @@ extern fpu_control_t __fpu_control; + typedef unsigned int fpu_control_t; + + /* Macros for accessing the hardware control word. */ +-# define __FPU_MFFS() \ +- ({register double __fr; \ +- __asm__ __volatile__("mffs %0" : "=f" (__fr)); \ +- __fr; \ +- }) +- + # define _FPU_GETCW(cw) \ + ({union { double __d; unsigned long long __ll; } __u; \ +- __u.__d = __FPU_MFFS(); \ ++ __asm__ __volatile__("mffs %0" : "=f" (__u.__d)); \ + (cw) = (fpu_control_t) __u.__ll; \ + (fpu_control_t) __u.__ll; \ + }) + +-#ifdef _ARCH_PWR9 +-# define __FPU_MFFSL() \ +- ({register double __fr; \ +- __asm__ __volatile__("mffsl %0" : "=f" (__fr)); \ +- __fr; \ ++# define _FPU_GET_RC_ISA300() \ ++ ({union { double __d; unsigned long long __ll; } __u; \ ++ __asm__ __volatile__( \ ++ ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ ++ : "=f" (__u.__d)); \ ++ (fpu_control_t) (__u.__ll & _FPU_MASK_RC); \ + }) +-#else +-# define __FPU_MFFSL() __FPU_MFFS() +-#endif +- +-# define _FPU_GET_RC() \ +- ({union { double __d; unsigned long long __ll; } __u; \ +- __u.__d = __FPU_MFFSL(); \ +- __u.__ll &= _FPU_MASK_RC; \ +- (fpu_control_t) __u.__ll; \ ++ ++# ifdef _ARCH_PWR9 ++# define _FPU_GET_RC() _FPU_GET_RC_ISA300() ++# elif defined __BUILTIN_CPU_SUPPORTS__ ++# define _FPU_GET_RC() \ ++ ({fpu_control_t __rc; \ ++ __rc = __glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ ++ ? _FPU_GET_RC_ISA300 () \ ++ : _FPU_GETCW (__rc) & _FPU_MASK_RC; \ ++ __rc; \ ++ }) ++# else ++# define _FPU_GET_RC() \ ++ ({fpu_control_t __rc = _FPU_GETCW (__rc) & _FPU_MASK_RC; \ ++ __rc; \ + }) ++# endif + + # define _FPU_SETCW(cw) \ + { union { double __d; unsigned long long __ll; } __u; \ diff --git a/SOURCES/glibc-rh1783303-5.patch b/SOURCES/glibc-rh1783303-5.patch new file mode 100644 index 0000000..e8c439e --- /dev/null +++ b/SOURCES/glibc-rh1783303-5.patch @@ -0,0 +1,37 @@ +commit b5232c9f9e6048b8f780d3cbfadbc8e59bb90ce4 +Author: Paul A. Clarke +Date: Mon Jul 8 17:06:19 2019 -0500 + + [powerpc] fenv_libc.h: protect use of __builtin_cpu_supports + + Using __builtin_cpu_supports() requires support in GCC and Glibc. + My recent patch to fenv_libc.h added an unprotected use of + __builtin_cpu_supports(). Compilation of Glibc itself will fail + with a sufficiently new GCC and sufficiently old Glibc: + + ../sysdeps/powerpc/fpu/fegetexcept.c: In function ‘__fegetexcept’: + ../sysdeps/powerpc/fpu/fenv_libc.h:52:20: error: builtin ‘__builtin_cpu_supports’ needs GLIBC (2.23 and newer) that exports hardware capability bits [-Werror] + + Reviewed-by: Florian Weimer + Fixes 3db85a9814784a74536a1f0e7b7ddbfef7dc84bb. + +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index cc00df033da47c1a..9dca6e760cc51946 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -48,12 +48,14 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + + #ifdef _ARCH_PWR9 + # define fegetenv_status() fegetenv_status_ISA300() +-#else ++#elif defined __BUILTIN_CPU_SUPPORTS__ + # define fegetenv_status() \ + (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ + ? fegetenv_status_ISA300() \ + : fegetenv_register() \ + ) ++#else ++# define fegetenv_status() fegetenv_register () + #endif + + /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ diff --git a/SOURCES/glibc-rh1783303-6.patch b/SOURCES/glibc-rh1783303-6.patch new file mode 100644 index 0000000..7313bd6 --- /dev/null +++ b/SOURCES/glibc-rh1783303-6.patch @@ -0,0 +1,185 @@ +commit cd7ce12a027656ad3cda774454088de5a2c7fbfa +Author: Paul A. Clarke +Date: Fri Jul 12 20:13:58 2019 -0500 + + [powerpc] fe{en,dis}ableexcept optimize bit translations + + The exceptions passed to fe{en,dis}ableexcept() are defined in the ABI + as a bitmask, a combination of FE_INVALID, FE_OVERFLOW, etc. + Within the functions, these bits must be translated to/from the corresponding + enable bits in the Floating Point Status Control Register (FPSCR). + This translation is currently done bit-by-bit. The compiler generates + a series of conditional bit operations. Nicely, the "FE" exception + bits are all a uniform offset from the FPSCR enable bits, so the bit-by-bit + operation can instead be performed by a shift with appropriate masking. + +diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c +index 2daed44a419301e8..90bc3d12c6d8558c 100644 +--- a/sysdeps/powerpc/fpu/fedisblxcpt.c ++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c +@@ -33,16 +33,7 @@ fedisableexcept (int excepts) + excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + + /* Sets the new exception mask. */ +- if (excepts & FE_INEXACT) +- fe.l &= ~(1 << (31 - FPSCR_XE)); +- if (excepts & FE_DIVBYZERO) +- fe.l &= ~(1 << (31 - FPSCR_ZE)); +- if (excepts & FE_UNDERFLOW) +- fe.l &= ~(1 << (31 - FPSCR_UE)); +- if (excepts & FE_OVERFLOW) +- fe.l &= ~(1 << (31 - FPSCR_OE)); +- if (excepts & FE_INVALID) +- fe.l &= ~(1 << (31 - FPSCR_VE)); ++ fe.l &= ~ fenv_exceptions_to_reg (excepts); + + if (fe.l != curr.l) + fesetenv_register (fe.fenv); +diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c +index 19cfe28e7aa307d4..e029971b9a460c28 100644 +--- a/sysdeps/powerpc/fpu/feenablxcpt.c ++++ b/sysdeps/powerpc/fpu/feenablxcpt.c +@@ -33,16 +33,7 @@ feenableexcept (int excepts) + excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + + /* Sets the new exception mask. */ +- if (excepts & FE_INEXACT) +- fe.l |= (1 << (31 - FPSCR_XE)); +- if (excepts & FE_DIVBYZERO) +- fe.l |= (1 << (31 - FPSCR_ZE)); +- if (excepts & FE_UNDERFLOW) +- fe.l |= (1 << (31 - FPSCR_UE)); +- if (excepts & FE_OVERFLOW) +- fe.l |= (1 << (31 - FPSCR_OE)); +- if (excepts & FE_INVALID) +- fe.l |= (1 << (31 - FPSCR_VE)); ++ fe.l |= fenv_exceptions_to_reg (excepts); + + if (fe.l != curr.l) + fesetenv_register (fe.fenv); +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index 9dca6e760cc51946..f9634a64d186c076 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -129,60 +129,108 @@ __fesetround_inline_nocheck (const int round) + asm volatile ("mtfsfi 7,%0" : : "i" (round)); + } + ++#define FPSCR_MASK(bit) (1 << (31 - (bit))) ++ + /* Definitions of all the FPSCR bit numbers */ + enum { + FPSCR_FX = 0, /* exception summary */ ++#define FPSCR_FX_MASK (FPSCR_MASK (FPSCR_FX)) + FPSCR_FEX, /* enabled exception summary */ ++#define FPSCR_FEX_MASK (FPSCR_MASK FPSCR_FEX)) + FPSCR_VX, /* invalid operation summary */ ++#define FPSCR_VX_MASK (FPSCR_MASK (FPSCR_VX)) + FPSCR_OX, /* overflow */ ++#define FPSCR_OX_MASK (FPSCR_MASK (FPSCR_OX)) + FPSCR_UX, /* underflow */ ++#define FPSCR_UX_MASK (FPSCR_MASK (FPSCR_UX)) + FPSCR_ZX, /* zero divide */ ++#define FPSCR_ZX_MASK (FPSCR_MASK (FPSCR_ZX)) + FPSCR_XX, /* inexact */ ++#define FPSCR_XX_MASK (FPSCR_MASK (FPSCR_XX)) + FPSCR_VXSNAN, /* invalid operation for sNaN */ ++#define FPSCR_VXSNAN_MASK (FPSCR_MASK (FPSCR_VXSNAN)) + FPSCR_VXISI, /* invalid operation for Inf-Inf */ ++#define FPSCR_VXISI_MASK (FPSCR_MASK (FPSCR_VXISI)) + FPSCR_VXIDI, /* invalid operation for Inf/Inf */ ++#define FPSCR_VXIDI_MASK (FPSCR_MASK (FPSCR_VXIDI)) + FPSCR_VXZDZ, /* invalid operation for 0/0 */ ++#define FPSCR_VXZDZ_MASK (FPSCR_MASK (FPSCR_VXZDZ)) + FPSCR_VXIMZ, /* invalid operation for Inf*0 */ ++#define FPSCR_VXIMZ_MASK (FPSCR_MASK (FPSCR_VXIMZ)) + FPSCR_VXVC, /* invalid operation for invalid compare */ ++#define FPSCR_VXVC_MASK (FPSCR_MASK (FPSCR_VXVC)) + FPSCR_FR, /* fraction rounded [fraction was incremented by round] */ ++#define FPSCR_FR_MASK (FPSCR_MASK (FPSCR_FR)) + FPSCR_FI, /* fraction inexact */ ++#define FPSCR_FI_MASK (FPSCR_MASK (FPSCR_FI)) + FPSCR_FPRF_C, /* result class descriptor */ ++#define FPSCR_FPRF_C_MASK (FPSCR_MASK (FPSCR_FPRF_C)) + FPSCR_FPRF_FL, /* result less than (usually, less than 0) */ ++#define FPSCR_FPRF_FL_MASK (FPSCR_MASK (FPSCR_FPRF_FL)) + FPSCR_FPRF_FG, /* result greater than */ ++#define FPSCR_FPRF_FG_MASK (FPSCR_MASK (FPSCR_FPRF_FG)) + FPSCR_FPRF_FE, /* result equal to */ ++#define FPSCR_FPRF_FE_MASK (FPSCR_MASK (FPSCR_FPRF_FE)) + FPSCR_FPRF_FU, /* result unordered */ ++#define FPSCR_FPRF_FU_MASK (FPSCR_MASK (FPSCR_FPRF_FU)) + FPSCR_20, /* reserved */ + FPSCR_VXSOFT, /* invalid operation set by software */ ++#define FPSCR_VXSOFT_MASK (FPSCR_MASK (FPSCR_VXSOFT)) + FPSCR_VXSQRT, /* invalid operation for square root */ ++#define FPSCR_VXSQRT_MASK (FPSCR_MASK (FPSCR_VXSQRT)) + FPSCR_VXCVI, /* invalid operation for invalid integer convert */ ++#define FPSCR_VXCVI_MASK (FPSCR_MASK (FPSCR_VXCVI)) + FPSCR_VE, /* invalid operation exception enable */ ++#define FPSCR_VE_MASK (FPSCR_MASK (FPSCR_VE)) + FPSCR_OE, /* overflow exception enable */ ++#define FPSCR_OE_MASK (FPSCR_MASK (FPSCR_OE)) + FPSCR_UE, /* underflow exception enable */ ++#define FPSCR_UE_MASK (FPSCR_MASK (FPSCR_UE)) + FPSCR_ZE, /* zero divide exception enable */ ++#define FPSCR_ZE_MASK (FPSCR_MASK (FPSCR_ZE)) + FPSCR_XE, /* inexact exception enable */ ++#define FPSCR_XE_MASK (FPSCR_MASK (FPSCR_XE)) + #ifdef _ARCH_PWR6 + FPSCR_29, /* Reserved in ISA 2.05 */ ++#define FPSCR_NI_MASK (FPSCR_MASK (FPSCR_29)) + #else +- FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */ ++ FPSCR_NI, /* non-IEEE mode (typically, no denormalised numbers) */ ++#define FPSCR_NI_MASK (FPSCR_MASK (FPSCR_NI)) + #endif /* _ARCH_PWR6 */ + /* the remaining two least-significant bits keep the rounding mode */ ++ FPSCR_RN_hi, ++#define FPSCR_RN_hi_MASK (FPSCR_MASK (FPSCR_RN_hi)) ++ FPSCR_RN_lo ++#define FPSCR_RN_lo_MASK (FPSCR_MASK (FPSCR_RN_lo)) + }; + ++#define FPSCR_RN_MASK (FPSCR_RN_hi_MASK|FPSCR_RN_lo_MASK) ++#define FPSCR_ENABLES_MASK \ ++ (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK) ++#define FPSCR_BASIC_EXCEPTIONS_MASK \ ++ (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK) ++ ++#define FPSCR_CONTROL_MASK (FPSCR_ENABLES_MASK|FPSCR_NI_MASK|FPSCR_RN_MASK) ++ ++/* The bits in the FENV(1) ABI for exceptions correspond one-to-one with bits ++ in the FPSCR, albeit shifted to different but corresponding locations. ++ Similarly, the exception indicator bits in the FPSCR correspond one-to-one ++ with the exception enable bits. It is thus possible to map the FENV(1) ++ exceptions directly to the FPSCR enables with a simple mask and shift, ++ and vice versa. */ ++#define FPSCR_EXCEPT_TO_ENABLE_SHIFT 22 ++ + static inline int + fenv_reg_to_exceptions (unsigned long long l) + { +- int result = 0; +- if (l & (1 << (31 - FPSCR_XE))) +- result |= FE_INEXACT; +- if (l & (1 << (31 - FPSCR_ZE))) +- result |= FE_DIVBYZERO; +- if (l & (1 << (31 - FPSCR_UE))) +- result |= FE_UNDERFLOW; +- if (l & (1 << (31 - FPSCR_OE))) +- result |= FE_OVERFLOW; +- if (l & (1 << (31 - FPSCR_VE))) +- result |= FE_INVALID; +- return result; ++ return (((int)l) & FPSCR_ENABLES_MASK) << FPSCR_EXCEPT_TO_ENABLE_SHIFT; ++} ++ ++static inline unsigned long long ++fenv_exceptions_to_reg (int excepts) ++{ ++ return (unsigned long long) ++ (excepts & FE_ALL_EXCEPT) >> FPSCR_EXCEPT_TO_ENABLE_SHIFT; + } + + #ifdef _ARCH_PWR6 diff --git a/SOURCES/glibc-rh1783303-7.patch b/SOURCES/glibc-rh1783303-7.patch new file mode 100644 index 0000000..a74f2eb --- /dev/null +++ b/SOURCES/glibc-rh1783303-7.patch @@ -0,0 +1,174 @@ +commit 3c1766ea10043f2e9625f3cba3bda37c84b32cf0 +Author: Paul A. Clarke +Date: Thu Jul 18 19:37:13 2019 -0500 + + [powerpc] fe{en,dis}ableexcept, fesetmode: optimize FPSCR accesses + + Since fe{en,dis}ableexcept() and fesetmode() read-modify-write just the + "mode" (exception enable and rounding mode) bits of the Floating Point Status + Control Register (FPSCR), the lighter weight 'mffsl' instruction can be used + to read the FPSCR (enables and rounding mode), and 'mtfsf 0b00000011' can be + used to write just those bits back to the FPSCR. The net is better performance. + + In addition, fe{en,dis}ableexcept() read the FPSCR again after writing it, or + they determine that it doesn't need to be written because it is not changing. + In either case, the local variable holds the current values of the enable + bits in the FPSCR. This local variable can be used instead of again reading + the FPSCR. + + Also, that value of the FPSCR which is read the second time is validated + against the requested enables. Since the write can't fail, this validation + step is unnecessary, and can be removed. Instead, the exceptions to be + enabled (or disabled) are transformed into available bits in the FPSCR, + then validated after being transformed back, to ensure that all requested + bits are actually being set. For example, FE_INVALID_SQRT can be + requested, but cannot actually be set. This bit is not mapped during the + transformations, so a test for that bit being set before and after + transformations will show the bit would not be set, and the function will + return -1 for failure. + + Finally, convert the local macros in fesetmode.c to more generally useful + macros in fenv_libc.h. + +diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c +index 90bc3d12c6d8558c..2a776c72fb5a2b70 100644 +--- a/sysdeps/powerpc/fpu/fedisblxcpt.c ++++ b/sysdeps/powerpc/fpu/fedisblxcpt.c +@@ -26,23 +26,25 @@ fedisableexcept (int excepts) + int result, new; + + /* Get current exception mask to return. */ +- fe.fenv = curr.fenv = fegetenv_register (); ++ fe.fenv = curr.fenv = fegetenv_status (); + result = fenv_reg_to_exceptions (fe.l); + + if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) + excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + ++ new = fenv_exceptions_to_reg (excepts); ++ ++ if (fenv_reg_to_exceptions (new) != excepts) ++ return -1; ++ + /* Sets the new exception mask. */ +- fe.l &= ~ fenv_exceptions_to_reg (excepts); ++ fe.l &= ~new; + + if (fe.l != curr.l) +- fesetenv_register (fe.fenv); ++ fesetenv_mode (fe.fenv); + +- new = __fegetexcept (); + if (new == 0 && result != 0) + (void)__fe_mask_env (); + +- if ((new & excepts) != 0) +- result = -1; + return result; + } +diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c +index e029971b9a460c28..6f5a828e80965bfa 100644 +--- a/sysdeps/powerpc/fpu/feenablxcpt.c ++++ b/sysdeps/powerpc/fpu/feenablxcpt.c +@@ -26,24 +26,25 @@ feenableexcept (int excepts) + int result, new; + + /* Get current exception mask to return. */ +- fe.fenv = curr.fenv = fegetenv_register (); ++ fe.fenv = curr.fenv = fegetenv_status (); + result = fenv_reg_to_exceptions (fe.l); + + if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) + excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + ++ new = fenv_exceptions_to_reg (excepts); ++ ++ if (fenv_reg_to_exceptions (new) != excepts) ++ return -1; ++ + /* Sets the new exception mask. */ +- fe.l |= fenv_exceptions_to_reg (excepts); ++ fe.l |= new; + + if (fe.l != curr.l) +- fesetenv_register (fe.fenv); ++ fesetenv_mode (fe.fenv); + +- new = __fegetexcept (); + if (new != 0 && result == 0) + (void) __fe_nomask_env_priv (); + +- if ((new & excepts) != excepts) +- result = -1; +- + return result; + } +diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h +index f9634a64d186c076..b244770d115ea7bb 100644 +--- a/sysdeps/powerpc/fpu/fenv_libc.h ++++ b/sysdeps/powerpc/fpu/fenv_libc.h +@@ -71,6 +71,11 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; + asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \ + } while(0) + ++/* Set the last 2 nibbles of the FPSCR, which contain the ++ exception enables and the rounding mode. ++ 'fegetenv_status' retrieves these bits by reading the FPSCR. */ ++#define fesetenv_mode(env) __builtin_mtfsf (0b00000011, (env)); ++ + /* This very handy macro: + - Sets the rounding mode to 'round to nearest'; + - Sets the processor into IEEE mode; and +@@ -209,8 +214,11 @@ enum { + (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK) + #define FPSCR_BASIC_EXCEPTIONS_MASK \ + (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK) +- ++#define FPSCR_FPRF_MASK \ ++ (FPSCR_FPRF_C_MASK|FPSCR_FPRF_FL_MASK|FPSCR_FPRF_FG_MASK| \ ++ FPSCR_FPRF_FE_MASK|FPSCR_FPRF_FU_MASK) + #define FPSCR_CONTROL_MASK (FPSCR_ENABLES_MASK|FPSCR_NI_MASK|FPSCR_RN_MASK) ++#define FPSCR_STATUS_MASK (FPSCR_FR_MASK|FPSCR_FI_MASK|FPSCR_FPRF_MASK) + + /* The bits in the FENV(1) ABI for exceptions correspond one-to-one with bits + in the FPSCR, albeit shifted to different but corresponding locations. +diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c +index 32203a24ff434a32..29e088d5ab1c0d93 100644 +--- a/sysdeps/powerpc/fpu/fesetmode.c ++++ b/sysdeps/powerpc/fpu/fesetmode.c +@@ -19,11 +19,6 @@ + #include + #include + +-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM \ +- | _FPU_MASK_XM | _FPU_MASK_IM) +- +-#define FPU_STATUS 0xbffff700ULL +- + int + fesetmode (const femode_t *modep) + { +@@ -32,18 +27,18 @@ fesetmode (const femode_t *modep) + /* Logic regarding enabled exceptions as in fesetenv. */ + + new.fenv = *modep; +- old.fenv = fegetenv_register (); +- new.l = (new.l & ~FPU_STATUS) | (old.l & FPU_STATUS); ++ old.fenv = fegetenv_status (); ++ new.l = (new.l & ~FPSCR_STATUS_MASK) | (old.l & FPSCR_STATUS_MASK); + + if (old.l == new.l) + return 0; + +- if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) ++ if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0) + (void) __fe_nomask_env_priv (); + +- if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) ++ if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0) + (void) __fe_mask_env (); + +- fesetenv_register (new.fenv); ++ fesetenv_mode (new.fenv); + return 0; + } diff --git a/SOURCES/glibc-rh1783303-8.patch b/SOURCES/glibc-rh1783303-8.patch new file mode 100644 index 0000000..142e3bb --- /dev/null +++ b/SOURCES/glibc-rh1783303-8.patch @@ -0,0 +1,124 @@ +commit e905212627350d54b58426214b5a54ddc852b0c9 +Author: Paul A. Clarke +Date: Fri Aug 2 22:47:57 2019 -0400 + + [powerpc] SET_RESTORE_ROUND improvements + + SET_RESTORE_ROUND uses libc_feholdsetround_ppc_ctx and + libc_feresetround_ppc_ctx to bracket a block of code where the floating point + rounding mode must be set to a certain value. + + For the *prologue*, libc_feholdsetround_ppc_ctx is used and performs: + 1. Read/save FPSCR. + 2. Create new value for FPSCR with new rounding mode and enables cleared. + 3. If new value is different than current value, + a. If transitioning from a state where some exceptions enabled, + enter "ignore exceptions / non-stop" mode. + b. Write new value to FPSCR. + c. Put a mark on the wall indicating the FPSCR was changed. + + (1) uses the 'mffs' instruction. On POWER9, the lighter weight 'mffsl' + instruction can be used, but it doesn't return all of the bits in the FPSCR. + fegetenv_status uses 'mffsl' on POWER9, 'mffs' otherwise, and can thus be + used instead of fegetenv_register. + (3b) uses 'mtfsf 0b11111111' to write the entire FPSCR, so it must + instead use 'mtfsf 0b00000011' to write just the enables and the mode, + because some of the rest of the bits are not valid if 'mffsl' was used. + fesetenv_mode uses 'mtfsf 0b00000011' on POWER9, 'mtfsf 0b11111111' + otherwise. + + For the *epilogue*, libc_feresetround_ppc_ctx checks the mark on the wall, then + calls libc_feresetround_ppc, which just calls __libc_femergeenv_ppc with + parameters such that it performs: + 1. Retreive saved value of FPSCR, saved in prologue above. + 2. Read FPSCR. + 3. Create new value of FPSCR where: + - Summary bits and exception indicators = current OR saved. + - Rounding mode and enables = saved. + - Status bits = current. + 4. If transitioning from some exceptions enabled to none, + enter "ignore exceptions / non-stop" mode. + 5. If transitioning from no exceptions enabled to some, + enter "catch exceptions" mode. + 6. Write new value to FPSCR. + + The summary bits are hardwired to the exception indicators, so there is no + need to restore any saved summary bits. + The exception indicator bits, which are sticky and remain set unless + explicitly cleared, would only need to be restored if the code block + might explicitly clear any of them. This is certainly not expected. + + So, the only bits that need to be restored are the enables and the mode. + If it is the case that only those bits are to be restored, there is no need to + read the FPSCR. Steps (2) and (3) are unnecessary, and step (6) only needs to + write the bits being restored. + + We know we are transitioning out of "ignore exceptions" mode, so step (4) is + unnecessary, and in step (6), we only need to check the state we are + entering. + +diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h +index 945ab98018450092..b0149aa243e69f5a 100644 +--- a/sysdeps/powerpc/fpu/fenv_private.h ++++ b/sysdeps/powerpc/fpu/fenv_private.h +@@ -132,7 +132,17 @@ libc_fesetenv_ppc (const fenv_t *envp) + static __always_inline void + libc_feresetround_ppc (fenv_t *envp) + { +- __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, _FPU_MASK_FRAC_INEX_RET_CC); ++ fenv_union_t new = { .fenv = *envp }; ++ ++ /* If the old env has no enabled exceptions and the new env has any enabled ++ exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the ++ hardware into "precise mode" and may cause the FPU to run slower on some ++ hardware. */ ++ if ((new.l & _FPU_ALL_TRAPS) != 0) ++ (void) __fe_nomask_env_priv (); ++ ++ /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ ++ fesetenv_mode (new.fenv); + } + + static __always_inline int +@@ -176,9 +186,30 @@ libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r) + { + fenv_union_t old, new; + ++ old.fenv = fegetenv_status (); ++ ++ new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r; ++ ++ ctx->env = old.fenv; ++ if (__glibc_unlikely (new.l != old.l)) ++ { ++ if ((old.l & _FPU_ALL_TRAPS) != 0) ++ (void) __fe_mask_env (); ++ fesetenv_mode (new.fenv); ++ ctx->updated_status = true; ++ } ++ else ++ ctx->updated_status = false; ++} ++ ++static __always_inline void ++libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r) ++{ ++ fenv_union_t old, new; ++ + old.fenv = fegetenv_register (); + +- new.l = (old.l & _FPU_MASK_TRAPS_RN) | r; ++ new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r; + + ctx->env = old.fenv; + if (__glibc_unlikely (new.l != old.l)) +@@ -218,6 +249,9 @@ libc_feresetround_ppc_ctx (struct rm_ctx *ctx) + #define libc_feholdsetround_ctx libc_feholdsetround_ppc_ctx + #define libc_feholdsetroundf_ctx libc_feholdsetround_ppc_ctx + #define libc_feholdsetroundl_ctx libc_feholdsetround_ppc_ctx ++#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_ppc_ctx ++#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ppc_ctx ++#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ppc_ctx + #define libc_feresetround_ctx libc_feresetround_ppc_ctx + #define libc_feresetroundf_ctx libc_feresetround_ppc_ctx + #define libc_feresetroundl_ctx libc_feresetround_ppc_ctx diff --git a/SOURCES/glibc-rh1783303-9.patch b/SOURCES/glibc-rh1783303-9.patch new file mode 100644 index 0000000..e151082 --- /dev/null +++ b/SOURCES/glibc-rh1783303-9.patch @@ -0,0 +1,61 @@ +commit fec2bd2c2d31bc731cf61623e150d047746954bd +Author: Paul A. Clarke +Date: Tue Aug 6 00:13:45 2019 -0400 + + [powerpc] fesetenv: optimize FPSCR access + + fesetenv() reads the current value of the Floating-Point Status and Control + Register (FPSCR) to determine the difference between the current state of + exception enables and the newly requested state. All of these bits are also + returned by the lighter weight 'mffsl' instruction used by fegetenv_status(). + Use that instead. + + Also, remove a local macro _FPU_MASK_ALL in favor of a common macro, + FPU_ENABLES_MASK from fenv_libc.h. + + Finally, use a local variable ('new') in favor of a pointer dereference + ('*envp'). + +diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c +index ad9fda15b12f15e3..ac927c8f3ada40b4 100644 +--- a/sysdeps/powerpc/fpu/fesetenv.c ++++ b/sysdeps/powerpc/fpu/fesetenv.c +@@ -19,8 +19,6 @@ + #include + #include + +-#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) +- + int + __fesetenv (const fenv_t *envp) + { +@@ -28,25 +26,23 @@ __fesetenv (const fenv_t *envp) + + /* get the currently set exceptions. */ + new.fenv = *envp; +- old.fenv = fegetenv_register (); +- if (old.l == new.l) +- return 0; ++ old.fenv = fegetenv_status (); + + /* If the old env has no enabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the + hardware into "precise mode" and may cause the FPU to run slower on some + hardware. */ +- if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) ++ if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0) + (void) __fe_nomask_env_priv (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ +- if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) ++ if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0) + (void)__fe_mask_env (); + +- fesetenv_register (*envp); ++ fesetenv_register (new.fenv); + + /* Success. */ + return 0; diff --git a/SOURCES/glibc-rh1784519.patch b/SOURCES/glibc-rh1784519.patch new file mode 100644 index 0000000..c9779d1 --- /dev/null +++ b/SOURCES/glibc-rh1784519.patch @@ -0,0 +1,29 @@ +commit 953ceff17a4a15b10cfdd5edc3c8cae4884c8ec3 +Author: Kamlesh Kumar +Date: Thu Dec 5 16:49:00 2019 +0100 + + : Define __CORRECT_ISO_CPP_STRING_H_PROTO for Clang [BZ #25232] + + Without the asm redirects, strchr et al. are not const-correct. + + libc++ has a wrapper header that works with and without + __CORRECT_ISO_CPP_STRING_H_PROTO (using a Clang extension). But when + Clang is used with libstdc++ or just C headers, the overloaded functions + with the correct types are not declared. + + This change does not impact current GCC (with libstdc++ or libc++). + +diff --git a/string/string.h b/string/string.h +index 73c22a535a..faf997b972 100644 +--- a/string/string.h ++++ b/string/string.h +@@ -33,7 +33,8 @@ __BEGIN_DECLS + #include + + /* Tell the caller that we provide correct C++ prototypes. */ +-#if defined __cplusplus && __GNUC_PREREQ (4, 4) ++#if defined __cplusplus && (__GNUC_PREREQ (4, 4) \ ++ || __glibc_clang_prereq (3, 5)) + # define __CORRECT_ISO_CPP_STRING_H_PROTO + #endif + diff --git a/SOURCES/glibc-rh1784520.patch b/SOURCES/glibc-rh1784520.patch new file mode 100644 index 0000000..90e9d77 --- /dev/null +++ b/SOURCES/glibc-rh1784520.patch @@ -0,0 +1,121 @@ +commit 16554464bcd9d77b07c6ff419dc54f00e394fa50 +Author: DJ Delorie +Date: Tue Dec 3 17:44:36 2019 -0500 + + Correct range checking in mallopt/mxfast/tcache [BZ #25194] + + do_set_tcache_max, do_set_mxfast: + Fix two instances of comparing "size_t < 0" + Both cases have upper limit, so the "negative value" case + is already handled via overflow semantics. + + do_set_tcache_max, do_set_tcache_count: + Fix return value on error. Note: currently not used. + + mallopt: + pass return value of helper functions to user. Behavior should + only be actually changed for mxfast, where we restore the old + (pre-tunables) behavior. + + Reviewed-by: Carlos O'Donell + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 90825b2aaed53761..00a37f218c0ab3b2 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -5111,13 +5111,14 @@ static inline int + __always_inline + do_set_tcache_max (size_t value) + { +- if (value >= 0 && value <= MAX_TCACHE_SIZE) ++ if (value <= MAX_TCACHE_SIZE) + { + LIBC_PROBE (memory_tunable_tcache_max_bytes, 2, value, mp_.tcache_max_bytes); + mp_.tcache_max_bytes = value; + mp_.tcache_bins = csize2tidx (request2size(value)) + 1; ++ return 1; + } +- return 1; ++ return 0; + } + + static inline int +@@ -5128,8 +5129,9 @@ do_set_tcache_count (size_t value) + { + LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count); + mp_.tcache_count = value; ++ return 1; + } +- return 1; ++ return 0; + } + + static inline int +@@ -5146,7 +5148,7 @@ static inline int + __always_inline + do_set_mxfast (size_t value) + { +- if (value >= 0 && value <= MAX_FAST_SIZE) ++ if (value <= MAX_FAST_SIZE) + { + LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); + set_max_fast (value); +@@ -5171,18 +5173,24 @@ __libc_mallopt (int param_number, int value) + (see definition of set_max_fast). */ + malloc_consolidate (av); + ++ /* Many of these helper functions take a size_t. We do not worry ++ about overflow here, because negative int values will wrap to ++ very large size_t values and the helpers have sufficient range ++ checking for such conversions. Many of these helpers are also ++ used by the tunables macros in arena.c. */ ++ + switch (param_number) + { + case M_MXFAST: +- do_set_mxfast (value); ++ res = do_set_mxfast (value); + break; + + case M_TRIM_THRESHOLD: +- do_set_trim_threshold (value); ++ res = do_set_trim_threshold (value); + break; + + case M_TOP_PAD: +- do_set_top_pad (value); ++ res = do_set_top_pad (value); + break; + + case M_MMAP_THRESHOLD: +@@ -5190,25 +5198,25 @@ __libc_mallopt (int param_number, int value) + break; + + case M_MMAP_MAX: +- do_set_mmaps_max (value); ++ res = do_set_mmaps_max (value); + break; + + case M_CHECK_ACTION: +- do_set_mallopt_check (value); ++ res = do_set_mallopt_check (value); + break; + + case M_PERTURB: +- do_set_perturb_byte (value); ++ res = do_set_perturb_byte (value); + break; + + case M_ARENA_TEST: + if (value > 0) +- do_set_arena_test (value); ++ res = do_set_arena_test (value); + break; + + case M_ARENA_MAX: + if (value > 0) +- do_set_arena_max (value); ++ res = do_set_arena_max (value); + break; + } + __libc_lock_unlock (av->mutex); diff --git a/SOURCES/glibc-rh1784525.patch b/SOURCES/glibc-rh1784525.patch new file mode 100644 index 0000000..3a5f000 --- /dev/null +++ b/SOURCES/glibc-rh1784525.patch @@ -0,0 +1,29 @@ +commit ef21bd2d8c6805c0c186a01f7c5039189f51b8c4 +Author: DJ Delorie +Date: Fri Oct 18 17:15:52 2019 -0400 + + loadarchive: guard against locale-archive corruption (Bug #25115) + + _nl_load_locale_from_archive() checks for a zero size, but + divides by both (size) and (size-2). Extend the check to + guard against a size of two or less. + + Tested by manually corrupting locale-archive and running a program + that calls setlocale() with LOCPATH unset (size is typically very + large). + + Reviewed-by: Carlos O'Donell + +diff --git a/locale/loadarchive.c b/locale/loadarchive.c +index 516d30d8d16bd578..b308fd886f44e1fd 100644 +--- a/locale/loadarchive.c ++++ b/locale/loadarchive.c +@@ -274,7 +274,7 @@ _nl_load_locale_from_archive (int category, const char **namep) + + head->namehash_offset); + + /* Avoid division by 0 if the file is corrupted. */ +- if (__glibc_unlikely (head->namehash_size == 0)) ++ if (__glibc_unlikely (head->namehash_size <= 2)) + goto close_and_out; + + idx = hval % head->namehash_size; diff --git a/SOURCES/glibc-rh1810142-1.patch b/SOURCES/glibc-rh1810142-1.patch new file mode 100644 index 0000000..4a6d2e9 --- /dev/null +++ b/SOURCES/glibc-rh1810142-1.patch @@ -0,0 +1,382 @@ +From: Florian Weimer +Date: Tue, 11 Feb 2020 12:52:06 +0000 (+0100) +Subject: Add internal header file +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=6c80c6e8767b860a5e18e136d04a80be2a8dce15 + +Add internal header file + +The code started out with bits form resolv/resolv_conf.c, but it +was enhanced to deal with directories and FIFOs in a more predictable +manner. A test case is included as well. + +This will be used to implement the /etc/resolv.conf change detection. + +This currently lives in a header file only. Once there are multiple +users, the implementations should be moved into C files. +--- + +diff -rupN a/include/file_change_detection.h b/include/file_change_detection.h +--- a/include/file_change_detection.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/include/file_change_detection.h 2020-03-25 16:57:24.227929816 -0400 +@@ -0,0 +1,140 @@ ++/* Detecting file changes using modification times. ++ Copyright (C) 2017-2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Items for identifying a particular file version. Excerpt from ++ struct stat64. */ ++struct file_change_detection ++{ ++ /* Special values: 0 if file does not exist. -1 to force mismatch ++ with the next comparison. */ ++ off64_t size; ++ ++ ino64_t ino; ++ struct timespec mtime; ++ struct timespec ctime; ++}; ++ ++/* Returns true if *LEFT and *RIGHT describe the same version of the ++ same file. */ ++static bool __attribute__ ((unused)) ++file_is_unchanged (const struct file_change_detection *left, ++ const struct file_change_detection *right) ++{ ++ if (left->size < 0 || right->size < 0) ++ /* Negative sizes are used as markers and never match. */ ++ return false; ++ else if (left->size == 0 && right->size == 0) ++ /* Both files are empty or do not exist, so they have the same ++ content, no matter what the other fields indicate. */ ++ return true; ++ else ++ return left->size == right->size ++ && left->ino == right->ino ++ && left->mtime.tv_sec == right->mtime.tv_sec ++ && left->mtime.tv_nsec == right->mtime.tv_nsec ++ && left->ctime.tv_sec == right->ctime.tv_sec ++ && left->ctime.tv_nsec == right->ctime.tv_nsec; ++} ++ ++/* Extract file change information to *FILE from the stat buffer ++ *ST. */ ++static void __attribute__ ((unused)) ++file_change_detection_for_stat (struct file_change_detection *file, ++ const struct stat64 *st) ++{ ++ if (S_ISDIR (st->st_mode)) ++ /* Treat as empty file. */ ++ file->size = 0; ++ else if (!S_ISREG (st->st_mode)) ++ /* Non-regular files cannot be cached. */ ++ file->size = -1; ++ else ++ { ++ file->size = st->st_size; ++ file->ino = st->st_ino; ++ file->mtime = st->st_mtim; ++ file->ctime = st->st_ctim; ++ } ++} ++ ++/* Writes file change information for PATH to *FILE. Returns true on ++ success. For benign errors, *FILE is cleared, and true is ++ returned. For errors indicating resource outages and the like, ++ false is returned. */ ++static bool __attribute__ ((unused)) ++file_change_detection_for_path (struct file_change_detection *file, ++ const char *path) ++{ ++ struct stat64 st; ++ if (stat64 (path, &st) != 0) ++ switch (errno) ++ { ++ case EACCES: ++ case EISDIR: ++ case ELOOP: ++ case ENOENT: ++ case ENOTDIR: ++ case EPERM: ++ /* Ignore errors due to file system contents. Instead, treat ++ the file as empty. */ ++ file->size = 0; ++ return true; ++ default: ++ /* Other errors are fatal. */ ++ return false; ++ } ++ else /* stat64 was successfull. */ ++ { ++ file_change_detection_for_stat (file, &st); ++ return true; ++ } ++} ++ ++/* Writes file change information for the stream FP to *FILE. Returns ++ ture on success, false on failure. If FP is NULL, treat the file ++ as non-existing. */ ++static bool __attribute__ ((unused)) ++file_change_detection_for_fp (struct file_change_detection *file, ++ FILE *fp) ++{ ++ if (fp == NULL) ++ { ++ /* The file does not exist. */ ++ file->size = 0; ++ return true; ++ } ++ else ++ { ++ struct stat64 st; ++ if (fstat64 (__fileno (fp), &st) != 0) ++ /* If we already have a file descriptor, all errors are fatal. */ ++ return false; ++ else ++ { ++ file_change_detection_for_stat (file, &st); ++ return true; ++ } ++ } ++} +diff -rupN a/io/Makefile b/io/Makefile +--- a/io/Makefile 2020-03-25 16:55:42.442195992 -0400 ++++ b/io/Makefile 2020-03-25 16:58:48.571023810 -0400 +@@ -74,6 +74,7 @@ tests := test-utime test-stat test-stat + tst-posix_fallocate tst-posix_fallocate64 \ + tst-fts tst-fts-lfs tst-open-tmpfile \ + tst-copy_file_range tst-getcwd-abspath \ ++ tst-file_change_detection + + # Likewise for statx, but we do not need static linking here. + tests-internal += tst-statx +diff -rupN a/io/tst-file_change_detection.c b/io/tst-file_change_detection.c +--- a/io/tst-file_change_detection.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/io/tst-file_change_detection.c 2020-03-25 16:57:24.242930366 -0400 +@@ -0,0 +1,206 @@ ++/* Test for . ++ 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 ++ . */ ++ ++/* The header uses the internal __fileno symbol, which is not ++ available outside of libc (even to internal tests). */ ++#define __fileno(fp) fileno (fp) ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++all_same (struct file_change_detection *array, size_t length) ++{ ++ for (size_t i = 0; i < length; ++i) ++ for (size_t j = 0; j < length; ++j) ++ { ++ if (test_verbose > 0) ++ printf ("info: comparing %zu and %zu\n", i, j); ++ TEST_VERIFY (file_is_unchanged (array + i, array + j)); ++ } ++} ++ ++static void ++all_different (struct file_change_detection *array, size_t length) ++{ ++ for (size_t i = 0; i < length; ++i) ++ for (size_t j = 0; j < length; ++j) ++ { ++ if (i == j) ++ continue; ++ if (test_verbose > 0) ++ printf ("info: comparing %zu and %zu\n", i, j); ++ TEST_VERIFY (!file_is_unchanged (array + i, array + j)); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ /* Use a temporary directory with various paths. */ ++ char *tempdir = support_create_temp_directory ("tst-file_change_detection-"); ++ ++ char *path_dangling = xasprintf ("%s/dangling", tempdir); ++ char *path_does_not_exist = xasprintf ("%s/does-not-exist", tempdir); ++ char *path_empty1 = xasprintf ("%s/empty1", tempdir); ++ char *path_empty2 = xasprintf ("%s/empty2", tempdir); ++ char *path_fifo = xasprintf ("%s/fifo", tempdir); ++ char *path_file1 = xasprintf ("%s/file1", tempdir); ++ char *path_file2 = xasprintf ("%s/file2", tempdir); ++ char *path_loop = xasprintf ("%s/loop", tempdir); ++ char *path_to_empty1 = xasprintf ("%s/to-empty1", tempdir); ++ char *path_to_file1 = xasprintf ("%s/to-file1", tempdir); ++ ++ add_temp_file (path_dangling); ++ add_temp_file (path_empty1); ++ add_temp_file (path_empty2); ++ add_temp_file (path_fifo); ++ add_temp_file (path_file1); ++ add_temp_file (path_file2); ++ add_temp_file (path_loop); ++ add_temp_file (path_to_empty1); ++ add_temp_file (path_to_file1); ++ ++ xsymlink ("target-does-not-exist", path_dangling); ++ support_write_file_string (path_empty1, ""); ++ support_write_file_string (path_empty2, ""); ++ TEST_COMPARE (mknod (path_fifo, 0777 | S_IFIFO, 0), 0); ++ support_write_file_string (path_file1, "line\n"); ++ support_write_file_string (path_file2, "line\n"); ++ xsymlink ("loop", path_loop); ++ xsymlink ("empty1", path_to_empty1); ++ xsymlink ("file1", path_to_file1); ++ ++ FILE *fp_file1 = xfopen (path_file1, "r"); ++ FILE *fp_file2 = xfopen (path_file2, "r"); ++ FILE *fp_empty1 = xfopen (path_empty1, "r"); ++ FILE *fp_empty2 = xfopen (path_empty2, "r"); ++ ++ /* Test for the same (empty) files. */ ++ { ++ struct file_change_detection fcd[10]; ++ int i = 0; ++ /* Two empty files always have the same contents. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1)); ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty2)); ++ /* So does a missing file (which is treated as empty). */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], ++ path_does_not_exist)); ++ /* And a symbolic link loop. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_loop)); ++ /* And a dangling symbolic link. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_dangling)); ++ /* And a directory. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], tempdir)); ++ /* And a symbolic link to an empty file. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_empty1)); ++ /* Likewise for access the file via a FILE *. */ ++ TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty1)); ++ TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty2)); ++ /* And a NULL FILE * (missing file). */ ++ TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], NULL)); ++ TEST_COMPARE (i, array_length (fcd)); ++ ++ all_same (fcd, array_length (fcd)); ++ } ++ ++ /* Symbolic links are resolved. */ ++ { ++ struct file_change_detection fcd[3]; ++ int i = 0; ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1)); ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_file1)); ++ TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_file1)); ++ TEST_COMPARE (i, array_length (fcd)); ++ all_same (fcd, array_length (fcd)); ++ } ++ ++ /* Test for different files. */ ++ { ++ struct file_change_detection fcd[5]; ++ int i = 0; ++ /* The other files are not empty. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1)); ++ /* These two files have the same contents, but have different file ++ identity. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1)); ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file2)); ++ /* FIFOs are always different, even with themselves. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo)); ++ TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo)); ++ TEST_COMPARE (i, array_length (fcd)); ++ all_different (fcd, array_length (fcd)); ++ ++ /* Replacing the file with its symbolic link does not make a ++ difference. */ ++ TEST_VERIFY (file_change_detection_for_path (&fcd[1], path_to_file1)); ++ all_different (fcd, array_length (fcd)); ++ } ++ ++ /* Wait for a file change. Depending on file system time stamp ++ resolution, this subtest blocks for a while. */ ++ for (int use_stdio = 0; use_stdio < 2; ++use_stdio) ++ { ++ struct file_change_detection initial; ++ TEST_VERIFY (file_change_detection_for_path (&initial, path_file1)); ++ while (true) ++ { ++ support_write_file_string (path_file1, "line\n"); ++ struct file_change_detection current; ++ if (use_stdio) ++ TEST_VERIFY (file_change_detection_for_fp (¤t, fp_file1)); ++ else ++ TEST_VERIFY (file_change_detection_for_path (¤t, path_file1)); ++ if (!file_is_unchanged (&initial, ¤t)) ++ break; ++ /* Wait for a bit to reduce system load. */ ++ usleep (100 * 1000); ++ } ++ } ++ ++ fclose (fp_empty1); ++ fclose (fp_empty2); ++ fclose (fp_file1); ++ fclose (fp_file2); ++ ++ free (path_dangling); ++ free (path_does_not_exist); ++ free (path_empty1); ++ free (path_empty2); ++ free (path_fifo); ++ free (path_file1); ++ free (path_file2); ++ free (path_loop); ++ free (path_to_empty1); ++ free (path_to_file1); ++ ++ free (tempdir); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1810142-2.patch b/SOURCES/glibc-rh1810142-2.patch new file mode 100644 index 0000000..cd7b4e4 --- /dev/null +++ b/SOURCES/glibc-rh1810142-2.patch @@ -0,0 +1,94 @@ +From: Florian Weimer +Date: Tue, 21 Jan 2020 15:52:33 +0000 (+0100) +Subject: resolv: Use in __resolv_conf_get_current +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=9642b85fd0dfa5731020a3271c08e33e1dc05c85 + +resolv: Use in __resolv_conf_get_current + +Only minor functional changes (i.e., regarding the handling of +directories, which are now treated as empty files). + +Reviewed-by: Adhemerval Zanella +--- + +diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c +index 08c50ef19e..d954ba9a5a 100644 +--- a/resolv/resolv_conf.c ++++ b/resolv/resolv_conf.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + /* _res._u._ext.__glibc_extension_index is used as an index into a + struct resolv_conf_array object. The intent of this construction +@@ -68,12 +69,8 @@ struct resolv_conf_global + /* Cached current configuration object for /etc/resolv.conf. */ + struct resolv_conf *conf_current; + +- /* These properties of /etc/resolv.conf are used to check if the +- configuration needs reloading. */ +- struct timespec conf_mtime; +- struct timespec conf_ctime; +- off64_t conf_size; +- ino64_t conf_ino; ++ /* File system identification for /etc/resolv.conf. */ ++ struct file_change_detection file_resolve_conf; + }; + + /* Lazily allocated storage for struct resolv_conf_global. */ +@@ -123,37 +120,16 @@ conf_decrement (struct resolv_conf *conf) + struct resolv_conf * + __resolv_conf_get_current (void) + { +- struct stat64 st; +- if (stat64 (_PATH_RESCONF, &st) != 0) +- { +- switch (errno) +- { +- case EACCES: +- case EISDIR: +- case ELOOP: +- case ENOENT: +- case ENOTDIR: +- case EPERM: +- /* Ignore errors due to file system contents. */ +- memset (&st, 0, sizeof (st)); +- break; +- default: +- /* Other errors are fatal. */ +- return NULL; +- } +- } ++ struct file_change_detection initial; ++ if (!file_change_detection_for_path (&initial, _PATH_RESCONF)) ++ return NULL; + + struct resolv_conf_global *global_copy = get_locked_global (); + if (global_copy == NULL) + return NULL; + struct resolv_conf *conf; + if (global_copy->conf_current != NULL +- && (global_copy->conf_mtime.tv_sec == st.st_mtim.tv_sec +- && global_copy->conf_mtime.tv_nsec == st.st_mtim.tv_nsec +- && global_copy->conf_ctime.tv_sec == st.st_ctim.tv_sec +- && global_copy->conf_ctime.tv_nsec == st.st_ctim.tv_nsec +- && global_copy->conf_ino == st.st_ino +- && global_copy->conf_size == st.st_size)) ++ && file_is_unchanged (&initial, &global_copy->file_resolve_conf)) + /* We can reuse the cached configuration object. */ + conf = global_copy->conf_current; + else +@@ -171,10 +147,7 @@ __resolv_conf_get_current (void) + read could be a newer version of the file, but this does + not matter because this will lead to an extraneous reload + later. */ +- global_copy->conf_mtime = st.st_mtim; +- global_copy->conf_ctime = st.st_ctim; +- global_copy->conf_ino = st.st_ino; +- global_copy->conf_size = st.st_size; ++ global_copy->file_resolve_conf = initial; + } + } + diff --git a/SOURCES/glibc-rh1810142-3.patch b/SOURCES/glibc-rh1810142-3.patch new file mode 100644 index 0000000..e13f74d --- /dev/null +++ b/SOURCES/glibc-rh1810142-3.patch @@ -0,0 +1,46 @@ +From: Florian Weimer +Date: Tue, 21 Jan 2020 16:11:01 +0000 (+0100) +Subject: resolv: Fix file handle leak in __resolv_conf_load [BZ #25429] +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=a1a20f029299dc27170912bb9233070c8403444d + +resolv: Fix file handle leak in __resolv_conf_load [BZ #25429] + +res_vinit_1 did not close the stream on errors, only on success. +This change moves closing the stream to __resolv_conf_load, for both +the success and error cases. + +Fixes commit 89f187a40fc0ad4e22838526bfe34d73f758b776 ("resolv: Use +getline for configuration file reading in res_vinit_1") and commit +3f853f22c87f0b671c0366eb290919719fa56c0e ("resolv: Lift domain search +list limits [BZ #19569] [BZ #21475]"), where memory allocation was +introduced into res_vinit_1. + +Reviewed-by: Adhemerval Zanella +--- + +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 95dce098aa..09345718cd 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -508,7 +508,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + continue; + } + } +- fclose (fp); + } + if (__glibc_unlikely (nameserver_list_size (&parser->nameserver_list) == 0)) + { +@@ -593,6 +592,13 @@ __resolv_conf_load (struct __res_state *preinit) + } + resolv_conf_parser_free (&parser); + ++ if (fp != NULL) ++ { ++ int saved_errno = errno; ++ fclose (fp); ++ __set_errno (saved_errno); ++ } ++ + return conf; + } + diff --git a/SOURCES/glibc-rh1810142-4.patch b/SOURCES/glibc-rh1810142-4.patch new file mode 100644 index 0000000..3d4ff39 --- /dev/null +++ b/SOURCES/glibc-rh1810142-4.patch @@ -0,0 +1,96 @@ +From: Florian Weimer +Date: Tue, 21 Jan 2020 16:25:39 +0000 (+0100) +Subject: resolv: Enhance __resolv_conf_load to capture file change data +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=dd0b4df329ff7ff2a656404db271c8ee8379ff9d + +resolv: Enhance __resolv_conf_load to capture file change data + +The data is captured after reading the file. This allows callers +to check the change data against an earlier measurement. + +Reviewed-by: Adhemerval Zanella +--- + +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 09345718cd..98d84f264d 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -103,6 +103,7 @@ + #include + #include + #include ++#include + + static uint32_t net_mask (struct in_addr); + +@@ -549,7 +550,8 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + } + + struct resolv_conf * +-__resolv_conf_load (struct __res_state *preinit) ++__resolv_conf_load (struct __res_state *preinit, ++ struct file_change_detection *change) + { + /* Ensure that /etc/hosts.conf has been loaded (once). */ + _res_hconf_init (); +@@ -577,7 +579,13 @@ __resolv_conf_load (struct __res_state *preinit) + resolv_conf_parser_init (&parser, preinit); + + struct resolv_conf *conf = NULL; +- if (res_vinit_1 (fp, &parser)) ++ bool ok = res_vinit_1 (fp, &parser); ++ if (ok && change != NULL) ++ /* Update the file change information if the configuration was ++ loaded successfully. */ ++ ok = file_change_detection_for_fp (change, fp); ++ ++ if (ok) + { + parser.template.nameserver_list + = nameserver_list_begin (&parser.nameserver_list); +@@ -615,7 +623,7 @@ __res_vinit (res_state statp, int preinit) + if (preinit && has_preinit_values (statp)) + /* For the preinit case, we cannot use the cached configuration + because some settings could be different. */ +- conf = __resolv_conf_load (statp); ++ conf = __resolv_conf_load (statp, NULL); + else + conf = __resolv_conf_get_current (); + if (conf == NULL) +diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c +index d954ba9a5a..bdd2ebb909 100644 +--- a/resolv/resolv_conf.c ++++ b/resolv/resolv_conf.c +@@ -136,7 +136,7 @@ __resolv_conf_get_current (void) + { + /* Parse configuration while holding the lock. This avoids + duplicate work. */ +- conf = __resolv_conf_load (NULL); ++ conf = __resolv_conf_load (NULL, NULL); + if (conf != NULL) + { + if (global_copy->conf_current != NULL) +diff --git a/resolv/resolv_conf.h b/resolv/resolv_conf.h +index 01cbff9111..101e14bfe5 100644 +--- a/resolv/resolv_conf.h ++++ b/resolv/resolv_conf.h +@@ -63,12 +63,16 @@ struct resolv_conf + and the struct resolv_context facility. */ + + struct __res_state; ++struct file_change_detection; + + /* Read /etc/resolv.conf and return a configuration object, or NULL if + /etc/resolv.conf cannot be read due to memory allocation errors. +- If PREINIT is not NULL, some configuration values are taken from the +- struct __res_state object. */ +-struct resolv_conf *__resolv_conf_load (struct __res_state *preinit) ++ If PREINIT is not NULL, some configuration values are taken from ++ the struct __res_state object. If CHANGE is not null, file change ++ detection data is written to *CHANGE, based on the state of the ++ file after reading it. */ ++struct resolv_conf *__resolv_conf_load (struct __res_state *preinit, ++ struct file_change_detection *change) + attribute_hidden __attribute__ ((warn_unused_result)); + + /* Return a configuration object for the current /etc/resolv.conf diff --git a/SOURCES/glibc-rh1810142-5.patch b/SOURCES/glibc-rh1810142-5.patch new file mode 100644 index 0000000..be991b0 --- /dev/null +++ b/SOURCES/glibc-rh1810142-5.patch @@ -0,0 +1,52 @@ +From: Florian Weimer +Date: Tue, 21 Jan 2020 16:38:15 +0000 (+0100) +Subject: resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420] +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=fa00db0a6eb755837ae5d413515e0da582b304f3 + +resolv: Fix ABA race in /etc/resolv.conf change detection [BZ #25420] + +__resolv_conf_get_current should only record the initial file +change data if after verifying that file just read matches the +original measurement. Fixes commit aef16cc8a4c670036d45590877 +("resolv: Automatically reload a changed /etc/resolv.conf file +[BZ #984]"). + +Reviewed-by: Adhemerval Zanella +--- + +diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c +index bdd2ebb909..29a1f4fb94 100644 +--- a/resolv/resolv_conf.c ++++ b/resolv/resolv_conf.c +@@ -136,18 +136,25 @@ __resolv_conf_get_current (void) + { + /* Parse configuration while holding the lock. This avoids + duplicate work. */ +- conf = __resolv_conf_load (NULL, NULL); ++ struct file_change_detection after_load; ++ conf = __resolv_conf_load (NULL, &after_load); + if (conf != NULL) + { + if (global_copy->conf_current != NULL) + conf_decrement (global_copy->conf_current); + global_copy->conf_current = conf; /* Takes ownership. */ + +- /* Update file modification stamps. The configuration we +- read could be a newer version of the file, but this does +- not matter because this will lead to an extraneous reload +- later. */ +- global_copy->file_resolve_conf = initial; ++ /* Update file change detection data, but only if it matches ++ the initial measurement. This avoids an ABA race in case ++ /etc/resolv.conf is temporarily replaced while the file ++ is read (after the initial measurement), and restored to ++ the initial version later. */ ++ if (file_is_unchanged (&initial, &after_load)) ++ global_copy->file_resolve_conf = after_load; ++ else ++ /* If there is a discrepancy, trigger a reload during the ++ next use. */ ++ global_copy->file_resolve_conf.size = -1; + } + } + diff --git a/SOURCES/glibc-rh1810142-6.patch b/SOURCES/glibc-rh1810142-6.patch new file mode 100644 index 0000000..8d96880 --- /dev/null +++ b/SOURCES/glibc-rh1810142-6.patch @@ -0,0 +1,481 @@ +From: Florian Weimer +Date: Tue, 18 Feb 2020 12:44:48 +0000 (+0100) +Subject: Move implementation of into a C file +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=631cf64bc1d8306e011ef39f60b8cb6de91bd271 + +Move implementation of into a C file + +file_change_detection_for_stat partially initialize +struct file_change_detection in some cases, when the size member +alone determines the outcome of all comparisons. This results +in maybe-uninitialized compiler warnings in case of sufficiently +aggressive inlining. + +Once the implementation is moved into a separate C file, this kind +of inlining is no longer possible, so the compiler warnings are gone. +--- + +diff --git a/include/file_change_detection.h b/include/file_change_detection.h +index aaed0a9b6d..767e578555 100644 +--- a/include/file_change_detection.h ++++ b/include/file_change_detection.h +@@ -16,9 +16,10 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#ifndef _FILE_CHANGE_DETECTION_H ++#define _FILE_CHANGE_DETECTION_H ++ + #include +-#include + #include + #include + #include +@@ -38,103 +39,32 @@ struct file_change_detection + + /* Returns true if *LEFT and *RIGHT describe the same version of the + same file. */ +-static bool __attribute__ ((unused)) +-file_is_unchanged (const struct file_change_detection *left, +- const struct file_change_detection *right) +-{ +- if (left->size < 0 || right->size < 0) +- /* Negative sizes are used as markers and never match. */ +- return false; +- else if (left->size == 0 && right->size == 0) +- /* Both files are empty or do not exist, so they have the same +- content, no matter what the other fields indicate. */ +- return true; +- else +- return left->size == right->size +- && left->ino == right->ino +- && left->mtime.tv_sec == right->mtime.tv_sec +- && left->mtime.tv_nsec == right->mtime.tv_nsec +- && left->ctime.tv_sec == right->ctime.tv_sec +- && left->ctime.tv_nsec == right->ctime.tv_nsec; +-} ++bool __file_is_unchanged (const struct file_change_detection *left, ++ const struct file_change_detection *right); + + /* Extract file change information to *FILE from the stat buffer + *ST. */ +-static void __attribute__ ((unused)) +-file_change_detection_for_stat (struct file_change_detection *file, +- const struct stat64 *st) +-{ +- if (S_ISDIR (st->st_mode)) +- /* Treat as empty file. */ +- file->size = 0; +- else if (!S_ISREG (st->st_mode)) +- /* Non-regular files cannot be cached. */ +- file->size = -1; +- else +- { +- file->size = st->st_size; +- file->ino = st->st_ino; +- file->mtime = st->st_mtim; +- file->ctime = st->st_ctim; +- } +-} ++void __file_change_detection_for_stat (struct file_change_detection *file, ++ const struct stat64 *st); + + /* Writes file change information for PATH to *FILE. Returns true on + success. For benign errors, *FILE is cleared, and true is + returned. For errors indicating resource outages and the like, + false is returned. */ +-static bool __attribute__ ((unused)) +-file_change_detection_for_path (struct file_change_detection *file, +- const char *path) +-{ +- struct stat64 st; +- if (stat64 (path, &st) != 0) +- switch (errno) +- { +- case EACCES: +- case EISDIR: +- case ELOOP: +- case ENOENT: +- case ENOTDIR: +- case EPERM: +- /* Ignore errors due to file system contents. Instead, treat +- the file as empty. */ +- file->size = 0; +- return true; +- default: +- /* Other errors are fatal. */ +- return false; +- } +- else /* stat64 was successfull. */ +- { +- file_change_detection_for_stat (file, &st); +- return true; +- } +-} ++bool __file_change_detection_for_path (struct file_change_detection *file, ++ const char *path); + + /* Writes file change information for the stream FP to *FILE. Returns + ture on success, false on failure. If FP is NULL, treat the file + as non-existing. */ +-static bool __attribute__ ((unused)) +-file_change_detection_for_fp (struct file_change_detection *file, +- FILE *fp) +-{ +- if (fp == NULL) +- { +- /* The file does not exist. */ +- file->size = 0; +- return true; +- } +- else +- { +- struct stat64 st; +- if (fstat64 (__fileno (fp), &st) != 0) +- /* If we already have a file descriptor, all errors are fatal. */ +- return false; +- else +- { +- file_change_detection_for_stat (file, &st); +- return true; +- } +- } +-} ++bool __file_change_detection_for_fp (struct file_change_detection *file, ++ FILE *fp); ++ ++#ifndef _ISOMAC ++libc_hidden_proto (__file_is_unchanged) ++libc_hidden_proto (__file_change_detection_for_stat) ++libc_hidden_proto (__file_change_detection_for_path) ++libc_hidden_proto (__file_change_detection_for_fp) ++#endif ++ ++#endif /* _FILE_CHANGE_DETECTION_H */ +diff --git a/io/Makefile b/io/Makefile +index 04c4647dc0..cf380f3516 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -55,7 +55,7 @@ routines := \ + posix_fadvise posix_fadvise64 \ + posix_fallocate posix_fallocate64 \ + sendfile sendfile64 copy_file_range \ +- utimensat futimens ++ utimensat futimens file_change_detection + + # These routines will be omitted from the libc shared object. + # Instead the static object files will be included in a special archive +diff --git a/io/Versions b/io/Versions +index f7e5dbe49e..ee468055ff 100644 +--- a/io/Versions ++++ b/io/Versions +@@ -137,5 +137,9 @@ libc { + __fcntl_nocancel; + __open64_nocancel; + __write_nocancel; ++ __file_is_unchanged; ++ __file_change_detection_for_stat; ++ __file_change_detection_for_path; ++ __file_change_detection_for_fp; + } + } +diff --git a/io/file_change_detection.c b/io/file_change_detection.c +new file mode 100644 +index 0000000000..c6d700ed05 +--- /dev/null ++++ b/io/file_change_detection.c +@@ -0,0 +1,118 @@ ++/* Detecting file changes using modification times. ++ Copyright (C) 2017-2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++ ++bool ++__file_is_unchanged (const struct file_change_detection *left, ++ const struct file_change_detection *right) ++{ ++ if (left->size < 0 || right->size < 0) ++ /* Negative sizes are used as markers and never match. */ ++ return false; ++ else if (left->size == 0 && right->size == 0) ++ /* Both files are empty or do not exist, so they have the same ++ content, no matter what the other fields indicate. */ ++ return true; ++ else ++ return left->size == right->size ++ && left->ino == right->ino ++ && left->mtime.tv_sec == right->mtime.tv_sec ++ && left->mtime.tv_nsec == right->mtime.tv_nsec ++ && left->ctime.tv_sec == right->ctime.tv_sec ++ && left->ctime.tv_nsec == right->ctime.tv_nsec; ++} ++libc_hidden_def (__file_is_unchanged) ++ ++void ++__file_change_detection_for_stat (struct file_change_detection *file, ++ const struct stat64 *st) ++{ ++ if (S_ISDIR (st->st_mode)) ++ /* Treat as empty file. */ ++ file->size = 0; ++ else if (!S_ISREG (st->st_mode)) ++ /* Non-regular files cannot be cached. */ ++ file->size = -1; ++ else ++ { ++ file->size = st->st_size; ++ file->ino = st->st_ino; ++ file->mtime = st->st_mtim; ++ file->ctime = st->st_ctim; ++ } ++} ++libc_hidden_def (__file_change_detection_for_stat) ++ ++bool ++__file_change_detection_for_path (struct file_change_detection *file, ++ const char *path) ++{ ++ struct stat64 st; ++ if (stat64 (path, &st) != 0) ++ switch (errno) ++ { ++ case EACCES: ++ case EISDIR: ++ case ELOOP: ++ case ENOENT: ++ case ENOTDIR: ++ case EPERM: ++ /* Ignore errors due to file system contents. Instead, treat ++ the file as empty. */ ++ file->size = 0; ++ return true; ++ default: ++ /* Other errors are fatal. */ ++ return false; ++ } ++ else /* stat64 was successfull. */ ++ { ++ __file_change_detection_for_stat (file, &st); ++ return true; ++ } ++} ++libc_hidden_def (__file_change_detection_for_path) ++ ++bool ++__file_change_detection_for_fp (struct file_change_detection *file, ++ FILE *fp) ++{ ++ if (fp == NULL) ++ { ++ /* The file does not exist. */ ++ file->size = 0; ++ return true; ++ } ++ else ++ { ++ struct stat64 st; ++ if (fstat64 (__fileno (fp), &st) != 0) ++ /* If we already have a file descriptor, all errors are fatal. */ ++ return false; ++ else ++ { ++ __file_change_detection_for_stat (file, &st); ++ return true; ++ } ++ } ++} ++libc_hidden_def (__file_change_detection_for_fp) +diff --git a/io/tst-file_change_detection.c b/io/tst-file_change_detection.c +index 035dd39c4d..6e00e787b1 100644 +--- a/io/tst-file_change_detection.c ++++ b/io/tst-file_change_detection.c +@@ -16,10 +16,6 @@ + License along with the GNU C Library; if not, see + . */ + +-/* The header uses the internal __fileno symbol, which is not +- available outside of libc (even to internal tests). */ +-#define __fileno(fp) fileno (fp) +- + #include + + #include +@@ -40,7 +36,7 @@ all_same (struct file_change_detection *array, size_t length) + { + if (test_verbose > 0) + printf ("info: comparing %zu and %zu\n", i, j); +- TEST_VERIFY (file_is_unchanged (array + i, array + j)); ++ TEST_VERIFY (__file_is_unchanged (array + i, array + j)); + } + } + +@@ -54,7 +50,7 @@ all_different (struct file_change_detection *array, size_t length) + continue; + if (test_verbose > 0) + printf ("info: comparing %zu and %zu\n", i, j); +- TEST_VERIFY (!file_is_unchanged (array + i, array + j)); ++ TEST_VERIFY (!__file_is_unchanged (array + i, array + j)); + } + } + +@@ -105,24 +101,24 @@ do_test (void) + struct file_change_detection fcd[10]; + int i = 0; + /* Two empty files always have the same contents. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1)); +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty2)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty1)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty2)); + /* So does a missing file (which is treated as empty). */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], +- path_does_not_exist)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], ++ path_does_not_exist)); + /* And a symbolic link loop. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_loop)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_loop)); + /* And a dangling symbolic link. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_dangling)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_dangling)); + /* And a directory. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], tempdir)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], tempdir)); + /* And a symbolic link to an empty file. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_empty1)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_to_empty1)); + /* Likewise for access the file via a FILE *. */ +- TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty1)); +- TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_empty2)); ++ TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_empty1)); ++ TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_empty2)); + /* And a NULL FILE * (missing file). */ +- TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], NULL)); ++ TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], NULL)); + TEST_COMPARE (i, array_length (fcd)); + + all_same (fcd, array_length (fcd)); +@@ -132,9 +128,9 @@ do_test (void) + { + struct file_change_detection fcd[3]; + int i = 0; +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1)); +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_to_file1)); +- TEST_VERIFY (file_change_detection_for_fp (&fcd[i++], fp_file1)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file1)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_to_file1)); ++ TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_file1)); + TEST_COMPARE (i, array_length (fcd)); + all_same (fcd, array_length (fcd)); + } +@@ -144,20 +140,20 @@ do_test (void) + struct file_change_detection fcd[5]; + int i = 0; + /* The other files are not empty. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_empty1)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty1)); + /* These two files have the same contents, but have different file + identity. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file1)); +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_file2)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file1)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file2)); + /* FIFOs are always different, even with themselves. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo)); +- TEST_VERIFY (file_change_detection_for_path (&fcd[i++], path_fifo)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_fifo)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_fifo)); + TEST_COMPARE (i, array_length (fcd)); + all_different (fcd, array_length (fcd)); + + /* Replacing the file with its symbolic link does not make a + difference. */ +- TEST_VERIFY (file_change_detection_for_path (&fcd[1], path_to_file1)); ++ TEST_VERIFY (__file_change_detection_for_path (&fcd[1], path_to_file1)); + all_different (fcd, array_length (fcd)); + } + +@@ -166,16 +162,17 @@ do_test (void) + for (int use_stdio = 0; use_stdio < 2; ++use_stdio) + { + struct file_change_detection initial; +- TEST_VERIFY (file_change_detection_for_path (&initial, path_file1)); ++ TEST_VERIFY (__file_change_detection_for_path (&initial, path_file1)); + while (true) + { + support_write_file_string (path_file1, "line\n"); + struct file_change_detection current; + if (use_stdio) +- TEST_VERIFY (file_change_detection_for_fp (¤t, fp_file1)); ++ TEST_VERIFY (__file_change_detection_for_fp (¤t, fp_file1)); + else +- TEST_VERIFY (file_change_detection_for_path (¤t, path_file1)); +- if (!file_is_unchanged (&initial, ¤t)) ++ TEST_VERIFY (__file_change_detection_for_path ++ (¤t, path_file1)); ++ if (!__file_is_unchanged (&initial, ¤t)) + break; + /* Wait for a bit to reduce system load. */ + usleep (100 * 1000); +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 98d84f264d..ee5dfdd391 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -583,7 +583,7 @@ __resolv_conf_load (struct __res_state *preinit, + if (ok && change != NULL) + /* Update the file change information if the configuration was + loaded successfully. */ +- ok = file_change_detection_for_fp (change, fp); ++ ok = __file_change_detection_for_fp (change, fp); + + if (ok) + { +diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c +index 29a1f4fb94..286149ffad 100644 +--- a/resolv/resolv_conf.c ++++ b/resolv/resolv_conf.c +@@ -121,7 +121,7 @@ struct resolv_conf * + __resolv_conf_get_current (void) + { + struct file_change_detection initial; +- if (!file_change_detection_for_path (&initial, _PATH_RESCONF)) ++ if (!__file_change_detection_for_path (&initial, _PATH_RESCONF)) + return NULL; + + struct resolv_conf_global *global_copy = get_locked_global (); +@@ -129,7 +129,7 @@ __resolv_conf_get_current (void) + return NULL; + struct resolv_conf *conf; + if (global_copy->conf_current != NULL +- && file_is_unchanged (&initial, &global_copy->file_resolve_conf)) ++ && __file_is_unchanged (&initial, &global_copy->file_resolve_conf)) + /* We can reuse the cached configuration object. */ + conf = global_copy->conf_current; + else +@@ -149,7 +149,7 @@ __resolv_conf_get_current (void) + /etc/resolv.conf is temporarily replaced while the file + is read (after the initial measurement), and restored to + the initial version later. */ +- if (file_is_unchanged (&initial, &after_load)) ++ if (__file_is_unchanged (&initial, &after_load)) + global_copy->file_resolve_conf = after_load; + else + /* If there is a discrepancy, trigger a reload during the diff --git a/SOURCES/glibc-rh1810146.patch b/SOURCES/glibc-rh1810146.patch new file mode 100644 index 0000000..da0d6b3 --- /dev/null +++ b/SOURCES/glibc-rh1810146.patch @@ -0,0 +1,28 @@ +commit 8b222fa38700422b4da6731806835f0bbf40920d +Author: Florian Weimer +Date: Mon Jan 20 18:37:13 2020 +0100 + + getaddrinfo: Fix resource leak after strdup failure in gethosts [BZ #25425] + + Filip Ochnik spotted that one of the error jumps in gethosts fails to + call __resolv_context_put to release the resolver context. + + Fixes commit 352f4ff9a268b81ef5d4b2413f582565806e4790 ("resolv: + Introduce struct resolv_context [BZ #21668]") and commit + 964263bb8d650f1681665c55704fb01a8e725621 ("getaddrinfo: Release + resolver context on error in gethosts [BZ #21885]"). + + Reviewed-by: Siddhesh Poyarekar + +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 6a5805c9e63a257c..fae3dea81f19dba6 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -292,6 +292,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, + canonbuf = __strdup (localcanon); \ + if (canonbuf == NULL) \ + { \ ++ __resolv_context_put (res_ctx); \ + result = -EAI_SYSTEM; \ + goto free_and_return; \ + } \ diff --git a/SOURCES/glibc-rh1810223-1.patch b/SOURCES/glibc-rh1810223-1.patch new file mode 100644 index 0000000..6771e16 --- /dev/null +++ b/SOURCES/glibc-rh1810223-1.patch @@ -0,0 +1,170 @@ +commit 0499a353a6e196f468e7ec554cb13c82011f0e36 +Author: Florian Weimer +Date: Mon Mar 2 14:24:27 2020 +0100 + + elf: Add elf/check-wx-segment, a test for the presence of WX segments + + Writable, executable segments defeat security hardening. The + existing check for DT_TEXTREL does not catch this. + + hppa and SPARC currently keep the PLT in an RWX load segment. + +# Conflicts: +# sysdeps/sparc/Makefile + +diff --git a/elf/Makefile b/elf/Makefile +index f1a16fe8ca594c57..a52d9b1f6a4364a7 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -378,6 +378,7 @@ tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \ + $(objpfx)tst-rtld-preload.out + endif + tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \ ++ $(objpfx)check-wx-segment.out \ + $(objpfx)check-localplt.out $(objpfx)check-initfini.out + endif + +@@ -1148,6 +1149,12 @@ $(objpfx)check-execstack.out: $(..)scripts/check-execstack.awk \ + $(evaluate-test) + generated += check-execstack.out + ++$(objpfx)check-wx-segment.out: $(..)scripts/check-wx-segment.py \ ++ $(all-built-dso:=.phdr) ++ $(PYTHON) $^ --xfail="$(check-wx-segment-xfail)" > $@; \ ++ $(evaluate-test) ++generated += check-wx-segment.out ++ + $(objpfx)tst-dlmodcount: $(libdl) + $(objpfx)tst-dlmodcount.out: $(test-modules) + +diff --git a/scripts/check-wx-segment.py b/scripts/check-wx-segment.py +new file mode 100644 +index 0000000000000000..e1fa79387ce22c4b +--- /dev/null ++++ b/scripts/check-wx-segment.py +@@ -0,0 +1,85 @@ ++#!/usr/bin/python3 ++# Check ELF program headers for WX segments. ++# Copyright (C) 2020 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++"""Check that the program headers do not contain write-exec segments.""" ++ ++import argparse ++import os.path ++import re ++import sys ++ ++# Regular expression to extract the RWE flags field. The ++# address/offset columns have varying width. ++RE_LOAD = re.compile( ++ r'^ LOAD +(?:0x[0-9a-fA-F]+ +){5}([R ][W ][ E]) +0x[0-9a-fA-F]+\n\Z') ++ ++def process_file(path, inp, xfail): ++ """Analyze one input file.""" ++ ++ errors = 0 ++ for line in inp: ++ error = None ++ if line.startswith(' LOAD '): ++ match = RE_LOAD.match(line) ++ if match is None: ++ error = 'Invalid LOAD line' ++ else: ++ flags, = match.groups() ++ if 'W' in flags and 'E' in flags: ++ if xfail: ++ print('{}: warning: WX segment (as expected)'.format( ++ path)) ++ else: ++ error = 'WX segment' ++ ++ if error is not None: ++ print('{}: error: {}: {!r}'.format(path, error, line.strip())) ++ errors += 1 ++ ++ if xfail and errors == 0: ++ print('{}: warning: missing expected WX segment'.format(path)) ++ return errors ++ ++ ++def main(): ++ """The main entry point.""" ++ parser = argparse.ArgumentParser(description=__doc__) ++ parser.add_argument('--xfail', ++ help='Mark input files as XFAILed ("*" for all)', ++ type=str, default='') ++ parser.add_argument('phdrs', ++ help='Files containing readelf -Wl output', ++ nargs='*') ++ opts = parser.parse_args(sys.argv) ++ ++ xfails = set(opts.xfail.split(' ')) ++ xfails_all = opts.xfail.strip() == '*' ++ ++ errors = 0 ++ for path in opts.phdrs: ++ xfail = ((os.path.basename(path) + '.phdrs') in xfails ++ or xfails_all) ++ with open(path) as inp: ++ errors += process_file(path, inp, xfail) ++ if errors > 0: ++ sys.exit(1) ++ ++ ++if __name__ == '__main__': ++ main() +diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile +index 3f0c0964002560f0..a1004e819c9b0c38 100644 +--- a/sysdeps/sparc/Makefile ++++ b/sysdeps/sparc/Makefile +@@ -16,5 +16,14 @@ CPPFLAGS-crti.S += -fPIC + CPPFLAGS-crtn.S += -fPIC + endif + ++ifeq ($(subdir),elf) ++ ++# Lazy binding on SPARC rewrites the PLT sequence. See the Solaris ++# Linker and Libraries Guide, section SPARC: Procedure Linkage Table. ++# ++test-xfail-check-wx-segment = * ++ ++endif # $(subdir) == elf ++ + # The assembler on SPARC needs the -fPIC flag even when it's assembler code. + ASFLAGS-.os += -fPIC +diff --git a/sysdeps/unix/sysv/linux/hppa/Makefile b/sysdeps/unix/sysv/linux/hppa/Makefile +index e1637f54f508c007..c89ec8318208205d 100644 +--- a/sysdeps/unix/sysv/linux/hppa/Makefile ++++ b/sysdeps/unix/sysv/linux/hppa/Makefile +@@ -3,9 +3,14 @@ ifeq ($(subdir),stdlib) + gen-as-const-headers += ucontext_i.sym + endif + ++ifeq ($(subdir),elf) + # Supporting non-executable stacks on HPPA requires changes to both + # the Linux kernel and glibc. The kernel currently needs an executable + # stack for syscall restarts and signal returns. +-ifeq ($(subdir),elf) + test-xfail-check-execstack = yes +-endif ++ ++# On hppa, the PLT is executable because it contains an executable ++# trampoline used during lazy binding. ++test-xfail-check-wx-segment = * ++ ++endif # $(subdir) == elf diff --git a/SOURCES/glibc-rh1810223-2.patch b/SOURCES/glibc-rh1810223-2.patch new file mode 100644 index 0000000..4bee60f --- /dev/null +++ b/SOURCES/glibc-rh1810223-2.patch @@ -0,0 +1,49 @@ +commit 279c68ce1336d84d82ce491a4b77086e574ba380 +Author: DJ Delorie +Date: Mon Feb 3 14:57:23 2020 -0500 + + Run nptl/tst-pthread-getattr in a container + + See https://bugzilla.redhat.com/show_bug.cgi?id=1653942 + + This test depends on the kernel's assignment of memory regions, but + running under ld.so explicitly changes those assignments, sometimes + sufficiently to cause the test to fail (esp with address space + randomization). + + The easiest way to "fix" the test, is to run it the way the user would + - without ld.so. Running it in a container does that. + + Reviewed-by: Carlos O'Donell + +diff --git a/nptl/Makefile b/nptl/Makefile +index b1003cf56b31ddfa..071c53866d14d2fe 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -293,7 +293,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-exec1 tst-exec2 tst-exec3 tst-exec4 tst-exec5 \ + tst-exit1 tst-exit2 tst-exit3 \ + tst-stdio1 tst-stdio2 \ +- tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \ ++ tst-stack1 tst-stack2 tst-stack3 tst-stack4 \ + tst-pthread-attr-affinity tst-pthread-mutexattr \ + tst-unload \ + tst-dlsym1 \ +@@ -322,6 +322,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-rwlock-pwn \ + tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall + ++tests-container = tst-pthread-getattr ++ + tests-internal := tst-rwlock19 tst-rwlock20 \ + tst-sem11 tst-sem12 tst-sem13 \ + tst-barrier5 tst-signal7 tst-mutex8 tst-mutex8-static \ +@@ -633,7 +635,7 @@ ifeq ($(build-shared),yes) + $(addprefix $(objpfx), \ + $(filter-out $(tests-static) $(xtests-static) $(tests-reverse) \ + $(tests-nolibpthread), \ +- $(tests) $(tests-internal) $(xtests) $(test-srcs))): \ ++ $(tests) $(tests-internal) $(xtests) $(test-srcs) $(tests-container))): \ + $(objpfx)libpthread.so + $(objpfx)tst-unload: $(libdl) + # $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so, diff --git a/SOURCES/glibc-rh1810224-1.patch b/SOURCES/glibc-rh1810224-1.patch new file mode 100644 index 0000000..a4b671a --- /dev/null +++ b/SOURCES/glibc-rh1810224-1.patch @@ -0,0 +1,28 @@ +commit a331150af65477fc3fa72ab341eed5e0b2daf7f3 +Author: Joseph Myers +Date: Thu Nov 28 20:32:09 2019 +0000 + + Update syscall-names.list for Linux 5.4. + + This patch updates syscall-names.list for Linux 5.4. There are no new + syscalls, so this is just a matter of updating the version number + listed in the file. + + Tested with build-many-glibcs.py. + +Reworked for RHEL 8.3.0. + +diff -Nrup a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +--- a/sysdeps/unix/sysv/linux/syscall-names.list 2020-04-05 20:20:41.471686371 -0400 ++++ b/sysdeps/unix/sysv/linux/syscall-names.list 2020-04-05 20:21:56.871912297 -0400 +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 5.3. +-kernel 5.3 ++# The list of system calls is current as of Linux 5.4. ++kernel 5.4 + + FAST_atomic_update + FAST_cmpxchg diff --git a/SOURCES/glibc-rh1810224-2.patch b/SOURCES/glibc-rh1810224-2.patch new file mode 100644 index 0000000..df51b1d --- /dev/null +++ b/SOURCES/glibc-rh1810224-2.patch @@ -0,0 +1,29 @@ +commit 5828bc4523230685ac29a4a882967913255f5666 +Author: Joseph Myers +Date: Fri Feb 7 13:54:58 2020 +0000 + + Update syscall lists for Linux 5.5. + + Linux 5.5 has no new syscalls to add to syscall-names.list, but it + does newly enable the clone3 syscall for AArch64. This patch updates + the kernel version listed in syscall-names.list and regenerates the + AArch64 arch-syscall.h. + + Tested with build-many-glibcs.py. + +Modified to only update syscall-names.list for RHEL 8.3.0. + +diff -Nrup a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +--- a/sysdeps/unix/sysv/linux/syscall-names.list 2020-04-06 12:10:47.683272882 -0400 ++++ b/sysdeps/unix/sysv/linux/syscall-names.list 2020-04-06 12:12:41.769598687 -0400 +@@ -22,8 +22,8 @@ + # names are only used if the installed kernel headers also provide + # them. + +-# The list of system calls is current as of Linux 5.4. +-kernel 5.4 ++# The list of system calls is current as of Linux 5.5. ++kernel 5.5 + + FAST_atomic_update + FAST_cmpxchg diff --git a/SOURCES/glibc-rh1810224-3.patch b/SOURCES/glibc-rh1810224-3.patch new file mode 100644 index 0000000..2293e42 --- /dev/null +++ b/SOURCES/glibc-rh1810224-3.patch @@ -0,0 +1,26 @@ +commit 6cf6a91d05d626698f158078961b3bffcb39ff8c +Author: Joseph Myers +Date: Wed Feb 12 13:37:16 2020 +0000 + + Rename RWF_WRITE_LIFE_NOT_SET to RWH_WRITE_LIFE_NOT_SET following Linux 5.5. + + Linux 5.5 renames RWF_WRITE_LIFE_NOT_SET to RWH_WRITE_LIFE_NOT_SET, + with the old name kept as an alias. This patch makes the + corresponding change in glibc. + + Tested for x86_64. + +diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +index 07a889d683..b06488a847 100644 +--- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h ++++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +@@ -290,7 +290,8 @@ struct f_owner_ex + + #ifdef __USE_GNU + /* Hint values for F_{GET,SET}_RW_HINT. */ +-# define RWF_WRITE_LIFE_NOT_SET 0 ++# define RWH_WRITE_LIFE_NOT_SET 0 ++# define RWF_WRITE_LIFE_NOT_SET RWH_WRITE_LIFE_NOT_SET + # define RWH_WRITE_LIFE_NONE 1 + # define RWH_WRITE_LIFE_SHORT 2 + # define RWH_WRITE_LIFE_MEDIUM 3 diff --git a/SOURCES/glibc-rh1810224-4.patch b/SOURCES/glibc-rh1810224-4.patch new file mode 100644 index 0000000..c1205a1 --- /dev/null +++ b/SOURCES/glibc-rh1810224-4.patch @@ -0,0 +1,54 @@ +commit e788beaf093bfafecd6b4456b984bd927c18987a +Author: Joseph Myers +Date: Fri Apr 3 18:07:55 2020 +0000 + + Update syscall lists for Linux 5.6. + + Linux 5.6 has new openat2 and pidfd_getfd syscalls. This patch adds + them to syscall-names.list and regenerates the arch-syscall.h files. + + Tested with build-many-glibcs.py. + +Modified to only update syscall-names.list for RHEL 8.3.0. +Also cleaned up typos in the comments. + +diff -Nrup a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +--- a/sysdeps/unix/sysv/linux/syscall-names.list 2020-04-06 12:27:10.519027866 -0400 ++++ b/sysdeps/unix/sysv/linux/syscall-names.list 2020-04-06 12:31:53.665812810 -0400 +@@ -16,14 +16,13 @@ + # License along with the GNU C Library; if not, see + # . + +-# This file contains the list of system call names names. It has to +-# remain in alphabetica order. Lines which start with # are treated +-# as comments. This file can list all potential system calls. The +-# names are only used if the installed kernel headers also provide +-# them. ++# This file contains the list of system call names. It has to remain in ++# alphabetical order. Lines which start with # are treated as comments. ++# This file can list all potential system calls. The names are only ++# used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.5. +-kernel 5.5 ++# The list of system calls is current as of Linux 5.6. ++kernel 5.6 + + FAST_atomic_update + FAST_cmpxchg +@@ -293,6 +292,7 @@ open + open_by_handle_at + open_tree + openat ++openat2 + osf_adjtime + osf_afs_syscall + osf_alt_plock +@@ -411,6 +411,7 @@ perf_event_open + perfctr + perfmonctl + personality ++pidfd_getfd + pidfd_open + pidfd_send_signal + pipe diff --git a/SOURCES/glibc-rh1811796-1.patch b/SOURCES/glibc-rh1811796-1.patch new file mode 100644 index 0000000..a7b711d --- /dev/null +++ b/SOURCES/glibc-rh1811796-1.patch @@ -0,0 +1,113 @@ +commit 9333498794cde1d5cca518badf79533a24114b6f +Author: Joseph Myers +Date: Wed Feb 12 23:31:56 2020 +0000 + + Avoid ldbl-96 stack corruption from range reduction of pseudo-zero (bug 25487). + + Bug 25487 reports stack corruption in ldbl-96 sinl on a pseudo-zero + argument (an representation where all the significand bits, including + the explicit high bit, are zero, but the exponent is not zero, which + is not a valid representation for the long double type). + + Although this is not a valid long double representation, existing + practice in this area (see bug 4586, originally marked invalid but + subsequently fixed) is that we still seek to avoid invalid memory + accesses as a result, in case of programs that treat arbitrary binary + data as long double representations, although the invalid + representations of the ldbl-96 format do not need to be consistently + handled the same as any particular valid representation. + + This patch makes the range reduction detect pseudo-zero and unnormal + representations that would otherwise go to __kernel_rem_pio2, and + returns a NaN for them instead of continuing with the range reduction + process. (Pseudo-zero and unnormal representations whose unbiased + exponent is less than -1 have already been safely returned from the + function before this point without going through the rest of range + reduction.) Pseudo-zero representations would previously result in + the value passed to __kernel_rem_pio2 being all-zero, which is + definitely unsafe; unnormal representations would previously result in + a value passed whose high bit is zero, which might well be unsafe + since that is not a form of input expected by __kernel_rem_pio2. + + Tested for x86_64. + +Revised for RHEL 8.3.0. + +diff -Nrup a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c +--- a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c 2020-04-03 13:05:02.609844427 -0400 +@@ -209,6 +209,18 @@ __ieee754_rem_pio2l (long double x, long + y[1] = y[0]; + return 0; + } ++ ++ if ((i0 & 0x80000000) == 0) ++ { ++ /* Pseudo-zero and unnormal representations are not valid ++ representations of long double. We need to avoid stack ++ corruption in __kernel_rem_pio2, which expects input in a ++ particular normal form, but those representations do not need ++ to be consistently handled like any particular floating-point ++ value. */ ++ y[1] = y[0] = __builtin_nanl (""); ++ return 0; ++ } + + /* Split the 64 bits of the mantissa into three 24-bit integers + stored in a double array. */ +diff -Nrup a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile +--- a/sysdeps/ieee754/ldbl-96/Makefile 2018-08-01 01:10:47.000000000 -0400 ++++ b/sysdeps/ieee754/ldbl-96/Makefile 2020-04-03 13:03:20.233546734 -0400 +@@ -17,5 +17,6 @@ + # . + + ifeq ($(subdir),math) +-tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 ++tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo ++CFLAGS-test-sinl-pseudo.c += -fstack-protector-all + endif +diff -Nrup a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c +--- a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c 2020-04-03 13:05:37.857952212 -0400 +@@ -0,0 +1,41 @@ ++/* Test sinl for pseudo-zeros and unnormals for ldbl-96 (bug 25487). ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++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 diff --git a/SOURCES/glibc-rh1811796-2.patch b/SOURCES/glibc-rh1811796-2.patch new file mode 100644 index 0000000..eae8269 --- /dev/null +++ b/SOURCES/glibc-rh1811796-2.patch @@ -0,0 +1,21 @@ +commit c10acd40262486dac597001aecc20ad9d3bd0e4a +Author: Florian Weimer +Date: Thu Feb 13 17:01:15 2020 +0100 + + math/test-sinl-pseudo: Use stack protector only if available + + This fixes commit 9333498794cde1d5cca518bad ("Avoid ldbl-96 stack + corruption from range reduction of pseudo-zero (bug 25487)."). + +diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile +index 318628aed6..6030adf7e7 100644 +--- a/sysdeps/ieee754/ldbl-96/Makefile ++++ b/sysdeps/ieee754/ldbl-96/Makefile +@@ -18,5 +18,7 @@ + + ifeq ($(subdir),math) + tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo ++ifeq ($(have-ssp),yes) + CFLAGS-test-sinl-pseudo.c += -fstack-protector-all + endif ++endif # $(subdir) == math diff --git a/SOURCES/glibc-rh1812756-1.patch b/SOURCES/glibc-rh1812756-1.patch new file mode 100644 index 0000000..7675c1c --- /dev/null +++ b/SOURCES/glibc-rh1812756-1.patch @@ -0,0 +1,517 @@ +commit eb447b7b4bd6177f876ba9420ad9e048c27bae91 +Author: David Kilroy +Date: Wed Feb 12 14:28:15 2020 -0300 + + elf: Allow dlopen of filter object to work [BZ #16272] + + There are two fixes that are needed to be able to dlopen filter + objects. First _dl_map_object_deps cannot assume that map will be at + the beginning of l_searchlist.r_list[], as filtees are inserted before + map. Secondly dl_open_worker needs to ensure that filtees get + relocated. + + In _dl_map_object_deps: + + * avoiding removing relocation dependencies of map by setting + l_reserved to 0 and otherwise processing the rest of the search + list. + + * ensure that map remains at the beginning of l_initfini - the list + of things that need initialisation (and destruction). Do this by + splitting the copy up. This may not be required, but matches the + initialization order without dlopen. + + Modify dl_open_worker to relocate the objects in new->l_inifini. + new->l_initfini is constructed in _dl_map_object_deps, and lists the + objects that need initialization and destruction. Originally the list + of objects in new->l_next are relocated. All of these objects should + also be included in new->l_initfini (both lists are populated with + dependencies in _dl_map_object_deps). We can't use new->l_prev to pick + up filtees, as during a recursive dlopen from an interposed malloc + call, l->prev can contain objects that are not ready for relocation. + + Add tests to verify that symbols resolve to the filtee implementation + when auxiliary and filter objects are used, both as a normal link and + when dlopen'd. + + Tested by running the testsuite on x86_64. + +# Conflicts: +# elf/Makefile + +diff --git a/elf/Makefile b/elf/Makefile +index a52d9b1f6a4364a7..b4b618ce62a9e6df 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -192,7 +192,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ + tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ + tst-sonamemove-link tst-sonamemove-dlopen tst-initfinilazyfail \ +- tst-dlopenfail tst-dlopenfail-2 ++ tst-dlopenfail tst-dlopenfail-2 \ ++ tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -302,7 +303,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ + tst-initlazyfailmod tst-finilazyfailmod \ + tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \ +- tst-dlopenfailmod3 ++ tst-dlopenfailmod3 \ ++ tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee + + ifeq (yes,$(have-mtls-dialect-gnu2)) + tests += tst-gnu2-tls1 +@@ -1626,3 +1628,15 @@ $(objpfx)tst-dlopen-nodelete-reloc-mod17.so: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod16.so + LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed ++ ++LDFLAGS-tst-filterobj-flt.so = -Wl,--filter=$(objpfx)tst-filterobj-filtee.so ++$(objpfx)tst-filterobj: $(objpfx)tst-filterobj-flt.so ++$(objpfx)tst-filterobj-dlopen: $(libdl) ++$(objpfx)tst-filterobj.out: $(objpfx)tst-filterobj-filtee.so ++$(objpfx)tst-filterobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so ++ ++LDFLAGS-tst-filterobj-aux.so = -Wl,--auxiliary=$(objpfx)tst-filterobj-filtee.so ++$(objpfx)tst-auxobj: $(objpfx)tst-filterobj-aux.so ++$(objpfx)tst-auxobj-dlopen: $(libdl) ++$(objpfx)tst-auxobj.out: $(objpfx)tst-filterobj-filtee.so ++$(objpfx)tst-auxobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so +diff --git a/elf/dl-deps.c b/elf/dl-deps.c +index 9d9b1ba7f244348a..50f053a1586efdc3 100644 +--- a/elf/dl-deps.c ++++ b/elf/dl-deps.c +@@ -485,14 +485,18 @@ _dl_map_object_deps (struct link_map *map, + + map->l_searchlist.r_list = &l_initfini[nlist + 1]; + map->l_searchlist.r_nlist = nlist; ++ unsigned int map_index = UINT_MAX; + + for (nlist = 0, runp = known; runp; runp = runp->next) + { + if (__builtin_expect (trace_mode, 0) && runp->map->l_faked) + /* This can happen when we trace the loading. */ + --map->l_searchlist.r_nlist; +- else ++ else { ++ if (runp->map == map) ++ map_index = nlist; + map->l_searchlist.r_list[nlist++] = runp->map; ++ } + + /* Now clear all the mark bits we set in the objects on the search list + to avoid duplicates, so the next call starts fresh. */ +@@ -550,13 +554,14 @@ Filters not supported with LD_TRACE_PRELINKING")); + } + + /* Maybe we can remove some relocation dependencies now. */ +- assert (map->l_searchlist.r_list[0] == map); + struct link_map_reldeps *l_reldeps = NULL; + if (map->l_reldeps != NULL) + { +- for (i = 1; i < nlist; ++i) ++ for (i = 0; i < nlist; ++i) + map->l_searchlist.r_list[i]->l_reserved = 1; + ++ /* Avoid removing relocation dependencies of the main binary. */ ++ map->l_reserved = 0; + struct link_map **list = &map->l_reldeps->list[0]; + for (i = 0; i < map->l_reldeps->act; ++i) + if (list[i]->l_reserved) +@@ -581,16 +586,30 @@ Filters not supported with LD_TRACE_PRELINKING")); + } + } + +- for (i = 1; i < nlist; ++i) ++ for (i = 0; i < nlist; ++i) + map->l_searchlist.r_list[i]->l_reserved = 0; + } + +- /* Sort the initializer list to take dependencies into account. The binary +- itself will always be initialize last. */ +- memcpy (l_initfini, map->l_searchlist.r_list, +- nlist * sizeof (struct link_map *)); +- /* We can skip looking for the binary itself which is at the front of +- the search list. */ ++ /* Sort the initializer list to take dependencies into account. Always ++ initialize the binary itself last. */ ++ assert (map_index < nlist); ++ if (map_index > 0) ++ { ++ /* Copy the binary into position 0. */ ++ l_initfini[0] = map->l_searchlist.r_list[map_index]; ++ ++ /* Copy the filtees. */ ++ for (i = 0; i < map_index; ++i) ++ l_initfini[i+1] = map->l_searchlist.r_list[i]; ++ ++ /* Copy the remainder. */ ++ for (i = map_index + 1; i < nlist; ++i) ++ l_initfini[i] = map->l_searchlist.r_list[i]; ++ } ++ else ++ memcpy (l_initfini, map->l_searchlist.r_list, ++ nlist * sizeof (struct link_map *)); ++ + _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false); + + /* Terminate the list of dependencies. */ +diff --git a/elf/dl-open.c b/elf/dl-open.c +index d834b89754d2b073..d31356f7e17dfb14 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -618,22 +618,25 @@ dl_open_worker (void *a) + allows IFUNC relocations to work and it also means copy + relocation of dependencies are if necessary overwritten. */ + unsigned int nmaps = 0; +- struct link_map *l = new; ++ unsigned int j = 0; ++ struct link_map *l = new->l_initfini[0]; + do + { + if (! l->l_real->l_relocated) + ++nmaps; +- l = l->l_next; ++ l = new->l_initfini[++j]; + } + while (l != NULL); ++ /* Stack allocation is limited by the number of loaded objects. */ + struct link_map *maps[nmaps]; + nmaps = 0; +- l = new; ++ j = 0; ++ l = new->l_initfini[0]; + do + { + if (! l->l_real->l_relocated) + maps[nmaps++] = l; +- l = l->l_next; ++ l = new->l_initfini[++j]; + } + while (l != NULL); + _dl_sort_maps (maps, nmaps, NULL, false); +diff --git a/elf/tst-auxobj-dlopen.c b/elf/tst-auxobj-dlopen.c +new file mode 100644 +index 0000000000000000..cb54aba19470a1fe +--- /dev/null ++++ b/elf/tst-auxobj-dlopen.c +@@ -0,0 +1,47 @@ ++/* Test for BZ#16272, dlopen'ing an auxiliary filter object. ++ Ensure that symbols from the resolve correctly. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++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 +diff --git a/elf/tst-auxobj.c b/elf/tst-auxobj.c +new file mode 100644 +index 0000000000000000..bdc7713b04b4a79b +--- /dev/null ++++ b/elf/tst-auxobj.c +@@ -0,0 +1,42 @@ ++/* Test that symbols from auxiliary filter objects are resolved to the ++ filtee. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#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 +diff --git a/elf/tst-filterobj-aux.c b/elf/tst-filterobj-aux.c +new file mode 100644 +index 0000000000000000..0b732f2fb3a69a7f +--- /dev/null ++++ b/elf/tst-filterobj-aux.c +@@ -0,0 +1,33 @@ ++/* Auxiliary filter object. ++ Contains symbols to be resolved in filtee, and one which doesn't. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-filterobj-filtee.h" ++ ++/* We never want to see the output of the auxiliary object. */ ++const char *get_text (void) ++{ ++ return "Hello from auxiliary filter object (FAIL)"; ++} ++ ++/* The filtee doesn't implement this symbol, so this should resolve. */ ++const char *get_text2 (void) ++{ ++ return "Hello from auxiliary filter object (PASS)"; ++} +diff --git a/elf/tst-filterobj-dlopen.c b/elf/tst-filterobj-dlopen.c +new file mode 100644 +index 0000000000000000..c5b5072979802b98 +--- /dev/null ++++ b/elf/tst-filterobj-dlopen.c +@@ -0,0 +1,39 @@ ++/* Test for BZ#16272, dlopen'ing a filter object. ++ Ensure that symbols from the filter object resolve to the filtee. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++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 +diff --git a/elf/tst-filterobj-filtee.c b/elf/tst-filterobj-filtee.c +new file mode 100644 +index 0000000000000000..8fa557cbd251f53c +--- /dev/null ++++ b/elf/tst-filterobj-filtee.c +@@ -0,0 +1,27 @@ ++/* Filtee for BZ#16272 test. ++ Contains desired symbol implementations. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-filterobj-filtee.h" ++ ++/* This is the real implementation that wants to be called */ ++const char *get_text (void) ++{ ++ return "Hello from filtee (PASS)"; ++} +diff --git a/elf/tst-filterobj-filtee.h b/elf/tst-filterobj-filtee.h +new file mode 100644 +index 0000000000000000..46aee28178b88a77 +--- /dev/null ++++ b/elf/tst-filterobj-filtee.h +@@ -0,0 +1,24 @@ ++/* Filtee header for BZ#16272 test. ++ Contains prototypes for symbols implemented in the filtee. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++const char *get_text (void); ++ ++/* For testing auxiliary filter object. */ ++const char *get_text2 (void); +diff --git a/elf/tst-filterobj-flt.c b/elf/tst-filterobj-flt.c +new file mode 100644 +index 0000000000000000..5062654be6f14a80 +--- /dev/null ++++ b/elf/tst-filterobj-flt.c +@@ -0,0 +1,27 @@ ++/* Filter object for BZ#16272 test. ++ Contains symbols to be resolved in filtee. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-filterobj-filtee.h" ++ ++/* We never want to see the output of the filter object */ ++const char *get_text (void) ++{ ++ return "Hello from filter object (FAIL)"; ++} +diff --git a/elf/tst-filterobj.c b/elf/tst-filterobj.c +new file mode 100644 +index 0000000000000000..96bfae019ea670bc +--- /dev/null ++++ b/elf/tst-filterobj.c +@@ -0,0 +1,36 @@ ++/* Test that symbols from filter objects are resolved to the filtee. ++ ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#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 diff --git a/SOURCES/glibc-rh1812756-2.patch b/SOURCES/glibc-rh1812756-2.patch new file mode 100644 index 0000000..e2df4e4 --- /dev/null +++ b/SOURCES/glibc-rh1812756-2.patch @@ -0,0 +1,37 @@ +commit 71bcfa62451dfaa015326d3524f2a0e2d09d80ed +Author: David Kilroy +Date: Wed Feb 12 14:30:31 2020 -0300 + + elf: avoid redundant sort in dlopen + + l_initfini is already sorted by dependency in _dl_map_object_deps(), + so avoid sorting again in dl_open_worker(). + + Tested by running the testsuite on x86_64. + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index d31356f7e17dfb14..980a28c836ca9a7a 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -614,9 +614,10 @@ dl_open_worker (void *a) + if (GLRO(dl_lazy)) + reloc_mode |= mode & RTLD_LAZY; + +- /* Sort the objects by dependency for the relocation process. This +- allows IFUNC relocations to work and it also means copy +- relocation of dependencies are if necessary overwritten. */ ++ /* Objects must be sorted by dependency for the relocation process. ++ This allows IFUNC relocations to work and it also means copy ++ relocation of dependencies are if necessary overwritten. ++ __dl_map_object_deps has already sorted l_initfini for us. */ + unsigned int nmaps = 0; + unsigned int j = 0; + struct link_map *l = new->l_initfini[0]; +@@ -639,7 +640,6 @@ dl_open_worker (void *a) + l = new->l_initfini[++j]; + } + while (l != NULL); +- _dl_sort_maps (maps, nmaps, NULL, false); + + int relocation_in_progress = 0; + diff --git a/SOURCES/glibc-rh1812756-3.patch b/SOURCES/glibc-rh1812756-3.patch new file mode 100644 index 0000000..93e54e2 --- /dev/null +++ b/SOURCES/glibc-rh1812756-3.patch @@ -0,0 +1,68 @@ +commit 0a8ce6a0966283b17f373f430929bcadef1ae205 +Author: David Kilroy +Date: Wed Feb 12 14:31:17 2020 -0300 + + elf: avoid stack allocation in dl_open_worker + + As the sort was removed, there's no need to keep a separate map of + links. Instead, when relocating objects iterate over l_initfini + directly. + + This allows us to remove the loop copying l_initfini elements into + map. We still need a loop to identify the first and last elements that + need relocation. + + Tested by running the testsuite on x86_64. + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 980a28c836ca9a7a..46a4c1e5a3f8d2dd 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -618,25 +618,18 @@ dl_open_worker (void *a) + This allows IFUNC relocations to work and it also means copy + relocation of dependencies are if necessary overwritten. + __dl_map_object_deps has already sorted l_initfini for us. */ +- unsigned int nmaps = 0; ++ unsigned int first = UINT_MAX; ++ unsigned int last = 0; + unsigned int j = 0; + struct link_map *l = new->l_initfini[0]; + do + { + if (! l->l_real->l_relocated) +- ++nmaps; +- l = new->l_initfini[++j]; +- } +- while (l != NULL); +- /* Stack allocation is limited by the number of loaded objects. */ +- struct link_map *maps[nmaps]; +- nmaps = 0; +- j = 0; +- l = new->l_initfini[0]; +- do +- { +- if (! l->l_real->l_relocated) +- maps[nmaps++] = l; ++ { ++ if (first == UINT_MAX) ++ first = j; ++ last = j + 1; ++ } + l = new->l_initfini[++j]; + } + while (l != NULL); +@@ -651,9 +644,12 @@ dl_open_worker (void *a) + them. However, such relocation dependencies in IFUNC resolvers + are undefined anyway, so this is not a problem. */ + +- for (unsigned int i = nmaps; i-- > 0; ) ++ for (unsigned int i = last; i-- > first; ) + { +- l = maps[i]; ++ l = new->l_initfini[i]; ++ ++ if (l->l_real->l_relocated) ++ continue; + + if (! relocation_in_progress) + { diff --git a/SOURCES/glibc-rh1813398.patch b/SOURCES/glibc-rh1813398.patch new file mode 100644 index 0000000..1355dfa --- /dev/null +++ b/SOURCES/glibc-rh1813398.patch @@ -0,0 +1,58 @@ +commit ddc650e9b3dc916eab417ce9f79e67337b05035c +Author: Andreas Schwab +Date: Wed Feb 19 17:21:46 2020 +0100 + + Fix use-after-free in glob when expanding ~user (bug 25414) + + The value of `end_name' points into the value of `dirname', thus don't + deallocate the latter before the last use of the former. + +diff --git a/posix/glob.c b/posix/glob.c +index cba9cd1819..4580cefb9f 100644 +--- a/posix/glob.c ++++ b/posix/glob.c +@@ -827,31 +827,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + { + size_t home_len = strlen (p->pw_dir); + size_t rest_len = end_name == NULL ? 0 : strlen (end_name); +- char *d; ++ char *d, *newp; ++ bool use_alloca = glob_use_alloca (alloca_used, ++ home_len + rest_len + 1); + +- if (__glibc_unlikely (malloc_dirname)) +- free (dirname); +- malloc_dirname = 0; +- +- if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) +- dirname = alloca_account (home_len + rest_len + 1, +- alloca_used); ++ if (use_alloca) ++ newp = alloca_account (home_len + rest_len + 1, alloca_used); + else + { +- dirname = malloc (home_len + rest_len + 1); +- if (dirname == NULL) ++ newp = malloc (home_len + rest_len + 1); ++ if (newp == NULL) + { + scratch_buffer_free (&pwtmpbuf); + retval = GLOB_NOSPACE; + goto out; + } +- malloc_dirname = 1; + } +- d = mempcpy (dirname, p->pw_dir, home_len); ++ d = mempcpy (newp, p->pw_dir, home_len); + if (end_name != NULL) + d = mempcpy (d, end_name, rest_len); + *d = '\0'; + ++ if (__glibc_unlikely (malloc_dirname)) ++ free (dirname); ++ dirname = newp; ++ malloc_dirname = !use_alloca; ++ + dirlen = home_len + rest_len; + dirname_modified = 1; + } diff --git a/SOURCES/glibc-rh1813399.patch b/SOURCES/glibc-rh1813399.patch new file mode 100644 index 0000000..16ef72d --- /dev/null +++ b/SOURCES/glibc-rh1813399.patch @@ -0,0 +1,59 @@ +commit d93769405996dfc11d216ddbe415946617b5a494 +Author: Andreas Schwab +Date: Mon Jan 20 17:01:50 2020 +0100 + + Fix array overflow in backtrace on PowerPC (bug 25423) + + When unwinding through a signal frame the backtrace function on PowerPC + didn't check array bounds when storing the frame address. Fixes commit + d400dcac5e ("PowerPC: fix backtrace to handle signal trampolines"). + +diff --git a/debug/tst-backtrace5.c b/debug/tst-backtrace5.c +index e7ce410845..b2f46160e7 100644 +--- a/debug/tst-backtrace5.c ++++ b/debug/tst-backtrace5.c +@@ -89,6 +89,18 @@ handle_signal (int signum) + } + /* Symbol names are not available for static functions, so we do not + check do_test. */ ++ ++ /* Check that backtrace does not return more than what fits in the array ++ (bug 25423). */ ++ for (int j = 0; j < NUM_FUNCTIONS; j++) ++ { ++ n = backtrace (addresses, j); ++ if (n > j) ++ { ++ FAIL (); ++ return; ++ } ++ } + } + + NO_INLINE int +diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c +index 7c2d4726f8..d1456c8ae4 100644 +--- a/sysdeps/powerpc/powerpc32/backtrace.c ++++ b/sysdeps/powerpc/powerpc32/backtrace.c +@@ -114,6 +114,8 @@ __backtrace (void **array, int size) + } + if (gregset) + { ++ if (count + 1 == size) ++ break; + array[++count] = (void*)((*gregset)[PT_NIP]); + current = (void*)((*gregset)[PT_R1]); + } +diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c +index 65c260ab76..8a53a1088f 100644 +--- a/sysdeps/powerpc/powerpc64/backtrace.c ++++ b/sysdeps/powerpc/powerpc64/backtrace.c +@@ -87,6 +87,8 @@ __backtrace (void **array, int size) + if (is_sigtramp_address (current->return_address)) + { + struct signal_frame_64 *sigframe = (struct signal_frame_64*) current; ++ if (count + 1 == size) ++ break; + array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP]; + current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1]; + } diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index d355d29..f9149e6 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.28 %define glibcversion 2.28 -%define glibcrelease 101%{?dist} +%define glibcrelease 121%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -396,6 +396,84 @@ Patch262: glibc-rh1410154-13.patch Patch263: glibc-rh1410154-14.patch Patch264: glibc-rh1410154-15.patch Patch265: glibc-rh1410154-16.patch +Patch266: glibc-rh1810142-1.patch +Patch267: glibc-rh1810142-2.patch +Patch268: glibc-rh1810142-3.patch +Patch269: glibc-rh1810142-4.patch +Patch270: glibc-rh1810142-5.patch +Patch271: glibc-rh1810142-6.patch +Patch272: glibc-rh1743445-1.patch +Patch273: glibc-rh1743445-2.patch +Patch274: glibc-rh1780204-01.patch +Patch275: glibc-rh1780204-02.patch +Patch276: glibc-rh1780204-03.patch +Patch277: glibc-rh1780204-04.patch +Patch278: glibc-rh1780204-05.patch +Patch279: glibc-rh1780204-06.patch +Patch280: glibc-rh1780204-07.patch +Patch281: glibc-rh1780204-08.patch +Patch282: glibc-rh1780204-09.patch +Patch283: glibc-rh1780204-10.patch +Patch284: glibc-rh1780204-11.patch +Patch285: glibc-rh1780204-12.patch +Patch286: glibc-rh1780204-13.patch +Patch287: glibc-rh1780204-14.patch +Patch288: glibc-rh1780204-15.patch +Patch289: glibc-rh1780204-16.patch +Patch290: glibc-rh1780204-17.patch +Patch291: glibc-rh1780204-18.patch +Patch292: glibc-rh1780204-19.patch +Patch293: glibc-rh1780204-20.patch +Patch294: glibc-rh1780204-21.patch +Patch295: glibc-rh1780204-22.patch +Patch296: glibc-rh1780204-23.patch +Patch297: glibc-rh1780204-24.patch +Patch298: glibc-rh1780204-25.patch +Patch299: glibc-rh1780204-26.patch +Patch300: glibc-rh1780204-27.patch +Patch301: glibc-rh1780204-28.patch +Patch302: glibc-rh1784519.patch +Patch303: glibc-rh1775819.patch +Patch304: glibc-rh1774114.patch +Patch305: glibc-rh1812756-1.patch +Patch306: glibc-rh1812756-2.patch +Patch307: glibc-rh1812756-3.patch +Patch308: glibc-rh1757354.patch +Patch309: glibc-rh1784520.patch +Patch310: glibc-rh1784525.patch +Patch311: glibc-rh1810146.patch +Patch312: glibc-rh1810223-1.patch +Patch313: glibc-rh1810223-2.patch +Patch314: glibc-rh1811796-1.patch +Patch315: glibc-rh1811796-2.patch +Patch316: glibc-rh1813398.patch +Patch317: glibc-rh1813399.patch +Patch318: glibc-rh1810224-1.patch +Patch319: glibc-rh1810224-2.patch +Patch320: glibc-rh1810224-3.patch +Patch321: glibc-rh1810224-4.patch +Patch322: glibc-rh1783303-1.patch +Patch323: glibc-rh1783303-2.patch +Patch324: glibc-rh1783303-3.patch +Patch325: glibc-rh1783303-4.patch +Patch326: glibc-rh1783303-5.patch +Patch327: glibc-rh1783303-6.patch +Patch328: glibc-rh1783303-7.patch +Patch329: glibc-rh1783303-8.patch +Patch330: glibc-rh1783303-9.patch +Patch331: glibc-rh1783303-10.patch +Patch332: glibc-rh1783303-11.patch +Patch333: glibc-rh1783303-12.patch +Patch334: glibc-rh1783303-13.patch +Patch335: glibc-rh1783303-14.patch +Patch336: glibc-rh1783303-15.patch +Patch337: glibc-rh1783303-16.patch +Patch338: glibc-rh1783303-17.patch +Patch339: glibc-rh1783303-18.patch +Patch340: glibc-rh1642150-1.patch +Patch341: glibc-rh1642150-2.patch +Patch342: glibc-rh1642150-3.patch +Patch343: glibc-rh1774115.patch ############################################################################## # Continued list of core "glibc" package information: @@ -412,6 +490,13 @@ Provides: bundled(gnulib) Requires(pre): basesystem +%ifarch %{ix86} +# Automatically install the 32-bit variant if the 64-bit variant has +# been installed. This covers the case when glibc.i686 is installed +# after nss_db.x86_64. (See below for the other ordering.) +Recommends: (nss_db(x86-32) if nss_db(x86-64)) +%endif + # This is for building auxiliary programs like memusage, nscd # For initial glibc bootstraps it can be commented out %if %{without bootstrap} @@ -803,6 +888,12 @@ performance with LDAP, and may help with DNS as well. %package -n nss_db Summary: Name Service Switch (NSS) module using hash-indexed files Requires: %{name}%{_isa} = %{version}-%{release} +%ifarch x86_64 +# Automatically install the 32-bit variant if the 64-bit variant has +# been installed. This covers the case when glibc.i686 is installed +# before nss_db.x86_64. (See above for the other ordering.) +Recommends: (nss_db(x86-32) if glibc(x86-32)) +%endif %description -n nss_db The nss_db Name Service Switch module uses hash-indexed files in /var/db @@ -2282,6 +2373,67 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Wed Apr 8 2020 Florian Weimer - 2.28-121 +- elf: Assign TLS modid later during dlopen (#1774115) + +* Wed Apr 8 2020 Florian Weimer - 2.28-120 +- x86-64: Automatically install nss_db.i686 for 32-bit environments (#1807824) + +* Tue Apr 7 2020 Florian Weimer - 2.28-119 +- ppc64le: Enable protection key support (#1642150) + +* Tue Apr 7 2020 Florian Weimer - 2.28-118 +- ppc64le: floating-point status and exception optimizations (#1783303) + +* Fri Apr 3 2020 Patsy Griffin - 2.28-117 +- Update to Linux 5.6 syscall-names.list. (#1810224) + +* Fri Apr 3 2020 Patsy Griffin - 2.28-116 +- CVE-2020-1751: Fix an array overflow in backtrace on PowerPC. (#1813399) + +* Fri Apr 3 2020 Patsy Griffin - 2.28-115 +- CVE:2020-1752: Fix a use after free in glob when expanding ~user. (#1813398) + +* Fri Apr 3 2020 Patsy Griffin - 2.28-114 +- CVE-2020-10029: Prevent stack corruption from crafted input in cosl, sinl, + sincosl, and tanl function. (#1811796) + +* Thu Apr 2 2020 Carlos O'Donell - 2.28-113 +- Improve elf/ and nptl/ testsuites (#1810223) + +* Thu Apr 2 2020 Carlos O'Donell - 2.28-112 +- Fix resource leak in getaddrinfo (#1810146) + +* Thu Apr 2 2020 Carlos O'Donell - 2.28-111 +- Protect locale archive against corruption (#1784525) + +* Thu Apr 2 2020 Carlos O'Donell - 2.28-110 +- Properly handle signed vs. unsigned values in mallopt (#1784520) + +* Thu Apr 2 2020 Carlos O'Donell - 2.28-109 +- Update and harmonize locale names with CLDR (#1757354) + +* Thu Apr 2 2020 Carlos O'Donell - 2.28-108 +- Fix filter and auxiliary filter implementation (#1812756) + +* Thu Apr 2 2020 Carlos O'Donell - 2.28-107 +- Handle .dynstr located in separate segment (#1774114) + +* Fri Mar 27 2020 Patsy Griffin - 2.28-106 +- Disable vtable validation for pre-2.1 interposed handles (#1775819) + +* Fri Mar 27 2020 Patsy Griffin - 2.28-105 +- Define __CORRECT_ISO_CPP_STRING_H_PROTO for Clang. (#1784519) + +* Wed Mar 25 2020 DJ Delorie - 2.28-104 +- Math library optimizations for IBM Z (#1780204) + +* Wed Mar 25 2020 DJ Delorie - 2.28-103 +- Filter "ignore" autofs mount entries in getmntent (#1743445) + +* Wed Mar 25 2020 DJ Delorie - 2.28-102 +- Fix /etc/resolv.conf reloading defects (#1810142) + * Thu Jan 16 2020 Florian Weimer - 2.28-101 - ld.so: Reset GL (dl_initfirst) pointer on dlopen failure (#1410154)