diff --git a/SOURCES/glibc-post_upgrade.patch b/SOURCES/glibc-post_upgrade.patch deleted file mode 100644 index a64adfc..0000000 --- a/SOURCES/glibc-post_upgrade.patch +++ /dev/null @@ -1,272 +0,0 @@ -Short description: RPM Post-upgrade cleanup program. -Author(s): Fedora glibc team -Origin: PATCH -Upstream status: not-needed - -A helper program is needed to clean up the system configuration -early during RPM package installation, so that other scriptlets -can run successfully. - -diff --git a/elf/Makefile b/elf/Makefile -index 2a432d8beebcd207..368dcae477fff2ae 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -117,6 +117,14 @@ others-extras = $(ldconfig-modules) - endif - endif - -+# This needs to be statically linked because it is executed at a time -+# when there might be incompatible shared objects on disk, and the -+# purpose of this program is to remove them (among other things). -+others-static += glibc_post_upgrade -+others += glibc_post_upgrade -+glibc_post_upgrade-modules := static-stubs -+CFLAGS-glibc_post_upgrade.c += -DGCONV_MODULES_DIR='"$(gconvdir)"' -+ - # To find xmalloc.c and xstrdup.c - vpath %.c ../locale/programs - -@@ -559,6 +567,8 @@ $(objpfx)sln: $(sln-modules:%=$(objpfx)%.o) - - $(objpfx)ldconfig: $(ldconfig-modules:%=$(objpfx)%.o) - -+$(objpfx)glibc_post_upgrade: $(glibc_post_upgrade-modules:%=$(objpfx)%.o) -+ - SYSCONF-FLAGS := -D'SYSCONFDIR="$(sysconfdir)"' - CFLAGS-ldconfig.c += $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \ - -D'SLIBDIR="$(slibdir)"' -diff --git a/elf/glibc_post_upgrade.c b/elf/glibc_post_upgrade.c -new file mode 100644 -index 0000000000000000..19b59f70e2308032 ---- /dev/null -+++ b/elf/glibc_post_upgrade.c -@@ -0,0 +1,229 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define LD_SO_CONF "/etc/ld.so.conf" -+#define ICONVCONFIG "/usr/sbin/iconvconfig" -+ -+#define verbose_exec(failcode, path...) \ -+ do \ -+ { \ -+ char *const arr[] = { path, NULL }; \ -+ vexec (failcode, arr); \ -+ } while (0) -+ -+__attribute__((noinline)) static void vexec (int failcode, char *const path[]); -+__attribute__((noinline)) static void says (const char *str); -+__attribute__((noinline)) static void sayn (long num); -+__attribute__((noinline)) static void message (char *const path[]); -+ -+int -+main (void) -+{ -+ char initpath[256]; -+ -+ char buffer[4096]; -+ struct pref { -+ const char *p; -+ int len; -+ } prefix[] = { { "libc-", 5 }, { "libm-", 5 }, -+ { "librt-", 6 }, { "libpthread-", 11 }, -+ { "librtkaio-", 10 }, { "libthread_db-", 13 } }; -+ int i, j, fd; -+ off_t base; -+ ssize_t ret; -+ -+ /* In order to support in-place upgrades, we must immediately remove -+ obsolete platform directories after installing a new glibc -+ version. RPM only deletes files removed by updates near the end -+ of the transaction. If we did not remove the obsolete platform -+ directories here, they would be preferred by the dynamic linker -+ during the execution of subsequent RPM scriptlets, likely -+ resulting in process startup failures. */ -+ const char *remove_dirs[] = -+ { -+#if defined (__i386__) -+ "/lib/i686", -+ "/lib/i686/nosegneg", -+#elif defined (__powerpc64__) && _CALL_ELF != 2 -+ "/lib64/power6", -+#endif -+ }; -+ for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j) -+ { -+ size_t rmlen = strlen (remove_dirs[j]); -+ fd = open (remove_dirs[j], O_RDONLY); -+ if (fd >= 0 -+ && (ret = getdirentries (fd, buffer, sizeof (buffer), &base)) -+ >= (ssize_t) offsetof (struct dirent, d_name)) -+ { -+ for (base = 0; base + offsetof (struct dirent, d_name) < ret; ) -+ { -+ struct dirent *d = (struct dirent *) (buffer + base); -+ -+ for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++) -+ if (! strncmp (d->d_name, prefix[i].p, prefix[i].len)) -+ { -+ char *p = d->d_name + prefix[i].len; -+ -+ while (*p == '.' || (*p >= '0' && *p <= '9')) p++; -+ if (p[0] == 's' && p[1] == 'o' && p[2] == '\0' -+ && p + 3 - d->d_name -+ < sizeof (initpath) - rmlen - 1) -+ { -+ memcpy (initpath, remove_dirs[j], rmlen); -+ initpath[rmlen] = '/'; -+ strcpy (initpath + rmlen + 1, d->d_name); -+ unlink (initpath); -+ break; -+ } -+ } -+ base += d->d_reclen; -+ } -+ close (fd); -+ } -+ } -+ -+ int ldsocfd = open (LD_SO_CONF, O_RDONLY); -+ struct stat ldsocst; -+ if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0) -+ { -+ char p[ldsocst.st_size + 1]; -+ if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size) -+ { -+ p[ldsocst.st_size] = '\0'; -+ if (strstr (p, "include ld.so.conf.d/*.conf") == NULL) -+ { -+ close (ldsocfd); -+ ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC); -+ if (ldsocfd >= 0) -+ { -+ size_t slen = strlen ("include ld.so.conf.d/*.conf\n"); -+ if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen) -+ != slen -+ || write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size) -+ _exit (109); -+ } -+ } -+ } -+ if (ldsocfd >= 0) -+ close (ldsocfd); -+ } -+ -+ /* If installing bi-arch glibc, rpm sometimes doesn't unpack all files -+ before running one of the lib's %post scriptlet. /sbin/ldconfig will -+ then be run by the other arch's %post. */ -+ if (! access ("/sbin/ldconfig", X_OK)) -+ verbose_exec (110, -+ (char *) "/sbin/ldconfig", -+ (char *) "/sbin/ldconfig"); -+ -+ if (! utimes (GCONV_MODULES_DIR "/gconv-modules.cache", NULL)) -+ { -+ const char *iconv_cache = GCONV_MODULES_DIR "/gconv-modules.cache"; -+ const char *iconv_dir = GCONV_MODULES_DIR; -+ verbose_exec (113, -+ (char *) ICONVCONFIG, -+ (char *) "/usr/sbin/iconvconfig", -+ (char *) "-o", -+ (char *) iconv_cache, -+ (char *) "--nostdlib", -+ (char *) iconv_dir); -+ } -+ -+ _exit(0); -+} -+ -+void -+vexec (int failcode, char *const path[]) -+{ -+ pid_t pid; -+ int status, save_errno; -+ int devnull = 0; -+ -+ if (failcode < 0) -+ { -+ devnull = 1; -+ failcode = -failcode; -+ } -+ pid = vfork (); -+ if (pid == 0) -+ { -+ int fd; -+ if (devnull && (fd = open ("/dev/null", O_WRONLY)) >= 0) -+ { -+ dup2 (fd, 1); -+ dup2 (fd, 2); -+ close (fd); -+ } -+ execv (path[0], path + 1); -+ save_errno = errno; -+ message (path); -+ says (" exec failed with errno "); -+ sayn (save_errno); -+ says ("\n"); -+ _exit (failcode); -+ } -+ else if (pid < 0) -+ { -+ save_errno = errno; -+ message (path); -+ says (" fork failed with errno "); -+ sayn (save_errno); -+ says ("\n"); -+ _exit (failcode + 1); -+ } -+ if (waitpid (0, &status, 0) != pid || !WIFEXITED (status)) -+ { -+ message (path); -+ says (" child terminated abnormally\n"); -+ _exit (failcode + 2); -+ } -+ if (WEXITSTATUS (status)) -+ { -+ message (path); -+ says (" child exited with exit code "); -+ sayn (WEXITSTATUS (status)); -+ says ("\n"); -+ _exit (WEXITSTATUS (status)); -+ } -+} -+ -+static void -+says (const char *str) -+{ -+ write (1, str, strlen (str)); -+} -+ -+static void -+sayn (long num) -+{ -+ char string[sizeof (long) * 3 + 1]; -+ char *p = string + sizeof (string) - 1; -+ -+ *p = '\0'; -+ if (num == 0) -+ *--p = '0'; -+ else -+ while (num) -+ { -+ *--p = '0' + num % 10; -+ num = num / 10; -+ } -+ -+ says (p); -+} -+ -+static void -+message (char *const path[]) -+{ -+ says ("/usr/sbin/glibc_post_upgrade: While trying to execute "); -+ says (path[0]); -+} diff --git a/SOURCES/glibc-rh1577438.patch b/SOURCES/glibc-rh1577438.patch new file mode 100644 index 0000000..aab01cc --- /dev/null +++ b/SOURCES/glibc-rh1577438.patch @@ -0,0 +1,24 @@ +Patch by Hanataka Shinya from +. Confirmed by TAMUKI +Shoichi's patch in +. + +The official announcement by the Japanese Prime Minister in + uses U+4EE4 U+548C +as well. + +diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP +index 1fd2fee44b2879d9..30190b624856cc53 100644 +--- a/localedata/locales/ja_JP ++++ b/localedata/locales/ja_JP +@@ -14946,7 +14946,9 @@ am_pm "";"" + + t_fmt_ampm "%p%I%M%S" + +-era "+:2:1990//01//01:+*::%EC%Ey";/ ++era "+:2:2020//01//01:+*::%EC%Ey";/ ++ "+:1:2019//05//01:2019//12//31::%EC";/ ++ "+:2:1990//01//01:2019//04//30::%EC%Ey";/ + "+:1:1989//01//08:1989//12//31::%EC";/ + "+:2:1927//01//01:1989//01//07::%EC%Ey";/ + "+:1:1926//12//25:1926//12//31::%EC";/ diff --git a/SOURCES/glibc-rh1623537.patch b/SOURCES/glibc-rh1623537.patch new file mode 100644 index 0000000..5165785 --- /dev/null +++ b/SOURCES/glibc-rh1623537.patch @@ -0,0 +1,61 @@ +commit b297581acb66f80b513996c1580158b0fb12d469 +Author: Tulio Magno Quites Machado Filho +Date: Mon Jan 14 17:54:44 2019 -0200 + + Add XFAIL_ROUNDING_IBM128_LIBGCC to more fma() tests + + Ignore 16 errors in math/test-ldouble-fma and 4 errors in + math/test-ildouble-fma when IBM 128-bit long double used. + These errors are caused by spurious overflows from libgcc. + + * math/libm-test-fma.inc (fma_test_data): Set + XFAIL_ROUNDING_IBM128_LIBGCC to more tests. + + Signed-off-by: Tulio Magno Quites Machado Filho + (cherry picked from commit ecdacd34a2ac3b6d5a529ff218b29261d9d98a7a) + +diff --git a/math/libm-test-fma.inc b/math/libm-test-fma.inc +index 5b29fb820194e055..a7ee40992420c1ab 100644 +--- a/math/libm-test-fma.inc ++++ b/math/libm-test-fma.inc +@@ -119,32 +119,32 @@ static const struct test_fff_f_data fma_test_data[] = + TEST_fff_f (fma, plus_infty, plus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, plus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, plus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + TEST_fff_f (fma, plus_infty, minus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, plus_infty, minus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + TEST_fff_f (fma, minus_infty, plus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, plus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + TEST_fff_f (fma, minus_infty, minus_infty, plus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, minus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fff_f (fma, minus_infty, minus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +- TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), ++ TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), ++ TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC), + + AUTO_TESTS_fff_f (fma), + }; diff --git a/SOURCES/glibc-rh1639343-1.patch b/SOURCES/glibc-rh1639343-1.patch new file mode 100644 index 0000000..51d2226 --- /dev/null +++ b/SOURCES/glibc-rh1639343-1.patch @@ -0,0 +1,35 @@ +commit f9b645b4b0a10c43753296ce3fa40053fa44606a +Author: Mike Frysinger +Date: Wed Apr 24 13:32:22 2019 +0200 + + memusagestat: use local glibc when linking [BZ #18465] + + The memusagestat is the only binary that has its own link line which + causes it to be linked against the existing installed C library. It + has been this way since it was originally committed in 1999, but I + don't see any reason as to why. Since we want all the programs we + build locally to be against the new copy of glibc, change the build + to be like all other programs. + +diff --git a/malloc/Makefile b/malloc/Makefile +index 388cf7e9ee3a2569..228a1279a5960d8c 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -131,6 +131,7 @@ ifneq ($(cross-compiling),yes) + # If the gd library is available we build the `memusagestat' program. + ifneq ($(LIBGD),no) + others: $(objpfx)memusage ++others += memusagestat + install-bin = memusagestat + install-bin-script += memusage + generated += memusagestat memusage +@@ -154,8 +155,7 @@ cpp-srcs-left := $(memusagestat-modules) + lib := memusagestat + include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) + +-$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o) +- $(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm ++LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm + + ifeq ($(run-built-tests),yes) + ifeq (yes,$(build-shared)) diff --git a/SOURCES/glibc-rh1639343-2.patch b/SOURCES/glibc-rh1639343-2.patch new file mode 100644 index 0000000..c5e4aa5 --- /dev/null +++ b/SOURCES/glibc-rh1639343-2.patch @@ -0,0 +1,90 @@ +commit 94a4e9e4f401ffe829a992820439977ead0a0ce7 +Author: Florian Weimer +Date: Thu Apr 25 10:41:43 2019 +0200 + + Extend BIND_NOW to installed programs with --enable-bind-now + + Commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix + --enable-bind-now [BZ #21015]") extended BIND_NOW to all installed + shared objects. This change also covers installed programs. + + Reviewed-by: Carlos O'Donell + +diff --git a/INSTALL b/INSTALL +index d6c8e899fbb47dac..d56e102ec9ed3281 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -169,10 +169,10 @@ if 'CFLAGS' is specified it must enable optimization. For example: + protection. + + '--enable-bind-now' +- Disable lazy binding for installed shared objects. This provides +- additional security hardening because it enables full RELRO and a +- read-only global offset table (GOT), at the cost of slightly +- increased program load times. ++ Disable lazy binding for installed shared objects and programs. ++ This provides additional security hardening because it enables full ++ RELRO and a read-only global offset table (GOT), at the cost of ++ slightly increased program load times. + + '--enable-pt_chown' + The file 'pt_chown' is a helper binary for 'grantpt' (*note +diff --git a/Makeconfig b/Makeconfig +index 8dc2fec9dc683416..742c0c0783a14bfa 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -398,6 +398,8 @@ endif + # test modules. + ifeq ($(bind-now),yes) + LDFLAGS-lib.so += -Wl,-z,now ++# Extra flags for dynamically linked non-test main programs. ++link-extra-flags += -Wl,-z,now + endif + + # Command to run after every final link (executable or shared object). +@@ -426,7 +428,7 @@ ifndef +link-pie + $(link-extra-libs) + +link-pie-after-libc = $(+postctorS) $(+postinit) + define +link-pie +-$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-pie-after-libc) ++$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-tests +@@ -454,7 +456,7 @@ ifndef +link-static + $(link-extra-libs-static) + +link-static-after-libc = $(+postctorT) $(+postinit) + define +link-static +-$(+link-static-before-libc) $(link-libc-static) $(+link-static-after-libc) ++$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc) + $(call after-link,$@) + endef + define +link-static-tests +@@ -485,7 +487,7 @@ else # not build-pie-default + $(link-extra-libs) + +link-after-libc = $(+postctor) $(+postinit) + define +link +-$(+link-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-after-libc) ++$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc) + $(call after-link,$@) + endef + define +link-tests +diff --git a/manual/install.texi b/manual/install.texi +index e757891dc2eebb2e..351d67c68b255f62 100644 +--- a/manual/install.texi ++++ b/manual/install.texi +@@ -199,10 +199,10 @@ number of routines called directly from assembler are excluded from this + protection. + + @item --enable-bind-now +-Disable lazy binding for installed shared objects. This provides +-additional security hardening because it enables full RELRO and a +-read-only global offset table (GOT), at the cost of slightly increased +-program load times. ++Disable lazy binding for installed shared objects and programs. This ++provides additional security hardening because it enables full RELRO ++and a read-only global offset table (GOT), at the cost of slightly ++increased program load times. + + @pindex pt_chown + @findex grantpt diff --git a/SOURCES/glibc-rh1639343-3.patch b/SOURCES/glibc-rh1639343-3.patch new file mode 100644 index 0000000..4e4e146 --- /dev/null +++ b/SOURCES/glibc-rh1639343-3.patch @@ -0,0 +1,43 @@ +commit b5ffdc48c20ae865b197b67e5a9068a528fbc198 +Author: Florian Weimer +Date: Thu Apr 25 10:41:52 2019 +0200 + + benchtests: Enable BIND_NOW if configured with --enable-bind-now + + Benchmarks should reflect distribution build policies, so it makes + sense to honor the BIND_NOW configuration for them. + + This commit keeps using $(+link-tests), so that the benchmarks are + linked according to the --enable-hardcoded-path-in-tests configure + option. + + Reviewed-by: Carlos O'Donell + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index bcd6a9c26d9a0005..28d6b0c43f5bd390 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -235,13 +235,21 @@ bench-func: $(binaries-bench) + scripts/benchout.schema.json; \ + fi + +-$(timing-type) $(binaries-bench) $(binaries-benchset) \ +- $(binaries-bench-malloc): %: %.o $(objpfx)json-lib.o \ ++ifeq ($(bind-now),yes) ++link-bench-bind-now = -Wl,-z,now ++endif ++ ++bench-link-targets = $(timing-type) $(binaries-bench) $(binaries-benchset) \ ++ $(binaries-bench-malloc) ++ ++$(bench-link-targets): %: %.o $(objpfx)json-lib.o \ + $(link-extra-libs-tests) \ + $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \ + $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) + $(+link-tests) + ++$(bench-link-targets): LDFLAGS += $(link-bench-bind-now) ++ + $(objpfx)bench-%.c: %-inputs $(bench-deps) + { if [ -n "$($*-INCLUDE)" ]; then \ + cat $($*-INCLUDE); \ diff --git a/SOURCES/glibc-rh1639343-4.patch b/SOURCES/glibc-rh1639343-4.patch new file mode 100644 index 0000000..10d4b48 --- /dev/null +++ b/SOURCES/glibc-rh1639343-4.patch @@ -0,0 +1,100 @@ +commit e30fb31c0ad8d31babd1d0d0f05e37c6579a870b +Author: Florian Weimer +Date: Fri Apr 26 07:16:47 2019 +0200 + + Makeconfig: Move $(CC) to +link command variables + + This change is needed to add linker flags which come very early in the + command linke (before LDFLAGS) and are not applied to test programs + (only to installed programs). + +diff --git a/Makeconfig b/Makeconfig +index 742c0c0783a14bfa..1ad25fc5a7251aea 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -415,7 +415,7 @@ link-extra-libs-tests = $(libsupport) + + # Command for linking PIE programs with the C library. + ifndef +link-pie +-+link-pie-before-libc = $(CC) $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ +++link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ + -Wl,-O1 -nostdlib -nostartfiles -o $@ \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ +@@ -428,23 +428,24 @@ ifndef +link-pie + $(link-extra-libs) + +link-pie-after-libc = $(+postctorS) $(+postinit) + define +link-pie +-$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc) ++$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \ ++ $(link-libc) $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-tests +-$(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ +- $(+link-pie-after-libc) ++$(CC) $(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ ++ $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-printers-tests +-$(+link-pie-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ +- $(+link-pie-after-libc) ++$(CC) $(+link-pie-before-libc) $(built-rtld-LDFLAGS) \ ++ $(link-libc-printers-tests) $(+link-pie-after-libc) + $(call after-link,$@) + endef + endif + # Command for statically linking programs with the C library. + ifndef +link-static +-+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \ +++link-static-before-libc = -nostdlib -nostartfiles -static -o $@ \ + $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \ +@@ -456,11 +457,13 @@ ifndef +link-static + $(link-extra-libs-static) + +link-static-after-libc = $(+postctorT) $(+postinit) + define +link-static +-$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc) ++$(CC) $(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) \ ++ $(+link-static-after-libc) + $(call after-link,$@) + endef + define +link-static-tests +-$(+link-static-before-libc) $(link-libc-static-tests) $(+link-static-after-libc) ++$(CC) $(+link-static-before-libc) $(link-libc-static-tests) \ ++ $(+link-static-after-libc) + $(call after-link,$@) + endef + endif +@@ -475,7 +478,7 @@ ifeq (yes,$(build-pie-default)) + +link-tests = $(+link-pie-tests) + +link-printers-tests = $(+link-pie-printers-tests) + else # not build-pie-default +-+link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \ +++link-before-libc = -nostdlib -nostartfiles -o $@ \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \ +@@ -487,16 +490,17 @@ else # not build-pie-default + $(link-extra-libs) + +link-after-libc = $(+postctor) $(+postinit) + define +link +-$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc) ++$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \ ++ $(+link-after-libc) + $(call after-link,$@) + endef + define +link-tests +-$(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ ++$(CC) $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ + $(+link-after-libc) + $(call after-link,$@) + endef + define +link-printers-tests +-$(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ ++$(CC) $(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ + $(+link-after-libc) + $(call after-link,$@) + endef diff --git a/SOURCES/glibc-rh1639343-5.patch b/SOURCES/glibc-rh1639343-5.patch new file mode 100644 index 0000000..cefd167 --- /dev/null +++ b/SOURCES/glibc-rh1639343-5.patch @@ -0,0 +1,74 @@ +commit a8ff215e56050a907189e713fd449bcafe99ff6b +Author: Florian Weimer +Date: Fri Apr 26 07:16:30 2019 +0200 + + Makeconfig: Move -Wl,-rpath-link options before library references + + Previously, the -Wl,-rpath-link options came after the libraries + injected using LDLIBS-* variables on the link editor command line for + main programs. As a result, it could happen that installed libraries + that reference glibc libraries used the installed glibc from the system + directories, instead of the glibc from the build tree. This can lead to + link failures if the wrong version of libpthread.so.0 is used, for + instance, due to differences in the internal GLIBC_PRIVATE interfaces, + as seen with memusagestat and -lgd after commit + f9b645b4b0a10c43753296ce3fa40053fa44606a ("memusagestat: use local glibc + when linking [BZ #18465]"). + + The isolation is necessarily imperfect because these installed + libraries are linked against the installed glibc in the system + directories. However, in most cases, the built glibc will be newer + than the installed glibc, and this link is permitted because of the + ABI backwards compatibility glibc provides. + +diff --git a/Makeconfig b/Makeconfig +index 1ad25fc5a7251aea..e315fb8a75ca5063 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -428,8 +428,8 @@ ifndef +link-pie + $(link-extra-libs) + +link-pie-after-libc = $(+postctorS) $(+postinit) + define +link-pie +-$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \ +- $(link-libc) $(+link-pie-after-libc) ++$(CC) $(link-libc-rpath-link) $(+link-pie-before-libc) $(rtld-LDFLAGS) \ ++ $(link-extra-flags) $(link-libc) $(+link-pie-after-libc) + $(call after-link,$@) + endef + define +link-pie-tests +@@ -490,8 +490,8 @@ else # not build-pie-default + $(link-extra-libs) + +link-after-libc = $(+postctor) $(+postinit) + define +link +-$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \ +- $(+link-after-libc) ++$(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \ ++ $(link-extra-flags) $(link-libc) $(+link-after-libc) + $(call after-link,$@) + endef + define +link-tests +@@ -552,6 +552,15 @@ ifeq (yes,$(build-shared)) + link-libc-rpath = -Wl,-rpath=$(rpath-link) + link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link) + ++# For programs which are not tests, $(link-libc-rpath-link) is added ++# directly in $(+link), $(+link-pie) above, so that -Wl,-rpath-link ++# comes before the expansion of LDLIBS-* and affects libraries added ++# there. For shared objects, -Wl,-rpath-link is added via ++# $(build-shlib-helper) and $(build-module-helper) in Makerules (also ++# before the expansion of LDLIBS-* variables). ++ ++# Tests use -Wl,-rpath instead of -Wl,-rpath-link for ++# build-hardcoded-path-in-tests. + ifeq (yes,$(build-hardcoded-path-in-tests)) + link-libc-tests-rpath-link = $(link-libc-rpath) + else +@@ -562,7 +571,7 @@ link-libc-before-gnulib = $(common-objpfx)libc.so$(libc.so-version) \ + $(common-objpfx)$(patsubst %,$(libtype.oS),c) \ + $(as-needed) $(elf-objpfx)ld.so \ + $(no-as-needed) +-link-libc = $(link-libc-rpath-link) $(link-libc-before-gnulib) $(gnulib) ++link-libc = $(link-libc-before-gnulib) $(gnulib) + + link-libc-tests-after-rpath-link = $(link-libc-before-gnulib) $(gnulib-tests) + link-libc-tests = $(link-libc-tests-rpath-link) \ diff --git a/SOURCES/glibc-rh1639343-6.patch b/SOURCES/glibc-rh1639343-6.patch new file mode 100644 index 0000000..643e192 --- /dev/null +++ b/SOURCES/glibc-rh1639343-6.patch @@ -0,0 +1,25 @@ +commit c57afec0a9b318bb691e0f5fa4e9681cf30df7a4 +Author: Florian Weimer +Date: Fri Apr 26 07:16:56 2019 +0200 + + elf: Link sotruss-lib.so with BIND_NOW for --enable-bind-now + + The audit module itself can be linked with BIND_NOW; it does not + affect its functionality. + + This should complete the leftovers from commit + 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix + --enable-bind-now [BZ #21015]"). + +diff --git a/elf/Makefile b/elf/Makefile +index f5285b99e22fe84d..9194339836900b9d 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -133,6 +133,7 @@ install-others += $(inst_auditdir)/sotruss-lib.so + install-bin-script += sotruss + generated += sotruss + libof-sotruss-lib = extramodules ++LDFLAGS-sotruss-lib.so += $(z-now-$(bind-now)) + $(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os + $(build-module-asneeded) + $(objpfx)sotruss-lib.so: $(common-objpfx)libc.so $(objpfx)ld.so \ diff --git a/SOURCES/glibc-rh1651283-1.patch b/SOURCES/glibc-rh1651283-1.patch new file mode 100644 index 0000000..cd7e903 --- /dev/null +++ b/SOURCES/glibc-rh1651283-1.patch @@ -0,0 +1,31 @@ +commit d6db68e66dff25d12c3bc5641b60cbd7fb6ab44f +Author: Moritz Eckert +Date: Thu Aug 16 21:08:36 2018 -0400 + + malloc: Mitigate null-byte overflow attacks + + * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size. + (malloc_consolidate): Likewise. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 13c52f376859562d..e450597e2e527fb7 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -4306,6 +4306,8 @@ _int_free (mstate av, mchunkptr p, int have_lock) + prevsize = prev_size (p); + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); ++ if (__glibc_unlikely (chunksize(p) != prevsize)) ++ malloc_printerr ("corrupted size vs. prev_size while consolidating"); + unlink(av, p, bck, fwd); + } + +@@ -4467,6 +4469,8 @@ static void malloc_consolidate(mstate av) + prevsize = prev_size (p); + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); ++ if (__glibc_unlikely (chunksize(p) != prevsize)) ++ malloc_printerr ("corrupted size vs. prev_size in fastbins"); + unlink(av, p, bck, fwd); + } + diff --git a/SOURCES/glibc-rh1651283-2.patch b/SOURCES/glibc-rh1651283-2.patch new file mode 100644 index 0000000..ad64396 --- /dev/null +++ b/SOURCES/glibc-rh1651283-2.patch @@ -0,0 +1,30 @@ +commit 30a17d8c95fbfb15c52d1115803b63aaa73a285c +Author: Pochang Chen +Date: Thu Aug 16 15:24:24 2018 -0400 + + malloc: Verify size of top chunk. + + The House of Force is a well-known technique to exploit heap + overflow. In essence, this exploit takes three steps: + 1. Overwrite the size of top chunk with very large value (e.g. -1). + 2. Request x bytes from top chunk. As the size of top chunk + is corrupted, x can be arbitrarily large and top chunk will + still be offset by x. + 3. The next allocation from top chunk will thus be controllable. + + If we verify the size of top chunk at step 2, we can stop such attack. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index e450597e2e527fb7..d8d4581a9dcea80a 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -4084,6 +4084,9 @@ _int_malloc (mstate av, size_t bytes) + victim = av->top; + size = chunksize (victim); + ++ if (__glibc_unlikely (size > av->system_mem)) ++ malloc_printerr ("malloc(): corrupted top size"); ++ + if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) + { + remainder_size = size - nb; diff --git a/SOURCES/glibc-rh1651283-3.patch b/SOURCES/glibc-rh1651283-3.patch new file mode 100644 index 0000000..65a07db --- /dev/null +++ b/SOURCES/glibc-rh1651283-3.patch @@ -0,0 +1,122 @@ +commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c +Author: Istvan Kurucsai +Date: Tue Jan 16 14:54:32 2018 +0100 + + malloc: Additional checks for unsorted bin integrity I. + + On Thu, Jan 11, 2018 at 3:50 PM, Florian Weimer wrote: + > On 11/07/2017 04:27 PM, Istvan Kurucsai wrote: + >> + >> + next = chunk_at_offset (victim, size); + > + > + > For new code, we prefer declarations with initializers. + + Noted. + + >> + if (__glibc_unlikely (chunksize_nomask (victim) <= 2 * SIZE_SZ) + >> + || __glibc_unlikely (chunksize_nomask (victim) > + >> av->system_mem)) + >> + malloc_printerr("malloc(): invalid size (unsorted)"); + >> + if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ) + >> + || __glibc_unlikely (chunksize_nomask (next) > + >> av->system_mem)) + >> + malloc_printerr("malloc(): invalid next size (unsorted)"); + >> + if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != + >> size)) + >> + malloc_printerr("malloc(): mismatching next->prev_size + >> (unsorted)"); + > + > + > I think this check is redundant because prev_size (next) and chunksize + > (victim) are loaded from the same memory location. + + I'm fairly certain that it compares mchunk_size of victim against + mchunk_prev_size of the next chunk, i.e. the size of victim in its + header and footer. + + >> + if (__glibc_unlikely (bck->fd != victim) + >> + || __glibc_unlikely (victim->fd != unsorted_chunks (av))) + >> + malloc_printerr("malloc(): unsorted double linked list + >> corrupted"); + >> + if (__glibc_unlikely (prev_inuse(next))) + >> + malloc_printerr("malloc(): invalid next->prev_inuse + >> (unsorted)"); + > + > + > There's a missing space after malloc_printerr. + + Noted. + + > Why do you keep using chunksize_nomask? We never investigated why the + > original code uses it. It may have been an accident. + + You are right, I don't think it makes a difference in these checks. So + the size local can be reused for the checks against victim. For next, + leaving it as such avoids the masking operation. + + > Again, for non-main arenas, the checks against av->system_mem could be made + > tighter (against the heap size). Maybe you could put the condition into a + > separate inline function? + + We could also do a chunk boundary check similar to what I proposed in + the thread for the first patch in the series to be even more strict. + I'll gladly try to implement either but believe that refining these + checks would bring less benefits than in the case of the top chunk. + Intra-arena or intra-heap overlaps would still be doable here with + unsorted chunks and I don't see any way to counter that besides more + generic measures like randomizing allocations and your metadata + encoding patches. + + I've attached a revised version with the above comments incorporated + but without the refined checks. + + Thanks, + Istvan + + From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001 + From: Istvan Kurucsai + Date: Tue, 16 Jan 2018 14:48:16 +0100 + Subject: [PATCH v2 1/1] malloc: Additional checks for unsorted bin integrity + I. + + Ensure the following properties of chunks encountered during binning: + - victim chunk has reasonable size + - next chunk has reasonable size + - next->prev_size == victim->size + - valid double linked list + - PREV_INUSE of next chunk is unset + + * malloc/malloc.c (_int_malloc): Additional binning code checks. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index d8d4581a9dcea80a..dad0e73735789530 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3724,11 +3724,22 @@ _int_malloc (mstate av, size_t bytes) + while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av)) + { + bck = victim->bk; +- if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0) +- || __builtin_expect (chunksize_nomask (victim) +- > av->system_mem, 0)) +- malloc_printerr ("malloc(): memory corruption"); + size = chunksize (victim); ++ mchunkptr next = chunk_at_offset (victim, size); ++ ++ if (__glibc_unlikely (size <= 2 * SIZE_SZ) ++ || __glibc_unlikely (size > av->system_mem)) ++ malloc_printerr ("malloc(): invalid size (unsorted)"); ++ if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ) ++ || __glibc_unlikely (chunksize_nomask (next) > av->system_mem)) ++ malloc_printerr ("malloc(): invalid next size (unsorted)"); ++ if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size)) ++ malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)"); ++ if (__glibc_unlikely (bck->fd != victim) ++ || __glibc_unlikely (victim->fd != unsorted_chunks (av))) ++ malloc_printerr ("malloc(): unsorted double linked list corrupted"); ++ if (__glibc_unlikely (prev_inuse(next))) ++ malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)"); + + /* + If a small request, try to use last remainder if it is the diff --git a/SOURCES/glibc-rh1651283-4.patch b/SOURCES/glibc-rh1651283-4.patch new file mode 100644 index 0000000..fcec8ee --- /dev/null +++ b/SOURCES/glibc-rh1651283-4.patch @@ -0,0 +1,26 @@ +The below commit contains only a whitespace change and was backported in +order to avoid future conflicts. + +commit 35cfefd96062145eeb8aee6bd72d07e0909a6b2e +Author: Florian Weimer +Date: Mon Aug 20 14:57:13 2018 +0200 + + malloc: Add ChangeLog for accidentally committed change + + Commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c ("malloc: Additional + checks for unsorted bin integrity I.") was committed without a + whitespace fix, so it is adjusted here as well. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index c07463001a65af90..eb6a8ff33c0c313b 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3745,7 +3745,7 @@ _int_malloc (mstate av, size_t bytes) + if (__glibc_unlikely (bck->fd != victim) + || __glibc_unlikely (victim->fd != unsorted_chunks (av))) + malloc_printerr ("malloc(): unsorted double linked list corrupted"); +- if (__glibc_unlikely (prev_inuse(next))) ++ if (__glibc_unlikely (prev_inuse (next))) + malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)"); + + /* diff --git a/SOURCES/glibc-rh1651283-5.patch b/SOURCES/glibc-rh1651283-5.patch new file mode 100644 index 0000000..e18b513 --- /dev/null +++ b/SOURCES/glibc-rh1651283-5.patch @@ -0,0 +1,38 @@ +commit ebe544bf6e8eec35e754fd49efb027c6f161b6cb +Author: Istvan Kurucsai +Date: Thu Dec 20 23:30:07 2018 -0500 + + malloc: Add more integrity checks to mremap_chunk. + + * malloc/malloc.c (mremap_chunk): Additional checks. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index eb6a8ff33c0c313b..4df5cb4862a7b854 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2856,16 +2856,22 @@ mremap_chunk (mchunkptr p, size_t new_size) + char *cp; + + assert (chunk_is_mmapped (p)); +- assert (((size + offset) & (GLRO (dl_pagesize) - 1)) == 0); ++ ++ uintptr_t block = (uintptr_t) p - offset; ++ uintptr_t mem = (uintptr_t) chunk2mem(p); ++ size_t total_size = offset + size; ++ if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0 ++ || __glibc_unlikely (!powerof2 (mem & (pagesize - 1)))) ++ malloc_printerr("mremap_chunk(): invalid pointer"); + + /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */ + new_size = ALIGN_UP (new_size + offset + SIZE_SZ, pagesize); + + /* No need to remap if the number of pages does not change. */ +- if (size + offset == new_size) ++ if (total_size == new_size) + return p; + +- cp = (char *) __mremap ((char *) p - offset, size + offset, new_size, ++ cp = (char *) __mremap ((char *) block, total_size, new_size, + MREMAP_MAYMOVE); + + if (cp == MAP_FAILED) diff --git a/SOURCES/glibc-rh1651283-6.patch b/SOURCES/glibc-rh1651283-6.patch new file mode 100644 index 0000000..c578d11 --- /dev/null +++ b/SOURCES/glibc-rh1651283-6.patch @@ -0,0 +1,38 @@ +commit c0e82f117357a941e4d40fcc08babbd6a3c3a1b5 +Author: Istvan Kurucsai +Date: Fri Dec 21 00:13:01 2018 -0500 + + malloc: Check the alignment of mmapped chunks before unmapping. + + * malloc/malloc.c (munmap_chunk): Verify chunk alignment. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 4df5cb4862a7b854..4412a4ffc83b013b 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2817,6 +2817,7 @@ systrim (size_t pad, mstate av) + static void + munmap_chunk (mchunkptr p) + { ++ size_t pagesize = GLRO (dl_pagesize); + INTERNAL_SIZE_T size = chunksize (p); + + assert (chunk_is_mmapped (p)); +@@ -2826,6 +2827,7 @@ munmap_chunk (mchunkptr p) + if (DUMPED_MAIN_ARENA_CHUNK (p)) + return; + ++ uintptr_t mem = (uintptr_t) chunk2mem (p); + uintptr_t block = (uintptr_t) p - prev_size (p); + size_t total_size = prev_size (p) + size; + /* Unfortunately we have to do the compilers job by hand here. Normally +@@ -2833,7 +2835,8 @@ munmap_chunk (mchunkptr p) + page size. But gcc does not recognize the optimization possibility + (in the moment at least) so we combine the two values into one before + the bit test. */ +- if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0)) ++ if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0 ++ || __glibc_unlikely (!powerof2 (mem & (pagesize - 1)))) + malloc_printerr ("munmap_chunk(): invalid pointer"); + + atomic_decrement (&mp_.n_mmaps); diff --git a/SOURCES/glibc-rh1651283-7.patch b/SOURCES/glibc-rh1651283-7.patch new file mode 100644 index 0000000..af0f92b --- /dev/null +++ b/SOURCES/glibc-rh1651283-7.patch @@ -0,0 +1,31 @@ +commit 5b06f538c5aee0389ed034f60d90a8884d6d54de +Author: Adam Maris +Date: Thu Mar 14 16:51:16 2019 -0400 + + malloc: Check for large bin list corruption when inserting unsorted chunk + + Fixes bug 24216. This patch adds security checks for bk and bk_nextsize pointers + of chunks in large bin when inserting chunk from unsorted bin. It was possible + to write the pointer to victim (newly inserted chunk) to arbitrary memory + locations if bk or bk_nextsize pointers of the next large bin chunk + got corrupted. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 4412a4ffc83b013b..723d393f529bdb4c 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3876,10 +3876,14 @@ _int_malloc (mstate av, size_t bytes) + { + victim->fd_nextsize = fwd; + victim->bk_nextsize = fwd->bk_nextsize; ++ if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd)) ++ malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)"); + fwd->bk_nextsize = victim; + victim->bk_nextsize->fd_nextsize = victim; + } + bck = fwd->bk; ++ if (bck->fd != fwd) ++ malloc_printerr ("malloc(): largebin double linked list corrupted (bk)"); + } + } + else diff --git a/SOURCES/glibc-rh1651742.patch b/SOURCES/glibc-rh1651742.patch new file mode 100644 index 0000000..1851691 --- /dev/null +++ b/SOURCES/glibc-rh1651742.patch @@ -0,0 +1,307 @@ +commit f0458cf4f9ff3d870c43b624e6dccaaf657d5e83 +Author: Adhemerval Zanella +Date: Mon Aug 27 09:42:50 2018 -0300 + + powerpc: Only enable TLE with PPC_FEATURE2_HTM_NOSC + + Linux from 3.9 through 4.2 does not abort HTM transaction on syscalls, + instead it suspend and resume it when leaving the kernel. The + side-effects of the syscall will always remain visible, even if the + transaction is aborted. This is an issue when transaction is used along + with futex syscall, on pthread_cond_wait for instance, where the futex + call might succeed but the transaction is rolled back leading the + pthread_cond object in an inconsistent state. + + Glibc used to prevent it by always aborting a transaction before issuing + a syscall. Linux 4.2 also decided to abort active transaction in + syscalls which makes the glibc workaround superfluous. Worse, glibc + transaction abortion leads to a performance issue on recent kernels + where the HTM state is saved/restore lazily (v4.9). By aborting a + transaction on every syscalls, regardless whether a transaction has being + initiated before, GLIBS makes the kernel always save/restore HTM state + (it can not even lazily disable it after a certain number of syscall + iterations). + + Because of this shortcoming, Transactional Lock Elision is just enabled + when it has been explicitly set (either by tunables of by a configure + switch) and if kernel aborts HTM transactions on syscalls + (PPC_FEATURE2_HTM_NOSC). It is reported that using simple benchmark [1], + the context-switch is about 5% faster by not issuing a tabort in every + syscall in newer kernels. + + Checked on powerpc64le-linux-gnu with 4.4.0 kernel (Ubuntu 16.04). + + * NEWS: Add note about new TLE support on powerpc64le. + * sysdeps/powerpc/nptl/tcb-offsets.sym (TM_CAPABLE): Remove. + * sysdeps/powerpc/nptl/tls.h (tcbhead_t): Rename tm_capable to + __ununsed1. + (TLS_INIT_TP, TLS_DEFINE_INIT_TP): Remove tm_capable setup. + (THREAD_GET_TM_CAPABLE, THREAD_SET_TM_CAPABLE): Remove macros. + * sysdeps/powerpc/powerpc32/sysdep.h, + sysdeps/powerpc/powerpc64/sysdep.h (ABORT_TRANSACTION_IMPL, + ABORT_TRANSACTION): Remove macros. + * sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise. + * sysdeps/unix/sysv/linux/powerpc/elision-conf.c (elision_init): Set + __pthread_force_elision iff PPC_FEATURE2_HTM_NOSC is set. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h, + sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h + sysdeps/unix/sysv/linux/powerpc/syscall.S (ABORT_TRANSACTION): Remove + usage. + * sysdeps/unix/sysv/linux/powerpc/not-errno.h: Remove file. + + Reported-by: Breno Leitão + +diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym +index e5bb2b3..4c01615 100644 +--- a/sysdeps/powerpc/nptl/tcb-offsets.sym ++++ b/sysdeps/powerpc/nptl/tcb-offsets.sym +@@ -21,7 +21,6 @@ DSO_SLOT2 (offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_ + #ifdef __powerpc64__ + TCB_AT_PLATFORM (offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) + #endif +-TM_CAPABLE (offsetof (tcbhead_t, tm_capable) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) + #ifndef __powerpc64__ + TCB_AT_PLATFORM (offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) + PADDING (offsetof (tcbhead_t, padding) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) +diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h +index f88fed5..8317ca7 100644 +--- a/sysdeps/powerpc/nptl/tls.h ++++ b/sysdeps/powerpc/nptl/tls.h +@@ -67,8 +67,7 @@ typedef struct + uint32_t padding; + uint32_t at_platform; + #endif +- /* Indicate if HTM capable (ISA 2.07). */ +- uint32_t tm_capable; ++ uint32_t __unused; + /* Reservation for AT_PLATFORM data - powerpc64. */ + #ifdef __powerpc64__ + uint32_t at_platform; +@@ -142,7 +141,6 @@ register void *__thread_register __asm__ ("r13"); + # define TLS_INIT_TP(tcbp) \ + ({ \ + __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET; \ +- THREAD_SET_TM_CAPABLE (__tcb_hwcap & PPC_FEATURE2_HAS_HTM ? 1 : 0); \ + THREAD_SET_HWCAP (__tcb_hwcap); \ + THREAD_SET_AT_PLATFORM (__tcb_platform); \ + NULL; \ +@@ -151,8 +149,6 @@ register void *__thread_register __asm__ ("r13"); + /* Value passed to 'clone' for initialization of the thread register. */ + # define TLS_DEFINE_INIT_TP(tp, pd) \ + void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE; \ +- (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) = \ +- THREAD_GET_TM_CAPABLE (); \ + (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].hwcap) = \ + THREAD_GET_HWCAP (); \ + (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].at_platform) = \ +@@ -210,13 +206,6 @@ register void *__thread_register __asm__ ("r13"); + + TLS_PRE_TCB_SIZE))[-1].pointer_guard \ + = THREAD_GET_POINTER_GUARD()) + +-/* tm_capable field in TCB head. */ +-# define THREAD_GET_TM_CAPABLE() \ +- (((tcbhead_t *) ((char *) __thread_register \ +- - TLS_TCB_OFFSET))[-1].tm_capable) +-# define THREAD_SET_TM_CAPABLE(value) \ +- (THREAD_GET_TM_CAPABLE () = (value)) +- + /* hwcap field in TCB head. */ + # define THREAD_GET_HWCAP() \ + (((tcbhead_t *) ((char *) __thread_register \ +diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h +index 5f1294e..93097c5 100644 +--- a/sysdeps/powerpc/powerpc32/sysdep.h ++++ b/sysdeps/powerpc/powerpc32/sysdep.h +@@ -90,24 +90,7 @@ GOT_LABEL: ; \ + cfi_endproc; \ + ASM_SIZE_DIRECTIVE(name) + +-#if !IS_IN(rtld) && !defined(__SPE__) +-# define ABORT_TRANSACTION_IMPL \ +- cmpwi 2,0; \ +- beq 1f; \ +- lwz 0,TM_CAPABLE(2); \ +- cmpwi 0,0; \ +- beq 1f; \ +- li 11,_ABORT_SYSCALL; \ +- tabort. 11; \ +- .align 4; \ +-1: +-#else +-# define ABORT_TRANSACTION_IMPL +-#endif +-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL +- + #define DO_CALL(syscall) \ +- ABORT_TRANSACTION \ + li 0,syscall; \ + sc + +diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h +index 2df1d9b..50e64f9 100644 +--- a/sysdeps/powerpc/powerpc64/sysdep.h ++++ b/sysdeps/powerpc/powerpc64/sysdep.h +@@ -263,24 +263,7 @@ LT_LABELSUFFIX(name,_name_end): ; \ + TRACEBACK_MASK(name,mask); \ + END_2(name) + +-#if !IS_IN(rtld) +-# define ABORT_TRANSACTION_IMPL \ +- cmpdi 13,0; \ +- beq 1f; \ +- lwz 0,TM_CAPABLE(13); \ +- cmpwi 0,0; \ +- beq 1f; \ +- li 11,_ABORT_SYSCALL; \ +- tabort. 11; \ +- .p2align 4; \ +-1: +-#else +-# define ABORT_TRANSACTION_IMPL +-#endif +-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL +- + #define DO_CALL(syscall) \ +- ABORT_TRANSACTION \ + li 0,syscall; \ + sc + +diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h +index 8a6d236..c8bf25e 100644 +--- a/sysdeps/powerpc/sysdep.h ++++ b/sysdeps/powerpc/sysdep.h +@@ -21,8 +21,6 @@ + */ + #define _SYSDEPS_SYSDEP_H 1 + #include +-#include +-#include + + #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) + +@@ -166,22 +164,4 @@ + #define ALIGNARG(log2) log2 + #define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +-#else +- +-/* Linux kernel powerpc documentation [1] states issuing a syscall inside a +- transaction is not recommended and may lead to undefined behavior. It +- also states syscalls do not abort transactions. To avoid such traps, +- we abort transaction just before syscalls. +- +- [1] Documentation/powerpc/transactional_memory.txt [Syscalls] */ +-#if !IS_IN(rtld) && !defined(__SPE__) +-# define ABORT_TRANSACTION \ +- ({ \ +- if (THREAD_GET_TM_CAPABLE ()) \ +- __libc_tabort (_ABORT_SYSCALL); \ +- }) +-#else +-# define ABORT_TRANSACTION +-#endif +- + #endif /* __ASSEMBLER__ */ +diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +index 906882a..fc82bd1 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c ++++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +@@ -127,6 +127,26 @@ elision_init (int argc __attribute__ ((unused)), + TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); + #endif + ++ /* Linux from 3.9 through 4.2 do not abort HTM transaction on syscalls, ++ instead it suspends the transaction and resumes it when returning to ++ usercode. The side-effects of the syscall will always remain visible, ++ even if the transaction is aborted. This is an issue when a transaction ++ is used along with futex syscall, on pthread_cond_wait for instance, ++ where futex might succeed but the transaction is rolled back leading ++ the condition variable object in an inconsistent state. ++ ++ Glibc used to prevent it by always aborting a transaction before issuing ++ a syscall. Linux 4.2 also decided to abort active transaction in ++ syscalls which makes the glibc workaround superflours. Worse, glibc ++ transaction abortions leads to a performance issues on recent kernels. ++ ++ So Lock Elision is just enabled when it has been explict set (either ++ by tunables of by a configure switch) and if kernel aborts HTM ++ transactions on syscalls (PPC_FEATURE2_HTM_NOSC) */ ++ ++ __pthread_force_elision = (__pthread_force_elision ++ && GLRO (dl_hwcap2) & PPC_FEATURE2_HTM_NOSC); ++ + if (!__pthread_force_elision) + __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */ + } +diff --git a/sysdeps/unix/sysv/linux/powerpc/not-errno.h b/sysdeps/unix/sysv/linux/powerpc/not-errno.h +deleted file mode 100644 +index 27da21b..0000000 +--- a/sysdeps/unix/sysv/linux/powerpc/not-errno.h ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* Syscall wrapper that do not set errno. Linux powerpc version. +- Copyright (C) 2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* __access_noerrno is used during process initialization in elf/dl-tunables.c +- before the TCB is initialized, prohibiting the usage of +- ABORT_TRANSACTION. */ +-#undef ABORT_TRANSACTION +-#define ABORT_TRANSACTION +- +-#include "sysdeps/unix/sysv/linux/not-errno.h" +- +-/* Recover ABORT_TRANSACTION's previous value, in order to not affect +- other syscalls. */ +-#undef ABORT_TRANSACTION +-#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +index f7277d5..ec5c525 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +@@ -109,7 +109,6 @@ + register long int r11 __asm__ ("r11"); \ + register long int r12 __asm__ ("r12"); \ + LOADARGS_##nr(name, args); \ +- ABORT_TRANSACTION; \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %0" \ +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +index 0956cf0..1f17f7b 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +@@ -131,7 +131,6 @@ + register long int r7 __asm__ ("r7"); \ + register long int r8 __asm__ ("r8"); \ + LOADARGS_##nr (name, ##args); \ +- ABORT_TRANSACTION; \ + __asm__ __volatile__ \ + ("sc\n\t" \ + "mfcr %0\n\t" \ +diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S +index 2da9172..bbab613 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S ++++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S +@@ -18,7 +18,6 @@ + #include + + ENTRY (syscall) +- ABORT_TRANSACTION + mr r0,r3 + mr r3,r4 + mr r4,r5 diff --git a/SOURCES/glibc-rh1658901.patch b/SOURCES/glibc-rh1658901.patch new file mode 100644 index 0000000..59d7cab --- /dev/null +++ b/SOURCES/glibc-rh1658901.patch @@ -0,0 +1,140 @@ +Upstream commit 1d880d4a9bf7608c2cd33bbe954ce6995f79121a + +From: Tulio Magno Quites Machado Filho +Date: Wed, 12 Dec 2018 12:41:52 +0000 (-0200) +Subject: powerpc: Add missing CFI register information (bug #23614) +X-Git-Tag: glibc-2.29~210 +X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=1d880d4a9bf7608c2cd33bbe954ce6995f79121a + +powerpc: Add missing CFI register information (bug #23614) + +Add CFI information about the offset of registers stored in the stack +frame. + + [BZ #23614] + * sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for + registers saved in the stack frame. + * sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise. + * sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise. + +Signed-off-by: Tulio Magno Quites Machado Filho +Reviewed-by: Gabriel F. T. Gomes +--- + +diff --git a/sysdeps/powerpc/powerpc64/addmul_1.S b/sysdeps/powerpc/powerpc64/addmul_1.S +index 48e3b1b..e450d6a 100644 +--- a/sysdeps/powerpc/powerpc64/addmul_1.S ++++ b/sysdeps/powerpc/powerpc64/addmul_1.S +@@ -34,16 +34,27 @@ + #define N r5 + #define VL r6 + ++#define R27SAVE (-40) ++#define R28SAVE (-32) ++#define R29SAVE (-24) ++#define R30SAVE (-16) ++#define R31SAVE (-8) ++ + ENTRY_TOCLESS (FUNC, 5) +- std r31, -8(r1) ++ std r31, R31SAVE(r1) + rldicl. r0, N, 0, 62 +- std r30, -16(r1) ++ std r30, R30SAVE(r1) + cmpdi VL, r0, 2 +- std r29, -24(r1) ++ std r29, R29SAVE(r1) + addi N, N, 3 +- std r28, -32(r1) ++ std r28, R28SAVE(r1) + srdi N, N, 2 +- std r27, -40(r1) ++ std r27, R27SAVE(r1) ++ cfi_offset(r31, R31SAVE) ++ cfi_offset(r30, R30SAVE) ++ cfi_offset(r29, R29SAVE) ++ cfi_offset(r28, R28SAVE) ++ cfi_offset(r27, R27SAVE) + mtctr N + beq cr0, L(b00) + blt cr6, L(b01) +@@ -199,10 +210,10 @@ L(end): mulld r0, r9, VL + addic r11, r11, 1 + #endif + addze RP, r8 +- ld r31, -8(r1) +- ld r30, -16(r1) +- ld r29, -24(r1) +- ld r28, -32(r1) +- ld r27, -40(r1) ++ ld r31, R31SAVE(r1) ++ ld r30, R30SAVE(r1) ++ ld r29, R29SAVE(r1) ++ ld r28, R28SAVE(r1) ++ ld r27, R27SAVE(r1) + blr + END(FUNC) +diff --git a/sysdeps/powerpc/powerpc64/lshift.S b/sysdeps/powerpc/powerpc64/lshift.S +index 8b6396e..855d6f2 100644 +--- a/sysdeps/powerpc/powerpc64/lshift.S ++++ b/sysdeps/powerpc/powerpc64/lshift.S +@@ -26,11 +26,15 @@ + #define TNC r0 + #define U0 r30 + #define U1 r31 ++#define U0SAVE (-16) ++#define U1SAVE (-8) + #define RETVAL r5 + + ENTRY_TOCLESS (__mpn_lshift, 5) +- std U1, -8(r1) +- std U0, -16(r1) ++ std U1, U1SAVE(r1) ++ std U0, U0SAVE(r1) ++ cfi_offset(U1, U1SAVE) ++ cfi_offset(U0, U0SAVE) + subfic TNC, CNT, 64 + sldi r7, N, RP + add UP, UP, r7 +@@ -170,8 +174,8 @@ L(cj3): or r10, r12, r7 + L(cj2): std r10, -32(RP) + std r8, -40(RP) + +-L(ret): ld U1, -8(r1) +- ld U0, -16(r1) ++L(ret): ld U1, U1SAVE(r1) ++ ld U0, U0SAVE(r1) + mr RP, RETVAL + blr + END(__mpn_lshift) +diff --git a/sysdeps/powerpc/powerpc64/mul_1.S b/sysdeps/powerpc/powerpc64/mul_1.S +index 953ded8..cade365 100644 +--- a/sysdeps/powerpc/powerpc64/mul_1.S ++++ b/sysdeps/powerpc/powerpc64/mul_1.S +@@ -24,9 +24,14 @@ + #define N r5 + #define VL r6 + ++#define R26SAVE (-48) ++#define R27SAVE (-40) ++ + ENTRY_TOCLESS (__mpn_mul_1, 5) +- std r27, -40(r1) +- std r26, -48(r1) ++ std r27, R27SAVE(r1) ++ std r26, R26SAVE(r1) ++ cfi_offset(r27, R27SAVE) ++ cfi_offset(r26, R26SAVE) + li r12, 0 + ld r26, 0(UP) + +@@ -129,7 +134,7 @@ L(end): mulld r0, r26, VL + std r0, 0(RP) + std r7, 8(RP) + L(ret): addze RP, r8 +- ld r27, -40(r1) +- ld r26, -48(r1) ++ ld r27, R27SAVE(r1) ++ ld r26, R26SAVE(r1) + blr + END(__mpn_mul_1) diff --git a/SOURCES/glibc-rh1659293-1.patch b/SOURCES/glibc-rh1659293-1.patch new file mode 100644 index 0000000..cf8ca21 --- /dev/null +++ b/SOURCES/glibc-rh1659293-1.patch @@ -0,0 +1,663 @@ +nptl: Fix pthread_rwlock_try*lock stalls (Bug 23844) + +For a full analysis of both the pthread_rwlock_tryrdlock() stall +and the pthread_rwlock_trywrlock() stall see: +https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14 + +In the pthread_rwlock_trydlock() function we fail to inspect for +PTHREAD_RWLOCK_FUTEX_USED in __wrphase_futex and wake the waiting +readers. + +In the pthread_rwlock_trywrlock() function we write 1 to +__wrphase_futex and loose the setting of the PTHREAD_RWLOCK_FUTEX_USED +bit, again failing to wake waiting readers during unlock. + +The fix in the case of pthread_rwlock_trydlock() is to check for +PTHREAD_RWLOCK_FUTEX_USED and wake the readers. + +The fix in the case of pthread_rwlock_trywrlock() is to only write +1 to __wrphase_futex if we installed the write phase, since all other +readers would be spinning waiting for this step. + +We add two new tests, one exercises the stall for +pthread_rwlock_trywrlock() which is easy to exercise, and one exercises +the stall for pthread_rwlock_trydlock() which is harder to exercise. + +The pthread_rwlock_trywrlock() test fails consistently without the fix, +and passes after. The pthread_rwlock_tryrdlock() test fails roughly +5-10% of the time without the fix, and passes all the time after. + +Signed-off-by: Carlos O'Donell +Signed-off-by: Torvald Riegel +Signed-off-by: Rik Prohaska +Co-authored-by: Torvald Riegel +Co-authored-by: Rik Prohaska +(cherry picked from commit 5fc9ed4c4058bfbdf51ad6e7aac7d209b580e8c4) + +diff --git a/ChangeLog b/ChangeLog +index 08b42bd2f56471e3..ed1a2ffe8356fd96 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,20 @@ ++2019-01-31 Carlos O'Donell ++ Torvald Riegel ++ Rik Prohaska ++ ++ [BZ# 23844] ++ * nptl/Makefile (tests): Add tst-rwlock-tryrdlock-stall, and ++ tst-rwlock-trywrlock-stall. ++ * nptl/pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock): ++ Wake waiters if PTHREAD_RWLOCK_FUTEX_USED is set. ++ * nptl/pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock): ++ Set __wrphase_fute to 1 only if we started the write phase. ++ * nptl/tst-rwlock-tryrdlock-stall.c: New file. ++ * nptl/tst-rwlock-trywrlock-stall.c: New file. ++ * support/Makefile (libsupport-routines): Add xpthread_rwlock_destroy. ++ * support/xpthread_rwlock_destroy.c: New file. ++ * support/xthread.h: Declare xpthread_rwlock_destroy. ++ + 2018-08-01 Carlos O'Donel + + * version.h (RELEASE): Set to "stable". +diff --git a/nptl/Makefile b/nptl/Makefile +index 2d2db648f730db61..b1003cf56b31ddfa 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -319,7 +319,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \ + tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \ +- tst-rwlock-pwn ++ tst-rwlock-pwn \ ++ tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall + + tests-internal := tst-rwlock19 tst-rwlock20 \ + tst-sem11 tst-sem12 tst-sem13 \ +diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c +index 4aec1fc15acb2448..31a88d33a6e8f256 100644 +--- a/nptl/pthread_rwlock_tryrdlock.c ++++ b/nptl/pthread_rwlock_tryrdlock.c +@@ -94,15 +94,22 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) + /* Same as in __pthread_rwlock_rdlock_full: + We started the read phase, so we are also responsible for + updating the write-phase futex. Relaxed MO is sufficient. +- Note that there can be no other reader that we have to wake +- because all other readers will see the read phase started by us +- (or they will try to start it themselves); if a writer started +- the read phase, we cannot have started it. Furthermore, we +- cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will +- overwrite the value set by the most recent writer (or the readers +- before it in case of explicit hand-over) and we know that there +- are no waiting readers. */ +- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0); ++ We have to do the same steps as a writer would when handing over the ++ read phase to use because other readers cannot distinguish between ++ us and the writer. ++ Note that __pthread_rwlock_tryrdlock callers will not have to be ++ woken up because they will either see the read phase started by us ++ or they will try to start it themselves; however, callers of ++ __pthread_rwlock_rdlock_full just increase the reader count and then ++ check what state the lock is in, so they cannot distinguish between ++ us and a writer that acquired and released the lock in the ++ meantime. */ ++ if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) ++ & PTHREAD_RWLOCK_FUTEX_USED) != 0) ++ { ++ int private = __pthread_rwlock_get_private (rwlock); ++ futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); ++ } + } + + return 0; +diff --git a/nptl/pthread_rwlock_trywrlock.c b/nptl/pthread_rwlock_trywrlock.c +index 5a73eba756077297..f2e3443466a2554f 100644 +--- a/nptl/pthread_rwlock_trywrlock.c ++++ b/nptl/pthread_rwlock_trywrlock.c +@@ -46,8 +46,15 @@ __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) + &rwlock->__data.__readers, &r, + r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED)) + { ++ /* We have become the primary writer and we cannot have shared ++ the PTHREAD_RWLOCK_FUTEX_USED flag with someone else, so we ++ can simply enable blocking (see full wrlock code). */ + atomic_store_relaxed (&rwlock->__data.__writers_futex, 1); +- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); ++ /* If we started a write phase, we need to enable readers to ++ wait. If we did not, we must not change it because other threads ++ may have set the PTHREAD_RWLOCK_FUTEX_USED in the meantime. */ ++ if ((r & PTHREAD_RWLOCK_WRPHASE) == 0) ++ atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); + atomic_store_relaxed (&rwlock->__data.__cur_writer, + THREAD_GETMEM (THREAD_SELF, tid)); + return 0; +diff --git a/nptl/tst-rwlock-tryrdlock-stall.c b/nptl/tst-rwlock-tryrdlock-stall.c +new file mode 100644 +index 0000000000000000..5e476da2b8d00c6a +--- /dev/null ++++ b/nptl/tst-rwlock-tryrdlock-stall.c +@@ -0,0 +1,355 @@ ++/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* For a full analysis see comment: ++ https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14 ++ ++ Provided here for reference: ++ ++ --- Analysis of pthread_rwlock_tryrdlock() stall --- ++ A read lock begins to execute. ++ ++ In __pthread_rwlock_rdlock_full: ++ ++ We can attempt a read lock, but find that the lock is ++ in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit ++ is set), and the lock is held by a primary writer ++ (PTHREAD_RWLOCK_WRLOCKED is set). In this case we must ++ wait for explicit hand over from the writer to us or ++ one of the other waiters. The read lock threads are ++ about to execute: ++ ++ 341 r = (atomic_fetch_add_acquire (&rwlock->__data.__readers, ++ 342 (1 << PTHREAD_RWLOCK_READER_SHIFT)) ++ 343 + (1 << PTHREAD_RWLOCK_READER_SHIFT)); ++ ++ An unlock beings to execute. ++ ++ Then in __pthread_rwlock_wrunlock: ++ ++ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); ++ ... ++ 549 while (!atomic_compare_exchange_weak_release ++ 550 (&rwlock->__data.__readers, &r, ++ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED) ++ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 ++ 553 : PTHREAD_RWLOCK_WRPHASE)))) ++ 554 { ++ ... ++ 556 } ++ ++ We clear PTHREAD_RWLOCK_WRLOCKED, and if there are ++ no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE. ++ ++ Back in the read lock. ++ ++ The read lock adjusts __readres as above. ++ ++ 383 while ((r & PTHREAD_RWLOCK_WRPHASE) != 0 ++ 384 && (r & PTHREAD_RWLOCK_WRLOCKED) == 0) ++ 385 { ++ ... ++ 390 if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r, ++ 391 r ^ PTHREAD_RWLOCK_WRPHASE)) ++ 392 { ++ ++ And then attemps to start the read phase. ++ ++ Assume there happens to be a tryrdlock at this point, noting ++ that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE ++ is 1. So the try lock attemps to start the read phase. ++ ++ In __pthread_rwlock_tryrdlock: ++ ++ 44 if ((r & PTHREAD_RWLOCK_WRPHASE) == 0) ++ 45 { ++ ... ++ 49 if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0) ++ 50 && (rwlock->__data.__flags ++ 51 == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) ++ 52 return EBUSY; ++ 53 rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT); ++ 54 } ++ ... ++ 89 while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, ++ 90 &r, rnew)); ++ ++ And succeeds. ++ ++ Back in the write unlock: ++ ++ 557 if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0) ++ 558 { ++ ... ++ 563 if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) ++ 564 & PTHREAD_RWLOCK_FUTEX_USED) != 0) ++ 565 futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); ++ 566 } ++ ++ We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero ++ and don't wake anyone. This is OK because we handed ++ over to the trylock. It will be the trylock's responsibility ++ to wake any waiters. ++ ++ Back in the read lock: ++ ++ The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because ++ the __readers value was adjusted by the trylock, and so it falls through ++ to waiting on the lock for explicit handover from either a new writer ++ or a new reader. ++ ++ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, ++ 449 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ 450 abstime, private); ++ ++ We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex ++ is in use. ++ ++ At this point we have readers waiting on the read lock ++ to unlock. The wrlock is done. The trylock is finishing ++ the installation of the read phase. ++ ++ 92 if ((r & PTHREAD_RWLOCK_WRPHASE) != 0) ++ 93 { ++ ... ++ 105 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0); ++ 106 } ++ ++ The trylock does note that we were the one that ++ installed the read phase, but the comments are not ++ correct, the execution ordering above shows that ++ readers might indeed be waiting, and they are. ++ ++ The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED, ++ and the waiting reader is never worken becuase as noted ++ above it is conditional on the futex being used. ++ ++ The solution is for the trylock thread to inspect ++ PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers. ++ ++ --- Analysis of pthread_rwlock_trywrlock() stall --- ++ ++ A write lock begins to execute, takes the write lock, ++ and then releases the lock... ++ ++ In pthread_rwlock_wrunlock(): ++ ++ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); ++ ... ++ 549 while (!atomic_compare_exchange_weak_release ++ 550 (&rwlock->__data.__readers, &r, ++ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED) ++ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 ++ 553 : PTHREAD_RWLOCK_WRPHASE)))) ++ 554 { ++ ... ++ 556 } ++ ++ ... leaving it in the write phase with zero readers ++ (the case where we leave the write phase in place ++ during a write unlock). ++ ++ A write trylock begins to execute. ++ ++ In __pthread_rwlock_trywrlock: ++ ++ 40 while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0) ++ 41 && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0) ++ 42 || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0)))) ++ 43 { ++ ++ The lock is not locked. ++ ++ There are no readers. ++ ++ 45 if (atomic_compare_exchange_weak_acquire ( ++ 46 &rwlock->__data.__readers, &r, ++ 47 r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED)) ++ ++ We atomically install the write phase and we take the ++ exclusive write lock. ++ ++ 48 { ++ 49 atomic_store_relaxed (&rwlock->__data.__writers_futex, 1); ++ ++ We get this far. ++ ++ A reader lock begins to execute. ++ ++ In pthread_rwlock_rdlock: ++ ++ 437 for (;;) ++ 438 { ++ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) ++ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ 441 { ++ 442 int private = __pthread_rwlock_get_private (rwlock); ++ 443 if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) ++ 444 && (!atomic_compare_exchange_weak_relaxed ++ 445 (&rwlock->__data.__wrphase_futex, ++ 446 &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))) ++ 447 continue; ++ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, ++ 449 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ 450 abstime, private); ++ ++ We are in a write phase, so the while() on line 439 is true. ++ ++ The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set ++ since this is the first reader to lock. ++ ++ The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED ++ on the expectation that this reader will be woken during ++ the handoff. ++ ++ Back in pthread_rwlock_trywrlock: ++ ++ 50 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); ++ 51 atomic_store_relaxed (&rwlock->__data.__cur_writer, ++ 52 THREAD_GETMEM (THREAD_SELF, tid)); ++ 53 return 0; ++ 54 } ++ ... ++ 57 } ++ ++ We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED, ++ and so in the unlock we will not awaken the waiting reader. ++ ++ The solution to this is to realize that if we did not start the write ++ phase we need not write 1 or any other value to __wrphase_futex. ++ This ensures that any readers (which saw __wrphase_futex != 0) can ++ set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to ++ wake them. ++ ++ If we installed the write phase then all other readers are looping ++ here: ++ ++ In __pthread_rwlock_rdlock_full: ++ ++ 437 for (;;) ++ 438 { ++ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) ++ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ 441 { ++ ... ++ 508 } ++ ++ waiting for the write phase to be installed or removed before they ++ can begin waiting on __wrphase_futex (part of the algorithm), or ++ taking a concurrent read lock, and thus we can safely write 1 to ++ __wrphase_futex. ++ ++ If we did not install the write phase then the readers may already ++ be waiting on the futex, the original writer wrote 1 to __wrphase_futex ++ as part of starting the write phase, and we cannot also write 1 ++ without loosing the PTHREAD_RWLOCK_FUTEX_USED bit. ++ ++ --- ++ ++ Summary for the pthread_rwlock_tryrdlock() stall: ++ ++ The stall is caused by pthread_rwlock_tryrdlock failing to check ++ that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex ++ and then waking the futex. ++ ++ The fix for bug 23844 ensures that waiters on __wrphase_futex are ++ correctly woken. Before the fix the test stalls as readers can ++ wait forever on __wrphase_futex. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* We need only one lock to reproduce the issue. We will need multiple ++ threads to get the exact case where we have a read, try, and unlock ++ all interleaving to produce the case where the readers are waiting ++ and the try fails to wake them. */ ++pthread_rwlock_t onelock; ++ ++/* The number of threads is arbitrary but empirically chosen to have ++ enough threads that we see the condition where waiting readers are ++ not woken by a successful tryrdlock. */ ++#define NTHREADS 32 ++ ++_Atomic int do_exit; ++ ++void * ++run_loop (void *arg) ++{ ++ int i = 0, ret; ++ while (!do_exit) ++ { ++ /* Arbitrarily choose if we are the writer or reader. Choose a ++ high enough ratio of readers to writers to make it likely ++ that readers block (and eventually are susceptable to ++ stalling). ++ ++ If we are a writer, take the write lock, and then unlock. ++ If we are a reader, try the lock, then lock, then unlock. */ ++ if ((i % 8) != 0) ++ xpthread_rwlock_wrlock (&onelock); ++ else ++ { ++ if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0) ++ { ++ if (ret == EBUSY) ++ xpthread_rwlock_rdlock (&onelock); ++ else ++ exit (EXIT_FAILURE); ++ } ++ } ++ /* Thread does some work and then unlocks. */ ++ xpthread_rwlock_unlock (&onelock); ++ i++; ++ } ++ return NULL; ++} ++ ++int ++do_test (void) ++{ ++ int i; ++ pthread_t tids[NTHREADS]; ++ xpthread_rwlock_init (&onelock, NULL); ++ for (i = 0; i < NTHREADS; i++) ++ tids[i] = xpthread_create (NULL, run_loop, NULL); ++ /* Run for some amount of time. Empirically speaking exercising ++ the stall via pthread_rwlock_tryrdlock is much harder, and on ++ a 3.5GHz 4 core x86_64 VM system it takes somewhere around ++ 20-200s to stall, approaching 100% stall past 200s. We can't ++ wait that long for a regression test so we just test for 20s, ++ and expect the stall to happen with a 5-10% chance (enough for ++ developers to see). */ ++ sleep (20); ++ /* Then exit. */ ++ printf ("INFO: Exiting...\n"); ++ do_exit = 1; ++ /* If any readers stalled then we will timeout waiting for them. */ ++ for (i = 0; i < NTHREADS; i++) ++ xpthread_join (tids[i]); ++ printf ("INFO: Done.\n"); ++ xpthread_rwlock_destroy (&onelock); ++ printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n"); ++ return 0; ++} ++ ++#define TIMEOUT 30 ++#include +diff --git a/nptl/tst-rwlock-trywrlock-stall.c b/nptl/tst-rwlock-trywrlock-stall.c +new file mode 100644 +index 0000000000000000..14d27cbcbc882cb1 +--- /dev/null ++++ b/nptl/tst-rwlock-trywrlock-stall.c +@@ -0,0 +1,108 @@ ++/* Bug 23844: Test for pthread_rwlock_trywrlock stalls. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c. ++ ++ Summary for the pthread_rwlock_trywrlock() stall: ++ ++ The stall is caused by pthread_rwlock_trywrlock setting ++ __wrphase_futex futex to 1 and loosing the ++ PTHREAD_RWLOCK_FUTEX_USED bit. ++ ++ The fix for bug 23844 ensures that waiters on __wrphase_futex are ++ correctly woken. Before the fix the test stalls as readers can ++ wait forever on __wrphase_futex. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* We need only one lock to reproduce the issue. We will need multiple ++ threads to get the exact case where we have a read, try, and unlock ++ all interleaving to produce the case where the readers are waiting ++ and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a ++ subsequent unlock fails to wake them. */ ++pthread_rwlock_t onelock; ++ ++/* The number of threads is arbitrary but empirically chosen to have ++ enough threads that we see the condition where waiting readers are ++ not woken by a successful unlock. */ ++#define NTHREADS 32 ++ ++_Atomic int do_exit; ++ ++void * ++run_loop (void *arg) ++{ ++ int i = 0, ret; ++ while (!do_exit) ++ { ++ /* Arbitrarily choose if we are the writer or reader. Choose a ++ high enough ratio of readers to writers to make it likely ++ that readers block (and eventually are susceptable to ++ stalling). ++ ++ If we are a writer, take the write lock, and then unlock. ++ If we are a reader, try the lock, then lock, then unlock. */ ++ if ((i % 8) != 0) ++ { ++ if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0) ++ { ++ if (ret == EBUSY) ++ xpthread_rwlock_wrlock (&onelock); ++ else ++ exit (EXIT_FAILURE); ++ } ++ } ++ else ++ xpthread_rwlock_rdlock (&onelock); ++ /* Thread does some work and then unlocks. */ ++ xpthread_rwlock_unlock (&onelock); ++ i++; ++ } ++ return NULL; ++} ++ ++int ++do_test (void) ++{ ++ int i; ++ pthread_t tids[NTHREADS]; ++ xpthread_rwlock_init (&onelock, NULL); ++ for (i = 0; i < NTHREADS; i++) ++ tids[i] = xpthread_create (NULL, run_loop, NULL); ++ /* Run for some amount of time. The pthread_rwlock_tryrwlock stall ++ is very easy to trigger and happens in seconds under the test ++ conditions. */ ++ sleep (10); ++ /* Then exit. */ ++ printf ("INFO: Exiting...\n"); ++ do_exit = 1; ++ /* If any readers stalled then we will timeout waiting for them. */ ++ for (i = 0; i < NTHREADS; i++) ++ xpthread_join (tids[i]); ++ printf ("INFO: Done.\n"); ++ xpthread_rwlock_destroy (&onelock); ++ printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n"); ++ return 0; ++} ++ ++#include +diff --git a/support/Makefile b/support/Makefile +index 93a514301654132e..41da4abaaa5a645a 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -129,6 +129,7 @@ libsupport-routines = \ + xpthread_mutexattr_settype \ + xpthread_once \ + xpthread_rwlock_init \ ++ xpthread_rwlock_destroy \ + xpthread_rwlock_rdlock \ + xpthread_rwlock_unlock \ + xpthread_rwlock_wrlock \ +diff --git a/support/xpthread_rwlock_destroy.c b/support/xpthread_rwlock_destroy.c +new file mode 100644 +index 0000000000000000..6d6e95356963b47f +--- /dev/null ++++ b/support/xpthread_rwlock_destroy.c +@@ -0,0 +1,26 @@ ++/* pthread_rwlock_destroy with error checking. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_rwlock_destroy (pthread_rwlock_t *rwlock) ++{ ++ xpthread_check_return ("pthread_rwlock_destroy", ++ pthread_rwlock_destroy (rwlock)); ++} +diff --git a/support/xthread.h b/support/xthread.h +index 623f5ad0acb895ef..1af77280871464c2 100644 +--- a/support/xthread.h ++++ b/support/xthread.h +@@ -84,6 +84,7 @@ void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref); + void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock); + void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock); + void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock); ++void xpthread_rwlock_destroy (pthread_rwlock_t *rwlock); + + __END_DECLS + diff --git a/SOURCES/glibc-rh1659293-2.patch b/SOURCES/glibc-rh1659293-2.patch new file mode 100644 index 0000000..eca43d2 --- /dev/null +++ b/SOURCES/glibc-rh1659293-2.patch @@ -0,0 +1,61 @@ +nptl/tst-rwlock14: Test pthread_rwlock_timedwrlock correctly + +(cherry picked from commit 82849fde3b8cb9b9396fa8cadf842dc2b1d2cced) + +diff --git a/ChangeLog b/ChangeLog +index ed1a2ffe8356fd96..74e634670c62d5c2 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2019-03-25 Mike Crowe ++ ++ * nptl/tst-rwlock14.c (do_test): Replace duplicate calls to ++ pthread_rwlock_timedrdlock with calls to ++ pthread_rwlock_timedwrlock to ensure that the latter is tested ++ too. Use new function name in diagnostic messages too. ++ + 2019-01-31 Carlos O'Donell + Torvald Riegel + Rik Prohaska +diff --git a/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c +index d6fda87c61e9aed4..073e6c98d2f5cc12 100644 +--- a/nptl/tst-rwlock14.c ++++ b/nptl/tst-rwlock14.c +@@ -117,15 +117,15 @@ do_test (void) + result = 1; + } + +- e = pthread_rwlock_timedrdlock (&r, &ts); ++ e = pthread_rwlock_timedwrlock (&r, &ts); + if (e == 0) + { +- puts ("second rwlock_timedrdlock did not fail"); ++ puts ("second rwlock_timedwrlock did not fail"); + result = 1; + } + else if (e != EINVAL) + { +- puts ("second rwlock_timedrdlock did not return EINVAL"); ++ puts ("second rwlock_timedwrlock did not return EINVAL"); + result = 1; + } + +@@ -145,15 +145,15 @@ do_test (void) + result = 1; + } + +- e = pthread_rwlock_timedrdlock (&r, &ts); ++ e = pthread_rwlock_timedwrlock (&r, &ts); + if (e == 0) + { +- puts ("third rwlock_timedrdlock did not fail"); ++ puts ("third rwlock_timedwrlock did not fail"); + result = 1; + } + else if (e != EINVAL) + { +- puts ("third rwlock_timedrdlock did not return EINVAL"); ++ puts ("third rwlock_timedwrlock did not return EINVAL"); + result = 1; + } + diff --git a/SOURCES/glibc-rh1659438-1.patch b/SOURCES/glibc-rh1659438-1.patch new file mode 100644 index 0000000..6e22946 --- /dev/null +++ b/SOURCES/glibc-rh1659438-1.patch @@ -0,0 +1,118 @@ +commit b8686c0d7098168481a246f8199ab2d865f52d3d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:03 2018 +0100 + + S390: Add configure check to detect z10 as mininum architecture level set. + + Add a configure check for z10 in the same way as done for z196. + + ChangeLog: + + * config.h.in (HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT): New undefine. + * sysdeps/s390/configure.ac: Add check for z10 support. + * sysdeps/s390/configure: Regenerated. + +diff --git a/config.h.in b/config.h.in +index 141db213a9046eb4..beecc39d5b8c3f4a 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -62,6 +62,9 @@ + /* Define if assembler supports AVX512DQ. */ + #undef HAVE_AVX512DQ_ASM_SUPPORT + ++/* Define if assembler supports z10 zarch instructions as default on S390. */ ++#undef HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++ + /* Define if assembler supports z196 zarch instructions as default on S390. */ + #undef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index 74b415f2ab0fa982..f30f8644361f474a 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -112,6 +112,45 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z10 zarch instruction support as default" >&5 ++$as_echo_n "checking for S390 z10 zarch instruction support as default... " >&6; } ++if ${libc_cv_asm_s390_min_z10_zarch+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testinsn (void *a, void *b, int n) ++{ ++ __asm__ ("exrl %2,1f \n\t" ++ "j 2f \n\t" ++ "1: mvc 0(1,%0),0(%1) \n\t" ++ "2:" ++ : : "a" (a), "a" (b), "d" (n) ++ : "memory", "cc"); ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_min_z10_zarch=yes ++else ++ libc_cv_asm_s390_min_z10_zarch=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z10_zarch" >&5 ++$as_echo "$libc_cv_asm_s390_min_z10_zarch" >&6; } ++ ++if test "$libc_cv_asm_s390_min_z10_zarch" = yes ; ++then ++ $as_echo "#define HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z196 zarch instruction support as default" >&5 + $as_echo_n "checking for S390 z196 zarch instruction support as default... " >&6; } + if ${libc_cv_asm_s390_min_z196_zarch+:} false; then : +diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac +index 1cdb0212825a3f18..981f7a79dd7066fc 100644 +--- a/sysdeps/s390/configure.ac ++++ b/sysdeps/s390/configure.ac +@@ -80,6 +80,35 @@ then + AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 z10 zarch instruction support as default, ++ libc_cv_asm_s390_min_z10_zarch, [dnl ++cat > conftest.c <<\EOF ++void testinsn (void *a, void *b, int n) ++{ ++ __asm__ ("exrl %2,1f \n\t" ++ "j 2f \n\t" ++ "1: mvc 0(1,%0),0(%1) \n\t" ++ "2:" ++ : : "a" (a), "a" (b), "d" (n) ++ : "memory", "cc"); ++} ++EOF ++dnl ++dnl test, if assembler supports S390 z10 zarch instructions as default ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_min_z10_zarch=yes ++else ++ libc_cv_asm_s390_min_z10_zarch=no ++fi ++rm -f conftest* ]) ++ ++if test "$libc_cv_asm_s390_min_z10_zarch" = yes ; ++then ++ AC_DEFINE(HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT) ++fi ++ + AC_CACHE_CHECK(for S390 z196 zarch instruction support as default, + libc_cv_asm_s390_min_z196_zarch, [dnl + cat > conftest.c <<\EOF diff --git a/SOURCES/glibc-rh1659438-10.patch b/SOURCES/glibc-rh1659438-10.patch new file mode 100644 index 0000000..729f1b5 --- /dev/null +++ b/SOURCES/glibc-rh1659438-10.patch @@ -0,0 +1,189 @@ +commit e099aab060df178a7fcd5a55282650fe45ccea66 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:07 2018 +0100 + + S390: Remove s390 specific implementation of bcopy. + + Nowadays gcc is automatically replacing a call to bcopy + with a call to memmove. Thus only old binaries will call + the s390 specific bcopy implementation. + + The s390 specific implementation is using an own + implementation for memcpy in the forward case and is + relying on memmove in the backward case. + + After removing the s390 specific bcopy, the common code + bcopy is used. It just performs a tail call to memmove. + + ChangeLog: + * sysdeps/s390/s390-32/bcopy.S: Remove. + * sysdeps/s390/s390-64/bcopy.S: Likewise. + +diff --git a/sysdeps/s390/s390-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S +deleted file mode 100644 +index 560e04fdee93dafb..0000000000000000 +--- a/sysdeps/s390/s390-32/bcopy.S ++++ /dev/null +@@ -1,85 +0,0 @@ +-/* bcopy -- copy a block from source to destination. S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of source +- %r3 = address of destination +- %r4 = number of bytes to copy. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bcopy) +- ltr %r1,%r4 # zero bcopy ? +- jz .L4 +- clr %r2,%r3 # check against destructive overlap +- jnl .L0 +- alr %r1,%r2 +- clr %r1,%r3 +- jh .L7 +-.L0: ahi %r4,-1 # length - 1 +- lr %r1,%r4 +- srl %r1,8 +- ltr %r1,%r1 # < 256 bytes to move ? +- jz .L2 +- chi %r1,255 # > 1MB to move ? +- jh .L5 +-.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks +- la %r2,256(%r2) +- la %r3,256(%r3) +- brct %r1,.L1 +-.L2: bras %r1,.L3 # setup base pointer for execute +- mvc 0(1,%r3),0(%r2) # instruction for execute +-.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1 +-.L4: br %r14 +- +- # data copies > 1MB are faster with mvcle. +-.L5: ahi %r4,1 # length + 1 +- lr %r5,%r4 # source length +- lr %r4,%r2 # source address +- lr %r2,%r3 # set destination +- lr %r3,%r5 # destination length = source length +-.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend +- jo .L6 +- br %r14 +-.L7: # destructive overlay, can not use mvcle +- lr %r1,%r2 # bcopy is called with source,dest +- lr %r2,%r3 # memmove with dest,source! Oh, well... +- lr %r3,%r1 +- basr %r1,0 +-.L8: +-#ifdef PIC +- al %r1,.L9-.L8(%r1) # get address of global offset table +- # load address of memmove +- l %r1,memmove@GOT(%r1) +- br %r1 +-.L9: .long _GLOBAL_OFFSET_TABLE_-.L8 +-#else +- al %r1,.L9-.L8(%r1) # load address of memmove +- br %r1 # jump to memmove +-.L9: .long memmove-.L8 +-#endif +- +-END(__bcopy) +- +-#ifndef NO_WEAK_ALIAS +-weak_alias (__bcopy, bcopy) +-#endif +- +diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S +deleted file mode 100644 +index 806dd15d0203d32a..0000000000000000 +--- a/sysdeps/s390/s390-64/bcopy.S ++++ /dev/null +@@ -1,71 +0,0 @@ +-/* bcopy -- copy a block from source to destination. 64 bit S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of source +- %r3 = address of destination +- %r4 = number of bytes to copy. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bcopy) +- ltgr %r1,%r4 # zero bcopy ? +- jz .L4 +- clgr %r2,%r3 # check against destructive overlap +- jnl .L0 +- algr %r1,%r2 +- clgr %r1,%r3 +- jh .L7 +-.L0: aghi %r4,-1 # length - 1 +- srlg %r1,%r4,8 +- ltgr %r1,%r1 # < 256 bytes to move ? +- jz .L2 +- cghi %r1,255 # > 1MB to move ? +- jh .L5 +-.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks +- la %r2,256(%r2) +- la %r3,256(%r3) +- brctg %r1,.L1 +-.L2: bras %r1,.L3 # setup base pointer for execute +- mvc 0(1,%r3),0(%r2) # instruction for execute +-.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1 +-.L4: br %r14 +- # data copies > 1MB are faster with mvcle. +-.L5: aghi %r4,1 # length + 1 +- lgr %r5,%r4 # source length +- lgr %r4,%r2 # source address +- lgr %r2,%r3 # set destination +- lgr %r3,%r5 # destination length = source length +-.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend +- jo .L6 +- br %r14 +-.L7: # destructive overlay, can not use mvcle +- lgr %r1,%r2 # bcopy is called with source,dest +- lgr %r2,%r3 # memmove with dest,source! Oh, well... +- lgr %r3,%r1 +- jg HIDDEN_BUILTIN_JUMPTARGET(memmove) +- +-END(__bcopy) +- +-#ifndef NO_WEAK_ALIAS +-weak_alias (__bcopy, bcopy) +-#endif +- diff --git a/SOURCES/glibc-rh1659438-11.patch b/SOURCES/glibc-rh1659438-11.patch new file mode 100644 index 0000000..71d20a3 --- /dev/null +++ b/SOURCES/glibc-rh1659438-11.patch @@ -0,0 +1,43 @@ +commit d097d97626e44bc6e76d5daf80ce3ff7d147b623 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:07 2018 +0100 + + S390: Use memcpy for forward cases in memmove. + + The s390/s390x memcpy implementations are safe to be + used by memmove. Starting with this commit, memmove is + using memcpy for the forward cases on s390. + + ChangeLog: + + * sysdeps/s390/memcopy.h: New file. + +diff --git a/sysdeps/s390/memcopy.h b/sysdeps/s390/memcopy.h +new file mode 100644 +index 0000000000000000..9a76196502f25bbf +--- /dev/null ++++ b/sysdeps/s390/memcopy.h +@@ -0,0 +1,23 @@ ++/* memcopy.h -- definitions for memory copy functions. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* The s390/s390x memcpy implementations are safe to be used by memmove. */ ++#undef MEMCPY_OK_FOR_FWD_MEMMOVE ++#define MEMCPY_OK_FOR_FWD_MEMMOVE 1 diff --git a/SOURCES/glibc-rh1659438-12.patch b/SOURCES/glibc-rh1659438-12.patch new file mode 100644 index 0000000..e257c4e --- /dev/null +++ b/SOURCES/glibc-rh1659438-12.patch @@ -0,0 +1,114 @@ +commit 2ee1bc57ab50737ee2ab88c4d796b90e08b4bf93 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:08 2018 +0100 + + S390: Add configure check to detect z13 as mininum architecture level set. + + Add a configure check for z13 in the same way as done for z196. + + ChangeLog: + + * config.h.in (HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT): New undefine. + * sysdeps/s390/configure.ac: Add check for z13 support. + * sysdeps/s390/configure: Regenerated. + +diff --git a/config.h.in b/config.h.in +index beecc39d5b8c3f4a..422a6036ab16e3b6 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -68,6 +68,9 @@ + /* Define if assembler supports z196 zarch instructions as default on S390. */ + #undef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + ++/* Define if assembler supports z13 zarch instructions as default on S390. */ ++#undef HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ + /* Define if assembler supports vector instructions on S390. */ + #undef HAVE_S390_VX_ASM_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index f30f8644361f474a..4a44775e3083d8c3 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -187,5 +187,43 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z13 zarch instruction support as default" >&5 ++$as_echo_n "checking for S390 z13 zarch instruction support as default... " >&6; } ++if ${libc_cv_asm_s390_min_z13_zarch+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++int testinsn (void) ++{ ++ int i; ++ __asm__ ("vl %%v16,0(%%r15)\n\t" ++ "vlgvf %0,%%v16,0" ++ : "=d" (i) : : "memory", "v16"); ++ return i; ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_min_z13_zarch=yes ++else ++ libc_cv_asm_s390_min_z13_zarch=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z13_zarch" >&5 ++$as_echo "$libc_cv_asm_s390_min_z13_zarch" >&6; } ++ ++if test "$libc_cv_asm_s390_min_z13_zarch" = yes ; ++then ++ $as_echo "#define HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ + test -n "$critic_missing" && as_fn_error $? " + *** $critic_missing" "$LINENO" 5 +diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac +index 981f7a79dd7066fc..4dfb5574b49d5949 100644 +--- a/sysdeps/s390/configure.ac ++++ b/sysdeps/s390/configure.ac +@@ -135,5 +135,33 @@ then + AC_DEFINE(HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 z13 zarch instruction support as default, ++ libc_cv_asm_s390_min_z13_zarch, [dnl ++cat > conftest.c <<\EOF ++int testinsn (void) ++{ ++ int i; ++ __asm__ ("vl %%v16,0(%%r15)\n\t" ++ "vlgvf %0,%%v16,0" ++ : "=d" (i) : : "memory", "v16"); ++ return i; ++} ++EOF ++dnl ++dnl test, if assembler supports S390 z13 zarch instructions as default ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_min_z13_zarch=yes ++else ++ libc_cv_asm_s390_min_z13_zarch=no ++fi ++rm -f conftest* ]) ++ ++if test "$libc_cv_asm_s390_min_z13_zarch" = yes ; ++then ++ AC_DEFINE(HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT) ++fi ++ + test -n "$critic_missing" && AC_MSG_ERROR([ + *** $critic_missing]) diff --git a/SOURCES/glibc-rh1659438-13.patch b/SOURCES/glibc-rh1659438-13.patch new file mode 100644 index 0000000..4f8aa88 --- /dev/null +++ b/SOURCES/glibc-rh1659438-13.patch @@ -0,0 +1,327 @@ +commit cdd927d98cc38acf55e1c6594b5c9451df8f239f +Author: Stefan Liebler +Date: Tue Dec 18 13:57:08 2018 +0100 + + S390: Add z13 memmove ifunc variant. + + This patch introduces a z13 specific ifunc variant for memmove. + As the common code implementation, it checks if we can copy from + the beginning to the end - with z196 memcpy implementation - or + if we have to copy from the end to the beginning. + The latter case is done by using vector load/store instructions. + + If vector instructions are not available, the common-code is + used as fallback. Therefore it is implemented in memmove-c with + a different name. + Furthermore the ifunc logic decides if we need the common-code + implementation at all. If vector instructions are supported + due to the minimum architecture level set we can skip the + common-code ifunc variant. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add memmove-c. + * sysdeps/s390/ifunc-memcpy.h (HAVE_MEMMOVE_IFUNC, + HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT, MEMMOVE_DEFAULT, + HAVE_MEMMOVE_C, MEMMOVE_C, HAVE_MEMMOVE_Z13, MEMMOVE_Z13): + New defines. + * sysdeps/s390/memcpy-z900.S: Add z13 memmove implementation. + * sysdeps/s390/memmove-c.c: New file. + * sysdeps/s390/memmove.c: Likewise. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variants for memmove. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 838950a5ab958e31..3a7cccdf8f147398 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -33,5 +33,6 @@ endif + ifeq ($(subdir),string) + sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ +- mempcpy memcpy memcpy-z900 ++ mempcpy memcpy memcpy-z900 \ ++ memmove memmove-c + endif +diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h +index 51c71baa2c0b0452..0e701968c8f39014 100644 +--- a/sysdeps/s390/ifunc-memcpy.h ++++ b/sysdeps/s390/ifunc-memcpy.h +@@ -43,6 +43,29 @@ + # define HAVE_MEMCPY_Z196 HAVE_MEMCPY_IFUNC + #endif + ++#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMMOVE_IFUNC 1 ++#else ++# define HAVE_MEMMOVE_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT HAVE_MEMMOVE_IFUNC ++#else ++# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMMOVE_DEFAULT MEMMOVE_Z13 ++# define HAVE_MEMMOVE_C 0 ++# define HAVE_MEMMOVE_Z13 1 ++#else ++# define MEMMOVE_DEFAULT MEMMOVE_C ++# define HAVE_MEMMOVE_C 1 ++# define HAVE_MEMMOVE_Z13 HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT ++#endif ++ + #if HAVE_MEMCPY_Z900_G5 + # define MEMCPY_Z900_G5 __memcpy_default + # define MEMPCPY_Z900_G5 __mempcpy_default +@@ -66,3 +89,15 @@ + # define MEMCPY_Z196 NULL + # define MEMPCPY_Z196 NULL + #endif ++ ++#if HAVE_MEMMOVE_C ++# define MEMMOVE_C __memmove_c ++#else ++# define MEMMOVE_C NULL ++#endif ++ ++#if HAVE_MEMMOVE_Z13 ++# define MEMMOVE_Z13 __memmove_z13 ++#else ++# define MEMMOVE_Z13 NULL ++#endif +diff --git a/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S +index 3a50cf44d85d2417..bd3b1950ee442c0c 100644 +--- a/sysdeps/s390/memcpy-z900.S ++++ b/sysdeps/s390/memcpy-z900.S +@@ -182,6 +182,7 @@ ENTRY(MEMCPY_Z196) + # endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 ++.L_Z196_start2: + aghi %r4,-1 + srlg %r5,%r4,8 + ltgr %r5,%r5 +@@ -207,6 +208,75 @@ ENTRY(MEMCPY_Z196) + END(MEMCPY_Z196) + #endif /* HAVE_MEMCPY_Z196 */ + ++#if HAVE_MEMMOVE_Z13 ++ENTRY(MEMMOVE_Z13) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ /* Note: The 31bit dst and src pointers are prefixed with zeroes. */ ++ llgfr %r4,%r4 ++ llgfr %r3,%r3 ++ llgfr %r2,%r2 ++# endif /* !defined __s390x__ */ ++ sgrk %r0,%r2,%r3 ++ clgijh %r4,16,.L_MEMMOVE_Z13_LARGE ++ aghik %r5,%r4,-1 ++.L_MEMMOVE_Z13_SMALL: ++ jl .L_MEMMOVE_Z13_END /* Jump away if len was zero. */ ++ /* Store up to 16 bytes with vll/vstl which needs the index ++ instead of lengths. */ ++ vll %v16,%r5,0(%r3) ++ vstl %v16,%r5,0(%r2) ++.L_MEMMOVE_Z13_END: ++ br %r14 ++.L_MEMMOVE_Z13_LARGE: ++ lgr %r1,%r2 /* For memcpy: r1: Use as dest ; ++ r2: Return dest */ ++ /* The unsigned comparison (dst - src >= len) determines if we can ++ execute the forward case with memcpy. */ ++#if ! HAVE_MEMCPY_Z196 ++# error The z13 variant of memmove needs the z196 variant of memcpy! ++#endif ++ clgrjhe %r0,%r4,.L_Z196_start2 ++ risbgn %r5,%r4,4,128+63,60 /* r5 = r4 / 16 */ ++ aghi %r4,-16 ++ clgijhe %r5,8,.L_MEMMOVE_Z13_LARGE_64B ++.L_MEMMOVE_Z13_LARGE_16B_LOOP: ++ /* Store at least 16 bytes with vl/vst. The number of 16byte blocks ++ is stored in r5. */ ++ vl %v16,0(%r4,%r3) ++ vst %v16,0(%r4,%r2) ++ aghi %r4,-16 ++ brctg %r5,.L_MEMMOVE_Z13_LARGE_16B_LOOP ++ aghik %r5,%r4,15 ++ j .L_MEMMOVE_Z13_SMALL ++.L_MEMMOVE_Z13_LARGE_64B: ++ /* Store at least 128 bytes with 4x vl/vst. The number of 64byte blocks ++ will be stored in r0. */ ++ aghi %r4,-48 ++ srlg %r0,%r5,2 /* r5 = %r0 / 4 ++ => Number of 64byte blocks. */ ++.L_MEMMOVE_Z13_LARGE_64B_LOOP: ++ vl %v20,48(%r4,%r3) ++ vl %v19,32(%r4,%r3) ++ vl %v18,16(%r4,%r3) ++ vl %v17,0(%r4,%r3) ++ vst %v20,48(%r4,%r2) ++ vst %v19,32(%r4,%r2) ++ vst %v18,16(%r4,%r2) ++ vst %v17,0(%r4,%r2) ++ aghi %r4,-64 ++ brctg %r0,.L_MEMMOVE_Z13_LARGE_64B_LOOP ++ aghi %r4,48 ++ /* Recalculate the number of 16byte blocks. */ ++ risbg %r5,%r5,62,128+63,0 /* r5 = r5 & 3 ++ => Remaining 16byte blocks. */ ++ jne .L_MEMMOVE_Z13_LARGE_16B_LOOP ++ aghik %r5,%r4,15 ++ j .L_MEMMOVE_Z13_SMALL ++END(MEMMOVE_Z13) ++#endif /* HAVE_MEMMOVE_Z13 */ ++ + #if ! HAVE_MEMCPY_IFUNC + /* If we don't use ifunc, define an alias for mem[p]cpy here. + Otherwise see sysdeps/s390/mem[p]cpy.c. */ +@@ -215,10 +285,27 @@ strong_alias (MEMPCPY_DEFAULT, __mempcpy) + weak_alias (__mempcpy, mempcpy) + #endif + ++#if ! HAVE_MEMMOVE_IFUNC ++/* If we don't use ifunc, define an alias for memmove here. ++ Otherwise see sysdeps/s390/memmove.c. */ ++# if ! HAVE_MEMMOVE_C ++/* If the c variant is needed, then sysdeps/s390/memmove-c.c ++ defines memmove. ++ Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it. */ ++strong_alias (MEMMOVE_DEFAULT, memmove) ++# endif ++#endif ++ + #if defined SHARED && IS_IN (libc) + /* Defines the internal symbols. + Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c. */ + strong_alias (MEMCPY_DEFAULT, __GI_memcpy) + strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy) + strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy) ++# if ! HAVE_MEMMOVE_C ++/* If the c variant is needed, then sysdeps/s390/memmove-c.c ++ defines the internal symbol. ++ Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it. */ ++strong_alias (MEMMOVE_DEFAULT, __GI_memmove) ++# endif + #endif +diff --git a/sysdeps/s390/memmove-c.c b/sysdeps/s390/memmove-c.c +new file mode 100644 +index 0000000000000000..be571093e019a38d +--- /dev/null ++++ b/sysdeps/s390/memmove-c.c +@@ -0,0 +1,37 @@ ++/* Fallback C version of memmove. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_MEMMOVE_C ++# if HAVE_MEMMOVE_IFUNC ++/* If we use ifunc, then the memmove symbol is defined ++ in sysdeps/s390/memmove.c and we use a different name here. ++ Otherwise, we have to define memmove here or in ++ sysdeps/s390/memcpy.S depending on the used default implementation. */ ++# define MEMMOVE MEMMOVE_C ++# if defined SHARED && IS_IN (libc) ++/* Define the internal symbol. */ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__memmove_c, __GI_memmove, __memmove_c); ++# endif ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c +new file mode 100644 +index 0000000000000000..ac34edf80f2678cd +--- /dev/null ++++ b/sysdeps/s390/memmove.c +@@ -0,0 +1,44 @@ ++/* Multiple versions of memmove. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_MEMMOVE_IFUNC ++/* If we don't use ifunc, an alias is defined for memmove ++ in sysdeps/s390/memmove-c.c or sysdeps/s390/memcpy.S ++ depending on the used default implementation. */ ++# undef memmove ++# define memmove __redirect_memmove ++# include ++# include ++# undef memmove ++ ++# if HAVE_MEMMOVE_C ++extern __typeof (__redirect_memmove) MEMMOVE_C attribute_hidden; ++# endif ++ ++# if HAVE_MEMMOVE_Z13 ++extern __typeof (__redirect_memmove) MEMMOVE_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memmove, memmove, ++ (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMMOVE_Z13 ++ : MEMMOVE_DEFAULT ++ ) ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 6969c480cc40e0e2..c05c63e00608dcd7 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -126,6 +126,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCPY_IFUNC */ + ++#if HAVE_MEMMOVE_IFUNC ++ IFUNC_IMPL (i, name, memmove, ++# if HAVE_MEMMOVE_Z13 ++ IFUNC_IMPL_ADD (array, i, memmove, ++ dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13) ++# endif ++# if HAVE_MEMMOVE_C ++ IFUNC_IMPL_ADD (array, i, memmove, 1, MEMMOVE_C) ++# endif ++ ) ++#endif /* HAVE_MEMMOVE_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ diff --git a/SOURCES/glibc-rh1659438-14.patch b/SOURCES/glibc-rh1659438-14.patch new file mode 100644 index 0000000..7209f89 --- /dev/null +++ b/SOURCES/glibc-rh1659438-14.patch @@ -0,0 +1,263 @@ +commit 8c25dddd2e32bce47dfe01ca51c8aab535dbe23d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:09 2018 +0100 + + S390: Add z13 strstr ifunc variant. + + The new vector variant of strstr is using the common code + implementation, but instead of calling the default + str* / mem* functions, the vector variants are called. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add strstr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variants for strstr. + * sysdeps/s390/ifunc-strstr.h: New file. + * sysdeps/s390/strstr.c: Likewise. + * sysdeps/s390/strstr-c.c: Likewise. + * sysdeps/s390/strstr-vx.c: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 3a7cccdf8f147398..4441e7a5cf6fa167 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -34,5 +34,6 @@ ifeq ($(subdir),string) + sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ + mempcpy memcpy memcpy-z900 \ +- memmove memmove-c ++ memmove memmove-c \ ++ strstr strstr-vx strstr-c + endif +diff --git a/sysdeps/s390/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h +new file mode 100644 +index 0000000000000000..e6ccfd4e44a1a790 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strstr.h +@@ -0,0 +1,52 @@ ++/* strstr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRSTR_IFUNC 1 ++#else ++# define HAVE_STRSTR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT HAVE_STRSTR_IFUNC ++#else ++# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRSTR_DEFAULT STRSTR_Z13 ++# define HAVE_STRSTR_C 0 ++# define HAVE_STRSTR_Z13 1 ++#else ++# define STRSTR_DEFAULT STRSTR_C ++# define HAVE_STRSTR_C 1 ++# define HAVE_STRSTR_Z13 HAVE_STRSTR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRSTR_C ++# define STRSTR_C __strstr_c ++#else ++# define STRSTR_C NULL ++#endif ++ ++#if HAVE_STRSTR_Z13 ++# define STRSTR_Z13 __strstr_vx ++#else ++# define STRSTR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c05c63e00608dcd7..14727f8fef5431dd 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -138,6 +139,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMMOVE_IFUNC */ + ++#if HAVE_STRSTR_IFUNC ++ IFUNC_IMPL (i, name, strstr, ++# if HAVE_STRSTR_Z13 ++ IFUNC_IMPL_ADD (array, i, strstr, ++ dl_hwcap & HWCAP_S390_VX, STRSTR_Z13) ++# endif ++# if HAVE_STRSTR_C ++ IFUNC_IMPL_ADD (array, i, strstr, 1, STRSTR_C) ++# endif ++ ) ++#endif /* HAVE_STRSTR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +diff --git a/sysdeps/s390/strstr-c.c b/sysdeps/s390/strstr-c.c +new file mode 100644 +index 0000000000000000..53717bfb276fed3d +--- /dev/null ++++ b/sysdeps/s390/strstr-c.c +@@ -0,0 +1,32 @@ ++/* Default strstr implementation for S/390. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_STRSTR_C ++# if HAVE_STRSTR_IFUNC ++# define STRSTR STRSTR_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strstr_c, __GI_strstr, __strstr_c); ++# endif ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/strstr-vx.c b/sysdeps/s390/strstr-vx.c +new file mode 100644 +index 0000000000000000..effae9d5eb7d2fb1 +--- /dev/null ++++ b/sysdeps/s390/strstr-vx.c +@@ -0,0 +1,52 @@ ++/* Default strstr implementation with vector string functions for S/390. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_STRSTR_Z13 ++# if HAVE_STRSTR_IFUNC ++# define STRSTR STRSTR_Z13 ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# if HAVE_STRSTR_C ++# define libc_hidden_builtin_def(name) ++# else ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strstr_vx, __GI_strstr, __strstr_vx); ++# endif ++# endif ++# endif ++ ++# include ++ ++# ifdef USE_MULTIARCH ++extern __typeof (strchr) __strchr_vx attribute_hidden; ++# define strchr __strchr_vx ++ ++extern __typeof (strlen) __strlen_vx attribute_hidden; ++# define strlen __strlen_vx ++ ++extern __typeof (__strnlen) __strnlen_vx attribute_hidden; ++# define __strnlen __strnlen_vx ++ ++extern __typeof (memcmp) __memcmp_z196 attribute_hidden; ++# define memcmp __memcmp_z196 ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/strstr.c b/sysdeps/s390/strstr.c +new file mode 100644 +index 0000000000000000..f8432349a7254cc6 +--- /dev/null ++++ b/sysdeps/s390/strstr.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of strstr. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_STRSTR_IFUNC ++# define strstr __redirect_strstr ++# include ++# include ++# undef strstr ++ ++# if HAVE_STRSTR_C ++extern __typeof (__redirect_strstr) STRSTR_C attribute_hidden; ++# endif ++ ++# if HAVE_STRSTR_Z13 ++extern __typeof (__redirect_strstr) STRSTR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_strstr, strstr, ++ (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRSTR_Z13 ++ : STRSTR_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-15.patch b/SOURCES/glibc-rh1659438-15.patch new file mode 100644 index 0000000..0cb1dbe --- /dev/null +++ b/SOURCES/glibc-rh1659438-15.patch @@ -0,0 +1,290 @@ +commit d2c4c403feddd6f0b9dbf31ca7541b37f90ee30a +Author: Stefan Liebler +Date: Tue Dec 18 13:57:09 2018 +0100 + + S390: Add z13 memmem ifunc variant. + + The new vector variant of memmem is using the common code + implementation, but instead of calling the default + mem* functions, the vector variants are called. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add memmem variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variants for memmem. + * sysdeps/s390/ifunc-memmem.h: New file. + * sysdeps/s390/memmem.c: Likewise. + * sysdeps/s390/memmem-c.c: Likewise. + * sysdeps/s390/memmem-vx.c: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 4441e7a5cf6fa167..47d606d3d5d99274 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -35,5 +35,6 @@ sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ +- strstr strstr-vx strstr-c ++ strstr strstr-vx strstr-c \ ++ memmem memmem-vx memmem-c + endif +diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h +new file mode 100644 +index 0000000000000000..0f860d8d40080acf +--- /dev/null ++++ b/sysdeps/s390/ifunc-memmem.h +@@ -0,0 +1,52 @@ ++/* memmem variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMMEM_IFUNC 1 ++#else ++# define HAVE_MEMMEM_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT HAVE_MEMMEM_IFUNC ++#else ++# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMMEM_DEFAULT MEMMEM_Z13 ++# define HAVE_MEMMEM_C 0 ++# define HAVE_MEMMEM_Z13 1 ++#else ++# define MEMMEM_DEFAULT MEMMEM_C ++# define HAVE_MEMMEM_C 1 ++# define HAVE_MEMMEM_Z13 HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMMEM_C ++# define MEMMEM_C __memmem_c ++#else ++# define MEMMEM_C NULL ++#endif ++ ++#if HAVE_MEMMEM_Z13 ++# define MEMMEM_Z13 __memmem_vx ++#else ++# define MEMMEM_Z13 NULL ++#endif +diff --git a/sysdeps/s390/memmem-c.c b/sysdeps/s390/memmem-c.c +new file mode 100644 +index 0000000000000000..1d8ffefcb840b8d2 +--- /dev/null ++++ b/sysdeps/s390/memmem-c.c +@@ -0,0 +1,47 @@ ++/* Default memmem implementation for S/390. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_MEMMEM_C ++# if HAVE_MEMMEM_IFUNC ++# include ++ ++# ifndef _LIBC ++# define memmem MEMMEM_C ++# else ++# define __memmem MEMMEM_C ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ strong_alias (__memmem_c, __memmem_c_1); \ ++ __hidden_ver1 (__memmem_c, __GI___memmem, __memmem_c); ++ ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) \ ++ __hidden_ver1 (__memmem_c_1, __GI_memmem, __memmem_c_1) __attribute__((weak)); ++# endif ++ ++# undef weak_alias ++# define weak_alias(a, b) ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/memmem-vx.c b/sysdeps/s390/memmem-vx.c +new file mode 100644 +index 0000000000000000..af6e200e4e0af1a5 +--- /dev/null ++++ b/sysdeps/s390/memmem-vx.c +@@ -0,0 +1,61 @@ ++/* Default memmem implementation with vector string functions for S/390. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_MEMMEM_Z13 ++# include ++# if HAVE_MEMMEM_IFUNC ++ ++# ifndef _LIBC ++# define memmem MEMMEM_Z13 ++# else ++# define __memmem MEMMEM_Z13 ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# undef libc_hidden_weak ++ ++# if HAVE_MEMMEM_C ++# define libc_hidden_def(name) ++# define libc_hidden_weak(name) ++# else ++# define libc_hidden_def(name) \ ++ strong_alias (__memmem_vx, __memmem_vx_1); \ ++ __hidden_ver1 (__memmem_vx, __GI___memmem, __memmem_vx); ++ ++# define libc_hidden_weak(name) \ ++ __hidden_ver1 (__memmem_vx_1, __GI_memmem, __memmem_vx_1) __attribute__((weak)); ++# endif ++# endif ++ ++# undef weak_alias ++# define weak_alias(a, b) ++# endif ++ ++# ifdef USE_MULTIARCH ++extern __typeof (memchr) __memchr_vx attribute_hidden; ++# define memchr __memchr_vx ++ ++extern __typeof (memcmp) __memcmp_z196 attribute_hidden; ++# define memcmp __memcmp_z196 ++# endif ++ ++# include ++#endif +diff --git a/sysdeps/s390/memmem.c b/sysdeps/s390/memmem.c +new file mode 100644 +index 0000000000000000..8c50b3f403eb8d1f +--- /dev/null ++++ b/sysdeps/s390/memmem.c +@@ -0,0 +1,43 @@ ++/* Multiple versions of memmem. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if HAVE_MEMMEM_IFUNC ++# define memmem __redirect_memmem ++# define __memmem __redirect___memmem ++# include ++# include ++# undef memmem ++# undef __memmem ++ ++# if HAVE_MEMMEM_C ++extern __typeof (__redirect_memmem) MEMMEM_C attribute_hidden; ++# endif ++ ++# if HAVE_MEMMEM_Z13 ++extern __typeof (__redirect_memmem) MEMMEM_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memmem, __memmem, ++ (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMMEM_Z13 ++ : MEMMEM_DEFAULT ++ ) ++weak_alias (__memmem, memmem) ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 14727f8fef5431dd..da8696d917abf51c 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -151,6 +152,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRSTR_IFUNC */ + ++#if HAVE_MEMMEM_IFUNC ++ IFUNC_IMPL (i, name, memmem, ++# if HAVE_MEMMEM_Z13 ++ IFUNC_IMPL_ADD (array, i, memmem, ++ dl_hwcap & HWCAP_S390_VX, MEMMEM_Z13) ++# endif ++# if HAVE_MEMMEM_C ++ IFUNC_IMPL_ADD (array, i, memmem, 1, MEMMEM_C) ++# endif ++ ) ++#endif /* HAVE_MEMMEM_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ diff --git a/SOURCES/glibc-rh1659438-16.patch b/SOURCES/glibc-rh1659438-16.patch new file mode 100644 index 0000000..b55bebc --- /dev/null +++ b/SOURCES/glibc-rh1659438-16.patch @@ -0,0 +1,259 @@ +commit ff3ca3743a00af749258cc242457b648d65a1537 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:10 2018 +0100 + + S390: Refactor strlen ifunc handling. + + The ifunc handling for strlen is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strlen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strlen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strlen. + * sysdeps/s390/multiarch/strlen-c.c: Move to ... + * sysdeps/s390/strlen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strlen-vx.S: Move to ... + * sysdeps/s390/strlen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strlen.c: Move to ... + * sysdeps/s390/strlen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strlen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 47d606d3d5d99274..600d8e629df7090e 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -36,5 +36,6 @@ sysdep_routines += bzero memset memset-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ + strstr strstr-vx strstr-c \ +- memmem memmem-vx memmem-c ++ memmem memmem-vx memmem-c \ ++ strlen strlen-vx strlen-c + endif +diff --git a/sysdeps/s390/ifunc-strlen.h b/sysdeps/s390/ifunc-strlen.h +new file mode 100644 +index 0000000000000000..f2070596636f29a9 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strlen.h +@@ -0,0 +1,52 @@ ++/* strlen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRLEN_IFUNC 1 ++#else ++# define HAVE_STRLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT HAVE_STRLEN_IFUNC ++#else ++# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRLEN_DEFAULT STRLEN_Z13 ++# define HAVE_STRLEN_C 0 ++# define HAVE_STRLEN_Z13 1 ++#else ++# define STRLEN_DEFAULT STRLEN_C ++# define HAVE_STRLEN_C 1 ++# define HAVE_STRLEN_Z13 HAVE_STRLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRLEN_C ++# define STRLEN_C __strlen_c ++#else ++# define STRLEN_C NULL ++#endif ++ ++#if HAVE_STRLEN_Z13 ++# define STRLEN_Z13 __strlen_vx ++#else ++# define STRLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 24949cd3a88b8015..601523919c235f76 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strlen strlen-vx strlen-c \ +- strnlen strnlen-vx strnlen-c \ ++sysdep_routines += strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index da8696d917abf51c..c531be4bc7eb3f55 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -164,6 +165,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMMEM_IFUNC */ + ++#if HAVE_STRLEN_IFUNC ++ IFUNC_IMPL (i, name, strlen, ++# if HAVE_STRLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, strlen, ++ dl_hwcap & HWCAP_S390_VX, STRLEN_Z13) ++# endif ++# if HAVE_STRLEN_C ++ IFUNC_IMPL_ADD (array, i, strlen, 1, STRLEN_C) ++# endif ++ ) ++#endif /* HAVE_STRLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -172,7 +185,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (strlen); + IFUNC_VX_IMPL (wcslen); + + IFUNC_VX_IMPL (strnlen); +diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/strlen-c.c +similarity index 78% +rename from sysdeps/s390/multiarch/strlen-c.c +rename to sysdeps/s390/strlen-c.c +index a2c8e43624a9bc91..b4569701af96f4a9 100644 +--- a/sysdeps/s390/multiarch/strlen-c.c ++++ b/sysdeps/s390/strlen-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRLEN __strlen_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRLEN_C ++# if HAVE_STRLEN_IFUNC ++# define STRLEN STRLEN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strlen_c, __GI_strlen, __strlen_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/strlen-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strlen-vx.S +rename to sysdeps/s390/strlen-vx.S +index 9308b332371dcdaa..39ef43107d11ec73 100644 +--- a/sysdeps/s390/multiarch/strlen-vx.S ++++ b/sysdeps/s390/strlen-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +35,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__strlen_vx) ++ENTRY(STRLEN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -80,5 +81,13 @@ ENTRY(__strlen_vx) + vlgvb %r2,%v16,7 /* Load byte index of zero. */ + algr %r2,%r5 + br %r14 +-END(__strlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRLEN_Z13) ++ ++# if ! HAVE_STRLEN_IFUNC ++strong_alias (STRLEN_Z13, strlen) ++# endif ++ ++# if ! HAVE_STRLEN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRLEN_Z13, __GI_strlen) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/strlen.c +similarity index 69% +rename from sysdeps/s390/multiarch/strlen.c +rename to sysdeps/s390/strlen.c +index 0edf8b7d0231cf31..6ba0fe86fe9789f0 100644 +--- a/sysdeps/s390/multiarch/strlen.c ++++ b/sysdeps/s390/strlen.c +@@ -16,14 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRLEN_IFUNC + # define strlen __redirect_strlen + # include + # include + # undef strlen + +-s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen) ++# if HAVE_STRLEN_C ++extern __typeof (__redirect_strlen) STRLEN_C attribute_hidden; ++# endif ++ ++# if HAVE_STRLEN_Z13 ++extern __typeof (__redirect_strlen) STRLEN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strlen, strlen, ++ (HAVE_STRLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRLEN_Z13 ++ : STRLEN_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-17.patch b/SOURCES/glibc-rh1659438-17.patch new file mode 100644 index 0000000..da43ae2 --- /dev/null +++ b/SOURCES/glibc-rh1659438-17.patch @@ -0,0 +1,269 @@ +commit de10e44dda686e3ed6a7a1463869df846ea39825 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:10 2018 +0100 + + S390: Refactor strnlen ifunc handling. + + The ifunc handling for strnlen is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strnlen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strnlen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strnlen. + * sysdeps/s390/multiarch/strnlen-c.c: Move to ... + * sysdeps/s390/strnlen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strnlen-vx.S: Move to ... + * sysdeps/s390/strnlen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strnlen.c: Move to ... + * sysdeps/s390/strnlen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strnlen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 600d8e629df7090e..f092355743e3908f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -37,5 +37,6 @@ sysdep_routines += bzero memset memset-z900 \ + memmove memmove-c \ + strstr strstr-vx strstr-c \ + memmem memmem-vx memmem-c \ +- strlen strlen-vx strlen-c ++ strlen strlen-vx strlen-c \ ++ strnlen strnlen-vx strnlen-c + endif +diff --git a/sysdeps/s390/ifunc-strnlen.h b/sysdeps/s390/ifunc-strnlen.h +new file mode 100644 +index 0000000000000000..e92329888773304d +--- /dev/null ++++ b/sysdeps/s390/ifunc-strnlen.h +@@ -0,0 +1,52 @@ ++/* strnlen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNLEN_IFUNC 1 ++#else ++# define HAVE_STRNLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT HAVE_STRNLEN_IFUNC ++#else ++# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNLEN_DEFAULT STRNLEN_Z13 ++# define HAVE_STRNLEN_C 0 ++# define HAVE_STRNLEN_Z13 1 ++#else ++# define STRNLEN_DEFAULT STRNLEN_C ++# define HAVE_STRNLEN_C 1 ++# define HAVE_STRNLEN_Z13 HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNLEN_C ++# define STRNLEN_C __strnlen_c ++#else ++# define STRNLEN_C NULL ++#endif ++ ++#if HAVE_STRNLEN_Z13 ++# define STRNLEN_Z13 __strnlen_vx ++#else ++# define STRNLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 601523919c235f76..35ba223c5d4fb52f 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strnlen strnlen-vx strnlen-c \ +- strcpy strcpy-vx \ ++sysdep_routines += strcpy strcpy-vx \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c531be4bc7eb3f55..680e5b738bfb7f32 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -177,6 +178,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRLEN_IFUNC */ + ++#if HAVE_STRNLEN_IFUNC ++ IFUNC_IMPL (i, name, strnlen, ++# if HAVE_STRNLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, strnlen, ++ dl_hwcap & HWCAP_S390_VX, STRNLEN_Z13) ++# endif ++# if HAVE_STRNLEN_C ++ IFUNC_IMPL_ADD (array, i, strnlen, 1, STRNLEN_C) ++# endif ++ ) ++#endif /* HAVE_STRNLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -187,7 +200,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcslen); + +- IFUNC_VX_IMPL (strnlen); + IFUNC_VX_IMPL (wcsnlen); + + IFUNC_VX_IMPL (strcpy); +diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/strnlen-c.c +similarity index 81% +rename from sysdeps/s390/multiarch/strnlen-c.c +rename to sysdeps/s390/strnlen-c.c +index 353e83ed356ca080..c2d887f1e4f504e8 100644 +--- a/sysdeps/s390/multiarch/strnlen-c.c ++++ b/sysdeps/s390/strnlen-c.c +@@ -16,15 +16,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRNLEN __strnlen_c +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#include ++ ++#if HAVE_STRNLEN_C ++# if HAVE_STRNLEN_IFUNC ++# define STRNLEN STRNLEN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ + __hidden_ver1 (__strnlen_c, __GI_strnlen, __strnlen_c); \ + strong_alias (__strnlen_c, __strnlen_c_1); \ + __hidden_ver1 (__strnlen_c_1, __GI___strnlen, __strnlen_c_1); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/strnlen-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strnlen-vx.S +rename to sysdeps/s390/strnlen-vx.S +index fc659a956cfc1fa1..0b8fe3da342f6803 100644 +--- a/sysdeps/s390/multiarch/strnlen-vx.S ++++ b/sysdeps/s390/strnlen-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +36,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__strnlen_vx) ++ENTRY(STRNLEN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -130,5 +132,16 @@ ENTRY(__strnlen_vx) + clgrjl %r1,%r3,.Lloop64 + + j .Llt64 +-END(__strnlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRNLEN_Z13) ++ ++# if ! HAVE_STRNLEN_IFUNC ++strong_alias (STRNLEN_Z13, __strnlen) ++weak_alias (__strnlen, strnlen) ++# endif ++ ++# if ! HAVE_STRNLEN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRNLEN_Z13, __GI_strnlen) ++strong_alias (STRNLEN_Z13, __GI___strnlen) ++# endif ++ ++#endif /* HAVE_STRNLEN_Z13 */ +diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/strnlen.c +similarity index 69% +rename from sysdeps/s390/multiarch/strnlen.c +rename to sysdeps/s390/strnlen.c +index 0f9cff5d69b017ae..aa4953d5035bc2fc 100644 +--- a/sysdeps/s390/multiarch/strnlen.c ++++ b/sysdeps/s390/strnlen.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNLEN_IFUNC + # define strnlen __redirect_strnlen + # define __strnlen __redirect___strnlen + # include +@@ -24,9 +26,18 @@ + # undef __strnlen + # include + +-s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen) +-weak_alias (__strnlen, strnlen) ++# if HAVE_STRNLEN_C ++extern __typeof (__redirect_strnlen) STRNLEN_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STRNLEN_Z13 ++extern __typeof (__redirect_strnlen) STRNLEN_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___strnlen, __strnlen, ++ (HAVE_STRNLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNLEN_Z13 ++ : STRNLEN_DEFAULT ++ ) ++weak_alias (__strnlen, strnlen) ++#endif /* HAVE_STRNLEN_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-18.patch b/SOURCES/glibc-rh1659438-18.patch new file mode 100644 index 0000000..bcd7958 --- /dev/null +++ b/SOURCES/glibc-rh1659438-18.patch @@ -0,0 +1,398 @@ +commit 914a4e05572e108201d71dcd3e47da8aeeecd70d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:10 2018 +0100 + + S390: Refactor strcpy ifunc handling. + + The ifunc handling for strcpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants with mvst instruction + are now moved to the unified strcpy-z900.S file which can be used for + 31/64bit. The s390-32/s390-64 files multiarch/strcpy.c and strcpy.S + are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcpy. + * sysdeps/s390/multiarch/strcpy-vx.S: Move to ... + * sysdeps/s390/strcpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcpy.c: Move to ... + * sysdeps/s390/strcpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcpy.h: New file. + * sysdeps/s390/s390-64/strcpy.S: Move to ... + * sysdeps/s390/strcpy-z900.S: ... here and adjust to be usable + for 31/64bit and ifunc handling. + * sysdeps/s390/s390-32/multiarch/strcpy.c: Delete file. + * sysdeps/s390/s390-64/multiarch/strcpy.c: Likewise. + * sysdeps/s390/s390-32/strcpy.S: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index f092355743e3908f..e4191319531ecb01 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -38,5 +38,6 @@ sysdep_routines += bzero memset memset-z900 \ + strstr strstr-vx strstr-c \ + memmem memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ +- strnlen strnlen-vx strnlen-c ++ strnlen strnlen-vx strnlen-c \ ++ strcpy strcpy-vx strcpy-z900 + endif +diff --git a/sysdeps/s390/ifunc-strcpy.h b/sysdeps/s390/ifunc-strcpy.h +new file mode 100644 +index 0000000000000000..85e45556e6a61dd5 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcpy.h +@@ -0,0 +1,52 @@ ++/* strcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCPY_IFUNC 1 ++#else ++# define HAVE_STRCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT HAVE_STRCPY_IFUNC ++#else ++# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCPY_DEFAULT STRCPY_Z13 ++# define HAVE_STRCPY_Z900_G5 0 ++# define HAVE_STRCPY_Z13 1 ++#else ++# define STRCPY_DEFAULT STRCPY_Z900_G5 ++# define HAVE_STRCPY_Z900_G5 1 ++# define HAVE_STRCPY_Z13 HAVE_STRCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCPY_Z900_G5 ++# define STRCPY_Z900_G5 __strcpy_default ++#else ++# define STRCPY_Z900_G5 NULL ++#endif ++ ++#if HAVE_STRCPY_Z13 ++# define STRCPY_Z13 __strcpy_vx ++#else ++# define STRCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 35ba223c5d4fb52f..50f7f0b78df723bb 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcpy strcpy-vx \ +- stpcpy stpcpy-vx stpcpy-c \ ++sysdep_routines += stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 680e5b738bfb7f32..1784372db9828463 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -190,6 +191,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNLEN_IFUNC */ + ++#if HAVE_STRCPY_IFUNC ++ IFUNC_IMPL (i, name, strcpy, ++# if HAVE_STRCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, strcpy, ++ dl_hwcap & HWCAP_S390_VX, STRCPY_Z13) ++# endif ++# if HAVE_STRCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, strcpy, 1, STRCPY_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_STRCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -202,7 +215,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsnlen); + +- IFUNC_VX_IMPL (strcpy); + IFUNC_VX_IMPL (wcscpy); + + IFUNC_VX_IMPL (stpcpy); +diff --git a/sysdeps/s390/s390-32/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c +deleted file mode 100644 +index 6a22e31a03c8c1c4..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/strcpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcpy. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S +deleted file mode 100644 +index d49136ee92b83378..0000000000000000 +--- a/sysdeps/s390/s390-32/strcpy.S ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* strcpy - copy a string from source to destination. For IBM S390 +- This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* +- * R2 = address of destination +- * R3 = address of source +- */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(strcpy) +- slr %r0,%r0 +- lr %r1,%r2 +-0: mvst %r1,%r3 +- jo 0b +- br %r14 +-END(strcpy) +-libc_hidden_builtin_def (strcpy) +diff --git a/sysdeps/s390/s390-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c +deleted file mode 100644 +index 6a22e31a03c8c1c4..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/strcpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcpy. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/strcpy-vx.S +similarity index 85% +rename from sysdeps/s390/multiarch/strcpy-vx.S +rename to sysdeps/s390/strcpy-vx.S +index 52197f57f7b5d5cf..844d23e4fee32c9b 100644 +--- a/sysdeps/s390/multiarch/strcpy-vx.S ++++ b/sysdeps/s390/strcpy-vx.S +@@ -16,13 +16,13 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +- +-# include "sysdep.h" +-# include "asm-syntax.h" ++#include ++#include "sysdep.h" ++#include "asm-syntax.h" + + .text + ++#if HAVE_STRCPY_Z13 + /* char * strcpy (const char *dest, const char *src) + Copy string src to dest. + +@@ -36,7 +36,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__strcpy_vx) ++ENTRY(STRCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -97,13 +97,13 @@ ENTRY(__strcpy_vx) + .Lfound_align: + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + br %r14 +-END(__strcpy_vx) ++END(STRCPY_Z13) + +-/* Use mvst-strcpy-implementation as default implementation. */ +-# define strcpy __strcpy_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__strcpy_c, __GI_strcpy) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_STRCPY_IFUNC ++strong_alias (STRCPY_Z13, strcpy) ++# endif + +-/* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory. */ +-#include ++# if ! HAVE_STRCPY_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (STRCPY_Z13, __GI_strcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/strcpy-z900.S +similarity index 66% +rename from sysdeps/s390/s390-64/strcpy.S +rename to sysdeps/s390/strcpy-z900.S +index 203c73c905d0d86c..42798b1fd5c51187 100644 +--- a/sysdeps/s390/s390-64/strcpy.S ++++ b/sysdeps/s390/strcpy-z900.S +@@ -1,4 +1,4 @@ +-/* strcpy - copy a string from source to destination. 64 bit S/390 version. ++/* strcpy - copy a string from source to destination. 64/31 bit S/390 version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. +@@ -21,15 +21,36 @@ + %r2 = address of destination + %r3 = address of source. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + ++#if HAVE_STRCPY_Z900_G5 ++# if defined __s390x__ ++# define SLGR slgr ++# define LGR lgr ++# else ++# define SLGR slr ++# define LGR lr ++# endif /* ! defined __s390x__ */ ++ + .text +-ENTRY(strcpy) +- slgr %r0,%r0 +- lgr %r1,%r2 ++ENTRY(STRCPY_Z900_G5) ++ SLGR %r0,%r0 ++ LGR %r1,%r2 + 0: mvst %r1,%r3 + jo 0b + br %r14 +-END(strcpy) +-libc_hidden_builtin_def (strcpy) ++END(STRCPY_Z900_G5) ++ ++# undef SLGR ++# undef LGR ++ ++# if ! HAVE_STRCPY_IFUNC ++strong_alias (STRCPY_Z900_G5, strcpy) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRCPY_Z900_G5, __GI_strcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/strcpy.c +similarity index 69% +rename from sysdeps/s390/multiarch/strcpy.c +rename to sysdeps/s390/strcpy.c +index 8f32a13f6730c427..f4e28e24c85b7162 100644 +--- a/sysdeps/s390/multiarch/strcpy.c ++++ b/sysdeps/s390/strcpy.c +@@ -16,12 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCPY_IFUNC + # define strcpy __redirect_strcpy + # include + # undef strcpy + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy) ++# if HAVE_STRCPY_Z900_G5 ++extern __typeof (__redirect_strcpy) STRCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_STRCPY_Z13 ++extern __typeof (__redirect_strcpy) STRCPY_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_strcpy, strcpy, ++ (HAVE_STRCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCPY_Z13 ++ : STRCPY_DEFAULT ++ ) + #endif diff --git a/SOURCES/glibc-rh1659438-19.patch b/SOURCES/glibc-rh1659438-19.patch new file mode 100644 index 0000000..b80b640 --- /dev/null +++ b/SOURCES/glibc-rh1659438-19.patch @@ -0,0 +1,279 @@ +commit 970449311ded3cacb6058c96143dd4c057900589 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:11 2018 +0100 + + S390: Refactor stpcpy ifunc handling. + + The ifunc handling for stpcpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove stpcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add stpcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for stpcpy. + * sysdeps/s390/multiarch/stpcpy-c.c: Move to ... + * sysdeps/s390/stpcpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpcpy-vx.S: Move to ... + * sysdeps/s390/stpcpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpcpy.c: Move to ... + * sysdeps/s390/stpcpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-stpcpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index e4191319531ecb01..b7e1bc8aecf2f8c9 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -39,5 +39,6 @@ sysdep_routines += bzero memset memset-z900 \ + memmem memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ +- strcpy strcpy-vx strcpy-z900 ++ strcpy strcpy-vx strcpy-z900 \ ++ stpcpy stpcpy-vx stpcpy-c + endif +diff --git a/sysdeps/s390/ifunc-stpcpy.h b/sysdeps/s390/ifunc-stpcpy.h +new file mode 100644 +index 0000000000000000..9a70cd7c8c4f4582 +--- /dev/null ++++ b/sysdeps/s390/ifunc-stpcpy.h +@@ -0,0 +1,52 @@ ++/* stpcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STPCPY_IFUNC 1 ++#else ++# define HAVE_STPCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT HAVE_STPCPY_IFUNC ++#else ++# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STPCPY_DEFAULT STPCPY_Z13 ++# define HAVE_STPCPY_C 0 ++# define HAVE_STPCPY_Z13 1 ++#else ++# define STPCPY_DEFAULT STPCPY_C ++# define HAVE_STPCPY_C 1 ++# define HAVE_STPCPY_Z13 HAVE_STPCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STPCPY_C ++# define STPCPY_C __stpcpy_c ++#else ++# define STPCPY_C NULL ++#endif ++ ++#if HAVE_STPCPY_Z13 ++# define STPCPY_Z13 __stpcpy_vx ++#else ++# define STPCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 50f7f0b78df723bb..9517417dcbe1c701 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += stpcpy stpcpy-vx stpcpy-c \ +- strncpy strncpy-vx \ ++sysdep_routines += strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 1784372db9828463..678ed13833332f11 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -203,6 +204,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCPY_IFUNC */ + ++#if HAVE_STPCPY_IFUNC ++ IFUNC_IMPL (i, name, stpcpy, ++# if HAVE_STPCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, stpcpy, ++ dl_hwcap & HWCAP_S390_VX, STPCPY_Z13) ++# endif ++# if HAVE_STPCPY_C ++ IFUNC_IMPL_ADD (array, i, stpcpy, 1, STPCPY_C) ++# endif ++ ) ++#endif /* HAVE_STPCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -217,7 +230,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscpy); + +- IFUNC_VX_IMPL (stpcpy); + IFUNC_VX_IMPL (wcpcpy); + + IFUNC_VX_IMPL (strncpy); +diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/stpcpy-c.c +similarity index 74% +rename from sysdeps/s390/multiarch/stpcpy-c.c +rename to sysdeps/s390/stpcpy-c.c +index 4a1c3e5832c9b544..76ec88462717799c 100644 +--- a/sysdeps/s390/multiarch/stpcpy-c.c ++++ b/sysdeps/s390/stpcpy-c.c +@@ -16,20 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STPCPY __stpcpy_c +-# undef weak_alias +-# define weak_alias(a, b) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#include ++ ++#if HAVE_STPCPY_C ++# if HAVE_STPCPY_IFUNC ++# define STPCPY STPCPY_C ++ ++# undef weak_alias ++# define weak_alias(a, b) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ + __hidden_ver1 (__stpcpy_c, __GI___stpcpy, __stpcpy_c); +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + strong_alias (__stpcpy_c, __stpcpy_c_1); \ + __hidden_ver1 (__stpcpy_c_1, __GI_stpcpy, __stpcpy_c_1); +-# endif /* SHARED */ +- ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/stpcpy-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/stpcpy-vx.S +rename to sysdeps/s390/stpcpy-vx.S +index 6c17def0fc35d60d..d2db02d0cd714d27 100644 +--- a/sysdeps/s390/multiarch/stpcpy-vx.S ++++ b/sysdeps/s390/stpcpy-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__stpcpy_vx) ++ENTRY(STPCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -100,5 +102,15 @@ ENTRY(__stpcpy_vx) + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + la %r2,0(%r5,%r2) /* Return pointer to zero. */ + br %r14 +-END(__stpcpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STPCPY_Z13) ++ ++# if ! HAVE_STPCPY_IFUNC ++strong_alias (STPCPY_Z13, __stpcpy) ++weak_alias (__stpcpy, stpcpy) ++# endif ++ ++# if ! HAVE_STPCPY_C && defined SHARED && IS_IN (libc) ++strong_alias (STPCPY_Z13, __GI_stpcpy) ++strong_alias (STPCPY_Z13, __GI___stpcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/stpcpy.c +similarity index 74% +rename from sysdeps/s390/multiarch/stpcpy.c +rename to sysdeps/s390/stpcpy.c +index 654f9dfbef512e34..670604e2de3806b7 100644 +--- a/sysdeps/s390/multiarch/stpcpy.c ++++ b/sysdeps/s390/stpcpy.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPCPY_IFUNC + # define stpcpy __redirect_stpcpy + # define __stpcpy __redirect___stpcpy + /* Omit the stpcpy inline definitions because it would redefine stpcpy. */ +@@ -27,9 +29,18 @@ + # undef __stpcpy + # include + +-s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy); +-weak_alias (__stpcpy, stpcpy) ++# if HAVE_STPCPY_C ++extern __typeof (__redirect_stpcpy) STPCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STPCPY_Z13 ++extern __typeof (__redirect_stpcpy) STPCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___stpcpy, __stpcpy, ++ (HAVE_STPCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STPCPY_Z13 ++ : STPCPY_DEFAULT ++ ) ++weak_alias (__stpcpy, stpcpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-2.patch b/SOURCES/glibc-rh1659438-2.patch new file mode 100644 index 0000000..855686c --- /dev/null +++ b/SOURCES/glibc-rh1659438-2.patch @@ -0,0 +1,58 @@ +commit e8023f2685c9f97e72bbe9d2a9c968e0d8438371 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:03 2018 +0100 + + S390: Use hwcap instead of dl_hwcap in ifunc-resolvers. + + The renaming of hwcap arguments in ifunc-resolvers is needed + in order to prepare for further commits which refactors + ifunc handling for memset, memcmp, and memcpy. Now you are able + to use s390_libc_ifunc_init which stores the stfle bits + within the expression for an ifunc-resolver generated by + s390_libc_ifunc_expr. + + ChangeLog: + + * sysdeps/s390/multiarch/ifunc-resolve.h + (s390_libc_ifunc_init, s390_libc_ifunc, + s390_vx_libc_ifunc2_redirected): Use hwcap instead of dl_hwcap. + +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index b42ed922fd27834b..b7e20abc59638251 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -42,9 +42,9 @@ + : : "cc"); + #define s390_libc_ifunc_init() \ + unsigned long long stfle_bits = 0ULL; \ +- if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE) \ +- && (dl_hwcap & HWCAP_S390_ZARCH) \ +- && (dl_hwcap & HWCAP_S390_HIGH_GPRS))) \ ++ if (__glibc_likely ((hwcap & HWCAP_S390_STFLE) \ ++ && (hwcap & HWCAP_S390_ZARCH) \ ++ && (hwcap & HWCAP_S390_HIGH_GPRS))) \ + { \ + S390_STORE_STFLE (stfle_bits); \ + } +@@ -61,7 +61,7 @@ + : __glibc_likely (S390_IS_Z10 (stfle_bits)) \ + ? RESOLVERFUNC##_z10 \ + : RESOLVERFUNC##_default, \ +- unsigned long int dl_hwcap, s390_libc_ifunc_init); ++ unsigned long int hwcap, s390_libc_ifunc_init); + + #define s390_vx_libc_ifunc(FUNC) \ + s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC) +@@ -79,10 +79,10 @@ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden; \ + __ifunc (TYPE_FUNC, FUNC, \ +- (dl_hwcap & HWCAP_S390_VX) \ ++ (hwcap & HWCAP_S390_VX) \ + ? RESOLVERFUNC##_vx \ + : RESOLVERFUNC##_c, \ +- unsigned long int dl_hwcap, s390_vx_libc_ifunc_init); ++ unsigned long int hwcap, s390_vx_libc_ifunc_init); + + #define s390_libc_ifunc_expr_init() + #define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR) \ diff --git a/SOURCES/glibc-rh1659438-20.patch b/SOURCES/glibc-rh1659438-20.patch new file mode 100644 index 0000000..855354d --- /dev/null +++ b/SOURCES/glibc-rh1659438-20.patch @@ -0,0 +1,378 @@ +commit d1bdbf380908c34f31ba145ec9afebade3f1418f +Author: Stefan Liebler +Date: Tue Dec 18 13:57:11 2018 +0100 + + S390: Refactor strncpy ifunc handling. + + The ifunc handling for strncpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants are now moved to + the strncpy-z900.S files. The s390-32/s390-64 files multiarch/strncpy.c + and strncpy.S are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strncpy. + * sysdeps/s390/multiarch/strncpy-vx.S: Move to ... + * sysdeps/s390/strncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncpy.c: Move to ... + * sysdeps/s390/strncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strncpy.h: New file. + * sysdeps/s390/s390-64/strncpy.S: Move to ... + * sysdeps/s390/s390-64/strncpy-z900.S: ... here + and adjust ifunc handling. + * sysdeps/s390/s390-32/strncpy.S: Move to ... + * sysdeps/s390/s390-32/strncpy-z900.S: ... here + and adjust ifunc handling. + * sysdeps/s390/s390-32/multiarch/strncpy.c: Delete file. + * sysdeps/s390/s390-64/multiarch/strncpy.c: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index b7e1bc8aecf2f8c9..db060c81aade84ca 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -40,5 +40,6 @@ sysdep_routines += bzero memset memset-z900 \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx strcpy-z900 \ +- stpcpy stpcpy-vx stpcpy-c ++ stpcpy stpcpy-vx stpcpy-c \ ++ strncpy strncpy-vx strncpy-z900 + endif +diff --git a/sysdeps/s390/ifunc-strncpy.h b/sysdeps/s390/ifunc-strncpy.h +new file mode 100644 +index 0000000000000000..31e87e93c529c443 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strncpy.h +@@ -0,0 +1,52 @@ ++/* strncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNCPY_IFUNC 1 ++#else ++# define HAVE_STRNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT HAVE_STRNCPY_IFUNC ++#else ++# define HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNCPY_DEFAULT STRNCPY_Z13 ++# define HAVE_STRNCPY_Z900_G5 0 ++# define HAVE_STRNCPY_Z13 1 ++#else ++# define STRNCPY_DEFAULT STRNCPY_Z900_G5 ++# define HAVE_STRNCPY_Z900_G5 1 ++# define HAVE_STRNCPY_Z13 HAVE_STRNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNCPY_Z900_G5 ++# define STRNCPY_Z900_G5 __strncpy_default ++#else ++# define STRNCPY_Z900_G5 NULL ++#endif ++ ++#if HAVE_STRNCPY_Z13 ++# define STRNCPY_Z13 __strncpy_vx ++#else ++# define STRNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 9517417dcbe1c701..c5189b556cf3762d 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strncpy strncpy-vx \ +- stpncpy stpncpy-vx stpncpy-c \ ++sysdep_routines += stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 678ed13833332f11..d598fc5c22050da2 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -216,6 +217,19 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STPCPY_IFUNC */ + ++#if HAVE_STRNCPY_IFUNC ++ IFUNC_IMPL (i, name, strncpy, ++# if HAVE_STRNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, strncpy, ++ dl_hwcap & HWCAP_S390_VX, STRNCPY_Z13) ++# endif ++# if HAVE_STRNCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, strncpy, 1, STRNCPY_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_STRNCPY_IFUNC */ ++ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -232,7 +246,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcpcpy); + +- IFUNC_VX_IMPL (strncpy); + IFUNC_VX_IMPL (wcsncpy); + + IFUNC_VX_IMPL (stpncpy); +diff --git a/sysdeps/s390/s390-32/multiarch/strncpy.c b/sysdeps/s390/s390-32/multiarch/strncpy.c +deleted file mode 100644 +index 57f9df18d12c1959..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/strncpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strncpy. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strncpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-32/strncpy.S b/sysdeps/s390/s390-32/strncpy-z900.S +similarity index 89% +rename from sysdeps/s390/s390-32/strncpy.S +rename to sysdeps/s390/s390-32/strncpy-z900.S +index 9086eb1c707bdfb3..ebdaba015214bc59 100644 +--- a/sysdeps/s390/s390-32/strncpy.S ++++ b/sysdeps/s390/s390-32/strncpy-z900.S +@@ -24,10 +24,12 @@ + * R4 = max of bytes to copy + */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + +-ENTRY(strncpy) ++#if HAVE_STRNCPY_Z900_G5 ++ENTRY(STRNCPY_Z900_G5) + .text + st %r2,24(%r15) # save dst pointer + slr %r2,%r3 # %r3 points to src, %r2+%r3 to dst +@@ -75,5 +77,13 @@ ENTRY(strncpy) + jo .L9 + .Lexit: l %r2,24(%r15) # return dst pointer + br %r14 +-END(strncpy) +-libc_hidden_builtin_def (strncpy) ++END(STRNCPY_Z900_G5) ++ ++# if ! HAVE_STRNCPY_IFUNC ++strong_alias (STRNCPY_Z900_G5, strncpy) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRNCPY_Z900_G5, __GI_strncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/multiarch/strncpy.c b/sysdeps/s390/s390-64/multiarch/strncpy.c +deleted file mode 100644 +index 57f9df18d12c1959..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/strncpy.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strncpy. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strncpy.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-64/strncpy.S b/sysdeps/s390/s390-64/strncpy-z900.S +similarity index 90% +rename from sysdeps/s390/s390-64/strncpy.S +rename to sysdeps/s390/s390-64/strncpy-z900.S +index be40aa32d5d9a2df..5732e6d83b5e8f30 100644 +--- a/sysdeps/s390/s390-64/strncpy.S ++++ b/sysdeps/s390/s390-64/strncpy-z900.S +@@ -23,10 +23,12 @@ + %r3 = address of source (src) + %r4 = max of bytes to copy. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + +-ENTRY(strncpy) ++#if HAVE_STRNCPY_Z900_G5 ++ENTRY(STRNCPY_Z900_G5) + .text + stg %r2,48(%r15) # save dst pointer + slgr %r2,%r3 # %r3 points to src, %r2+%r3 to dst +@@ -86,5 +88,13 @@ ENTRY(strncpy) + jo .L13 + .Lexit: lg %r2,48(%r15) # return dst pointer + br %r14 +-END(strncpy) +-libc_hidden_builtin_def (strncpy) ++END(STRNCPY_Z900_G5) ++ ++# if ! HAVE_STRNCPY_IFUNC ++strong_alias (STRNCPY_Z900_G5, strncpy) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRNCPY_Z900_G5, __GI_strncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strncpy-vx.S b/sysdeps/s390/strncpy-vx.S +similarity index 93% +rename from sysdeps/s390/multiarch/strncpy-vx.S +rename to sysdeps/s390/strncpy-vx.S +index 2a37b7b84e0a2514..be09ddf092388c72 100644 +--- a/sysdeps/s390/multiarch/strncpy-vx.S ++++ b/sysdeps/s390/strncpy-vx.S +@@ -16,13 +16,13 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +- +-# include "sysdep.h" +-# include "asm-syntax.h" ++#include ++#include "sysdep.h" ++#include "asm-syntax.h" + + .text + ++#if HAVE_STRNCPY_Z13 + /* char * strncpy (const char *dest, const char *src, size_t n) + Copy at most n characters of string src to dest. + +@@ -40,7 +40,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__strncpy_vx) ++ENTRY(STRNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -196,12 +196,13 @@ ENTRY(__strncpy_vx) + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 +-END(__strncpy_vx) ++END(STRNCPY_Z13) + +-# define strncpy __strncpy_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__strncpy_c, __GI_strncpy) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_STRNCPY_IFUNC ++strong_alias (STRNCPY_Z13, strncpy) ++# endif + +-/* Include strncpy-implementation in s390-32/s390-64 subdirectory. */ +-#include ++# if ! HAVE_STRNCPY_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (STRNCPY_Z13, __GI_strncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/strncpy.c +similarity index 71% +rename from sysdeps/s390/multiarch/strncpy.c +rename to sysdeps/s390/strncpy.c +index 2d4c456d96dad0d6..ec8a26471b6536e8 100644 +--- a/sysdeps/s390/multiarch/strncpy.c ++++ b/sysdeps/s390/strncpy.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCPY_IFUNC + # define strncpy __redirect_strncpy + /* Omit the strncpy inline definitions because it would redefine strncpy. */ + # define __NO_STRING_INLINES +@@ -24,6 +26,17 @@ + # undef strncpy + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strncpy, __strncpy, strncpy); ++# if HAVE_STRNCPY_Z900_G5 ++extern __typeof (__redirect_strncpy) STRNCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_STRNCPY_Z13 ++extern __typeof (__redirect_strncpy) STRNCPY_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_strncpy, strncpy, ++ (HAVE_STRNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNCPY_Z13 ++ : STRNCPY_DEFAULT ++ ) + #endif diff --git a/SOURCES/glibc-rh1659438-21.patch b/SOURCES/glibc-rh1659438-21.patch new file mode 100644 index 0000000..91393ae --- /dev/null +++ b/SOURCES/glibc-rh1659438-21.patch @@ -0,0 +1,267 @@ +commit 25218822bdbfb49b8ea0f419e8a20d2b9bd47cd0 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:11 2018 +0100 + + S390: Refactor stpncpy ifunc handling. + + The ifunc handling for stpncpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove stpncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add stpncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for stpncpy. + * sysdeps/s390/multiarch/stpncpy-c.c: Move to ... + * sysdeps/s390/stpncpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpncpy-vx.S: Move to ... + * sysdeps/s390/stpncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/stpncpy.c: Move to ... + * sysdeps/s390/stpncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-stpncpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index db060c81aade84ca..a9882b3996c30322 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -41,5 +41,6 @@ sysdep_routines += bzero memset memset-z900 \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx strcpy-z900 \ + stpcpy stpcpy-vx stpcpy-c \ +- strncpy strncpy-vx strncpy-z900 ++ strncpy strncpy-vx strncpy-z900 \ ++ stpncpy stpncpy-vx stpncpy-c + endif +diff --git a/sysdeps/s390/ifunc-stpncpy.h b/sysdeps/s390/ifunc-stpncpy.h +new file mode 100644 +index 0000000000000000..46e57334e8439c1c +--- /dev/null ++++ b/sysdeps/s390/ifunc-stpncpy.h +@@ -0,0 +1,52 @@ ++/* stpncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STPNCPY_IFUNC 1 ++#else ++# define HAVE_STPNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT HAVE_STPNCPY_IFUNC ++#else ++# define HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STPNCPY_DEFAULT STPNCPY_Z13 ++# define HAVE_STPNCPY_C 0 ++# define HAVE_STPNCPY_Z13 1 ++#else ++# define STPNCPY_DEFAULT STPNCPY_C ++# define HAVE_STPNCPY_C 1 ++# define HAVE_STPNCPY_Z13 HAVE_STPNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STPNCPY_C ++# define STPNCPY_C __stpncpy_c ++#else ++# define STPNCPY_C NULL ++#endif ++ ++#if HAVE_STPNCPY_Z13 ++# define STPNCPY_Z13 __stpncpy_vx ++#else ++# define STPNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c5189b556cf3762d..3d97d21da1fc852b 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += stpncpy stpncpy-vx stpncpy-c \ +- strcat strcat-vx strcat-c \ ++sysdep_routines += strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index d598fc5c22050da2..021e9f247fff44df 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -229,6 +230,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNCPY_IFUNC */ + ++#if HAVE_STPNCPY_IFUNC ++ IFUNC_IMPL (i, name, stpncpy, ++# if HAVE_STPNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, stpncpy, ++ dl_hwcap & HWCAP_S390_VX, STPNCPY_Z13) ++# endif ++# if HAVE_STPNCPY_C ++ IFUNC_IMPL_ADD (array, i, stpncpy, 1, STPNCPY_C) ++# endif ++ ) ++#endif /* HAVE_STPNCPY_IFUNC */ ++ + + #ifdef HAVE_S390_VX_ASM_SUPPORT + +@@ -248,7 +261,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsncpy); + +- IFUNC_VX_IMPL (stpncpy); + IFUNC_VX_IMPL (wcpncpy); + + IFUNC_VX_IMPL (strcat); +diff --git a/sysdeps/s390/multiarch/stpncpy-c.c b/sysdeps/s390/stpncpy-c.c +similarity index 74% +rename from sysdeps/s390/multiarch/stpncpy-c.c +rename to sysdeps/s390/stpncpy-c.c +index 45e50aa9e7df0b5e..e5d1ae867562da6c 100644 +--- a/sysdeps/s390/multiarch/stpncpy-c.c ++++ b/sysdeps/s390/stpncpy-c.c +@@ -16,13 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STPNCPY __stpncpy_c +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STPNCPY_C ++# if HAVE_STPNCPY_IFUNC ++# define STPNCPY STPNCPY_C ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/stpncpy-vx.S b/sysdeps/s390/stpncpy-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/stpncpy-vx.S +rename to sysdeps/s390/stpncpy-vx.S +index 922bd7a355a2d8a0..3dccc10be3b58d8d 100644 +--- a/sysdeps/s390/multiarch/stpncpy-vx.S ++++ b/sysdeps/s390/stpncpy-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPNCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +40,7 @@ + -%r6 = loaded bytes + -%r7 = border, tmp + */ +-ENTRY(__stpncpy_vx) ++ENTRY(STPNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -196,5 +198,14 @@ ENTRY(__stpncpy_vx) + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 +-END(__stpncpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STPNCPY_Z13) ++ ++# if ! HAVE_STPNCPY_IFUNC ++strong_alias (STPNCPY_Z13, __stpncpy) ++weak_alias (__stpncpy, stpncpy) ++# endif ++ ++# if ! HAVE_STPNCPY_C && defined SHARED && IS_IN (libc) ++strong_alias (STPNCPY_Z13, __GI___stpncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/stpncpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/stpncpy.c +rename to sysdeps/s390/stpncpy.c +index f7f9d51a50db47d7..250dc68ed19bf6d9 100644 +--- a/sysdeps/s390/multiarch/stpncpy.c ++++ b/sysdeps/s390/stpncpy.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STPNCPY_IFUNC + # define stpncpy __redirect_stpncpy + # define __stpncpy __redirect___stpncpy + # include +@@ -24,9 +26,18 @@ + # undef __stpncpy + # include + +-s390_vx_libc_ifunc_redirected (__redirect___stpncpy, __stpncpy) +-weak_alias (__stpncpy, stpncpy) ++# if HAVE_STPNCPY_C ++extern __typeof (__redirect_stpncpy) STPNCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STPNCPY_Z13 ++extern __typeof (__redirect_stpncpy) STPNCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___stpncpy, __stpncpy, ++ (HAVE_STPNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STPNCPY_Z13 ++ : STPNCPY_DEFAULT ++ ) ++weak_alias (__stpncpy, stpncpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-22.patch b/SOURCES/glibc-rh1659438-22.patch new file mode 100644 index 0000000..3e74480 --- /dev/null +++ b/SOURCES/glibc-rh1659438-22.patch @@ -0,0 +1,259 @@ +commit 8e5a0afbbf0a96fb873e27aa064c9bacc9cfd9c6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:12 2018 +0100 + + S390: Refactor strcat ifunc handling. + + The ifunc handling for strcat is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcat. + * sysdeps/s390/multiarch/strcat-c.c: Move to ... + * sysdeps/s390/strcat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcat-vx.S: Move to ... + * sysdeps/s390/strcat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcat.c: Move to ... + * sysdeps/s390/strcat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index a9882b3996c30322..de2d5e5652dde412 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -42,5 +42,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcpy strcpy-vx strcpy-z900 \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx strncpy-z900 \ +- stpncpy stpncpy-vx stpncpy-c ++ stpncpy stpncpy-vx stpncpy-c \ ++ strcat strcat-vx strcat-c + endif +diff --git a/sysdeps/s390/ifunc-strcat.h b/sysdeps/s390/ifunc-strcat.h +new file mode 100644 +index 0000000000000000..6fd2f7dd31fff64f +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcat.h +@@ -0,0 +1,52 @@ ++/* strcat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCAT_IFUNC 1 ++#else ++# define HAVE_STRCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCAT_IFUNC_AND_VX_SUPPORT HAVE_STRCAT_IFUNC ++#else ++# define HAVE_STRCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCAT_DEFAULT STRCAT_Z13 ++# define HAVE_STRCAT_C 0 ++# define HAVE_STRCAT_Z13 1 ++#else ++# define STRCAT_DEFAULT STRCAT_C ++# define HAVE_STRCAT_C 1 ++# define HAVE_STRCAT_Z13 HAVE_STRCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCAT_C ++# define STRCAT_C __strcat_c ++#else ++# define STRCAT_C NULL ++#endif ++ ++#if HAVE_STRCAT_Z13 ++# define STRCAT_Z13 __strcat_vx ++#else ++# define STRCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3d97d21da1fc852b..9b66237aaf9eb47e 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcat strcat-vx strcat-c \ +- strncat strncat-vx strncat-c \ ++sysdep_routines += strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 021e9f247fff44df..1b7f3df3a3cfe561 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -242,6 +243,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STPNCPY_IFUNC */ + ++#if HAVE_STRCAT_IFUNC ++ IFUNC_IMPL (i, name, strcat, ++# if HAVE_STRCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, strcat, ++ dl_hwcap & HWCAP_S390_VX, STRCAT_Z13) ++# endif ++# if HAVE_STRCAT_C ++ IFUNC_IMPL_ADD (array, i, strcat, 1, STRCAT_C) ++# endif ++ ) ++#endif /* HAVE_STRCAT_IFUNC */ + + #ifdef HAVE_S390_VX_ASM_SUPPORT + +@@ -263,7 +275,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcpncpy); + +- IFUNC_VX_IMPL (strcat); + IFUNC_VX_IMPL (wcscat); + + IFUNC_VX_IMPL (strncat); +diff --git a/sysdeps/s390/multiarch/strcat-c.c b/sysdeps/s390/strcat-c.c +similarity index 73% +rename from sysdeps/s390/multiarch/strcat-c.c +rename to sysdeps/s390/strcat-c.c +index f871faa7b563e74b..7accc6c7ef80ecf2 100644 +--- a/sysdeps/s390/multiarch/strcat-c.c ++++ b/sysdeps/s390/strcat-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCAT __strcat_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STRCAT_C ++# if HAVE_STRCAT_IFUNC ++# define STRCAT STRCAT_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strcat-vx.S b/sysdeps/s390/strcat-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/strcat-vx.S +rename to sysdeps/s390/strcat-vx.S +index 3abbbcccedad0eb4..218e301f10c6abe3 100644 +--- a/sysdeps/s390/multiarch/strcat-vx.S ++++ b/sysdeps/s390/strcat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__strcat_vx) ++ENTRY(STRCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -157,5 +158,13 @@ ENTRY(__strcat_vx) + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 +-END(__strcat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCAT_Z13) ++ ++# if ! HAVE_STRCAT_IFUNC ++strong_alias (STRCAT_Z13, strcat) ++# endif ++ ++# if ! HAVE_STRCAT_C && defined SHARED && IS_IN (libc) ++strong_alias (STRCAT_Z13, __GI_strcat) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/strcat.c +similarity index 69% +rename from sysdeps/s390/multiarch/strcat.c +rename to sysdeps/s390/strcat.c +index 7d4126b44f23679a..d378519c8af59620 100644 +--- a/sysdeps/s390/multiarch/strcat.c ++++ b/sysdeps/s390/strcat.c +@@ -16,14 +16,25 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCAT_IFUNC + # define strcat __redirect_strcat + # include + # undef strcat + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat) ++# if HAVE_STRCAT_C ++extern __typeof (__redirect_strcat) STRCAT_C attribute_hidden; ++# endif ++ ++# if HAVE_STRCAT_Z13 ++extern __typeof (__redirect_strcat) STRCAT_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strcat, strcat, ++ (HAVE_STRCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCAT_Z13 ++ : STRCAT_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-23.patch b/SOURCES/glibc-rh1659438-23.patch new file mode 100644 index 0000000..46f3173 --- /dev/null +++ b/SOURCES/glibc-rh1659438-23.patch @@ -0,0 +1,252 @@ +commit b935335155d65971fe2a54e32c0eb74303d4e4fc +Author: Stefan Liebler +Date: Tue Dec 18 13:57:12 2018 +0100 + + S390: Refactor strncat ifunc handling. + + The ifunc handling for strncat is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strncat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strncat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strncat. + * sysdeps/s390/multiarch/strncat-c.c: Move to ... + * sysdeps/s390/strncat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncat-vx.S: Move to ... + * sysdeps/s390/strncat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncat.c: Move to ... + * sysdeps/s390/strncat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strncat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index de2d5e5652dde412..cb5dc1d4f95fd11c 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -43,5 +43,6 @@ sysdep_routines += bzero memset memset-z900 \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx strncpy-z900 \ + stpncpy stpncpy-vx stpncpy-c \ +- strcat strcat-vx strcat-c ++ strcat strcat-vx strcat-c \ ++ strncat strncat-vx strncat-c + endif +diff --git a/sysdeps/s390/ifunc-strncat.h b/sysdeps/s390/ifunc-strncat.h +new file mode 100644 +index 0000000000000000..bb164dcc32905b18 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strncat.h +@@ -0,0 +1,52 @@ ++/* strncat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNCAT_IFUNC 1 ++#else ++# define HAVE_STRNCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT HAVE_STRNCAT_IFUNC ++#else ++# define HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNCAT_DEFAULT STRNCAT_Z13 ++# define HAVE_STRNCAT_C 0 ++# define HAVE_STRNCAT_Z13 1 ++#else ++# define STRNCAT_DEFAULT STRNCAT_C ++# define HAVE_STRNCAT_C 1 ++# define HAVE_STRNCAT_Z13 HAVE_STRNCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNCAT_C ++# define STRNCAT_C __strncat_c ++#else ++# define STRNCAT_C NULL ++#endif ++ ++#if HAVE_STRNCAT_Z13 ++# define STRNCAT_Z13 __strncat_vx ++#else ++# define STRNCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 9b66237aaf9eb47e..24be3eac5131fd4a 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strncat strncat-vx strncat-c \ +- strcmp strcmp-vx \ ++sysdep_routines += strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 1b7f3df3a3cfe561..3abcaf08e0ccd385 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -255,6 +256,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCAT_IFUNC */ + ++#if HAVE_STRNCAT_IFUNC ++ IFUNC_IMPL (i, name, strncat, ++# if HAVE_STRNCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, strncat, ++ dl_hwcap & HWCAP_S390_VX, STRNCAT_Z13) ++# endif ++# if HAVE_STRNCAT_C ++ IFUNC_IMPL_ADD (array, i, strncat, 1, STRNCAT_C) ++# endif ++ ) ++#endif /* HAVE_STRNCAT_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -277,7 +290,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscat); + +- IFUNC_VX_IMPL (strncat); + IFUNC_VX_IMPL (wcsncat); + + IFUNC_VX_IMPL (strcmp); +diff --git a/sysdeps/s390/multiarch/strncat-c.c b/sysdeps/s390/strncat-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/strncat-c.c +rename to sysdeps/s390/strncat-c.c +index 9e6c245ccbbc2e23..86df89887c7b6293 100644 +--- a/sysdeps/s390/multiarch/strncat-c.c ++++ b/sysdeps/s390/strncat-c.c +@@ -16,8 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRNCAT __strncat_c +-# define STRNCAT_PRIMARY ++#include ++ ++#if HAVE_STRNCAT_C ++# if HAVE_STRNCAT_IFUNC ++# define STRNCAT STRNCAT_C ++# define STRNCAT_PRIMARY ++# endif + # include + #endif +diff --git a/sysdeps/s390/multiarch/strncat-vx.S b/sysdeps/s390/strncat-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/strncat-vx.S +rename to sysdeps/s390/strncat-vx.S +index e6584d0f438f0e38..76345e7dd702dd85 100644 +--- a/sysdeps/s390/multiarch/strncat-vx.S ++++ b/sysdeps/s390/strncat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRNCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +41,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__strncat_vx) ++ENTRY(STRNCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -235,5 +236,17 @@ ENTRY(__strncat_vx) + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Lcpy_lt64 +-END(__strncat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRNCAT_Z13) ++ ++# if ! HAVE_STRNCAT_IFUNC ++strong_alias (STRNCAT_Z13, strncat) ++# endif ++ ++# if ! HAVE_STRNCAT_C ++/* See string/strncat.c and define STRNCAT_PRIMARY. */ ++strong_alias (STRNCAT_Z13, __strncat) ++# if defined SHARED && IS_IN (libc) ++strong_alias (__strncat, __GI___strncat) ++# endif ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strncat.c b/sysdeps/s390/strncat.c +similarity index 69% +rename from sysdeps/s390/multiarch/strncat.c +rename to sysdeps/s390/strncat.c +index 94b8dffa85420cfa..b4b3656c5ae9c535 100644 +--- a/sysdeps/s390/multiarch/strncat.c ++++ b/sysdeps/s390/strncat.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCAT_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__strncat, strncat) ++# if HAVE_STRNCAT_C ++extern __typeof (__strncat) STRNCAT_C attribute_hidden; ++# endif ++ ++# if HAVE_STRNCAT_Z13 ++extern __typeof (__strncat) STRNCAT_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__strncat, strncat, ++ (HAVE_STRNCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNCAT_Z13 ++ : STRNCAT_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-24.patch b/SOURCES/glibc-rh1659438-24.patch new file mode 100644 index 0000000..b0f4be8 --- /dev/null +++ b/SOURCES/glibc-rh1659438-24.patch @@ -0,0 +1,394 @@ +commit cdab85fe33b0443a645509cbb5b929a0d3307f18 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:13 2018 +0100 + + S390: Refactor strcmp ifunc handling. + + The ifunc handling for strcmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants with clst instruction + are now moved to the unified strcmp-z900.S file which can be used for + 31/64bit. The s390-32/s390-64 files multiarch/strcmp.c and strcmp.S + are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcmp. + * sysdeps/s390/multiarch/strcmp-vx.S: Move to ... + * sysdeps/s390/strcmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcmp.c: Move to ... + * sysdeps/s390/strcmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcmp.h: New file. + * sysdeps/s390/s390-64/strcmp.S: Move to ... + * sysdeps/s390/strcmp-z900.S: ... here and adjust to be usable + for 31/64bit and ifunc handling. + * sysdeps/s390/s390-32/multiarch/strcmp.c: Delete file. + * sysdeps/s390/s390-64/multiarch/strcmp.c: Likewise. + * sysdeps/s390/s390-32/strcmp.S: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index cb5dc1d4f95fd11c..71a4658b43aeb745 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -44,5 +44,6 @@ sysdep_routines += bzero memset memset-z900 \ + strncpy strncpy-vx strncpy-z900 \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ +- strncat strncat-vx strncat-c ++ strncat strncat-vx strncat-c \ ++ strcmp strcmp-vx strcmp-z900 + endif +diff --git a/sysdeps/s390/ifunc-strcmp.h b/sysdeps/s390/ifunc-strcmp.h +new file mode 100644 +index 0000000000000000..86ffe686ade52b64 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcmp.h +@@ -0,0 +1,52 @@ ++/* strcmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCMP_IFUNC 1 ++#else ++# define HAVE_STRCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCMP_IFUNC_AND_VX_SUPPORT HAVE_STRCMP_IFUNC ++#else ++# define HAVE_STRCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCMP_DEFAULT STRCMP_Z13 ++# define HAVE_STRCMP_Z900_G5 0 ++# define HAVE_STRCMP_Z13 1 ++#else ++# define STRCMP_DEFAULT STRCMP_Z900_G5 ++# define HAVE_STRCMP_Z900_G5 1 ++# define HAVE_STRCMP_Z13 HAVE_STRCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCMP_Z900_G5 ++# define STRCMP_Z900_G5 __strcmp_default ++#else ++# define STRCMP_Z900_G5 NULL ++#endif ++ ++#if HAVE_STRCMP_Z13 ++# define STRCMP_Z13 __strcmp_vx ++#else ++# define STRCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 24be3eac5131fd4a..97421a499625c7f2 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcmp strcmp-vx \ +- strncmp strncmp-vx strncmp-c \ ++sysdep_routines += strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 3abcaf08e0ccd385..44637c431b144c66 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -268,6 +269,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNCAT_IFUNC */ + ++#if HAVE_STRCMP_IFUNC ++ IFUNC_IMPL (i, name, strcmp, ++# if HAVE_STRCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, strcmp, ++ dl_hwcap & HWCAP_S390_VX, STRCMP_Z13) ++# endif ++# if HAVE_STRCMP_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, strcmp, 1, STRCMP_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_STRCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -292,7 +305,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsncat); + +- IFUNC_VX_IMPL (strcmp); + IFUNC_VX_IMPL (wcscmp); + + IFUNC_VX_IMPL (strncmp); +diff --git a/sysdeps/s390/s390-32/multiarch/strcmp.c b/sysdeps/s390/s390-32/multiarch/strcmp.c +deleted file mode 100644 +index d06b0f3436b2abfd..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/strcmp.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcmp. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcmp.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-32/strcmp.S b/sysdeps/s390/s390-32/strcmp.S +deleted file mode 100644 +index 3cf3f239fddccce8..0000000000000000 +--- a/sysdeps/s390/s390-32/strcmp.S ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* strcmp - compare two string. S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2001-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of string 1 +- %r3 = address of string 2. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(strcmp) +- slr %r0,%r0 +-0: clst %r2,%r3 +- jo 0b +- jp 1f +- jm 2f +- slr %r2,%r2 +- br %r14 +-1: lhi %r2,1 +- br %r14 +-2: lhi %r2,-1 +- br %r14 +-END(strcmp) +-libc_hidden_builtin_def (strcmp) +diff --git a/sysdeps/s390/s390-64/multiarch/strcmp.c b/sysdeps/s390/s390-64/multiarch/strcmp.c +deleted file mode 100644 +index d06b0f3436b2abfd..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/strcmp.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of strcmp. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/strcmp.S will be used. */ +-#include +diff --git a/sysdeps/s390/multiarch/strcmp-vx.S b/sysdeps/s390/strcmp-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strcmp-vx.S +rename to sysdeps/s390/strcmp-vx.S +index bcaeb564d47c58ff..801ad9d32bbd76c0 100644 +--- a/sysdeps/s390/multiarch/strcmp-vx.S ++++ b/sysdeps/s390/strcmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_STRCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +37,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__strcmp_vx) ++ENTRY(STRCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -106,11 +107,13 @@ ENTRY(__strcmp_vx) + .Lend_equal: + lghi %r2,0 + br %r14 +-END(__strcmp_vx) ++END(STRCMP_Z13) + +-# define strcmp __strcmp_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__strcmp_c, __GI_strcmp) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_STRCMP_IFUNC ++strong_alias (STRCMP_Z13, strcmp) ++# endif + +-#include ++# if ! HAVE_STRCMP_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (STRCMP_Z13, __GI_strcmp) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/strcmp.S b/sysdeps/s390/strcmp-z900.S +similarity index 70% +rename from sysdeps/s390/s390-64/strcmp.S +rename to sysdeps/s390/strcmp-z900.S +index 6cf1addd8bdf1a19..67b3c8b2e5989cd2 100644 +--- a/sysdeps/s390/s390-64/strcmp.S ++++ b/sysdeps/s390/strcmp-z900.S +@@ -21,21 +21,39 @@ + %r2 = address of string 1 + %r3 = address of string 2. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + ++#if HAVE_STRCMP_Z900_G5 ++# if defined __s390x__ ++# define SLGR slgr ++# define LGHI lghi ++# else ++# define SLGR slr ++# define LGHI lhi ++# endif /* ! defined __s390x__ */ ++ + .text +-ENTRY(strcmp) +- slr %r0,%r0 ++ENTRY(STRCMP_Z900_G5) ++ SLGR %r0,%r0 + 0: clst %r2,%r3 + jo 0b + jp 1f + jm 2f +- slgr %r2,%r2 ++ SLGR %r2,%r2 + br %r14 +-1: lghi %r2,1 ++1: LGHI %r2,1 + br %r14 +-2: lghi %r2,-1 ++2: LGHI %r2,-1 + br %r14 +-END(strcmp) +-libc_hidden_builtin_def (strcmp) ++END(STRCMP_Z900_G5) ++ ++# if ! HAVE_STRCMP_IFUNC ++strong_alias (STRCMP_Z900_G5, strcmp) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (STRCMP_Z900_G5, __GI_strcmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/strcmp.c +similarity index 71% +rename from sysdeps/s390/multiarch/strcmp.c +rename to sysdeps/s390/strcmp.c +index 7c8b17b3041dd549..9efa30acaf21f4e8 100644 +--- a/sysdeps/s390/multiarch/strcmp.c ++++ b/sysdeps/s390/strcmp.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCMP_IFUNC + # define strcmp __redirect_strcmp + /* Omit the strcmp inline definitions because it would redefine strcmp. */ + # define __NO_STRING_INLINES +@@ -24,6 +26,17 @@ + # include + # undef strcmp + +-s390_vx_libc_ifunc2_redirected (__redirect_strcmp, __strcmp, strcmp) ++# if HAVE_STRCMP_Z900_G5 ++extern __typeof (__redirect_strcmp) STRCMP_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_STRCMP_Z13 ++extern __typeof (__redirect_strcmp) STRCMP_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_strcmp, strcmp, ++ (HAVE_STRCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCMP_Z13 ++ : STRCMP_DEFAULT ++ ) + #endif diff --git a/SOURCES/glibc-rh1659438-25.patch b/SOURCES/glibc-rh1659438-25.patch new file mode 100644 index 0000000..afe7ad0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-25.patch @@ -0,0 +1,263 @@ +commit 316b88421993d540513a6b25b59ec16df267e9b4 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:13 2018 +0100 + + S390: Refactor strncmp ifunc handling. + + The ifunc handling for strncmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strncmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strncmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strncmp. + * sysdeps/s390/multiarch/strncmp-c.c: Move to ... + * sysdeps/s390/strncmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncmp-vx.S: Move to ... + * sysdeps/s390/strncmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strncmp.c: Move to ... + * sysdeps/s390/strncmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strncmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 71a4658b43aeb745..adf3521876725ac8 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -45,5 +45,6 @@ sysdep_routines += bzero memset memset-z900 \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ +- strcmp strcmp-vx strcmp-z900 ++ strcmp strcmp-vx strcmp-z900 \ ++ strncmp strncmp-vx strncmp-c + endif +diff --git a/sysdeps/s390/ifunc-strncmp.h b/sysdeps/s390/ifunc-strncmp.h +new file mode 100644 +index 0000000000000000..511b3e9720520a0c +--- /dev/null ++++ b/sysdeps/s390/ifunc-strncmp.h +@@ -0,0 +1,52 @@ ++/* strncmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRNCMP_IFUNC 1 ++#else ++# define HAVE_STRNCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT HAVE_STRNCMP_IFUNC ++#else ++# define HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRNCMP_DEFAULT STRNCMP_Z13 ++# define HAVE_STRNCMP_C 0 ++# define HAVE_STRNCMP_Z13 1 ++#else ++# define STRNCMP_DEFAULT STRNCMP_C ++# define HAVE_STRNCMP_C 1 ++# define HAVE_STRNCMP_Z13 HAVE_STRNCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRNCMP_C ++# define STRNCMP_C __strncmp_c ++#else ++# define STRNCMP_C NULL ++#endif ++ ++#if HAVE_STRNCMP_Z13 ++# define STRNCMP_Z13 __strncmp_vx ++#else ++# define STRNCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 97421a499625c7f2..381376bf9fcb0f58 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strncmp strncmp-vx strncmp-c \ +- strchr strchr-vx strchr-c \ ++sysdep_routines += strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 44637c431b144c66..d982de5788c0b5d5 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -281,6 +282,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCMP_IFUNC */ + ++#if HAVE_STRNCMP_IFUNC ++ IFUNC_IMPL (i, name, strncmp, ++# if HAVE_STRNCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, strncmp, ++ dl_hwcap & HWCAP_S390_VX, STRNCMP_Z13) ++# endif ++# if HAVE_STRNCMP_C ++ IFUNC_IMPL_ADD (array, i, strncmp, 1, STRNCMP_C) ++# endif ++ ) ++#endif /* HAVE_STRNCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -307,7 +320,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscmp); + +- IFUNC_VX_IMPL (strncmp); + IFUNC_VX_IMPL (wcsncmp); + + IFUNC_VX_IMPL (strchr); +diff --git a/sysdeps/s390/multiarch/strncmp-c.c b/sysdeps/s390/strncmp-c.c +similarity index 78% +rename from sysdeps/s390/multiarch/strncmp-c.c +rename to sysdeps/s390/strncmp-c.c +index e54277ec1b10f8d7..c7ffdb03e37dc8d8 100644 +--- a/sysdeps/s390/multiarch/strncmp-c.c ++++ b/sysdeps/s390/strncmp-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRNCMP __strncmp_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRNCMP_C ++# if HAVE_STRNCMP_IFUNC ++# define STRNCMP STRNCMP_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strncmp_c, __GI_strncmp, __strncmp_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strncmp-vx.S b/sysdeps/s390/strncmp-vx.S +similarity index 93% +rename from sysdeps/s390/multiarch/strncmp-vx.S +rename to sysdeps/s390/strncmp-vx.S +index 168fd657da2a1173..f557afb336d418ff 100644 +--- a/sysdeps/s390/multiarch/strncmp-vx.S ++++ b/sysdeps/s390/strncmp-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +39,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__strncmp_vx) ++ENTRY(STRNCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -133,5 +135,14 @@ ENTRY(__strncmp_vx) + .Lend_equal: + lghi %r2,0 + br %r14 +-END(__strncmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRNCMP_Z13) ++ ++# if ! HAVE_STRNCMP_IFUNC ++strong_alias (STRNCMP_Z13, strncmp) ++# endif ++ ++# if ! HAVE_STRNCMP_C && defined SHARED && IS_IN (libc) ++strong_alias (STRNCMP_Z13, __GI_strncmp) ++# endif ++ ++#endif /* HAVE_STRNCMP_Z13 */ +diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/strncmp.c +similarity index 70% +rename from sysdeps/s390/multiarch/strncmp.c +rename to sysdeps/s390/strncmp.c +index 0ec472c3b03419a3..71351273c4058129 100644 +--- a/sysdeps/s390/multiarch/strncmp.c ++++ b/sysdeps/s390/strncmp.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRNCMP_IFUNC + # define strncmp __redirect_strncmp + /* Omit the strncmp inline definitions because it would redefine strncmp. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strncmp + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp) ++# if HAVE_STRNCMP_C ++extern __typeof (__redirect_strncmp) STRNCMP_C attribute_hidden; ++# endif ++ ++# if HAVE_STRNCMP_Z13 ++extern __typeof (__redirect_strncmp) STRNCMP_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strncmp, strncmp, ++ (HAVE_STRNCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRNCMP_Z13 ++ : STRNCMP_DEFAULT ++ ) ++#endif /* HAVE_STRNCMP_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-26.patch b/SOURCES/glibc-rh1659438-26.patch new file mode 100644 index 0000000..65995ca --- /dev/null +++ b/SOURCES/glibc-rh1659438-26.patch @@ -0,0 +1,268 @@ +commit 32f12653d4ea2fbff409351bf8067f9a0b4a3963 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:14 2018 +0100 + + S390: Refactor strchr ifunc handling. + + The ifunc handling for strchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strchr. + * sysdeps/s390/multiarch/strchr-c.c: Move to ... + * sysdeps/s390/strchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchr-vx.S: Move to ... + * sysdeps/s390/strchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchr.c: Move to ... + * sysdeps/s390/strchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index adf3521876725ac8..8bb396f498e0b0b0 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -46,5 +46,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx strcmp-z900 \ +- strncmp strncmp-vx strncmp-c ++ strncmp strncmp-vx strncmp-c \ ++ strchr strchr-vx strchr-c + endif +diff --git a/sysdeps/s390/ifunc-strchr.h b/sysdeps/s390/ifunc-strchr.h +new file mode 100644 +index 0000000000000000..cfeb00eeda890512 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strchr.h +@@ -0,0 +1,52 @@ ++/* strchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCHR_IFUNC 1 ++#else ++# define HAVE_STRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCHR_IFUNC_AND_VX_SUPPORT HAVE_STRCHR_IFUNC ++#else ++# define HAVE_STRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCHR_DEFAULT STRCHR_Z13 ++# define HAVE_STRCHR_C 0 ++# define HAVE_STRCHR_Z13 1 ++#else ++# define STRCHR_DEFAULT STRCHR_C ++# define HAVE_STRCHR_C 1 ++# define HAVE_STRCHR_Z13 HAVE_STRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCHR_C ++# define STRCHR_C __strchr_c ++#else ++# define STRCHR_C NULL ++#endif ++ ++#if HAVE_STRCHR_Z13 ++# define STRCHR_Z13 __strchr_vx ++#else ++# define STRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 381376bf9fcb0f58..a8e9d0acd9ebf986 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strchr strchr-vx strchr-c \ +- strchrnul strchrnul-vx strchrnul-c \ ++sysdep_routines += strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index d982de5788c0b5d5..e809ca3bacb18aa9 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -294,6 +295,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRNCMP_IFUNC */ + ++#if HAVE_STRCHR_IFUNC ++ IFUNC_IMPL (i, name, strchr, ++# if HAVE_STRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, strchr, ++ dl_hwcap & HWCAP_S390_VX, STRCHR_Z13) ++# endif ++# if HAVE_STRCHR_C ++ IFUNC_IMPL_ADD (array, i, strchr, 1, STRCHR_C) ++# endif ++ ) ++#endif /* HAVE_STRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -322,7 +335,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsncmp); + +- IFUNC_VX_IMPL (strchr); + IFUNC_VX_IMPL (wcschr); + + IFUNC_VX_IMPL (strchrnul); +diff --git a/sysdeps/s390/multiarch/strchr-c.c b/sysdeps/s390/strchr-c.c +similarity index 77% +rename from sysdeps/s390/multiarch/strchr-c.c +rename to sysdeps/s390/strchr-c.c +index 606cb56788966153..3d3579a1d3bc06d0 100644 +--- a/sysdeps/s390/multiarch/strchr-c.c ++++ b/sysdeps/s390/strchr-c.c +@@ -16,14 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCHR __strchr_c +-# undef weak_alias +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRCHR_C ++# if HAVE_STRCHR_IFUNC ++# define STRCHR STRCHR_C ++# undef weak_alias ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strchr_c, __GI_strchr, __strchr_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strchr-vx.S b/sysdeps/s390/strchr-vx.S +similarity index 90% +rename from sysdeps/s390/multiarch/strchr-vx.S +rename to sysdeps/s390/strchr-vx.S +index 6e744fb82f3249a6..6ffa06f78c14c8da 100644 +--- a/sysdeps/s390/multiarch/strchr-vx.S ++++ b/sysdeps/s390/strchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +38,7 @@ + -v17=index of unequal + -v18=replicated c + */ +-ENTRY(__strchr_vx) ++ENTRY(STRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -96,5 +98,15 @@ ENTRY(__strchr_vx) + clije %r3,0,.Lcharacter /* Found zero and c is zero. */ + lghi %r2,0 /* Return null if character not found. */ + br %r14 +-END(__strchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCHR_Z13) ++ ++# if ! HAVE_STRCHR_IFUNC ++strong_alias (STRCHR_Z13, strchr) ++weak_alias (strchr, index) ++# endif ++ ++# if ! HAVE_STRCHR_C && defined SHARED && IS_IN (libc) ++strong_alias (STRCHR_Z13, __GI_strchr) ++# endif ++ ++#endif /* HAVE_STRCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/strchr.c +similarity index 71% +rename from sysdeps/s390/multiarch/strchr.c +rename to sysdeps/s390/strchr.c +index 8aa33a51cc7e91de..a106c6106dcd5307 100644 +--- a/sysdeps/s390/multiarch/strchr.c ++++ b/sysdeps/s390/strchr.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHR_IFUNC + # define strchr __redirect_strchr + /* Omit the strchr inline definitions because it would redefine strchr. */ + # define __NO_STRING_INLINES +@@ -24,9 +26,18 @@ + # undef strchr + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strchr, __strchr, strchr) +-weak_alias (strchr, index) ++# if HAVE_STRCHR_C ++extern __typeof (__redirect_strchr) STRCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STRCHR_Z13 ++extern __typeof (__redirect_strchr) STRCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_strchr, strchr, ++ (HAVE_STRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCHR_Z13 ++ : STRCHR_DEFAULT ++ ) ++weak_alias (strchr, index) ++#endif /* HAVE_STRCHR_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-27.patch b/SOURCES/glibc-rh1659438-27.patch new file mode 100644 index 0000000..9fb75a4 --- /dev/null +++ b/SOURCES/glibc-rh1659438-27.patch @@ -0,0 +1,253 @@ +commit a1361e65617c660a3ba7d561e081dcd18762a688 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:14 2018 +0100 + + S390: Refactor strchrnul ifunc handling. + + The ifunc handling for strchrnul is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strchrnul variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strchrnul variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strchrnul. + * sysdeps/s390/multiarch/strchrnul-c.c: Move to ... + * sysdeps/s390/strchrnul-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchrnul-vx.S: Move to ... + * sysdeps/s390/strchrnul-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strchrnul.c: Move to ... + * sysdeps/s390/strchrnul.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strchrnul.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 8bb396f498e0b0b0..c54bb82f4d4f8a67 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -47,5 +47,6 @@ sysdep_routines += bzero memset memset-z900 \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx strcmp-z900 \ + strncmp strncmp-vx strncmp-c \ +- strchr strchr-vx strchr-c ++ strchr strchr-vx strchr-c \ ++ strchrnul strchrnul-vx strchrnul-c + endif +diff --git a/sysdeps/s390/ifunc-strchrnul.h b/sysdeps/s390/ifunc-strchrnul.h +new file mode 100644 +index 0000000000000000..cac817e6f0a9406d +--- /dev/null ++++ b/sysdeps/s390/ifunc-strchrnul.h +@@ -0,0 +1,52 @@ ++/* strchrnul variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCHRNUL_IFUNC 1 ++#else ++# define HAVE_STRCHRNUL_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT HAVE_STRCHRNUL_IFUNC ++#else ++# define HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCHRNUL_DEFAULT STRCHRNUL_Z13 ++# define HAVE_STRCHRNUL_C 0 ++# define HAVE_STRCHRNUL_Z13 1 ++#else ++# define STRCHRNUL_DEFAULT STRCHRNUL_C ++# define HAVE_STRCHRNUL_C 1 ++# define HAVE_STRCHRNUL_Z13 HAVE_STRCHRNUL_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCHRNUL_C ++# define STRCHRNUL_C __strchrnul_c ++#else ++# define STRCHRNUL_C NULL ++#endif ++ ++#if HAVE_STRCHRNUL_Z13 ++# define STRCHRNUL_Z13 __strchrnul_vx ++#else ++# define STRCHRNUL_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index a8e9d0acd9ebf986..999a979fee1417b2 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strchrnul strchrnul-vx strchrnul-c \ +- strrchr strrchr-vx strrchr-c \ ++sysdep_routines += strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index e809ca3bacb18aa9..0a47ffeac3492b3e 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -307,6 +308,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCHR_IFUNC */ + ++#if HAVE_STRCHRNUL_IFUNC ++ IFUNC_IMPL (i, name, strchrnul, ++# if HAVE_STRCHRNUL_Z13 ++ IFUNC_IMPL_ADD (array, i, strchrnul, ++ dl_hwcap & HWCAP_S390_VX, STRCHRNUL_Z13) ++# endif ++# if HAVE_STRCHRNUL_C ++ IFUNC_IMPL_ADD (array, i, strchrnul, 1, STRCHRNUL_C) ++# endif ++ ) ++#endif /* HAVE_STRCHRNUL_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -337,7 +350,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcschr); + +- IFUNC_VX_IMPL (strchrnul); + IFUNC_VX_IMPL (wcschrnul); + + IFUNC_VX_IMPL (strrchr); +diff --git a/sysdeps/s390/multiarch/strchrnul-c.c b/sysdeps/s390/strchrnul-c.c +similarity index 81% +rename from sysdeps/s390/multiarch/strchrnul-c.c +rename to sysdeps/s390/strchrnul-c.c +index 020cebcf3e275b07..585273f5de8b82bc 100644 +--- a/sysdeps/s390/multiarch/strchrnul-c.c ++++ b/sysdeps/s390/strchrnul-c.c +@@ -16,11 +16,15 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCHRNUL __strchrnul_c +-# define __strchrnul STRCHRNUL +-# undef weak_alias +-# define weak_alias(name, alias) ++#include ++ ++#if HAVE_STRCHRNUL_C ++# if HAVE_STRCHRNUL_IFUNC ++# define STRCHRNUL STRCHRNUL_C ++# define __strchrnul STRCHRNUL ++# undef weak_alias ++# define weak_alias(name, alias) ++# endif + + # include + #endif +diff --git a/sysdeps/s390/multiarch/strchrnul-vx.S b/sysdeps/s390/strchrnul-vx.S +similarity index 91% +rename from sysdeps/s390/multiarch/strchrnul-vx.S +rename to sysdeps/s390/strchrnul-vx.S +index d561825e0432458c..0cd587bc32cf811f 100644 +--- a/sysdeps/s390/multiarch/strchrnul-vx.S ++++ b/sysdeps/s390/strchrnul-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHRNUL_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -35,7 +37,7 @@ + -v16=part of s + -v18=vector with c replicated in every byte + */ +-ENTRY(__strchrnul_vx) ++ENTRY(STRCHRNUL_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -89,5 +91,11 @@ ENTRY(__strchrnul_vx) + + .Lend: + br %r14 +-END(__strchrnul_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCHRNUL_Z13) ++ ++# if ! HAVE_STRCHRNUL_IFUNC ++strong_alias (STRCHRNUL_Z13, __strchrnul) ++weak_alias (__strchrnul, strchrnul) ++# endif ++ ++#endif /* HAVE_STRCHRNUL_Z13 */ +diff --git a/sysdeps/s390/multiarch/strchrnul.c b/sysdeps/s390/strchrnul.c +similarity index 67% +rename from sysdeps/s390/multiarch/strchrnul.c +rename to sysdeps/s390/strchrnul.c +index 62dfc6bd90638b60..e9fefe1bdc77f038 100644 +--- a/sysdeps/s390/multiarch/strchrnul.c ++++ b/sysdeps/s390/strchrnul.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCHRNUL_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__strchrnul) +-weak_alias (__strchrnul, strchrnul) ++# if HAVE_STRCHRNUL_C ++extern __typeof (__strchrnul) STRCHRNUL_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_STRCHRNUL_Z13 ++extern __typeof (__strchrnul) STRCHRNUL_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__strchrnul, __strchrnul, ++ (HAVE_STRCHRNUL_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCHRNUL_Z13 ++ : STRCHRNUL_DEFAULT ++ ) ++weak_alias (__strchrnul, strchrnul) ++#endif /* HAVE_STRCHRNUL_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-28.patch b/SOURCES/glibc-rh1659438-28.patch new file mode 100644 index 0000000..2e29a54 --- /dev/null +++ b/SOURCES/glibc-rh1659438-28.patch @@ -0,0 +1,266 @@ +commit 26ea8760877cf03272e98c21eb1a7745ceca76c4 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:14 2018 +0100 + + S390: Refactor strrchr ifunc handling. + + The ifunc handling for strrchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strrchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strrchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strrchr. + * sysdeps/s390/multiarch/strrchr-c.c: Move to ... + * sysdeps/s390/strrchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strrchr-vx.S: Move to ... + * sysdeps/s390/strrchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strrchr.c: Move to ... + * sysdeps/s390/strrchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strrchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index c54bb82f4d4f8a67..3ad44c997e9f1f6b 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -48,5 +48,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcmp strcmp-vx strcmp-z900 \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ +- strchrnul strchrnul-vx strchrnul-c ++ strchrnul strchrnul-vx strchrnul-c \ ++ strrchr strrchr-vx strrchr-c + endif +diff --git a/sysdeps/s390/ifunc-strrchr.h b/sysdeps/s390/ifunc-strrchr.h +new file mode 100644 +index 0000000000000000..7185fc32601f7388 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strrchr.h +@@ -0,0 +1,52 @@ ++/* strrchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRRCHR_IFUNC 1 ++#else ++# define HAVE_STRRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT HAVE_STRRCHR_IFUNC ++#else ++# define HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRRCHR_DEFAULT STRRCHR_Z13 ++# define HAVE_STRRCHR_C 0 ++# define HAVE_STRRCHR_Z13 1 ++#else ++# define STRRCHR_DEFAULT STRRCHR_C ++# define HAVE_STRRCHR_C 1 ++# define HAVE_STRRCHR_Z13 HAVE_STRRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRRCHR_C ++# define STRRCHR_C __strrchr_c ++#else ++# define STRRCHR_C NULL ++#endif ++ ++#if HAVE_STRRCHR_Z13 ++# define STRRCHR_Z13 __strrchr_vx ++#else ++# define STRRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 999a979fee1417b2..c8267555585b617e 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strrchr strrchr-vx strrchr-c \ +- strspn strspn-vx strspn-c \ ++sysdep_routines += strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 0a47ffeac3492b3e..60cd705ffa4e2c35 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -320,6 +321,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCHRNUL_IFUNC */ + ++#if HAVE_STRRCHR_IFUNC ++ IFUNC_IMPL (i, name, strrchr, ++# if HAVE_STRRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, strrchr, ++ dl_hwcap & HWCAP_S390_VX, STRRCHR_Z13) ++# endif ++# if HAVE_STRRCHR_C ++ IFUNC_IMPL_ADD (array, i, strrchr, 1, STRRCHR_C) ++# endif ++ ) ++#endif /* HAVE_STRRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -352,7 +365,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcschrnul); + +- IFUNC_VX_IMPL (strrchr); + IFUNC_VX_IMPL (wcsrchr); + + IFUNC_VX_IMPL (strspn); +diff --git a/sysdeps/s390/multiarch/strrchr-c.c b/sysdeps/s390/strrchr-c.c +similarity index 77% +rename from sysdeps/s390/multiarch/strrchr-c.c +rename to sysdeps/s390/strrchr-c.c +index 53ceb8086f0711c8..615f16da7d9db5ef 100644 +--- a/sysdeps/s390/multiarch/strrchr-c.c ++++ b/sysdeps/s390/strrchr-c.c +@@ -16,14 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRRCHR __strrchr_c +-# undef weak_alias +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRRCHR_C ++# if HAVE_STRRCHR_IFUNC ++# define STRRCHR STRRCHR_C ++# undef weak_alias ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strrchr_c, __GI_strrchr, __strrchr_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strrchr-vx.S b/sysdeps/s390/strrchr-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/strrchr-vx.S +rename to sysdeps/s390/strrchr-vx.S +index 8b3b989631f23de5..5f4ac14ee338c790 100644 +--- a/sysdeps/s390/multiarch/strrchr-vx.S ++++ b/sysdeps/s390/strrchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -39,7 +41,7 @@ + -v19=part of s with last occurence of c. + -v20=permute pattern + */ +-ENTRY(__strrchr_vx) ++ENTRY(STRRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -176,5 +178,15 @@ ENTRY(__strrchr_vx) + .Lpermute_mask: + .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 + .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 +-END(__strrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRRCHR_Z13) ++ ++# if ! HAVE_STRRCHR_IFUNC ++strong_alias (STRRCHR_Z13, strrchr) ++weak_alias (strrchr, rindex) ++# endif ++ ++# if ! HAVE_STRRCHR_C && defined SHARED && IS_IN (libc) ++strong_alias (STRRCHR_Z13, __GI_strrchr) ++# endif ++ ++#endif /* HAVE_STRRCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/strrchr.c +similarity index 66% +rename from sysdeps/s390/multiarch/strrchr.c +rename to sysdeps/s390/strrchr.c +index e00e25a3a4f51b1e..9a8cecff0b29c057 100644 +--- a/sysdeps/s390/multiarch/strrchr.c ++++ b/sysdeps/s390/strrchr.c +@@ -16,15 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRRCHR_IFUNC + # define strrchr __redirect_strrchr + # include + # undef strrchr + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr) +-weak_alias (strrchr, rindex); ++# if HAVE_STRRCHR_C ++extern __typeof (__redirect_strrchr) STRRCHR_C attribute_hidden; ++# endif ++ ++# if HAVE_STRRCHR_Z13 ++extern __typeof (__redirect_strrchr) STRRCHR_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strrchr, strrchr, ++ (HAVE_STRRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRRCHR_Z13 ++ : STRRCHR_DEFAULT ++ ) ++weak_alias (strrchr, rindex) ++#endif /* HAVE_STRRCHR_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-29.patch b/SOURCES/glibc-rh1659438-29.patch new file mode 100644 index 0000000..edb4940 --- /dev/null +++ b/SOURCES/glibc-rh1659438-29.patch @@ -0,0 +1,263 @@ +commit 483fc56978d11c7118326f92ea678bea2f092300 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:15 2018 +0100 + + S390: Refactor strspn ifunc handling. + + The ifunc handling for strspn is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strspn. + * sysdeps/s390/multiarch/strspn-c.c: Move to ... + * sysdeps/s390/strspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strspn-vx.S: Move to ... + * sysdeps/s390/strspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strspn.c: Move to ... + * sysdeps/s390/strspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 3ad44c997e9f1f6b..c0a402117197b87f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -49,5 +49,6 @@ sysdep_routines += bzero memset memset-z900 \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ +- strrchr strrchr-vx strrchr-c ++ strrchr strrchr-vx strrchr-c \ ++ strspn strspn-vx strspn-c + endif +diff --git a/sysdeps/s390/ifunc-strspn.h b/sysdeps/s390/ifunc-strspn.h +new file mode 100644 +index 0000000000000000..1152ba1f3d3b9b62 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strspn.h +@@ -0,0 +1,52 @@ ++/* strspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRSPN_IFUNC 1 ++#else ++# define HAVE_STRSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRSPN_IFUNC_AND_VX_SUPPORT HAVE_STRSPN_IFUNC ++#else ++# define HAVE_STRSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRSPN_DEFAULT STRSPN_Z13 ++# define HAVE_STRSPN_C 0 ++# define HAVE_STRSPN_Z13 1 ++#else ++# define STRSPN_DEFAULT STRSPN_C ++# define HAVE_STRSPN_C 1 ++# define HAVE_STRSPN_Z13 HAVE_STRSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRSPN_C ++# define STRSPN_C __strspn_c ++#else ++# define STRSPN_C NULL ++#endif ++ ++#if HAVE_STRSPN_Z13 ++# define STRSPN_Z13 __strspn_vx ++#else ++# define STRSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c8267555585b617e..9b141e338ca551ec 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strspn strspn-vx strspn-c \ +- strpbrk strpbrk-vx strpbrk-c \ ++sysdep_routines += strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 60cd705ffa4e2c35..c39e1f793aad530c 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -333,6 +334,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRRCHR_IFUNC */ + ++#if HAVE_STRSPN_IFUNC ++ IFUNC_IMPL (i, name, strspn, ++# if HAVE_STRSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, strspn, ++ dl_hwcap & HWCAP_S390_VX, STRSPN_Z13) ++# endif ++# if HAVE_STRSPN_C ++ IFUNC_IMPL_ADD (array, i, strspn, 1, STRSPN_C) ++# endif ++ ) ++#endif /* HAVE_STRSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -367,7 +380,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsrchr); + +- IFUNC_VX_IMPL (strspn); + IFUNC_VX_IMPL (wcsspn); + + IFUNC_VX_IMPL (strpbrk); +diff --git a/sysdeps/s390/multiarch/strspn-c.c b/sysdeps/s390/strspn-c.c +similarity index 78% +rename from sysdeps/s390/multiarch/strspn-c.c +rename to sysdeps/s390/strspn-c.c +index 0efe61bfb2f89caf..506f6683212f03ab 100644 +--- a/sysdeps/s390/multiarch/strspn-c.c ++++ b/sysdeps/s390/strspn-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRSPN __strspn_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ ++#include ++ ++#if HAVE_STRSPN_C ++# if HAVE_STRSPN_IFUNC ++# define STRSPN STRSPN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strspn_c, __GI_strspn, __strspn_c); +-# endif /* SHARED */ ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strspn-vx.S b/sysdeps/s390/strspn-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/strspn-vx.S +rename to sysdeps/s390/strspn-vx.S +index 6aa823e63b1189c3..ae5529b567ee7435 100644 +--- a/sysdeps/s390/multiarch/strspn-vx.S ++++ b/sysdeps/s390/strspn-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -57,7 +59,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__strspn_vx) ++ENTRY(STRSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -252,5 +254,14 @@ ENTRY(__strspn_vx) + Check for zero is in jump-target. */ + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ +-END(__strspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRSPN_Z13) ++ ++# if ! HAVE_STRSPN_IFUNC ++strong_alias (STRSPN_Z13, strspn) ++# endif ++ ++# if ! HAVE_STRSPN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRSPN_Z13, __GI_strspn) ++# endif ++ ++#endif /* HAVE_STRSPN_Z13 */ +diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/strspn.c +similarity index 70% +rename from sysdeps/s390/multiarch/strspn.c +rename to sysdeps/s390/strspn.c +index bedbe98cfc4ab14d..91401fdaf89ed8a2 100644 +--- a/sysdeps/s390/multiarch/strspn.c ++++ b/sysdeps/s390/strspn.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRSPN_IFUNC + # define strspn __redirect_strspn + /* Omit the strspn inline definitions because it would redefine strspn. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strspn + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strspn, __strspn, strspn) ++# if HAVE_STRSPN_C ++extern __typeof (__redirect_strspn) STRSPN_C attribute_hidden; ++# endif ++ ++# if HAVE_STRSPN_Z13 ++extern __typeof (__redirect_strspn) STRSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strspn, strspn, ++ (HAVE_STRSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRSPN_Z13 ++ : STRSPN_DEFAULT ++ ) ++#endif /* HAVE_STRSPN_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-3.patch b/SOURCES/glibc-rh1659438-3.patch new file mode 100644 index 0000000..161448c --- /dev/null +++ b/SOURCES/glibc-rh1659438-3.patch @@ -0,0 +1,440 @@ +commit 5f1743d118047ff1fbefe713f2397090e0418deb +Author: Stefan Liebler +Date: Tue Dec 18 13:57:04 2018 +0100 + + S390: Unify 31/64bit memset. + + The implementation of memset for s390-32 (31bit) and + s390-64 (64bit) is nearly the same. + This patch unifies it for maintability reasons. + + __memset_z10 and __memset_z196 differs between 31 and 64bit: + -31bit needs .machinemode "zarch_nohighgprs" and llgfr %r4,%r4 + -lr vs lgr and some other instructions: + But lgr and co can be also used on 31bit as this ifunc variant + is only called if we are on a zarch machine. + + __memset_default differs between 31 and 64bit: + -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr. + Solved with 31/64 specific instruction macros). + -The address of mvc instruction is setup in different ways + (larl vs bras). Solved with #if defined __s390x__. + + Otherwise 31/64bit implementation has the same structure of the code. + + ChangeLog: + + * sysdeps/s390/s390-64/memset.S: Move to ... + * sysdeps/s390/memset.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/memset.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memset. + * sysdeps/s390/s390-32/multiarch/Makefile (sysdep_routines): + Remove memset. + * sysdeps/s390/s390-64/multiarch/Makefile: Likewise. + * sysdeps/s390/s390-64/multiarch/memset-s390x.S: Move to ... + * sysdeps/s390/multiarch/memset-s390x.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/multiarch/memset-s390.S: Delete File. + * sysdeps/s390/s390-64/multiarch/memset.c: Move to ... + * sysdeps/s390/multiarch/memset.c: ... here. + * sysdeps/s390/s390-32/multiarch/memset.c: Delete File. + +diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/memset.S +similarity index 58% +rename from sysdeps/s390/s390-64/memset.S +rename to sysdeps/s390/memset.S +index 8799c6592ce2dacf..72e7c5a42efbaf6c 100644 +--- a/sysdeps/s390/s390-64/memset.S ++++ b/sysdeps/s390/memset.S +@@ -1,4 +1,4 @@ +-/* Set a block of memory to some byte value. 64 bit S/390 version. ++/* Set a block of memory to some byte value. 31/64 bit S/390 version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. +@@ -28,33 +28,60 @@ + + .text + ++#if defined __s390x__ ++# define LTGR ltgr ++# define CGHI cghi ++# define LGR lgr ++# define AGHI aghi ++# define BRCTG brctg ++#else ++# define LTGR ltr ++# define CGHI chi ++# define LGR lr ++# define AGHI ahi ++# define BRCTG brct ++#endif /* ! defined __s390x__ */ ++ + #ifdef USE_MULTIARCH + ENTRY(__memset_default) + #else + ENTRY(memset) + #endif ++#if defined __s390x__ + .machine "z900" +- ltgr %r4,%r4 +- je .L_Z900_4 ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 + stc %r3,0(%r2) +- cghi %r4,1 +- lgr %r1,%r2 +- je .L_Z900_4 +- aghi %r4,-2 ++ CGHI %r4,1 ++ LGR %r1,%r2 ++ je .L_Z900_G5_4 ++ AGHI %r4,-2 ++#if defined __s390x__ ++ larl %r5,.L_Z900_G5_18 + srlg %r3,%r4,8 +- ltgr %r3,%r3 +- jne .L_Z900_14 +-.L_Z900_3: +- larl %r3,.L_Z900_18 +- ex %r4,0(%r3) +-.L_Z900_4: ++# define Z900_G5_EX_D 0 ++#else ++ basr %r5,0 ++.L_Z900_G5_19: ++# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19 ++ lr %r3,%r4 ++ srl %r3,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r3,%r3 ++ jne .L_Z900_G5_14 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + br %r14 +-.L_Z900_14: ++.L_Z900_G5_14: + mvc 1(256,%r1),0(%r1) + la %r1,256(%r1) +- brctg %r3,.L_Z900_14 +- j .L_Z900_3 +-.L_Z900_18: ++ BRCTG %r3,.L_Z900_G5_14 ++ j .L_Z900_G5_3 ++.L_Z900_G5_18: + mvc 1(1,%r1),0(%r1) + #ifdef USE_MULTIARCH + END(__memset_default) +@@ -62,3 +89,9 @@ END(__memset_default) + END(memset) + libc_hidden_builtin_def (memset) + #endif ++ ++#undef LTGR ++#undef CGHI ++#undef LGR ++#undef AGHI ++#undef BRCTG +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c893ebc5659fd4ae..93ad21bfa2686ee5 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,7 +19,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy ++ mempcpy \ ++ memset memset-s390x + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/sysdeps/s390/multiarch/memset-s390x.S +similarity index 90% +rename from sysdeps/s390/s390-64/multiarch/memset-s390x.S +rename to sysdeps/s390/multiarch/memset-s390x.S +index 0c5aaef34fdf47e6..aca3ac3fda1dd228 100644 +--- a/sysdeps/s390/s390-64/multiarch/memset-s390x.S ++++ b/sysdeps/s390/multiarch/memset-s390x.S +@@ -1,4 +1,4 @@ +-/* Set a block of memory to some byte value. 64 bit S/390 version. ++/* Set a block of memory to some byte value. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -31,6 +31,10 @@ + + ENTRY(__memset_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 + stc %r3,0(%r2) +@@ -61,6 +65,10 @@ END(__memset_z196) + + ENTRY(__memset_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + cgije %r4,0,.L_Z10_4 + stc %r3,0(%r2) + lgr %r1,%r2 +diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/multiarch/memset.c +similarity index 100% +rename from sysdeps/s390/s390-32/multiarch/memset.c +rename to sysdeps/s390/multiarch/memset.c +diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S +deleted file mode 100644 +index 57f08e1cae1abd01..0000000000000000 +--- a/sysdeps/s390/s390-32/memset.S ++++ /dev/null +@@ -1,65 +0,0 @@ +-/* Set a block of memory to some byte value. For IBM S390 +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address to memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#ifdef USE_MULTIARCH +-ENTRY(__memset_default) +-#else +-ENTRY(memset) +-#endif +- .machine "g5" +- basr %r5,0 +-.L_G5_19: +- ltr %r4,%r4 +- je .L_G5_4 +- stc %r3,0(%r2) +- chi %r4,1 +- lr %r1,%r2 +- je .L_G5_4 +- ahi %r4,-2 +- lr %r3,%r4 +- srl %r3,8 +- ltr %r3,%r3 +- jne .L_G5_14 +- ex %r4,.L_G5_20-.L_G5_19(%r5) +-.L_G5_4: +- br %r14 +-.L_G5_14: +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brct %r3,.L_G5_14 +- ex %r4,.L_G5_20-.L_G5_19(%r5) +- j .L_G5_4 +-.L_G5_20: +- mvc 1(1,%r1),0(%r1) +-#ifdef USE_MULTIARCH +-END(__memset_default) +-#else +-END(memset) +-libc_hidden_builtin_def (memset) +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile +index f8aee14bbd4736ad..4b11e28656ac19ab 100644 +--- a/sysdeps/s390/s390-32/multiarch/Makefile ++++ b/sysdeps/s390/s390-32/multiarch/Makefile +@@ -1,4 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memset memset-s390 memcpy memcpy-s390 \ +- memcmp memcmp-s390 ++sysdep_routines += memcpy memcpy-s390 memcmp memcmp-s390 + endif +diff --git a/sysdeps/s390/s390-32/multiarch/memset-s390.S b/sysdeps/s390/s390-32/multiarch/memset-s390.S +deleted file mode 100644 +index b092073d6bef6b56..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memset-s390.S ++++ /dev/null +@@ -1,116 +0,0 @@ +-/* Set a block of memory to some byte value. 32 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#if IS_IN (libc) +- +-ENTRY(__memset_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- ltgr %r4,%r4 +- je .L_Z196_4 +- stc %r3,0(%r2) +- lr %r1,%r2 +- cghi %r4,1 +- je .L_Z196_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_1 +-.L_Z196_3: +- exrl %r4,.L_Z196_17 +-.L_Z196_4: +- br %r14 +-.L_Z196_1: +- cgfi %r5,1048576 +- jh __memset_mvcle # Switch to mvcle for >256MB +-.L_Z196_2: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- aghi %r5,-1 +- la %r1,256(%r1) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_17: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z196) +- +-ENTRY(__memset_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- cgije %r4,0,.L_Z10_4 +- stc %r3,0(%r2) +- lr %r1,%r2 +- cgije %r4,1,.L_Z10_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_15 +-.L_Z10_3: +- exrl %r4,.L_Z10_18 +-.L_Z10_4: +- br %r14 +-.L_Z10_15: +- cgfi %r5,163840 # Switch to mvcle for >40MB +- jh __memset_mvcle +-.L_Z10_14: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brctg %r5,.L_Z10_14 +- j .L_Z10_3 +-.L_Z10_18: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z10) +- +-ENTRY(__memset_mvcle) +- ahi %r4,2 # take back the change done by the caller +- lr %r0,%r2 # save source address +- lr %r1,%r3 # move pad byte to R1 +- lr %r3,%r4 +- sr %r4,%r4 # no source for MVCLE, only a pad byte +- sr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +- lr %r2,%r0 # return value is source address +-.L1: +- br %r14 +-END(__memset_mvcle) +- +-#endif /* IS_IN (libc) */ +- +-#include "../memset.S" +- +-#if !IS_IN (libc) +-.globl memset +-.set memset,__memset_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memset +-.set __GI_memset,__memset_default +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile +index 91053b536420aabb..e4870c7ee177ad0d 100644 +--- a/sysdeps/s390/s390-64/multiarch/Makefile ++++ b/sysdeps/s390/s390-64/multiarch/Makefile +@@ -1,4 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memset memset-s390x memcpy memcpy-s390x \ +- memcmp memcmp-s390x ++sysdep_routines += memcpy memcpy-s390x memcmp memcmp-s390x + endif +diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c +deleted file mode 100644 +index 760b3e9df201b8b4..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memset.c ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* Multiple versions of memset. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#if IS_IN (libc) +-# define memset __redirect_memset +-# include +-# undef memset +-# include +- +-s390_libc_ifunc (__redirect_memset, __memset, memset) +-#endif diff --git a/SOURCES/glibc-rh1659438-30.patch b/SOURCES/glibc-rh1659438-30.patch new file mode 100644 index 0000000..9e7db8e --- /dev/null +++ b/SOURCES/glibc-rh1659438-30.patch @@ -0,0 +1,264 @@ +commit 572cca93fafa59d641c11372a9556722d95b038c +Author: Stefan Liebler +Date: Tue Dec 18 13:57:15 2018 +0100 + + S390: Refactor strpbrk ifunc handling. + + The ifunc handling for strpbrk is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strpbrk variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strpbrk variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strpbrk. + * sysdeps/s390/multiarch/strpbrk-c.c: Move to ... + * sysdeps/s390/strpbrk-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strpbrk-vx.S: Move to ... + * sysdeps/s390/strpbrk-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strpbrk.c: Move to ... + * sysdeps/s390/strpbrk.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strpbrk.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index c0a402117197b87f..a21fa7507b1d64a1 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -50,5 +50,6 @@ sysdep_routines += bzero memset memset-z900 \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ +- strspn strspn-vx strspn-c ++ strspn strspn-vx strspn-c \ ++ strpbrk strpbrk-vx strpbrk-c + endif +diff --git a/sysdeps/s390/ifunc-strpbrk.h b/sysdeps/s390/ifunc-strpbrk.h +new file mode 100644 +index 0000000000000000..4a3138c6bf377286 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strpbrk.h +@@ -0,0 +1,52 @@ ++/* strpbrk variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRPBRK_IFUNC 1 ++#else ++# define HAVE_STRPBRK_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT HAVE_STRPBRK_IFUNC ++#else ++# define HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRPBRK_DEFAULT STRPBRK_Z13 ++# define HAVE_STRPBRK_C 0 ++# define HAVE_STRPBRK_Z13 1 ++#else ++# define STRPBRK_DEFAULT STRPBRK_C ++# define HAVE_STRPBRK_C 1 ++# define HAVE_STRPBRK_Z13 HAVE_STRPBRK_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRPBRK_C ++# define STRPBRK_C __strpbrk_c ++#else ++# define STRPBRK_C NULL ++#endif ++ ++#if HAVE_STRPBRK_Z13 ++# define STRPBRK_Z13 __strpbrk_vx ++#else ++# define STRPBRK_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 9b141e338ca551ec..1a3fed9fc88012d1 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strpbrk strpbrk-vx strpbrk-c \ +- strcspn strcspn-vx strcspn-c \ ++sysdep_routines += strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c39e1f793aad530c..8e23416730f8a8d5 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -346,6 +347,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRSPN_IFUNC */ + ++#if HAVE_STRPBRK_IFUNC ++ IFUNC_IMPL (i, name, strpbrk, ++# if HAVE_STRPBRK_Z13 ++ IFUNC_IMPL_ADD (array, i, strpbrk, ++ dl_hwcap & HWCAP_S390_VX, STRPBRK_Z13) ++# endif ++# if HAVE_STRPBRK_C ++ IFUNC_IMPL_ADD (array, i, strpbrk, 1, STRPBRK_C) ++# endif ++ ) ++#endif /* HAVE_STRPBRK_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -382,7 +395,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcsspn); + +- IFUNC_VX_IMPL (strpbrk); + IFUNC_VX_IMPL (wcspbrk); + + IFUNC_VX_IMPL (strcspn); +diff --git a/sysdeps/s390/multiarch/strpbrk-c.c b/sysdeps/s390/strpbrk-c.c +similarity index 73% +rename from sysdeps/s390/multiarch/strpbrk-c.c +rename to sysdeps/s390/strpbrk-c.c +index 2c0517aeb52985b3..70cc5db672adb6c9 100644 +--- a/sysdeps/s390/multiarch/strpbrk-c.c ++++ b/sysdeps/s390/strpbrk-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRPBRK __strpbrk_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STRPBRK_C ++# if HAVE_STRPBRK_IFUNC ++# define STRPBRK STRPBRK_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strpbrk-vx.S b/sysdeps/s390/strpbrk-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/strpbrk-vx.S +rename to sysdeps/s390/strpbrk-vx.S +index e19c550ed404a9a8..0fc7dc143337779f 100644 +--- a/sysdeps/s390/multiarch/strpbrk-vx.S ++++ b/sysdeps/s390/strpbrk-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRPBRK_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -59,7 +61,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__strpbrk_vx) ++ENTRY(STRPBRK_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -298,5 +300,14 @@ ENTRY(__strpbrk_vx) + vlgvg %r9,%v31,1 + lgr %r2,%r1 + br %r14 +-END(__strpbrk_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRPBRK_Z13) ++ ++# if ! HAVE_STRPBRK_IFUNC ++strong_alias (STRPBRK_Z13, strpbrk) ++# endif ++ ++# if ! HAVE_STRPBRK_C && defined SHARED && IS_IN (libc) ++strong_alias (STRPBRK_Z13, __GI_strpbrk) ++# endif ++ ++#endif /* HAVE_STRPBRK_Z13 */ +diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/strpbrk.c +similarity index 70% +rename from sysdeps/s390/multiarch/strpbrk.c +rename to sysdeps/s390/strpbrk.c +index 11afc268f702ce09..41ce00a1aedf0020 100644 +--- a/sysdeps/s390/multiarch/strpbrk.c ++++ b/sysdeps/s390/strpbrk.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRPBRK_IFUNC + # define strpbrk __redirect_strpbrk + /* Omit the strpbrk inline definitions because it would redefine strpbrk. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strpbrk + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strpbrk, __strpbrk, strpbrk) ++# if HAVE_STRPBRK_C ++extern __typeof (__redirect_strpbrk) STRPBRK_C attribute_hidden; ++# endif ++ ++# if HAVE_STRPBRK_Z13 ++extern __typeof (__redirect_strpbrk) STRPBRK_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strpbrk, strpbrk, ++ (HAVE_STRPBRK_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRPBRK_Z13 ++ : STRPBRK_DEFAULT ++ ) ++#endif /* HAVE_STRPBRK_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-31.patch b/SOURCES/glibc-rh1659438-31.patch new file mode 100644 index 0000000..e448fc9 --- /dev/null +++ b/SOURCES/glibc-rh1659438-31.patch @@ -0,0 +1,264 @@ +commit 5d2ec20a997b87c1667e0e71b3ff1e9df96eac15 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:15 2018 +0100 + + S390: Refactor strcspn ifunc handling. + + The ifunc handling for strcspn is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove strcspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add strcspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for strcspn. + * sysdeps/s390/multiarch/strcspn-c.c: Move to ... + * sysdeps/s390/strcspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcspn-vx.S: Move to ... + * sysdeps/s390/strcspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/strcspn.c: Move to ... + * sysdeps/s390/strcspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-strcspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index a21fa7507b1d64a1..092d55826fbd15a5 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -51,5 +51,6 @@ sysdep_routines += bzero memset memset-z900 \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ +- strpbrk strpbrk-vx strpbrk-c ++ strpbrk strpbrk-vx strpbrk-c \ ++ strcspn strcspn-vx strcspn-c + endif +diff --git a/sysdeps/s390/ifunc-strcspn.h b/sysdeps/s390/ifunc-strcspn.h +new file mode 100644 +index 0000000000000000..9b7032509a2fb9a8 +--- /dev/null ++++ b/sysdeps/s390/ifunc-strcspn.h +@@ -0,0 +1,52 @@ ++/* strcspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_STRCSPN_IFUNC 1 ++#else ++# define HAVE_STRCSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT HAVE_STRCSPN_IFUNC ++#else ++# define HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define STRCSPN_DEFAULT STRCSPN_Z13 ++# define HAVE_STRCSPN_C 0 ++# define HAVE_STRCSPN_Z13 1 ++#else ++# define STRCSPN_DEFAULT STRCSPN_C ++# define HAVE_STRCSPN_C 1 ++# define HAVE_STRCSPN_Z13 HAVE_STRCSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_STRCSPN_C ++# define STRCSPN_C __strcspn_c ++#else ++# define STRCSPN_C NULL ++#endif ++ ++#if HAVE_STRCSPN_Z13 ++# define STRCSPN_Z13 __strcspn_vx ++#else ++# define STRCSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 1a3fed9fc88012d1..1578f21af4a1bd06 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += strcspn strcspn-vx strcspn-c \ +- memchr memchr-vx \ ++sysdep_routines += memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 8e23416730f8a8d5..2d48c99c8d5663fe 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -359,6 +360,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRPBRK_IFUNC */ + ++#if HAVE_STRCSPN_IFUNC ++ IFUNC_IMPL (i, name, strcspn, ++# if HAVE_STRCSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, strcspn, ++ dl_hwcap & HWCAP_S390_VX, STRCSPN_Z13) ++# endif ++# if HAVE_STRCSPN_C ++ IFUNC_IMPL_ADD (array, i, strcspn, 1, STRCSPN_C) ++# endif ++ ) ++#endif /* HAVE_STRCSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -397,7 +410,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcspbrk); + +- IFUNC_VX_IMPL (strcspn); + IFUNC_VX_IMPL (wcscspn); + + IFUNC_VX_IMPL (memchr); +diff --git a/sysdeps/s390/multiarch/strcspn-c.c b/sysdeps/s390/strcspn-c.c +similarity index 73% +rename from sysdeps/s390/multiarch/strcspn-c.c +rename to sysdeps/s390/strcspn-c.c +index 7b454f5b56077abc..9f51f92bdbd49a67 100644 +--- a/sysdeps/s390/multiarch/strcspn-c.c ++++ b/sysdeps/s390/strcspn-c.c +@@ -16,13 +16,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define STRCSPN __strcspn_c +-# ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c); +-# endif /* SHARED */ ++#include ++ ++#if HAVE_STRCSPN_C ++# if HAVE_STRCSPN_IFUNC ++# define STRCSPN STRCSPN_C ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c); ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/strcspn-vx.S b/sysdeps/s390/strcspn-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/strcspn-vx.S +rename to sysdeps/s390/strcspn-vx.S +index ea1668742bd1c7ff..ff5b1be549e6e210 100644 +--- a/sysdeps/s390/multiarch/strcspn-vx.S ++++ b/sysdeps/s390/strcspn-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -58,7 +60,7 @@ + otherwise =0; + r9: loaded byte count of vlbb reject-string + */ +-ENTRY(__strcspn_vx) ++ENTRY(STRCSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -277,5 +279,14 @@ ENTRY(__strcspn_vx) + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + br %r14 +-END(__strcspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(STRCSPN_Z13) ++ ++# if ! HAVE_STRCSPN_IFUNC ++strong_alias (STRCSPN_Z13, strcspn) ++# endif ++ ++# if ! HAVE_STRCSPN_C && defined SHARED && IS_IN (libc) ++strong_alias (STRCSPN_Z13, __GI_strcspn) ++# endif ++ ++#endif /* HAVE_STRCSPN_Z13 */ +diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/strcspn.c +similarity index 70% +rename from sysdeps/s390/multiarch/strcspn.c +rename to sysdeps/s390/strcspn.c +index 418ffcdded76fe50..a3f35d39c50dd5e5 100644 +--- a/sysdeps/s390/multiarch/strcspn.c ++++ b/sysdeps/s390/strcspn.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_STRCSPN_IFUNC + # define strcspn __redirect_strcspn + /* Omit the strcspn inline definitions because it would redefine strcspn. */ + # define __NO_STRING_INLINES +@@ -24,8 +26,17 @@ + # undef strcspn + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_strcspn, __strcspn, strcspn) ++# if HAVE_STRCSPN_C ++extern __typeof (__redirect_strcspn) STRCSPN_C attribute_hidden; ++# endif ++ ++# if HAVE_STRCSPN_Z13 ++extern __typeof (__redirect_strcspn) STRCSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_strcspn, strcspn, ++ (HAVE_STRCSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? STRCSPN_Z13 ++ : STRCSPN_DEFAULT ++ ) ++#endif /* HAVE_STRCSPN_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-32.patch b/SOURCES/glibc-rh1659438-32.patch new file mode 100644 index 0000000..85327b9 --- /dev/null +++ b/SOURCES/glibc-rh1659438-32.patch @@ -0,0 +1,403 @@ +commit 581a051c2e09a847332d4750f6132de0f0ad15b6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:16 2018 +0100 + + S390: Refactor memchr ifunc handling. + + The ifunc handling for memchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + Note: The fallback s390-32/s390-64 ifunc variants with srst instruction + are now moved to the unified memchr-z900.S file which can be used for + 31/64bit. The s390-32/s390-64 files multiarch/memchr.c and memchr.S + are deleted. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove memchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add memchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for memchr. + * sysdeps/s390/multiarch/memchr-vx.S: Move to ... + * sysdeps/s390/memchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memchr.c: Move to ... + * sysdeps/s390/memchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-memchr.h: New file. + * sysdeps/s390/s390-64/memchr.S: Move to ... + * sysdeps/s390/memchr-z900.S: ... here and adjust to be usable + for 31/64bit and ifunc handling. + * sysdeps/s390/s390-32/multiarch/memchr.c: Delete file. + * sysdeps/s390/s390-64/multiarch/memchr.c: Likewise. + * sysdeps/s390/s390-32/memchr.S: Likewise. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 092d55826fbd15a5..816b2fccdc75e4cf 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -52,5 +52,6 @@ sysdep_routines += bzero memset memset-z900 \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ +- strcspn strcspn-vx strcspn-c ++ strcspn strcspn-vx strcspn-c \ ++ memchr memchr-vx memchr-z900 + endif +diff --git a/sysdeps/s390/ifunc-memchr.h b/sysdeps/s390/ifunc-memchr.h +new file mode 100644 +index 0000000000000000..5d1327b45353322b +--- /dev/null ++++ b/sysdeps/s390/ifunc-memchr.h +@@ -0,0 +1,52 @@ ++/* memchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCHR_IFUNC 1 ++#else ++# define HAVE_MEMCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT HAVE_MEMCHR_IFUNC ++#else ++# define HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMCHR_DEFAULT MEMCHR_Z13 ++# define HAVE_MEMCHR_Z900_G5 0 ++# define HAVE_MEMCHR_Z13 1 ++#else ++# define MEMCHR_DEFAULT MEMCHR_Z900_G5 ++# define HAVE_MEMCHR_Z900_G5 1 ++# define HAVE_MEMCHR_Z13 HAVE_MEMCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMCHR_Z900_G5 ++# define MEMCHR_Z900_G5 __memchr_default ++#else ++# define MEMCHR_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMCHR_Z13 ++# define MEMCHR_Z13 __memchr_vx ++#else ++# define MEMCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memchr-vx.S b/sysdeps/s390/memchr-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/memchr-vx.S +rename to sysdeps/s390/memchr-vx.S +index 77d31e0036915665..274e7971ca7e9413 100644 +--- a/sysdeps/s390/multiarch/memchr-vx.S ++++ b/sysdeps/s390/memchr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_MEMCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -v17=index of found c + -v18=c replicated + */ +-ENTRY(__memchr_vx) ++ENTRY(MEMCHR_Z13) + + .machine "z13" + .machinemode "zarch_nohighgprs" +@@ -149,11 +150,14 @@ ENTRY(__memchr_vx) + clgrjl %r0,%r4,.Lloop64 + + j .Llt64 +-END(__memchr_vx) ++END(MEMCHR_Z13) + +-# define memchr __memchr_c +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) strong_alias(__memchr_c, __GI_memchr) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++# if ! HAVE_MEMCHR_IFUNC ++strong_alias (MEMCHR_Z13, __memchr) ++weak_alias (__memchr, memchr) ++# endif + +-#include ++# if ! HAVE_MEMCHR_Z900_G5 && defined SHARED && IS_IN (libc) ++strong_alias (MEMCHR_Z13, __GI_memchr) ++# endif ++#endif +diff --git a/sysdeps/s390/s390-64/memchr.S b/sysdeps/s390/memchr-z900.S +similarity index 63% +rename from sysdeps/s390/s390-64/memchr.S +rename to sysdeps/s390/memchr-z900.S +index a19fcafa147dc338..c016bc41c61be2dc 100644 +--- a/sysdeps/s390/s390-64/memchr.S ++++ b/sysdeps/s390/memchr-z900.S +@@ -1,4 +1,4 @@ +-/* Search a character in a block of memory. 64 bit S/390 version. ++/* Search a character in a block of memory. 31/64 bit S/390 version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. +@@ -22,19 +22,42 @@ + %r3 = character to find + %r4 = number of bytes to search. */ + ++#include + #include "sysdep.h" + #include "asm-syntax.h" + ++#if HAVE_MEMCHR_Z900_G5 ++# if defined __s390x__ ++# define SLGR slgr ++# define LGHI lghi ++# define NGR ngr ++# define LGR lgr ++# else ++# define SLGR slr ++# define LGHI lhi ++# define NGR nr ++# define LGR lr ++# endif /* ! defined __s390x__ */ ++ + .text +-ENTRY(memchr) +- lghi %r0,0xff +- ngr %r0,%r3 +- lgr %r1,%r2 ++ENTRY(MEMCHR_Z900_G5) ++ LGHI %r0,0xff ++ NGR %r0,%r3 ++ LGR %r1,%r2 + la %r2,0(%r4,%r1) + 0: srst %r2,%r1 + jo 0b + brc 13,1f +- slgr %r2,%r2 ++ SLGR %r2,%r2 + 1: br %r14 +-END(memchr) +-libc_hidden_builtin_def (memchr) ++END(MEMCHR_Z900_G5) ++ ++# if ! HAVE_MEMCHR_IFUNC ++strong_alias (MEMCHR_Z900_G5, __memchr) ++weak_alias (__memchr, memchr) ++# endif ++ ++# if defined SHARED && IS_IN (libc) ++strong_alias (MEMCHR_Z900_G5, __GI_memchr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/memchr.c +similarity index 68% +rename from sysdeps/s390/multiarch/memchr.c +rename to sysdeps/s390/memchr.c +index 3885ebaa4d90ed1a..490f1b66002aae05 100644 +--- a/sysdeps/s390/multiarch/memchr.c ++++ b/sysdeps/s390/memchr.c +@@ -16,12 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCHR_IFUNC + # define memchr __redirect_memchr + # include + # undef memchr + # include + +-s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr) ++# if HAVE_MEMCHR_Z900_G5 ++extern __typeof (__redirect_memchr) MEMCHR_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCHR_Z13 ++extern __typeof (__redirect_memchr) MEMCHR_Z13 attribute_hidden; ++# endif + ++s390_libc_ifunc_expr (__redirect_memchr, __memchr, ++ (HAVE_MEMCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMCHR_Z13 ++ : MEMCHR_DEFAULT ++ ) ++weak_alias (__memchr, memchr) + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 1578f21af4a1bd06..fa1f7b81db912be0 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += memchr memchr-vx \ +- rawmemchr rawmemchr-vx rawmemchr-c \ ++sysdep_routines += rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 2d48c99c8d5663fe..b4be0140424aed69 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -372,6 +373,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_STRCSPN_IFUNC */ + ++#if HAVE_MEMCHR_IFUNC ++ IFUNC_IMPL (i, name, memchr, ++# if HAVE_MEMCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, memchr, ++ dl_hwcap & HWCAP_S390_VX, MEMCHR_Z13) ++# endif ++# if HAVE_MEMCHR_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memchr, 1, MEMCHR_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -412,7 +425,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wcscspn); + +- IFUNC_VX_IMPL (memchr); + IFUNC_VX_IMPL (wmemchr); + IFUNC_VX_IMPL (rawmemchr); + +diff --git a/sysdeps/s390/s390-32/memchr.S b/sysdeps/s390/s390-32/memchr.S +deleted file mode 100644 +index 54f9b85f578fa1c7..0000000000000000 +--- a/sysdeps/s390/s390-32/memchr.S ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* Search a character in a block of memory. For IBM S390 +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* +- * R2 = address to memory area +- * R3 = character to find +- * R4 = number of bytes to search +- */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(memchr) +- lhi %r0,0xff +- nr %r0,%r3 +- lr %r1,%r2 +- la %r2,0(%r4,%r1) +-0: srst %r2,%r1 +- jo 0b +- brc 13,1f +- slr %r2,%r2 +-1: br %r14 +-END(memchr) +-libc_hidden_builtin_def (memchr) +diff --git a/sysdeps/s390/s390-32/multiarch/memchr.c b/sysdeps/s390/s390-32/multiarch/memchr.c +deleted file mode 100644 +index 5e1610afa43ee549..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memchr.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of memchr. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/memchr.S will be used. */ +-#include +diff --git a/sysdeps/s390/s390-64/multiarch/memchr.c b/sysdeps/s390/s390-64/multiarch/memchr.c +deleted file mode 100644 +index 5e1610afa43ee549..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memchr.c ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* Multiple versions of memchr. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* This wrapper-file is needed, because otherwise file +- sysdeps/s390/s390-[32|64]/memchr.S will be used. */ +-#include diff --git a/SOURCES/glibc-rh1659438-33.patch b/SOURCES/glibc-rh1659438-33.patch new file mode 100644 index 0000000..b2b59ee --- /dev/null +++ b/SOURCES/glibc-rh1659438-33.patch @@ -0,0 +1,287 @@ +commit 4c7b3cec113d9bb7dfc004e22c7a98e310ab9bcc +Author: Stefan Liebler +Date: Tue Dec 18 13:57:16 2018 +0100 + + S390: Refactor rawmemchr ifunc handling. + + The ifunc handling for rawmemchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove rawmemchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add rawmemchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for rawmemchr. + * sysdeps/s390/multiarch/rawmemchr-c.c: Move to ... + * sysdeps/s390/rawmemchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/rawmemchr-vx.S: Move to ... + * sysdeps/s390/rawmemchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/rawmemchr.c: Move to ... + * sysdeps/s390/rawmemchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-rawmemchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 816b2fccdc75e4cf..9b38b461b34176b0 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -53,5 +53,6 @@ sysdep_routines += bzero memset memset-z900 \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ +- memchr memchr-vx memchr-z900 ++ memchr memchr-vx memchr-z900 \ ++ rawmemchr rawmemchr-vx rawmemchr-c + endif +diff --git a/sysdeps/s390/ifunc-rawmemchr.h b/sysdeps/s390/ifunc-rawmemchr.h +new file mode 100644 +index 0000000000000000..bfcbeae802fb372e +--- /dev/null ++++ b/sysdeps/s390/ifunc-rawmemchr.h +@@ -0,0 +1,52 @@ ++/* rawmemchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_RAWMEMCHR_IFUNC 1 ++#else ++# define HAVE_RAWMEMCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT HAVE_RAWMEMCHR_IFUNC ++#else ++# define HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define RAWMEMCHR_DEFAULT RAWMEMCHR_Z13 ++# define HAVE_RAWMEMCHR_C 0 ++# define HAVE_RAWMEMCHR_Z13 1 ++#else ++# define RAWMEMCHR_DEFAULT RAWMEMCHR_C ++# define HAVE_RAWMEMCHR_C 1 ++# define HAVE_RAWMEMCHR_Z13 HAVE_RAWMEMCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_RAWMEMCHR_C ++# define RAWMEMCHR_C __rawmemchr_c ++#else ++# define RAWMEMCHR_C NULL ++#endif ++ ++#if HAVE_RAWMEMCHR_Z13 ++# define RAWMEMCHR_Z13 __rawmemchr_vx ++#else ++# define RAWMEMCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index fa1f7b81db912be0..ac6cfcf9c7dbbc3a 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += rawmemchr rawmemchr-vx rawmemchr-c \ +- memccpy memccpy-vx memccpy-c \ ++sysdep_routines += memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c + endif + +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b4be0140424aed69..bf3b40e111a6bd31 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -385,6 +386,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCHR_IFUNC */ + ++#if HAVE_RAWMEMCHR_IFUNC ++ IFUNC_IMPL (i, name, rawmemchr, ++# if HAVE_RAWMEMCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, rawmemchr, ++ dl_hwcap & HWCAP_S390_VX, RAWMEMCHR_Z13) ++# endif ++# if HAVE_RAWMEMCHR_C ++ IFUNC_IMPL_ADD (array, i, rawmemchr, 1, RAWMEMCHR_C) ++# endif ++ ) ++#endif /* HAVE_RAWMEMCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -426,7 +439,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (wcscspn); + + IFUNC_VX_IMPL (wmemchr); +- IFUNC_VX_IMPL (rawmemchr); + + IFUNC_VX_IMPL (memccpy); + +diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/rawmemchr-c.c +similarity index 67% +rename from sysdeps/s390/multiarch/rawmemchr.c +rename to sysdeps/s390/rawmemchr-c.c +index 5fdb2252df7f8fa1..8b8208e542092383 100644 +--- a/sysdeps/s390/multiarch/rawmemchr.c ++++ b/sysdeps/s390/rawmemchr-c.c +@@ -1,4 +1,4 @@ +-/* Multiple versions of rawmemchr. ++/* Default rawmemchr implementation for S/390. + Copyright (C) 2015-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -16,16 +16,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define __rawmemchr __redirect___rawmemchr +-# include +-# undef __rawmemchr +-# include ++#include + +-s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr +- , __rawmemchr) +-weak_alias (__rawmemchr, rawmemchr) ++#if HAVE_RAWMEMCHR_C ++# if HAVE_RAWMEMCHR_IFUNC ++# define RAWMEMCHR RAWMEMCHR_C ++# undef weak_alias ++# define weak_alias(a, b) ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c); ++# endif ++# endif + +-#else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++#endif +diff --git a/sysdeps/s390/multiarch/rawmemchr-vx.S b/sysdeps/s390/rawmemchr-vx.S +similarity index 87% +rename from sysdeps/s390/multiarch/rawmemchr-vx.S +rename to sysdeps/s390/rawmemchr-vx.S +index d5778be068394394..f04c0e8b616a76ea 100644 +--- a/sysdeps/s390/multiarch/rawmemchr-vx.S ++++ b/sysdeps/s390/rawmemchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_RAWMEMCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +39,7 @@ + -v17=index of unequal + -v18=c replicated + */ +-ENTRY(__rawmemchr_vx) ++ENTRY(RAWMEMCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -88,5 +90,15 @@ ENTRY(__rawmemchr_vx) + .Lend_found: + la %r2,0(%r5,%r2) /* Return pointer to character. */ + br %r14 +-END(__rawmemchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(RAWMEMCHR_Z13) ++ ++# if ! HAVE_RAWMEMCHR_IFUNC ++strong_alias (RAWMEMCHR_Z13, __rawmemchr) ++weak_alias (__rawmemchr, rawmemchr) ++# endif ++ ++# if ! HAVE_RAWMEMCHR_C && defined SHARED && IS_IN (libc) ++strong_alias (RAWMEMCHR_Z13, __GI___rawmemchr) ++# endif ++ ++#endif /* HAVE_RAWMEMCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/rawmemchr-c.c b/sysdeps/s390/rawmemchr.c +similarity index 56% +rename from sysdeps/s390/multiarch/rawmemchr-c.c +rename to sysdeps/s390/rawmemchr.c +index f43c883a76e52480..d9263ce208ea6361 100644 +--- a/sysdeps/s390/multiarch/rawmemchr-c.c ++++ b/sysdeps/s390/rawmemchr.c +@@ -1,4 +1,4 @@ +-/* Default rawmemchr implementation for S/390. ++/* Multiple versions of rawmemchr. + Copyright (C) 2015-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -16,19 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_RAWMEMCHR_IFUNC ++# define __rawmemchr __redirect___rawmemchr + # include ++# undef __rawmemchr ++# include + +-# define RAWMEMCHR __rawmemchr_c +-# undef weak_alias +-# define weak_alias(a, b) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c); +-# endif /* SHARED */ ++# if HAVE_RAWMEMCHR_C ++extern __typeof (__redirect___rawmemchr) RAWMEMCHR_C attribute_hidden; ++# endif + +-extern __typeof (rawmemchr) __rawmemchr_c attribute_hidden; ++# if HAVE_RAWMEMCHR_Z13 ++extern __typeof (__redirect___rawmemchr) RAWMEMCHR_Z13 attribute_hidden; ++# endif + +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect___rawmemchr, __rawmemchr, ++ (HAVE_RAWMEMCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? RAWMEMCHR_Z13 ++ : RAWMEMCHR_DEFAULT ++ ) ++weak_alias (__rawmemchr, rawmemchr) ++#endif /* HAVE_RAWMEMCHR_IFUNC */ diff --git a/SOURCES/glibc-rh1659438-34.patch b/SOURCES/glibc-rh1659438-34.patch new file mode 100644 index 0000000..f2fbe7f --- /dev/null +++ b/SOURCES/glibc-rh1659438-34.patch @@ -0,0 +1,252 @@ +commit 196655ba54ebdcdcc0468bcb6e136757b013d350 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:16 2018 +0100 + + S390: Refactor memccpy ifunc handling. + + The ifunc handling for memccpy is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove memccpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add memccpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for memccpy. + * sysdeps/s390/multiarch/memccpy-c.c: Move to ... + * sysdeps/s390/memccpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memccpy-vx.S: Move to ... + * sysdeps/s390/memccpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memccpy.c: Move to ... + * sysdeps/s390/memccpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-memccpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 9b38b461b34176b0..239426dbc1ce9d09 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -54,5 +54,6 @@ sysdep_routines += bzero memset memset-z900 \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx memchr-z900 \ +- rawmemchr rawmemchr-vx rawmemchr-c ++ rawmemchr rawmemchr-vx rawmemchr-c \ ++ memccpy memccpy-vx memccpy-c + endif +diff --git a/sysdeps/s390/ifunc-memccpy.h b/sysdeps/s390/ifunc-memccpy.h +new file mode 100644 +index 0000000000000000..8f7a1d0f9fffe106 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memccpy.h +@@ -0,0 +1,52 @@ ++/* memccpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCCPY_IFUNC 1 ++#else ++# define HAVE_MEMCCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT HAVE_MEMCCPY_IFUNC ++#else ++# define HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMCCPY_DEFAULT MEMCCPY_Z13 ++# define HAVE_MEMCCPY_C 0 ++# define HAVE_MEMCCPY_Z13 1 ++#else ++# define MEMCCPY_DEFAULT MEMCCPY_C ++# define HAVE_MEMCCPY_C 1 ++# define HAVE_MEMCCPY_Z13 HAVE_MEMCCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMCCPY_C ++# define MEMCCPY_C __memccpy_c ++#else ++# define MEMCCPY_C NULL ++#endif ++ ++#if HAVE_MEMCCPY_Z13 ++# define MEMCCPY_Z13 __memccpy_vx ++#else ++# define MEMCCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memccpy-c.c b/sysdeps/s390/memccpy-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/memccpy-c.c +rename to sysdeps/s390/memccpy-c.c +index 1f4c5481991fcb70..2b2f81eb9cfe9369 100644 +--- a/sysdeps/s390/multiarch/memccpy-c.c ++++ b/sysdeps/s390/memccpy-c.c +@@ -16,10 +16,14 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define MEMCCPY __memccpy_c ++#include ++ ++#if HAVE_MEMCCPY_C ++# if HAVE_MEMCCPY_IFUNC ++# define MEMCCPY MEMCCPY_C ++# undef weak_alias ++# define weak_alias(a, b) ++#endif + +-# include +-extern __typeof (__memccpy) __memccpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/memccpy-vx.S b/sysdeps/s390/memccpy-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/memccpy-vx.S +rename to sysdeps/s390/memccpy-vx.S +index 150aa0e4a48ca181..44f7bc582410ba22 100644 +--- a/sysdeps/s390/multiarch/memccpy-vx.S ++++ b/sysdeps/s390/memccpy-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -42,7 +44,7 @@ + -v19=part #2 of s + -v31=save area for r6 + */ +-ENTRY(__memccpy_vx) ++ENTRY(MEMCCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -152,5 +154,11 @@ ENTRY(__memccpy_vx) + vlgvg %r7,%v31,1 + lghi %r2,0 /* Return null. */ + br %r14 +-END(__memccpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(MEMCCPY_Z13) ++ ++# if ! HAVE_MEMCCPY_IFUNC ++strong_alias (MEMCCPY_Z13, __memccpy) ++weak_alias (__memccpy, memccpy) ++# endif ++ ++#endif /* HAVE_MEMCCPY_Z13 */ +diff --git a/sysdeps/s390/multiarch/memccpy.c b/sysdeps/s390/memccpy.c +similarity index 68% +rename from sysdeps/s390/multiarch/memccpy.c +rename to sysdeps/s390/memccpy.c +index 30aae82321048b7d..bcfeb31e86c56115 100644 +--- a/sysdeps/s390/multiarch/memccpy.c ++++ b/sysdeps/s390/memccpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__memccpy) +-weak_alias (__memccpy, memccpy) ++# if HAVE_MEMCCPY_C ++extern __typeof (__memccpy) MEMCCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_MEMCCPY_Z13 ++extern __typeof (__memccpy) MEMCCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__memccpy, __memccpy, ++ (HAVE_MEMCCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMCCPY_Z13 ++ : MEMCCPY_DEFAULT ++ ) ++weak_alias (__memccpy, memccpy) ++#endif /* HAVE_MEMCCPY_IFUNC */ +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index ac6cfcf9c7dbbc3a..d5a32fc309ba4b3c 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),string) +-sysdep_routines += memccpy memccpy-vx memccpy-c \ +- memrchr memrchr-vx memrchr-c ++sysdep_routines += memrchr memrchr-vx memrchr-c + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index bf3b40e111a6bd31..b8917747f0f23cd9 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -398,6 +399,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_RAWMEMCHR_IFUNC */ + ++#if HAVE_MEMCCPY_IFUNC ++ IFUNC_IMPL (i, name, memccpy, ++# if HAVE_MEMCCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, memccpy, ++ dl_hwcap & HWCAP_S390_VX, MEMCCPY_Z13) ++# endif ++# if HAVE_MEMCCPY_C ++ IFUNC_IMPL_ADD (array, i, memccpy, 1, MEMCCPY_C) ++# endif ++ ) ++#endif /* HAVE_MEMCCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -440,8 +453,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wmemchr); + +- IFUNC_VX_IMPL (memccpy); +- + IFUNC_VX_IMPL (wmemset); + + IFUNC_VX_IMPL (wmemcmp); diff --git a/SOURCES/glibc-rh1659438-35.patch b/SOURCES/glibc-rh1659438-35.patch new file mode 100644 index 0000000..53091b6 --- /dev/null +++ b/SOURCES/glibc-rh1659438-35.patch @@ -0,0 +1,250 @@ +commit 89bfcbdf9d3d36eff0d544f655991149a7ae680b +Author: Stefan Liebler +Date: Tue Dec 18 13:57:17 2018 +0100 + + S390: Refactor memrchr ifunc handling. + + The ifunc handling for memrchr is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove memrchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add memrchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for memrchr. + * sysdeps/s390/multiarch/memrchr-c.c: Move to ... + * sysdeps/s390/memrchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memrchr-vx.S: Move to ... + * sysdeps/s390/memrchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/memrchr.c: Move to ... + * sysdeps/s390/memrchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-memrchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 239426dbc1ce9d09..9a16ce1692e51607 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -55,5 +55,6 @@ sysdep_routines += bzero memset memset-z900 \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx memchr-z900 \ + rawmemchr rawmemchr-vx rawmemchr-c \ +- memccpy memccpy-vx memccpy-c ++ memccpy memccpy-vx memccpy-c \ ++ memrchr memrchr-vx memrchr-c + endif +diff --git a/sysdeps/s390/ifunc-memrchr.h b/sysdeps/s390/ifunc-memrchr.h +new file mode 100644 +index 0000000000000000..9d80d5528dc92dab +--- /dev/null ++++ b/sysdeps/s390/ifunc-memrchr.h +@@ -0,0 +1,52 @@ ++/* memrchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_MEMRCHR_IFUNC 1 ++#else ++# define HAVE_MEMRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT HAVE_MEMRCHR_IFUNC ++#else ++# define HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define MEMRCHR_DEFAULT MEMRCHR_Z13 ++# define HAVE_MEMRCHR_C 0 ++# define HAVE_MEMRCHR_Z13 1 ++#else ++# define MEMRCHR_DEFAULT MEMRCHR_C ++# define HAVE_MEMRCHR_C 1 ++# define HAVE_MEMRCHR_Z13 HAVE_MEMRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_MEMRCHR_C ++# define MEMRCHR_C __memrchr_c ++#else ++# define MEMRCHR_C NULL ++#endif ++ ++#if HAVE_MEMRCHR_Z13 ++# define MEMRCHR_Z13 __memrchr_vx ++#else ++# define MEMRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memrchr-c.c b/sysdeps/s390/memrchr-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/memrchr-c.c +rename to sysdeps/s390/memrchr-c.c +index 1e3c914a5d61dbc5..333c0fc8d1855323 100644 +--- a/sysdeps/s390/multiarch/memrchr-c.c ++++ b/sysdeps/s390/memrchr-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define MEMRCHR __memrchr_c ++#include ++ ++#if HAVE_MEMRCHR_C ++# if HAVE_MEMRCHR_IFUNC ++# define MEMRCHR MEMRCHR_C ++# endif + +-# include +-extern __typeof (__memrchr) __memrchr_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/memrchr-vx.S b/sysdeps/s390/memrchr-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/memrchr-vx.S +rename to sysdeps/s390/memrchr-vx.S +index 8e81f5ed7519c2cc..ba832f1b21ad5a4c 100644 +--- a/sysdeps/s390/multiarch/memrchr-vx.S ++++ b/sysdeps/s390/memrchr-vx.S +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +42,7 @@ + -v18=c replicated + -v20=permute pattern + */ +-ENTRY(__memrchr_vx) ++ENTRY(MEMRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -156,5 +158,11 @@ ENTRY(__memrchr_vx) + + clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ + j .Llt64 +-END(__memrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(MEMRCHR_Z13) ++ ++# if ! HAVE_MEMRCHR_IFUNC ++strong_alias (MEMRCHR_Z13, __memrchr) ++weak_alias (__memrchr, memrchr) ++# endif ++ ++#endif /* HAVE_MEMRCHR_Z13 */ +diff --git a/sysdeps/s390/multiarch/memrchr.c b/sysdeps/s390/memrchr.c +similarity index 68% +rename from sysdeps/s390/multiarch/memrchr.c +rename to sysdeps/s390/memrchr.c +index 43a44abcf6cc3bdc..d995e9961c1cc9eb 100644 +--- a/sysdeps/s390/multiarch/memrchr.c ++++ b/sysdeps/s390/memrchr.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_MEMRCHR_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__memrchr) +-weak_alias (__memrchr, memrchr) ++# if HAVE_MEMRCHR_C ++extern __typeof (__memrchr) MEMRCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_MEMRCHR_Z13 ++extern __typeof (__memrchr) MEMRCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__memrchr, __memrchr, ++ (HAVE_MEMRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMRCHR_Z13 ++ : MEMRCHR_DEFAULT ++ ) ++weak_alias (__memrchr, memrchr) ++#endif /* HAVE_MEMRCHR_IFUNC */ +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index d5a32fc309ba4b3c..260b514936b93306 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,7 +1,3 @@ +-ifeq ($(subdir),string) +-sysdep_routines += memrchr memrchr-vx memrchr-c +-endif +- + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b8917747f0f23cd9..0f01b99691002be0 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -411,6 +412,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCCPY_IFUNC */ + ++#if HAVE_MEMRCHR_IFUNC ++ IFUNC_IMPL (i, name, memrchr, ++# if HAVE_MEMRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, memrchr, ++ dl_hwcap & HWCAP_S390_VX, MEMRCHR_Z13) ++# endif ++# if HAVE_MEMRCHR_C ++ IFUNC_IMPL_ADD (array, i, memrchr, 1, MEMRCHR_C) ++# endif ++ ) ++#endif /* HAVE_MEMRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -457,8 +470,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wmemcmp); + +- IFUNC_VX_IMPL (memrchr); +- + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; diff --git a/SOURCES/glibc-rh1659438-36.patch b/SOURCES/glibc-rh1659438-36.patch new file mode 100644 index 0000000..146d137 --- /dev/null +++ b/SOURCES/glibc-rh1659438-36.patch @@ -0,0 +1,252 @@ +commit 2e02d0b7a9bf3421638d2d0f2526275a1df5c0da +Author: Stefan Liebler +Date: Tue Dec 18 13:57:17 2018 +0100 + + S390: Refactor wcslen ifunc handling. + + The ifunc handling for wcslen is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcslen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcslen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcslen. + * sysdeps/s390/multiarch/wcslen-c.c: Move to ... + * sysdeps/s390/wcslen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcslen-vx.S: Move to ... + * sysdeps/s390/wcslen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcslen.c: Move to ... + * sysdeps/s390/wcslen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcslen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 9a16ce1692e51607..65e89118936bb668 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -58,3 +58,7 @@ sysdep_routines += bzero memset memset-z900 \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c + endif ++ ++ifeq ($(subdir),wcsmbs) ++sysdep_routines += wcslen wcslen-vx wcslen-c ++endif +diff --git a/sysdeps/s390/ifunc-wcslen.h b/sysdeps/s390/ifunc-wcslen.h +new file mode 100644 +index 0000000000000000..50d879caf2b8186b +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcslen.h +@@ -0,0 +1,53 @@ ++/* wcslen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSLEN_IFUNC 1 ++#else ++# define HAVE_WCSLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT HAVE_WCSLEN_IFUNC ++#else ++# define HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSLEN_DEFAULT WCSLEN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSLEN_C 1 ++# define HAVE_WCSLEN_Z13 1 ++#else ++# define WCSLEN_DEFAULT WCSLEN_C ++# define HAVE_WCSLEN_C 1 ++# define HAVE_WCSLEN_Z13 HAVE_WCSLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSLEN_C ++# define WCSLEN_C __wcslen_c ++#else ++# define WCSLEN_C NULL ++#endif ++ ++#if HAVE_WCSLEN_Z13 ++# define WCSLEN_Z13 __wcslen_vx ++#else ++# define WCSLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 260b514936b93306..421d40d020b81560 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcslen wcslen-vx wcslen-c \ +- wcsnlen wcsnlen-vx wcsnlen-c \ ++sysdep_routines += wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 0f01b99691002be0..7bf5f14c015b54fe 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -424,6 +425,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMRCHR_IFUNC */ + ++#if HAVE_WCSLEN_IFUNC ++ IFUNC_IMPL (i, name, wcslen, ++# if HAVE_WCSLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcslen, ++ dl_hwcap & HWCAP_S390_VX, WCSLEN_Z13) ++# endif ++# if HAVE_WCSLEN_C ++ IFUNC_IMPL_ADD (array, i, wcslen, 1, WCSLEN_C) ++# endif ++ ) ++#endif /* HAVE_WCSLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -432,8 +445,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcslen); +- + IFUNC_VX_IMPL (wcsnlen); + + IFUNC_VX_IMPL (wcscpy); +diff --git a/sysdeps/s390/multiarch/wcslen-c.c b/sysdeps/s390/wcslen-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcslen-c.c +rename to sysdeps/s390/wcslen-c.c +index 32a23e206d2e9cf9..45399cff3a127b5e 100644 +--- a/sysdeps/s390/multiarch/wcslen-c.c ++++ b/sysdeps/s390/wcslen-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSLEN __wcslen_c ++#include ++ ++#if HAVE_WCSLEN_C ++# if HAVE_WCSLEN_IFUNC || HAVE_WCSLEN_Z13 ++# define WCSLEN WCSLEN_C ++# endif + +-# include +-extern __typeof (__wcslen) __wcslen_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcslen-vx.S b/sysdeps/s390/wcslen-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wcslen-vx.S +rename to sysdeps/s390/wcslen-vx.S +index 337cbed6ec21db76..114f7ef743b10c63 100644 +--- a/sysdeps/s390/multiarch/wcslen-vx.S ++++ b/sysdeps/s390/wcslen-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +35,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__wcslen_vx) ++ENTRY(WCSLEN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -86,6 +87,11 @@ ENTRY(__wcslen_vx) + srlg %r2,%r2,2 /* Convert byte-count to character-count. */ + br %r14 + .Lfallback: +- jg __wcslen_c +-END(__wcslen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSLEN_C ++END(WCSLEN_Z13) ++ ++# if ! HAVE_WCSLEN_IFUNC ++strong_alias (WCSLEN_Z13, __wcslen) ++weak_alias (__wcslen, wcslen) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcslen.c b/sysdeps/s390/wcslen.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcslen.c +rename to sysdeps/s390/wcslen.c +index 3a1d1a32c9a99749..a5eee83f6cae7166 100644 +--- a/sysdeps/s390/multiarch/wcslen.c ++++ b/sysdeps/s390/wcslen.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSLEN_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcslen) +-weak_alias (__wcslen, wcslen) ++# if HAVE_WCSLEN_C ++extern __typeof (__wcslen) WCSLEN_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSLEN_Z13 ++extern __typeof (__wcslen) WCSLEN_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcslen, __wcslen, ++ (HAVE_WCSLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSLEN_Z13 ++ : WCSLEN_DEFAULT ++ ) ++weak_alias (__wcslen, wcslen) ++#endif diff --git a/SOURCES/glibc-rh1659438-37.patch b/SOURCES/glibc-rh1659438-37.patch new file mode 100644 index 0000000..827d82d --- /dev/null +++ b/SOURCES/glibc-rh1659438-37.patch @@ -0,0 +1,253 @@ +commit c7e7cd266ed123b6dfb722f599934ca5dcfd3e93 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:18 2018 +0100 + + S390: Refactor wcsnlen ifunc handling. + + The ifunc handling for wcsnlen is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsnlen variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsnlen variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsnlen. + * sysdeps/s390/multiarch/wcsnlen-c.c: Move to ... + * sysdeps/s390/wcsnlen-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsnlen-vx.S: Move to ... + * sysdeps/s390/wcsnlen-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsnlen.c: Move to ... + * sysdeps/s390/wcsnlen.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsnlen.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 65e89118936bb668..f5983815479a76da 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -60,5 +60,6 @@ sysdep_routines += bzero memset memset-z900 \ + endif + + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcslen wcslen-vx wcslen-c ++sysdep_routines += wcslen wcslen-vx wcslen-c \ ++ wcsnlen wcsnlen-vx wcsnlen-c + endif +diff --git a/sysdeps/s390/ifunc-wcsnlen.h b/sysdeps/s390/ifunc-wcsnlen.h +new file mode 100644 +index 0000000000000000..b5b21da2f17d9cd9 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsnlen.h +@@ -0,0 +1,53 @@ ++/* wcsnlen variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNLEN_IFUNC 1 ++#else ++# define HAVE_WCSNLEN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT HAVE_WCSNLEN_IFUNC ++#else ++# define HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNLEN_DEFAULT WCSNLEN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSNLEN_C 1 ++# define HAVE_WCSNLEN_Z13 1 ++#else ++# define WCSNLEN_DEFAULT WCSNLEN_C ++# define HAVE_WCSNLEN_C 1 ++# define HAVE_WCSNLEN_Z13 HAVE_WCSNLEN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNLEN_C ++# define WCSNLEN_C __wcsnlen_c ++#else ++# define WCSNLEN_C NULL ++#endif ++ ++#if HAVE_WCSNLEN_Z13 ++# define WCSNLEN_Z13 __wcsnlen_vx ++#else ++# define WCSNLEN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 421d40d020b81560..ce2e7ce5f4eef0fa 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsnlen wcsnlen-vx wcsnlen-c \ +- wcscpy wcscpy-vx wcscpy-c \ ++sysdep_routines += wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7bf5f14c015b54fe..c199fd0e0b43e4b4 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -437,6 +438,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSLEN_IFUNC */ + ++#if HAVE_WCSNLEN_IFUNC ++ IFUNC_IMPL (i, name, wcsnlen, ++# if HAVE_WCSNLEN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsnlen, ++ dl_hwcap & HWCAP_S390_VX, WCSNLEN_Z13) ++# endif ++# if HAVE_WCSNLEN_C ++ IFUNC_IMPL_ADD (array, i, wcsnlen, 1, WCSNLEN_C) ++# endif ++ ) ++#endif /* HAVE_WCSNLEN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -445,8 +458,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsnlen); +- + IFUNC_VX_IMPL (wcscpy); + + IFUNC_VX_IMPL (wcpcpy); +diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/wcsnlen-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsnlen-c.c +rename to sysdeps/s390/wcsnlen-c.c +index 8f43f5104f2eab3f..7495a6f97cfeca62 100644 +--- a/sysdeps/s390/multiarch/wcsnlen-c.c ++++ b/sysdeps/s390/wcsnlen-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNLEN __wcsnlen_c ++#include ++ ++#if HAVE_WCSNLEN_C ++# if HAVE_WCSNLEN_IFUNC || HAVE_WCSNLEN_Z13 ++# define WCSNLEN WCSNLEN_C ++# endif + +-# include +-extern __typeof (__wcsnlen) __wcsnlen_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsnlen-vx.S b/sysdeps/s390/wcsnlen-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/wcsnlen-vx.S +rename to sysdeps/s390/wcsnlen-vx.S +index 420f29fbc0d2965a..47f4ca82840538d9 100644 +--- a/sysdeps/s390/multiarch/wcsnlen-vx.S ++++ b/sysdeps/s390/wcsnlen-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNLEN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -34,7 +35,7 @@ + -r5=current_len and return_value + -v16=part of s + */ +-ENTRY(__wcsnlen_vx) ++ENTRY(WCSNLEN_Z13) + + .machine "z13" + .machinemode "zarch_nohighgprs" +@@ -146,6 +147,11 @@ ENTRY(__wcsnlen_vx) + j .Llt64 + + .Lfallback: +- jg __wcsnlen_c +-END(__wcsnlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSNLEN_C ++END(WCSNLEN_Z13) ++ ++# if ! HAVE_WCSNLEN_IFUNC ++strong_alias (WCSNLEN_Z13, __wcsnlen) ++weak_alias (__wcsnlen, wcsnlen) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/wcsnlen.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcsnlen.c +rename to sysdeps/s390/wcsnlen.c +index 5234074b1fce8ca1..b5c8ad9fde5a9752 100644 +--- a/sysdeps/s390/multiarch/wcsnlen.c ++++ b/sysdeps/s390/wcsnlen.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNLEN_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcsnlen) +-weak_alias (__wcsnlen, wcsnlen) ++# if HAVE_WCSNLEN_C ++extern __typeof (__wcsnlen) WCSNLEN_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSNLEN_Z13 ++extern __typeof (__wcsnlen) WCSNLEN_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcsnlen, __wcsnlen, ++ (HAVE_WCSNLEN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNLEN_Z13 ++ : WCSNLEN_DEFAULT ++ ) ++weak_alias (__wcsnlen, wcsnlen) ++#endif diff --git a/SOURCES/glibc-rh1659438-38.patch b/SOURCES/glibc-rh1659438-38.patch new file mode 100644 index 0000000..7549d69 --- /dev/null +++ b/SOURCES/glibc-rh1659438-38.patch @@ -0,0 +1,249 @@ +commit 804f2e5c73b1363836ce5db29a0abb3d36e1286a +Author: Stefan Liebler +Date: Tue Dec 18 13:57:18 2018 +0100 + + S390: Refactor wcscpy ifunc handling. + + The ifunc handling for wcscpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscpy. + * sysdeps/s390/multiarch/wcscpy-c.c: Move to ... + * sysdeps/s390/wcscpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscpy-vx.S: Move to ... + * sysdeps/s390/wcscpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscpy.c: Move to ... + * sysdeps/s390/wcscpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index f5983815479a76da..8bdbd1b5d8e9df01 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -61,5 +61,6 @@ endif + + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ +- wcsnlen wcsnlen-vx wcsnlen-c ++ wcsnlen wcsnlen-vx wcsnlen-c \ ++ wcscpy wcscpy-vx wcscpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcscpy.h b/sysdeps/s390/ifunc-wcscpy.h +new file mode 100644 +index 0000000000000000..fba7c9c7a7c354d1 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscpy.h +@@ -0,0 +1,53 @@ ++/* wcscpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCPY_IFUNC 1 ++#else ++# define HAVE_WCSCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT HAVE_WCSCPY_IFUNC ++#else ++# define HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCPY_DEFAULT WCSCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCPY_C 1 ++# define HAVE_WCSCPY_Z13 1 ++#else ++# define WCSCPY_DEFAULT WCSCPY_C ++# define HAVE_WCSCPY_C 1 ++# define HAVE_WCSCPY_Z13 HAVE_WCSCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCPY_C ++# define WCSCPY_C __wcscpy_c ++#else ++# define WCSCPY_C NULL ++#endif ++ ++#if HAVE_WCSCPY_Z13 ++# define WCSCPY_Z13 __wcscpy_vx ++#else ++# define WCSCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index ce2e7ce5f4eef0fa..8828897a59ae580c 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscpy wcscpy-vx wcscpy-c \ +- wcpcpy wcpcpy-vx wcpcpy-c \ ++sysdep_routines += wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c199fd0e0b43e4b4..aac8f4ea4671d0cf 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -450,6 +451,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNLEN_IFUNC */ + ++#if HAVE_WCSCPY_IFUNC ++ IFUNC_IMPL (i, name, wcscpy, ++# if HAVE_WCSCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscpy, ++ dl_hwcap & HWCAP_S390_VX, WCSCPY_Z13) ++# endif ++# if HAVE_WCSCPY_C ++ IFUNC_IMPL_ADD (array, i, wcscpy, 1, WCSCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCSCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -458,8 +471,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscpy); +- + IFUNC_VX_IMPL (wcpcpy); + + IFUNC_VX_IMPL (wcsncpy); +diff --git a/sysdeps/s390/multiarch/wcscpy-c.c b/sysdeps/s390/wcscpy-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcscpy-c.c +rename to sysdeps/s390/wcscpy-c.c +index 4a510f466be80679..db2967f47d7bc3cc 100644 +--- a/sysdeps/s390/multiarch/wcscpy-c.c ++++ b/sysdeps/s390/wcscpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCPY __wcscpy_c ++#include ++ ++#if HAVE_WCSCPY_C ++# if HAVE_WCSCPY_IFUNC || HAVE_WCSCPY_Z13 ++# define WCSCPY WCSCPY_C ++# endif + +-# include +-extern __typeof (wcscpy) __wcscpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcscpy-vx.S b/sysdeps/s390/wcscpy-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/wcscpy-vx.S +rename to sysdeps/s390/wcscpy-vx.S +index c2e81055be958907..8fe12f4d8b3e66a8 100644 +--- a/sysdeps/s390/multiarch/wcscpy-vx.S ++++ b/sysdeps/s390/wcscpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__wcscpy_vx) ++ENTRY(WCSCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -106,6 +107,10 @@ ENTRY(__wcscpy_vx) + br %r14 + + .Lfallback: +- jg __wcscpy_c +-END(__wcscpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCPY_C ++END(WCSCPY_Z13) ++ ++# if ! HAVE_WCSCPY_IFUNC ++strong_alias (WCSCPY_Z13, wcscpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscpy.c b/sysdeps/s390/wcscpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcscpy.c +rename to sysdeps/s390/wcscpy.c +index e69baa6c59906df3..51f07327da1bec74 100644 +--- a/sysdeps/s390/multiarch/wcscpy.c ++++ b/sysdeps/s390/wcscpy.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcscpy, wcscpy) ++# if HAVE_WCSCPY_C ++extern __typeof (wcscpy) WCSCPY_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSCPY_Z13 ++extern __typeof (wcscpy) WCSCPY_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcscpy, wcscpy, ++ (HAVE_WCSCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCPY_Z13 ++ : WCSCPY_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-39.patch b/SOURCES/glibc-rh1659438-39.patch new file mode 100644 index 0000000..8fe2754 --- /dev/null +++ b/SOURCES/glibc-rh1659438-39.patch @@ -0,0 +1,252 @@ +commit 0582e4284529b4ea0fcd1a8973ccab7d95ec0e87 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:19 2018 +0100 + + S390: Refactor wcpcpy ifunc handling. + + The ifunc handling for wcpcpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcpcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcpcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcpcpy. + * sysdeps/s390/multiarch/wcpcpy-c.c: Move to ... + * sysdeps/s390/wcpcpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpcpy-vx.S: Move to ... + * sysdeps/s390/wcpcpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpcpy.c: Move to ... + * sysdeps/s390/wcpcpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcpcpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 8bdbd1b5d8e9df01..5b6446f55299af03 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -62,5 +62,6 @@ endif + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ +- wcscpy wcscpy-vx wcscpy-c ++ wcscpy wcscpy-vx wcscpy-c \ ++ wcpcpy wcpcpy-vx wcpcpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcpcpy.h b/sysdeps/s390/ifunc-wcpcpy.h +new file mode 100644 +index 0000000000000000..0d5e2ba1a0b09905 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcpcpy.h +@@ -0,0 +1,53 @@ ++/* wcpcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCPCPY_IFUNC 1 ++#else ++# define HAVE_WCPCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT HAVE_WCPCPY_IFUNC ++#else ++# define HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCPCPY_DEFAULT WCPCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCPCPY_C 1 ++# define HAVE_WCPCPY_Z13 1 ++#else ++# define WCPCPY_DEFAULT WCPCPY_C ++# define HAVE_WCPCPY_C 1 ++# define HAVE_WCPCPY_Z13 HAVE_WCPCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCPCPY_C ++# define WCPCPY_C __wcpcpy_c ++#else ++# define WCPCPY_C NULL ++#endif ++ ++#if HAVE_WCPCPY_Z13 ++# define WCPCPY_Z13 __wcpcpy_vx ++#else ++# define WCPCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 8828897a59ae580c..7d7b05dcf21cff7d 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcpcpy wcpcpy-vx wcpcpy-c \ +- wcsncpy wcsncpy-vx wcsncpy-c \ ++sysdep_routines += wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index aac8f4ea4671d0cf..656ab59db66dbb48 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -463,6 +464,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCPY_IFUNC */ + ++#if HAVE_WCPCPY_IFUNC ++ IFUNC_IMPL (i, name, wcpcpy, ++# if HAVE_WCPCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcpcpy, ++ dl_hwcap & HWCAP_S390_VX, WCPCPY_Z13) ++# endif ++# if HAVE_WCPCPY_C ++ IFUNC_IMPL_ADD (array, i, wcpcpy, 1, WCPCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCPCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -471,8 +484,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcpcpy); +- + IFUNC_VX_IMPL (wcsncpy); + + IFUNC_VX_IMPL (wcpncpy); +diff --git a/sysdeps/s390/multiarch/wcpcpy-c.c b/sysdeps/s390/wcpcpy-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcpcpy-c.c +rename to sysdeps/s390/wcpcpy-c.c +index e3282fde19c5262a..ed1539cde2f6f858 100644 +--- a/sysdeps/s390/multiarch/wcpcpy-c.c ++++ b/sysdeps/s390/wcpcpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCPCPY __wcpcpy_c ++#include ++ ++#if HAVE_WCPCPY_C ++# if HAVE_WCPCPY_IFUNC || HAVE_WCPCPY_Z13 ++# define WCPCPY WCPCPY_C ++# endif + +-# include +-extern __typeof (__wcpcpy) __wcpcpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcpcpy-vx.S b/sysdeps/s390/wcpcpy-vx.S +similarity index 94% +rename from sysdeps/s390/multiarch/wcpcpy-vx.S +rename to sysdeps/s390/wcpcpy-vx.S +index bff6e8562884066c..5154ad44610c1ed1 100644 +--- a/sysdeps/s390/multiarch/wcpcpy-vx.S ++++ b/sysdeps/s390/wcpcpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCPCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__wcpcpy_vx) ++ENTRY(WCPCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -109,6 +110,11 @@ ENTRY(__wcpcpy_vx) + br %r14 + + .Lfallback: +- jg __wcpcpy_c +-END(__wcpcpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCPCPY_C ++END(WCPCPY_Z13) ++ ++# if ! HAVE_WCPCPY_IFUNC ++strong_alias (WCPCPY_Z13, __wcpcpy) ++weak_alias (__wcpcpy, wcpcpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcpcpy.c b/sysdeps/s390/wcpcpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcpcpy.c +rename to sysdeps/s390/wcpcpy.c +index f19d376d8530d0a4..34ac68b31fedcb09 100644 +--- a/sysdeps/s390/multiarch/wcpcpy.c ++++ b/sysdeps/s390/wcpcpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCPCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcpcpy) +-weak_alias (__wcpcpy, wcpcpy) ++# if HAVE_WCPCPY_C ++extern __typeof (__wcpcpy) WCPCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCPCPY_Z13 ++extern __typeof (__wcpcpy) WCPCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcpcpy, __wcpcpy, ++ (HAVE_WCPCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCPCPY_Z13 ++ : WCPCPY_DEFAULT ++ ) ++weak_alias (__wcpcpy, wcpcpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-4.patch b/SOURCES/glibc-rh1659438-4.patch new file mode 100644 index 0000000..38bf785 --- /dev/null +++ b/SOURCES/glibc-rh1659438-4.patch @@ -0,0 +1,521 @@ +commit 712a254a97ade7f48fb7a434339faa05c048ce1f +Author: Stefan Liebler +Date: Tue Dec 18 13:57:04 2018 +0100 + + S390: Refactor memset ifunc handling. + + This patch moves all ifunc variants for memset + to sysdeps/s390/memset-z900.S. The configure-check/preprocessor logic + in sysdeps/s390/ifunc-memset.h decides if ifunc is needed at all + and which ifunc variants should be available. + E.g. if the compiler/assembler already supports z196 by default, + the older ifunc variants are not included. + If we only need the newest ifunc variant, + then we can skip ifunc at all. + + Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted + in order to handle only the available ifunc variants. + + ChangeLog: + + * sysdeps/s390/ifunc-memset.h: New File. + * sysdeps/s390/memset.S: Move to ... + * sysdeps/s390/memset-z900.S ... here. + Move implementations from memset-s390x.s to here. + * sysdeps/s390/multiarch/memset-s390x.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): + Remove memset variants. + * sysdeps/s390/Makefile (sysdep_routines): + Add memset variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Adjust ifunc variants for + memset. + * sysdeps/s390/multiarch/memset.c: Move ifunc resolver + to ... + * sysdeps/s390/memset.c: ... here. + Adjust ifunc variants for memset. + +Conflicts: + sysdeps/s390/Makefile + Missing backport of commit 69e2444ab1444ab8210598abbcb4822701d368b9 + ("S390: Test that lazy binding does not clobber R0"). + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 8a54f88cd7ac880e..360838e172f4ca37 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -29,3 +29,7 @@ $(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) + + sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules + endif ++ ++ifeq ($(subdir),string) ++sysdep_routines += memset memset-z900 ++endif +diff --git a/sysdeps/s390/ifunc-memset.h b/sysdeps/s390/ifunc-memset.h +new file mode 100644 +index 0000000000000000..9a13b1001fed9979 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memset.h +@@ -0,0 +1,65 @@ ++/* memset variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_MEMSET_IFUNC 1 ++#else ++# define HAVE_MEMSET_IFUNC 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define MEMSET_DEFAULT MEMSET_Z196 ++# define HAVE_MEMSET_Z900_G5 0 ++# define HAVE_MEMSET_Z10 0 ++# define HAVE_MEMSET_Z196 1 ++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++# define MEMSET_DEFAULT MEMSET_Z10 ++# define HAVE_MEMSET_Z900_G5 0 ++# define HAVE_MEMSET_Z10 1 ++# define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC ++#else ++# define MEMSET_DEFAULT MEMSET_Z900_G5 ++# define HAVE_MEMSET_Z900_G5 1 ++# define HAVE_MEMSET_Z10 HAVE_MEMSET_IFUNC ++# define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC ++#endif ++ ++#if HAVE_MEMSET_Z10 || HAVE_MEMSET_Z196 ++# define HAVE_MEMSET_MVCLE 1 ++#else ++# define HAVE_MEMSET_MVCLE 0 ++#endif ++ ++#if HAVE_MEMSET_Z900_G5 ++# define MEMSET_Z900_G5 __memset_default ++#else ++# define MEMSET_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMSET_Z10 ++# define MEMSET_Z10 __memset_z10 ++#else ++# define MEMSET_Z10 NULL ++#endif ++ ++#if HAVE_MEMSET_Z196 ++# define MEMSET_Z196 __memset_z196 ++#else ++# define MEMSET_Z196 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memset-s390x.S b/sysdeps/s390/memset-z900.S +similarity index 57% +rename from sysdeps/s390/multiarch/memset-s390x.S +rename to sysdeps/s390/memset-z900.S +index aca3ac3fda1dd228..eaf13402bd3e251d 100644 +--- a/sysdeps/s390/multiarch/memset-s390x.S ++++ b/sysdeps/s390/memset-z900.S +@@ -1,5 +1,6 @@ + /* Set a block of memory to some byte value. 31/64 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. ++ Copyright (C) 2001-2018 Free Software Foundation, Inc. ++ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,8 +18,9 @@ + . */ + + +-#include "sysdep.h" ++#include + #include "asm-syntax.h" ++#include + + /* INPUT PARAMETERS + %r2 = address of memory area +@@ -27,43 +29,68 @@ + + .text + +-#if IS_IN (libc) ++#if HAVE_MEMSET_Z900_G5 ++# if defined __s390x__ ++# define LTGR ltgr ++# define CGHI cghi ++# define LGR lgr ++# define AGHI aghi ++# define BRCTG brctg ++# else ++# define LTGR ltr ++# define CGHI chi ++# define LGR lr ++# define AGHI ahi ++# define BRCTG brct ++# endif /* ! defined __s390x__ */ + +-ENTRY(__memset_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- ltgr %r4,%r4 +- je .L_Z196_4 ++ENTRY(MEMSET_Z900_G5) ++#if defined __s390x__ ++ .machine "z900" ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 + stc %r3,0(%r2) +- lgr %r1,%r2 +- cghi %r4,1 +- je .L_Z196_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_1 +-.L_Z196_3: +- exrl %r4,.L_Z196_17 +-.L_Z196_4: ++ CGHI %r4,1 ++ LGR %r1,%r2 ++ je .L_Z900_G5_4 ++ AGHI %r4,-2 ++#if defined __s390x__ ++ larl %r5,.L_Z900_G5_18 ++ srlg %r3,%r4,8 ++# define Z900_G5_EX_D 0 ++#else ++ basr %r5,0 ++.L_Z900_G5_19: ++# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19 ++ lr %r3,%r4 ++ srl %r3,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r3,%r3 ++ jne .L_Z900_G5_14 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + br %r14 +-.L_Z196_1: +- cgfi %r5,1048576 +- jh __memset_mvcle # Switch to mvcle for >256MB +-.L_Z196_2: +- pfd 2,1024(%r1) ++.L_Z900_G5_14: + mvc 1(256,%r1),0(%r1) +- aghi %r5,-1 + la %r1,256(%r1) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_17: ++ BRCTG %r3,.L_Z900_G5_14 ++ j .L_Z900_G5_3 ++.L_Z900_G5_18: + mvc 1(1,%r1),0(%r1) +-END(__memset_z196) ++END(MEMSET_Z900_G5) ++# undef LTGR ++# undef CGHI ++# undef LGR ++# undef AGHI ++# undef BRCTG ++#endif /* HAVE_MEMSET_Z900_G5 */ + +-ENTRY(__memset_z10) ++#if HAVE_MEMSET_Z10 ++ENTRY(MEMSET_Z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -91,8 +118,46 @@ ENTRY(__memset_z10) + j .L_Z10_3 + .L_Z10_18: + mvc 1(1,%r1),0(%r1) +-END(__memset_z10) ++END(MEMSET_Z10) ++#endif /* HAVE_MEMSET_Z10 */ ++ ++#if HAVE_MEMSET_Z196 ++ENTRY(MEMSET_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ stc %r3,0(%r2) ++ lgr %r1,%r2 ++ cghi %r4,1 ++ je .L_Z196_4 ++ aghi %r4,-2 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_1 ++.L_Z196_3: ++ exrl %r4,.L_Z196_17 ++.L_Z196_4: ++ br %r14 ++.L_Z196_1: ++ cgfi %r5,1048576 ++ jh __memset_mvcle # Switch to mvcle for >256MB ++.L_Z196_2: ++ pfd 2,1024(%r1) ++ mvc 1(256,%r1),0(%r1) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_17: ++ mvc 1(1,%r1),0(%r1) ++END(MEMSET_Z196) ++#endif /* HAVE_MEMSET_Z196 */ + ++#if HAVE_MEMSET_MVCLE + ENTRY(__memset_mvcle) + aghi %r4,2 # take back the change done by the caller + lgr %r0,%r2 # save source address +@@ -106,15 +171,16 @@ ENTRY(__memset_mvcle) + .L1: + br %r14 + END(__memset_mvcle) ++#endif /* HAVE_MEMSET_MVCLE */ + +-#endif /* IS_IN (libc) */ +- +-#include "../memset.S" ++#if ! HAVE_MEMSET_IFUNC ++/* If we don't use ifunc, define an alias for memset here. ++ Otherwise see sysdeps/s390/memset.c. */ ++strong_alias (MEMSET_DEFAULT, memset) ++#endif + +-#if !IS_IN (libc) +-.globl memset +-.set memset,__memset_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memset +-.set __GI_memset,__memset_default ++#if defined SHARED && IS_IN (libc) ++/* Defines the internal symbol. ++ Compare to libc_hidden_builtin_def (memset) in string/memset.c. */ ++strong_alias (MEMSET_DEFAULT, __GI_memset) + #endif +diff --git a/sysdeps/s390/memset.S b/sysdeps/s390/memset.S +deleted file mode 100644 +index 72e7c5a42efbaf6c..0000000000000000 +--- a/sysdeps/s390/memset.S ++++ /dev/null +@@ -1,97 +0,0 @@ +-/* Set a block of memory to some byte value. 31/64 bit S/390 version. +- Copyright (C) 2001-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#if defined __s390x__ +-# define LTGR ltgr +-# define CGHI cghi +-# define LGR lgr +-# define AGHI aghi +-# define BRCTG brctg +-#else +-# define LTGR ltr +-# define CGHI chi +-# define LGR lr +-# define AGHI ahi +-# define BRCTG brct +-#endif /* ! defined __s390x__ */ +- +-#ifdef USE_MULTIARCH +-ENTRY(__memset_default) +-#else +-ENTRY(memset) +-#endif +-#if defined __s390x__ +- .machine "z900" +-#else +- .machine "g5" +-#endif /* ! defined __s390x__ */ +- LTGR %r4,%r4 +- je .L_Z900_G5_4 +- stc %r3,0(%r2) +- CGHI %r4,1 +- LGR %r1,%r2 +- je .L_Z900_G5_4 +- AGHI %r4,-2 +-#if defined __s390x__ +- larl %r5,.L_Z900_G5_18 +- srlg %r3,%r4,8 +-# define Z900_G5_EX_D 0 +-#else +- basr %r5,0 +-.L_Z900_G5_19: +-# define Z900_G5_EX_D .L_Z900_G5_18-.L_Z900_G5_19 +- lr %r3,%r4 +- srl %r3,8 +-#endif /* ! defined __s390x__ */ +- LTGR %r3,%r3 +- jne .L_Z900_G5_14 +-.L_Z900_G5_3: +- ex %r4,Z900_G5_EX_D(%r5) +-.L_Z900_G5_4: +- br %r14 +-.L_Z900_G5_14: +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- BRCTG %r3,.L_Z900_G5_14 +- j .L_Z900_G5_3 +-.L_Z900_G5_18: +- mvc 1(1,%r1),0(%r1) +-#ifdef USE_MULTIARCH +-END(__memset_default) +-#else +-END(memset) +-libc_hidden_builtin_def (memset) +-#endif +- +-#undef LTGR +-#undef CGHI +-#undef LGR +-#undef AGHI +-#undef BRCTG +diff --git a/sysdeps/s390/multiarch/memset.c b/sysdeps/s390/memset.c +similarity index 60% +rename from sysdeps/s390/multiarch/memset.c +rename to sysdeps/s390/memset.c +index 760b3e9df201b8b4..57a35aebc7d3c794 100644 +--- a/sysdeps/s390/multiarch/memset.c ++++ b/sysdeps/s390/memset.c +@@ -16,11 +16,33 @@ + License along with the GNU C Library; if not, see + . */ + +-#if IS_IN (libc) ++#include ++#if HAVE_MEMSET_IFUNC + # define memset __redirect_memset + # include + # undef memset + # include + +-s390_libc_ifunc (__redirect_memset, __memset, memset) ++# if HAVE_MEMSET_Z900_G5 ++extern __typeof (__redirect_memset) MEMSET_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z10 ++extern __typeof (__redirect_memset) MEMSET_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z196 ++extern __typeof (__redirect_memset) MEMSET_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memset, memset, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMSET_Z196 ++ : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMSET_Z10 ++ : MEMSET_DEFAULT; ++ }) ++ ) + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 93ad21bfa2686ee5..c893ebc5659fd4ae 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,8 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy \ +- memset memset-s390x ++ mempcpy + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ec3373ae2653d66e..2f671eac1f4f1ffd 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -46,12 +47,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + S390_STORE_STFLE (stfle_bits); + } + ++#if HAVE_MEMSET_IFUNC + IFUNC_IMPL (i, name, memset, ++# if HAVE_MEMSET_Z196 + IFUNC_IMPL_ADD (array, i, memset, +- S390_IS_Z196 (stfle_bits), __memset_z196) ++ S390_IS_Z196 (stfle_bits), MEMSET_Z196) ++# endif ++# if HAVE_MEMSET_Z10 + IFUNC_IMPL_ADD (array, i, memset, +- S390_IS_Z10 (stfle_bits), __memset_z10) +- IFUNC_IMPL_ADD (array, i, memset, 1, __memset_default)) ++ S390_IS_Z10 (stfle_bits), MEMSET_Z10) ++# endif ++# if HAVE_MEMSET_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memset, 1, MEMSET_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMSET_IFUNC */ + + IFUNC_IMPL (i, name, memcmp, + IFUNC_IMPL_ADD (array, i, memcmp, diff --git a/SOURCES/glibc-rh1659438-40.patch b/SOURCES/glibc-rh1659438-40.patch new file mode 100644 index 0000000..3eddef4 --- /dev/null +++ b/SOURCES/glibc-rh1659438-40.patch @@ -0,0 +1,253 @@ +commit 0966dd86896d7cd6c107c751ba7d3b69542ca11d +Author: Stefan Liebler +Date: Tue Dec 18 13:57:19 2018 +0100 + + S390: Refactor wcsncpy ifunc handling. + + The ifunc handling for wcsncpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncpy. + * sysdeps/s390/multiarch/wcsncpy-c.c: Move to ... + * sysdeps/s390/wcsncpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncpy-vx.S: Move to ... + * sysdeps/s390/wcsncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncpy.c: Move to ... + * sysdeps/s390/wcsncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsncpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 5b6446f55299af03..cc8357361e1f2574 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -63,5 +63,6 @@ ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ +- wcpcpy wcpcpy-vx wcpcpy-c ++ wcpcpy wcpcpy-vx wcpcpy-c \ ++ wcsncpy wcsncpy-vx wcsncpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcsncpy.h b/sysdeps/s390/ifunc-wcsncpy.h +new file mode 100644 +index 0000000000000000..d7beca128aaaebc8 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsncpy.h +@@ -0,0 +1,53 @@ ++/* wcsncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNCPY_IFUNC 1 ++#else ++# define HAVE_WCSNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT HAVE_WCSNCPY_IFUNC ++#else ++# define HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNCPY_DEFAULT WCSNCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSNCPY_C 1 ++# define HAVE_WCSNCPY_Z13 1 ++#else ++# define WCSNCPY_DEFAULT WCSNCPY_C ++# define HAVE_WCSNCPY_C 1 ++# define HAVE_WCSNCPY_Z13 HAVE_WCSNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNCPY_C ++# define WCSNCPY_C __wcsncpy_c ++#else ++# define WCSNCPY_C NULL ++#endif ++ ++#if HAVE_WCSNCPY_Z13 ++# define WCSNCPY_Z13 __wcsncpy_vx ++#else ++# define WCSNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 7d7b05dcf21cff7d..6631fd14d32fde72 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsncpy wcsncpy-vx wcsncpy-c \ +- wcpncpy wcpncpy-vx wcpncpy-c \ ++sysdep_routines += wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 656ab59db66dbb48..9ebaf4de6f2eb841 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -476,6 +477,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCPCPY_IFUNC */ + ++#if HAVE_WCSNCPY_IFUNC ++ IFUNC_IMPL (i, name, wcsncpy, ++# if HAVE_WCSNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsncpy, ++ dl_hwcap & HWCAP_S390_VX, WCSNCPY_Z13) ++# endif ++# if HAVE_WCSNCPY_C ++ IFUNC_IMPL_ADD (array, i, wcsncpy, 1, WCSNCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCSNCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -484,8 +497,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsncpy); +- + IFUNC_VX_IMPL (wcpncpy); + + IFUNC_VX_IMPL (wcscat); +diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/wcsncpy-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsncpy-c.c +rename to sysdeps/s390/wcsncpy-c.c +index 6b89b8c14bf58198..4d0ddb09ecb1c849 100644 +--- a/sysdeps/s390/multiarch/wcsncpy-c.c ++++ b/sysdeps/s390/wcsncpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNCPY __wcsncpy_c ++#include ++ ++#if HAVE_WCSNCPY_C ++# if HAVE_WCSNCPY_IFUNC || HAVE_WCSNCPY_Z13 ++# define WCSNCPY WCSNCPY_C ++# endif + +-# include +-extern __typeof (__wcsncpy) __wcsncpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsncpy-vx.S b/sysdeps/s390/wcsncpy-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsncpy-vx.S +rename to sysdeps/s390/wcsncpy-vx.S +index b3400d50d9ab3324..9bcbdbf3229033da 100644 +--- a/sysdeps/s390/multiarch/wcsncpy-vx.S ++++ b/sysdeps/s390/wcsncpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +41,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__wcsncpy_vx) ++ENTRY(WCSNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -217,7 +218,11 @@ ENTRY(__wcsncpy_vx) + j .Llt64 + + .Lfallback: +- jg __wcsncpy_c +-END(__wcsncpy_vx) +- +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSNCPY_C ++END(WCSNCPY_Z13) ++ ++# if ! HAVE_WCSNCPY_IFUNC ++strong_alias (WCSNCPY_Z13, __wcsncpy) ++weak_alias (__wcsncpy, wcsncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/wcsncpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcsncpy.c +rename to sysdeps/s390/wcsncpy.c +index 7209c7d4310d6013..e011de7ee7652bec 100644 +--- a/sysdeps/s390/multiarch/wcsncpy.c ++++ b/sysdeps/s390/wcsncpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcsncpy) +-weak_alias (__wcsncpy, wcsncpy) ++# if HAVE_WCSNCPY_C ++extern __typeof (__wcsncpy) WCSNCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSNCPY_Z13 ++extern __typeof (__wcsncpy) WCSNCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcsncpy, __wcsncpy, ++ (HAVE_WCSNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNCPY_Z13 ++ : WCSNCPY_DEFAULT ++ ) ++weak_alias (__wcsncpy, wcsncpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-41.patch b/SOURCES/glibc-rh1659438-41.patch new file mode 100644 index 0000000..ee4a97f --- /dev/null +++ b/SOURCES/glibc-rh1659438-41.patch @@ -0,0 +1,252 @@ +commit c3081bcbd91a619115f047c2ceea90a9090d5216 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:19 2018 +0100 + + S390: Refactor wcpncpy ifunc handling. + + The ifunc handling for wcpncpy is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcpncpy variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcpncpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcpncpy. + * sysdeps/s390/multiarch/wcpncpy-c.c: Move to ... + * sysdeps/s390/wcpncpy-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpncpy-vx.S: Move to ... + * sysdeps/s390/wcpncpy-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcpncpy.c: Move to ... + * sysdeps/s390/wcpncpy.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcpncpy.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index cc8357361e1f2574..640177370382235f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -64,5 +64,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ +- wcsncpy wcsncpy-vx wcsncpy-c ++ wcsncpy wcsncpy-vx wcsncpy-c \ ++ wcpncpy wcpncpy-vx wcpncpy-c + endif +diff --git a/sysdeps/s390/ifunc-wcpncpy.h b/sysdeps/s390/ifunc-wcpncpy.h +new file mode 100644 +index 0000000000000000..0dd5633aa9cd780b +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcpncpy.h +@@ -0,0 +1,53 @@ ++/* wcpncpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCPNCPY_IFUNC 1 ++#else ++# define HAVE_WCPNCPY_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT HAVE_WCPNCPY_IFUNC ++#else ++# define HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCPNCPY_DEFAULT WCPNCPY_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCPNCPY_C 1 ++# define HAVE_WCPNCPY_Z13 1 ++#else ++# define WCPNCPY_DEFAULT WCPNCPY_C ++# define HAVE_WCPNCPY_C 1 ++# define HAVE_WCPNCPY_Z13 HAVE_WCPNCPY_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCPNCPY_C ++# define WCPNCPY_C __wcpncpy_c ++#else ++# define WCPNCPY_C NULL ++#endif ++ ++#if HAVE_WCPNCPY_Z13 ++# define WCPNCPY_Z13 __wcpncpy_vx ++#else ++# define WCPNCPY_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 6631fd14d32fde72..158fb495523438b4 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcpncpy wcpncpy-vx wcpncpy-c \ +- wcscat wcscat-vx wcscat-c \ ++sysdep_routines += wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 9ebaf4de6f2eb841..e60238fcde4dcd4f 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -489,6 +490,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNCPY_IFUNC */ + ++#if HAVE_WCPNCPY_IFUNC ++ IFUNC_IMPL (i, name, wcpncpy, ++# if HAVE_WCPNCPY_Z13 ++ IFUNC_IMPL_ADD (array, i, wcpncpy, ++ dl_hwcap & HWCAP_S390_VX, WCPNCPY_Z13) ++# endif ++# if HAVE_WCPNCPY_C ++ IFUNC_IMPL_ADD (array, i, wcpncpy, 1, WCPNCPY_C) ++# endif ++ ) ++#endif /* HAVE_WCPNCPY_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -497,8 +510,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcpncpy); +- + IFUNC_VX_IMPL (wcscat); + + IFUNC_VX_IMPL (wcsncat); +diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/wcpncpy-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcpncpy-c.c +rename to sysdeps/s390/wcpncpy-c.c +index 1f44bacea9b65d44..d03359217e98a1f3 100644 +--- a/sysdeps/s390/multiarch/wcpncpy-c.c ++++ b/sysdeps/s390/wcpncpy-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCPNCPY __wcpncpy_c ++#include ++ ++#if HAVE_WCPNCPY_C ++# if HAVE_WCPNCPY_IFUNC || HAVE_WCPNCPY_Z13 ++# define WCPNCPY WCPNCPY_C ++# endif + +-# include +-extern __typeof (__wcpncpy) __wcpncpy_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcpncpy-vx.S b/sysdeps/s390/wcpncpy-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcpncpy-vx.S +rename to sysdeps/s390/wcpncpy-vx.S +index 004f512e1f1a7982..7b5e4ad32d42d44b 100644 +--- a/sysdeps/s390/multiarch/wcpncpy-vx.S ++++ b/sysdeps/s390/wcpncpy-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCPNCPY_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -%r6 = loaded bytes + -%r7 = border, tmp + */ +-ENTRY(__wcpncpy_vx) ++ENTRY(WCPNCPY_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -217,6 +218,11 @@ ENTRY(__wcpncpy_vx) + j .Llt64 + + .Lfallback: +- jg __wcpncpy_c +-END(__wcpncpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCPNCPY_C ++END(WCPNCPY_Z13) ++ ++# if ! HAVE_WCPNCPY_IFUNC ++strong_alias (WCPNCPY_Z13, __wcpncpy) ++weak_alias (__wcpncpy, wcpncpy) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/wcpncpy.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcpncpy.c +rename to sysdeps/s390/wcpncpy.c +index b72265fbe9df65d0..08d097dd2cb6dfd7 100644 +--- a/sysdeps/s390/multiarch/wcpncpy.c ++++ b/sysdeps/s390/wcpncpy.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCPNCPY_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcpncpy) +-weak_alias (__wcpncpy, wcpncpy) ++# if HAVE_WCPNCPY_C ++extern __typeof (__wcpncpy) WCPNCPY_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCPNCPY_Z13 ++extern __typeof (__wcpncpy) WCPNCPY_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcpncpy, __wcpncpy, ++ (HAVE_WCPNCPY_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCPNCPY_Z13 ++ : WCPNCPY_DEFAULT ++ ) ++weak_alias (__wcpncpy, wcpncpy) ++#endif diff --git a/SOURCES/glibc-rh1659438-42.patch b/SOURCES/glibc-rh1659438-42.patch new file mode 100644 index 0000000..49b154b --- /dev/null +++ b/SOURCES/glibc-rh1659438-42.patch @@ -0,0 +1,252 @@ +commit 3389cae427b4032c3a991cb32b5178a85a652d84 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:20 2018 +0100 + + S390: Refactor wcscat ifunc handling. + + The ifunc handling for wcscat is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscat. + * sysdeps/s390/multiarch/wcscat-c.c: Move to ... + * sysdeps/s390/wcscat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscat-vx.S: Move to ... + * sysdeps/s390/wcscat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscat.c: Move to ... + * sysdeps/s390/wcscat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 640177370382235f..5fd00ad4a8661c4c 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -65,5 +65,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ +- wcpncpy wcpncpy-vx wcpncpy-c ++ wcpncpy wcpncpy-vx wcpncpy-c \ ++ wcscat wcscat-vx wcscat-c + endif +diff --git a/sysdeps/s390/ifunc-wcscat.h b/sysdeps/s390/ifunc-wcscat.h +new file mode 100644 +index 0000000000000000..fecae21403e4c664 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscat.h +@@ -0,0 +1,53 @@ ++/* wcscat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCAT_IFUNC 1 ++#else ++# define HAVE_WCSCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT HAVE_WCSCAT_IFUNC ++#else ++# define HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCAT_DEFAULT WCSCAT_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCAT_C 1 ++# define HAVE_WCSCAT_Z13 1 ++#else ++# define WCSCAT_DEFAULT WCSCAT_C ++# define HAVE_WCSCAT_C 1 ++# define HAVE_WCSCAT_Z13 HAVE_WCSCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCAT_C ++# define WCSCAT_C __wcscat_c ++#else ++# define WCSCAT_C NULL ++#endif ++ ++#if HAVE_WCSCAT_Z13 ++# define WCSCAT_Z13 __wcscat_vx ++#else ++# define WCSCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 158fb495523438b4..617017496c79e2ca 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscat wcscat-vx wcscat-c \ +- wcsncat wcsncat-vx wcsncat-c \ ++sysdep_routines += wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index e60238fcde4dcd4f..b05bd35fd898d0a6 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -502,6 +503,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCPNCPY_IFUNC */ + ++#if HAVE_WCSCAT_IFUNC ++ IFUNC_IMPL (i, name, wcscat, ++# if HAVE_WCSCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscat, ++ dl_hwcap & HWCAP_S390_VX, WCSCAT_Z13) ++# endif ++# if HAVE_WCSCAT_C ++ IFUNC_IMPL_ADD (array, i, wcscat, 1, WCSCAT_C) ++# endif ++ ) ++#endif /* HAVE_WCSCAT_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -510,8 +523,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscat); +- + IFUNC_VX_IMPL (wcsncat); + + IFUNC_VX_IMPL (wcscmp); +diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/wcscat-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcscat-c.c +rename to sysdeps/s390/wcscat-c.c +index 9a31c65a0ba668e5..bc1a50b1a52da259 100644 +--- a/sysdeps/s390/multiarch/wcscat-c.c ++++ b/sysdeps/s390/wcscat-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCAT __wcscat_c ++#include ++ ++#if HAVE_WCSCAT_C ++# if HAVE_WCSCAT_IFUNC || HAVE_WCSCAT_Z13 ++# define WCSCAT WCSCAT_C ++# endif + +-# include +-extern __typeof (__wcscat) __wcscat_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcscat-vx.S b/sysdeps/s390/wcscat-vx.S +similarity index 96% +rename from sysdeps/s390/multiarch/wcscat-vx.S +rename to sysdeps/s390/wcscat-vx.S +index 2164a8da411eadaa..4e40d69e8417d6d1 100644 +--- a/sysdeps/s390/multiarch/wcscat-vx.S ++++ b/sysdeps/s390/wcscat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=index of zero + -v18=part of src + */ +-ENTRY(__wcscat_vx) ++ENTRY(WCSCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -170,6 +171,11 @@ ENTRY(__wcscat_vx) + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + .Lfallback: +- jg __wcscat_c +-END(__wcscat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCAT_C ++END(WCSCAT_Z13) ++ ++# if ! HAVE_WCSCAT_IFUNC ++strong_alias (WCSCAT_Z13, __wcscat) ++weak_alias (__wcscat, wcscat) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/wcscat.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcscat.c +rename to sysdeps/s390/wcscat.c +index 33e4f6da3ff8eea7..3741210a177f8029 100644 +--- a/sysdeps/s390/multiarch/wcscat.c ++++ b/sysdeps/s390/wcscat.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCAT_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcscat) +-weak_alias (__wcscat, wcscat) ++# if HAVE_WCSCAT_C ++extern __typeof (__wcscat) WCSCAT_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCAT_Z13 ++extern __typeof (__wcscat) WCSCAT_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcscat, __wcscat, ++ (HAVE_WCSCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCAT_Z13 ++ : WCSCAT_DEFAULT ++ ) ++weak_alias (__wcscat, wcscat) ++#endif diff --git a/SOURCES/glibc-rh1659438-43.patch b/SOURCES/glibc-rh1659438-43.patch new file mode 100644 index 0000000..df2053a --- /dev/null +++ b/SOURCES/glibc-rh1659438-43.patch @@ -0,0 +1,249 @@ +commit 814a76e1bcc59e6c4899279ede887bf9fecf5a40 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:20 2018 +0100 + + S390: Refactor wcsncat ifunc handling. + + The ifunc handling for wcsncat is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsncat variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsncat variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncat. + * sysdeps/s390/multiarch/wcsncat-c.c: Move to ... + * sysdeps/s390/wcsncat-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncat-vx.S: Move to ... + * sysdeps/s390/wcsncat-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncat.c: Move to ... + * sysdeps/s390/wcsncat.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsncat.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 5fd00ad4a8661c4c..cafabe62165f0213 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -66,5 +66,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ +- wcscat wcscat-vx wcscat-c ++ wcscat wcscat-vx wcscat-c \ ++ wcsncat wcsncat-vx wcsncat-c + endif +diff --git a/sysdeps/s390/ifunc-wcsncat.h b/sysdeps/s390/ifunc-wcsncat.h +new file mode 100644 +index 0000000000000000..99495e0e640611ca +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsncat.h +@@ -0,0 +1,53 @@ ++/* wcsncat variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNCAT_IFUNC 1 ++#else ++# define HAVE_WCSNCAT_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT HAVE_WCSNCAT_IFUNC ++#else ++# define HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNCAT_DEFAULT WCSNCAT_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSNCAT_C 1 ++# define HAVE_WCSNCAT_Z13 1 ++#else ++# define WCSNCAT_DEFAULT WCSNCAT_C ++# define HAVE_WCSNCAT_C 1 ++# define HAVE_WCSNCAT_Z13 HAVE_WCSNCAT_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNCAT_C ++# define WCSNCAT_C __wcsncat_c ++#else ++# define WCSNCAT_C NULL ++#endif ++ ++#if HAVE_WCSNCAT_Z13 ++# define WCSNCAT_Z13 __wcsncat_vx ++#else ++# define WCSNCAT_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 617017496c79e2ca..6cb75950c2c453f6 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsncat wcsncat-vx wcsncat-c \ +- wcscmp wcscmp-vx wcscmp-c \ ++sysdep_routines += wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b05bd35fd898d0a6..7b7b1e7497ec1a4f 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -53,6 +53,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -515,6 +516,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCAT_IFUNC */ + ++#if HAVE_WCSNCAT_IFUNC ++ IFUNC_IMPL (i, name, wcsncat, ++# if HAVE_WCSNCAT_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsncat, ++ dl_hwcap & HWCAP_S390_VX, WCSNCAT_Z13) ++# endif ++# if HAVE_WCSNCAT_C ++ IFUNC_IMPL_ADD (array, i, wcsncat, 1, WCSNCAT_C) ++# endif ++ ) ++#endif /* HAVE_WCSNCAT_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -523,8 +536,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsncat); +- + IFUNC_VX_IMPL (wcscmp); + + IFUNC_VX_IMPL (wcsncmp); +diff --git a/sysdeps/s390/multiarch/wcsncat-c.c b/sysdeps/s390/wcsncat-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsncat-c.c +rename to sysdeps/s390/wcsncat-c.c +index 2cf1a76385932c64..5782d5cb28c9e7f6 100644 +--- a/sysdeps/s390/multiarch/wcsncat-c.c ++++ b/sysdeps/s390/wcsncat-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNCAT __wcsncat_c ++#include ++ ++#if HAVE_WCSNCAT_C ++# if HAVE_WCSNCAT_IFUNC || HAVE_WCSNCAT_Z13 ++# define WCSNCAT WCSNCAT_C ++# endif + +-# include +-extern __typeof (wcsncat) __wcsncat_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsncat-vx.S b/sysdeps/s390/wcsncat-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsncat-vx.S +rename to sysdeps/s390/wcsncat-vx.S +index 1d3935690d9f91a3..7c89d3d856faee24 100644 +--- a/sysdeps/s390/multiarch/wcsncat-vx.S ++++ b/sysdeps/s390/wcsncat-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNCAT_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -40,7 +41,7 @@ + -v18=part of src + -v31=register save area for r6, r7 + */ +-ENTRY(__wcsncat_vx) ++ENTRY(WCSNCAT_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -260,6 +261,10 @@ ENTRY(__wcsncat_vx) + j .Lcpy_lt64 + + .Lfallback: +- jg __wcsncat_c +-END(__wcsncat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSNCAT_C ++END(WCSNCAT_Z13) ++ ++# if ! HAVE_WCSNCAT_IFUNC ++strong_alias (WCSNCAT_Z13, wcsncat) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncat.c b/sysdeps/s390/wcsncat.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsncat.c +rename to sysdeps/s390/wcsncat.c +index c49b8ff78671cb99..722429fd5b5b4d9d 100644 +--- a/sysdeps/s390/multiarch/wcsncat.c ++++ b/sysdeps/s390/wcsncat.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNCAT_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcsncat, wcsncat) ++# if HAVE_WCSNCAT_C ++extern __typeof (wcsncat) WCSNCAT_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSNCAT_Z13 ++extern __typeof (wcsncat) WCSNCAT_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcsncat, wcsncat, ++ (HAVE_WCSNCAT_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNCAT_Z13 ++ : WCSNCAT_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-44.patch b/SOURCES/glibc-rh1659438-44.patch new file mode 100644 index 0000000..c49fa9a --- /dev/null +++ b/SOURCES/glibc-rh1659438-44.patch @@ -0,0 +1,269 @@ +commit 3459e23dd4ae4aa8999df7111d833a0bb9add7cd +Author: Stefan Liebler +Date: Tue Dec 18 13:57:21 2018 +0100 + + S390: Refactor wcscmp ifunc handling. + + The ifunc handling for wcscmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + Glibc internal calls will then also use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscmp. + * sysdeps/s390/multiarch/wcscmp-c.c: Move to ... + * sysdeps/s390/wcscmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscmp-vx.S: Move to ... + * sysdeps/s390/wcscmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscmp.c: Move to ... + * sysdeps/s390/wcscmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index cafabe62165f0213..fb104af231c48d3a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -67,5 +67,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ +- wcsncat wcsncat-vx wcsncat-c ++ wcsncat wcsncat-vx wcsncat-c \ ++ wcscmp wcscmp-vx wcscmp-c + endif +diff --git a/sysdeps/s390/ifunc-wcscmp.h b/sysdeps/s390/ifunc-wcscmp.h +new file mode 100644 +index 0000000000000000..99fe0213021458ae +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscmp.h +@@ -0,0 +1,52 @@ ++/* wcscmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCMP_IFUNC 1 ++#else ++# define HAVE_WCSCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT HAVE_WCSCMP_IFUNC ++#else ++# define HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCMP_DEFAULT WCSCMP_Z13 ++# define HAVE_WCSCMP_C 0 ++# define HAVE_WCSCMP_Z13 1 ++#else ++# define WCSCMP_DEFAULT WCSCMP_C ++# define HAVE_WCSCMP_C 1 ++# define HAVE_WCSCMP_Z13 HAVE_WCSCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCMP_C ++# define WCSCMP_C __wcscmp_c ++#else ++# define WCSCMP_C NULL ++#endif ++ ++#if HAVE_WCSCMP_Z13 ++# define WCSCMP_Z13 __wcscmp_vx ++#else ++# define WCSCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 6cb75950c2c453f6..70162d0eaa6a0dee 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscmp wcscmp-vx wcscmp-c \ +- wcsncmp wcsncmp-vx wcsncmp-c \ ++sysdep_routines += wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7b7b1e7497ec1a4f..f461063c80b364fb 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -528,6 +529,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNCAT_IFUNC */ + ++#if HAVE_WCSCMP_IFUNC ++ IFUNC_IMPL (i, name, wcscmp, ++# if HAVE_WCSCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscmp, ++ dl_hwcap & HWCAP_S390_VX, WCSCMP_Z13) ++# endif ++# if HAVE_WCSCMP_C ++ IFUNC_IMPL_ADD (array, i, wcscmp, 1, WCSCMP_C) ++# endif ++ ) ++#endif /* HAVE_WCSCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -536,8 +549,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscmp); +- + IFUNC_VX_IMPL (wcsncmp); + + IFUNC_VX_IMPL (wcschr); +diff --git a/sysdeps/s390/multiarch/wcscmp-c.c b/sysdeps/s390/wcscmp-c.c +similarity index 72% +rename from sysdeps/s390/multiarch/wcscmp-c.c +rename to sysdeps/s390/wcscmp-c.c +index ce0817ae97deab77..643ba7a682469e73 100644 +--- a/sysdeps/s390/multiarch/wcscmp-c.c ++++ b/sysdeps/s390/wcscmp-c.c +@@ -16,17 +16,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCMP __wcscmp_c ++#include + +-# include +-extern __typeof (wcscmp) __wcscmp_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#if HAVE_WCSCMP_C ++# if HAVE_WCSCMP_IFUNC ++# define WCSCMP WCSCMP_C ++# undef weak_alias ++# define weak_alias(name, alias) ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ + __hidden_ver1 (__wcscmp_c, __GI___wcscmp, __wcscmp_c); +-# endif /* SHARED */ ++# endif ++# endif ++ + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcscmp-vx.S b/sysdeps/s390/wcscmp-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wcscmp-vx.S +rename to sysdeps/s390/wcscmp-vx.S +index 14267dbfc7d9b936..a2789d8a693802cc 100644 +--- a/sysdeps/s390/multiarch/wcscmp-vx.S ++++ b/sysdeps/s390/wcscmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +37,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__wcscmp_vx) ++ENTRY(WCSCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -127,5 +128,14 @@ ENTRY(__wcscmp_vx) + .Lend_equal: + lghi %r2,0 + br %r14 +-END(__wcscmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(WCSCMP_Z13) ++ ++# if ! HAVE_WCSCMP_IFUNC ++strong_alias (WCSCMP_Z13, __wcscmp) ++weak_alias (__wcscmp, wcscmp) ++# endif ++ ++# if ! HAVE_WCSCMP_C && defined SHARED && IS_IN (libc) ++strong_alias (WCSCMP_Z13, __GI___wcscmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/wcscmp.c +similarity index 70% +rename from sysdeps/s390/multiarch/wcscmp.c +rename to sysdeps/s390/wcscmp.c +index 5ee0fd4d881db9cb..769c73506e40c3a0 100644 +--- a/sysdeps/s390/multiarch/wcscmp.c ++++ b/sysdeps/s390/wcscmp.c +@@ -16,15 +16,26 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCMP_IFUNC + # define __wcscmp __redirect___wcscmp + # include + # undef __wcscmp + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp) +-weak_alias (__wcscmp, wcscmp) ++# if HAVE_WCSCMP_C ++extern __typeof (__redirect___wcscmp) WCSCMP_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCMP_Z13 ++extern __typeof (__redirect___wcscmp) WCSCMP_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wcscmp, __wcscmp, ++ (HAVE_WCSCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCMP_Z13 ++ : WCSCMP_DEFAULT ++ ) ++weak_alias (__wcscmp, wcscmp) ++#endif diff --git a/SOURCES/glibc-rh1659438-45.patch b/SOURCES/glibc-rh1659438-45.patch new file mode 100644 index 0000000..a4233ac --- /dev/null +++ b/SOURCES/glibc-rh1659438-45.patch @@ -0,0 +1,245 @@ +commit e9873e1d47c870d707117ada91c9be21e3bf1537 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:21 2018 +0100 + + S390: Refactor wcsncmp ifunc handling. + + The ifunc handling for wcsncmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsncmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsncmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsncmp. + * sysdeps/s390/multiarch/wcsncmp-c.c: Move to ... + * sysdeps/s390/wcsncmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncmp-vx.S: Move to ... + * sysdeps/s390/wcsncmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsncmp.c: Move to ... + * sysdeps/s390/wcsncmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsncmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index fb104af231c48d3a..9146b32a939fd5bd 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -68,5 +68,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ +- wcscmp wcscmp-vx wcscmp-c ++ wcscmp wcscmp-vx wcscmp-c \ ++ wcsncmp wcsncmp-vx wcsncmp-c + endif +diff --git a/sysdeps/s390/ifunc-wcsncmp.h b/sysdeps/s390/ifunc-wcsncmp.h +new file mode 100644 +index 0000000000000000..3a22bc9c126107ad +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsncmp.h +@@ -0,0 +1,52 @@ ++/* wcsncmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSNCMP_IFUNC 1 ++#else ++# define HAVE_WCSNCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT HAVE_WCSNCMP_IFUNC ++#else ++# define HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSNCMP_DEFAULT WCSNCMP_Z13 ++# define HAVE_WCSNCMP_C 0 ++# define HAVE_WCSNCMP_Z13 1 ++#else ++# define WCSNCMP_DEFAULT WCSNCMP_C ++# define HAVE_WCSNCMP_C 1 ++# define HAVE_WCSNCMP_Z13 HAVE_WCSNCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSNCMP_C ++# define WCSNCMP_C __wcsncmp_c ++#else ++# define WCSNCMP_C NULL ++#endif ++ ++#if HAVE_WCSNCMP_Z13 ++# define WCSNCMP_Z13 __wcsncmp_vx ++#else ++# define WCSNCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 70162d0eaa6a0dee..d1740fa8e4f5faa8 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsncmp wcsncmp-vx wcsncmp-c \ +- wcschr wcschr-vx wcschr-c \ ++sysdep_routines += wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index f461063c80b364fb..8c9e788ae5962e2a 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -55,6 +55,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -541,6 +542,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCMP_IFUNC */ + ++#if HAVE_WCSNCMP_IFUNC ++ IFUNC_IMPL (i, name, wcsncmp, ++# if HAVE_WCSNCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsncmp, ++ dl_hwcap & HWCAP_S390_VX, WCSNCMP_Z13) ++# endif ++# if HAVE_WCSNCMP_C ++ IFUNC_IMPL_ADD (array, i, wcsncmp, 1, WCSNCMP_C) ++# endif ++ ) ++#endif /* HAVE_WCSNCMP_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -549,8 +562,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsncmp); +- + IFUNC_VX_IMPL (wcschr); + + IFUNC_VX_IMPL (wcschrnul); +diff --git a/sysdeps/s390/multiarch/wcsncmp-c.c b/sysdeps/s390/wcsncmp-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsncmp-c.c +rename to sysdeps/s390/wcsncmp-c.c +index 92ab5e8b50bd93d0..a9ccb8de8276e97c 100644 +--- a/sysdeps/s390/multiarch/wcsncmp-c.c ++++ b/sysdeps/s390/wcsncmp-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSNCMP __wcsncmp_c ++#include ++ ++#if HAVE_WCSNCMP_C ++# if HAVE_WCSNCMP_IFUNC ++# define WCSNCMP WCSNCMP_C ++# endif + +-# include +-extern __typeof (wcsncmp) __wcsncmp_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsncmp-vx.S +rename to sysdeps/s390/wcsncmp-vx.S +index 34c203bc90b2b012..9bdd21acefc2d44d 100644 +--- a/sysdeps/s390/multiarch/wcsncmp-vx.S ++++ b/sysdeps/s390/wcsncmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSNCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__wcsncmp_vx) ++ENTRY(WCSNCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -173,5 +174,9 @@ ENTRY(__wcsncmp_vx) + lghi %r1,-1 + locgrl %r2,%r1 + br %r14 +-END(__wcsncmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(WCSNCMP_Z13) ++ ++# if ! HAVE_WCSNCMP_IFUNC ++strong_alias (WCSNCMP_Z13, wcsncmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncmp.c b/sysdeps/s390/wcsncmp.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsncmp.c +rename to sysdeps/s390/wcsncmp.c +index ee5f08c1e4106495..101db445918b0f7d 100644 +--- a/sysdeps/s390/multiarch/wcsncmp.c ++++ b/sysdeps/s390/wcsncmp.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSNCMP_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcsncmp, wcsncmp) ++# if HAVE_WCSNCMP_C ++extern __typeof (wcsncmp) WCSNCMP_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSNCMP_Z13 ++extern __typeof (wcsncmp) WCSNCMP_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcsncmp, wcsncmp, ++ (HAVE_WCSNCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSNCMP_Z13 ++ : WCSNCMP_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-46.patch b/SOURCES/glibc-rh1659438-46.patch new file mode 100644 index 0000000..a4a0eb0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-46.patch @@ -0,0 +1,292 @@ +commit cf3ccc31a3d76a9b4db410d3087055c3aff2b71b +Author: Stefan Liebler +Date: Tue Dec 18 13:57:22 2018 +0100 + + S390: Refactor wcschr ifunc handling. + + The ifunc handling for wcschr is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcschr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcschr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcschr. + * sysdeps/s390/multiarch/wcschr-c.c: Move to ... + * sysdeps/s390/wcschr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschr-vx.S: Move to ... + * sysdeps/s390/wcschr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschr.c: Move to ... + * sysdeps/s390/wcschr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcschr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 9146b32a939fd5bd..91ee84a54b713e4a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -69,5 +69,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ +- wcsncmp wcsncmp-vx wcsncmp-c ++ wcsncmp wcsncmp-vx wcsncmp-c \ ++ wcschr wcschr-vx wcschr-c + endif +diff --git a/sysdeps/s390/ifunc-wcschr.h b/sysdeps/s390/ifunc-wcschr.h +new file mode 100644 +index 0000000000000000..2fe9110f7c9564d2 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcschr.h +@@ -0,0 +1,53 @@ ++/* wcschr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCHR_IFUNC 1 ++#else ++# define HAVE_WCSCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT HAVE_WCSCHR_IFUNC ++#else ++# define HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCHR_DEFAULT WCSCHR_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCHR_C 1 ++# define HAVE_WCSCHR_Z13 1 ++#else ++# define WCSCHR_DEFAULT WCSCHR_C ++# define HAVE_WCSCHR_C 1 ++# define HAVE_WCSCHR_Z13 HAVE_WCSCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCHR_C ++# define WCSCHR_C __wcschr_c ++#else ++# define WCSCHR_C NULL ++#endif ++ ++#if HAVE_WCSCHR_Z13 ++# define WCSCHR_Z13 __wcschr_vx ++#else ++# define WCSCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index d1740fa8e4f5faa8..b282613b4705bb14 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcschr wcschr-vx wcschr-c \ +- wcschrnul wcschrnul-vx wcschrnul-c \ ++sysdep_routines += wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 8c9e788ae5962e2a..c69165465dc97111 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -56,6 +56,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -554,6 +555,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSNCMP_IFUNC */ + ++#if HAVE_WCSCHR_IFUNC ++ IFUNC_IMPL (i, name, wcschr, ++# if HAVE_WCSCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, wcschr, ++ dl_hwcap & HWCAP_S390_VX, WCSCHR_Z13) ++# endif ++# if HAVE_WCSCHR_C ++ IFUNC_IMPL_ADD (array, i, wcschr, 1, WCSCHR_C) ++# endif ++ ) ++#endif /* HAVE_WCSCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -562,8 +575,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcschr); +- + IFUNC_VX_IMPL (wcschrnul); + + IFUNC_VX_IMPL (wcsrchr); +diff --git a/sysdeps/s390/multiarch/wcschr-c.c b/sysdeps/s390/wcschr-c.c +similarity index 61% +rename from sysdeps/s390/multiarch/wcschr-c.c +rename to sysdeps/s390/wcschr-c.c +index 8d6679c7f2f89864..4908492a0a72ed28 100644 +--- a/sysdeps/s390/multiarch/wcschr-c.c ++++ b/sysdeps/s390/wcschr-c.c +@@ -16,22 +16,29 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCHR __wcschr_c +- +-# include +-extern __typeof (__wcschr) __wcschr_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c); \ +- strong_alias (__wcschr_c, __wcschr_c_1); \ ++#include ++ ++#if HAVE_WCSCHR_C ++# if HAVE_WCSCHR_IFUNC || HAVE_WCSCHR_Z13 ++# define WCSCHR WCSCHR_C ++ ++# undef weak_alias ++# define weak_alias(name, alias) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c) __attribute__((weak)); \ ++ strong_alias (__wcschr_c, __wcschr_c_1); \ + __hidden_ver1 (__wcschr_c_1, __GI___wcschr, __wcschr_c_1); +-# undef libc_hidden_weak +-# define libc_hidden_weak(name) +-# endif /* SHARED */ ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcschr-vx.S b/sysdeps/s390/wcschr-vx.S +similarity index 88% +rename from sysdeps/s390/multiarch/wcschr-vx.S +rename to sysdeps/s390/wcschr-vx.S +index 94e5df7f365aa361..dd24998390c7e2e6 100644 +--- a/sysdeps/s390/multiarch/wcschr-vx.S ++++ b/sysdeps/s390/wcschr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -36,7 +37,7 @@ + -v17=index of unequal + -v18=replicated c + */ +-ENTRY(__wcschr_vx) ++ENTRY(WCSCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -98,6 +99,17 @@ ENTRY(__wcschr_vx) + lghi %r2,0 /* Return null if character not found. */ + br %r14 + .Lfallback: +- jg __wcschr_c +-END(__wcschr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCHR_C ++END(WCSCHR_Z13) ++ ++# if ! HAVE_WCSCHR_IFUNC ++strong_alias (WCSCHR_Z13, __wcschr) ++weak_alias (__wcschr, wcschr) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WCSCHR_Z13, __GI___wcschr) ++weak_alias (WCSCHR_Z13, __GI_wcschr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/wcschr.c +similarity index 71% +rename from sysdeps/s390/multiarch/wcschr.c +rename to sysdeps/s390/wcschr.c +index f44138f771f9f9cb..9923864ff8f5ef1f 100644 +--- a/sysdeps/s390/multiarch/wcschr.c ++++ b/sysdeps/s390/wcschr.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCHR_IFUNC + # define wcschr __redirect_wcschr + # define __wcschr __redirect___wcschr + # include +@@ -24,9 +26,18 @@ + # undef __wcschr + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wcschr, __wcschr) +-weak_alias (__wcschr, wcschr) ++# if HAVE_WCSCHR_C ++extern __typeof (__redirect___wcschr) WCSCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCHR_Z13 ++extern __typeof (__redirect___wcschr) WCSCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wcschr, __wcschr, ++ (HAVE_WCSCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCHR_Z13 ++ : WCSCHR_DEFAULT ++ ) ++weak_alias (__wcschr, wcschr) ++#endif diff --git a/SOURCES/glibc-rh1659438-47.patch b/SOURCES/glibc-rh1659438-47.patch new file mode 100644 index 0000000..d79d982 --- /dev/null +++ b/SOURCES/glibc-rh1659438-47.patch @@ -0,0 +1,252 @@ +commit c09c1b6f014a45f6c4ba189f5ae94b1fb1a2982a +Author: Stefan Liebler +Date: Tue Dec 18 13:57:22 2018 +0100 + + S390: Refactor wcschrnul ifunc handling. + + The ifunc handling for wcschrnul is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcschrnul variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcschrnul variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcschrnul. + * sysdeps/s390/multiarch/wcschrnul-c.c: Move to ... + * sysdeps/s390/wcschrnul-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschrnul-vx.S: Move to ... + * sysdeps/s390/wcschrnul-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcschrnul.c: Move to ... + * sysdeps/s390/wcschrnul.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcschrnul.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 91ee84a54b713e4a..a6ebf11ad1913cc4 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -70,5 +70,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ +- wcschr wcschr-vx wcschr-c ++ wcschr wcschr-vx wcschr-c \ ++ wcschrnul wcschrnul-vx wcschrnul-c + endif +diff --git a/sysdeps/s390/ifunc-wcschrnul.h b/sysdeps/s390/ifunc-wcschrnul.h +new file mode 100644 +index 0000000000000000..39d4120eb3cfafdf +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcschrnul.h +@@ -0,0 +1,53 @@ ++/* wcschrnul variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCHRNUL_IFUNC 1 ++#else ++# define HAVE_WCSCHRNUL_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT HAVE_WCSCHRNUL_IFUNC ++#else ++# define HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCHRNUL_DEFAULT WCSCHRNUL_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCHRNUL_C 1 ++# define HAVE_WCSCHRNUL_Z13 1 ++#else ++# define WCSCHRNUL_DEFAULT WCSCHRNUL_C ++# define HAVE_WCSCHRNUL_C 1 ++# define HAVE_WCSCHRNUL_Z13 HAVE_WCSCHRNUL_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCHRNUL_C ++# define WCSCHRNUL_C __wcschrnul_c ++#else ++# define WCSCHRNUL_C NULL ++#endif ++ ++#if HAVE_WCSCHRNUL_Z13 ++# define WCSCHRNUL_Z13 __wcschrnul_vx ++#else ++# define WCSCHRNUL_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index b282613b4705bb14..0eb01d5d84c60408 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcschrnul wcschrnul-vx wcschrnul-c \ +- wcsrchr wcsrchr-vx wcsrchr-c \ ++sysdep_routines += wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c69165465dc97111..553a76c39ecc87ae 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -57,6 +57,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -567,6 +568,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCHR_IFUNC */ + ++#if HAVE_WCSCHRNUL_IFUNC ++ IFUNC_IMPL (i, name, wcschrnul, ++# if HAVE_WCSCHRNUL_Z13 ++ IFUNC_IMPL_ADD (array, i, wcschrnul, ++ dl_hwcap & HWCAP_S390_VX, WCSCHRNUL_Z13) ++# endif ++# if HAVE_WCSCHRNUL_C ++ IFUNC_IMPL_ADD (array, i, wcschrnul, 1, WCSCHRNUL_C) ++# endif ++ ) ++#endif /* HAVE_WCSCHRNUL_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -575,8 +588,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcschrnul); +- + IFUNC_VX_IMPL (wcsrchr); + + IFUNC_VX_IMPL (wcsspn); +diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/wcschrnul-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcschrnul-c.c +rename to sysdeps/s390/wcschrnul-c.c +index 00e776a3adc11e67..410cee1399a67914 100644 +--- a/sysdeps/s390/multiarch/wcschrnul-c.c ++++ b/sysdeps/s390/wcschrnul-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCHRNUL __wcschrnul_c ++#include ++ ++#if HAVE_WCSCHRNUL_C ++# if HAVE_WCSCHRNUL_IFUNC || HAVE_WCSCHRNUL_Z13 ++# define WCSCHRNUL WCSCHRNUL_C ++# endif + +-# include +-extern __typeof (__wcschrnul) __wcschrnul_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcschrnul-vx.S b/sysdeps/s390/wcschrnul-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wcschrnul-vx.S +rename to sysdeps/s390/wcschrnul-vx.S +index ebcd32b8703608d6..4ffb937c6bbd7008 100644 +--- a/sysdeps/s390/multiarch/wcschrnul-vx.S ++++ b/sysdeps/s390/wcschrnul-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCHRNUL_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -35,7 +36,7 @@ + -v16=part of s + -v18=vector with c replicated in every byte + */ +-ENTRY(__wcschrnul_vx) ++ENTRY(WCSCHRNUL_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -92,6 +93,11 @@ ENTRY(__wcschrnul_vx) + .Lend: + br %r14 + .Lfallback: +- jg __wcschrnul_c +-END(__wcschrnul_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCHRNUL_C ++END(WCSCHRNUL_Z13) ++ ++# if ! HAVE_WCSCHRNUL_IFUNC ++strong_alias (WCSCHRNUL_Z13, __wcschrnul) ++weak_alias (__wcschrnul, wcschrnul) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/wcschrnul.c +similarity index 68% +rename from sysdeps/s390/multiarch/wcschrnul.c +rename to sysdeps/s390/wcschrnul.c +index 807d7ee08963a601..ab5aaf04020bb571 100644 +--- a/sysdeps/s390/multiarch/wcschrnul.c ++++ b/sysdeps/s390/wcschrnul.c +@@ -16,13 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCHRNUL_IFUNC + # include + # include + +-s390_vx_libc_ifunc (__wcschrnul) +-weak_alias (__wcschrnul, wcschrnul) ++# if HAVE_WCSCHRNUL_C ++extern __typeof (__wcschrnul) WCSCHRNUL_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WCSCHRNUL_Z13 ++extern __typeof (__wcschrnul) WCSCHRNUL_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__wcschrnul, __wcschrnul, ++ (HAVE_WCSCHRNUL_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCHRNUL_Z13 ++ : WCSCHRNUL_DEFAULT ++ ) ++weak_alias (__wcschrnul, wcschrnul) ++#endif diff --git a/SOURCES/glibc-rh1659438-48.patch b/SOURCES/glibc-rh1659438-48.patch new file mode 100644 index 0000000..f786c3b --- /dev/null +++ b/SOURCES/glibc-rh1659438-48.patch @@ -0,0 +1,249 @@ +commit 4753713aaed400d88cfc598e25d504478120b065 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:22 2018 +0100 + + S390: Refactor wcsrchr ifunc handling. + + The ifunc handling for wcsrchr is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsrchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsrchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsrchr. + * sysdeps/s390/multiarch/wcsrchr-c.c: Move to ... + * sysdeps/s390/wcsrchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsrchr-vx.S: Move to ... + * sysdeps/s390/wcsrchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsrchr.c: Move to ... + * sysdeps/s390/wcsrchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsrchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index a6ebf11ad1913cc4..19a556eccf285e2f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -71,5 +71,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ +- wcschrnul wcschrnul-vx wcschrnul-c ++ wcschrnul wcschrnul-vx wcschrnul-c \ ++ wcsrchr wcsrchr-vx wcsrchr-c + endif +diff --git a/sysdeps/s390/ifunc-wcsrchr.h b/sysdeps/s390/ifunc-wcsrchr.h +new file mode 100644 +index 0000000000000000..4eec0c17074c99fc +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsrchr.h +@@ -0,0 +1,53 @@ ++/* wcsrchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSRCHR_IFUNC 1 ++#else ++# define HAVE_WCSRCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT HAVE_WCSRCHR_IFUNC ++#else ++# define HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSRCHR_DEFAULT WCSRCHR_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSRCHR_C 1 ++# define HAVE_WCSRCHR_Z13 1 ++#else ++# define WCSRCHR_DEFAULT WCSRCHR_C ++# define HAVE_WCSRCHR_C 1 ++# define HAVE_WCSRCHR_Z13 HAVE_WCSRCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSRCHR_C ++# define WCSRCHR_C __wcsrchr_c ++#else ++# define WCSRCHR_C NULL ++#endif ++ ++#if HAVE_WCSRCHR_Z13 ++# define WCSRCHR_Z13 __wcsrchr_vx ++#else ++# define WCSRCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 0eb01d5d84c60408..3d72cbb5f32e68f3 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsrchr wcsrchr-vx wcsrchr-c \ +- wcsspn wcsspn-vx wcsspn-c \ ++sysdep_routines += wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 553a76c39ecc87ae..ffb4d5b6872ef9db 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -58,6 +58,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -580,6 +581,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCHRNUL_IFUNC */ + ++#if HAVE_WCSRCHR_IFUNC ++ IFUNC_IMPL (i, name, wcsrchr, ++# if HAVE_WCSRCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsrchr, ++ dl_hwcap & HWCAP_S390_VX, WCSRCHR_Z13) ++# endif ++# if HAVE_WCSRCHR_C ++ IFUNC_IMPL_ADD (array, i, wcsrchr, 1, WCSRCHR_C) ++# endif ++ ) ++#endif /* HAVE_WCSRCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -588,8 +601,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsrchr); +- + IFUNC_VX_IMPL (wcsspn); + + IFUNC_VX_IMPL (wcspbrk); +diff --git a/sysdeps/s390/multiarch/wcsrchr-c.c b/sysdeps/s390/wcsrchr-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wcsrchr-c.c +rename to sysdeps/s390/wcsrchr-c.c +index 615250358ba9c00a..65164a897fb773f7 100644 +--- a/sysdeps/s390/multiarch/wcsrchr-c.c ++++ b/sysdeps/s390/wcsrchr-c.c +@@ -16,10 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSRCHR __wcsrchr_c ++#include ++ ++#if HAVE_WCSRCHR_C ++# if HAVE_WCSRCHR_IFUNC || HAVE_WCSRCHR_Z13 ++# define WCSRCHR WCSRCHR_C ++# endif + +-# include +-extern __typeof (wcsrchr) __wcsrchr_c; + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcsrchr-vx.S b/sysdeps/s390/wcsrchr-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsrchr-vx.S +rename to sysdeps/s390/wcsrchr-vx.S +index e40a554e5d9a216d..c7b6585beaeaef53 100644 +--- a/sysdeps/s390/multiarch/wcsrchr-vx.S ++++ b/sysdeps/s390/wcsrchr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSRCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -39,7 +40,7 @@ + -v19=part of s with last occurence of c. + -v20=permute pattern + */ +-ENTRY(__wcsrchr_vx) ++ENTRY(WCSRCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -185,6 +186,10 @@ ENTRY(__wcsrchr_vx) + .byte 0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B + .byte 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03 + .Lfallback: +- jg __wcsrchr_c +-END(__wcsrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSRCHR_C ++END(WCSRCHR_Z13) ++ ++# if ! HAVE_WCSRCHR_IFUNC ++strong_alias (WCSRCHR_Z13, wcsrchr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsrchr.c b/sysdeps/s390/wcsrchr.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsrchr.c +rename to sysdeps/s390/wcsrchr.c +index aa0b8a8f82545f64..eb70f270383880f2 100644 +--- a/sysdeps/s390/multiarch/wcsrchr.c ++++ b/sysdeps/s390/wcsrchr.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSRCHR_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcsrchr, wcsrchr) ++# if HAVE_WCSRCHR_C ++extern __typeof (wcsrchr) WCSRCHR_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSRCHR_Z13 ++extern __typeof (wcsrchr) WCSRCHR_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcsrchr, wcsrchr, ++ (HAVE_WCSRCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSRCHR_Z13 ++ : WCSRCHR_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-49.patch b/SOURCES/glibc-rh1659438-49.patch new file mode 100644 index 0000000..3508d5e --- /dev/null +++ b/SOURCES/glibc-rh1659438-49.patch @@ -0,0 +1,271 @@ +commit 8507e831907ff46d06382fe453c6832db2594e0b +Author: Stefan Liebler +Date: Tue Dec 18 13:57:23 2018 +0100 + + S390: Refactor wcsspn ifunc handling. + + The ifunc handling for wcsspn is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcsspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcsspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcsspn. + * sysdeps/s390/multiarch/wcsspn-c.c: Move to ... + * sysdeps/s390/wcsspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsspn-vx.S: Move to ... + * sysdeps/s390/wcsspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcsspn.c: Move to ... + * sysdeps/s390/wcsspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcsspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 19a556eccf285e2f..38dbba8ccfd3cd66 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -72,5 +72,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ +- wcsrchr wcsrchr-vx wcsrchr-c ++ wcsrchr wcsrchr-vx wcsrchr-c \ ++ wcsspn wcsspn-vx wcsspn-c + endif +diff --git a/sysdeps/s390/ifunc-wcsspn.h b/sysdeps/s390/ifunc-wcsspn.h +new file mode 100644 +index 0000000000000000..1189c6b93ff9fbec +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcsspn.h +@@ -0,0 +1,53 @@ ++/* wcsspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSSPN_IFUNC 1 ++#else ++# define HAVE_WCSSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT HAVE_WCSSPN_IFUNC ++#else ++# define HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSSPN_DEFAULT WCSSPN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSSPN_C 1 ++# define HAVE_WCSSPN_Z13 1 ++#else ++# define WCSSPN_DEFAULT WCSSPN_C ++# define HAVE_WCSSPN_C 1 ++# define HAVE_WCSSPN_Z13 HAVE_WCSSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSSPN_C ++# define WCSSPN_C __wcsspn_c ++#else ++# define WCSSPN_C NULL ++#endif ++ ++#if HAVE_WCSSPN_Z13 ++# define WCSSPN_Z13 __wcsspn_vx ++#else ++# define WCSSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3d72cbb5f32e68f3..091f5150847a404a 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcsspn wcsspn-vx wcsspn-c \ +- wcspbrk wcspbrk-vx wcspbrk-c \ ++sysdep_routines += wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ + wmemset wmemset-vx wmemset-c \ +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ffb4d5b6872ef9db..6f4de2845ba0a378 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -59,6 +59,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -593,6 +594,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSRCHR_IFUNC */ + ++#if HAVE_WCSSPN_IFUNC ++ IFUNC_IMPL (i, name, wcsspn, ++# if HAVE_WCSSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcsspn, ++ dl_hwcap & HWCAP_S390_VX, WCSSPN_Z13) ++# endif ++# if HAVE_WCSSPN_C ++ IFUNC_IMPL_ADD (array, i, wcsspn, 1, WCSSPN_C) ++# endif ++ ) ++#endif /* HAVE_WCSSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -601,8 +614,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcsspn); +- + IFUNC_VX_IMPL (wcspbrk); + + IFUNC_VX_IMPL (wcscspn); +diff --git a/sysdeps/s390/multiarch/wcsspn-c.c b/sysdeps/s390/wcsspn-c.c +similarity index 72% +rename from sysdeps/s390/multiarch/wcsspn-c.c +rename to sysdeps/s390/wcsspn-c.c +index 2c0bd0f4e69516de..db3bdb9b9f09e500 100644 +--- a/sysdeps/s390/multiarch/wcsspn-c.c ++++ b/sysdeps/s390/wcsspn-c.c +@@ -16,16 +16,22 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSSPN __wcsspn_c ++#include + +-# include +-extern __typeof (wcsspn) __wcsspn_c; +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#if HAVE_WCSSPN_C ++# if HAVE_WCSSPN_IFUNC || HAVE_WCSSPN_Z13 ++# define WCSSPN WCSSPN_C ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ + __hidden_ver1 (__wcsspn_c, __GI_wcsspn, __wcsspn_c); +-# endif /* SHARED */ ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcsspn-vx.S b/sysdeps/s390/wcsspn-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcsspn-vx.S +rename to sysdeps/s390/wcsspn-vx.S +index 548f2ad1644c8e88..61f7d6d0902125b7 100644 +--- a/sysdeps/s390/multiarch/wcsspn-vx.S ++++ b/sysdeps/s390/wcsspn-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -57,7 +58,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__wcsspn_vx) ++ENTRY(WCSSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -265,6 +266,15 @@ ENTRY(__wcsspn_vx) + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ + .Lfallback: +- jg __wcsspn_c +-END(__wcsspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSSPN_C ++END(WCSSPN_Z13) ++ ++# if ! HAVE_WCSSPN_IFUNC ++strong_alias (WCSSPN_Z13, wcsspn) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WCSSPN_Z13, __GI_wcsspn) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/wcsspn.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcsspn.c +rename to sysdeps/s390/wcsspn.c +index 7743144a8ca7c2ee..e916b1e4414e774d 100644 +--- a/sysdeps/s390/multiarch/wcsspn.c ++++ b/sysdeps/s390/wcsspn.c +@@ -16,14 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSSPN_IFUNC + # define wcsspn __redirect_wcsspn + # include + # undef wcsspn + # include ++# if HAVE_WCSSPN_C ++extern __typeof (__redirect_wcsspn) WCSSPN_C attribute_hidden; ++# endif + +-s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn) ++# if HAVE_WCSSPN_Z13 ++extern __typeof (__redirect_wcsspn) WCSSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_wcsspn, wcsspn, ++ (HAVE_WCSSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSSPN_Z13 ++ : WCSSPN_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-5.patch b/SOURCES/glibc-rh1659438-5.patch new file mode 100644 index 0000000..440659f --- /dev/null +++ b/SOURCES/glibc-rh1659438-5.patch @@ -0,0 +1,306 @@ +commit 07be392807ac78330da90f01408aa7e042a97a88 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:05 2018 +0100 + + S390: Implement bzero with memset. + + This patch removes the bzero s390 implementation with mvcle and + adds entry points for bzero in memset ifunc variants. + Therefore an ifunc resolver is implemented for bzero, too. + + ChangeLog: + + * sysdeps/s390/s390-32/bzero.S: Delete file. + * sysdeps/s390/s390-64/bzero.S: Likewise. + * sysdeps/s390/Makefile (sysdep_routines): Add bzero. + * sysdeps/s390/bzero.c: New file. + * sysdeps/s390/memset-z900.S: Add bzero entry points. + * sysdeps/s390/ifunc-memset.h: Add bzero function macros. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add bzero ifunc variants. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 360838e172f4ca37..e40e5bd982e54d89 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -31,5 +31,5 @@ sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules + endif + + ifeq ($(subdir),string) +-sysdep_routines += memset memset-z900 ++sysdep_routines += bzero memset memset-z900 + endif +diff --git a/sysdeps/s390/s390-32/bzero.S b/sysdeps/s390/bzero.c +similarity index 52% +rename from sysdeps/s390/s390-32/bzero.S +rename to sysdeps/s390/bzero.c +index 897aa2154a861b7f..9f8d95781bf2fb68 100644 +--- a/sysdeps/s390/s390-32/bzero.S ++++ b/sysdeps/s390/bzero.c +@@ -1,7 +1,6 @@ +-/* bzero -- set a block of memory to zero. IBM S390 version ++/* Multiple versions of bzero. ++ Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. +- Copyright (C) 2000-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public +@@ -17,26 +16,32 @@ + License along with the GNU C Library; if not, see + . */ + +-/* +- * R2 = address to memory area +- * R3 = number of bytes to fill +- */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bzero) +- ltr %r3,%r3 +- jz .L1 +- sr %r1,%r1 # set pad byte to zero +- sr %r4,%r4 # no source for MVCLE, only a pad byte +- sr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +-.L1: br %r14 +-END(__bzero) +- +-#ifndef NO_WEAK_ALIAS ++#include ++#if HAVE_MEMSET_IFUNC ++# include ++# include ++ ++# if HAVE_MEMSET_Z900_G5 ++extern __typeof (__bzero) BZERO_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z10 ++extern __typeof (__bzero) BZERO_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMSET_Z196 ++extern __typeof (__bzero) BZERO_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__bzero, __bzero, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? BZERO_Z196 ++ : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? BZERO_Z10 ++ : BZERO_DEFAULT; ++ }) ++ ) + weak_alias (__bzero, bzero) + #endif +diff --git a/sysdeps/s390/ifunc-memset.h b/sysdeps/s390/ifunc-memset.h +index 9a13b1001fed9979..32bc155f7e79fa26 100644 +--- a/sysdeps/s390/ifunc-memset.h ++++ b/sysdeps/s390/ifunc-memset.h +@@ -25,16 +25,19 @@ + + #if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT + # define MEMSET_DEFAULT MEMSET_Z196 ++# define BZERO_DEFAULT BZERO_Z196 + # define HAVE_MEMSET_Z900_G5 0 + # define HAVE_MEMSET_Z10 0 + # define HAVE_MEMSET_Z196 1 + #elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT + # define MEMSET_DEFAULT MEMSET_Z10 ++# define BZERO_DEFAULT BZERO_Z10 + # define HAVE_MEMSET_Z900_G5 0 + # define HAVE_MEMSET_Z10 1 + # define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC + #else + # define MEMSET_DEFAULT MEMSET_Z900_G5 ++# define BZERO_DEFAULT BZERO_Z900_G5 + # define HAVE_MEMSET_Z900_G5 1 + # define HAVE_MEMSET_Z10 HAVE_MEMSET_IFUNC + # define HAVE_MEMSET_Z196 HAVE_MEMSET_IFUNC +@@ -48,18 +51,24 @@ + + #if HAVE_MEMSET_Z900_G5 + # define MEMSET_Z900_G5 __memset_default ++# define BZERO_Z900_G5 __bzero_default + #else + # define MEMSET_Z900_G5 NULL ++# define BZERO_Z900_G5 NULL + #endif + + #if HAVE_MEMSET_Z10 + # define MEMSET_Z10 __memset_z10 ++# define BZERO_Z10 __bzero_z10 + #else + # define MEMSET_Z10 NULL ++# define BZERO_Z10 NULL + #endif + + #if HAVE_MEMSET_Z196 + # define MEMSET_Z196 __memset_z196 ++# define BZERO_Z196 __bzero_z196 + #else + # define MEMSET_Z196 NULL ++# define BZERO_Z196 NULL + #endif +diff --git a/sysdeps/s390/memset-z900.S b/sysdeps/s390/memset-z900.S +index eaf13402bd3e251d..bfc659ae0b029eb4 100644 +--- a/sysdeps/s390/memset-z900.S ++++ b/sysdeps/s390/memset-z900.S +@@ -22,10 +22,14 @@ + #include "asm-syntax.h" + #include + +-/* INPUT PARAMETERS ++/* INPUT PARAMETERS - MEMSET + %r2 = address of memory area + %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ ++ %r4 = number of bytes to fill. ++ ++ INPUT PARAMETERS - BZERO ++ %r2 = address of memory area ++ %r3 = number of bytes to fill. */ + + .text + +@@ -44,7 +48,14 @@ + # define BRCTG brct + # endif /* ! defined __s390x__ */ + ++ENTRY(BZERO_Z900_G5) ++ LGR %r4,%r3 ++ xr %r3,%r3 ++ j .L_Z900_G5_start ++END(BZERO_Z900_G5) ++ + ENTRY(MEMSET_Z900_G5) ++.L_Z900_G5_start: + #if defined __s390x__ + .machine "z900" + #else +@@ -90,7 +101,16 @@ END(MEMSET_Z900_G5) + #endif /* HAVE_MEMSET_Z900_G5 */ + + #if HAVE_MEMSET_Z10 ++ENTRY(BZERO_Z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ lgr %r4,%r3 ++ xr %r3,%r3 ++ j .L_Z10_start ++END(BZERO_Z10) ++ + ENTRY(MEMSET_Z10) ++.L_Z10_start: + .machine "z10" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -122,7 +142,16 @@ END(MEMSET_Z10) + #endif /* HAVE_MEMSET_Z10 */ + + #if HAVE_MEMSET_Z196 ++ENTRY(BZERO_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ lgr %r4,%r3 ++ xr %r3,%r3 ++ j .L_Z196_start ++END(BZERO_Z196) ++ + ENTRY(MEMSET_Z196) ++.L_Z196_start: + .machine "z196" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -177,6 +206,10 @@ END(__memset_mvcle) + /* If we don't use ifunc, define an alias for memset here. + Otherwise see sysdeps/s390/memset.c. */ + strong_alias (MEMSET_DEFAULT, memset) ++/* Same for bzero. If ifunc is used, see ++ sysdeps/s390/bzero.c. */ ++strong_alias (BZERO_DEFAULT, __bzero) ++weak_alias (__bzero, bzero) + #endif + + #if defined SHARED && IS_IN (libc) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 2f671eac1f4f1ffd..253f36045b57cc3c 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -59,6 +59,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + # endif + # if HAVE_MEMSET_Z900_G5 + IFUNC_IMPL_ADD (array, i, memset, 1, MEMSET_Z900_G5) ++# endif ++ ) ++ ++ /* Note: bzero is implemented in memset. */ ++ IFUNC_IMPL (i, name, bzero, ++# if HAVE_MEMSET_Z196 ++ IFUNC_IMPL_ADD (array, i, bzero, ++ S390_IS_Z196 (stfle_bits), BZERO_Z196) ++# endif ++# if HAVE_MEMSET_Z10 ++ IFUNC_IMPL_ADD (array, i, bzero, ++ S390_IS_Z10 (stfle_bits), BZERO_Z10) ++# endif ++# if HAVE_MEMSET_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, bzero, 1, BZERO_Z900_G5) + # endif + ) + #endif /* HAVE_MEMSET_IFUNC */ +diff --git a/sysdeps/s390/s390-64/bzero.S b/sysdeps/s390/s390-64/bzero.S +deleted file mode 100644 +index b3216652985cc239..0000000000000000 +--- a/sysdeps/s390/s390-64/bzero.S ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* bzero -- set a block of memory to zero. 64 bit S/390 version. +- This file is part of the GNU C Library. +- Copyright (C) 2001-2018 Free Software Foundation, Inc. +- Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = number of bytes to fill. */ +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +- .text +-ENTRY(__bzero) +- ltgr %r3,%r3 +- jz .L1 +- sgr %r1,%r1 # set pad byte to zero +- sgr %r4,%r4 # no source for MVCLE, only a pad byte +- sgr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +-.L1: br %r14 +-END(__bzero) +- +-#ifndef NO_WEAK_ALIAS +-weak_alias (__bzero, bzero) +-#endif diff --git a/SOURCES/glibc-rh1659438-50.patch b/SOURCES/glibc-rh1659438-50.patch new file mode 100644 index 0000000..41d29db --- /dev/null +++ b/SOURCES/glibc-rh1659438-50.patch @@ -0,0 +1,271 @@ +commit 8e87c1f6d45a63dc2175825c2dc5d66192a13aab +Author: Stefan Liebler +Date: Tue Dec 18 13:57:23 2018 +0100 + + S390: Refactor wcspbrk ifunc handling. + + The ifunc handling for wcspbrk is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcspbrk variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcspbrk variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcspbrk. + * sysdeps/s390/multiarch/wcspbrk-c.c: Move to ... + * sysdeps/s390/wcspbrk-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcspbrk-vx.S: Move to ... + * sysdeps/s390/wcspbrk-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcspbrk.c: Move to ... + * sysdeps/s390/wcspbrk.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcspbrk.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 38dbba8ccfd3cd66..af595050d43c63ed 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -73,5 +73,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ +- wcsspn wcsspn-vx wcsspn-c ++ wcsspn wcsspn-vx wcsspn-c \ ++ wcspbrk wcspbrk-vx wcspbrk-c + endif +diff --git a/sysdeps/s390/ifunc-wcspbrk.h b/sysdeps/s390/ifunc-wcspbrk.h +new file mode 100644 +index 0000000000000000..d3b9b7363a73fab0 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcspbrk.h +@@ -0,0 +1,53 @@ ++/* wcspbrk variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSPBRK_IFUNC 1 ++#else ++# define HAVE_WCSPBRK_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT HAVE_WCSPBRK_IFUNC ++#else ++# define HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSPBRK_DEFAULT WCSPBRK_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSPBRK_C 1 ++# define HAVE_WCSPBRK_Z13 1 ++#else ++# define WCSPBRK_DEFAULT WCSPBRK_C ++# define HAVE_WCSPBRK_C 1 ++# define HAVE_WCSPBRK_Z13 HAVE_WCSPBRK_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSPBRK_C ++# define WCSPBRK_C __wcspbrk_c ++#else ++# define WCSPBRK_C NULL ++#endif ++ ++#if HAVE_WCSPBRK_Z13 ++# define WCSPBRK_Z13 __wcspbrk_vx ++#else ++# define WCSPBRK_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 091f5150847a404a..e1e2d9dc7495ebdc 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcspbrk wcspbrk-vx wcspbrk-c \ +- wcscspn wcscspn-vx wcscspn-c \ ++sysdep_routines += wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ + wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 6f4de2845ba0a378..89d6e8ad7e323fec 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -606,6 +607,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSSPN_IFUNC */ + ++#if HAVE_WCSPBRK_IFUNC ++ IFUNC_IMPL (i, name, wcspbrk, ++# if HAVE_WCSPBRK_Z13 ++ IFUNC_IMPL_ADD (array, i, wcspbrk, ++ dl_hwcap & HWCAP_S390_VX, WCSPBRK_Z13) ++# endif ++# if HAVE_WCSPBRK_C ++ IFUNC_IMPL_ADD (array, i, wcspbrk, 1, WCSPBRK_C) ++# endif ++ ) ++#endif /* HAVE_WCSPBRK_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -614,8 +627,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcspbrk); +- + IFUNC_VX_IMPL (wcscspn); + + IFUNC_VX_IMPL (wmemchr); +diff --git a/sysdeps/s390/multiarch/wcspbrk-c.c b/sysdeps/s390/wcspbrk-c.c +similarity index 72% +rename from sysdeps/s390/multiarch/wcspbrk-c.c +rename to sysdeps/s390/wcspbrk-c.c +index 6b6e7aade46942ed..e79c6a85503dc32b 100644 +--- a/sysdeps/s390/multiarch/wcspbrk-c.c ++++ b/sysdeps/s390/wcspbrk-c.c +@@ -16,16 +16,22 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSPBRK __wcspbrk_c ++#include + +-# include +-extern __typeof (wcspbrk) __wcspbrk_c; +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ ++#if HAVE_WCSPBRK_C ++# if HAVE_WCSPBRK_IFUNC || HAVE_WCSPBRK_Z13 ++# define WCSPBRK WCSPBRK_C ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ + __hidden_ver1 (__wcspbrk_c, __GI_wcspbrk, __wcspbrk_c); +-# endif /* SHARED */ ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wcspbrk-vx.S b/sysdeps/s390/wcspbrk-vx.S +similarity index 97% +rename from sysdeps/s390/multiarch/wcspbrk-vx.S +rename to sysdeps/s390/wcspbrk-vx.S +index 5c89ec5d336c1acd..5870c4684d140ab0 100644 +--- a/sysdeps/s390/multiarch/wcspbrk-vx.S ++++ b/sysdeps/s390/wcspbrk-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSPBRK_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -59,7 +60,7 @@ + otherwise =0; + r9: loaded byte count of vlbb accept-string + */ +-ENTRY(__wcspbrk_vx) ++ENTRY(WCSPBRK_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -310,6 +311,15 @@ ENTRY(__wcspbrk_vx) + lgr %r2,%r1 + br %r14 + .Lfallback: +- jg __wcspbrk_c +-END(__wcspbrk_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSPBRK_C ++END(WCSPBRK_Z13) ++ ++# if ! HAVE_WCSPBRK_IFUNC ++strong_alias (WCSPBRK_Z13, wcspbrk) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WCSPBRK_Z13, __GI_wcspbrk) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/wcspbrk.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcspbrk.c +rename to sysdeps/s390/wcspbrk.c +index 97876328b5ad9425..84ab911a24fba3c4 100644 +--- a/sysdeps/s390/multiarch/wcspbrk.c ++++ b/sysdeps/s390/wcspbrk.c +@@ -16,14 +16,24 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSPBRK_IFUNC + # define wcspbrk __redirect_wcspbrk + # include + # undef wcspbrk + # include ++# if HAVE_WCSPBRK_C ++extern __typeof (__redirect_wcspbrk) WCSPBRK_C attribute_hidden; ++# endif + +-s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk) ++# if HAVE_WCSPBRK_Z13 ++extern __typeof (__redirect_wcspbrk) WCSPBRK_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (__redirect_wcspbrk, wcspbrk, ++ (HAVE_WCSPBRK_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSPBRK_Z13 ++ : WCSPBRK_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-51.patch b/SOURCES/glibc-rh1659438-51.patch new file mode 100644 index 0000000..264a0e1 --- /dev/null +++ b/SOURCES/glibc-rh1659438-51.patch @@ -0,0 +1,249 @@ +commit 79b44cf61115bd48006227bb325b709f294c56f9 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:23 2018 +0100 + + S390: Refactor wcscspn ifunc handling. + + The ifunc handling for wcscspn is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wcscspn variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wcscspn variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wcscspn. + * sysdeps/s390/multiarch/wcscspn-c.c: Move to ... + * sysdeps/s390/wcscspn-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscspn-vx.S: Move to ... + * sysdeps/s390/wcscspn-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wcscspn.c: Move to ... + * sysdeps/s390/wcscspn.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wcscspn.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index af595050d43c63ed..da96ac3a36bd7f4e 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -74,5 +74,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ +- wcspbrk wcspbrk-vx wcspbrk-c ++ wcspbrk wcspbrk-vx wcspbrk-c \ ++ wcscspn wcscspn-vx wcscspn-c + endif +diff --git a/sysdeps/s390/ifunc-wcscspn.h b/sysdeps/s390/ifunc-wcscspn.h +new file mode 100644 +index 0000000000000000..23f3667ba3823e99 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wcscspn.h +@@ -0,0 +1,53 @@ ++/* wcscspn variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WCSCSPN_IFUNC 1 ++#else ++# define HAVE_WCSCSPN_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT HAVE_WCSCSPN_IFUNC ++#else ++# define HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WCSCSPN_DEFAULT WCSCSPN_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WCSCSPN_C 1 ++# define HAVE_WCSCSPN_Z13 1 ++#else ++# define WCSCSPN_DEFAULT WCSCSPN_C ++# define HAVE_WCSCSPN_C 1 ++# define HAVE_WCSCSPN_Z13 HAVE_WCSCSPN_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WCSCSPN_C ++# define WCSCSPN_C __wcscspn_c ++#else ++# define WCSCSPN_C NULL ++#endif ++ ++#if HAVE_WCSCSPN_Z13 ++# define WCSCSPN_Z13 __wcscspn_vx ++#else ++# define WCSCSPN_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index e1e2d9dc7495ebdc..5be635542361b355 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcscspn wcscspn-vx wcscspn-c \ +- wmemchr wmemchr-vx wmemchr-c \ ++sysdep_routines += wmemchr wmemchr-vx wmemchr-c \ + wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 89d6e8ad7e323fec..7d8031a069bd23ba 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -619,6 +620,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSPBRK_IFUNC */ + ++#if HAVE_WCSCSPN_IFUNC ++ IFUNC_IMPL (i, name, wcscspn, ++# if HAVE_WCSCSPN_Z13 ++ IFUNC_IMPL_ADD (array, i, wcscspn, ++ dl_hwcap & HWCAP_S390_VX, WCSCSPN_Z13) ++# endif ++# if HAVE_WCSCSPN_C ++ IFUNC_IMPL_ADD (array, i, wcscspn, 1, WCSCSPN_C) ++# endif ++ ) ++#endif /* HAVE_WCSCSPN_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -627,8 +640,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wcscspn); +- + IFUNC_VX_IMPL (wmemchr); + + IFUNC_VX_IMPL (wmemset); +diff --git a/sysdeps/s390/multiarch/wcscspn-c.c b/sysdeps/s390/wcscspn-c.c +similarity index 86% +rename from sysdeps/s390/multiarch/wcscspn-c.c +rename to sysdeps/s390/wcscspn-c.c +index 161e52e686c73907..d47cb6b75be14e14 100644 +--- a/sysdeps/s390/multiarch/wcscspn-c.c ++++ b/sysdeps/s390/wcscspn-c.c +@@ -16,11 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WCSCSPN __wcscspn_c ++#include + +-# include +-extern __typeof (wcscspn) __wcscspn_c; ++#if HAVE_WCSCSPN_C ++# if HAVE_WCSCSPN_IFUNC || HAVE_WCSCSPN_Z13 ++# define WCSCSPN WCSCSPN_C ++# endif + + # include + #endif +diff --git a/sysdeps/s390/multiarch/wcscspn-vx.S b/sysdeps/s390/wcscspn-vx.S +similarity index 98% +rename from sysdeps/s390/multiarch/wcscspn-vx.S +rename to sysdeps/s390/wcscspn-vx.S +index 06bc4e25d0456aea..882cb93fb807caa1 100644 +--- a/sysdeps/s390/multiarch/wcscspn-vx.S ++++ b/sysdeps/s390/wcscspn-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WCSCSPN_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -57,7 +58,7 @@ + otherwise =0; + r9: loaded byte count of vlbb reject-string + */ +-ENTRY(__wcscspn_vx) ++ENTRY(WCSCSPN_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -288,6 +289,10 @@ ENTRY(__wcscspn_vx) + vlgvg %r9,%v31,1 + br %r14 + .Lfallback: +- jg __wcscspn_c +-END(__wcscspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WCSCSPN_C ++END(WCSCSPN_Z13) ++ ++# if ! HAVE_WCSCSPN_IFUNC ++strong_alias (WCSCSPN_Z13, wcscspn) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wcscspn.c b/sysdeps/s390/wcscspn.c +similarity index 69% +rename from sysdeps/s390/multiarch/wcscspn.c +rename to sysdeps/s390/wcscspn.c +index 707327522ad20287..0ce31b8aabf3b429 100644 +--- a/sysdeps/s390/multiarch/wcscspn.c ++++ b/sysdeps/s390/wcscspn.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WCSCSPN_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wcscspn, wcscspn) ++# if HAVE_WCSCSPN_C ++extern __typeof (wcscspn) WCSCSPN_C attribute_hidden; ++# endif ++ ++# if HAVE_WCSCSPN_Z13 ++extern __typeof (wcscspn) WCSCSPN_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wcscspn, wcscspn, ++ (HAVE_WCSCSPN_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WCSCSPN_Z13 ++ : WCSCSPN_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-52.patch b/SOURCES/glibc-rh1659438-52.patch new file mode 100644 index 0000000..c46c2ec --- /dev/null +++ b/SOURCES/glibc-rh1659438-52.patch @@ -0,0 +1,292 @@ +commit c62534ae524111eae48b2c2adf3f9a2ca90824f5 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:24 2018 +0100 + + S390: Refactor wmemchr ifunc handling. + + The ifunc handling for wmemchr is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wmemchr variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wmemchr variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wmemchr. + * sysdeps/s390/multiarch/wmemchr-c.c: Move to ... + * sysdeps/s390/wmemchr-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemchr-vx.S: Move to ... + * sysdeps/s390/wmemchr-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemchr.c: Move to ... + * sysdeps/s390/wmemchr.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wmemchr.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index da96ac3a36bd7f4e..fdfd1c605c28ddc7 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -75,5 +75,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ +- wcscspn wcscspn-vx wcscspn-c ++ wcscspn wcscspn-vx wcscspn-c \ ++ wmemchr wmemchr-vx wmemchr-c + endif +diff --git a/sysdeps/s390/ifunc-wmemchr.h b/sysdeps/s390/ifunc-wmemchr.h +new file mode 100644 +index 0000000000000000..0610cfb5d4a7fb18 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wmemchr.h +@@ -0,0 +1,53 @@ ++/* wmemchr variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WMEMCHR_IFUNC 1 ++#else ++# define HAVE_WMEMCHR_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT HAVE_WMEMCHR_IFUNC ++#else ++# define HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WMEMCHR_DEFAULT WMEMCHR_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WMEMCHR_C 1 ++# define HAVE_WMEMCHR_Z13 1 ++#else ++# define WMEMCHR_DEFAULT WMEMCHR_C ++# define HAVE_WMEMCHR_C 1 ++# define HAVE_WMEMCHR_Z13 HAVE_WMEMCHR_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WMEMCHR_C ++# define WMEMCHR_C __wmemchr_c ++#else ++# define WMEMCHR_C NULL ++#endif ++ ++#if HAVE_WMEMCHR_Z13 ++# define WMEMCHR_Z13 __wmemchr_vx ++#else ++# define WMEMCHR_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 5be635542361b355..92e28dc45ddbae37 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wmemchr wmemchr-vx wmemchr-c \ +- wmemset wmemset-vx wmemset-c \ ++sysdep_routines += wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c + endif + +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7d8031a069bd23ba..b5f55deb7faae9c4 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -62,6 +62,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -632,6 +633,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WCSCSPN_IFUNC */ + ++#if HAVE_WMEMCHR_IFUNC ++ IFUNC_IMPL (i, name, wmemchr, ++# if HAVE_WMEMCHR_Z13 ++ IFUNC_IMPL_ADD (array, i, wmemchr, ++ dl_hwcap & HWCAP_S390_VX, WMEMCHR_Z13) ++# endif ++# if HAVE_WMEMCHR_C ++ IFUNC_IMPL_ADD (array, i, wmemchr, 1, WMEMCHR_C) ++# endif ++ ) ++#endif /* HAVE_WMEMCHR_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -640,8 +653,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wmemchr); +- + IFUNC_VX_IMPL (wmemset); + + IFUNC_VX_IMPL (wmemcmp); +diff --git a/sysdeps/s390/multiarch/wmemchr-c.c b/sysdeps/s390/wmemchr-c.c +similarity index 59% +rename from sysdeps/s390/multiarch/wmemchr-c.c +rename to sysdeps/s390/wmemchr-c.c +index 089392b512d29187..bb2526e76c41d0c7 100644 +--- a/sysdeps/s390/multiarch/wmemchr-c.c ++++ b/sysdeps/s390/wmemchr-c.c +@@ -16,22 +16,29 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WMEMCHR __wmemchr_c +- +-# include +-extern __typeof (wmemchr) __wmemchr_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__wmemchr_c, __GI___wmemchr, __wmemchr_c); +-# undef libc_hidden_weak +-# define libc_hidden_weak(name) \ ++#include ++ ++#if HAVE_WMEMCHR_C ++# if HAVE_WMEMCHR_IFUNC || HAVE_WMEMCHR_Z13 ++# define WMEMCHR WMEMCHR_C ++ ++# undef weak_alias ++# define weak_alias(name, alias) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wmemchr_c, __GI_wmemchr, __wmemchr_c) __attribute__((weak)); \ + strong_alias (__wmemchr_c, __wmemchr_c_1); \ +- __hidden_ver1 (__wmemchr_c_1, __GI_wmemchr, __wmemchr_c_1); +-# endif /* SHARED */ ++ __hidden_ver1 (__wmemchr_c_1, __GI___wmemchr, __wmemchr_c_1); ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wmemchr-vx.S b/sysdeps/s390/wmemchr-vx.S +similarity index 92% +rename from sysdeps/s390/multiarch/wmemchr-vx.S +rename to sysdeps/s390/wmemchr-vx.S +index db057b579a7230f0..72e9ef59af77b8f7 100644 +--- a/sysdeps/s390/multiarch/wmemchr-vx.S ++++ b/sysdeps/s390/wmemchr-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WMEMCHR_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -v17=index of found c + -v18=c replicated + */ +-ENTRY(__wmemchr_vx) ++ENTRY(WMEMCHR_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -161,6 +162,17 @@ ENTRY(__wmemchr_vx) + + j .Llt64 + .Lfallback: +- jg __wmemchr_c +-END(__wmemchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WMEMCHR_C ++END(WMEMCHR_Z13) ++ ++# if ! HAVE_WMEMCHR_IFUNC ++strong_alias (WMEMCHR_Z13, __wmemchr) ++weak_alias (__wmemchr, wmemchr) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WMEMCHR_Z13, __GI___wmemchr) ++weak_alias (WMEMCHR_Z13, __GI_wmemchr) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/wmemchr.c +similarity index 70% +rename from sysdeps/s390/multiarch/wmemchr.c +rename to sysdeps/s390/wmemchr.c +index 6b55c1d7fa10afb9..0d2fbb22c6d65a97 100644 +--- a/sysdeps/s390/multiarch/wmemchr.c ++++ b/sysdeps/s390/wmemchr.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WMEMCHR_IFUNC + # define wmemchr __redirect_wmemchr + # define __wmemchr __redirect___wmemchr + # include +@@ -24,9 +26,18 @@ + # undef __wmemchr + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wmemchr, __wmemchr) +-weak_alias (__wmemchr, wmemchr) ++# if HAVE_WMEMCHR_C ++extern __typeof (__redirect___wmemchr) WMEMCHR_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WMEMCHR_Z13 ++extern __typeof (__redirect___wmemchr) WMEMCHR_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wmemchr, __wmemchr, ++ (HAVE_WMEMCHR_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WMEMCHR_Z13 ++ : WMEMCHR_DEFAULT ++ ) ++weak_alias (__wmemchr, wmemchr) ++#endif diff --git a/SOURCES/glibc-rh1659438-53.patch b/SOURCES/glibc-rh1659438-53.patch new file mode 100644 index 0000000..7d8150d --- /dev/null +++ b/SOURCES/glibc-rh1659438-53.patch @@ -0,0 +1,292 @@ +commit d2a7436c1c6144bbba2eb2a7b25db9b90515f0e6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:24 2018 +0100 + + S390: Refactor wmemset ifunc handling. + + The ifunc handling for wmemset is adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Unfortunately the c ifunc variant can't be omitted at all as it is used + by the z13 ifunc variant as fallback if the pointers are not 4-byte aligned. + Glibc internal calls will use the "newer" ifunc variant. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wmemset variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wmemset variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wmemset. + * sysdeps/s390/multiarch/wmemset-c.c: Move to ... + * sysdeps/s390/wmemset-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemset-vx.S: Move to ... + * sysdeps/s390/wmemset-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemset.c: Move to ... + * sysdeps/s390/wmemset.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wmemset.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index fdfd1c605c28ddc7..f9a71276331b396a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -76,5 +76,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ +- wmemchr wmemchr-vx wmemchr-c ++ wmemchr wmemchr-vx wmemchr-c \ ++ wmemset wmemset-vx wmemset-c + endif +diff --git a/sysdeps/s390/ifunc-wmemset.h b/sysdeps/s390/ifunc-wmemset.h +new file mode 100644 +index 0000000000000000..c9d1d17c3bfc7e9e +--- /dev/null ++++ b/sysdeps/s390/ifunc-wmemset.h +@@ -0,0 +1,53 @@ ++/* wmemset variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WMEMSET_IFUNC 1 ++#else ++# define HAVE_WMEMSET_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT HAVE_WMEMSET_IFUNC ++#else ++# define HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WMEMSET_DEFAULT WMEMSET_Z13 ++/* The z13 ifunc variant is using the common code variant as fallback! */ ++# define HAVE_WMEMSET_C 1 ++# define HAVE_WMEMSET_Z13 1 ++#else ++# define WMEMSET_DEFAULT WMEMSET_C ++# define HAVE_WMEMSET_C 1 ++# define HAVE_WMEMSET_Z13 HAVE_WMEMSET_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WMEMSET_C ++# define WMEMSET_C __wmemset_c ++#else ++# define WMEMSET_C NULL ++#endif ++ ++#if HAVE_WMEMSET_Z13 ++# define WMEMSET_Z13 __wmemset_vx ++#else ++# define WMEMSET_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 92e28dc45ddbae37..cc6dd7adb10ee8ad 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,6 +1,5 @@ + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wmemset wmemset-vx wmemset-c \ +- wmemcmp wmemcmp-vx wmemcmp-c ++sysdep_routines += wmemcmp wmemcmp-vx wmemcmp-c + endif + + ifeq ($(subdir),iconvdata) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b5f55deb7faae9c4..7040959269c1612b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -63,6 +63,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -645,6 +646,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WMEMCHR_IFUNC */ + ++#if HAVE_WMEMSET_IFUNC ++ IFUNC_IMPL (i, name, wmemset, ++# if HAVE_WMEMSET_Z13 ++ IFUNC_IMPL_ADD (array, i, wmemset, ++ dl_hwcap & HWCAP_S390_VX, WMEMSET_Z13) ++# endif ++# if HAVE_WMEMSET_C ++ IFUNC_IMPL_ADD (array, i, wmemset, 1, WMEMSET_C) ++# endif ++ ) ++#endif /* HAVE_WMEMSET_IFUNC */ ++ + #ifdef HAVE_S390_VX_ASM_SUPPORT + + # define IFUNC_VX_IMPL(FUNC) \ +@@ -653,8 +666,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __##FUNC##_vx) \ + IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) + +- IFUNC_VX_IMPL (wmemset); +- + IFUNC_VX_IMPL (wmemcmp); + + #endif /* HAVE_S390_VX_ASM_SUPPORT */ +diff --git a/sysdeps/s390/multiarch/wmemset-c.c b/sysdeps/s390/wmemset-c.c +similarity index 59% +rename from sysdeps/s390/multiarch/wmemset-c.c +rename to sysdeps/s390/wmemset-c.c +index 1969cf93dcf08892..01e625496d8c2e4e 100644 +--- a/sysdeps/s390/multiarch/wmemset-c.c ++++ b/sysdeps/s390/wmemset-c.c +@@ -16,22 +16,29 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WMEMSET __wmemset_c +- +-# include +-extern __typeof (__wmemset) __wmemset_c; +-# undef weak_alias +-# define weak_alias(name, alias) +-# ifdef SHARED +-# undef libc_hidden_def +-# define libc_hidden_def(name) \ +- __hidden_ver1 (__wmemset_c, __GI___wmemset, __wmemset_c); +-# undef libc_hidden_weak +-# define libc_hidden_weak(name) \ ++#include ++ ++#if HAVE_WMEMSET_C ++# if HAVE_WMEMSET_IFUNC || HAVE_WMEMSET_Z13 ++# define WMEMSET WMEMSET_C ++ ++# undef weak_alias ++# define weak_alias(name, alias) ++ ++# if defined SHARED && IS_IN (libc) ++# undef libc_hidden_weak ++# define libc_hidden_weak(name) ++# undef libc_hidden_def ++# if ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wmemset_c, __GI_wmemset, __wmemset_c) __attribute__((weak)); \ + strong_alias (__wmemset_c, __wmemset_c_1); \ +- __hidden_ver1 (__wmemset_c_1, __GI_wmemset, __wmemset_c_1); +-# endif /* SHARED */ ++ __hidden_ver1 (__wmemset_c_1, __GI___wmemset, __wmemset_c_1); ++# else ++# define libc_hidden_def(name) ++# endif ++# endif ++# endif + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++#endif +diff --git a/sysdeps/s390/multiarch/wmemset-vx.S b/sysdeps/s390/wmemset-vx.S +similarity index 91% +rename from sysdeps/s390/multiarch/wmemset-vx.S +rename to sysdeps/s390/wmemset-vx.S +index 0c2f6337b0e554ec..4b6050b5accd732b 100644 +--- a/sysdeps/s390/multiarch/wmemset-vx.S ++++ b/sysdeps/s390/wmemset-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WMEMSET_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -38,7 +39,7 @@ + -v17,v18,v19=copy of v16 for vstm + -v31=saved dest for return + */ +-ENTRY(__wmemset_vx) ++ENTRY(WMEMSET_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -137,6 +138,17 @@ ENTRY(__wmemset_vx) + br %r14 + .Lfallback: + srlg %r4,%r4,2 /* Convert byte-count to character-count. */ +- jg __wmemset_c +-END(__wmemset_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++ jg WMEMSET_C ++END(WMEMSET_Z13) ++ ++# if ! HAVE_WMEMSET_IFUNC ++strong_alias (WMEMSET_Z13, __wmemset) ++weak_alias (__wmemset, wmemset) ++# endif ++ ++# if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT \ ++ && defined SHARED && IS_IN (libc) ++strong_alias (WMEMSET_Z13, __GI___wmemset) ++weak_alias (WMEMSET_Z13, __GI_wmemset) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/wmemset.c +similarity index 70% +rename from sysdeps/s390/multiarch/wmemset.c +rename to sysdeps/s390/wmemset.c +index 149b4814708d820a..6118754d1df71948 100644 +--- a/sysdeps/s390/multiarch/wmemset.c ++++ b/sysdeps/s390/wmemset.c +@@ -16,7 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WMEMSET_IFUNC + # define wmemset __redirect_wmemset + # define __wmemset __redirect___wmemset + # include +@@ -24,9 +26,18 @@ + # undef __wmemset + # include + +-s390_vx_libc_ifunc_redirected (__redirect___wmemset, __wmemset) +-weak_alias (__wmemset, wmemset) ++# if HAVE_WMEMSET_C ++extern __typeof (__redirect___wmemset) WMEMSET_C attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++# if HAVE_WMEMSET_Z13 ++extern __typeof (__redirect___wmemset) WMEMSET_Z13 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___wmemset, __wmemset, ++ (HAVE_WMEMSET_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WMEMSET_Z13 ++ : WMEMSET_DEFAULT ++ ) ++weak_alias (__wmemset, wmemset) ++#endif diff --git a/SOURCES/glibc-rh1659438-54.patch b/SOURCES/glibc-rh1659438-54.patch new file mode 100644 index 0000000..2bd37c0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-54.patch @@ -0,0 +1,246 @@ +commit 25654a8c74dce51e162c29749c6bd6d2a67490e6 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:25 2018 +0100 + + S390: Refactor wmemcmp ifunc handling. + + The ifunc handling for wmemcmp is adjusted in order to omit ifunc + variants if those will never be used as the minimum architecture level + already supports newer CPUs by default. + + ChangeLog: + + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Remove wmemcmp variants. + * sysdeps/s390/Makefile (sysdep_routines): Add wmemcmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Refactor ifunc handling for wmemcmp. + * sysdeps/s390/multiarch/wmemcmp-c.c: Move to ... + * sysdeps/s390/wmemcmp-c.c: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemcmp-vx.S: Move to ... + * sysdeps/s390/wmemcmp-vx.S: ... here and adjust ifunc handling. + * sysdeps/s390/multiarch/wmemcmp.c: Move to ... + * sysdeps/s390/wmemcmp.c: ... here and adjust ifunc handling. + * sysdeps/s390/ifunc-wmemcmp.h: New file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index f9a71276331b396a..3f7de6613c343819 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -77,5 +77,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ +- wmemset wmemset-vx wmemset-c ++ wmemset wmemset-vx wmemset-c \ ++ wmemcmp wmemcmp-vx wmemcmp-c + endif +diff --git a/sysdeps/s390/ifunc-wmemcmp.h b/sysdeps/s390/ifunc-wmemcmp.h +new file mode 100644 +index 0000000000000000..1b38a014590ec060 +--- /dev/null ++++ b/sysdeps/s390/ifunc-wmemcmp.h +@@ -0,0 +1,52 @@ ++/* wmemcmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define HAVE_WMEMCMP_IFUNC 1 ++#else ++# define HAVE_WMEMCMP_IFUNC 0 ++#endif ++ ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++# define HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT HAVE_WMEMCMP_IFUNC ++#else ++# define HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++# define WMEMCMP_DEFAULT WMEMCMP_Z13 ++# define HAVE_WMEMCMP_C 0 ++# define HAVE_WMEMCMP_Z13 1 ++#else ++# define WMEMCMP_DEFAULT WMEMCMP_C ++# define HAVE_WMEMCMP_C 1 ++# define HAVE_WMEMCMP_Z13 HAVE_WMEMCMP_IFUNC_AND_VX_SUPPORT ++#endif ++ ++#if HAVE_WMEMCMP_C ++# define WMEMCMP_C __wmemcmp_c ++#else ++# define WMEMCMP_C NULL ++#endif ++ ++#if HAVE_WMEMCMP_Z13 ++# define WMEMCMP_Z13 __wmemcmp_vx ++#else ++# define WMEMCMP_Z13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index cc6dd7adb10ee8ad..fec36153047e4585 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,7 +1,3 @@ +-ifeq ($(subdir),wcsmbs) +-sysdep_routines += wmemcmp wmemcmp-vx wmemcmp-c +-endif +- + ifeq ($(subdir),iconvdata) + override define generate-8bit-table + $(make-target-directory) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7040959269c1612b..177c5fd6fe269d9b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -64,6 +64,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -658,17 +659,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_WMEMSET_IFUNC */ + +-#ifdef HAVE_S390_VX_ASM_SUPPORT +- +-# define IFUNC_VX_IMPL(FUNC) \ +- IFUNC_IMPL (i, name, FUNC, \ +- IFUNC_IMPL_ADD (array, i, FUNC, dl_hwcap & HWCAP_S390_VX, \ +- __##FUNC##_vx) \ +- IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) +- +- IFUNC_VX_IMPL (wmemcmp); +- +-#endif /* HAVE_S390_VX_ASM_SUPPORT */ ++#if HAVE_WMEMCMP_IFUNC ++ IFUNC_IMPL (i, name, wmemcmp, ++# if HAVE_WMEMCMP_Z13 ++ IFUNC_IMPL_ADD (array, i, wmemcmp, ++ dl_hwcap & HWCAP_S390_VX, WMEMCMP_Z13) ++# endif ++# if HAVE_WMEMCMP_C ++ IFUNC_IMPL_ADD (array, i, wmemcmp, 1, WMEMCMP_C) ++# endif ++ ) ++#endif /* HAVE_WMEMCMP_IFUNC */ + + return i; + } +diff --git a/sysdeps/s390/multiarch/wmemcmp-c.c b/sysdeps/s390/wmemcmp-c.c +similarity index 85% +rename from sysdeps/s390/multiarch/wmemcmp-c.c +rename to sysdeps/s390/wmemcmp-c.c +index 2fd39d501360e6f8..0c73636adda82f8b 100644 +--- a/sysdeps/s390/multiarch/wmemcmp-c.c ++++ b/sysdeps/s390/wmemcmp-c.c +@@ -16,11 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +-# define WMEMCMP __wmemcmp_c ++#include + +-# include +-extern __typeof (wmemcmp) __wmemcmp_c; ++#if HAVE_WMEMCMP_C ++# if HAVE_WMEMCMP_IFUNC ++# define WMEMCMP WMEMCMP_C ++# endif + + # include + #endif +diff --git a/sysdeps/s390/multiarch/wmemcmp-vx.S b/sysdeps/s390/wmemcmp-vx.S +similarity index 95% +rename from sysdeps/s390/multiarch/wmemcmp-vx.S +rename to sysdeps/s390/wmemcmp-vx.S +index e2fc21e4192b0dd8..87ae21b4f13c5d69 100644 +--- a/sysdeps/s390/multiarch/wmemcmp-vx.S ++++ b/sysdeps/s390/wmemcmp-vx.S +@@ -16,7 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++#if HAVE_WMEMCMP_Z13 + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -37,7 +38,7 @@ + -v17=part of s2 + -v18=index of unequal + */ +-ENTRY(__wmemcmp_vx) ++ENTRY(WMEMCMP_Z13) + .machine "z13" + .machinemode "zarch_nohighgprs" + +@@ -145,5 +146,9 @@ ENTRY(__wmemcmp_vx) + la %r2,0(%r5,%r2) + la %r3,0(%r5,%r3) + j .Lremaining +-END(__wmemcmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ ++END(WMEMCMP_Z13) ++ ++# if ! HAVE_WMEMCMP_IFUNC ++strong_alias (WMEMCMP_Z13, wmemcmp) ++# endif ++#endif +diff --git a/sysdeps/s390/multiarch/wmemcmp.c b/sysdeps/s390/wmemcmp.c +similarity index 69% +rename from sysdeps/s390/multiarch/wmemcmp.c +rename to sysdeps/s390/wmemcmp.c +index a4cb440c452fd6a9..6c8ca5f0e8ffdb50 100644 +--- a/sysdeps/s390/multiarch/wmemcmp.c ++++ b/sysdeps/s390/wmemcmp.c +@@ -16,12 +16,23 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) ++#include ++ ++#if HAVE_WMEMCMP_IFUNC + # include + # include + +-s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp) ++# if HAVE_WMEMCMP_C ++extern __typeof (wmemcmp) WMEMCMP_C attribute_hidden; ++# endif ++ ++# if HAVE_WMEMCMP_Z13 ++extern __typeof (wmemcmp) WMEMCMP_Z13 attribute_hidden; ++# endif + +-#else +-# include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ ++s390_libc_ifunc_expr (wmemcmp, wmemcmp, ++ (HAVE_WMEMCMP_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? WMEMCMP_Z13 ++ : WMEMCMP_DEFAULT ++ ) ++#endif diff --git a/SOURCES/glibc-rh1659438-55.patch b/SOURCES/glibc-rh1659438-55.patch new file mode 100644 index 0000000..e4be220 --- /dev/null +++ b/SOURCES/glibc-rh1659438-55.patch @@ -0,0 +1,53 @@ +commit 12f0dcb8da2c7c74d673583ec3286c0354273f52 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:25 2018 +0100 + + S390: Refactor gconv_simple ifunc handling. + + The ifunc handling for various __gconv_transform_* functions + which are using IFUNC on s390x are adjusted in order to omit ifunc + if the minimum architecture level already supports newer CPUs by default. + Instead those functions are just an alias to the vector variants. + + Furthermore the ifunc-macro s390_libc_ifunc_expr is now used instead of + s390_vx_libc_ifunc. + + ChangeLog: + + * sysdeps/s390/multiarch/gconv_simple.c (ICONV_VX_IFUNC): + Define macro dependent on HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT. + +diff --git a/sysdeps/s390/multiarch/gconv_simple.c b/sysdeps/s390/multiarch/gconv_simple.c +index aaa1ebf74acf4dde..078d992c13eb548c 100644 +--- a/sysdeps/s390/multiarch/gconv_simple.c ++++ b/sysdeps/s390/multiarch/gconv_simple.c +@@ -27,17 +27,18 @@ + + # define ICONV_C_NAME(NAME) __##NAME##_c + # define ICONV_VX_NAME(NAME) __##NAME##_vx +-# define ICONV_VX_IFUNC(FUNC) \ +- extern __typeof (ICONV_C_NAME (FUNC)) __##FUNC; \ +- s390_vx_libc_ifunc (__##FUNC) \ +- int FUNC (struct __gconv_step *step, struct __gconv_step_data *data, \ +- const unsigned char **inptrp, const unsigned char *inend, \ +- unsigned char **outbufstart, size_t *irreversible, \ +- int do_flush, int consume_incomplete) \ +- { \ +- return __##FUNC (step, data, inptrp, inend,outbufstart, \ +- irreversible, do_flush, consume_incomplete); \ +- } ++# ifdef HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++/* We support z13 instructions by default -> Just use the vector variant. */ ++# define ICONV_VX_IFUNC(FUNC) strong_alias (ICONV_VX_NAME (FUNC), FUNC) ++# else ++/* We have to use ifunc to determine if z13 instructions are supported. */ ++# define ICONV_VX_IFUNC(FUNC) \ ++ s390_libc_ifunc_expr (ICONV_C_NAME (FUNC), FUNC, \ ++ (hwcap & HWCAP_S390_VX) \ ++ ? ICONV_VX_NAME (FUNC) \ ++ : ICONV_C_NAME (FUNC) \ ++ ) ++# endif + # define ICONV_VX_SINGLE(NAME) \ + static __typeof (NAME##_single) __##NAME##_vx_single __attribute__((alias(#NAME "_single"))); + diff --git a/SOURCES/glibc-rh1659438-56.patch b/SOURCES/glibc-rh1659438-56.patch new file mode 100644 index 0000000..934b8da --- /dev/null +++ b/SOURCES/glibc-rh1659438-56.patch @@ -0,0 +1,152 @@ +commit 80190d2b0e3f48d973724218f37d2da5bf1a20ab +Author: Stefan Liebler +Date: Tue Dec 18 13:57:25 2018 +0100 + + S390: Cleanup ifunc-resolve.h. + + The ifunc macros s390_vx_libc* are no longer used and + can be removed as all users are now relying on + s390_libc_ifunc_expr. + + The same applies to s390_libc_ifunc. The macro + s390_libc_ifunc_init is now renamed to + s390_libc_ifunc_expr_stfle_init and the users are + adjusted accordingly. + + ChangeLog: + + * sysdeps/s390/multiarch/ifunc-resolve.h + (s390_vx_libc_ifunc, s390_vx_libc_ifunc_redirected, + s390_vx_libc_ifunc2, s390_vx_libc_ifunc_init, + s390_vx_libc_ifunc2_redirected, s390_libc_ifunc): + Delete macro definition. + (s390_libc_ifunc_init): Rename to + s390_libc_ifunc_expr_stfle_init. + * sysdeps/s390/bzero: Use + s390_libc_ifunc_expr_stfle_init instead of + s390_libc_ifunc_init. + * sysdeps/s390/memcmp.c: Likewise. + * sysdeps/s390/memcpy.c: Likewise. + * sysdeps/s390/mempcpy.c: Likewise. + * sysdeps/s390/memset.c: Likewise. + +diff --git a/sysdeps/s390/bzero.c b/sysdeps/s390/bzero.c +index 9f8d95781bf2fb68..6b5d471c40250543 100644 +--- a/sysdeps/s390/bzero.c ++++ b/sysdeps/s390/bzero.c +@@ -35,7 +35,7 @@ extern __typeof (__bzero) BZERO_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__bzero, __bzero, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) + ? BZERO_Z196 + : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/memcmp.c b/sysdeps/s390/memcmp.c +index 952ff6af7364fd92..6d9276320abbe332 100644 +--- a/sysdeps/s390/memcmp.c ++++ b/sysdeps/s390/memcmp.c +@@ -37,7 +37,7 @@ extern __typeof (__redirect_memcmp) MEMCMP_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect_memcmp, memcmp, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMCMP_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMCMP_Z196 + : (HAVE_MEMCMP_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/memcpy.c b/sysdeps/s390/memcpy.c +index 90a53ac27d4be755..0ff24f18cf3600da 100644 +--- a/sysdeps/s390/memcpy.c ++++ b/sysdeps/s390/memcpy.c +@@ -38,7 +38,7 @@ extern __typeof (__redirect_memcpy) MEMCPY_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect_memcpy, memcpy, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMCPY_Z196 + : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/mempcpy.c b/sysdeps/s390/mempcpy.c +index a6a237312659c2c1..b687b3362034bfb0 100644 +--- a/sysdeps/s390/mempcpy.c ++++ b/sysdeps/s390/mempcpy.c +@@ -42,7 +42,7 @@ extern __typeof (__redirect___mempcpy) MEMPCPY_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect___mempcpy, __mempcpy, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMPCPY_Z196 + : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/memset.c b/sysdeps/s390/memset.c +index 57a35aebc7d3c794..75b011f1a24f39bc 100644 +--- a/sysdeps/s390/memset.c ++++ b/sysdeps/s390/memset.c +@@ -37,7 +37,7 @@ extern __typeof (__redirect_memset) MEMSET_Z196 attribute_hidden; + + s390_libc_ifunc_expr (__redirect_memset, memset, + ({ +- s390_libc_ifunc_init (); ++ s390_libc_ifunc_expr_stfle_init (); + (HAVE_MEMSET_Z196 && S390_IS_Z196 (stfle_bits)) + ? MEMSET_Z196 + : (HAVE_MEMSET_Z10 && S390_IS_Z10 (stfle_bits)) +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index b7e20abc59638251..b2be015401313d4b 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -40,7 +40,7 @@ + ".machine pop" "\n" \ + : "=QS" (STFLE_BITS), "+d" (reg0) \ + : : "cc"); +-#define s390_libc_ifunc_init() \ ++#define s390_libc_ifunc_expr_stfle_init() \ + unsigned long long stfle_bits = 0ULL; \ + if (__glibc_likely ((hwcap & HWCAP_S390_STFLE) \ + && (hwcap & HWCAP_S390_ZARCH) \ +@@ -49,41 +49,6 @@ + S390_STORE_STFLE (stfle_bits); \ + } + +-#define s390_libc_ifunc(TYPE_FUNC, RESOLVERFUNC, FUNC) \ +- /* Make the declarations of the optimized functions hidden in order +- to prevent GOT slots being generated for them. */ \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z196 attribute_hidden; \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z10 attribute_hidden; \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_default attribute_hidden; \ +- __ifunc (TYPE_FUNC, FUNC, \ +- __glibc_likely (S390_IS_Z196 (stfle_bits)) \ +- ? RESOLVERFUNC##_z196 \ +- : __glibc_likely (S390_IS_Z10 (stfle_bits)) \ +- ? RESOLVERFUNC##_z10 \ +- : RESOLVERFUNC##_default, \ +- unsigned long int hwcap, s390_libc_ifunc_init); +- +-#define s390_vx_libc_ifunc(FUNC) \ +- s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC) +- +-#define s390_vx_libc_ifunc_redirected(TYPE_FUNC, FUNC) \ +- s390_vx_libc_ifunc2_redirected(TYPE_FUNC, FUNC, FUNC) +- +-#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \ +- s390_vx_libc_ifunc2_redirected(FUNC, RESOLVERFUNC, FUNC) +- +-#define s390_vx_libc_ifunc_init() +-#define s390_vx_libc_ifunc2_redirected(TYPE_FUNC, RESOLVERFUNC, FUNC) \ +- /* Make the declarations of the optimized functions hidden in order +- to prevent GOT slots being generated for them. */ \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden; \ +- extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden; \ +- __ifunc (TYPE_FUNC, FUNC, \ +- (hwcap & HWCAP_S390_VX) \ +- ? RESOLVERFUNC##_vx \ +- : RESOLVERFUNC##_c, \ +- unsigned long int hwcap, s390_vx_libc_ifunc_init); +- + #define s390_libc_ifunc_expr_init() + #define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR) \ + __ifunc (TYPE_FUNC, FUNC, EXPR, unsigned long int hwcap, \ diff --git a/SOURCES/glibc-rh1659438-57.patch b/SOURCES/glibc-rh1659438-57.patch new file mode 100644 index 0000000..50b5945 --- /dev/null +++ b/SOURCES/glibc-rh1659438-57.patch @@ -0,0 +1,29 @@ +commit 61f5e9470fb397a4c334938ac5a667427d9047df +Author: Stefan Liebler +Date: Thu Mar 21 09:14:26 2019 +0100 + + S390: Mark vx and vxe as important hwcap. + + This patch adds vx and vxe as important hwcaps + which allows one to provide shared libraries + tuned for platforms with non-vx/-vxe, vx or vxe. + + ChangeLog: + + * sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT): + Add HWCAP_S390_VX and HWCAP_S390_VXE. + +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index b0383bfb4cef7972..f71d64c3ab24e715 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -57,7 +57,8 @@ enum + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ +- | HWCAP_S390_EIMM | HWCAP_S390_DFP) ++ | HWCAP_S390_EIMM | HWCAP_S390_DFP \ ++ | HWCAP_S390_VX | HWCAP_S390_VXE) + + /* We cannot provide a general printing function. */ + #define _dl_procinfo(type, word) -1 diff --git a/SOURCES/glibc-rh1659438-58.patch b/SOURCES/glibc-rh1659438-58.patch new file mode 100644 index 0000000..3f16140 --- /dev/null +++ b/SOURCES/glibc-rh1659438-58.patch @@ -0,0 +1,88 @@ +commit 1a7df49c92f62e14d8727f083fd055eba7c91ad9 +Author: Stefan Liebler +Date: Fri Mar 22 11:14:07 2019 +0100 + + S390: Add new hwcap values for new cpu architecture arch13. + + The new hwcap values indicate support for: + -"Vector-Enhancements Facility 2" (tag "vxe2", hwcap 2^15) + -"Vector-Packed-Decimal-Enhancement Facility" (tag "vxp", hwcap 2^16) + -"Enhanced-Sort Facility" (tag "sort", hwcap 2^17) + -"Deflate-Conversion Facility" (tag "dflt", hwcap 2^18) + + The vxe2 hwcap is also marked as important hwcap. + + ChangeLog: + + * sysdeps/s390/dl-procinfo.c (_dl_s390_cap_flags): + Add vxe2, vxp, dflt, sort flags. + * sysdeps/s390/dl-procinfo.h: Add HWCAP_S390_VXRS_EXT2, + HWCAP_S390_VXRS_PDE, HWCAP_S390_SORT, HWCAP_S390_DFLT + capabilities. + (HWCAP_IMPORTANT): Add HWCAP_S390_VXRS_EXT2. + * sysdeps/unix/sysv/linux/s390/bits/hwcap.h + (HWCAP_S390_VXRS_EXT2, HWCAP_S390_VXRS_PDE, HWCAP_S390_SORT, + HWCAP_S390_DFLT): Define. + +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index 86c964caff6a1bc4..6ea220a171d8fab7 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -46,12 +46,12 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_cap_flags + #else +-PROCINFO_CLASS const char _dl_s390_cap_flags[15][9] ++PROCINFO_CLASS const char _dl_s390_cap_flags[19][9] + #endif + #ifndef PROCINFO_DECL + = { + "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", +- "highgprs", "te", "vx", "vxd", "vxe", "gs" ++ "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index f71d64c3ab24e715..d03c69fffdbd06de 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -21,7 +21,7 @@ + #define _DL_PROCINFO_H 1 + #include + +-#define _DL_HWCAP_COUNT 15 ++#define _DL_HWCAP_COUNT 19 + + #define _DL_PLATFORMS_COUNT 9 + +@@ -54,11 +54,16 @@ enum + HWCAP_S390_VXD = 1 << 12, + HWCAP_S390_VXE = 1 << 13, + HWCAP_S390_GS = 1 << 14, ++ HWCAP_S390_VXRS_EXT2 = 1 << 15, ++ HWCAP_S390_VXRS_PDE = 1 << 16, ++ HWCAP_S390_SORT = 1 << 17, ++ HWCAP_S390_DFLT = 1 << 18, + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ + | HWCAP_S390_EIMM | HWCAP_S390_DFP \ +- | HWCAP_S390_VX | HWCAP_S390_VXE) ++ | HWCAP_S390_VX | HWCAP_S390_VXE \ ++ | HWCAP_S390_VXRS_EXT2) + + /* We cannot provide a general printing function. */ + #define _dl_procinfo(type, word) -1 +diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +index 2564712399948375..6b9b59522e3d3bec 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +@@ -39,3 +39,7 @@ + #define HWCAP_S390_VXD 4096 + #define HWCAP_S390_VXE 8192 + #define HWCAP_S390_GS 16384 ++#define HWCAP_S390_VXRS_EXT2 32768 ++#define HWCAP_S390_VXRS_PDE 65536 ++#define HWCAP_S390_SORT 131072 ++#define HWCAP_S390_DFLT 262144 diff --git a/SOURCES/glibc-rh1659438-59.patch b/SOURCES/glibc-rh1659438-59.patch new file mode 100644 index 0000000..8cb861c --- /dev/null +++ b/SOURCES/glibc-rh1659438-59.patch @@ -0,0 +1,195 @@ +commit a899a5512f618d5c4093a2d65e8dee07c791b0ab +Author: Stefan Liebler +Date: Fri Mar 22 11:14:08 2019 +0100 + + S390: Add configure check to detect support for arch13. + + Add two configure checks which detect if arch13 is supported + by the assembler at all - by explicitely setting the machine - + and if it is supported with default settings. + + ChangeLog: + + * config.h.in (HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT, + HAVE_S390_ARCH13_ASM_SUPPORT): New undefine. + * sysdeps/s390/configure.ac: Add checks for arch13 support. + * sysdeps/s390/configure: Regenerated. + +diff --git a/config.h.in b/config.h.in +index 422a6036ab16e3b6..f63f6c8442914aa1 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -71,6 +71,9 @@ + /* Define if assembler supports z13 zarch instructions as default on S390. */ + #undef HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + ++/* Define if assembler supports arch13 zarch instruction as default on S390. */ ++#undef HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++ + /* Define if assembler supports vector instructions on S390. */ + #undef HAVE_S390_VX_ASM_SUPPORT + +@@ -78,6 +81,9 @@ + on S390. */ + #undef HAVE_S390_VX_GCC_SUPPORT + ++/* Define if assembler supports arch13 instructions on S390. */ ++#undef HAVE_S390_ARCH13_ASM_SUPPORT ++ + /* Define if assembler supports Intel MPX. */ + #undef HAVE_MPX_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index 4a44775e3083d8c3..fa46e9e351e37e55 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -112,6 +112,43 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 arch13 zarch instruction support" >&5 ++$as_echo_n "checking for S390 arch13 zarch instruction support... " >&6; } ++if ${libc_cv_asm_s390_arch13+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ (".machine \"arch13\" \n\t" ++ ".machinemode \"zarch_nohighgprs\" \n\t" ++ "lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_arch13=yes ++else ++ libc_cv_asm_s390_arch13=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_arch13" >&5 ++$as_echo "$libc_cv_asm_s390_arch13" >&6; } ++if test "$libc_cv_asm_s390_arch13" = yes ; ++then ++ $as_echo "#define HAVE_S390_ARCH13_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z10 zarch instruction support as default" >&5 + $as_echo_n "checking for S390 z10 zarch instruction support as default... " >&6; } + if ${libc_cv_asm_s390_min_z10_zarch+:} false; then : +@@ -225,5 +262,39 @@ then + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 arch13 zarch instruction support as default" >&5 ++$as_echo_n "checking for S390 arch13 zarch instruction support as default... " >&6; } ++if ${libc_cv_asm_s390_min_arch13_zarch+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ ("lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_min_arch13_zarch=yes ++else ++ libc_cv_asm_s390_min_arch13_zarch=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_arch13_zarch" >&5 ++$as_echo "$libc_cv_asm_s390_min_arch13_zarch" >&6; } ++if test "$libc_cv_asm_s390_min_arch13_zarch" = yes ; ++then ++ $as_echo "#define HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ + test -n "$critic_missing" && as_fn_error $? " + *** $critic_missing" "$LINENO" 5 +diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac +index 4dfb5574b49d5949..3ed5a8ef87f9694b 100644 +--- a/sysdeps/s390/configure.ac ++++ b/sysdeps/s390/configure.ac +@@ -80,6 +80,32 @@ then + AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 arch13 zarch instruction support, ++ libc_cv_asm_s390_arch13, [dnl ++cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ (".machine \"arch13\" \n\t" ++ ".machinemode \"zarch_nohighgprs\" \n\t" ++ "lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++dnl test, if assembler supports S390 arch13 instructions ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_arch13=yes ++else ++ libc_cv_asm_s390_arch13=no ++fi ++rm -f conftest* ]) ++if test "$libc_cv_asm_s390_arch13" = yes ; ++then ++ AC_DEFINE(HAVE_S390_ARCH13_ASM_SUPPORT) ++fi ++ ++ + AC_CACHE_CHECK(for S390 z10 zarch instruction support as default, + libc_cv_asm_s390_min_z10_zarch, [dnl + cat > conftest.c <<\EOF +@@ -163,5 +189,28 @@ then + AC_DEFINE(HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT) + fi + ++AC_CACHE_CHECK(for S390 arch13 zarch instruction support as default, ++ libc_cv_asm_s390_min_arch13_zarch, [dnl ++cat > conftest.c <<\EOF ++void testinsn (char *buf) ++{ ++ __asm__ ("lghi %%r0,16 \n\t" ++ "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0"); ++} ++EOF ++dnl test, if assembler supports S390 arch13 zarch instructions as default ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_min_arch13_zarch=yes ++else ++ libc_cv_asm_s390_min_arch13_zarch=no ++fi ++rm -f conftest* ]) ++if test "$libc_cv_asm_s390_min_arch13_zarch" = yes ; ++then ++ AC_DEFINE(HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT) ++fi ++ + test -n "$critic_missing" && AC_MSG_ERROR([ + *** $critic_missing]) diff --git a/SOURCES/glibc-rh1659438-6.patch b/SOURCES/glibc-rh1659438-6.patch new file mode 100644 index 0000000..9f4157d --- /dev/null +++ b/SOURCES/glibc-rh1659438-6.patch @@ -0,0 +1,429 @@ +commit 6c6b8c747096d74b900e2711b9b0d463677f6d31 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:05 2018 +0100 + + S390: Unify 31/64bit memcmp. + + The implementation of memcmp for s390-32 (31bit) and + s390-64 (64bit) is nearly the same. + This patch unifies it for maintability reasons. + + __memcmp_z10 and __memcmp_z196 differs between 31 and 64bit: + -31bit needs .machinemode "zarch_nohighgprs" and llgfr %r4,%r4 + -lr vs lgr and some other instructions: + But lgr and co can be also used on 31bit as this ifunc variant + is only called if we are on a zarch machine. + + __memcmp_default differs between 31 and 64bit: + -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr. + Solved with 31/64 specific instruction macros). + -The address of mvc instruction is setup in different ways + (larl vs bras). Solved with #if defined __s390x__. + + Otherwise 31/64bit implementation has the same structure of the code. + + ChangeLog: + + * sysdeps/s390/s390-64/memcmp.S: Move to ... + * sysdeps/s390/memcmp.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/memcmp.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memcmp. + * sysdeps/s390/s390-32/multiarch/Makefile (sysdep_routines): + Remove memcmp. + * sysdeps/s390/s390-64/multiarch/Makefile: Likewise. + * sysdeps/s390/s390-64/multiarch/memcmp-s390x.S: Move to ... + * sysdeps/s390/multiarch/memcmp-s390x.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/multiarch/memcmp-s390.S: Delete File. + * sysdeps/s390/s390-64/multiarch/memcmp.c: Move to ... + * sysdeps/s390/multiarch/memcmp.c: ... here. + * sysdeps/s390/s390-32/multiarch/memcmp.c: Delete File. + +diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/memcmp.S +similarity index 60% +rename from sysdeps/s390/s390-64/memcmp.S +rename to sysdeps/s390/memcmp.S +index 005b19de45fcd883..751293a99e34f530 100644 +--- a/sysdeps/s390/s390-64/memcmp.S ++++ b/sysdeps/s390/memcmp.S +@@ -1,4 +1,4 @@ +-/* memcmp - compare two memory blocks. 64 bit S/390 version. ++/* memcmp - compare two memory blocks. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -26,34 +26,62 @@ + %r4 = number of bytes to compare. */ + + .text ++#if defined __s390x__ ++# define LTGR ltgr ++# define AGHI aghi ++# define BRCTG brctg ++#else ++# define LTGR ltr ++# define AGHI ahi ++# define BRCTG brct ++#endif /* ! defined __s390x__ */ ++ + #ifdef USE_MULTIARCH + ENTRY(__memcmp_default) + #else + ENTRY(memcmp) + #endif ++#if defined __s390x__ + .machine "z900" +- ltgr %r4,%r4 +- je .L_Z900_4 +- aghi %r4,-1 ++#else ++ .machine "g5" ++ basr %r5,0 ++.L_Z900_G5_16: ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16 ++#endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 ++ AGHI %r4,-1 ++#if defined __s390x__ + srlg %r1,%r4,8 +- ltgr %r1,%r1 +- jne .L_Z900_12 +-.L_Z900_3: +- larl %r1,.L_Z900_15 +- ex %r4,0(%r1) +-.L_Z900_4: ++ larl %r5,.L_Z900_G5_15 ++# define Z900_G5_EX_D 0 ++#else ++ lr %r1,%r4 ++ srl %r1,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r1,%r1 ++ jne .L_Z900_G5_12 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + ipm %r2 ++#if defined __s390x__ + sllg %r2,%r2,34 + srag %r2,%r2,62 ++#else ++ sll %r2,2 ++ sra %r2,30 ++#endif /* ! defined __s390x__ */ + br %r14 +-.L_Z900_12: ++.L_Z900_G5_12: + clc 0(256,%r3),0(%r2) +- jne .L_Z900_4 ++ jne .L_Z900_G5_4 + la %r3,256(%r3) + la %r2,256(%r2) +- brctg %r1,.L_Z900_12 +- j .L_Z900_3 +-.L_Z900_15: ++ BRCTG %r1,.L_Z900_G5_12 ++ j .L_Z900_G5_3 ++.L_Z900_G5_15: + clc 0(1,%r3),0(%r2) + #ifdef USE_MULTIARCH + END(__memcmp_default) +@@ -62,3 +90,7 @@ END(memcmp) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) + #endif ++ ++#undef LTGR ++#undef AGHI ++#undef BRCTG +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c893ebc5659fd4ae..53dd8654d73677db 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,7 +19,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy ++ mempcpy \ ++ memcmp memcmp-s390x + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/sysdeps/s390/multiarch/memcmp-s390x.S +similarity index 89% +rename from sysdeps/s390/s390-64/multiarch/memcmp-s390x.S +rename to sysdeps/s390/multiarch/memcmp-s390x.S +index 35f9bf9cf72da503..6321737acec821ec 100644 +--- a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S ++++ b/sysdeps/s390/multiarch/memcmp-s390x.S +@@ -1,4 +1,4 @@ +-/* CPU specific memcmp implementations. 64 bit S/390 version. ++/* CPU specific memcmp implementations. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -31,6 +31,10 @@ + + ENTRY(__memcmp_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 + aghi %r4,-1 +@@ -64,6 +68,10 @@ END(__memcmp_z196) + + ENTRY(__memcmp_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z10_4 + aghi %r4,-1 +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.c b/sysdeps/s390/multiarch/memcmp.c +similarity index 100% +rename from sysdeps/s390/s390-32/multiarch/memcmp.c +rename to sysdeps/s390/multiarch/memcmp.c +diff --git a/sysdeps/s390/s390-32/memcmp.S b/sysdeps/s390/s390-32/memcmp.S +deleted file mode 100644 +index f9ad0bc745daf05f..0000000000000000 +--- a/sysdeps/s390/s390-32/memcmp.S ++++ /dev/null +@@ -1,66 +0,0 @@ +-/* memcmp - compare two memory blocks. 32 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +-#ifdef USE_MULTIARCH +-ENTRY(__memcmp_default) +-#else +-ENTRY(memcmp) +-#endif +- .machine "g5" +- basr %r5,0 +-.L_G5_16: +- ltr %r4,%r4 +- je .L_G5_4 +- ahi %r4,-1 +- lr %r1,%r4 +- srl %r1,8 +- ltr %r1,%r1 +- jne .L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r5) +-.L_G5_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_G5_12: +- clc 0(256,%r3),0(%r2) +- jne .L_G5_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brct %r1,.L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r5) +- j .L_G5_4 +-.L_G5_17: +- clc 0(1,%r3),0(%r2) +-#ifdef USE_MULTIARCH +-END(__memcmp_default) +-#else +-END(memcmp) +-libc_hidden_builtin_def (memcmp) +-weak_alias(memcmp, bcmp) +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile +index 4b11e28656ac19ab..82a7492eb8436479 100644 +--- a/sysdeps/s390/s390-32/multiarch/Makefile ++++ b/sysdeps/s390/s390-32/multiarch/Makefile +@@ -1,3 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390 memcmp memcmp-s390 ++sysdep_routines += memcpy memcpy-s390 + endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S +deleted file mode 100644 +index e53b508c98bebeba..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S ++++ /dev/null +@@ -1,107 +0,0 @@ +-/* CPU specific memcmp implementations. 32 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +- +-#if IS_IN (libc) +- +-ENTRY(__memcmp_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- ltr %r4,%r4 +- je .L_Z196_4 +- ahi %r4,-1 +- srlk %r1,%r4,8 +- ltr %r1,%r1 +- jne .L_Z196_2 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z196_17: +- la %r3,256(%r3) +- la %r2,256(%r2) +- ahi %r1,-1 +- je .L_Z196_3 +-.L_Z196_2: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- je .L_Z196_17 +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z196_14: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z196) +- +-ENTRY(__memcmp_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- ltr %r4,%r4 +- je .L_Z10_4 +- ahi %r4,-1 +- lr %r1,%r4 +- srl %r1,8 +- cijlh %r1,0,.L_Z10_12 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z10_12: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- jne .L_Z10_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brct %r1,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z10) +- +-#endif /* IS_IN (libc) */ +- +-#include "../memcmp.S" +- +-#if !IS_IN (libc) +-.globl memcmp +-.set memcmp,__memcmp_default +-.weak bcmp +-.set bcmp,__memcmp_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memcmp +-.set __GI_memcmp,__memcmp_default +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile +index e4870c7ee177ad0d..8a043e3327a1527a 100644 +--- a/sysdeps/s390/s390-64/multiarch/Makefile ++++ b/sysdeps/s390/s390-64/multiarch/Makefile +@@ -1,3 +1,3 @@ + ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390x memcmp memcmp-s390x ++sysdep_routines += memcpy memcpy-s390x + endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c +deleted file mode 100644 +index 1e6f31806e172d7d..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memcmp.c ++++ /dev/null +@@ -1,27 +0,0 @@ +-/* Multiple versions of memcmp. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#if IS_IN (libc) +-# define memcmp __redirect_memcmp +-# include +-# undef memcmp +-# include +- +-s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp) +-weak_alias (memcmp, bcmp); +-#endif diff --git a/SOURCES/glibc-rh1659438-60.patch b/SOURCES/glibc-rh1659438-60.patch new file mode 100644 index 0000000..6eacc7f --- /dev/null +++ b/SOURCES/glibc-rh1659438-60.patch @@ -0,0 +1,202 @@ +commit 96fbb9a328232e42814334d6e29a9a9c7995c01d +Author: Stefan Liebler +Date: Fri Mar 22 11:14:08 2019 +0100 + + S390: Add arch13 memmove ifunc variant. + + This patch introduces the new arch13 ifunc variant for memmove. + For the forward or non-overlapping case it is just using memcpy. + For the backward case it relies on the new instruction mvcrl. + The instruction copies up to 256 bytes at once. + In case of an overlap, it copies the bytes like copying them + one by one starting from right to left. + + ChangeLog: + + * sysdeps/s390/ifunc-memcpy.h (HAVE_MEMMOVE_ARCH13, MEMMOVE_ARCH13 + HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT): New defines. + * sysdeps/s390/memcpy-z900.S: Add arch13 memmove implementation. + * sysdeps/s390/memmove.c (memmove): Add arch13 variant in + ifunc selector. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variant for arch13 memmove. + * sysdeps/s390/multiarch/ifunc-resolve.h (S390_STFLE_BITS_ARCH13_MIE3, + S390_IS_ARCH13_MIE3): New defines. + +diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h +index 0e701968c8f39014..e8cd794587b44922 100644 +--- a/sysdeps/s390/ifunc-memcpy.h ++++ b/sysdeps/s390/ifunc-memcpy.h +@@ -44,7 +44,7 @@ + #endif + + #if defined SHARED && defined USE_MULTIARCH && IS_IN (libc) \ +- && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT + # define HAVE_MEMMOVE_IFUNC 1 + #else + # define HAVE_MEMMOVE_IFUNC 0 +@@ -56,14 +56,27 @@ + # define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT 0 + #endif + +-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT ++# define HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT HAVE_MEMMOVE_IFUNC ++#else ++# define HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++# define MEMMOVE_DEFAULT MEMMOVE_ARCH13 ++# define HAVE_MEMMOVE_C 0 ++# define HAVE_MEMMOVE_Z13 0 ++# define HAVE_MEMMOVE_ARCH13 1 ++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + # define MEMMOVE_DEFAULT MEMMOVE_Z13 + # define HAVE_MEMMOVE_C 0 + # define HAVE_MEMMOVE_Z13 1 ++# define HAVE_MEMMOVE_ARCH13 HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT + #else + # define MEMMOVE_DEFAULT MEMMOVE_C + # define HAVE_MEMMOVE_C 1 + # define HAVE_MEMMOVE_Z13 HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT ++# define HAVE_MEMMOVE_ARCH13 HAVE_MEMMOVE_IFUNC_AND_ARCH13_SUPPORT + #endif + + #if HAVE_MEMCPY_Z900_G5 +@@ -101,3 +114,9 @@ + #else + # define MEMMOVE_Z13 NULL + #endif ++ ++#if HAVE_MEMMOVE_ARCH13 ++# define MEMMOVE_ARCH13 __memmove_arch13 ++#else ++# define MEMMOVE_ARCH13 NULL ++#endif +diff --git a/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S +index bd3b1950ee442c0c..45eddc67a48e991e 100644 +--- a/sysdeps/s390/memcpy-z900.S ++++ b/sysdeps/s390/memcpy-z900.S +@@ -277,6 +277,61 @@ ENTRY(MEMMOVE_Z13) + END(MEMMOVE_Z13) + #endif /* HAVE_MEMMOVE_Z13 */ + ++#if HAVE_MEMMOVE_ARCH13 ++ENTRY(MEMMOVE_ARCH13) ++ .machine "arch13" ++ .machinemode "zarch_nohighgprs" ++# if ! defined __s390x__ ++ /* Note: The 31bit dst and src pointers are prefixed with zeroes. */ ++ llgfr %r4,%r4 ++ llgfr %r3,%r3 ++ llgfr %r2,%r2 ++# endif /* ! defined __s390x__ */ ++ sgrk %r5,%r2,%r3 ++ aghik %r0,%r4,-1 /* Both vstl and mvcrl needs highest index. */ ++ clgijh %r4,16,.L_MEMMOVE_ARCH13_LARGE ++.L_MEMMOVE_ARCH13_SMALL: ++ jl .L_MEMMOVE_ARCH13_END /* Return if len was zero (cc of aghik). */ ++ /* Store up to 16 bytes with vll/vstl (needs highest index). */ ++ vll %v16,%r0,0(%r3) ++ vstl %v16,%r0,0(%r2) ++.L_MEMMOVE_ARCH13_END: ++ br %r14 ++.L_MEMMOVE_ARCH13_LARGE: ++ lgr %r1,%r2 /* For memcpy: r1: Use as dest ; r2: Return dest */ ++ /* The unsigned comparison (dst - src >= len) determines if we can ++ execute the forward case with memcpy. */ ++#if ! HAVE_MEMCPY_Z196 ++# error The arch13 variant of memmove needs the z196 variant of memcpy! ++#endif ++ /* Backward case. */ ++ clgrjhe %r5,%r4,.L_Z196_start2 ++ clgijh %r0,255,.L_MEMMOVE_ARCH13_LARGER_256B ++ /* Move up to 256bytes with mvcrl (move right to left). */ ++ mvcrl 0(%r1),0(%r3) /* Move (r0 + 1) bytes from r3 to r1. */ ++ br %r14 ++.L_MEMMOVE_ARCH13_LARGER_256B: ++ /* First move the "remaining" block of up to 256 bytes at the end of ++ src/dst buffers. Then move blocks of 256bytes in a loop starting ++ with the block at the end. ++ (If src/dst pointers are aligned e.g. to 256 bytes, then the pointers ++ passed to mvcrl instructions are aligned, too) */ ++ risbgn %r5,%r0,8,128+63,56 /* r5 = r0 / 256 */ ++ risbgn %r0,%r0,56,128+63,0 /* r0 = r0 & 0xFF */ ++ slgr %r4,%r0 ++ lay %r1,-1(%r4,%r1) ++ lay %r3,-1(%r4,%r3) ++ mvcrl 0(%r1),0(%r3) /* Move (r0 + 1) bytes from r3 to r1. */ ++ lghi %r0,255 /* Always copy 256 bytes in the loop below! */ ++.L_MEMMOVE_ARCH13_LARGE_256B_LOOP: ++ aghi %r1,-256 ++ aghi %r3,-256 ++ mvcrl 0(%r1),0(%r3) /* Move (r0 + 1) bytes from r3 to r1. */ ++ brctg %r5,.L_MEMMOVE_ARCH13_LARGE_256B_LOOP ++ br %r14 ++END(MEMMOVE_ARCH13) ++#endif /* HAVE_MEMMOVE_ARCH13 */ ++ + #if ! HAVE_MEMCPY_IFUNC + /* If we don't use ifunc, define an alias for mem[p]cpy here. + Otherwise see sysdeps/s390/mem[p]cpy.c. */ +diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c +index ac34edf80f2678cd..f6d31a4fcd56355b 100644 +--- a/sysdeps/s390/memmove.c ++++ b/sysdeps/s390/memmove.c +@@ -36,9 +36,19 @@ extern __typeof (__redirect_memmove) MEMMOVE_C attribute_hidden; + extern __typeof (__redirect_memmove) MEMMOVE_Z13 attribute_hidden; + # endif + ++# if HAVE_MEMMOVE_ARCH13 ++extern __typeof (__redirect_memmove) MEMMOVE_ARCH13 attribute_hidden; ++# endif ++ + s390_libc_ifunc_expr (__redirect_memmove, memmove, +- (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX)) +- ? MEMMOVE_Z13 +- : MEMMOVE_DEFAULT ++ ({ ++ s390_libc_ifunc_expr_stfle_init (); ++ (HAVE_MEMMOVE_ARCH13 ++ && S390_IS_ARCH13_MIE3 (stfle_bits)) ++ ? MEMMOVE_ARCH13 ++ : (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX)) ++ ? MEMMOVE_Z13 ++ : MEMMOVE_DEFAULT; ++ }) + ) + #endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 177c5fd6fe269d9b..c24bfc95f2d7a22d 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -169,6 +169,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + #if HAVE_MEMMOVE_IFUNC + IFUNC_IMPL (i, name, memmove, ++# if HAVE_MEMMOVE_ARCH13 ++ IFUNC_IMPL_ADD (array, i, memmove, ++ S390_IS_ARCH13_MIE3 (stfle_bits), ++ MEMMOVE_ARCH13) ++# endif + # if HAVE_MEMMOVE_Z13 + IFUNC_IMPL_ADD (array, i, memmove, + dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13) +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index b2be015401313d4b..db735bb341ab6b86 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -22,6 +22,11 @@ + + #define S390_STFLE_BITS_Z10 34 /* General instructions extension */ + #define S390_STFLE_BITS_Z196 45 /* Distinct operands, pop ... */ ++#define S390_STFLE_BITS_ARCH13_MIE3 61 /* Miscellaneous-Instruction-Extensions ++ Facility 3, e.g. mvcrl. */ ++ ++#define S390_IS_ARCH13_MIE3(STFLE_BITS) \ ++ ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_ARCH13_MIE3))) != 0) + + #define S390_IS_Z196(STFLE_BITS) \ + ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_Z196))) != 0) diff --git a/SOURCES/glibc-rh1659438-61.patch b/SOURCES/glibc-rh1659438-61.patch new file mode 100644 index 0000000..32e535a --- /dev/null +++ b/SOURCES/glibc-rh1659438-61.patch @@ -0,0 +1,332 @@ +commit 6f47401bd5fc71209219779a0426170a9a7395b0 +Author: Stefan Liebler +Date: Fri Mar 22 11:14:08 2019 +0100 + + S390: Add arch13 strstr ifunc variant. + + This patch introduces the new arch13 ifunc variant for strstr. + For needles longer than 9 charachters it is relying on the common-code + implementation. For shorter needles it is using the new vstrs instruction + which is able to search a substring within a vector register. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add strstr-arch13. + * sysdeps/s390/ifunc-strstr.h (HAVE_STRSTR_ARCH13, STRSTR_ARCH13, + STRSTR_Z13_ONLY_USED_AS_FALLBACK, HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT): + New defines. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variant for arch13 strstr. + * sysdeps/s390/strstr-arch13.S: New file. + * sysdeps/s390/strstr-vx.c: Omit GI symbol for z13 strstr ifunc variant + if it is only used as fallback. + * sysdeps/s390/strstr.c (strstr): Add arch13 variant in ifunc selector. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 3f7de6613c343819..7287b1833da9500f 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -35,7 +35,7 @@ sysdep_routines += bzero memset memset-z900 \ + memcmp memcmp-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ +- strstr strstr-vx strstr-c \ ++ strstr strstr-arch13 strstr-vx strstr-c \ + memmem memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ +diff --git a/sysdeps/s390/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h +index e6ccfd4e44a1a790..809184d425ad06b0 100644 +--- a/sysdeps/s390/ifunc-strstr.h ++++ b/sysdeps/s390/ifunc-strstr.h +@@ -17,7 +17,7 @@ + . */ + + #if defined USE_MULTIARCH && IS_IN (libc) \ +- && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT + # define HAVE_STRSTR_IFUNC 1 + #else + # define HAVE_STRSTR_IFUNC 0 +@@ -29,14 +29,32 @@ + # define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT 0 + #endif + +-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT ++# define HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT HAVE_STRSTR_IFUNC ++#else ++# define HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++# define STRSTR_DEFAULT STRSTR_ARCH13 ++# define HAVE_STRSTR_C 0 ++# define HAVE_STRSTR_Z13 1 ++# define STRSTR_Z13_ONLY_USED_AS_FALLBACK 1 ++# define HAVE_STRSTR_ARCH13 1 ++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + # define STRSTR_DEFAULT STRSTR_Z13 + # define HAVE_STRSTR_C 0 + # define HAVE_STRSTR_Z13 1 ++# define HAVE_STRSTR_ARCH13 HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT + #else + # define STRSTR_DEFAULT STRSTR_C + # define HAVE_STRSTR_C 1 + # define HAVE_STRSTR_Z13 HAVE_STRSTR_IFUNC_AND_VX_SUPPORT ++# define HAVE_STRSTR_ARCH13 HAVE_STRSTR_IFUNC_AND_ARCH13_SUPPORT ++#endif ++ ++#ifndef STRSTR_Z13_ONLY_USED_AS_FALLBACK ++# define STRSTR_Z13_ONLY_USED_AS_FALLBACK 0 + #endif + + #if HAVE_STRSTR_C +@@ -50,3 +68,9 @@ + #else + # define STRSTR_Z13 NULL + #endif ++ ++#if HAVE_STRSTR_ARCH13 ++# define STRSTR_ARCH13 __strstr_arch13 ++#else ++# define STRSTR_ARCH13 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c24bfc95f2d7a22d..67a6a9c94afccd48 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -186,6 +186,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + #if HAVE_STRSTR_IFUNC + IFUNC_IMPL (i, name, strstr, ++# if HAVE_STRSTR_ARCH13 ++ IFUNC_IMPL_ADD (array, i, strstr, ++ dl_hwcap & HWCAP_S390_VXRS_EXT2, STRSTR_ARCH13) ++# endif + # if HAVE_STRSTR_Z13 + IFUNC_IMPL_ADD (array, i, strstr, + dl_hwcap & HWCAP_S390_VX, STRSTR_Z13) +diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S +new file mode 100644 +index 0000000000000000..929b026adfeba740 +--- /dev/null ++++ b/sysdeps/s390/strstr-arch13.S +@@ -0,0 +1,179 @@ ++/* Vector optimized 32/64 bit S/390 version of strstr. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#if HAVE_STRSTR_ARCH13 ++# include "sysdep.h" ++# include "asm-syntax.h" ++ .text ++ ++/* char *strstr (const char *haystack=r2, const char *needle=r3) ++ Locate a substring. */ ++ENTRY(STRSTR_ARCH13) ++ .machine "arch13" ++ .machinemode "zarch_nohighgprs" ++ lcbb %r1,0(%r3),6 ++ jo .Lneedle_on_bb /* Needle on block-boundary? */ ++ vl %v18,0(%r3),6 /* Load needle. */ ++ vfenezb %v19,%v18,%v18 /* v19[7] contains the length of needle. */ ++.Lneedle_loaded: ++ vlgvb %r4,%v19,7 /* Get index of zero or 16 if not found. */ ++ lghi %r5,17 /* See below: min-skip-partial-match-index. */ ++ cgibe %r4,0,0(%r14) /* Test if needle is zero and return. */ ++ ++ /* The vstrs instruction is able to handle needles up to a length of 16, ++ but then we may have to load the next part of haystack with a ++ small offset. This will be slow - see examples: ++ haystack =mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm...mmmmmmmmmmmmmmmmmmma ++ needle = mmmmmmmmmmmmmma0 ++ => needle_len=15; vstrs reports a partial match; haystack+=2 ++ haystack =mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm...mmmmmmmmmmmmmmmmmmma ++ needle = mmmmmmmma0000000 ++ => needle_len=9; vstrs reports a partial match; haystack+=8 */ ++# if ! HAVE_STRSTR_Z13 ++# error The arch13 variant of strstr needs the z13 variant of strstr! ++# endif ++ clgfi %r4,9 ++ jh STRSTR_Z13 ++ ++ /* In case of a partial match, the vstrs instruction returns the index ++ of the partial match in a vector-register. Then we have to ++ reload the string at the "current-position plus this index" and run ++ vstrs again in order to determine if it was a full match or no match. ++ Transferring this index from vr to gr, compute the haystack-address ++ and loading with vl is quite slow as all instructions have data ++ dependencies. Thus we assume, that a partial match is always at the ++ first possible index and just load the next part of haystack from ++ there instead of waiting until the correct index is computed: ++ min-skip-partial-match-index = (16 - n_len) + 1 */ ++ sgr %r5,%r4 ++ ++.Lloop: ++ lcbb %r1,0(%r2),6 ++ jo .Lloop_haystack_on_bb /* Haystack on block-boundary? */ ++ vl %v16,0(%r2) /* Load next part of haystack. */ ++.Lloop_haystack_loaded: ++ /* Vector string search with zero search (cc=0 => no match). */ ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc ++ lcbb %r1,16(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb16 ++ vl %v16,16(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc16 ++ lcbb %r1,32(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb32 ++ vl %v16,32(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc32 ++ lcbb %r1,48(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb48 ++ vl %v16,48(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jne .Lloop_vstrs_nonzero_cc48 ++ la %r2,64(%r2) ++ j .Lloop ++ ++.Lloop_vstrs_nonzero_cc48: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc32: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc16: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc: ++ jh .Lend_match_found /* cc == 2 (full match) */ ++ jl .Lend_no_match /* cc == 1 (no match, end of string) */ ++ /* cc == 3 (partial match) See above: min-skip-partial-match-index! */ ++ lcbb %r1,0(%r5,%r2),6 ++ la %r2,0(%r5,%r2) ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++.Lloop_vstrs_nonzero_cc_loop: ++ jh .Lend_match_found ++ jl .Lend_no_match ++ la %r2,0(%r5,%r2) ++ je .Lloop ++ lcbb %r1,0(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jh .Lend_match_found ++ jl .Lend_no_match ++ la %r2,0(%r5,%r2) ++ je .Lloop ++ lcbb %r1,0(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ jh .Lend_match_found ++ jl .Lend_no_match ++ la %r2,0(%r5,%r2) ++ je .Lloop ++ lcbb %r1,0(%r2),6 /* Next part of haystack. */ ++ jo .Lloop_haystack_on_bb ++ vl %v16,0(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,2 ++ j .Lloop_vstrs_nonzero_cc_loop ++ ++.Lend_no_match: ++ lghi %r2,0 ++ br %r14 ++.Lend_match_found: ++ vlgvb %r4,%v20,7 ++ la %r2,0(%r4,%r2) ++ br %r14 ++ ++.Lloop_haystack_on_bb48: ++ la %r2,16(%r2) ++.Lloop_haystack_on_bb32: ++ la %r2,16(%r2) ++.Lloop_haystack_on_bb16: ++ la %r2,16(%r2) ++.Lloop_haystack_on_bb: ++ /* Haystack located on page-boundary. */ ++ ahi %r1,-1 /* vll needs highest index instead of count. */ ++ vll %v16,%r1,0(%r2) ++ vlvgb %v21,%r1,7 ++ vfenezb %v17,%v16,%v16 /* Search zero in loaded haystack bytes. */ ++ veclb %v17,%v21 /* Zero index <= loaded byte index? */ ++ jle .Lloop_haystack_loaded /* -> v16 contains full haystack. */ ++ vl %v16,0(%r2) /* Load haystack beyond page boundary. */ ++ j .Lloop_haystack_loaded ++ ++.Lneedle_on_bb: ++ /* Needle located on page-boundary. */ ++ ahi %r1,-1 /* vll needs highest index instead of count. */ ++ vll %v18,%r1,0(%r3) ++ vlvgb %v21,%r1,7 ++ vfenezb %v19,%v18,%v18 /* Search zero in loaded needle bytes. */ ++ veclb %v19,%v21 /* Zero index <= max loaded byte index? */ ++ jle .Lneedle_loaded /* -> v18 contains full needle. */ ++ vl %v16,0(%r3) /* Load needle beyond page boundary. */ ++ vfenezb %v19,%v18,%v18 ++ j .Lneedle_loaded ++END(STRSTR_ARCH13) ++ ++# if ! HAVE_STRSTR_IFUNC ++strong_alias (STRSTR_ARCH13, strstr) ++# endif ++ ++# if STRSTR_Z13_ONLY_USED_AS_FALLBACK && defined SHARED && IS_IN (libc) ++strong_alias (STRSTR_ARCH13, __GI_strstr) ++# endif ++#endif +diff --git a/sysdeps/s390/strstr-vx.c b/sysdeps/s390/strstr-vx.c +index effae9d5eb7d2fb1..f69159ffc198b10b 100644 +--- a/sysdeps/s390/strstr-vx.c ++++ b/sysdeps/s390/strstr-vx.c +@@ -19,11 +19,11 @@ + #include + + #if HAVE_STRSTR_Z13 +-# if HAVE_STRSTR_IFUNC ++# if HAVE_STRSTR_IFUNC || STRSTR_Z13_ONLY_USED_AS_FALLBACK + # define STRSTR STRSTR_Z13 + # if defined SHARED && IS_IN (libc) + # undef libc_hidden_builtin_def +-# if HAVE_STRSTR_C ++# if HAVE_STRSTR_C || STRSTR_Z13_ONLY_USED_AS_FALLBACK + # define libc_hidden_builtin_def(name) + # else + # define libc_hidden_builtin_def(name) \ +diff --git a/sysdeps/s390/strstr.c b/sysdeps/s390/strstr.c +index f8432349a7254cc6..d2969fd0a68fadbf 100644 +--- a/sysdeps/s390/strstr.c ++++ b/sysdeps/s390/strstr.c +@@ -32,8 +32,14 @@ extern __typeof (__redirect_strstr) STRSTR_C attribute_hidden; + extern __typeof (__redirect_strstr) STRSTR_Z13 attribute_hidden; + # endif + ++# if HAVE_STRSTR_ARCH13 ++extern __typeof (__redirect_strstr) STRSTR_ARCH13 attribute_hidden; ++# endif ++ + s390_libc_ifunc_expr (__redirect_strstr, strstr, +- (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX)) ++ (HAVE_STRSTR_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)) ++ ? STRSTR_ARCH13 ++ : (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX)) + ? STRSTR_Z13 + : STRSTR_DEFAULT + ) diff --git a/SOURCES/glibc-rh1659438-62.patch b/SOURCES/glibc-rh1659438-62.patch new file mode 100644 index 0000000..9d430c0 --- /dev/null +++ b/SOURCES/glibc-rh1659438-62.patch @@ -0,0 +1,318 @@ +commit 421749d693c4147017bc55f5ac3227c3a6e4bf31 +Author: Stefan Liebler +Date: Fri Mar 22 11:14:09 2019 +0100 + + S390: Add arch13 memmem ifunc variant. + + This patch introduces the new arch13 ifunc variant for memmem. + For needles longer than 9 bytes it is relying on the common-code + implementation. For shorter needles it is using the new vstrs instruction + which is able to search a substring within a vector register. + + ChangeLog: + + * sysdeps/s390/Makefile (sysdep_routines): Add memmem-arch13. + * sysdeps/s390/ifunc-memmem.h (HAVE_MEMMEM_ARCH13, MEMMEM_ARCH13, + MEMMEM_Z13_ONLY_USED_AS_FALLBACK, HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT): + New defines. + * sysdeps/s390/memmem-arch13.S: New file. + * sysdeps/s390/memmem-vx.c: Omit GI symbol for z13 memmem ifunc variant + if it is only used as fallback. + * sysdeps/s390/memmem.c (memmem): Add arch13 variant in ifunc selector. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc variant for arch13 memmem. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index 7287b1833da9500f..8bc82e523f9049db 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -36,7 +36,7 @@ sysdep_routines += bzero memset memset-z900 \ + mempcpy memcpy memcpy-z900 \ + memmove memmove-c \ + strstr strstr-arch13 strstr-vx strstr-c \ +- memmem memmem-vx memmem-c \ ++ memmem memmem-arch13 memmem-vx memmem-c \ + strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx strcpy-z900 \ +diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h +index 0f860d8d40080acf..48079b22b070f381 100644 +--- a/sysdeps/s390/ifunc-memmem.h ++++ b/sysdeps/s390/ifunc-memmem.h +@@ -17,7 +17,7 @@ + . */ + + #if defined USE_MULTIARCH && IS_IN (libc) \ +- && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++ && ! defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT + # define HAVE_MEMMEM_IFUNC 1 + #else + # define HAVE_MEMMEM_IFUNC 0 +@@ -29,14 +29,32 @@ + # define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT 0 + #endif + +-#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT ++#ifdef HAVE_S390_ARCH13_ASM_SUPPORT ++# define HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT HAVE_MEMMEM_IFUNC ++#else ++# define HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT 0 ++#endif ++ ++#if defined HAVE_S390_MIN_ARCH13_ZARCH_ASM_SUPPORT ++# define MEMMEM_DEFAULT MEMMEM_ARCH13 ++# define HAVE_MEMMEM_C 0 ++# define HAVE_MEMMEM_Z13 1 ++# define MEMMEM_Z13_ONLY_USED_AS_FALLBACK 1 ++# define HAVE_MEMMEM_ARCH13 1 ++#elif defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT + # define MEMMEM_DEFAULT MEMMEM_Z13 + # define HAVE_MEMMEM_C 0 + # define HAVE_MEMMEM_Z13 1 ++# define HAVE_MEMMEM_ARCH13 HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT + #else + # define MEMMEM_DEFAULT MEMMEM_C + # define HAVE_MEMMEM_C 1 + # define HAVE_MEMMEM_Z13 HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT ++# define HAVE_MEMMEM_ARCH13 HAVE_MEMMEM_IFUNC_AND_ARCH13_SUPPORT ++#endif ++ ++#ifndef MEMMEM_Z13_ONLY_USED_AS_FALLBACK ++# define MEMMEM_Z13_ONLY_USED_AS_FALLBACK 0 + #endif + + #if HAVE_MEMMEM_C +@@ -50,3 +68,9 @@ + #else + # define MEMMEM_Z13 NULL + #endif ++ ++#if HAVE_MEMMEM_ARCH13 ++# define MEMMEM_ARCH13 __memmem_arch13 ++#else ++# define MEMMEM_ARCH13 NULL ++#endif +diff --git a/sysdeps/s390/memmem-arch13.S b/sysdeps/s390/memmem-arch13.S +new file mode 100644 +index 0000000000000000..b59d60acf0f6aaa0 +--- /dev/null ++++ b/sysdeps/s390/memmem-arch13.S +@@ -0,0 +1,161 @@ ++/* Vector optimized 32/64 bit S/390 version of memmem. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#if HAVE_MEMMEM_ARCH13 ++# include "sysdep.h" ++# include "asm-syntax.h" ++ .text ++ ++/* void *memmem(const void *haystack=r2, size_t haystacklen=r3, ++ const void *needle=r4, size_t needlelen=r5); ++ Locate a substring. */ ++ENTRY(MEMMEM_ARCH13) ++ .machine "arch13" ++ .machinemode "zarch_nohighgprs" ++# if ! defined __s390x__ ++ llgfr %r3,%r3 ++ llgfr %r5,%r5 ++ llgfr %r4,%r4 ++ llgfr %r2,%r2 ++# endif /* ! defined __s390x__ */ ++ clgrjl %r3,%r5,.Lend_no_match /* Haystack < needle? */ ++ ++ /* Jump to fallback if needle > 9. See also strstr-arch13.S. */ ++# if ! HAVE_MEMMEM_Z13 ++# error The arch13 variant of memmem needs the z13 variant of memmem! ++# endif ++ clgfi %r5,9 ++ jh MEMMEM_Z13 ++ ++ aghik %r0,%r5,-1 /* vll needs highest index. */ ++ bc 4,0(%r14) /* cc==1: return if needle-len == 0. */ ++ vll %v18,%r0,0(%r4) /* Load needle. */ ++ vlvgb %v19,%r5,7 /* v19[7] contains length of needle. */ ++ ++ clgijh %r3,16,.Lhaystack_larger_16 ++.Lhaystack_smaller_16_on_bb: ++ aghik %r0,%r3,-1 /* vll needs highest index. */ ++ vll %v16,%r0,0(%r2) /* Load haystack. */ ++.Lhaystack_smaller_16: ++ sgr %r3,%r5 /* r3 = largest valid match-index. */ ++ jl .Lend_no_match /* Haystack-len < needle-len? */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ /* Vector string search without zero search where v20 will contain ++ the index of a partial/full match or 16 (index is named k). ++ cc=0 (no match; k=16): .Lend_no_match ++ cc=1 (only available with zero-search): Ignore ++ cc=2 (full match; k<16): Needle found, but could be beyond haystack! ++ cc=3 (partial match; k<16): Always at end of v16 and thus beyond! */ ++ brc 9,.Lend_no_match /* Jump away if cc == 0 || cc == 3. */ ++ vlgvb %r1,%v20,7 ++ /* Verify that the full-match (cc=2) is valid! */ ++ clgrjh %r1,%r3,.Lend_no_match /* Jump away if match is beyond. */ ++ la %r2,0(%r1,%r2) ++ br %r14 ++.Lend_no_match: ++ lghi %r2,0 ++ br %r14 ++ ++.Lhaystack_larger_16: ++ vl %v16,0(%r2) ++ lghi %r1,17 ++ lay %r4,-16(%r3,%r2) /* Boundary for loading with vl. */ ++ lay %r0,-64(%r3,%r2) /* Boundary for loading with 4xvl. */ ++ /* See also strstr-arch13.S: ++ min-skip-partial-match-index = (16 - n_len) + 1 */ ++ sgr %r1,%r5 ++ clgfi %r3,64 /* Set Boundary to zero ... */ ++ la %r3,0(%r3,%r2) ++ locghil %r0,0 /* ... if haystack < 64bytes. */ ++ jh .Lloop64 ++.Lloop: ++ la %r2,16(%r2) ++ /* Vector string search with zero search. cc=0 => no match. */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc ++ clgrjh %r2,%r4,.Lhaystack_too_small ++.Lloop16: ++ vl %v16,0(%r2) ++ la %r2,16(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc ++ clgrjle %r2,%r4,.Lloop16 ++.Lhaystack_too_small: ++ sgr %r3,%r2 /* r3 = (haystack + len) - curr_pos */ ++ je .Lend_no_match /* Remaining haystack is empty. */ ++ lcbb %r0,0(%r2),6 ++ jo .Lhaystack_smaller_16_on_bb ++ vl %v16,0(%r2) /* Load haystack. */ ++ j .Lhaystack_smaller_16 ++ ++.Lend_match_found: ++ vlgvb %r4,%v20,7 ++ sgr %r2,%r1 ++ la %r2,0(%r4,%r2) ++ br %r14 ++ ++.Lloop_vstrs_nonzero_cc32: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc16: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc0: ++ la %r2,16(%r2) ++.Lloop_vstrs_nonzero_cc: ++ lay %r2,-16(%r1,%r2) /* Compute next load address. */ ++ jh .Lend_match_found /* cc == 2 (full match) */ ++ clgrjh %r2,%r4,.Lhaystack_too_small ++ vl %v16,0(%r2) ++.Lloop_vstrs_nonzero_cc_loop: ++ la %r2,0(%r1,%r2) ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jh .Lend_match_found ++ clgrjh %r2,%r4,.Lhaystack_too_small ++ vl %v16,0(%r2) /* Next part of haystack. */ ++ jo .Lloop_vstrs_nonzero_cc_loop ++ /* Case: no-match. */ ++ clgrjh %r2,%r0,.Lloop /* Jump away if haystack has less than 64b. */ ++.Lloop64: ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc0 ++ vl %v16,16(%r2) /* Next part of haystack. */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc16 ++ vl %v16,32(%r2) /* Next part of haystack. */ ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc32 ++ vl %v16,48(%r2) /* Next part of haystack. */ ++ la %r2,64(%r2) ++ vstrs %v20,%v16,%v18,%v19,0,0 ++ jne .Lloop_vstrs_nonzero_cc ++ clgrjh %r2,%r4,.Lhaystack_too_small ++ vl %v16,0(%r2) /* Next part of haystack. */ ++ clgrjle %r2,%r0,.Lloop64 ++ j .Lloop ++END(MEMMEM_ARCH13) ++ ++# if ! HAVE_MEMMEM_IFUNC ++strong_alias (MEMMEM_ARCH13, __memmem) ++weak_alias (__memmem, memmem) ++# endif ++ ++# if MEMMEM_Z13_ONLY_USED_AS_FALLBACK && defined SHARED && IS_IN (libc) ++weak_alias (MEMMEM_ARCH13, __GI_memmem) ++strong_alias (MEMMEM_ARCH13, __GI___memmem) ++# endif ++#endif +diff --git a/sysdeps/s390/memmem-vx.c b/sysdeps/s390/memmem-vx.c +index af6e200e4e0af1a5..e5608be77f05f2a9 100644 +--- a/sysdeps/s390/memmem-vx.c ++++ b/sysdeps/s390/memmem-vx.c +@@ -20,7 +20,7 @@ + + #if HAVE_MEMMEM_Z13 + # include +-# if HAVE_MEMMEM_IFUNC ++# if HAVE_MEMMEM_IFUNC || MEMMEM_Z13_ONLY_USED_AS_FALLBACK + + # ifndef _LIBC + # define memmem MEMMEM_Z13 +@@ -32,7 +32,7 @@ + # undef libc_hidden_def + # undef libc_hidden_weak + +-# if HAVE_MEMMEM_C ++# if HAVE_MEMMEM_C || MEMMEM_Z13_ONLY_USED_AS_FALLBACK + # define libc_hidden_def(name) + # define libc_hidden_weak(name) + # else +diff --git a/sysdeps/s390/memmem.c b/sysdeps/s390/memmem.c +index 8c50b3f403eb8d1f..28871cd4b24868cc 100644 +--- a/sysdeps/s390/memmem.c ++++ b/sysdeps/s390/memmem.c +@@ -34,8 +34,14 @@ extern __typeof (__redirect_memmem) MEMMEM_C attribute_hidden; + extern __typeof (__redirect_memmem) MEMMEM_Z13 attribute_hidden; + # endif + ++# if HAVE_MEMMEM_ARCH13 ++extern __typeof (__redirect_memmem) MEMMEM_ARCH13 attribute_hidden; ++# endif ++ + s390_libc_ifunc_expr (__redirect_memmem, __memmem, +- (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX)) ++ (HAVE_MEMMEM_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)) ++ ? MEMMEM_ARCH13 ++ : (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX)) + ? MEMMEM_Z13 + : MEMMEM_DEFAULT + ) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 67a6a9c94afccd48..787d40688f4110ff 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -202,6 +202,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + #if HAVE_MEMMEM_IFUNC + IFUNC_IMPL (i, name, memmem, ++# if HAVE_MEMMEM_ARCH13 ++ IFUNC_IMPL_ADD (array, i, memmem, ++ dl_hwcap & HWCAP_S390_VXRS_EXT2, MEMMEM_ARCH13) ++# endif + # if HAVE_MEMMEM_Z13 + IFUNC_IMPL_ADD (array, i, memmem, + dl_hwcap & HWCAP_S390_VX, MEMMEM_Z13) diff --git a/SOURCES/glibc-rh1659438-7.patch b/SOURCES/glibc-rh1659438-7.patch new file mode 100644 index 0000000..bad570b --- /dev/null +++ b/SOURCES/glibc-rh1659438-7.patch @@ -0,0 +1,503 @@ +commit b7e024a838452a85870256d8f1ab946dc8f931cd +Author: Stefan Liebler +Date: Tue Dec 18 13:57:05 2018 +0100 + + S390: Refactor memcmp ifunc handling. + + This patch moves all ifunc variants for memcmp + to sysdeps/s390/memcmp-z900.S. The configure-check/preprocessor logic + in sysdeps/s390/ifunc-memcmp.h decides if ifunc is needed at all + and which ifunc variants should be available. + E.g. if the compiler/assembler already supports z196 by default, + the older ifunc variants are not included. + If we only need the newest ifunc variant, + then we can skip ifunc at all. + + Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted + in order to handle only the available ifunc variants. + + ChangeLog: + + * sysdeps/s390/ifunc-memcmp.h: New File. + * sysdeps/s390/memcmp.S: Move to ... + * sysdeps/s390/memcmp-z900.S ... here. + Move implementations from memcmp-s390x.s to here. + * sysdeps/s390/multiarch/memcmp-s390x.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): + Remove memcmp variants. + * sysdeps/s390/Makefile (sysdep_routines): + Add memcmp variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Adjust ifunc variants for + memcmp. + * sysdeps/s390/multiarch/memcmp.c: Move ifunc resolver + to ... + * sysdeps/s390/memcmp.c: ... here. + Adjust ifunc variants for memcmp. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index e40e5bd982e54d89..c59cbdc25aad408a 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -31,5 +31,6 @@ sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules + endif + + ifeq ($(subdir),string) +-sysdep_routines += bzero memset memset-z900 ++sysdep_routines += bzero memset memset-z900 \ ++ memcmp memcmp-z900 + endif +diff --git a/sysdeps/s390/ifunc-memcmp.h b/sysdeps/s390/ifunc-memcmp.h +new file mode 100644 +index 0000000000000000..536ac455d177c027 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memcmp.h +@@ -0,0 +1,59 @@ ++/* memcmp variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCMP_IFUNC 1 ++#else ++# define HAVE_MEMCMP_IFUNC 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define MEMCMP_DEFAULT MEMCMP_Z196 ++# define HAVE_MEMCMP_Z900_G5 0 ++# define HAVE_MEMCMP_Z10 0 ++# define HAVE_MEMCMP_Z196 1 ++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++# define MEMCMP_DEFAULT MEMCMP_Z10 ++# define HAVE_MEMCMP_Z900_G5 0 ++# define HAVE_MEMCMP_Z10 1 ++# define HAVE_MEMCMP_Z196 HAVE_MEMCMP_IFUNC ++#else ++# define MEMCMP_DEFAULT MEMCMP_Z900_G5 ++# define HAVE_MEMCMP_Z900_G5 1 ++# define HAVE_MEMCMP_Z10 HAVE_MEMCMP_IFUNC ++# define HAVE_MEMCMP_Z196 HAVE_MEMCMP_IFUNC ++#endif ++ ++#if HAVE_MEMCMP_Z900_G5 ++# define MEMCMP_Z900_G5 __memcmp_default ++#else ++# define MEMCMP_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMCMP_Z10 ++# define MEMCMP_Z10 __memcmp_z10 ++#else ++# define MEMCMP_Z10 NULL ++#endif ++ ++#if HAVE_MEMCMP_Z196 ++# define MEMCMP_Z196 __memcmp_z196 ++#else ++# define MEMCMP_Z196 NULL ++#endif +diff --git a/sysdeps/s390/multiarch/memcmp-s390x.S b/sysdeps/s390/memcmp-z900.S +similarity index 54% +rename from sysdeps/s390/multiarch/memcmp-s390x.S +rename to sysdeps/s390/memcmp-z900.S +index 6321737acec821ec..c3b3677ba78264ee 100644 +--- a/sysdeps/s390/multiarch/memcmp-s390x.S ++++ b/sysdeps/s390/memcmp-z900.S +@@ -1,4 +1,4 @@ +-/* CPU specific memcmp implementations. 31/64 bit S/390 version. ++/* memcmp - compare two memory blocks. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -17,8 +17,9 @@ + . */ + + +-#include "sysdep.h" ++#include + #include "asm-syntax.h" ++#include + + /* INPUT PARAMETERS + %r2 = address of first memory area +@@ -27,46 +28,67 @@ + + .text + +-#if IS_IN (libc) +- +-ENTRY(__memcmp_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 ++#if HAVE_MEMCMP_Z900_G5 ++# if defined __s390x__ ++# define LTGR ltgr ++# define AGHI aghi ++# define BRCTG brctg ++# else ++# define LTGR ltr ++# define AGHI ahi ++# define BRCTG brct ++# endif /* ! defined __s390x__ */ ++ENTRY(MEMCMP_Z900_G5) ++# if defined __s390x__ ++ .machine "z900" ++# else ++ .machine "g5" ++ basr %r5,0 ++.L_Z900_G5_16: ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16 ++# endif /* ! defined __s390x__ */ ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 ++ AGHI %r4,-1 ++# if defined __s390x__ + srlg %r1,%r4,8 +- ltgr %r1,%r1 +- jne .L_Z196_2 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: ++ larl %r5,.L_Z900_G5_15 ++# define Z900_G5_EX_D 0 ++# else ++ lr %r1,%r4 ++ srl %r1,8 ++# endif /* ! defined __s390x__ */ ++ LTGR %r1,%r1 ++ jne .L_Z900_G5_12 ++.L_Z900_G5_3: ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + ipm %r2 ++# if defined __s390x__ + sllg %r2,%r2,34 + srag %r2,%r2,62 ++# else ++ sll %r2,2 ++ sra %r2,30 ++# endif /* ! defined __s390x__ */ + br %r14 +-.L_Z196_17: ++.L_Z900_G5_12: ++ clc 0(256,%r3),0(%r2) ++ jne .L_Z900_G5_4 + la %r3,256(%r3) + la %r2,256(%r2) +- aghi %r1,-1 +- je .L_Z196_3 +-.L_Z196_2: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- je .L_Z196_17 +- ipm %r2 +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +- br %r14 +-.L_Z196_14: ++ BRCTG %r1,.L_Z900_G5_12 ++ j .L_Z900_G5_3 ++.L_Z900_G5_15: + clc 0(1,%r3),0(%r2) +-END(__memcmp_z196) ++END(MEMCMP_Z900_G5) ++# undef LTGR ++# undef AGHI ++# undef BRCTG ++#endif /* HAVE_MEMCMP_Z900_G5 */ + +-ENTRY(__memcmp_z10) ++#if HAVE_MEMCMP_Z10 ++ENTRY(MEMCMP_Z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + # if !defined __s390x__ +@@ -95,18 +117,57 @@ ENTRY(__memcmp_z10) + j .L_Z10_3 + .L_Z10_15: + clc 0(1,%r3),0(%r2) +-END(__memcmp_z10) ++END(MEMCMP_Z10) ++#endif /* HAVE_MEMCMP_Z10 */ + +-#endif /* IS_IN (libc) */ ++#if HAVE_MEMCMP_Z196 ++ENTRY(MEMCMP_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ aghi %r4,-1 ++ srlg %r1,%r4,8 ++ ltgr %r1,%r1 ++ jne .L_Z196_2 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 ++.L_Z196_17: ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ aghi %r1,-1 ++ je .L_Z196_3 ++.L_Z196_2: ++ pfd 1,512(%r3) ++ pfd 1,512(%r2) ++ clc 0(256,%r3),0(%r2) ++ je .L_Z196_17 ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 ++.L_Z196_14: ++ clc 0(1,%r3),0(%r2) ++END(MEMCMP_Z196) ++#endif /* HAVE_MEMCMP_Z196 */ + +-#include "../memcmp.S" ++#if ! HAVE_MEMCMP_IFUNC ++/* If we don't use ifunc, define an alias for memcmp here. ++ Otherwise see sysdeps/s390/memcmp.c. */ ++strong_alias (MEMCMP_DEFAULT, memcmp) ++weak_alias (memcmp, bcmp) ++#endif + +-#if !IS_IN (libc) +-.globl memcmp +-.set memcmp,__memcmp_default +-.weak bcmp +-.set bcmp,__memcmp_default +-#elif defined SHARED && IS_IN (libc) +-.globl __GI_memcmp +-.set __GI_memcmp,__memcmp_default ++#if defined SHARED && IS_IN (libc) ++/* Defines the internal symbols. ++ Compare to libc_hidden_builtin_def (memcmp) in string/memcmp.c. */ ++strong_alias (MEMCMP_DEFAULT, __GI_memcmp) + #endif +diff --git a/sysdeps/s390/memcmp.S b/sysdeps/s390/memcmp.S +deleted file mode 100644 +index 751293a99e34f530..0000000000000000 +--- a/sysdeps/s390/memcmp.S ++++ /dev/null +@@ -1,96 +0,0 @@ +-/* memcmp - compare two memory blocks. 31/64 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +-#if defined __s390x__ +-# define LTGR ltgr +-# define AGHI aghi +-# define BRCTG brctg +-#else +-# define LTGR ltr +-# define AGHI ahi +-# define BRCTG brct +-#endif /* ! defined __s390x__ */ +- +-#ifdef USE_MULTIARCH +-ENTRY(__memcmp_default) +-#else +-ENTRY(memcmp) +-#endif +-#if defined __s390x__ +- .machine "z900" +-#else +- .machine "g5" +- basr %r5,0 +-.L_Z900_G5_16: +-# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_16 +-#endif /* ! defined __s390x__ */ +- LTGR %r4,%r4 +- je .L_Z900_G5_4 +- AGHI %r4,-1 +-#if defined __s390x__ +- srlg %r1,%r4,8 +- larl %r5,.L_Z900_G5_15 +-# define Z900_G5_EX_D 0 +-#else +- lr %r1,%r4 +- srl %r1,8 +-#endif /* ! defined __s390x__ */ +- LTGR %r1,%r1 +- jne .L_Z900_G5_12 +-.L_Z900_G5_3: +- ex %r4,Z900_G5_EX_D(%r5) +-.L_Z900_G5_4: +- ipm %r2 +-#if defined __s390x__ +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +-#else +- sll %r2,2 +- sra %r2,30 +-#endif /* ! defined __s390x__ */ +- br %r14 +-.L_Z900_G5_12: +- clc 0(256,%r3),0(%r2) +- jne .L_Z900_G5_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- BRCTG %r1,.L_Z900_G5_12 +- j .L_Z900_G5_3 +-.L_Z900_G5_15: +- clc 0(1,%r3),0(%r2) +-#ifdef USE_MULTIARCH +-END(__memcmp_default) +-#else +-END(memcmp) +-libc_hidden_builtin_def (memcmp) +-weak_alias (memcmp, bcmp) +-#endif +- +-#undef LTGR +-#undef AGHI +-#undef BRCTG +diff --git a/sysdeps/s390/multiarch/memcmp.c b/sysdeps/s390/memcmp.c +similarity index 60% +rename from sysdeps/s390/multiarch/memcmp.c +rename to sysdeps/s390/memcmp.c +index 1e6f31806e172d7d..952ff6af7364fd92 100644 +--- a/sysdeps/s390/multiarch/memcmp.c ++++ b/sysdeps/s390/memcmp.c +@@ -16,12 +16,34 @@ + License along with the GNU C Library; if not, see + . */ + +-#if IS_IN (libc) ++#include ++#if HAVE_MEMCMP_IFUNC + # define memcmp __redirect_memcmp + # include + # undef memcmp + # include + +-s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp) ++# if HAVE_MEMCMP_Z900_G5 ++extern __typeof (__redirect_memcmp) MEMCMP_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCMP_Z10 ++extern __typeof (__redirect_memcmp) MEMCMP_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCMP_Z196 ++extern __typeof (__redirect_memcmp) MEMCMP_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memcmp, memcmp, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMCMP_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMCMP_Z196 ++ : (HAVE_MEMCMP_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMCMP_Z10 ++ : MEMCMP_DEFAULT; ++ }) ++ ) + weak_alias (memcmp, bcmp); + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 53dd8654d73677db..c893ebc5659fd4ae 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,8 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy \ +- memcmp memcmp-s390x ++ mempcpy + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 253f36045b57cc3c..2e57d01abc21522e 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -78,12 +79,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMSET_IFUNC */ + ++#if HAVE_MEMCMP_IFUNC + IFUNC_IMPL (i, name, memcmp, ++# if HAVE_MEMCMP_Z196 + IFUNC_IMPL_ADD (array, i, memcmp, +- S390_IS_Z196 (stfle_bits), __memcmp_z196) ++ S390_IS_Z196 (stfle_bits), MEMCMP_Z196) ++# endif ++# if HAVE_MEMCMP_Z10 + IFUNC_IMPL_ADD (array, i, memcmp, +- S390_IS_Z10 (stfle_bits), __memcmp_z10) +- IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_default)) ++ S390_IS_Z10 (stfle_bits), MEMCMP_Z10) ++# endif ++# if HAVE_MEMCMP_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memcmp, 1, MEMCMP_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMCMP_IFUNC */ + + #ifdef SHARED + diff --git a/SOURCES/glibc-rh1659438-8.patch b/SOURCES/glibc-rh1659438-8.patch new file mode 100644 index 0000000..464f5d2 --- /dev/null +++ b/SOURCES/glibc-rh1659438-8.patch @@ -0,0 +1,538 @@ +commit df3eb8de31a530f285f54f3c41cd7b636816c062 +Author: Stefan Liebler +Date: Tue Dec 18 13:57:06 2018 +0100 + + S390: Unify 31/64bit memcpy. + + The implementation of memcpy/mempcpy for s390-32 (31bit) + and s390-64 (64bit) is nearly the same. + This patch unifies it for maintability reasons. + + __mem[p]cpy_z10 and __mem[p]cpy_z196 differs between 31 and 64bit: + -31bit needs .machinemode "zarch_nohighgprs" and llgfr %r4,%r4 + -lr vs lgr; lgr can be also used on 31bit as this ifunc variant + is only called if we are on a zarch machine. + + __mem[p]cpy_default differs between 31 and 64bit: + -Some 31bit vs 64bit instructions (e.g. ltr vs ltgr. + Solved with 31/64 specific instruction macros). + -The address of mvc instruction is setup in different ways + (larl vs bras). Solved with #if defined __s390x__. + + __memcpy_mvcle differs between 31 and 64bit: + -lr vs lgr; ahi vs aghi; + Solved with 31/64bit specific instruction macros. + + Otherwise 31/64bit implementation has the same structure of the code. + + ChangeLog: + + * sysdeps/s390/s390-64/memcpy.S: Move to ... + * sysdeps/s390/memcpy.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/memcpy.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memcpy. + * sysdeps/s390/s390-32/multiarch/Makefile: Delete file. + * sysdeps/s390/s390-64/multiarch/Makefile: Likewise. + * sysdeps/s390/s390-64/multiarch/memcpy-s390x.S: Move to ... + * sysdeps/s390/multiarch/memcpy-s390x.S: ... here. + Adjust to be usable for 31/64bit. + * sysdeps/s390/s390-32/multiarch/memcpy-s390.S: Delete File. + * sysdeps/s390/s390-64/multiarch/memcpy.c: Move to ... + * sysdeps/s390/multiarch/memcpy.c: ... here. + * sysdeps/s390/s390-32/multiarch/memcpy.c: Delete File. + +diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/memcpy.S +similarity index 52% +rename from sysdeps/s390/s390-64/memcpy.S +rename to sysdeps/s390/memcpy.S +index 2e5490df23d64325..2a6c6b750377c7bb 100644 +--- a/sysdeps/s390/s390-64/memcpy.S ++++ b/sysdeps/s390/memcpy.S +@@ -1,4 +1,4 @@ +-/* memcpy - copy a block from source to destination. 64 bit S/390 version. ++/* memcpy - copy a block from source to destination. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -25,13 +25,31 @@ + %r3 = address of source memory area + %r4 = number of bytes to copy. */ + +- + .text ++ ++#if defined __s390x__ ++# define LTGR ltgr ++# define CGHI cghi ++# define LGR lgr ++# define AGHI aghi ++# define BRCTG brctg ++#else ++# define LTGR ltr ++# define CGHI chi ++# define LGR lr ++# define AGHI ahi ++# define BRCTG brct ++#endif /* ! defined __s390x__ */ ++ + ENTRY(__mempcpy) ++#if defined __s390x__ + .machine "z900" +- lgr %r1,%r2 # Use as dest ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LGR %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z900_start ++ j .L_Z900_G5_start + END(__mempcpy) + #ifndef USE_MULTIARCH + libc_hidden_def (__mempcpy) +@@ -40,30 +58,46 @@ libc_hidden_builtin_def (mempcpy) + #endif + + ENTRY(memcpy) ++#if defined __s390x__ + .machine "z900" +- lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z900_start: +- ltgr %r4,%r4 +- je .L_Z900_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z900_13 +-.L_Z900_3: +- larl %r5,.L_Z900_15 +- ex %r4,0(%r5) +-.L_Z900_4: ++#else ++ .machine "g5" ++#endif /* ! defined __s390x__ */ ++ LGR %r1,%r2 # r1: Use as dest ; r2: Return dest ++.L_Z900_G5_start: ++ LTGR %r4,%r4 ++ je .L_Z900_G5_4 ++ AGHI %r4,-1 ++#if defined __s390x__ ++ srlg %r5,%r4,8 ++#else ++ lr %r5,%r4 ++ srl %r5,8 ++#endif /* ! defined __s390x__ */ ++ LTGR %r5,%r5 ++ jne .L_Z900_G5_13 ++.L_Z900_G5_3: ++#if defined __s390x__ ++ larl %r5,.L_Z900_G5_15 ++# define Z900_G5_EX_D 0 ++#else ++ basr %r5,0 ++.L_Z900_G5_14: ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14 ++#endif /* ! defined __s390x__ */ ++ ex %r4,Z900_G5_EX_D(%r5) ++.L_Z900_G5_4: + br %r14 +-.L_Z900_13: +- cghi %r5,4096 # Switch to mvcle for copies >1MB ++.L_Z900_G5_13: ++ CGHI %r5,4096 # Switch to mvcle for copies >1MB + jh __memcpy_mvcle +-.L_Z900_12: ++.L_Z900_G5_12: + mvc 0(256,%r1),0(%r3) + la %r1,256(%r1) + la %r3,256(%r3) +- brctg %r5,.L_Z900_12 +- j .L_Z900_3 +-.L_Z900_15: ++ BRCTG %r5,.L_Z900_G5_12 ++ j .L_Z900_G5_3 ++.L_Z900_G5_15: + mvc 0(1,%r1),0(%r3) + END(memcpy) + #ifndef USE_MULTIARCH +@@ -74,15 +108,21 @@ ENTRY(__memcpy_mvcle) + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. +- lgr %r0,%r2 # backup return dest [ + n ] +- aghi %r4,1 # length + 1 +- lgr %r5,%r4 # source length +- lgr %r4,%r3 # source address +- lgr %r2,%r1 # destination address +- lgr %r3,%r5 # destination length = source length ++ LGR %r0,%r2 # backup return dest [ + n ] ++ AGHI %r4,1 # length + 1 ++ LGR %r5,%r4 # source length ++ LGR %r4,%r3 # source address ++ LGR %r2,%r1 # destination address ++ LGR %r3,%r5 # destination length = source length + .L_MVCLE_1: + mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L_MVCLE_1 +- lgr %r2,%r0 # return destination address ++ LGR %r2,%r0 # return destination address + br %r14 + END(__memcpy_mvcle) ++ ++#undef LTGR ++#undef CGHI ++#undef LGR ++#undef AGHI ++#undef BRCTG +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index c893ebc5659fd4ae..3cbd5fad69e355a5 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -19,7 +19,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ +- mempcpy ++ mempcpy memcpy memcpy-s390x + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/sysdeps/s390/multiarch/memcpy-s390x.S +similarity index 89% +rename from sysdeps/s390/s390-64/multiarch/memcpy-s390x.S +rename to sysdeps/s390/multiarch/memcpy-s390x.S +index 6d60a70834c32120..b38caac72b8742e6 100644 +--- a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S ++++ b/sysdeps/s390/multiarch/memcpy-s390x.S +@@ -1,4 +1,4 @@ +-/* CPU specific memcpy implementations. 64 bit S/390 version. ++/* CPU specific memcpy implementations. 31/64 bit S/390 version. + Copyright (C) 2012-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -31,6 +31,7 @@ + + ENTRY(____mempcpy_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z196_start +@@ -38,8 +39,12 @@ END(____mempcpy_z196) + + ENTRY(__memcpy_z196) + .machine "z196" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest + .L_Z196_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + ltgr %r4,%r4 + je .L_Z196_4 + aghi %r4,-1 +@@ -68,6 +73,7 @@ END(__memcpy_z196) + + ENTRY(____mempcpy_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z10_start +@@ -75,8 +81,12 @@ END(____mempcpy_z10) + + ENTRY(__memcpy_z10) + .machine "z10" ++ .machinemode "zarch_nohighgprs" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest + .L_Z10_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ + cgije %r4,0,.L_Z10_4 + aghi %r4,-1 + srlg %r5,%r4,8 +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/multiarch/memcpy.c +similarity index 100% +rename from sysdeps/s390/s390-32/multiarch/memcpy.c +rename to sysdeps/s390/multiarch/memcpy.c +diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S +deleted file mode 100644 +index 493cc18aba67d6ec..0000000000000000 +--- a/sysdeps/s390/s390-32/memcpy.S ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* memcpy - copy a block from source to destination. S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of destination memory area +- %r3 = address of source memory area +- %r4 = number of bytes to copy. */ +- +- .text +-ENTRY(__mempcpy) +- .machine "g5" +- lr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_G5_start +-END(__mempcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_def (__mempcpy) +-weak_alias (__mempcpy, mempcpy) +-libc_hidden_builtin_def (mempcpy) +-#endif +- +-ENTRY(memcpy) +- .machine "g5" +- lr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_G5_start: +- ltr %r4,%r4 +- je .L_G5_99 +- ahi %r4,-1 +- lr %r5,%r4 +- srl %r5,8 +- ltr %r5,%r5 +- jne .L_G5_13 +-.L_G5_4: +- basr %r5,0 +-.L_G5_16: +- ex %r4,.L_G5_17-.L_G5_16(%r5) +-.L_G5_99: +- br %r14 +-.L_G5_13: +- chi %r5,4096 # Switch to mvcle for copies >1MB +- jh __memcpy_mvcle +-.L_G5_12: +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brct %r5,.L_G5_12 +- j .L_G5_4 +-.L_G5_17: +- mvc 0(1,%r1),0(%r3) +-END(memcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_builtin_def (memcpy) +-#endif +- +-ENTRY(__memcpy_mvcle) +- # Using as standalone function will result in unexpected +- # results since the length field is incremented by 1 in order to +- # compensate the changes already done in the functions above. +- lr %r0,%r2 # backup return dest [ + n ] +- ahi %r4,1 # length + 1 +- lr %r5,%r4 # source length +- lr %r4,%r3 # source address +- lr %r2,%r1 # destination address +- lr %r3,%r5 # destination length = source length +-.L_MVCLE_1: +- mvcle %r2,%r4,0 # thats it, MVCLE is your friend +- jo .L_MVCLE_1 +- lr %r2,%r0 # return destination address +- br %r14 +-END(__memcpy_mvcle) +diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile +deleted file mode 100644 +index 82a7492eb8436479..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/Makefile ++++ /dev/null +@@ -1,3 +0,0 @@ +-ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390 +-endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S +deleted file mode 100644 +index aad13bd07c31dab9..0000000000000000 +--- a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S ++++ /dev/null +@@ -1,128 +0,0 @@ +-/* CPU specific memcpy implementations. 32 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = target operands address +- %r3 = source operands address +- %r4 = number of bytes to copy. */ +- +- .text +- +-#if defined SHARED && IS_IN (libc) +- +-ENTRY(____mempcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z196_start +-END(____mempcpy_z196) +- +-ENTRY(__memcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z196_start: +- llgfr %r4,%r4 +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_5 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- br %r14 +-.L_Z196_5: +- cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh __memcpy_mvcle +-.L_Z196_2: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- aghi %r5,-1 +- la %r1,256(%r1) +- la %r3,256(%r3) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_14: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z196) +- +-ENTRY(____mempcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z10_start +-END(____mempcpy_z10) +- +-ENTRY(__memcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z10_start: +- llgfr %r4,%r4 +- cgije %r4,0,.L_Z10_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_13 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- br %r14 +-.L_Z10_13: +- cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh __memcpy_mvcle +-.L_Z10_12: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brctg %r5,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z10) +- +-# define __mempcpy ____mempcpy_default +-#endif /* SHARED && IS_IN (libc) */ +- +-#define memcpy __memcpy_default +-#include "../memcpy.S" +-#undef memcpy +- +-#if defined SHARED && IS_IN (libc) +-.globl __GI_memcpy +-.set __GI_memcpy,__memcpy_default +-.globl __GI_mempcpy +-.set __GI_mempcpy,____mempcpy_default +-.globl __GI___mempcpy +-.set __GI___mempcpy,____mempcpy_default +-#else +-.globl memcpy +-.set memcpy,__memcpy_default +-.weak mempcpy +-.set mempcpy,__mempcpy +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile +deleted file mode 100644 +index 8a043e3327a1527a..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/Makefile ++++ /dev/null +@@ -1,3 +0,0 @@ +-ifeq ($(subdir),string) +-sysdep_routines += memcpy memcpy-s390x +-endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c +deleted file mode 100644 +index c9577a854a0c7e68..0000000000000000 +--- a/sysdeps/s390/s390-64/multiarch/memcpy.c ++++ /dev/null +@@ -1,27 +0,0 @@ +-/* Multiple versions of memcpy. +- Copyright (C) 2015-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* In the static lib memcpy is needed before the reloc is resolved. */ +-#if defined SHARED && IS_IN (libc) +-# define memcpy __redirect_memcpy +-# include +-# undef memcpy +-# include +- +-s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy) +-#endif diff --git a/SOURCES/glibc-rh1659438-9.patch b/SOURCES/glibc-rh1659438-9.patch new file mode 100644 index 0000000..d3387ca --- /dev/null +++ b/SOURCES/glibc-rh1659438-9.patch @@ -0,0 +1,656 @@ +commit 18eb862d454a41012ccdd5127715ef7cd2a711ec +Author: Stefan Liebler +Date: Tue Dec 18 13:57:06 2018 +0100 + + S390: Refactor memcpy/mempcpy ifunc handling. + + This patch moves all ifunc variants for memcpy/mempcpy + to sysdeps/s390/memcpy-z900.S. The configure-check/preprocessor logic + in sysdeps/s390/ifunc-memcpy.h decides if ifunc is needed at all + and which ifunc variants should be available. + E.g. if the compiler/assembler already supports z196 by default, + the older ifunc variants are not included. + If we only need the newest ifunc variant, + then we can skip ifunc at all. + + Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted + in order to handle only the available ifunc variants. + + ChangeLog: + + * sysdeps/s390/ifunc-memcpy.h: New File. + * sysdeps/s390/memcpy.S: Move to ... + * sysdeps/s390/memcpy-z900.S ... here. + Move implementations from memcpy-s390x.s to here. + * sysdeps/s390/multiarch/memcpy-s390x.S: Delete File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): + Remove memcpy/mempcpy variants. + * sysdeps/s390/Makefile (sysdep_routines): + Add memcpy/mempcpy variants. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Adjust ifunc variants for + memcpy and mempcpy. + * sysdeps/s390/multiarch/memcpy.c: Move ifunc resolver + to ... + * sysdeps/s390/memcpy.c: ... here. + Adjust ifunc variants for memcpy. + * sysdeps/s390/multiarch/mempcpy.c: Move to ... + * sysdeps/s390/mempcpy.c: ... here. + Adjust ifunc variants for mempcpy. + * sysdeps/s390/mempcpy.S: Delete file. + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +index c59cbdc25aad408a..838950a5ab958e31 100644 +--- a/sysdeps/s390/Makefile ++++ b/sysdeps/s390/Makefile +@@ -32,5 +32,6 @@ endif + + ifeq ($(subdir),string) + sysdep_routines += bzero memset memset-z900 \ +- memcmp memcmp-z900 ++ memcmp memcmp-z900 \ ++ mempcpy memcpy memcpy-z900 + endif +diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h +new file mode 100644 +index 0000000000000000..51c71baa2c0b0452 +--- /dev/null ++++ b/sysdeps/s390/ifunc-memcpy.h +@@ -0,0 +1,68 @@ ++/* memcpy variant information on S/390 version. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc) \ ++ && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_MEMCPY_IFUNC 1 ++#else ++# define HAVE_MEMCPY_IFUNC 0 ++#endif ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define MEMCPY_DEFAULT MEMCPY_Z196 ++# define MEMPCPY_DEFAULT MEMPCPY_Z196 ++# define HAVE_MEMCPY_Z900_G5 0 ++# define HAVE_MEMCPY_Z10 0 ++# define HAVE_MEMCPY_Z196 1 ++#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT ++# define MEMCPY_DEFAULT MEMCPY_Z10 ++# define MEMPCPY_DEFAULT MEMPCPY_Z10 ++# define HAVE_MEMCPY_Z900_G5 0 ++# define HAVE_MEMCPY_Z10 1 ++# define HAVE_MEMCPY_Z196 HAVE_MEMCPY_IFUNC ++#else ++# define MEMCPY_DEFAULT MEMCPY_Z900_G5 ++# define MEMPCPY_DEFAULT MEMPCPY_Z900_G5 ++# define HAVE_MEMCPY_Z900_G5 1 ++# define HAVE_MEMCPY_Z10 HAVE_MEMCPY_IFUNC ++# define HAVE_MEMCPY_Z196 HAVE_MEMCPY_IFUNC ++#endif ++ ++#if HAVE_MEMCPY_Z900_G5 ++# define MEMCPY_Z900_G5 __memcpy_default ++# define MEMPCPY_Z900_G5 __mempcpy_default ++#else ++# define MEMCPY_Z900_G5 NULL ++# define MEMPCPY_Z900_G5 NULL ++#endif ++ ++#if HAVE_MEMCPY_Z10 ++# define MEMCPY_Z10 __memcpy_z10 ++# define MEMPCPY_Z10 __mempcpy_z10 ++#else ++# define MEMCPY_Z10 NULL ++# define MEMPCPY_Z10 NULL ++#endif ++ ++#if HAVE_MEMCPY_Z196 ++# define MEMCPY_Z196 __memcpy_z196 ++# define MEMPCPY_Z196 __mempcpy_z196 ++#else ++# define MEMCPY_Z196 NULL ++# define MEMPCPY_Z196 NULL ++#endif +diff --git a/sysdeps/s390/memcpy.S b/sysdeps/s390/memcpy-z900.S +similarity index 50% +rename from sysdeps/s390/memcpy.S +rename to sysdeps/s390/memcpy-z900.S +index 2a6c6b750377c7bb..3a50cf44d85d2417 100644 +--- a/sysdeps/s390/memcpy.S ++++ b/sysdeps/s390/memcpy-z900.S +@@ -19,6 +19,7 @@ + + #include + #include "asm-syntax.h" ++#include + + /* INPUT PARAMETERS + %r2 = address of destination memory area +@@ -41,50 +42,46 @@ + # define BRCTG brct + #endif /* ! defined __s390x__ */ + +-ENTRY(__mempcpy) +-#if defined __s390x__ ++#if HAVE_MEMCPY_Z900_G5 ++ENTRY(MEMPCPY_Z900_G5) ++# if defined __s390x__ + .machine "z900" +-#else ++# else + .machine "g5" +-#endif /* ! defined __s390x__ */ ++# endif /* ! defined __s390x__ */ + LGR %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z900_G5_start +-END(__mempcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_def (__mempcpy) +-weak_alias (__mempcpy, mempcpy) +-libc_hidden_builtin_def (mempcpy) +-#endif ++END(MEMPCPY_Z900_G5) + +-ENTRY(memcpy) +-#if defined __s390x__ ++ENTRY(MEMCPY_Z900_G5) ++# if defined __s390x__ + .machine "z900" +-#else ++# else + .machine "g5" +-#endif /* ! defined __s390x__ */ ++# endif /* ! defined __s390x__ */ + LGR %r1,%r2 # r1: Use as dest ; r2: Return dest + .L_Z900_G5_start: + LTGR %r4,%r4 + je .L_Z900_G5_4 + AGHI %r4,-1 +-#if defined __s390x__ ++# if defined __s390x__ + srlg %r5,%r4,8 +-#else ++# else + lr %r5,%r4 + srl %r5,8 +-#endif /* ! defined __s390x__ */ ++# endif /* ! defined __s390x__ */ + LTGR %r5,%r5 + jne .L_Z900_G5_13 + .L_Z900_G5_3: +-#if defined __s390x__ ++# if defined __s390x__ + larl %r5,.L_Z900_G5_15 +-# define Z900_G5_EX_D 0 +-#else ++# define Z900_G5_EX_D 0 ++# else + basr %r5,0 + .L_Z900_G5_14: +-# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14 +-#endif /* ! defined __s390x__ */ ++# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14 ++# endif /* ! defined __s390x__ */ + ex %r4,Z900_G5_EX_D(%r5) + .L_Z900_G5_4: + br %r14 +@@ -99,10 +96,8 @@ ENTRY(memcpy) + j .L_Z900_G5_3 + .L_Z900_G5_15: + mvc 0(1,%r1),0(%r3) +-END(memcpy) +-#ifndef USE_MULTIARCH +-libc_hidden_builtin_def (memcpy) +-#endif ++END(MEMCPY_Z900_G5) ++#endif /* HAVE_MEMCPY_Z900_G5 */ + + ENTRY(__memcpy_mvcle) + # Using as standalone function will result in unexpected +@@ -126,3 +121,104 @@ END(__memcpy_mvcle) + #undef LGR + #undef AGHI + #undef BRCTG ++ ++#if HAVE_MEMCPY_Z10 ++ENTRY(MEMPCPY_Z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # Use as dest ++ la %r2,0(%r4,%r2) # Return dest + n ++ j .L_Z10_start ++END(MEMPCPY_Z10) ++ ++ENTRY(MEMCPY_Z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # r1: Use as dest ; r2: Return dest ++.L_Z10_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ cgije %r4,0,.L_Z10_4 ++ aghi %r4,-1 ++ srlg %r5,%r4,8 ++ cgijlh %r5,0,.L_Z10_13 ++.L_Z10_3: ++ exrl %r4,.L_Z10_15 ++.L_Z10_4: ++ br %r14 ++.L_Z10_13: ++ cgfi %r5,65535 # Switch to mvcle for copies >16MB ++ jh __memcpy_mvcle ++.L_Z10_12: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ brctg %r5,.L_Z10_12 ++ j .L_Z10_3 ++.L_Z10_15: ++ mvc 0(1,%r1),0(%r3) ++END(MEMCPY_Z10) ++#endif /* HAVE_MEMCPY_Z10 */ ++ ++#if HAVE_MEMCPY_Z196 ++ENTRY(MEMPCPY_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # Use as dest ++ la %r2,0(%r4,%r2) # Return dest + n ++ j .L_Z196_start ++END(MEMPCPY_Z196) ++ ++ENTRY(MEMCPY_Z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ lgr %r1,%r2 # r1: Use as dest ; r2: Return dest ++.L_Z196_start: ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ aghi %r4,-1 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_5 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ br %r14 ++.L_Z196_5: ++ cgfi %r5,262144 # Switch to mvcle for copies >64MB ++ jh __memcpy_mvcle ++.L_Z196_2: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_14: ++ mvc 0(1,%r1),0(%r3) ++END(MEMCPY_Z196) ++#endif /* HAVE_MEMCPY_Z196 */ ++ ++#if ! HAVE_MEMCPY_IFUNC ++/* If we don't use ifunc, define an alias for mem[p]cpy here. ++ Otherwise see sysdeps/s390/mem[p]cpy.c. */ ++strong_alias (MEMCPY_DEFAULT, memcpy) ++strong_alias (MEMPCPY_DEFAULT, __mempcpy) ++weak_alias (__mempcpy, mempcpy) ++#endif ++ ++#if defined SHARED && IS_IN (libc) ++/* Defines the internal symbols. ++ Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c. */ ++strong_alias (MEMCPY_DEFAULT, __GI_memcpy) ++strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy) ++strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy) ++#endif +diff --git a/sysdeps/s390/multiarch/memcpy.c b/sysdeps/s390/memcpy.c +similarity index 60% +rename from sysdeps/s390/multiarch/memcpy.c +rename to sysdeps/s390/memcpy.c +index c9577a854a0c7e68..90a53ac27d4be755 100644 +--- a/sysdeps/s390/multiarch/memcpy.c ++++ b/sysdeps/s390/memcpy.c +@@ -16,12 +16,34 @@ + License along with the GNU C Library; if not, see + . */ + +-/* In the static lib memcpy is needed before the reloc is resolved. */ +-#if defined SHARED && IS_IN (libc) ++#include ++ ++#if HAVE_MEMCPY_IFUNC + # define memcpy __redirect_memcpy + # include + # undef memcpy + # include + +-s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy) ++# if HAVE_MEMCPY_Z900_G5 ++extern __typeof (__redirect_memcpy) MEMCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z10 ++extern __typeof (__redirect_memcpy) MEMCPY_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z196 ++extern __typeof (__redirect_memcpy) MEMCPY_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect_memcpy, memcpy, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMCPY_Z196 ++ : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMCPY_Z10 ++ : MEMCPY_DEFAULT; ++ }) ++ ) + #endif +diff --git a/sysdeps/s390/mempcpy.S b/sysdeps/s390/mempcpy.S +deleted file mode 100644 +index 18ef29213e26e76d..0000000000000000 +--- a/sysdeps/s390/mempcpy.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* CPU specific mempcpy without multiarch - 32/64 bit S/390 version. +- Copyright (C) 2016-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* mempcpy is implemented in memcpy.S. */ +diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/mempcpy.c +similarity index 63% +rename from sysdeps/s390/multiarch/mempcpy.c +rename to sysdeps/s390/mempcpy.c +index 363fe47aefb80978..a6a237312659c2c1 100644 +--- a/sysdeps/s390/multiarch/mempcpy.c ++++ b/sysdeps/s390/mempcpy.c +@@ -16,8 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + +-#if defined SHARED && IS_IN (libc) ++#if HAVE_MEMCPY_IFUNC + # define mempcpy __redirect_mempcpy + # define __mempcpy __redirect___mempcpy + # define __NO_STRING_INLINES +@@ -27,6 +28,27 @@ + # undef __mempcpy + # include + +-s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy) ++# if HAVE_MEMCPY_Z900_G5 ++extern __typeof (__redirect___mempcpy) MEMPCPY_Z900_G5 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z10 ++extern __typeof (__redirect___mempcpy) MEMPCPY_Z10 attribute_hidden; ++# endif ++ ++# if HAVE_MEMCPY_Z196 ++extern __typeof (__redirect___mempcpy) MEMPCPY_Z196 attribute_hidden; ++# endif ++ ++s390_libc_ifunc_expr (__redirect___mempcpy, __mempcpy, ++ ({ ++ s390_libc_ifunc_init (); ++ (HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits)) ++ ? MEMPCPY_Z196 ++ : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits)) ++ ? MEMPCPY_Z10 ++ : MEMPCPY_DEFAULT; ++ }) ++ ) + weak_alias (__mempcpy, mempcpy); + #endif +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3cbd5fad69e355a5..24949cd3a88b8015 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -18,8 +18,7 @@ sysdep_routines += strlen strlen-vx strlen-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ +- memrchr memrchr-vx memrchr-c \ +- mempcpy memcpy memcpy-s390x ++ memrchr memrchr-vx memrchr-c + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 2e57d01abc21522e..6969c480cc40e0e2 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + /* Maximum number of IFUNC implementations. */ + #define MAX_IFUNC 3 +@@ -95,23 +96,35 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + ) + #endif /* HAVE_MEMCMP_IFUNC */ + +-#ifdef SHARED +- ++#if HAVE_MEMCPY_IFUNC + IFUNC_IMPL (i, name, memcpy, ++# if HAVE_MEMCPY_Z196 + IFUNC_IMPL_ADD (array, i, memcpy, +- S390_IS_Z196 (stfle_bits), __memcpy_z196) ++ S390_IS_Z196 (stfle_bits), MEMCPY_Z196) ++# endif ++# if HAVE_MEMCPY_Z10 + IFUNC_IMPL_ADD (array, i, memcpy, +- S390_IS_Z10 (stfle_bits), __memcpy_z10) +- IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default)) ++ S390_IS_Z10 (stfle_bits), MEMCPY_Z10) ++# endif ++# if HAVE_MEMCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, memcpy, 1, MEMCPY_Z900_G5) ++# endif ++ ) + + IFUNC_IMPL (i, name, mempcpy, ++# if HAVE_MEMCPY_Z196 + IFUNC_IMPL_ADD (array, i, mempcpy, +- S390_IS_Z196 (stfle_bits), ____mempcpy_z196) ++ S390_IS_Z196 (stfle_bits), MEMPCPY_Z196) ++# endif ++# if HAVE_MEMCPY_Z10 + IFUNC_IMPL_ADD (array, i, mempcpy, +- S390_IS_Z10 (stfle_bits), ____mempcpy_z10) +- IFUNC_IMPL_ADD (array, i, mempcpy, 1, ____mempcpy_default)) +- +-#endif /* SHARED */ ++ S390_IS_Z10 (stfle_bits), MEMPCPY_Z10) ++# endif ++# if HAVE_MEMCPY_Z900_G5 ++ IFUNC_IMPL_ADD (array, i, mempcpy, 1, MEMPCPY_Z900_G5) ++# endif ++ ) ++#endif /* HAVE_MEMCPY_IFUNC */ + + #ifdef HAVE_S390_VX_ASM_SUPPORT + +diff --git a/sysdeps/s390/multiarch/memcpy-s390x.S b/sysdeps/s390/multiarch/memcpy-s390x.S +deleted file mode 100644 +index b38caac72b8742e6..0000000000000000 +--- a/sysdeps/s390/multiarch/memcpy-s390x.S ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* CPU specific memcpy implementations. 31/64 bit S/390 version. +- Copyright (C) 2012-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = target operands address +- %r3 = source operands address +- %r4 = number of bytes to copy. */ +- +- .text +- +-#if defined SHARED && IS_IN (libc) +- +-ENTRY(____mempcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z196_start +-END(____mempcpy_z196) +- +-ENTRY(__memcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z196_start: +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_5 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- br %r14 +-.L_Z196_5: +- cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh __memcpy_mvcle +-.L_Z196_2: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- aghi %r5,-1 +- la %r1,256(%r1) +- la %r3,256(%r3) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_14: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z196) +- +-ENTRY(____mempcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # Use as dest +- la %r2,0(%r4,%r2) # Return dest + n +- j .L_Z10_start +-END(____mempcpy_z10) +- +-ENTRY(__memcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +-.L_Z10_start: +-# if !defined __s390x__ +- llgfr %r4,%r4 +-# endif /* !defined __s390x__ */ +- cgije %r4,0,.L_Z10_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_13 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- br %r14 +-.L_Z10_13: +- cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh __memcpy_mvcle +-.L_Z10_12: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brctg %r5,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z10) +- +-# define __mempcpy ____mempcpy_default +-#endif /* SHARED && IS_IN (libc) */ +- +-#define memcpy __memcpy_default +-#include "../memcpy.S" +-#undef memcpy +- +-#if defined SHARED && IS_IN (libc) +-.globl __GI_memcpy +-.set __GI_memcpy,__memcpy_default +-.globl __GI_mempcpy +-.set __GI_mempcpy,____mempcpy_default +-.globl __GI___mempcpy +-.set __GI___mempcpy,____mempcpy_default +-#else +-.globl memcpy +-.set memcpy,__memcpy_default +-.weak mempcpy +-.set mempcpy,__mempcpy +-#endif diff --git a/SOURCES/glibc-rh1659512-1.patch b/SOURCES/glibc-rh1659512-1.patch new file mode 100644 index 0000000..71956e9 --- /dev/null +++ b/SOURCES/glibc-rh1659512-1.patch @@ -0,0 +1,312 @@ +commit c70271662aa53aee0c4794d480dca6d9ba3ccc3d +Author: Adhemerval Zanella +Date: Wed Sep 19 11:12:05 2018 -0700 + + Use libsupport for tst-spawn.c + + No function changes is done. Checked on x86_64-linux-gnu. + + * posix/tst-spawn.c (do_prepare, handle_restart, do_test): + Use libsupport. + +diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c +index 7c785c430c..41f1a65243 100644 +--- a/posix/tst-spawn.c ++++ b/posix/tst-spawn.c +@@ -17,16 +17,20 @@ + License along with the GNU C Library; if not, see + . */ + ++#include ++#include + #include + #include + #include + #include + #include + #include +-#include + #include ++ + #include + #include ++#include ++#include + + + /* Nonzero if the program gets called via `exec'. */ +@@ -36,16 +40,6 @@ static int restart; + #define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +-/* Prototype for our test function. */ +-extern void do_prepare (int argc, char *argv[]); +-extern int do_test (int argc, char *argv[]); +- +-/* We have a preparation function. */ +-#define PREPARE do_prepare +- +-#include "../test-skeleton.c" +- +- + /* Name of the temporary files. */ + static char *name1; + static char *name2; +@@ -63,19 +57,18 @@ static const char fd3string[] = "This file will be opened"; + + + /* We have a preparation function. */ +-void ++static void + do_prepare (int argc, char *argv[]) + { + /* We must not open any files in the restart case. */ + if (restart) + return; + +- temp_fd1 = create_temp_file ("spawn", &name1); +- temp_fd2 = create_temp_file ("spawn", &name2); +- temp_fd3 = create_temp_file ("spawn", &name3); +- if (temp_fd1 < 0 || temp_fd2 < 0 || temp_fd3 < 0) +- exit (1); ++ TEST_VERIFY_EXIT ((temp_fd1 = create_temp_file ("spawn", &name1)) != -1); ++ TEST_VERIFY_EXIT ((temp_fd2 = create_temp_file ("spawn", &name2)) != -1); ++ TEST_VERIFY_EXIT ((temp_fd3 = create_temp_file ("spawn", &name3)) != -1); + } ++#define PREPARE do_prepare + + + static int +@@ -95,64 +88,45 @@ handle_restart (const char *fd1s, const char *fd2s, const char *fd3s, + fd4 = atol (fd4s); + + /* Sanity check. */ +- if (fd1 == fd2) +- error (EXIT_FAILURE, 0, "value of fd1 and fd2 is the same"); +- if (fd1 == fd3) +- error (EXIT_FAILURE, 0, "value of fd1 and fd3 is the same"); +- if (fd1 == fd4) +- error (EXIT_FAILURE, 0, "value of fd1 and fd4 is the same"); +- if (fd2 == fd3) +- error (EXIT_FAILURE, 0, "value of fd2 and fd3 is the same"); +- if (fd2 == fd4) +- error (EXIT_FAILURE, 0, "value of fd2 and fd4 is the same"); +- if (fd3 == fd4) +- error (EXIT_FAILURE, 0, "value of fd3 and fd4 is the same"); ++ TEST_VERIFY_EXIT (fd1 != fd2); ++ TEST_VERIFY_EXIT (fd1 != fd3); ++ TEST_VERIFY_EXIT (fd1 != fd4); ++ TEST_VERIFY_EXIT (fd2 != fd3); ++ TEST_VERIFY_EXIT (fd2 != fd4); ++ TEST_VERIFY_EXIT (fd3 != fd4); + + /* First the easy part: read from the file descriptor which is + supposed to be open. */ +- if (lseek (fd2, 0, SEEK_CUR) != strlen (fd2string)) +- error (EXIT_FAILURE, errno, "file 2 not in right position"); ++ TEST_COMPARE (xlseek (fd2, 0, SEEK_CUR), strlen (fd2string)); + /* The duped descriptor must have the same position. */ +- if (lseek (fd4, 0, SEEK_CUR) != strlen (fd2string)) +- error (EXIT_FAILURE, errno, "file 4 not in right position"); +- if (lseek (fd2, 0, SEEK_SET) != 0) +- error (EXIT_FAILURE, 0, "cannot reset position in file 2"); +- if (lseek (fd4, 0, SEEK_CUR) != 0) +- error (EXIT_FAILURE, errno, "file 4 not set back, too"); +- if (read (fd2, buf, sizeof buf) != strlen (fd2string)) +- error (EXIT_FAILURE, 0, "cannot read file 2"); +- if (memcmp (fd2string, buf, strlen (fd2string)) != 0) +- error (EXIT_FAILURE, 0, "file 2 does not match"); ++ TEST_COMPARE (xlseek (fd4, 0, SEEK_CUR), strlen (fd2string)); ++ TEST_COMPARE (xlseek (fd2, 0, SEEK_SET), 0); ++ TEST_COMPARE (xlseek (fd4, 0, SEEK_CUR), 0); ++ TEST_COMPARE (read (fd2, buf, sizeof buf), strlen (fd2string)); ++ TEST_COMPARE_BLOB (fd2string, strlen (fd2string), buf, strlen (fd2string)); + + /* Now read from the third file. */ +- if (read (fd3, buf, sizeof buf) != strlen (fd3string)) +- error (EXIT_FAILURE, 0, "cannot read file 3"); +- if (memcmp (fd3string, buf, strlen (fd3string)) != 0) +- error (EXIT_FAILURE, 0, "file 3 does not match"); ++ TEST_COMPARE (read (fd3, buf, sizeof buf), strlen (fd3string)); ++ TEST_COMPARE_BLOB (fd3string, strlen (fd3string), buf, strlen (fd3string)); + /* Try to write to the file. This should not be allowed. */ +- if (write (fd3, "boo!", 4) != -1 || errno != EBADF) +- error (EXIT_FAILURE, 0, "file 3 is writable"); ++ TEST_COMPARE (write (fd3, "boo!", 4), -1); ++ TEST_COMPARE (errno, EBADF); + + /* Now try to read the first file. First make sure it is not opened. */ +- if (lseek (fd1, 0, SEEK_CUR) != (off_t) -1 || errno != EBADF) +- error (EXIT_FAILURE, 0, "file 1 (%d) is not closed", fd1); ++ TEST_COMPARE (lseek (fd1, 0, SEEK_CUR), (off_t) -1); ++ TEST_COMPARE (errno, EBADF); + + /* Now open the file and read it. */ +- fd1 = open (name, O_RDONLY); +- if (fd1 == -1) +- error (EXIT_FAILURE, errno, +- "cannot open first file \"%s\" for verification", name); ++ fd1 = xopen (name, O_RDONLY, 0600); + +- if (read (fd1, buf, sizeof buf) != strlen (fd1string)) +- error (EXIT_FAILURE, errno, "cannot read file 1"); +- if (memcmp (fd1string, buf, strlen (fd1string)) != 0) +- error (EXIT_FAILURE, 0, "file 1 does not match"); ++ TEST_COMPARE (read (fd1, buf, sizeof buf), strlen (fd1string)); ++ TEST_COMPARE_BLOB (fd1string, strlen (fd1string), buf, strlen (fd1string)); + + return 0; + } + + +-int ++static int + do_test (int argc, char *argv[]) + { + pid_t pid; +@@ -181,7 +155,7 @@ do_test (int argc, char *argv[]) + + the name of the closed descriptor + */ + if (argc != (restart ? 6 : 2) && argc != (restart ? 6 : 5)) +- error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc); ++ FAIL_EXIT1 ("wrong number of arguments (%d)", argc); + + if (restart) + return handle_restart (argv[1], argv[2], argv[3], argv[4], argv[5]); +@@ -189,77 +163,73 @@ do_test (int argc, char *argv[]) + /* Prepare the test. We are creating two files: one which file descriptor + will be marked with FD_CLOEXEC, another which is not. */ + +- /* Write something in the files. */ +- if (write (temp_fd1, fd1string, strlen (fd1string)) != strlen (fd1string)) +- error (EXIT_FAILURE, errno, "cannot write to first file"); +- if (write (temp_fd2, fd2string, strlen (fd2string)) != strlen (fd2string)) +- error (EXIT_FAILURE, errno, "cannot write to second file"); +- if (write (temp_fd3, fd3string, strlen (fd3string)) != strlen (fd3string)) +- error (EXIT_FAILURE, errno, "cannot write to third file"); +- +- /* Close the third file. It'll be opened by `spawn'. */ +- close (temp_fd3); +- +- /* Tell `spawn' what to do. */ +- if (posix_spawn_file_actions_init (&actions) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_init"); +- /* Close `temp_fd1'. */ +- if (posix_spawn_file_actions_addclose (&actions, temp_fd1) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose"); +- /* We want to open the third file. */ +- name3_copy = strdup (name3); +- if (name3_copy == NULL) +- error (EXIT_FAILURE, errno, "strdup"); +- if (posix_spawn_file_actions_addopen (&actions, temp_fd3, name3_copy, +- O_RDONLY, 0666) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen"); +- /* Overwrite the name to check that a copy has been made. */ +- memset (name3_copy, 'X', strlen (name3_copy)); +- +- /* We dup the second descriptor. */ +- fd4 = MAX (2, MAX (temp_fd1, MAX (temp_fd2, temp_fd3))) + 1; +- if (posix_spawn_file_actions_adddup2 (&actions, temp_fd2, fd4) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_adddup2"); +- +- /* Now spawn the process. */ +- snprintf (fd1name, sizeof fd1name, "%d", temp_fd1); +- snprintf (fd2name, sizeof fd2name, "%d", temp_fd2); +- snprintf (fd3name, sizeof fd3name, "%d", temp_fd3); +- snprintf (fd4name, sizeof fd4name, "%d", fd4); +- +- for (i = 0; i < (argc == (restart ? 6 : 5) ? 4 : 1); i++) +- spargv[i] = argv[i + 1]; +- spargv[i++] = (char *) "--direct"; +- spargv[i++] = (char *) "--restart"; +- spargv[i++] = fd1name; +- spargv[i++] = fd2name; +- spargv[i++] = fd3name; +- spargv[i++] = fd4name; +- spargv[i++] = name1; +- spargv[i] = NULL; +- +- if (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn"); +- +- /* Same test but with a NULL pid argument. */ +- if (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn"); +- +- /* Cleanup. */ +- if (posix_spawn_file_actions_destroy (&actions) != 0) +- error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy"); +- free (name3_copy); ++ /* Write something in the files. */ ++ xwrite (temp_fd1, fd1string, strlen (fd1string)); ++ xwrite (temp_fd2, fd2string, strlen (fd2string)); ++ xwrite (temp_fd3, fd3string, strlen (fd3string)); ++ ++ /* Close the third file. It'll be opened by `spawn'. */ ++ xclose (temp_fd3); ++ ++ /* Tell `spawn' what to do. */ ++ TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); ++ /* Close `temp_fd1'. */ ++ TEST_COMPARE (posix_spawn_file_actions_addclose (&actions, temp_fd1), 0); ++ /* We want to open the third file. */ ++ name3_copy = xstrdup (name3); ++ TEST_COMPARE (posix_spawn_file_actions_addopen (&actions, temp_fd3, ++ name3_copy, ++ O_RDONLY, 0666), ++ 0); ++ /* Overwrite the name to check that a copy has been made. */ ++ memset (name3_copy, 'X', strlen (name3_copy)); ++ ++ /* We dup the second descriptor. */ ++ fd4 = MAX (2, MAX (temp_fd1, MAX (temp_fd2, temp_fd3))) + 1; ++ TEST_COMPARE (posix_spawn_file_actions_adddup2 (&actions, temp_fd2, fd4), ++ 0); ++ ++ /* Now spawn the process. */ ++ snprintf (fd1name, sizeof fd1name, "%d", temp_fd1); ++ snprintf (fd2name, sizeof fd2name, "%d", temp_fd2); ++ snprintf (fd3name, sizeof fd3name, "%d", temp_fd3); ++ snprintf (fd4name, sizeof fd4name, "%d", fd4); ++ ++ for (i = 0; i < (argc == (restart ? 6 : 5) ? 4 : 1); i++) ++ spargv[i] = argv[i + 1]; ++ spargv[i++] = (char *) "--direct"; ++ spargv[i++] = (char *) "--restart"; ++ spargv[i++] = fd1name; ++ spargv[i++] = fd2name; ++ spargv[i++] = fd3name; ++ spargv[i++] = fd4name; ++ spargv[i++] = name1; ++ spargv[i] = NULL; ++ ++ TEST_COMPARE (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ), ++ 0); ++ ++ /* Same test but with a NULL pid argument. */ ++ TEST_COMPARE (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ), ++ 0); ++ ++ /* Cleanup. */ ++ TEST_COMPARE (posix_spawn_file_actions_destroy (&actions), 0); ++ free (name3_copy); + + /* Wait for the children. */ +- TEST_VERIFY (xwaitpid (pid, &status, 0) == pid); ++ TEST_COMPARE (xwaitpid (pid, &status, 0), pid); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); +- TEST_VERIFY (WEXITSTATUS (status) == 0); ++ TEST_COMPARE (WEXITSTATUS (status), 0); + + xwaitpid (-1, &status, 0); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); +- TEST_VERIFY (WEXITSTATUS (status) == 0); ++ TEST_COMPARE (WEXITSTATUS (status), 0); + + return 0; + } ++ ++#define TEST_FUNCTION_ARGV do_test ++#include diff --git a/SOURCES/glibc-rh1659512-2.patch b/SOURCES/glibc-rh1659512-2.patch new file mode 100644 index 0000000..ac36900 --- /dev/null +++ b/SOURCES/glibc-rh1659512-2.patch @@ -0,0 +1,62 @@ +commit 114f792eaea2505cd8aee02d330aad37238da6a5 +Author: Stefan Liebler +Date: Fri Feb 1 11:03:35 2019 +0100 + + posix/tst-spawn: Fix racy tests in spawned processes. + + From time to time I get fails in tst-spawn like: + tst-spawn.c:111: numeric comparison failure + left: 0 (0x0); from: xlseek (fd2, 0, SEEK_CUR) + right: 28 (0x1c); from: strlen (fd2string) + error: 1 test failures + tst-spawn.c:252: numeric comparison failure + left: 1 (0x1); from: WEXITSTATUS (status) + right: 0 (0x0); from: 0 + error: 1 test failures + + It turned out, that a child process is testing it's open file descriptors + with e.g. a sequence of testing the current position, setting the position + to zero and reading a specific amount of bytes. + + Unfortunately starting with commit 2a69f853c03034c2e383e0f9c35b5402ce8b5473 + the test is spawning a second child process which is sharing some of the + file descriptors. If the test sequence as mentioned above is running in parallel + it leads to test failures. + + As the second call of posix_spawn shall test a NULL pid argument, + this patch is just moving the waitpid of the first child + before the posix_spawn of the second child. + + ChangeLog: + + * posix/tst-spawn do_test(): Move waitpid before posix_spawn. + +diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c +index eea5addbf3..9aa7e621e6 100644 +--- a/posix/tst-spawn.c ++++ b/posix/tst-spawn.c +@@ -237,6 +237,12 @@ do_test (int argc, char *argv[]) + TEST_COMPARE (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ), + 0); + ++ /* Wait for the children. */ ++ TEST_COMPARE (xwaitpid (pid, &status, 0), pid); ++ TEST_VERIFY (WIFEXITED (status)); ++ TEST_VERIFY (!WIFSIGNALED (status)); ++ TEST_COMPARE (WEXITSTATUS (status), 0); ++ + /* Same test but with a NULL pid argument. */ + TEST_COMPARE (posix_spawn (NULL, argv[1], &actions, NULL, spargv, environ), + 0); +@@ -246,11 +252,6 @@ do_test (int argc, char *argv[]) + free (name3_copy); + + /* Wait for the children. */ +- TEST_COMPARE (xwaitpid (pid, &status, 0), pid); +- TEST_VERIFY (WIFEXITED (status)); +- TEST_VERIFY (!WIFSIGNALED (status)); +- TEST_COMPARE (WEXITSTATUS (status), 0); +- + xwaitpid (-1, &status, 0); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); diff --git a/SOURCES/glibc-rh1662843-1.patch b/SOURCES/glibc-rh1662843-1.patch new file mode 100644 index 0000000..5261045 --- /dev/null +++ b/SOURCES/glibc-rh1662843-1.patch @@ -0,0 +1,206 @@ +commit 1ecba1fafc160ca70f81211b23f688df8676e612 +Author: Florian Weimer +Date: Mon Nov 12 14:15:14 2018 +0100 + + malloc: Convert the unlink macro to the unlink_chunk function + + This commit is in preparation of turning the macro into a proper + function. The output arguments of the macro were in fact unused. + + Also clean up uses of __builtin_expect. + +diff --git a/malloc/arena.c b/malloc/arena.c +index 497ae475e7a85902..ff8fd5d2a7e51ac8 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -596,7 +596,7 @@ heap_trim (heap_info *heap, size_t pad) + { + mstate ar_ptr = heap->ar_ptr; + unsigned long pagesz = GLRO (dl_pagesize); +- mchunkptr top_chunk = top (ar_ptr), p, bck, fwd; ++ mchunkptr top_chunk = top (ar_ptr), p; + heap_info *prev_heap; + long new_size, top_size, top_area, extra, prev_size, misalign; + +@@ -625,7 +625,7 @@ heap_trim (heap_info *heap, size_t pad) + if (!prev_inuse (p)) /* consolidate backward */ + { + p = prev_chunk (p); +- unlink (ar_ptr, p, bck, fwd); ++ unlink_chunk (ar_ptr, p); + } + assert (((unsigned long) ((char *) p + new_size) & (pagesz - 1)) == 0); + assert (((char *) p + new_size) == ((char *) heap + heap->size)); +diff --git a/malloc/malloc.c b/malloc/malloc.c +index e450597e2e527fb7..7bfa66a56786d110 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1384,39 +1384,6 @@ typedef struct malloc_chunk *mbinptr; + #define first(b) ((b)->fd) + #define last(b) ((b)->bk) + +-/* Take a chunk off a bin list */ +-#define unlink(AV, P, BK, FD) { \ +- if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0)) \ +- malloc_printerr ("corrupted size vs. prev_size"); \ +- FD = P->fd; \ +- BK = P->bk; \ +- if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \ +- malloc_printerr ("corrupted double-linked list"); \ +- else { \ +- FD->bk = BK; \ +- BK->fd = FD; \ +- if (!in_smallbin_range (chunksize_nomask (P)) \ +- && __builtin_expect (P->fd_nextsize != NULL, 0)) { \ +- if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0) \ +- || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0)) \ +- malloc_printerr ("corrupted double-linked list (not small)"); \ +- if (FD->fd_nextsize == NULL) { \ +- if (P->fd_nextsize == P) \ +- FD->fd_nextsize = FD->bk_nextsize = FD; \ +- else { \ +- FD->fd_nextsize = P->fd_nextsize; \ +- FD->bk_nextsize = P->bk_nextsize; \ +- P->fd_nextsize->bk_nextsize = FD; \ +- P->bk_nextsize->fd_nextsize = FD; \ +- } \ +- } else { \ +- P->fd_nextsize->bk_nextsize = P->bk_nextsize; \ +- P->bk_nextsize->fd_nextsize = P->fd_nextsize; \ +- } \ +- } \ +- } \ +-} +- + /* + Indexing + +@@ -1489,6 +1456,46 @@ typedef struct malloc_chunk *mbinptr; + #define bin_index(sz) \ + ((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz)) + ++/* Take a chunk off a bin list. */ ++static void ++unlink_chunk (mstate av, mchunkptr p) ++{ ++ if (chunksize (p) != prev_size (next_chunk (p))) ++ malloc_printerr ("corrupted size vs. prev_size"); ++ ++ mchunkptr fd = p->fd; ++ mchunkptr bk = p->bk; ++ ++ if (__builtin_expect (fd->bk != p || bk->fd != p, 0)) ++ malloc_printerr ("corrupted double-linked list"); ++ ++ fd->bk = bk; ++ bk->fd = fd; ++ if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL) ++ { ++ if (p->fd_nextsize->bk_nextsize != p ++ || p->bk_nextsize->fd_nextsize != p) ++ malloc_printerr ("corrupted double-linked list (not small)"); ++ ++ if (fd->fd_nextsize == NULL) ++ { ++ if (p->fd_nextsize == p) ++ fd->fd_nextsize = fd->bk_nextsize = fd; ++ else ++ { ++ fd->fd_nextsize = p->fd_nextsize; ++ fd->bk_nextsize = p->bk_nextsize; ++ p->fd_nextsize->bk_nextsize = fd; ++ p->bk_nextsize->fd_nextsize = fd; ++ } ++ } ++ else ++ { ++ p->fd_nextsize->bk_nextsize = p->bk_nextsize; ++ p->bk_nextsize->fd_nextsize = p->fd_nextsize; ++ } ++ } ++} + + /* + Unsorted chunks +@@ -3917,7 +3924,7 @@ _int_malloc (mstate av, size_t bytes) + victim = victim->fd; + + remainder_size = size - nb; +- unlink (av, victim, bck, fwd); ++ unlink_chunk (av, victim); + + /* Exhaust */ + if (remainder_size < MINSIZE) +@@ -4019,7 +4026,7 @@ _int_malloc (mstate av, size_t bytes) + remainder_size = size - nb; + + /* unlink */ +- unlink (av, victim, bck, fwd); ++ unlink_chunk (av, victim); + + /* Exhaust */ + if (remainder_size < MINSIZE) +@@ -4308,7 +4315,7 @@ _int_free (mstate av, mchunkptr p, int have_lock) + p = chunk_at_offset(p, -((long) prevsize)); + if (__glibc_unlikely (chunksize(p) != prevsize)) + malloc_printerr ("corrupted size vs. prev_size while consolidating"); +- unlink(av, p, bck, fwd); ++ unlink_chunk (av, p); + } + + if (nextchunk != av->top) { +@@ -4317,7 +4324,7 @@ _int_free (mstate av, mchunkptr p, int have_lock) + + /* consolidate forward */ + if (!nextinuse) { +- unlink(av, nextchunk, bck, fwd); ++ unlink_chunk (av, nextchunk); + size += nextsize; + } else + clear_inuse_bit_at_offset(nextchunk, 0); +@@ -4430,8 +4437,6 @@ static void malloc_consolidate(mstate av) + INTERNAL_SIZE_T nextsize; + INTERNAL_SIZE_T prevsize; + int nextinuse; +- mchunkptr bck; +- mchunkptr fwd; + + atomic_store_relaxed (&av->have_fastchunks, false); + +@@ -4471,7 +4476,7 @@ static void malloc_consolidate(mstate av) + p = chunk_at_offset(p, -((long) prevsize)); + if (__glibc_unlikely (chunksize(p) != prevsize)) + malloc_printerr ("corrupted size vs. prev_size in fastbins"); +- unlink(av, p, bck, fwd); ++ unlink_chunk (av, p); + } + + if (nextchunk != av->top) { +@@ -4479,7 +4484,7 @@ static void malloc_consolidate(mstate av) + + if (!nextinuse) { + size += nextsize; +- unlink(av, nextchunk, bck, fwd); ++ unlink_chunk (av, nextchunk); + } else + clear_inuse_bit_at_offset(nextchunk, 0); + +@@ -4527,9 +4532,6 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + mchunkptr remainder; /* extra space at end of newp */ + unsigned long remainder_size; /* its size */ + +- mchunkptr bck; /* misc temp for linking */ +- mchunkptr fwd; /* misc temp for linking */ +- + unsigned long copysize; /* bytes to copy */ + unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */ + INTERNAL_SIZE_T* s; /* copy source */ +@@ -4579,7 +4581,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + (unsigned long) (nb)) + { + newp = oldp; +- unlink (av, next, bck, fwd); ++ unlink_chunk (av, next); + } + + /* allocate, copy, free */ diff --git a/SOURCES/glibc-rh1662843-2.patch b/SOURCES/glibc-rh1662843-2.patch new file mode 100644 index 0000000..27fe8c8 --- /dev/null +++ b/SOURCES/glibc-rh1662843-2.patch @@ -0,0 +1,73 @@ +commit b50dd3bc8cbb1efe85399b03d7e6c0310c2ead84 +Author: Florian Weimer +Date: Mon Dec 31 22:04:36 2018 +0100 + + malloc: Always call memcpy in _int_realloc [BZ #24027] + + This commit removes the custom memcpy implementation from _int_realloc + for small chunk sizes. The ncopies variable has the wrong type, and + an integer wraparound could cause the existing code to copy too few + elements (leaving the new memory region mostly uninitialized). + Therefore, removing this code fixes bug 24027. + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 7bfa66a56786d110..0234d968c0ce65a0 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -4532,11 +4532,6 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + mchunkptr remainder; /* extra space at end of newp */ + unsigned long remainder_size; /* its size */ + +- unsigned long copysize; /* bytes to copy */ +- unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */ +- INTERNAL_SIZE_T* s; /* copy source */ +- INTERNAL_SIZE_T* d; /* copy destination */ +- + /* oldmem size */ + if (__builtin_expect (chunksize_nomask (oldp) <= 2 * SIZE_SZ, 0) + || __builtin_expect (oldsize >= av->system_mem, 0)) +@@ -4604,43 +4599,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, + } + else + { +- /* +- Unroll copy of <= 36 bytes (72 if 8byte sizes) +- We know that contents have an odd number of +- INTERNAL_SIZE_T-sized words; minimally 3. +- */ +- +- copysize = oldsize - SIZE_SZ; +- s = (INTERNAL_SIZE_T *) (chunk2mem (oldp)); +- d = (INTERNAL_SIZE_T *) (newmem); +- ncopies = copysize / sizeof (INTERNAL_SIZE_T); +- assert (ncopies >= 3); +- +- if (ncopies > 9) +- memcpy (d, s, copysize); +- +- else +- { +- *(d + 0) = *(s + 0); +- *(d + 1) = *(s + 1); +- *(d + 2) = *(s + 2); +- if (ncopies > 4) +- { +- *(d + 3) = *(s + 3); +- *(d + 4) = *(s + 4); +- if (ncopies > 6) +- { +- *(d + 5) = *(s + 5); +- *(d + 6) = *(s + 6); +- if (ncopies > 8) +- { +- *(d + 7) = *(s + 7); +- *(d + 8) = *(s + 8); +- } +- } +- } +- } +- ++ memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ); + _int_free (av, oldp, 1); + check_inuse_chunk (av, newp); + return chunk2mem (newp); diff --git a/SOURCES/glibc-rh1663035.patch b/SOURCES/glibc-rh1663035.patch new file mode 100644 index 0000000..ec38f0a --- /dev/null +++ b/SOURCES/glibc-rh1663035.patch @@ -0,0 +1,22 @@ +commit 8c1aafc1f34d090a5b41dc527c33e8687f6a1287 +Author: Florian Weimer +Date: Fri Dec 21 16:08:55 2018 +0100 + + intl: Do not return NULL on asprintf failure in gettext [BZ #24018] + + Fixes commit 9695dd0c9309712ed8e9c17a7040fe7af347f2dc ("DCIGETTEXT: + Use getcwd, asprintf to construct absolute pathname"). + +diff --git a/intl/dcigettext.c b/intl/dcigettext.c +index 2a5036994824875b..25f47c5bd3b0ea04 100644 +--- a/intl/dcigettext.c ++++ b/intl/dcigettext.c +@@ -631,7 +631,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2, + int ret = __asprintf (&xdirname, "%s/%s", cwd, dirname); + free (cwd); + if (ret < 0) +- return NULL; ++ goto return_untranslated; + dirname = xdirname; + } + #ifndef IN_LIBGLOCALE diff --git a/SOURCES/glibc-rh1664408.patch b/SOURCES/glibc-rh1664408.patch new file mode 100644 index 0000000..f2f960f --- /dev/null +++ b/SOURCES/glibc-rh1664408.patch @@ -0,0 +1,131 @@ +commit 2ef427168818ce04b03cecb7b739f9db0156e3e4 +Author: Aurelien Jarno +Date: Thu Jan 3 15:51:37 2019 +0100 + + Only build libm with -fno-math-errno (bug 24024) + + Commit 1294b1892e ("Add support for sqrt asm redirects") added the + -fno-math-errno flag to build most of the glibc in order to enable GCC + to inline math functions. Due to GCC bug #88576, saving and restoring + errno around calls to malloc are optimized-out. In turn this causes + strerror to set errno to ENOMEM if it get passed an invalid error number + and if malloc sets errno to ENOMEM (which might happen even if it + succeeds). This is not allowed by POSIX. + + This patch changes the build flags, building only libm with + -fno-math-errno and all the remaining code with -fno-math-errno. This + should be safe as libm doesn't contain any code saving and restoring + errno around malloc. This patch can probably be reverted once the GCC + bug is fixed and available in stable releases. + + Tested on x86-64, no regression in the testsuite. + + Changelog: + [BZ #24024] + * Makeconfig: Build libm with -fno-math-errno but build the remaining + code with -fmath-errno. + * string/Makefile [$(build-shared)] (tests): Add test-strerror-errno. + [$(build-shared)] (LDLIBS-test-strerror-errno): New variable. + * string/test-strerror-errno.c: New file. + +diff --git a/Makeconfig b/Makeconfig +index 92e76d6200bbcd5b..8dc2fec9dc683416 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -831,8 +831,10 @@ endif + # disable any optimization that assume default rounding mode. + +math-flags = -frounding-math + +-# Build libc/libm using -fno-math-errno, but run testsuite with -fmath-errno. +-+extra-math-flags = $(if $(filter libnldbl nonlib testsuite,$(in-module)),-fmath-errno,-fno-math-errno) ++# Logically only "libnldbl", "nonlib" and "testsuite" should be using ++# -fno-math-errno. However due to GCC bug #88576, only "libm" can use ++# -fno-math-errno. +++extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno) + + # We might want to compile with some stack-protection flag. + ifneq ($(stack-protector),) +diff --git a/string/Makefile b/string/Makefile +index 680431f92185f914..aa2da9ca72262886 100644 +--- a/string/Makefile ++++ b/string/Makefile +@@ -64,6 +64,12 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \ + # This test allocates a lot of memory and can run for a long time. + xtests = tst-strcoll-overflow + ++# This test needs libdl. ++ifeq (yes,$(build-shared)) ++tests += test-strerror-errno ++LDLIBS-test-strerror-errno = $(libdl) ++endif ++ + ifeq ($(run-built-tests),yes) + tests-special += $(objpfx)tst-svc-cmp.out + endif +diff --git a/string/test-strerror-errno.c b/string/test-strerror-errno.c +new file mode 100644 +index 0000000000000000..8e744e7ed9df5924 +--- /dev/null ++++ b/string/test-strerror-errno.c +@@ -0,0 +1,61 @@ ++/* BZ #24024 strerror and errno test. ++ ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* malloc is allowed to change errno to a value different than 0, even when ++ there is no actual error. This happens for example when the memory ++ allocation through sbrk fails. Simulate this by interposing our own ++ malloc implementation which sets errno to ENOMEM and calls the original ++ malloc. */ ++void ++*malloc (size_t size) ++{ ++ static void *(*real_malloc) (size_t size); ++ ++ if (!real_malloc) ++ real_malloc = dlsym (RTLD_NEXT, "malloc"); ++ ++ errno = ENOMEM; ++ ++ return (*real_malloc) (size); ++} ++ ++/* strerror must not change the value of errno. Unfortunately due to GCC bug ++ #88576, this happens when -fmath-errno is used. This simple test checks ++ that it doesn't happen. */ ++static int ++do_test (void) ++{ ++ char *msg; ++ ++ errno = 0; ++ msg = strerror (-3); ++ (void) msg; ++ TEST_COMPARE (errno, 0); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1670043-1.patch b/SOURCES/glibc-rh1670043-1.patch new file mode 100644 index 0000000..73939d9 --- /dev/null +++ b/SOURCES/glibc-rh1670043-1.patch @@ -0,0 +1,104 @@ +commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda +Author: Florian Weimer +Date: Tue Mar 12 11:40:47 2019 +0100 + + resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047] + + The Linux kernel suppresses some ICMP error messages by default for + UDP sockets. This commit enables full ICMP error reporting, + hopefully resulting in faster failover to working name servers. + +diff --git a/resolv/Makefile b/resolv/Makefile +index 8f22e6a154..ebe1b733f2 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -105,7 +105,7 @@ libresolv-routines := res_comp res_debug \ + res_data res_mkquery res_query res_send \ + inet_net_ntop inet_net_pton inet_neta base64 \ + ns_parse ns_name ns_netint ns_ttl ns_print \ +- ns_samedomain ns_date \ ++ ns_samedomain ns_date res_enable_icmp \ + compat-hooks compat-gethnamaddr + + libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \ +diff --git a/resolv/res_enable_icmp.c b/resolv/res_enable_icmp.c +new file mode 100644 +index 0000000000..bdc9220f08 +--- /dev/null ++++ b/resolv/res_enable_icmp.c +@@ -0,0 +1,37 @@ ++/* Enable full ICMP errors on a socket. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++__res_enable_icmp (int family, int fd) ++{ ++ int one = 1; ++ switch (family) ++ { ++ case AF_INET: ++ return setsockopt (fd, SOL_IP, IP_RECVERR, &one, sizeof (one)); ++ case AF_INET6: ++ return setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &one, sizeof (one)); ++ default: ++ __set_errno (EAFNOSUPPORT); ++ return -1; ++ } ++} +diff --git a/resolv/res_send.c b/resolv/res_send.c +index fa040c1198..0f6ec83a7b 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -943,6 +943,18 @@ reopen (res_state statp, int *terrno, int ns) + return (-1); + } + ++ /* Enable full ICMP error reporting for this ++ socket. */ ++ if (__res_enable_icmp (nsap->sa_family, ++ EXT (statp).nssocks[ns]) < 0) ++ { ++ int saved_errno = errno; ++ __res_iclose (statp, false); ++ __set_errno (saved_errno); ++ *terrno = saved_errno; ++ return -1; ++ } ++ + /* + * On a 4.3BSD+ machine (client and server, + * actually), sending to a nameserver datagram +diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h +index 6ab8f2af09..1500adc607 100644 +--- a/resolv/resolv-internal.h ++++ b/resolv/resolv-internal.h +@@ -100,4 +100,10 @@ libc_hidden_proto (__inet_pton_length) + /* Called as part of the thread shutdown sequence. */ + void __res_thread_freeres (void) attribute_hidden; + ++/* The Linux kernel does not enable all ICMP messages on a UDP socket ++ by default. A call this function enables full error reporting for ++ the socket FD. FAMILY must be AF_INET or AF_INET6. Returns 0 on ++ success, -1 on failure. */ ++int __res_enable_icmp (int family, int fd) attribute_hidden; ++ + #endif /* _RESOLV_INTERNAL_H */ diff --git a/SOURCES/glibc-rh1670043-2.patch b/SOURCES/glibc-rh1670043-2.patch new file mode 100644 index 0000000..d73d211 --- /dev/null +++ b/SOURCES/glibc-rh1670043-2.patch @@ -0,0 +1,47 @@ +commit 043440e761d395e1f507d9faa6e82b3fe4536c3f +Author: Florian Weimer +Date: Wed Mar 13 14:58:58 2019 +0100 + + hurd: Add no-op version of __res_enable_icmp [BZ #24047] + + Mach does not support IP_RECVERR, so replace this function with a + stub in a sysdeps override for Hurd. + + This fixes commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda + ("resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047]"). + + Reviewed-by: Carlos O'Donell + +diff --git a/sysdeps/mach/hurd/res_enable_icmp.c b/sysdeps/mach/hurd/res_enable_icmp.c +new file mode 100644 +index 0000000000..4b0456340c +--- /dev/null ++++ b/sysdeps/mach/hurd/res_enable_icmp.c +@@ -0,0 +1,27 @@ ++/* Enable full ICMP errors on a socket. No-op version for Hurd. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Mach does not support the IP_RECVERR extension. */ ++ ++#include ++ ++int ++__res_enable_icmp (int family, int fd) ++{ ++ return 0; ++} diff --git a/SOURCES/glibc-rh1672773.patch b/SOURCES/glibc-rh1672773.patch new file mode 100644 index 0000000..1e34531 --- /dev/null +++ b/SOURCES/glibc-rh1672773.patch @@ -0,0 +1,199 @@ +commit 823624bdc47f1f80109c9c52dee7939b9386d708 +Author: Stefan Liebler +Date: Thu Feb 7 15:18:36 2019 +0100 + + Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock. [BZ #24180] + + While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and + Heiko Carstens found a bug in pthread_mutex_trylock due to misordered + instructions: + 140: a5 1b 00 01 oill %r1,1 + 144: e5 48 a0 f0 00 00 mvghi 240(%r10),0 <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + 14a: e3 10 a0 e0 00 24 stg %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI + + vs (with compiler barriers): + 140: a5 1b 00 01 oill %r1,1 + 144: e3 10 a0 e0 00 24 stg %r1,224(%r10) + 14a: e5 48 a0 f0 00 00 mvghi 240(%r10),0 + + Please have a look at the discussion: + "Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede" + (https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/) + + This patch is introducing the same compiler barriers and comments + for pthread_mutex_trylock as introduced for pthread_mutex_lock and + pthread_mutex_timedlock by commit 8f9450a0b7a9e78267e8ae1ab1000ebca08e473e + "Add compiler barriers around modifications of the robust mutex list." + + ChangeLog: + + [BZ #24180] + * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): + +diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c +index 8fe43b8f0f..bf2869eca2 100644 +--- a/nptl/pthread_mutex_trylock.c ++++ b/nptl/pthread_mutex_trylock.c +@@ -94,6 +94,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP: + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + &mutex->__data.__list.__next); ++ /* We need to set op_pending before starting the operation. Also ++ see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + + oldval = mutex->__data.__lock; + do +@@ -119,7 +122,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + /* But it is inconsistent unless marked otherwise. */ + mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Note that we deliberately exist here. If we fall +@@ -135,6 +143,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + int kind = PTHREAD_MUTEX_TYPE (mutex); + if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. Also see comments at ENQUEUE_MUTEX. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + return EDEADLK; +@@ -142,6 +152,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + + if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + +@@ -160,6 +172,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + id, 0); + if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0) + { ++ /* We haven't acquired the lock as it is already acquired by ++ another owner. We do not need to ensure ordering wrt another ++ memory access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -173,13 +188,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + if (oldval == id) + lll_unlock (mutex->__data.__lock, + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)); ++ /* FIXME This violates the mutex destruction requirements. See ++ __pthread_mutex_unlock_full. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return ENOTRECOVERABLE; + } + } + while ((oldval & FUTEX_OWNER_DIED) != 0); + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + mutex->__data.__owner = id; +@@ -211,10 +233,15 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + } + + if (robust) +- /* Note: robust PI futexes are signaled by setting bit 0. */ +- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, +- (void *) (((uintptr_t) &mutex->__data.__list.__next) +- | 1)); ++ { ++ /* Note: robust PI futexes are signaled by setting bit 0. */ ++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, ++ (void *) (((uintptr_t) &mutex->__data.__list.__next) ++ | 1)); ++ /* We need to set op_pending before starting the operation. Also ++ see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); ++ } + + oldval = mutex->__data.__lock; + +@@ -223,12 +250,16 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + { + if (kind == PTHREAD_MUTEX_ERRORCHECK_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return EDEADLK; + } + + if (kind == PTHREAD_MUTEX_RECURSIVE_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Just bump the counter. */ +@@ -250,6 +281,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + { + if ((oldval & FUTEX_OWNER_DIED) == 0) + { ++ /* We haven't acquired the lock as it is already acquired by ++ another owner. We do not need to ensure ordering wrt another ++ memory access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -270,6 +304,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + if (INTERNAL_SYSCALL_ERROR_P (e, __err) + && INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK) + { ++ /* The kernel has not yet finished the mutex owner death. ++ We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -287,7 +324,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + /* But it is inconsistent unless marked otherwise. */ + mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Note that we deliberately exit here. If we fall +@@ -310,13 +352,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)), + 0, 0); + ++ /* To the kernel, this will be visible after the kernel has ++ acquired the mutex in the syscall. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return ENOTRECOVERABLE; + } + + if (robust) + { ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX_PI (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + } + diff --git a/SOURCES/glibc-rh1691528-1.patch b/SOURCES/glibc-rh1691528-1.patch new file mode 100644 index 0000000..9f07b78 --- /dev/null +++ b/SOURCES/glibc-rh1691528-1.patch @@ -0,0 +1,48 @@ +commit ac64195ccd4f320659fd0058bc7524c6fd0b37b4 +Author: DJ Delorie +Date: Wed Mar 20 23:56:59 2019 -0400 + + iconv, localedef: avoid floating point rounding differences [BZ #24372] + + Two cases of "int * 1.4" may result in imprecise results, which + in at least one case resulted in i686 and x86-64 producing + different locale files. This replaced that floating point multiply + with integer operations. While the hash table margin is increased + from 40% to 50%, testing shows only 2% increase in overall size + of the locale archive. + + https://bugzilla.redhat.com/show_bug.cgi?id=1311954 + + Reviewed-by: Carlos O'Donell + +diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c +index d5e8e714233f78d8..696fc8d31231ca2d 100644 +--- a/iconv/iconvconfig.c ++++ b/iconv/iconvconfig.c +@@ -1079,9 +1079,9 @@ write_output (void) + + /* Create the hashing table. We know how many strings we have. + Creating a perfect hash table is not reasonable here. Therefore +- we use open hashing and a table size which is the next prime 40% ++ we use open hashing and a table size which is the next prime 50% + larger than the number of strings. */ +- hash_size = next_prime (nnames * 1.4); ++ hash_size = next_prime (nnames + nnames >> 1); + hash_table = (struct hash_entry *) xcalloc (hash_size, + sizeof (struct hash_entry)); + /* Fill the hash table. */ +diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c +index d2eebcfdbb0677e5..9a1639b999d0e2aa 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -2401,8 +2401,8 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + + runp = runp->next; + } +- /* Add 40% and find the next prime number. */ +- elem_size = next_prime (elem_size * 1.4); ++ /* Add 50% and find the next prime number. */ ++ elem_size = next_prime (elem_size + elem_size >> 1); + + /* Allocate the table. Each entry consists of two words: the hash + value and an index in a secondary table which provides the index diff --git a/SOURCES/glibc-rh1691528-2.patch b/SOURCES/glibc-rh1691528-2.patch new file mode 100644 index 0000000..568320e --- /dev/null +++ b/SOURCES/glibc-rh1691528-2.patch @@ -0,0 +1,49 @@ +commit 5abcddd7949270998c6e8d99fdbbba821b664f8b +Author: Gabriel F. T. Gomes +Date: Thu Mar 21 17:24:30 2019 -0300 + + Fix parentheses error in iconvconfig.c and ld-collate.c [BZ #24372] + + When -Werror=parentheses is in use, iconvconfig.c builds fail with: + + iconvconfig.c: In function ‘write_output’: + iconvconfig.c:1084:34: error: suggest parentheses around ‘+’ inside ‘>>’ [-Werror=parentheses] + hash_size = next_prime (nnames + nnames >> 1); + ~~~~~~~^~~~~~~~ + + This patch adds parentheses to the expression. Not where suggested by + the compiler warning, but where it produces the expected result, i.e.: + where it has the effect of multiplying nnames by 1.5. + + Likewise for elem_size in ld-collate.c. + + Tested for powerpc64le. + + Reviewed-by: Carlos O'Donell + +diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c +index 696fc8d31231ca2d..b6fef1553cbbdd3d 100644 +--- a/iconv/iconvconfig.c ++++ b/iconv/iconvconfig.c +@@ -1081,7 +1081,7 @@ write_output (void) + Creating a perfect hash table is not reasonable here. Therefore + we use open hashing and a table size which is the next prime 50% + larger than the number of strings. */ +- hash_size = next_prime (nnames + nnames >> 1); ++ hash_size = next_prime (nnames + (nnames >> 1)); + hash_table = (struct hash_entry *) xcalloc (hash_size, + sizeof (struct hash_entry)); + /* Fill the hash table. */ +diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c +index 9a1639b999d0e2aa..a5530655fd5638b5 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -2402,7 +2402,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + runp = runp->next; + } + /* Add 50% and find the next prime number. */ +- elem_size = next_prime (elem_size + elem_size >> 1); ++ elem_size = next_prime (elem_size + (elem_size >> 1)); + + /* Allocate the table. Each entry consists of two words: the hash + value and an index in a secondary table which provides the index diff --git a/SOURCES/glibc-rh1692450.patch b/SOURCES/glibc-rh1692450.patch deleted file mode 100644 index aab01cc..0000000 --- a/SOURCES/glibc-rh1692450.patch +++ /dev/null @@ -1,24 +0,0 @@ -Patch by Hanataka Shinya from -. Confirmed by TAMUKI -Shoichi's patch in -. - -The official announcement by the Japanese Prime Minister in - uses U+4EE4 U+548C -as well. - -diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP -index 1fd2fee44b2879d9..30190b624856cc53 100644 ---- a/localedata/locales/ja_JP -+++ b/localedata/locales/ja_JP -@@ -14946,7 +14946,9 @@ am_pm "";"" - - t_fmt_ampm "%p%I%M%S" - --era "+:2:1990//01//01:+*::%EC%Ey";/ -+era "+:2:2020//01//01:+*::%EC%Ey";/ -+ "+:1:2019//05//01:2019//12//31::%EC";/ -+ "+:2:1990//01//01:2019//04//30::%EC%Ey";/ - "+:1:1989//01//08:1989//12//31::%EC";/ - "+:2:1927//01//01:1989//01//07::%EC%Ey";/ - "+:1:1926//12//25:1926//12//31::%EC";/ diff --git a/SOURCES/glibc-rh1699194-1.patch b/SOURCES/glibc-rh1699194-1.patch new file mode 100644 index 0000000..3db05de --- /dev/null +++ b/SOURCES/glibc-rh1699194-1.patch @@ -0,0 +1,23 @@ +commit 4e75c2a43bb3208f32556a2b19c939cfe1f54ba6 +Author: Florian Weimer +Date: Wed Jun 12 10:41:19 2019 +0200 + + : Add __glibc_has_include macro + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 3f6fe3cc8563b493..0500779d0c1b64c2 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -412,6 +412,12 @@ + # define __glibc_has_attribute(attr) 0 + #endif + ++#ifdef __has_include ++# define __glibc_has_include(header) __has_include (header) ++#else ++# define __glibc_has_include(header) 0 ++#endif ++ + #if (!defined _Noreturn \ + && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ + && !__GNUC_PREREQ (4,7)) diff --git a/SOURCES/glibc-rh1699194-2.patch b/SOURCES/glibc-rh1699194-2.patch new file mode 100644 index 0000000..e292641 --- /dev/null +++ b/SOURCES/glibc-rh1699194-2.patch @@ -0,0 +1,383 @@ +commit 5dad6ffbb2b76215cfcd38c3001778536ada8e8a +Author: Florian Weimer +Date: Wed Jun 12 12:04:09 2019 +0200 + + : Use Linux UAPI header for statx if available and useful + + This will automatically import new STATX_* constants. It also avoids + a conflict between and . + +Conflicts: + io/bits/statx.h + (Year range in copyright header.) + +diff --git a/include/bits/statx-generic.h b/include/bits/statx-generic.h +new file mode 100644 +index 0000000000000000..21674721b6d85265 +--- /dev/null ++++ b/include/bits/statx-generic.h +@@ -0,0 +1 @@ ++#include +diff --git a/include/bits/types/struct_statx.h b/include/bits/types/struct_statx.h +new file mode 100644 +index 0000000000000000..82add6484f2ee963 +--- /dev/null ++++ b/include/bits/types/struct_statx.h +@@ -0,0 +1 @@ ++#include +diff --git a/include/bits/types/struct_statx_timestamp.h b/include/bits/types/struct_statx_timestamp.h +new file mode 100644 +index 0000000000000000..9fbedd5749fc1172 +--- /dev/null ++++ b/include/bits/types/struct_statx_timestamp.h +@@ -0,0 +1 @@ ++#include +diff --git a/io/Makefile b/io/Makefile +index ec5c6d7a2fb87914..787a5c550ab64b17 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -25,7 +25,9 @@ include ../Makeconfig + headers := sys/stat.h bits/stat.h sys/statfs.h bits/statfs.h sys/vfs.h \ + sys/statvfs.h bits/statvfs.h fcntl.h sys/fcntl.h bits/fcntl.h \ + poll.h sys/poll.h bits/poll.h bits/fcntl2.h bits/poll2.h \ +- bits/statx.h utime.h ftw.h fts.h sys/sendfile.h ++ bits/statx.h bits/statx-generic.h bits/types/struct_statx.h \ ++ bits/types/struct_statx_timestamp.h \ ++ utime.h ftw.h fts.h sys/sendfile.h + + routines := \ + utime \ +diff --git a/io/bits/statx-generic.h b/io/bits/statx-generic.h +new file mode 100644 +index 0000000000000000..1f5abbf148681e9b +--- /dev/null ++++ b/io/bits/statx-generic.h +@@ -0,0 +1,60 @@ ++/* Generic statx-related definitions and declarations. ++ Copyright (C) 2018-2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This interface is based on in Linux. */ ++ ++#ifndef _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++#include ++#include ++ ++#ifndef STATX_TYPE ++# define STATX_TYPE 0x0001U ++# define STATX_MODE 0x0002U ++# define STATX_NLINK 0x0004U ++# define STATX_UID 0x0008U ++# define STATX_GID 0x0010U ++# define STATX_ATIME 0x0020U ++# define STATX_MTIME 0x0040U ++# define STATX_CTIME 0x0080U ++# define STATX_INO 0x0100U ++# define STATX_SIZE 0x0200U ++# define STATX_BLOCKS 0x0400U ++# define STATX_BASIC_STATS 0x07ffU ++# define STATX_ALL 0x0fffU ++# define STATX_BTIME 0x0800U ++# define STATX__RESERVED 0x80000000U ++ ++# define STATX_ATTR_COMPRESSED 0x0004 ++# define STATX_ATTR_IMMUTABLE 0x0010 ++# define STATX_ATTR_APPEND 0x0020 ++# define STATX_ATTR_NODUMP 0x0040 ++# define STATX_ATTR_ENCRYPTED 0x0800 ++# define STATX_ATTR_AUTOMOUNT 0x1000 ++#endif /* !STATX_TYPE */ ++ ++__BEGIN_DECLS ++ ++/* Fill *BUF with information about PATH in DIRFD. */ ++int statx (int __dirfd, const char *__restrict __path, int __flags, ++ unsigned int __mask, struct statx *__restrict __buf) ++ __THROW __nonnull ((2, 5)); ++ ++__END_DECLS +diff --git a/io/bits/statx.h b/io/bits/statx.h +index e31254e3617bb17b..b3147bfa8af1818f 100644 +--- a/io/bits/statx.h ++++ b/io/bits/statx.h +@@ -1,5 +1,5 @@ +-/* statx-related definitions and declarations. +- Copyright (C) 2018 Free Software Foundation, Inc. ++/* statx-related definitions and declarations. Generic version. ++ Copyright (C) 2018-2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -19,73 +19,8 @@ + /* This interface is based on in Linux. */ + + #ifndef _SYS_STAT_H +-# error Never include directly, include instead. ++# error Never include directly, include instead. + #endif + +-struct statx_timestamp +-{ +- __int64_t tv_sec; +- __uint32_t tv_nsec; +- __int32_t __statx_timestamp_pad1[1]; +-}; +- +-/* Warning: The kernel may add additional fields to this struct in the +- future. Only use this struct for calling the statx function, not +- for storing data. (Expansion will be controlled by the mask +- argument of the statx function.) */ +-struct statx +-{ +- __uint32_t stx_mask; +- __uint32_t stx_blksize; +- __uint64_t stx_attributes; +- __uint32_t stx_nlink; +- __uint32_t stx_uid; +- __uint32_t stx_gid; +- __uint16_t stx_mode; +- __uint16_t __statx_pad1[1]; +- __uint64_t stx_ino; +- __uint64_t stx_size; +- __uint64_t stx_blocks; +- __uint64_t stx_attributes_mask; +- struct statx_timestamp stx_atime; +- struct statx_timestamp stx_btime; +- struct statx_timestamp stx_ctime; +- struct statx_timestamp stx_mtime; +- __uint32_t stx_rdev_major; +- __uint32_t stx_rdev_minor; +- __uint32_t stx_dev_major; +- __uint32_t stx_dev_minor; +- __uint64_t __statx_pad2[14]; +-}; +- +-#define STATX_TYPE 0x0001U +-#define STATX_MODE 0x0002U +-#define STATX_NLINK 0x0004U +-#define STATX_UID 0x0008U +-#define STATX_GID 0x0010U +-#define STATX_ATIME 0x0020U +-#define STATX_MTIME 0x0040U +-#define STATX_CTIME 0x0080U +-#define STATX_INO 0x0100U +-#define STATX_SIZE 0x0200U +-#define STATX_BLOCKS 0x0400U +-#define STATX_BASIC_STATS 0x07ffU +-#define STATX_ALL 0x0fffU +-#define STATX_BTIME 0x0800U +-#define STATX__RESERVED 0x80000000U +- +-#define STATX_ATTR_COMPRESSED 0x0004 +-#define STATX_ATTR_IMMUTABLE 0x0010 +-#define STATX_ATTR_APPEND 0x0020 +-#define STATX_ATTR_NODUMP 0x0040 +-#define STATX_ATTR_ENCRYPTED 0x0800 +-#define STATX_ATTR_AUTOMOUNT 0x1000 +- +-__BEGIN_DECLS +- +-/* Fill *BUF with information about PATH in DIRFD. */ +-int statx (int __dirfd, const char *__restrict __path, int __flags, +- unsigned int __mask, struct statx *__restrict __buf) +- __THROW __nonnull ((2, 5)); +- +-__END_DECLS ++/* Use the generic definitions. */ ++#include +diff --git a/io/bits/types/struct_statx.h b/io/bits/types/struct_statx.h +new file mode 100644 +index 0000000000000000..4f3ae3ece62a0ad2 +--- /dev/null ++++ b/io/bits/types/struct_statx.h +@@ -0,0 +1,55 @@ ++/* Definition of the generic version of struct statx. ++ Copyright (C) 2018-2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++#ifndef __statx_defined ++#define __statx_defined 1 ++ ++/* Warning: The kernel may add additional fields to this struct in the ++ future. Only use this struct for calling the statx function, not ++ for storing data. (Expansion will be controlled by the mask ++ argument of the statx function.) */ ++struct statx ++{ ++ __uint32_t stx_mask; ++ __uint32_t stx_blksize; ++ __uint64_t stx_attributes; ++ __uint32_t stx_nlink; ++ __uint32_t stx_uid; ++ __uint32_t stx_gid; ++ __uint16_t stx_mode; ++ __uint16_t __statx_pad1[1]; ++ __uint64_t stx_ino; ++ __uint64_t stx_size; ++ __uint64_t stx_blocks; ++ __uint64_t stx_attributes_mask; ++ struct statx_timestamp stx_atime; ++ struct statx_timestamp stx_btime; ++ struct statx_timestamp stx_ctime; ++ struct statx_timestamp stx_mtime; ++ __uint32_t stx_rdev_major; ++ __uint32_t stx_rdev_minor; ++ __uint32_t stx_dev_major; ++ __uint32_t stx_dev_minor; ++ __uint64_t __statx_pad2[14]; ++}; ++ ++#endif /* __statx_defined */ +diff --git a/io/bits/types/struct_statx_timestamp.h b/io/bits/types/struct_statx_timestamp.h +new file mode 100644 +index 0000000000000000..0f104ef84ed7d356 +--- /dev/null ++++ b/io/bits/types/struct_statx_timestamp.h +@@ -0,0 +1,33 @@ ++/* Definition of the generic version of struct statx_timestamp. ++ Copyright (C) 2018-2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++#ifndef __statx_timestamp_defined ++#define __statx_timestamp_defined 1 ++ ++struct statx_timestamp ++{ ++ __int64_t tv_sec; ++ __uint32_t tv_nsec; ++ __int32_t __statx_timestamp_pad1[1]; ++}; ++ ++#endif /* __statx_timestamp_defined */ +diff --git a/io/statx_generic.c b/io/statx_generic.c +index df327f8c525f748c..987c84fb45f5db63 100644 +--- a/io/statx_generic.c ++++ b/io/statx_generic.c +@@ -18,9 +18,16 @@ + + #include + #include ++#include + #include + #include + ++/* Obtain the original definition of struct statx. */ ++#undef __statx_defined ++#define statx original_statx ++#include ++#undef statx ++ + static inline struct statx_timestamp + statx_convert_timestamp (struct timespec tv) + { +@@ -57,7 +64,7 @@ statx_generic (int fd, const char *path, int flags, + /* The interface is defined in such a way that unused (padding) + fields have to be cleared. STATX_BASIC_STATS corresponds to the + data which is available via fstatat64. */ +- *buf = (struct statx) ++ struct original_statx obuf = + { + .stx_mask = STATX_BASIC_STATS, + .stx_blksize = st.st_blksize, +@@ -76,6 +83,8 @@ statx_generic (int fd, const char *path, int flags, + .stx_dev_major = major (st.st_dev), + .stx_dev_minor = minor (st.st_dev), + }; ++ _Static_assert (sizeof (*buf) >= sizeof (obuf), "struct statx size"); ++ memcpy (buf, &obuf, sizeof (obuf)); + + return 0; + } +diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h +new file mode 100644 +index 0000000000000000..d36f44efc60a0bed +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/bits/statx.h +@@ -0,0 +1,34 @@ ++/* statx-related definitions and declarations. Linux version. ++ Copyright (C) 2018-2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This interface is based on in Linux. */ ++ ++#ifndef _SYS_STAT_H ++# error Never include directly, include instead. ++#endif ++ ++/* Use the Linux kernel header if available. */ ++#if __glibc_has_include () ++# include ++# ifdef STATX_TYPE ++# define __statx_timestamp_defined 1 ++# define __statx_defined 1 ++# endif ++#endif ++ ++#include diff --git a/SOURCES/glibc-rh1699194-3.patch b/SOURCES/glibc-rh1699194-3.patch new file mode 100644 index 0000000..ced417e --- /dev/null +++ b/SOURCES/glibc-rh1699194-3.patch @@ -0,0 +1,28 @@ +commit 8d141877e07cc594e9fefc3795b8ba729288093c +Author: Florian Weimer +Date: Fri Jun 14 15:46:02 2019 +0200 + + : Inhibit macro expansion for __glibc_has_include + + This is currently ineffective with GCC because of GCC PR 80005, but + it makes sense to anticipate a fix for this defect. + + Suggested by Zack Weinberg. + + Reviewed-by: Carlos O'Donell + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 0500779d0c1b64c2..9e840e602f815d86 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -413,7 +413,9 @@ + #endif + + #ifdef __has_include +-# define __glibc_has_include(header) __has_include (header) ++/* Do not use a function-like macro, so that __has_include can inhibit ++ macro expansion. */ ++# define __glibc_has_include __has_include + #else + # define __glibc_has_include(header) 0 + #endif diff --git a/SOURCES/glibc-rh1699194-4.patch b/SOURCES/glibc-rh1699194-4.patch new file mode 100644 index 0000000..1892855 --- /dev/null +++ b/SOURCES/glibc-rh1699194-4.patch @@ -0,0 +1,37 @@ +commit 48c3c1238925410b4e777dc94e2fde4cc9132d44 +Author: Florian Weimer +Date: Fri Jun 14 16:28:41 2019 +0200 + + Linux: Fix __glibc_has_include use for and statx + + The identifier linux is used as a predefined macro, so the actually + used path is 1/stat.h or 1/stat64.h. Using the quote-based version + triggers a file lookup for /usr/include/bits/linux/stat.h (or whatever + directory is used to store bits/statx.h), but since bits/ is pretty + much reserved by glibc, this appears to be acceptable. + + This is related to GCC PR 80005: incorrect macro expansion of the + argument of __has_include. + + Suggested by Zack Weinberg. + + Reviewed-by: Carlos O'Donell + +diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h +index d36f44efc60a0bed..206878723fd37881 100644 +--- a/sysdeps/unix/sysv/linux/bits/statx.h ++++ b/sysdeps/unix/sysv/linux/bits/statx.h +@@ -23,8 +23,11 @@ + #endif + + /* Use the Linux kernel header if available. */ +-#if __glibc_has_include () +-# include ++ ++/* Use "" to work around incorrect macro expansion of the ++ __has_include argument (GCC PR 80005). */ ++#if __glibc_has_include ("linux/stat.h") ++# include "linux/stat.h" + # ifdef STATX_TYPE + # define __statx_timestamp_defined 1 + # define __statx_defined 1 diff --git a/SOURCES/glibc-rh1701605-1.patch b/SOURCES/glibc-rh1701605-1.patch new file mode 100644 index 0000000..b21720c --- /dev/null +++ b/SOURCES/glibc-rh1701605-1.patch @@ -0,0 +1,298 @@ +commit e485b2b6e006a7efa5d73e6be7e357a395c77fe3 +Author: Florian Weimer +Date: Tue Apr 23 18:16:26 2019 +0200 + + locale: Add LOCPATH diagnostics to the locale program + + The implementation of quote_string is based on support_quote_blob. + + Reviewed-by: Carlos O'Donell + +diff --git a/locale/Makefile b/locale/Makefile +index fd9972279ba7fe0b..42bb36c7d374eebe 100644 +--- a/locale/Makefile ++++ b/locale/Makefile +@@ -28,6 +28,7 @@ routines = setlocale findlocale loadlocale loadarchive \ + localeconv nl_langinfo nl_langinfo_l mb_cur_max \ + newlocale duplocale freelocale uselocale + tests = tst-C-locale tst-locname tst-duplocale ++tests-special = $(objpfx)tst-locale-locpath.out + categories = ctype messages monetary numeric time paper name \ + address telephone measurement identification collate + aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \ +@@ -104,3 +105,7 @@ cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \ + $(lib-modules) + lib := locale-programs + include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) ++ ++$(objpfx)tst-locale-locpath.out : tst-locale-locpath.sh $(objpfx)locale ++ $(SHELL) $< '$(common-objpfx)' '$(test-wrapper)' '$(test-wrapper-env)' > $@; \ ++ $(evaluate-test) +diff --git a/locale/programs/locale.c b/locale/programs/locale.c +index 86941e4ef6e67d78..0e2e3e4e5788246f 100644 +--- a/locale/programs/locale.c ++++ b/locale/programs/locale.c +@@ -173,6 +173,9 @@ static int write_archive_locales (void **all_datap, char *linebuf); + static void write_charmaps (void); + static void show_locale_vars (void); + static void show_info (const char *name); ++static void try_setlocale (int category, const char *category_name); ++static char *quote_string (const char *input); ++static void setlocale_diagnostics (void); + + + int +@@ -186,10 +189,8 @@ main (int argc, char *argv[]) + + /* Set locale. Do not set LC_ALL because the other categories must + not be affected (according to POSIX.2). */ +- if (setlocale (LC_CTYPE, "") == NULL) +- error (0, errno, gettext ("Cannot set LC_CTYPE to default locale")); +- if (setlocale (LC_MESSAGES, "") == NULL) +- error (0, errno, gettext ("Cannot set LC_MESSAGES to default locale")); ++ try_setlocale (LC_CTYPE, "LC_CTYPE"); ++ try_setlocale (LC_MESSAGES, "LC_MESSAGES"); + + /* Initialize the message catalog. */ + textdomain (PACKAGE); +@@ -200,9 +201,8 @@ main (int argc, char *argv[]) + /* `-a' requests the names of all available locales. */ + if (do_all != 0) + { +- if (setlocale (LC_COLLATE, "") == NULL) +- error (0, errno, +- gettext ("Cannot set LC_COLLATE to default locale")); ++ setlocale_diagnostics (); ++ try_setlocale (LC_COLLATE, "LC_COLLATE"); + write_locales (); + exit (EXIT_SUCCESS); + } +@@ -211,14 +211,15 @@ main (int argc, char *argv[]) + used for the -f argument to localedef(1). */ + if (do_charmaps != 0) + { ++ setlocale_diagnostics (); + write_charmaps (); + exit (EXIT_SUCCESS); + } + + /* Specific information about the current locale are requested. + Change to this locale now. */ +- if (setlocale (LC_ALL, "") == NULL) +- error (0, errno, gettext ("Cannot set LC_ALL to default locale")); ++ try_setlocale (LC_ALL, "LC_ALL"); ++ setlocale_diagnostics (); + + /* If no real argument is given we have to print the contents of the + current locale definition variables. These are LANG and the LC_*. */ +@@ -983,3 +984,121 @@ show_info (const char *name) + For testing and perhaps advanced use allow some more symbols. */ + locale_special (name, show_category_name, show_keyword_name); + } ++ ++/* Set to true by try_setlocale if setlocale fails. Used by ++ setlocale_diagnostics. */ ++static bool setlocale_failed; ++ ++/* Call setlocale, with non-fatal error reporting. */ ++static void ++try_setlocale (int category, const char *category_name) ++{ ++ if (setlocale (category, "") == NULL) ++ { ++ error (0, errno, gettext ("Cannot set %s to default locale"), ++ category_name); ++ setlocale_failed = true; ++ } ++} ++ ++/* Return a quoted version of the passed string, or NULL on error. */ ++static char * ++quote_string (const char *input) ++{ ++ char *buffer; ++ size_t length; ++ FILE *stream = open_memstream (&buffer, &length); ++ if (stream == NULL) ++ return NULL; ++ ++ while (true) ++ { ++ unsigned char ch = *input++; ++ if (ch == '\0') ++ break; ++ ++ /* Use C backslash escapes for those control characters for ++ which they are defined. */ ++ switch (ch) ++ { ++ case '\a': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('a', stream); ++ break; ++ case '\b': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('b', stream); ++ break; ++ case '\f': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('f', stream); ++ break; ++ case '\n': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('n', stream); ++ break; ++ case '\r': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('r', stream); ++ break; ++ case '\t': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('t', stream); ++ break; ++ case '\v': ++ putc_unlocked ('\\', stream); ++ putc_unlocked ('v', stream); ++ break; ++ case '\\': ++ case '\'': ++ case '\"': ++ putc_unlocked ('\\', stream); ++ putc_unlocked (ch, stream); ++ break; ++ default: ++ if (ch < ' ' || ch > '~') ++ /* Use octal sequences because they are fixed width, ++ unlike hexadecimal sequences. */ ++ fprintf (stream, "\\%03o", ch); ++ else ++ putc_unlocked (ch, stream); ++ } ++ } ++ ++ if (ferror (stream)) ++ { ++ fclose (stream); ++ free (buffer); ++ return NULL; ++ } ++ if (fclose (stream) != 0) ++ { ++ free (buffer); ++ return NULL; ++ } ++ ++ return buffer; ++} ++ ++/* Print additional information if there was a setlocale error (during ++ try_setlocale). */ ++static void ++setlocale_diagnostics (void) ++{ ++ if (setlocale_failed) ++ { ++ const char *locpath = getenv ("LOCPATH"); ++ if (locpath != NULL) ++ { ++ char *quoted = quote_string (locpath); ++ if (quoted != NULL) ++ fprintf (stderr, ++ gettext ("\ ++warning: The LOCPATH variable is set to \"%s\"\n"), ++ quoted); ++ else ++ fputs ("warning: The LOCPATH variable is set\n", stderr); ++ free (quoted); ++ } ++ } ++} +diff --git a/locale/tst-locale-locpath.sh b/locale/tst-locale-locpath.sh +new file mode 100644 +index 0000000000000000..b83de90a39121af6 +--- /dev/null ++++ b/locale/tst-locale-locpath.sh +@@ -0,0 +1,83 @@ ++#!/bin/sh ++# Test that locale prints LOCPATH on failure. ++# Copyright (C) 2019 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++set -ex ++ ++common_objpfx=$1 ++test_wrapper_env=$2 ++run_program_env=$3 ++ ++LIBPATH="$common_objpfx" ++ ++testroot="${common_objpfx}locale/tst-locale-locpath-directory" ++cleanup () { ++ rm -rf "$testroot" ++} ++trap cleanup 0 ++ ++rm -rf "$testroot" ++mkdir -p $testroot ++ ++unset LANG ++ ++${test_wrapper_env} \ ++${run_program_env} LC_ALL=invalid-locale LOCPATH=does-not-exist \ ++${common_objpfx}elf/ld.so --library-path "$LIBPATH" \ ++ "${common_objpfx}locale/locale" \ ++ > "$testroot/stdout" 2> "$testroot/stderr" ++ ++echo "* standard error" ++cat "$testroot/stderr" ++echo "* standard output" ++cat "$testroot/stdout" ++ ++cat > "$testroot/stderr-expected" < "$testroot/stdout-expected" < +Date: Wed Apr 24 07:31:29 2019 +0200 + + locale/tst-locale-locpath: Run test only for $(run-built-tests) == yes + +diff --git a/locale/Makefile b/locale/Makefile +index 42bb36c7d374eebe..23a71321b6646c49 100644 +--- a/locale/Makefile ++++ b/locale/Makefile +@@ -28,7 +28,6 @@ routines = setlocale findlocale loadlocale loadarchive \ + localeconv nl_langinfo nl_langinfo_l mb_cur_max \ + newlocale duplocale freelocale uselocale + tests = tst-C-locale tst-locname tst-duplocale +-tests-special = $(objpfx)tst-locale-locpath.out + categories = ctype messages monetary numeric time paper name \ + address telephone measurement identification collate + aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \ +@@ -61,6 +60,10 @@ lib-modules := charmap-dir simple-hash xmalloc xstrdup \ + GPERF = gperf + GPERFFLAGS = -acCgopt -k1,2,5,9,$$ -L ANSI-C + ++ifeq ($(run-built-tests),yes) ++tests-special += $(objpfx)tst-locale-locpath.out ++endif ++ + include ../Rules + + CFLAGS-md5.c += -I../crypt diff --git a/SOURCES/glibc-rh1702539-1.patch b/SOURCES/glibc-rh1702539-1.patch new file mode 100644 index 0000000..8023b6c --- /dev/null +++ b/SOURCES/glibc-rh1702539-1.patch @@ -0,0 +1,789 @@ +This patch is a rework of the following upstream patch: + +commit 0e169691290a6d2187a4ff41495fc5678cbfdcdc +Author: Adhemerval Zanella +Date: Fri Apr 12 17:39:53 2019 -0300 + + support: Add support_capture_subprogram + + Its API is similar to support_capture_subprocess, but rather creates a + new process based on the input path and arguments. Under the hoods it + uses posix_spawn to create the new process. + + It also allows the use of other support_capture_* functions to check + for expected results and free the resources. + + Checked on x86_64-linux-gnu. + + * support/Makefile (libsupport-routines): Add support_subprocess, + xposix_spawn, xposix_spawn_file_actions_addclose, and + xposix_spawn_file_actions_adddup2. + (tst-support_capture_subprocess-ARGS): New rule. + * support/capture_subprocess.h (support_capture_subprogram): New + prototype. + * support/support_capture_subprocess.c (support_capture_subprocess): + Refactor to use support_subprocess and support_capture_poll. + (support_capture_subprogram): New function. + * support/tst-support_capture_subprocess.c (write_mode_to_str, + str_to_write_mode, test_common, parse_int, handle_restart, + do_subprocess, do_subprogram, do_multiple_tests): New functions. + (do_test): Add support_capture_subprogram tests. + * support/subprocess.h: New file. + * support/support_subprocess.c: Likewise. + * support/xposix_spawn.c: Likewise. + * support/xposix_spawn_file_actions_addclose.c: Likewise. + * support/xposix_spawn_file_actions_adddup2.c: Likewise. + * support/xspawn.h: Likewise. + + Reviewed-by: Carlos O'Donell + + + +diff -Nrup a/support/capture_subprocess.h b/support/capture_subprocess.h +--- a/support/capture_subprocess.h 2018-08-01 01:10:47.000000000 -0400 ++++ b/support/capture_subprocess.h 2019-05-16 23:37:19.903845257 -0400 +@@ -35,6 +35,12 @@ struct support_capture_subprocess + struct support_capture_subprocess support_capture_subprocess + (void (*callback) (void *), void *closure); + ++/* Issue FILE with ARGV arguments by using posix_spawn and capture standard ++ output, standard error, and the exit status. The out.buffer and err.buffer ++ are handle as support_capture_subprocess. */ ++struct support_capture_subprocess support_capture_subprogram ++ (const char *file, char *const argv[]); ++ + /* Deallocate the subprocess data captured by + support_capture_subprocess. */ + void support_capture_subprocess_free (struct support_capture_subprocess *); +diff -Nrup a/support/Makefile b/support/Makefile +--- a/support/Makefile 2019-05-16 23:36:51.066665814 -0400 ++++ b/support/Makefile 2019-05-17 10:31:24.268313761 -0400 +@@ -63,6 +63,7 @@ libsupport-routines = \ + support_record_failure \ + support_run_diff \ + support_shared_allocate \ ++ support_subprocess \ + support_test_compare_blob \ + support_test_compare_failure \ + support_test_compare_string \ +@@ -147,6 +148,9 @@ libsupport-routines = \ + xsigaction \ + xsignal \ + xsocket \ ++ xposix_spawn \ ++ xposix_spawn_file_actions_addclose \ ++ xposix_spawn_file_actions_adddup2 \ + xstrdup \ + xstrndup \ + xsymlink \ +@@ -221,4 +225,6 @@ endif + + $(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so + ++tst-support_capture_subprocess-ARGS = -- $(host-test-program-cmd) ++ + include ../Rules +diff -Nrup a/support/subprocess.h b/support/subprocess.h +--- a/support/subprocess.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/subprocess.h 2019-05-16 23:37:19.903845257 -0400 +@@ -0,0 +1,49 @@ ++/* Create a subprocess. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_SUBPROCESS_H ++#define SUPPORT_SUBPROCESS_H ++ ++#include ++ ++struct support_subprocess ++{ ++ int stdout_pipe[2]; ++ int stderr_pipe[2]; ++ pid_t pid; ++}; ++ ++/* Invoke CALLBACK (CLOSURE) in a subprocess created with fork and return ++ its PID, a pipe redirected to STDOUT, and a pipe redirected to STDERR. */ ++struct support_subprocess support_subprocess ++ (void (*callback) (void *), void *closure); ++ ++/* Issue FILE with ARGV arguments by using posix_spawn and return is PID, a ++ pipe redirected to STDOUT, and a pipe redirected to STDERR. */ ++struct support_subprocess support_subprogram ++ (const char *file, char *const argv[]); ++ ++/* Wait for the subprocess indicated by PROC::PID. Return the status ++ indicate by waitpid call. */ ++int support_process_wait (struct support_subprocess *proc); ++ ++/* Terminate the subprocess indicated by PROC::PID, first with a SIGTERM and ++ then with a SIGKILL. Return the status as for waitpid call. */ ++int support_process_terminate (struct support_subprocess *proc); ++ ++#endif +diff -Nrup a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +--- a/support/support_capture_subprocess.c 2019-05-16 23:36:50.672677025 -0400 ++++ b/support/support_capture_subprocess.c 2019-05-16 23:38:34.298728367 -0400 +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + + #include +@@ -23,6 +24,7 @@ + #include + #include + #include ++#include + + static void + transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream) +@@ -50,59 +52,52 @@ transfer (const char *what, struct pollf + } + } + +-struct support_capture_subprocess +-support_capture_subprocess (void (*callback) (void *), void *closure) ++static void ++support_capture_poll (struct support_capture_subprocess *result, ++ struct support_subprocess *proc) + { +- struct support_capture_subprocess result; +- xopen_memstream (&result.out); +- xopen_memstream (&result.err); +- +- int stdout_pipe[2]; +- xpipe (stdout_pipe); +- TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO); +- TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO); +- int stderr_pipe[2]; +- xpipe (stderr_pipe); +- TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO); +- TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO); +- +- TEST_VERIFY (fflush (stdout) == 0); +- TEST_VERIFY (fflush (stderr) == 0); +- +- pid_t pid = xfork (); +- if (pid == 0) +- { +- xclose (stdout_pipe[0]); +- xclose (stderr_pipe[0]); +- xdup2 (stdout_pipe[1], STDOUT_FILENO); +- xdup2 (stderr_pipe[1], STDERR_FILENO); +- xclose (stdout_pipe[1]); +- xclose (stderr_pipe[1]); +- callback (closure); +- _exit (0); +- } +- xclose (stdout_pipe[1]); +- xclose (stderr_pipe[1]); +- + struct pollfd fds[2] = + { +- { .fd = stdout_pipe[0], .events = POLLIN }, +- { .fd = stderr_pipe[0], .events = POLLIN }, ++ { .fd = proc->stdout_pipe[0], .events = POLLIN }, ++ { .fd = proc->stderr_pipe[0], .events = POLLIN }, + }; + + do + { + xpoll (fds, 2, -1); +- transfer ("stdout", &fds[0], &result.out); +- transfer ("stderr", &fds[1], &result.err); ++ transfer ("stdout", &fds[0], &result->out); ++ transfer ("stderr", &fds[1], &result->err); + } + while (fds[0].events != 0 || fds[1].events != 0); +- xclose (stdout_pipe[0]); +- xclose (stderr_pipe[0]); ++ xfclose_memstream (&result->out); ++ xfclose_memstream (&result->err); ++ ++ result->status = support_process_wait (proc); ++} ++ ++struct support_capture_subprocess ++support_capture_subprocess (void (*callback) (void *), void *closure) ++{ ++ struct support_capture_subprocess result; ++ xopen_memstream (&result.out); ++ xopen_memstream (&result.err); ++ ++ struct support_subprocess proc = support_subprocess (callback, closure); ++ ++ support_capture_poll (&result, &proc); ++ return result; ++} ++ ++struct support_capture_subprocess ++support_capture_subprogram (const char *file, char *const argv[]) ++{ ++ struct support_capture_subprocess result; ++ xopen_memstream (&result.out); ++ xopen_memstream (&result.err); ++ ++ struct support_subprocess proc = support_subprogram (file, argv); + +- xfclose_memstream (&result.out); +- xfclose_memstream (&result.err); +- xwaitpid (pid, &result.status, 0); ++ support_capture_poll (&result, &proc); + return result; + } + +diff -Nrup a/support/support_subprocess.c b/support/support_subprocess.c +--- a/support/support_subprocess.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/support_subprocess.c 2019-05-16 23:37:19.903845257 -0400 +@@ -0,0 +1,152 @@ ++/* Create subprocess. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct support_subprocess ++support_suprocess_init (void) ++{ ++ struct support_subprocess result; ++ ++ xpipe (result.stdout_pipe); ++ TEST_VERIFY (result.stdout_pipe[0] > STDERR_FILENO); ++ TEST_VERIFY (result.stdout_pipe[1] > STDERR_FILENO); ++ ++ xpipe (result.stderr_pipe); ++ TEST_VERIFY (result.stderr_pipe[0] > STDERR_FILENO); ++ TEST_VERIFY (result.stderr_pipe[1] > STDERR_FILENO); ++ ++ TEST_VERIFY (fflush (stdout) == 0); ++ TEST_VERIFY (fflush (stderr) == 0); ++ ++ return result; ++} ++ ++struct support_subprocess ++support_subprocess (void (*callback) (void *), void *closure) ++{ ++ struct support_subprocess result = support_suprocess_init (); ++ ++ result.pid = xfork (); ++ if (result.pid == 0) ++ { ++ xclose (result.stdout_pipe[0]); ++ xclose (result.stderr_pipe[0]); ++ xdup2 (result.stdout_pipe[1], STDOUT_FILENO); ++ xdup2 (result.stderr_pipe[1], STDERR_FILENO); ++ xclose (result.stdout_pipe[1]); ++ xclose (result.stderr_pipe[1]); ++ callback (closure); ++ _exit (0); ++ } ++ xclose (result.stdout_pipe[1]); ++ xclose (result.stderr_pipe[1]); ++ ++ return result; ++} ++ ++struct support_subprocess ++support_subprogram (const char *file, char *const argv[]) ++{ ++ struct support_subprocess result = support_suprocess_init (); ++ ++ posix_spawn_file_actions_t fa; ++ /* posix_spawn_file_actions_init does not fail. */ ++ posix_spawn_file_actions_init (&fa); ++ ++ xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[0]); ++ xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[0]); ++ xposix_spawn_file_actions_adddup2 (&fa, result.stdout_pipe[1], STDOUT_FILENO); ++ xposix_spawn_file_actions_adddup2 (&fa, result.stderr_pipe[1], STDERR_FILENO); ++ xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[1]); ++ xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[1]); ++ ++ result.pid = xposix_spawn (file, &fa, NULL, argv, NULL); ++ ++ xclose (result.stdout_pipe[1]); ++ xclose (result.stderr_pipe[1]); ++ ++ return result; ++} ++ ++int ++support_process_wait (struct support_subprocess *proc) ++{ ++ xclose (proc->stdout_pipe[0]); ++ xclose (proc->stderr_pipe[0]); ++ ++ int status; ++ xwaitpid (proc->pid, &status, 0); ++ return status; ++} ++ ++ ++static bool ++support_process_kill (int pid, int signo, int *status) ++{ ++ /* Kill the whole process group. */ ++ kill (-pid, signo); ++ /* In case setpgid failed in the child, kill it individually too. */ ++ kill (pid, signo); ++ ++ /* Wait for it to terminate. */ ++ pid_t killed; ++ for (int i = 0; i < 5; ++i) ++ { ++ int status; ++ killed = xwaitpid (pid, &status, WNOHANG|WUNTRACED); ++ if (killed != 0) ++ break; ++ ++ /* Delay, give the system time to process the kill. If the ++ nanosleep() call return prematurely, all the better. We ++ won't restart it since this probably means the child process ++ finally died. */ ++ nanosleep (&((struct timespec) { 0, 100000000 }), NULL); ++ } ++ if (killed != 0 && killed != pid) ++ return false; ++ ++ return true; ++} ++ ++int ++support_process_terminate (struct support_subprocess *proc) ++{ ++ xclose (proc->stdout_pipe[0]); ++ xclose (proc->stderr_pipe[0]); ++ ++ int status; ++ pid_t killed = xwaitpid (proc->pid, &status, WNOHANG|WUNTRACED); ++ if (killed != 0 && killed == proc->pid) ++ return status; ++ ++ /* Subprocess is still running, terminate it. */ ++ if (!support_process_kill (proc->pid, SIGTERM, &status) ) ++ support_process_kill (proc->pid, SIGKILL, &status); ++ ++ return status; ++} +diff -Nrup a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c +--- a/support/tst-support_capture_subprocess.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/support/tst-support_capture_subprocess.c 2019-05-16 23:37:19.904845228 -0400 +@@ -23,8 +23,20 @@ + #include + #include + #include ++#include + #include + #include ++#include ++#include ++#include ++#include ++#include ++ ++/* Nonzero if the program gets called via 'exec'. */ ++static int restart; ++ ++/* Hold the four initial argument used to respawn the process. */ ++static char *initial_argv[5]; + + /* Write one byte at *P to FD and advance *P. Do nothing if *P is + '\0'. */ +@@ -42,6 +54,30 @@ transfer (const unsigned char **p, int f + enum write_mode { out_first, err_first, interleave, + write_mode_last = interleave }; + ++static const char * ++write_mode_to_str (enum write_mode mode) ++{ ++ switch (mode) ++ { ++ case out_first: return "out_first"; ++ case err_first: return "err_first"; ++ case interleave: return "interleave"; ++ default: return "write_mode_last"; ++ } ++} ++ ++static enum write_mode ++str_to_write_mode (const char *mode) ++{ ++ if (strcmp (mode, "out_first") == 0) ++ return out_first; ++ else if (strcmp (mode, "err_first") == 0) ++ return err_first; ++ else if (strcmp (mode, "interleave") == 0) ++ return interleave; ++ return write_mode_last; ++} ++ + /* Describe what to write in the subprocess. */ + struct test + { +@@ -52,11 +88,9 @@ struct test + int status; + }; + +-/* For use with support_capture_subprocess. */ +-static void +-callback (void *closure) ++_Noreturn static void ++test_common (const struct test *test) + { +- const struct test *test = closure; + bool mode_ok = false; + switch (test->write_mode) + { +@@ -95,6 +129,40 @@ callback (void *closure) + exit (test->status); + } + ++static int ++parse_int (const char *str) ++{ ++ char *endptr; ++ long int ret = strtol (str, &endptr, 10); ++ TEST_COMPARE (errno, 0); ++ TEST_VERIFY (ret >= 0 && ret <= INT_MAX); ++ return ret; ++} ++ ++/* For use with support_capture_subprogram. */ ++_Noreturn static void ++handle_restart (char *out, char *err, const char *write_mode, ++ const char *signal, const char *status) ++{ ++ struct test test = ++ { ++ out, ++ err, ++ str_to_write_mode (write_mode), ++ parse_int (signal), ++ parse_int (status) ++ }; ++ test_common (&test); ++} ++ ++/* For use with support_capture_subprocess. */ ++_Noreturn static void ++callback (void *closure) ++{ ++ const struct test *test = closure; ++ test_common (test); ++} ++ + /* Create a heap-allocated random string of letters. */ + static char * + random_string (size_t length) +@@ -130,12 +198,59 @@ check_stream (const char *what, const st + } + } + ++static struct support_capture_subprocess ++do_subprocess (struct test *test) ++{ ++ return support_capture_subprocess (callback, test); ++} ++ ++static struct support_capture_subprocess ++do_subprogram (const struct test *test) ++{ ++ /* Three digits per byte plus null terminator. */ ++ char signalstr[3 * sizeof(int) + 1]; ++ snprintf (signalstr, sizeof (signalstr), "%d", test->signal); ++ char statusstr[3 * sizeof(int) + 1]; ++ snprintf (statusstr, sizeof (statusstr), "%d", test->status); ++ ++ int argc = 0; ++ enum { ++ /* 4 elements from initial_argv (path to ld.so, '--library-path', the ++ path', and application name'), 2 for restart argument ('--direct', ++ '--restart'), 5 arguments plus NULL. */ ++ argv_size = 12 ++ }; ++ char *args[argv_size]; ++ ++ for (char **arg = initial_argv; *arg != NULL; arg++) ++ args[argc++] = *arg; ++ ++ args[argc++] = (char*) "--direct"; ++ args[argc++] = (char*) "--restart"; ++ ++ args[argc++] = test->out; ++ args[argc++] = test->err; ++ args[argc++] = (char*) write_mode_to_str (test->write_mode); ++ args[argc++] = signalstr; ++ args[argc++] = statusstr; ++ args[argc] = NULL; ++ TEST_VERIFY (argc < argv_size); ++ ++ return support_capture_subprogram (args[0], args); ++} ++ ++enum test_type ++{ ++ subprocess, ++ subprogram, ++}; ++ + static int +-do_test (void) ++do_multiple_tests (enum test_type type) + { + const int lengths[] = {0, 1, 17, 512, 20000, -1}; + +- /* Test multiple combinations of support_capture_subprocess. ++ /* Test multiple combinations of support_capture_sub{process,program}. + + length_idx_stdout: Index into the lengths array above, + controls how many bytes are written by the subprocess to +@@ -164,8 +279,10 @@ do_test (void) + TEST_VERIFY (strlen (test.out) == lengths[length_idx_stdout]); + TEST_VERIFY (strlen (test.err) == lengths[length_idx_stderr]); + +- struct support_capture_subprocess result +- = support_capture_subprocess (callback, &test); ++ struct support_capture_subprocess result ++ = type == subprocess ? do_subprocess (&test) ++ : do_subprogram (&test); ++ + check_stream ("stdout", &result.out, test.out); + check_stream ("stderr", &result.err, test.err); + if (test.signal != 0) +@@ -185,4 +302,54 @@ do_test (void) + return 0; + } + ++static int ++do_test (int argc, char *argv[]) ++{ ++ /* We must have either: ++ ++ - one or four parameters if called initially: ++ + argv[1]: path for ld.so optional ++ + argv[2]: "--library-path" optional ++ + argv[3]: the library path optional ++ + argv[4]: the application name ++ ++ - six parameters left if called through re-execution: ++ + argv[1]: the application name ++ + argv[2]: the stdout to print ++ + argv[3]: the stderr to print ++ + argv[4]: the write mode to use ++ + argv[5]: the signal to issue ++ + argv[6]: the exit status code to use ++ ++ * When built with --enable-hardcoded-path-in-tests or issued without ++ using the loader directly. ++ */ ++ ++ if (argc != (restart ? 6 : 5) && argc != (restart ? 6 : 2)) ++ FAIL_EXIT1 ("wrong number of arguments (%d)", argc); ++ ++ if (restart) ++ { ++ handle_restart (argv[1], /* stdout */ ++ argv[2], /* stderr */ ++ argv[3], /* write_mode */ ++ argv[4], /* signal */ ++ argv[5]); /* status */ ++ } ++ ++ initial_argv[0] = argv[1]; /* path for ld.so */ ++ initial_argv[1] = argv[2]; /* "--library-path" */ ++ initial_argv[2] = argv[3]; /* the library path */ ++ initial_argv[3] = argv[4]; /* the application name */ ++ initial_argv[4] = NULL; ++ ++ do_multiple_tests (subprocess); ++ do_multiple_tests (subprogram); ++ ++ return 0; ++} ++ ++#define CMDLINE_OPTIONS \ ++ { "restart", no_argument, &restart, 1 }, ++#define TEST_FUNCTION_ARGV do_test + #include +diff -Nrup a/support/xposix_spawn.c b/support/xposix_spawn.c +--- a/support/xposix_spawn.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xposix_spawn.c 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,32 @@ ++/* xposix_spawn implementation. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++pid_t ++xposix_spawn (const char *file, const posix_spawn_file_actions_t *fa, ++ const posix_spawnattr_t *attr, char *const args[], ++ char *const envp[]) ++{ ++ pid_t pid; ++ int status = posix_spawn (&pid, file, fa, attr, args, envp); ++ if (status != 0) ++ FAIL_EXIT1 ("posix_spawn to %s file failed: %m", file); ++ return pid; ++} +diff -Nrup a/support/xposix_spawn_file_actions_addclose.c b/support/xposix_spawn_file_actions_addclose.c +--- a/support/xposix_spawn_file_actions_addclose.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xposix_spawn_file_actions_addclose.c 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,29 @@ ++/* xposix_spawn_file_actions_addclose implementation. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *fa, int fd) ++{ ++ int status = posix_spawn_file_actions_addclose (fa, fd); ++ if (status == -1) ++ FAIL_EXIT1 ("posix_spawn_file_actions_addclose failed: %m\n"); ++ return status; ++} +diff -Nrup a/support/xposix_spawn_file_actions_adddup2.c b/support/xposix_spawn_file_actions_adddup2.c +--- a/support/xposix_spawn_file_actions_adddup2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xposix_spawn_file_actions_adddup2.c 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,30 @@ ++/* xposix_spawn_file_actions_adddup2 implementation. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *fa, int fd, ++ int newfd) ++{ ++ int status = posix_spawn_file_actions_adddup2 (fa, fd, newfd); ++ if (status == -1) ++ FAIL_EXIT1 ("posix_spawn_file_actions_adddup2 failed: %m\n"); ++ return status; ++} +diff -Nrup a/support/xspawn.h b/support/xspawn.h +--- a/support/xspawn.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xspawn.h 2019-05-16 23:37:19.904845228 -0400 +@@ -0,0 +1,34 @@ ++/* posix_spawn with support checks. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_XSPAWN_H ++#define SUPPORT_XSPAWN_H ++ ++#include ++ ++__BEGIN_DECLS ++ ++int xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *, int); ++int xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *, int, int); ++ ++pid_t xposix_spawn (const char *, const posix_spawn_file_actions_t *, ++ const posix_spawnattr_t *, char *const [], char *const []); ++ ++__END_DECLS ++ ++#endif diff --git a/SOURCES/glibc-rh1702539-2.patch b/SOURCES/glibc-rh1702539-2.patch new file mode 100644 index 0000000..1c1b8bb --- /dev/null +++ b/SOURCES/glibc-rh1702539-2.patch @@ -0,0 +1,558 @@ +This patch is a rework of the following upstream patch: + +commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f +Author: Adhemerval Zanella +Date: Thu Apr 11 18:12:00 2019 -0300 + + elf: Fix pldd (BZ#18035) + + Since 9182aa67994 (Fix vDSO l_name for GDB's, BZ#387) the initial link_map + for executable itself and loader will have both l_name and l_libname->name + holding the same value due: + + elf/dl-object.c + + 95 new->l_name = *realname ? realname : (char *) newname->name + libname_len - 1; + + Since newname->name points to new->l_libname->name. + + This leads to pldd to an infinite call at: + + elf/pldd-xx.c + + 203 again: + 204 while (1) + 205 { + 206 ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset); + + 228 /* Try the l_libname element. */ + 229 struct E(libname_list) ln; + 230 if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln)) + 231 { + 232 name_offset = ln.name; + 233 goto again; + 234 } + + Since the value at ln.name (l_libname->name) will be the same as previously + read. The straightforward fix is just avoid the check and read the new list + entry. + + I checked also against binaries issues with old loaders with fix for BZ#387, + and pldd could dump the shared objects. + + Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, and + powerpc64le-linux-gnu. + +diff -Nrup a/elf/Makefile b/elf/Makefile +--- a/elf/Makefile 2019-05-17 12:35:12.663074766 -0400 ++++ b/elf/Makefile 2019-05-17 12:35:45.816147975 -0400 +@@ -201,6 +201,7 @@ tests-internal += loadtest unload unload + neededtest neededtest2 neededtest3 neededtest4 \ + tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \ + tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym ++tests-container += tst-pldd + ifeq ($(build-hardcoded-path-in-tests),yes) + tests += tst-dlopen-aout + tst-dlopen-aout-no-pie = yes +diff -Nrup a/elf/pldd.c b/elf/pldd.c +--- a/elf/pldd.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/elf/pldd.c 2019-05-17 12:35:45.817147947 -0400 +@@ -17,23 +17,17 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#define _FILE_OFFSET_BITS 64 ++ + #include +-#include + #include +-#include +-#include + #include + #include + #include +-#include +-#include + #include + #include +-#include + #include + #include +-#include + #include + #include + +@@ -76,14 +70,8 @@ static struct argp argp = + options, parse_opt, args_doc, doc, NULL, more_help, NULL + }; + +-// File descriptor of /proc/*/mem file. +-static int memfd; +- +-/* Name of the executable */ +-static char *exe; +- + /* Local functions. */ +-static int get_process_info (int dfd, long int pid); ++static int get_process_info (const char *exe, int dfd, long int pid); + static void wait_for_ptrace_stop (long int pid); + + +@@ -102,8 +90,10 @@ main (int argc, char *argv[]) + return 1; + } + +- assert (sizeof (pid_t) == sizeof (int) +- || sizeof (pid_t) == sizeof (long int)); ++ _Static_assert (sizeof (pid_t) == sizeof (int) ++ || sizeof (pid_t) == sizeof (long int), ++ "sizeof (pid_t) != sizeof (int) or sizeof (long int)"); ++ + char *endp; + errno = 0; + long int pid = strtol (argv[remaining], &endp, 10); +@@ -119,25 +109,24 @@ main (int argc, char *argv[]) + if (dfd == -1) + error (EXIT_FAILURE, errno, gettext ("cannot open %s"), buf); + +- struct scratch_buffer exebuf; +- scratch_buffer_init (&exebuf); ++ /* Name of the executable */ ++ struct scratch_buffer exe; ++ scratch_buffer_init (&exe); + ssize_t nexe; + while ((nexe = readlinkat (dfd, "exe", +- exebuf.data, exebuf.length)) == exebuf.length) ++ exe.data, exe.length)) == exe.length) + { +- if (!scratch_buffer_grow (&exebuf)) ++ if (!scratch_buffer_grow (&exe)) + { + nexe = -1; + break; + } + } + if (nexe == -1) +- exe = (char *) ""; ++ /* Default stack allocation is at least 1024. */ ++ snprintf (exe.data, exe.length, ""); + else +- { +- exe = exebuf.data; +- exe[nexe] = '\0'; +- } ++ ((char*)exe.data)[nexe] = '\0'; + + /* Stop all threads since otherwise the list of loaded modules might + change while we are reading it. */ +@@ -155,8 +144,8 @@ main (int argc, char *argv[]) + error (EXIT_FAILURE, errno, gettext ("cannot prepare reading %s/task"), + buf); + +- struct dirent64 *d; +- while ((d = readdir64 (dir)) != NULL) ++ struct dirent *d; ++ while ((d = readdir (dir)) != NULL) + { + if (! isdigit (d->d_name[0])) + continue; +@@ -182,7 +171,7 @@ main (int argc, char *argv[]) + + wait_for_ptrace_stop (tid); + +- struct thread_list *newp = alloca (sizeof (*newp)); ++ struct thread_list *newp = xmalloc (sizeof (*newp)); + newp->tid = tid; + newp->next = thread_list; + thread_list = newp; +@@ -190,17 +179,22 @@ main (int argc, char *argv[]) + + closedir (dir); + +- int status = get_process_info (dfd, pid); ++ if (thread_list == NULL) ++ error (EXIT_FAILURE, 0, gettext ("no valid %s/task entries"), buf); ++ ++ int status = get_process_info (exe.data, dfd, pid); + +- assert (thread_list != NULL); + do + { + ptrace (PTRACE_DETACH, thread_list->tid, NULL, NULL); ++ struct thread_list *prev = thread_list; + thread_list = thread_list->next; ++ free (prev); + } + while (thread_list != NULL); + + close (dfd); ++ scratch_buffer_free (&exe); + + return status; + } +@@ -281,9 +275,10 @@ warranty; not even for MERCHANTABILITY o + + + static int +-get_process_info (int dfd, long int pid) ++get_process_info (const char *exe, int dfd, long int pid) + { +- memfd = openat (dfd, "mem", O_RDONLY); ++ /* File descriptor of /proc//mem file. */ ++ int memfd = openat (dfd, "mem", O_RDONLY); + if (memfd == -1) + goto no_info; + +@@ -333,9 +328,9 @@ get_process_info (int dfd, long int pid) + + int retval; + if (e_ident[EI_CLASS] == ELFCLASS32) +- retval = find_maps32 (pid, auxv, auxv_size); ++ retval = find_maps32 (exe, memfd, pid, auxv, auxv_size); + else +- retval = find_maps64 (pid, auxv, auxv_size); ++ retval = find_maps64 (exe, memfd, pid, auxv, auxv_size); + + free (auxv); + close (memfd); +diff -Nrup a/elf/pldd-xx.c b/elf/pldd-xx.c +--- a/elf/pldd-xx.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/elf/pldd-xx.c 2019-05-17 13:05:29.587147445 -0400 +@@ -23,10 +23,6 @@ + #define EW_(e, w, t) EW__(e, w, _##t) + #define EW__(e, w, t) e##w##t + +-#define pldd_assert(name, exp) \ +- typedef int __assert_##name[((exp) != 0) - 1] +- +- + struct E(link_map) + { + EW(Addr) l_addr; +@@ -39,12 +35,12 @@ struct E(link_map) + EW(Addr) l_libname; + }; + #if CLASS == __ELF_NATIVE_CLASS +-pldd_assert (l_addr, (offsetof (struct link_map, l_addr) +- == offsetof (struct E(link_map), l_addr))); +-pldd_assert (l_name, (offsetof (struct link_map, l_name) +- == offsetof (struct E(link_map), l_name))); +-pldd_assert (l_next, (offsetof (struct link_map, l_next) +- == offsetof (struct E(link_map), l_next))); ++_Static_assert (offsetof (struct link_map, l_addr) ++ == offsetof (struct E(link_map), l_addr), "l_addr"); ++_Static_assert (offsetof (struct link_map, l_name) ++ == offsetof (struct E(link_map), l_name), "l_name"); ++_Static_assert (offsetof (struct link_map, l_next) ++ == offsetof (struct E(link_map), l_next), "l_next"); + #endif + + +@@ -54,10 +50,10 @@ struct E(libname_list) + EW(Addr) next; + }; + #if CLASS == __ELF_NATIVE_CLASS +-pldd_assert (name, (offsetof (struct libname_list, name) +- == offsetof (struct E(libname_list), name))); +-pldd_assert (next, (offsetof (struct libname_list, next) +- == offsetof (struct E(libname_list), next))); ++_Static_assert (offsetof (struct libname_list, name) ++ == offsetof (struct E(libname_list), name), "name"); ++_Static_assert (offsetof (struct libname_list, next) ++ == offsetof (struct E(libname_list), next), "next"); + #endif + + struct E(r_debug) +@@ -69,16 +65,17 @@ struct E(r_debug) + EW(Addr) r_map; + }; + #if CLASS == __ELF_NATIVE_CLASS +-pldd_assert (r_version, (offsetof (struct r_debug, r_version) +- == offsetof (struct E(r_debug), r_version))); +-pldd_assert (r_map, (offsetof (struct r_debug, r_map) +- == offsetof (struct E(r_debug), r_map))); ++_Static_assert (offsetof (struct r_debug, r_version) ++ == offsetof (struct E(r_debug), r_version), "r_version"); ++_Static_assert (offsetof (struct r_debug, r_map) ++ == offsetof (struct E(r_debug), r_map), "r_map"); + #endif + + + static int + +-E(find_maps) (pid_t pid, void *auxv, size_t auxv_size) ++E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, ++ size_t auxv_size) + { + EW(Addr) phdr = 0; + unsigned int phnum = 0; +@@ -104,12 +101,9 @@ E(find_maps) (pid_t pid, void *auxv, siz + if (phdr == 0 || phnum == 0 || phent == 0) + error (EXIT_FAILURE, 0, gettext ("cannot find program header of process")); + +- EW(Phdr) *p = alloca (phnum * phent); +- if (pread64 (memfd, p, phnum * phent, phdr) != phnum * phent) +- { +- error (0, 0, gettext ("cannot read program header")); +- return EXIT_FAILURE; +- } ++ EW(Phdr) *p = xmalloc (phnum * phent); ++ if (pread (memfd, p, phnum * phent, phdr) != phnum * phent) ++ error (EXIT_FAILURE, 0, gettext ("cannot read program header")); + + /* Determine the load offset. We need this for interpreting the + other program header entries so we do this in a separate loop. +@@ -129,24 +123,18 @@ E(find_maps) (pid_t pid, void *auxv, siz + if (p[i].p_type == PT_DYNAMIC) + { + EW(Dyn) *dyn = xmalloc (p[i].p_filesz); +- if (pread64 (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr) ++ if (pread (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr) + != p[i].p_filesz) +- { +- error (0, 0, gettext ("cannot read dynamic section")); +- return EXIT_FAILURE; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); + + /* Search for the DT_DEBUG entry. */ + for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) + if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) + { + struct E(r_debug) r; +- if (pread64 (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) ++ if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) + != sizeof (r)) +- { +- error (0, 0, gettext ("cannot read r_debug")); +- return EXIT_FAILURE; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); + + if (r.r_map != 0) + { +@@ -160,13 +148,10 @@ E(find_maps) (pid_t pid, void *auxv, siz + } + else if (p[i].p_type == PT_INTERP) + { +- interp = alloca (p[i].p_filesz); +- if (pread64 (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr) ++ interp = xmalloc (p[i].p_filesz); ++ if (pread (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr) + != p[i].p_filesz) +- { +- error (0, 0, gettext ("cannot read program interpreter")); +- return EXIT_FAILURE; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read program interpreter")); + } + + if (list == 0) +@@ -174,14 +159,16 @@ E(find_maps) (pid_t pid, void *auxv, siz + if (interp == NULL) + { + // XXX check whether the executable itself is the loader +- return EXIT_FAILURE; ++ exit (EXIT_FAILURE); + } + + // XXX perhaps try finding ld.so and _r_debug in it +- +- return EXIT_FAILURE; ++ exit (EXIT_FAILURE); + } + ++ free (p); ++ free (interp); ++ + /* Print the PID and program name first. */ + printf ("%lu:\t%s\n", (unsigned long int) pid, exe); + +@@ -192,47 +179,27 @@ E(find_maps) (pid_t pid, void *auxv, siz + do + { + struct E(link_map) m; +- if (pread64 (memfd, &m, sizeof (m), list) != sizeof (m)) +- { +- error (0, 0, gettext ("cannot read link map")); +- status = EXIT_FAILURE; +- goto out; +- } ++ if (pread (memfd, &m, sizeof (m), list) != sizeof (m)) ++ error (EXIT_FAILURE, 0, gettext ("cannot read link map")); + + EW(Addr) name_offset = m.l_name; +- again: + while (1) + { +- ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset); ++ ssize_t n = pread (memfd, tmpbuf.data, tmpbuf.length, name_offset); + if (n == -1) +- { +- error (0, 0, gettext ("cannot read object name")); +- status = EXIT_FAILURE; +- goto out; +- } ++ error (EXIT_FAILURE, 0, gettext ("cannot read object name")); + + if (memchr (tmpbuf.data, '\0', n) != NULL) + break; + + if (!scratch_buffer_grow (&tmpbuf)) +- { +- error (0, 0, gettext ("cannot allocate buffer for object name")); +- status = EXIT_FAILURE; +- goto out; +- } ++ error (EXIT_FAILURE, 0, ++ gettext ("cannot allocate buffer for object name")); + } + +- if (((char *)tmpbuf.data)[0] == '\0' && name_offset == m.l_name +- && m.l_libname != 0) +- { +- /* Try the l_libname element. */ +- struct E(libname_list) ln; +- if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln)) +- { +- name_offset = ln.name; +- goto again; +- } +- } ++ /* The m.l_name and m.l_libname.name for loader linkmap points to same ++ values (since BZ#387 fix). Trying to use l_libname name as the ++ shared object name might lead to an infinite loop (BZ#18035). */ + + /* Skip over the executable. */ + if (((char *)tmpbuf.data)[0] != '\0') +@@ -242,7 +209,6 @@ E(find_maps) (pid_t pid, void *auxv, siz + } + while (list != 0); + +- out: + scratch_buffer_free (&tmpbuf); + return status; + } +diff -Nrup a/elf/tst-pldd.c b/elf/tst-pldd.c +--- a/elf/tst-pldd.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/elf/tst-pldd.c 2019-05-17 12:35:45.817147947 -0400 +@@ -0,0 +1,118 @@ ++/* Basic tests for pldd program. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++static void ++target_process (void *arg) ++{ ++ pause (); ++} ++ ++/* The test runs in a container because pldd does not support tracing ++ a binary started by the loader iself (as with testrun.sh). */ ++ ++static int ++do_test (void) ++{ ++ /* Create a copy of current test to check with pldd. */ ++ struct support_subprocess target = support_subprocess (target_process, NULL); ++ ++ /* Run 'pldd' on test subprocess. */ ++ struct support_capture_subprocess pldd; ++ { ++ /* Three digits per byte plus null terminator. */ ++ char pid[3 * sizeof (uint32_t) + 1]; ++ snprintf (pid, array_length (pid), "%d", target.pid); ++ ++ const char prog[] = "/usr/bin/pldd"; ++ ++ pldd = support_capture_subprogram (prog, ++ (char *const []) { (char *) prog, pid, NULL }); ++ ++ support_capture_subprocess_check (&pldd, "pldd", 0, sc_allow_stdout); ++ } ++ ++ /* Check 'pldd' output. The test is expected to be linked against only ++ loader and libc. */ ++ { ++ pid_t pid; ++ char buffer[512]; ++#define STRINPUT(size) "%" # size "s" ++ ++ FILE *out = fmemopen (pldd.out.buffer, pldd.out.length, "r"); ++ TEST_VERIFY (out != NULL); ++ ++ /* First line is in the form of : */ ++ TEST_COMPARE (fscanf (out, "%u: " STRINPUT (512), &pid, buffer), 2); ++ ++ TEST_COMPARE (pid, target.pid); ++ TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0); ++ ++ /* It expects only one loader and libc loaded by the program. */ ++ bool interpreter_found = false, libc_found = false; ++ while (fgets (buffer, array_length (buffer), out) != NULL) ++ { ++ /* Ignore vDSO. */ ++ if (buffer[0] != '/') ++ continue; ++ ++ /* Remove newline so baseline (buffer) can compare against the ++ LD_SO and LIBC_SO macros unmodified. */ ++ if (buffer[strlen(buffer)-1] == '\n') ++ buffer[strlen(buffer)-1] = '\0'; ++ ++ if (strcmp (basename (buffer), LD_SO) == 0) ++ { ++ TEST_COMPARE (interpreter_found, false); ++ interpreter_found = true; ++ continue; ++ } ++ ++ if (strcmp (basename (buffer), LIBC_SO) == 0) ++ { ++ TEST_COMPARE (libc_found, false); ++ libc_found = true; ++ continue; ++ } ++ } ++ TEST_COMPARE (interpreter_found, true); ++ TEST_COMPARE (libc_found, true); ++ ++ fclose (out); ++ } ++ ++ support_capture_subprocess_free (&pldd); ++ support_process_terminate (&target); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1706777.patch b/SOURCES/glibc-rh1706777.patch new file mode 100644 index 0000000..9e64daa --- /dev/null +++ b/SOURCES/glibc-rh1706777.patch @@ -0,0 +1,44 @@ +commit 38b0593e9a862c3b35392a0f5b202696b8116aa3 +Author: Tobias Klauser +Date: Tue Aug 21 17:22:53 2018 +0000 + + Add PF_XDP, AF_XDP and SOL_XDP from Linux 4.18 to bits/socket.h. + + This patch adds the PF_XDP, AF_XDP and SOL_XDP macros from Linux 4.18 to + sysdeps/unix/sysv/linux/bits/socket.h. + + * sysdeps/unix/sysv/linux/bits/socket.h (PF_MAX): Set to 45. + (PF_XDP): New macro. + (AF_XDP): New macro. + (SOL_XDP): New macro. + +diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +index fa409f0fabc22d33..c3fbb2110296273c 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -85,7 +85,8 @@ typedef __socklen_t socklen_t; + #define PF_KCM 41 /* Kernel Connection Multiplexor. */ + #define PF_QIPCRTR 42 /* Qualcomm IPC Router. */ + #define PF_SMC 43 /* SMC sockets. */ +-#define PF_MAX 44 /* For now.. */ ++#define PF_XDP 44 /* XDP sockets. */ ++#define PF_MAX 45 /* For now.. */ + + /* Address families. */ + #define AF_UNSPEC PF_UNSPEC +@@ -135,6 +136,7 @@ typedef __socklen_t socklen_t; + #define AF_KCM PF_KCM + #define AF_QIPCRTR PF_QIPCRTR + #define AF_SMC PF_SMC ++#define AF_XDP PF_XDP + #define AF_MAX PF_MAX + + /* Socket level values. Others are defined in the appropriate headers. +@@ -164,6 +166,7 @@ typedef __socklen_t socklen_t; + #define SOL_NFC 280 + #define SOL_KCM 281 + #define SOL_TLS 282 ++#define SOL_XDP 283 + + /* Maximum queue length specifiable by listen. */ + #define SOMAXCONN 128 diff --git a/SOURCES/glibc-rh1710478.patch b/SOURCES/glibc-rh1710478.patch new file mode 100644 index 0000000..3546690 --- /dev/null +++ b/SOURCES/glibc-rh1710478.patch @@ -0,0 +1,107 @@ +commit 32ff397533715988c19cbf3675dcbd727ec13e18 +Author: Andreas Schwab +Date: Tue May 14 17:14:59 2019 +0200 + + Fix crash in _IO_wfile_sync (bug 20568) + + When computing the length of the converted part of the stdio buffer, use + the number of consumed wide characters, not the (negative) distance to the + end of the wide buffer. + +Conflicts: + libio/Makefile + (Usual conflict when adding tests due to missing backports.) + +diff --git a/libio/Makefile b/libio/Makefile +index cab0eae946b1f307..cbfaf3832a45fc22 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -64,7 +64,8 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ + bug-memstream1 bug-wmemstream1 \ + tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ + tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ +- tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof ++ tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \ ++ tst-wfile-sync + + tests-internal = tst-vtables tst-vtables-interposed tst-readline + +@@ -207,6 +208,7 @@ $(objpfx)tst-ungetwc1.out: $(gen-locales) + $(objpfx)tst-ungetwc2.out: $(gen-locales) + $(objpfx)tst-widetext.out: $(gen-locales) + $(objpfx)tst_wprintf2.out: $(gen-locales) ++$(objpfx)tst-wfile-sync.out: $(gen-locales) + endif + + $(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen +diff --git a/libio/tst-wfile-sync.c b/libio/tst-wfile-sync.c +new file mode 100644 +index 0000000000000000..618682064da4035c +--- /dev/null ++++ b/libio/tst-wfile-sync.c +@@ -0,0 +1,39 @@ ++/* Test that _IO_wfile_sync does not crash (bug 20568). ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ TEST_VERIFY_EXIT (setlocale (LC_ALL, "de_DE.UTF-8") != NULL); ++ /* Fill the stdio buffer and advance the read pointer. */ ++ TEST_VERIFY_EXIT (fgetwc (stdin) != WEOF); ++ /* This calls _IO_wfile_sync, it should not crash. */ ++ TEST_VERIFY_EXIT (setvbuf (stdin, NULL, _IONBF, 0) == 0); ++ /* Verify that the external file offset has been synchronized. */ ++ TEST_COMPARE (xlseek (0, 0, SEEK_CUR), 1); ++ ++ return 0; ++} ++ ++#include +diff --git a/libio/tst-wfile-sync.input b/libio/tst-wfile-sync.input +new file mode 100644 +index 0000000000000000..12d0958f7aaa3865 +--- /dev/null ++++ b/libio/tst-wfile-sync.input +@@ -0,0 +1 @@ ++This is a test of _IO_wfile_sync. +diff --git a/libio/wfileops.c b/libio/wfileops.c +index 63cb687652c72ce1..10e7343f8fdb8781 100644 +--- a/libio/wfileops.c ++++ b/libio/wfileops.c +@@ -508,11 +508,12 @@ _IO_wfile_sync (FILE *fp) + generate the wide characters up to the current reading + position. */ + int nread; +- ++ size_t wnread = (fp->_wide_data->_IO_read_ptr ++ - fp->_wide_data->_IO_read_base); + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, +- fp->_IO_read_end, delta); ++ fp->_IO_read_end, wnread); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); + } diff --git a/SOURCES/glibc-rh1710894.patch b/SOURCES/glibc-rh1710894.patch new file mode 100644 index 0000000..790d27a --- /dev/null +++ b/SOURCES/glibc-rh1710894.patch @@ -0,0 +1,310 @@ +commit a9368c34d70cef91ca59b09941f496df11d6b146 +Author: Florian Weimer +Date: Wed May 15 13:51:35 2019 +0200 + + nss: Turn __nss_database_lookup into a compatibility symbol + + The function uses the internal service_user type, so it is not + really usable from the outside of glibc. Rename the function + to __nss_database_lookup2 for internal use, and change + __nss_database_lookup to always indicate failure to the caller. + + __nss_next already was a compatibility symbol. The new + implementation always fails and no longer calls __nss_next2. + + unscd, the alternative nscd implementation, does not use + __nss_database_lookup, so it is not affected by this change. + +DJ - Added 2.30 clause to nss/Versions as RHEL 8 will always be 2.28. + +diff -rup a/grp/initgroups.c b/grp/initgroups.c +--- a/grp/initgroups.c 2019-06-06 17:15:32.184092617 -0400 ++++ b/grp/initgroups.c 2019-06-06 17:16:59.136114679 -0400 +@@ -79,12 +79,12 @@ internal_getgrouplist (const char *user, + + if (__nss_initgroups_database == NULL) + { +- if (__nss_database_lookup ("initgroups", NULL, "", +- &__nss_initgroups_database) < 0) ++ if (__nss_database_lookup2 ("initgroups", NULL, "", ++ &__nss_initgroups_database) < 0) + { + if (__nss_group_database == NULL) +- no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG, +- &__nss_group_database); ++ no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG, ++ &__nss_group_database); + + __nss_initgroups_database = __nss_group_database; + } +diff -rup a/nscd/aicache.c b/nscd/aicache.c +--- a/nscd/aicache.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nscd/aicache.c 2019-06-06 17:16:59.501114771 -0400 +@@ -93,9 +93,9 @@ addhstaiX (struct database_dyn *db, int + int herrno = 0; + + if (hosts_database == NULL) +- no_more = __nss_database_lookup ("hosts", NULL, +- "dns [!UNAVAIL=return] files", +- &hosts_database); ++ no_more = __nss_database_lookup2 ("hosts", NULL, ++ "dns [!UNAVAIL=return] files", ++ &hosts_database); + else + no_more = 0; + nip = hosts_database; +diff -rup a/nscd/initgrcache.c b/nscd/initgrcache.c +--- a/nscd/initgrcache.c 2019-06-06 17:15:32.205092622 -0400 ++++ b/nscd/initgrcache.c 2019-06-06 17:16:59.510114774 -0400 +@@ -88,8 +88,8 @@ addinitgroupsX (struct database_dyn *db, + int no_more; + + if (group_database == NULL) +- no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG, +- &group_database); ++ no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG, ++ &group_database); + else + no_more = 0; + nip = group_database; +diff -rup a/nscd/netgroupcache.c b/nscd/netgroupcache.c +--- a/nscd/netgroupcache.c 2019-06-06 17:15:32.151092608 -0400 ++++ b/nscd/netgroupcache.c 2019-06-06 17:16:59.514114775 -0400 +@@ -143,7 +143,7 @@ addgetnetgrentX (struct database_dyn *db + *tofreep = NULL; + + if (netgroup_database == NULL +- && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database)) ++ && __nss_database_lookup2 ("netgroup", NULL, NULL, &netgroup_database)) + { + /* No such service. */ + cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, +diff -rup a/nss/Versions b/nss/Versions +--- a/nss/Versions 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/Versions 2019-06-10 16:59:34.920054974 -0400 +@@ -1,21 +1,26 @@ + libc { + GLIBC_2.0 { +- # functions used in other libraries ++ __nss_configure_lookup; ++ ++ # Functions exported as no-op compat symbols. + __nss_passwd_lookup; __nss_group_lookup; __nss_hosts_lookup; __nss_next; +- __nss_database_lookup; __nss_configure_lookup; ++ __nss_database_lookup; + } + GLIBC_2.2.2 { + __nss_hostname_digits_dots; + } + GLIBC_2.27 { + } ++ GLIBC_2.30 { ++ # Added for rhbz 1710894 ++ } + GLIBC_PRIVATE { + _nss_files_parse_grent; _nss_files_parse_pwent; _nss_files_parse_spent; + __nss_disable_nscd; __nss_lookup_function; _nss_files_parse_sgent; + + __nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2; + __nss_services_lookup2; __nss_next2; __nss_lookup; +- __nss_hash; ++ __nss_hash; __nss_database_lookup2; + } + } + +diff -rup a/nss/XXX-lookup.c b/nss/XXX-lookup.c +--- a/nss/XXX-lookup.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/XXX-lookup.c 2019-06-06 17:16:59.562114786 -0400 +@@ -57,8 +57,8 @@ DB_LOOKUP_FCT (service_user **ni, const + void **fctp) + { + if (DATABASE_NAME_SYMBOL == NULL +- && __nss_database_lookup (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, +- DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0) ++ && __nss_database_lookup2 (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, ++ DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0) + return -1; + + *ni = DATABASE_NAME_SYMBOL; +diff -rup a/nss/compat-lookup.c b/nss/compat-lookup.c +--- a/nss/compat-lookup.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/compat-lookup.c 2019-06-07 22:14:09.057668330 -0400 +@@ -16,11 +16,12 @@ + License along with the GNU C Library; if not, see + . */ + ++#include ++ + #include + #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) + + # include +-# include + + /* On i386, the function calling convention changed from the standard + ABI calling convention to three register parameters in glibc 2.8. +@@ -40,3 +41,31 @@ strong_alias (__nss_passwd_lookup, __nss + compat_symbol (libc, __nss_hosts_lookup, __nss_hosts_lookup, GLIBC_2_0); + + #endif /* SHLIB_COMPAT */ ++ ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_30) ++ ++/* These functions were exported under a non-GLIBC_PRIVATE version, ++ even though it is not usable externally due to the service_user ++ type dependency. */ ++ ++int ++attribute_compat_text_section ++__nss_next (service_user **ni, const char *fct_name, void **fctp, int status, ++ int all_values) ++{ ++ return -1; ++} ++compat_symbol (libc, __nss_next, __nss_next, GLIBC_2_0); ++ ++int ++attribute_compat_text_section ++__nss_database_lookup (const char *database, const char *alternate_name, ++ const char *defconfig, service_user **ni) ++{ ++ *ni = NULL; ++ return -1; ++} ++compat_symbol (libc, __nss_database_lookup, __nss_database_lookup, GLIBC_2_0); ++ ++#endif /* SHLIB_COMPAT */ +diff -rup a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c +--- a/nss/nss_compat/compat-grp.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-grp.c 2019-06-06 17:16:59.618114799 -0400 +@@ -78,7 +78,7 @@ static bool in_blacklist (const char *, + static void + init_nss_interface (void) + { +- if (__nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0) ++ if (__nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + { + nss_setgrent = __nss_lookup_function (ni, "setgrent"); + nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r"); +diff -rup a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c +--- a/nss/nss_compat/compat-initgroups.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-initgroups.c 2019-06-06 17:16:59.646114807 -0400 +@@ -89,7 +89,7 @@ init_nss_interface (void) + + /* Retest. */ + if (ni == NULL +- && __nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0) ++ && __nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + { + nss_initgroups_dyn = __nss_lookup_function (ni, "initgroups_dyn"); + nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r"); +diff -rup a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c +--- a/nss/nss_compat/compat-pwd.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-pwd.c 2019-06-06 17:16:59.654114809 -0400 +@@ -88,7 +88,7 @@ static bool in_blacklist (const char *, + static void + init_nss_interface (void) + { +- if (__nss_database_lookup ("passwd_compat", NULL, "nis", &ni) >= 0) ++ if (__nss_database_lookup2 ("passwd_compat", NULL, "nis", &ni) >= 0) + { + nss_setpwent = __nss_lookup_function (ni, "setpwent"); + nss_getpwnam_r = __nss_lookup_function (ni, "getpwnam_r"); +diff -rup a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c +--- a/nss/nss_compat/compat-spwd.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nss_compat/compat-spwd.c 2019-06-06 17:16:59.668114812 -0400 +@@ -85,8 +85,8 @@ static bool in_blacklist (const char *, + static void + init_nss_interface (void) + { +- if (__nss_database_lookup ("shadow_compat", "passwd_compat", +- "nis", &ni) >= 0) ++ if (__nss_database_lookup2 ("shadow_compat", "passwd_compat", ++ "nis", &ni) >= 0) + { + nss_setspent = __nss_lookup_function (ni, "setspent"); + nss_getspnam_r = __nss_lookup_function (ni, "getspnam_r"); +diff -rup a/nss/nsswitch.c b/nss/nsswitch.c +--- a/nss/nsswitch.c 2019-06-06 17:15:32.210092623 -0400 ++++ b/nss/nsswitch.c 2019-06-06 17:16:59.672114813 -0400 +@@ -115,8 +115,8 @@ static void (*nscd_init_cb) (size_t, str + /* -1 == database not found + 0 == database entry pointer stored */ + int +-__nss_database_lookup (const char *database, const char *alternate_name, +- const char *defconfig, service_user **ni) ++__nss_database_lookup2 (const char *database, const char *alternate_name, ++ const char *defconfig, service_user **ni) + { + /* Prevent multiple threads to change the service table. */ + __libc_lock_lock (lock); +@@ -185,7 +185,7 @@ __nss_database_lookup (const char *datab + + return *ni != NULL ? 0 : -1; + } +-libc_hidden_def (__nss_database_lookup) ++libc_hidden_def (__nss_database_lookup2) + + + /* -1 == not found +@@ -260,16 +260,6 @@ __nss_next2 (service_user **ni, const ch + } + libc_hidden_def (__nss_next2) + +- +-int +-attribute_compat_text_section +-__nss_next (service_user **ni, const char *fct_name, void **fctp, int status, +- int all_values) +-{ +- return __nss_next2 (ni, fct_name, NULL, fctp, status, all_values); +-} +- +- + int + __nss_configure_lookup (const char *dbname, const char *service_line) + { +@@ -835,7 +825,7 @@ nss_load_all_libraries (const char *serv + { + service_user *ni = NULL; + +- if (__nss_database_lookup (service, NULL, def, &ni) == 0) ++ if (__nss_database_lookup2 (service, NULL, def, &ni) == 0) + while (ni != NULL) + { + nss_load_library (ni); +diff -rup a/nss/nsswitch.h b/nss/nsswitch.h +--- a/nss/nsswitch.h 2018-08-01 01:10:47.000000000 -0400 ++++ b/nss/nsswitch.h 2019-06-06 17:16:59.691114818 -0400 +@@ -125,10 +125,10 @@ extern bool __nss_database_custom[NSS_DB + If there is no configuration for this database in the file, + parse a service list from DEFCONFIG and use that. More + than one function can use the database. */ +-extern int __nss_database_lookup (const char *database, +- const char *alternative_name, +- const char *defconfig, service_user **ni); +-libc_hidden_proto (__nss_database_lookup) ++extern int __nss_database_lookup2 (const char *database, ++ const char *alternative_name, ++ const char *defconfig, service_user **ni); ++libc_hidden_proto (__nss_database_lookup2) + + /* Put first function with name FCT_NAME for SERVICE in FCTP. The + position is remembered in NI. The function returns a value < 0 if +diff -rup a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +--- a/sysdeps/posix/getaddrinfo.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/sysdeps/posix/getaddrinfo.c 2019-06-06 17:16:59.724114827 -0400 +@@ -737,9 +737,9 @@ gaih_inet (const char *name, const struc + #endif + + if (__nss_hosts_database == NULL) +- no_more = __nss_database_lookup ("hosts", NULL, +- "dns [!UNAVAIL=return] files", +- &__nss_hosts_database); ++ no_more = __nss_database_lookup2 ("hosts", NULL, ++ "dns [!UNAVAIL=return] files", ++ &__nss_hosts_database); + else + no_more = 0; + nip = __nss_hosts_database; diff --git a/SOURCES/glibc-rh1717438.patch b/SOURCES/glibc-rh1717438.patch new file mode 100644 index 0000000..8bfaec8 --- /dev/null +++ b/SOURCES/glibc-rh1717438.patch @@ -0,0 +1,71 @@ +commit 11b451c8868d8a2b0edc5dfd44fc58d9ee538be0 +Author: Mark Wielaard +Date: Wed May 15 17:14:01 2019 +0200 + + dlfcn: Guard __dlerror_main_freeres with __libc_once_get (once) [BZ# 24476] + + dlerror.c (__dlerror_main_freeres) will try to free resources which only + have been initialized when init () has been called. That function is + called when resources are needed using __libc_once (once, init) where + once is a __libc_once_define (static, once) in the dlerror.c file. + Trying to free those resources if init () hasn't been called will + produce errors under valgrind memcheck. So guard the freeing of those + resources using __libc_once_get (once) and make sure we have a valid + key. Also add a similar guard to __dlerror (). + + * dlfcn/dlerror.c (__dlerror_main_freeres): Guard using + __libc_once_get (once) and static_bug == NULL. + (__dlerror): Check we have a valid key, set result to static_buf + otherwise. + + Reviewed-by: Carlos O'Donell + +diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c +index 96bf92533335036b..06732460ea1512cd 100644 +--- a/dlfcn/dlerror.c ++++ b/dlfcn/dlerror.c +@@ -72,9 +72,16 @@ __dlerror (void) + __libc_once (once, init); + + /* Get error string. */ +- result = (struct dl_action_result *) __libc_getspecific (key); +- if (result == NULL) +- result = &last_result; ++ if (static_buf != NULL) ++ result = static_buf; ++ else ++ { ++ /* init () has been run and we don't use the static buffer. ++ So we have a valid key. */ ++ result = (struct dl_action_result *) __libc_getspecific (key); ++ if (result == NULL) ++ result = &last_result; ++ } + + /* Test whether we already returned the string. */ + if (result->returned != 0) +@@ -230,13 +237,19 @@ free_key_mem (void *mem) + void + __dlerror_main_freeres (void) + { +- void *mem; + /* Free the global memory if used. */ + check_free (&last_result); +- /* Free the TSD memory if used. */ +- mem = __libc_getspecific (key); +- if (mem != NULL) +- free_key_mem (mem); ++ ++ if (__libc_once_get (once) && static_buf == NULL) ++ { ++ /* init () has been run and we don't use the static buffer. ++ So we have a valid key. */ ++ void *mem; ++ /* Free the TSD memory if used. */ ++ mem = __libc_getspecific (key); ++ if (mem != NULL) ++ free_key_mem (mem); ++ } + } + + struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon)); diff --git a/SOURCES/glibc-rh1722215.patch b/SOURCES/glibc-rh1722215.patch new file mode 100644 index 0000000..cbda401 --- /dev/null +++ b/SOURCES/glibc-rh1722215.patch @@ -0,0 +1,186 @@ +commit 21cc130b78a4db9113fb6695e2b951e697662440 +Author: Dmitry V. Levin +Date: Wed Feb 13 01:20:51 2019 +0000 + + libio: do not attempt to free wide buffers of legacy streams [BZ #24228] + + Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693 + ("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem + when _G_HAVE_MMAP is turned off.") introduced a regression: + _IO_unbuffer_all now invokes _IO_wsetb to free wide buffers of all + files, including legacy standard files which are small statically + allocated objects that do not have wide buffers and the _mode member, + causing memory corruption. + + Another memory corruption in _IO_unbuffer_all happens when -1 + is assigned to the _mode member of legacy standard files that + do not have it. + + [BZ #24228] + * libio/genops.c (_IO_unbuffer_all) + [SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide + buffers and access _IO_FILE_complete members of legacy libio streams. + * libio/tst-bz24228.c: New file. + * libio/tst-bz24228.map: Likewise. + * libio/Makefile [build-shared] (tests): Add tst-bz24228. + [build-shared] (generated): Add tst-bz24228.mtrace and + tst-bz24228.check. + [run-built-tests && build-shared] (tests-special): Add + $(objpfx)tst-bz24228-mem.out. + (LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables. + ($(objpfx)tst-bz24228-mem.out): New rule. + +# Conflicts: +# libio/Makefile + +diff --git a/libio/Makefile b/libio/Makefile +index cbfaf3832a45fc22..314e03d5ce72be2d 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -73,6 +73,9 @@ ifeq (yes,$(build-shared)) + # Add test-fopenloc only if shared library is enabled since it depends on + # shared localedata objects. + tests += tst-fopenloc ++# Add tst-bz24228 only if shared library is enabled since it can never meet its ++# objective with static linking because the relevant code just is not there. ++tests += tst-bz24228 + endif + test-srcs = test-freopen + +@@ -153,11 +156,14 @@ CFLAGS-oldtmpfile.c += -fexceptions + + CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\" + ++LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map ++ + tst_wprintf2-ARGS = "Some Text" + + test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace + tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace + tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace ++tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace + + generated += test-fmemopen.mtrace test-fmemopen.check + generated += tst-fopenloc.mtrace tst-fopenloc.check +@@ -166,6 +172,7 @@ generated += tst-bz22415.mtrace tst-bz22415.check + aux := fileops genops stdfiles stdio strops + + ifeq ($(build-shared),yes) ++generated += tst-bz24228.mtrace tst-bz24228.check + aux += oldfileops oldstdfiles + endif + +@@ -180,7 +187,8 @@ tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \ + ifeq (yes,$(build-shared)) + # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared + # library is enabled since they depend on tst-fopenloc.out. +-tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out ++tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out \ ++ $(objpfx)tst-bz24228-mem.out + endif + endif + +@@ -232,3 +240,7 @@ $(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out + $(objpfx)tst-bz22415-mem.out: $(objpfx)tst-bz22415.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-bz22415.mtrace > $@; \ + $(evaluate-test) ++ ++$(objpfx)tst-bz24228-mem.out: $(objpfx)tst-bz24228.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-bz24228.mtrace > $@; \ ++ $(evaluate-test) +diff --git a/libio/genops.c b/libio/genops.c +index 2fec221b99729718..a8241dd26640bbcb 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -789,9 +789,16 @@ _IO_unbuffer_all (void) + + for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain) + { ++ int legacy = 0; ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) ++ if (__glibc_unlikely (_IO_vtable_offset (fp) != 0)) ++ legacy = 1; ++#endif ++ + if (! (fp->_flags & _IO_UNBUFFERED) + /* Iff stream is un-orientated, it wasn't used. */ +- && fp->_mode != 0) ++ && (legacy || fp->_mode != 0)) + { + #ifdef _IO_MTSAFE_IO + int cnt; +@@ -805,7 +812,7 @@ _IO_unbuffer_all (void) + __sched_yield (); + #endif + +- if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) ++ if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) + { + fp->_flags |= _IO_USER_BUF; + +@@ -816,7 +823,7 @@ _IO_unbuffer_all (void) + + _IO_SETBUF (fp, NULL, 0); + +- if (fp->_mode > 0) ++ if (! legacy && fp->_mode > 0) + _IO_wsetb (fp, NULL, NULL, 0); + + #ifdef _IO_MTSAFE_IO +@@ -827,7 +834,8 @@ _IO_unbuffer_all (void) + + /* Make sure that never again the wide char functions can be + used. */ +- fp->_mode = -1; ++ if (! legacy) ++ fp->_mode = -1; + } + + #ifdef _IO_MTSAFE_IO +diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c +new file mode 100644 +index 0000000000000000..6a74500d473ceeab +--- /dev/null ++++ b/libio/tst-bz24228.c +@@ -0,0 +1,29 @@ ++/* BZ #24228 check for memory corruption in legacy libio ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ mtrace (); ++ return 0; ++} ++ ++#include +diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map +new file mode 100644 +index 0000000000000000..4383e0817d7f5583 +--- /dev/null ++++ b/libio/tst-bz24228.map +@@ -0,0 +1,5 @@ ++# Hide the symbol from libc.so.6 to switch to the libio/oldfileops.c ++# implementation when it is available for the architecture. ++{ ++ local: _IO_stdin_used; ++}; diff --git a/SOURCES/glibc-rh1724975.patch b/SOURCES/glibc-rh1724975.patch new file mode 100644 index 0000000..7ea3267 --- /dev/null +++ b/SOURCES/glibc-rh1724975.patch @@ -0,0 +1,1013 @@ +commit 5a659ccc0ec217ab02a4c273a1f6d346a359560a +Author: Florian Weimer +Date: Fri Jun 28 09:39:21 2019 +0200 + + io: Remove copy_file_range emulation [BZ #24744] + + The kernel is evolving this interface (e.g., removal of the + restriction on cross-device copies), and keeping up with that + is difficult. Applications which need the function should + run kernels which support the system call instead of relying on + the imperfect glibc emulation. + + Reviewed-by: Adhemerval Zanella + +# Conflicts: +# io/copy_file_range-compat.c +# io/copy_file_range.c +# io/tst-copy_file_range-compat.c +# io/tst-copy_file_range.c +# sysdeps/unix/sysv/linux/arm/kernel-features.h +# sysdeps/unix/sysv/linux/microblaze/kernel-features.h +# sysdeps/unix/sysv/linux/sh/kernel-features.h + +diff --git a/io/Makefile b/io/Makefile +index 787a5c550ab64b17..62e71b4cbe879dbc 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -75,11 +75,6 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-fts tst-fts-lfs tst-open-tmpfile \ + tst-copy_file_range tst-getcwd-abspath \ + +-# This test includes the compat implementation of copy_file_range, +-# which uses internal, unexported libc functions. +-tests-static += tst-copy_file_range-compat +-tests-internal += tst-copy_file_range-compat +- + # Likewise for statx, but we do not need static linking here. + tests-internal += tst-statx + +diff --git a/io/copy_file_range-compat.c b/io/copy_file_range-compat.c +deleted file mode 100644 +index 4ab22cad19146ca9..0000000000000000 +--- a/io/copy_file_range-compat.c ++++ /dev/null +@@ -1,160 +0,0 @@ +-/* Emulation of copy_file_range. +- Copyright (C) 2017-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* The following macros should be defined before including this +- file: +- +- COPY_FILE_RANGE_DECL Declaration specifiers for the function below. +- COPY_FILE_RANGE Name of the function to define. */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-COPY_FILE_RANGE_DECL +-ssize_t +-COPY_FILE_RANGE (int infd, __off64_t *pinoff, +- int outfd, __off64_t *poutoff, +- size_t length, unsigned int flags) +-{ +- if (flags != 0) +- { +- __set_errno (EINVAL); +- return -1; +- } +- +- { +- struct stat64 instat; +- struct stat64 outstat; +- if (fstat64 (infd, &instat) != 0 || fstat64 (outfd, &outstat) != 0) +- return -1; +- if (S_ISDIR (instat.st_mode) || S_ISDIR (outstat.st_mode)) +- { +- __set_errno (EISDIR); +- return -1; +- } +- if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode)) +- { +- /* We need a regular input file so that the we can seek +- backwards in case of a write failure. */ +- __set_errno (EINVAL); +- return -1; +- } +- if (instat.st_dev != outstat.st_dev) +- { +- /* Cross-device copies are not supported. */ +- __set_errno (EXDEV); +- return -1; +- } +- } +- +- /* The output descriptor must not have O_APPEND set. */ +- { +- int flags = __fcntl (outfd, F_GETFL); +- if (flags & O_APPEND) +- { +- __set_errno (EBADF); +- return -1; +- } +- } +- +- /* Avoid an overflow in the result. */ +- if (length > SSIZE_MAX) +- length = SSIZE_MAX; +- +- /* Main copying loop. The buffer size is arbitrary and is a +- trade-off between stack size consumption, cache usage, and +- amortization of system call overhead. */ +- size_t copied = 0; +- char buf[8192]; +- while (length > 0) +- { +- size_t to_read = length; +- if (to_read > sizeof (buf)) +- to_read = sizeof (buf); +- +- /* Fill the buffer. */ +- ssize_t read_count; +- if (pinoff == NULL) +- read_count = read (infd, buf, to_read); +- else +- read_count = __libc_pread64 (infd, buf, to_read, *pinoff); +- if (read_count == 0) +- /* End of file reached prematurely. */ +- return copied; +- if (read_count < 0) +- { +- if (copied > 0) +- /* Report the number of bytes copied so far. */ +- return copied; +- return -1; +- } +- if (pinoff != NULL) +- *pinoff += read_count; +- +- /* Write the buffer part which was read to the destination. */ +- char *end = buf + read_count; +- for (char *p = buf; p < end; ) +- { +- ssize_t write_count; +- if (poutoff == NULL) +- write_count = write (outfd, p, end - p); +- else +- write_count = __libc_pwrite64 (outfd, p, end - p, *poutoff); +- if (write_count < 0) +- { +- /* Adjust the input read position to match what we have +- written, so that the caller can pick up after the +- error. */ +- size_t written = p - buf; +- /* NB: This needs to be signed so that we can form the +- negative value below. */ +- ssize_t overread = read_count - written; +- if (pinoff == NULL) +- { +- if (overread > 0) +- { +- /* We are on an error recovery path, so we +- cannot deal with failure here. */ +- int save_errno = errno; +- (void) __libc_lseek64 (infd, -overread, SEEK_CUR); +- __set_errno (save_errno); +- } +- } +- else /* pinoff != NULL */ +- *pinoff -= overread; +- +- if (copied + written > 0) +- /* Report the number of bytes copied so far. */ +- return copied + written; +- return -1; +- } +- p += write_count; +- if (poutoff != NULL) +- *poutoff += write_count; +- } /* Write loop. */ +- +- copied += read_count; +- length -= read_count; +- } +- return copied; +-} +diff --git a/io/copy_file_range.c b/io/copy_file_range.c +index 98bff8bd2615b214..59fb979773b2b202 100644 +--- a/io/copy_file_range.c ++++ b/io/copy_file_range.c +@@ -1,5 +1,5 @@ +-/* Generic implementation of copy_file_range. +- Copyright (C) 2017-2018 Free Software Foundation, Inc. ++/* Stub implementation of copy_file_range. ++ Copyright (C) 2017-2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -16,7 +16,15 @@ + License along with the GNU C Library; if not, see + . */ + +-#define COPY_FILE_RANGE_DECL +-#define COPY_FILE_RANGE copy_file_range ++#include ++#include + +-#include ++ssize_t ++copy_file_range (int infd, __off64_t *pinoff, ++ int outfd, __off64_t *poutoff, ++ size_t length, unsigned int flags) ++{ ++ __set_errno (ENOSYS); ++ return -1; ++} ++stub_warning (copy_file_range) +diff --git a/io/tst-copy_file_range-compat.c b/io/tst-copy_file_range-compat.c +deleted file mode 100644 +index 00c109a74d3c9d64..0000000000000000 +--- a/io/tst-copy_file_range-compat.c ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* Test the fallback implementation of copy_file_range. +- Copyright (C) 2017-2018 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* Get the declaration of the official copy_of_range function. */ +-#include +- +-/* Compile a local version of copy_file_range. */ +-#define COPY_FILE_RANGE_DECL static +-#define COPY_FILE_RANGE copy_file_range_compat +-#include +- +-/* Re-use the test, but run it against copy_file_range_compat defined +- above. */ +-#define copy_file_range copy_file_range_compat +-#include "tst-copy_file_range.c" +diff --git a/io/tst-copy_file_range.c b/io/tst-copy_file_range.c +index 3d531a19370911e5..4504020d2ee7d2ee 100644 +--- a/io/tst-copy_file_range.c ++++ b/io/tst-copy_file_range.c +@@ -20,22 +20,15 @@ + #include + #include + #include +-#include +-#include +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include + #include +-#ifdef CLONE_NEWNS +-# include +-#endif + + /* Boolean flags which indicate whether to use pointers with explicit + output flags. */ +@@ -49,10 +42,6 @@ static int infd; + static char *outfile; + static int outfd; + +-/* Like the above, but on a different file system. xdevfile can be +- NULL if no suitable file system has been found. */ +-static char *xdevfile; +- + /* Input and output offsets. Set according to do_inoff and do_outoff + before the test. The offsets themselves are always set to + zero. */ +@@ -61,13 +50,10 @@ static off64_t *pinoff; + static off64_t outoff; + static off64_t *poutoff; + +-/* These are a collection of copy sizes used in tests. The selection +- takes into account that the fallback implementation uses an +- internal buffer of 8192 bytes. */ ++/* These are a collection of copy sizes used in tests. */ + enum { maximum_size = 99999 }; + static const int typical_sizes[] = +- { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, 16383, 16384, 16385, +- maximum_size }; ++ { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, maximum_size }; + + /* The random contents of this array can be used as a pattern to check + for correct write operations. */ +@@ -76,101 +62,6 @@ static unsigned char random_data[maximum_size]; + /* The size chosen by the test harness. */ + static int current_size; + +-/* Maximum writable file offset. Updated by find_maximum_offset +- below. */ +-static off64_t maximum_offset; +- +-/* Error code when crossing the offset. */ +-static int maximum_offset_errno; +- +-/* If true: Writes which cross the limit will fail. If false: Writes +- which cross the limit will result in a partial write. */ +-static bool maximum_offset_hard_limit; +- +-/* Fills maximum_offset etc. above. Truncates outfd as a side +- effect. */ +-static void +-find_maximum_offset (void) +-{ +- xftruncate (outfd, 0); +- if (maximum_offset != 0) +- return; +- +- uint64_t upper = -1; +- upper >>= 1; /* Maximum of off64_t. */ +- TEST_VERIFY ((off64_t) upper > 0); +- TEST_VERIFY ((off64_t) (upper + 1) < 0); +- if (lseek64 (outfd, upper, SEEK_SET) >= 0) +- { +- if (write (outfd, "", 1) == 1) +- FAIL_EXIT1 ("created a file larger than the off64_t range"); +- } +- +- uint64_t lower = 1024 * 1024; /* A reasonable minimum file size. */ +- /* Loop invariant: writing at lower succeeds, writing at upper fails. */ +- while (lower + 1 < upper) +- { +- uint64_t middle = (lower + upper) / 2; +- if (test_verbose > 0) +- printf ("info: %s: remaining test range %" PRIu64 " .. %" PRIu64 +- ", probe at %" PRIu64 "\n", __func__, lower, upper, middle); +- xftruncate (outfd, 0); +- if (lseek64 (outfd, middle, SEEK_SET) >= 0 +- && write (outfd, "", 1) == 1) +- lower = middle; +- else +- upper = middle; +- } +- TEST_VERIFY (lower + 1 == upper); +- maximum_offset = lower; +- printf ("info: maximum writable file offset: %" PRIu64 " (%" PRIx64 ")\n", +- lower, lower); +- +- /* Check that writing at the valid offset actually works. */ +- xftruncate (outfd, 0); +- xlseek (outfd, lower, SEEK_SET); +- TEST_COMPARE (write (outfd, "", 1), 1); +- +- /* Cross the boundary with a two-byte write. This can either result +- in a short write, or a failure. */ +- xlseek (outfd, lower, SEEK_SET); +- ssize_t ret = write (outfd, " ", 2); +- if (ret < 0) +- { +- maximum_offset_errno = errno; +- maximum_offset_hard_limit = true; +- } +- else +- maximum_offset_hard_limit = false; +- +- /* Check that writing at the next offset actually fails. This also +- obtains the expected errno value. */ +- xftruncate (outfd, 0); +- const char *action; +- if (lseek64 (outfd, lower + 1, SEEK_SET) != 0) +- { +- if (write (outfd, "", 1) != -1) +- FAIL_EXIT1 ("write to impossible offset %" PRIu64 " succeeded", +- lower + 1); +- action = "writing"; +- int errno_copy = errno; +- if (maximum_offset_hard_limit) +- TEST_COMPARE (errno_copy, maximum_offset_errno); +- else +- maximum_offset_errno = errno_copy; +- } +- else +- { +- action = "seeking"; +- maximum_offset_errno = errno; +- } +- printf ("info: %s out of range fails with %m (%d)\n", +- action, maximum_offset_errno); +- +- xftruncate (outfd, 0); +- xlseek (outfd, 0, SEEK_SET); +-} +- + /* Perform a copy of a file. */ + static void + simple_file_copy (void) +@@ -247,390 +138,6 @@ simple_file_copy (void) + free (bytes); + } + +-/* Test that reading from a pipe willfails. */ +-static void +-pipe_as_source (void) +-{ +- int pipefds[2]; +- xpipe (pipefds); +- +- for (int length = 0; length < 2; ++length) +- { +- if (test_verbose > 0) +- printf ("info: %s: length=%d\n", __func__, length); +- +- /* Make sure that there is something to copy in the pipe. */ +- xwrite (pipefds[1], "@", 1); +- +- TEST_COMPARE (copy_file_range (pipefds[0], pinoff, outfd, poutoff, +- length, 0), -1); +- /* Linux 4.10 and later return EINVAL. Older kernels return +- EXDEV. */ +- TEST_VERIFY (errno == EINVAL || errno == EXDEV); +- TEST_COMPARE (inoff, 0); +- TEST_COMPARE (outoff, 0); +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 0); +- +- /* Make sure that nothing was read. */ +- char buf = 'A'; +- TEST_COMPARE (read (pipefds[0], &buf, 1), 1); +- TEST_COMPARE (buf, '@'); +- } +- +- xclose (pipefds[0]); +- xclose (pipefds[1]); +-} +- +-/* Test that writing to a pipe fails. */ +-static void +-pipe_as_destination (void) +-{ +- /* Make sure that there is something to read in the input file. */ +- xwrite (infd, "abc", 3); +- xlseek (infd, 0, SEEK_SET); +- +- int pipefds[2]; +- xpipe (pipefds); +- +- for (int length = 0; length < 2; ++length) +- { +- if (test_verbose > 0) +- printf ("info: %s: length=%d\n", __func__, length); +- +- TEST_COMPARE (copy_file_range (infd, pinoff, pipefds[1], poutoff, +- length, 0), -1); +- /* Linux 4.10 and later return EINVAL. Older kernels return +- EXDEV. */ +- TEST_VERIFY (errno == EINVAL || errno == EXDEV); +- TEST_COMPARE (inoff, 0); +- TEST_COMPARE (outoff, 0); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- +- /* Make sure that nothing was written. */ +- struct pollfd pollfd = { .fd = pipefds[0], .events = POLLIN, }; +- TEST_COMPARE (poll (&pollfd, 1, 0), 0); +- } +- +- xclose (pipefds[0]); +- xclose (pipefds[1]); +-} +- +-/* Test a write failure after (potentially) writing some bytes. +- Failure occurs near the start of the buffer. */ +-static void +-delayed_write_failure_beginning (void) +-{ +- /* We need to write something to provoke the error. */ +- if (current_size == 0) +- return; +- xwrite (infd, random_data, sizeof (random_data)); +- xlseek (infd, 0, SEEK_SET); +- +- /* Write failure near the start. The actual error code varies among +- file systems. */ +- find_maximum_offset (); +- off64_t where = maximum_offset; +- +- if (current_size == 1) +- ++where; +- outoff = where; +- if (do_outoff) +- xlseek (outfd, 1, SEEK_SET); +- else +- xlseek (outfd, where, SEEK_SET); +- if (maximum_offset_hard_limit || where > maximum_offset) +- { +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0), -1); +- TEST_COMPARE (errno, maximum_offset_errno); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- TEST_COMPARE (inoff, 0); +- if (do_outoff) +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1); +- else +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where); +- TEST_COMPARE (outoff, where); +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, 0); +- } +- else +- { +- /* The offset is not a hard limit. This means we write one +- byte. */ +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0), 1); +- if (do_inoff) +- { +- TEST_COMPARE (inoff, 1); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- } +- else +- { +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 1); +- TEST_COMPARE (inoff, 0); +- } +- if (do_outoff) +- { +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), 1); +- TEST_COMPARE (outoff, where + 1); +- } +- else +- { +- TEST_COMPARE (xlseek (outfd, 0, SEEK_CUR), where + 1); +- TEST_COMPARE (outoff, where); +- } +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, where + 1); +- } +-} +- +-/* Test a write failure after (potentially) writing some bytes. +- Failure occurs near the end of the buffer. */ +-static void +-delayed_write_failure_end (void) +-{ +- if (current_size <= 1) +- /* This would be same as the first test because there is not +- enough data to write to make a difference. */ +- return; +- xwrite (infd, random_data, sizeof (random_data)); +- xlseek (infd, 0, SEEK_SET); +- +- find_maximum_offset (); +- off64_t where = maximum_offset - current_size + 1; +- if (current_size == sizeof (random_data)) +- /* Otherwise we do not reach the non-writable byte. */ +- ++where; +- outoff = where; +- if (do_outoff) +- xlseek (outfd, 1, SEEK_SET); +- else +- xlseek (outfd, where, SEEK_SET); +- ssize_t ret = copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0); +- if (ret < 0) +- { +- TEST_COMPARE (ret, -1); +- TEST_COMPARE (errno, maximum_offset_errno); +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, 0); +- } +- else +- { +- /* The first copy succeeded. This happens in the emulation +- because the internal buffer of limited size does not +- necessarily cross the off64_t boundary on the first write +- operation. */ +- if (test_verbose > 0) +- printf ("info: copy_file_range (%zu) returned %zd\n", +- sizeof (random_data), ret); +- TEST_VERIFY (ret > 0); +- TEST_VERIFY (ret < maximum_size); +- struct stat64 st; +- xfstat (outfd, &st); +- TEST_COMPARE (st.st_size, where + ret); +- if (do_inoff) +- { +- TEST_COMPARE (inoff, ret); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- } +- else +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), ret); +- +- char *buffer = xmalloc (ret); +- TEST_COMPARE (pread64 (outfd, buffer, ret, where), ret); +- TEST_VERIFY (memcmp (buffer, random_data, ret) == 0); +- free (buffer); +- +- /* The second copy fails. */ +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- sizeof (random_data), 0), -1); +- TEST_COMPARE (errno, maximum_offset_errno); +- } +-} +- +-/* Test a write failure across devices. */ +-static void +-cross_device_failure (void) +-{ +- if (xdevfile == NULL) +- /* Subtest not supported due to missing cross-device file. */ +- return; +- +- /* We need something to write. */ +- xwrite (infd, random_data, sizeof (random_data)); +- xlseek (infd, 0, SEEK_SET); +- +- int xdevfd = xopen (xdevfile, O_RDWR | O_LARGEFILE, 0); +- TEST_COMPARE (copy_file_range (infd, pinoff, xdevfd, poutoff, +- current_size, 0), -1); +- TEST_COMPARE (errno, EXDEV); +- TEST_COMPARE (xlseek (infd, 0, SEEK_CUR), 0); +- struct stat64 st; +- xfstat (xdevfd, &st); +- TEST_COMPARE (st.st_size, 0); +- +- xclose (xdevfd); +-} +- +-/* Try to exercise ENOSPC behavior with a tempfs file system (so that +- we do not have to fill up a regular file system to get the error). +- This function runs in a subprocess, so that we do not change the +- mount namespace of the actual test process. */ +-static void +-enospc_failure_1 (void *closure) +-{ +-#ifdef CLONE_NEWNS +- support_become_root (); +- +- /* Make sure that we do not alter the file system mounts of the +- parents. */ +- if (! support_enter_mount_namespace ()) +- { +- printf ("warning: ENOSPC test skipped\n"); +- return; +- } +- +- char *mountpoint = closure; +- if (mount ("none", mountpoint, "tmpfs", MS_NODEV | MS_NOEXEC, +- "size=500k") != 0) +- { +- printf ("warning: could not mount tmpfs at %s: %m\n", mountpoint); +- return; +- } +- +- /* The source file must reside on the same file system. */ +- char *intmpfsfile = xasprintf ("%s/%s", mountpoint, "in"); +- int intmpfsfd = xopen (intmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600); +- xwrite (intmpfsfd, random_data, sizeof (random_data)); +- xlseek (intmpfsfd, 1, SEEK_SET); +- inoff = 1; +- +- char *outtmpfsfile = xasprintf ("%s/%s", mountpoint, "out"); +- int outtmpfsfd = xopen (outtmpfsfile, O_RDWR | O_CREAT | O_LARGEFILE, 0600); +- +- /* Fill the file with data until ENOSPC is reached. */ +- while (true) +- { +- ssize_t ret = write (outtmpfsfd, random_data, sizeof (random_data)); +- if (ret < 0 && errno != ENOSPC) +- FAIL_EXIT1 ("write to %s: %m", outtmpfsfile); +- if (ret < sizeof (random_data)) +- break; +- } +- TEST_COMPARE (write (outtmpfsfd, "", 1), -1); +- TEST_COMPARE (errno, ENOSPC); +- off64_t maxsize = xlseek (outtmpfsfd, 0, SEEK_CUR); +- TEST_VERIFY_EXIT (maxsize > sizeof (random_data)); +- +- /* Constructed the expected file contents. */ +- char *expected = xmalloc (maxsize); +- TEST_COMPARE (pread64 (outtmpfsfd, expected, maxsize, 0), maxsize); +- /* Go back a little, so some bytes can be written. */ +- enum { offset = 20000 }; +- TEST_VERIFY_EXIT (offset < maxsize); +- TEST_VERIFY_EXIT (offset < sizeof (random_data)); +- memcpy (expected + maxsize - offset, random_data + 1, offset); +- +- if (do_outoff) +- { +- outoff = maxsize - offset; +- xlseek (outtmpfsfd, 2, SEEK_SET); +- } +- else +- xlseek (outtmpfsfd, -offset, SEEK_CUR); +- +- /* First call is expected to succeed because we made room for some +- bytes. */ +- TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff, +- maximum_size, 0), offset); +- if (do_inoff) +- { +- TEST_COMPARE (inoff, 1 + offset); +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1); +- } +- else +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset); +- if (do_outoff) +- { +- TEST_COMPARE (outoff, maxsize); +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2); +- } +- else +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize); +- struct stat64 st; +- xfstat (outtmpfsfd, &st); +- TEST_COMPARE (st.st_size, maxsize); +- char *actual = xmalloc (st.st_size); +- TEST_COMPARE (pread64 (outtmpfsfd, actual, st.st_size, 0), st.st_size); +- TEST_VERIFY (memcmp (expected, actual, maxsize) == 0); +- +- /* Second call should fail with ENOSPC. */ +- TEST_COMPARE (copy_file_range (intmpfsfd, pinoff, outtmpfsfd, poutoff, +- maximum_size, 0), -1); +- TEST_COMPARE (errno, ENOSPC); +- +- /* Offsets should be unchanged. */ +- if (do_inoff) +- { +- TEST_COMPARE (inoff, 1 + offset); +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1); +- } +- else +- TEST_COMPARE (xlseek (intmpfsfd, 0, SEEK_CUR), 1 + offset); +- if (do_outoff) +- { +- TEST_COMPARE (outoff, maxsize); +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), 2); +- } +- else +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_CUR), maxsize); +- TEST_COMPARE (xlseek (outtmpfsfd, 0, SEEK_END), maxsize); +- TEST_COMPARE (pread64 (outtmpfsfd, actual, maxsize, 0), maxsize); +- TEST_VERIFY (memcmp (expected, actual, maxsize) == 0); +- +- free (actual); +- free (expected); +- +- xclose (intmpfsfd); +- xclose (outtmpfsfd); +- free (intmpfsfile); +- free (outtmpfsfile); +- +-#else /* !CLONE_NEWNS */ +- puts ("warning: ENOSPC test skipped (no mount namespaces)"); +-#endif +-} +- +-/* Call enospc_failure_1 in a subprocess. */ +-static void +-enospc_failure (void) +-{ +- char *mountpoint +- = support_create_temp_directory ("tst-copy_file_range-enospc-"); +- support_isolate_in_subprocess (enospc_failure_1, mountpoint); +- free (mountpoint); +-} +- +-/* The target file descriptor must have O_APPEND enabled. */ +-static void +-oappend_failure (void) +-{ +- /* Add data, to make sure we do not fail because there is +- insufficient input data. */ +- xwrite (infd, random_data, current_size); +- xlseek (infd, 0, SEEK_SET); +- +- xclose (outfd); +- outfd = xopen (outfile, O_RDWR | O_APPEND, 0); +- TEST_COMPARE (copy_file_range (infd, pinoff, outfd, poutoff, +- current_size, 0), -1); +- TEST_COMPARE (errno, EBADF); +-} +- + /* Test that a short input file results in a shortened copy. */ + static void + short_copy (void) +@@ -721,14 +228,6 @@ struct test_case + static struct test_case tests[] = + { + { "simple_file_copy", simple_file_copy, .sizes = true }, +- { "pipe_as_source", pipe_as_source, }, +- { "pipe_as_destination", pipe_as_destination, }, +- { "delayed_write_failure_beginning", delayed_write_failure_beginning, +- .sizes = true }, +- { "delayed_write_failure_end", delayed_write_failure_end, .sizes = true }, +- { "cross_device_failure", cross_device_failure, .sizes = true }, +- { "enospc_failure", enospc_failure, }, +- { "oappend_failure", oappend_failure, .sizes = true }, + { "short_copy", short_copy, .sizes = true }, + }; + +@@ -739,53 +238,18 @@ do_test (void) + *p = rand () >> 24; + + infd = create_temp_file ("tst-copy_file_range-in-", &infile); +- xclose (create_temp_file ("tst-copy_file_range-out-", &outfile)); +- +- /* Try to find a different directory from the default input/output +- file. */ ++ outfd = create_temp_file ("tst-copy_file_range-out-", &outfile); + { +- struct stat64 instat; +- xfstat (infd, &instat); +- static const char *const candidates[] = +- { NULL, "/var/tmp", "/dev/shm" }; +- for (const char *const *c = candidates; c < array_end (candidates); ++c) +- { +- const char *path = *c; +- char *to_free = NULL; +- if (path == NULL) +- { +- to_free = xreadlink ("/proc/self/exe"); +- path = dirname (to_free); +- } +- +- struct stat64 cstat; +- xstat (path, &cstat); +- if (cstat.st_dev == instat.st_dev) +- { +- free (to_free); +- continue; +- } +- +- printf ("info: using alternate temporary files directory: %s\n", path); +- xdevfile = xasprintf ("%s/tst-copy_file_range-xdev-XXXXXX", path); +- free (to_free); +- break; +- } +- if (xdevfile != NULL) ++ ssize_t ret = copy_file_range (infd, NULL, outfd, NULL, 0, 0); ++ if (ret != 0) + { +- int xdevfd = mkstemp (xdevfile); +- if (xdevfd < 0) +- FAIL_EXIT1 ("mkstemp (\"%s\"): %m", xdevfile); +- struct stat64 xdevst; +- xfstat (xdevfd, &xdevst); +- TEST_VERIFY (xdevst.st_dev != instat.st_dev); +- add_temp_file (xdevfile); +- xclose (xdevfd); ++ if (errno == ENOSYS) ++ FAIL_UNSUPPORTED ("copy_file_range is not support on this system"); ++ FAIL_EXIT1 ("copy_file_range probing call: %m"); + } +- else +- puts ("warning: no alternate directory on different file system found"); + } + xclose (infd); ++ xclose (outfd); + + for (do_inoff = 0; do_inoff < 2; ++do_inoff) + for (do_outoff = 0; do_outoff < 2; ++do_outoff) +@@ -827,7 +291,6 @@ do_test (void) + + free (infile); + free (outfile); +- free (xdevfile); + + return 0; + } +diff --git a/manual/llio.texi b/manual/llio.texi +index 2733b9cb7331df07..26f7d2cb3ea220d9 100644 +--- a/manual/llio.texi ++++ b/manual/llio.texi +@@ -1404,10 +1404,13 @@ failure occurs. The return value is zero if the end of the input file + is encountered immediately. + + If no bytes can be copied, to report an error, @code{copy_file_range} +-returns the value @math{-1} and sets @code{errno}. The following +-@code{errno} error conditions are specific to this function: ++returns the value @math{-1} and sets @code{errno}. The table below ++lists some of the error conditions for this function. + + @table @code ++@item ENOSYS ++The kernel does not implement the required functionality. ++ + @item EISDIR + At least one of the descriptors @var{inputfd} or @var{outputfd} refers + to a directory. +@@ -1437,9 +1440,6 @@ reading. + + The argument @var{outputfd} is not a valid file descriptor open for + writing, or @var{outputfd} has been opened with @code{O_APPEND}. +- +-@item EXDEV +-The input and output files reside on different file systems. + @end table + + In addition, @code{copy_file_range} can fail with the error codes +diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h +index 402d2573d75794d5..26344cd610a1f8e7 100644 +--- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h ++++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h +@@ -48,7 +48,6 @@ + /* Support for copy_file_range, statx was added in kernel 4.13. */ + #if __LINUX_KERNEL_VERSION < 0x040D00 + # undef __ASSUME_MLOCK2 +-# undef __ASSUME_COPY_FILE_RANGE + # undef __ASSUME_STATX + #endif + +diff --git a/sysdeps/unix/sysv/linux/copy_file_range.c b/sysdeps/unix/sysv/linux/copy_file_range.c +index 7b1a50f7529f2a84..b88b7c9e2ecd825f 100644 +--- a/sysdeps/unix/sysv/linux/copy_file_range.c ++++ b/sysdeps/unix/sysv/linux/copy_file_range.c +@@ -20,27 +20,16 @@ + #include + #include + +-/* Include the fallback implementation. */ +-#ifndef __ASSUME_COPY_FILE_RANGE +-#define COPY_FILE_RANGE_DECL static +-#define COPY_FILE_RANGE copy_file_range_compat +-#include +-#endif +- + ssize_t + copy_file_range (int infd, __off64_t *pinoff, + int outfd, __off64_t *poutoff, + size_t length, unsigned int flags) + { + #ifdef __NR_copy_file_range +- ssize_t ret = SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff, +- length, flags); +-# ifndef __ASSUME_COPY_FILE_RANGE +- if (ret == -1 && errno == ENOSYS) +- ret = copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags); +-# endif +- return ret; +-#else /* !__NR_copy_file_range */ +- return copy_file_range_compat (infd, pinoff, outfd, poutoff, length, flags); ++ return SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff, ++ length, flags); ++#else ++ __set_errno (ENOSYS); ++ return -1; + #endif + } +diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h +index 5543d92d7e32e501..7a74835495250268 100644 +--- a/sysdeps/unix/sysv/linux/kernel-features.h ++++ b/sysdeps/unix/sysv/linux/kernel-features.h +@@ -111,10 +111,6 @@ + # define __ASSUME_MLOCK2 1 + #endif + +-#if __LINUX_KERNEL_VERSION >= 0x040500 +-# define __ASSUME_COPY_FILE_RANGE 1 +-#endif +- + /* Support for statx was added in kernel 4.11. */ + #if __LINUX_KERNEL_VERSION >= 0x040B00 + # define __ASSUME_STATX 1 +diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +index e8e2ac6a873126ac..1c49f099b7993f1d 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h ++++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +@@ -58,11 +58,6 @@ + # undef __ASSUME_EXECVEAT + #endif + +-/* Support for the copy_file_range syscall was added in 4.10. */ +-#if __LINUX_KERNEL_VERSION < 0x040A00 +-# undef __ASSUME_COPY_FILE_RANGE +-#endif +- + /* Support for statx was added in kernel 4.12. */ + #if __LINUX_KERNEL_VERSION < 0X040C00 + # undef __ASSUME_STATX diff --git a/SOURCES/glibc-rh1727152.patch b/SOURCES/glibc-rh1727152.patch new file mode 100644 index 0000000..8a5ed92 --- /dev/null +++ b/SOURCES/glibc-rh1727152.patch @@ -0,0 +1,22 @@ +commit 61595e3d36ded374f97961503e843a314b0203c2 +Author: Andreas Schwab +Date: Tue May 15 14:42:37 2018 +0200 + + nscd: avoid assertion failure during persistent db check + + nscd should not abort when it finds inconsistencies in the persistent db. + +diff --git a/nscd/connections.c b/nscd/connections.c +index 47fbb9923aa2aac7..98182007646a33d5 100644 +--- a/nscd/connections.c ++++ b/nscd/connections.c +@@ -304,7 +304,8 @@ static int + check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap, + enum usekey use, ref_t start, size_t len) + { +- assert (len >= 2); ++ if (len < 2) ++ return 0; + + if (start > first_free || start + len > first_free + || (start & BLOCK_ALIGN_M1)) diff --git a/SOURCES/glibc-rh1727241-1.patch b/SOURCES/glibc-rh1727241-1.patch new file mode 100644 index 0000000..5842b08 --- /dev/null +++ b/SOURCES/glibc-rh1727241-1.patch @@ -0,0 +1,221 @@ +commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0 +Author: Florian Weimer +Date: Mon Jan 21 08:59:42 2019 +0100 + + resolv: Reformat inet_addr, inet_aton to GNU style + +diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c +index 022f7ea0841b6bae..32f58b0e13598b32 100644 +--- a/resolv/inet_addr.c ++++ b/resolv/inet_addr.c +@@ -1,3 +1,21 @@ ++/* Legacy IPv4 text-to-address functions. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. +@@ -78,105 +96,97 @@ + #include + #include + +-/* +- * Ascii internet address interpretation routine. +- * The value returned is in network order. +- */ ++/* ASCII IPv4 Internet address interpretation routine. The value ++ returned is in network order. */ + in_addr_t +-__inet_addr(const char *cp) { +- struct in_addr val; ++__inet_addr (const char *cp) ++{ ++ struct in_addr val; + +- if (__inet_aton(cp, &val)) +- return (val.s_addr); +- return (INADDR_NONE); ++ if (__inet_aton (cp, &val)) ++ return val.s_addr; ++ return INADDR_NONE; + } + weak_alias (__inet_addr, inet_addr) + +-/* +- * Check whether "cp" is a valid ascii representation +- * of an Internet address and convert to a binary address. +- * Returns 1 if the address is valid, 0 if not. +- * This replaces inet_addr, the return value from which +- * cannot distinguish between failure and a local broadcast address. +- */ ++/* Check whether "cp" is a valid ASCII representation of an IPv4 ++ Internet address and convert it to a binary address. Returns 1 if ++ the address is valid, 0 if not. This replaces inet_addr, the ++ return value from which cannot distinguish between failure and a ++ local broadcast address. */ + int +-__inet_aton(const char *cp, struct in_addr *addr) ++__inet_aton (const char *cp, struct in_addr *addr) + { +- static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; +- in_addr_t val; +- char c; +- union iaddr { +- uint8_t bytes[4]; +- uint32_t word; +- } res; +- uint8_t *pp = res.bytes; +- int digit; +- +- int saved_errno = errno; +- __set_errno (0); +- +- res.word = 0; +- +- c = *cp; +- for (;;) { +- /* +- * Collect number up to ``.''. +- * Values are specified as for C: +- * 0x=hex, 0=octal, isdigit=decimal. +- */ +- if (!isdigit(c)) +- goto ret_0; +- { +- char *endp; +- unsigned long ul = strtoul (cp, (char **) &endp, 0); +- if (ul == ULONG_MAX && errno == ERANGE) +- goto ret_0; +- if (ul > 0xfffffffful) +- goto ret_0; +- val = ul; +- digit = cp != endp; +- cp = endp; +- } +- c = *cp; +- if (c == '.') { +- /* +- * Internet format: +- * a.b.c.d +- * a.b.c (with c treated as 16 bits) +- * a.b (with b treated as 24 bits) +- */ +- if (pp > res.bytes + 2 || val > 0xff) +- goto ret_0; +- *pp++ = val; +- c = *++cp; +- } else +- break; +- } +- /* +- * Check for trailing characters. +- */ +- if (c != '\0' && (!isascii(c) || !isspace(c))) +- goto ret_0; +- /* +- * Did we get a valid digit? +- */ +- if (!digit) +- goto ret_0; +- +- /* Check whether the last part is in its limits depending on +- the number of parts in total. */ +- if (val > max[pp - res.bytes]) ++ static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; ++ in_addr_t val; ++ char c; ++ union iaddr ++ { ++ uint8_t bytes[4]; ++ uint32_t word; ++ } res; ++ uint8_t *pp = res.bytes; ++ int digit; ++ ++ int saved_errno = errno; ++ __set_errno (0); ++ ++ res.word = 0; ++ ++ c = *cp; ++ for (;;) ++ { ++ /* Collect number up to ``.''. Values are specified as for C: ++ 0x=hex, 0=octal, isdigit=decimal. */ ++ if (!isdigit (c)) ++ goto ret_0; ++ { ++ char *endp; ++ unsigned long ul = strtoul (cp, &endp, 0); ++ if (ul == ULONG_MAX && errno == ERANGE) + goto ret_0; +- +- if (addr != NULL) +- addr->s_addr = res.word | htonl (val); +- +- __set_errno (saved_errno); +- return (1); +- +-ret_0: +- __set_errno (saved_errno); +- return (0); ++ if (ul > 0xfffffffful) ++ goto ret_0; ++ val = ul; ++ digit = cp != endp; ++ cp = endp; ++ } ++ c = *cp; ++ if (c == '.') ++ { ++ /* Internet format: ++ a.b.c.d ++ a.b.c (with c treated as 16 bits) ++ a.b (with b treated as 24 bits). */ ++ if (pp > res.bytes + 2 || val > 0xff) ++ goto ret_0; ++ *pp++ = val; ++ c = *++cp; ++ } ++ else ++ break; ++ } ++ /* Check for trailing characters. */ ++ if (c != '\0' && (!isascii (c) || !isspace (c))) ++ goto ret_0; ++ /* Did we get a valid digit? */ ++ if (!digit) ++ goto ret_0; ++ ++ /* Check whether the last part is in its limits depending on the ++ number of parts in total. */ ++ if (val > max[pp - res.bytes]) ++ goto ret_0; ++ ++ if (addr != NULL) ++ addr->s_addr = res.word | htonl (val); ++ ++ __set_errno (saved_errno); ++ return 1; ++ ++ ret_0: ++ __set_errno (saved_errno); ++ return 0; + } + weak_alias (__inet_aton, inet_aton) + libc_hidden_def (__inet_aton) diff --git a/SOURCES/glibc-rh1727241-2.patch b/SOURCES/glibc-rh1727241-2.patch new file mode 100644 index 0000000..7f9f417 --- /dev/null +++ b/SOURCES/glibc-rh1727241-2.patch @@ -0,0 +1,80 @@ +commit 6ca53a2453598804a2559a548a08424fca96434a +Author: Florian Weimer +Date: Mon Jan 21 09:26:41 2019 +0100 + + resolv: Do not send queries for non-host-names in nss_dns [BZ #24112] + + Before this commit, nss_dns would send a query which did not contain a + host name as the query name (such as invalid\032name.example.com) and + then reject the answer in getanswer_r and gaih_getanswer_slice, using + a check based on res_hnok. With this commit, no query is sent, and a + host-not-found error is returned to NSS without network interaction. + +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 5dc2829cd148a568..99c3b61e1cee4d42 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -274,11 +274,26 @@ gethostbyname3_context (struct resolv_context *ctx, + return status; + } + ++/* Verify that the name looks like a host name. There is no point in ++ sending a query which will not produce a usable name in the ++ response. */ ++static enum nss_status ++check_name (const char *name, int *h_errnop) ++{ ++ if (res_hnok (name)) ++ return NSS_STATUS_SUCCESS; ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; ++} ++ + enum nss_status + _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop) + { ++ enum nss_status status = check_name (name, h_errnop); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop, + h_errnop, NULL, NULL); + } +@@ -289,6 +304,9 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop) + { ++ enum nss_status status = check_name (name, h_errnop); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { +@@ -296,7 +314,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_UNAVAIL; + } +- enum nss_status status = NSS_STATUS_NOTFOUND; ++ status = NSS_STATUS_NOTFOUND; + if (res_use_inet6 ()) + status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer, + buflen, errnop, h_errnop, NULL, NULL); +@@ -313,6 +331,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + char *buffer, size_t buflen, int *errnop, + int *herrnop, int32_t *ttlp) + { ++ enum nss_status status = check_name (name, herrnop); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { +@@ -347,7 +368,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + int ans2p_malloced = 0; + + int olderr = errno; +- enum nss_status status; + int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA, + host_buffer.buf->buf, 2048, &host_buffer.ptr, + &ans2p, &nans2p, &resplen2, &ans2p_malloced); diff --git a/SOURCES/glibc-rh1727241-3.patch b/SOURCES/glibc-rh1727241-3.patch new file mode 100644 index 0000000..f578ebd --- /dev/null +++ b/SOURCES/glibc-rh1727241-3.patch @@ -0,0 +1,698 @@ +commit 108bc4049f8ae82710aec26a92ffdb4b439c83fd +Author: Florian Weimer +Date: Mon Jan 21 21:26:03 2019 +0100 + + CVE-2016-10739: getaddrinfo: Fully parse IPv4 address strings [BZ #20018] + + The IPv4 address parser in the getaddrinfo function is changed so that + it does not ignore trailing whitespace and all characters after it. + For backwards compatibility, the getaddrinfo function still recognizes + legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8 + (octal). + + This commit does not change the behavior of inet_addr and inet_aton. + gethostbyname already had additional sanity checks (but is switched + over to the new __inet_aton_exact function for completeness as well). + + To avoid sending the problematic query names over DNS, commit + 6ca53a2453598804a2559a548a08424fca96434a ("resolv: Do not send queries + for non-host-names in nss_dns [BZ #24112]") is needed. + +diff --git a/include/arpa/inet.h b/include/arpa/inet.h +index c3f28f2baaa2ed66..19aec74275069a45 100644 +--- a/include/arpa/inet.h ++++ b/include/arpa/inet.h +@@ -1,10 +1,10 @@ + #include + + #ifndef _ISOMAC +-extern int __inet_aton (const char *__cp, struct in_addr *__inp); +-libc_hidden_proto (__inet_aton) ++/* Variant of inet_aton which rejects trailing garbage. */ ++extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp); ++libc_hidden_proto (__inet_aton_exact) + +-libc_hidden_proto (inet_aton) + libc_hidden_proto (inet_ntop) + libc_hidden_proto (inet_pton) + extern __typeof (inet_pton) __inet_pton; +diff --git a/nscd/gai.c b/nscd/gai.c +index 24bdfee1db3791e2..f57f396f574a6e52 100644 +--- a/nscd/gai.c ++++ b/nscd/gai.c +@@ -19,7 +19,6 @@ + + /* This file uses the getaddrinfo code but it compiles it without NSCD + support. We just need a few symbol renames. */ +-#define __inet_aton inet_aton + #define __ioctl ioctl + #define __getsockname getsockname + #define __socket socket +diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c +index 7beb9dce9f4b350c..f792c4fcd042d13d 100644 +--- a/nscd/gethstbynm3_r.c ++++ b/nscd/gethstbynm3_r.c +@@ -38,8 +38,6 @@ + #define HAVE_LOOKUP_BUFFER 1 + #define HAVE_AF 1 + +-#define __inet_aton inet_aton +- + /* We are nscd, so we don't want to be talking to ourselves. */ + #undef USE_NSCD + +diff --git a/nss/digits_dots.c b/nss/digits_dots.c +index 39bff38865a1ac5b..5441bce16ea8b2e9 100644 +--- a/nss/digits_dots.c ++++ b/nss/digits_dots.c +@@ -29,7 +29,6 @@ + #include "nsswitch.h" + + #ifdef USE_NSCD +-# define inet_aton __inet_aton + # include + #endif + +@@ -160,7 +159,7 @@ __nss_hostname_digits_dots_context (struct resolv_context *ctx, + 255.255.255.255? The test below will succeed + spuriously... ??? */ + if (af == AF_INET) +- ok = __inet_aton (name, (struct in_addr *) host_addr); ++ ok = __inet_aton_exact (name, (struct in_addr *) host_addr); + else + { + assert (af == AF_INET6); +diff --git a/resolv/Makefile b/resolv/Makefile +index 56718654eeab85a3..72a0f196506ac489 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -34,6 +34,9 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ + tests = tst-aton tst-leaks tst-inet_ntop + xtests = tst-leaks2 + ++tests-internal += tst-inet_aton_exact ++ ++ + generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace + + extra-libs := libresolv libnss_dns +@@ -54,8 +57,10 @@ tests += \ + tst-resolv-binary \ + tst-resolv-edns \ + tst-resolv-network \ ++ tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ ++ tst-resolv-trailing \ + + # These tests need libdl. + ifeq (yes,$(build-shared)) +@@ -190,9 +195,11 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \ + $(shared-thread-library) ++$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-threads: \ + $(libdl) $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-canonname: \ +diff --git a/resolv/Versions b/resolv/Versions +index b05778d9654aa0f2..9a82704af75f789b 100644 +--- a/resolv/Versions ++++ b/resolv/Versions +@@ -27,6 +27,7 @@ libc { + __h_errno; __resp; + + __res_iclose; ++ __inet_aton_exact; + __inet_pton_length; + __resolv_context_get; + __resolv_context_get_preinit; +diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c +index 32f58b0e13598b32..41b6166a5bd5a44b 100644 +--- a/resolv/inet_addr.c ++++ b/resolv/inet_addr.c +@@ -96,26 +96,14 @@ + #include + #include + +-/* ASCII IPv4 Internet address interpretation routine. The value +- returned is in network order. */ +-in_addr_t +-__inet_addr (const char *cp) +-{ +- struct in_addr val; +- +- if (__inet_aton (cp, &val)) +- return val.s_addr; +- return INADDR_NONE; +-} +-weak_alias (__inet_addr, inet_addr) +- + /* Check whether "cp" is a valid ASCII representation of an IPv4 + Internet address and convert it to a binary address. Returns 1 if + the address is valid, 0 if not. This replaces inet_addr, the + return value from which cannot distinguish between failure and a +- local broadcast address. */ +-int +-__inet_aton (const char *cp, struct in_addr *addr) ++ local broadcast address. Write a pointer to the first ++ non-converted character to *endp. */ ++static int ++inet_aton_end (const char *cp, struct in_addr *addr, const char **endp) + { + static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; + in_addr_t val; +@@ -180,6 +168,7 @@ __inet_aton (const char *cp, struct in_addr *addr) + + if (addr != NULL) + addr->s_addr = res.word | htonl (val); ++ *endp = cp; + + __set_errno (saved_errno); + return 1; +@@ -188,6 +177,41 @@ __inet_aton (const char *cp, struct in_addr *addr) + __set_errno (saved_errno); + return 0; + } +-weak_alias (__inet_aton, inet_aton) +-libc_hidden_def (__inet_aton) +-libc_hidden_weak (inet_aton) ++ ++int ++__inet_aton_exact (const char *cp, struct in_addr *addr) ++{ ++ struct in_addr val; ++ const char *endp; ++ /* Check that inet_aton_end parsed the entire string. */ ++ if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0) ++ { ++ *addr = val; ++ return 1; ++ } ++ else ++ return 0; ++} ++libc_hidden_def (__inet_aton_exact) ++ ++/* inet_aton ignores trailing garbage. */ ++int ++__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr) ++{ ++ const char *endp; ++ return inet_aton_end (cp, addr, &endp); ++} ++weak_alias (__inet_aton_ignore_trailing, inet_aton) ++ ++/* ASCII IPv4 Internet address interpretation routine. The value ++ returned is in network order. */ ++in_addr_t ++__inet_addr (const char *cp) ++{ ++ struct in_addr val; ++ const char *endp; ++ if (inet_aton_end (cp, &val, &endp)) ++ return val.s_addr; ++ return INADDR_NONE; ++} ++weak_alias (__inet_addr, inet_addr) +diff --git a/resolv/res_init.c b/resolv/res_init.c +index f5e52cbbb9377762..94743a252e39d64a 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -399,8 +399,16 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + cp = parser->buffer + sizeof ("nameserver") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; ++ ++ /* Ignore trailing contents on the name server line. */ ++ { ++ char *el; ++ if ((el = strpbrk (cp, " \t\n")) != NULL) ++ *el = '\0'; ++ } ++ + struct sockaddr *sa; +- if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a)) ++ if ((*cp != '\0') && (*cp != '\n') && __inet_aton_exact (cp, &a)) + { + sa = allocate_address_v4 (a, NAMESERVER_PORT); + if (sa == NULL) +@@ -410,9 +418,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + { + struct in6_addr a6; + char *el; +- +- if ((el = strpbrk (cp, " \t\n")) != NULL) +- *el = '\0'; + if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL) + *el = '\0'; + if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0)) +@@ -472,7 +477,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + char separator = *cp; + *cp = 0; + struct resolv_sortlist_entry e; +- if (__inet_aton (net, &a)) ++ if (__inet_aton_exact (net, &a)) + { + e.addr = a; + if (is_sort_mask (separator)) +@@ -484,7 +489,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) + cp++; + separator = *cp; + *cp = 0; +- if (__inet_aton (net, &a)) ++ if (__inet_aton_exact (net, &a)) + e.mask = a.s_addr; + else + e.mask = net_mask (e.addr); +diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c +index 08110a007af909ff..eb734d7758d6ed87 100644 +--- a/resolv/tst-aton.c ++++ b/resolv/tst-aton.c +@@ -1,11 +1,29 @@ ++/* Test legacy IPv4 text-to-address function inet_aton. ++ Copyright (C) 1998-2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include + #include + #include + #include + #include + #include + +- +-static struct tests ++static const struct tests + { + const char *input; + int valid; +@@ -16,6 +34,7 @@ static struct tests + { "-1", 0, 0 }, + { "256", 1, 0x00000100 }, + { "256.", 0, 0 }, ++ { "255a", 0, 0 }, + { "256a", 0, 0 }, + { "0x100", 1, 0x00000100 }, + { "0200.0x123456", 1, 0x80123456 }, +@@ -40,7 +59,12 @@ static struct tests + { "1.2.256.4", 0, 0 }, + { "1.2.3.0x100", 0, 0 }, + { "323543357756889", 0, 0 }, +- { "10.1.2.3.4", 0, 0}, ++ { "10.1.2.3.4", 0, 0 }, ++ { "192.0.2.1", 1, 0xc0000201 }, ++ { "192.0.2.2\nX", 1, 0xc0000202 }, ++ { "192.0.2.3 Y", 1, 0xc0000203 }, ++ { "192.0.2.3Z", 0, 0 }, ++ { "192.000.002.010", 1, 0xc0000208 }, + }; + + +@@ -50,7 +74,7 @@ do_test (void) + int result = 0; + size_t cnt; + +- for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt) ++ for (cnt = 0; cnt < array_length (tests); ++cnt) + { + struct in_addr addr; + +@@ -73,5 +97,4 @@ do_test (void) + return result; + } + +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++#include +diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c +new file mode 100644 +index 0000000000000000..0fdfa3d6aa9aef91 +--- /dev/null ++++ b/resolv/tst-inet_aton_exact.c +@@ -0,0 +1,47 @@ ++/* Test internal legacy IPv4 text-to-address function __inet_aton_exact. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct in_addr addr = { }; ++ ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.1", &addr), 1); ++ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000201); ++ ++ TEST_COMPARE (__inet_aton_exact ("192.000.002.010", &addr), 1); ++ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000208); ++ TEST_COMPARE (__inet_aton_exact ("0xC0000234", &addr), 1); ++ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000234); ++ ++ /* Trailing content is not accepted. */ ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.2X", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.3 Y", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.4\nZ", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.5\tT", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.6 Y", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.7\n", &addr), 0); ++ TEST_COMPARE (__inet_aton_exact ("192.0.2.8\t", &addr), 0); ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-nondecimal.c b/resolv/tst-resolv-nondecimal.c +new file mode 100644 +index 0000000000000000..a0df6f332ae8faf7 +--- /dev/null ++++ b/resolv/tst-resolv-nondecimal.c +@@ -0,0 +1,139 @@ ++/* Test name resolution behavior for octal, hexadecimal IPv4 addresses. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* The tests are not supposed send any DNS queries. */ ++ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype); ++} ++ ++static void ++run_query_addrinfo (const char *query, const char *address) ++{ ++ char *quoted_query = support_quote_string (query); ++ ++ struct addrinfo *ai; ++ struct addrinfo hints = ++ { ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ ++ char *context = xasprintf ("getaddrinfo \"%s\" AF_INET", quoted_query); ++ char *expected = xasprintf ("address: STREAM/TCP %s 80\n", address); ++ hints.ai_family = AF_INET; ++ int ret = getaddrinfo (query, "80", &hints, &ai); ++ check_addrinfo (context, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (context); ++ ++ context = xasprintf ("getaddrinfo \"%s\" AF_UNSPEC", quoted_query); ++ hints.ai_family = AF_UNSPEC; ++ ret = getaddrinfo (query, "80", &hints, &ai); ++ check_addrinfo (context, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (expected); ++ free (context); ++ ++ context = xasprintf ("getaddrinfo \"%s\" AF_INET6", quoted_query); ++ expected = xasprintf ("flags: AI_V4MAPPED\n" ++ "address: STREAM/TCP ::ffff:%s 80\n", ++ address); ++ hints.ai_family = AF_INET6; ++ hints.ai_flags = AI_V4MAPPED; ++ ret = getaddrinfo (query, "80", &hints, &ai); ++ check_addrinfo (context, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (expected); ++ free (context); ++ ++ free (quoted_query); ++} ++ ++static void ++run_query (const char *query, const char *address) ++{ ++ char *quoted_query = support_quote_string (query); ++ char *context = xasprintf ("gethostbyname (\"%s\")", quoted_query); ++ char *expected = xasprintf ("name: %s\n" ++ "address: %s\n", query, address); ++ check_hostent (context, gethostbyname (query), expected); ++ free (context); ++ ++ context = xasprintf ("gethostbyname_r \"%s\"", quoted_query); ++ struct hostent storage; ++ char buf[4096]; ++ struct hostent *e = NULL; ++ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ check_hostent (context, e, expected); ++ free (context); ++ ++ context = xasprintf ("gethostbyname2 (\"%s\", AF_INET)", quoted_query); ++ check_hostent (context, gethostbyname2 (query, AF_INET), expected); ++ free (context); ++ ++ context = xasprintf ("gethostbyname2_r \"%s\" AF_INET", quoted_query); ++ e = NULL; ++ TEST_COMPARE (gethostbyname2_r (query, AF_INET, &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ check_hostent (context, e, expected); ++ free (context); ++ free (expected); ++ ++ free (quoted_query); ++ ++ /* The gethostbyname tests are always valid for getaddrinfo, but not ++ vice versa. */ ++ run_query_addrinfo (query, address); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ run_query ("192.000.002.010", "192.0.2.8"); ++ ++ /* Hexadecimal numbers are not accepted by gethostbyname. */ ++ run_query_addrinfo ("0xc0000210", "192.0.2.16"); ++ run_query_addrinfo ("192.0x234", "192.0.2.52"); ++ ++ resolv_test_end (aux); ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-trailing.c b/resolv/tst-resolv-trailing.c +new file mode 100644 +index 0000000000000000..7504bdae572ed8d0 +--- /dev/null ++++ b/resolv/tst-resolv-trailing.c +@@ -0,0 +1,136 @@ ++/* Test name resolution behavior with trailing characters. ++ Copyright (C) 2019 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* The tests are not supposed send any DNS queries. */ ++ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ static const char *const queries[] = ++ { ++ "192.0.2.1 ", ++ "192.0.2.2\t", ++ "192.0.2.3\n", ++ "192.0.2.4 X", ++ "192.0.2.5\tY", ++ "192.0.2.6\nZ", ++ "192.0.2. ", ++ "192.0.2.\t", ++ "192.0.2.\n", ++ "192.0.2. X", ++ "192.0.2.\tY", ++ "192.0.2.\nZ", ++ "2001:db8::1 ", ++ "2001:db8::2\t", ++ "2001:db8::3\n", ++ "2001:db8::4 X", ++ "2001:db8::5\tY", ++ "2001:db8::6\nZ", ++ }; ++ for (size_t query_idx = 0; query_idx < array_length (queries); ++query_idx) ++ { ++ const char *query = queries[query_idx]; ++ struct hostent storage; ++ char buf[4096]; ++ struct hostent *e; ++ ++ h_errno = 0; ++ TEST_VERIFY (gethostbyname (query) == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ e = NULL; ++ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ TEST_VERIFY (e == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ TEST_VERIFY (gethostbyname2 (query, AF_INET) == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ e = NULL; ++ TEST_COMPARE (gethostbyname2_r (query, AF_INET, ++ &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ TEST_VERIFY (e == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ TEST_VERIFY (gethostbyname2 (query, AF_INET6) == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ h_errno = 0; ++ e = NULL; ++ TEST_COMPARE (gethostbyname2_r (query, AF_INET6, ++ &storage, buf, sizeof (buf), ++ &e, &h_errno), 0); ++ TEST_VERIFY (e == NULL); ++ TEST_COMPARE (h_errno, HOST_NOT_FOUND); ++ ++ static const int gai_flags[] = ++ { ++ 0, ++ AI_ADDRCONFIG, ++ AI_NUMERICHOST, ++ AI_IDN, ++ AI_IDN | AI_NUMERICHOST, ++ AI_V4MAPPED, ++ AI_V4MAPPED | AI_NUMERICHOST, ++ }; ++ for (size_t gai_flags_idx; gai_flags_idx < array_length (gai_flags); ++ ++gai_flags_idx) ++ { ++ struct addrinfo hints = { .ai_flags = gai_flags[gai_flags_idx], }; ++ struct addrinfo *ai; ++ hints.ai_family = AF_INET; ++ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME); ++ hints.ai_family = AF_INET6; ++ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME); ++ hints.ai_family = AF_UNSPEC; ++ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME); ++ } ++ }; ++ ++ resolv_test_end (aux); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 00e0d94a8f5bb30d..6a5805c9e63a257c 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -488,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + malloc_name = true; + } + +- if (__inet_aton (name, (struct in_addr *) at->addr) != 0) ++ if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0) + { + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) + at->family = AF_INET; diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index 8388f74..a416a96 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.28 %define glibcversion 2.28 -%define glibcrelease 42%{?dist}.1 +%define glibcrelease 72%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -138,7 +138,6 @@ Source12: ChangeLog.old # - See each individual patch file for origin and upstream status. # - For new patches follow template.patch format. ############################################################################## -Patch1: glibc-post_upgrade.patch Patch2: glibc-fedora-nscd.patch Patch3: glibc-rh697421.patch Patch4: glibc-fedora-linux-tcsetattr.patch @@ -206,7 +205,116 @@ Patch70: glibc-rh1642094-2.patch Patch71: glibc-rh1642094-3.patch Patch72: glibc-rh1654872-1.patch Patch73: glibc-rh1654872-2.patch -Patch74: glibc-rh1692450.patch +Patch74: glibc-rh1651283-1.patch +Patch75: glibc-rh1662843-1.patch +Patch76: glibc-rh1662843-2.patch +Patch77: glibc-rh1623537.patch +Patch78: glibc-rh1577438.patch +Patch79: glibc-rh1664408.patch +Patch80: glibc-rh1651742.patch +Patch81: glibc-rh1672773.patch +Patch82: glibc-rh1651283-2.patch +Patch83: glibc-rh1651283-3.patch +Patch84: glibc-rh1651283-4.patch +Patch85: glibc-rh1651283-5.patch +Patch86: glibc-rh1651283-6.patch +Patch87: glibc-rh1651283-7.patch +Patch88: glibc-rh1659293-1.patch +Patch89: glibc-rh1659293-2.patch +Patch90: glibc-rh1639343-1.patch +Patch91: glibc-rh1639343-2.patch +Patch92: glibc-rh1639343-3.patch +Patch93: glibc-rh1639343-4.patch +Patch94: glibc-rh1639343-5.patch +Patch95: glibc-rh1639343-6.patch +Patch96: glibc-rh1663035.patch +Patch97: glibc-rh1658901.patch +Patch98: glibc-rh1659512-1.patch +Patch99: glibc-rh1659512-2.patch +Patch100: glibc-rh1659438-1.patch +Patch101: glibc-rh1659438-2.patch +Patch102: glibc-rh1659438-3.patch +Patch103: glibc-rh1659438-4.patch +Patch104: glibc-rh1659438-5.patch +Patch105: glibc-rh1659438-6.patch +Patch106: glibc-rh1659438-7.patch +Patch107: glibc-rh1659438-8.patch +Patch108: glibc-rh1659438-9.patch +Patch109: glibc-rh1659438-10.patch +Patch110: glibc-rh1659438-11.patch +Patch111: glibc-rh1659438-12.patch +Patch112: glibc-rh1659438-13.patch +Patch113: glibc-rh1659438-14.patch +Patch114: glibc-rh1659438-15.patch +Patch115: glibc-rh1659438-16.patch +Patch116: glibc-rh1659438-17.patch +Patch117: glibc-rh1659438-18.patch +Patch118: glibc-rh1659438-19.patch +Patch119: glibc-rh1659438-20.patch +Patch120: glibc-rh1659438-21.patch +Patch121: glibc-rh1659438-22.patch +Patch122: glibc-rh1659438-23.patch +Patch123: glibc-rh1659438-24.patch +Patch124: glibc-rh1659438-25.patch +Patch125: glibc-rh1659438-26.patch +Patch126: glibc-rh1659438-27.patch +Patch127: glibc-rh1659438-28.patch +Patch128: glibc-rh1659438-29.patch +Patch129: glibc-rh1659438-30.patch +Patch130: glibc-rh1659438-31.patch +Patch131: glibc-rh1659438-32.patch +Patch132: glibc-rh1659438-33.patch +Patch133: glibc-rh1659438-34.patch +Patch134: glibc-rh1659438-35.patch +Patch135: glibc-rh1659438-36.patch +Patch136: glibc-rh1659438-37.patch +Patch137: glibc-rh1659438-38.patch +Patch138: glibc-rh1659438-39.patch +Patch139: glibc-rh1659438-40.patch +Patch140: glibc-rh1659438-41.patch +Patch141: glibc-rh1659438-42.patch +Patch142: glibc-rh1659438-43.patch +Patch143: glibc-rh1659438-44.patch +Patch144: glibc-rh1659438-45.patch +Patch145: glibc-rh1659438-46.patch +Patch146: glibc-rh1659438-47.patch +Patch147: glibc-rh1659438-48.patch +Patch148: glibc-rh1659438-49.patch +Patch149: glibc-rh1659438-50.patch +Patch150: glibc-rh1659438-51.patch +Patch151: glibc-rh1659438-52.patch +Patch152: glibc-rh1659438-53.patch +Patch153: glibc-rh1659438-54.patch +Patch154: glibc-rh1659438-55.patch +Patch155: glibc-rh1659438-56.patch +Patch156: glibc-rh1659438-57.patch +Patch157: glibc-rh1659438-58.patch +Patch158: glibc-rh1659438-59.patch +Patch159: glibc-rh1659438-60.patch +Patch160: glibc-rh1659438-61.patch +Patch161: glibc-rh1659438-62.patch +Patch162: glibc-rh1702539-1.patch +Patch163: glibc-rh1702539-2.patch +Patch164: glibc-rh1701605-1.patch +Patch165: glibc-rh1701605-2.patch +Patch166: glibc-rh1691528-1.patch +Patch167: glibc-rh1691528-2.patch +Patch168: glibc-rh1706777.patch +Patch169: glibc-rh1710478.patch +Patch170: glibc-rh1670043-1.patch +Patch171: glibc-rh1670043-2.patch +Patch172: glibc-rh1710894.patch +Patch173: glibc-rh1699194-1.patch +Patch174: glibc-rh1699194-2.patch +Patch175: glibc-rh1699194-3.patch +Patch176: glibc-rh1699194-4.patch +Patch177: glibc-rh1727241-1.patch +Patch178: glibc-rh1727241-2.patch +Patch179: glibc-rh1727241-3.patch +Patch180: glibc-rh1717438.patch +Patch181: glibc-rh1727152.patch +Patch182: glibc-rh1724975.patch +Patch183: glibc-rh1722215.patch ############################################################################## # Continued list of core "glibc" package information: @@ -287,8 +395,8 @@ BuildRequires: make >= 4.0 # The intl subsystem generates a parser using bison. BuildRequires: bison >= 2.7 -# binutils 2.30-17 is needed for --generate-missing-build-notes. -BuildRequires: binutils >= 2.30-17 +# binutils 2.30-51 is needed for z13 support on s390x. +BuildRequires: binutils >= 2.30-51 # Earlier releases have broken support for IRELATIVE relocations Conflicts: prelink < 0.4.2 @@ -445,8 +553,11 @@ libraries, as well as national language (locale) support. /sbin/ldconfig %end -# We need to run ldconfig manually because ldconfig cannot handle the -# relative include path in the /etc/ld.so.conf file we gneerate. +# We need to run ldconfig manually because __brp_ldconfig assumes that +# glibc itself is always installed in $RPM_BUILD_ROOT, but with sysroots +# we may be installed into a subdirectory of that path. Therefore we +# unset __brp_ldconfig and run ldconfig by hand with the sysroots path +# passed to -r. %undefine __brp_ldconfig ###################################################################### @@ -1086,8 +1197,19 @@ $olddir/build-%{target}/elf/ld.so \ $olddir/build-%{target}/locale/localedef \ --prefix %{glibc_sysroot} --add-to-archive \ eo *_* -# Setup the locale-archive template for use by glibc-all-langpacks. -mv locale-archive{,.tmpl} +# Setup the locale-archive template for use by glibc-all-langpacks. We +# copy the archive in place to keep the size of the file. Even though we +# mark the file with "ghost" the size is used by rpm to compute the +# required free space (see rhbz#1725131). We do this because there is a +# point in the install when build-locale-archive has copied 100% of the +# template into the new locale archive and so this consumes twice the +# amount of diskspace. Note that this doesn't account for copying +# existing compiled locales into the archive, this may consume even more +# disk space and we can't fix that issue. In upstream we have moved away +# from this process, removing build-locale-archive and installing a +# default locale-archive without modification, and leaving compiled +# locales as they are (without inclusion into the archive). +cp locale-archive{,.tmpl} # Create the file lists for the language specific sub-packages: for i in eo *_* do @@ -1141,10 +1263,6 @@ truncate -s 0 %{glibc_sysroot}/etc/gai.conf truncate -s 0 %{glibc_sysroot}%{_libdir}/gconv/gconv-modules.cache chmod 644 %{glibc_sysroot}%{_libdir}/gconv/gconv-modules.cache -# Install the upgrade program -install -m 700 build-%{target}/elf/glibc_post_upgrade \ - %{glibc_sysroot}%{_prefix}/sbin/glibc_post_upgrade.%{_target_cpu} - ############################################################################## # Install debug copies of unstripped static libraries # - This step must be last in order to capture any additional static @@ -1167,8 +1285,8 @@ rm -rf %{glibc_sysroot}%{_prefix}/share/zoneinfo # # XXX: Ideally ld.so.conf should have the timestamp of the spec file, but there # doesn't seem to be any macro to give us that. So we do the next best thing, -# which is to at least keep the timestamp consistent. The choice of using -# glibc_post_upgrade.c is arbitrary. +# which is to at least keep the timestamp consistent. The choice of using +# SOURCE0 is arbitrary. touch -r %{SOURCE0} %{glibc_sysroot}/etc/ld.so.conf touch -r sunrpc/etc.rpc %{glibc_sysroot}/etc/rpc @@ -1231,7 +1349,6 @@ rm -f %{glibc_sysroot}%{_infodir}/dir %endif %ifnarch %{auxarches} -truncate -s 0 %{glibc_sysroot}/%{_prefix}/lib/locale/locale-archive mkdir -p %{glibc_sysroot}/var/{db,run}/nscd touch %{glibc_sysroot}/var/{db,run}/nscd/{passwd,group,hosts,services} touch %{glibc_sysroot}/var/run/nscd/{socket,nscd.pid} @@ -1404,8 +1521,9 @@ chmod 0444 master.filelist # - The partial (lib*_p.a) static libraries, include files. # - The static files, objects, unversioned DSOs, and nscd. # - The bin, locale, some sbin, and share. -# - The use of [^gi] is meant to exclude all files except glibc_post_upgrade, -# and iconvconfig, which we want in the main packages. +# - We want iconvconfig in the main package and we do this by using +# a double negation of -v and [^i] so it removes all files in +# sbin *but* iconvconfig. # - All the libnss files (we add back the ones we want later). # - All bench test binaries. # - The aux-cache, since it's handled specially in the files section. @@ -1421,7 +1539,7 @@ cat master.filelist \ -e 'nscd' \ -e '%{_prefix}/bin' \ -e '%{_prefix}/lib/locale' \ - -e '%{_prefix}/sbin/[^gi]' \ + -e '%{_prefix}/sbin/[^i]' \ -e '%{_prefix}/share' \ -e '/var/db/Makefile' \ -e '/libnss_.*\.so[0-9.]*$' \ @@ -1498,10 +1616,13 @@ grep '%{_libdir}/lib.*\.a' < master.filelist \ ############################################################################### # All of the bin and certain sbin files go into the common package except -# glibc_post_upgrade.* and iconvconfig which need to go in glibc. Likewise -# nscd is excluded because it goes in nscd. +# iconvconfig which needs to go in glibc. Likewise nscd is excluded because +# it goes in nscd. The iconvconfig binary is kept in the main glibc package +# because we use it in the post-install scriptlet to rebuild the +# gconv-modules.cache. grep '%{_prefix}/bin' master.filelist >> common.filelist -grep '%{_prefix}/sbin/[^gi]' master.filelist \ +grep '%{_prefix}/sbin' master.filelist \ + | grep -v '%{_prefix}/sbin/iconvconfig' \ | grep -v 'nscd' >> common.filelist # All of the files under share go into the common package since they should be # multilib-independent. @@ -1595,7 +1716,7 @@ echo "%{_libdir}/libpthread_nonshared.a" >> compat-libpthread-nonshared.filelist # glibc-debuginfocommon, and glibc-debuginfo ############################################################################### -find_debuginfo_args='--strict-build-id -g' +find_debuginfo_args='--strict-build-id -g -i' %ifarch %{debuginfocommonarches} find_debuginfo_args="$find_debuginfo_args \ -l common.filelist \ @@ -1799,7 +1920,135 @@ if rpm.vercmp(rel, required) < 0 then error("FATAL: kernel too old", 0) end -%post -p %{_prefix}/sbin/glibc_post_upgrade.%{_target_cpu} +%post -p +-- We use lua's posix.exec because there may be no shell that we can +-- run during glibc upgrade. +function post_exec (program, ...) + local pid = posix.fork () + if pid == 0 then + assert (posix.exec (program, ...)) + elseif pid > 0 then + posix.wait (pid) + end +end + +-- (1) Remove multilib libraries from previous installs. +-- In order to support in-place upgrades, we must immediately remove +-- obsolete platform directories after installing a new glibc +-- version. RPM only deletes files removed by updates near the end +-- of the transaction. If we did not remove the obsolete platform +-- directories here, they may be preferred by the dynamic linker +-- during the execution of subsequent RPM scriptlets, likely +-- resulting in process startup failures. + +-- Full set of libraries glibc may install. +install_libs = { "anl", "BrokenLocale", "c", "dl", "m", "mvec", + "nss_compat", "nss_db", "nss_dns", "nss_files", + "nss_hesiod", "pthread", "resolv", "rt", "SegFault", + "thread_db", "util" } + +-- We are going to remove these libraries. Generally speaking we remove +-- all core libraries in the multilib directory. +-- We employ a tight match where X.Y is in [2.0,9.9*], so we would +-- match "libc-2.0.so" and so on up to "libc-9.9*". +remove_regexps = {} +for i = 1, #install_libs do + remove_regexps[i] = ("lib" .. install_libs[i] + .. "%%-[2-9]%%.[0-9]+%%.so$") +end + +-- Two exceptions: +remove_regexps[#install_libs + 1] = "libthread_db%%-1%%.0%%.so" +remove_regexps[#install_libs + 2] = "libSegFault%%.so" + +-- We are going to search these directories. +local remove_dirs = { "%{_libdir}/i686", + "%{_libdir}/i686/nosegneg", + "%{_libdir}/power6", + "%{_libdir}/power7", + "%{_libdir}/power8" } + +-- Walk all the directories with files we need to remove... +for _, rdir in ipairs (remove_dirs) do + if posix.access (rdir) then + -- If the directory exists we look at all the files... + local remove_files = posix.files (rdir) + for rfile in remove_files do + for _, rregexp in ipairs (remove_regexps) do + -- Does it match the regexp? + local dso = string.match (rfile, rregexp) + if (dso ~= nil) then + -- Removing file... + os.remove (rdir .. '/' .. rfile) + end + end + end + end +end + +-- (2) Update /etc/ld.so.conf +-- Next we update /etc/ld.so.conf to ensure that it starts with +-- a literal "include ld.so.conf.d/*.conf". + +local ldsoconf = "/etc/ld.so.conf" +local ldsoconf_tmp = "/etc/glibc_post_upgrade.ld.so.conf" + +if posix.access (ldsoconf) then + + -- We must have a "include ld.so.conf.d/*.conf" line. + local have_include = false + for line in io.lines (ldsoconf) do + -- This must match, and we don't ignore whitespace. + if string.match (line, "^include ld.so.conf.d/%%*%%.conf$") ~= nil then + have_include = true + end + end + + if not have_include then + -- Insert "include ld.so.conf.d/*.conf" line at the start of the + -- file. We only support one of these post upgrades running at + -- a time (temporary file name is fixed). + local tmp_fd = io.open (ldsoconf_tmp, "w") + if tmp_fd ~= nil then + tmp_fd:write ("include ld.so.conf.d/*.conf\n") + for line in io.lines (ldsoconf) do + tmp_fd:write (line .. "\n") + end + tmp_fd:close () + local res = os.rename (ldsoconf_tmp, ldsoconf) + if res == nil then + io.stdout:write ("Error: Unable to update configuration file (rename).\n") + end + else + io.stdout:write ("Error: Unable to update configuration file (open).\n") + end + end +end + +-- (3) Rebuild ld.so.cache early. +-- If the format of the cache changes then we need to rebuild +-- the cache early to avoid any problems running binaries with +-- the new glibc. + +-- Note: We use _prefix because Fedora's UsrMove says so. +post_exec ("%{_prefix}/sbin/ldconfig") + +-- (4) Update gconv modules cache. +-- If the /usr/lib/gconv/gconv-modules.cache exists, then update it +-- with the latest set of modules that were just installed. +-- We assume that the cache is in _libdir/gconv and called +-- "gconv-modules.cache". + +local iconv_dir = "%{_libdir}/gconv" +local iconv_cache = iconv_dir .. "/gconv-modules.cache" +if (posix.utime (iconv_cache) == 0) then + post_exec ("%{_prefix}/sbin/iconvconfig", + "-o", iconv_cache, + "--nostdlib", + iconv_dir) +else + io.stdout:write ("Error: Missing " .. iconv_cache .. " file.\n") +end %posttrans all-langpacks -e -p -- If at the end of the transaction we are still installed @@ -1816,11 +2065,11 @@ if posix.stat("%{_prefix}/lib/locale/locale-archive.tmpl", "size") > 0 then end %postun all-langpacks -p --- In the postun we always remove the locale cache. --- We are being uninstalled and if this is an upgrade --- then the new packages template will be used to --- recreate a new copy of the cache. -os.remove("%{_prefix}/lib/locale/locale-archive") +-- In the postun we remove the locale cache if unstalling. +-- (build-locale-archive will delete the archive during an upgrade.) +if arg[2] == 0 then + os.remove("%{_prefix}/lib/locale/locale-archive") +end %if %{with docs} %post devel @@ -1891,7 +2140,7 @@ fi %files all-langpacks %attr(0644,root,root) %verify(not md5 size mtime) %{_prefix}/lib/locale/locale-archive.tmpl -%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %config(missingok,noreplace) %{_prefix}/lib/locale/locale-archive +%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %{_prefix}/lib/locale/locale-archive %files locale-source %dir %{_prefix}/share/i18n/locales @@ -1952,8 +2201,99 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog -* Mon Apr 1 2019 Florian Weimer - 2.28-42.1 -- ja_JP: Add new Japanese Era name (#1692450) +* Mon Jul 22 2019 Carlos O'Donell - 2.28-72 +- Skip wide buffer handling for legacy stdio handles (#1722215) + +* Mon Jul 22 2019 Carlos O'Donell - 2.28-71 +- Remove copy_file_range emulation (#1724975) + +* Mon Jul 22 2019 Carlos O'Donell - 2.28-70 +- Avoid nscd assertion failure during persistent db check (#1727152) + +* Mon Jul 22 2019 Carlos O'Donell - 2.28-69 +- Fix invalid free under valgrind with libdl (#1717438) + +* Thu Jul 18 2019 Carlos O'Donell - 2.28-68 +- Account for size of locale-archive in rpm package (#1725131) + +* Thu Jul 18 2019 Carlos O'Donell - 2.28-67 +- Reject IP addresses with trailing characters in getaddrinfo (#1727241) + +* Fri Jun 14 2019 Florian Weimer - 2.28-66 +- Avoid header conflict between and (#1699194) + +* Wed Jun 12 2019 Florian Weimer - 2.28-65 +- glibc-all-langpacks: Do not delete locale archive during update (#1717347) +- Do not mark /usr/lib/locale/locale-archive as a configuration file + because it is always automatically overwritten by build-locale-archive. + +* Mon Jun 10 2019 DJ Delorie - 2.28-64 +- Avoid ABI exposure of the NSS service_user type (#1710894) + +* Thu Jun 6 2019 Patsy Griffin Franklin - 2.28-63 +- Enable full ICMP errors for UDP DNS sockets. (#1670043) + +* Mon Jun 3 2019 Carlos O'Donell - 2.28-62 +- Convert post-install binary to rpm lua scriptlet (#1639346) + +* Mon Jun 3 2019 Florian Weimer - 2.28-61 +- Fix crash during wide stream buffer flush (#1710478) + +* Fri May 31 2019 Carlos O'Donell - 2.28-60 +- Add PF_XDP, AF_XDP and SOL_XDP from Linux 4.18 (#1706777) + +* Wed May 22 2019 DJ Delorie - 2.28-59 +- Add .gdb_index to debug information (#1612448) + +* Wed May 22 2019 DJ Delorie - 2.28-57 +- locale: Add LOCPATH diagnostics to the locale program (#1701605) + +* Fri May 17 2019 Patsy Griffin Franklin - 2.28-56 +- Fix hang in pldd. (#1702539) + +* Mon May 13 2019 Florian Weimer - 2.28-55 +- s390x string function improvements (#1659438) + +* Thu May 2 2019 Patsy Griffin Franklin - 2.28-54 +- Fix test suite failures due to race conditions in posix/tst-spawn + spawned processes. (#1659512) + +* Wed May 1 2019 DJ Delorie - 2.28-53 +- Add missing CFI data to __mpn_* functions on ppc64le (#1658901) + +* Fri Apr 26 2019 Arjun Shankar - 2.28-52 +- intl: Do not return NULL on asprintf failure in gettext (#1663035) + +* Fri Apr 26 2019 Florian Weimer - 2.28-51 +- Increase BIND_NOW coverage (#1639343) + +* Tue Apr 23 2019 Carlos O'Donell - 2.28-50 +- Fix pthread_rwlock_trywrlock and pthread_rwlock_tryrdlock stalls (#1659293) + +* Tue Apr 23 2019 Arjun Shankar - 2.28-49 +- malloc: Improve bad chunk detection (#1651283) + +* Mon Apr 22 2019 Patsy Griffin Franklin - 2.28-48 +- Add compiler barriers around modifications of the robust mutex list + for pthread_mutex_trylock. (#1672773) + +* Tue Apr 16 2019 DJ Delorie - 2.28-47 +- powerpc: Only enable HTM if kernel supports PPC_FEATURE2_HTM_NOSC (#1651742) + +* Fri Apr 12 2019 Florian Weimer - 2.28-46 +- Only build libm with -fno-math-errno (#1664408) + +* Tue Apr 2 2019 Florian Weimer - 2.28-45 +- ja_JP: Add new Japanese Era name (#1577438) + +* Wed Mar 6 2019 Florian Weimer - 2.28-44 +- math: Add XFAILs for some IBM 128-bit long double fma tests (#1623537) + +* Fri Mar 1 2019 Florian Weimer - 2.28-43 +- malloc: realloc ncopies integer overflow (#1662843) * Fri Dec 14 2018 Florian Weimer - 2.28-42 - Fix rdlock stall with PREFER_WRITER_NONRECURSIVE_NP (#1654872)