From 93dc7acb038ab57cb12d951676abc44634126c14 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 08 2020 11:16:47 +0000 Subject: Prepare for a new update Reverting patches so we can apply the latest update and changes can be seen in the spec file and sources. --- diff --git a/.gitignore b/.gitignore index e9e6657..07d4a12 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ TODO AUTHORS copyr-* copying.* +glibc-* configparms diff --git a/.packit.yaml b/.packit.yaml index e214156..86592de 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -1,16 +1,12 @@ jobs: - job: copr_build metadata: - targets: + targets: &id001 - centos-stream-x86_64 trigger: pull_request - job: tests metadata: - targets: - - centos-stream-x86_64 + targets: *id001 trigger: pull_request specfile_path: SPECS/glibc.spec upstream_ref: sg-start -patch_generation_ignore_paths: -- SPECS/ -- .gitignore diff --git a/ChangeLog b/ChangeLog index 74e6346..08b42bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,27 +1,3 @@ -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 - - [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/INSTALL b/INSTALL index d56e102..781cb84 100644 --- a/INSTALL +++ b/INSTALL @@ -90,15 +90,6 @@ if 'CFLAGS' is specified it must enable optimization. For example: library will still be usable, but functionality may be lost--for example, you can't build a shared libc with old binutils. -'--with-nonshared-cflags=CFLAGS' - Use additional compiler flags CFLAGS to build the parts of the - library which are always statically linked into applications and - libraries even with shared linking (that is, the object files - contained in 'lib*_nonshared.a' libraries). The build process will - automatically use the appropriate flags, but this option can be - used to set additional flags required for building applications and - libraries, to match local policy. - '--disable-shared' Don't build shared libraries even if it is possible. Not all systems support shared libraries; you need ELF support and @@ -169,10 +160,10 @@ if 'CFLAGS' is specified it must enable optimization. For example: protection. '--enable-bind-now' - 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. + 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. '--enable-pt_chown' The file 'pt_chown' is a helper binary for 'grantpt' (*note diff --git a/Makeconfig b/Makeconfig index 0ac6ed9..608ffe6 100644 --- a/Makeconfig +++ b/Makeconfig @@ -398,8 +398,6 @@ 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). @@ -415,7 +413,7 @@ link-extra-libs-tests = $(libsupport) # Command for linking PIE programs with the C library. ifndef +link-pie -+link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ ++link-pie-before-libc = $(CC) $(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,24 +426,23 @@ ifndef +link-pie $(link-extra-libs) +link-pie-after-libc = $(+postctorS) $(+postinit) define +link-pie -$(CC) $(link-libc-rpath-link) $(+link-pie-before-libc) $(rtld-LDFLAGS) \ - $(link-extra-flags) $(link-libc) $(+link-pie-after-libc) +$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-pie-after-libc) $(call after-link,$@) endef define +link-pie-tests -$(CC) $(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ - $(+link-pie-after-libc) +$(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ + $(+link-pie-after-libc) $(call after-link,$@) endef define +link-pie-printers-tests -$(CC) $(+link-pie-before-libc) $(built-rtld-LDFLAGS) \ - $(link-libc-printers-tests) $(+link-pie-after-libc) +$(+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 = -nostdlib -nostartfiles -static -o $@ \ ++link-static-before-libc = $(CC) -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)) \ @@ -457,13 +454,11 @@ ifndef +link-static $(link-extra-libs-static) +link-static-after-libc = $(+postctorT) $(+postinit) define +link-static -$(CC) $(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) \ - $(+link-static-after-libc) +$(+link-static-before-libc) $(link-libc-static) $(+link-static-after-libc) $(call after-link,$@) endef define +link-static-tests -$(CC) $(+link-static-before-libc) $(link-libc-static-tests) \ - $(+link-static-after-libc) +$(+link-static-before-libc) $(link-libc-static-tests) $(+link-static-after-libc) $(call after-link,$@) endef endif @@ -478,7 +473,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 = -nostdlib -nostartfiles -o $@ \ ++link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \ @@ -490,17 +485,16 @@ else # not build-pie-default $(link-extra-libs) +link-after-libc = $(+postctor) $(+postinit) define +link -$(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \ - $(link-extra-flags) $(link-libc) $(+link-after-libc) +$(+link-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-after-libc) $(call after-link,$@) endef define +link-tests -$(CC) $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ +$(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \ $(+link-after-libc) $(call after-link,$@) endef define +link-printers-tests -$(CC) $(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ +$(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \ $(+link-after-libc) $(call after-link,$@) endef @@ -552,15 +546,6 @@ 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 @@ -571,7 +556,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-before-gnulib) $(gnulib) +link-libc = $(link-libc-rpath-link) $(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) \ @@ -846,10 +831,8 @@ endif # disable any optimization that assume default rounding mode. +math-flags = -frounding-math -# 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) +# 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) # We might want to compile with some stack-protection flag. ifneq ($(stack-protector),) @@ -1055,7 +1038,7 @@ object-suffixes-for-libc += .oS # Must build the routines as PIC, though, because they can end up in (users') # shared objects. We don't want to use CFLAGS-os because users may, for # example, make that processor-specific. -CFLAGS-.oS = $(CFLAGS-.o) $(PIC-ccflag) $(extra-nonshared-cflags) +CFLAGS-.oS = $(CFLAGS-.o) $(PIC-ccflag) CPPFLAGS-.oS = $(CPPFLAGS-.o) -DPIC -DLIBC_NONSHARED=1 libtype.oS = lib%_nonshared.a endif @@ -1064,7 +1047,7 @@ endif ifndef ASFLAGS ASFLAGS := $(filter -g% -fdebug-prefix-map=%,$(CFLAGS)) endif -override ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu) +ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu) ifndef BUILD_CC BUILD_CC = $(CC) @@ -1215,9 +1198,9 @@ else libsupport = $(common-objpfx)support/libsupport.a endif -# This is a partial list of subdirectories containing the library source. -# The order is more or less arbitrary. The sorting step will take care of the -# dependencies and generate sorted-subdirs dynamically. +# These are the subdirectories containing the library source. The order +# is more or less arbitrary. The sorting step will take care of the +# dependencies. all-subdirs = csu assert ctype locale intl catgets math setjmp signal \ stdlib stdio-common libio malloc string wcsmbs time dirent \ grp pwd posix io termios resource misc socket sysvipc gmon \ diff --git a/Makefile b/Makefile index ae44b9c..d3f25a5 100644 --- a/Makefile +++ b/Makefile @@ -340,65 +340,6 @@ define summarize-tests @! egrep -q -v '^(X?PASS|XFAIL|UNSUPPORTED):' $(objpfx)$1 endef -# The intention here is to do ONE install of our build into the -# testroot.pristine/ directory, then rsync (internal to -# support/test-container) that to testroot.root/ at the start of each -# test. That way we can promise each test a "clean" install, without -# having to do the install for each test. -# -# In addition, we have to copy some files (which we build) into this -# root in addition to what glibc installs. For example, many tests -# require additional programs including /bin/sh, /bin/true, and -# /bin/echo, all of which we build below to limit library dependencies -# to just those things in glibc and language support libraries which -# we also copy into the into the rootfs. To determine what language -# support libraries we need we build a "test" program in either C or -# (if available) C++ just so we can copy in any shared objects -# (which we do not build) that GCC-compiled programs depend on. - - -ifeq (,$(CXX)) -LINKS_DSO_PROGRAM = links-dso-program-c -else -LINKS_DSO_PROGRAM = links-dso-program -endif - -$(tests-container) $(addsuffix /tests,$(subdirs)) : \ - $(objpfx)testroot.pristine/install.stamp -$(objpfx)testroot.pristine/install.stamp : - test -d $(objpfx)testroot.pristine || \ - mkdir $(objpfx)testroot.pristine - # We need a working /bin/sh for some of the tests. - test -d $(objpfx)testroot.pristine/bin || \ - mkdir $(objpfx)testroot.pristine/bin - cp $(objpfx)support/shell-container $(objpfx)testroot.pristine/bin/sh - cp $(objpfx)support/echo-container $(objpfx)testroot.pristine/bin/echo - cp $(objpfx)support/true-container $(objpfx)testroot.pristine/bin/true -ifeq ($(run-built-tests),yes) - # Copy these DSOs first so we can overwrite them with our own. - for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ - $(rtld-prefix) \ - $(objpfx)testroot.pristine/bin/sh \ - | sed -n '/\//{s@.*=> /@/@;s/^[^/]*//;s/ .*//p;}'` ;\ - do \ - test -d `dirname $(objpfx)testroot.pristine$$dso` || \ - mkdir -p `dirname $(objpfx)testroot.pristine$$dso` ;\ - $(test-wrapper) cp $$dso $(objpfx)testroot.pristine$$dso ;\ - done - for dso in `$(test-wrapper-env) LD_TRACE_LOADED_OBJECTS=1 \ - $(rtld-prefix) \ - $(objpfx)support/$(LINKS_DSO_PROGRAM) \ - | sed -n '/\//{s@.*=> /@/@;s/^[^/]*//;s/ .*//p;}'` ;\ - do \ - test -d `dirname $(objpfx)testroot.pristine$$dso` || \ - mkdir -p `dirname $(objpfx)testroot.pristine$$dso` ;\ - $(test-wrapper) cp $$dso $(objpfx)testroot.pristine$$dso ;\ - done -endif - $(MAKE) install DESTDIR=$(objpfx)testroot.pristine \ - subdirs='$(sorted-subdirs)' - touch $(objpfx)testroot.pristine/install.stamp - tests-special-notdir = $(patsubst $(objpfx)%, %, $(tests-special)) tests: $(tests-special) $(..)scripts/merge-test-results.sh -s $(objpfx) "" \ diff --git a/Makerules b/Makerules index 5d6434c..a10a0b4 100644 --- a/Makerules +++ b/Makerules @@ -1369,8 +1369,7 @@ xcheck: xtests # The only difference between MODULE_NAME=testsuite and MODULE_NAME=nonlib is # that almost all internal declarations from config.h, libc-symbols.h, and # include/*.h are not available to 'testsuite' code, but are to 'nonlib' code. -all-testsuite := $(strip $(tests) $(xtests) $(test-srcs) $(test-extras) \ - $(tests-container)) +all-testsuite := $(strip $(tests) $(xtests) $(test-srcs) $(test-extras)) ifneq (,$(all-testsuite)) cpp-srcs-left = $(all-testsuite) lib := testsuite diff --git a/Rules b/Rules index a07dbb8..706c8a7 100644 --- a/Rules +++ b/Rules @@ -82,8 +82,7 @@ $(common-objpfx)dummy.c: common-generated += dummy.o dummy.c ifneq "$(headers)" "" -# Test that all of the headers installed by this directory can be compiled -# in isolation. +# Special test of all the installed headers in this directory. tests-special += $(objpfx)check-installed-headers-c.out libof-check-installed-headers-c := testsuite $(objpfx)check-installed-headers-c.out: \ @@ -94,8 +93,6 @@ $(objpfx)check-installed-headers-c.out: \ $(evaluate-test) ifneq "$(CXX)" "" -# If a C++ compiler is available, also test that they can be compiled -# in isolation as C++. tests-special += $(objpfx)check-installed-headers-cxx.out libof-check-installed-headers-cxx := testsuite $(objpfx)check-installed-headers-cxx.out: \ @@ -104,19 +101,8 @@ $(objpfx)check-installed-headers-cxx.out: \ "$(CXX) $(filter-out -std=%,$(CXXFLAGS)) -D_ISOMAC $(+includes)" \ $(headers) > $@; \ $(evaluate-test) -endif # $(CXX) - -# Test that none of the headers installed by this directory use certain -# obsolete constructs (e.g. legacy BSD typedefs superseded by stdint.h). -# This script does not need $(py-env). -tests-special += $(objpfx)check-obsolete-constructs.out -libof-check-obsolete-constructs := testsuite -$(objpfx)check-obsolete-constructs.out: \ - $(..)scripts/check-obsolete-constructs.py $(headers) - $(PYTHON) $^ > $@ 2>&1; \ - $(evaluate-test) - -endif # $(headers) +endif +endif # This makes all the auxiliary and test programs. @@ -144,14 +130,12 @@ others: $(py-const) ifeq ($(run-built-tests),no) tests: $(addprefix $(objpfx),$(filter-out $(tests-unsupported), \ - $(tests) $(tests-internal) \ - $(tests-container)) \ + $(tests) $(tests-internal)) \ $(test-srcs)) $(tests-special) \ $(tests-printers-programs) xtests: tests $(xtests-special) else tests: $(tests:%=$(objpfx)%.out) $(tests-internal:%=$(objpfx)%.out) \ - $(tests-container:%=$(objpfx)%.out) \ $(tests-special) $(tests-printers-out) xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-special) endif @@ -161,8 +145,7 @@ xtests-special-notdir = $(patsubst $(objpfx)%, %, $(xtests-special)) ifeq ($(run-built-tests),no) tests-expected = else -tests-expected = $(tests) $(tests-internal) $(tests-printers) \ - $(tests-container) +tests-expected = $(tests) $(tests-internal) $(tests-printers) endif tests: $(..)scripts/merge-test-results.sh -s $(objpfx) $(subdir) \ @@ -175,8 +158,7 @@ xtests: ifeq ($(build-programs),yes) binaries-all-notests = $(others) $(sysdep-others) -binaries-all-tests = $(tests) $(tests-internal) $(xtests) $(test-srcs) \ - $(tests-container) +binaries-all-tests = $(tests) $(tests-internal) $(xtests) $(test-srcs) binaries-all = $(binaries-all-notests) $(binaries-all-tests) binaries-static-notests = $(others-static) binaries-static-tests = $(tests-static) $(xtests-static) @@ -266,17 +248,6 @@ $(objpfx)%.out: /dev/null $(objpfx)% # Make it 2nd arg for canned sequence. $(make-test-out) > $@; \ $(evaluate-test) - -# Any tests that require an isolated container (filesystem, network -# and pid namespaces) in which to run, should be added to -# tests-container. -$(tests-container:%=$(objpfx)%.out): $(objpfx)%.out : $(if $(wildcard $(objpfx)%.files),$(objpfx)%.files,/dev/null) $(objpfx)% - $(test-wrapper-env) $(run-program-env) $(run-via-rtld-prefix) \ - $(common-objpfx)support/test-container env $(run-program-env) $($*-ENV) \ - $(host-test-program-cmd) $($*-ARGS) > $@; \ - $(evaluate-test) - - # tests-unsupported lists tests that we will not try to build at all in # this configuration. Note this runs every time because it does not # actually create its target. The dependency on Makefile is meant to diff --git a/SPECS/glibc-bench-compare b/SPECS/glibc-bench-compare deleted file mode 100755 index 84e3aba..0000000 --- a/SPECS/glibc-bench-compare +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/bash -# This script can be invoked as follows: -# -# glibc-bench-compare [options] [BUILD] -# -# Options may be one of the following: -# -# -t The BUILD arguments are task ids and not a version-release string -# -a ARCH Do comparison for ARCH architecture -# -# If any of the above options are given, both BUILD arguments must be given. -# Otherwise, if only one BUILD is specified, then it is compared against the -# installed glibc. - -# Silence the pushd/popd messages -pushd() { - command pushd "$@" > /dev/null 2>&1 -} - -popd() { - command popd "$@" > /dev/null 2>&1 -} - -# Clean up any downloaded files before we exit -trap "rm -rf /tmp/glibc-bench-compare.$BASHPID.*" EXIT - -task=0 -arch=$(uname -i) -options=0 -path=0 -installed= - -# Look for any commandline options -while getopts ":tpa:" opt; do - case $opt in - p) - path=1 - ;; - t) - task=1 - options=1 - echo "Not implemented." - exit 1 - ;; - a) - arch=$OPTARG - options=1 - ;; - *) - ;; - esac -done - -# Done, now shift all option arguments out. -shift $((OPTIND-1)) - -if [ $# -gt 2 ] || [ $# -eq 0 ] || [ $# -lt 2 -a $options -eq 1 ]; then - echo "Usage: $0 [OPTIONS] [new]" - echo - echo "OPTIONS:" - echo -e "\t-t\tCompare two brew tasks" - echo -e "\t-a ARCH\tGet rpms for the ARCH architecture" - echo -e "\t-p\tCompare built rpms in two paths." - echo -e "\t\tThis minimally needs glibc, glibc-common and glibc-benchtests" - exit 1 -fi - -if [ -z $2 ]; then - new="$1" - old=$(rpm --queryformat "%{VERSION}-%{RELEASE}\n" -q glibc | head -1) - installed=$old -else - new="$2" - old="$1" -fi - -decompress_rpms() { - # We were given a path to the rpms. Figure out the version-release and - # decompress the rpms. - if [ -n $1 ]; then - vr=$(rpm --queryformat="%{VERSION}-%{RELEASE}" -qp $1/glibc-2*.rpm | head -1) - mkdir $vr && pushd $vr - fi - - for r in $1*.rpm; do - ( rpm2cpio $r | cpio -di ) > /dev/null - done - - if [ -n $1 ]; then - popd - echo $vr - fi -} - -# Get rpms for a build and decompress them -get_build() { - echo "Processing build $1" - mkdir $1 && pushd $1 - brew buildinfo "glibc-$1" | - sed -n -e "s|/mnt/koji\(.\+$arch.\+\)|http://kojipkgs.fedoraproject.org\1|p" | - while read url; do - echo "Downloading $url" - wget -q $url - done - decompress_rpms - - echo "Removing rpms" - rm -f $1/*.rpm - - popd -} - -# Run benchmarks for a build -run_bench() { - if [ -z $1 ]; then - make DETAILED=1 ver=$installed prefix= -f /usr/libexec/glibc-benchtests/bench.mk bench - else - make DETAILED=1 ver=$1 prefix=$PWD -f $1/usr/libexec/glibc-benchtests/bench.mk bench - fi -} - -# Get absolute paths if needed, since we will change into the working directory -# next. -if [ $path -eq 1 ]; then - old_path=$(realpath $old)/ - new_path=$(realpath $new)/ -fi - -tmpdir=$(mktemp -p /tmp -d glibc-bench-compare.$$.XXXX) -pushd $tmpdir - -# Get both builds. -if [ $path -eq 0 ]; then - if [ -z $installed ]; then - get_build $old - fi - get_build $new -else - old=$(decompress_rpms $old_path) - new=$(decompress_rpms $new_path) -fi - -# make bench for each of those. -if [ -z $installed ]; then - run_bench $old -else - run_bench -fi -run_bench $new - -# Now run the comparison script. -$old/usr/libexec/glibc-benchtests/compare_bench.py $old/usr/libexec/glibc-benchtests/benchout.schema.json \ - bench.$old.out bench.$new.out diff --git a/benchtests/Makefile b/benchtests/Makefile index 28d6b0c..bcd6a9c 100644 --- a/benchtests/Makefile +++ b/benchtests/Makefile @@ -235,21 +235,13 @@ bench-func: $(binaries-bench) scripts/benchout.schema.json; \ fi -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 \ +$(timing-type) $(binaries-bench) $(binaries-benchset) \ + $(binaries-bench-malloc): %: %.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/benchtests/scripts/compare_bench.py b/benchtests/scripts/compare_bench.py index 47ae305..88e8911 100755 --- a/benchtests/scripts/compare_bench.py +++ b/benchtests/scripts/compare_bench.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python # Copyright (C) 2015-2018 Free Software Foundation, Inc. # This file is part of the GNU C Library. # diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py index 76bf152..602b3f9 100755 --- a/benchtests/scripts/import_bench.py +++ b/benchtests/scripts/import_bench.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python # Copyright (C) 2015-2018 Free Software Foundation, Inc. # This file is part of the GNU C Library. # diff --git a/benchtests/scripts/validate_benchout.py b/benchtests/scripts/validate_benchout.py index 9a5c794..6147f05 100755 --- a/benchtests/scripts/validate_benchout.py +++ b/benchtests/scripts/validate_benchout.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python # Copyright (C) 2014-2018 Free Software Foundation, Inc. # This file is part of the GNU C Library. # diff --git a/bits/utmp.h b/bits/utmp.h index 854b342..6e8695f 100644 --- a/bits/utmp.h +++ b/bits/utmp.h @@ -1,5 +1,5 @@ -/* The `struct utmp' type, describing entries in the utmp file. - Copyright (C) 1993-2019 Free Software Foundation, Inc. +/* The `struct utmp' type, describing entries in the utmp file. Generic/BSDish + Copyright (C) 1993-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 @@ -21,107 +21,29 @@ #endif #include -#include -#include -#include +#include -#define UT_LINESIZE 32 -#define UT_NAMESIZE 32 -#define UT_HOSTSIZE 256 +#define UT_NAMESIZE 8 +#define UT_LINESIZE 8 +#define UT_HOSTSIZE 16 -/* The structure describing an entry in the database of - previous logins. */ struct lastlog { -#if __WORDSIZE_TIME64_COMPAT32 - int32_t ll_time; -#else - __time_t ll_time; -#endif + time_t ll_time; char ll_line[UT_LINESIZE]; char ll_host[UT_HOSTSIZE]; }; - -/* The structure describing the status of a terminated process. This - type is used in `struct utmp' below. */ -struct exit_status - { - short int e_termination; /* Process termination status. */ - short int e_exit; /* Process exit status. */ - }; - - -/* The structure describing an entry in the user accounting database. */ struct utmp -{ - short int ut_type; /* Type of login. */ - pid_t ut_pid; /* Process ID of login process. */ - char ut_line[UT_LINESIZE] - __attribute_nonstring__; /* Devicename. */ - char ut_id[4] - __attribute_nonstring__; /* Inittab ID. */ - char ut_user[UT_NAMESIZE] - __attribute_nonstring__; /* Username. */ - char ut_host[UT_HOSTSIZE] - __attribute_nonstring__; /* Hostname for remote login. */ - struct exit_status ut_exit; /* Exit status of a process marked - as DEAD_PROCESS. */ -/* The ut_session and ut_tv fields must be the same size when compiled - 32- and 64-bit. This allows data files and shared memory to be - shared between 32- and 64-bit applications. */ -#if __WORDSIZE_TIME64_COMPAT32 - int32_t ut_session; /* Session ID, used for windowing. */ - struct { - int32_t tv_sec; /* Seconds. */ - int32_t tv_usec; /* Microseconds. */ - } ut_tv; /* Time entry was made. */ -#else - long int ut_session; /* Session ID, used for windowing. */ - struct timeval ut_tv; /* Time entry was made. */ -#endif - - int32_t ut_addr_v6[4]; /* Internet address of remote host. */ - char __glibc_reserved[20]; /* Reserved for future use. */ -}; - -/* Backwards compatibility hacks. */ -#define ut_name ut_user -#ifndef _NO_UT_TIME -/* We have a problem here: `ut_time' is also used otherwise. Define - _NO_UT_TIME if the compiler complains. */ -# define ut_time ut_tv.tv_sec -#endif -#define ut_xtime ut_tv.tv_sec -#define ut_addr ut_addr_v6[0] - - -/* Values for the `ut_type' field of a `struct utmp'. */ -#define EMPTY 0 /* No valid user accounting information. */ - -#define RUN_LVL 1 /* The system's runlevel. */ -#define BOOT_TIME 2 /* Time of system boot. */ -#define NEW_TIME 3 /* Time after system clock changed. */ -#define OLD_TIME 4 /* Time when system clock changed. */ - -#define INIT_PROCESS 5 /* Process spawned by the init process. */ -#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ -#define USER_PROCESS 7 /* Normal process. */ -#define DEAD_PROCESS 8 /* Terminated process. */ - -#define ACCOUNTING 9 - -/* Old Linux name for the EMPTY type. */ -#define UT_UNKNOWN EMPTY + char ut_line[UT_LINESIZE]; + char ut_user[UT_NAMESIZE]; +#define ut_name ut_user + char ut_host[UT_HOSTSIZE]; + long int ut_time; + }; -/* Tell the user that we have a modern system with UT_HOST, UT_PID, - UT_TYPE, UT_ID and UT_TV fields. */ -#define _HAVE_UT_TYPE 1 -#define _HAVE_UT_PID 1 -#define _HAVE_UT_ID 1 -#define _HAVE_UT_TV 1 -#define _HAVE_UT_HOST 1 +#define _HAVE_UT_HOST 1 /* We have the ut_host field. */ diff --git a/config.h.in b/config.h.in index f63f6c8..141db21 100644 --- a/config.h.in +++ b/config.h.in @@ -62,18 +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 -/* 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 @@ -81,9 +72,6 @@ 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/config.make.in b/config.make.in index a6fe48d..d9891b2 100644 --- a/config.make.in +++ b/config.make.in @@ -110,7 +110,6 @@ BUILD_CC = @BUILD_CC@ CFLAGS = @CFLAGS@ CPPFLAGS-config = @CPPFLAGS@ CPPUNDEFS = @CPPUNDEFS@ -extra-nonshared-cflags = @extra_nonshared_cflags@ ASFLAGS-config = @ASFLAGS_config@ AR = @AR@ NM = @NM@ diff --git a/configure b/configure index 8b3681d..fde57d6 100755 --- a/configure +++ b/configure @@ -684,7 +684,6 @@ force_install bindnow hardcoded_path_in_tests enable_timezone_tools -extra_nonshared_cflags use_default_link sysheaders ac_ct_CXX @@ -763,7 +762,6 @@ with_binutils with_selinux with_headers with_default_link -with_nonshared_cflags enable_sanity_checks enable_shared enable_profile @@ -1484,8 +1482,6 @@ Optional Packages: --with-headers=PATH location of system headers to use (for example /usr/src/linux/include) [default=compiler default] --with-default-link do not use explicit linker scripts - --with-nonshared-cflags=FLAGS - build nonshared libraries with additional FLAGS --with-cpu=CPU select code for CPU variant Some influential environment variables: @@ -3343,16 +3339,6 @@ else fi - -# Check whether --with-nonshared-cflags was given. -if test "${with_nonshared_cflags+set}" = set; then : - withval=$with_nonshared_cflags; extra_nonshared_cflags=$withval -else - extra_nonshared_cflags= -fi - - - # Check whether --enable-sanity-checks was given. if test "${enable_sanity_checks+set}" = set; then : enableval=$enable_sanity_checks; enable_sanity=$enableval diff --git a/configure.ac b/configure.ac index 82d9ab2..014e09a 100644 --- a/configure.ac +++ b/configure.ac @@ -154,14 +154,6 @@ AC_ARG_WITH([default-link], [use_default_link=$withval], [use_default_link=default]) -dnl Additional build flags injection. -AC_ARG_WITH([nonshared-cflags], - AC_HELP_STRING([--with-nonshared-cflags=FLAGS], - [build nonshared libraries with additional FLAGS]), - [extra_nonshared_cflags=$withval], - [extra_nonshared_cflags=]) -AC_SUBST(extra_nonshared_cflags) - AC_ARG_ENABLE([sanity-checks], AC_HELP_STRING([--disable-sanity-checks], [really do not use threads (should not be used except in special situations) @<:@default=yes@:>@]), diff --git a/debug/tst-backtrace5.c b/debug/tst-backtrace5.c index a117f15..0e6fb1a 100644 --- a/debug/tst-backtrace5.c +++ b/debug/tst-backtrace5.c @@ -88,18 +88,6 @@ handle_signal (int signum) } /* Symbol names are not available for static functions, so we do not check do_test. */ - - /* Check that backtrace does not return more than what fits in the array - (bug 25423). */ - for (int j = 0; j < NUM_FUNCTIONS; j++) - { - n = backtrace (addresses, j); - if (n > j) - { - FAIL (); - return; - } - } } NO_INLINE int diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c index 0673246..33574fa 100644 --- a/dlfcn/dlerror.c +++ b/dlfcn/dlerror.c @@ -72,16 +72,9 @@ __dlerror (void) __libc_once (once, init); /* Get error string. */ - 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; - } + 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) @@ -205,10 +198,7 @@ check_free (struct dl_action_result *rec) Dl_info info; if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0) #endif - { - free ((char *) rec->errstring); - rec->errstring = NULL; - } + free ((char *) rec->errstring); } } @@ -237,19 +227,13 @@ free_key_mem (void *mem) void __dlerror_main_freeres (void) { + void *mem; /* Free the global memory if used. */ check_free (&last_result); - - 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); - } + /* 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/elf/Makefile b/elf/Makefile index b4b618c..cd07713 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -125,7 +125,6 @@ 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 \ @@ -156,9 +155,6 @@ tests-static-internal := tst-tls1-static tst-tls2-static \ CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o tst-tls1-static-non-pie-no-pie = yes -tests-container = \ - tst-ldconfig-bad-aux-cache - tests := tst-tls9 tst-leaks1 \ tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ tst-auxv @@ -185,21 +181,17 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ tst-addr1 tst-thrlock \ tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \ - tst-nodelete tst-dlopen-nodelete-reloc) \ + tst-nodelete) \ tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ - tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ - tst-sonamemove-link tst-sonamemove-dlopen tst-initfinilazyfail \ - tst-dlopenfail tst-dlopenfail-2 \ - tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen + tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note # reldep9 tests-internal += loadtest unload unload2 circleload1 \ 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 @@ -267,24 +259,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod9a tst-auditmod9b \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ - tst-nodelete-zmod \ - tst-dlopen-nodelete-reloc-mod1 \ - tst-dlopen-nodelete-reloc-mod2 \ - tst-dlopen-nodelete-reloc-mod3 \ - tst-dlopen-nodelete-reloc-mod4 \ - tst-dlopen-nodelete-reloc-mod5 \ - tst-dlopen-nodelete-reloc-mod6 \ - tst-dlopen-nodelete-reloc-mod7 \ - tst-dlopen-nodelete-reloc-mod8 \ - tst-dlopen-nodelete-reloc-mod9 \ - tst-dlopen-nodelete-reloc-mod10 \ - tst-dlopen-nodelete-reloc-mod11 \ - tst-dlopen-nodelete-reloc-mod12 \ - tst-dlopen-nodelete-reloc-mod13 \ - tst-dlopen-nodelete-reloc-mod14 \ - tst-dlopen-nodelete-reloc-mod15 \ - tst-dlopen-nodelete-reloc-mod16 \ - tst-dlopen-nodelete-reloc-mod17) \ + tst-nodelete-zmod) \ tst-initordera1 tst-initorderb1 \ tst-initordera2 tst-initorderb2 \ tst-initordera3 tst-initordera4 \ @@ -298,13 +273,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-latepthreadmod $(tst-tls-many-dynamic-modules) \ tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \ tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \ - tst-absolute-zero-lib tst-big-note-lib \ - tst-sonamemove-linkmod1 \ - tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ - tst-initlazyfailmod tst-finilazyfailmod \ - tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \ - tst-dlopenfailmod3 \ - tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee + tst-absolute-zero-lib tst-big-note-lib ifeq (yes,$(have-mtls-dialect-gnu2)) tests += tst-gnu2-tls1 @@ -329,7 +298,7 @@ test-xfail-tst-protected1b = yes endif ifeq (yesyes,$(have-fpie)$(build-shared)) modules-names += tst-piemod1 -tests += tst-pie1 tst-pie2 tst-dlopen-pie +tests += tst-pie1 tst-pie2 tests-pie += tst-pie1 tst-pie2 ifeq (yes,$(have-protected-data)) tests += vismain @@ -376,11 +345,9 @@ endif ifeq (yes,$(build-shared)) ifeq ($(run-built-tests),yes) -tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \ - $(objpfx)tst-rtld-preload.out +tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out endif tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \ - $(objpfx)check-wx-segment.out \ $(objpfx)check-localplt.out $(objpfx)check-initfini.out endif @@ -907,15 +874,6 @@ $(objpfx)tst-rtld-load-self.out: tst-rtld-load-self.sh $(objpfx)ld.so $(SHELL) $^ '$(test-wrapper)' '$(test-wrapper-env)' > $@; \ $(evaluate-test) -tst-rtld-preload-OBJS = $(subst $(empty) ,:,$(strip $(preloadtest-preloads:=.so))) -$(objpfx)tst-rtld-preload.out: tst-rtld-preload.sh $(objpfx)ld.so \ - $(objpfx)preloadtest \ - $(preloadtest-preloads:%=$(objpfx)%.so) - $(SHELL) $< $(objpfx)ld.so $(objpfx)preloadtest \ - '$(test-wrapper)' '$(test-wrapper-env)' '$(run_program_env)' \ - '$(rpath-link)' '$(tst-rtld-preload-OBJS)' > $@; \ - $(evaluate-test) - $(objpfx)initfirst: $(libdl) $(objpfx)initfirst.out: $(objpfx)firstobj.so @@ -1098,8 +1056,6 @@ CFLAGS-tst-pie2.c += $(pie-ccflag) $(objpfx)tst-piemod1.so: $(libsupport) $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so -$(objpfx)tst-dlopen-pie: $(libdl) -$(objpfx)tst-dlopen-pie.out: $(objpfx)tst-pie1 ifeq (yes,$(build-shared)) # NB: Please keep cet-built-dso in sysdeps/x86/Makefile in sync with @@ -1151,12 +1107,6 @@ $(objpfx)check-execstack.out: $(..)scripts/check-execstack.awk \ $(evaluate-test) generated += check-execstack.out -$(objpfx)check-wx-segment.out: $(..)scripts/check-wx-segment.py \ - $(all-built-dso:=.phdr) - $(PYTHON) $^ --xfail="$(check-wx-segment-xfail)" > $@; \ - $(evaluate-test) -generated += check-wx-segment.out - $(objpfx)tst-dlmodcount: $(libdl) $(objpfx)tst-dlmodcount.out: $(test-modules) @@ -1422,28 +1372,6 @@ tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so $(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map -# tst-sonamemove links against an older implementation of the library. -LDFLAGS-tst-sonamemove-linkmod1.so = \ - -Wl,--version-script=tst-sonamemove-linkmod1.map \ - -Wl,-soname,tst-sonamemove-runmod1.so -LDFLAGS-tst-sonamemove-runmod1.so = -Wl,--no-as-needed \ - -Wl,--version-script=tst-sonamemove-runmod1.map \ - -Wl,-soname,tst-sonamemove-runmod1.so -LDFLAGS-tst-sonamemove-runmod2.so = \ - -Wl,--version-script=tst-sonamemove-runmod2.map \ - -Wl,-soname,tst-sonamemove-runmod2.so -$(objpfx)tst-sonamemove-runmod1.so: $(objpfx)tst-sonamemove-runmod2.so -# Link against the link module, but depend on the run-time modules -# for execution. -$(objpfx)tst-sonamemove-link: $(objpfx)tst-sonamemove-linkmod1.so -$(objpfx)tst-sonamemove-link.out: \ - $(objpfx)tst-sonamemove-runmod1.so \ - $(objpfx)tst-sonamemove-runmod2.so -$(objpfx)tst-sonamemove-dlopen: $(libdl) -$(objpfx)tst-sonamemove-dlopen.out: \ - $(objpfx)tst-sonamemove-runmod1.so \ - $(objpfx)tst-sonamemove-runmod2.so - # Override -z defs, so that we can reference an undefined symbol. # Force lazy binding for the same reason. LDFLAGS-tst-latepthreadmod.so = \ @@ -1556,87 +1484,3 @@ tst-libc_dlvsym-static-ENV = \ $(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so - -$(objpfx)tst-initfinilazyfail: $(libdl) -$(objpfx)tst-initfinilazyfail.out: \ - $(objpfx)tst-initlazyfailmod.so $(objpfx)tst-finilazyfailmod.so -# Override -z defs, so that we can reference an undefined symbol. -# Force lazy binding for the same reason. -LDFLAGS-tst-initlazyfailmod.so = \ - -Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all -LDFLAGS-tst-finilazyfailmod.so = \ - -Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all - -$(objpfx)tst-dlopenfail: $(libdl) -$(objpfx)tst-dlopenfail.out: \ - $(objpfx)tst-dlopenfailmod1.so $(objpfx)tst-dlopenfailmod2.so -# Order matters here. tst-dlopenfaillinkmod.so's soname ensures a -# run-time loader failure. --as-needed breaks this test because -# nothing actually references tst-dlopenfailmod2.so (with its soname -# tst-dlopenfail-missingmod.so). -LDFLAGS-tst-dlopenfailmod1.so = -Wl,--no-as-needed -$(objpfx)tst-dlopenfailmod1.so: \ - $(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so -LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so -$(objpfx)tst-dlopenfailmod2.so: $(shared-thread-library) -$(objpfx)tst-dlopenfail-2: $(libdl) -$(objpfx)tst-dlopenfail.out: \ - $(objpfx)tst-dlopenfailmod1.so $(objpfx)tst-dlopenfailmod2.so \ - $(objpfx)tst-dlopenfailmod3.so - -$(objpfx)tst-dlopen-nodelete-reloc: $(libdl) -$(objpfx)tst-dlopen-nodelete-reloc.out: \ - $(objpfx)tst-dlopen-nodelete-reloc-mod1.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod2.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod3.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod4.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod5.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod6.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod7.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod8.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod9.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod10.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod11.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod12.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod13.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod14.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod16.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod17.so -tst-dlopen-nodelete-reloc-mod2.so-no-z-defs = yes -LDFLAGS-tst-dlopen-nodelete-reloc-mod2.so = -Wl,-z,nodelete -$(objpfx)tst-dlopen-nodelete-reloc-mod4.so: \ - $(objpfx)tst-dlopen-nodelete-reloc-mod3.so -LDFLAGS-tst-dlopen-nodelete-reloc-mod4.so = -Wl,--no-as-needed -$(objpfx)tst-dlopen-nodelete-reloc-mod5.so: \ - $(objpfx)tst-dlopen-nodelete-reloc-mod4.so -LDFLAGS-tst-dlopen-nodelete-reloc-mod5.so = -Wl,-z,nodelete,--no-as-needed -tst-dlopen-nodelete-reloc-mod5.so-no-z-defs = yes -tst-dlopen-nodelete-reloc-mod7.so-no-z-defs = yes -$(objpfx)tst-dlopen-nodelete-reloc-mod8.so: $(libdl) -$(objpfx)tst-dlopen-nodelete-reloc-mod10.so: $(libdl) -tst-dlopen-nodelete-reloc-mod11.so-no-z-defs = yes -$(objpfx)tst-dlopen-nodelete-reloc-mod13.so: \ - $(objpfx)tst-dlopen-nodelete-reloc-mod12.so -$(objpfx)tst-dlopen-nodelete-reloc-mod15.so: \ - $(objpfx)tst-dlopen-nodelete-reloc-mod14.so -tst-dlopen-nodelete-reloc-mod16.so-no-z-defs = yes -$(objpfx)tst-dlopen-nodelete-reloc-mod16.so: \ - $(objpfx)tst-dlopen-nodelete-reloc-mod15.so -LDFLAGS-tst-dlopen-nodelete-reloc-mod16.so = -Wl,--no-as-needed -$(objpfx)tst-dlopen-nodelete-reloc-mod17.so: \ - $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ - $(objpfx)tst-dlopen-nodelete-reloc-mod16.so -LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed - -LDFLAGS-tst-filterobj-flt.so = -Wl,--filter=$(objpfx)tst-filterobj-filtee.so -$(objpfx)tst-filterobj: $(objpfx)tst-filterobj-flt.so -$(objpfx)tst-filterobj-dlopen: $(libdl) -$(objpfx)tst-filterobj.out: $(objpfx)tst-filterobj-filtee.so -$(objpfx)tst-filterobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so - -LDFLAGS-tst-filterobj-aux.so = -Wl,--auxiliary=$(objpfx)tst-filterobj-filtee.so -$(objpfx)tst-auxobj: $(objpfx)tst-filterobj-aux.so -$(objpfx)tst-auxobj-dlopen: $(libdl) -$(objpfx)tst-auxobj.out: $(objpfx)tst-filterobj-filtee.so -$(objpfx)tst-auxobj-dlopen.out: $(objpfx)tst-filterobj-filtee.so diff --git a/elf/dl-close.c b/elf/dl-close.c index a9ecdff..ecd6729 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -106,30 +106,6 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp, return false; } -/* Invoke dstructors for CLOSURE (a struct link_map *). Called with - exception handling temporarily disabled, to make errors fatal. */ -static void -call_destructors (void *closure) -{ - struct link_map *map = closure; - - if (map->l_info[DT_FINI_ARRAY] != NULL) - { - ElfW(Addr) *array = - (ElfW(Addr) *) (map->l_addr - + map->l_info[DT_FINI_ARRAY]->d_un.d_ptr); - unsigned int sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val - / sizeof (ElfW(Addr))); - - while (sz-- > 0) - ((fini_t) array[sz]) (); - } - - /* Next try the old-style destructor. */ - if (map->l_info[DT_FINI] != NULL) - DL_CALL_DT_FINI (map, ((void *) map->l_addr - + map->l_info[DT_FINI]->d_un.d_ptr)); -} void _dl_close_worker (struct link_map *map, bool force) @@ -168,6 +144,14 @@ _dl_close_worker (struct link_map *map, bool force) char done[nloaded]; struct link_map *maps[nloaded]; + /* Clear DF_1_NODELETE to force object deletion. We don't need to touch + l_tls_dtor_count because forced object deletion only happens when an + error occurs during object load. Destructor registration for TLS + non-POD objects should not have happened till then for this + object. */ + if (force) + map->l_flags_1 &= ~DF_1_NODELETE; + /* Run over the list and assign indexes to the link maps and enter them into the MAPS array. */ int idx = 0; @@ -197,7 +181,7 @@ _dl_close_worker (struct link_map *map, bool force) /* Check whether this object is still used. */ if (l->l_type == lt_loaded && l->l_direct_opencount == 0 - && !l->l_nodelete_active + && (l->l_flags_1 & DF_1_NODELETE) == 0 /* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why acquire is sufficient and correct. */ && atomic_load_acquire (&l->l_tls_dtor_count) == 0 @@ -279,11 +263,11 @@ _dl_close_worker (struct link_map *map, bool force) if (!used[i]) { - assert (imap->l_type == lt_loaded && !imap->l_nodelete_active); + assert (imap->l_type == lt_loaded + && (imap->l_flags_1 & DF_1_NODELETE) == 0); /* Call its termination function. Do not do it for - half-cooked objects. Temporarily disable exception - handling, so that errors are fatal. */ + half-cooked objects. */ if (imap->l_init_called) { /* When debugging print a message first. */ @@ -292,9 +276,22 @@ _dl_close_worker (struct link_map *map, bool force) _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", imap->l_name, nsid); - if (imap->l_info[DT_FINI_ARRAY] != NULL - || imap->l_info[DT_FINI] != NULL) - _dl_catch_exception (NULL, call_destructors, imap); + if (imap->l_info[DT_FINI_ARRAY] != NULL) + { + ElfW(Addr) *array = + (ElfW(Addr) *) (imap->l_addr + + imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr); + unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val + / sizeof (ElfW(Addr))); + + while (sz-- > 0) + ((fini_t) array[sz]) (); + } + + /* Next try the old-style destructor. */ + if (imap->l_info[DT_FINI] != NULL) + DL_CALL_DT_FINI (imap, ((void *) imap->l_addr + + imap->l_info[DT_FINI]->d_un.d_ptr)); } #ifdef SHARED @@ -749,10 +746,6 @@ _dl_close_worker (struct link_map *map, bool force) if (imap->l_runpath_dirs.dirs != (void *) -1) free (imap->l_runpath_dirs.dirs); - /* Clear GL(dl_initfirst) when freeing its link_map memory. */ - if (imap == GL(dl_initfirst)) - GL(dl_initfirst) = NULL; - free (imap); } } @@ -823,7 +816,7 @@ _dl_close (void *_map) before we took the lock. There is no way to detect this (see below) so we proceed assuming this isn't the case. First see whether we can remove the object at all. */ - if (__glibc_unlikely (map->l_nodelete_active)) + if (__glibc_unlikely (map->l_flags_1 & DF_1_NODELETE)) { /* Nope. Do nothing. */ __rtld_lock_unlock_recursive (GL(dl_load_lock)); diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 50f053a..9d9b1ba 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -485,18 +485,14 @@ _dl_map_object_deps (struct link_map *map, map->l_searchlist.r_list = &l_initfini[nlist + 1]; map->l_searchlist.r_nlist = nlist; - unsigned int map_index = UINT_MAX; for (nlist = 0, runp = known; runp; runp = runp->next) { if (__builtin_expect (trace_mode, 0) && runp->map->l_faked) /* This can happen when we trace the loading. */ --map->l_searchlist.r_nlist; - else { - if (runp->map == map) - map_index = nlist; + else map->l_searchlist.r_list[nlist++] = runp->map; - } /* Now clear all the mark bits we set in the objects on the search list to avoid duplicates, so the next call starts fresh. */ @@ -554,14 +550,13 @@ Filters not supported with LD_TRACE_PRELINKING")); } /* Maybe we can remove some relocation dependencies now. */ + assert (map->l_searchlist.r_list[0] == map); struct link_map_reldeps *l_reldeps = NULL; if (map->l_reldeps != NULL) { - for (i = 0; i < nlist; ++i) + for (i = 1; i < nlist; ++i) map->l_searchlist.r_list[i]->l_reserved = 1; - /* Avoid removing relocation dependencies of the main binary. */ - map->l_reserved = 0; struct link_map **list = &map->l_reldeps->list[0]; for (i = 0; i < map->l_reldeps->act; ++i) if (list[i]->l_reserved) @@ -586,30 +581,16 @@ Filters not supported with LD_TRACE_PRELINKING")); } } - for (i = 0; i < nlist; ++i) + for (i = 1; i < nlist; ++i) map->l_searchlist.r_list[i]->l_reserved = 0; } - /* Sort the initializer list to take dependencies into account. Always - initialize the binary itself last. */ - assert (map_index < nlist); - if (map_index > 0) - { - /* Copy the binary into position 0. */ - l_initfini[0] = map->l_searchlist.r_list[map_index]; - - /* Copy the filtees. */ - for (i = 0; i < map_index; ++i) - l_initfini[i+1] = map->l_searchlist.r_list[i]; - - /* Copy the remainder. */ - for (i = map_index + 1; i < nlist; ++i) - l_initfini[i] = map->l_searchlist.r_list[i]; - } - else - memcpy (l_initfini, map->l_searchlist.r_list, - nlist * sizeof (struct link_map *)); - + /* Sort the initializer list to take dependencies into account. The binary + itself will always be initialize last. */ + memcpy (l_initfini, map->l_searchlist.r_list, + nlist * sizeof (struct link_map *)); + /* We can skip looking for the binary itself which is at the front of + the search list. */ _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false); /* Terminate the list of dependencies. */ diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c index 9cb002c..d5f418a 100644 --- a/elf/dl-error-skeleton.c +++ b/elf/dl-error-skeleton.c @@ -173,18 +173,6 @@ int _dl_catch_exception (struct dl_exception *exception, void (*operate) (void *), void *args) { - /* If exception is NULL, temporarily disable exception handling. - Exceptions during operate (args) are fatal. */ - if (exception == NULL) - { - struct catch *const old = catch_hook; - catch_hook = NULL; - operate (args); - /* If we get here, the operation was successful. */ - catch_hook = old; - return 0; - } - /* We need not handle `receiver' since setting a `catch' is handled before it. */ diff --git a/elf/dl-init.c b/elf/dl-init.c index 45405cd..3e72fa3 100644 --- a/elf/dl-init.c +++ b/elf/dl-init.c @@ -118,6 +118,8 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env) while (i-- > 0) call_init (main_map->l_initfini[i], argc, argv, env); +#ifndef HAVE_INLINED_SYSCALLS /* Finished starting up. */ _dl_starting_up = 0; +#endif } diff --git a/elf/dl-load.c b/elf/dl-load.c index b190b28..c51e4b3 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -878,8 +878,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, /* Get file information. */ struct r_file_id id; - struct stat64 st; - if (__glibc_unlikely (!_dl_get_file_id (fd, &id, &st))) + if (__glibc_unlikely (!_dl_get_file_id (fd, &id))) { errstring = N_("cannot stat shared object"); call_lose_errno: @@ -1080,16 +1079,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, = N_("ELF load command address/offset not properly aligned"); goto call_lose; } - if (__glibc_unlikely (ph->p_offset + ph->p_filesz > st.st_size)) - { - /* If the segment requires zeroing of part of its last - page, we'll crash when accessing the unmapped page. - There's still a possibility of a race, if the shared - object is truncated between the fxstat above and the - memset below. */ - errstring = N_("ELF load command past end of file"); - goto call_lose; - } struct loadcmd *c = &loadcmds[nloadcmds++]; c->mapstart = ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize)); @@ -1134,21 +1123,27 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, offset. We will adjust it later. */ l->l_tls_initimage = (void *) ph->p_vaddr; - /* l->l_tls_modid is assigned below, once there is no - possibility for failure. */ - - if (l->l_type != lt_library - && GL(dl_tls_dtv_slotinfo_list) == NULL) + /* If not loading the initial set of shared libraries, + check whether we should permit loading a TLS segment. */ + if (__glibc_likely (l->l_type == lt_library) + /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did + not set up TLS data structures, so don't use them now. */ + || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL)) { + /* Assign the next available module ID. */ + l->l_tls_modid = _dl_next_tls_modid (); + break; + } + #ifdef SHARED - /* We are loading the executable itself when the dynamic - linker was executed directly. The setup will happen - later. */ - assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0); + /* We are loading the executable itself when the dynamic + linker was executed directly. The setup will happen + later. Otherwise, the TLS data structures are already + initialized, and we assigned a TLS modid above. */ + assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0); #else - assert (false && "TLS not initialized in static application"); + assert (false && "TLS not initialized in static application"); #endif - } break; case PT_GNU_STACK: @@ -1178,10 +1173,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, goto call_lose; } - /* dlopen of an executable is not valid because it is not possible - to perform proper relocations, handle static TLS, or run the - ELF constructors. For PIE, the check needs the dynamic - section, so there is another check below. */ if (__glibc_unlikely (type != ET_DYN) && __glibc_unlikely ((mode & __RTLD_OPENEXEC) == 0)) { @@ -1218,11 +1209,9 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, elf_get_dynamic_info (l, NULL); /* Make sure we are not dlopen'ing an object that has the - DF_1_NOOPEN flag set, or a PIE object. */ - if ((__glibc_unlikely (l->l_flags_1 & DF_1_NOOPEN) - && (mode & __RTLD_DLOPEN)) - || (__glibc_unlikely (l->l_flags_1 & DF_1_PIE) - && __glibc_unlikely ((mode & __RTLD_OPENEXEC) == 0))) + DF_1_NOOPEN flag set. */ + if (__glibc_unlikely (l->l_flags_1 & DF_1_NOOPEN) + && (mode & __RTLD_DLOPEN)) { /* We are not supposed to load this object. Free all resources. */ _dl_unmap_segments (l); @@ -1233,11 +1222,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, if (l->l_phdr_allocated) free ((void *) l->l_phdr); - if (l->l_flags_1 & DF_1_PIE) - errstring - = N_("cannot dynamically load position-independent executable"); - else - errstring = N_("shared object cannot be dlopen()ed"); + errstring = N_("shared object cannot be dlopen()ed"); goto call_lose; } @@ -1389,18 +1374,6 @@ cannot enable executable stack as shared object requires"); add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB]) + l->l_info[DT_SONAME]->d_un.d_val)); - /* _dl_close can only eventually undo the module ID assignment (via - remove_slotinfo) if this function returns a pointer to a link - map. Therefore, delay this step until all possibilities for - failure have been excluded. */ - if (l->l_tls_blocksize > 0 - && (__glibc_likely (l->l_type == lt_library) - /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did - not set up TLS data structures, so don't use them now. */ - || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL))) - /* Assign the next available module ID. */ - l->l_tls_modid = _dl_next_tls_modid (); - #ifdef DL_AFTER_LOAD DL_AFTER_LOAD (l); #endif @@ -1668,6 +1641,17 @@ open_verify (const char *name, int fd, errstring = N_("only ET_DYN and ET_EXEC can be loaded"); goto call_lose; } + else if (__glibc_unlikely (ehdr->e_type == ET_EXEC + && (mode & __RTLD_OPENEXEC) == 0)) + { + /* BZ #16634. It is an error to dlopen ET_EXEC (unless + __RTLD_OPENEXEC is explicitly set). We return error here + so that code in _dl_map_object_from_fd does not try to set + l_tls_modid for this module. */ + + errstring = N_("cannot dynamically load executable"); + goto call_lose; + } else if (__glibc_unlikely (ehdr->e_phentsize != sizeof (ElfW(Phdr)))) { errstring = N_("ELF file's phentsize not the expected size"); diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 01724a5..68ecc61 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -187,37 +187,14 @@ enter_unique_sym (struct unique_sym *table, size_t size, table[idx].map = map; } -/* Mark MAP as NODELETE according to the lookup mode in FLAGS. During - initial relocation, NODELETE state is pending only. */ -static void -mark_nodelete (struct link_map *map, int flags) -{ - if (flags & DL_LOOKUP_FOR_RELOCATE) - map->l_nodelete_pending = true; - else - map->l_nodelete_active = true; -} - -/* Return true if MAP is marked as NODELETE according to the lookup - mode in FLAGS> */ -static bool -is_nodelete (struct link_map *map, int flags) -{ - /* Non-pending NODELETE always counts. Pending NODELETE only counts - during initial relocation processing. */ - return map->l_nodelete_active - || ((flags & DL_LOOKUP_FOR_RELOCATE) && map->l_nodelete_pending); -} - /* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol in the unique symbol table, creating a new entry if necessary. Return the matching symbol in RESULT. */ static void do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, - struct link_map *map, struct sym_val *result, + const struct link_map *map, struct sym_val *result, int type_class, const ElfW(Sym) *sym, const char *strtab, - const ElfW(Sym) *ref, const struct link_map *undef_map, - int flags) + const ElfW(Sym) *ref, const struct link_map *undef_map) { /* We have to determine whether we already found a symbol with this name before. If not then we have to add it to the search table. @@ -245,7 +222,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, copy from the copy addressed through the relocation. */ result->s = sym; - result->m = map; + result->m = (struct link_map *) map; } else { @@ -333,16 +310,10 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, enter_unique_sym (entries, size, new_hash, strtab + sym->st_name, sym, map); - if (map->l_type == lt_loaded && !is_nodelete (map, flags)) - { - /* Make sure we don't unload this object by - setting the appropriate flag. */ - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)) - _dl_debug_printf ("\ -marking %s [%lu] as NODELETE due to unique symbol\n", - map->l_name, map->l_ns); - mark_nodelete (map, flags); - } + if (map->l_type == lt_loaded) + /* Make sure we don't unload this object by + setting the appropriate flag. */ + ((struct link_map *) map)->l_flags_1 |= DF_1_NODELETE; } ++tab->n_elements; @@ -554,9 +525,8 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, return 1; case STB_GNU_UNIQUE:; - do_lookup_unique (undef_name, new_hash, (struct link_map *) map, - result, type_class, sym, strtab, ref, - undef_map, flags); + do_lookup_unique (undef_name, new_hash, map, result, type_class, + sym, strtab, ref, undef_map); return 1; default: @@ -566,7 +536,11 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, } skip: - ; + /* If this current map is the one mentioned in the verneed entry + and we have not found a weak entry, it is a bug. */ + if (symidx == STN_UNDEF && version != NULL && version->filename != NULL + && __glibc_unlikely (_dl_name_match_p (version->filename, map))) + return -1; } while (++i < n); @@ -598,13 +572,9 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) if (undef_map == map) return 0; - /* Avoid references to objects which cannot be unloaded anyway. We - do not need to record dependencies if this object goes away - during dlopen failure, either. IFUNC resolvers with relocation - dependencies may pick an dependency which can be dlclose'd, but - such IFUNC resolvers are undefined anyway. */ + /* Avoid references to objects which cannot be unloaded anyway. */ assert (map->l_type == lt_loaded); - if (is_nodelete (map, flags)) + if ((map->l_flags_1 & DF_1_NODELETE) != 0) return 0; struct link_map_reldeps *l_reldeps @@ -712,28 +682,16 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags) /* Redo the NODELETE check, as when dl_load_lock wasn't held yet this could have changed. */ - if (is_nodelete (map, flags)) + if ((map->l_flags_1 & DF_1_NODELETE) != 0) goto out; /* If the object with the undefined reference cannot be removed ever just make sure the same is true for the object which contains the definition. */ - if (undef_map->l_type != lt_loaded || is_nodelete (map, flags)) + if (undef_map->l_type != lt_loaded + || (undef_map->l_flags_1 & DF_1_NODELETE) != 0) { - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) - && !is_nodelete (map, flags)) - { - if (undef_map->l_name[0] == '\0') - _dl_debug_printf ("\ -marking %s [%lu] as NODELETE due to reference to main program\n", - map->l_name, map->l_ns); - else - _dl_debug_printf ("\ -marking %s [%lu] as NODELETE due to reference to %s [%lu]\n", - map->l_name, map->l_ns, - undef_map->l_name, undef_map->l_ns); - } - mark_nodelete (map, flags); + map->l_flags_1 |= DF_1_NODELETE; goto out; } @@ -758,15 +716,7 @@ marking %s [%lu] as NODELETE due to reference to %s [%lu]\n", no fatal problem. We simply make sure the referenced object cannot be unloaded. This is semantically the correct behavior. */ - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS) - && !is_nodelete (map, flags)) - _dl_debug_printf ("\ -marking %s [%lu] as NODELETE due to memory allocation failure\n", - map->l_name, map->l_ns); - /* In case of non-lazy binding, we could actually report - the memory allocation error, but for now, we use the - conservative approximation as well. */ - mark_nodelete (map, flags); + map->l_flags_1 |= DF_1_NODELETE; goto out; } else @@ -846,9 +796,11 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, bump_num_relocations (); - /* DL_LOOKUP_RETURN_NEWEST does not make sense for versioned - lookups. */ - assert (version == NULL || !(flags & DL_LOOKUP_RETURN_NEWEST)); + /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK + is allowed if we look up a versioned symbol. */ + assert (version == NULL + || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK)) + == 0); size_t i = 0; if (__glibc_unlikely (skip_map != NULL)) @@ -858,10 +810,34 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, /* Search the relevant loaded objects for a definition. */ for (size_t start = i; *scope != NULL; start = 0, ++scope) - if (do_lookup_x (undef_name, new_hash, &old_hash, *ref, - ¤t_value, *scope, start, version, flags, - skip_map, type_class, undef_map) != 0) - break; + { + int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref, + ¤t_value, *scope, start, version, flags, + skip_map, type_class, undef_map); + if (res > 0) + break; + + if (__glibc_unlikely (res < 0) && skip_map == NULL) + { + /* Oh, oh. The file named in the relocation entry does not + contain the needed symbol. This code is never reached + for unversioned lookups. */ + assert (version != NULL); + const char *reference_name = undef_map ? undef_map->l_name : ""; + struct dl_exception exception; + /* XXX We cannot translate the message. */ + _dl_exception_create_format + (&exception, DSO_FILENAME (reference_name), + "symbol %s version %s not defined in file %s" + " with link time reference%s", + undef_name, version->name, version->filename, + res == -2 ? " (no version symbols)" : ""); + _dl_signal_cexception (0, &exception, N_("relocation error")); + _dl_exception_free (&exception); + *ref = NULL; + return 0; + } + } if (__glibc_unlikely (current_value.s == NULL)) { diff --git a/elf/dl-open.c b/elf/dl-open.c index 46a4c1e..f6c8ef1 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -51,38 +50,22 @@ struct dl_open_args struct link_map *map; /* Namespace ID. */ Lmid_t nsid; - - /* Original value of _ns_global_scope_pending_adds. Set by - dl_open_worker. Only valid if nsid is a real namespace - (non-negative). */ - unsigned int original_global_scope_pending_adds; - /* Original parameters to the program and the current environment. */ int argc; char **argv; char **env; }; -/* Called in case the global scope cannot be extended. */ -static void __attribute__ ((noreturn)) -add_to_global_resize_failure (struct link_map *new) -{ - _dl_signal_error (ENOMEM, new->l_libname->name, NULL, - N_ ("cannot extend global scope")); -} -/* Grow the global scope array for the namespace, so that all the new - global objects can be added later in add_to_global_update, without - risk of memory allocation failure. add_to_global_resize raises - exceptions for memory allocation errors. */ -static void -add_to_global_resize (struct link_map *new) +static int +add_to_global (struct link_map *new) { - struct link_namespaces *ns = &GL (dl_ns)[new->l_ns]; + struct link_map **new_global; + unsigned int to_add = 0; + unsigned int cnt; /* Count the objects we have to put in the global scope. */ - unsigned int to_add = 0; - for (unsigned int cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) + for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) if (new->l_searchlist.r_list[cnt]->l_global == 0) ++to_add; @@ -100,51 +83,47 @@ add_to_global_resize (struct link_map *new) in an realloc() call. Therefore we allocate a completely new array the first time we have to add something to the locale scope. */ - if (__builtin_add_overflow (ns->_ns_global_scope_pending_adds, to_add, - &ns->_ns_global_scope_pending_adds)) - add_to_global_resize_failure (new); - - unsigned int new_size = 0; /* 0 means no new allocation. */ - void *old_global = NULL; /* Old allocation if free-able. */ - - /* Minimum required element count for resizing. Adjusted below for - an exponential resizing policy. */ - size_t required_new_size; - if (__builtin_add_overflow (ns->_ns_main_searchlist->r_nlist, - ns->_ns_global_scope_pending_adds, - &required_new_size)) - add_to_global_resize_failure (new); - + struct link_namespaces *ns = &GL(dl_ns)[new->l_ns]; if (ns->_ns_global_scope_alloc == 0) { - if (__builtin_add_overflow (required_new_size, 8, &new_size)) - add_to_global_resize_failure (new); - } - else if (required_new_size > ns->_ns_global_scope_alloc) - { - if (__builtin_mul_overflow (required_new_size, 2, &new_size)) - add_to_global_resize_failure (new); + /* This is the first dynamic object given global scope. */ + ns->_ns_global_scope_alloc + = ns->_ns_main_searchlist->r_nlist + to_add + 8; + new_global = (struct link_map **) + malloc (ns->_ns_global_scope_alloc * sizeof (struct link_map *)); + if (new_global == NULL) + { + ns->_ns_global_scope_alloc = 0; + nomem: + _dl_signal_error (ENOMEM, new->l_libname->name, NULL, + N_("cannot extend global scope")); + return 1; + } - /* The old array was allocated with our malloc, not the minimal - malloc. */ - old_global = ns->_ns_main_searchlist->r_list; + /* Copy over the old entries. */ + ns->_ns_main_searchlist->r_list + = memcpy (new_global, ns->_ns_main_searchlist->r_list, + (ns->_ns_main_searchlist->r_nlist + * sizeof (struct link_map *))); } - - if (new_size > 0) + else if (ns->_ns_main_searchlist->r_nlist + to_add + > ns->_ns_global_scope_alloc) { - size_t allocation_size; - if (__builtin_mul_overflow (new_size, sizeof (struct link_map *), - &allocation_size)) - add_to_global_resize_failure (new); - struct link_map **new_global = malloc (allocation_size); + /* We have to extend the existing array of link maps in the + main map. */ + struct link_map **old_global + = GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list; + size_t new_nalloc = ((ns->_ns_global_scope_alloc + to_add) * 2); + + new_global = (struct link_map **) + malloc (new_nalloc * sizeof (struct link_map *)); if (new_global == NULL) - add_to_global_resize_failure (new); + goto nomem; - /* Copy over the old entries. */ - memcpy (new_global, ns->_ns_main_searchlist->r_list, - ns->_ns_main_searchlist->r_nlist * sizeof (struct link_map *)); + memcpy (new_global, old_global, + ns->_ns_global_scope_alloc * sizeof (struct link_map *)); - ns->_ns_global_scope_alloc = new_size; + ns->_ns_global_scope_alloc = new_nalloc; ns->_ns_main_searchlist->r_list = new_global; if (!RTLD_SINGLE_THREAD_P) @@ -152,28 +131,16 @@ add_to_global_resize (struct link_map *new) free (old_global); } -} - -/* Actually add the new global objects to the global scope. Must be - called after add_to_global_resize. This function cannot fail. */ -static void -add_to_global_update (struct link_map *new) -{ - struct link_namespaces *ns = &GL (dl_ns)[new->l_ns]; /* Now add the new entries. */ unsigned int new_nlist = ns->_ns_main_searchlist->r_nlist; - for (unsigned int cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) + for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) { struct link_map *map = new->l_searchlist.r_list[cnt]; if (map->l_global == 0) { map->l_global = 1; - - /* The array has been resized by add_to_global_resize. */ - assert (new_nlist < ns->_ns_global_scope_alloc); - ns->_ns_main_searchlist->r_list[new_nlist++] = map; /* We modify the global scope. Report this. */ @@ -182,15 +149,10 @@ add_to_global_update (struct link_map *new) map->l_name, map->l_ns); } } - - /* Some of the pending adds have been performed by the loop above. - Adjust the counter accordingly. */ - unsigned int added = new_nlist - ns->_ns_main_searchlist->r_nlist; - assert (added <= ns->_ns_global_scope_pending_adds); - ns->_ns_global_scope_pending_adds -= added; - atomic_write_barrier (); ns->_ns_main_searchlist->r_nlist = new_nlist; + + return 0; } /* Search link maps in all namespaces for the DSO that contains the object at @@ -215,260 +177,6 @@ _dl_find_dso_for_object (const ElfW(Addr) addr) } rtld_hidden_def (_dl_find_dso_for_object); -/* Return true if NEW is found in the scope for MAP. */ -static size_t -scope_has_map (struct link_map *map, struct link_map *new) -{ - size_t cnt; - for (cnt = 0; map->l_scope[cnt] != NULL; ++cnt) - if (map->l_scope[cnt] == &new->l_searchlist) - return true; - return false; -} - -/* Return the length of the scope for MAP. */ -static size_t -scope_size (struct link_map *map) -{ - size_t cnt; - for (cnt = 0; map->l_scope[cnt] != NULL; ) - ++cnt; - return cnt; -} - -/* Resize the scopes of depended-upon objects, so that the new object - can be added later without further allocation of memory. This - function can raise an exceptions due to malloc failure. */ -static void -resize_scopes (struct link_map *new) -{ - /* If the file is not loaded now as a dependency, add the search - list of the newly loaded object to the scope. */ - for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) - { - struct link_map *imap = new->l_searchlist.r_list[i]; - - /* If the initializer has been called already, the object has - not been loaded here and now. */ - if (imap->l_init_called && imap->l_type == lt_loaded) - { - if (scope_has_map (imap, new)) - /* Avoid duplicates. */ - continue; - - size_t cnt = scope_size (imap); - if (__glibc_unlikely (cnt + 1 >= imap->l_scope_max)) - { - /* The l_scope array is too small. Allocate a new one - dynamically. */ - size_t new_size; - struct r_scope_elem **newp; - - if (imap->l_scope != imap->l_scope_mem - && imap->l_scope_max < array_length (imap->l_scope_mem)) - { - /* If the current l_scope memory is not pointing to - the static memory in the structure, but the - static memory in the structure is large enough to - use for cnt + 1 scope entries, then switch to - using the static memory. */ - new_size = array_length (imap->l_scope_mem); - newp = imap->l_scope_mem; - } - else - { - new_size = imap->l_scope_max * 2; - newp = (struct r_scope_elem **) - malloc (new_size * sizeof (struct r_scope_elem *)); - if (newp == NULL) - _dl_signal_error (ENOMEM, "dlopen", NULL, - N_("cannot create scope list")); - } - - /* Copy the array and the terminating NULL. */ - memcpy (newp, imap->l_scope, - (cnt + 1) * sizeof (imap->l_scope[0])); - struct r_scope_elem **old = imap->l_scope; - - imap->l_scope = newp; - - if (old != imap->l_scope_mem) - _dl_scope_free (old); - - imap->l_scope_max = new_size; - } - } - } -} - -/* Second stage of resize_scopes: Add NEW to the scopes. Also print - debugging information about scopes if requested. - - This function cannot raise an exception because all required memory - has been allocated by a previous call to resize_scopes. */ -static void -update_scopes (struct link_map *new) -{ - for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) - { - struct link_map *imap = new->l_searchlist.r_list[i]; - int from_scope = 0; - - if (imap->l_init_called && imap->l_type == lt_loaded) - { - if (scope_has_map (imap, new)) - /* Avoid duplicates. */ - continue; - - size_t cnt = scope_size (imap); - /* Assert that resize_scopes has sufficiently enlarged the - array. */ - assert (cnt + 1 < imap->l_scope_max); - - /* First terminate the extended list. Otherwise a thread - might use the new last element and then use the garbage - at offset IDX+1. */ - imap->l_scope[cnt + 1] = NULL; - atomic_write_barrier (); - imap->l_scope[cnt] = &new->l_searchlist; - - from_scope = cnt; - } - - /* Print scope information. */ - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) - _dl_show_scope (imap, from_scope); - } -} - -/* Call _dl_add_to_slotinfo with DO_ADD set to false, to allocate - space in GL (dl_tls_dtv_slotinfo_list). This can raise an - exception. The return value is true if any of the new objects use - TLS. */ -static bool -resize_tls_slotinfo (struct link_map *new) -{ - bool any_tls = false; - for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) - { - struct link_map *imap = new->l_searchlist.r_list[i]; - - /* Only add TLS memory if this object is loaded now and - therefore is not yet initialized. */ - if (! imap->l_init_called && imap->l_tls_blocksize > 0) - { - _dl_add_to_slotinfo (imap, false); - any_tls = true; - } - } - return any_tls; -} - -/* Second stage of TLS update, after resize_tls_slotinfo. This - function does not raise any exception. It should only be called if - resize_tls_slotinfo returned true. */ -static void -update_tls_slotinfo (struct link_map *new) -{ - unsigned int first_static_tls = new->l_searchlist.r_nlist; - for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) - { - struct link_map *imap = new->l_searchlist.r_list[i]; - - /* Only add TLS memory if this object is loaded now and - therefore is not yet initialized. */ - if (! imap->l_init_called && imap->l_tls_blocksize > 0) - { - _dl_add_to_slotinfo (imap, true); - - if (imap->l_need_tls_init - && first_static_tls == new->l_searchlist.r_nlist) - first_static_tls = i; - } - } - - if (__builtin_expect (++GL(dl_tls_generation) == 0, 0)) - _dl_fatal_printf (N_("\ -TLS generation counter wrapped! Please report this.")); - - /* We need a second pass for static tls data, because - _dl_update_slotinfo must not be run while calls to - _dl_add_to_slotinfo are still pending. */ - for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i) - { - struct link_map *imap = new->l_searchlist.r_list[i]; - - if (imap->l_need_tls_init - && ! imap->l_init_called - && imap->l_tls_blocksize > 0) - { - /* For static TLS we have to allocate the memory here and - now, but we can delay updating the DTV. */ - imap->l_need_tls_init = 0; -#ifdef SHARED - /* Update the slot information data for at least the - generation of the DSO we are allocating data for. */ - - /* FIXME: This can terminate the process on memory - allocation failure. It is not possible to raise - exceptions from this context; to fix this bug, - _dl_update_slotinfo would have to be split into two - operations, similar to resize_scopes and update_scopes - above. This is related to bug 16134. */ - _dl_update_slotinfo (imap->l_tls_modid); -#endif - - GL(dl_init_static_tls) (imap); - assert (imap->l_need_tls_init == 0); - } - } -} - -/* Mark the objects as NODELETE if required. This is delayed until - after dlopen failure is not possible, so that _dl_close can clean - up objects if necessary. */ -static void -activate_nodelete (struct link_map *new) -{ - /* It is necessary to traverse the entire namespace. References to - objects in the global scope and unique symbol bindings can force - NODELETE status for objects outside the local scope. */ - for (struct link_map *l = GL (dl_ns)[new->l_ns]._ns_loaded; l != NULL; - l = l->l_next) - if (l->l_nodelete_pending) - { - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)) - _dl_debug_printf ("activating NODELETE for %s [%lu]\n", - l->l_name, l->l_ns); - - /* The flag can already be true at this point, e.g. a signal - handler may have triggered lazy binding and set NODELETE - status immediately. */ - l->l_nodelete_active = true; - - /* This is just a debugging aid, to indicate that - activate_nodelete has run for this map. */ - l->l_nodelete_pending = false; - } -} - -/* struct dl_init_args and call_dl_init are used to call _dl_init with - exception handling disabled. */ -struct dl_init_args -{ - struct link_map *new; - int argc; - char **argv; - char **env; -}; - -static void -call_dl_init (void *closure) -{ - struct dl_init_args *args = closure; - _dl_init (args->new, args->argc, args->argv, args->env); -} - static void dl_open_worker (void *a) { @@ -500,10 +208,6 @@ dl_open_worker (void *a) args->nsid = call_map->l_ns; } - /* Retain the old value, so that it can be restored. */ - args->original_global_scope_pending_adds - = GL (dl_ns)[args->nsid]._ns_global_scope_pending_adds; - /* One might be tempted to assert that we are RT_CONSISTENT at this point, but that may not be true if this is a recursive call to dlopen. */ _dl_debug_initialize (0, args->nsid); @@ -521,6 +225,12 @@ dl_open_worker (void *a) return; } + /* Mark the object as not deletable if the RTLD_NODELETE flags was passed. + Do this early so that we don't skip marking the object if it was + already loaded. */ + if (__glibc_unlikely (mode & RTLD_NODELETE)) + new->l_flags_1 |= DF_1_NODELETE; + if (__glibc_unlikely (mode & __RTLD_SPROF)) /* This happens only if we load a DSO for 'sprof'. */ return; @@ -536,37 +246,16 @@ dl_open_worker (void *a) _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", new->l_name, new->l_ns, new->l_direct_opencount); - /* If the user requested the object to be in the global - namespace but it is not so far, prepare to add it now. This - can raise an exception to do a malloc failure. */ + /* If the user requested the object to be in the global namespace + but it is not so far, add it now. */ if ((mode & RTLD_GLOBAL) && new->l_global == 0) - add_to_global_resize (new); - - /* Mark the object as not deletable if the RTLD_NODELETE flags - was passed. */ - if (__glibc_unlikely (mode & RTLD_NODELETE)) - { - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES) - && !new->l_nodelete_active) - _dl_debug_printf ("marking %s [%lu] as NODELETE\n", - new->l_name, new->l_ns); - new->l_nodelete_active = true; - } - - /* Finalize the addition to the global scope. */ - if ((mode & RTLD_GLOBAL) && new->l_global == 0) - add_to_global_update (new); + (void) add_to_global (new); assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); return; } - /* Schedule NODELETE marking for the directly loaded object if - requested. */ - if (__glibc_unlikely (mode & RTLD_NODELETE)) - new->l_nodelete_pending = true; - /* Load that object's dependencies. */ _dl_map_object_deps (new, NULL, 0, 0, mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); @@ -614,42 +303,35 @@ dl_open_worker (void *a) if (GLRO(dl_lazy)) reloc_mode |= mode & RTLD_LAZY; - /* Objects must be sorted by dependency for the relocation process. - This allows IFUNC relocations to work and it also means copy - relocation of dependencies are if necessary overwritten. - __dl_map_object_deps has already sorted l_initfini for us. */ - unsigned int first = UINT_MAX; - unsigned int last = 0; - unsigned int j = 0; - struct link_map *l = new->l_initfini[0]; + /* Sort the objects by dependency for the relocation process. This + allows IFUNC relocations to work and it also means copy + relocation of dependencies are if necessary overwritten. */ + unsigned int nmaps = 0; + struct link_map *l = new; do { if (! l->l_real->l_relocated) - { - if (first == UINT_MAX) - first = j; - last = j + 1; - } - l = new->l_initfini[++j]; + ++nmaps; + l = l->l_next; + } + while (l != NULL); + struct link_map *maps[nmaps]; + nmaps = 0; + l = new; + do + { + if (! l->l_real->l_relocated) + maps[nmaps++] = l; + l = l->l_next; } while (l != NULL); + _dl_sort_maps (maps, nmaps, NULL, false); int relocation_in_progress = 0; - /* Perform relocation. This can trigger lazy binding in IFUNC - resolvers. For NODELETE mappings, these dependencies are not - recorded because the flag has not been applied to the newly - loaded objects. This means that upon dlopen failure, these - NODELETE objects can be unloaded despite existing references to - them. However, such relocation dependencies in IFUNC resolvers - are undefined anyway, so this is not a problem. */ - - for (unsigned int i = last; i-- > first; ) + for (unsigned int i = nmaps; i-- > 0; ) { - l = new->l_initfini[i]; - - if (l->l_real->l_relocated) - continue; + l = maps[i]; if (! relocation_in_progress) { @@ -676,7 +358,7 @@ dl_open_worker (void *a) _dl_start_profile (); /* Prevent unloading the object. */ - GL(dl_profile_map)->l_nodelete_active = true; + GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE; } } else @@ -684,48 +366,133 @@ dl_open_worker (void *a) _dl_relocate_object (l, l->l_scope, reloc_mode, 0); } - /* This only performs the memory allocations. The actual update of - the scopes happens below, after failure is impossible. */ - resize_scopes (new); + /* If the file is not loaded now as a dependency, add the search + list of the newly loaded object to the scope. */ + bool any_tls = false; + unsigned int first_static_tls = new->l_searchlist.r_nlist; + for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) + { + struct link_map *imap = new->l_searchlist.r_list[i]; + int from_scope = 0; - /* Increase the size of the GL (dl_tls_dtv_slotinfo_list) data - structure. */ - bool any_tls = resize_tls_slotinfo (new); + /* If the initializer has been called already, the object has + not been loaded here and now. */ + if (imap->l_init_called && imap->l_type == lt_loaded) + { + struct r_scope_elem **runp = imap->l_scope; + size_t cnt = 0; - /* Perform the necessary allocations for adding new global objects - to the global scope below. */ - if (mode & RTLD_GLOBAL) - add_to_global_resize (new); - - /* Demarcation point: After this, no recoverable errors are allowed. - All memory allocations for new objects must have happened - before. */ - - /* Finalize the NODELETE status first. This comes before - update_scopes, so that lazy binding will not see pending NODELETE - state for newly loaded objects. There is a compiler barrier in - update_scopes which ensures that the changes from - activate_nodelete are visible before new objects show up in the - local scope. */ - activate_nodelete (new); - - /* Second stage after resize_scopes: Actually perform the scope - update. After this, dlsym and lazy binding can bind to new - objects. */ - update_scopes (new); - - /* FIXME: It is unclear whether the order here is correct. - Shouldn't new objects be made available for binding (and thus - execution) only after there TLS data has been set up fully? - Fixing bug 16134 will likely make this distinction less - important. */ - - /* Second stage after resize_tls_slotinfo: Update the slotinfo data - structures. */ - if (any_tls) - /* FIXME: This calls _dl_update_slotinfo, which aborts the process - on memory allocation failure. See bug 16134. */ - update_tls_slotinfo (new); + while (*runp != NULL) + { + if (*runp == &new->l_searchlist) + break; + ++cnt; + ++runp; + } + + if (*runp != NULL) + /* Avoid duplicates. */ + continue; + + if (__glibc_unlikely (cnt + 1 >= imap->l_scope_max)) + { + /* The 'r_scope' array is too small. Allocate a new one + dynamically. */ + size_t new_size; + struct r_scope_elem **newp; + +#define SCOPE_ELEMS(imap) \ + (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0])) + + if (imap->l_scope != imap->l_scope_mem + && imap->l_scope_max < SCOPE_ELEMS (imap)) + { + new_size = SCOPE_ELEMS (imap); + newp = imap->l_scope_mem; + } + else + { + new_size = imap->l_scope_max * 2; + newp = (struct r_scope_elem **) + malloc (new_size * sizeof (struct r_scope_elem *)); + if (newp == NULL) + _dl_signal_error (ENOMEM, "dlopen", NULL, + N_("cannot create scope list")); + } + + memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0])); + struct r_scope_elem **old = imap->l_scope; + + imap->l_scope = newp; + + if (old != imap->l_scope_mem) + _dl_scope_free (old); + + imap->l_scope_max = new_size; + } + + /* First terminate the extended list. Otherwise a thread + might use the new last element and then use the garbage + at offset IDX+1. */ + imap->l_scope[cnt + 1] = NULL; + atomic_write_barrier (); + imap->l_scope[cnt] = &new->l_searchlist; + + /* Print only new scope information. */ + from_scope = cnt; + } + /* Only add TLS memory if this object is loaded now and + therefore is not yet initialized. */ + else if (! imap->l_init_called + /* Only if the module defines thread local data. */ + && __builtin_expect (imap->l_tls_blocksize > 0, 0)) + { + /* Now that we know the object is loaded successfully add + modules containing TLS data to the slot info table. We + might have to increase its size. */ + _dl_add_to_slotinfo (imap); + + if (imap->l_need_tls_init + && first_static_tls == new->l_searchlist.r_nlist) + first_static_tls = i; + + /* We have to bump the generation counter. */ + any_tls = true; + } + + /* Print scope information. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) + _dl_show_scope (imap, from_scope); + } + + /* Bump the generation number if necessary. */ + if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0)) + _dl_fatal_printf (N_("\ +TLS generation counter wrapped! Please report this.")); + + /* We need a second pass for static tls data, because _dl_update_slotinfo + must not be run while calls to _dl_add_to_slotinfo are still pending. */ + for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i) + { + struct link_map *imap = new->l_searchlist.r_list[i]; + + if (imap->l_need_tls_init + && ! imap->l_init_called + && imap->l_tls_blocksize > 0) + { + /* For static TLS we have to allocate the memory here and + now, but we can delay updating the DTV. */ + imap->l_need_tls_init = 0; +#ifdef SHARED + /* Update the slot information data for at least the + generation of the DSO we are allocating data for. */ + _dl_update_slotinfo (imap->l_tls_modid); +#endif + + GL(dl_init_static_tls) (imap); + assert (imap->l_need_tls_init == 0); + } + } /* Notify the debugger all new objects have been relocated. */ if (relocation_in_progress) @@ -735,28 +502,15 @@ dl_open_worker (void *a) DL_STATIC_INIT (new); #endif - /* Perform the necessary allocations for adding new global objects - to the global scope below, via add_to_global_update. */ - if (mode & RTLD_GLOBAL) - add_to_global_resize (new); - - /* Run the initializer functions of new objects. Temporarily - disable the exception handler, so that lazy binding failures are - fatal. */ - { - struct dl_init_args init_args = - { - .new = new, - .argc = args->argc, - .argv = args->argv, - .env = args->env - }; - _dl_catch_exception (NULL, call_dl_init, &init_args); - } + /* Run the initializer functions of new objects. */ + _dl_init (new, args->argc, args->argv, args->env); /* Now we can make the new map available in the global scope. */ if (mode & RTLD_GLOBAL) - add_to_global_update (new); + /* Move the object in the global namespace. */ + if (add_to_global (new) != 0) + /* It failed. */ + return; #ifndef SHARED /* We must be the static _dl_open in libc.a. A static program that @@ -770,6 +524,7 @@ dl_open_worker (void *a) new->l_name, new->l_ns, new->l_direct_opencount); } + void * _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, int argc, char *argv[], char *env[]) @@ -837,19 +592,6 @@ no more namespaces available for dlmopen()")); _dl_unload_cache (); #endif - /* Do this for both the error and success cases. The old value has - only been determined if the namespace ID was assigned (i.e., it - is not __LM_ID_CALLER). In the success case, we actually may - have consumed more pending adds than planned (because the local - scopes overlap in case of a recursive dlopen, the inner dlopen - doing some of the globalization work of the outer dlopen), so the - old pending adds value is larger than absolutely necessary. - Since it is just a conservative upper bound, this is harmless. - The top-level dlopen call will restore the field to zero. */ - if (args.nsid >= 0) - GL (dl_ns)[args.nsid]._ns_global_scope_pending_adds - = args.original_global_scope_pending_adds; - /* See if an error occurred during loading. */ if (__glibc_unlikely (exception.errstring != NULL)) { @@ -868,10 +610,6 @@ no more namespaces available for dlmopen()")); GL(dl_tls_dtv_gaps) = true; _dl_close_worker (args.map, true); - - /* All l_nodelete_pending objects should have been deleted - at this point, which is why it is not necessary to reset - the flag here. */ } assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index afeace4..053916e 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -248,8 +248,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], v = (version); \ _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \ scope, v, _tc, \ - DL_LOOKUP_ADD_DEPENDENCY \ - | DL_LOOKUP_FOR_RELOCATE, NULL); \ + DL_LOOKUP_ADD_DEPENDENCY, NULL); \ l->l_lookup_cache.ret = (*ref); \ l->l_lookup_cache.value = _lr; })) \ : l) diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 3d2f4a7..63bbc89 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -183,36 +183,10 @@ _dl_profile_fixup ( /* This is the address in the array where we store the result of previous relocations. */ struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index]; + DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr; - /* CONCURRENCY NOTES: - - Multiple threads may be calling the same PLT sequence and with - LD_AUDIT enabled they will be calling into _dl_profile_fixup to - update the reloc_result with the result of the lazy resolution. - The reloc_result guard variable is reloc_init, and we use - acquire/release loads and store to it to ensure that the results of - the structure are consistent with the loaded value of the guard. - This does not fix all of the data races that occur when two or more - threads read reloc_result->reloc_init with a value of zero and read - and write to that reloc_result concurrently. The expectation is - generally that while this is a data race it works because the - threads write the same values. Until the data races are fixed - there is a potential for problems to arise from these data races. - The reloc result updates should happen in parallel but there should - be an atomic RMW which does the final update to the real result - entry (see bug 23790). - - The following code uses reloc_result->init set to 0 to indicate if it is - the first time this object is being relocated, otherwise 1 which - indicates the object has already been relocated. - - Reading/Writing from/to reloc_result->reloc_init must not happen - before previous writes to reloc_result complete as they could - end-up with an incomplete struct. */ - DL_FIXUP_VALUE_TYPE value; - unsigned int init = atomic_load_acquire (&reloc_result->init); - - if (init == 0) + DL_FIXUP_VALUE_TYPE value = *resultp; + if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0) { /* This is the first time we have to relocate this object. */ const ElfW(Sym) *const symtab @@ -372,31 +346,19 @@ _dl_profile_fixup ( /* Store the result for later runs. */ if (__glibc_likely (! GLRO(dl_bind_not))) - { - reloc_result->addr = value; - /* Guarantee all previous writes complete before - init is updated. See CONCURRENCY NOTES earlier */ - atomic_store_release (&reloc_result->init, 1); - } - init = 1; + *resultp = value; } - else - value = reloc_result->addr; /* By default we do not call the pltexit function. */ long int framesize = -1; - #ifdef SHARED /* Auditing checkpoint: report the PLT entering and allow the auditors to change the value. */ - if (GLRO(dl_naudit) > 0 + if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0 /* Don't do anything if no auditor wants to intercept this call. */ && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0) { - /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been - initialized earlier in this function or in another thread. */ - assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0); ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, l_info[DT_SYMTAB]) + reloc_result->boundndx); diff --git a/elf/dl-support.c b/elf/dl-support.c index ef5455b..b5f10d5 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -117,8 +117,10 @@ struct r_scope_elem _dl_initial_searchlist = .r_nlist = 1, }; +#ifndef HAVE_INLINED_SYSCALLS /* Nonzero during startup. */ int _dl_starting_up = 1; +#endif /* Random data provided by the kernel. */ void *_dl_random; @@ -127,6 +129,11 @@ void *_dl_random; #include #include +/* Initial value of the CPU clock. */ +#ifndef HP_TIMING_NONAVAIL +hp_timing_t _dl_cpuclock_offset; +#endif + void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls; size_t _dl_pagesize = EXEC_PAGESIZE; @@ -307,6 +314,9 @@ _dl_non_dynamic_init (void) _dl_main_map.l_phdr = GL(dl_phdr); _dl_main_map.l_phnum = GL(dl_phnum); + if (HP_SMALL_TIMING_AVAIL) + HP_TIMING_NOW (_dl_cpuclock_offset); + _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; /* Set up the data structures for the system-supplied DSO early, diff --git a/elf/dl-tls.c b/elf/dl-tls.c index a2def28..c87caf1 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -883,7 +883,7 @@ _dl_tls_get_addr_soft (struct link_map *l) void -_dl_add_to_slotinfo (struct link_map *l, bool do_add) +_dl_add_to_slotinfo (struct link_map *l) { /* Now that we know the object is loaded successfully add modules containing TLS data to the dtv info table. We @@ -939,9 +939,6 @@ cannot create TLS data structures")); } /* Add the information into the slotinfo data structure. */ - if (do_add) - { - listp->slotinfo[idx].map = l; - listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; - } + listp->slotinfo[idx].map = l; + listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; } diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 1ff6fcb..1f8ecb8 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -85,11 +85,6 @@ glibc { tcache_unsorted_limit { type: SIZE_T } - mxfast { - type: SIZE_T - minval: 0 - security_level: SXID_IGNORE - } } tune { hwcap_mask { diff --git a/elf/elf.h b/elf/elf.h index 74f7f47..7e2b072 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -2847,13 +2847,6 @@ enum #define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ #define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ -/* AArch64 specific values for the Dyn d_tag field. */ -#define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5) -#define DT_AARCH64_NUM 6 - -/* AArch64 specific values for the st_other field. */ -#define STO_AARCH64_VARIANT_PCS 0x80 - /* ARM relocs. */ #define R_ARM_NONE 0 /* No reloc */ diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h index 78ba7e7..4b1ea7c 100644 --- a/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h @@ -163,8 +163,6 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) if (info[VERSYMIDX (DT_FLAGS_1)] != NULL) { l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; - if (l->l_flags_1 & DF_1_NODELETE) - l->l_nodelete_pending = true; /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like to assert this, but we can't. Users have been setting diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c index a9cfce1..2823dea 100644 --- a/elf/pldd-xx.c +++ b/elf/pldd-xx.c @@ -23,6 +23,10 @@ #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; @@ -35,12 +39,12 @@ struct E(link_map) EW(Addr) l_libname; }; #if CLASS == __ELF_NATIVE_CLASS -_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"); +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))); #endif @@ -50,10 +54,10 @@ struct E(libname_list) EW(Addr) next; }; #if CLASS == __ELF_NATIVE_CLASS -_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"); +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))); #endif struct E(r_debug) @@ -65,17 +69,16 @@ struct E(r_debug) EW(Addr) r_map; }; #if CLASS == __ELF_NATIVE_CLASS -_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"); +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))); #endif static int -E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, - size_t auxv_size) +E(find_maps) (pid_t pid, void *auxv, size_t auxv_size) { EW(Addr) phdr = 0; unsigned int phnum = 0; @@ -101,9 +104,12 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, if (phdr == 0 || phnum == 0 || phent == 0) error (EXIT_FAILURE, 0, gettext ("cannot find program header of process")); - EW(Phdr) *p = xmalloc (phnum * phent); - if (pread (memfd, p, phnum * phent, phdr) != phnum * phent) - error (EXIT_FAILURE, 0, gettext ("cannot read program header")); + 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; + } /* Determine the load offset. We need this for interpreting the other program header entries so we do this in a separate loop. @@ -123,18 +129,24 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, if (p[i].p_type == PT_DYNAMIC) { EW(Dyn) *dyn = xmalloc (p[i].p_filesz); - if (pread (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr) + if (pread64 (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr) != p[i].p_filesz) - error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); + { + error (0, 0, gettext ("cannot read dynamic section")); + return EXIT_FAILURE; + } /* 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 (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) + if (pread64 (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) != sizeof (r)) - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); + { + error (0, 0, gettext ("cannot read r_debug")); + return EXIT_FAILURE; + } if (r.r_map != 0) { @@ -148,10 +160,13 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, } else if (p[i].p_type == PT_INTERP) { - interp = xmalloc (p[i].p_filesz); - if (pread (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr) + interp = alloca (p[i].p_filesz); + if (pread64 (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr) != p[i].p_filesz) - error (EXIT_FAILURE, 0, gettext ("cannot read program interpreter")); + { + error (0, 0, gettext ("cannot read program interpreter")); + return EXIT_FAILURE; + } } if (list == 0) @@ -159,15 +174,13 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, if (interp == NULL) { // XXX check whether the executable itself is the loader - exit (EXIT_FAILURE); + return EXIT_FAILURE; } // XXX perhaps try finding ld.so and _r_debug in it - exit (EXIT_FAILURE); - } - free (p); - free (interp); + return EXIT_FAILURE; + } /* Print the PID and program name first. */ printf ("%lu:\t%s\n", (unsigned long int) pid, exe); @@ -179,27 +192,47 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, do { struct E(link_map) m; - if (pread (memfd, &m, sizeof (m), list) != sizeof (m)) - error (EXIT_FAILURE, 0, gettext ("cannot read link map")); + if (pread64 (memfd, &m, sizeof (m), list) != sizeof (m)) + { + error (0, 0, gettext ("cannot read link map")); + status = EXIT_FAILURE; + goto out; + } EW(Addr) name_offset = m.l_name; + again: while (1) { - ssize_t n = pread (memfd, tmpbuf.data, tmpbuf.length, name_offset); + ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset); if (n == -1) - error (EXIT_FAILURE, 0, gettext ("cannot read object name")); + { + error (0, 0, gettext ("cannot read object name")); + status = EXIT_FAILURE; + goto out; + } if (memchr (tmpbuf.data, '\0', n) != NULL) break; if (!scratch_buffer_grow (&tmpbuf)) - error (EXIT_FAILURE, 0, - gettext ("cannot allocate buffer for object name")); + { + error (0, 0, gettext ("cannot allocate buffer for object name")); + status = EXIT_FAILURE; + goto out; + } } - /* 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). */ + 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; + } + } /* Skip over the executable. */ if (((char *)tmpbuf.data)[0] != '\0') @@ -209,6 +242,7 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, } while (list != 0); + out: scratch_buffer_free (&tmpbuf); return status; } diff --git a/elf/pldd.c b/elf/pldd.c index 69467d2..b8106fd 100644 --- a/elf/pldd.c +++ b/elf/pldd.c @@ -17,17 +17,23 @@ License along with the GNU C Library; if not, see . */ -#define _FILE_OFFSET_BITS 64 - +#include #include +#include #include +#include +#include #include #include #include +#include +#include #include #include +#include #include #include +#include #include #include @@ -70,8 +76,14 @@ 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 (const char *exe, int dfd, long int pid); +static int get_process_info (int dfd, long int pid); static void wait_for_ptrace_stop (long int pid); @@ -90,10 +102,8 @@ main (int argc, char *argv[]) return 1; } - _Static_assert (sizeof (pid_t) == sizeof (int) - || sizeof (pid_t) == sizeof (long int), - "sizeof (pid_t) != sizeof (int) or sizeof (long int)"); - + assert (sizeof (pid_t) == sizeof (int) + || sizeof (pid_t) == sizeof (long int)); char *endp; errno = 0; long int pid = strtol (argv[remaining], &endp, 10); @@ -109,24 +119,25 @@ main (int argc, char *argv[]) if (dfd == -1) error (EXIT_FAILURE, errno, gettext ("cannot open %s"), buf); - /* Name of the executable */ - struct scratch_buffer exe; - scratch_buffer_init (&exe); + struct scratch_buffer exebuf; + scratch_buffer_init (&exebuf); ssize_t nexe; while ((nexe = readlinkat (dfd, "exe", - exe.data, exe.length)) == exe.length) + exebuf.data, exebuf.length)) == exebuf.length) { - if (!scratch_buffer_grow (&exe)) + if (!scratch_buffer_grow (&exebuf)) { nexe = -1; break; } } if (nexe == -1) - /* Default stack allocation is at least 1024. */ - snprintf (exe.data, exe.length, ""); + exe = (char *) ""; else - ((char*)exe.data)[nexe] = '\0'; + { + exe = exebuf.data; + exe[nexe] = '\0'; + } /* Stop all threads since otherwise the list of loaded modules might change while we are reading it. */ @@ -144,8 +155,8 @@ main (int argc, char *argv[]) error (EXIT_FAILURE, errno, gettext ("cannot prepare reading %s/task"), buf); - struct dirent *d; - while ((d = readdir (dir)) != NULL) + struct dirent64 *d; + while ((d = readdir64 (dir)) != NULL) { if (! isdigit (d->d_name[0])) continue; @@ -171,7 +182,7 @@ main (int argc, char *argv[]) wait_for_ptrace_stop (tid); - struct thread_list *newp = xmalloc (sizeof (*newp)); + struct thread_list *newp = alloca (sizeof (*newp)); newp->tid = tid; newp->next = thread_list; thread_list = newp; @@ -179,22 +190,17 @@ main (int argc, char *argv[]) closedir (dir); - if (thread_list == NULL) - error (EXIT_FAILURE, 0, gettext ("no valid %s/task entries"), buf); - - int status = get_process_info (exe.data, dfd, pid); + int status = get_process_info (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; } @@ -275,10 +281,9 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ static int -get_process_info (const char *exe, int dfd, long int pid) +get_process_info (int dfd, long int pid) { - /* File descriptor of /proc//mem file. */ - int memfd = openat (dfd, "mem", O_RDONLY); + memfd = openat (dfd, "mem", O_RDONLY); if (memfd == -1) goto no_info; @@ -328,9 +333,9 @@ get_process_info (const char *exe, int dfd, long int pid) int retval; if (e_ident[EI_CLASS] == ELFCLASS32) - retval = find_maps32 (exe, memfd, pid, auxv, auxv_size); + retval = find_maps32 (pid, auxv, auxv_size); else - retval = find_maps64 (exe, memfd, pid, auxv, auxv_size); + retval = find_maps64 (pid, auxv, auxv_size); free (auxv); close (memfd); diff --git a/elf/readelflib.c b/elf/readelflib.c index 8774e77..5a1e2dc 100644 --- a/elf/readelflib.c +++ b/elf/readelflib.c @@ -45,6 +45,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, { int i; unsigned int j; + ElfW(Addr) loadaddr; unsigned int dynamic_addr; size_t dynamic_size; char *program_interpreter; @@ -86,6 +87,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, libc5/libc6. */ *flag = FLAG_ELF; + loadaddr = -1; dynamic_addr = 0; dynamic_size = 0; program_interpreter = NULL; @@ -96,6 +98,11 @@ process_elf_file (const char *file_name, const char *lib, int *flag, switch (segment->p_type) { + case PT_LOAD: + if (loadaddr == (ElfW(Addr)) -1) + loadaddr = segment->p_vaddr - segment->p_offset; + break; + case PT_DYNAMIC: if (dynamic_addr) error (0, 0, _("more than one dynamic segment\n")); @@ -169,6 +176,11 @@ process_elf_file (const char *file_name, const char *lib, int *flag, } } + if (loadaddr == (ElfW(Addr)) -1) + { + /* Very strange. */ + loadaddr = 0; + } /* Now we can read the dynamic sections. */ if (dynamic_size == 0) @@ -185,29 +197,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, check_ptr (dyn_entry); if (dyn_entry->d_tag == DT_STRTAB) { - /* Find the file offset of the segment containing the dynamic - string table. */ - ElfW(Off) loadoff = -1; - for (i = 0, segment = elf_pheader; - i < elf_header->e_phnum; i++, segment++) - { - if (segment->p_type == PT_LOAD - && dyn_entry->d_un.d_val >= segment->p_vaddr - && (dyn_entry->d_un.d_val - segment->p_vaddr - < segment->p_filesz)) - { - loadoff = segment->p_vaddr - segment->p_offset; - break; - } - } - if (loadoff == (ElfW(Off)) -1) - { - /* Very strange. */ - loadoff = 0; - } - - dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - - loadoff); + dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); check_ptr (dynamic_strings); break; } diff --git a/elf/rtld.c b/elf/rtld.c index e107bd1..1b0c747 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -216,6 +216,7 @@ audit_list_iter_next (struct audit_list_iter *iter) return iter->previous->name; } +#ifndef HAVE_INLINED_SYSCALLS /* Set nonzero during loading and initialization of executable and libraries, cleared before the executable's entry point runs. This must not be initialized to nonzero, because the unused dynamic @@ -225,6 +226,7 @@ audit_list_iter_next (struct audit_list_iter *iter) never be called. */ int _dl_starting_up = 0; rtld_hidden_def (_dl_starting_up) +#endif /* This is the structure which defines all variables global to ld.so (except those which cannot be added for some reason). */ @@ -401,6 +403,8 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) # endif #endif + HP_TIMING_NOW (GL(dl_cpuclock_offset)); + /* Initialize the stack end variable. */ __libc_stack_end = __builtin_frame_address (0); @@ -822,18 +826,15 @@ static const char *library_path attribute_relro; static const char *preloadlist attribute_relro; /* Nonzero if information about versions has to be printed. */ static int version_info attribute_relro; -/* The preload list passed as a command argument. */ -static const char *preloadarg attribute_relro; /* The LD_PRELOAD environment variable gives list of libraries separated by white space or colons that are loaded before the executable's dependencies and prepended to the global scope list. (If the binary is running setuid all elements containing a '/' are ignored since it is insecure.) Return the number of preloads - performed. Ditto for --preload command argument. */ + performed. */ unsigned int -handle_preload_list (const char *preloadlist, struct link_map *main_map, - const char *where) +handle_ld_preload (const char *preloadlist, struct link_map *main_map) { unsigned int npreloads = 0; const char *p = preloadlist; @@ -857,7 +858,7 @@ handle_preload_list (const char *preloadlist, struct link_map *main_map, ++p; if (dso_name_valid_for_suid (fname)) - npreloads += do_preload (fname, main_map, where); + npreloads += do_preload (fname, main_map, "LD_PRELOAD"); } return npreloads; } @@ -899,8 +900,10 @@ dl_main (const ElfW(Phdr) *phdr, /* Process the environment variable which control the behaviour. */ process_envvars (&mode); +#ifndef HAVE_INLINED_SYSCALLS /* Set up a flag which tells we are just starting. */ _dl_starting_up = 1; +#endif if (*user_entry == (ElfW(Addr)) ENTRY_POINT) { @@ -975,13 +978,6 @@ dl_main (const ElfW(Phdr) *phdr, _dl_argc -= 2; _dl_argv += 2; } - else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2) - { - preloadarg = _dl_argv[2]; - _dl_skip_args += 2; - _dl_argc -= 2; - _dl_argv += 2; - } else break; @@ -1010,8 +1006,7 @@ of this helper program; chances are you did not intend to run this program.\n\ variable LD_LIBRARY_PATH\n\ --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\ in LIST\n\ - --audit LIST use objects named in LIST as auditors\n\ - --preload LIST preload objects named in LIST\n"); + --audit LIST use objects named in LIST as auditors\n"); ++_dl_skip_args; --_dl_argc; @@ -1625,16 +1620,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", if (__glibc_unlikely (preloadlist != NULL)) { HP_TIMING_NOW (start); - npreloads += handle_preload_list (preloadlist, main_map, "LD_PRELOAD"); - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (diff, start, stop); - HP_TIMING_ACCUM_NT (load_time, diff); - } - - if (__glibc_unlikely (preloadarg != NULL)) - { - HP_TIMING_NOW (start); - npreloads += handle_preload_list (preloadarg, main_map, "--preload"); + npreloads += handle_ld_preload (preloadlist, main_map); HP_TIMING_NOW (stop); HP_TIMING_DIFF (diff, start, stop); HP_TIMING_ACCUM_NT (load_time, diff); @@ -2165,7 +2151,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", /* Add object to slot information data if necessasy. */ if (l->l_tls_blocksize != 0 && tls_init_tp_called) - _dl_add_to_slotinfo (l, true); + _dl_add_to_slotinfo (l); } } else @@ -2213,7 +2199,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", /* Add object to slot information data if necessasy. */ if (l->l_tls_blocksize != 0 && tls_init_tp_called) - _dl_add_to_slotinfo (l, true); + _dl_add_to_slotinfo (l); } HP_TIMING_NOW (stop); diff --git a/elf/tst-auxobj-dlopen.c b/elf/tst-auxobj-dlopen.c deleted file mode 100644 index cb54aba..0000000 --- a/elf/tst-auxobj-dlopen.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Test for BZ#16272, dlopen'ing an auxiliary filter object. - Ensure that symbols from the resolve correctly. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -static int do_test (void) -{ - void *lib = xdlopen ("tst-filterobj-aux.so", RTLD_LAZY); - char *(*fn)(void) = xdlsym (lib, "get_text"); - const char* text = fn (); - - printf ("%s\n", text); - - /* Verify the text matches what we expect from the filtee */ - TEST_COMPARE_STRING (text, "Hello from filtee (PASS)"); - - fn = xdlsym (lib, "get_text2"); - text = fn (); - - printf ("%s\n", text); - - /* Verify the text matches what we expect from the auxiliary object */ - TEST_COMPARE_STRING (text, "Hello from auxiliary filter object (PASS)"); - - return 0; -} - -#include diff --git a/elf/tst-auxobj.c b/elf/tst-auxobj.c deleted file mode 100644 index bdc7713..0000000 --- a/elf/tst-auxobj.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Test that symbols from auxiliary filter objects are resolved to the - filtee. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include "tst-filterobj-filtee.h" - -static int do_test (void) -{ - const char* text = get_text (); - printf ("%s\n", text); - - /* Verify the text matches what we expect from the filtee */ - TEST_COMPARE_STRING (text, "Hello from filtee (PASS)"); - - text = get_text2 (); - printf ("%s\n", text); - - /* Verify the text matches what we expect from the auxiliary object */ - TEST_COMPARE_STRING (text, "Hello from auxiliary filter object (PASS)"); - - return 0; -} - -#include diff --git a/elf/tst-dlopen-nodelete-reloc-mod1.c b/elf/tst-dlopen-nodelete-reloc-mod1.c deleted file mode 100644 index 397d60a..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod1.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Test propagation of NODELETE to an already-loaded object via relocation. - Non-NODELETE helper module. - 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 - -/* Globally exported. Set by the main program to true before - termination, and used by tst-dlopen-nodelete-reloc-mod2.so to - trigger marking this module as NODELETE (and also for its destructor - check). */ -bool may_finalize_mod1 = false; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod1) - { - puts ("error: tst-dlopen-nodelete-reloc-mod1.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod10.c b/elf/tst-dlopen-nodelete-reloc-mod10.c deleted file mode 100644 index 30748b7..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod10.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Helper module to load tst-dlopen-nodelete-reloc-mod11.so. - 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 - -static void *handle; - -static void __attribute__ ((constructor)) -init (void) -{ - handle = dlopen ("tst-dlopen-nodelete-reloc-mod11.so", RTLD_NOW); - if (handle == NULL) - { - printf ("error: dlopen in module 10: %s\n", dlerror ()); - _exit (1); - } -} - -static void __attribute__ ((destructor)) -fini (void) -{ - dlclose (handle); -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod11.cc b/elf/tst-dlopen-nodelete-reloc-mod11.cc deleted file mode 100644 index 48c9104..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod11.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* Second module defining a unique symbol (loaded indirectly). - 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 "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -/* Just a flag here, not used for NODELETE processing. */ -bool may_finalize_mod11 = false; - -/* Trigger the creation of a unique symbol reference. This should - cause tst-dlopen-nodelete-reloc-mod9.so to be marked as - NODELETE. */ - -extern template struct unique_symbol<9>; - -int -global_function_mod11 (void) -{ - return unique_symbol<9>::value; -} - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod11) - { - puts ("error: tst-dlopen-nodelete-reloc-mod11.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod12.cc b/elf/tst-dlopen-nodelete-reloc-mod12.cc deleted file mode 100644 index 5c093fd..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod12.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* First module for NODELETE test defining a unique symbol (with DT_NEEDED). - 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 "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -/* Just a flag here, not used for NODELETE processing. */ -bool may_finalize_mod12 = false; - -/* Explicit instantiation. This produces a unique symbol definition - which is not referenced by the library itself, so the library is - not marked NODELETE. */ -template struct unique_symbol<12>; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod12) - { - puts ("error: tst-dlopen-nodelete-reloc-mod12.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod13.cc b/elf/tst-dlopen-nodelete-reloc-mod13.cc deleted file mode 100644 index caf4fd1..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod13.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* Second module for NODELETE test defining a unique symbol (with DT_NEEDED). - 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 "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -/* Just a flag here, not used for NODELETE processing. */ -bool may_finalize_mod13 = false; - -extern template struct unique_symbol<12>; - -/* Trigger the creation of a unique symbol reference. This should - cause tst-dlopen-nodelete-reloc-mod12.so to be marked as - NODELETE. */ -int -global_function_mod13 (void) -{ - return unique_symbol<12>::value; -} - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod13) - { - puts ("error: tst-dlopen-nodelete-reloc-mod13.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod13.h b/elf/tst-dlopen-nodelete-reloc-mod13.h deleted file mode 100644 index 5d33848..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod13.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Inline function which produces a unique symbol. - 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 - . */ - -inline char * -third_function_with_local_static (void) -{ - static char local; - return &local; -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod14.cc b/elf/tst-dlopen-nodelete-reloc-mod14.cc deleted file mode 100644 index e67621a..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod14.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* This object must retain NODELETE status after a dlopen 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 - . */ - -#include "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -/* Just a flag here, not used for NODELETE processing. */ -bool may_finalize_mod14 = false; - -/* Explicit instantiation. This produces a unique symbol definition - which is not referenced by the library itself, so the library is - not marked NODELETE. */ -template struct unique_symbol<14>; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod14) - { - puts ("error: tst-dlopen-nodelete-reloc-mod14.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod15.cc b/elf/tst-dlopen-nodelete-reloc-mod15.cc deleted file mode 100644 index ead362b..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod15.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* Helper object to mark tst-dlopen-nodelete-reloc-mod14.so as NODELETE. - 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 "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -extern template struct unique_symbol<14>; - -/* Trigger the creation of a unique symbol reference. This should - cause tst-dlopen-nodelete-reloc-mod14.so to be marked as - NODELETE. */ -int -global_function_mod15 (void) -{ - return unique_symbol<14>::value; -} - -static void __attribute__ ((destructor)) -fini (void) -{ - /* This object is never loaded completely. */ - puts ("error: tst-dlopen-nodelete-reloc-mod15.so destructor invoked"); - _exit (1); -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod16.c b/elf/tst-dlopen-nodelete-reloc-mod16.c deleted file mode 100644 index fa2ed14..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod16.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Object with an undefined symbol to trigger a relocation 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 - . */ - -/* The reference to undefined_mod16 triggers a relocation failure. */ - -extern int undefined_mod16; - -int -global_function_mod16 (void) -{ - return undefined_mod16; -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod17.c b/elf/tst-dlopen-nodelete-reloc-mod17.c deleted file mode 100644 index 426562e..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod17.c +++ /dev/null @@ -1,19 +0,0 @@ -/* Top-level object with dependency on an object that fails relocation. - 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 - . */ - -/* The dependencies do all the work. */ diff --git a/elf/tst-dlopen-nodelete-reloc-mod2.c b/elf/tst-dlopen-nodelete-reloc-mod2.c deleted file mode 100644 index 81ea8e5..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod2.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Test propagation of NODELETE to an already-loaded object via relocation. - NODELETE helper module. - 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 - -/* Defined in tst-dlopen-nodelete-reloc-mod1.so. This dependency is - not expressed via DT_NEEDED, so this reference marks the other - object as NODELETE dynamically, during initially relocation. */ -extern bool may_finalize_mod1; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod1) - { - puts ("error: tst-dlopen-nodelete-reloc-mod2.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod3.c b/elf/tst-dlopen-nodelete-reloc-mod3.c deleted file mode 100644 index d33f4ec..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod3.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Test propagation of NODELETE to an already-loaded object via relocation. - Non-NODELETE helper module. - 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 - -/* Globally exported. Set by the main program to true before - termination, and used by tst-dlopen-nodelete-reloc-mod4.so, - tst-dlopen-nodelete-reloc-mod5.so. */ -bool may_finalize_mod3 = false; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod3) - { - puts ("error: tst-dlopen-nodelete-reloc-mod3.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod4.c b/elf/tst-dlopen-nodelete-reloc-mod4.c deleted file mode 100644 index 7e6633a..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod4.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Test propagation of NODELETE to an already-loaded object via relocation. - Intermediate helper module. - 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 - -/* Defined in tst-dlopen-nodelete-reloc-mod3.so. The dependency is - expressed via DT_NEEDED. */ -extern bool may_finalize_mod3; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod3) - { - puts ("error: tst-dlopen-nodelete-reloc-mod4.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod5.c b/elf/tst-dlopen-nodelete-reloc-mod5.c deleted file mode 100644 index 22aa16f..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod5.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Test propagation of NODELETE to an already-loaded object via relocation. - NODELETE helper module. - 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 - -/* Defined in tst-dlopen-nodelete-reloc-mod3.so. The dependency is - expressed via DT_NEEDED on the intermediate DSO - tst-dlopen-nodelete-reloc-mod3.so. */ -extern bool may_finalize_mod3; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod3) - { - puts ("error: tst-dlopen-nodelete-reloc-mod5.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod6.cc b/elf/tst-dlopen-nodelete-reloc-mod6.cc deleted file mode 100644 index 180f5b5..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod6.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* First module for NODELETE test defining a unique symbol. - 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 "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -/* Just a flag here, not used for NODELETE processing. */ -bool may_finalize_mod6 = false; - -/* Explicit instantiation. This produces a unique symbol definition - which is not referenced by the library itself, so the library is - not marked NODELETE. */ -template struct unique_symbol<6>; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod6) - { - puts ("error: tst-dlopen-nodelete-reloc-mod6.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod7.cc b/elf/tst-dlopen-nodelete-reloc-mod7.cc deleted file mode 100644 index c85e7c9..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod7.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* Second module for NODELETE test defining a unique symbol. - 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 "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -/* Just a flag here, not used for NODELETE processing. */ -bool may_finalize_mod7 = false; - -extern template struct unique_symbol<6>; - -/* Trigger the creation of a unique symbol reference. This should - cause tst-dlopen-nodelete-reloc-mod6.so to be marked as - NODELETE. */ -int -global_function_mod7 (void) -{ - return unique_symbol<6>::value; -} - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod7) - { - puts ("error: tst-dlopen-nodelete-reloc-mod7.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod8.c b/elf/tst-dlopen-nodelete-reloc-mod8.c deleted file mode 100644 index ebb1c35..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod8.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Helper module to load tst-dlopen-nodelete-reloc-mod9.so. - 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 - -static void *handle; - -static void __attribute__ ((constructor)) -init (void) -{ - handle = dlopen ("tst-dlopen-nodelete-reloc-mod9.so", RTLD_NOW); - if (handle == NULL) - { - printf ("error: dlopen in module 8: %s\n", dlerror ()); - _exit (1); - } -} - -static void __attribute__ ((destructor)) -fini (void) -{ - dlclose (handle); -} diff --git a/elf/tst-dlopen-nodelete-reloc-mod9.cc b/elf/tst-dlopen-nodelete-reloc-mod9.cc deleted file mode 100644 index 06fb49c..0000000 --- a/elf/tst-dlopen-nodelete-reloc-mod9.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* First module defining a unique symbol (loaded indirectly). - 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 "tst-dlopen-nodelete-reloc.h" - -#include -#include -#include - -/* Just a flag here, not used for NODELETE processing. */ -bool may_finalize_mod9 = false; - -/* Explicit instantiation. This produces a unique symbol definition - which is not referenced by the library itself, so the library is - not marked NODELETE. */ -template struct unique_symbol<9>; - -static void __attribute__ ((destructor)) -fini (void) -{ - if (!may_finalize_mod9) - { - puts ("error: tst-dlopen-nodelete-reloc-mod9.so destructor" - " called too early"); - _exit (1); - } -} diff --git a/elf/tst-dlopen-nodelete-reloc.c b/elf/tst-dlopen-nodelete-reloc.c deleted file mode 100644 index 291ac9e..0000000 --- a/elf/tst-dlopen-nodelete-reloc.c +++ /dev/null @@ -1,179 +0,0 @@ -/* Test interactions of dlopen, NODELETE, and relocations. - 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 - . */ - -/* This test exercises NODELETE propagation due to data relocations - and unique symbols, and the interaction with already-loaded - objects. Some test objects are written in C++, to produce unique - symbol definitions. - - First test: Global scope variant, data relocation as the NODELETE - trigger. mod1 is loaded first with a separate dlopen call. - - mod2 ---(may_finalize_mod1 relocation dependency)---> mod1 - (NODELETE) (marked as NODELETE) - - Second test: Local scope variant, data relocation. mod3 is loaded - first, then mod5. - - mod5 ---(DT_NEEDED)---> mod4 ---(DT_NEEDED)---> mod3 - (NODELETE) (not NODELETE) ^ - \ / (marked as - `--(may_finalize_mod3 relocation dependency)--/ NODELETE) - - Third test: Shared local scope with unique symbol. mod6 is loaded - first, then mod7. No explicit dependencies between the two - objects, so first object has to be opened with RTLD_GLOBAL. - - mod7 ---(unique symbol)---> mod6 - (marked as NODELETE) - - Forth test: Non-shared scopes with unique symbol. mod8 and mod10 - are loaded from the main program. mod8 loads mod9 from an ELF - constructor, mod10 loads mod11. There are no DT_NEEDED - dependencies. mod9 is promoted to the global scope form the main - program. The unique symbol dependency is: - - mod9 ---(unique symbol)---> mod11 - (marked as NODELETE) - - Fifth test: Shared local scope with unique symbol, like test 3, but - this time, there is also a DT_NEEDED dependency (so no RTLD_GLOBAL - needed): - - DT_NEEDED - mod13 ---(unique symbol)---> mod12 - (marked as NODELETE) - - Sixth test: NODELETE status is retained after relocation failure - with unique symbol dependency. The object graph ensures that the - unique symbol binding is processed before the dlopen failure. - - DT_NEEDED - mod17 --(DT_NEEDED)--> mod15 --(unique symbol)--> mod14 - \ ^ (RTLD_NODELETE) - \ (DT_NEEDED) - \ | - `---(DT_NEEDED)--> mod16 - (fails to relocate) - - mod14 is loaded first, and the loading mod17 is attempted. - mod14 must remain NODELETE after opening mod17 failed. */ - -#include -#include -#include -#include -#include - -static int -do_test (void) -{ - /* First case: global scope, regular data symbol. Open the object - which is not NODELETE initially. */ - void *mod1 = xdlopen ("tst-dlopen-nodelete-reloc-mod1.so", - RTLD_NOW | RTLD_GLOBAL); - /* This is used to indicate that the ELF destructor may be - called. */ - bool *may_finalize_mod1 = xdlsym (mod1, "may_finalize_mod1"); - /* Open the NODELETE object. */ - void *mod2 = xdlopen ("tst-dlopen-nodelete-reloc-mod2.so", RTLD_NOW); - /* This has no effect because the DSO is directly marked as - NODELETE. */ - xdlclose (mod2); - /* This has no effect because the DSO has been indirectly marked as - NODELETE due to a relocation dependency. */ - xdlclose (mod1); - - /* Second case: local scope, regular data symbol. Open the object - which is not NODELETE initially. */ - void *mod3 = xdlopen ("tst-dlopen-nodelete-reloc-mod3.so", RTLD_NOW); - bool *may_finalize_mod3 = xdlsym (mod3, "may_finalize_mod3"); - /* Open the NODELETE object. */ - void *mod5 = xdlopen ("tst-dlopen-nodelete-reloc-mod5.so", RTLD_NOW); - /* Again those have no effect because of NODELETE. */ - xdlclose (mod5); - xdlclose (mod3); - - /* Third case: Unique symbol. */ - void *mod6 = xdlopen ("tst-dlopen-nodelete-reloc-mod6.so", - RTLD_NOW | RTLD_GLOBAL); - bool *may_finalize_mod6 = xdlsym (mod6, "may_finalize_mod6"); - void *mod7 = xdlopen ("tst-dlopen-nodelete-reloc-mod7.so", RTLD_NOW); - bool *may_finalize_mod7 = xdlsym (mod7, "may_finalize_mod7"); - /* This should not have any effect because of the unique symbol and - the resulting NODELETE status. */ - xdlclose (mod6); - /* mod7 is not NODELETE and can be closed. */ - *may_finalize_mod7 = true; - xdlclose (mod7); - - /* Fourth case: Unique symbol, indirect loading. */ - void *mod8 = xdlopen ("tst-dlopen-nodelete-reloc-mod8.so", RTLD_NOW); - /* Also promote to global scope. */ - void *mod9 = xdlopen ("tst-dlopen-nodelete-reloc-mod9.so", - RTLD_NOW | RTLD_NOLOAD | RTLD_GLOBAL); - bool *may_finalize_mod9 = xdlsym (mod9, "may_finalize_mod9"); - xdlclose (mod9); /* Drop mod9 reference. */ - void *mod10 = xdlopen ("tst-dlopen-nodelete-reloc-mod10.so", RTLD_NOW); - void *mod11 = xdlopen ("tst-dlopen-nodelete-reloc-mod11.so", - RTLD_NOW | RTLD_NOLOAD); - bool *may_finalize_mod11 = xdlsym (mod11, "may_finalize_mod11"); - xdlclose (mod11); /* Drop mod11 reference. */ - /* mod11 is not NODELETE and can be closed. */ - *may_finalize_mod11 = true; - /* Trigger closing of mod11, too. */ - xdlclose (mod10); - /* Does not trigger closing of mod9. */ - xdlclose (mod8); - - /* Fifth case: Unique symbol, with DT_NEEDED dependency. */ - void *mod12 = xdlopen ("tst-dlopen-nodelete-reloc-mod12.so", RTLD_NOW); - bool *may_finalize_mod12 = xdlsym (mod12, "may_finalize_mod12"); - void *mod13 = xdlopen ("tst-dlopen-nodelete-reloc-mod13.so", RTLD_NOW); - bool *may_finalize_mod13 = xdlsym (mod13, "may_finalize_mod13"); - /* This should not have any effect because of the unique symbol. */ - xdlclose (mod12); - /* mod13 is not NODELETE and can be closed. */ - *may_finalize_mod13 = true; - xdlclose (mod13); - - /* Sixth case: Unique symbol binding must not cause loss of NODELETE - status. */ - void *mod14 = xdlopen ("tst-dlopen-nodelete-reloc-mod14.so", - RTLD_NOW | RTLD_NODELETE); - bool *may_finalize_mod14 = xdlsym (mod14, "may_finalize_mod14"); - TEST_VERIFY (dlopen ("tst-dlopen-nodelete-reloc-mod17.so", RTLD_NOW) - == NULL); - const char *message = dlerror (); - printf ("info: test 6 message: %s\n", message); - /* This must not close the object, it must still be NODELETE. */ - xdlclose (mod14); - xdlopen ("tst-dlopen-nodelete-reloc-mod14.so", RTLD_NOW | RTLD_NOLOAD); - - /* Prepare for process exit. Destructors for NODELETE objects will - be invoked. */ - *may_finalize_mod1 = true; - *may_finalize_mod3 = true; - *may_finalize_mod6 = true; - *may_finalize_mod9 = true; - *may_finalize_mod12 = true; - *may_finalize_mod14 = true; - return 0; -} - -#include diff --git a/elf/tst-dlopen-nodelete-reloc.h b/elf/tst-dlopen-nodelete-reloc.h deleted file mode 100644 index 8844de6..0000000 --- a/elf/tst-dlopen-nodelete-reloc.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Template to produce unique symbols. - 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 - . */ - -/* This template produces a unique symbol definition for an explicit - template instantiation (without also incorporating a reference), - and an extern template declaration can be used to reference that - symbol from another object. The modid parameter is just a - placeholder to create different symbols (because it affects the - name mangling of the static value member). By convention, it - should match the number of the module that contains the - definition. */ - -template -struct unique_symbol -{ - static int value; -}; - -template -int unique_symbol::value; diff --git a/elf/tst-dlopen-pie.c b/elf/tst-dlopen-pie.c deleted file mode 100644 index 6a41c73..0000000 --- a/elf/tst-dlopen-pie.c +++ /dev/null @@ -1,49 +0,0 @@ -/* dlopen test for PIE objects. - 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 - . */ - -/* This test attempts to open the (otherwise unrelated) PIE test - program elf/tst-pie1 and expects the attempt to fail. */ - -#include -#include -#include -#include -#include - -static void -test_mode (int mode) -{ - char *pie_path = xasprintf ("%s/elf/tst-pie1", support_objdir_root); - if (dlopen (pie_path, mode) != NULL) - FAIL_EXIT1 ("dlopen succeeded unexpectedly (%d)", mode); - const char *message = dlerror (); - const char *expected - = "cannot dynamically load position-independent executable"; - if (strstr (message, expected) == NULL) - FAIL_EXIT1 ("unexpected error message (mode %d): %s", mode, message); -} - -static int -do_test (void) -{ - test_mode (RTLD_LAZY); - test_mode (RTLD_NOW); - return 0; -} - -#include diff --git a/elf/tst-dlopenfail-2.c b/elf/tst-dlopenfail-2.c deleted file mode 100644 index 35bbde6..0000000 --- a/elf/tst-dlopenfail-2.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Test unrelated dlopen after dlopen failure involving NODELETE. - Copyright (C) 2019-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int -do_test (void) -{ - /* This test uses libpthread as the canonical NODELETE module. If - libpthread is no longer NODELETE because it has been merged into - libc, the test needs to be updated. */ - TEST_VERIFY (dlsym (NULL, "pthread_create") == NULL); - - /* This is expected to fail because of the missing dependency. */ - puts ("info: attempting to load tst-dlopenfailmod1.so"); - TEST_VERIFY (dlopen ("tst-dlopenfailmod1.so", RTLD_LAZY) == NULL); - const char *message = dlerror (); - TEST_COMPARE_STRING (message, - "tst-dlopenfail-missingmod.so:" - " cannot open shared object file:" - " No such file or directory"); - - /* Open a small shared object. With a dangling GL (dl_initfirst) - pointer, this is likely to crash because there is no longer any - mapped text segment there (bug 25396). */ - - puts ("info: attempting to load tst-dlopenfailmod3.so"); - xdlclose (xdlopen ("tst-dlopenfailmod3.so", RTLD_NOW)); - - return 0; -} - -/* Do not perturb the dangling link map. With M_PERTURB, the link map - appears to have l_init_called set, so there are no constructor - calls and no crashes. */ -#define TEST_NO_MALLOPT -#include diff --git a/elf/tst-dlopenfail.c b/elf/tst-dlopenfail.c deleted file mode 100644 index ce3140c..0000000 --- a/elf/tst-dlopenfail.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Test dlopen rollback after failures involving NODELETE objects (bug 20839). - 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 - -static int -do_test (void) -{ - /* This test uses libpthread as the canonical NODELETE module. If - libpthread is no longer NODELETE because it has been merged into - libc, the test needs to be updated. */ - TEST_VERIFY (dlsym (NULL, "pthread_create") == NULL); - - /* This is expected to fail because of the missing dependency. */ - puts ("info: attempting to load tst-dlopenfailmod1.so"); - TEST_VERIFY (dlopen ("tst-dlopenfailmod1.so", RTLD_LAZY) == NULL); - const char *message = dlerror (); - TEST_COMPARE_STRING (message, - "tst-dlopenfail-missingmod.so:" - " cannot open shared object file:" - " No such file or directory"); - - /* Do not probe for the presence of libpthread at this point because - that might trigger relocation if bug 20839 is present, obscuring - a subsequent crash. */ - - /* This is expected to succeed. */ - puts ("info: loading tst-dlopenfailmod2.so"); - void *handle = xdlopen ("tst-dlopenfailmod2.so", RTLD_NOW); - xdlclose (handle); - - /* libpthread should remain loaded. */ - TEST_VERIFY (dlopen (LIBPTHREAD_SO, RTLD_LAZY | RTLD_NOLOAD) != NULL); - TEST_VERIFY (dlsym (NULL, "pthread_create") == NULL); - - /* We can make libpthread global, and then the symbol should become - available. */ - TEST_VERIFY (dlopen (LIBPTHREAD_SO, RTLD_LAZY | RTLD_GLOBAL) != NULL); - TEST_VERIFY (dlsym (NULL, "pthread_create") != NULL); - - /* sem_open is sufficiently complex to depend on relocations. */ - void *(*sem_open_ptr) (const char *, int flag, ...) - = dlsym (NULL, "sem_open"); - if (sem_open_ptr == NULL) - /* Hurd does not implement sem_open. */ - puts ("warning: sem_open not found, further testing not possible"); - else - { - errno = 0; - TEST_VERIFY (sem_open_ptr ("/", 0) == NULL); - TEST_COMPARE (errno, EINVAL); - } - - return 0; -} - -#include diff --git a/elf/tst-dlopenfaillinkmod.c b/elf/tst-dlopenfaillinkmod.c deleted file mode 100644 index 3b14b02..0000000 --- a/elf/tst-dlopenfaillinkmod.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Empty module with a soname which is not available at run time. - 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 - . */ diff --git a/elf/tst-dlopenfailmod1.c b/elf/tst-dlopenfailmod1.c deleted file mode 100644 index 6ef4882..0000000 --- a/elf/tst-dlopenfailmod1.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Module which depends on two modules: one NODELETE, one missing. - 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 - . */ - -/* Note: Due to the missing second module, this object cannot be - loaded at run time. */ - -#include -#include -#include - -/* Force linking against libpthread. */ -void *pthread_create_reference = pthread_create; - -/* The constructor will never be executed because the module cannot be - loaded. */ -static void __attribute__ ((constructor)) -init (void) -{ - puts ("tst-dlopenfailmod1 constructor executed"); - _exit (1); -} diff --git a/elf/tst-dlopenfailmod2.c b/elf/tst-dlopenfailmod2.c deleted file mode 100644 index 7d60038..0000000 --- a/elf/tst-dlopenfailmod2.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Module which depends on on a NODELETE module, and can be loaded. - 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 - -/* Force linking against libpthread. */ -void *pthread_create_reference = pthread_create; - -static void __attribute__ ((constructor)) -init (void) -{ - puts ("info: tst-dlopenfailmod2.so constructor invoked"); -} diff --git a/elf/tst-dlopenfailmod3.c b/elf/tst-dlopenfailmod3.c deleted file mode 100644 index 636e971..0000000 --- a/elf/tst-dlopenfailmod3.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Empty module for the tst-dlopenfail-2 test. - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ diff --git a/elf/tst-filterobj-aux.c b/elf/tst-filterobj-aux.c deleted file mode 100644 index 0b732f2..0000000 --- a/elf/tst-filterobj-aux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Auxiliary filter object. - Contains symbols to be resolved in filtee, and one which doesn't. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include "tst-filterobj-filtee.h" - -/* We never want to see the output of the auxiliary object. */ -const char *get_text (void) -{ - return "Hello from auxiliary filter object (FAIL)"; -} - -/* The filtee doesn't implement this symbol, so this should resolve. */ -const char *get_text2 (void) -{ - return "Hello from auxiliary filter object (PASS)"; -} diff --git a/elf/tst-filterobj-dlopen.c b/elf/tst-filterobj-dlopen.c deleted file mode 100644 index c5b5072..0000000 --- a/elf/tst-filterobj-dlopen.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Test for BZ#16272, dlopen'ing a filter object. - Ensure that symbols from the filter object resolve to the filtee. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -static int do_test (void) -{ - void *lib = xdlopen ("tst-filterobj-flt.so", RTLD_LAZY); - char *(*fn)(void) = xdlsym (lib, "get_text"); - const char* text = fn (); - - printf ("%s\n", text); - - /* Verify the text matches what we expect from the filtee */ - TEST_COMPARE_STRING (text, "Hello from filtee (PASS)"); - - return 0; -} - -#include diff --git a/elf/tst-filterobj-filtee.c b/elf/tst-filterobj-filtee.c deleted file mode 100644 index 8fa557c..0000000 --- a/elf/tst-filterobj-filtee.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Filtee for BZ#16272 test. - Contains desired symbol implementations. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include "tst-filterobj-filtee.h" - -/* This is the real implementation that wants to be called */ -const char *get_text (void) -{ - return "Hello from filtee (PASS)"; -} diff --git a/elf/tst-filterobj-filtee.h b/elf/tst-filterobj-filtee.h deleted file mode 100644 index 46aee28..0000000 --- a/elf/tst-filterobj-filtee.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Filtee header for BZ#16272 test. - Contains prototypes for symbols implemented in the filtee. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -const char *get_text (void); - -/* For testing auxiliary filter object. */ -const char *get_text2 (void); diff --git a/elf/tst-filterobj-flt.c b/elf/tst-filterobj-flt.c deleted file mode 100644 index 5062654..0000000 --- a/elf/tst-filterobj-flt.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Filter object for BZ#16272 test. - Contains symbols to be resolved in filtee. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include "tst-filterobj-filtee.h" - -/* We never want to see the output of the filter object */ -const char *get_text (void) -{ - return "Hello from filter object (FAIL)"; -} diff --git a/elf/tst-filterobj.c b/elf/tst-filterobj.c deleted file mode 100644 index 96bfae0..0000000 --- a/elf/tst-filterobj.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Test that symbols from filter objects are resolved to the filtee. - - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include "tst-filterobj-filtee.h" - -static int do_test (void) -{ - const char* text = get_text (); - - printf ("%s\n", text); - - /* Verify the text matches what we expect from the filtee */ - TEST_COMPARE_STRING (text, "Hello from filtee (PASS)"); - - return 0; -} - -#include diff --git a/elf/tst-finilazyfailmod.c b/elf/tst-finilazyfailmod.c deleted file mode 100644 index 2670bd1..0000000 --- a/elf/tst-finilazyfailmod.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Helper module for tst-initfinilazyfail: lazy binding failure in destructor. - 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 - . */ - -/* An undefined function. Calling it will cause a lazy binding - failure. */ -void undefined_function (void); - -static void __attribute__ ((destructor)) -fini (void) -{ - undefined_function (); -} diff --git a/elf/tst-initfinilazyfail.c b/elf/tst-initfinilazyfail.c deleted file mode 100644 index 9b4a3d0..0000000 --- a/elf/tst-initfinilazyfail.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Test that lazy binding failures in constructors and destructors are fatal. - 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 void -test_constructor (void *closure) -{ - void *handle = dlopen ("tst-initlazyfailmod.so", RTLD_LAZY); - if (handle == NULL) - FAIL_EXIT (2, "dlopen did not terminate the process: %s", dlerror ()); - else - FAIL_EXIT (2, "dlopen did not terminate the process (%p)", handle); -} - -static void -test_destructor (void *closure) -{ - void *handle = xdlopen ("tst-finilazyfailmod.so", RTLD_LAZY); - int ret = dlclose (handle); - const char *message = dlerror (); - if (message != NULL) - FAIL_EXIT (2, "dlclose did not terminate the process: %d, %s", - ret, message); - else - FAIL_EXIT (2, "dlopen did not terminate the process: %d", ret); -} - -static int -do_test (void) -{ - { - struct support_capture_subprocess proc - = support_capture_subprocess (test_constructor, NULL); - support_capture_subprocess_check (&proc, "constructor", 127, - sc_allow_stderr); - printf ("info: constructor failure output: [[%s]]\n", proc.err.buffer); - TEST_VERIFY (strstr (proc.err.buffer, - "tst-initfinilazyfail: symbol lookup error: ") - != NULL); - TEST_VERIFY (strstr (proc.err.buffer, - "tst-initlazyfailmod.so: undefined symbol:" - " undefined_function\n") != NULL); - support_capture_subprocess_free (&proc); - } - - { - struct support_capture_subprocess proc - = support_capture_subprocess (test_destructor, NULL); - support_capture_subprocess_check (&proc, "destructor", 127, - sc_allow_stderr); - printf ("info: destructor failure output: [[%s]]\n", proc.err.buffer); - TEST_VERIFY (strstr (proc.err.buffer, - "tst-initfinilazyfail: symbol lookup error: ") - != NULL); - TEST_VERIFY (strstr (proc.err.buffer, - "tst-finilazyfailmod.so: undefined symbol:" - " undefined_function\n") != NULL); - support_capture_subprocess_free (&proc); - } - - return 0; -} - -#include diff --git a/elf/tst-initlazyfailmod.c b/elf/tst-initlazyfailmod.c deleted file mode 100644 index 36348b5..0000000 --- a/elf/tst-initlazyfailmod.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Helper module for tst-initfinilazyfail: lazy binding failure in constructor. - 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 - . */ - -/* An undefined function. Calling it will cause a lazy binding - failure. */ -void undefined_function (void); - -static void __attribute__ ((constructor)) -init (void) -{ - undefined_function (); -} diff --git a/elf/tst-ldconfig-bad-aux-cache.c b/elf/tst-ldconfig-bad-aux-cache.c deleted file mode 100644 index 6e22ff8..0000000 --- a/elf/tst-ldconfig-bad-aux-cache.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Test ldconfig does not segfault when aux-cache is corrupted (Bug 18093). - 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; see the file COPYING.LIB. If - not, see . */ - -/* This test does the following: - Run ldconfig to create the caches. - Corrupt the caches. - Run ldconfig again. - At each step we verify that ldconfig does not crash. */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -static int -display_info (const char *fpath, const struct stat *sb, - int tflag, struct FTW *ftwbuf) -{ - printf ("info: %-3s %2d %7jd %-40s %d %s\n", - (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" : - (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" : - (tflag == FTW_NS) ? "ns" : (tflag == FTW_SL) ? "sl" : - (tflag == FTW_SLN) ? "sln" : "???", - ftwbuf->level, (intmax_t) sb->st_size, - fpath, ftwbuf->base, fpath + ftwbuf->base); - /* To tell nftw to continue. */ - return 0; -} - -static void -execv_wrapper (void *args) -{ - char **argv = args; - - execv (argv[0], argv); - FAIL_EXIT1 ("execv: %m"); -} - -/* Run ldconfig with a corrupt aux-cache, in particular we test for size - truncation that might happen if a previous ldconfig run failed or if - there were storage or power issues while we were writing the file. - We want ldconfig not to crash, and it should be able to do so by - computing the expected size of the file (bug 18093). */ -static int -do_test (void) -{ - char *prog = xasprintf ("%s/ldconfig", support_install_rootsbindir); - char *args[] = { prog, NULL }; - const char *path = "/var/cache/ldconfig/aux-cache"; - struct stat64 fs; - long int size, new_size, i; - - /* Create the needed directories. */ - xmkdirp ("/var/cache/ldconfig", 0777); - - /* Run ldconfig first to generate the aux-cache. */ - struct support_capture_subprocess result; - result = support_capture_subprocess (execv_wrapper, args); - support_capture_subprocess_check (&result, "execv", 0, sc_allow_none); - support_capture_subprocess_free (&result); - - xstat (path, &fs); - - size = fs.st_size; - /* Run 3 tests, each truncating aux-cache shorter and shorter. */ - for (i = 3; i > 0; i--) - { - new_size = size * i / 4; - if (truncate (path, new_size)) - FAIL_EXIT1 ("truncation failed: %m"); - if (nftw (path, display_info, 1000, 0) == -1) - FAIL_EXIT1 ("nftw failed."); - - /* Verify that ldconfig can run with a truncated - aux-cache and doesn't crash. */ - struct support_capture_subprocess result; - result = support_capture_subprocess (execv_wrapper, args); - support_capture_subprocess_check (&result, "execv", 0, sc_allow_none); - support_capture_subprocess_free (&result); - } - - free (prog); - return 0; -} - -#include diff --git a/elf/tst-ldconfig-bad-aux-cache.root/etc/ld.so.conf b/elf/tst-ldconfig-bad-aux-cache.root/etc/ld.so.conf deleted file mode 100644 index e1e74db..0000000 --- a/elf/tst-ldconfig-bad-aux-cache.root/etc/ld.so.conf +++ /dev/null @@ -1,2 +0,0 @@ -# This file was created to suppress a warning from ldconfig: -# /sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory diff --git a/elf/tst-ldconfig-bad-aux-cache.root/postclean.req b/elf/tst-ldconfig-bad-aux-cache.root/postclean.req deleted file mode 100644 index e69de29..0000000 --- a/elf/tst-ldconfig-bad-aux-cache.root/postclean.req +++ /dev/null diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c deleted file mode 100644 index 0f51c95..0000000 --- a/elf/tst-pldd.c +++ /dev/null @@ -1,118 +0,0 @@ -/* 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/elf/tst-rtld-preload.sh b/elf/tst-rtld-preload.sh deleted file mode 100755 index f0c0ca1..0000000 --- a/elf/tst-rtld-preload.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# Test --preload argument ld.so. -# 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 -e - -rtld=$1 -test_program=$2 -test_wrapper=$3 -test_wrapper_env=$4 -run_program_env=$5 -library_path=$6 -preload=$7 - -echo "# [${test_wrapper}] [$rtld] [--library-path] [$library_path]" \ - "[--preload] [$preload] [$test_program]" -${test_wrapper_env} \ -${run_program_env} \ -${test_wrapper} $rtld --library-path "$library_path" \ - --preload "$preload" $test_program 2>&1 && rc=0 || rc=$? -echo "# exit status $rc" - -exit $rc diff --git a/elf/tst-sonamemove-dlopen.c b/elf/tst-sonamemove-dlopen.c deleted file mode 100644 index c496705..0000000 --- a/elf/tst-sonamemove-dlopen.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Check that a moved versioned symbol can be found using dlsym, dlvsym. - 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 - -static int -do_test (void) -{ - /* tst-sonamemove-runmod1.so does not define moved_function, but it - depends on tst-sonamemove-runmod2.so, which does. */ - void *handle = xdlopen ("tst-sonamemove-runmod1.so", RTLD_NOW); - TEST_VERIFY (xdlsym (handle, "moved_function") != NULL); - TEST_VERIFY (xdlvsym (handle, "moved_function", "SONAME_MOVE") != NULL); - - return 0; -} - -#include diff --git a/elf/tst-sonamemove-link.c b/elf/tst-sonamemove-link.c deleted file mode 100644 index 4bc3bf3..0000000 --- a/elf/tst-sonamemove-link.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Check that a versioned symbol can move from one library to another. - 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 - . */ - -/* At link time, moved_function is bound to the symbol version - SONAME_MOVE in tst-sonamemove-runmod1.so, using the - tst-sonamemove-linkmod1.so stub object. - - At run time, the process loads the real tst-sonamemove-runmod1.so, - which depends on tst-sonamemove-runmod2.so. - tst-sonamemove-runmod1.so does not define moved_function, but - tst-sonamemove-runmod2.so does. - - The net effect is that the versioned symbol - moved_function@SONAME_MOVE moved from the soname - tst-sonamemove-linkmod1.so at link time to the soname - tst-sonamemove-linkmod2.so at run time. */ -void moved_function (void); - -static int -do_test (void) -{ - moved_function (); - return 0; -} - -#include diff --git a/elf/tst-sonamemove-linkmod1.c b/elf/tst-sonamemove-linkmod1.c deleted file mode 100644 index b8a354e..0000000 --- a/elf/tst-sonamemove-linkmod1.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Link interface for (lack of) soname matching in versioned symbol refs. - 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 - . */ - -/* This function moved from tst-sonamemove-runmod1.so. This module is - intended for linking only, to simulate an old application which was - linked against an older version of the library. */ -void -moved_function (void) -{ -} diff --git a/elf/tst-sonamemove-linkmod1.map b/elf/tst-sonamemove-linkmod1.map deleted file mode 100644 index 8fe5904..0000000 --- a/elf/tst-sonamemove-linkmod1.map +++ /dev/null @@ -1,3 +0,0 @@ -SONAME_MOVE { - global: moved_function; -}; diff --git a/elf/tst-sonamemove-runmod1.c b/elf/tst-sonamemove-runmod1.c deleted file mode 100644 index 5c409e2..0000000 --- a/elf/tst-sonamemove-runmod1.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Run-time module whose moved_function moved to a library dependency. - 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 - . */ - -/* Dummy function to add the required symbol version. */ -void -other_function (void) -{ -} diff --git a/elf/tst-sonamemove-runmod1.map b/elf/tst-sonamemove-runmod1.map deleted file mode 100644 index 2ea81c6..0000000 --- a/elf/tst-sonamemove-runmod1.map +++ /dev/null @@ -1,3 +0,0 @@ -SONAME_MOVE { - global: other_function; -}; diff --git a/elf/tst-sonamemove-runmod2.c b/elf/tst-sonamemove-runmod2.c deleted file mode 100644 index b5e482e..0000000 --- a/elf/tst-sonamemove-runmod2.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Run-time module with the actual implementation of moved_function. - 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 - . */ - -/* In the test scenario, this function was originally in - tst-sonamemove-runmod1.so. */ -void -moved_function (void) -{ -} diff --git a/elf/tst-sonamemove-runmod2.map b/elf/tst-sonamemove-runmod2.map deleted file mode 100644 index 8fe5904..0000000 --- a/elf/tst-sonamemove-runmod2.map +++ /dev/null @@ -1,3 +0,0 @@ -SONAME_MOVE { - global: moved_function; -}; diff --git a/grp/initgroups.c b/grp/initgroups.c index 85dc456..f056fbf 100644 --- a/grp/initgroups.c +++ b/grp/initgroups.c @@ -79,12 +79,12 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, if (__nss_initgroups_database == NULL) { - if (__nss_database_lookup2 ("initgroups", NULL, "", - &__nss_initgroups_database) < 0) + if (__nss_database_lookup ("initgroups", NULL, "", + &__nss_initgroups_database) < 0) { if (__nss_group_database == NULL) - no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG, - &__nss_group_database); + no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG, + &__nss_group_database); __nss_initgroups_database = __nss_group_database; } @@ -128,7 +128,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, /* This is really only for debugging. */ if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) - __libc_fatal ("Illegal status in internal_getgrouplist.\n"); + __libc_fatal ("illegal status in internal_getgrouplist"); /* For compatibility reason we will continue to look for more entries using the next service even though data has already diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c index b6fef15..d5e8e71 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 50% + we use open hashing and a table size which is the next prime 40% larger than the number of strings. */ - hash_size = next_prime (nnames + (nnames >> 1)); + hash_size = next_prime (nnames * 1.4); hash_table = (struct hash_entry *) xcalloc (hash_size, sizeof (struct hash_entry)); /* Fill the hash table. */ diff --git a/iconvdata/gconv-modules b/iconvdata/gconv-modules index e12b0aa..81687c1 100644 --- a/iconvdata/gconv-modules +++ b/iconvdata/gconv-modules @@ -1970,6 +1970,3 @@ alias HPGREEK8// HP-GREEK8// alias OSF10010004// HP-GREEK8// module HP-GREEK8// INTERNAL HP-GREEK8 1 module INTERNAL HP-GREEK8// HP-GREEK8 1 - -alias ISO-10646-UCS-2// UNICODE// -alias ISO-10646-UCS-2// ISO-10646/UTF8/ diff --git a/include/arpa/inet.h b/include/arpa/inet.h index 19aec74..c3f28f2 100644 --- a/include/arpa/inet.h +++ b/include/arpa/inet.h @@ -1,10 +1,10 @@ #include #ifndef _ISOMAC -/* 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) +extern int __inet_aton (const char *__cp, struct in_addr *__inp); +libc_hidden_proto (__inet_aton) +libc_hidden_proto (inet_aton) libc_hidden_proto (inet_ntop) libc_hidden_proto (inet_pton) extern __typeof (inet_pton) __inet_pton; diff --git a/include/bits/statx-generic.h b/include/bits/statx-generic.h deleted file mode 100644 index 2167472..0000000 --- a/include/bits/statx-generic.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/bits/types/struct_statx.h b/include/bits/types/struct_statx.h deleted file mode 100644 index 82add64..0000000 --- a/include/bits/types/struct_statx.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/bits/types/struct_statx_timestamp.h b/include/bits/types/struct_statx_timestamp.h deleted file mode 100644 index 9fbedd5..0000000 --- a/include/bits/types/struct_statx_timestamp.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/elf.h b/include/elf.h index 14ed67f..ab76aaf 100644 --- a/include/elf.h +++ b/include/elf.h @@ -23,7 +23,7 @@ # endif # define DT_1_SUPPORTED_MASK \ (DF_1_NOW | DF_1_NODELETE | DF_1_INITFIRST | DF_1_NOOPEN \ - | DF_1_ORIGIN | DF_1_NODEFLIB | DF_1_PIE) + | DF_1_ORIGIN | DF_1_NODEFLIB) #endif /* !_ISOMAC */ #endif /* elf.h */ diff --git a/include/file_change_detection.h b/include/file_change_detection.h deleted file mode 100644 index 767e578..0000000 --- a/include/file_change_detection.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Detecting file changes using modification times. - Copyright (C) 2017-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _FILE_CHANGE_DETECTION_H -#define _FILE_CHANGE_DETECTION_H - -#include -#include -#include -#include - -/* Items for identifying a particular file version. Excerpt from - struct stat64. */ -struct file_change_detection -{ - /* Special values: 0 if file does not exist. -1 to force mismatch - with the next comparison. */ - off64_t size; - - ino64_t ino; - struct timespec mtime; - struct timespec ctime; -}; - -/* Returns true if *LEFT and *RIGHT describe the same version of the - same file. */ -bool __file_is_unchanged (const struct file_change_detection *left, - const struct file_change_detection *right); - -/* Extract file change information to *FILE from the stat buffer - *ST. */ -void __file_change_detection_for_stat (struct file_change_detection *file, - const struct stat64 *st); - -/* Writes file change information for PATH to *FILE. Returns true on - success. For benign errors, *FILE is cleared, and true is - returned. For errors indicating resource outages and the like, - false is returned. */ -bool __file_change_detection_for_path (struct file_change_detection *file, - const char *path); - -/* Writes file change information for the stream FP to *FILE. Returns - ture on success, false on failure. If FP is NULL, treat the file - as non-existing. */ -bool __file_change_detection_for_fp (struct file_change_detection *file, - FILE *fp); - -#ifndef _ISOMAC -libc_hidden_proto (__file_is_unchanged) -libc_hidden_proto (__file_change_detection_for_stat) -libc_hidden_proto (__file_change_detection_for_path) -libc_hidden_proto (__file_change_detection_for_fp) -#endif - -#endif /* _FILE_CHANGE_DETECTION_H */ diff --git a/include/libc-internal.h b/include/libc-internal.h index 2ec07d9..2167990 100644 --- a/include/libc-internal.h +++ b/include/libc-internal.h @@ -36,6 +36,9 @@ libc_hidden_proto (__profile_frequency) extern void __cyg_profile_func_enter (void *this_fn, void *call_site); extern void __cyg_profile_func_exit (void *this_fn, void *call_site); +/* Get frequency of the system processor. */ +extern hp_timing_t __get_clockfreq (void); + /* Free all allocated resources. */ extern void __libc_freeres (void); libc_hidden_proto (__libc_freeres) diff --git a/include/link.h b/include/link.h index e90fa79..5924594 100644 --- a/include/link.h +++ b/include/link.h @@ -79,6 +79,7 @@ struct r_search_path_struct int malloced; }; + /* Structure describing a loaded shared object. The `l_next' and `l_prev' members form a chain of all the shared objects loaded at startup. @@ -202,18 +203,6 @@ struct link_map freed, ie. not allocated with the dummy malloc in ld.so. */ - /* NODELETE status of the map. Only valid for maps of type - lt_loaded. Lazy binding sets l_nodelete_active directly, - potentially from signal handlers. Initial loading of an - DF_1_NODELETE object set l_nodelete_pending. Relocation may - set l_nodelete_pending as well. l_nodelete_pending maps are - promoted to l_nodelete_active status in the final stages of - dlopen, prior to calling ELF constructors. dlclose only - refuses to unload l_nodelete_active maps, the pending status is - ignored. */ - bool l_nodelete_active; - bool l_nodelete_pending; - #include /* Collected information about own RPATH directories. */ @@ -227,10 +216,6 @@ struct link_map unsigned int boundndx; uint32_t enterexit; unsigned int flags; - /* CONCURRENCY NOTE: This is used to guard the concurrent initialization - of the relocation result across multiple threads. See the more - detailed notes in elf/dl-runtime.c. */ - unsigned int init; } *l_reloc_result; /* Pointer to the version information if available. */ diff --git a/include/stdio.h b/include/stdio.h index 7a5c090..9162d4e 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -98,8 +98,7 @@ enum __libc_message_action do_backtrace = 1 << 1 /* Backtrace. */ }; -/* Print out MESSAGE (which should end with a newline) on the error output - and abort. */ +/* Print out MESSAGE on the error output and abort. */ extern void __libc_fatal (const char *__message) __attribute__ ((__noreturn__)); extern void __libc_message (enum __libc_message_action action, diff --git a/include/time.h b/include/time.h index 832ee68..23d2580 100644 --- a/include/time.h +++ b/include/time.h @@ -16,10 +16,12 @@ libc_hidden_proto (localtime) libc_hidden_proto (strftime) libc_hidden_proto (strptime) +extern __typeof (clock_getres) __clock_getres; extern __typeof (clock_gettime) __clock_gettime; libc_hidden_proto (__clock_gettime) extern __typeof (clock_settime) __clock_settime; -libc_hidden_proto (__clock_settime) +extern __typeof (clock_nanosleep) __clock_nanosleep; +extern __typeof (clock_getcpuclockid) __clock_getcpuclockid; /* Now define the internal interfaces. */ struct tm; diff --git a/inet/Makefile b/inet/Makefile index 7782913..09f5ba7 100644 --- a/inet/Makefile +++ b/inet/Makefile @@ -52,7 +52,7 @@ aux := check_pf check_native ifreq tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \ tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-checks-posix \ - tst-sockaddr test-hnto-types tst-if_index-long + tst-sockaddr test-hnto-types # tst-deadline must be linked statically so that we can access # internal functions. diff --git a/inet/tst-if_index-long.c b/inet/tst-if_index-long.c deleted file mode 100644 index 3dc7487..0000000 --- a/inet/tst-if_index-long.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Check for descriptor leak in if_nametoindex with a long interface name. - 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 - . */ - -/* This test checks for a descriptor leak in case of a long interface - name (CVE-2018-19591, bug 23927). */ - -#include -#include -#include -#include -#include -#include -#include - -static int -do_test (void) -{ - struct support_descriptors *descrs = support_descriptors_list (); - - /* Prepare a name which is just as long as required for trigging the - bug. */ - char name[IFNAMSIZ + 1]; - memset (name, 'A', IFNAMSIZ); - name[IFNAMSIZ] = '\0'; - TEST_COMPARE (strlen (name), IFNAMSIZ); - struct ifreq ifr; - TEST_COMPARE (strlen (name), sizeof (ifr.ifr_name)); - - /* Test directly via if_nametoindex. */ - TEST_COMPARE (if_nametoindex (name), 0); - TEST_COMPARE (errno, ENODEV); - support_descriptors_check (descrs); - - /* Same test via getaddrinfo. */ - char *host = xasprintf ("fea0::%%%s", name); - struct addrinfo hints = { .ai_flags = AI_NUMERICHOST, }; - struct addrinfo *ai; - TEST_COMPARE (getaddrinfo (host, NULL, &hints, &ai), EAI_NONAME); - support_descriptors_check (descrs); - - support_descriptors_free (descrs); - - return 0; -} - -#include diff --git a/intl/dcigettext.c b/intl/dcigettext.c index 25f47c5..2a50369 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) - goto return_untranslated; + return NULL; dirname = xdirname; } #ifndef IN_LIBGLOCALE diff --git a/io/Makefile b/io/Makefile index daccbcf..ec5c6d7 100644 --- a/io/Makefile +++ b/io/Makefile @@ -25,9 +25,7 @@ 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 bits/statx-generic.h bits/types/struct_statx.h \ - bits/types/struct_statx_timestamp.h \ - utime.h ftw.h fts.h sys/sendfile.h + bits/statx.h utime.h ftw.h fts.h sys/sendfile.h routines := \ utime \ @@ -55,7 +53,7 @@ routines := \ posix_fadvise posix_fadvise64 \ posix_fallocate posix_fallocate64 \ sendfile sendfile64 copy_file_range \ - utimensat futimens file_change_detection + utimensat futimens # These routines will be omitted from the libc shared object. # Instead the static object files will be included in a special archive @@ -74,7 +72,11 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ tst-posix_fallocate tst-posix_fallocate64 \ tst-fts tst-fts-lfs tst-open-tmpfile \ tst-copy_file_range tst-getcwd-abspath \ - tst-file_change_detection + +# 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/Versions b/io/Versions index ee46805..f7e5dbe 100644 --- a/io/Versions +++ b/io/Versions @@ -137,9 +137,5 @@ libc { __fcntl_nocancel; __open64_nocancel; __write_nocancel; - __file_is_unchanged; - __file_change_detection_for_stat; - __file_change_detection_for_path; - __file_change_detection_for_fp; } } diff --git a/io/bits/statx-generic.h b/io/bits/statx-generic.h deleted file mode 100644 index 1f5abbf..0000000 --- a/io/bits/statx-generic.h +++ /dev/null @@ -1,60 +0,0 @@ -/* 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 b3147bf..e31254e 100644 --- a/io/bits/statx.h +++ b/io/bits/statx.h @@ -1,5 +1,5 @@ -/* statx-related definitions and declarations. Generic version. - Copyright (C) 2018-2019 Free Software Foundation, Inc. +/* statx-related definitions and declarations. + 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 @@ -19,8 +19,73 @@ /* This interface is based on in Linux. */ #ifndef _SYS_STAT_H -# error Never include directly, include instead. +# error Never include directly, include instead. #endif -/* Use the generic definitions. */ -#include +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 diff --git a/io/bits/types/struct_statx.h b/io/bits/types/struct_statx.h deleted file mode 100644 index 4f3ae3e..0000000 --- a/io/bits/types/struct_statx.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 deleted file mode 100644 index 0f104ef..0000000 --- a/io/bits/types/struct_statx_timestamp.h +++ /dev/null @@ -1,33 +0,0 @@ -/* 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/copy_file_range-compat.c b/io/copy_file_range-compat.c new file mode 100644 index 0000000..4ab22ca --- /dev/null +++ b/io/copy_file_range-compat.c @@ -0,0 +1,160 @@ +/* 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 59fb979..98bff8b 100644 --- a/io/copy_file_range.c +++ b/io/copy_file_range.c @@ -1,5 +1,5 @@ -/* Stub implementation of copy_file_range. - Copyright (C) 2017-2019 Free Software Foundation, Inc. +/* Generic 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 @@ -16,15 +16,7 @@ License along with the GNU C Library; if not, see . */ -#include -#include +#define COPY_FILE_RANGE_DECL +#define COPY_FILE_RANGE copy_file_range -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) +#include diff --git a/io/file_change_detection.c b/io/file_change_detection.c deleted file mode 100644 index c6d700e..0000000 --- a/io/file_change_detection.c +++ /dev/null @@ -1,118 +0,0 @@ -/* Detecting file changes using modification times. - Copyright (C) 2017-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -#include -#include - -bool -__file_is_unchanged (const struct file_change_detection *left, - const struct file_change_detection *right) -{ - if (left->size < 0 || right->size < 0) - /* Negative sizes are used as markers and never match. */ - return false; - else if (left->size == 0 && right->size == 0) - /* Both files are empty or do not exist, so they have the same - content, no matter what the other fields indicate. */ - return true; - else - return left->size == right->size - && left->ino == right->ino - && left->mtime.tv_sec == right->mtime.tv_sec - && left->mtime.tv_nsec == right->mtime.tv_nsec - && left->ctime.tv_sec == right->ctime.tv_sec - && left->ctime.tv_nsec == right->ctime.tv_nsec; -} -libc_hidden_def (__file_is_unchanged) - -void -__file_change_detection_for_stat (struct file_change_detection *file, - const struct stat64 *st) -{ - if (S_ISDIR (st->st_mode)) - /* Treat as empty file. */ - file->size = 0; - else if (!S_ISREG (st->st_mode)) - /* Non-regular files cannot be cached. */ - file->size = -1; - else - { - file->size = st->st_size; - file->ino = st->st_ino; - file->mtime = st->st_mtim; - file->ctime = st->st_ctim; - } -} -libc_hidden_def (__file_change_detection_for_stat) - -bool -__file_change_detection_for_path (struct file_change_detection *file, - const char *path) -{ - struct stat64 st; - if (stat64 (path, &st) != 0) - switch (errno) - { - case EACCES: - case EISDIR: - case ELOOP: - case ENOENT: - case ENOTDIR: - case EPERM: - /* Ignore errors due to file system contents. Instead, treat - the file as empty. */ - file->size = 0; - return true; - default: - /* Other errors are fatal. */ - return false; - } - else /* stat64 was successfull. */ - { - __file_change_detection_for_stat (file, &st); - return true; - } -} -libc_hidden_def (__file_change_detection_for_path) - -bool -__file_change_detection_for_fp (struct file_change_detection *file, - FILE *fp) -{ - if (fp == NULL) - { - /* The file does not exist. */ - file->size = 0; - return true; - } - else - { - struct stat64 st; - if (fstat64 (__fileno (fp), &st) != 0) - /* If we already have a file descriptor, all errors are fatal. */ - return false; - else - { - __file_change_detection_for_stat (file, &st); - return true; - } - } -} -libc_hidden_def (__file_change_detection_for_fp) diff --git a/io/statx_generic.c b/io/statx_generic.c index 987c84f..df327f8 100644 --- a/io/statx_generic.c +++ b/io/statx_generic.c @@ -18,16 +18,9 @@ #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) { @@ -64,7 +57,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. */ - struct original_statx obuf = + *buf = (struct statx) { .stx_mask = STATX_BASIC_STATS, .stx_blksize = st.st_blksize, @@ -83,8 +76,6 @@ 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/io/tst-copy_file_range-compat.c b/io/tst-copy_file_range-compat.c new file mode 100644 index 0000000..00c109a --- /dev/null +++ b/io/tst-copy_file_range-compat.c @@ -0,0 +1,30 @@ +/* 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 4504020..3d531a1 100644 --- a/io/tst-copy_file_range.c +++ b/io/tst-copy_file_range.c @@ -20,15 +20,22 @@ #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. */ @@ -42,6 +49,10 @@ 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. */ @@ -50,10 +61,13 @@ static off64_t *pinoff; static off64_t outoff; static off64_t *poutoff; -/* These are a collection of copy sizes used in tests. */ +/* 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. */ enum { maximum_size = 99999 }; static const int typical_sizes[] = - { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, maximum_size }; + { 0, 1, 2, 3, 1024, 2048, 4096, 8191, 8192, 8193, 16383, 16384, 16385, + maximum_size }; /* The random contents of this array can be used as a pattern to check for correct write operations. */ @@ -62,6 +76,101 @@ 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) @@ -138,6 +247,390 @@ 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) @@ -228,6 +721,14 @@ 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 }, }; @@ -238,18 +739,53 @@ do_test (void) *p = rand () >> 24; infd = create_temp_file ("tst-copy_file_range-in-", &infile); - outfd = create_temp_file ("tst-copy_file_range-out-", &outfile); + xclose (create_temp_file ("tst-copy_file_range-out-", &outfile)); + + /* Try to find a different directory from the default input/output + file. */ { - ssize_t ret = copy_file_range (infd, NULL, outfd, NULL, 0, 0); - if (ret != 0) + 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) { - if (errno == ENOSYS) - FAIL_UNSUPPORTED ("copy_file_range is not support on this system"); - FAIL_EXIT1 ("copy_file_range probing call: %m"); + 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); } + 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) @@ -291,6 +827,7 @@ do_test (void) free (infile); free (outfile); + free (xdevfile); return 0; } diff --git a/io/tst-file_change_detection.c b/io/tst-file_change_detection.c deleted file mode 100644 index 6e00e78..0000000 --- a/io/tst-file_change_detection.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Test for . - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void -all_same (struct file_change_detection *array, size_t length) -{ - for (size_t i = 0; i < length; ++i) - for (size_t j = 0; j < length; ++j) - { - if (test_verbose > 0) - printf ("info: comparing %zu and %zu\n", i, j); - TEST_VERIFY (__file_is_unchanged (array + i, array + j)); - } -} - -static void -all_different (struct file_change_detection *array, size_t length) -{ - for (size_t i = 0; i < length; ++i) - for (size_t j = 0; j < length; ++j) - { - if (i == j) - continue; - if (test_verbose > 0) - printf ("info: comparing %zu and %zu\n", i, j); - TEST_VERIFY (!__file_is_unchanged (array + i, array + j)); - } -} - -static int -do_test (void) -{ - /* Use a temporary directory with various paths. */ - char *tempdir = support_create_temp_directory ("tst-file_change_detection-"); - - char *path_dangling = xasprintf ("%s/dangling", tempdir); - char *path_does_not_exist = xasprintf ("%s/does-not-exist", tempdir); - char *path_empty1 = xasprintf ("%s/empty1", tempdir); - char *path_empty2 = xasprintf ("%s/empty2", tempdir); - char *path_fifo = xasprintf ("%s/fifo", tempdir); - char *path_file1 = xasprintf ("%s/file1", tempdir); - char *path_file2 = xasprintf ("%s/file2", tempdir); - char *path_loop = xasprintf ("%s/loop", tempdir); - char *path_to_empty1 = xasprintf ("%s/to-empty1", tempdir); - char *path_to_file1 = xasprintf ("%s/to-file1", tempdir); - - add_temp_file (path_dangling); - add_temp_file (path_empty1); - add_temp_file (path_empty2); - add_temp_file (path_fifo); - add_temp_file (path_file1); - add_temp_file (path_file2); - add_temp_file (path_loop); - add_temp_file (path_to_empty1); - add_temp_file (path_to_file1); - - xsymlink ("target-does-not-exist", path_dangling); - support_write_file_string (path_empty1, ""); - support_write_file_string (path_empty2, ""); - TEST_COMPARE (mknod (path_fifo, 0777 | S_IFIFO, 0), 0); - support_write_file_string (path_file1, "line\n"); - support_write_file_string (path_file2, "line\n"); - xsymlink ("loop", path_loop); - xsymlink ("empty1", path_to_empty1); - xsymlink ("file1", path_to_file1); - - FILE *fp_file1 = xfopen (path_file1, "r"); - FILE *fp_file2 = xfopen (path_file2, "r"); - FILE *fp_empty1 = xfopen (path_empty1, "r"); - FILE *fp_empty2 = xfopen (path_empty2, "r"); - - /* Test for the same (empty) files. */ - { - struct file_change_detection fcd[10]; - int i = 0; - /* Two empty files always have the same contents. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty1)); - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty2)); - /* So does a missing file (which is treated as empty). */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], - path_does_not_exist)); - /* And a symbolic link loop. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_loop)); - /* And a dangling symbolic link. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_dangling)); - /* And a directory. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], tempdir)); - /* And a symbolic link to an empty file. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_to_empty1)); - /* Likewise for access the file via a FILE *. */ - TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_empty1)); - TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_empty2)); - /* And a NULL FILE * (missing file). */ - TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], NULL)); - TEST_COMPARE (i, array_length (fcd)); - - all_same (fcd, array_length (fcd)); - } - - /* Symbolic links are resolved. */ - { - struct file_change_detection fcd[3]; - int i = 0; - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file1)); - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_to_file1)); - TEST_VERIFY (__file_change_detection_for_fp (&fcd[i++], fp_file1)); - TEST_COMPARE (i, array_length (fcd)); - all_same (fcd, array_length (fcd)); - } - - /* Test for different files. */ - { - struct file_change_detection fcd[5]; - int i = 0; - /* The other files are not empty. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_empty1)); - /* These two files have the same contents, but have different file - identity. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file1)); - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_file2)); - /* FIFOs are always different, even with themselves. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_fifo)); - TEST_VERIFY (__file_change_detection_for_path (&fcd[i++], path_fifo)); - TEST_COMPARE (i, array_length (fcd)); - all_different (fcd, array_length (fcd)); - - /* Replacing the file with its symbolic link does not make a - difference. */ - TEST_VERIFY (__file_change_detection_for_path (&fcd[1], path_to_file1)); - all_different (fcd, array_length (fcd)); - } - - /* Wait for a file change. Depending on file system time stamp - resolution, this subtest blocks for a while. */ - for (int use_stdio = 0; use_stdio < 2; ++use_stdio) - { - struct file_change_detection initial; - TEST_VERIFY (__file_change_detection_for_path (&initial, path_file1)); - while (true) - { - support_write_file_string (path_file1, "line\n"); - struct file_change_detection current; - if (use_stdio) - TEST_VERIFY (__file_change_detection_for_fp (¤t, fp_file1)); - else - TEST_VERIFY (__file_change_detection_for_path - (¤t, path_file1)); - if (!__file_is_unchanged (&initial, ¤t)) - break; - /* Wait for a bit to reduce system load. */ - usleep (100 * 1000); - } - } - - fclose (fp_empty1); - fclose (fp_empty2); - fclose (fp_file1); - fclose (fp_file2); - - free (path_dangling); - free (path_does_not_exist); - free (path_empty1); - free (path_empty2); - free (path_fifo); - free (path_file1); - free (path_file2); - free (path_loop); - free (path_to_empty1); - free (path_to_file1); - - free (tempdir); - - return 0; -} - -#include diff --git a/libio/Makefile b/libio/Makefile index 314e03d..cab0eae 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -64,8 +64,7 @@ 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-wfile-sync + tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof tests-internal = tst-vtables tst-vtables-interposed tst-readline @@ -73,9 +72,6 @@ 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 @@ -156,14 +152,11 @@ 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 @@ -172,7 +165,6 @@ 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 @@ -187,8 +179,7 @@ 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 \ - $(objpfx)tst-bz24228-mem.out +tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out endif endif @@ -216,7 +207,6 @@ $(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 @@ -240,7 +230,3 @@ $(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/fileops.c b/libio/fileops.c index dd66cc6..c9c5cbc 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -331,6 +331,9 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode, cc = fp->_codecvt = &fp->_wide_data->_codecvt; + /* The functions are always the same. */ + *cc = __libio_codecvt; + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; cc->__cd_in.__cd.__steps = fcts.towc; diff --git a/libio/genops.c b/libio/genops.c index a8241dd..2fec221 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -789,16 +789,9 @@ _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. */ - && (legacy || fp->_mode != 0)) + && fp->_mode != 0) { #ifdef _IO_MTSAFE_IO int cnt; @@ -812,7 +805,7 @@ _IO_unbuffer_all (void) __sched_yield (); #endif - if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) + if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) { fp->_flags |= _IO_USER_BUF; @@ -823,7 +816,7 @@ _IO_unbuffer_all (void) _IO_SETBUF (fp, NULL, 0); - if (! legacy && fp->_mode > 0) + if (fp->_mode > 0) _IO_wsetb (fp, NULL, NULL, 0); #ifdef _IO_MTSAFE_IO @@ -834,8 +827,7 @@ _IO_unbuffer_all (void) /* Make sure that never again the wide char functions can be used. */ - if (! legacy) - fp->_mode = -1; + fp->_mode = -1; } #ifdef _IO_MTSAFE_IO diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c index 808ddc4..8177326 100644 --- a/libio/iofgetpos.c +++ b/libio/iofgetpos.c @@ -70,7 +70,8 @@ _IO_new_fgetpos (FILE *fp, __fpos_t *posp) else { posp->__pos = pos; - if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) /* This is a stateful encoding, safe the state. */ posp->__state = fp->_wide_data->_IO_state; } diff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c index 5a0d8bd..0ec5413 100644 --- a/libio/iofgetpos64.c +++ b/libio/iofgetpos64.c @@ -54,7 +54,8 @@ _IO_new_fgetpos64 (FILE *fp, __fpos64_t *posp) else { posp->__pos = pos; - if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) /* This is a stateful encoding, safe the state. */ posp->__state = fp->_wide_data->_IO_state; } diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c index 0cbe3b7..da48b27 100644 --- a/libio/iofsetpos.c +++ b/libio/iofsetpos.c @@ -58,7 +58,8 @@ _IO_new_fsetpos (FILE *fp, const __fpos_t *posp) else { result = 0; - if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) /* This is a stateful encoding, restore the state. */ fp->_wide_data->_IO_state = posp->__state; } diff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c index 695a832..29da981 100644 --- a/libio/iofsetpos64.c +++ b/libio/iofsetpos64.c @@ -48,7 +48,8 @@ _IO_new_fsetpos64 (FILE *fp, const fpos64_t *posp) else { result = 0; - if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) /* This is a stateful encoding, safe the state. */ fp->_wide_data->_IO_state = posp->__state; } diff --git a/libio/iofwide.c b/libio/iofwide.c index 0e9e7dd..d8ec664 100644 --- a/libio/iofwide.c +++ b/libio/iofwide.c @@ -39,6 +39,44 @@ #include +/* Prototypes of libio's codecvt functions. */ +static enum __codecvt_result do_out (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const wchar_t *from_start, + const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt, + __mbstate_t *statep, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_in (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const char *from_start, + const char *from_end, + const char **from_stop, wchar_t *to_start, + wchar_t *to_end, wchar_t **to_stop); +static int do_encoding (struct _IO_codecvt *codecvt); +static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, + const char *from_end, size_t max); +static int do_max_length (struct _IO_codecvt *codecvt); +static int do_always_noconv (struct _IO_codecvt *codecvt); + + +/* The functions used in `codecvt' for libio are always the same. */ +const struct _IO_codecvt __libio_codecvt = +{ + .__codecvt_destr = NULL, /* Destructor, never used. */ + .__codecvt_do_out = do_out, + .__codecvt_do_unshift = do_unshift, + .__codecvt_do_in = do_in, + .__codecvt_do_encoding = do_encoding, + .__codecvt_do_always_noconv = do_always_noconv, + .__codecvt_do_length = do_length, + .__codecvt_do_max_length = do_max_length +}; + + /* Return orientation of stream. If mode is nonzero try to change the orientation first. */ #undef _IO_fwide @@ -81,6 +119,9 @@ _IO_fwide (FILE *fp, int mode) assert (fcts.towc_nsteps == 1); assert (fcts.tomb_nsteps == 1); + /* The functions are always the same. */ + *cc = __libio_codecvt; + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; cc->__cd_in.__cd.__steps = fcts.towc; @@ -110,11 +151,11 @@ _IO_fwide (FILE *fp, int mode) } -enum __codecvt_result -__libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, - const wchar_t *from_start, const wchar_t *from_end, - const wchar_t **from_stop, char *to_start, char *to_end, - char **to_stop) +static enum __codecvt_result +do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const wchar_t *from_start, const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, char *to_end, + char **to_stop) { enum __codecvt_result result; @@ -162,11 +203,57 @@ __libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, } -enum __codecvt_result -__libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, - const char *from_start, const char *from_end, - const char **from_stop, - wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) +static enum __codecvt_result +do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, + char *to_start, char *to_end, char **to_stop) +{ + enum __codecvt_result result; + + struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; + int status; + size_t dummy; + + codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start; + codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end; + codecvt->__cd_out.__cd.__data[0].__statep = statep; + + __gconv_fct fct = gs->__fct; +#ifdef PTR_DEMANGLE + if (gs->__shlib_handle != NULL) + PTR_DEMANGLE (fct); +#endif + + status = DL_CALL_FCT (fct, + (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, + NULL, &dummy, 1, 0)); + + *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } + + return result; +} + + +static enum __codecvt_result +do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, const char **from_stop, + wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) { enum __codecvt_result result; @@ -214,8 +301,8 @@ __libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, } -int -__libio_codecvt_encoding (struct _IO_codecvt *codecvt) +static int +do_encoding (struct _IO_codecvt *codecvt) { /* See whether the encoding is stateful. */ if (codecvt->__cd_in.__cd.__steps[0].__stateful) @@ -231,10 +318,16 @@ __libio_codecvt_encoding (struct _IO_codecvt *codecvt) } -int -__libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, - const char *from_start, const char *from_end, - size_t max) +static int +do_always_noconv (struct _IO_codecvt *codecvt) +{ + return 0; +} + + +static int +do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, size_t max) { int result; const unsigned char *cp = (const unsigned char *) from_start; @@ -261,3 +354,10 @@ __libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, return result; } + + +static int +do_max_length (struct _IO_codecvt *codecvt) +{ + return codecvt->__cd_in.__cd.__steps[0].__max_needed_from; +} diff --git a/libio/libio.h b/libio/libio.h index 5291bb8..00f9169 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -118,8 +118,40 @@ struct _IO_marker { int _pos; }; +/* This is the structure from the libstdc++ codecvt class. */ +enum __codecvt_result +{ + __codecvt_ok, + __codecvt_partial, + __codecvt_error, + __codecvt_noconv +}; + +/* The order of the elements in the following struct must match the order + of the virtual functions in the libstdc++ codecvt class. */ struct _IO_codecvt { + void (*__codecvt_destr) (struct _IO_codecvt *); + enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *, + __mbstate_t *, + const wchar_t *, + const wchar_t *, + const wchar_t **, char *, + char *, char **); + enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *, + __mbstate_t *, char *, + char *, char **); + enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *, + __mbstate_t *, + const char *, const char *, + const char **, wchar_t *, + wchar_t *, wchar_t **); + int (*__codecvt_do_encoding) (struct _IO_codecvt *); + int (*__codecvt_do_always_noconv) (struct _IO_codecvt *); + int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *, + const char *, const char *, size_t); + int (*__codecvt_do_max_length) (struct _IO_codecvt *); + _IO_iconv_t __cd_in; _IO_iconv_t __cd_out; }; diff --git a/libio/libioP.h b/libio/libioP.h index 7ee71a6..df2633d 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -476,6 +476,7 @@ extern const struct _IO_jump_t _IO_streambuf_jumps; extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden; extern const struct _IO_jump_t _IO_str_jumps attribute_hidden; extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden; +extern const struct _IO_codecvt __libio_codecvt attribute_hidden; extern int _IO_do_write (FILE *, const char *, size_t); libc_hidden_proto (_IO_do_write) extern int _IO_new_do_write (FILE *, const char *, size_t); @@ -838,32 +839,4 @@ IO_validate_vtable (const struct _IO_jump_t *vtable) return vtable; } -/* Character set conversion. */ - -enum __codecvt_result -{ - __codecvt_ok, - __codecvt_partial, - __codecvt_error, - __codecvt_noconv -}; - -enum __codecvt_result __libio_codecvt_out (struct _IO_codecvt *, - __mbstate_t *, - const wchar_t *, - const wchar_t *, - const wchar_t **, char *, - char *, char **) - attribute_hidden; -enum __codecvt_result __libio_codecvt_in (struct _IO_codecvt *, - __mbstate_t *, - const char *, const char *, - const char **, wchar_t *, - wchar_t *, wchar_t **) - attribute_hidden; -int __libio_codecvt_encoding (struct _IO_codecvt *) attribute_hidden; -int __libio_codecvt_length (struct _IO_codecvt *, __mbstate_t *, - const char *, const char *, size_t) - attribute_hidden; - #endif /* libioP.h. */ diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c index 9fe809b..f3dda89 100644 --- a/libio/oldstdfiles.c +++ b/libio/oldstdfiles.c @@ -87,11 +87,6 @@ _IO_check_libio (void) stdout->_vtable_offset = stderr->_vtable_offset = ((int) sizeof (struct _IO_FILE) - (int) sizeof (struct _IO_FILE_complete)); - - if (_IO_stdin_.vtable != &_IO_old_file_jumps - || _IO_stdout_.vtable != &_IO_old_file_jumps - || _IO_stderr_.vtable != &_IO_old_file_jumps) - IO_set_accept_foreign_vtables (&_IO_vtable_check); } } diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c deleted file mode 100644 index 6a74500..0000000 --- a/libio/tst-bz24228.c +++ /dev/null @@ -1,29 +0,0 @@ -/* 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 deleted file mode 100644 index 4383e08..0000000 --- a/libio/tst-bz24228.map +++ /dev/null @@ -1,5 +0,0 @@ -# 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/libio/tst-readline.c b/libio/tst-readline.c index 63f5227..9322ef6 100644 --- a/libio/tst-readline.c +++ b/libio/tst-readline.c @@ -232,6 +232,5 @@ do_test (void) return 0; } -#define TIMEOUT 100 #define PREPARE prepare #include diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c index 85e246c..5e31012 100644 --- a/libio/tst-vtables-common.c +++ b/libio/tst-vtables-common.c @@ -380,6 +380,21 @@ without_compatibility_fflush (void *closure) _exit (1); } +/* Exit status after abnormal termination. */ +static int termination_status; + +static void +init_termination_status (void) +{ + pid_t pid = xfork (); + if (pid == 0) + abort (); + xwaitpid (pid, &termination_status, 0); + + TEST_VERIFY (WIFSIGNALED (termination_status)); + TEST_COMPARE (WTERMSIG (termination_status), SIGABRT); +} + static void check_for_termination (const char *name, void (*callback) (void *)) { @@ -389,7 +404,7 @@ check_for_termination (const char *name, void (*callback) (void *)) shared->calls = 0; struct support_capture_subprocess proc = support_capture_subprocess (callback, NULL); - support_capture_subprocess_check (&proc, name, -SIGABRT, + support_capture_subprocess_check (&proc, name, termination_status, sc_allow_stderr); const char *message = "Fatal error: glibc detected an invalid stdio handle\n"; @@ -476,6 +491,7 @@ run_tests (bool initially_disabled) shared = support_shared_allocate (sizeof (*shared)); shared->initially_disabled = initially_disabled; + init_termination_status (); if (initially_disabled) { diff --git a/libio/tst-wfile-sync.c b/libio/tst-wfile-sync.c deleted file mode 100644 index 6186820..0000000 --- a/libio/tst-wfile-sync.c +++ /dev/null @@ -1,39 +0,0 @@ -/* 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 deleted file mode 100644 index 12d0958..0000000 --- a/libio/tst-wfile-sync.input +++ /dev/null @@ -1 +0,0 @@ -This is a test of _IO_wfile_sync. diff --git a/libio/wfileops.c b/libio/wfileops.c index d3deb34..63cb687 100644 --- a/libio/wfileops.c +++ b/libio/wfileops.c @@ -72,11 +72,11 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do) } /* Now convert from the internal format into the external buffer. */ - result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state, - data, data + to_do, &new_data, - write_ptr, - buf_end, - &write_ptr); + result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state, + data, data + to_do, &new_data, + write_ptr, + buf_end, + &write_ptr); /* Write out what we produced so far. */ if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF) @@ -140,12 +140,12 @@ _IO_wfile_underflow (FILE *fp) fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_buf_base; - status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, - fp->_IO_read_ptr, fp->_IO_read_end, - &read_stop, - fp->_wide_data->_IO_read_ptr, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); fp->_IO_read_base = fp->_IO_read_ptr; fp->_IO_read_ptr = (char *) read_stop; @@ -266,11 +266,11 @@ _IO_wfile_underflow (FILE *fp) naccbuf += to_copy; from = accbuf; } - status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, - from, to, &read_ptr_copy, - fp->_wide_data->_IO_read_end, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + from, to, &read_ptr_copy, + fp->_wide_data->_IO_read_end, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); if (__glibc_unlikely (naccbuf != 0)) fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]); @@ -372,12 +372,12 @@ _IO_wfile_underflow_mmap (FILE *fp) fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_buf_base; - __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, - fp->_IO_read_ptr, fp->_IO_read_end, - &read_stop, - fp->_wide_data->_IO_read_ptr, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); fp->_IO_read_ptr = (char *) read_stop; @@ -495,7 +495,7 @@ _IO_wfile_sync (FILE *fp) struct _IO_codecvt *cv = fp->_codecvt; off64_t new_pos; - int clen = __libio_codecvt_encoding (cv); + int clen = (*cv->__codecvt_do_encoding) (cv); if (clen > 0) /* It is easy, a fixed number of input bytes are used for each @@ -508,12 +508,11 @@ _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 = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state, - fp->_IO_read_base, - fp->_IO_read_end, wnread); + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); fp->_IO_read_ptr = fp->_IO_read_base + nread; delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); } @@ -548,7 +547,7 @@ adjust_wide_data (FILE *fp, bool do_convert) { struct _IO_codecvt *cv = fp->_codecvt; - int clen = __libio_codecvt_encoding (cv); + int clen = (*cv->__codecvt_do_encoding) (cv); /* Take the easy way out for constant length encodings if we don't need to convert. */ @@ -565,12 +564,12 @@ adjust_wide_data (FILE *fp, bool do_convert) { fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; - status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state, - fp->_IO_read_base, fp->_IO_read_ptr, - &read_stop, - fp->_wide_data->_IO_read_base, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, fp->_IO_read_ptr, + &read_stop, + fp->_wide_data->_IO_read_base, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); /* Should we return EILSEQ? */ if (__glibc_unlikely (status == __codecvt_error)) @@ -648,7 +647,7 @@ do_ftell_wide (FILE *fp) } struct _IO_codecvt *cv = fp->_codecvt; - int clen = __libio_codecvt_encoding (cv); + int clen = (*cv->__codecvt_do_encoding) (cv); if (!unflushed_writes) { @@ -663,9 +662,9 @@ do_ftell_wide (FILE *fp) size_t delta = wide_read_ptr - wide_read_base; __mbstate_t state = fp->_wide_data->_IO_last_state; - nread = __libio_codecvt_length (cv, &state, - fp->_IO_read_base, - fp->_IO_read_end, delta); + nread = (*cv->__codecvt_do_length) (cv, &state, + fp->_IO_read_base, + fp->_IO_read_end, delta); offset -= fp->_IO_read_end - fp->_IO_read_base - nread; } } @@ -688,8 +687,9 @@ do_ftell_wide (FILE *fp) enum __codecvt_result status; __mbstate_t state = fp->_wide_data->_IO_last_state; - status = __libio_codecvt_out (cv, &state, in, in + delta, &in, - out, out + outsize, &outstop); + status = (*cv->__codecvt_do_out) (cv, &state, + in, in + delta, &in, + out, out + outsize, &outstop); /* We don't check for __codecvt_partial because it can be returned on one of two conditions: either the output @@ -800,7 +800,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) find out which position in the external buffer corresponds to the current position in the internal buffer. */ cv = fp->_codecvt; - clen = __libio_codecvt_encoding (cv); + clen = (*cv->__codecvt_do_encoding) (cv); if (mode != 0 || !was_writing) { @@ -818,10 +818,10 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) delta = (fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base); fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; - nread = __libio_codecvt_length (cv, - &fp->_wide_data->_IO_state, - fp->_IO_read_base, - fp->_IO_read_end, delta); + nread = (*cv->__codecvt_do_length) (cv, + &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); fp->_IO_read_ptr = fp->_IO_read_base + nread; fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; offset -= fp->_IO_read_end - fp->_IO_read_base - nread; diff --git a/locale/Makefile b/locale/Makefile index 23a7132..fd99722 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -60,10 +60,6 @@ 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 @@ -108,7 +104,3 @@ 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/loadarchive.c b/locale/loadarchive.c index b308fd8..516d30d 100644 --- a/locale/loadarchive.c +++ b/locale/loadarchive.c @@ -274,7 +274,7 @@ _nl_load_locale_from_archive (int category, const char **namep) + head->namehash_offset); /* Avoid division by 0 if the file is corrupted. */ - if (__glibc_unlikely (head->namehash_size <= 2)) + if (__glibc_unlikely (head->namehash_size == 0)) goto close_and_out; idx = hval % head->namehash_size; diff --git a/locale/loadlocale.c b/locale/loadlocale.c index e521b11..15f93be 100644 --- a/locale/loadlocale.c +++ b/locale/loadlocale.c @@ -172,6 +172,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) int save_err; int alloc = ld_mapped; + file->decided = 1; file->data = NULL; fd = __open_nocancel (file->filename, O_RDONLY | O_CLOEXEC); @@ -280,7 +281,6 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) newdata->alloc = alloc; file->data = newdata; - file->decided = 1; } void diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c index a553065..d2eebcf 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 50% and find the next prime number. */ - elem_size = next_prime (elem_size + (elem_size >> 1)); + /* Add 40% and find the next prime number. */ + elem_size = next_prime (elem_size * 1.4); /* 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/locale/programs/locale.c b/locale/programs/locale.c index 0e2e3e4..86941e4 100644 --- a/locale/programs/locale.c +++ b/locale/programs/locale.c @@ -173,9 +173,6 @@ 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 @@ -189,8 +186,10 @@ main (int argc, char *argv[]) /* Set locale. Do not set LC_ALL because the other categories must not be affected (according to POSIX.2). */ - try_setlocale (LC_CTYPE, "LC_CTYPE"); - try_setlocale (LC_MESSAGES, "LC_MESSAGES"); + 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")); /* Initialize the message catalog. */ textdomain (PACKAGE); @@ -201,8 +200,9 @@ main (int argc, char *argv[]) /* `-a' requests the names of all available locales. */ if (do_all != 0) { - setlocale_diagnostics (); - try_setlocale (LC_COLLATE, "LC_COLLATE"); + if (setlocale (LC_COLLATE, "") == NULL) + error (0, errno, + gettext ("Cannot set LC_COLLATE to default locale")); write_locales (); exit (EXIT_SUCCESS); } @@ -211,15 +211,14 @@ 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. */ - try_setlocale (LC_ALL, "LC_ALL"); - setlocale_diagnostics (); + if (setlocale (LC_ALL, "") == NULL) + error (0, errno, gettext ("Cannot set LC_ALL to default locale")); /* If no real argument is given we have to print the contents of the current locale definition variables. These are LANG and the LC_*. */ @@ -984,121 +983,3 @@ 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/programs/locarchive.c b/locale/programs/locarchive.c index dec7326..ca332a3 100644 --- a/locale/programs/locarchive.c +++ b/locale/programs/locarchive.c @@ -281,9 +281,9 @@ oldlocrecentcmp (const void *a, const void *b) /* forward decls for below */ static uint32_t add_locale (struct locarhandle *ah, const char *name, locale_data_t data, bool replace); -void add_alias (struct locarhandle *ah, const char *alias, - bool replace, const char *oldname, - uint32_t *locrec_offset_p); +static void add_alias (struct locarhandle *ah, const char *alias, + bool replace, const char *oldname, + uint32_t *locrec_offset_p); static bool @@ -695,7 +695,7 @@ close_archive (struct locarhandle *ah) #include "../../intl/explodename.c" #include "../../intl/l10nflist.c" -struct namehashent * +static struct namehashent * insert_name (struct locarhandle *ah, const char *name, size_t name_len, bool replace) { @@ -756,7 +756,7 @@ insert_name (struct locarhandle *ah, return &namehashtab[idx]; } -void +static void add_alias (struct locarhandle *ah, const char *alias, bool replace, const char *oldname, uint32_t *locrec_offset_p) { diff --git a/locale/tst-locale-locpath.sh b/locale/tst-locale-locpath.sh deleted file mode 100644 index b83de90..0000000 --- a/locale/tst-locale-locpath.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/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" < -.. - - -.. - - -.. - - -.. - - -.. - - -.. - -UNDEFINED -order_end -END LC_COLLATE - -LC_MONETARY -% This is the 14652 i18n fdcc-set definition for -% the LC_MONETARY category -% (except for the int_curr_symbol and currency_symbol, they are empty in -% the 14652 i18n fdcc-set definition and also empty in -% glibc/locale/C-monetary.c. But localedef complains in that case). -% -% Using "USD" for int_curr_symbol. But maybe "XXX" would be better? -% XXX is "No currency" (https://en.wikipedia.org/wiki/ISO_4217) -int_curr_symbol "" -% Using "$" for currency_symbol. But maybe would be better? -% U+00A4 is the "generic currency symbol" -% (https://en.wikipedia.org/wiki/Currency_sign_%28typography%29) -currency_symbol "" -mon_decimal_point "" -mon_thousands_sep "" -mon_grouping -1 -positive_sign "" -negative_sign "" -int_frac_digits -1 -frac_digits -1 -p_cs_precedes -1 -int_p_sep_by_space -1 -p_sep_by_space -1 -n_cs_precedes -1 -int_n_sep_by_space -1 -n_sep_by_space -1 -p_sign_posn -1 -n_sign_posn -1 -% -END LC_MONETARY - -LC_NUMERIC -% This is the POSIX Locale definition for -% the LC_NUMERIC category. -% -decimal_point "" -thousands_sep "" -grouping -1 -END LC_NUMERIC - -LC_TIME -% This is the POSIX Locale definition for -% the LC_TIME category. -% -% Abbreviated weekday names (%a) -abday "";"";/ - "";"";/ - "";"";/ - "" - -% Full weekday names (%A) -day "";/ - "";/ - "";/ - "";/ - "";/ - "";/ - "" - -% Abbreviated month names (%b) -abmon "";"";/ - "";"";/ - "";"";/ - "";"";/ - "";"";/ - "";"" - -% Full month names (%B) -mon "";/ - "";/ - "";/ - "";/ - "";/ - "";/ - "";/ - "";/ - "";/ - "";/ - "";/ - "" - -% Week description, consists of three fields: -% 1. Number of days in a week. -% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday). -% 3. The weekday number to be contained in the first week of the year. -% -% ISO 8601 conforming applications should use the values 7, 19971201 (a -% Monday), and 4 (Thursday), respectively. -week 7;19971201;4 -first_weekday 1 -first_workday 1 - -% Appropriate date and time representation (%c) -% "%a %b %e %H:%M:%S %Y" -d_t_fmt "" - -% Appropriate date representation (%x) -% "%m/%d/%y" -d_fmt "" - -% Appropriate time representation (%X) -% "%H:%M:%S" -t_fmt "" - -% Appropriate AM/PM time representation (%r) -% "%I:%M:%S %p" -t_fmt_ampm "" - -% Equivalent of AM/PM (%p) "AM"/"PM" -% -am_pm "";"" - -% Appropriate date representation (date(1)) "%a %b %e %H:%M:%S %Z %Y" -date_fmt "" -END LC_TIME - -LC_MESSAGES -% This is the POSIX Locale definition for -% the LC_NUMERIC category. -% -yesexpr "" -noexpr "" -yesstr "" -nostr "" -END LC_MESSAGES - -LC_PAPER -% This is the ISO/IEC 14652 "i18n" definition for -% the LC_PAPER category. -% (A4 paper, this is also used in the built in C/POSIX -% locale in glibc/locale/C-paper.c) -height 297 -width 210 -END LC_PAPER - -LC_NAME -% This is the ISO/IEC 14652 "i18n" definition for -% the LC_NAME category. -% "%p%t%g%t%m%t%f" -% (also used in the built in C/POSIX locale in glibc/locale/C-name.c) -name_fmt "/ -" -END LC_NAME - -LC_ADDRESS -% This is the ISO/IEC 14652 "i18n" definition for -% the LC_ADDRESS category. -% "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" -% (also used in the built in C/POSIX locale in glibc/locale/C-address.c) -postal_fmt "/ -/ -/ -/ -" -END LC_ADDRESS - -LC_TELEPHONE -% This is the ISO/IEC 14652 "i18n" definition for -% the LC_TELEPHONE category. -% "+%c %a %l" -tel_int_fmt "/ -" -% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c) -END LC_TELEPHONE - -LC_MEASUREMENT -% This is the ISO/IEC 14652 "i18n" definition for -% the LC_MEASUREMENT category. -% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c) -%metric -measurement 1 -END LC_MEASUREMENT - diff --git a/localedata/locales/az_AZ b/localedata/locales/az_AZ index 3c0db0b..6fe8839 100644 --- a/localedata/locales/az_AZ +++ b/localedata/locales/az_AZ @@ -243,7 +243,7 @@ country_ab3 "AZE" country_num 031 country_car "AZ" % Azərbaycanca -lang_name "azrbaycan" +lang_name "azrbaycan dili" lang_ab "az" lang_term "aze" lang_lib "aze" diff --git a/localedata/locales/be_BY@latin b/localedata/locales/be_BY@latin index fef339f..43b13cc 100644 --- a/localedata/locales/be_BY@latin +++ b/localedata/locales/be_BY@latin @@ -156,7 +156,7 @@ country_ab2 "BY" country_ab3 "BLR" country_num 112 country_car "BY" -lang_name "biearuskaja" +lang_name "biearuskaja mova" lang_ab "be" lang_term "bel" lang_lib "bel" diff --git a/localedata/locales/ber_DZ b/localedata/locales/ber_DZ index 4fa1bdf..79f3d28 100644 --- a/localedata/locales/ber_DZ +++ b/localedata/locales/ber_DZ @@ -8,7 +8,7 @@ escape_char / % exempt you from the conditions of the license if your use would % otherwise be governed by that license. -% Berber Language Locale for Algeria (latin) +% Amazigh Language Locale for Algeria (latin) % Source: % Contact: Pablo Saratxaga % Email: @@ -20,14 +20,14 @@ escape_char / % Users: general LC_IDENTIFICATION -title "Berber language locale for Algeria (latin)" +title "Amazigh language locale for Algeria (latin)" source "" address "" contact "Pablo Saratxaga" email "pablo@mandrakesoft.com" tel "" fax "" -language "Berber" +language "Amazigh" territory "Algeria" revision "0.1" date "2002-04-16" @@ -253,15 +253,14 @@ LC_ADDRESS % This is the ISO_IEC TR14652 Locale definition for the % LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" -country_name "Lezzayer" %country_post "" country_ab2 "DZ" country_ab3 "DZA" country_num 012 %country_isbn "" country_car "DZ" -% Tamaziɣt -lang_name "Tamazit" +% ⵜⴰⵎⴰⵣⵉⵖⵜ +lang_name "" %lang_ab lang_term "ber" lang_lib "ber" diff --git a/localedata/locales/ber_MA b/localedata/locales/ber_MA index 5d19354..b9bd648 100644 --- a/localedata/locales/ber_MA +++ b/localedata/locales/ber_MA @@ -8,7 +8,7 @@ escape_char / % exempt you from the conditions of the license if your use would % otherwise be governed by that license. -% Berber Language Locale for Morocco (tifinagh) +% Amazigh Language Locale for Morocco (tifinagh) % Source: % Contact: Pablo Saratxaga % Email: @@ -20,14 +20,14 @@ escape_char / % Users: general LC_IDENTIFICATION -title "Berber language locale for Morocco (tifinagh)" +title "Amazigh language locale for Morocco (tifinagh)" source "" address "" contact "Pablo Saratxaga" email "pablo@mandrakesoft.com" tel "" fax "" -language "Berber" +language "Amazigh" territory "Morocco" revision "0.1" date "2002-06-26" @@ -204,8 +204,6 @@ LC_ADDRESS % This is the ISO_IEC TR14652 Locale definition for the % LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" -% https://en.wikipedia.org/wiki/Morocco ⵜⴰⴳⵍⴷⵉⵜ ⵏ ⵍⵎⵖⵔⵉⴱ -country_name " " %country_post "" country_ab2 "MA" country_ab3 "MAR" @@ -213,7 +211,7 @@ country_num 504 %country_isbn "" country_car "MA" % ⵜⴰⵎⴰⵣⵉⵖⵜ -lang_name "" +lang_name "" % lang_ab lang_term "ber" lang_lib "ber" diff --git a/localedata/locales/bhb_IN b/localedata/locales/bhb_IN index 80d590d..549974d 100644 --- a/localedata/locales/bhb_IN +++ b/localedata/locales/bhb_IN @@ -145,13 +145,11 @@ LC_ADDRESS % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category % generated by IBM Basic CountryPack Transformer. postal_fmt "%z%c%T%s%b%e%r" -country_name "" country_ab2 "IN" country_ab3 "IND" country_car "IND" country_num 356 -% भीली -lang_name "" +lang_name "bhili" lang_ab "" lang_term "bhb" lang_lib "bhb" diff --git a/localedata/locales/bho_IN b/localedata/locales/bho_IN index 4a0f25d..99a91c2 100644 --- a/localedata/locales/bho_IN +++ b/localedata/locales/bho_IN @@ -147,7 +147,6 @@ END LC_NAME LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" -country_name "" country_ab2 "IN" country_ab3 "IND" country_num 356 diff --git a/localedata/locales/chr_US b/localedata/locales/chr_US index 86868c0..290d1b2 100644 --- a/localedata/locales/chr_US +++ b/localedata/locales/chr_US @@ -113,7 +113,7 @@ END LC_NAME LC_ADDRESS postal_fmt "%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N" -country_name "" +country_name "" country_post "USA" country_ab2 "US" country_ab3 "USA" diff --git a/localedata/locales/crh_UA b/localedata/locales/crh_UA index 86281a2..b2ac8c6 100644 --- a/localedata/locales/crh_UA +++ b/localedata/locales/crh_UA @@ -198,8 +198,8 @@ country_ab2 "UA" country_ab3 "UKR" country_num 804 country_car "UA" -% qırımtatar tili -lang_name "qrmtatar tili" +% Qırımtatarca +lang_name "Qrmtatarca" lang_term "crh" lang_lib "crh" END LC_ADDRESS diff --git a/localedata/locales/csb_PL b/localedata/locales/csb_PL index 662dcef..c8572f8 100644 --- a/localedata/locales/csb_PL +++ b/localedata/locales/csb_PL @@ -210,7 +210,6 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -country_name "Plsk" country_ab2 "PL" country_ab3 "POL" country_num 616 diff --git a/localedata/locales/doi_IN b/localedata/locales/doi_IN index df9dfc6..0428ae5 100644 --- a/localedata/locales/doi_IN +++ b/localedata/locales/doi_IN @@ -156,7 +156,6 @@ END LC_NAME LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" -country_name "" country_ab2 "IN" country_ab3 "IND" country_num 356 diff --git a/localedata/locales/dv_MV b/localedata/locales/dv_MV index ab78fa5..0d7842f 100644 --- a/localedata/locales/dv_MV +++ b/localedata/locales/dv_MV @@ -182,8 +182,9 @@ country_ab2 "MV" country_ab3 "MDV" country_num 462 country_car "MV" -% ދިވެހި -lang_name "" +% lang_name FIXME +% Cannot represent Dhivehi in Thaana script +% http://en.wikipedia.org/wiki/Maldivian_language lang_ab "dv" lang_term "div" lang_lib "div" diff --git a/localedata/locales/eo b/localedata/locales/eo index b2ad575..33a8103 100644 --- a/localedata/locales/eo +++ b/localedata/locales/eo @@ -206,7 +206,7 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%%z %T%N%c%N" -lang_name "esperanto" +lang_name "Esperanto" lang_ab "eo" lang_term "epo" END LC_ADDRESS diff --git a/localedata/locales/hak_TW b/localedata/locales/hak_TW index 87f2a00..f62937e 100644 --- a/localedata/locales/hak_TW +++ b/localedata/locales/hak_TW @@ -187,8 +187,8 @@ country_ab3 "TWN" country_num 158 country_car "RC" country_isbn 957 -% 客家語 -lang_name "" +% 漢語客家語 +lang_name "" lang_term "hak" lang_lib "hak" END LC_ADDRESS diff --git a/localedata/locales/hif_FJ b/localedata/locales/hif_FJ index a6868b7..5433bb4 100644 --- a/localedata/locales/hif_FJ +++ b/localedata/locales/hif_FJ @@ -176,8 +176,7 @@ country_car "FJI" country_num 242 % https://en.wikipedia.org/wiki/ISO_3166-1_numeric % https://en.wikipedia.org/wiki/Fiji_Hindi -% फ़िजी बात -lang_name "" +lang_name "Fiji Baat" % iso-639-1 lang_ab "" % iso-639-3 diff --git a/localedata/locales/hne_IN b/localedata/locales/hne_IN index d8b8361..7abec63 100644 --- a/localedata/locales/hne_IN +++ b/localedata/locales/hne_IN @@ -154,7 +154,6 @@ END LC_NAME LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" -country_name "" country_ab2 "IN" country_ab3 "IND" country_num 356 diff --git a/localedata/locales/ia_FR b/localedata/locales/ia_FR index 4ce7c7f..f3fbf21 100644 --- a/localedata/locales/ia_FR +++ b/localedata/locales/ia_FR @@ -127,7 +127,7 @@ country_ab3 "FRA" country_num 250 country_isbn "979-10" country_car "F" -lang_name "interlingua" +lang_name "Interlingua" lang_ab "ia" lang_term "ina" lang_lib "ina" diff --git a/localedata/locales/id_ID b/localedata/locales/id_ID index 92ff81d..3ddd8d0 100644 --- a/localedata/locales/id_ID +++ b/localedata/locales/id_ID @@ -155,7 +155,7 @@ country_ab2 "ID" country_ab3 "IDN" country_num 360 country_car "RI" -lang_name "Indonesia" +lang_name "Bahasa Indonesia" lang_ab "id" lang_term "ind" lang_lib "ind" diff --git a/localedata/locales/ig_NG b/localedata/locales/ig_NG index 113294a..bddd2cc 100644 --- a/localedata/locales/ig_NG +++ b/localedata/locales/ig_NG @@ -321,11 +321,11 @@ LC_ADDRESS % "end of line postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -% Country name in Igbo - "Naịjịrịa" -country_name "Najra" +% Country name in Igbo - "Nigeria" +country_name "Nigeria" -% Language name in Igbo - "Asụsụ Igbo" -lang_name "Ass Igbo" +% Language name in Igbo - "Igbo" +lang_name "Igbo" % CEPT MAILCODES are suggested % Alternatively use the code found on your countries postal item tracking number diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP index 30190b6..1fd2fee 100644 --- a/localedata/locales/ja_JP +++ b/localedata/locales/ja_JP @@ -14946,9 +14946,7 @@ am_pm "";"" t_fmt_ampm "%p%I%M%S" -era "+:2:2020//01//01:+*::%EC%Ey";/ - "+:1:2019//05//01:2019//12//31::%EC";/ - "+:2:1990//01//01:2019//04//30::%EC%Ey";/ +era "+:2:1990//01//01:+*::%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/localedata/locales/kab_DZ b/localedata/locales/kab_DZ index ef57235..a165f53 100644 --- a/localedata/locales/kab_DZ +++ b/localedata/locales/kab_DZ @@ -154,7 +154,7 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -country_name "Lezzayer" +country_name "Zzayer" country_ab2 "DZ" country_ab3 "DZA" country_num 012 diff --git a/localedata/locales/kl_GL b/localedata/locales/kl_GL index 5723ce7..5ab14a3 100644 --- a/localedata/locales/kl_GL +++ b/localedata/locales/kl_GL @@ -70,11 +70,11 @@ copy "da_DK" END LC_NUMERIC LC_TIME -abday "sap";"ata";/ +abday "sab";"ata";/ "mar";"pin";/ "sis";"tal";/ "arf" -day "sapaat";/ +day "sabaat";/ "ataasinngorneq";/ "marlunngorneq";/ "pingasunngorneq";/ diff --git a/localedata/locales/ks_IN b/localedata/locales/ks_IN index e1efea3..6992a55 100644 --- a/localedata/locales/ks_IN +++ b/localedata/locales/ks_IN @@ -167,7 +167,7 @@ LC_ADDRESS % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category % generated by IBM Basic CountryPack Transformer. postal_fmt "%z%c%T%s%b%e%r" -country_name "" +country_name "" country_ab2 "IN" country_ab3 "IND" country_num 356 diff --git a/localedata/locales/ku_TR b/localedata/locales/ku_TR index f6a8925..595cdb1 100644 --- a/localedata/locales/ku_TR +++ b/localedata/locales/ku_TR @@ -182,14 +182,14 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" % TODO -country_name "Tirkiye" +country_name "Turkey" country_post "TR" country_ab2 "TR" country_ab3 "TUR" country_num 792 country_isbn 975 country_car "TR" -lang_name "kurd" +lang_name "kurdi" lang_ab "ku" lang_term "kur" lang_lib "kur" diff --git a/localedata/locales/mag_IN b/localedata/locales/mag_IN index c86d9ba..b8f65f7 100644 --- a/localedata/locales/mag_IN +++ b/localedata/locales/mag_IN @@ -152,7 +152,6 @@ END LC_NAME LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" -country_name "" country_ab2 "IN" country_ab3 "IND" country_num 356 diff --git a/localedata/locales/mfe_MU b/localedata/locales/mfe_MU index 7fabc5f..7415e92 100644 --- a/localedata/locales/mfe_MU +++ b/localedata/locales/mfe_MU @@ -170,7 +170,7 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%h%s%N%T" -country_name "Moris" +country_name "Mauritius" country_ab2 "MU" country_ab3 "MUS" country_num 480 diff --git a/localedata/locales/mhr_RU b/localedata/locales/mhr_RU index 02bec3e..85ac21b 100644 --- a/localedata/locales/mhr_RU +++ b/localedata/locales/mhr_RU @@ -159,8 +159,6 @@ country_ab2 "RU" country_ab3 "RUS" country_num 643 country_car "RUS" -% марий йылме -lang_name " " lang_term "mhr" lang_lib "mhr" END LC_ADDRESS diff --git a/localedata/locales/mi_NZ b/localedata/locales/mi_NZ index d08bc24..782f023 100644 --- a/localedata/locales/mi_NZ +++ b/localedata/locales/mi_NZ @@ -157,7 +157,7 @@ country_ab2 "NZ" country_ab3 "NZL" country_num 554 country_car "NZ" -lang_name "Mori" +lang_name "Te Reo" lang_ab "mi" lang_term "mri" lang_lib "mao" diff --git a/localedata/locales/ms_MY b/localedata/locales/ms_MY index 8ffe915..66b5dd9 100644 --- a/localedata/locales/ms_MY +++ b/localedata/locales/ms_MY @@ -184,7 +184,7 @@ country_ab3 "MYS" country_num 458 country_car "MAL" % Bahasa Melayu -lang_name "Melayu" +lang_name "Bahasa Melayu" lang_ab "ms" lang_term "msa" lang_lib "may" diff --git a/localedata/locales/my_MM b/localedata/locales/my_MM index 8463632..d612e53 100644 --- a/localedata/locales/my_MM +++ b/localedata/locales/my_MM @@ -309,8 +309,7 @@ country_ab2 "MM" country_num 104 country_car "MYA" lang_ab "my" -% မြန်မာ -lang_name "" +lang_name "" lang_term "mya" lang_lib "bur" END LC_ADDRESS diff --git a/localedata/locales/nan_TW b/localedata/locales/nan_TW index 53884e0..f5bc5d1 100644 --- a/localedata/locales/nan_TW +++ b/localedata/locales/nan_TW @@ -188,8 +188,8 @@ country_ab3 "TWN" country_num 158 country_car "RC" country_isbn 957 -% 閩南語 -lang_name "" +% 漢語閩南語 +lang_name "" lang_term "nan" lang_lib "nan" END LC_ADDRESS diff --git a/localedata/locales/nan_TW@latin b/localedata/locales/nan_TW@latin index 104f415..d4579a4 100644 --- a/localedata/locales/nan_TW@latin +++ b/localedata/locales/nan_TW@latin @@ -165,8 +165,8 @@ country_ab3 "TWN" country_num 158 country_car "RC" country_isbn 957 -%lang_name "Bân-lâm-gú" -lang_name "Bn-lm-g" +%lang_name "Bân-lâm-gú, Hō-ló-oē" +lang_name "Bn-lm-g, H-l-o" lang_term "nan" lang_lib "nan" END LC_ADDRESS diff --git a/localedata/locales/nds_DE b/localedata/locales/nds_DE index d6200b7..232f9e4 100644 --- a/localedata/locales/nds_DE +++ b/localedata/locales/nds_DE @@ -45,7 +45,7 @@ country_ab3 "DEU" country_car "D" country_num 276 country_isbn "3" -lang_name "Neddersasssch" +lang_name "Neddersassisch" %lang_ab lang_term "nds" lang_lib "nds" diff --git a/localedata/locales/nds_NL b/localedata/locales/nds_NL index 9fd50fb..8c8bebd 100644 --- a/localedata/locales/nds_NL +++ b/localedata/locales/nds_NL @@ -44,7 +44,7 @@ country_ab3 "NLD" country_car "NL" country_num 528 country_isbn "3" -lang_name "Neddersasssch" +lang_name "Neddersassisch" %lang_ab lang_term "nds" lang_lib "nds" diff --git a/localedata/locales/nhn_MX b/localedata/locales/nhn_MX index 2dbfcb3..88a8976 100644 --- a/localedata/locales/nhn_MX +++ b/localedata/locales/nhn_MX @@ -133,12 +133,11 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -country_name "Mexihco" country_ab2 "MX" country_ab3 "MEX" country_num 484 country_car "MEX" -lang_name "Tlahco nhuatlahtlli" +lang_name "Tlaxcala-Puebla Nahuatl" lang_term "nhn" lang_lib "nhn" END LC_ADDRESS diff --git a/localedata/locales/niu_NU b/localedata/locales/niu_NU index 387e109..553c5d9 100644 --- a/localedata/locales/niu_NU +++ b/localedata/locales/niu_NU @@ -163,12 +163,10 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -country_name "Niu" country_post "NU" country_ab2 "NU" country_ab3 "NIU" country_num 570 -lang_name "ko e vagahau Niu" lang_term "niu" lang_lib "niu" END LC_ADDRESS diff --git a/localedata/locales/niu_NZ b/localedata/locales/niu_NZ index 2eba7d2..560101b 100644 --- a/localedata/locales/niu_NZ +++ b/localedata/locales/niu_NZ @@ -99,7 +99,6 @@ country_ab2 "NZ" country_ab3 "NZL" country_num 554 country_car "NZ" -lang_name "ko e vagahau Niu" lang_term "niu" lang_lib "niu" END LC_ADDRESS diff --git a/localedata/locales/nr_ZA b/localedata/locales/nr_ZA index f64434f..7de6420 100644 --- a/localedata/locales/nr_ZA +++ b/localedata/locales/nr_ZA @@ -225,7 +225,7 @@ country_car "ZA" country_num 710 % Language name in Southern Ndebele -lang_name "isiNdebele" +lang_name "IsiNdebele" % ISO 639 two and three letter language names % see http://www.loc.gov/standards/iso639-2/englangn.html diff --git a/localedata/locales/oc_FR b/localedata/locales/oc_FR index a106f8d..707927e 100644 --- a/localedata/locales/oc_FR +++ b/localedata/locales/oc_FR @@ -44,7 +44,7 @@ country_ab3 "FRA" country_num 250 country_isbn "979-10" country_car "F" -lang_name "occitan" +lang_name "Occitan" lang_ab "oc" lang_term "oci" lang_lib "oci" diff --git a/localedata/locales/or_IN b/localedata/locales/or_IN index 2e4975e..ef28b58 100644 --- a/localedata/locales/or_IN +++ b/localedata/locales/or_IN @@ -20,7 +20,7 @@ contact "" email "bug-glibc@gnu.org" tel "" fax "" -language "Odia" +language "Oriya" territory "India" revision "1.0" date "2006-05-25" diff --git a/localedata/locales/pa_PK b/localedata/locales/pa_PK index 0a58411..1f49bdc 100644 --- a/localedata/locales/pa_PK +++ b/localedata/locales/pa_PK @@ -173,7 +173,7 @@ END LC_NAME LC_ADDRESS % FIXME postal_fmt "%a%N%f%N%d%N%b%N%h %s %e %r%N%T %z%N%c%N" -country_name "" +country_name "" country_ab2 "PK" country_ab3 "PAK" country_num 586 diff --git a/localedata/locales/ps_AF b/localedata/locales/ps_AF index 23dc86d..66f560e 100644 --- a/localedata/locales/ps_AF +++ b/localedata/locales/ps_AF @@ -308,7 +308,8 @@ END LC_NAME LC_ADDRESS postal_fmt "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" -country_name "" +country_name "/ +" country_post "AF" country_ab2 "AF" country_ab3 "AFG" diff --git a/localedata/locales/quz_PE b/localedata/locales/quz_PE index 9ed890c..f6b1956 100644 --- a/localedata/locales/quz_PE +++ b/localedata/locales/quz_PE @@ -10,7 +10,7 @@ escape_char / %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% Cusco Quechua language locale for Peru +% Quechua (Cusco-Collao) language locale for Peru % % Prepared and contributed to glibc by Chris Leonard % and Amos Batto @@ -25,14 +25,14 @@ escape_char / %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LC_IDENTIFICATION -title "Cusco Quechua locale for Peru" +title "Quechua (Cusco-Collao) locale for Peru" source "Sugar Labs // OLPC" address "" contact "sugarlabs.org" email "libc-alpha@sourceware.org" tel "" fax "" -language "Cusco Quechua" +language "Quechua (Cusco-Collao)" territory "Peru" revision "1.0" date "2013-08-24" @@ -144,7 +144,7 @@ country_ab2 "PE" country_ab3 "PER" country_num 604 country_car "PE" -lang_name "Qusqu runasimi" +lang_name "Quechua (Cusco)" lang_term "quz" lang_lib "quz" END LC_ADDRESS diff --git a/localedata/locales/raj_IN b/localedata/locales/raj_IN index ce009e4..ece0802 100644 --- a/localedata/locales/raj_IN +++ b/localedata/locales/raj_IN @@ -158,16 +158,7 @@ name_ms "" END LC_NAME LC_ADDRESS -postal_fmt "%z%c%T%s%b%e%r" -country_name "" -country_ab2 "IN" -country_ab3 "IND" -country_num 356 -country_car "IND" -% राजस्थानी -lang_name "" -lang_term "raj" -lang_lib "raj" +copy "hi_IN" END LC_ADDRESS LC_TELEPHONE diff --git a/localedata/locales/rw_RW b/localedata/locales/rw_RW index 31cb467..e0bc763 100644 --- a/localedata/locales/rw_RW +++ b/localedata/locales/rw_RW @@ -132,7 +132,7 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -country_name "U Rwanda" +country_name "Rwanda" country_ab2 "RW" country_ab3 "RWA" country_num 646 diff --git a/localedata/locales/sah_RU b/localedata/locales/sah_RU index 2b5a4b7..80f6721 100644 --- a/localedata/locales/sah_RU +++ b/localedata/locales/sah_RU @@ -1,7 +1,7 @@ escape_char / comment_char % -% Sakha (Yakut) locale for Russian Federation +% Yakut (Sakha) locale for Russian Federation % Source: Valery Timiriliyev % Email: timiriliyev@gmail.com % Tel: @@ -13,14 +13,14 @@ comment_char % % Users: general LC_IDENTIFICATION -title "Sakha (Yakut) locale for Russian Federation" +title "Yakut (Sakha) locale for Russian Federation" source "Valery Timiriliyev" address "" contact "Valery Timiriliyev" email "timiriliyev@gmail.com" tel "" fax "" -language "Sakha" +language "Yakut" territory "Russian Federation" revision "1.1.0" date "2018-07-06" @@ -264,11 +264,11 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -% Арассыыйа -country_name "" +% Россия +country_name "" -% саха тыла -lang_name "" +% Саха тыла +lang_name " " % UN Geneve 1949:68 Distinguishing signs of vehicles in international traffic % RUS diff --git a/localedata/locales/sat_IN b/localedata/locales/sat_IN index e1775a4..134eb8a 100644 --- a/localedata/locales/sat_IN +++ b/localedata/locales/sat_IN @@ -158,13 +158,12 @@ END LC_NAME LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" -country_name "" country_ab2 "IN" country_ab3 "IND" country_num 356 country_car "IND" -% ᱥᱟᱱᱛᱟᱲᱤ -lang_name "" +% Satār +lang_name "Satr" lang_term "sat" lang_lib "sat" END LC_ADDRESS diff --git a/localedata/locales/sc_IT b/localedata/locales/sc_IT index 3262640..1488744 100644 --- a/localedata/locales/sc_IT +++ b/localedata/locales/sc_IT @@ -144,7 +144,7 @@ country_ab3 "ITA" country_num 380 country_isbn "978-88,979-12" country_car "I" -lang_name "sardu" +lang_name "Sardu" lang_ab "sc" lang_term "srd" lang_lib "srd" diff --git a/localedata/locales/sd_IN b/localedata/locales/sd_IN index 64c5366..66aa0e2 100644 --- a/localedata/locales/sd_IN +++ b/localedata/locales/sd_IN @@ -164,14 +164,12 @@ LC_ADDRESS % This is the ISO_IEC TR14652 Locale definition for the LC_ADDRESS category % generated by IBM Basic CountryPack Transformer. postal_fmt "%z%c%T%s%b%e%r" -% From cldr: انڊيا -country_name "" +% https://sd.wikipedia.org/wiki/%DA%80%D8%A7%D8%B1%D8%AA : "ڀارت" +country_name "" country_ab2 "IN" country_ab3 "IND" country_num 356 country_car "IND" -% سنڌي -lang_name "" lang_ab "sd" lang_term "snd" lang_lib "snd" diff --git a/localedata/locales/sd_IN@devanagari b/localedata/locales/sd_IN@devanagari index 97357e0..b1ce87d 100644 --- a/localedata/locales/sd_IN@devanagari +++ b/localedata/locales/sd_IN@devanagari @@ -167,8 +167,6 @@ country_ab2 "IN" country_ab3 "IND" country_num 356 country_car "IND" -% सिन्धी -lang_name "" lang_ab "sd" lang_term "snd" lang_lib "snd" diff --git a/localedata/locales/shn_MM b/localedata/locales/shn_MM index a837f5f..4212c50 100644 --- a/localedata/locales/shn_MM +++ b/localedata/locales/shn_MM @@ -281,8 +281,7 @@ END LC_NAME LC_ADDRESS postal_fmt "%a%N%d%N%f%N%b%N%h%t%r%t%e%t%s%N%T%t%z%N%c%N" -% https://shn.wikipedia.org/wiki/%E1%80%99%E1%80%AD%E1%80%B0%E1%80%84%E1%80%BA%E1%80%B8%E1%80%99%E1%81%A2%E1%81%BC%E1%80%BA%E1%82%88 မိူင်းမၢၼ်ႈ -country_name "" +country_name "" country_post "Myanmar" country_ab2 "MM" country_num 104 diff --git a/localedata/locales/shs_CA b/localedata/locales/shs_CA index ab48d60..a5b675a 100644 --- a/localedata/locales/shs_CA +++ b/localedata/locales/shs_CA @@ -8,7 +8,7 @@ escape_char / % exempt you from the conditions of the license if your use would % otherwise be governed by that license. -% Shuswap language locale for Canada +% Secwepemctsin (Shuswap) language locale for Canada % sorting according to CAN/CSA-Z243.4.1-1992 % Source: Neskie Manuel % Address: 745 Ska-Hiish Dr @@ -25,14 +25,14 @@ escape_char / % Users: general LC_IDENTIFICATION -title "Shuswap locale for Canada" +title "Secwepemctsin locale for Canada" source "Neskie Manuel" address "745 Ska-Hiish Dr, Chase BC V0E 1M3" contact "" email "bug-glibc-locales@gnu.org" tel "" fax "" -language "Shuswap" +language "Secwepemctsin" territory "Canada" revision "1.0" date "2008-01-15" @@ -155,7 +155,7 @@ country_ab2 "CA" country_ab3 "CAN" country_num 124 country_car "CDN" -lang_name "Secwepemctsn" +lang_name "Secwepemctsin" lang_term "shs" lang_lib "shs" END LC_ADDRESS diff --git a/localedata/locales/sm_WS b/localedata/locales/sm_WS index 2823005..6058fbd 100644 --- a/localedata/locales/sm_WS +++ b/localedata/locales/sm_WS @@ -159,7 +159,7 @@ END LC_NAME LC_ADDRESS postal_fmt "%a%N%f%N%d%N%b%N%h %s %e %r%N%T, %S %z%N%c%N" -country_name "Smoa" +country_name "Samoa" country_post "%a %N %f %N %d %N %b %N %h %s %e %/ r %N %T, %c %N" % http://laendercode.net/en/2-letter-list.html diff --git a/localedata/locales/ss_ZA b/localedata/locales/ss_ZA index 8e08a85..7532a19 100644 --- a/localedata/locales/ss_ZA +++ b/localedata/locales/ss_ZA @@ -228,7 +228,7 @@ country_car "ZA" % country_isbn "" % Language name in Swati -lang_name "siSwati" +lang_name "SiSwati" % ISO 639 two and three letter language names % see http://www.loc.gov/standards/iso639-2/englangn.html diff --git a/localedata/locales/szl_PL b/localedata/locales/szl_PL index 88f1df4..8d5de21 100644 --- a/localedata/locales/szl_PL +++ b/localedata/locales/szl_PL @@ -188,7 +188,6 @@ END LC_NAME LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -country_name "Polska" country_ab2 "PL" country_ab3 "POL" country_num 616 diff --git a/localedata/locales/te_IN b/localedata/locales/te_IN index cb1b110..fb5bb21 100644 --- a/localedata/locales/te_IN +++ b/localedata/locales/te_IN @@ -177,7 +177,7 @@ LC_ADDRESS % generated by IBM Basic CountryPack Transformer. postal_fmt "%a%N%d%N%f%N%r%t%e%N%h%t%b%N%s%t%N%T%t%z%N%S%N%c" -country_name "" +country_name " " country_ab2 "IN" country_ab3 "IND" country_num 356 diff --git a/localedata/locales/tg_TJ b/localedata/locales/tg_TJ index 6d1e4d8..35dfca4 100644 --- a/localedata/locales/tg_TJ +++ b/localedata/locales/tg_TJ @@ -222,8 +222,6 @@ country_ab2 "TJ" country_ab3 "TJK" country_num 762 country_car "TJ" -% тоҷикӣ -lang_name "" lang_ab "tg" lang_term "tgk" lang_lib "tgk" diff --git a/localedata/locales/the_NP b/localedata/locales/the_NP index 296e997..993e62f 100644 --- a/localedata/locales/the_NP +++ b/localedata/locales/the_NP @@ -162,14 +162,10 @@ LC_ADDRESS postal_fmt "%z%c%T%s%b%e%r" lang_term "the" lang_lib "the" -% नेपाल -country_name "" country_ab2 "NP" country_ab3 "NPL" country_num 524 country_car "NEP" -% थारु -lang_name "" END LC_ADDRESS diff --git a/localedata/locales/tk_TM b/localedata/locales/tk_TM index e29ae20..410afaf 100644 --- a/localedata/locales/tk_TM +++ b/localedata/locales/tk_TM @@ -399,7 +399,7 @@ country_num 795 country_ab2 "TM" country_ab3 "TKM" % Türkmençe -lang_name "trkmen dili" +lang_name "trkmene" lang_term "tuk" lang_lib "tuk" lang_ab "tk" diff --git a/localedata/locales/tl_PH b/localedata/locales/tl_PH index 03b8350..40fd71d 100644 --- a/localedata/locales/tl_PH +++ b/localedata/locales/tl_PH @@ -138,7 +138,6 @@ country_ab2 "PH" country_ab3 "PHL" country_num 608 country_car "RP" -lang_name "Tagalog" lang_ab "tl" lang_term "tgl" lang_lib "tgl" diff --git a/localedata/locales/to_TO b/localedata/locales/to_TO index 403a121..7abe868 100644 --- a/localedata/locales/to_TO +++ b/localedata/locales/to_TO @@ -169,7 +169,7 @@ country_ab3 "TON" country_car "TON" country_num 776 % Tongan -lang_name "lea fakatonga" +lang_name "Tonga" % https://en.wikipedia.org/wiki/Tongan_language lang_ab "to" lang_term "ton" diff --git a/localedata/locales/tpi_PG b/localedata/locales/tpi_PG index 8854819..3315c27 100644 --- a/localedata/locales/tpi_PG +++ b/localedata/locales/tpi_PG @@ -172,8 +172,7 @@ END LC_NAME LC_ADDRESS % http://www.addressexamples.com/papua-new-guinea-address-format/ postal_fmt "%a%s%z%C" -% https://tpi.wikipedia.org/wiki/Papua_Niugini -country_name "Papua Niugini" +country_name "Papua New Guinea" country_post "" country_ab2 "PG" country_ab3 "PNG" @@ -181,7 +180,7 @@ country_car "PNG" % https://en.wikipedia.org/wiki/ISO_3166-1_numeric country_num 598 % Tok Pisin -lang_name "Tok Pisin" +lang_name "Tok Pisin" % https://en.wikipedia.org/wiki/Tok_Pisin lang_ab "" lang_term "tpi" diff --git a/localedata/locales/tt_RU@iqtelif b/localedata/locales/tt_RU@iqtelif index b52b129..d4737c8 100644 --- a/localedata/locales/tt_RU@iqtelif +++ b/localedata/locales/tt_RU@iqtelif @@ -155,12 +155,10 @@ END LC_MEASUREMENT LC_ADDRESS postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -country_name "Urs Patahlq" country_ab2 "RU" country_ab3 "RUS" country_num 643 country_car "RUS" -lang_name "tatar tele" lang_ab "tt" lang_term "tat" lang_lib "tat" diff --git a/localedata/locales/ug_CN b/localedata/locales/ug_CN index acb8b68..1ba583c 100644 --- a/localedata/locales/ug_CN +++ b/localedata/locales/ug_CN @@ -195,8 +195,6 @@ country_ab3 "CHN" country_num 156 country_car "CHN" country_isbn 7 -% ئۇيغۇرچە -lang_name "" lang_ab "ug" lang_term "uig" lang_lib "uig" diff --git a/localedata/locales/unm_US b/localedata/locales/unm_US index ef458e2..1e62c60 100644 --- a/localedata/locales/unm_US +++ b/localedata/locales/unm_US @@ -139,7 +139,7 @@ country_ab3 "USA" country_num 840 country_car "USA" country_isbn 0 -lang_name "Lenape" +% lang_name "" % lang_ab "" lang_term "unm" lang_lib "unm" diff --git a/localedata/locales/wa_BE b/localedata/locales/wa_BE index afec10f..e974930 100644 --- a/localedata/locales/wa_BE +++ b/localedata/locales/wa_BE @@ -44,7 +44,7 @@ country_ab3 "BEL" country_num 056 country_isbn "2" country_car "B" -lang_name "walon" +lang_name "Walon" lang_ab "wa" lang_term "wln" lang_lib "wln" diff --git a/localedata/locales/wo_SN b/localedata/locales/wo_SN index 2019092..47263d2 100644 --- a/localedata/locales/wo_SN +++ b/localedata/locales/wo_SN @@ -161,7 +161,6 @@ country_ab2 "SN" country_ab3 "SEN" country_num 686 country_car "SN" -lang_name "Wolof" lang_ab "wo" lang_term "wol" lang_lib "wol" diff --git a/localedata/locales/xh_ZA b/localedata/locales/xh_ZA index 327f725..4564137 100644 --- a/localedata/locales/xh_ZA +++ b/localedata/locales/xh_ZA @@ -209,13 +209,13 @@ END LC_NAME LC_ADDRESS % https://xh.wikipedia.org/wiki/UMzantsi_Afrika -country_name "uMzantsi Afrika" +country_name "UMzantsi Afrika" % % Abbreviated country postal name country_post "ZA" % % Language name in Sotho -lang_name "isiXhosa" +lang_name "IsiXhosa" % UN Geneve 1949:68 Distinguishing signs of vehicles in international traffic % http://www.unece.org/trans/conventn/disting-signs-5-2001.pdf diff --git a/localedata/locales/yo_NG b/localedata/locales/yo_NG index a310227..ec72d07 100644 --- a/localedata/locales/yo_NG +++ b/localedata/locales/yo_NG @@ -271,8 +271,8 @@ LC_ADDRESS % "country designation for the keyword", % "end of line postal_fmt "%f%N%a%N%d%N%b%N%s %h %e %r%N%z %T%N%c%N" -% https://yo.wikipedia.org/wiki/N%C3%A0%C3%ACj%C3%ADr%C3%AD%C3%A0 and CLDR: Orilẹ̀-èdè Nàìjíríà -country_name "Orild Njr" + +country_name "Orlde Njr" % Language name in Yoruba - "Yorùbá" lang_name "d Yorb" diff --git a/localedata/locales/yuw_PG b/localedata/locales/yuw_PG index 55e787a..0cb3cad 100644 --- a/localedata/locales/yuw_PG +++ b/localedata/locales/yuw_PG @@ -16,7 +16,7 @@ contact "Hannah Sarvasy" email "nungon.localization@gmail.com" tel "" fax "" -language "Yau" +language "Yau/Nungon" territory "Papua New Guinea" revision "1.0" date "2016-12-07" @@ -133,8 +133,8 @@ country_ab2 "PG" country_ab3 "PNG" % ISO 3166-1 numeric code for PNG country_num 598 -% See: https://en.wikipedia.org/wiki/Yau_language, the endonym seems to be Uruwa -lang_name "Uruwa" +% Yau/Nungon +lang_name "Yau/Nungon" country_car "PNG" lang_ab "" lang_term "yuw" diff --git a/localedata/locales/zh_HK b/localedata/locales/zh_HK index e8097d6..c130878 100644 --- a/localedata/locales/zh_HK +++ b/localedata/locales/zh_HK @@ -178,7 +178,6 @@ country_ab2 "HK" country_ab3 "HKG" country_num 344 country_car "HK" -lang_name "" lang_ab "zh" lang_term "zho" lang_lib "chi" diff --git a/localedata/locales/zh_SG b/localedata/locales/zh_SG index 472843c..2427cd3 100644 --- a/localedata/locales/zh_SG +++ b/localedata/locales/zh_SG @@ -175,7 +175,6 @@ country_ab3 "SGP" country_num 702 % SGP country_car "SGP" -lang_name "" lang_ab "zh" lang_term "zho" lang_lib "chi" diff --git a/login/Makefile b/login/Makefile index 030cf48..8b31991 100644 --- a/login/Makefile +++ b/login/Makefile @@ -43,8 +43,7 @@ endif subdir-dirs = programs vpath %.c programs -tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \ - tst-pututxline-lockfail tst-pututxline-cache +tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin # Build the -lutil library with these extra functions. extra-libs := libutil @@ -72,6 +71,3 @@ endif $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force) $(make-target-directory) -$(INSTALL_PROGRAM) -m 4755 -o root $< $@ - -$(objpfx)tst-pututxline-lockfail: $(shared-thread-library) -$(objpfx)tst-pututxline-cache: $(shared-thread-library) diff --git a/login/getutent_r.c b/login/getutent_r.c index 44239ec..6a244ba 100644 --- a/login/getutent_r.c +++ b/login/getutent_r.c @@ -23,16 +23,115 @@ #include "utmp-private.h" + +/* Functions defined here. */ +static int setutent_unknown (void); +static int getutent_r_unknown (struct utmp *buffer, struct utmp **result); +static int getutid_r_unknown (const struct utmp *line, struct utmp *buffer, + struct utmp **result); +static int getutline_r_unknown (const struct utmp *id, struct utmp *buffer, + struct utmp **result); +static struct utmp *pututline_unknown (const struct utmp *data); +static void endutent_unknown (void); + +/* Initial Jump table. */ +const struct utfuncs __libc_utmp_unknown_functions = +{ + setutent_unknown, + getutent_r_unknown, + getutid_r_unknown, + getutline_r_unknown, + pututline_unknown, + endutent_unknown, + NULL +}; + +/* Currently selected backend. */ +const struct utfuncs *__libc_utmp_jump_table = &__libc_utmp_unknown_functions; + /* We need to protect the opening of the file. */ __libc_lock_define_initialized (, __libc_utmp_lock attribute_hidden) +static int +setutent_unknown (void) +{ + int result; + + result = (*__libc_utmp_file_functions.setutent) (); + if (result) + __libc_utmp_jump_table = &__libc_utmp_file_functions; + + return result; +} + + +static int +getutent_r_unknown (struct utmp *buffer, struct utmp **result) +{ + /* The backend was not yet initialized. */ + if (setutent_unknown ()) + return (*__libc_utmp_jump_table->getutent_r) (buffer, result); + + /* Not available. */ + *result = NULL; + return -1; +} + + +static int +getutid_r_unknown (const struct utmp *id, struct utmp *buffer, + struct utmp **result) +{ + /* The backend was not yet initialized. */ + if (setutent_unknown ()) + return (*__libc_utmp_jump_table->getutid_r) (id, buffer, result); + + /* Not available. */ + *result = NULL; + return -1; +} + + +static int +getutline_r_unknown (const struct utmp *line, struct utmp *buffer, + struct utmp **result) +{ + /* The backend was not yet initialized. */ + if (setutent_unknown ()) + return (*__libc_utmp_jump_table->getutline_r) (line, buffer, result); + + /* Not available. */ + *result = NULL; + return -1; +} + + +static struct utmp * +pututline_unknown (const struct utmp *data) +{ + /* The backend was not yet initialized. */ + if (setutent_unknown ()) + return (*__libc_utmp_jump_table->pututline) (data); + + /* Not available. */ + return NULL; +} + + +static void +endutent_unknown (void) +{ + /* Nothing to do. */ +} + + void __setutent (void) { __libc_lock_lock (__libc_utmp_lock); - __libc_setutent (); + (*__libc_utmp_jump_table->setutent) (); __libc_lock_unlock (__libc_utmp_lock); } @@ -46,7 +145,7 @@ __getutent_r (struct utmp *buffer, struct utmp **result) __libc_lock_lock (__libc_utmp_lock); - retval = __libc_getutent_r (buffer, result); + retval = (*__libc_utmp_jump_table->getutent_r) (buffer, result); __libc_lock_unlock (__libc_utmp_lock); @@ -63,7 +162,7 @@ __pututline (const struct utmp *data) __libc_lock_lock (__libc_utmp_lock); - buffer = __libc_pututline (data); + buffer = (*__libc_utmp_jump_table->pututline) (data); __libc_lock_unlock (__libc_utmp_lock); @@ -78,7 +177,8 @@ __endutent (void) { __libc_lock_lock (__libc_utmp_lock); - __libc_endutent (); + (*__libc_utmp_jump_table->endutent) (); + __libc_utmp_jump_table = &__libc_utmp_unknown_functions; __libc_lock_unlock (__libc_utmp_lock); } diff --git a/login/getutid_r.c b/login/getutid_r.c index 11b288e..b7d3dba 100644 --- a/login/getutid_r.c +++ b/login/getutid_r.c @@ -32,6 +32,7 @@ __libc_lock_define (extern, __libc_utmp_lock attribute_hidden) int __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result) { +#if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0) int retval; /* Test whether ID has any of the legal types. */ @@ -48,11 +49,15 @@ __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result) __libc_lock_lock (__libc_utmp_lock); - retval = __libc_getutid_r (id, buffer, result); + retval = (*__libc_utmp_jump_table->getutid_r) (id, buffer, result); __libc_lock_unlock (__libc_utmp_lock); return retval; +#else /* !_HAVE_UT_ID && !_HAVE_UT_TYPE */ + __set_errno (ENOSYS); + return -1; +#endif } libc_hidden_def (__getutid_r) weak_alias (__getutid_r, getutid_r) diff --git a/login/getutline_r.c b/login/getutline_r.c index 5607c19..6996887 100644 --- a/login/getutline_r.c +++ b/login/getutline_r.c @@ -36,7 +36,7 @@ __getutline_r (const struct utmp *line, struct utmp *buffer, __libc_lock_lock (__libc_utmp_lock); - retval = __libc_getutline_r (line, buffer, result); + retval = (*__libc_utmp_jump_table->getutline_r) (line, buffer, result); __libc_lock_unlock (__libc_utmp_lock); diff --git a/login/getutmp.c b/login/getutmp.c index 32468ec..481150d 100644 --- a/login/getutmp.c +++ b/login/getutmp.c @@ -23,11 +23,23 @@ void getutmp (const struct utmpx *utmpx, struct utmp *utmp) { +#if _HAVE_UT_TYPE - 0 utmp->ut_type = utmpx->ut_type; +#endif +#if _HAVE_UT_PID - 0 utmp->ut_pid = utmpx->ut_pid; +#endif memcpy (utmp->ut_line, utmpx->ut_line, sizeof (utmp->ut_line)); memcpy (utmp->ut_user, utmpx->ut_user, sizeof (utmp->ut_user)); +#if _HAVE_UT_ID - 0 memcpy (utmp->ut_id, utmpx->ut_id, sizeof (utmp->ut_id)); +#endif +#if _HAVE_UT_HOST - 0 memcpy (utmp->ut_host, utmpx->ut_host, sizeof (utmp->ut_host)); +#endif +#if _HAVE_UT_TV - 0 utmp->ut_tv = utmpx->ut_tv; +#else + utmp->ut_time = utmpx->ut_time; +#endif } diff --git a/login/getutmpx.c b/login/getutmpx.c index 92a1826..34145fe 100644 --- a/login/getutmpx.c +++ b/login/getutmpx.c @@ -24,11 +24,24 @@ void getutmpx (const struct utmp *utmp, struct utmpx *utmpx) { memset (utmpx, 0, sizeof (struct utmpx)); + +#if _HAVE_UT_TYPE - 0 utmpx->ut_type = utmp->ut_type; +#endif +#if _HAVE_UT_PID - 0 utmpx->ut_pid = utmp->ut_pid; +#endif memcpy (utmpx->ut_line, utmp->ut_line, sizeof (utmp->ut_line)); memcpy (utmpx->ut_user, utmp->ut_user, sizeof (utmp->ut_user)); +#if _HAVE_UT_ID - 0 memcpy (utmpx->ut_id, utmp->ut_id, sizeof (utmp->ut_id)); +#endif +#if _HAVE_UT_HOST - 0 memcpy (utmpx->ut_host, utmp->ut_host, sizeof (utmp->ut_host)); +#endif +#if _HAVE_UT_TV - 0 utmpx->ut_tv = utmp->ut_tv; +#else + utmpx->ut_time = utmp->ut_time; +#endif } diff --git a/login/login.c b/login/login.c index 1729fc0..5d48cd4 100644 --- a/login/login.c +++ b/login/login.c @@ -91,8 +91,12 @@ login (const struct utmp *ut) struct utmp copy = *ut; /* Fill in those fields we supply. */ +#if _HAVE_UT_TYPE - 0 copy.ut_type = USER_PROCESS; +#endif +#if _HAVE_UT_PID - 0 copy.ut_pid = getpid (); +#endif /* Seek tty. */ found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty)); diff --git a/login/logout.c b/login/logout.c index 4d76ecf..d49bc4e 100644 --- a/login/logout.c +++ b/login/logout.c @@ -36,7 +36,9 @@ logout (const char *line) setutent (); /* Fill in search information. */ +#if _HAVE_UT_TYPE - 0 tmp.ut_type = USER_PROCESS; +#endif strncpy (tmp.ut_line, line, sizeof tmp.ut_line); /* Read the record. */ @@ -44,12 +46,20 @@ logout (const char *line) { /* Clear information about who & from where. */ memset (ut->ut_name, '\0', sizeof ut->ut_name); +#if _HAVE_UT_HOST - 0 memset (ut->ut_host, '\0', sizeof ut->ut_host); +#endif +#if _HAVE_UT_TV - 0 struct timeval tv; __gettimeofday (&tv, NULL); ut->ut_tv.tv_sec = tv.tv_sec; ut->ut_tv.tv_usec = tv.tv_usec; +#else + ut->ut_time = time (NULL); +#endif +#if _HAVE_UT_TYPE - 0 ut->ut_type = DEAD_PROCESS; +#endif if (pututline (ut) != NULL) result = 1; diff --git a/login/logwtmp.c b/login/logwtmp.c index e0b52b2..a19da4a 100644 --- a/login/logwtmp.c +++ b/login/logwtmp.c @@ -30,16 +30,26 @@ logwtmp (const char *line, const char *name, const char *host) /* Set information in new entry. */ memset (&ut, 0, sizeof (ut)); +#if _HAVE_UT_PID - 0 ut.ut_pid = getpid (); +#endif +#if _HAVE_UT_TYPE - 0 ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS; +#endif strncpy (ut.ut_line, line, sizeof ut.ut_line); strncpy (ut.ut_name, name, sizeof ut.ut_name); +#if _HAVE_UT_HOST - 0 strncpy (ut.ut_host, host, sizeof ut.ut_host); +#endif +#if _HAVE_UT_TV - 0 struct timeval tv; __gettimeofday (&tv, NULL); ut.ut_tv.tv_sec = tv.tv_sec; ut.ut_tv.tv_usec = tv.tv_usec; +#else + ut.ut_time = time (NULL); +#endif updwtmp (_PATH_WTMP, &ut); } diff --git a/login/programs/utmpdump.c b/login/programs/utmpdump.c index 1763e55..dccdb66 100644 --- a/login/programs/utmpdump.c +++ b/login/programs/utmpdump.c @@ -37,11 +37,47 @@ print_entry (struct utmp *up) temp_tv.tv_sec = up->ut_tv.tv_sec; temp_tv.tv_usec = up->ut_tv.tv_usec; - printf ("[%d] [%05d] [%-4.4s] [%-8.8s] [%-12.12s] [%-16.16s] [%-15.15s]" - " [%ld]\n", - up->ut_type, up->ut_pid, up->ut_id, up->ut_user, up->ut_line, - up->ut_host, 4 + ctime (&temp_tv.tv_sec), - (long int) temp_tv.tv_usec); + (printf) ( + /* The format string. */ +#if _HAVE_UT_TYPE + "[%d] " +#endif +#if _HAVE_UT_PID + "[%05d] " +#endif +#if _HAVE_UT_ID + "[%-4.4s] " +#endif + "[%-8.8s] [%-12.12s]" +#if _HAVE_UT_HOST + " [%-16.16s]" +#endif + " [%-15.15s]" +#if _HAVE_UT_TV + " [%ld]" +#endif + "\n" + /* The arguments. */ +#if _HAVE_UT_TYPE + , up->ut_type +#endif +#if _HAVE_UT_PID + , up->ut_pid +#endif +#if _HAVE_UT_ID + , up->ut_id +#endif + , up->ut_user, up->ut_line +#if _HAVE_UT_HOST + , up->ut_host +#endif +#if _HAVE_UT_TV + , 4 + ctime (&temp_tv.tv_sec) + , (long int) temp_tv.tv_usec +#else + , 4 + ctime (&up->ut_time) +#endif + ); } int diff --git a/login/tst-pututxline-cache.c b/login/tst-pututxline-cache.c deleted file mode 100644 index 3f30dd1..0000000 --- a/login/tst-pututxline-cache.c +++ /dev/null @@ -1,193 +0,0 @@ -/* Test case for cache invalidation after concurrent write (bug 24882). - 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; see the file COPYING.LIB. If - not, see . */ - -/* This test writes an entry to the utmpx file, reads it (so that it - is cached) in process1, and overwrites the same entry in process2 - with something that does not match the search criteria. At this - point, the cache of the first process is stale, and when process1 - attempts to write a new record which would have gone to the same - place (as indicated by the cache), it needs to realize that it has - to pick a different slot because the old slot is now used for - something else. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Set to the path of the utmp file. */ -static char *utmp_file; - -/* Used to synchronize the subprocesses. The barrier itself is - allocated in shared memory. */ -static pthread_barrier_t *barrier; - -/* setutxent with error checking. */ -static void -xsetutxent (void) -{ - errno = 0; - setutxent (); - TEST_COMPARE (errno, 0); -} - -/* getutxent with error checking. */ -static struct utmpx * -xgetutxent (void) -{ - errno = 0; - struct utmpx *result = getutxent (); - if (result == NULL) - FAIL_EXIT1 ("getutxent: %m"); - return result; -} - -static void -put_entry (const char *id, pid_t pid, const char *user, const char *line) -{ - struct utmpx ut = - { - .ut_type = LOGIN_PROCESS, - .ut_pid = pid, - .ut_host = "localhost", - }; - strcpy (ut.ut_id, id); - strncpy (ut.ut_user, user, sizeof (ut.ut_user)); - strncpy (ut.ut_line, line, sizeof (ut.ut_line)); - TEST_VERIFY (pututxline (&ut) != NULL); -} - -/* Use two cooperating subprocesses to avoid issues related to - unlock-on-close semantics of POSIX advisory locks. */ - -static __attribute__ ((noreturn)) void -process1 (void) -{ - TEST_COMPARE (utmpname (utmp_file), 0); - - /* Create an entry. */ - xsetutxent (); - put_entry ("1", 101, "root", "process1"); - - /* Retrieve the entry. This will fill the internal cache. */ - { - errno = 0; - setutxent (); - TEST_COMPARE (errno, 0); - struct utmpx ut = - { - .ut_type = LOGIN_PROCESS, - .ut_line = "process1", - }; - struct utmpx *result = getutxline (&ut); - if (result == NULL) - FAIL_EXIT1 ("getutxline (\"process1\"): %m"); - TEST_COMPARE (result->ut_pid, 101); - } - - /* Signal the other process to overwrite the entry. */ - xpthread_barrier_wait (barrier); - - /* Wait for the other process to complete the write operation. */ - xpthread_barrier_wait (barrier); - - /* Add another entry. Note: This time, there is no setutxent call. */ - put_entry ("1", 103, "root", "process1"); - - _exit (0); -} - -static void -process2 (void *closure) -{ - /* Wait for the first process to write its entry. */ - xpthread_barrier_wait (barrier); - - /* Truncate the file. The glibc interface does not support - re-purposing records, but an external expiration mechanism may - trigger this. */ - TEST_COMPARE (truncate64 (utmp_file, 0), 0); - - /* Write the replacement entry. */ - TEST_COMPARE (utmpname (utmp_file), 0); - xsetutxent (); - put_entry ("2", 102, "user", "process2"); - - /* Signal the other process that the entry has been replaced. */ - xpthread_barrier_wait (barrier); -} - -static int -do_test (void) -{ - xclose (create_temp_file ("tst-tumpx-cache-write-", &utmp_file)); - { - pthread_barrierattr_t attr; - xpthread_barrierattr_init (&attr); - xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS); - barrier = support_shared_allocate (sizeof (*barrier)); - xpthread_barrier_init (barrier, &attr, 2); - } - - /* Run both subprocesses in parallel. */ - { - pid_t pid1 = xfork (); - if (pid1 == 0) - process1 (); - support_isolate_in_subprocess (process2, NULL); - int status; - xwaitpid (pid1, &status, 0); - TEST_COMPARE (status, 0); - } - - /* Check that the utmpx database contains the expected records. */ - { - TEST_COMPARE (utmpname (utmp_file), 0); - xsetutxent (); - - struct utmpx *ut = xgetutxent (); - TEST_COMPARE_STRING (ut->ut_id, "2"); - TEST_COMPARE (ut->ut_pid, 102); - TEST_COMPARE_STRING (ut->ut_user, "user"); - TEST_COMPARE_STRING (ut->ut_line, "process2"); - - ut = xgetutxent (); - TEST_COMPARE_STRING (ut->ut_id, "1"); - TEST_COMPARE (ut->ut_pid, 103); - TEST_COMPARE_STRING (ut->ut_user, "root"); - TEST_COMPARE_STRING (ut->ut_line, "process1"); - - if (getutxent () != NULL) - FAIL_EXIT1 ("additional utmpx entry"); - } - - xpthread_barrier_destroy (barrier); - support_shared_free (barrier); - free (utmp_file); - - return 0; -} - -#include diff --git a/login/tst-pututxline-lockfail.c b/login/tst-pututxline-lockfail.c deleted file mode 100644 index 47c25dc..0000000 --- a/login/tst-pututxline-lockfail.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Test the lock upgrade path in tst-pututxline. - 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; see the file COPYING.LIB. If - not, see . */ - -/* pututxline upgrades the read lock on the file to a write lock. - This test verifies that if the lock upgrade fails, the utmp - subsystem remains in a consistent state, so that pututxline can be - called again. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Path to the temporary utmp file. */ -static char *path; - -/* Used to synchronize the subprocesses. The barrier itself is - allocated in shared memory. */ -static pthread_barrier_t *barrier; - -/* Use pututxline to write an entry for PID. */ -static struct utmpx * -write_entry (pid_t pid) -{ - struct utmpx ut = - { - .ut_type = LOGIN_PROCESS, - .ut_id = "1", - .ut_user = "root", - .ut_pid = pid, - .ut_line = "entry", - .ut_host = "localhost", - }; - return pututxline (&ut); -} - -/* Create the initial entry in a subprocess, so that the utmp - subsystem in the original process is not disturbed. */ -static void -subprocess_create_entry (void *closure) -{ - TEST_COMPARE (utmpname (path), 0); - TEST_VERIFY (write_entry (101) != NULL); -} - -/* Acquire an advisory read lock on PATH. */ -__attribute__ ((noreturn)) static void -subprocess_lock_file (void) -{ - int fd = xopen (path, O_RDONLY, 0); - - struct flock64 fl = - { - .l_type = F_RDLCK, - fl.l_whence = SEEK_SET, - }; - TEST_COMPARE (fcntl64 (fd, F_SETLKW, &fl), 0); - - /* Signal to the main process that the lock has been acquired. */ - xpthread_barrier_wait (barrier); - - /* Wait for the unlock request from the main process. */ - xpthread_barrier_wait (barrier); - - /* Implicitly unlock the file. */ - xclose (fd); - - /* Overwrite the existing entry. */ - TEST_COMPARE (utmpname (path), 0); - errno = 0; - setutxent (); - TEST_COMPARE (errno, 0); - TEST_VERIFY (write_entry (102) != NULL); - errno = 0; - endutxent (); - TEST_COMPARE (errno, 0); - - _exit (0); -} - -static int -do_test (void) -{ - xclose (create_temp_file ("tst-pututxline-lockfail-", &path)); - - { - pthread_barrierattr_t attr; - xpthread_barrierattr_init (&attr); - xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS); - barrier = support_shared_allocate (sizeof (*barrier)); - xpthread_barrier_init (barrier, &attr, 2); - xpthread_barrierattr_destroy (&attr); - } - - /* Write the initial entry. */ - support_isolate_in_subprocess (subprocess_create_entry, NULL); - - pid_t locker_pid = xfork (); - if (locker_pid == 0) - subprocess_lock_file (); - - /* Wait for the file locking to complete. */ - xpthread_barrier_wait (barrier); - - /* Try to add another entry. This attempt will fail, with EINTR or - EAGAIN. */ - TEST_COMPARE (utmpname (path), 0); - TEST_VERIFY (write_entry (102) == NULL); - if (errno != EINTR) - TEST_COMPARE (errno, EAGAIN); - - /* Signal the subprocess to overwrite the entry. */ - xpthread_barrier_wait (barrier); - - /* Wait for write and unlock to complete. */ - { - int status; - xwaitpid (locker_pid, &status, 0); - TEST_COMPARE (status, 0); - } - - /* The file is no longer locked, so this operation will succeed. */ - TEST_VERIFY (write_entry (103) != NULL); - errno = 0; - endutxent (); - TEST_COMPARE (errno, 0); - - /* Check that there is just one entry with the expected contents. - If pututxline becomes desynchronized internally, the entry is not - overwritten (bug 24902). */ - errno = 0; - setutxent (); - TEST_COMPARE (errno, 0); - struct utmpx *ut = getutxent (); - TEST_VERIFY_EXIT (ut != NULL); - TEST_COMPARE (ut->ut_type, LOGIN_PROCESS); - TEST_COMPARE_STRING (ut->ut_id, "1"); - TEST_COMPARE_STRING (ut->ut_user, "root"); - TEST_COMPARE (ut->ut_pid, 103); - TEST_COMPARE_STRING (ut->ut_line, "entry"); - TEST_COMPARE_STRING (ut->ut_host, "localhost"); - TEST_VERIFY (getutxent () == NULL); - errno = 0; - endutxent (); - TEST_COMPARE (errno, 0); - - xpthread_barrier_destroy (barrier); - support_shared_free (barrier); - free (path); - return 0; -} - -#include diff --git a/login/tst-updwtmpx.c b/login/tst-updwtmpx.c deleted file mode 100644 index 0a4a27d..0000000 --- a/login/tst-updwtmpx.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Basic test coverage for updwtmpx. - 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; see the file COPYING.LIB. If - not, see . */ - -/* This program runs a series of tests. Each one calls updwtmpx - twice, to write two records, optionally with misalignment in the - file, and reads back the results. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int -do_test (void) -{ - /* Two entries filled with an arbitrary bit pattern. */ - struct utmpx entries[2]; - unsigned char pad; - { - unsigned char *p = (unsigned char *) &entries[0]; - for (size_t i = 0; i < sizeof (entries); ++i) - { - p[i] = i; - } - /* Make sure that the first and second entry and the padding are - different. */ - p[sizeof (struct utmpx)] = p[0] + 1; - pad = p[0] + 2; - } - - char *path; - int fd = create_temp_file ("tst-updwtmpx-", &path); - - /* Used to check that updwtmpx does not leave an open file - descriptor around. */ - struct support_descriptors *descriptors = support_descriptors_list (); - - /* updwtmpx is expected to remove misalignment. Optionally insert - one byte of misalignment at the start and in the middle (after - the first entry). */ - for (int misaligned_start = 0; misaligned_start < 2; ++misaligned_start) - for (int misaligned_middle = 0; misaligned_middle < 2; ++misaligned_middle) - { - if (test_verbose > 0) - printf ("info: misaligned_start=%d misaligned_middle=%d\n", - misaligned_start, misaligned_middle); - - xftruncate (fd, 0); - TEST_COMPARE (pwrite64 (fd, &pad, misaligned_start, 0), - misaligned_start); - - /* Write first entry and check it. */ - errno = 0; - updwtmpx (path, &entries[0]); - TEST_COMPARE (errno, 0); - support_descriptors_check (descriptors); - TEST_COMPARE (xlseek (fd, 0, SEEK_END), sizeof (struct utmpx)); - struct utmpx buffer; - TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0), - sizeof (buffer)); - TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]), - &buffer, sizeof (buffer)); - - /* Middle mis-alignmet. */ - TEST_COMPARE (pwrite64 (fd, &pad, misaligned_middle, - sizeof (struct utmpx)), misaligned_middle); - - /* Write second entry and check both entries. */ - errno = 0; - updwtmpx (path, &entries[1]); - TEST_COMPARE (errno, 0); - support_descriptors_check (descriptors); - TEST_COMPARE (xlseek (fd, 0, SEEK_END), 2 * sizeof (struct utmpx)); - TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0), - sizeof (buffer)); - TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]), - &buffer, sizeof (buffer)); - TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), sizeof (buffer)), - sizeof (buffer)); - TEST_COMPARE_BLOB (&entries[1], sizeof (entries[1]), - &buffer, sizeof (buffer)); - } - - support_descriptors_free (descriptors); - free (path); - xclose (fd); - - return 0; -} - -#include diff --git a/login/tst-utmp.c b/login/tst-utmp.c index 49b0cbd..8cc7aaf 100644 --- a/login/tst-utmp.c +++ b/login/tst-utmp.c @@ -39,6 +39,8 @@ #endif +#if defined UTMPX || _HAVE_UT_TYPE + /* Prototype for our test function. */ static int do_test (int argc, char *argv[]); @@ -73,7 +75,11 @@ do_prepare (int argc, char *argv[]) struct utmp entry[] = { +#if defined UTMPX || _HAVE_UT_TV #define UT(a) .ut_tv = { .tv_sec = (a)} +#else +#define UT(a) .ut_time = (a) +#endif { .ut_type = BOOT_TIME, .ut_pid = 1, UT(1000) }, { .ut_type = RUN_LVL, .ut_pid = 1, UT(2000) }, @@ -161,7 +167,11 @@ simulate_login (const char *line, const char *user) entry[n].ut_pid = (entry_pid += 27); entry[n].ut_type = USER_PROCESS; strncpy (entry[n].ut_user, user, sizeof (entry[n].ut_user)); +#if defined UTMPX || _HAVE_UT_TV - 0 entry[n].ut_tv.tv_sec = (entry_time += 1000); +#else + entry[n].ut_time = (entry_time += 1000); +#endif setutent (); if (pututline (&entry[n]) == NULL) @@ -191,7 +201,11 @@ simulate_logout (const char *line) { entry[n].ut_type = DEAD_PROCESS; strncpy (entry[n].ut_user, "", sizeof (entry[n].ut_user)); +#if defined UTMPX || _HAVE_UT_TV - 0 entry[n].ut_tv.tv_sec = (entry_time += 1000); +#else + entry[n].ut_time = (entry_time += 1000); +#endif setutent (); if (pututline (&entry[n]) == NULL) @@ -376,3 +390,14 @@ do_test (int argc, char *argv[]) return result; } + +#else + +/* No field 'ut_type' in struct utmp. */ +int +main (void) +{ + return 0; +} + +#endif diff --git a/login/updwtmp.c b/login/updwtmp.c index 7ae9622..56fb419 100644 --- a/login/updwtmp.c +++ b/login/updwtmp.c @@ -29,7 +29,7 @@ __updwtmp (const char *wtmp_file, const struct utmp *utmp) { const char *file_name = TRANSFORM_UTMP_FILE_NAME (wtmp_file); - __libc_updwtmp (file_name, utmp); + (*__libc_utmp_file_functions.updwtmp) (file_name, utmp); } libc_hidden_def (__updwtmp) weak_alias (__updwtmp, updwtmp) diff --git a/login/utmp-private.h b/login/utmp-private.h index 5c2048e..bd87739 100644 --- a/login/utmp-private.h +++ b/login/utmp-private.h @@ -24,17 +24,24 @@ #include #include -/* These functions check for initialization, but not perform any - locking. */ -int __libc_setutent (void) attribute_hidden; -int __libc_getutent_r (struct utmp *, struct utmp **) attribute_hidden; -int __libc_getutid_r (const struct utmp *, struct utmp *, struct utmp **) - attribute_hidden; -int __libc_getutline_r (const struct utmp *, struct utmp *, struct utmp **) - attribute_hidden; -struct utmp *__libc_pututline (const struct utmp *) attribute_hidden; -void __libc_endutent (void) attribute_hidden; -int __libc_updwtmp (const char *, const struct utmp *) attribute_hidden; +/* The structure describing the functions in a backend. */ +struct utfuncs +{ + int (*setutent) (void); + int (*getutent_r) (struct utmp *, struct utmp **); + int (*getutid_r) (const struct utmp *, struct utmp *, struct utmp **); + int (*getutline_r) (const struct utmp *, struct utmp *, struct utmp **); + struct utmp *(*pututline) (const struct utmp *); + void (*endutent) (void); + int (*updwtmp) (const char *, const struct utmp *); +}; + +/* The tables from the services. */ +extern const struct utfuncs __libc_utmp_file_functions attribute_hidden; +extern const struct utfuncs __libc_utmp_unknown_functions attribute_hidden; + +/* Currently selected backend. */ +extern const struct utfuncs *__libc_utmp_jump_table attribute_hidden; /* Current file name. */ extern const char *__libc_utmp_file_name attribute_hidden; diff --git a/login/utmp_file.c b/login/utmp_file.c index c828a28..040a505 100644 --- a/login/utmp_file.c +++ b/login/utmp_file.c @@ -43,25 +43,6 @@ static off64_t file_offset; /* Cache for the last read entry. */ static struct utmp last_entry; -/* Returns true if *ENTRY matches last_entry, based on - data->ut_type. */ -static bool -matches_last_entry (const struct utmp *data) -{ - if (file_offset <= 0) - /* Nothing has been read. last_entry is stale and cannot match. */ - return false; - - if (data->ut_type == RUN_LVL - || data->ut_type == BOOT_TIME - || data->ut_type == OLD_TIME - || data->ut_type == NEW_TIME) - /* For some entry types, only a type match is required. */ - return data->ut_type == last_entry.ut_type; - else - /* For the process-related entries, a full match is needed. */ - return __utmp_equal (&last_entry, data); -} /* Locking timeout. */ #ifndef TIMEOUT @@ -71,70 +52,90 @@ matches_last_entry (const struct utmp *data) /* Do-nothing handler for locking timeout. */ static void timeout_handler (int signum) {}; - -/* try_file_lock (LOCKING, FD, TYPE) returns true if the locking - operation failed and recovery needs to be performed. - - file_unlock (FD) removes the lock (which must have been - successfully acquired). */ - -static bool -try_file_lock (int fd, int type) +/* LOCK_FILE(fd, type) failure_statement + attempts to get a lock on the utmp file referenced by FD. If it fails, + the failure_statement is executed, otherwise it is skipped. + LOCKING_FAILED() + jumps into the UNLOCK_FILE macro and ensures cleanup of LOCK_FILE. + UNLOCK_FILE(fd) + unlocks the utmp file referenced by FD and performs the cleanup of + LOCK_FILE. + */ +#define LOCK_FILE(fd, type) \ +{ \ + struct flock fl; \ + struct sigaction action, old_action; \ + unsigned int old_timeout; \ + \ + /* Cancel any existing alarm. */ \ + old_timeout = alarm (0); \ + \ + /* Establish signal handler. */ \ + action.sa_handler = timeout_handler; \ + __sigemptyset (&action.sa_mask); \ + action.sa_flags = 0; \ + __sigaction (SIGALRM, &action, &old_action); \ + \ + alarm (TIMEOUT); \ + \ + /* Try to get the lock. */ \ + memset (&fl, '\0', sizeof (struct flock)); \ + fl.l_type = (type); \ + fl.l_whence = SEEK_SET; \ + if (__fcntl64_nocancel ((fd), F_SETLKW, &fl) < 0) + +#define LOCKING_FAILED() \ + goto unalarm_return + +#define UNLOCK_FILE(fd) \ + /* Unlock the file. */ \ + fl.l_type = F_UNLCK; \ + __fcntl64_nocancel ((fd), F_SETLKW, &fl); \ + \ + unalarm_return: \ + /* Reset the signal handler and alarm. We must reset the alarm \ + before resetting the handler so our alarm does not generate a \ + spurious SIGALRM seen by the user. However, we cannot just set \ + the user's old alarm before restoring the handler, because then \ + it's possible our handler could catch the user alarm's SIGARLM \ + and then the user would never see the signal he expected. */ \ + alarm (0); \ + __sigaction (SIGALRM, &old_action, NULL); \ + if (old_timeout != 0) \ + alarm (old_timeout); \ +} while (0) + + +/* Functions defined here. */ +static int setutent_file (void); +static int getutent_r_file (struct utmp *buffer, struct utmp **result); +static int getutid_r_file (const struct utmp *key, struct utmp *buffer, + struct utmp **result); +static int getutline_r_file (const struct utmp *key, struct utmp *buffer, + struct utmp **result); +static struct utmp *pututline_file (const struct utmp *data); +static void endutent_file (void); +static int updwtmp_file (const char *file, const struct utmp *utmp); + +/* Jump table for file functions. */ +const struct utfuncs __libc_utmp_file_functions = { - /* Cancel any existing alarm. */ - int old_timeout = alarm (0); - - /* Establish signal handler. */ - struct sigaction old_action; - struct sigaction action; - action.sa_handler = timeout_handler; - __sigemptyset (&action.sa_mask); - action.sa_flags = 0; - __sigaction (SIGALRM, &action, &old_action); - - alarm (TIMEOUT); - - /* Try to get the lock. */ - struct flock64 fl = - { - .l_type = type, - .l_whence = SEEK_SET, - }; - - bool status = __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0; - int saved_errno = errno; - - /* Reset the signal handler and alarm. We must reset the alarm - before resetting the handler so our alarm does not generate a - spurious SIGALRM seen by the user. However, we cannot just set - the user's old alarm before restoring the handler, because then - it's possible our handler could catch the user alarm's SIGARLM and - then the user would never see the signal he expected. */ - alarm (0); - __sigaction (SIGALRM, &old_action, NULL); - if (old_timeout != 0) - alarm (old_timeout); - - __set_errno (saved_errno); - return status; -} + setutent_file, + getutent_r_file, + getutid_r_file, + getutline_r_file, + pututline_file, + endutent_file, + updwtmp_file +}; -static void -file_unlock (int fd) -{ - struct flock64 fl = - { - .l_type = F_UNLCK, - }; - __fcntl64_nocancel (fd, F_SETLKW, &fl); -} #ifndef TRANSFORM_UTMP_FILE_NAME # define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name) #endif -int -__libc_setutent (void) +static int +setutent_file (void) { if (file_fd < 0) { @@ -152,68 +153,56 @@ __libc_setutent (void) __lseek64 (file_fd, 0, SEEK_SET); file_offset = 0; + /* Make sure the entry won't match. */ +#if _HAVE_UT_TYPE - 0 + last_entry.ut_type = -1; +#else + last_entry.ut_line[0] = '\177'; +# if _HAVE_UT_ID - 0 + last_entry.ut_id[0] = '\0'; +# endif +#endif + return 1; } -/* Preform initialization if necessary. */ -static bool -maybe_setutent (void) -{ - return file_fd >= 0 || __libc_setutent (); -} -/* Reads the entry at file_offset, storing it in last_entry and - updating file_offset on success. Returns -1 for a read error, 0 - for EOF, and 1 for a successful read. last_entry and file_offset - are only updated on a successful and complete read. */ -static ssize_t -read_last_entry (void) +static int +getutent_r_file (struct utmp *buffer, struct utmp **result) { - struct utmp buffer; - ssize_t nbytes = __pread64_nocancel (file_fd, &buffer, sizeof (buffer), - file_offset); - if (nbytes < 0) - return -1; - else if (nbytes != sizeof (buffer)) - /* Assume EOF. */ - return 0; - else - { - last_entry = buffer; - file_offset += sizeof (buffer); - return 1; - } -} + ssize_t nbytes; -int -__libc_getutent_r (struct utmp *buffer, struct utmp **result) -{ - int saved_errno = errno; + assert (file_fd >= 0); - if (!maybe_setutent ()) + if (file_offset == -1l) { /* Not available. */ *result = NULL; return -1; } - if (try_file_lock (file_fd, F_RDLCK)) - return -1; + LOCK_FILE (file_fd, F_RDLCK) + { + nbytes = 0; + LOCKING_FAILED (); + } - ssize_t nbytes = read_last_entry (); - file_unlock (file_fd); + /* Read the next entry. */ + nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp)); - if (nbytes <= 0) /* Read error or EOF. */ + UNLOCK_FILE (file_fd); + + if (nbytes != sizeof (struct utmp)) { - if (nbytes == 0) - /* errno should be unchanged to indicate success. A premature - EOF is treated like an EOF (missing complete record at the - end). */ - __set_errno (saved_errno); + if (nbytes != 0) + file_offset = -1l; *result = NULL; return -1; } + /* Update position pointer. */ + file_offset += sizeof (struct utmp); + memcpy (buffer, &last_entry, sizeof (struct utmp)); *result = buffer; @@ -221,55 +210,82 @@ __libc_getutent_r (struct utmp *buffer, struct utmp **result) } -/* Search for *ID, updating last_entry and file_offset. Return 0 on - success and -1 on failure. Does not perform locking; for that see - internal_getut_r below. */ static int -internal_getut_nolock (const struct utmp *id) +internal_getut_r (const struct utmp *id, struct utmp *buffer, + bool *lock_failed) { - while (1) + int result = -1; + + LOCK_FILE (file_fd, F_RDLCK) + { + *lock_failed = true; + LOCKING_FAILED (); + } + +#if _HAVE_UT_TYPE - 0 + if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME + || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME) { - ssize_t nbytes = read_last_entry (); - if (nbytes < 0) - return -1; - if (nbytes == 0) + /* Search for next entry with type RUN_LVL, BOOT_TIME, + OLD_TIME, or NEW_TIME. */ + + while (1) { - /* End of file reached. */ - __set_errno (ESRCH); - return -1; + /* Read the next entry. */ + if (__read_nocancel (file_fd, buffer, sizeof (struct utmp)) + != sizeof (struct utmp)) + { + __set_errno (ESRCH); + file_offset = -1l; + goto unlock_return; + } + file_offset += sizeof (struct utmp); + + if (id->ut_type == buffer->ut_type) + break; } + } + else +#endif /* _HAVE_UT_TYPE */ + { + /* Search for the next entry with the specified ID and with type + INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS. */ - if (matches_last_entry (id)) - break; + while (1) + { + /* Read the next entry. */ + if (__read_nocancel (file_fd, buffer, sizeof (struct utmp)) + != sizeof (struct utmp)) + { + __set_errno (ESRCH); + file_offset = -1l; + goto unlock_return; + } + file_offset += sizeof (struct utmp); + + if (__utmp_equal (buffer, id)) + break; + } } - return 0; -} + result = 0; -/* Search for *ID, updating last_entry and file_offset. Return 0 on - success and -1 on failure. If the locking operation failed, write - true to *LOCK_FAILED. */ -static int -internal_getut_r (const struct utmp *id, bool *lock_failed) -{ - if (try_file_lock (file_fd, F_RDLCK)) - { - *lock_failed = true; - return -1; - } +unlock_return: + UNLOCK_FILE (file_fd); - int result = internal_getut_nolock (id); - file_unlock (file_fd); return result; } + /* For implementing this function we don't use the getutent_r function because we can avoid the reposition on every new entry this way. */ -int -__libc_getutid_r (const struct utmp *id, struct utmp *buffer, - struct utmp **result) +static int +getutid_r_file (const struct utmp *id, struct utmp *buffer, + struct utmp **result) { - if (!maybe_setutent ()) + assert (file_fd >= 0); + + if (file_offset == -1l) { *result = NULL; return -1; @@ -278,7 +294,7 @@ __libc_getutid_r (const struct utmp *id, struct utmp *buffer, /* We don't have to distinguish whether we can lock the file or whether there is no entry. */ bool lock_failed = false; - if (internal_getut_r (id, &lock_failed) < 0) + if (internal_getut_r (id, &last_entry, &lock_failed) < 0) { *result = NULL; return -1; @@ -290,65 +306,69 @@ __libc_getutid_r (const struct utmp *id, struct utmp *buffer, return 0; } + /* For implementing this function we don't use the getutent_r function because we can avoid the reposition on every new entry this way. */ -int -__libc_getutline_r (const struct utmp *line, struct utmp *buffer, - struct utmp **result) +static int +getutline_r_file (const struct utmp *line, struct utmp *buffer, + struct utmp **result) { - if (!maybe_setutent ()) + assert (file_fd >= 0); + + if (file_offset == -1l) { *result = NULL; return -1; } - if (try_file_lock (file_fd, F_RDLCK)) + LOCK_FILE (file_fd, F_RDLCK) { *result = NULL; - return -1; + LOCKING_FAILED (); } while (1) { - ssize_t nbytes = read_last_entry (); - if (nbytes < 0) - { - file_unlock (file_fd); - *result = NULL; - return -1; - } - if (nbytes == 0) + /* Read the next entry. */ + if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) + != sizeof (struct utmp)) { - /* End of file reached. */ - file_unlock (file_fd); __set_errno (ESRCH); + file_offset = -1l; *result = NULL; - return -1; + goto unlock_return; } + file_offset += sizeof (struct utmp); /* Stop if we found a user or login entry. */ - if ((last_entry.ut_type == USER_PROCESS + if ( +#if _HAVE_UT_TYPE - 0 + (last_entry.ut_type == USER_PROCESS || last_entry.ut_type == LOGIN_PROCESS) - && (strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line) - == 0)) + && +#endif + !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line)) break; } - file_unlock (file_fd); memcpy (buffer, &last_entry, sizeof (struct utmp)); *result = buffer; - return 0; +unlock_return: + UNLOCK_FILE (file_fd); + + return ((*result == NULL) ? -1 : 0); } -struct utmp * -__libc_pututline (const struct utmp *data) +static struct utmp * +pututline_file (const struct utmp *data) { - if (!maybe_setutent ()) - return NULL; - + struct utmp buffer; struct utmp *pbuf; + int found; + + assert (file_fd >= 0); if (! file_writable) { @@ -360,7 +380,8 @@ __libc_pututline (const struct utmp *data) if (new_fd == -1) return NULL; - if (__dup2 (new_fd, file_fd) < 0) + if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1 + || __dup2 (new_fd, file_fd) < 0) { __close_nocancel_nostatus (new_fd); return NULL; @@ -369,96 +390,95 @@ __libc_pututline (const struct utmp *data) file_writable = true; } - /* Exclude other writers before validating the cache. */ - if (try_file_lock (file_fd, F_WRLCK)) - return NULL; - /* Find the correct place to insert the data. */ - bool found = false; - if (matches_last_entry (data)) + if (file_offset > 0 + && ( +#if _HAVE_UT_TYPE - 0 + (last_entry.ut_type == data->ut_type + && (last_entry.ut_type == RUN_LVL + || last_entry.ut_type == BOOT_TIME + || last_entry.ut_type == OLD_TIME + || last_entry.ut_type == NEW_TIME)) + || +#endif + __utmp_equal (&last_entry, data))) + found = 1; + else { - /* Read back the entry under the write lock. */ - file_offset -= sizeof (last_entry); - ssize_t nbytes = read_last_entry (); - if (nbytes < 0) + bool lock_failed = false; + found = internal_getut_r (data, &buffer, &lock_failed); + + if (__builtin_expect (lock_failed, false)) { - file_unlock (file_fd); + __set_errno (EAGAIN); return NULL; } - - if (nbytes == 0) - /* End of file reached. */ - found = false; - else - found = matches_last_entry (data); } - if (!found) - /* Search forward for the entry. */ - found = internal_getut_nolock (data) >= 0; + LOCK_FILE (file_fd, F_WRLCK) + { + pbuf = NULL; + LOCKING_FAILED (); + } - off64_t write_offset; - if (!found) + if (found < 0) { /* We append the next entry. */ - write_offset = __lseek64 (file_fd, 0, SEEK_END); - - /* Round down to the next multiple of the entry size. This - ensures any partially-written record is overwritten by the - new record. */ - write_offset = (write_offset / sizeof (struct utmp) - * sizeof (struct utmp)); + file_offset = __lseek64 (file_fd, 0, SEEK_END); + if (file_offset % sizeof (struct utmp) != 0) + { + file_offset -= file_offset % sizeof (struct utmp); + __ftruncate64 (file_fd, file_offset); + + if (__lseek64 (file_fd, 0, SEEK_END) < 0) + { + pbuf = NULL; + goto unlock_return; + } + } } else - /* Overwrite last_entry. */ - write_offset = file_offset - sizeof (struct utmp); - - /* Write the new data. */ - ssize_t nbytes; - if (__lseek64 (file_fd, write_offset, SEEK_SET) < 0 - || (nbytes = __write_nocancel (file_fd, data, sizeof (struct utmp))) < 0) { - /* There is no need to recover the file position because all - reads use pread64, and any future write is preceded by - another seek. */ - file_unlock (file_fd); - return NULL; + /* We replace the just read entry. */ + file_offset -= sizeof (struct utmp); + __lseek64 (file_fd, file_offset, SEEK_SET); } - if (nbytes != sizeof (struct utmp)) + /* Write the new data. */ + if (__write_nocancel (file_fd, data, sizeof (struct utmp)) + != sizeof (struct utmp)) { /* If we appended a new record this is only partially written. Remove it. */ - if (!found) - (void) __ftruncate64 (file_fd, write_offset); - file_unlock (file_fd); - /* Assume that the write failure was due to missing disk - space. */ - __set_errno (ENOSPC); - return NULL; + if (found < 0) + (void) __ftruncate64 (file_fd, file_offset); + pbuf = NULL; + } + else + { + file_offset += sizeof (struct utmp); + pbuf = (struct utmp *) data; } - file_unlock (file_fd); - file_offset = write_offset + sizeof (struct utmp); - pbuf = (struct utmp *) data; + unlock_return: + UNLOCK_FILE (file_fd); return pbuf; } -void -__libc_endutent (void) +static void +endutent_file (void) { - if (file_fd >= 0) - { - __close_nocancel_nostatus (file_fd); - file_fd = -1; - } + assert (file_fd >= 0); + + __close_nocancel_nostatus (file_fd); + file_fd = -1; } -int -__libc_updwtmp (const char *file, const struct utmp *utmp) +static int +updwtmp_file (const char *file, const struct utmp *utmp) { int result = -1; off64_t offset; @@ -469,11 +489,8 @@ __libc_updwtmp (const char *file, const struct utmp *utmp) if (fd < 0) return -1; - if (try_file_lock (fd, F_WRLCK)) - { - __close_nocancel_nostatus (fd); - return -1; - } + LOCK_FILE (fd, F_WRLCK) + LOCKING_FAILED (); /* Remember original size of log file. */ offset = __lseek64 (fd, 0, SEEK_END); @@ -499,7 +516,7 @@ __libc_updwtmp (const char *file, const struct utmp *utmp) result = 0; unlock_return: - file_unlock (fd); + UNLOCK_FILE (fd); /* Close WTMP file. */ __close_nocancel_nostatus (fd); diff --git a/login/utmpname.c b/login/utmpname.c index 73b19c3..21cb890 100644 --- a/login/utmpname.c +++ b/login/utmpname.c @@ -42,7 +42,8 @@ __utmpname (const char *file) __libc_lock_lock (__libc_utmp_lock); /* Close the old file. */ - __libc_endutent (); + (*__libc_utmp_jump_table->endutent) (); + __libc_utmp_jump_table = &__libc_utmp_unknown_functions; if (strcmp (file, __libc_utmp_file_name) != 0) { diff --git a/malloc/Depend b/malloc/Depend index f5e2480..910c6d9 100644 --- a/malloc/Depend +++ b/malloc/Depend @@ -1,3 +1 @@ dlfcn -nptl -htl diff --git a/malloc/Makefile b/malloc/Makefile index 19c2a84..7d54bad 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -38,7 +38,6 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ tst-malloc_info \ tst-malloc-too-large \ tst-malloc-stats-cancellation \ - tst-tcfree1 tst-tcfree2 tst-tcfree3 \ tests-static := \ tst-interpose-static-nothread \ @@ -54,7 +53,7 @@ tests-internal += \ tst-dynarray-at-fail \ ifneq (no,$(have-tunables)) -tests += tst-malloc-usable-tunables tst-mxfast +tests += tst-malloc-usable-tunables tests-static += tst-malloc-usable-static-tunables endif @@ -131,7 +130,6 @@ 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 @@ -155,7 +153,8 @@ cpp-srcs-left := $(memusagestat-modules) lib := memusagestat include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) -LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm +$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o) + $(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm ifeq ($(run-built-tests),yes) ifeq (yes,$(build-shared)) @@ -196,8 +195,6 @@ tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV) tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV) -tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0 - ifeq ($(experimental-malloc),yes) CPPFLAGS-malloc.c += -DUSE_TCACHE=1 else diff --git a/malloc/arena.c b/malloc/arena.c index f5c7ad4..497ae47 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -237,7 +237,6 @@ TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t) TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t) TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t) #endif -TUNABLE_CALLBACK_FNDECL (set_mxfast, size_t) #else /* Initialization routine. */ #include @@ -325,7 +324,6 @@ ptmalloc_init (void) TUNABLE_GET (tcache_unsorted_limit, size_t, TUNABLE_CALLBACK (set_tcache_unsorted_limit)); # endif - TUNABLE_GET (mxfast, size_t, TUNABLE_CALLBACK (set_mxfast)); #else const char *s = NULL; if (__glibc_likely (_environ != NULL)) @@ -598,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; + mchunkptr top_chunk = top (ar_ptr), p, bck, fwd; heap_info *prev_heap; long new_size, top_size, top_area, extra, prev_size, misalign; @@ -627,7 +625,7 @@ heap_trim (heap_info *heap, size_t pad) if (!prev_inuse (p)) /* consolidate backward */ { p = prev_chunk (p); - unlink_chunk (ar_ptr, p); + unlink (ar_ptr, p, bck, fwd); } 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 00a37f2..e247c77 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -321,10 +321,6 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line, /* This is another arbitrary limit, which tunables can change. Each tcache bin will hold at most this number of chunks. */ # define TCACHE_FILL_COUNT 7 - -/* Maximum chunks in tcache bins for tunables. This value must fit the range - of tcache->counts[] entries, else they may overflow. */ -# define MAX_TCACHE_COUNT UINT16_MAX #endif @@ -1388,6 +1384,39 @@ 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 @@ -1460,46 +1489,6 @@ 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 @@ -1635,7 +1624,7 @@ static INTERNAL_SIZE_T global_max_fast; #define set_max_fast(s) \ global_max_fast = (((s) == 0) \ - ? MIN_CHUNK_SIZE / 2 : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK)) + ? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK)) static inline INTERNAL_SIZE_T get_max_fast (void) @@ -2821,7 +2810,6 @@ 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)); @@ -2831,7 +2819,6 @@ 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 @@ -2839,8 +2826,7 @@ 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 (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0 - || __glibc_unlikely (!powerof2 (mem & (pagesize - 1)))) + if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0)) malloc_printerr ("munmap_chunk(): invalid pointer"); atomic_decrement (&mp_.n_mmaps); @@ -2863,22 +2849,16 @@ mremap_chunk (mchunkptr p, size_t new_size) char *cp; assert (chunk_is_mmapped (p)); - - 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"); + assert (((size + offset) & (GLRO (dl_pagesize) - 1)) == 0); /* 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 (total_size == new_size) + if (size + offset == new_size) return p; - cp = (char *) __mremap ((char *) block, total_size, new_size, + cp = (char *) __mremap ((char *) p - offset, size + offset, new_size, MREMAP_MAYMOVE); if (cp == MAP_FAILED) @@ -2908,8 +2888,6 @@ mremap_chunk (mchunkptr p, size_t new_size) typedef struct tcache_entry { struct tcache_entry *next; - /* This field exists to detect double frees. */ - struct tcache_perthread_struct *key; } tcache_entry; /* There is one of these for each thread, which contains the @@ -2919,7 +2897,7 @@ typedef struct tcache_entry time), this is for performance reasons. */ typedef struct tcache_perthread_struct { - uint16_t counts[TCACHE_MAX_BINS]; + char counts[TCACHE_MAX_BINS]; tcache_entry *entries[TCACHE_MAX_BINS]; } tcache_perthread_struct; @@ -2932,11 +2910,7 @@ static __always_inline void tcache_put (mchunkptr chunk, size_t tc_idx) { tcache_entry *e = (tcache_entry *) chunk2mem (chunk); - - /* Mark this chunk as "in the tcache" so the test in _int_free will - detect a double free. */ - e->key = tcache; - + assert (tc_idx < TCACHE_MAX_BINS); e->next = tcache->entries[tc_idx]; tcache->entries[tc_idx] = e; ++(tcache->counts[tc_idx]); @@ -2948,9 +2922,10 @@ static __always_inline void * tcache_get (size_t tc_idx) { tcache_entry *e = tcache->entries[tc_idx]; + assert (tc_idx < TCACHE_MAX_BINS); + assert (tcache->entries[tc_idx] > 0); tcache->entries[tc_idx] = e->next; --(tcache->counts[tc_idx]); - e->key = NULL; return (void *) e; } @@ -3052,8 +3027,9 @@ __libc_malloc (size_t bytes) DIAG_PUSH_NEEDS_COMMENT; if (tc_idx < mp_.tcache_bins + /*&& tc_idx < TCACHE_MAX_BINS*/ /* to appease gcc */ && tcache - && tcache->counts[tc_idx] > 0) + && tcache->entries[tc_idx] != NULL) { return tcache_get (tc_idx); } @@ -3740,22 +3716,11 @@ _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 @@ -3876,14 +3841,10 @@ _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 @@ -3948,7 +3909,7 @@ _int_malloc (mstate av, size_t bytes) victim = victim->fd; remainder_size = size - nb; - unlink_chunk (av, victim); + unlink (av, victim, bck, fwd); /* Exhaust */ if (remainder_size < MINSIZE) @@ -4050,7 +4011,7 @@ _int_malloc (mstate av, size_t bytes) remainder_size = size - nb; /* unlink */ - unlink_chunk (av, victim); + unlink (av, victim, bck, fwd); /* Exhaust */ if (remainder_size < MINSIZE) @@ -4115,9 +4076,6 @@ _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; @@ -4193,33 +4151,13 @@ _int_free (mstate av, mchunkptr p, int have_lock) #if USE_TCACHE { size_t tc_idx = csize2tidx (size); - if (tcache != NULL && tc_idx < mp_.tcache_bins) - { - /* Check to see if it's already in the tcache. */ - tcache_entry *e = (tcache_entry *) chunk2mem (p); - - /* This test succeeds on double free. However, we don't 100% - trust it (it also matches random payload data at a 1 in - 2^ chance), so verify it's not an unlikely - coincidence before aborting. */ - if (__glibc_unlikely (e->key == tcache)) - { - tcache_entry *tmp; - LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); - for (tmp = tcache->entries[tc_idx]; - tmp; - tmp = tmp->next) - if (tmp == e) - malloc_printerr ("free(): double free detected in tcache 2"); - /* If we get here, it was a coincidence. We've wasted a - few cycles, but don't abort. */ - } - if (tcache->counts[tc_idx] < mp_.tcache_count) - { - tcache_put (p, tc_idx); - return; - } + if (tcache + && tc_idx < mp_.tcache_bins + && tcache->counts[tc_idx] < mp_.tcache_count) + { + tcache_put (p, tc_idx); + return; } } #endif @@ -4340,9 +4278,7 @@ _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_chunk (av, p); + unlink(av, p, bck, fwd); } if (nextchunk != av->top) { @@ -4351,7 +4287,7 @@ _int_free (mstate av, mchunkptr p, int have_lock) /* consolidate forward */ if (!nextinuse) { - unlink_chunk (av, nextchunk); + unlink(av, nextchunk, bck, fwd); size += nextsize; } else clear_inuse_bit_at_offset(nextchunk, 0); @@ -4464,6 +4400,8 @@ 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); @@ -4501,9 +4439,7 @@ 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_chunk (av, p); + unlink(av, p, bck, fwd); } if (nextchunk != av->top) { @@ -4511,7 +4447,7 @@ static void malloc_consolidate(mstate av) if (!nextinuse) { size += nextsize; - unlink_chunk (av, nextchunk); + unlink(av, nextchunk, bck, fwd); } else clear_inuse_bit_at_offset(nextchunk, 0); @@ -4559,6 +4495,14 @@ _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 */ + 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)) @@ -4603,7 +4547,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, (unsigned long) (nb)) { newp = oldp; - unlink_chunk (av, next); + unlink (av, next, bck, fwd); } /* allocate, copy, free */ @@ -4626,7 +4570,43 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, } else { - memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ); + /* + 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); + } + } + } + } + _int_free (av, oldp, 1); check_inuse_chunk (av, newp); return chunk2mem (newp); @@ -5111,27 +5091,22 @@ static inline int __always_inline do_set_tcache_max (size_t value) { - if (value <= MAX_TCACHE_SIZE) + if (value >= 0 && value <= MAX_TCACHE_SIZE) { LIBC_PROBE (memory_tunable_tcache_max_bytes, 2, value, mp_.tcache_max_bytes); mp_.tcache_max_bytes = value; mp_.tcache_bins = csize2tidx (request2size(value)) + 1; - return 1; } - return 0; + return 1; } static inline int __always_inline do_set_tcache_count (size_t value) { - if (value <= MAX_TCACHE_COUNT) - { - LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count); - mp_.tcache_count = value; - return 1; - } - return 0; + LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count); + mp_.tcache_count = value; + return 1; } static inline int @@ -5144,19 +5119,6 @@ do_set_tcache_unsorted_limit (size_t value) } #endif -static inline int -__always_inline -do_set_mxfast (size_t value) -{ - if (value <= MAX_FAST_SIZE) - { - LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); - set_max_fast (value); - return 1; - } - return 0; -} - int __libc_mallopt (int param_number, int value) { @@ -5173,24 +5135,24 @@ __libc_mallopt (int param_number, int value) (see definition of set_max_fast). */ malloc_consolidate (av); - /* Many of these helper functions take a size_t. We do not worry - about overflow here, because negative int values will wrap to - very large size_t values and the helpers have sufficient range - checking for such conversions. Many of these helpers are also - used by the tunables macros in arena.c. */ - switch (param_number) { case M_MXFAST: - res = do_set_mxfast (value); + if (value >= 0 && value <= MAX_FAST_SIZE) + { + LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); + set_max_fast (value); + } + else + res = 0; break; case M_TRIM_THRESHOLD: - res = do_set_trim_threshold (value); + do_set_trim_threshold (value); break; case M_TOP_PAD: - res = do_set_top_pad (value); + do_set_top_pad (value); break; case M_MMAP_THRESHOLD: @@ -5198,25 +5160,25 @@ __libc_mallopt (int param_number, int value) break; case M_MMAP_MAX: - res = do_set_mmaps_max (value); + do_set_mmaps_max (value); break; case M_CHECK_ACTION: - res = do_set_mallopt_check (value); + do_set_mallopt_check (value); break; case M_PERTURB: - res = do_set_perturb_byte (value); + do_set_perturb_byte (value); break; case M_ARENA_TEST: if (value > 0) - res = do_set_arena_test (value); + do_set_arena_test (value); break; case M_ARENA_MAX: if (value > 0) - res = do_set_arena_max (value); + do_set_arena_max (value); break; } __libc_lock_unlock (av->mutex); @@ -5448,12 +5410,6 @@ __malloc_info (int options, FILE *fp) __libc_lock_lock (ar_ptr->mutex); - /* Account for top chunk. The top-most available chunk is - treated specially and is never in any bin. See "initial_top" - comments. */ - avail = chunksize (ar_ptr->top); - nblocks = 1; /* Top always exists. */ - for (size_t i = 0; i < NFASTBINS; ++i) { mchunkptr p = fastbin (ar_ptr, i); @@ -5539,7 +5495,7 @@ __malloc_info (int options, FILE *fp) for (size_t i = 0; i < nsizes; ++i) if (sizes[i].count != 0 && i != NFASTBINS) - fprintf (fp, "\ + fprintf (fp, " \ \n", sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count); diff --git a/malloc/mtrace.c b/malloc/mtrace.c index 546d37a..9064f20 100644 --- a/malloc/mtrace.c +++ b/malloc/mtrace.c @@ -121,41 +121,6 @@ lock_and_info (const void *caller, Dl_info *mem) return res; } -static void tr_freehook (void *, const void *); -static void * tr_mallochook (size_t, const void *); -static void * tr_reallochook (void *, size_t, const void *); -static void * tr_memalignhook (size_t, size_t, const void *); - -/* Set all the default non-trace hooks. */ -static __always_inline void -set_default_hooks (void) -{ - __free_hook = tr_old_free_hook; - __malloc_hook = tr_old_malloc_hook; - __realloc_hook = tr_old_realloc_hook; - __memalign_hook = tr_old_memalign_hook; -} - -/* Set all of the tracing hooks used for mtrace. */ -static __always_inline void -set_trace_hooks (void) -{ - __free_hook = tr_freehook; - __malloc_hook = tr_mallochook; - __realloc_hook = tr_reallochook; - __memalign_hook = tr_memalignhook; -} - -/* Save the current set of hooks as the default hooks. */ -static __always_inline void -save_default_hooks (void) -{ - tr_old_free_hook = __free_hook; - tr_old_malloc_hook = __malloc_hook; - tr_old_realloc_hook = __realloc_hook; - tr_old_memalign_hook = __memalign_hook; -} - static void tr_freehook (void *ptr, const void *caller) { @@ -173,12 +138,12 @@ tr_freehook (void *ptr, const void *caller) tr_break (); __libc_lock_lock (lock); } - set_default_hooks (); + __free_hook = tr_old_free_hook; if (tr_old_free_hook != NULL) (*tr_old_free_hook)(ptr, caller); else free (ptr); - set_trace_hooks (); + __free_hook = tr_freehook; __libc_lock_unlock (lock); } @@ -190,12 +155,12 @@ tr_mallochook (size_t size, const void *caller) Dl_info mem; Dl_info *info = lock_and_info (caller, &mem); - set_default_hooks (); + __malloc_hook = tr_old_malloc_hook; if (tr_old_malloc_hook != NULL) hdr = (void *) (*tr_old_malloc_hook)(size, caller); else hdr = (void *) malloc (size); - set_trace_hooks (); + __malloc_hook = tr_mallochook; tr_where (caller, info); /* We could be printing a NULL here; that's OK. */ @@ -220,12 +185,16 @@ tr_reallochook (void *ptr, size_t size, const void *caller) Dl_info mem; Dl_info *info = lock_and_info (caller, &mem); - set_default_hooks (); + __free_hook = tr_old_free_hook; + __malloc_hook = tr_old_malloc_hook; + __realloc_hook = tr_old_realloc_hook; if (tr_old_realloc_hook != NULL) hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller); else hdr = (void *) realloc (ptr, size); - set_trace_hooks (); + __free_hook = tr_freehook; + __malloc_hook = tr_mallochook; + __realloc_hook = tr_reallochook; tr_where (caller, info); if (hdr == NULL) @@ -261,12 +230,14 @@ tr_memalignhook (size_t alignment, size_t size, const void *caller) Dl_info mem; Dl_info *info = lock_and_info (caller, &mem); - set_default_hooks (); + __memalign_hook = tr_old_memalign_hook; + __malloc_hook = tr_old_malloc_hook; if (tr_old_memalign_hook != NULL) hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller); else hdr = (void *) memalign (alignment, size); - set_trace_hooks (); + __memalign_hook = tr_memalignhook; + __malloc_hook = tr_mallochook; tr_where (caller, info); /* We could be printing a NULL here; that's OK. */ @@ -334,8 +305,14 @@ mtrace (void) malloc_trace_buffer = mtb; setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE); fprintf (mallstream, "= Start\n"); - save_default_hooks (); - set_trace_hooks (); + tr_old_free_hook = __free_hook; + __free_hook = tr_freehook; + tr_old_malloc_hook = __malloc_hook; + __malloc_hook = tr_mallochook; + tr_old_realloc_hook = __realloc_hook; + __realloc_hook = tr_reallochook; + tr_old_memalign_hook = __memalign_hook; + __memalign_hook = tr_memalignhook; #ifdef _LIBC if (!added_atexit_handler) { @@ -361,7 +338,10 @@ muntrace (void) file. */ FILE *f = mallstream; mallstream = NULL; - set_default_hooks (); + __free_hook = tr_old_free_hook; + __malloc_hook = tr_old_malloc_hook; + __realloc_hook = tr_old_realloc_hook; + __memalign_hook = tr_old_memalign_hook; fprintf (f, "= End\n"); fclose (f); diff --git a/malloc/tst-mxfast.c b/malloc/tst-mxfast.c deleted file mode 100644 index 7a7750b..0000000 --- a/malloc/tst-mxfast.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Test that glibc.malloc.mxfast tunable works. - 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 - . */ - -/* This test verifies that setting the glibc.malloc.mxfast tunable to - zero results in free'd blocks being returned to the small bins, not - the fast bins. */ - -#include -#include - -int -do_test (void) -{ - struct mallinfo m; - char *volatile p1; - char *volatile p2; - - /* Arbitrary value; must be in default fastbin range. */ - p1 = malloc (3); - /* Something large so that p1 isn't a "top block" */ - p2 = malloc (512); - free (p1); - - m = mallinfo (); - - /* This will fail if there are any blocks in the fastbins. */ - TEST_COMPARE (m.smblks, 0); - - /* To keep gcc happy. */ - free (p2); - - return 0; -} - -#include diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c deleted file mode 100644 index bc29375..0000000 --- a/malloc/tst-tcfree1.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Test that malloc tcache catches double free. - 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 -#include -#include -#include -#include -#include -#include - -static int -do_test (void) -{ - /* Do one allocation of any size that fits in tcache. */ - char * volatile x = malloc (32); - - free (x); // puts in tcache - free (x); // should abort - - printf("FAIL: tcache double free not detected\n"); - return 1; -} - -#define TEST_FUNCTION do_test -#define EXPECTED_SIGNAL SIGABRT -#include diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c deleted file mode 100644 index 17f06ba..0000000 --- a/malloc/tst-tcfree2.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Test that malloc tcache catches double free. - 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 -#include -#include -#include -#include -#include -#include - -static int -do_test (void) -{ - char * volatile ptrs[20]; - int i; - - /* Allocate enough small chunks so that when we free them all, the tcache - is full, and the first one we freed is at the end of its linked list. */ -#define COUNT 20 - for (i=0; i diff --git a/malloc/tst-tcfree3.c b/malloc/tst-tcfree3.c deleted file mode 100644 index 016d30d..0000000 --- a/malloc/tst-tcfree3.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Test that malloc tcache catches double free. - 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 -#include - -/* Prevent GCC from optimizing away any malloc/free pairs. */ -#pragma GCC optimize ("O0") - -static int -do_test (void) -{ - /* Do two allocation of any size that fit in tcache, and one that - doesn't. */ - int ** volatile a = malloc (32); - int ** volatile b = malloc (32); - /* This is just under the mmap threshold. */ - int ** volatile c = malloc (127 * 1024); - - /* The invalid "tcache bucket" we might dereference will likely end - up somewhere within this memory block, so make all the accidental - "next" pointers cause segfaults. BZ #23907. */ - memset (c, 0xff, 127 * 1024); - - free (a); // puts in tcache - - /* A is now free and contains the key we use to detect in-tcache. - Copy the key to the other chunks. */ - memcpy (b, a, 32); - memcpy (c, a, 32); - - /* This free tests the "are we in the tcache already" loop with a - VALID bin but "coincidental" matching key. */ - free (b); // should NOT abort - /* This free tests the "is it a valid tcache bin" test. */ - free (c); // should NOT abort - - return 0; -} - -#include diff --git a/manual/install.texi b/manual/install.texi index 351d67c..c39e63b 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -117,15 +117,6 @@ problem and suppress these constructs, so that the library will still be usable, but functionality may be lost---for example, you can't build a shared libc with old binutils. -@item --with-nonshared-cflags=@var{cflags} -Use additional compiler flags @var{cflags} to build the parts of the -library which are always statically linked into applications and -libraries even with shared linking (that is, the object files contained -in @file{lib*_nonshared.a} libraries). The build process will -automatically use the appropriate flags, but this option can be used to -set additional flags required for building applications and libraries, -to match local policy. - @c disable static doesn't work currently @c @item --disable-static @c Don't build static libraries. Static libraries aren't that useful these @@ -199,10 +190,10 @@ number of routines called directly from assembler are excluded from this protection. @item --enable-bind-now -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. +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. @pindex pt_chown @findex grantpt diff --git a/manual/libc.texinfo b/manual/libc.texinfo index fcbdb35..23dd3ac 100644 --- a/manual/libc.texinfo +++ b/manual/libc.texinfo @@ -14,7 +14,7 @@ @include macros.texi @comment Tell install-info what to do. -@dircategory Libraries +@dircategory Software libraries @direntry * Libc: (libc). C library. @end direntry diff --git a/manual/llio.texi b/manual/llio.texi index 26f7d2c..2733b9c 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -1404,13 +1404,10 @@ 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 table below -lists some of the error conditions for this function. +returns the value @math{-1} and sets @code{errno}. The following +@code{errno} error conditions are specific to 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. @@ -1440,6 +1437,9 @@ 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/manual/memory.texi b/manual/memory.texi index 4731a38..a1435aa 100644 --- a/manual/memory.texi +++ b/manual/memory.texi @@ -3289,10 +3289,6 @@ in which memory protection keys are disabled. @item ENOSPC All available protection keys already have been allocated. - -The system does not implement memory protection keys or runs in a mode -in which memory protection keys are disabled. - @end table @end deftypefun diff --git a/manual/nss.texi b/manual/nss.texi index e595356..18361b6 100644 --- a/manual/nss.texi +++ b/manual/nss.texi @@ -56,17 +56,13 @@ functions to access the databases. @noindent The databases available in the NSS are -@cindex aliases @cindex ethers @cindex group -@cindex gshadow @cindex hosts -@cindex initgroups @cindex netgroup @cindex networks -@cindex passwd @cindex protocols -@cindex publickey +@cindex passwd @cindex rpc @cindex services @cindex shadow @@ -79,22 +75,16 @@ Ethernet numbers, @comment @pxref{Ethernet Numbers}. @item group Groups of users, @pxref{Group Database}. -@item gshadow -Group passphrase hashes and related information. @item hosts Host names and numbers, @pxref{Host Names}. -@item initgroups -Supplementary group access list. @item netgroup Network wide list of host and users, @pxref{Netgroup Database}. @item networks Network names and numbers, @pxref{Networks Database}. -@item passwd -User identities, @pxref{User Database}. @item protocols Network protocols, @pxref{Protocols Database}. -@item publickey -Public keys for Secure RPC. +@item passwd +User identities, @pxref{User Database}. @item rpc Remote procedure call names and numbers. @comment @pxref{RPC Database}. @@ -106,8 +96,8 @@ User passphrase hashes and related information. @end table @noindent -@c We currently don't implement automount, netmasks, or bootparams. -More databases may be added later. +There will be some more added later (@code{automount}, @code{bootparams}, +@code{netmasks}, and @code{publickey}). @node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch @section The NSS Configuration File @@ -169,10 +159,6 @@ these files since they should be placed in a directory where they are found automatically. Only the names of all available services are important. -Lastly, some system software may make use of the NSS configuration file -to store their own configuration for similar purposes. Examples of this -include the @code{automount} service which is used by @code{autofs}. - @node Actions in the NSS configuration, Notes on NSS Configuration File, Services in the NSS configuration, NSS Configuration File @subsection Actions in the NSS configuration diff --git a/manual/probes.texi b/manual/probes.texi index 0ea560e..ab2a310 100644 --- a/manual/probes.texi +++ b/manual/probes.texi @@ -243,18 +243,6 @@ This probe is triggered when the value of this tunable. @end deftp -@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2}) -This probe is triggered when @code{free} determines that the memory -being freed has probably already been freed, and resides in the -per-thread cache. Note that there is an extremely unlikely chance -that this probe will trigger due to random payload data remaining in -the allocated memory matching the key used to detect double frees. -This probe actually indicates that an expensive linear search of the -tcache, looking for a double free, has happened. Argument @var{$arg1} -is the memory location as passed to @code{free}, Argument @var{$arg2} -is the tcache bin it resides in. -@end deftp - @node Mathematical Function Probes @section Mathematical Function Probes diff --git a/manual/startup.texi b/manual/startup.texi index 21c48cd..7395d32 100644 --- a/manual/startup.texi +++ b/manual/startup.texi @@ -1005,6 +1005,14 @@ This function actually terminates the process by raising a intercept this signal; see @ref{Signal Handling}. @end deftypefun +@c Put in by rms. Don't remove. +@cartouche +@strong{Future Change Warning:} Proposed Federal censorship regulations +may prohibit us from giving you information about the possibility of +calling this function. We would be required to say that this is not an +acceptable way of terminating a program. +@end cartouche + @node Termination Internals @subsection Termination Internals diff --git a/manual/tunables.texi b/manual/tunables.texi index 3dc6f9a..bb4819b 100644 --- a/manual/tunables.texi +++ b/manual/tunables.texi @@ -188,8 +188,8 @@ per-thread cache. The default (and maximum) value is 1032 bytes on @deftp Tunable glibc.malloc.tcache_count The maximum number of chunks of each size to cache. The default is 7. -The upper limit is 65535. If set to zero, the per-thread cache is effectively -disabled. +There is no upper limit, other than available system memory. If set +to zero, the per-thread cache is effectively disabled. The approximate maximum overhead of the per-thread cache is thus equal to the number of bins times the chunk count in each bin times the size @@ -213,18 +213,6 @@ pre-fill the per-thread cache with. The default, or when set to zero, is no limit. @end deftp -@deftp Tunable glibc.malloc.mxfast -One of the optimizations malloc uses is to maintain a series of ``fast -bins'' that hold chunks up to a specific size. The default and -maximum size which may be held this way is 80 bytes on 32-bit systems -or 160 bytes on 64-bit systems. Applications which value size over -speed may choose to reduce the size of requests which are serviced -from fast bins with this tunable. Note that the value specified -includes malloc's internal overhead, which is normally the size of one -pointer, so add 4 on 32-bit systems or 8 on 64-bit systems to the size -passed to @code{malloc} for the largest bin size to enable. -@end deftp - @node Elision Tunables @section Elision Tunables @cindex elision tunables diff --git a/manual/users.texi b/manual/users.texi index a006bb5..4ed79ba 100644 --- a/manual/users.texi +++ b/manual/users.texi @@ -894,9 +894,9 @@ The @code{getlogin} function is declared in @file{unistd.h}, while @c ttyname_r dup @ascuheap @acsmem @acsfd @c strncpy dup ok @c libc_lock_lock dup @asulock @aculock -@c __libc_setutent dup @mtasurace:utent @acsfd -@c __libc_getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer -@c __libc_endutent dup @mtasurace:utent @asulock @aculock +@c *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd +@c *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer +@c *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock @c libc_lock_unlock dup ok @c strlen dup ok @c memcpy dup ok @@ -1111,7 +1111,7 @@ compatibility only, @file{utmp.h} defines @code{ut_time} as an alias for @c setutent @mtasurace:utent @asulock @aculock @acsfd @c libc_lock_lock dup @asulock @aculock -@c __libc_setutent @mtasurace:utent @acsfd +@c *libc_utmp_jump_table->setutent @mtasurace:utent @acsfd @c setutent_unknown @mtasurace:utent @acsfd @c *libc_utmp_file_functions.setutent = setutent_file @mtasurace:utent @acsfd @c open_not_cancel_2 dup @acsfd @@ -1152,7 +1152,7 @@ A null pointer is returned in case no further entry is available. @safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} @c endutent @mtasurace:utent @asulock @aculock @acsfd @c libc_lock_lock dup @asulock @aculock -@c __libc_endutent @mtasurace:utent @acsfd +@c *libc_utmp_jump_table->endutent @mtasurace:utent @acsfd @c endutent_unknown ok @c endutent_file @mtasurace:utent @acsfd @c close_not_cancel_no_status dup @acsfd @@ -1230,7 +1230,7 @@ over again. @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} @c pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd @c libc_lock_lock dup @asulock @aculock -@c __libc_pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd +@c *libc_utmp_jump_table->pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd @c pututline_unknown @mtasurace:utent @acsfd @c setutent_unknown dup @mtasurace:utent @acsfd @c pututline_file @mtascusig:ALRM @mtascutimer @acsfd @@ -1282,7 +1282,7 @@ user-provided buffer. @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} @c getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd @c libc_lock_lock dup @asulock @aculock -@c __libc_getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd +@c *libc_utmp_jump_table->getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd @c getutent_r_unknown @mtasurace:utent @acsfd @c setutent_unknown dup @mtasurace:utent @acsfd @c getutent_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer @@ -1319,7 +1319,7 @@ This function is a GNU extension. @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} @c getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd @c libc_lock_lock dup @asulock @aculock -@c __libc_getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd +@c *libc_utmp_jump_table->getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd @c getutid_r_unknown @mtasurace:utent @acsfd @c setutent_unknown dup @mtasurace:utent @acsfd @c getutid_r_file @mtascusig:ALRM @mtascutimer @@ -1349,7 +1349,7 @@ This function is a GNU extension. @safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} @c getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd @c libc_lock_lock dup @asulock @aculock -@c __libc_getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd +@c *libc_utmp_jump_table->getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd @c getutline_r_unknown @mtasurace:utent @acsfd @c setutent_unknown dup @mtasurace:utent @acsfd @c getutline_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer @@ -1393,7 +1393,7 @@ be used. @safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} @c utmpname @mtasurace:utent @asulock @ascuheap @aculock @acsmem @c libc_lock_lock dup @asulock @aculock -@c __libc_endutent dup @mtasurace:utent +@c *libc_utmp_jump_table->endutent dup @mtasurace:utent @c strcmp dup ok @c free dup @ascuheap @acsmem @c strdup dup @ascuheap @acsmem diff --git a/math/Makefile b/math/Makefile index df73d70..90b3b68 100644 --- a/math/Makefile +++ b/math/Makefile @@ -26,7 +26,6 @@ headers := math.h bits/mathcalls.h bits/mathinline.h \ fpu_control.h complex.h bits/cmathcalls.h fenv.h \ bits/fenv.h bits/fenvinline.h bits/mathdef.h tgmath.h \ bits/math-finite.h bits/math-vector.h \ - finclude/math-vector-fortran.h \ bits/libm-simd-decl-stubs.h bits/iscanonical.h \ bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \ bits/long-double.h bits/mathcalls-helper-functions.h \ diff --git a/math/finclude/math-vector-fortran.h b/math/finclude/math-vector-fortran.h deleted file mode 100644 index 7c1e095..0000000 --- a/math/finclude/math-vector-fortran.h +++ /dev/null @@ -1,19 +0,0 @@ -! Platform-specific declarations of SIMD math functions for Fortran. -*- f90 -*- -! 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 -! . - -! No SIMD math functions are available for this platform. diff --git a/math/libm-test-fma.inc b/math/libm-test-fma.inc index a7ee409..5b29fb8 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|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, 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, 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|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, 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, 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|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, 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, 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|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), + 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), AUTO_TESTS_fff_f (fma), }; diff --git a/math/math.h b/math/math.h index b3b414f..ddee4e4 100644 --- a/math/math.h +++ b/math/math.h @@ -874,8 +874,7 @@ enum the __SUPPORT_SNAN__ check may be skipped for those versions. */ /* Return number of classification appropriate for X. */ -# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ - || __glibc_clang_prereq (2,8)) \ +# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \ && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus) /* The check for __cplusplus allows the use of the builtin, even when optimization for size is on. This is provided for @@ -890,7 +889,7 @@ enum # endif /* Return nonzero value if sign of X is negative. */ -# if __GNUC_PREREQ (6,0) || __glibc_clang_prereq (3,3) +# if __GNUC_PREREQ (6,0) # define signbit(x) __builtin_signbit (x) # elif defined __cplusplus /* In C++ mode, __MATH_TG cannot be used, because it relies on @@ -908,16 +907,14 @@ enum # endif /* Return nonzero value if X is not +-Inf or NaN. */ -# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ - || __glibc_clang_prereq (2,8) +# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ # define isfinite(x) __builtin_isfinite (x) # else # define isfinite(x) __MATH_TG ((x), __finite, (x)) # endif /* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ -# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ - || __glibc_clang_prereq (2,8) +# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ # define isnormal(x) __builtin_isnormal (x) # else # define isnormal(x) (fpclassify (x) == FP_NORMAL) @@ -925,8 +922,7 @@ enum /* Return nonzero value if X is a NaN. We could use `fpclassify' but we already have this functions `__isnan' and it is faster. */ -# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ - || __glibc_clang_prereq (2,8) +# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ # define isnan(x) __builtin_isnan (x) # else # define isnan(x) __MATH_TG ((x), __isnan, (x)) @@ -943,8 +939,7 @@ enum # define isinf(x) \ (__builtin_types_compatible_p (__typeof (x), _Float128) \ ? __isinff128 (x) : __builtin_isinf_sign (x)) -# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ - || __glibc_clang_prereq (3,7) +# elif __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ # define isinf(x) __builtin_isinf_sign (x) # else # define isinf(x) __MATH_TG ((x), __isinf, (x)) diff --git a/misc/Makefile b/misc/Makefile index 5b6a908..b7be2bc 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -84,13 +84,7 @@ tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \ tst-mntent-blank-corrupt tst-mntent-blank-passno bug18240 \ tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \ - tst-preadvwritev2 tst-preadvwritev64v2 \ - tst-mntent-autofs - -# Tests which need libdl. -ifeq (yes,$(build-shared)) -tests += tst-gethostid -endif + tst-preadvwritev2 tst-preadvwritev64v2 tests-internal := tst-atomic tst-atomic-long tst-allocate_once tests-static := tst-empty @@ -151,5 +145,3 @@ tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \ $(evaluate-test) - -$(objpfx)tst-gethostid: $(libdl) diff --git a/misc/error.c b/misc/error.c index 03378e2..b4e8b6c 100644 --- a/misc/error.c +++ b/misc/error.c @@ -319,7 +319,6 @@ error (int status, int errnum, const char *message, ...) va_start (args, message); error_tail (status, errnum, message, args); - va_end (args); #ifdef _LIBC _IO_funlockfile (stderr); @@ -391,7 +390,6 @@ error_at_line (int status, int errnum, const char *file_name, va_start (args, message); error_tail (status, errnum, message, args); - va_end (args); #ifdef _LIBC _IO_funlockfile (stderr); diff --git a/misc/mntent_r.c b/misc/mntent_r.c index 7bb224f..7a82658 100644 --- a/misc/mntent_r.c +++ b/misc/mntent_r.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -113,18 +112,26 @@ decode_name (char *buf) return buf; } -static bool -get_mnt_entry (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) + +/* Read one mount table entry from STREAM. Returns a pointer to storage + reused on the next call, or null for EOF or error (use feof/ferror to + check). */ +struct mntent * +__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) { char *cp; char *head; + flockfile (stream); do { char *end_ptr; if (__fgets_unlocked (buffer, bufsiz, stream) == NULL) - return false; + { + funlockfile (stream); + return NULL; + } end_ptr = strchr (buffer, '\n'); if (end_ptr != NULL) /* chop newline */ @@ -172,40 +179,9 @@ get_mnt_entry (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) case 2: break; } - - return true; -} - -/* Read one mount table entry from STREAM. Returns a pointer to storage - reused on the next call, or null for EOF or error (use feof/ferror to - check). */ -struct mntent * -__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) -{ - struct mntent *result; - - flockfile (stream); - while (true) - if (get_mnt_entry (stream, mp, buffer, bufsiz)) - { - /* If the file system is autofs look for a mount option hint - ("ignore") to skip the entry. */ - if (strcmp (mp->mnt_type, "autofs") == 0 && __hasmntopt (mp, "ignore")) - memset (mp, 0, sizeof (*mp)); - else - { - result = mp; - break; - } - } - else - { - result = NULL; - break; - } funlockfile (stream); - return result; + return mp; } libc_hidden_def (__getmntent_r) weak_alias (__getmntent_r, getmntent_r) diff --git a/misc/tst-gethostid.c b/misc/tst-gethostid.c deleted file mode 100644 index 1490aaf..0000000 --- a/misc/tst-gethostid.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Basic test for gethostid. - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Initial test is run outside a chroot, to increase the likelihood of - success. */ -static void -outside_chroot (void *closure) -{ - long id = gethostid (); - printf ("info: host ID outside chroot: 0x%lx\n", id); -} - -/* The same, but this time perform a chroot operation. */ -static void -in_chroot (void *closure) -{ - const char *chroot_path = closure; - xchroot (chroot_path); - long id = gethostid (); - printf ("info: host ID in chroot: 0x%lx\n", id); -} - -static int -do_test (void) -{ - support_isolate_in_subprocess (outside_chroot, NULL); - - /* Now run the test inside a chroot. */ - support_become_root (); - if (!support_can_chroot ()) - /* Cannot perform further tests. */ - return 0; - - /* Only use nss_files. */ - __nss_configure_lookup ("hosts", "files"); - - /* Load the DSO outside of the chroot. */ - xdlopen (LIBNSS_FILES_SO, RTLD_LAZY); - - char *chroot_dir = support_create_temp_directory ("tst-gethostid-"); - support_isolate_in_subprocess (in_chroot, chroot_dir); - - /* Tests with /etc/hosts in the chroot. */ - { - char *path = xasprintf ("%s/etc", chroot_dir); - add_temp_file (path); - xmkdir (path, 0777); - free (path); - path = xasprintf ("%s/etc/hosts", chroot_dir); - add_temp_file (path); - - FILE *fp = xfopen (path, "w"); - xfclose (fp); - printf ("info: chroot test with an empty /etc/hosts file\n"); - support_isolate_in_subprocess (in_chroot, chroot_dir); - - char hostname[1024]; - int ret = gethostname (hostname, sizeof (hostname)); - if (ret < 0) - printf ("warning: invalid result from gethostname: %d\n", ret); - else if (strlen (hostname) == 0) - puts ("warning: gethostname returned empty string"); - else - { - printf ("info: chroot test with IPv6 address in /etc/hosts for: %s\n", - hostname); - fp = xfopen (path, "w"); - /* Use an IPv6 address to induce another lookup failure. */ - fprintf (fp, "2001:db8::1 %s\n", hostname); - xfclose (fp); - support_isolate_in_subprocess (in_chroot, chroot_dir); - } - free (path); - } - free (chroot_dir); - - return 0; -} - -#include diff --git a/misc/tst-mntent-autofs.c b/misc/tst-mntent-autofs.c deleted file mode 100644 index bf4d4e7..0000000 --- a/misc/tst-mntent-autofs.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Test autofs "ignore" filtering for getment_r. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct test_case -{ - const char *line; - struct - { - /* Like struct mntent, but with const pointers. */ - const char *mnt_fsname; - const char *mnt_dir; - const char *mnt_type; - const char *mnt_opts; - int mnt_freq; - int mnt_passno; - } expected; -}; - -static struct test_case test_cases[] = - { - { "/etc/auto.direct /mnt/auto/1 autofs defaults 0 0", - { "/etc/auto.direct", "/mnt/auto/1", "autofs", "defaults", 0, 0 } }, - - /* These entries are filtered out. */ - { "/etc/auto.2 /mnt/auto/2 autofs ignore 0 0", { NULL, } }, - { "/etc/auto.3 /mnt/auto/3 autofs ignore,other 1 2", { NULL, } }, - { "/etc/auto.4 /mnt/auto/4 autofs other,ignore 3 4", { NULL, } }, - { "/etc/auto.5 /mnt/auto/5 autofs opt1,ignore,opt2 5 6", { NULL, } }, - - /* Dummy entry to make the desynchronization more obvious. */ - { "/dev/sda1 / xfs defaults 0 0", - { "/dev/sda1", "/", "xfs", "defaults", 0, 0 } }, - - /* These are not filtered because the file system is not autofs. */ - { "/etc/auto.direct /mnt/auto/6 autofs1 ignore 0 0", - { "/etc/auto.direct", "/mnt/auto/6", "autofs1", "ignore", 0, 0 } }, - { "/etc/auto.direct /mnt/auto/7 autofs1 ignore,other 0 0", - { "/etc/auto.direct", "/mnt/auto/7", "autofs1", "ignore,other", 0, 0 } }, - { "/etc/auto.direct /mnt/auto/8 autofs1 other,ignore 0 0", - { "/etc/auto.direct", "/mnt/auto/8", "autofs1", "other,ignore", 0, 0 } }, - { "/etc/auto.direct /mnt/auto/9 autofs1 opt1,ignore,opt2 0 0", - { "/etc/auto.direct", "/mnt/auto/9", "autofs1", "opt1,ignore,opt2", } }, - - /* These are not filtered because the string "ignore" is not an - option name. */ - { "/etc/auto.direct /mnt/auto/10 autofs noignore 1 2", - { "/etc/auto.direct", "/mnt/auto/10", "autofs", "noignore", 1, 2 } }, - { "/etc/auto.direct /mnt/auto/11 autofs noignore,other 0 0", - { "/etc/auto.direct", "/mnt/auto/11", "autofs", "noignore,other", } }, - { "/etc/auto.direct /mnt/auto/12 autofs other,noignore 0 0", - { "/etc/auto.direct", "/mnt/auto/12", "autofs", "other,noignore", } }, - { "/etc/auto.direct /mnt/auto/13 autofs errors=ignore 0 0", - { "/etc/auto.direct", "/mnt/auto/13", "autofs", "errors=ignore", } }, - { "/etc/auto.direct /mnt/auto/14 autofs errors=ignore,other 0 0", - { "/etc/auto.direct", "/mnt/auto/14", "autofs", - "errors=ignore,other", } }, - { "/etc/auto.direct /mnt/auto/15 autofs other,errors=ignore 0 0", - { "/etc/auto.direct", "/mnt/auto/15", "autofs", - "other,errors=ignore", } }, - - /* These are not filtered because the string is escaped. '\151' - is 'i', but it is not actually decoded by the parser. */ - { "/etc/auto.\\151gnore /mnt/auto/16 autofs \\151gnore 0 0", - { "/etc/auto.\\151gnore", "/mnt/auto/16", "autofs", - "\\151gnore", } }, - }; - -static int -do_test (void) -{ - char *path; - xclose (create_temp_file ("tst-mntent-autofs-", &path)); - - /* Write the test file. */ - FILE *fp = xfopen (path, "w"); - for (size_t i = 0; i < array_length (test_cases); ++i) - fprintf (fp, "%s\n", test_cases[i].line); - xfclose (fp); - - /* Open the test file again, this time for parsing. */ - fp = setmntent (path, "r"); - TEST_VERIFY_EXIT (fp != NULL); - char buffer[512]; - struct mntent me; - - for (size_t i = 0; i < array_length (test_cases); ++i) - { - if (test_cases[i].expected.mnt_type == NULL) - continue; - - memset (buffer, 0xcc, sizeof (buffer)); - memset (&me, 0xcc, sizeof (me)); - struct mntent *pme = getmntent_r (fp, &me, buffer, sizeof (buffer)); - TEST_VERIFY_EXIT (pme != NULL); - TEST_VERIFY (pme == &me); - TEST_COMPARE_STRING (test_cases[i].expected.mnt_fsname, me.mnt_fsname); - TEST_COMPARE_STRING (test_cases[i].expected.mnt_dir, me.mnt_dir); - TEST_COMPARE_STRING (test_cases[i].expected.mnt_type, me.mnt_type); - TEST_COMPARE_STRING (test_cases[i].expected.mnt_opts, me.mnt_opts); - TEST_COMPARE (test_cases[i].expected.mnt_freq, me.mnt_freq); - TEST_COMPARE (test_cases[i].expected.mnt_passno, me.mnt_passno); - } - - TEST_VERIFY (getmntent_r (fp, &me, buffer, sizeof (buffer)) == NULL); - - TEST_COMPARE (feof (fp), 1); - TEST_COMPARE (ferror (fp), 0); - errno = 0; - TEST_COMPARE (endmntent (fp), 1); - TEST_COMPARE (errno, 0); - free (path); - return 0; -} - -#include diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c index 50b9da3..f889a21 100644 --- a/misc/tst-preadvwritev2-common.c +++ b/misc/tst-preadvwritev2-common.c @@ -19,6 +19,9 @@ #include #include +static void +do_test_with_invalid_flags (void) +{ #ifndef RWF_HIPRI # define RWF_HIPRI 0 #endif @@ -36,68 +39,6 @@ #endif #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \ | RWF_APPEND) - -static void -do_test_with_invalid_fd (void) -{ - char buf[256]; - struct iovec iov = { buf, sizeof buf }; - - /* Check with flag being 0 to use the fallback code which calls pwritev - or writev. */ - TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1); - TEST_COMPARE (errno, EBADF); - TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1); - TEST_COMPARE (errno, EBADF); - - /* Same tests as before but with flags being different than 0. Since - there is no emulation for any flag value, fallback code returns - ENOTSUP. This is different running on a kernel with preadv2/pwritev2 - support, where EBADF is returned). */ - TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1); - TEST_VERIFY (errno == EBADF || errno == ENOTSUP); - TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1); - TEST_VERIFY (errno == EBADF || errno == ENOTSUP); -} - -static void -do_test_with_invalid_iov (void) -{ - { - char buf[256]; - struct iovec iov; - - iov.iov_base = buf; - iov.iov_len = (size_t)SSIZE_MAX + 1; - - TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1); - TEST_COMPARE (errno, EINVAL); - TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1); - TEST_COMPARE (errno, EINVAL); - - /* Same as for invalid file descriptor tests, emulation fallback - first checks for flag value and return ENOTSUP. */ - TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1); - TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); - TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1); - TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); - } - - { - /* An invalid iovec buffer should trigger an invalid memory access - or an error (Linux for instance returns EFAULT). */ - struct iovec iov[IOV_MAX+1] = { 0 }; - - TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1); - TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); - TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1); - TEST_VERIFY (errno == EINVAL || errno == ENOTSUP); - } -} - -static void -do_test_with_invalid_flags (void) -{ /* Set the next bit from the mask of all supported flags. */ int invalid_flag = RWF_SUPPORTED != 0 ? __builtin_clz (RWF_SUPPORTED) : 2; invalid_flag = 0x1 << ((sizeof (int) * CHAR_BIT) - invalid_flag); diff --git a/misc/tst-preadvwritev2.c b/misc/tst-preadvwritev2.c index cb58cbe..be22802 100644 --- a/misc/tst-preadvwritev2.c +++ b/misc/tst-preadvwritev2.c @@ -30,8 +30,6 @@ do_test (void) { do_test_with_invalid_flags (); do_test_without_offset (); - do_test_with_invalid_fd (); - do_test_with_invalid_iov (); return do_test_with_offset (0); } diff --git a/misc/tst-preadvwritev64v2.c b/misc/tst-preadvwritev64v2.c index 6a9de54..8d3cc32 100644 --- a/misc/tst-preadvwritev64v2.c +++ b/misc/tst-preadvwritev64v2.c @@ -32,8 +32,6 @@ do_test (void) { do_test_with_invalid_flags (); do_test_without_offset (); - do_test_with_invalid_fd (); - do_test_with_invalid_iov (); return do_test_with_offset (0); } diff --git a/nis/nss b/nis/nss index d720e71..0ac6774 100644 --- a/nis/nss +++ b/nis/nss @@ -25,7 +25,7 @@ # memory with every getXXent() call. Otherwise each getXXent() call # might result into a network communication with the server to get # the next entry. -SETENT_BATCH_READ=TRUE +#SETENT_BATCH_READ=TRUE # # ADJUNCT_AS_SHADOW # If set to TRUE, the passwd routines in the NIS NSS module will not diff --git a/nptl/Makefile b/nptl/Makefile index d6b37b6..be80665 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -109,6 +109,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ pthread_once \ old_pthread_atfork \ pthread_getcpuclockid \ + pthread_clock_gettime pthread_clock_settime \ shm-directory \ sem_init sem_destroy \ sem_open sem_close sem_unlink \ @@ -120,7 +121,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ cancellation \ lowlevellock \ lll_timedlock_wait lll_timedwait_tid \ - pt-fork pt-fcntl \ + pt-fork pt-vfork pt-fcntl \ $(pthread-compat-wrappers) \ pt-raise pt-system \ flockfile ftrylockfile funlockfile \ @@ -144,8 +145,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ mtx_destroy mtx_init mtx_lock mtx_timedlock \ mtx_trylock mtx_unlock call_once cnd_broadcast \ cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait \ - tss_create tss_delete tss_get tss_set \ - libpthread-compat + tss_create tss_delete tss_get tss_set # pthread_setuid pthread_seteuid pthread_setreuid \ # pthread_setresuid \ # pthread_setgid pthread_setegid pthread_setregid \ @@ -241,9 +241,9 @@ LDLIBS-tst-minstack-throw = -lstdc++ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ - tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \ - tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \ - tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ + tst-mutex7 tst-mutex9 tst-mutex5a tst-mutex7a tst-mutex7robust \ + tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \ + tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ tst-mutexpi9 \ tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ @@ -293,7 +293,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ tst-exec1 tst-exec2 tst-exec3 tst-exec4 tst-exec5 \ tst-exit1 tst-exit2 tst-exit3 \ tst-stdio1 tst-stdio2 \ - tst-stack1 tst-stack2 tst-stack3 tst-stack4 \ + tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \ tst-pthread-attr-affinity tst-pthread-mutexattr \ tst-unload \ tst-dlsym1 \ @@ -318,11 +318,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ tst-minstack-throw \ 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-tryrdlock-stall tst-rwlock-trywrlock-stall - -tests-container = tst-pthread-getattr + tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock tests-internal := tst-rwlock19 tst-rwlock20 \ tst-sem11 tst-sem12 tst-sem13 \ @@ -386,8 +382,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \ tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \ tst-oncex3 tst-oncex4 ifeq ($(build-shared),yes) -tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \ - tst-audit-threads +tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1 tests-nolibpthread += tst-fini1 ifeq ($(have-z-execstack),yes) @@ -399,8 +394,7 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \ tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \ tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \ tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \ - tst-join7mod tst-compat-forwarder-mod tst-audit-threads-mod1 \ - tst-audit-threads-mod2 + tst-join7mod tst-compat-forwarder-mod extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \ tst-cleanup4aux.o tst-cleanupx4aux.o test-extras += tst-cleanup4aux tst-cleanupx4aux @@ -635,7 +629,7 @@ ifeq ($(build-shared),yes) $(addprefix $(objpfx), \ $(filter-out $(tests-static) $(xtests-static) $(tests-reverse) \ $(tests-nolibpthread), \ - $(tests) $(tests-internal) $(xtests) $(test-srcs) $(tests-container))): \ + $(tests) $(tests-internal) $(xtests) $(test-srcs))): \ $(objpfx)libpthread.so $(objpfx)tst-unload: $(libdl) # $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so, @@ -715,16 +709,6 @@ endif $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so -tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1 - -# Protect against a build using -Wl,-z,now. -LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy -LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy -LDFLAGS-tst-audit-threads = -Wl,-z,lazy -$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so -$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so -tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so - # The tests here better do not run in parallel ifneq ($(filter %tests,$(MAKECMDGOALS)),) .NOTPARALLEL: diff --git a/nptl/Versions b/nptl/Versions index 6007fd0..e7f691d 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -36,6 +36,7 @@ libc { __libc_alloca_cutoff; # Internal libc interface to libpthread __libc_dl_error_tsd; + __libc_vfork; __libc_pthread_init; __libc_current_sigrtmin_private; __libc_current_sigrtmax_private; __libc_allocate_rtsig_private; @@ -97,7 +98,7 @@ libpthread { sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait; # Special fork handling. - fork; __fork; + fork; __fork; vfork; # Cancellation points. close; __close; fcntl; __fcntl; read; __read; write; __write; accept; @@ -151,7 +152,7 @@ libpthread { } GLIBC_2.1.2 { - __libpthread_version_placeholder; + __vfork; } GLIBC_2.2 { diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 5fa45b1..04e3f08 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -572,9 +572,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* Place the thread descriptor at the end of the stack. */ #if TLS_TCB_AT_TP - pd = (struct pthread *) ((((uintptr_t) mem + size) - - TLS_TCB_SIZE) - & ~__static_tls_align_m1); + pd = (struct pthread *) ((char *) mem + size) - 1; #elif TLS_DTV_AT_TP pd = (struct pthread *) ((((uintptr_t) mem + size - __static_tls_size) @@ -964,6 +962,54 @@ __reclaim_stacks (void) } +#if HP_TIMING_AVAIL +# undef __find_thread_by_id +/* Find a thread given the thread ID. */ +attribute_hidden +struct pthread * +__find_thread_by_id (pid_t tid) +{ + struct pthread *result = NULL; + + lll_lock (stack_cache_lock, LLL_PRIVATE); + + /* Iterate over the list with system-allocated threads first. */ + list_t *runp; + list_for_each (runp, &stack_used) + { + struct pthread *curp; + + curp = list_entry (runp, struct pthread, list); + + if (curp->tid == tid) + { + result = curp; + goto out; + } + } + + /* Now the list with threads using user-allocated stacks. */ + list_for_each (runp, &__stack_user) + { + struct pthread *curp; + + curp = list_entry (runp, struct pthread, list); + + if (curp->tid == tid) + { + result = curp; + goto out; + } + } + + out: + lll_unlock (stack_cache_lock, LLL_PRIVATE); + + return result; +} +#endif + + #ifdef SIGSETXID static void setxid_mark_thread (struct xid_command *cmdp, struct pthread *t) diff --git a/nptl/descr.h b/nptl/descr.h index c3b81d8..9c01e1b 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -343,7 +343,8 @@ struct pthread unsigned int setxid_futex; #if HP_TIMING_AVAIL - hp_timing_t cpuclock_offset_ununsed; + /* Offset of the CPU clock at start thread start time. */ + hp_timing_t cpuclock_offset; #endif /* If the thread waits to join another one the ID of the latter is diff --git a/nptl/libpthread-compat.c b/nptl/libpthread-compat.c deleted file mode 100644 index ea29e9f..0000000 --- a/nptl/libpthread-compat.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Placeholder definitions to pull in removed symbol versions. - 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 - -/* This is an unused compatibility symbol definition, to prevent ld - from creating a weak version definition for GLIBC_2.1.2. (__vfork - used to be defined at that version, but it is now provided by libc, - and there are no versions left in libpthread for that symbol - version.) If the ABI baseline for glibc is the GLIBC_2.2 symbol - version or later, the placeholder symbol is not needed because - there are plenty of other symbols which populate those later - versions. */ -#if (SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_2)) -void -attribute_compat_text_section -__libpthread_version_placeholder (void) -{ -} -compat_symbol (libpthread, __libpthread_version_placeholder, - __libpthread_version_placeholder, GLIBC_2_1_2); -#endif diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index 098bc05..907411d 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -275,6 +275,9 @@ __pthread_initialize_minimal_internal (void) THREAD_SETMEM (pd, user_stack, true); if (LLL_LOCK_INITIALIZER != 0) THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER); +#if HP_TIMING_AVAIL + THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset)); +#endif /* Initialize the robust mutex data. */ { diff --git a/nptl/pt-vfork.c b/nptl/pt-vfork.c new file mode 100644 index 0000000..2f890d3 --- /dev/null +++ b/nptl/pt-vfork.c @@ -0,0 +1,65 @@ +/* vfork ABI-compatibility entry points for libpthread. + Copyright (C) 2014-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 + +/* libpthread used to have its own vfork implementation that differed + from libc's only in having a pointless micro-optimization. There + is no longer any use to having a separate copy in libpthread, but + the historical ABI requires it. For static linking, there is no + need to provide anything here--the libc version will be linked in. + For shared library ABI compatibility, there must be __vfork and + vfork symbols in libpthread.so; so we define them using IFUNC to + redirect to the libc function. */ + +/* Note! If the architecture doesn't support IFUNC, then we need an + alternate target-specific mechanism to implement this. So we just + assume IFUNC here and require that the target override this file + if necessary. + + If the architecture can assume all supported versions of gcc will + produce a tail-call to __libc_vfork, consider including the version + in sysdeps/unix/sysv/linux/aarch64/pt-vfork.c. */ + +#if !HAVE_IFUNC +# error "must write pt-vfork for this machine or get IFUNC support" +#endif + +#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \ + || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)) + +extern __typeof (vfork) __libc_vfork; /* Defined in libc. */ + +# undef INIT_ARCH +# define INIT_ARCH() +# define DEFINE_VFORK(name) libc_ifunc (name, &__libc_vfork) + +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) +extern __typeof(vfork) vfork_ifunc; +DEFINE_VFORK (vfork_ifunc) +compat_symbol (libpthread, vfork_ifunc, vfork, GLIBC_2_0); +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20) +extern __typeof(vfork) __vfork_ifunc; +DEFINE_VFORK (__vfork_ifunc) +compat_symbol (libpthread, __vfork_ifunc, __vfork, GLIBC_2_1_2); +#endif diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 00be8f9..13bdb11 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -110,23 +110,19 @@ enum }; #define PTHREAD_MUTEX_PSHARED_BIT 128 -/* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ #define PTHREAD_MUTEX_TYPE(m) \ - (atomic_load_relaxed (&((m)->__data.__kind)) & 127) + ((m)->__data.__kind & 127) /* Don't include NO_ELISION, as that type is always the same as the underlying lock type. */ #define PTHREAD_MUTEX_TYPE_ELISION(m) \ - (atomic_load_relaxed (&((m)->__data.__kind)) \ - & (127 | PTHREAD_MUTEX_ELISION_NP)) + ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP)) #if LLL_PRIVATE == 0 && LLL_SHARED == 128 # define PTHREAD_MUTEX_PSHARED(m) \ - (atomic_load_relaxed (&((m)->__data.__kind)) & 128) + ((m)->__data.__kind & 128) #else # define PTHREAD_MUTEX_PSHARED(m) \ - ((atomic_load_relaxed (&((m)->__data.__kind)) & 128) \ - ? LLL_SHARED : LLL_PRIVATE) + (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE) #endif /* The kernel when waking robust mutexes on exit never uses @@ -406,6 +402,16 @@ extern int __pthread_multiple_threads attribute_hidden; extern int *__libc_multiple_threads_ptr attribute_hidden; #endif +/* Find a thread given its TID. */ +extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden +#ifdef SHARED +; +#else +weak_function; +#define __find_thread_by_id(tid) \ + (__find_thread_by_id ? (__find_thread_by_id) (tid) : (struct pthread *) NULL) +#endif + extern void __pthread_init_static_tls (struct link_map *) attribute_hidden; extern size_t __pthread_get_minstack (const pthread_attr_t *attr); diff --git a/nptl/pthread_clock_gettime.c b/nptl/pthread_clock_gettime.c new file mode 100644 index 0000000..6bc75cf --- /dev/null +++ b/nptl/pthread_clock_gettime.c @@ -0,0 +1,67 @@ +/* Copyright (C) 2001-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; see the file COPYING.LIB. If + not, see . */ + +#include +#include +#include +#include "pthreadP.h" + + +#if HP_TIMING_AVAIL +int +__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, + struct timespec *tp) +{ + hp_timing_t tsc; + + /* Get the current counter. */ + HP_TIMING_NOW (tsc); + + /* This is the ID of the thread we are looking for. */ + pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE; + + /* Compute the offset since the start time of the process. */ + if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid)) + /* Our own clock. */ + tsc -= THREAD_GETMEM (THREAD_SELF, cpuclock_offset); + else + { + /* This is more complicated. We have to locate the thread based + on the ID. This means walking the list of existing + threads. */ + struct pthread *thread = __find_thread_by_id (tid); + if (thread == NULL) + { + __set_errno (EINVAL); + return -1; + } + + /* There is a race here. The thread might terminate and the stack + become unusable. But this is the user's problem. */ + tsc -= thread->cpuclock_offset; + } + + /* Compute the seconds. */ + tp->tv_sec = tsc / freq; + + /* And the nanoseconds. This computation should be stable until + we get machines with about 16GHz frequency. */ + tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq; + + return 0; +} +#endif diff --git a/nptl/pthread_clock_settime.c b/nptl/pthread_clock_settime.c new file mode 100644 index 0000000..29d35c6 --- /dev/null +++ b/nptl/pthread_clock_settime.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2001-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; see the file COPYING.LIB. If + not, see . */ + +#include +#include +#include +#include "pthreadP.h" + + +#if HP_TIMING_AVAIL +int +__pthread_clock_settime (clockid_t clock_id, hp_timing_t offset) +{ + /* This is the ID of the thread we are looking for. */ + pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE; + + /* Compute the offset since the start time of the process. */ + if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid)) + /* Our own clock. */ + THREAD_SETMEM (THREAD_SELF, cpuclock_offset, offset); + else + { + /* This is more complicated. We have to locate the thread based + on the ID. This means walking the list of existing + threads. */ + struct pthread *thread = __find_thread_by_id (tid); + if (thread == NULL) + { + __set_errno (EINVAL); + return -1; + } + + /* There is a race here. The thread might terminate and the stack + become unusable. But this is the user's problem. */ + thread->cpuclock_offset = offset; + } + + return 0; +} +#endif diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c index 479e54f..8e425eb 100644 --- a/nptl/pthread_cond_common.c +++ b/nptl/pthread_cond_common.c @@ -405,12 +405,8 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq, { /* There is still a waiter after spinning. Set the wake-request flag and block. Relaxed MO is fine because this is just about - this futex word. - - Update r to include the set wake-request flag so that the upcoming - futex_wait only blocks if the flag is still set (otherwise, we'd - violate the basic client-side futex protocol). */ - r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1; + this futex word. */ + r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1); if ((r >> 1) > 0) futex_wait_simple (cond->__data.__g_refs + g1, r, private); diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c index ebf07ca..3e11054 100644 --- a/nptl/pthread_cond_wait.c +++ b/nptl/pthread_cond_wait.c @@ -516,7 +516,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec rt; if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0) __libc_fatal ("clock_gettime does not support " - "CLOCK_MONOTONIC\n"); + "CLOCK_MONOTONIC"); /* Convert the absolute timeout value to a relative timeout. */ rt.tv_sec = abstime->tv_sec - rt.tv_sec; diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index f58a15c..fe75d04 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -379,6 +379,13 @@ START_THREAD_DEFN { struct pthread *pd = START_THREAD_SELF; +#if HP_TIMING_AVAIL + /* Remember the time when the thread was started. */ + hp_timing_t now; + HP_TIMING_NOW (now); + THREAD_SETMEM (pd, cpuclock_offset, now); +#endif + /* Initialize resolver state pointer. */ __resp = &pd->res; diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c index 4fbd875..85b8e1a 100644 --- a/nptl/pthread_mutex_consistent.c +++ b/nptl/pthread_mutex_consistent.c @@ -23,11 +23,8 @@ int pthread_mutex_consistent (pthread_mutex_t *mutex) { - /* Test whether this is a robust mutex with a dead owner. - See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - if ((atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 + /* Test whether this is a robust mutex with a dead owner. */ + if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 || mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT) return EINVAL; diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c index 713ea68..5a22611 100644 --- a/nptl/pthread_mutex_destroy.c +++ b/nptl/pthread_mutex_destroy.c @@ -27,17 +27,12 @@ __pthread_mutex_destroy (pthread_mutex_t *mutex) { LIBC_PROBE (mutex_destroy, 1, mutex); - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - if ((atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 + if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 && mutex->__data.__nusers != 0) return EBUSY; - /* Set to an invalid value. Relaxed MO is enough as it is undefined behavior - if the mutex is used after it has been destroyed. But you can reinitialize - it with pthread_mutex_init. */ - atomic_store_relaxed (&(mutex->__data.__kind), -1); + /* Set to an invalid value. */ + mutex->__data.__kind = -1; return 0; } diff --git a/nptl/pthread_mutex_getprioceiling.c b/nptl/pthread_mutex_getprioceiling.c index ee85949..efa37b0 100644 --- a/nptl/pthread_mutex_getprioceiling.c +++ b/nptl/pthread_mutex_getprioceiling.c @@ -24,9 +24,7 @@ int pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling) { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - if (__builtin_expect ((atomic_load_relaxed (&(mutex->__data.__kind)) + if (__builtin_expect ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0, 0)) return EINVAL; diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c index 5cf290c..d8fe473 100644 --- a/nptl/pthread_mutex_init.c +++ b/nptl/pthread_mutex_init.c @@ -101,7 +101,7 @@ __pthread_mutex_init (pthread_mutex_t *mutex, memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T); /* Copy the values from the attribute. */ - int mutex_kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; + mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0) { @@ -111,17 +111,17 @@ __pthread_mutex_init (pthread_mutex_t *mutex, return ENOTSUP; #endif - mutex_kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP; + mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP; } switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK) { case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: - mutex_kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP; + mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP; break; case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: - mutex_kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP; + mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP; int ceiling = (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK) @@ -145,11 +145,7 @@ __pthread_mutex_init (pthread_mutex_t *mutex, FUTEX_PRIVATE_FLAG FUTEX_WAKE. */ if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED | PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0) - mutex_kind |= PTHREAD_MUTEX_PSHARED_BIT; - - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - atomic_store_relaxed (&(mutex->__data.__kind), mutex_kind); + mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT; /* Default values: mutex not used yet. */ // mutex->__count = 0; already done by memset diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c index 29cc143..1519c14 100644 --- a/nptl/pthread_mutex_lock.c +++ b/nptl/pthread_mutex_lock.c @@ -62,8 +62,6 @@ static int __pthread_mutex_lock_full (pthread_mutex_t *mutex) int __pthread_mutex_lock (pthread_mutex_t *mutex) { - /* See concurrency notes regarding mutex type which is loaded from __kind - in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); LIBC_PROBE (mutex_entry, 1, mutex); @@ -352,14 +350,8 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: { - int kind, robust; - { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); - kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; - robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; - } + int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; + int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; if (robust) { @@ -510,10 +502,7 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) case PTHREAD_MUTEX_PP_NORMAL_NP: case PTHREAD_MUTEX_PP_ADAPTIVE_NP: { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int kind = atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_KIND_MASK_NP; + int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; oldval = mutex->__data.__lock; @@ -618,18 +607,15 @@ hidden_def (__pthread_mutex_lock) void __pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex) { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); - assert ((mutex_kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0); - assert ((mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0); - assert ((mutex_kind & PTHREAD_MUTEX_PSHARED_BIT) == 0); + assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0); + assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0); + assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0); /* Record the ownership. */ pid_t id = THREAD_GETMEM (THREAD_SELF, tid); mutex->__data.__owner = id; - if (mutex_kind == PTHREAD_MUTEX_PI_RECURSIVE_NP) + if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP) ++mutex->__data.__count; } #endif diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c index 8306cab..8594874 100644 --- a/nptl/pthread_mutex_setprioceiling.c +++ b/nptl/pthread_mutex_setprioceiling.c @@ -27,10 +27,9 @@ int pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling, int *old_ceiling) { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - if ((atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0) + /* The low bits of __kind aren't ever changed after pthread_mutex_init, + so we don't need a lock yet. */ + if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0) return EINVAL; /* See __init_sched_fifo_prio. */ diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index 888c12f..28237b0 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -53,8 +53,6 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, /* We must not check ABSTIME here. If the thread does not block abstime must not be checked for a valid value. */ - /* See concurrency notes regarding mutex type which is loaded from __kind - in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), PTHREAD_MUTEX_TIMED_NP)) { @@ -340,14 +338,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: { - int kind, robust; - { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); - kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; - robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; - } + int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; + int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; if (robust) { @@ -517,10 +509,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, case PTHREAD_MUTEX_PP_NORMAL_NP: case PTHREAD_MUTEX_PP_ADAPTIVE_NP: { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int kind = atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_KIND_MASK_NP; + int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; oldval = mutex->__data.__lock; diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c index 8e01113..7de61f4 100644 --- a/nptl/pthread_mutex_trylock.c +++ b/nptl/pthread_mutex_trylock.c @@ -36,8 +36,6 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) int oldval; pid_t id = THREAD_GETMEM (THREAD_SELF, tid); - /* See concurrency notes regarding mutex type which is loaded from __kind - in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), PTHREAD_MUTEX_TIMED_NP)) { @@ -94,9 +92,6 @@ __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 @@ -122,12 +117,7 @@ __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 @@ -143,8 +133,6 @@ __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; @@ -152,8 +140,6 @@ __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); @@ -172,9 +158,6 @@ __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; @@ -188,20 +171,13 @@ __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; @@ -223,25 +199,14 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: { - int kind, robust; - { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); - kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; - robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; - } + int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; + int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; if (robust) - { - /* Note: robust PI futexes are signaled by setting bit 0. */ - THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, - (void *) (((uintptr_t) &mutex->__data.__list.__next) - | 1)); - /* We need to set op_pending before starting the operation. Also - see comments at ENQUEUE_MUTEX. */ - __asm ("" ::: "memory"); - } + /* 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)); oldval = mutex->__data.__lock; @@ -250,16 +215,12 @@ __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. */ @@ -281,9 +242,6 @@ __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; @@ -304,9 +262,6 @@ __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; @@ -324,12 +279,7 @@ __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 @@ -352,20 +302,13 @@ __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); } @@ -382,10 +325,7 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) case PTHREAD_MUTEX_PP_NORMAL_NP: case PTHREAD_MUTEX_PP_ADAPTIVE_NP: { - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int kind = atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_KIND_MASK_NP; + int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; oldval = mutex->__data.__lock; diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c index 68d04d5..9ea6294 100644 --- a/nptl/pthread_mutex_unlock.c +++ b/nptl/pthread_mutex_unlock.c @@ -35,8 +35,6 @@ int attribute_hidden __pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr) { - /* See concurrency notes regarding mutex type which is loaded from __kind - in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); if (__builtin_expect (type & ~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0)) @@ -224,19 +222,13 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) /* If the previous owner died and the caller did not succeed in making the state consistent, mark the mutex as unrecoverable and make all waiters. */ - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - if ((atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0 + if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0 && __builtin_expect (mutex->__data.__owner == PTHREAD_MUTEX_INCONSISTENT, 0)) pi_notrecoverable: newowner = PTHREAD_MUTEX_NOTRECOVERABLE; - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - if ((atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0) + if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0) { continue_pi_robust: /* Remove mutex from the list. @@ -259,10 +251,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) /* Unlock. Load all necessary mutex data before releasing the mutex to not violate the mutex destruction requirements (see lll_unlock). */ - /* See concurrency notes regarding __kind in struct __pthread_mutex_s - in sysdeps/nptl/bits/thread-shared-types.h. */ - int robust = atomic_load_relaxed (&(mutex->__data.__kind)) - & PTHREAD_MUTEX_ROBUST_NORMAL_NP; + int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; private = (robust ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex) : PTHREAD_MUTEX_PSHARED (mutex)); diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c index 85fc1bc..a290d08 100644 --- a/nptl/pthread_rwlock_common.c +++ b/nptl/pthread_rwlock_common.c @@ -34,7 +34,7 @@ A thread is allowed to acquire a read lock recursively (i.e., have rdlock critical sections that overlap in sequenced-before) unless the kind of the - rwlock is set to PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP. + rwlock is set to PTHREAD_RWLOCK_PREFER_WRITERS_NONRECURSIVE_NP. This lock is built so that workloads of mostly readers can be executed with low runtime overheads. This matches that the default kind of the lock is @@ -46,7 +46,7 @@ An uncontended write lock acquisition is as fast as for a normal exclusive mutex but writer contention is somewhat more costly due to keeping track of the exact number of writers. If the rwlock kind requests - writers to be preferred (i.e., PTHREAD_RWLOCK_PREFER_WRITER_NP or the + writers to be preferred (i.e., PTHREAD_RWLOCK_PREFER_WRITERS_NP or the no-recursive-readers variant of it), then writer--to--writer lock ownership hand-over is fairly fast and bypasses lock acquisition attempts by readers. The costs of lock ownership transfer between readers and writers vary. If @@ -251,7 +251,7 @@ __pthread_rwlock_rdunlock (pthread_rwlock_t *rwlock) the first reader's store to __wrphase_futex (or a later value) if the writer observes that a write phase has been started. */ if (atomic_compare_exchange_weak_release (&rwlock->__data.__readers, - &r, rnew)) + &r, rnew)) break; /* TODO Back-off. */ } @@ -285,7 +285,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, /* Make sure we are not holding the rwlock as a writer. This is a deadlock situation we recognize and report. */ if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer) - == THREAD_GETMEM (THREAD_SELF, tid))) + == THREAD_GETMEM (THREAD_SELF, tid))) return EDEADLK; /* If we prefer writers, recursive rdlock is disallowed, we are in a read @@ -299,9 +299,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, if (rwlock->__data.__flags == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) { r = atomic_load_relaxed (&rwlock->__data.__readers); - while ((r & PTHREAD_RWLOCK_WRPHASE) == 0 - && (r & PTHREAD_RWLOCK_WRLOCKED) != 0 - && (r >> PTHREAD_RWLOCK_READER_SHIFT) > 0) + while (((r & PTHREAD_RWLOCK_WRPHASE) == 0) + && ((r & PTHREAD_RWLOCK_WRLOCKED) != 0) + && ((r >> PTHREAD_RWLOCK_READER_SHIFT) > 0)) { /* TODO Spin first. */ /* Try setting the flag signaling that we are waiting without having @@ -314,12 +314,12 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, harmless because the flag is just about the state of __readers, and all threads set the flag under the same conditions. */ - while (((r = atomic_load_relaxed (&rwlock->__data.__readers)) - & PTHREAD_RWLOCK_RWAITING) != 0) + while ((atomic_load_relaxed (&rwlock->__data.__readers) + & PTHREAD_RWLOCK_RWAITING) != 0) { int private = __pthread_rwlock_get_private (rwlock); int err = futex_abstimed_wait (&rwlock->__data.__readers, - r, abstime, private); + r, abstime, private); /* We ignore EAGAIN and EINTR. On time-outs, we can just return because we don't need to clean up anything. */ if (err == ETIMEDOUT) @@ -338,9 +338,8 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, expected value for future operations. Acquire MO so we synchronize with prior writers as well as the last reader of the previous read phase (see below). */ - r = (atomic_fetch_add_acquire (&rwlock->__data.__readers, - (1 << PTHREAD_RWLOCK_READER_SHIFT)) - + (1 << PTHREAD_RWLOCK_READER_SHIFT)); + r = atomic_fetch_add_acquire (&rwlock->__data.__readers, + (1 << PTHREAD_RWLOCK_READER_SHIFT)) + (1 << PTHREAD_RWLOCK_READER_SHIFT); /* Check whether there is an overflow in the number of readers. We assume that the total number of threads is less than half the maximum number @@ -360,9 +359,8 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, /* Relaxed MO is okay because we just want to undo our registration and cannot have changed the rwlock state substantially if the CAS succeeds. */ - if (atomic_compare_exchange_weak_relaxed - (&rwlock->__data.__readers, - &r, r - (1 << PTHREAD_RWLOCK_READER_SHIFT))) + if (atomic_compare_exchange_weak_relaxed (&rwlock->__data.__readers, &r, + r - (1 << PTHREAD_RWLOCK_READER_SHIFT))) return EAGAIN; } @@ -380,15 +378,15 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, /* Otherwise, if we were in a write phase (states #6 or #8), we must wait for explicit hand-over of the read phase; the only exception is if we can start a read phase if there is no primary writer currently. */ - while ((r & PTHREAD_RWLOCK_WRPHASE) != 0 - && (r & PTHREAD_RWLOCK_WRLOCKED) == 0) + while (((r & PTHREAD_RWLOCK_WRPHASE) != 0) + && ((r & PTHREAD_RWLOCK_WRLOCKED) == 0)) { - /* Try to enter a read phase: If the CAS below succeeds, we have + /* Try to enter a read phase: If the CAS below succeeds, we have ownership; if it fails, we will simply retry and reassess the situation. Acquire MO so we synchronize with prior writers. */ if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r, - r ^ PTHREAD_RWLOCK_WRPHASE)) + r ^ PTHREAD_RWLOCK_WRPHASE)) { /* We started the read phase, so we are also responsible for updating the write-phase futex. Relaxed MO is sufficient. @@ -399,7 +397,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, (but we can pretend to do the setting and unsetting of WRLOCKED atomically, and thus can skip this step). */ if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) - & PTHREAD_RWLOCK_FUTEX_USED) != 0) + & PTHREAD_RWLOCK_FUTEX_USED) != 0) { int private = __pthread_rwlock_get_private (rwlock); futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); @@ -437,17 +435,16 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, for (;;) { while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) - | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) + | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) { int private = __pthread_rwlock_get_private (rwlock); if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) - && (!atomic_compare_exchange_weak_relaxed + && !atomic_compare_exchange_weak_relaxed (&rwlock->__data.__wrphase_futex, - &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))) + &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)) continue; int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, - 1 | PTHREAD_RWLOCK_FUTEX_USED, - abstime, private); + 1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private); if (err == ETIMEDOUT) { /* If we timed out, we need to unregister. If no read phase @@ -480,8 +477,8 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, in this case and thus make the spin-waiting we need unnecessarily expensive. */ while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex) - | PTHREAD_RWLOCK_FUTEX_USED) - == (1 | PTHREAD_RWLOCK_FUTEX_USED)) + | PTHREAD_RWLOCK_FUTEX_USED) + == (1 | PTHREAD_RWLOCK_FUTEX_USED)) { /* TODO Back-off? */ } @@ -498,7 +495,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock, release of the writer, and so that we observe a recent value of __wrphase_futex (see below). */ if ((atomic_load_acquire (&rwlock->__data.__readers) - & PTHREAD_RWLOCK_WRPHASE) == 0) + & PTHREAD_RWLOCK_WRPHASE) == 0) /* We are in a read phase now, so the least recent modification of __wrphase_futex we can read from is the store by the writer with value 1. Thus, only now we can assume that if we observe @@ -519,9 +516,8 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock) atomic_store_relaxed (&rwlock->__data.__cur_writer, 0); /* Disable waiting by writers. We will wake up after we decided how to proceed. */ - bool wake_writers - = ((atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0) - & PTHREAD_RWLOCK_FUTEX_USED) != 0); + bool wake_writers = ((atomic_exchange_relaxed + (&rwlock->__data.__writers_futex, 0) & PTHREAD_RWLOCK_FUTEX_USED) != 0); if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP) { @@ -533,8 +529,8 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock) synchronize with us and thus can take over our view of __readers (including, for example, whether we are in a write phase or not). */ - if (atomic_compare_exchange_weak_release - (&rwlock->__data.__writers, &w, w | PTHREAD_RWLOCK_WRHANDOVER)) + if (atomic_compare_exchange_weak_release (&rwlock->__data.__writers, + &w, w | PTHREAD_RWLOCK_WRHANDOVER)) /* Another writer will take over. */ goto done; /* TODO Back-off. */ @@ -547,10 +543,9 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock) unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); /* Release MO so that subsequent readers or writers synchronize with us. */ while (!atomic_compare_exchange_weak_release - (&rwlock->__data.__readers, &r, - ((r ^ PTHREAD_RWLOCK_WRLOCKED) - ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 - : PTHREAD_RWLOCK_WRPHASE)))) + (&rwlock->__data.__readers, &r, (r ^ PTHREAD_RWLOCK_WRLOCKED) + ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 + : PTHREAD_RWLOCK_WRPHASE))) { /* TODO Back-off. */ } @@ -579,7 +574,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, /* Make sure we are not holding the rwlock as a writer. This is a deadlock situation we recognize and report. */ if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer) - == THREAD_GETMEM (THREAD_SELF, tid))) + == THREAD_GETMEM (THREAD_SELF, tid))) return EDEADLK; /* First we try to acquire the role of primary writer by setting WRLOCKED; @@ -598,12 +593,12 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, this could be less scalable if readers arrive and leave frequently. */ bool may_share_futex_used_flag = false; unsigned int r = atomic_fetch_or_acquire (&rwlock->__data.__readers, - PTHREAD_RWLOCK_WRLOCKED); + PTHREAD_RWLOCK_WRLOCKED); if (__glibc_unlikely ((r & PTHREAD_RWLOCK_WRLOCKED) != 0)) { /* There is another primary writer. */ - bool prefer_writer - = (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP); + bool prefer_writer = + (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP); if (prefer_writer) { /* We register as a waiting writer, so that we can make use of @@ -622,7 +617,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, /* Try to become the primary writer or retry. Acquire MO as in the fetch_or above. */ if (atomic_compare_exchange_weak_acquire - (&rwlock->__data.__readers, &r, r | PTHREAD_RWLOCK_WRLOCKED)) + (&rwlock->__data.__readers, &r, + r | PTHREAD_RWLOCK_WRLOCKED)) { if (prefer_writer) { @@ -637,7 +633,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, __writers). ??? Perhaps this is not strictly necessary for reasons we do not yet know of. */ - atomic_fetch_add_relaxed (&rwlock->__data.__writers, -1); + atomic_fetch_add_relaxed (&rwlock->__data.__writers, + -1); } break; } @@ -649,7 +646,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, succeed, we own WRLOCKED. */ if (prefer_writer) { - unsigned int w = atomic_load_relaxed (&rwlock->__data.__writers); + unsigned int w = atomic_load_relaxed + (&rwlock->__data.__writers); if ((w & PTHREAD_RWLOCK_WRHANDOVER) != 0) { /* Acquire MO is required here so that we synchronize with @@ -679,13 +677,13 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, /* We did not acquire WRLOCKED nor were able to use writer--writer hand-over, so we block on __writers_futex. */ int private = __pthread_rwlock_get_private (rwlock); - unsigned int wf - = atomic_load_relaxed (&rwlock->__data.__writers_futex); + unsigned int wf = atomic_load_relaxed + (&rwlock->__data.__writers_futex); if (((wf & ~(unsigned int) PTHREAD_RWLOCK_FUTEX_USED) != 1) || ((wf != (1 | PTHREAD_RWLOCK_FUTEX_USED)) - && (!atomic_compare_exchange_weak_relaxed + && !atomic_compare_exchange_weak_relaxed (&rwlock->__data.__writers_futex, &wf, - 1 | PTHREAD_RWLOCK_FUTEX_USED)))) + 1 | PTHREAD_RWLOCK_FUTEX_USED))) { /* If we cannot block on __writers_futex because there is no primary writer, or we cannot set PTHREAD_RWLOCK_FUTEX_USED, @@ -706,8 +704,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, in this group. */ may_share_futex_used_flag = true; int err = futex_abstimed_wait (&rwlock->__data.__writers_futex, - 1 | PTHREAD_RWLOCK_FUTEX_USED, - abstime, private); + 1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private); if (err == ETIMEDOUT) { if (prefer_writer) @@ -719,10 +716,10 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, that this happened before the timeout; see pthread_rwlock_rdlock_full for the full reasoning.) Also see the similar code above. */ - unsigned int w - = atomic_load_relaxed (&rwlock->__data.__writers); + unsigned int w = atomic_load_relaxed + (&rwlock->__data.__writers); while (!atomic_compare_exchange_weak_acquire - (&rwlock->__data.__writers, &w, + (&rwlock->__data.__writers, &w, (w == PTHREAD_RWLOCK_WRHANDOVER + 1 ? 0 : w - 1))) { /* TODO Back-off. */ @@ -754,8 +751,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, modifications of __readers ensures that this store happens after the store of value 0 by the previous primary writer. */ atomic_store_relaxed (&rwlock->__data.__writers_futex, - 1 | (may_share_futex_used_flag - ? PTHREAD_RWLOCK_FUTEX_USED : 0)); + 1 | (may_share_futex_used_flag ? PTHREAD_RWLOCK_FUTEX_USED : 0)); /* If we are in a write phase, we have acquired the lock. */ if ((r & PTHREAD_RWLOCK_WRPHASE) != 0) @@ -763,15 +759,15 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, /* If we are in a read phase and there are no readers, try to start a write phase. */ - while ((r & PTHREAD_RWLOCK_WRPHASE) == 0 - && (r >> PTHREAD_RWLOCK_READER_SHIFT) == 0) + while (((r & PTHREAD_RWLOCK_WRPHASE) == 0) + && ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)) { /* Acquire MO so that we synchronize with prior writers and do not interfere with their updates to __writers_futex, as well as regarding prior readers and their updates to __wrphase_futex, respectively. */ if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, - &r, r | PTHREAD_RWLOCK_WRPHASE)) + &r, r | PTHREAD_RWLOCK_WRPHASE)) { /* We have started a write phase, so need to enable readers to wait. See the similar case in __pthread_rwlock_rdlock_full. Unlike in @@ -796,24 +792,24 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, for (;;) { while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) - | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED) + | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED) { int private = __pthread_rwlock_get_private (rwlock); - if ((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0 - && (!atomic_compare_exchange_weak_relaxed + if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) + && !atomic_compare_exchange_weak_relaxed (&rwlock->__data.__wrphase_futex, &wpf, - PTHREAD_RWLOCK_FUTEX_USED))) + PTHREAD_RWLOCK_FUTEX_USED)) continue; int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, - PTHREAD_RWLOCK_FUTEX_USED, - abstime, private); + PTHREAD_RWLOCK_FUTEX_USED, abstime, private); if (err == ETIMEDOUT) { - if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP) + if (rwlock->__data.__flags + != PTHREAD_RWLOCK_PREFER_READER_NP) { /* We try writer--writer hand-over. */ - unsigned int w - = atomic_load_relaxed (&rwlock->__data.__writers); + unsigned int w = atomic_load_relaxed + (&rwlock->__data.__writers); if (w != 0) { /* We are about to hand over WRLOCKED, so we must @@ -827,13 +823,13 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, Release MO so that another writer that gets WRLOCKED from us can take over our view of __readers. */ - unsigned int wf - = atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0); + unsigned int wf = atomic_exchange_relaxed + (&rwlock->__data.__writers_futex, 0); while (w != 0) { if (atomic_compare_exchange_weak_release (&rwlock->__data.__writers, &w, - w | PTHREAD_RWLOCK_WRHANDOVER)) + w | PTHREAD_RWLOCK_WRHANDOVER)) { /* Wake other writers. */ if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0) @@ -848,7 +844,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, again. Make sure we don't loose the flag that signals whether there are threads waiting on this futex. */ - atomic_store_relaxed (&rwlock->__data.__writers_futex, wf); + atomic_store_relaxed + (&rwlock->__data.__writers_futex, wf); } } /* If we timed out and we are not in a write phase, we can @@ -860,8 +857,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, /* We are about to release WRLOCKED, so we must release __writers_futex too; see the handling of writer--writer hand-over above. */ - unsigned int wf - = atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0); + unsigned int wf = atomic_exchange_relaxed + (&rwlock->__data.__writers_futex, 0); while ((r & PTHREAD_RWLOCK_WRPHASE) == 0) { /* While we don't need to make anything from a @@ -880,11 +877,11 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, /* Wake other writers. */ if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0) futex_wake (&rwlock->__data.__writers_futex, - 1, private); + 1, private); /* Wake waiting readers. */ if ((r & PTHREAD_RWLOCK_RWAITING) != 0) futex_wake (&rwlock->__data.__readers, - INT_MAX, private); + INT_MAX, private); return ETIMEDOUT; } } @@ -901,9 +898,10 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, atomic_thread_fence_acquire (); /* We still need to wait for explicit hand-over, but we must not use futex_wait anymore. */ - while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex) - | PTHREAD_RWLOCK_FUTEX_USED) - == PTHREAD_RWLOCK_FUTEX_USED) + while ((atomic_load_relaxed + (&rwlock->__data.__wrphase_futex) + | PTHREAD_RWLOCK_FUTEX_USED) + == PTHREAD_RWLOCK_FUTEX_USED) { /* TODO Back-off. */ } @@ -917,12 +915,12 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock, if (ready) break; if ((atomic_load_acquire (&rwlock->__data.__readers) - & PTHREAD_RWLOCK_WRPHASE) != 0) + & PTHREAD_RWLOCK_WRPHASE) != 0) ready = true; } done: atomic_store_relaxed (&rwlock->__data.__cur_writer, - THREAD_GETMEM (THREAD_SELF, tid)); + THREAD_GETMEM (THREAD_SELF, tid)); return 0; } diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c index 31a88d3..4aec1fc 100644 --- a/nptl/pthread_rwlock_tryrdlock.c +++ b/nptl/pthread_rwlock_tryrdlock.c @@ -94,22 +94,15 @@ __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. - 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); - } + 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); } return 0; diff --git a/nptl/pthread_rwlock_trywrlock.c b/nptl/pthread_rwlock_trywrlock.c index f2e3443..5a73eba 100644 --- a/nptl/pthread_rwlock_trywrlock.c +++ b/nptl/pthread_rwlock_trywrlock.c @@ -46,15 +46,8 @@ __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); - /* 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.__wrphase_futex, 1); atomic_store_relaxed (&rwlock->__data.__cur_writer, THREAD_GETMEM (THREAD_SELF, tid)); return 0; diff --git a/nptl/register-atfork.c b/nptl/register-atfork.c index 9edb7d4..5ff1c1b 100644 --- a/nptl/register-atfork.c +++ b/nptl/register-atfork.c @@ -107,14 +107,13 @@ __unregister_atfork (void *dso_handle) } void -__run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking) +__run_fork_handlers (enum __run_fork_handler_type who) { struct fork_handler *runp; if (who == atfork_run_prepare) { - if (do_locking) - lll_lock (atfork_lock, LLL_PRIVATE); + lll_lock (atfork_lock, LLL_PRIVATE); size_t sl = fork_handler_list_size (&fork_handlers); for (size_t i = sl; i > 0; i--) { @@ -134,8 +133,7 @@ __run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking) else if (who == atfork_run_parent && runp->parent_handler) runp->parent_handler (); } - if (do_locking) - lll_unlock (atfork_lock, LLL_PRIVATE); + lll_unlock (atfork_lock, LLL_PRIVATE); } } diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c deleted file mode 100644 index 615d5ee..0000000 --- a/nptl/tst-audit-threads-mod1.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Dummy audit library for test-audit-threads. - - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include - -/* We must use a dummy LD_AUDIT module to force the dynamic loader to - *not* update the real PLT, and instead use a cached value for the - lazy resolution result. It is the update of that cached value that - we are testing for correctness by doing this. */ - -/* Library to be audited. */ -#define LIB "tst-audit-threads-mod2.so" -/* CALLNUM is the number of retNum functions. */ -#define CALLNUM 7999 - -#define CONCATX(a, b) __CONCAT (a, b) - -static int previous = 0; - -unsigned int -la_version (unsigned int ver) -{ - return 1; -} - -unsigned int -la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie) -{ - return LA_FLG_BINDTO | LA_FLG_BINDFROM; -} - -uintptr_t -CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym, - unsigned int ndx, - uintptr_t *refcook, - uintptr_t *defcook, - unsigned int *flags, - const char *symname) -{ - const char * retnum = "retNum"; - char * num = strstr (symname, retnum); - int n; - /* Validate if the symbols are getting called in the correct order. - This code is here to verify binutils does not optimize out the PLT - entries that require the symbol binding. */ - if (num != NULL) - { - n = atoi (num); - assert (n >= previous); - assert (n <= CALLNUM); - previous = n; - } - return sym->st_value; -} diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c deleted file mode 100644 index f9817dd..0000000 --- a/nptl/tst-audit-threads-mod2.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Shared object with a huge number of functions for test-audit-threads. - - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* Define all the retNumN functions in a library. */ -#define definenum -#include "tst-audit-threads.h" diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c deleted file mode 100644 index e4bf433..0000000 --- a/nptl/tst-audit-threads.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Test multi-threading using LD_AUDIT. - - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a - library with a huge number of functions in order to validate lazy symbol - binding with an audit library. We use one thread per CPU to test that - concurrent lazy resolution does not have any defects which would cause - the process to fail. We use an LD_AUDIT library to force the testing of - the relocation resolution caching code in the dynamic loader i.e. - _dl_runtime_profile and _dl_profile_fixup. */ - -#include -#include -#include -#include - -static int do_test (void); - -/* This test usually takes less than 3s to run. However, there are cases that - take up to 30s. */ -#define TIMEOUT 60 -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" - -/* Declare the functions we are going to call. */ -#define externnum -#include "tst-audit-threads.h" -#undef externnum - -int num_threads; -pthread_barrier_t barrier; - -void -sync_all (int num) -{ - pthread_barrier_wait (&barrier); -} - -void -call_all_ret_nums (void) -{ - /* Call each function one at a time from all threads. */ -#define callnum -#include "tst-audit-threads.h" -#undef callnum -} - -void * -thread_main (void *unused) -{ - call_all_ret_nums (); - return NULL; -} - -#define STR2(X) #X -#define STR(X) STR2(X) - -static int -do_test (void) -{ - int i; - pthread_t *threads; - - num_threads = get_nprocs (); - if (num_threads <= 1) - num_threads = 2; - - /* Used to synchronize all the threads after calling each retNumN. */ - xpthread_barrier_init (&barrier, NULL, num_threads); - - threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t)); - for (i = 0; i < num_threads; i++) - threads[i] = xpthread_create(NULL, thread_main, NULL); - - for (i = 0; i < num_threads; i++) - xpthread_join(threads[i]); - - free (threads); - - return 0; -} diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h deleted file mode 100644 index 1c9ecc0..0000000 --- a/nptl/tst-audit-threads.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Helper header for test-audit-threads. - - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* We use this helper to create a large number of functions, all of - which will be resolved lazily and thus have their PLT updated. - This is done to provide enough functions that we can statistically - observe a thread vs. PLT resolution failure if one exists. */ - -#define CONCAT(a, b) a ## b -#define NUM(x, y) CONCAT (x, y) - -#define FUNC10(x) \ - FUNC (NUM (x, 0)); \ - FUNC (NUM (x, 1)); \ - FUNC (NUM (x, 2)); \ - FUNC (NUM (x, 3)); \ - FUNC (NUM (x, 4)); \ - FUNC (NUM (x, 5)); \ - FUNC (NUM (x, 6)); \ - FUNC (NUM (x, 7)); \ - FUNC (NUM (x, 8)); \ - FUNC (NUM (x, 9)) - -#define FUNC100(x) \ - FUNC10 (NUM (x, 0)); \ - FUNC10 (NUM (x, 1)); \ - FUNC10 (NUM (x, 2)); \ - FUNC10 (NUM (x, 3)); \ - FUNC10 (NUM (x, 4)); \ - FUNC10 (NUM (x, 5)); \ - FUNC10 (NUM (x, 6)); \ - FUNC10 (NUM (x, 7)); \ - FUNC10 (NUM (x, 8)); \ - FUNC10 (NUM (x, 9)) - -#define FUNC1000(x) \ - FUNC100 (NUM (x, 0)); \ - FUNC100 (NUM (x, 1)); \ - FUNC100 (NUM (x, 2)); \ - FUNC100 (NUM (x, 3)); \ - FUNC100 (NUM (x, 4)); \ - FUNC100 (NUM (x, 5)); \ - FUNC100 (NUM (x, 6)); \ - FUNC100 (NUM (x, 7)); \ - FUNC100 (NUM (x, 8)); \ - FUNC100 (NUM (x, 9)) - -#define FUNC7000() \ - FUNC1000 (1); \ - FUNC1000 (2); \ - FUNC1000 (3); \ - FUNC1000 (4); \ - FUNC1000 (5); \ - FUNC1000 (6); \ - FUNC1000 (7); - -#ifdef FUNC -# undef FUNC -#endif - -#ifdef externnum -# define FUNC(x) extern int CONCAT (retNum, x) (void) -#endif - -#ifdef definenum -# define FUNC(x) int CONCAT (retNum, x) (void) { return x; } -#endif - -#ifdef callnum -# define FUNC(x) CONCAT (retNum, x) (); sync_all (x) -#endif - -/* A value of 7000 functions is chosen as an arbitrarily large - number of functions that will allow us enough attempts to - verify lazy resolution operation. */ -FUNC7000 (); diff --git a/nptl/tst-mutex10.c b/nptl/tst-mutex10.c deleted file mode 100644 index e1113ca..0000000 --- a/nptl/tst-mutex10.c +++ /dev/null @@ -1,109 +0,0 @@ -/* Testing race while enabling lock elision. - 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 -#include -#include -#include -#include -#include -#include -#include - -static pthread_barrier_t barrier; -static pthread_mutex_t mutex; -static long long int iteration_count = 1000000; -static unsigned int thread_count = 3; - -static void * -thr_func (void *arg) -{ - long long int i; - for (i = 0; i < iteration_count; i++) - { - if ((uintptr_t) arg == 0) - { - xpthread_mutex_destroy (&mutex); - xpthread_mutex_init (&mutex, NULL); - } - - xpthread_barrier_wait (&barrier); - - /* Test if enabling lock elision works if it is enabled concurrently. - There was a race in FORCE_ELISION macro which leads to either - pthread_mutex_destroy returning EBUSY as the owner was recorded - by pthread_mutex_lock - in "normal mutex" code path - but was not - resetted in pthread_mutex_unlock - in "elision" code path. - Or it leads to the assertion in nptl/pthread_mutex_lock.c: - assert (mutex->__data.__owner == 0); - Please ensure that the test is run with lock elision: - export GLIBC_TUNABLES=glibc.elision.enable=1 */ - xpthread_mutex_lock (&mutex); - xpthread_mutex_unlock (&mutex); - - xpthread_barrier_wait (&barrier); - } - return NULL; -} - -static int -do_test (void) -{ - unsigned int i; - printf ("Starting %d threads to run %lld iterations.\n", - thread_count, iteration_count); - - pthread_t *threads = xmalloc (thread_count * sizeof (pthread_t)); - xpthread_barrier_init (&barrier, NULL, thread_count); - xpthread_mutex_init (&mutex, NULL); - - for (i = 0; i < thread_count; i++) - threads[i] = xpthread_create (NULL, thr_func, (void *) (uintptr_t) i); - - for (i = 0; i < thread_count; i++) - xpthread_join (threads[i]); - - xpthread_barrier_destroy (&barrier); - free (threads); - - return EXIT_SUCCESS; -} - -#define OPT_ITERATIONS 10000 -#define OPT_THREADS 10001 -#define CMDLINE_OPTIONS \ - { "iterations", required_argument, NULL, OPT_ITERATIONS }, \ - { "threads", required_argument, NULL, OPT_THREADS }, -static void -cmdline_process (int c) -{ - long long int arg = strtoll (optarg, NULL, 0); - switch (c) - { - case OPT_ITERATIONS: - if (arg > 0) - iteration_count = arg; - break; - case OPT_THREADS: - if (arg > 0 && arg < 100) - thread_count = arg; - break; - } -} -#define CMDLINE_PROCESS cmdline_process -#define TIMEOUT 50 -#include diff --git a/nptl/tst-rwlock-pwn.c b/nptl/tst-rwlock-pwn.c deleted file mode 100644 index c39dd70..0000000 --- a/nptl/tst-rwlock-pwn.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Test rwlock with PREFER_WRITER_NONRECURSIVE_NP (bug 23861). - 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 -#include -#include -#include -#include - -/* We choose 10 iterations because this happens to be able to trigger the - stall on contemporary hardware. */ -#define LOOPS 10 -/* We need 3 threads to trigger bug 23861. One thread as a writer, and - two reader threads. The test verifies that the second-to-last reader - is able to notify the *last* reader that it should be done waiting. - If the second-to-last reader fails to notify the last reader or does - so incorrectly then the last reader may stall indefinitely. */ -#define NTHREADS 3 - -_Atomic int do_exit; -pthread_rwlockattr_t mylock_attr; -pthread_rwlock_t mylock; - -void * -run_loop (void *a) -{ - while (!do_exit) - { - if (random () & 1) - { - xpthread_rwlock_wrlock (&mylock); - xpthread_rwlock_unlock (&mylock); - } - else - { - xpthread_rwlock_rdlock (&mylock); - xpthread_rwlock_unlock (&mylock); - } - } - return NULL; -} - -int -do_test (void) -{ - xpthread_rwlockattr_init (&mylock_attr); - xpthread_rwlockattr_setkind_np (&mylock_attr, - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - xpthread_rwlock_init (&mylock, &mylock_attr); - - for (int n = 0; n < LOOPS; n++) - { - pthread_t tids[NTHREADS]; - do_exit = 0; - for (int i = 0; i < NTHREADS; i++) - tids[i] = xpthread_create (NULL, run_loop, NULL); - /* Let the threads run for some time. */ - sleep (1); - printf ("Exiting..."); - fflush (stdout); - do_exit = 1; - for (int i = 0; i < NTHREADS; i++) - xpthread_join (tids[i]); - printf ("done.\n"); - } - pthread_rwlock_destroy (&mylock); - pthread_rwlockattr_destroy (&mylock_attr); - return 0; -} - -#define TIMEOUT (DEFAULT_TIMEOUT + 3 * LOOPS) -#include diff --git a/nptl/tst-rwlock-tryrdlock-stall.c b/nptl/tst-rwlock-tryrdlock-stall.c deleted file mode 100644 index 5e476da..0000000 --- a/nptl/tst-rwlock-tryrdlock-stall.c +++ /dev/null @@ -1,355 +0,0 @@ -/* 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 deleted file mode 100644 index 14d27cb..0000000 --- a/nptl/tst-rwlock-trywrlock-stall.c +++ /dev/null @@ -1,108 +0,0 @@ -/* 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/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c index 073e6c9..d6fda87 100644 --- a/nptl/tst-rwlock14.c +++ b/nptl/tst-rwlock14.c @@ -117,15 +117,15 @@ do_test (void) result = 1; } - e = pthread_rwlock_timedwrlock (&r, &ts); + e = pthread_rwlock_timedrdlock (&r, &ts); if (e == 0) { - puts ("second rwlock_timedwrlock did not fail"); + puts ("second rwlock_timedrdlock did not fail"); result = 1; } else if (e != EINVAL) { - puts ("second rwlock_timedwrlock did not return EINVAL"); + puts ("second rwlock_timedrdlock did not return EINVAL"); result = 1; } @@ -145,15 +145,15 @@ do_test (void) result = 1; } - e = pthread_rwlock_timedwrlock (&r, &ts); + e = pthread_rwlock_timedrdlock (&r, &ts); if (e == 0) { - puts ("third rwlock_timedwrlock did not fail"); + puts ("third rwlock_timedrdlock did not fail"); result = 1; } else if (e != EINVAL) { - puts ("third rwlock_timedwrlock did not return EINVAL"); + puts ("third rwlock_timedrdlock did not return EINVAL"); result = 1; } diff --git a/nptl/tst-tls1.c b/nptl/tst-tls1.c index 573dd37..1295170 100644 --- a/nptl/tst-tls1.c +++ b/nptl/tst-tls1.c @@ -19,16 +19,12 @@ #include #include #include -#include -#include -#include -#include -#include + struct test_s { - __attribute__ ((aligned(0x20))) int a; - __attribute__ ((aligned(0x200))) int b; + int a; + int b; }; #define INIT_A 1 @@ -40,34 +36,15 @@ __thread struct test_s s __attribute__ ((tls_model ("initial-exec"))) = .b = INIT_B }; -/* Use noinline in combination with not static to ensure that the - alignment check is really done. Otherwise it was optimized out! */ -__attribute__ ((noinline)) void -check_alignment (const char *thr_name, const char *ptr_name, - int *ptr, int alignment) -{ - uintptr_t offset_aligment = ((uintptr_t) ptr) & (alignment - 1); - if (offset_aligment) - { - FAIL_EXIT1 ("%s (%p) is not 0x%x-byte aligned in %s thread\n", - ptr_name, ptr, alignment, thr_name); - } -} - -static void -check_s (const char *thr_name) -{ - if (s.a != INIT_A || s.b != INIT_B) - FAIL_EXIT1 ("initial value of s in %s thread wrong\n", thr_name); - - check_alignment (thr_name, "s.a", &s.a, 0x20); - check_alignment (thr_name, "s.b", &s.b, 0x200); -} static void * tf (void *arg) { - check_s ("child"); + if (s.a != INIT_A || s.b != INIT_B) + { + puts ("initial value of s in child thread wrong"); + exit (1); + } ++s.a; @@ -78,14 +55,25 @@ tf (void *arg) int do_test (void) { - check_s ("main"); + if (s.a != INIT_A || s.b != INIT_B) + { + puts ("initial value of s in main thread wrong"); + exit (1); + } pthread_attr_t a; - xpthread_attr_init (&a); + if (pthread_attr_init (&a) != 0) + { + puts ("attr_init failed"); + exit (1); + } -#define STACK_SIZE (1 * 1024 * 1024) - xpthread_attr_setstacksize (&a, STACK_SIZE); + if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0) + { + puts ("attr_setstacksize failed"); + return 1; + } #define N 10 int i; @@ -95,25 +83,29 @@ do_test (void) pthread_t th[M]; int j; for (j = 0; j < M; ++j, ++s.a) - th[j] = xpthread_create (&a, tf, NULL); + if (pthread_create (&th[j], &a, tf, NULL) != 0) + { + puts ("pthread_create failed"); + exit (1); + } for (j = 0; j < M; ++j) - xpthread_join (th[j]); + if (pthread_join (th[j], NULL) != 0) + { + puts ("pthread_join failed"); + exit (1); + } } - /* Also check the alignment of the tls variables if a misaligned stack is - specified. */ - pthread_t th; - void *thr_stack = NULL; - thr_stack = xposix_memalign (0x200, STACK_SIZE + 1); - xpthread_attr_setstack (&a, thr_stack + 1, STACK_SIZE); - th = xpthread_create (&a, tf, NULL); - xpthread_join (th); - free (thr_stack); - - xpthread_attr_destroy (&a); + if (pthread_attr_destroy (&a) != 0) + { + puts ("attr_destroy failed"); + exit (1); + } return 0; } -#include + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/nscd/aicache.c b/nscd/aicache.c index b8e8134..439e0ea 100644 --- a/nscd/aicache.c +++ b/nscd/aicache.c @@ -93,9 +93,9 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, int herrno = 0; if (hosts_database == NULL) - no_more = __nss_database_lookup2 ("hosts", NULL, - "dns [!UNAVAIL=return] files", - &hosts_database); + no_more = __nss_database_lookup ("hosts", NULL, + "dns [!UNAVAIL=return] files", + &hosts_database); else no_more = 0; nip = hosts_database; diff --git a/nscd/connections.c b/nscd/connections.c index 9818200..47fbb99 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -304,8 +304,7 @@ static int check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap, enum usekey use, ref_t start, size_t len) { - if (len < 2) - return 0; + assert (len >= 2); if (start > first_free || start + len > first_free || (start & BLOCK_ALIGN_M1)) diff --git a/nscd/gai.c b/nscd/gai.c index f57f396..24bdfee 100644 --- a/nscd/gai.c +++ b/nscd/gai.c @@ -19,6 +19,7 @@ /* 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 f792c4f..7beb9dc 100644 --- a/nscd/gethstbynm3_r.c +++ b/nscd/gethstbynm3_r.c @@ -38,6 +38,8 @@ #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/nscd/initgrcache.c b/nscd/initgrcache.c index 90531e2..2c74951 100644 --- a/nscd/initgrcache.c +++ b/nscd/initgrcache.c @@ -88,8 +88,8 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, int no_more; if (group_database == NULL) - no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG, - &group_database); + no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG, + &group_database); else no_more = 0; nip = group_database; @@ -159,7 +159,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, /* This is really only for debugging. */ if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) - __libc_fatal ("Illegal status in internal_getgrouplist.\n"); + __libc_fatal ("illegal status in internal_getgrouplist"); any_success |= status == NSS_STATUS_SUCCESS; diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c index f521df8..2b35389 100644 --- a/nscd/netgroupcache.c +++ b/nscd/netgroupcache.c @@ -113,8 +113,7 @@ do_notfound (struct database_dyn *db, int fd, request_header *req, static time_t addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, const char *key, uid_t uid, struct hashentry *he, - struct datahead *dh, struct dataset **resultp, - void **tofreep) + struct datahead *dh, struct dataset **resultp) { if (__glibc_unlikely (debug_level > 0)) { @@ -140,10 +139,9 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, size_t group_len = strlen (key) + 1; struct name_list *first_needed = alloca (sizeof (struct name_list) + group_len); - *tofreep = NULL; if (netgroup_database == NULL - && __nss_database_lookup2 ("netgroup", NULL, NULL, &netgroup_database)) + && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database)) { /* No such service. */ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, @@ -153,7 +151,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, memset (&data, '\0', sizeof (data)); buffer = xmalloc (buflen); - *tofreep = buffer; first_needed->next = first_needed; memcpy (first_needed->name, key, group_len); data.needed_groups = first_needed; @@ -442,6 +439,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, } out: + free (buffer); + *resultp = dataset; return timeout; @@ -478,12 +477,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, group, group_len, db, uid); time_t timeout; - void *tofree; if (result != NULL) - { - timeout = result->head.timeout; - tofree = NULL; - } + timeout = result->head.timeout; else { request_header req_get = @@ -492,7 +487,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, .key_len = group_len }; timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL, - &result, &tofree); + &result); } struct indataset @@ -565,7 +560,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, ++dh->nreloads; if (cacheable) pthread_rwlock_unlock (&db->lock); - goto out; + return timeout; } if (he == NULL) @@ -601,30 +596,17 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, dh->usable = false; } - out: - free (tofree); return timeout; } -static time_t -addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req, - const char *key, uid_t uid, struct hashentry *he, - struct datahead *dh) -{ - struct dataset *ignore; - void *tofree; - time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, - &ignore, &tofree); - free (tofree); - return timeout; -} - void addgetnetgrent (struct database_dyn *db, int fd, request_header *req, void *key, uid_t uid) { - addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL); + struct dataset *ignore; + + addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore); } @@ -637,8 +619,10 @@ readdgetnetgrent (struct database_dyn *db, struct hashentry *he, .type = GETNETGRENT, .key_len = he->len }; - return addgetnetgrentX_ignore - (db, -1, &req, db->data + he->key, he->owner, he, dh); + struct dataset *ignore; + + return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh, + &ignore); } diff --git a/nscd/nscd.conf b/nscd/nscd.conf index 4a97165..39b8759 100644 --- a/nscd/nscd.conf +++ b/nscd/nscd.conf @@ -3,9 +3,6 @@ # # An example Name Service Cache config file. This file is needed by nscd. # -# WARNING: Running nscd with a secondary caching service like sssd may lead to -# unexpected behaviour, especially with how long entries are cached. -# # Legal entries are: # # logfile @@ -26,9 +23,6 @@ # check-files # persistent # shared -# NOTE: Setting 'shared' to a value of 'yes' will accelerate the lookup, -# but those lookups will not be counted as cache hits -# i.e. 'nscd -g' may show '0%'. # max-db-size # auto-propagate # @@ -39,7 +33,7 @@ # logfile /var/log/nscd.log # threads 4 # max-threads 32 - server-user nscd +# server-user nobody # stat-user somebody debug-level 0 # reload-count 5 diff --git a/nscd/nscd.service b/nscd/nscd.service index 32aa268..ab38e8f 100644 --- a/nscd/nscd.service +++ b/nscd/nscd.service @@ -2,12 +2,10 @@ [Unit] Description=Name Service Cache Daemon -After=syslog.target [Service] Type=forking -EnvironmentFile=-/etc/sysconfig/nscd -ExecStart=/usr/sbin/nscd $NSCD_OPTIONS +ExecStart=/usr/sbin/nscd ExecStop=/usr/sbin/nscd --shutdown ExecReload=/usr/sbin/nscd -i passwd ExecReload=/usr/sbin/nscd -i group @@ -19,4 +17,3 @@ PIDFile=/run/nscd/nscd.pid [Install] WantedBy=multi-user.target -Also=nscd.socket diff --git a/nscd/nscd.socket b/nscd/nscd.socket deleted file mode 100644 index 7e512d5..0000000 --- a/nscd/nscd.socket +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Name Service Cache Daemon Socket - -[Socket] -ListenDatagram=/var/run/nscd/socket - -[Install] -WantedBy=sockets.target diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c index 7293b79..265a024 100644 --- a/nscd/nscd_conf.c +++ b/nscd/nscd_conf.c @@ -190,10 +190,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) if (!arg1) error (0, 0, _("Must specify user name for server-user option")); else - { - free ((char *) server_user); - server_user = xstrdup (arg1); - } + server_user = xstrdup (arg1); } else if (strcmp (entry, "stat-user") == 0) { @@ -201,7 +198,6 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) error (0, 0, _("Must specify user name for stat-user option")); else { - free ((char *) stat_user); stat_user = xstrdup (arg1); struct passwd *pw = getpwnam (stat_user); diff --git a/nss/Makefile b/nss/Makefile index 2d59164..66fac7f 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -60,16 +60,11 @@ tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \ tst-nss-test5 xtests = bug-erange -tests-container = \ - tst-nss-db-endpwent \ - tst-nss-db-endgrent - # Tests which need libdl ifeq (yes,$(build-shared)) tests += tst-nss-files-hosts-erange tests += tst-nss-files-hosts-multi tests += tst-nss-files-hosts-getent -tests += tst-nss-files-alias-leak endif # If we have a thread library then we can test cancellation against @@ -176,5 +171,3 @@ endif $(objpfx)tst-nss-files-hosts-erange: $(libdl) $(objpfx)tst-nss-files-hosts-multi: $(libdl) $(objpfx)tst-nss-files-hosts-getent: $(libdl) -$(objpfx)tst-nss-files-alias-leak: $(libdl) -$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so diff --git a/nss/Versions b/nss/Versions index f0ad598..db8c887 100644 --- a/nss/Versions +++ b/nss/Versions @@ -1,26 +1,21 @@ libc { GLIBC_2.0 { - __nss_configure_lookup; - - # Functions exported as no-op compat symbols. + # functions used in other libraries __nss_passwd_lookup; __nss_group_lookup; __nss_hosts_lookup; __nss_next; - __nss_database_lookup; + __nss_database_lookup; __nss_configure_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_database_lookup2; + __nss_hash; } } diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c index c1c8731..e0f9471 100644 --- a/nss/XXX-lookup.c +++ b/nss/XXX-lookup.c @@ -57,8 +57,8 @@ DB_LOOKUP_FCT (service_user **ni, const char *fct_name, const char *fct2_name, void **fctp) { if (DATABASE_NAME_SYMBOL == NULL - && __nss_database_lookup2 (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, - DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0) + && __nss_database_lookup (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING, + DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0) return -1; *ni = DATABASE_NAME_SYMBOL; diff --git a/nss/compat-lookup.c b/nss/compat-lookup.c index ecfffb8..f51e94a 100644 --- a/nss/compat-lookup.c +++ b/nss/compat-lookup.c @@ -16,12 +16,11 @@ 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. @@ -41,31 +40,3 @@ strong_alias (__nss_passwd_lookup, __nss_hosts_lookup) 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 --git a/nss/digits_dots.c b/nss/digits_dots.c index 5441bce..39bff38 100644 --- a/nss/digits_dots.c +++ b/nss/digits_dots.c @@ -29,6 +29,7 @@ #include "nsswitch.h" #ifdef USE_NSCD +# define inet_aton __inet_aton # include #endif @@ -159,7 +160,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_exact (name, (struct in_addr *) host_addr); + ok = __inet_aton (name, (struct in_addr *) host_addr); else { assert (af == AF_INET6); diff --git a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c index fca9f48..0442e75 100644 --- a/nss/nss_compat/compat-grp.c +++ b/nss/nss_compat/compat-grp.c @@ -78,7 +78,7 @@ static bool in_blacklist (const char *, int, ent_t *); static void init_nss_interface (void) { - if (__nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + if (__nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0) { nss_setgrent = __nss_lookup_function (ni, "setgrent"); nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r"); @@ -142,7 +142,7 @@ _nss_compat_setgrent (int stayopen) } -static enum nss_status __attribute_warn_unused_result__ +static enum nss_status internal_endgrent (ent_t *ent) { if (ent->stream != NULL) @@ -163,15 +163,6 @@ internal_endgrent (ent_t *ent) return NSS_STATUS_SUCCESS; } -/* Like internal_endgrent, but preserve errno in all cases. */ -static void -internal_endgrent_noerror (ent_t *ent) -{ - int saved_errno = errno; - enum nss_status unused __attribute__ ((unused)) = internal_endgrent (ent); - __set_errno (saved_errno); -} - enum nss_status _nss_compat_endgrent (void) { @@ -492,7 +483,7 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp, if (result == NSS_STATUS_SUCCESS) result = internal_getgrnam_r (name, grp, &ent, buffer, buflen, errnop); - internal_endgrent_noerror (&ent); + internal_endgrent (&ent); return result; } @@ -621,7 +612,7 @@ _nss_compat_getgrgid_r (gid_t gid, struct group *grp, if (result == NSS_STATUS_SUCCESS) result = internal_getgrgid_r (gid, grp, &ent, buffer, buflen, errnop); - internal_endgrent_noerror (&ent); + internal_endgrent (&ent); return result; } diff --git a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c index d7a89ea..540eee8 100644 --- a/nss/nss_compat/compat-initgroups.c +++ b/nss/nss_compat/compat-initgroups.c @@ -89,7 +89,7 @@ init_nss_interface (void) /* Retest. */ if (ni == NULL - && __nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0) + && __nss_database_lookup ("group_compat", NULL, "nis", &ni) >= 0) { nss_initgroups_dyn = __nss_lookup_function (ni, "initgroups_dyn"); nss_getgrnam_r = __nss_lookup_function (ni, "getgrnam_r"); @@ -133,7 +133,7 @@ internal_setgrent (ent_t *ent) } -static enum nss_status __attribute_warn_unused_result__ +static enum nss_status internal_endgrent (ent_t *ent) { if (ent->stream != NULL) @@ -157,15 +157,6 @@ internal_endgrent (ent_t *ent) return NSS_STATUS_SUCCESS; } -/* Like internal_endgrent, but preserve errno in all cases. */ -static void -internal_endgrent_noerror (ent_t *ent) -{ - int saved_errno = errno; - enum nss_status unused __attribute__ ((unused)) = internal_endgrent (ent); - __set_errno (saved_errno); -} - /* Add new group record. */ static void add_group (long int *start, long int *size, gid_t **groupsp, long int limit, @@ -510,7 +501,7 @@ _nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start, done: scratch_buffer_free (&tmpbuf); - internal_endgrent_noerror (&intern); + internal_endgrent (&intern); return status; } diff --git a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c index 8832fb7..27d947c 100644 --- a/nss/nss_compat/compat-pwd.c +++ b/nss/nss_compat/compat-pwd.c @@ -88,7 +88,7 @@ static bool in_blacklist (const char *, int, ent_t *); static void init_nss_interface (void) { - if (__nss_database_lookup2 ("passwd_compat", NULL, "nis", &ni) >= 0) + if (__nss_database_lookup ("passwd_compat", NULL, "nis", &ni) >= 0) { nss_setpwent = __nss_lookup_function (ni, "setpwent"); nss_getpwnam_r = __nss_lookup_function (ni, "getpwnam_r"); @@ -259,7 +259,7 @@ _nss_compat_setpwent (int stayopen) } -static enum nss_status __attribute_warn_unused_result__ +static enum nss_status internal_endpwent (ent_t *ent) { if (ent->stream != NULL) @@ -287,15 +287,6 @@ internal_endpwent (ent_t *ent) return NSS_STATUS_SUCCESS; } -/* Like internal_endpwent, but preserve errno in all cases. */ -static void -internal_endpwent_noerror (ent_t *ent) -{ - int saved_errno = errno; - enum nss_status unused __attribute__ ((unused)) = internal_endpwent (ent); - __set_errno (saved_errno); -} - enum nss_status _nss_compat_endpwent (void) { @@ -831,7 +822,7 @@ _nss_compat_getpwnam_r (const char *name, struct passwd *pwd, if (result == NSS_STATUS_SUCCESS) result = internal_getpwnam_r (name, pwd, &ent, buffer, buflen, errnop); - internal_endpwent_noerror (&ent); + internal_endpwent (&ent); return result; } @@ -1070,7 +1061,7 @@ _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd, if (result == NSS_STATUS_SUCCESS) result = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen, errnop); - internal_endpwent_noerror (&ent); + internal_endpwent (&ent); return result; } diff --git a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c index 684a060..ce2a02e 100644 --- a/nss/nss_compat/compat-spwd.c +++ b/nss/nss_compat/compat-spwd.c @@ -85,8 +85,8 @@ static bool in_blacklist (const char *, int, ent_t *); static void init_nss_interface (void) { - if (__nss_database_lookup2 ("shadow_compat", "passwd_compat", - "nis", &ni) >= 0) + if (__nss_database_lookup ("shadow_compat", "passwd_compat", + "nis", &ni) >= 0) { nss_setspent = __nss_lookup_function (ni, "setspent"); nss_getspnam_r = __nss_lookup_function (ni, "getspnam_r"); @@ -215,7 +215,7 @@ _nss_compat_setspent (int stayopen) } -static enum nss_status __attribute_warn_unused_result__ +static enum nss_status internal_endspent (ent_t *ent) { if (ent->stream != NULL) @@ -244,15 +244,6 @@ internal_endspent (ent_t *ent) return NSS_STATUS_SUCCESS; } -/* Like internal_endspent, but preserve errno in all cases. */ -static void -internal_endspent_noerror (ent_t *ent) -{ - int saved_errno = errno; - enum nss_status unused __attribute__ ((unused)) = internal_endspent (ent); - __set_errno (saved_errno); -} - enum nss_status _nss_compat_endspent (void) { @@ -270,6 +261,7 @@ _nss_compat_endspent (void) return result; } + static enum nss_status getspent_next_nss_netgr (const char *name, struct spwd *result, ent_t *ent, char *group, char *buffer, size_t buflen, @@ -794,7 +786,7 @@ _nss_compat_getspnam_r (const char *name, struct spwd *pwd, if (result == NSS_STATUS_SUCCESS) result = internal_getspnam_r (name, pwd, &ent, buffer, buflen, errnop); - internal_endspent_noerror (&ent); + internal_endspent (&ent); return result; } diff --git a/nss/nss_db/db-open.c b/nss/nss_db/db-open.c index ac430f4..8538f8e 100644 --- a/nss/nss_db/db-open.c +++ b/nss/nss_db/db-open.c @@ -63,9 +63,5 @@ internal_setent (const char *file, struct nss_db_map *mapping) void internal_endent (struct nss_db_map *mapping) { - if (mapping->header != NULL) - { - munmap (mapping->header, mapping->len); - mapping->header = NULL; - } + munmap (mapping->header, mapping->len); } diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c index 35b0bfc..cfd34b6 100644 --- a/nss/nss_files/files-alias.c +++ b/nss/nss_files/files-alias.c @@ -221,13 +221,6 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, { while (! feof_unlocked (listfile)) { - if (room_left < 2) - { - free (old_line); - fclose (listfile); - goto no_more_room; - } - first_unused[room_left - 1] = '\xff'; line = fgets_unlocked (first_unused, room_left, listfile); @@ -236,7 +229,6 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, if (first_unused[room_left - 1] != '\xff') { free (old_line); - fclose (listfile); goto no_more_room; } @@ -264,7 +256,6 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, + __alignof__ (char *))) { free (old_line); - fclose (listfile); goto no_more_room; } room_left -= ((first_unused - cp) diff --git a/nss/nsswitch.c b/nss/nsswitch.c index 17adf1e..ee46f24 100644 --- a/nss/nsswitch.c +++ b/nss/nsswitch.c @@ -115,8 +115,8 @@ static void (*nscd_init_cb) (size_t, struct traced_file *); /* -1 == database not found 0 == database entry pointer stored */ int -__nss_database_lookup2 (const char *database, const char *alternate_name, - const char *defconfig, service_user **ni) +__nss_database_lookup (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_lookup2 (const char *database, const char *alternate_name, return *ni != NULL ? 0 : -1; } -libc_hidden_def (__nss_database_lookup2) +libc_hidden_def (__nss_database_lookup) /* -1 == not found @@ -235,7 +235,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name, /* This is really only for debugging. */ if (__builtin_expect (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN, 0)) - __libc_fatal ("Illegal status in __nss_next.\n"); + __libc_fatal ("illegal status in __nss_next"); if (nss_next_action (*ni, status) == NSS_ACTION_RETURN) return 1; @@ -260,6 +260,16 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name, } 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) { @@ -825,7 +835,7 @@ nss_load_all_libraries (const char *service, const char *def) { service_user *ni = NULL; - if (__nss_database_lookup2 (service, NULL, def, &ni) == 0) + if (__nss_database_lookup (service, NULL, def, &ni) == 0) while (ni != NULL) { nss_load_library (ni); diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf index 980a68e..39ca88b 100644 --- a/nss/nsswitch.conf +++ b/nss/nsswitch.conf @@ -1,72 +1,20 @@ -# # /etc/nsswitch.conf # -# Name Service Switch config file. This file should be -# sorted with the most-used services at the beginning. -# -# Valid databases are: aliases, ethers, group, gshadow, hosts, -# initgroups, netgroup, networks, passwd, protocols, publickey, -# rpc, services, and shadow. -# -# Valid service provider entries include (in alphabetical order): -# -# compat Use /etc files plus *_compat pseudo-db -# db Use the pre-processed /var/db files -# dns Use DNS (Domain Name Service) -# files Use the local files in /etc -# hesiod Use Hesiod (DNS) for user lookups -# nis Use NIS (NIS version 2), also called YP -# nisplus Use NIS+ (NIS version 3) -# -# See `info libc 'NSS Basics'` for more information. -# -# Commonly used alternative service providers (may need installation): -# -# ldap Use LDAP directory server -# myhostname Use systemd host names -# mymachines Use systemd machine names -# mdns*, mdns*_minimal Use Avahi mDNS/DNS-SD -# resolve Use systemd resolved resolver -# sss Use System Security Services Daemon (sssd) -# systemd Use systemd for dynamic user option -# winbind Use Samba winbind support -# wins Use Samba wins support -# wrapper Use wrapper module for testing +# Example configuration of GNU Name Service Switch functionality. # -# Notes: -# -# 'sssd' performs its own 'files'-based caching, so it should generally -# come before 'files'. -# -# WARNING: Running nscd with a secondary caching service like sssd may -# lead to unexpected behaviour, especially with how long -# entries are cached. -# -# Installation instructions: -# -# To use 'db', install the appropriate package(s) (provide 'makedb' and -# libnss_db.so.*), and place the 'db' in front of 'files' for entries -# you want to be looked up first in the databases, like this: -# -# passwd: db files -# shadow: db files -# group: db files -# In order of likelihood of use to accelerate lookup. -passwd: sss files -shadow: files sss -group: sss files -hosts: files dns myhostname -services: files sss -netgroup: sss -automount: files sss +passwd: db files +group: db files +initgroups: db [SUCCESS=continue] files +shadow: db files +gshadow: files + +hosts: files dns +networks: files dns + +protocols: db files +services: db files +ethers: db files +rpc: db files -aliases: files -ethers: files -gshadow: files -# Allow initgroups to default to the setting for group. -# initgroups: files -networks: files dns -protocols: files -publickey: files -rpc: files +netgroup: db files diff --git a/nss/nsswitch.h b/nss/nsswitch.h index 1aad279..63573b9 100644 --- a/nss/nsswitch.h +++ b/nss/nsswitch.h @@ -125,10 +125,10 @@ extern bool __nss_database_custom[NSS_DBSIDX_max] attribute_hidden; 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_lookup2 (const char *database, - const char *alternative_name, - const char *defconfig, service_user **ni); -libc_hidden_proto (__nss_database_lookup2) +extern int __nss_database_lookup (const char *database, + const char *alternative_name, + const char *defconfig, service_user **ni); +libc_hidden_proto (__nss_database_lookup) /* 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 --git a/nss/tst-nss-db-endgrent.c b/nss/tst-nss-db-endgrent.c deleted file mode 100644 index 367cc6c..0000000 --- a/nss/tst-nss-db-endgrent.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Test for endgrent changing errno for BZ #24696 - 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 - -/* The following test verifies that if the db NSS Service is initialized - with no database (getgrent), that a subsequent closure (endgrent) does - not set errno. In the case of the db service it is not an error to close - the service and so it should not set errno. */ - -static int -do_test (void) -{ - /* Just make sure it's not there, although usually it won't be. */ - unlink ("/var/db/group.db"); - - /* This, in conjunction with the testroot's nsswitch.conf, causes - the nss_db module to be "connected" and initialized - but the - testroot has no group.db, so no mapping will be created. */ - getgrent (); - - errno = 0; - - /* Before the fix, this would call munmap (NULL) and set errno. */ - endgrent (); - - if (errno != 0) - FAIL_EXIT1 ("endgrent set errno to %d\n", errno); - - return 0; -} -#include diff --git a/nss/tst-nss-db-endgrent.root/etc/nsswitch.conf b/nss/tst-nss-db-endgrent.root/etc/nsswitch.conf deleted file mode 100644 index 21471df..0000000 --- a/nss/tst-nss-db-endgrent.root/etc/nsswitch.conf +++ /dev/null @@ -1 +0,0 @@ -group : db files diff --git a/nss/tst-nss-db-endpwent.c b/nss/tst-nss-db-endpwent.c deleted file mode 100644 index cb85410..0000000 --- a/nss/tst-nss-db-endpwent.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Test for endpwent->getpwent crash for BZ #24695 - 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 - -/* It is entirely allowed to start with a getpwent call without - resetting the state of the service via a call to setpwent. - You can also call getpwent more times than you have entries in - the service, and it should not fail. This test iteratates the - database once, gets to the end, and then attempts a second - iteration to look for crashes. */ - -static void -try_it (void) -{ - struct passwd *pw; - - /* setpwent is intentionally omitted here. The first call to - getpwent detects that it's first and initializes. The second - time try_it is called, this "first call" was not detected before - the fix, and getpwent would crash. */ - - while ((pw = getpwent ()) != NULL) - ; - - /* We only care if this segfaults or not. */ - endpwent (); -} - -static int -do_test (void) -{ - char *cmd; - - cmd = xasprintf ("%s/makedb -o /var/db/passwd.db /var/db/passwd.in", - support_bindir_prefix); - system (cmd); - free (cmd); - - try_it (); - try_it (); - - return 0; -} -#include diff --git a/nss/tst-nss-db-endpwent.root/etc/nsswitch.conf b/nss/tst-nss-db-endpwent.root/etc/nsswitch.conf deleted file mode 100644 index 593ffc5..0000000 --- a/nss/tst-nss-db-endpwent.root/etc/nsswitch.conf +++ /dev/null @@ -1 +0,0 @@ -passwd: db diff --git a/nss/tst-nss-db-endpwent.root/var/db/passwd.in b/nss/tst-nss-db-endpwent.root/var/db/passwd.in deleted file mode 100644 index 98f3912..0000000 --- a/nss/tst-nss-db-endpwent.root/var/db/passwd.in +++ /dev/null @@ -1,4 +0,0 @@ -.root root:x:0:0:root:/root:/bin/bash -=0 root:x:0:0:root:/root:/bin/bash -.bin bin:x:1:1:bin:/bin:/sbin/nologin -=1 bin:x:1:1:bin:/bin:/sbin/nologin diff --git a/nss/tst-nss-files-alias-leak.c b/nss/tst-nss-files-alias-leak.c deleted file mode 100644 index 26d38e2..0000000 --- a/nss/tst-nss-files-alias-leak.c +++ /dev/null @@ -1,237 +0,0 @@ -/* Check for file descriptor leak in alias :include: processing (bug 23521). - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct support_chroot *chroot_env; - -/* Number of the aliases for the "many" user. This must be large - enough to trigger reallocation for the pointer array, but result in - answers below the maximum size tried in do_test. */ -enum { many_aliases = 30 }; - -static void -prepare (int argc, char **argv) -{ - chroot_env = support_chroot_create - ((struct support_chroot_configuration) { } ); - - char *path = xasprintf ("%s/etc/aliases", chroot_env->path_chroot); - add_temp_file (path); - support_write_file_string - (path, - "user1: :include:/etc/aliases.user1\n" - "user2: :include:/etc/aliases.user2\n" - "comment: comment1, :include:/etc/aliases.comment\n" - "many: :include:/etc/aliases.many\n"); - free (path); - - path = xasprintf ("%s/etc/aliases.user1", chroot_env->path_chroot); - add_temp_file (path); - support_write_file_string (path, "alias1\n"); - free (path); - - path = xasprintf ("%s/etc/aliases.user2", chroot_env->path_chroot); - add_temp_file (path); - support_write_file_string (path, "alias1a, alias2\n"); - free (path); - - path = xasprintf ("%s/etc/aliases.comment", chroot_env->path_chroot); - add_temp_file (path); - support_write_file_string - (path, - /* The line must be longer than the line with the :include: - directive in /etc/aliases. */ - "# Long line. ##############################################\n" - "comment2\n"); - free (path); - - path = xasprintf ("%s/etc/aliases.many", chroot_env->path_chroot); - add_temp_file (path); - FILE *fp = xfopen (path, "w"); - for (int i = 0; i < many_aliases; ++i) - fprintf (fp, "a%d\n", i); - TEST_VERIFY_EXIT (! ferror (fp)); - xfclose (fp); - free (path); -} - -/* The names of the users to test. */ -static const char *users[] = { "user1", "user2", "comment", "many" }; - -static void -check_aliases (int id, const struct aliasent *e) -{ - TEST_VERIFY_EXIT (id >= 0 || id < array_length (users)); - const char *name = users[id]; - TEST_COMPARE_BLOB (e->alias_name, strlen (e->alias_name), - name, strlen (name)); - - switch (id) - { - case 0: - TEST_COMPARE (e->alias_members_len, 1); - TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]), - "alias1", strlen ("alias1")); - break; - - case 1: - TEST_COMPARE (e->alias_members_len, 2); - TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]), - "alias1a", strlen ("alias1a")); - TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]), - "alias2", strlen ("alias2")); - break; - - case 2: - TEST_COMPARE (e->alias_members_len, 2); - TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]), - "comment1", strlen ("comment1")); - TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]), - "comment2", strlen ("comment2")); - break; - - case 3: - TEST_COMPARE (e->alias_members_len, many_aliases); - for (int i = 0; i < e->alias_members_len; ++i) - { - char alias[30]; - int len = snprintf (alias, sizeof (alias), "a%d", i); - TEST_VERIFY_EXIT (len > 0); - TEST_COMPARE_BLOB (e->alias_members[i], strlen (e->alias_members[i]), - alias, len); - } - break; - } -} - -static int -do_test (void) -{ - /* Make sure we don't try to load the module in the chroot. */ - if (dlopen (LIBNSS_FILES_SO, RTLD_NOW) == NULL) - FAIL_EXIT1 ("could not load " LIBNSS_FILES_SO ": %s", dlerror ()); - - /* Some of these descriptors will become unavailable if there is a - file descriptor leak. 10 is chosen somewhat arbitrarily. The - array must be longer than the number of files opened by nss_files - at the same time (currently that number is 2). */ - int next_descriptors[10]; - for (size_t i = 0; i < array_length (next_descriptors); ++i) - { - next_descriptors[i] = dup (0); - TEST_VERIFY_EXIT (next_descriptors[i] > 0); - } - for (size_t i = 0; i < array_length (next_descriptors); ++i) - xclose (next_descriptors[i]); - - support_become_root (); - if (!support_can_chroot ()) - return EXIT_UNSUPPORTED; - - __nss_configure_lookup ("aliases", "files"); - - xchroot (chroot_env->path_chroot); - - /* Attempt various buffer sizes. If the operation succeeds, we - expect correct data. */ - for (int id = 0; id < array_length (users); ++id) - { - bool found = false; - for (size_t size = 1; size <= 1000; ++size) - { - void *buffer = malloc (size); - struct aliasent result; - struct aliasent *res; - errno = EINVAL; - int ret = getaliasbyname_r (users[id], &result, buffer, size, &res); - if (ret == 0) - { - if (res != NULL) - { - found = true; - check_aliases (id, res); - } - else - { - support_record_failure (); - printf ("error: failed lookup for user \"%s\", size %zu\n", - users[id], size); - } - } - else if (ret != ERANGE) - { - support_record_failure (); - printf ("error: invalid return code %d (user \%s\", size %zu)\n", - ret, users[id], size); - } - free (buffer); - - /* Make sure that we did not have a file descriptor leak. */ - for (size_t i = 0; i < array_length (next_descriptors); ++i) - { - int new_fd = dup (0); - if (new_fd != next_descriptors[i]) - { - support_record_failure (); - printf ("error: descriptor %d at index %zu leaked" - " (user \"%s\", size %zu)\n", - next_descriptors[i], i, users[id], size); - - /* Close unexpected descriptor, the leak probing - descriptors, and the leaked descriptor - next_descriptors[i]. */ - xclose (new_fd); - for (size_t j = 0; j <= i; ++j) - xclose (next_descriptors[j]); - goto next_size; - } - } - for (size_t i = 0; i < array_length (next_descriptors); ++i) - xclose (next_descriptors[i]); - - next_size: - ; - } - if (!found) - { - support_record_failure (); - printf ("error: user %s not found\n", users[id]); - } - } - - support_chroot_free (chroot_env); - return 0; -} - -#define PREPARE prepare -#include diff --git a/posix/Makefile b/posix/Makefile index 8316212..00c6284 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -96,7 +96,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-posix_fadvise tst-posix_fadvise64 \ tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ - bug-regex38 tst-regcomp-truncated + bug-regex38 tests-internal := bug-regex5 bug-regex20 bug-regex33 \ tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \ tst-glob_lstat_compat tst-spawn4-compat @@ -194,7 +194,6 @@ $(objpfx)tst-regex2.out: $(gen-locales) $(objpfx)tst-regexloc.out: $(gen-locales) $(objpfx)tst-rxspencer.out: $(gen-locales) $(objpfx)tst-rxspencer-no-utf8.out: $(gen-locales) -$(objpfx)tst-regcomp-truncated.out: $(gen-locales) endif # If we will use the generic uname implementation, we must figure out what diff --git a/posix/bits/types.h b/posix/bits/types.h index 64f344c..5e22ce4 100644 --- a/posix/bits/types.h +++ b/posix/bits/types.h @@ -86,7 +86,7 @@ __extension__ typedef unsigned long long int __uintmax_t; 32 -- "natural" 32-bit type (always int) 64 -- "natural" 64-bit type (long or long long) LONG32 -- 32-bit type, traditionally long - QUAD -- 64-bit type, traditionally long long + QUAD -- 64-bit type, always long long WORD -- natural type of __WORDSIZE bits (int or long) LONGWORD -- type of __WORDSIZE bits, traditionally long @@ -112,14 +112,14 @@ __extension__ typedef unsigned long long int __uintmax_t; #define __SLONGWORD_TYPE long int #define __ULONGWORD_TYPE unsigned long int #if __WORDSIZE == 32 -# define __SQUAD_TYPE __int64_t -# define __UQUAD_TYPE __uint64_t +# define __SQUAD_TYPE __quad_t +# define __UQUAD_TYPE __u_quad_t # define __SWORD_TYPE int # define __UWORD_TYPE unsigned int # define __SLONG32_TYPE long int # define __ULONG32_TYPE unsigned long int -# define __S64_TYPE __int64_t -# define __U64_TYPE __uint64_t +# define __S64_TYPE __quad_t +# define __U64_TYPE __u_quad_t /* We want __extension__ before typedef's that use nonstandard base types such as `long long' in C89 mode. */ # define __STD_TYPE __extension__ typedef diff --git a/posix/fnmatch.c b/posix/fnmatch.c index 0213c63..a9b7626 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -322,7 +322,6 @@ fnmatch (const char *pattern, const char *string, int flags) # if HANDLE_MULTIBYTE if (__builtin_expect (MB_CUR_MAX, 1) != 1) { - const char *orig_pattern = pattern; mbstate_t ps; size_t n; const char *p; @@ -346,8 +345,10 @@ fnmatch (const char *pattern, const char *string, int flags) alloca_used); n = mbsrtowcs (wpattern, &p, n + 1, &ps); if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong: Fall back to single byte matching. */ - goto try_singlebyte; + /* Something wrong. + XXX Do we have to set `errno' to something which mbsrtows hasn't + already done? */ + return -1; if (p) { memset (&ps, '\0', sizeof (ps)); @@ -359,8 +360,10 @@ fnmatch (const char *pattern, const char *string, int flags) prepare_wpattern: n = mbsrtowcs (NULL, &pattern, 0, &ps); if (__glibc_unlikely (n == (size_t) -1)) - /*Something wrong: Fall back to single byte matching. */ - goto try_singlebyte; + /* Something wrong. + XXX Do we have to set `errno' to something which mbsrtows hasn't + already done? */ + return -1; if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) { __set_errno (ENOMEM); @@ -387,8 +390,14 @@ fnmatch (const char *pattern, const char *string, int flags) alloca_used); n = mbsrtowcs (wstring, &p, n + 1, &ps); if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong: Fall back to single byte matching. */ - goto free_and_try_singlebyte; + { + /* Something wrong. + XXX Do we have to set `errno' to something which + mbsrtows hasn't already done? */ + free_return: + free (wpattern_malloc); + return -1; + } if (p) { memset (&ps, '\0', sizeof (ps)); @@ -400,8 +409,10 @@ fnmatch (const char *pattern, const char *string, int flags) prepare_wstring: n = mbsrtowcs (NULL, &string, 0, &ps); if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong: Fall back to singlebyte matching. */ - goto free_and_try_singlebyte; + /* Something wrong. + XXX Do we have to set `errno' to something which mbsrtows hasn't + already done? */ + goto free_return; if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) { free (wpattern_malloc); @@ -428,10 +439,6 @@ fnmatch (const char *pattern, const char *string, int flags) free (wpattern_malloc); return res; - free_and_try_singlebyte: - free(wpattern_malloc); - try_singlebyte: - pattern = orig_pattern; } # endif /* mbstate_t and mbsrtowcs or _LIBC. */ diff --git a/posix/glob.c b/posix/glob.c index 1b389d2..8444b2f 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -827,32 +827,31 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { size_t home_len = strlen (p->pw_dir); size_t rest_len = end_name == NULL ? 0 : strlen (end_name); - char *d, *newp; - bool use_alloca = glob_use_alloca (alloca_used, - home_len + rest_len + 1); + char *d; - if (use_alloca) - newp = alloca_account (home_len + rest_len + 1, alloca_used); + if (__glibc_unlikely (malloc_dirname)) + free (dirname); + malloc_dirname = 0; + + if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) + dirname = alloca_account (home_len + rest_len + 1, + alloca_used); else { - newp = malloc (home_len + rest_len + 1); - if (newp == NULL) + dirname = malloc (home_len + rest_len + 1); + if (dirname == NULL) { scratch_buffer_free (&pwtmpbuf); retval = GLOB_NOSPACE; goto out; } + malloc_dirname = 1; } - d = mempcpy (newp, p->pw_dir, home_len); + d = mempcpy (dirname, p->pw_dir, home_len); if (end_name != NULL) d = mempcpy (d, end_name, rest_len); *d = '\0'; - if (__glibc_unlikely (malloc_dirname)) - free (dirname); - dirname = newp; - malloc_dirname = !use_alloca; - dirlen = home_len + rest_len; dirname_modified = 1; } diff --git a/posix/regex_internal.c b/posix/regex_internal.c index b10588f..7f0083b 100644 --- a/posix/regex_internal.c +++ b/posix/regex_internal.c @@ -317,7 +317,7 @@ build_wcs_upper_buffer (re_string_t *pstr) mbclen = __mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx), remain_len, &pstr->cur_state); - if (BE (0 < mbclen && mbclen < (size_t) -2, 1)) + if (BE (mbclen < (size_t) -2, 1)) { wchar_t wcu = __towupper (wc); if (wcu != wc) @@ -386,7 +386,7 @@ build_wcs_upper_buffer (re_string_t *pstr) else p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (0 < mbclen && mbclen < (size_t) -2, 1)) + if (BE (mbclen < (size_t) -2, 1)) { wchar_t wcu = __towupper (wc); if (wcu != wc) diff --git a/posix/sys/types.h b/posix/sys/types.h index 47eff1a..db524d6 100644 --- a/posix/sys/types.h +++ b/posix/sys/types.h @@ -154,20 +154,37 @@ typedef unsigned int uint; #include +#if !__GNUC_PREREQ (2, 7) + /* These were defined by ISO C without the first `_'. */ -typedef __uint8_t u_int8_t; -typedef __uint16_t u_int16_t; -typedef __uint32_t u_int32_t; -typedef __uint64_t u_int64_t; +typedef unsigned char u_int8_t; +typedef unsigned short int u_int16_t; +typedef unsigned int u_int32_t; +# if __WORDSIZE == 64 +typedef unsigned long int u_int64_t; +# else +__extension__ typedef unsigned long long int u_int64_t; +# endif -#if __GNUC_PREREQ (2, 7) -typedef int register_t __attribute__ ((__mode__ (__word__))); -#else typedef int register_t; -#endif + +#else + +/* For GCC 2.7 and later, we can use specific type-size attributes. */ +# define __u_intN_t(N, MODE) \ + typedef unsigned int u_int##N##_t __attribute__ ((__mode__ (MODE))) + +__u_intN_t (8, __QI__); +__u_intN_t (16, __HI__); +__u_intN_t (32, __SI__); +__u_intN_t (64, __DI__); + +typedef int register_t __attribute__ ((__mode__ (__word__))); + /* Some code from BIND tests this macro to see if the types above are defined. */ +#endif #define __BIT_TYPES_DEFINED__ 1 diff --git a/posix/tst-regcomp-truncated.c b/posix/tst-regcomp-truncated.c deleted file mode 100644 index a4a1581..0000000 --- a/posix/tst-regcomp-truncated.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Test compilation of truncated regular expressions. - 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 - . */ - -/* This test constructs various patterns in an attempt to trigger - over-reading the regular expression compiler, such as bug - 23578. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Locales to test. */ -static const char locales[][17] = - { - "C", - "en_US.UTF-8", - "de_DE.ISO-8859-1", - }; - -/* Syntax options. Will be combined with other flags. */ -static const reg_syntax_t syntaxes[] = - { - RE_SYNTAX_EMACS, - RE_SYNTAX_AWK, - RE_SYNTAX_GNU_AWK, - RE_SYNTAX_POSIX_AWK, - RE_SYNTAX_GREP, - RE_SYNTAX_EGREP, - RE_SYNTAX_POSIX_EGREP, - RE_SYNTAX_POSIX_BASIC, - RE_SYNTAX_POSIX_EXTENDED, - RE_SYNTAX_POSIX_MINIMAL_EXTENDED, - }; - -/* Trailing characters placed after the initial character. */ -static const char trailing_strings[][4] = - { - "", - "[", - "\\", - "[\\", - "(", - "(\\", - "\\(", - }; - -static int -do_test (void) -{ - /* Staging buffer for the constructed regular expression. */ - char buffer[16]; - - /* Allocation used to detect over-reading by the regular expression - compiler. */ - struct support_next_to_fault ntf - = support_next_to_fault_allocate (sizeof (buffer)); - - /* Arbitrary Unicode codepoint at which we stop generating - characters. We do not probe the whole range because that would - take too long due to combinatorical exploision as the result of - combination with other flags. */ - static const wchar_t last_character = 0xfff; - - for (size_t locale_idx = 0; locale_idx < array_length (locales); - ++ locale_idx) - { - if (setlocale (LC_ALL, locales[locale_idx]) == NULL) - { - support_record_failure (); - printf ("error: setlocale (\"%s\"): %m", locales[locale_idx]); - continue; - } - if (test_verbose > 0) - printf ("info: testing locale \"%s\"\n", locales[locale_idx]); - - for (wchar_t wc = 0; wc <= last_character; ++wc) - { - char *after_wc; - if (wc == 0) - { - /* wcrtomb treats L'\0' in a special way. */ - *buffer = '\0'; - after_wc = &buffer[1]; - } - else - { - mbstate_t ps = { }; - size_t ret = wcrtomb (buffer, wc, &ps); - if (ret == (size_t) -1) - { - /* EILSEQ means that the target character set - cannot encode the character. */ - if (errno != EILSEQ) - { - support_record_failure (); - printf ("error: wcrtomb (0x%x) failed: %m\n", - (unsigned) wc); - } - continue; - } - TEST_VERIFY_EXIT (ret != 0); - after_wc = &buffer[ret]; - } - - for (size_t trailing_idx = 0; - trailing_idx < array_length (trailing_strings); - ++trailing_idx) - { - char *after_trailing - = stpcpy (after_wc, trailing_strings[trailing_idx]); - - for (int do_nul = 0; do_nul < 2; ++do_nul) - { - char *after_nul; - if (do_nul) - { - *after_trailing = '\0'; - after_nul = &after_trailing[1]; - } - else - after_nul = after_trailing; - - size_t length = after_nul - buffer; - - /* Make sure that the faulting region starts - after the used portion of the buffer. */ - char *ntf_start = ntf.buffer + sizeof (buffer) - length; - memcpy (ntf_start, buffer, length); - - for (const reg_syntax_t *psyntax = syntaxes; - psyntax < array_end (syntaxes); ++psyntax) - for (int do_icase = 0; do_icase < 2; ++do_icase) - { - re_syntax_options = *psyntax; - if (do_icase) - re_syntax_options |= RE_ICASE; - - regex_t reg; - memset (®, 0, sizeof (reg)); - const char *msg = re_compile_pattern - (ntf_start, length, ®); - if (msg != NULL) - { - if (test_verbose > 0) - { - char *quoted = support_quote_blob - (buffer, length); - printf ("info: compilation failed for pattern" - " \"%s\", syntax 0x%lx: %s\n", - quoted, re_syntax_options, msg); - free (quoted); - } - } - else - regfree (®); - } - } - } - } - } - - support_next_to_fault_free (&ntf); - - return 0; -} - -#include diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c index 7943db9..7c785c4 100644 --- a/posix/tst-spawn.c +++ b/posix/tst-spawn.c @@ -17,20 +17,16 @@ 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'. */ @@ -40,6 +36,16 @@ 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; @@ -57,18 +63,19 @@ static const char fd3string[] = "This file will be opened"; /* We have a preparation function. */ -static void +void do_prepare (int argc, char *argv[]) { /* We must not open any files in the restart case. */ if (restart) return; - 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); + 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); } -#define PREPARE do_prepare static int @@ -88,45 +95,64 @@ handle_restart (const char *fd1s, const char *fd2s, const char *fd3s, fd4 = atol (fd4s); /* Sanity check. */ - 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); + 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"); /* First the easy part: read from the file descriptor which is supposed to be open. */ - TEST_COMPARE (xlseek (fd2, 0, SEEK_CUR), strlen (fd2string)); + if (lseek (fd2, 0, SEEK_CUR) != strlen (fd2string)) + error (EXIT_FAILURE, errno, "file 2 not in right position"); /* The duped descriptor must have the same position. */ - 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)); + 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"); /* Now read from the third file. */ - TEST_COMPARE (read (fd3, buf, sizeof buf), strlen (fd3string)); - TEST_COMPARE_BLOB (fd3string, strlen (fd3string), buf, strlen (fd3string)); + 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"); /* Try to write to the file. This should not be allowed. */ - TEST_COMPARE (write (fd3, "boo!", 4), -1); - TEST_COMPARE (errno, EBADF); + if (write (fd3, "boo!", 4) != -1 || errno != EBADF) + error (EXIT_FAILURE, 0, "file 3 is writable"); /* Now try to read the first file. First make sure it is not opened. */ - TEST_COMPARE (lseek (fd1, 0, SEEK_CUR), (off_t) -1); - TEST_COMPARE (errno, EBADF); + if (lseek (fd1, 0, SEEK_CUR) != (off_t) -1 || errno != EBADF) + error (EXIT_FAILURE, 0, "file 1 (%d) is not closed", fd1); /* Now open the file and read it. */ - fd1 = xopen (name, O_RDONLY, 0600); + fd1 = open (name, O_RDONLY); + if (fd1 == -1) + error (EXIT_FAILURE, errno, + "cannot open first file \"%s\" for verification", name); - TEST_COMPARE (read (fd1, buf, sizeof buf), strlen (fd1string)); - TEST_COMPARE_BLOB (fd1string, strlen (fd1string), buf, strlen (fd1string)); + 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"); return 0; } -static int +int do_test (int argc, char *argv[]) { pid_t pid; @@ -155,7 +181,7 @@ do_test (int argc, char *argv[]) + the name of the closed descriptor */ if (argc != (restart ? 6 : 2) && argc != (restart ? 6 : 5)) - FAIL_EXIT1 ("wrong number of arguments (%d)", argc); + error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc); if (restart) return handle_restart (argv[1], argv[2], argv[3], argv[4], argv[5]); @@ -163,74 +189,77 @@ 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. */ - 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); + /* 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); /* Wait for the children. */ - TEST_COMPARE (xwaitpid (pid, &status, 0), pid); + TEST_VERIFY (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); + TEST_VERIFY (WEXITSTATUS (status) == 0); - /* Cleanup. */ - TEST_COMPARE (posix_spawn_file_actions_destroy (&actions), 0); - free (name3_copy); - - /* Wait for the children. */ xwaitpid (-1, &status, 0); TEST_VERIFY (WIFEXITED (status)); TEST_VERIFY (!WIFSIGNALED (status)); - TEST_COMPARE (WEXITSTATUS (status), 0); + TEST_VERIFY (WEXITSTATUS (status) == 0); return 0; } - -#define TEST_FUNCTION_ARGV do_test -#include diff --git a/resolv/Makefile b/resolv/Makefile index 72a0f19..ea395ac 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -34,9 +34,6 @@ 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 @@ -57,10 +54,8 @@ 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)) @@ -105,7 +100,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 res_enable_icmp \ + ns_samedomain ns_date \ compat-hooks compat-gethnamaddr libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \ @@ -195,11 +190,9 @@ $(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 9a82704..b05778d 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -27,7 +27,6 @@ libc { __h_errno; __resp; __res_iclose; - __inet_aton_exact; __inet_pton_length; __resolv_context_get; __resolv_context_get_preinit; diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c index 80a2cff..e7c3b63 100644 --- a/resolv/gai_misc.c +++ b/resolv/gai_misc.c @@ -261,11 +261,8 @@ __gai_enqueue_request (struct gaicb *gaicbp) /* We cannot create a thread in the moment and there is also no thread running. This is a problem. `errno' is set to EAGAIN if this is only a temporary problem. */ - assert (requests == newp || lastp->next == newp); - if (lastp != NULL) - lastp->next = NULL; - else - requests = NULL; + assert (lastp->next == newp); + lastp->next = NULL; requests_tail = lastp; newp->next = freelist; diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c index 41b6166..022f7ea 100644 --- a/resolv/inet_addr.c +++ b/resolv/inet_addr.c @@ -1,21 +1,3 @@ -/* 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. @@ -96,122 +78,106 @@ #include #include -/* 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. 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; - 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 (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); - *endp = cp; - - __set_errno (saved_errno); - return 1; - - ret_0: - __set_errno (saved_errno); - return 0; -} +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +in_addr_t +__inet_addr(const char *cp) { + struct in_addr val; -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; + if (__inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); } -libc_hidden_def (__inet_aton_exact) +weak_alias (__inet_addr, inet_addr) -/* inet_aton ignores trailing garbage. */ +/* + * 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. + */ int -__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr) +__inet_aton(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) + 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]) + goto ret_0; -/* 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; + 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_addr, inet_addr) +weak_alias (__inet_aton, inet_aton) +libc_hidden_def (__inet_aton) +libc_hidden_weak (inet_aton) diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 99c3b61..5dc2829 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -274,26 +274,11 @@ 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); } @@ -304,9 +289,6 @@ _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) { @@ -314,7 +296,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, *h_errnop = NETDB_INTERNAL; return NSS_STATUS_UNAVAIL; } - status = NSS_STATUS_NOTFOUND; + enum nss_status status = NSS_STATUS_NOTFOUND; if (res_use_inet6 ()) status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer, buflen, errnop, h_errnop, NULL, NULL); @@ -331,9 +313,6 @@ _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) { @@ -368,6 +347,7 @@ _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/resolv/res_enable_icmp.c b/resolv/res_enable_icmp.c deleted file mode 100644 index bdc9220..0000000 --- a/resolv/res_enable_icmp.c +++ /dev/null @@ -1,37 +0,0 @@ -/* 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_init.c b/resolv/res_init.c index bb99dde..f5e52cb 100644 --- a/resolv/res_init.c +++ b/resolv/res_init.c @@ -103,7 +103,6 @@ #include #include #include -#include static uint32_t net_mask (struct in_addr); @@ -400,16 +399,8 @@ 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_exact (cp, &a)) + if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a)) { sa = allocate_address_v4 (a, NAMESERVER_PORT); if (sa == NULL) @@ -419,6 +410,9 @@ 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)) @@ -478,7 +472,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) char separator = *cp; *cp = 0; struct resolv_sortlist_entry e; - if (__inet_aton_exact (net, &a)) + if (__inet_aton (net, &a)) { e.addr = a; if (is_sort_mask (separator)) @@ -490,7 +484,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) cp++; separator = *cp; *cp = 0; - if (__inet_aton_exact (net, &a)) + if (__inet_aton (net, &a)) e.mask = a.s_addr; else e.mask = net_mask (e.addr); @@ -509,6 +503,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) continue; } } + fclose (fp); } if (__glibc_unlikely (nameserver_list_size (&parser->nameserver_list) == 0)) { @@ -550,8 +545,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) } struct resolv_conf * -__resolv_conf_load (struct __res_state *preinit, - struct file_change_detection *change) +__resolv_conf_load (struct __res_state *preinit) { /* Ensure that /etc/hosts.conf has been loaded (once). */ _res_hconf_init (); @@ -579,13 +573,7 @@ __resolv_conf_load (struct __res_state *preinit, resolv_conf_parser_init (&parser, preinit); struct resolv_conf *conf = NULL; - bool ok = res_vinit_1 (fp, &parser); - if (ok && change != NULL) - /* Update the file change information if the configuration was - loaded successfully. */ - ok = __file_change_detection_for_fp (change, fp); - - if (ok) + if (res_vinit_1 (fp, &parser)) { parser.template.nameserver_list = nameserver_list_begin (&parser.nameserver_list); @@ -600,13 +588,6 @@ __resolv_conf_load (struct __res_state *preinit, } resolv_conf_parser_free (&parser); - if (fp != NULL) - { - int saved_errno = errno; - fclose (fp); - __set_errno (saved_errno); - } - return conf; } @@ -623,7 +604,7 @@ __res_vinit (res_state statp, int preinit) if (preinit && has_preinit_values (statp)) /* For the preinit case, we cannot use the cached configuration because some settings could be different. */ - conf = __resolv_conf_load (statp, NULL); + conf = __resolv_conf_load (statp); else conf = __resolv_conf_get_current (); if (conf == NULL) diff --git a/resolv/res_send.c b/resolv/res_send.c index 705ecb7..947ebf5 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -943,18 +943,6 @@ 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 0878f68..b8e447c 100644 --- a/resolv/resolv-internal.h +++ b/resolv/resolv-internal.h @@ -100,10 +100,4 @@ 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/resolv/resolv_conf.c b/resolv/resolv_conf.c index 6188f1b..2f0ffbc 100644 --- a/resolv/resolv_conf.c +++ b/resolv/resolv_conf.c @@ -24,7 +24,6 @@ #include #include #include -#include /* _res._u._ext.__glibc_extension_index is used as an index into a struct resolv_conf_array object. The intent of this construction @@ -69,8 +68,12 @@ struct resolv_conf_global /* Cached current configuration object for /etc/resolv.conf. */ struct resolv_conf *conf_current; - /* File system identification for /etc/resolv.conf. */ - struct file_change_detection file_resolve_conf; + /* These properties of /etc/resolv.conf are used to check if the + configuration needs reloading. */ + struct timespec conf_mtime; + struct timespec conf_ctime; + off64_t conf_size; + ino64_t conf_ino; }; /* Lazily allocated storage for struct resolv_conf_global. */ @@ -120,41 +123,58 @@ conf_decrement (struct resolv_conf *conf) struct resolv_conf * __resolv_conf_get_current (void) { - struct file_change_detection initial; - if (!__file_change_detection_for_path (&initial, _PATH_RESCONF)) - return NULL; + struct stat64 st; + if (stat64 (_PATH_RESCONF, &st) != 0) + { + switch (errno) + { + case EACCES: + case EISDIR: + case ELOOP: + case ENOENT: + case ENOTDIR: + case EPERM: + /* Ignore errors due to file system contents. */ + memset (&st, 0, sizeof (st)); + break; + default: + /* Other errors are fatal. */ + return NULL; + } + } struct resolv_conf_global *global_copy = get_locked_global (); if (global_copy == NULL) return NULL; struct resolv_conf *conf; if (global_copy->conf_current != NULL - && __file_is_unchanged (&initial, &global_copy->file_resolve_conf)) + && (global_copy->conf_mtime.tv_sec == st.st_mtim.tv_sec + && global_copy->conf_mtime.tv_nsec == st.st_mtim.tv_nsec + && global_copy->conf_ctime.tv_sec == st.st_ctim.tv_sec + && global_copy->conf_ctime.tv_nsec == st.st_ctim.tv_nsec + && global_copy->conf_ino == st.st_ino + && global_copy->conf_size == st.st_size)) /* We can reuse the cached configuration object. */ conf = global_copy->conf_current; else { /* Parse configuration while holding the lock. This avoids duplicate work. */ - struct file_change_detection after_load; - conf = __resolv_conf_load (NULL, &after_load); + conf = __resolv_conf_load (NULL); if (conf != NULL) { if (global_copy->conf_current != NULL) conf_decrement (global_copy->conf_current); global_copy->conf_current = conf; /* Takes ownership. */ - /* Update file change detection data, but only if it matches - the initial measurement. This avoids an ABA race in case - /etc/resolv.conf is temporarily replaced while the file - is read (after the initial measurement), and restored to - the initial version later. */ - if (__file_is_unchanged (&initial, &after_load)) - global_copy->file_resolve_conf = after_load; - else - /* If there is a discrepancy, trigger a reload during the - next use. */ - global_copy->file_resolve_conf.size = -1; + /* Update file modification stamps. The configuration we + read could be a newer version of the file, but this does + not matter because this will lead to an extraneous reload + later. */ + global_copy->conf_mtime = st.st_mtim; + global_copy->conf_ctime = st.st_ctim; + global_copy->conf_ino = st.st_ino; + global_copy->conf_size = st.st_size; } } diff --git a/resolv/resolv_conf.h b/resolv/resolv_conf.h index da07c04..e903a20 100644 --- a/resolv/resolv_conf.h +++ b/resolv/resolv_conf.h @@ -63,16 +63,12 @@ struct resolv_conf and the struct resolv_context facility. */ struct __res_state; -struct file_change_detection; /* Read /etc/resolv.conf and return a configuration object, or NULL if /etc/resolv.conf cannot be read due to memory allocation errors. - If PREINIT is not NULL, some configuration values are taken from - the struct __res_state object. If CHANGE is not null, file change - detection data is written to *CHANGE, based on the state of the - file after reading it. */ -struct resolv_conf *__resolv_conf_load (struct __res_state *preinit, - struct file_change_detection *change) + If PREINIT is not NULL, some configuration values are taken from the + struct __res_state object. */ +struct resolv_conf *__resolv_conf_load (struct __res_state *preinit) attribute_hidden __attribute__ ((warn_unused_result)); /* Return a configuration object for the current /etc/resolv.conf diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c index eb734d7..08110a0 100644 --- a/resolv/tst-aton.c +++ b/resolv/tst-aton.c @@ -1,29 +1,11 @@ -/* 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 const struct tests + +static struct tests { const char *input; int valid; @@ -34,7 +16,6 @@ static const struct tests { "-1", 0, 0 }, { "256", 1, 0x00000100 }, { "256.", 0, 0 }, - { "255a", 0, 0 }, { "256a", 0, 0 }, { "0x100", 1, 0x00000100 }, { "0200.0x123456", 1, 0x80123456 }, @@ -59,12 +40,7 @@ static const struct tests { "1.2.256.4", 0, 0 }, { "1.2.3.0x100", 0, 0 }, { "323543357756889", 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 }, + { "10.1.2.3.4", 0, 0}, }; @@ -74,7 +50,7 @@ do_test (void) int result = 0; size_t cnt; - for (cnt = 0; cnt < array_length (tests); ++cnt) + for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt) { struct in_addr addr; @@ -97,4 +73,5 @@ do_test (void) return result; } -#include +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c deleted file mode 100644 index 0fdfa3d..0000000 --- a/resolv/tst-inet_aton_exact.c +++ /dev/null @@ -1,47 +0,0 @@ -/* 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 deleted file mode 100644 index a0df6f3..0000000 --- a/resolv/tst-resolv-nondecimal.c +++ /dev/null @@ -1,139 +0,0 @@ -/* 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 deleted file mode 100644 index 7504bda..0000000 --- a/resolv/tst-resolv-trailing.c +++ /dev/null @@ -1,136 +0,0 @@ -/* 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/rt/Makefile b/rt/Makefile index de53133..6d6b896 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -28,6 +28,9 @@ aio-routines := aio_cancel aio_error aio_fsync aio_misc aio_read \ aio_read64 aio_return aio_suspend aio_write \ aio_write64 lio_listio lio_listio64 aio_sigqueue \ aio_notify +clock-routines := get_clockfreq clock_getcpuclockid \ + clock_getres clock_gettime clock_settime \ + clock_nanosleep timer-routines := timer_create timer_delete timer_getoverr \ timer_gettime timer_settime shm-routines := shm_open shm_unlink @@ -35,18 +38,22 @@ mq-routines := mq_open mq_close mq_unlink mq_getattr mq_setattr \ mq_notify mq_send mq_receive mq_timedsend \ mq_timedreceive +routines = $(clock-routines) + librt-routines = $(aio-routines) \ $(timer-routines) \ - $(shm-routines) $(mq-routines) + $(shm-routines) $(mq-routines) \ + clock-compat -tests := tst-shm tst-timer tst-timer2 \ +tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \ tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \ tst-aio7 tst-aio8 tst-aio9 tst-aio10 \ tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \ tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \ tst-timer3 tst-timer4 tst-timer5 \ - tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \ - tst-shm-cancel + tst-cpuclock1 tst-cpuclock2 \ + tst-cputimer1 tst-cputimer2 tst-cputimer3 \ + tst-clock2 tst-shm-cancel extra-libs := librt extra-libs-others := $(extra-libs) diff --git a/rt/Versions b/rt/Versions index 84d1345..91e3fd2 100644 --- a/rt/Versions +++ b/rt/Versions @@ -1,3 +1,15 @@ +libc { + GLIBC_2.17 { + # c* + clock_getres; clock_gettime; clock_settime; clock_getcpuclockid; + clock_nanosleep; + } + GLIBC_PRIVATE { + __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid; + __clock_nanosleep; + } +} + librt { GLIBC_2.1 { # AIO functions. @@ -6,6 +18,10 @@ librt { aio_suspend64; aio_write; aio_write64; lio_listio; lio_listio64; } GLIBC_2.2 { + # These have moved to libc and are still here only for compatibility. + clock_getres; clock_gettime; clock_settime; clock_getcpuclockid; + clock_nanosleep; + # s* shm_open; shm_unlink; diff --git a/rt/clock-compat.c b/rt/clock-compat.c new file mode 100644 index 0000000..f816973 --- /dev/null +++ b/rt/clock-compat.c @@ -0,0 +1,61 @@ +/* ABI compatibility redirects for clock_* symbols in librt. + 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 + +/* The clock_* symbols were originally defined in librt and so + are part of its ABI. As of 2.17, they have moved to libc. + So we supply definitions for librt that just redirect to + their libc counterparts. */ + +#if SHLIB_COMPAT (librt, GLIBC_2_2, GLIBC_2_17) + +#include + +#if HAVE_IFUNC +# undef INIT_ARCH +# define INIT_ARCH() +# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name) +#else +# define COMPAT_REDIRECT(name, proto, arglist) \ + int \ + name proto \ + { \ + return __##name arglist; \ + } +#endif + +COMPAT_REDIRECT (clock_getres, + (clockid_t clock_id, struct timespec *res), + (clock_id, res)) +COMPAT_REDIRECT (clock_gettime, + (clockid_t clock_id, struct timespec *tp), + (clock_id, tp)) +COMPAT_REDIRECT (clock_settime, + (clockid_t clock_id, const struct timespec *tp), + (clock_id, tp)) +COMPAT_REDIRECT (clock_getcpuclockid, + (pid_t pid, clockid_t *clock_id), + (pid, clock_id)) +COMPAT_REDIRECT (clock_nanosleep, + (clockid_t clock_id, int flags, + const struct timespec *req, + struct timespec *rem), + (clock_id, flags, req, rem)) + +#endif diff --git a/rt/clock_getcpuclockid.c b/rt/clock_getcpuclockid.c new file mode 100644 index 0000000..6bc42a0 --- /dev/null +++ b/rt/clock_getcpuclockid.c @@ -0,0 +1,40 @@ +/* Get a clockid_t for the process CPU clock of a given process. Generic. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +int +__clock_getcpuclockid (pid_t pid, clockid_t *clock_id) +{ + /* We don't allow any process ID but our own. */ + if (pid != 0 && pid != getpid ()) + return EPERM; + +#ifdef CLOCK_PROCESS_CPUTIME_ID + /* Store the number. */ + *clock_id = CLOCK_PROCESS_CPUTIME_ID; + + return 0; +#else + /* We don't have a timer for that. */ + return ENOENT; +#endif +} +weak_alias (__clock_getcpuclockid, clock_getcpuclockid) diff --git a/rt/clock_getres.c b/rt/clock_getres.c new file mode 100644 index 0000000..816f7b2 --- /dev/null +++ b/rt/clock_getres.c @@ -0,0 +1,30 @@ +/* Get the resolution of a clock. Stub version. + Copyright (C) 1999-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 + +/* Get resolution of clock. */ +int +__clock_getres (clockid_t clock_id, struct timespec *res) +{ + __set_errno (ENOSYS); + return -1; +} +weak_alias (__clock_getres, clock_getres) +stub_warning (clock_getres) diff --git a/rt/clock_gettime.c b/rt/clock_gettime.c new file mode 100644 index 0000000..30a0124 --- /dev/null +++ b/rt/clock_gettime.c @@ -0,0 +1,31 @@ +/* Get the current value of a clock. Stub version. + Copyright (C) 1999-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 + +/* Get current value of CLOCK and store it in TP. */ +int +__clock_gettime (clockid_t clock_id, struct timespec *tp) +{ + __set_errno (ENOSYS); + return -1; +} +weak_alias (__clock_gettime, clock_gettime) +libc_hidden_def (__clock_gettime) +stub_warning (clock_gettime) diff --git a/rt/clock_nanosleep.c b/rt/clock_nanosleep.c new file mode 100644 index 0000000..15aa6f7 --- /dev/null +++ b/rt/clock_nanosleep.c @@ -0,0 +1,37 @@ +/* High-resolution sleep with the specified clock. Stub version. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +int +__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, + struct timespec *rem) +{ + if (__builtin_expect (req->tv_nsec, 0) < 0 + || __builtin_expect (req->tv_nsec, 0) >= 1000000000) + return EINVAL; + + if (flags != TIMER_ABSTIME && flags != 0) + return EINVAL; + + /* Not implemented. */ + return ENOSYS; +} +weak_alias (__clock_nanosleep, clock_nanosleep) +stub_warning (clock_nanosleep) diff --git a/rt/clock_settime.c b/rt/clock_settime.c new file mode 100644 index 0000000..0b6d4b2 --- /dev/null +++ b/rt/clock_settime.c @@ -0,0 +1,30 @@ +/* Set a clock to a given value. Stub version. + Copyright (C) 1999-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 + +/* Set CLOCK to value TP. */ +int +__clock_settime (clockid_t clock_id, const struct timespec *tp) +{ + __set_errno (ENOSYS); + return -1; +} +weak_alias (__clock_settime, clock_settime) +stub_warning (clock_settime) diff --git a/rt/get_clockfreq.c b/rt/get_clockfreq.c new file mode 100644 index 0000000..e695a60 --- /dev/null +++ b/rt/get_clockfreq.c @@ -0,0 +1,27 @@ +/* Get frequency of the system processor. + Copyright (C) 2000-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 + +hp_timing_t +__get_clockfreq (void) +{ + /* There is no generic way to find this out since we have in general + no counter register either. */ + return 0; +} diff --git a/rt/tst-clock.c b/rt/tst-clock.c new file mode 100644 index 0000000..bec76d0 --- /dev/null +++ b/rt/tst-clock.c @@ -0,0 +1,124 @@ +/* Test program for POSIX clock_* functions. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 + + +/* We want to see output immediately. */ +#define STDOUT_UNBUFFERED + +/* We expect to run at least 10 seconds. */ +#define TIMEOUT 15 + +static int +clock_test (clockid_t cl) +{ + struct timespec old_ts; + struct timespec ts; + struct timespec waitit; + int result = 0; + int i; + + memset (&ts, '\0', sizeof ts); + + waitit.tv_sec = 0; + waitit.tv_nsec = 500000000; + + /* Get and print resolution of the clock. */ + if (clock_getres (cl, &ts) == 0) + { + if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000) + { + printf ("clock %d: nanosecond value of resolution wrong\n", cl); + result = 1; + } + else + printf ("clock %d: resolution = %jd.%09jd secs\n", + cl, (intmax_t) ts.tv_sec, (intmax_t) ts.tv_nsec); + } + else + { + printf ("clock %d: cannot get resolution\n", cl); + result = 1; + } + + memset (&ts, '\0', sizeof ts); + memset (&old_ts, '\0', sizeof old_ts); + + /* Next get the current time value a few times. */ + for (i = 0; i < 10; ++i) + { + if (clock_gettime (cl, &ts) == 0) + { + if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000) + { + printf ("clock %d: nanosecond value of time wrong (try %d)\n", + cl, i); + result = 1; + } + else + { + printf ("clock %d: time = %jd.%09jd secs\n", + cl, (intmax_t) ts.tv_sec, (intmax_t) ts.tv_nsec); + + if (memcmp (&ts, &old_ts, sizeof ts) == 0) + { + printf ("clock %d: time hasn't changed (try %d)\n", cl, i); + result = 1; + + old_ts = ts; + } + } + } + else + { + printf ("clock %d: cannot get time (try %d)\n", cl, i); + result = 1; + } + + /* Wait a bit before the next iteration. */ + nanosleep (&waitit, NULL); + } + + return result; +} + +static int +do_test (void) +{ + clockid_t cl; + int result; + + result = clock_test (CLOCK_REALTIME); + + if (clock_getcpuclockid (0, &cl) == 0) + /* XXX It's not yet a bug when this fails. */ + clock_test (cl); + else + printf("CPU clock unavailble, skipping test\n"); + + return result; +} +#define TEST_FUNCTION do_test () + + +#include "../test-skeleton.c" diff --git a/rt/tst-clock2.c b/rt/tst-clock2.c new file mode 100644 index 0000000..4c8fb9f --- /dev/null +++ b/rt/tst-clock2.c @@ -0,0 +1,43 @@ +/* Test setting the monotonic clock. */ + +#include +#include + +#if defined CLOCK_MONOTONIC && defined _POSIX_MONOTONIC_CLOCK + +# include +# include + +static int +do_test (void) +{ + if (sysconf (_SC_MONOTONIC_CLOCK) <= 0) + return 0; + + struct timespec ts; + if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) + { + puts ("clock_gettime(CLOCK_MONOTONIC) failed"); + return 1; + } + + /* Setting the monotonic clock must fail. */ + if (clock_settime (CLOCK_MONOTONIC, &ts) != -1) + { + puts ("clock_settime(CLOCK_MONOTONIC) did not fail"); + return 1; + } + if (errno != EINVAL) + { + printf ("clock_settime(CLOCK_MONOTONIC) set errno to %d, expected %d\n", + errno, EINVAL); + return 1; + } + return 0; +} +# define TEST_FUNCTION do_test () + +#else +# define TEST_FUNCTION 0 +#endif +#include "../test-skeleton.c" diff --git a/rt/tst-clock_nanosleep.c b/rt/tst-clock_nanosleep.c new file mode 100644 index 0000000..eb2b906 --- /dev/null +++ b/rt/tst-clock_nanosleep.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2003-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include + + +/* Test that clock_nanosleep() does sleep. */ +static int +do_test (void) +{ + /* Current time. */ + struct timeval tv1; + (void) gettimeofday (&tv1, NULL); + + struct timespec ts; + ts.tv_sec = 1; + ts.tv_nsec = 0; + TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts)); + + /* At least one second must have passed. */ + struct timeval tv2; + (void) gettimeofday (&tv2, NULL); + + tv2.tv_sec -= tv1.tv_sec; + tv2.tv_usec -= tv1.tv_usec; + if (tv2.tv_usec < 0) + --tv2.tv_sec; + + if (tv2.tv_sec < 1) + { + puts ("clock_nanosleep didn't sleep long enough"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/rt/tst-cpuclock1.c b/rt/tst-cpuclock1.c new file mode 100644 index 0000000..f6d76e3 --- /dev/null +++ b/rt/tst-cpuclock1.c @@ -0,0 +1,321 @@ +/* Test program for process CPU clocks. + Copyright (C) 2004-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* This function is intended to rack up both user and system time. */ +static void +chew_cpu (void) +{ + while (1) + { + static volatile char buf[4096]; + for (int i = 0; i < 100; ++i) + for (size_t j = 0; j < sizeof buf; ++j) + buf[j] = 0xaa; + int nullfd = open ("/dev/null", O_WRONLY); + for (int i = 0; i < 100; ++i) + for (size_t j = 0; j < sizeof buf; ++j) + buf[j] = 0xbb; + write (nullfd, (char *) buf, sizeof buf); + close (nullfd); + if (getppid () == 1) + _exit (2); + } +} + +static int +do_test (void) +{ + int result = 0; + clockid_t cl; + int e; + pid_t dead_child, child; + + /* Fork a child and let it die, to give us a PID known not be valid + (assuming PIDs don't wrap around during the test). */ + { + dead_child = fork (); + if (dead_child == 0) + _exit (0); + if (dead_child < 0) + { + perror ("fork"); + return 1; + } + int x; + if (wait (&x) != dead_child) + { + perror ("wait"); + return 2; + } + } + + /* POSIX says we should get ESRCH for this. */ + e = clock_getcpuclockid (dead_child, &cl); + if (e != ENOSYS && e != ESRCH && e != EPERM) + { + printf ("clock_getcpuclockid on dead PID %d => %s\n", + dead_child, strerror (e)); + result = 1; + } + + /* Now give us a live child eating up CPU time. */ + child = fork (); + if (child == 0) + { + chew_cpu (); + _exit (1); + } + if (child < 0) + { + perror ("fork"); + return 1; + } + + e = clock_getcpuclockid (child, &cl); + if (e == EPERM) + { + puts ("clock_getcpuclockid does not support other processes"); + goto done; + } + if (e != 0) + { + printf ("clock_getcpuclockid on live PID %d => %s\n", + child, strerror (e)); + result = 1; + goto done; + } + + const clockid_t child_clock = cl; + struct timespec res; + if (clock_getres (child_clock, &res) < 0) + { + printf ("clock_getres on live PID %d clock %lx => %s\n", + child, (unsigned long int) child_clock, strerror (errno)); + result = 1; + goto done; + } + printf ("live PID %d clock %lx resolution %ju.%.9ju\n", + child, (unsigned long int) child_clock, + (uintmax_t) res.tv_sec, (uintmax_t) res.tv_nsec); + + struct timespec before, after; + if (clock_gettime (child_clock, &before) < 0) + { + printf ("clock_gettime on live PID %d clock %lx => %s\n", + child, (unsigned long int) child_clock, strerror (errno)); + result = 1; + goto done; + } + /* Should be close to 0.0. */ + printf ("live PID %d before sleep => %ju.%.9ju\n", + child, (uintmax_t) before.tv_sec, (uintmax_t) before.tv_nsec); + + struct timespec sleeptime = { .tv_nsec = 500000000 }; + if (nanosleep (&sleeptime, NULL) != 0) + { + perror ("nanosleep"); + result = 1; + goto done; + } + + if (clock_gettime (child_clock, &after) < 0) + { + printf ("clock_gettime on live PID %d clock %lx => %s\n", + child, (unsigned long int) child_clock, strerror (errno)); + result = 1; + goto done; + } + /* Should be close to 0.5. */ + printf ("live PID %d after sleep => %ju.%.9ju\n", + child, (uintmax_t) after.tv_sec, (uintmax_t) after.tv_nsec); + + struct timespec diff = { .tv_sec = after.tv_sec - before.tv_sec, + .tv_nsec = after.tv_nsec - before.tv_nsec }; + if (diff.tv_nsec < 0) + { + --diff.tv_sec; + diff.tv_nsec += 1000000000; + } + if (diff.tv_sec != 0 + || diff.tv_nsec > 600000000 + || diff.tv_nsec < 100000000) + { + printf ("before - after %ju.%.9ju outside reasonable range\n", + (uintmax_t) diff.tv_sec, (uintmax_t) diff.tv_nsec); + result = 1; + } + + sleeptime.tv_nsec = 100000000; + e = clock_nanosleep (child_clock, 0, &sleeptime, NULL); + if (e == EINVAL || e == ENOTSUP || e == ENOSYS) + { + printf ("clock_nanosleep not supported for other process clock: %s\n", + strerror (e)); + } + else if (e != 0) + { + printf ("clock_nanosleep on other process clock: %s\n", strerror (e)); + result = 1; + } + else + { + struct timespec afterns; + if (clock_gettime (child_clock, &afterns) < 0) + { + printf ("clock_gettime on live PID %d clock %lx => %s\n", + child, (unsigned long int) child_clock, strerror (errno)); + result = 1; + } + else + { + struct timespec d = { .tv_sec = afterns.tv_sec - after.tv_sec, + .tv_nsec = afterns.tv_nsec - after.tv_nsec }; + if (d.tv_nsec < 0) + { + --d.tv_sec; + d.tv_nsec += 1000000000; + } + if (d.tv_sec > 0 + || d.tv_nsec < sleeptime.tv_nsec + || d.tv_nsec > sleeptime.tv_nsec * 2) + { + printf ("nanosleep time %ju.%.9ju outside reasonable range\n", + (uintmax_t) d.tv_sec, (uintmax_t) d.tv_nsec); + result = 1; + } + } + } + + if (kill (child, SIGKILL) != 0) + { + perror ("kill"); + result = 2; + goto done; + } + + /* Wait long enough to let the child finish dying. */ + + sleeptime.tv_nsec = 200000000; + if (nanosleep (&sleeptime, NULL) != 0) + { + perror ("nanosleep"); + result = 1; + goto done; + } + + struct timespec dead; + if (clock_gettime (child_clock, &dead) < 0) + { + printf ("clock_gettime on dead PID %d clock %lx => %s\n", + child, (unsigned long int) child_clock, strerror (errno)); + result = 1; + goto done; + } + /* Should be close to 0.6. */ + printf ("dead PID %d => %ju.%.9ju\n", + child, (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec); + + diff.tv_sec = dead.tv_sec - after.tv_sec; + diff.tv_nsec = dead.tv_nsec - after.tv_nsec; + if (diff.tv_nsec < 0) + { + --diff.tv_sec; + diff.tv_nsec += 1000000000; + } + if (diff.tv_sec != 0 || diff.tv_nsec > 200000000) + { + printf ("dead - after %ju.%.9ju outside reasonable range\n", + (uintmax_t) diff.tv_sec, (uintmax_t) diff.tv_nsec); + result = 1; + } + + /* Now reap the child and verify that its clock is no longer valid. */ + { + int x; + if (waitpid (child, &x, 0) != child) + { + perror ("waitpid"); + result = 1; + } + } + + if (clock_gettime (child_clock, &dead) == 0) + { + printf ("clock_gettime on reaped PID %d clock %lx => %ju%.9ju\n", + child, (unsigned long int) child_clock, + (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec); + result = 1; + } + else + { + if (errno != EINVAL) + result = 1; + printf ("clock_gettime on reaped PID %d clock %lx => %s\n", + child, (unsigned long int) child_clock, strerror (errno)); + } + + if (clock_getres (child_clock, &dead) == 0) + { + printf ("clock_getres on reaped PID %d clock %lx => %ju%.9ju\n", + child, (unsigned long int) child_clock, + (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec); + result = 1; + } + else + { + if (errno != EINVAL) + result = 1; + printf ("clock_getres on reaped PID %d clock %lx => %s\n", + child, (unsigned long int) child_clock, strerror (errno)); + } + + return result; + + done: + { + if (kill (child, SIGKILL) != 0 && errno != ESRCH) + { + perror ("kill"); + return 2; + } + int x; + if (waitpid (child, &x, 0) != child && errno != ECHILD) + { + perror ("waitpid"); + return 2; + } + } + + return result; +} + + +#define TIMEOUT 5 +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/scripts/check-installed-headers.sh b/scripts/check-installed-headers.sh index c2aeea5..4a062e9 100644 --- a/scripts/check-installed-headers.sh +++ b/scripts/check-installed-headers.sh @@ -16,9 +16,11 @@ # License along with the GNU C Library; if not, see # . -# For each installed header, confirm that it's possible to compile a -# file that includes that header and does nothing else, in several -# different compilation modes. +# Check installed headers for cleanliness. For each header, confirm +# that it's possible to compile a file that includes that header and +# does nothing else, in several different compilation modes. Also, +# scan the header for a set of obsolete typedefs that should no longer +# appear. # These compilation switches assume GCC or compatible, which is probably # fine since we also assume that when _building_ glibc. @@ -29,6 +31,13 @@ cxx_modes="-std=c++98 -std=gnu++98 -std=c++11 -std=gnu++11" # These are probably the most commonly used three. lib_modes="-D_DEFAULT_SOURCE=1 -D_GNU_SOURCE=1 -D_XOPEN_SOURCE=700" +# sys/types.h+bits/types.h have to define the obsolete types. +# rpc(svc)/* have the obsolete types too deeply embedded in their API +# to remove. +skip_obsolete_type_check='*/sys/types.h|*/bits/types.h|*/rpc/*|*/rpcsvc/*' +obsolete_type_re=\ +'\<((__)?(quad_t|u(short|int|long|_(char|short|int([0-9]+_t)?|long|quad_t))))\>' + if [ $# -lt 3 ]; then echo "usage: $0 c|c++ \"compile command\" header header header..." >&2 exit 2 @@ -37,10 +46,14 @@ case "$1" in (c) lang_modes="$c_modes" cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.c) + already="$skip_obsolete_type_check" ;; (c++) lang_modes="$cxx_modes" cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.cc) + # The obsolete-type check can be skipped for C++; it is + # sufficient to do it for C. + already="*" ;; (*) echo "usage: $0 c|c++ \"compile command\" header header header..." >&2 @@ -71,10 +84,6 @@ for header in "$@"; do (sys/elf.h) continue;; - # Skip Fortran headers. - (finclude/*) - continue;; - # sys/sysctl.h is unsupported for x32. (sys/sysctl.h) case "$is_x32" in @@ -142,8 +151,22 @@ $expanded_lib_mode int avoid_empty_translation_unit; EOF if $cc_cmd -fsyntax-only $lang_mode "$cih_test_c" 2>&1 - then : - else failed=1 + then + includes=$($cc_cmd -fsyntax-only -H $lang_mode \ + "$cih_test_c" 2>&1 | sed -ne 's/^[.][.]* //p') + for h in $includes; do + # Don't repeat work. + eval 'case "$h" in ('"$already"') continue;; esac' + + if grep -qE "$obsolete_type_re" "$h"; then + echo "*** Obsolete types detected:" + grep -HE "$obsolete_type_re" "$h" + failed=1 + fi + already="$already|$h" + done + else + failed=1 fi done done diff --git a/scripts/check-obsolete-constructs.py b/scripts/check-obsolete-constructs.py deleted file mode 100755 index ce5c722..0000000 --- a/scripts/check-obsolete-constructs.py +++ /dev/null @@ -1,466 +0,0 @@ -#! /usr/bin/python3 -# 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 -# . - -"""Verifies that installed headers do not use any obsolete constructs: - * legacy BSD typedefs superseded by : - ushort uint ulong u_char u_short u_int u_long u_intNN_t quad_t u_quad_t - (sys/types.h is allowed to _define_ these types, but not to use them - to define anything else). -""" - -import argparse -import collections -import re -import sys - -# Simplified lexical analyzer for C preprocessing tokens. -# Does not implement trigraphs. -# Does not implement backslash-newline in the middle of any lexical -# item other than a string literal. -# Does not implement universal-character-names in identifiers. -# Treats prefixed strings (e.g. L"...") as two tokens (L and "...") -# Accepts non-ASCII characters only within comments and strings. - -# Caution: The order of the outermost alternation matters. -# STRING must be before BAD_STRING, CHARCONST before BAD_CHARCONST, -# BLOCK_COMMENT before BAD_BLOCK_COM before PUNCTUATOR, and OTHER must -# be last. -# Caution: There should be no capturing groups other than the named -# captures in the outermost alternation. - -# For reference, these are all of the C punctuators as of C11: -# [ ] ( ) { } , ; ? ~ -# ! != * *= / /= ^ ^= = == -# # ## -# % %= %> %: %:%: -# & &= && -# | |= || -# + += ++ -# - -= -- -> -# . ... -# : :> -# < <% <: << <<= <= -# > >= >> >>= - -# The BAD_* tokens are not part of the official definition of pp-tokens; -# they match unclosed strings, character constants, and block comments, -# so that the regex engine doesn't have to backtrack all the way to the -# beginning of a broken construct and then emit dozens of junk tokens. - -PP_TOKEN_RE_ = re.compile(r""" - (?P \"(?:[^\"\\\r\n]|\\(?:[\r\n -~]|\r\n))*\") - |(?P \"(?:[^\"\\\r\n]|\\[ -~])*) - |(?P \'(?:[^\'\\\r\n]|\\(?:[\r\n -~]|\r\n))*\') - |(?P \'(?:[^\'\\\r\n]|\\[ -~])*) - |(?P /\*(?:\*(?!/)|[^*])*\*/) - |(?P /\*(?:\*(?!/)|[^*])*\*?) - |(?P //[^\r\n]*) - |(?P [_a-zA-Z][_a-zA-Z0-9]*) - |(?P \.?[0-9](?:[0-9a-df-oq-zA-DF-OQ-Z_.]|[eEpP][+-]?)*) - |(?P - [,;?~(){}\[\]] - | [!*/^=]=? - | \#\#? - | %(?:[=>]|:(?:%:)?)? - | &[=&]? - |\|[=|]? - |\+[=+]? - | -[=->]? - |\.(?:\.\.)? - | :>? - | <(?:[%:]|<(?:=|<=?)?)? - | >(?:=|>=?)?) - |(?P \\(?:\r|\n|\r\n)) - |(?P [ \t\n\r\v\f]+) - |(?P .) -""", re.DOTALL | re.VERBOSE) - -HEADER_NAME_RE_ = re.compile(r""" - < [^>\r\n]+ > - | " [^"\r\n]+ " -""", re.DOTALL | re.VERBOSE) - -ENDLINE_RE_ = re.compile(r"""\r|\n|\r\n""") - -# based on the sample code in the Python re documentation -Token_ = collections.namedtuple("Token", ( - "kind", "text", "line", "column", "context")) -Token_.__doc__ = """ - One C preprocessing token, comment, or chunk of whitespace. - 'kind' identifies the token type, which will be one of: - STRING, CHARCONST, BLOCK_COMMENT, LINE_COMMENT, IDENT, - PP_NUMBER, PUNCTUATOR, ESCNL, WHITESPACE, HEADER_NAME, - or OTHER. The BAD_* alternatives in PP_TOKEN_RE_ are - handled within tokenize_c, below. - - 'text' is the sequence of source characters making up the token; - no decoding whatsoever is performed. - - 'line' and 'column' give the position of the first character of the - token within the source file. They are both 1-based. - - 'context' indicates whether or not this token occurred within a - preprocessing directive; it will be None for running text, - '' for the leading '#' of a directive line (because '#' - all by itself on a line is a "null directive"), or the name of - the directive for tokens within a directive line, starting with - the IDENT for the name itself. -""" - -def tokenize_c(file_contents, reporter): - """Yield a series of Token objects, one for each preprocessing - token, comment, or chunk of whitespace within FILE_CONTENTS. - The REPORTER object is expected to have one method, - reporter.error(token, message), which will be called to - indicate a lexical error at the position of TOKEN. - If MESSAGE contains the four-character sequence '{!r}', that - is expected to be replaced by repr(token.text). - """ - - Token = Token_ - PP_TOKEN_RE = PP_TOKEN_RE_ - ENDLINE_RE = ENDLINE_RE_ - HEADER_NAME_RE = HEADER_NAME_RE_ - - line_num = 1 - line_start = 0 - pos = 0 - limit = len(file_contents) - directive = None - at_bol = True - while pos < limit: - if directive == "include": - mo = HEADER_NAME_RE.match(file_contents, pos) - if mo: - kind = "HEADER_NAME" - directive = "after_include" - else: - mo = PP_TOKEN_RE.match(file_contents, pos) - kind = mo.lastgroup - if kind != "WHITESPACE": - directive = "after_include" - else: - mo = PP_TOKEN_RE.match(file_contents, pos) - kind = mo.lastgroup - - text = mo.group() - line = line_num - column = mo.start() - line_start - adj_line_start = 0 - # only these kinds can contain a newline - if kind in ("WHITESPACE", "BLOCK_COMMENT", "LINE_COMMENT", - "STRING", "CHARCONST", "BAD_BLOCK_COM", "ESCNL"): - for tmo in ENDLINE_RE.finditer(text): - line_num += 1 - adj_line_start = tmo.end() - if adj_line_start: - line_start = mo.start() + adj_line_start - - # Track whether or not we are scanning a preprocessing directive. - if kind == "LINE_COMMENT" or (kind == "WHITESPACE" and adj_line_start): - at_bol = True - directive = None - else: - if kind == "PUNCTUATOR" and text == "#" and at_bol: - directive = "" - elif kind == "IDENT" and directive == "": - directive = text - at_bol = False - - # Report ill-formed tokens and rewrite them as their well-formed - # equivalents, so downstream processing doesn't have to know about them. - # (Rewriting instead of discarding provides better error recovery.) - if kind == "BAD_BLOCK_COM": - reporter.error(Token("BAD_BLOCK_COM", "", line, column+1, ""), - "unclosed block comment") - text += "*/" - kind = "BLOCK_COMMENT" - elif kind == "BAD_STRING": - reporter.error(Token("BAD_STRING", "", line, column+1, ""), - "unclosed string") - text += "\"" - kind = "STRING" - elif kind == "BAD_CHARCONST": - reporter.error(Token("BAD_CHARCONST", "", line, column+1, ""), - "unclosed char constant") - text += "'" - kind = "CHARCONST" - - tok = Token(kind, text, line, column+1, - "include" if directive == "after_include" else directive) - # Do not complain about OTHER tokens inside macro definitions. - # $ and @ appear in macros defined by headers intended to be - # included from assembly language, e.g. sysdeps/mips/sys/asm.h. - if kind == "OTHER" and directive != "define": - self.error(tok, "stray {!r} in program") - - yield tok - pos = mo.end() - -# -# Base and generic classes for individual checks. -# - -class ConstructChecker: - """Scan a stream of C preprocessing tokens and possibly report - problems with them. The REPORTER object passed to __init__ has - one method, reporter.error(token, message), which should be - called to indicate a problem detected at the position of TOKEN. - If MESSAGE contains the four-character sequence '{!r}' then that - will be replaced with a textual representation of TOKEN. - """ - def __init__(self, reporter): - self.reporter = reporter - - def examine(self, tok): - """Called once for each token in a header file. - Call self.reporter.error if a problem is detected. - """ - raise NotImplementedError - - def eof(self): - """Called once at the end of the stream. Subclasses need only - override this if it might have something to do.""" - pass - -class NoCheck(ConstructChecker): - """Generic checker class which doesn't do anything. Substitute this - class for a real checker when a particular check should be skipped - for some file.""" - - def examine(self, tok): - pass - -# -# Check for obsolete type names. -# - -# The obsolete type names we're looking for: -OBSOLETE_TYPE_RE_ = re.compile(r"""\A - (__)? - ( quad_t - | u(?: short | int | long - | _(?: char | short | int(?:[0-9]+_t)? | long | quad_t ))) -\Z""", re.VERBOSE) - -class ObsoleteNotAllowed(ConstructChecker): - """Don't allow any use of the obsolete typedefs.""" - def examine(self, tok): - if OBSOLETE_TYPE_RE_.match(tok.text): - self.reporter.error(tok, "use of {!r}") - -class ObsoletePrivateDefinitionsAllowed(ConstructChecker): - """Allow definitions of the private versions of the - obsolete typedefs; that is, 'typedef [anything] __obsolete;' - """ - def __init__(self, reporter): - super().__init__(reporter) - self.in_typedef = False - self.prev_token = None - - def examine(self, tok): - # bits/types.h hides 'typedef' in a macro sometimes. - if (tok.kind == "IDENT" - and tok.text in ("typedef", "__STD_TYPE") - and tok.context is None): - self.in_typedef = True - elif tok.kind == "PUNCTUATOR" and tok.text == ";" and self.in_typedef: - self.in_typedef = False - if self.prev_token.kind == "IDENT": - m = OBSOLETE_TYPE_RE_.match(self.prev_token.text) - if m and m.group(1) != "__": - self.reporter.error(self.prev_token, "use of {!r}") - self.prev_token = None - else: - self._check_prev() - - self.prev_token = tok - - def eof(self): - self._check_prev() - - def _check_prev(self): - if (self.prev_token is not None - and self.prev_token.kind == "IDENT" - and OBSOLETE_TYPE_RE_.match(self.prev_token.text)): - self.reporter.error(self.prev_token, "use of {!r}") - -class ObsoletePublicDefinitionsAllowed(ConstructChecker): - """Allow definitions of the public versions of the obsolete - typedefs. Only specific forms of definition are allowed: - - typedef __obsolete obsolete; // identifiers must agree - typedef __uintN_t u_intN_t; // N must agree - typedef unsigned long int ulong; - typedef unsigned short int ushort; - typedef unsigned int uint; - """ - def __init__(self, reporter): - super().__init__(reporter) - self.typedef_tokens = [] - - def examine(self, tok): - if tok.kind in ("WHITESPACE", "BLOCK_COMMENT", - "LINE_COMMENT", "NL", "ESCNL"): - pass - - elif (tok.kind == "IDENT" and tok.text == "typedef" - and tok.context is None): - if self.typedef_tokens: - self.reporter.error(tok, "typedef inside typedef") - self._reset() - self.typedef_tokens.append(tok) - - elif tok.kind == "PUNCTUATOR" and tok.text == ";": - self._finish() - - elif self.typedef_tokens: - self.typedef_tokens.append(tok) - - def eof(self): - self._reset() - - def _reset(self): - while self.typedef_tokens: - tok = self.typedef_tokens.pop(0) - if tok.kind == "IDENT" and OBSOLETE_TYPE_RE_.match(tok.text): - self.reporter.error(tok, "use of {!r}") - - def _finish(self): - if not self.typedef_tokens: return - if self.typedef_tokens[-1].kind == "IDENT": - m = OBSOLETE_TYPE_RE_.match(self.typedef_tokens[-1].text) - if m: - if self._permissible_public_definition(m): - self.typedef_tokens.clear() - self._reset() - - def _permissible_public_definition(self, m): - if m.group(1) == "__": return False - name = m.group(2) - toks = self.typedef_tokens - ntok = len(toks) - if ntok == 3 and toks[1].kind == "IDENT": - defn = toks[1].text - n = OBSOLETE_TYPE_RE_.match(defn) - if n and n.group(1) == "__" and n.group(2) == name: - return True - - if (name[:5] == "u_int" and name[-2:] == "_t" - and defn[:6] == "__uint" and defn[-2:] == "_t" - and name[5:-2] == defn[6:-2]): - return True - - return False - - if (name == "ulong" and ntok == 5 - and toks[1].kind == "IDENT" and toks[1].text == "unsigned" - and toks[2].kind == "IDENT" and toks[2].text == "long" - and toks[3].kind == "IDENT" and toks[3].text == "int"): - return True - - if (name == "ushort" and ntok == 5 - and toks[1].kind == "IDENT" and toks[1].text == "unsigned" - and toks[2].kind == "IDENT" and toks[2].text == "short" - and toks[3].kind == "IDENT" and toks[3].text == "int"): - return True - - if (name == "uint" and ntok == 4 - and toks[1].kind == "IDENT" and toks[1].text == "unsigned" - and toks[2].kind == "IDENT" and toks[2].text == "int"): - return True - - return False - -def ObsoleteTypedefChecker(reporter, fname): - """Factory: produce an instance of the appropriate - obsolete-typedef checker for FNAME.""" - - # The obsolete rpc/ and rpcsvc/ headers are allowed to use the - # obsolete types, because it would be more trouble than it's - # worth to remove them from headers that we intend to stop - # installing eventually anyway. - if (fname.startswith("rpc/") - or fname.startswith("rpcsvc/") - or "/rpc/" in fname - or "/rpcsvc/" in fname): - return NoCheck(reporter) - - # bits/types.h is allowed to define the __-versions of the - # obsolete types. - if (fname == "bits/types.h" - or fname.endswith("/bits/types.h")): - return ObsoletePrivateDefinitionsAllowed(reporter) - - # sys/types.h is allowed to use the __-versions of the - # obsolete types, but only to define the unprefixed versions. - if (fname == "sys/types.h" - or fname.endswith("/sys/types.h")): - return ObsoletePublicDefinitionsAllowed(reporter) - - return ObsoleteNotAllowed(reporter) - -# -# Master control -# - -class HeaderChecker: - """Perform all of the checks on each header. This is also the - "reporter" object expected by tokenize_c and ConstructChecker. - """ - def __init__(self): - self.fname = None - self.status = 0 - - def error(self, tok, message): - self.status = 1 - if '{!r}' in message: - message = message.format(tok.text) - sys.stderr.write("{}:{}:{}: error: {}\n".format( - self.fname, tok.line, tok.column, message)) - - def check(self, fname): - self.fname = fname - try: - with open(fname, "rt") as fp: - contents = fp.read() - except OSError as e: - sys.stderr.write("{}: {}\n".format(fname, e.strerror)) - self.status = 1 - return - - typedef_checker = ObsoleteTypedefChecker(self, self.fname) - - for tok in tokenize_c(contents, self): - typedef_checker.examine(tok) - -def main(): - ap = argparse.ArgumentParser(description=__doc__) - ap.add_argument("headers", metavar="header", nargs="+", - help="one or more headers to scan for obsolete constructs") - args = ap.parse_args() - - checker = HeaderChecker() - for fname in args.headers: - # Headers whose installed name begins with "finclude/" contain - # Fortran, not C, and this program should completely ignore them. - if not (fname.startswith("finclude/") or "/finclude/" in fname): - checker.check(fname) - sys.exit(checker.status) - -main() diff --git a/scripts/check-wx-segment.py b/scripts/check-wx-segment.py deleted file mode 100644 index e1fa793..0000000 --- a/scripts/check-wx-segment.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/python3 -# Check ELF program headers for WX segments. -# Copyright (C) 2020 Free Software Foundation, Inc. -# This file is part of the GNU C Library. -# -# The GNU C Library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# The GNU C Library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with the GNU C Library; if not, see -# . - -"""Check that the program headers do not contain write-exec segments.""" - -import argparse -import os.path -import re -import sys - -# Regular expression to extract the RWE flags field. The -# address/offset columns have varying width. -RE_LOAD = re.compile( - r'^ LOAD +(?:0x[0-9a-fA-F]+ +){5}([R ][W ][ E]) +0x[0-9a-fA-F]+\n\Z') - -def process_file(path, inp, xfail): - """Analyze one input file.""" - - errors = 0 - for line in inp: - error = None - if line.startswith(' LOAD '): - match = RE_LOAD.match(line) - if match is None: - error = 'Invalid LOAD line' - else: - flags, = match.groups() - if 'W' in flags and 'E' in flags: - if xfail: - print('{}: warning: WX segment (as expected)'.format( - path)) - else: - error = 'WX segment' - - if error is not None: - print('{}: error: {}: {!r}'.format(path, error, line.strip())) - errors += 1 - - if xfail and errors == 0: - print('{}: warning: missing expected WX segment'.format(path)) - return errors - - -def main(): - """The main entry point.""" - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('--xfail', - help='Mark input files as XFAILed ("*" for all)', - type=str, default='') - parser.add_argument('phdrs', - help='Files containing readelf -Wl output', - nargs='*') - opts = parser.parse_args(sys.argv) - - xfails = set(opts.xfail.split(' ')) - xfails_all = opts.xfail.strip() == '*' - - errors = 0 - for path in opts.phdrs: - xfail = ((os.path.basename(path) + '.phdrs') in xfails - or xfails_all) - with open(path) as inp: - errors += process_file(path, inp, xfail) - if errors > 0: - sys.exit(1) - - -if __name__ == '__main__': - main() diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c index 8035e8a..e7837f9 100644 --- a/stdlib/test-bz22786.c +++ b/stdlib/test-bz22786.c @@ -26,39 +26,49 @@ #include #include #include -#include -#include -#include -#include #include #include static int do_test (void) { - char *dir = support_create_temp_directory ("bz22786."); - char *lnk = xasprintf ("%s/symlink", dir); - const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; + const char dir[] = "bz22786"; + const char lnk[] = "bz22786/symlink"; + + rmdir (dir); + if (mkdir (dir, 0755) != 0 && errno != EEXIST) + { + printf ("mkdir %s: %m\n", dir); + return EXIT_FAILURE; + } + if (symlink (".", lnk) != 0 && errno != EEXIST) + { + printf ("symlink (%s, %s): %m\n", dir, lnk); + return EXIT_FAILURE; + } + + const size_t path_len = (size_t) INT_MAX + 1; + + DIAG_PUSH_NEEDS_COMMENT; +#if __GNUC_PREREQ (7, 0) + /* GCC 7 warns about too-large allocations; here we need such + allocation to succeed for the test to work. */ + DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); +#endif + char *path = malloc (path_len); + DIAG_POP_NEEDS_COMMENT; - struct support_blob_repeat repeat - = support_blob_repeat_allocate ("a", 1, path_len); - char *path = repeat.start; if (path == NULL) { - printf ("Repeated allocation (%zu bytes): %m\n", path_len); - /* On 31-bit s390 the malloc will always fail as we do not have - so much memory, and we want to mark the test unsupported. - Likewise on systems with little physical memory the test will - fail and should be unsupported. */ + printf ("malloc (%zu): %m\n", path_len); return EXIT_UNSUPPORTED; } - TEST_VERIFY_EXIT (symlink (".", lnk) == 0); - - /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */ - char *p = mempcpy (path, lnk, strlen (lnk)); + /* Construct very long path = "bz22786/symlink/aaaa....." */ + char *p = mempcpy (path, lnk, sizeof (lnk) - 1); *(p++) = '/'; - p[path_len - (p - path) - 1] = '\0'; + memset (p, 'a', path_len - (path - p) - 2); + p[path_len - (path - p) - 1] = '\0'; /* This call crashes before the fix for bz22786 on 32-bit platforms. */ p = realpath (path, NULL); @@ -71,9 +81,7 @@ do_test (void) /* Cleanup. */ unlink (lnk); - support_blob_repeat_free (&repeat); - free (lnk); - free (dir); + rmdir (dir); return 0; } diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c index 0099282..4636ce9 100644 --- a/stdlib/tst-setcontext9.c +++ b/stdlib/tst-setcontext9.c @@ -41,59 +41,30 @@ f2 (void) } static void -f1b (void) +f1 (void) { + puts ("start f1"); + if (getcontext (&ctx[2]) != 0) + { + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } if (done) { - puts ("set context in f1b"); + puts ("set context in f1"); if (setcontext (&ctx[3]) != 0) { printf ("%s: setcontext: %m\n", __FUNCTION__); exit (EXIT_FAILURE); } } - exit (EXIT_FAILURE); -} - -static void -f1a (void) -{ - static char st2[32768]; - puts ("start f1a"); - if (getcontext (&ctx[2]) != 0) - { - printf ("%s: getcontext: %m\n", __FUNCTION__); - exit (EXIT_FAILURE); - } - ctx[2].uc_stack.ss_sp = st2; - ctx[2].uc_stack.ss_size = sizeof st2; - ctx[2].uc_link = &ctx[0]; - makecontext (&ctx[2], (void (*) (void)) f1b, 0); f2 (); } -/* The execution path through the test looks like this: - do_test (call) - -> "making contexts" - -> "swap contexts" - f1a (via swapcontext to ctx[1], with alternate stack) - -> "start f1a" - f2 (call) - -> "swap contexts in f2" - f1b (via swapcontext to ctx[2], with alternate stack) - -> "set context in f1b" - do_test (via setcontext to ctx[3], main stack) - -> "setcontext" - f2 (via setcontext to ctx[4], with alternate stack) - -> "end f2" - - We must use an alternate stack for f1b, because if we don't then the - result of executing an earlier caller may overwrite registers - spilled to the stack in f2. */ static int do_test (void) { - static char st1[32768]; + char st1[32768]; puts ("making contexts"); if (getcontext (&ctx[0]) != 0) { @@ -108,7 +79,7 @@ do_test (void) ctx[1].uc_stack.ss_sp = st1; ctx[1].uc_stack.ss_size = sizeof st1; ctx[1].uc_link = &ctx[0]; - makecontext (&ctx[1], (void (*) (void)) f1a, 0); + makecontext (&ctx[1], (void (*) (void)) f1, 0); puts ("swap contexts"); if (swapcontext (&ctx[3], &ctx[1]) != 0) { diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c index dc53c1e..d14638d 100644 --- a/stdlib/tst-strtod-overflow.c +++ b/stdlib/tst-strtod-overflow.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #define EXPONENT "e-2147483649" #define SIZE 214748364 @@ -28,23 +26,21 @@ static int do_test (void) { - struct support_blob_repeat repeat = support_blob_repeat_allocate - ("0", 1, 1 + SIZE + sizeof (EXPONENT)); - if (repeat.size == 0) + char *p = malloc (1 + SIZE + sizeof (EXPONENT)); + if (p == NULL) { - puts ("warning: memory allocation failed, cannot test for overflow"); - return EXIT_UNSUPPORTED; + puts ("malloc failed, cannot test for overflow"); + return 0; } - char *p = repeat.start; p[0] = '1'; + memset (p + 1, '0', SIZE); memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT)); double d = strtod (p, NULL); if (d != 0) { - printf ("error: strtod returned wrong value: %a\n", d); + printf ("strtod returned wrong value: %a\n", d); return 1; } - support_blob_repeat_free (&repeat); return 0; } diff --git a/streams/Makefile b/streams/Makefile index 04922fa..ac8963c 100644 --- a/streams/Makefile +++ b/streams/Makefile @@ -22,7 +22,7 @@ subdir := streams include ../Makeconfig -#headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h +headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach include ../Rules diff --git a/string/Makefile b/string/Makefile index aa2da9c..680431f 100644 --- a/string/Makefile +++ b/string/Makefile @@ -64,12 +64,6 @@ 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/str-two-way.h b/string/str-two-way.h index 358959b..523d946 100644 --- a/string/str-two-way.h +++ b/string/str-two-way.h @@ -221,7 +221,7 @@ critical_factorization (const unsigned char *needle, size_t needle_len, most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */ -static inline RETURN_TYPE +static RETURN_TYPE two_way_short_needle (const unsigned char *haystack, size_t haystack_len, const unsigned char *needle, size_t needle_len) { @@ -382,11 +382,8 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len, and sublinear performance O(HAYSTACK_LEN / NEEDLE_LEN) is possible. If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and - sublinear performance is not possible. - - Since this function is large and complex, block inlining to avoid - slowing down the common case of small needles. */ -__attribute__((noinline)) static RETURN_TYPE + sublinear performance is not possible. */ +static RETURN_TYPE two_way_long_needle (const unsigned char *haystack, size_t haystack_len, const unsigned char *needle, size_t needle_len) { diff --git a/string/strcasestr.c b/string/strcasestr.c index 8aa7603..5909fe3 100644 --- a/string/strcasestr.c +++ b/string/strcasestr.c @@ -37,9 +37,8 @@ /* Two-Way algorithm. */ #define RETURN_TYPE char * #define AVAILABLE(h, h_l, j, n_l) \ - (((j) + (n_l) <= (h_l)) \ - || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \ - (j) + (n_l) <= (h_l))) + (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \ + (j) + (n_l) <= (h_l))) #define CHECK_EOL (1) #define RET0_IF_0(a) if (!a) goto ret0 #define CANON_ELEMENT(c) TOLOWER (c) @@ -59,22 +58,31 @@ case-insensitive comparison. This function gives unspecified results in multibyte locales. */ char * -STRCASESTR (const char *haystack, const char *needle) +STRCASESTR (const char *haystack_start, const char *needle_start) { + const char *haystack = haystack_start; + const char *needle = needle_start; size_t needle_len; /* Length of NEEDLE. */ size_t haystack_len; /* Known minimum length of HAYSTACK. */ - - /* Handle empty NEEDLE special case. */ - if (needle[0] == '\0') - return (char *) haystack; - - /* Ensure HAYSTACK length is at least as long as NEEDLE length. - Since a match may occur early on in a huge HAYSTACK, use strnlen - and read ahead a few cachelines for improved performance. */ - needle_len = strlen (needle); - haystack_len = __strnlen (haystack, needle_len + 256); - if (haystack_len < needle_len) + bool ok = true; /* True if NEEDLE is prefix of HAYSTACK. */ + + /* Determine length of NEEDLE, and in the process, make sure + HAYSTACK is at least as long (no point processing all of a long + NEEDLE if HAYSTACK is too short). */ + while (*haystack && *needle) + { + ok &= (TOLOWER ((unsigned char) *haystack) + == TOLOWER ((unsigned char) *needle)); + haystack++; + needle++; + } + if (*needle) return NULL; + if (ok) + return (char *) haystack_start; + needle_len = needle - needle_start; + haystack = haystack_start + 1; + haystack_len = needle_len - 1; /* Perform the search. Abstract memory is considered to be an array of 'unsigned char' values, not an array of 'char' values. See @@ -82,10 +90,10 @@ STRCASESTR (const char *haystack, const char *needle) if (needle_len < LONG_NEEDLE_THRESHOLD) return two_way_short_needle ((const unsigned char *) haystack, haystack_len, - (const unsigned char *) needle, + (const unsigned char *) needle_start, needle_len); return two_way_long_needle ((const unsigned char *) haystack, haystack_len, - (const unsigned char *) needle, + (const unsigned char *) needle_start, needle_len); } diff --git a/string/string.h b/string/string.h index 22cd0fa..150cfd8 100644 --- a/string/string.h +++ b/string/string.h @@ -33,8 +33,7 @@ __BEGIN_DECLS #include /* Tell the caller that we provide correct C++ prototypes. */ -#if defined __cplusplus && (__GNUC_PREREQ (4, 4) \ - || __glibc_clang_prereq (3, 5)) +#if defined __cplusplus && __GNUC_PREREQ (4, 4) # define __CORRECT_ISO_CPP_STRING_H_PROTO #endif diff --git a/string/strstr.c b/string/strstr.c index 7ffb18a..265e9f3 100644 --- a/string/strstr.c +++ b/string/strstr.c @@ -16,17 +16,28 @@ License along with the GNU C Library; if not, see . */ +/* This particular implementation was written by Eric Blake, 2008. */ + #ifndef _LIBC # include #endif +/* Specification of strstr. */ #include +#include + +#ifndef _LIBC +# define __builtin_expect(expr, val) (expr) +#endif + #define RETURN_TYPE char * #define AVAILABLE(h, h_l, j, n_l) \ - (((j) + (n_l) <= (h_l)) \ - || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \ - (j) + (n_l) <= (h_l))) + (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \ + (j) + (n_l) <= (h_l))) +#define CHECK_EOL (1) +#define RET0_IF_0(a) if (!a) goto ret0 +#define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C)) #include "str-two-way.h" #undef strstr @@ -35,128 +46,48 @@ #define STRSTR strstr #endif -static inline char * -strstr2 (const unsigned char *hs, const unsigned char *ne) -{ - uint32_t h1 = (ne[0] << 16) | ne[1]; - uint32_t h2 = 0; - for (int c = hs[0]; h1 != h2 && c != 0; c = *++hs) - h2 = (h2 << 16) | c; - return h1 == h2 ? (char *)hs - 2 : NULL; -} - -static inline char * -strstr3 (const unsigned char *hs, const unsigned char *ne) -{ - uint32_t h1 = ((uint32_t)ne[0] << 24) | (ne[1] << 16) | (ne[2] << 8); - uint32_t h2 = 0; - for (int c = hs[0]; h1 != h2 && c != 0; c = *++hs) - h2 = (h2 | c) << 8; - return h1 == h2 ? (char *)hs - 3 : NULL; -} - -/* Hash character pairs so a small shift table can be used. All bits of - p[0] are included, but not all bits from p[-1]. So if two equal hashes - match on p[-1], p[0] matches too. Hash collisions are harmless and result - in smaller shifts. */ -#define hash2(p) (((size_t)(p)[0] - ((size_t)(p)[-1] << 3)) % sizeof (shift)) - -/* Fast strstr algorithm with guaranteed linear-time performance. - Small needles up to size 3 use a dedicated linear search. Longer needles - up to size 256 use a novel modified Horspool algorithm. It hashes pairs - of characters to quickly skip past mismatches. The main search loop only - exits if the last 2 characters match, avoiding unnecessary calls to memcmp - and allowing for a larger skip if there is no match. A self-adapting - filtering check is used to quickly detect mismatches in long needles. - By limiting the needle length to 256, the shift table can be reduced to 8 - bits per entry, lowering preprocessing overhead and minimizing cache effects. - The limit also implies worst-case performance is linear. - Needles larger than 256 characters use the linear-time Two-Way algorithm. */ +/* Return the first occurrence of NEEDLE in HAYSTACK. Return HAYSTACK + if NEEDLE is empty, otherwise NULL if NEEDLE is not found in + HAYSTACK. */ char * -STRSTR (const char *haystack, const char *needle) +STRSTR (const char *haystack_start, const char *needle_start) { - const unsigned char *hs = (const unsigned char *) haystack; - const unsigned char *ne = (const unsigned char *) needle; - - /* Handle short needle special cases first. */ - if (ne[0] == '\0') - return (char *)hs; - hs = (const unsigned char *)strchr ((const char*)hs, ne[0]); - if (hs == NULL || ne[1] == '\0') - return (char*)hs; - if (ne[2] == '\0') - return strstr2 (hs, ne); - if (ne[3] == '\0') - return strstr3 (hs, ne); - - /* Ensure haystack length is at least as long as needle length. - Since a match may occur early on in a huge haystack, use strnlen - and read ahead a few cachelines for improved performance. */ - size_t ne_len = strlen ((const char*)ne); - size_t hs_len = __strnlen ((const char*)hs, ne_len | 512); - if (hs_len < ne_len) + const char *haystack = haystack_start; + const char *needle = needle_start; + size_t needle_len; /* Length of NEEDLE. */ + size_t haystack_len; /* Known minimum length of HAYSTACK. */ + bool ok = true; /* True if NEEDLE is prefix of HAYSTACK. */ + + /* Determine length of NEEDLE, and in the process, make sure + HAYSTACK is at least as long (no point processing all of a long + NEEDLE if HAYSTACK is too short). */ + while (*haystack && *needle) + ok &= *haystack++ == *needle++; + if (*needle) return NULL; - - /* Check whether we have a match. This improves performance since we - avoid initialization overheads. */ - if (memcmp (hs, ne, ne_len) == 0) - return (char *) hs; - - /* Use Two-Way algorithm for very long needles. */ - if (__glibc_unlikely (ne_len > 256)) - return two_way_long_needle (hs, hs_len, ne, ne_len); - - const unsigned char *end = hs + hs_len - ne_len; - uint8_t shift[256]; - size_t tmp, shift1; - size_t m1 = ne_len - 1; - size_t offset = 0; - - /* Initialize bad character shift hash table. */ - memset (shift, 0, sizeof (shift)); - for (int i = 1; i < m1; i++) - shift[hash2 (ne + i)] = i; - /* Shift1 is the amount we can skip after matching the hash of the - needle end but not the full needle. */ - shift1 = m1 - shift[hash2 (ne + m1)]; - shift[hash2 (ne + m1)] = m1; - - while (1) - { - if (__glibc_unlikely (hs > end)) - { - end += __strnlen ((const char*)end + m1 + 1, 2048); - if (hs > end) - return NULL; - } - - /* Skip past character pairs not in the needle. */ - do - { - hs += m1; - tmp = shift[hash2 (hs)]; - } - while (tmp == 0 && hs <= end); - - /* If the match is not at the end of the needle, shift to the end - and continue until we match the hash of the needle end. */ - hs -= tmp; - if (tmp < m1) - continue; - - /* Hash of the last 2 characters matches. If the needle is long, - try to quickly filter out mismatches. */ - if (m1 < 15 || memcmp (hs + offset, ne + offset, 8) == 0) - { - if (memcmp (hs, ne, m1) == 0) - return (void *) hs; - - /* Adjust filter offset when it doesn't find the mismatch. */ - offset = (offset >= 8 ? offset : m1) - 8; - } - - /* Skip based on matching the hash of the needle end. */ - hs += shift1; - } + if (ok) + return (char *) haystack_start; + + /* Reduce the size of haystack using strchr, since it has a smaller + linear coefficient than the Two-Way algorithm. */ + needle_len = needle - needle_start; + haystack = strchr (haystack_start + 1, *needle_start); + if (!haystack || __builtin_expect (needle_len == 1, 0)) + return (char *) haystack; + needle -= needle_len; + haystack_len = (haystack > haystack_start + needle_len ? 1 + : needle_len + haystack_start - haystack); + + /* Perform the search. Abstract memory is considered to be an array + of 'unsigned char' values, not an array of 'char' values. See + ISO C 99 section 6.2.6.1. */ + if (needle_len < LONG_NEEDLE_THRESHOLD) + return two_way_short_needle ((const unsigned char *) haystack, + haystack_len, + (const unsigned char *) needle, needle_len); + return two_way_long_needle ((const unsigned char *) haystack, haystack_len, + (const unsigned char *) needle, needle_len); } libc_hidden_builtin_def (strstr) + +#undef LONG_NEEDLE_THRESHOLD diff --git a/string/test-strerror-errno.c b/string/test-strerror-errno.c deleted file mode 100644 index 8e744e7..0000000 --- a/string/test-strerror-errno.c +++ /dev/null @@ -1,61 +0,0 @@ -/* 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/string/test-strstr.c b/string/test-strstr.c index e9e14c1..8d99716 100644 --- a/string/test-strstr.c +++ b/string/test-strstr.c @@ -138,74 +138,19 @@ check1 (void) static void check2 (void) { - const char s1_stack[] = ", enable_static, \0, enable_shared, "; - const size_t s1_byte_count = 18; - const char *s2_stack = &(s1_stack[s1_byte_count]); - const size_t s2_byte_count = 18; + const char s1[] = ", enable_static, \0, enable_shared, "; char *exp_result; - const size_t page_size_real = getpagesize (); + char *s2 = (void *) buf1 + page_size - 18; - /* Haystack at end of page. The following page is protected. */ - char *s1_page_end = (void *) buf1 + page_size - s1_byte_count; - strcpy (s1_page_end, s1_stack); - - /* Haystack which crosses a page boundary. - Note: page_size is at least 2 * getpagesize. See test_init. */ - char *s1_page_cross = (void *) buf1 + page_size_real - 8; - strcpy (s1_page_cross, s1_stack); - - /* Needle at end of page. The following page is protected. */ - char *s2_page_end = (void *) buf2 + page_size - s2_byte_count; - strcpy (s2_page_end, s2_stack); - - /* Needle which crosses a page boundary. - Note: page_size is at least 2 * getpagesize. See test_init. */ - char *s2_page_cross = (void *) buf2 + page_size_real - 8; - strcpy (s2_page_cross, s2_stack); - - exp_result = stupid_strstr (s1_stack, s2_stack); + strcpy (s2, s1); + exp_result = stupid_strstr (s1, s1 + 18); FOR_EACH_IMPL (impl, 0) { - check_result (impl, s1_stack, s2_stack, exp_result); - check_result (impl, s1_stack, s2_page_end, exp_result); - check_result (impl, s1_stack, s2_page_cross, exp_result); - - check_result (impl, s1_page_end, s2_stack, exp_result); - check_result (impl, s1_page_end, s2_page_end, exp_result); - check_result (impl, s1_page_end, s2_page_cross, exp_result); - - check_result (impl, s1_page_cross, s2_stack, exp_result); - check_result (impl, s1_page_cross, s2_page_end, exp_result); - check_result (impl, s1_page_cross, s2_page_cross, exp_result); + check_result (impl, s1, s1 + 18, exp_result); + check_result (impl, s2, s1 + 18, exp_result); } } -#define N 1024 - -static void -pr23637 (void) -{ - char *h = (char*) buf1; - char *n = (char*) buf2; - - for (int i = 0; i < N; i++) - { - n[i] = 'x'; - h[i] = ' '; - h[i + N] = 'x'; - } - - n[N] = '\0'; - h[N * 2] = '\0'; - - /* Ensure we don't match at the first 'x'. */ - h[0] = 'x'; - - char *exp_result = stupid_strstr (h, n); - FOR_EACH_IMPL (impl, 0) - check_result (impl, h, n, exp_result); -} - static int test_main (void) { @@ -213,7 +158,6 @@ test_main (void) check1 (); check2 (); - pr23637 (); printf ("%23s", ""); FOR_EACH_IMPL (impl, 0) @@ -258,9 +202,6 @@ test_main (void) do_test (15, 9, hlen, klen, 1); do_test (15, 15, hlen, klen, 0); do_test (15, 15, hlen, klen, 1); - - do_test (15, 15, hlen + klen * 4, klen * 4, 0); - do_test (15, 15, hlen + klen * 4, klen * 4, 1); } do_test (0, 0, page_size - 1, 16, 0); diff --git a/support/Makefile b/support/Makefile index 3c940aa..652d2cd 100644 --- a/support/Makefile +++ b/support/Makefile @@ -25,7 +25,6 @@ extra-libs-others = $(extra-libs) extra-libs-noinstall := $(extra-libs) libsupport-routines = \ - blob_repeat \ check \ check_addrinfo \ check_dns_packet \ @@ -44,9 +43,6 @@ libsupport-routines = \ support_capture_subprocess \ support_capture_subprocess_check \ support_chroot \ - support_copy_file_range \ - support_descriptor_supports_holes \ - support_descriptors \ support_enter_mount_namespace \ support_enter_network_namespace \ support_format_address_family \ @@ -57,16 +53,12 @@ libsupport-routines = \ support_format_netent \ support_isolate_in_subprocess \ support_openpty \ - support_paths \ support_quote_blob \ - support_quote_string \ support_record_failure \ support_run_diff \ support_shared_allocate \ - support_subprocess \ support_test_compare_blob \ support_test_compare_failure \ - support_test_compare_string \ support_write_file_string \ support_test_main \ support_test_verify_impl \ @@ -80,7 +72,6 @@ libsupport-routines = \ xchroot \ xclose \ xconnect \ - xcopy_file_range \ xdlfcn \ xdup2 \ xfclose \ @@ -93,19 +84,16 @@ libsupport-routines = \ xmalloc \ xmemstream \ xmkdir \ - xmkdirp \ xmmap \ xmprotect \ xmunmap \ xopen \ xpipe \ xpoll \ - xposix_memalign \ xpthread_attr_destroy \ xpthread_attr_init \ xpthread_attr_setdetachstate \ xpthread_attr_setguardsize \ - xpthread_attr_setstack \ xpthread_attr_setstacksize \ xpthread_barrier_destroy \ xpthread_barrier_init \ @@ -132,7 +120,6 @@ libsupport-routines = \ xpthread_mutexattr_settype \ xpthread_once \ xpthread_rwlock_init \ - xpthread_rwlock_destroy \ xpthread_rwlock_rdlock \ xpthread_rwlock_unlock \ xpthread_rwlock_wrlock \ @@ -150,12 +137,8 @@ libsupport-routines = \ xsigaction \ xsignal \ xsocket \ - xposix_spawn \ - xposix_spawn_file_actions_addclose \ - xposix_spawn_file_actions_adddup2 \ xstrdup \ xstrndup \ - xsymlink \ xsysconf \ xunlink \ xwaitpid \ @@ -168,56 +151,15 @@ ifeq ($(build-shared),yes) libsupport-inhibit-o += .o endif -CFLAGS-support_paths.c = \ - -DSRCDIR_PATH=\"`cd .. ; pwd`\" \ - -DOBJDIR_PATH=\"`cd $(objpfx)/..; pwd`\" \ - -DOBJDIR_ELF_LDSO_PATH=\"`cd $(objpfx)/..; pwd`/elf/$(rtld-installed-name)\" \ - -DINSTDIR_PATH=\"$(prefix)\" \ - -DLIBDIR_PATH=\"$(libdir)\" \ - -DBINDIR_PATH=\"$(bindir)\" \ - -DROOTSBINDIR_PATH=\"$(rootsbindir)\" - -ifeq (,$(CXX)) -LINKS_DSO_PROGRAM = links-dso-program-c -else -LINKS_DSO_PROGRAM = links-dso-program -LDLIBS-links-dso-program = -lstdc++ -lgcc -lgcc_s $(libunwind) -endif - -ifeq (yes,$(have-selinux)) -LDLIBS-$(LINKS_DSO_PROGRAM) += -lselinux -endif - - -LDLIBS-test-container = $(libsupport) - -others += test-container -others-noinstall += test-container - -others += shell-container echo-container true-container -others-noinstall += shell-container echo-container true-container - -others += $(LINKS_DSO_PROGRAM) -others-noinstall += $(LINKS_DSO_PROGRAM) - -$(objpfx)test-container : $(libsupport) -$(objpfx)shell-container : $(libsupport) -$(objpfx)echo-container : $(libsupport) -$(objpfx)true-container : $(libsupport) - tests = \ README-testing \ tst-support-namespace \ - tst-support_blob_repeat \ tst-support_capture_subprocess \ - tst-support_descriptors \ tst-support_format_dns_packet \ tst-support_quote_blob \ - tst-support_quote_string \ tst-support_record_failure \ tst-test_compare \ tst-test_compare_blob \ - tst-test_compare_string \ tst-xreadlink \ ifeq ($(run-built-tests),yes) @@ -234,6 +176,4 @@ endif $(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so -tst-support_capture_subprocess-ARGS = -- $(host-test-program-cmd) - include ../Rules diff --git a/support/blob_repeat.c b/support/blob_repeat.c deleted file mode 100644 index 16c1e44..0000000 --- a/support/blob_repeat.c +++ /dev/null @@ -1,282 +0,0 @@ -/* Repeating a memory blob, with alias mapping optimization. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Small allocations should use malloc directly instead of the mmap - optimization because mappings carry a lot of overhead. */ -static const size_t maximum_small_size = 4 * 1024 * 1024; - -/* Internal helper for fill. */ -static void -fill0 (char *target, const char *element, size_t element_size, - size_t count) -{ - while (count > 0) - { - memcpy (target, element, element_size); - target += element_size; - --count; - } -} - -/* Fill the buffer at TARGET with COUNT copies of the ELEMENT_SIZE - bytes starting at ELEMENT. */ -static void -fill (char *target, const char *element, size_t element_size, - size_t count) -{ - if (element_size == 0 || count == 0) - return; - else if (element_size == 1) - memset (target, element[0], count); - else if (element_size == sizeof (wchar_t)) - { - wchar_t wc; - memcpy (&wc, element, sizeof (wc)); - wmemset ((wchar_t *) target, wc, count); - } - else if (element_size < 1024 && count > 4096) - { - /* Use larger copies for really small element sizes. */ - char buffer[8192]; - size_t buffer_count = sizeof (buffer) / element_size; - fill0 (buffer, element, element_size, buffer_count); - while (count > 0) - { - size_t copy_count = buffer_count; - if (copy_count > count) - copy_count = count; - size_t copy_bytes = copy_count * element_size; - memcpy (target, buffer, copy_bytes); - target += copy_bytes; - count -= copy_count; - } - } - else - fill0 (target, element, element_size, count); -} - -/* Use malloc instead of mmap for small allocations and unusual size - combinations. */ -static struct support_blob_repeat -allocate_malloc (size_t total_size, const void *element, size_t element_size, - size_t count) -{ - void *buffer = malloc (total_size); - if (buffer == NULL) - return (struct support_blob_repeat) { 0 }; - fill (buffer, element, element_size, count); - return (struct support_blob_repeat) - { - .start = buffer, - .size = total_size, - .use_malloc = true - }; -} - -/* Return the least common multiple of PAGE_SIZE and ELEMENT_SIZE, - avoiding overflow. This assumes that PAGE_SIZE is a power of - two. */ -static size_t -minimum_stride_size (size_t page_size, size_t element_size) -{ - TEST_VERIFY_EXIT (page_size > 0); - TEST_VERIFY_EXIT (element_size > 0); - - /* Compute the number of trailing zeros common to both sizes. */ - unsigned int common_zeros = __builtin_ctzll (page_size | element_size); - - /* In the product, this power of two appears twice, but in the least - common multiple, it appears only once. Therefore, shift one - factor. */ - size_t multiple; - if (__builtin_mul_overflow (page_size >> common_zeros, element_size, - &multiple)) - return 0; - return multiple; -} - -/* Allocations larger than maximum_small_size potentially use mmap - with alias mappings. */ -static struct support_blob_repeat -allocate_big (size_t total_size, const void *element, size_t element_size, - size_t count) -{ - unsigned long page_size = xsysconf (_SC_PAGESIZE); - size_t stride_size = minimum_stride_size (page_size, element_size); - if (stride_size == 0) - { - errno = EOVERFLOW; - return (struct support_blob_repeat) { 0 }; - } - - /* Ensure that the stride size is at least maximum_small_size. This - is necessary to reduce the number of distinct mappings. */ - if (stride_size < maximum_small_size) - stride_size - = ((maximum_small_size + stride_size - 1) / stride_size) * stride_size; - - if (stride_size > total_size) - /* The mmap optimization would not save anything. */ - return allocate_malloc (total_size, element, element_size, count); - - /* Reserve the memory region. If we cannot create the mapping, - there is no reason to set up the backing file. */ - void *target = mmap (NULL, total_size, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (target == MAP_FAILED) - return (struct support_blob_repeat) { 0 }; - - /* Create the backing file for the repeated mapping. Call mkstemp - directly to remove the resources backing the temporary file - immediately, once support_blob_repeat_free is called. Using - create_temp_file would result in a warning during post-test - cleanup. */ - int fd; - { - char *temppath = xasprintf ("%s/support_blob_repeat-XXXXXX", test_dir); - fd = mkstemp (temppath); - if (fd < 0) - FAIL_EXIT1 ("mkstemp (\"%s\"): %m", temppath); - xunlink (temppath); - free (temppath); - } - - /* Make sure that there is backing storage, so that the fill - operation will not fault. */ - if (posix_fallocate (fd, 0, stride_size) != 0) - FAIL_EXIT1 ("posix_fallocate (%zu): %m", stride_size); - - /* The stride size must still be a multiple of the page size and - element size. */ - TEST_VERIFY_EXIT ((stride_size % page_size) == 0); - TEST_VERIFY_EXIT ((stride_size % element_size) == 0); - - /* Fill the backing store. */ - { - void *ptr = mmap (target, stride_size, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_FILE | MAP_SHARED, fd, 0); - if (ptr == MAP_FAILED) - { - int saved_errno = errno; - xmunmap (target, total_size); - xclose (fd); - errno = saved_errno; - return (struct support_blob_repeat) { 0 }; - } - if (ptr != target) - FAIL_EXIT1 ("mapping of %zu bytes moved from %p to %p", - stride_size, target, ptr); - - /* Write the repeating data. */ - fill (target, element, element_size, stride_size / element_size); - - /* Return to a PROT_NONE mapping, just to be on the safe side. */ - ptr = mmap (target, stride_size, PROT_NONE, - MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (ptr == MAP_FAILED) - FAIL_EXIT1 ("Failed to reinstate PROT_NONE mapping: %m"); - if (ptr != target) - FAIL_EXIT1 ("PROT_NONE mapping of %zu bytes moved from %p to %p", - stride_size, target, ptr); - } - - /* Create the alias mappings. */ - { - size_t remaining_size = total_size; - char *current = target; - int flags = MAP_FIXED | MAP_FILE | MAP_PRIVATE; -#ifdef MAP_NORESERVE - flags |= MAP_NORESERVE; -#endif - while (remaining_size > 0) - { - size_t to_map = stride_size; - if (to_map > remaining_size) - to_map = remaining_size; - void *ptr = mmap (current, to_map, PROT_READ | PROT_WRITE, - flags, fd, 0); - if (ptr == MAP_FAILED) - { - int saved_errno = errno; - xmunmap (target, total_size); - xclose (fd); - errno = saved_errno; - return (struct support_blob_repeat) { 0 }; - } - if (ptr != current) - FAIL_EXIT1 ("MAP_PRIVATE mapping of %zu bytes moved from %p to %p", - to_map, target, ptr); - remaining_size -= to_map; - current += to_map; - } - } - - xclose (fd); - - return (struct support_blob_repeat) - { - .start = target, - .size = total_size, - .use_malloc = false - }; -} - -struct support_blob_repeat -support_blob_repeat_allocate (const void *element, size_t element_size, - size_t count) -{ - size_t total_size; - if (__builtin_mul_overflow (element_size, count, &total_size)) - { - errno = EOVERFLOW; - return (struct support_blob_repeat) { 0 }; - } - if (total_size <= maximum_small_size) - return allocate_malloc (total_size, element, element_size, count); - else - return allocate_big (total_size, element, element_size, count); -} - -void -support_blob_repeat_free (struct support_blob_repeat *blob) -{ - if (blob->size > 0) - { - int saved_errno = errno; - if (blob->use_malloc) - free (blob->start); - else - xmunmap (blob->start, blob->size); - errno = saved_errno; - } - *blob = (struct support_blob_repeat) { 0 }; -} diff --git a/support/blob_repeat.h b/support/blob_repeat.h deleted file mode 100644 index 8e9d7ff..0000000 --- a/support/blob_repeat.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Repeating a memory blob, with alias mapping optimization. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef SUPPORT_BLOB_REPEAT_H -#define SUPPORT_BLOB_REPEAT_H - -#include -#include - -struct support_blob_repeat -{ - void *start; - size_t size; - bool use_malloc; -}; - -/* Return an allocation of COUNT elements, each of ELEMENT_SIZE bytes, - initialized with the bytes starting at ELEMENT. The memory is - writable (and thus counts towards the commit charge). In case of - on error, all members of the return struct are zero-initialized, - and errno is set accordingly. */ -struct support_blob_repeat support_blob_repeat_allocate (const void *element, - size_t element_size, - size_t count); - -/* Deallocate the blob created by support_blob_repeat_allocate. */ -void support_blob_repeat_free (struct support_blob_repeat *); - -#endif /* SUPPORT_BLOB_REPEAT_H */ diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h index 2d2384e..b0886ba 100644 --- a/support/capture_subprocess.h +++ b/support/capture_subprocess.h @@ -35,12 +35,6 @@ 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 *); @@ -55,16 +49,13 @@ enum support_capture_allow sc_allow_stderr = 0x04, }; -/* Check that the subprocess exited and that only the allowed outputs - happened. If STATUS_OR_SIGNAL is nonnegative, it is the expected - (decoded) exit status of the process, as returned by WEXITSTATUS. - If STATUS_OR_SIGNAL is negative, -STATUS_OR_SIGNAL is the expected - termination signal, as returned by WTERMSIG. ALLOWED is a - combination of support_capture_allow flags. Report errors under - the CONTEXT message. */ +/* Check that the subprocess exited with STATUS and that only the + allowed outputs happened. ALLOWED is a combination of + support_capture_allow flags. Report errors under the CONTEXT + message. */ void support_capture_subprocess_check (struct support_capture_subprocess *, - const char *context, - int status_or_signal, int allowed) + const char *context, int status, + int allowed) __attribute__ ((nonnull (1, 2))); #endif /* SUPPORT_CAPTURE_SUBPROCESS_H */ diff --git a/support/check.h b/support/check.h index 7ea9a86..b3a4645 100644 --- a/support/check.h +++ b/support/check.h @@ -163,19 +163,6 @@ void support_test_compare_blob (const void *left, const char *right_exp, const char *right_len_exp); -/* Compare the strings LEFT and RIGHT and report a test failure if - they are different. Also report failure if one of the arguments is - a null pointer and the other is not. The strings should be - reasonably short because on mismatch, both are printed. */ -#define TEST_COMPARE_STRING(left, right) \ - (support_test_compare_string (left, right, __FILE__, __LINE__, \ - #left, #right)) - -void support_test_compare_string (const char *left, const char *right, - const char *file, int line, - const char *left_expr, - const char *right_expr); - /* Internal function called by the test driver. */ int support_report_failure (int status) __attribute__ ((weak, warn_unused_result)); @@ -183,10 +170,6 @@ int support_report_failure (int status) /* Internal function used to test the failure recording framework. */ void support_record_failure_reset (void); -/* Returns true or false depending on whether there have been test - failures or not. */ -int support_record_failure_is_failed (void); - __END_DECLS #endif /* SUPPORT_CHECK_H */ diff --git a/support/descriptors.h b/support/descriptors.h deleted file mode 100644 index 8ec4cbb..0000000 --- a/support/descriptors.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Monitoring file descriptor usage. - 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 - . */ - -#ifndef SUPPORT_DESCRIPTORS_H -#define SUPPORT_DESCRIPTORS_H - -#include - -/* Opaque pointer, for capturing file descriptor lists. */ -struct support_descriptors; - -/* Record the currently open file descriptors and store them in the - returned list. Terminate the process if the listing operation - fails. */ -struct support_descriptors *support_descriptors_list (void); - -/* Deallocate the list of descriptors. */ -void support_descriptors_free (struct support_descriptors *); - -/* Write the list of descriptors to STREAM, adding PREFIX to each - line. */ -void support_descriptors_dump (struct support_descriptors *, - const char *prefix, FILE *stream); - -/* Check for file descriptor leaks and other file descriptor changes: - Compare the current list of descriptors with the passed list. - Record a test failure if there are additional open descriptors, - descriptors have been closed, or if a change in file descriptor can - be detected. */ -void support_descriptors_check (struct support_descriptors *); - -#endif /* SUPPORT_DESCRIPTORS_H */ diff --git a/support/echo-container.c b/support/echo-container.c deleted file mode 100644 index e4d48df..0000000 --- a/support/echo-container.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Minimal /bin/echo for in-container use. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -int -main (int argc, const char **argv) -{ - int i; - - for (i = 1; i < argc; i++) - { - if (i > 1) - putchar (' '); - fputs (argv[i], stdout); - } - putchar ('\n'); - return 0; -} diff --git a/support/links-dso-program-c.c b/support/links-dso-program-c.c deleted file mode 100644 index 5fcbab2..0000000 --- a/support/links-dso-program-c.c +++ /dev/null @@ -1,26 +0,0 @@ -#include - -/* makedb needs selinux dso's. */ -#ifdef HAVE_SELINUX -# include -#endif - -/* The purpose of this file is to indicate to the build system which - shared objects need to be copied into the testroot, such as gcc or - selinux support libraries. This program is never executed, only - scanned for dependencies on shared objects, so the code below may - seem weird - it's written to survive gcc optimization and force - such dependencies. -*/ - -int -main (int argc, char **argv) -{ - /* Complexity to keep gcc from optimizing this away. */ - printf ("This is a test %s.\n", argc > 1 ? argv[1] : "null"); -#ifdef HAVE_SELINUX - /* This exists to force libselinux.so to be required. */ - printf ("selinux %d\n", is_selinux_enabled ()); -#endif - return 0; -} diff --git a/support/links-dso-program.cc b/support/links-dso-program.cc deleted file mode 100644 index 4bc2411..0000000 --- a/support/links-dso-program.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include - -/* makedb needs selinux dso's. */ -#ifdef HAVE_SELINUX -# include -#endif - -using namespace std; - -/* The purpose of this file is to indicate to the build system which - shared objects need to be copied into the testroot, such as gcc or - selinux support libraries. This program is never executed, only - scanned for dependencies on shared objects, so the code below may - seem weird - it's written to survive gcc optimization and force - such dependencies. -*/ - -int -main (int argc, char **argv) -{ - /* Complexity to keep gcc from optimizing this away. */ - cout << (argc > 1 ? argv[1] : "null"); -#ifdef HAVE_SELINUX - /* This exists to force libselinux.so to be required. */ - cout << "selinux " << is_selinux_enabled (); -#endif - return 0; -} diff --git a/support/shell-container.c b/support/shell-container.c deleted file mode 100644 index 9bd90d3..0000000 --- a/support/shell-container.c +++ /dev/null @@ -1,395 +0,0 @@ -/* Minimal /bin/sh for in-container use. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#define _FILE_OFFSET_BITS 64 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Design considerations - - General rule: optimize for developer time, not run time. - - Specifically: - - * Don't worry about slow algorithms - * Don't worry about free'ing memory - * Don't implement anything the testsuite doesn't need. - * Line and argument counts are limited, see below. - -*/ - -#define MAX_ARG_COUNT 100 -#define MAX_LINE_LENGTH 1000 - -/* Debugging is enabled via --debug, which must be the first argument. */ -static int debug_mode = 0; -#define dprintf if (debug_mode) fprintf - -/* Emulate the "/bin/true" command. Arguments are ignored. */ -static int -true_func (char **argv) -{ - return 0; -} - -/* Emulate the "/bin/echo" command. Options are ignored, arguments - are printed to stdout. */ -static int -echo_func (char **argv) -{ - int i; - - for (i = 0; argv[i]; i++) - { - if (i > 0) - putchar (' '); - fputs (argv[i], stdout); - } - putchar ('\n'); - - return 0; -} - -/* Emulate the "/bin/cp" command. Options are ignored. Only copies - one source file to one destination file. Directory destinations - are not supported. */ -static int -copy_func (char **argv) -{ - char *sname = argv[0]; - char *dname = argv[1]; - int sfd, dfd; - struct stat st; - - sfd = open (sname, O_RDONLY); - if (sfd < 0) - { - fprintf (stderr, "cp: unable to open %s for reading: %s\n", - sname, strerror (errno)); - return 1; - } - - if (fstat (sfd, &st) < 0) - { - fprintf (stderr, "cp: unable to fstat %s: %s\n", - sname, strerror (errno)); - return 1; - } - - dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600); - if (dfd < 0) - { - fprintf (stderr, "cp: unable to open %s for writing: %s\n", - dname, strerror (errno)); - return 1; - } - - if (support_copy_file_range (sfd, 0, dfd, 0, st.st_size, 0) != st.st_size) - { - fprintf (stderr, "cp: cannot copy file %s to %s: %s\n", - sname, dname, strerror (errno)); - return 1; - } - - close (sfd); - close (dfd); - - chmod (dname, st.st_mode & 0777); - - return 0; - -} - -/* This is a list of all the built-in commands we understand. */ -static struct { - const char *name; - int (*func) (char **argv); -} builtin_funcs[] = { - { "true", true_func }, - { "echo", echo_func }, - { "cp", copy_func }, - { NULL, NULL } -}; - -/* Run one tokenized command. argv[0] is the command. argv is - NULL-terminated. */ -static void -run_command_array (char **argv) -{ - int i, j; - pid_t pid; - int status; - int (*builtin_func) (char **args); - - if (argv[0] == NULL) - return; - - builtin_func = NULL; - - int new_stdin = 0; - int new_stdout = 1; - int new_stderr = 2; - - dprintf (stderr, "run_command_array starting\n"); - for (i = 0; argv[i]; i++) - dprintf (stderr, " argv [%d] `%s'\n", i, argv[i]); - - for (j = i = 0; argv[i]; i++) - { - if (strcmp (argv[i], "<") == 0 && argv[i + 1]) - { - new_stdin = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777); - ++i; - continue; - } - if (strcmp (argv[i], ">") == 0 && argv[i + 1]) - { - new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777); - ++i; - continue; - } - if (strcmp (argv[i], ">>") == 0 && argv[i + 1]) - { - new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_APPEND, 0777); - ++i; - continue; - } - if (strcmp (argv[i], "2>") == 0 && argv[i + 1]) - { - new_stderr = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777); - ++i; - continue; - } - argv[j++] = argv[i]; - } - argv[j] = NULL; - - - for (i = 0; builtin_funcs[i].name != NULL; i++) - if (strcmp (argv[0], builtin_funcs[i].name) == 0) - builtin_func = builtin_funcs[i].func; - - dprintf (stderr, "builtin %p argv0 `%s'\n", builtin_func, argv[0]); - - pid = fork (); - if (pid < 0) - { - fprintf (stderr, "sh: fork failed\n"); - exit (1); - } - - if (pid == 0) - { - if (new_stdin != 0) - { - dup2 (new_stdin, 0); - close (new_stdin); - } - if (new_stdout != 1) - { - dup2 (new_stdout, 1); - close (new_stdout); - } - if (new_stderr != 2) - { - dup2 (new_stderr, 2); - close (new_stdout); - } - - if (builtin_func != NULL) - exit (builtin_func (argv + 1)); - - execvp (argv[0], argv); - - fprintf (stderr, "sh: execing %s failed: %s", - argv[0], strerror (errno)); - exit (1); - } - - waitpid (pid, &status, 0); - - dprintf (stderr, "exiting run_command_array\n"); - - if (WIFEXITED (status)) - { - int rv = WEXITSTATUS (status); - if (rv) - exit (rv); - } - else - exit (1); -} - -/* Run one command-as-a-string, by tokenizing it. Limited to - MAX_ARG_COUNT arguments. Simple substitution is done of $1 to $9 - (as whole separate tokens) from iargs[]. Quoted strings work if - the quotes wrap whole tokens; i.e. "foo bar" but not foo" bar". */ -static void -run_command_string (const char *cmdline, const char **iargs) -{ - char *args[MAX_ARG_COUNT+1]; - int ap = 0; - const char *start, *end; - int nargs; - - for (nargs = 0; iargs[nargs] != NULL; ++nargs) - ; - - dprintf (stderr, "run_command_string starting: '%s'\n", cmdline); - - while (ap < MAX_ARG_COUNT) - { - /* If the argument is quoted, this is the quote character, else NUL. */ - int in_quote = 0; - - /* Skip whitespace up to the next token. */ - while (*cmdline && isspace (*cmdline)) - cmdline ++; - if (*cmdline == 0) - break; - - start = cmdline; - /* Check for quoted argument. */ - in_quote = (*cmdline == '\'' || *cmdline == '"') ? *cmdline : 0; - - /* Skip to end of token; either by whitespace or matching quote. */ - dprintf (stderr, "in_quote %d\n", in_quote); - while (*cmdline - && (!isspace (*cmdline) || in_quote)) - { - if (*cmdline == in_quote - && cmdline != start) - in_quote = 0; - dprintf (stderr, "[%c]%d ", *cmdline, in_quote); - cmdline ++; - } - dprintf (stderr, "\n"); - - /* Allocate space for this token and store it in args[]. */ - end = cmdline; - dprintf (stderr, "start<%s> end<%s>\n", start, end); - args[ap] = (char *) xmalloc (end - start + 1); - memcpy (args[ap], start, end - start); - args[ap][end - start] = 0; - - /* Strip off quotes, if found. */ - dprintf (stderr, "args[%d] = <%s>\n", ap, args[ap]); - if (args[ap][0] == '\'' - && args[ap][strlen (args[ap])-1] == '\'') - { - args[ap][strlen (args[ap])-1] = 0; - args[ap] ++; - } - - else if (args[ap][0] == '"' - && args[ap][strlen (args[ap])-1] == '"') - { - args[ap][strlen (args[ap])-1] = 0; - args[ap] ++; - } - - /* Replace positional parameters like $4. */ - else if (args[ap][0] == '$' - && isdigit (args[ap][1]) - && args[ap][2] == 0) - { - int a = args[ap][1] - '1'; - if (0 <= a && a < nargs) - args[ap] = strdup (iargs[a]); - } - - ap ++; - - if (*cmdline == 0) - break; - } - - /* Lastly, NULL terminate the array and run it. */ - args[ap] = NULL; - run_command_array (args); -} - -/* Run a script by reading lines and passing them to the above - function. */ -static void -run_script (const char *filename, const char **args) -{ - char line[MAX_LINE_LENGTH + 1]; - dprintf (stderr, "run_script starting: '%s'\n", filename); - FILE *f = fopen (filename, "r"); - if (f == NULL) - { - fprintf (stderr, "sh: %s: %s\n", filename, strerror (errno)); - exit (1); - } - while (fgets (line, sizeof (line), f) != NULL) - { - if (line[0] == '#') - { - dprintf (stderr, "comment: %s\n", line); - continue; - } - run_command_string (line, args); - } - fclose (f); -} - -int -main (int argc, const char **argv) -{ - int i; - - if (strcmp (argv[1], "--debug") == 0) - { - debug_mode = 1; - --argc; - ++argv; - } - - dprintf (stderr, "container-sh starting:\n"); - for (i = 0; i < argc; i++) - dprintf (stderr, " argv[%d] is `%s'\n", i, argv[i]); - - if (strcmp (argv[1], "-c") == 0) - run_command_string (argv[2], argv+3); - else - run_script (argv[1], argv+2); - - dprintf (stderr, "normal exit 0\n"); - return 0; -} diff --git a/support/subprocess.h b/support/subprocess.h deleted file mode 100644 index c031878..0000000 --- a/support/subprocess.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 --git a/support/support.h b/support/support.h index 61a10c3..b61fe07 100644 --- a/support/support.h +++ b/support/support.h @@ -25,10 +25,6 @@ #include #include -/* For mode_t. */ -#include -/* For ssize_t and off64_t. */ -#include __BEGIN_DECLS @@ -69,50 +65,17 @@ void support_write_file_string (const char *path, const char *contents); the result). */ char *support_quote_blob (const void *blob, size_t length); -/* Quote the contents of the string, in such a way that the result - string can be included in a C literal (in single/double quotes, - without putting the quotes into the result). */ -char *support_quote_string (const char *); - -/* Returns non-zero if the file descriptor is a regular file on a file - system which supports holes (that is, seeking and writing does not - allocate storage for the range of zeros). FD must refer to a - regular file open for writing, and initially empty. */ -int support_descriptor_supports_holes (int fd); - /* Error-checking wrapper functions which terminate the process on error. */ void *xmalloc (size_t) __attribute__ ((malloc)); void *xcalloc (size_t n, size_t s) __attribute__ ((malloc)); void *xrealloc (void *p, size_t n); -void *xposix_memalign (size_t alignment, size_t n); char *xasprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2), malloc)); char *xstrdup (const char *); char *xstrndup (const char *, size_t); -/* These point to the TOP of the source/build tree, not your (or - support's) subdirectory. */ -extern const char support_srcdir_root[]; -extern const char support_objdir_root[]; - -/* Corresponds to the path to the runtime linker used by the testsuite, - e.g. OBJDIR_PATH/elf/ld-linux-x86-64.so.2 */ -extern const char support_objdir_elf_ldso[]; - -/* Corresponds to the --prefix= passed to configure. */ -extern const char support_install_prefix[]; -/* Corresponds to the install's lib/ or lib64/ directory. */ -extern const char support_libdir_prefix[]; -/* Corresponds to the install's bin/ directory. */ -extern const char support_bindir_prefix[]; -/* Corresponds to the install's sbin/ directory. */ -extern const char support_install_rootsbindir[]; - -extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *, - size_t, unsigned int); - __END_DECLS #endif /* SUPPORT_H */ diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c index c13b3e5..6d2029e 100644 --- a/support/support_capture_subprocess.c +++ b/support/support_capture_subprocess.c @@ -16,7 +16,6 @@ License along with the GNU C Library; if not, see . */ -#include #include #include @@ -24,7 +23,6 @@ #include #include #include -#include static void transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream) @@ -52,29 +50,6 @@ transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream) } } -static void -support_capture_poll (struct support_capture_subprocess *result, - struct support_subprocess *proc) -{ - struct pollfd fds[2] = - { - { .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); - } - while (fds[0].events != 0 || fds[1].events != 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) { @@ -82,22 +57,46 @@ support_capture_subprocess (void (*callback) (void *), void *closure) xopen_memstream (&result.out); xopen_memstream (&result.err); - struct support_subprocess proc = support_subprocess (callback, closure); + int stdout_pipe[2]; + xpipe (stdout_pipe); + int stderr_pipe[2]; + xpipe (stderr_pipe); - support_capture_poll (&result, &proc); - return result; -} + TEST_VERIFY (fflush (stdout) == 0); + TEST_VERIFY (fflush (stderr) == 0); -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); + 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); + 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 }, + }; - struct support_subprocess proc = support_subprogram (file, argv); + do + { + xpoll (fds, 2, -1); + 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]); - support_capture_poll (&result, &proc); + xfclose_memstream (&result.out); + xfclose_memstream (&result.err); + xwaitpid (pid, &result.status, 0); return result; } diff --git a/support/support_capture_subprocess_check.c b/support/support_capture_subprocess_check.c index 8b4c352..ff5ee89 100644 --- a/support/support_capture_subprocess_check.c +++ b/support/support_capture_subprocess_check.c @@ -20,7 +20,6 @@ #include #include #include -#include static void print_context (const char *context, bool *failed) @@ -32,22 +31,9 @@ print_context (const char *context, bool *failed) printf ("error: subprocess failed: %s\n", context); } -static void -print_actual_status (struct support_capture_subprocess *proc) -{ - if (WIFEXITED (proc->status)) - printf ("error: actual exit status: %d [0x%x]\n", - WEXITSTATUS (proc->status), proc->status); - else if (WIFSIGNALED (proc->status)) - printf ("error: actual termination signal: %d [0x%x]\n", - WTERMSIG (proc->status), proc->status); - else - printf ("error: actual undecoded exit status: [0x%x]\n", proc->status); -} - void support_capture_subprocess_check (struct support_capture_subprocess *proc, - const char *context, int status_or_signal, + const char *context, int status, int allowed) { TEST_VERIFY ((allowed & sc_allow_none) @@ -58,28 +44,11 @@ support_capture_subprocess_check (struct support_capture_subprocess *proc, || (allowed & sc_allow_stderr)))); bool failed = false; - if (status_or_signal >= 0) + if (proc->status != status) { - /* Expect regular termination. */ - if (!(WIFEXITED (proc->status) - && WEXITSTATUS (proc->status) == status_or_signal)) - { - print_context (context, &failed); - printf ("error: expected exit status: %d\n", status_or_signal); - print_actual_status (proc); - } - } - else - { - /* status_or_signal < 0. Expect termination by signal. */ - if (!(WIFSIGNALED (proc->status) - && WTERMSIG (proc->status) == -status_or_signal)) - { - print_context (context, &failed); - printf ("error: expected termination signal: %d\n", - -status_or_signal); - print_actual_status (proc); - } + print_context (context, &failed); + printf ("error: expected exit status: %d\n", status); + printf ("error: actual exit status: %d\n", proc->status); } if (!(allowed & sc_allow_stdout) && proc->out.length != 0) { diff --git a/support/support_copy_file_range.c b/support/support_copy_file_range.c deleted file mode 100644 index 9a1e397..0000000 --- a/support/support_copy_file_range.c +++ /dev/null @@ -1,143 +0,0 @@ -/* Simplified copy_file_range with cross-device copy. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for 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 - -ssize_t -support_copy_file_range (int infd, __off64_t *pinoff, - int outfd, __off64_t *poutoff, - size_t length, unsigned int flags) -{ - if (flags != 0) - { - 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)) - { - errno = EISDIR; - return -1; - } - if (!S_ISREG (instat.st_mode) || !S_ISREG (outstat.st_mode)) - { - /* We need a regular input file so that the we can seek - backwards in case of a write failure. */ - errno = EINVAL; - return -1; - } - - /* The output descriptor must not have O_APPEND set. */ - if (fcntl (outfd, F_GETFL) & O_APPEND) - { - errno = EBADF; - return -1; - } - - /* Avoid an overflow in the result. */ - if (length > SSIZE_MAX) - length = SSIZE_MAX; - - /* Main copying loop. The buffer size is arbitrary and is a - trade-off between stack size consumption, cache usage, and - amortization of system call overhead. */ - size_t copied = 0; - char buf[8192]; - while (length > 0) - { - size_t to_read = length; - if (to_read > sizeof (buf)) - to_read = sizeof (buf); - - /* Fill the buffer. */ - ssize_t read_count; - if (pinoff == NULL) - read_count = read (infd, buf, to_read); - else - read_count = pread64 (infd, buf, to_read, *pinoff); - if (read_count == 0) - /* End of file reached prematurely. */ - return copied; - if (read_count < 0) - { - if (copied > 0) - /* Report the number of bytes copied so far. */ - return copied; - return -1; - } - if (pinoff != NULL) - *pinoff += read_count; - - /* Write the buffer part which was read to the destination. */ - char *end = buf + read_count; - for (char *p = buf; p < end; ) - { - ssize_t write_count; - if (poutoff == NULL) - write_count = write (outfd, p, end - p); - else - write_count = pwrite64 (outfd, p, end - p, *poutoff); - if (write_count < 0) - { - /* Adjust the input read position to match what we have - written, so that the caller can pick up after the - error. */ - size_t written = p - buf; - /* NB: This needs to be signed so that we can form the - negative value below. */ - ssize_t overread = read_count - written; - if (pinoff == NULL) - { - if (overread > 0) - { - /* We are on an error recovery path, so we - cannot deal with failure here. */ - int save_errno = errno; - (void) lseek64 (infd, -overread, SEEK_CUR); - errno = save_errno; - } - } - else /* pinoff != NULL */ - *pinoff -= overread; - - if (copied + written > 0) - /* Report the number of bytes copied so far. */ - return copied + written; - return -1; - } - p += write_count; - if (poutoff != NULL) - *poutoff += write_count; - } /* Write loop. */ - - copied += read_count; - length -= read_count; - } - return copied; -} diff --git a/support/support_descriptor_supports_holes.c b/support/support_descriptor_supports_holes.c deleted file mode 100644 index c7099ca..0000000 --- a/support/support_descriptor_supports_holes.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Test for file system hole support. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include - -int -support_descriptor_supports_holes (int fd) -{ - enum - { - /* Write offset for the enlarged file. This value is arbitrary - and hopefully large enough to trigger the creation of holes. - We cannot use the file system block size as a reference here - because it is incorrect for network file systems. */ - write_offset = 16 * 1024 * 1024, - - /* Our write may add this number of additional blocks (see - block_limit below). */ - block_headroom = 8, - }; - - struct stat64 st; - xfstat (fd, &st); - if (!S_ISREG (st.st_mode)) - FAIL_EXIT1 ("descriptor %d does not refer to a regular file", fd); - if (st.st_size != 0) - FAIL_EXIT1 ("descriptor %d does not refer to an empty file", fd); - if (st.st_blocks > block_headroom) - FAIL_EXIT1 ("descriptor %d refers to a pre-allocated file (%lld blocks)", - fd, (long long int) st.st_blocks); - - /* Write a single byte at the start of the file to compute the block - usage for a single byte. */ - xlseek (fd, 0, SEEK_SET); - char b = '@'; - xwrite (fd, &b, 1); - /* Attempt to bypass delayed allocation. */ - TEST_COMPARE (fsync (fd), 0); - xfstat (fd, &st); - - /* This limit is arbitrary. The file system needs to store - somewhere that data exists at the write offset, and this may - moderately increase the number of blocks used by the file, in - proportion to the initial block count, but not in proportion to - the write offset. */ - unsigned long long int block_limit = 2 * st.st_blocks + block_headroom; - - /* Write a single byte at 16 megabytes. */ - xlseek (fd, write_offset, SEEK_SET); - xwrite (fd, &b, 1); - /* Attempt to bypass delayed allocation. */ - TEST_COMPARE (fsync (fd), 0); - xfstat (fd, &st); - bool supports_holes = st.st_blocks <= block_limit; - - /* Also check that extending the file does not fill up holes. */ - xftruncate (fd, 2 * write_offset); - /* Attempt to bypass delayed allocation. */ - TEST_COMPARE (fsync (fd), 0); - xfstat (fd, &st); - supports_holes = supports_holes && st.st_blocks <= block_limit; - - /* Return to a zero-length file. */ - xftruncate (fd, 0); - xlseek (fd, 0, SEEK_SET); - - return supports_holes; -} diff --git a/support/support_descriptors.c b/support/support_descriptors.c deleted file mode 100644 index d66cf55..0000000 --- a/support/support_descriptors.c +++ /dev/null @@ -1,274 +0,0 @@ -/* Monitoring file descriptor usage. - 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 -#include -#include -#include -#include -#include -#include -#include -#include - -struct procfs_descriptor -{ - int fd; - char *link_target; - dev_t dev; - ino64_t ino; -}; - -/* Used with qsort. */ -static int -descriptor_compare (const void *l, const void *r) -{ - const struct procfs_descriptor *left = l; - const struct procfs_descriptor *right = r; - /* Cannot overflow due to limited file descriptor range. */ - return left->fd - right->fd; -} - -#define DYNARRAY_STRUCT descriptor_list -#define DYNARRAY_ELEMENT struct procfs_descriptor -#define DYNARRAY_PREFIX descriptor_list_ -#define DYNARRAY_ELEMENT_FREE(e) free ((e)->link_target) -#define DYNARRAY_INITIAL_SIZE 0 -#include - -struct support_descriptors -{ - struct descriptor_list list; -}; - -struct support_descriptors * -support_descriptors_list (void) -{ - struct support_descriptors *result = xmalloc (sizeof (*result)); - descriptor_list_init (&result->list); - - DIR *fds = opendir ("/proc/self/fd"); - if (fds == NULL) - FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m"); - - while (true) - { - errno = 0; - struct dirent64 *e = readdir64 (fds); - if (e == NULL) - { - if (errno != 0) - FAIL_EXIT1 ("readdir: %m"); - break; - } - - if (e->d_name[0] == '.') - continue; - - char *endptr; - long int fd = strtol (e->d_name, &endptr, 10); - if (*endptr != '\0' || fd < 0 || fd > INT_MAX) - FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s", - e->d_name); - - /* Skip the descriptor which is used to enumerate the - descriptors. */ - if (fd == dirfd (fds)) - continue; - - char *target; - { - char *path = xasprintf ("/proc/self/fd/%ld", fd); - target = xreadlink (path); - free (path); - } - struct stat64 st; - if (fstat64 (fd, &st) != 0) - FAIL_EXIT1 ("readdir: fstat64 (%ld) failed: %m", fd); - - struct procfs_descriptor *item = descriptor_list_emplace (&result->list); - if (item == NULL) - FAIL_EXIT1 ("descriptor_list_emplace: %m"); - item->fd = fd; - item->link_target = target; - item->dev = st.st_dev; - item->ino = st.st_ino; - } - - closedir (fds); - - /* Perform a merge join between descrs and current. This assumes - that the arrays are sorted by file descriptor. */ - - qsort (descriptor_list_begin (&result->list), - descriptor_list_size (&result->list), - sizeof (struct procfs_descriptor), descriptor_compare); - - return result; -} - -void -support_descriptors_free (struct support_descriptors *descrs) -{ - descriptor_list_free (&descrs->list); - free (descrs); -} - -void -support_descriptors_dump (struct support_descriptors *descrs, - const char *prefix, FILE *fp) -{ - struct procfs_descriptor *end = descriptor_list_end (&descrs->list); - for (struct procfs_descriptor *d = descriptor_list_begin (&descrs->list); - d != end; ++d) - { - char *quoted = support_quote_string (d->link_target); - fprintf (fp, "%s%d: target=\"%s\" major=%lld minor=%lld ino=%lld\n", - prefix, d->fd, quoted, - (long long int) major (d->dev), - (long long int) minor (d->dev), - (long long int) d->ino); - free (quoted); - } -} - -static void -dump_mismatch (bool *first, - struct support_descriptors *descrs, - struct support_descriptors *current) -{ - if (*first) - *first = false; - else - return; - - puts ("error: Differences found in descriptor set"); - puts ("Reference descriptor set:"); - support_descriptors_dump (descrs, " ", stdout); - puts ("Current descriptor set:"); - support_descriptors_dump (current, " ", stdout); - puts ("Differences:"); -} - -static void -report_closed_descriptor (bool *first, - struct support_descriptors *descrs, - struct support_descriptors *current, - struct procfs_descriptor *left) -{ - support_record_failure (); - dump_mismatch (first, descrs, current); - printf ("error: descriptor %d was closed\n", left->fd); -} - -static void -report_opened_descriptor (bool *first, - struct support_descriptors *descrs, - struct support_descriptors *current, - struct procfs_descriptor *right) -{ - support_record_failure (); - dump_mismatch (first, descrs, current); - char *quoted = support_quote_string (right->link_target); - printf ("error: descriptor %d was opened (\"%s\")\n", right->fd, quoted); - free (quoted); -} - -void -support_descriptors_check (struct support_descriptors *descrs) -{ - struct support_descriptors *current = support_descriptors_list (); - - /* Perform a merge join between descrs and current. This assumes - that the arrays are sorted by file descriptor. */ - - struct procfs_descriptor *left = descriptor_list_begin (&descrs->list); - struct procfs_descriptor *left_end = descriptor_list_end (&descrs->list); - struct procfs_descriptor *right = descriptor_list_begin (¤t->list); - struct procfs_descriptor *right_end = descriptor_list_end (¤t->list); - - bool first = true; - while (left != left_end && right != right_end) - { - if (left->fd == right->fd) - { - if (strcmp (left->link_target, right->link_target) != 0) - { - support_record_failure (); - char *left_quoted = support_quote_string (left->link_target); - char *right_quoted = support_quote_string (right->link_target); - dump_mismatch (&first, descrs, current); - printf ("error: descriptor %d changed from \"%s\" to \"%s\"\n", - left->fd, left_quoted, right_quoted); - free (left_quoted); - free (right_quoted); - } - if (left->dev != right->dev) - { - support_record_failure (); - dump_mismatch (&first, descrs, current); - printf ("error: descriptor %d changed device" - " from %lld:%lld to %lld:%lld\n", - left->fd, - (long long int) major (left->dev), - (long long int) minor (left->dev), - (long long int) major (right->dev), - (long long int) minor (right->dev)); - } - if (left->ino != right->ino) - { - support_record_failure (); - dump_mismatch (&first, descrs, current); - printf ("error: descriptor %d changed ino from %lld to %lld\n", - left->fd, - (long long int) left->ino, (long long int) right->ino); - } - ++left; - ++right; - } - else if (left->fd < right->fd) - { - /* Gap on the right. */ - report_closed_descriptor (&first, descrs, current, left); - ++left; - } - else - { - /* Gap on the left. */ - TEST_VERIFY_EXIT (left->fd > right->fd); - report_opened_descriptor (&first, descrs, current, right); - ++right; - } - } - - while (left != left_end) - { - /* Closed descriptors (more descriptors on the left). */ - report_closed_descriptor (&first, descrs, current, left); - ++left; - } - - while (right != right_end) - { - /* Opened descriptors (more descriptors on the right). */ - report_opened_descriptor (&first, descrs, current, right); - ++right; - } - - support_descriptors_free (current); -} diff --git a/support/support_paths.c b/support/support_paths.c deleted file mode 100644 index a37a072..0000000 --- a/support/support_paths.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Various paths that might be needed. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - -/* The idea here is to make various makefile-level paths available to - support programs, as canonicalized absolute paths. */ - -/* These point to the TOP of the source/build tree, not your (or - support's) subdirectory. */ -#ifdef SRCDIR_PATH -const char support_srcdir_root[] = SRCDIR_PATH; -#else -# error please -DSRCDIR_PATH=something in the Makefile -#endif - -#ifdef OBJDIR_PATH -const char support_objdir_root[] = OBJDIR_PATH; -#else -# error please -DOBJDIR_PATH=something in the Makefile -#endif - -#ifdef OBJDIR_ELF_LDSO_PATH -/* Corresponds to the path to the runtime linker used by the testsuite, - e.g. OBJDIR_PATH/elf/ld-linux-x86-64.so.2 */ -const char support_objdir_elf_ldso[] = OBJDIR_ELF_LDSO_PATH; -#else -# error please -DOBJDIR_ELF_LDSO_PATH=something in the Makefile -#endif - -#ifdef INSTDIR_PATH -/* Corresponds to the --prefix= passed to configure. */ -const char support_install_prefix[] = INSTDIR_PATH; -#else -# error please -DINSTDIR_PATH=something in the Makefile -#endif - -#ifdef LIBDIR_PATH -/* Corresponds to the install's lib/ or lib64/ directory. */ -const char support_libdir_prefix[] = LIBDIR_PATH; -#else -# error please -DLIBDIR_PATH=something in the Makefile -#endif - -#ifdef BINDIR_PATH -/* Corresponds to the install's bin/ directory. */ -const char support_bindir_prefix[] = BINDIR_PATH; -#else -# error please -DBINDIR_PATH=something in the Makefile -#endif - -#ifdef ROOTSBINDIR_PATH -/* Corresponds to the install's sbin/ directory. */ -const char support_install_rootsbindir[] = ROOTSBINDIR_PATH; -#else -# error please -DROOTSBINDIR_PATH=something in the Makefile -#endif diff --git a/support/support_quote_string.c b/support/support_quote_string.c deleted file mode 100644 index d324371..0000000 --- a/support/support_quote_string.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Quote a string so that it can be used in C literals. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - -char * -support_quote_string (const char *str) -{ - return support_quote_blob (str, strlen (str)); -} diff --git a/support/support_record_failure.c b/support/support_record_failure.c index 17ab1d8..356798f 100644 --- a/support/support_record_failure.c +++ b/support/support_record_failure.c @@ -104,11 +104,3 @@ support_record_failure_reset (void) __atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED); __atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED); } - -int -support_record_failure_is_failed (void) -{ - /* Relaxed MO is sufficient because we need (blocking) external - synchronization for reliable test error reporting anyway. */ - return __atomic_load_n (&state->failed, __ATOMIC_RELAXED); -} diff --git a/support/support_subprocess.c b/support/support_subprocess.c deleted file mode 100644 index 12c79ff..0000000 --- a/support/support_subprocess.c +++ /dev/null @@ -1,152 +0,0 @@ -/* 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 --git a/support/support_test_compare_string.c b/support/support_test_compare_string.c deleted file mode 100644 index a76ba8e..0000000 --- a/support/support_test_compare_string.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Check two strings for equality. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include - -static void -report_length (const char *what, const char *str, size_t length) -{ - if (str == NULL) - printf (" %s string: NULL\n", what); - else - printf (" %s string: %zu bytes\n", what, length); -} - -static void -report_string (const char *what, const unsigned char *blob, - size_t length, const char *expr) -{ - if (length > 0) - { - printf (" %s (evaluated from %s):\n", what, expr); - char *quoted = support_quote_blob (blob, length); - printf (" \"%s\"\n", quoted); - free (quoted); - - fputs (" ", stdout); - for (size_t i = 0; i < length; ++i) - printf (" %02X", blob[i]); - putc ('\n', stdout); - } -} - -static size_t -string_length_or_zero (const char *str) -{ - if (str == NULL) - return 0; - else - return strlen (str); -} - -void -support_test_compare_string (const char *left, const char *right, - const char *file, int line, - const char *left_expr, const char *right_expr) -{ - /* Two null pointers are accepted. */ - if (left == NULL && right == NULL) - return; - - size_t left_length = string_length_or_zero (left); - size_t right_length = string_length_or_zero (right); - - if (left_length != right_length || left == NULL || right == NULL - || memcmp (left, right, left_length) != 0) - { - support_record_failure (); - printf ("%s:%d: error: blob comparison failed\n", file, line); - if (left_length == right_length && right != NULL && left != NULL) - printf (" string length: %zu bytes\n", left_length); - else - { - report_length ("left", left, left_length); - report_length ("right", right, right_length); - } - report_string ("left", (const unsigned char *) left, - left_length, left_expr); - report_string ("right", (const unsigned char *) right, - right_length, right_expr); - } -} diff --git a/support/support_test_main.c b/support/support_test_main.c index fa3c2e0..2342977 100644 --- a/support/support_test_main.c +++ b/support/support_test_main.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -87,19 +86,6 @@ static pid_t test_pid; /* The cleanup handler passed to test_main. */ static void (*cleanup_function) (void); -static void -print_timestamp (const char *what, struct timeval tv) -{ - struct tm tm; - if (gmtime_r (&tv.tv_sec, &tm) == NULL) - printf ("%s: %lld.%06d\n", - what, (long long int) tv.tv_sec, (int) tv.tv_usec); - else - printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n", - what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec); -} - /* Timeout handler. We kill the child and exit with an error. */ static void __attribute__ ((noreturn)) @@ -108,13 +94,6 @@ signal_handler (int sig) int killed; int status; - /* Do this first to avoid further interference from the - subprocess. */ - struct timeval now; - bool now_available = gettimeofday (&now, NULL) == 0; - struct stat64 st; - bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0; - assert (test_pid > 1); /* Kill the whole process group. */ kill (-test_pid, SIGKILL); @@ -165,13 +144,6 @@ signal_handler (int sig) printf ("Timed out: killed the child process but it exited %d\n", WEXITSTATUS (status)); - if (now_available) - print_timestamp ("Termination time", now); - if (st_available) - print_timestamp ("Last write to standard output", - (struct timeval) { st.st_mtim.tv_sec, - st.st_mtim.tv_nsec / 1000 }); - /* Exit with an error. */ exit (1); } diff --git a/support/test-container.c b/support/test-container.c deleted file mode 100644 index fe0ebbd..0000000 --- a/support/test-container.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* Run a test case in an isolated namespace. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#define _FILE_OFFSET_BITS 64 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include -#endif - -#include -#include -#include "check.h" -#include "test-driver.h" - -#ifndef __linux__ -#define mount(s,t,fs,f,d) no_mount() -int no_mount (void) -{ - FAIL_UNSUPPORTED("mount not supported; port needed"); -} -#endif - -int verbose = 0; - -/* Running a test in a container is tricky. There are two main - categories of things to do: - - 1. "Once" actions, like setting up the container and doing an - install into it. - - 2. "Per-test" actions, like copying in support files and - configuring the container. - - - "Once" actions: - - * mkdir $buildroot/testroot.pristine/ - * install into it - * rsync to $buildroot/testroot.root/ - - "Per-test" actions: - * maybe rsync to $buildroot/testroot.root/ - * copy support files and test binary - * chroot/unshare - * set up any mounts (like /proc) - - Magic files: - - For test $srcdir/foo/mytest.c we look for $srcdir/foo/mytest.root - and, if found... - - * mytest.root/ is rsync'd into container - * mytest.root/preclean.req causes fresh rsync (with delete) before - test if present - * mytest.root/mytset.script has a list of "commands" to run: - syntax: - # comment - mv FILE FILE - cp FILE FILE - rm FILE - FILE must start with $B/, $S/, $I/, $L/, or / - (expands to build dir, source dir, install dir, library dir - (in container), or container's root) - * mytest.root/postclean.req causes fresh rsync (with delete) after - test if present - - Note that $srcdir/foo/mytest.script may be used instead of a - $srcdir/foo/mytest.root/mytest.script in the sysroot template, if - there is no other reason for a sysroot. - - Design goals: - - * independent of other packages which may not be installed (like - rsync or Docker, or even "cp") - - * Simple, easy to review code (i.e. prefer simple naive code over - complex efficient code) - - * The current implementation ist parallel-make-safe, but only in - that it uses a lock to prevent parallel access to the testroot. */ - - -/* Utility Functions */ - -/* Like xunlink, but it's OK if the file already doesn't exist. */ -void -maybe_xunlink (const char *path) -{ - int rv = unlink (path); - if (rv < 0 && errno != ENOENT) - FAIL_EXIT1 ("unlink (\"%s\"): %m", path); -} - -/* Like xmkdir, but it's OK if the directory already exists. */ -void -maybe_xmkdir (const char *path, mode_t mode) -{ - struct stat st; - - if (stat (path, &st) == 0 - && S_ISDIR (st.st_mode)) - return; - xmkdir (path, mode); -} - -/* Temporarily concatenate multiple strings into one. Allows up to 10 - temporary results; use strdup () if you need them to be - permanent. */ -static char * -concat (const char *str, ...) -{ - /* Assume initialized to NULL/zero. */ - static char *bufs[10]; - static size_t buflens[10]; - static int bufn = 0; - int n; - size_t len; - va_list ap, ap2; - char *cp; - char *next; - - va_start (ap, str); - va_copy (ap2, ap); - - n = bufn; - bufn = (bufn + 1) % 10; - len = strlen (str); - - while ((next = va_arg (ap, char *)) != NULL) - len = len + strlen (next); - - va_end (ap); - - if (bufs[n] == NULL) - { - bufs[n] = xmalloc (len + 1); /* NUL */ - buflens[n] = len + 1; - } - else if (buflens[n] < len + 1) - { - bufs[n] = xrealloc (bufs[n], len + 1); /* NUL */ - buflens[n] = len + 1; - } - - strcpy (bufs[n], str); - cp = strchr (bufs[n], '\0'); - while ((next = va_arg (ap2, char *)) != NULL) - { - strcpy (cp, next); - cp = strchr (cp, '\0'); - } - *cp = 0; - va_end (ap2); - - return bufs[n]; -} - -/* Try to mount SRC onto DEST. */ -static void -trymount (const char *src, const char *dest) -{ - if (mount (src, dest, "", MS_BIND, NULL) < 0) - FAIL_EXIT1 ("can't mount %s onto %s\n", src, dest); -} - -/* Special case of above for devices like /dev/zero where we have to - mount a device over a device, not a directory over a directory. */ -static void -devmount (const char *new_root_path, const char *which) -{ - int fd; - fd = open (concat (new_root_path, "/dev/", which, NULL), - O_CREAT | O_TRUNC | O_RDWR, 0777); - xclose (fd); - - trymount (concat ("/dev/", which, NULL), - concat (new_root_path, "/dev/", which, NULL)); -} - -/* Returns true if the string "looks like" an environement variable - being set. */ -static int -is_env_setting (const char *a) -{ - int count_name = 0; - - while (*a) - { - if (isalnum (*a) || *a == '_') - ++count_name; - else if (*a == '=' && count_name > 0) - return 1; - else - return 0; - ++a; - } - return 0; -} - -/* Break the_line into words and store in the_words. Max nwords, - returns actual count. */ -static int -tokenize (char *the_line, char **the_words, int nwords) -{ - int rv = 0; - - while (nwords > 0) - { - /* Skip leading whitespace, if any. */ - while (*the_line && isspace (*the_line)) - ++the_line; - - /* End of line? */ - if (*the_line == 0) - return rv; - - /* THE_LINE points to a non-whitespace character, so we have a - word. */ - *the_words = the_line; - ++the_words; - nwords--; - ++rv; - - /* Skip leading whitespace, if any. */ - while (*the_line && ! isspace (*the_line)) - ++the_line; - - /* We now point at the trailing NUL *or* some whitespace. */ - if (*the_line == 0) - return rv; - - /* It was whitespace, skip and keep tokenizing. */ - *the_line++ = 0; - } - - /* We get here if we filled the words buffer. */ - return rv; -} - - -/* Mini-RSYNC implementation. Optimize later. */ - -/* A few routines for an "rsync buffer" which stores the paths we're - working on. We continuously grow and shrink the paths in each - buffer so there's lot of re-use. */ - -/* We rely on "initialized to zero" to set these up. */ -typedef struct -{ - char *buf; - size_t len; - size_t size; -} path_buf; - -static path_buf spath, dpath; - -static void -r_setup (char *path, path_buf * pb) -{ - size_t len = strlen (path); - if (pb->buf == NULL || pb->size < len + 1) - { - /* Round up. This is an arbitrary number, just to keep from - reallocing too often. */ - size_t sz = ALIGN_UP (len + 1, 512); - if (pb->buf == NULL) - pb->buf = (char *) xmalloc (sz); - else - pb->buf = (char *) xrealloc (pb->buf, sz); - if (pb->buf == NULL) - FAIL_EXIT1 ("Out of memory while rsyncing\n"); - - pb->size = sz; - } - strcpy (pb->buf, path); - pb->len = len; -} - -static void -r_append (const char *path, path_buf * pb) -{ - size_t len = strlen (path) + pb->len; - if (pb->size < len + 1) - { - /* Round up */ - size_t sz = ALIGN_UP (len + 1, 512); - pb->buf = (char *) xrealloc (pb->buf, sz); - if (pb->buf == NULL) - FAIL_EXIT1 ("Out of memory while rsyncing\n"); - - pb->size = sz; - } - strcpy (pb->buf + pb->len, path); - pb->len = len; -} - -static int -file_exists (char *path) -{ - struct stat st; - if (lstat (path, &st) == 0) - return 1; - return 0; -} - -static void -recursive_remove (char *path) -{ - pid_t child; - int status; - - child = fork (); - - switch (child) { - case -1: - FAIL_EXIT1 ("Unable to fork"); - case 0: - /* Child. */ - execlp ("rm", "rm", "-rf", path, NULL); - default: - /* Parent. */ - waitpid (child, &status, 0); - /* "rm" would have already printed a suitable error message. */ - if (! WIFEXITED (status) - || WEXITSTATUS (status) != 0) - exit (1); - - break; - } -} - -/* Used for both rsync and the mytest.script "cp" command. */ -static void -copy_one_file (const char *sname, const char *dname) -{ - int sfd, dfd; - struct stat st; - struct utimbuf times; - - sfd = open (sname, O_RDONLY); - if (sfd < 0) - FAIL_EXIT1 ("unable to open %s for reading\n", sname); - - if (fstat (sfd, &st) < 0) - FAIL_EXIT1 ("unable to fstat %s\n", sname); - - dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600); - if (dfd < 0) - FAIL_EXIT1 ("unable to open %s for writing\n", dname); - - xcopy_file_range (sfd, 0, dfd, 0, st.st_size, 0); - - xclose (sfd); - xclose (dfd); - - if (chmod (dname, st.st_mode & 0777) < 0) - FAIL_EXIT1 ("chmod %s: %s\n", dname, strerror (errno)); - - times.actime = st.st_atime; - times.modtime = st.st_mtime; - if (utime (dname, ×) < 0) - FAIL_EXIT1 ("utime %s: %s\n", dname, strerror (errno)); -} - -/* We don't check *everything* about the two files to see if a copy is - needed, just the minimum to make sure we get the latest copy. */ -static int -need_sync (char *ap, char *bp, struct stat *a, struct stat *b) -{ - if ((a->st_mode & S_IFMT) != (b->st_mode & S_IFMT)) - return 1; - - if (S_ISLNK (a->st_mode)) - { - int rv; - char *al, *bl; - - if (a->st_size != b->st_size) - return 1; - - al = xreadlink (ap); - bl = xreadlink (bp); - rv = strcmp (al, bl); - free (al); - free (bl); - if (rv == 0) - return 0; /* links are same */ - return 1; /* links differ */ - } - - if (verbose) - { - if (a->st_size != b->st_size) - printf ("SIZE\n"); - if ((a->st_mode & 0777) != (b->st_mode & 0777)) - printf ("MODE\n"); - if (a->st_mtime != b->st_mtime) - printf ("TIME\n"); - } - - if (a->st_size == b->st_size - && ((a->st_mode & 0777) == (b->st_mode & 0777)) - && a->st_mtime == b->st_mtime) - return 0; - - return 1; -} - -static void -rsync_1 (path_buf * src, path_buf * dest, int and_delete) -{ - DIR *dir; - struct dirent *de; - struct stat s, d; - - r_append ("/", src); - r_append ("/", dest); - - if (verbose) - printf ("sync %s to %s %s\n", src->buf, dest->buf, - and_delete ? "and delete" : ""); - - size_t staillen = src->len; - - size_t dtaillen = dest->len; - - dir = opendir (src->buf); - - while ((de = readdir (dir)) != NULL) - { - if (strcmp (de->d_name, ".") == 0 - || strcmp (de->d_name, "..") == 0) - continue; - - src->len = staillen; - r_append (de->d_name, src); - dest->len = dtaillen; - r_append (de->d_name, dest); - - s.st_mode = ~0; - d.st_mode = ~0; - - if (lstat (src->buf, &s) != 0) - FAIL_EXIT1 ("%s obtained by readdir, but stat failed.\n", src->buf); - - /* It's OK if this one fails, since we know the file might be - missing. */ - lstat (dest->buf, &d); - - if (! need_sync (src->buf, dest->buf, &s, &d)) - { - if (S_ISDIR (s.st_mode)) - rsync_1 (src, dest, and_delete); - continue; - } - - if (d.st_mode != ~0) - switch (d.st_mode & S_IFMT) - { - case S_IFDIR: - if (!S_ISDIR (s.st_mode)) - { - if (verbose) - printf ("-D %s\n", dest->buf); - recursive_remove (dest->buf); - } - break; - - default: - if (verbose) - printf ("-F %s\n", dest->buf); - maybe_xunlink (dest->buf); - break; - } - - switch (s.st_mode & S_IFMT) - { - case S_IFREG: - if (verbose) - printf ("+F %s\n", dest->buf); - copy_one_file (src->buf, dest->buf); - break; - - case S_IFDIR: - if (verbose) - printf ("+D %s\n", dest->buf); - maybe_xmkdir (dest->buf, (s.st_mode & 0777) | 0700); - rsync_1 (src, dest, and_delete); - break; - - case S_IFLNK: - { - char *lp; - if (verbose) - printf ("+L %s\n", dest->buf); - lp = xreadlink (src->buf); - xsymlink (lp, dest->buf); - free (lp); - break; - } - - default: - break; - } - } - - closedir (dir); - src->len = staillen; - src->buf[staillen] = 0; - dest->len = dtaillen; - dest->buf[dtaillen] = 0; - - if (!and_delete) - return; - - /* The rest of this function removes any files/directories in DEST - that do not exist in SRC. This is triggered as part of a - preclean or postsclean step. */ - - dir = opendir (dest->buf); - - while ((de = readdir (dir)) != NULL) - { - if (strcmp (de->d_name, ".") == 0 - || strcmp (de->d_name, "..") == 0) - continue; - - src->len = staillen; - r_append (de->d_name, src); - dest->len = dtaillen; - r_append (de->d_name, dest); - - s.st_mode = ~0; - d.st_mode = ~0; - - lstat (src->buf, &s); - - if (lstat (dest->buf, &d) != 0) - FAIL_EXIT1 ("%s obtained by readdir, but stat failed.\n", dest->buf); - - if (s.st_mode == ~0) - { - /* dest exists and src doesn't, clean it. */ - switch (d.st_mode & S_IFMT) - { - case S_IFDIR: - if (!S_ISDIR (s.st_mode)) - { - if (verbose) - printf ("-D %s\n", dest->buf); - recursive_remove (dest->buf); - } - break; - - default: - if (verbose) - printf ("-F %s\n", dest->buf); - maybe_xunlink (dest->buf); - break; - } - } - } - - closedir (dir); -} - -static void -rsync (char *src, char *dest, int and_delete) -{ - r_setup (src, &spath); - r_setup (dest, &dpath); - - rsync_1 (&spath, &dpath, and_delete); -} - - -int -main (int argc, char **argv) -{ - pid_t child; - char *pristine_root_path; - char *new_root_path; - char *new_cwd_path; - char *new_objdir_path; - char *new_srcdir_path; - char **new_child_proc; - char *command_root; - char *command_base; - char *command_basename; - char *so_base; - int do_postclean = 0; - - uid_t original_uid; - gid_t original_gid; - int UMAP; - int GMAP; - /* Used for "%lld %lld 1" so need not be large. */ - char tmp[100]; - struct stat st; - int lock_fd; - - setbuf (stdout, NULL); - - /* The command line we're expecting looks like this: - env ld.so test-binary - - We need to peel off any "env" or "ld.so" portion of the command - line, and keep track of which env vars we should preserve and - which we drop. */ - - if (argc < 2) - { - fprintf (stderr, "Usage: containerize \n"); - exit (1); - } - - if (strcmp (argv[1], "-v") == 0) - { - verbose = 1; - ++argv; - --argc; - } - - if (strcmp (argv[1], "env") == 0) - { - ++argv; - --argc; - while (is_env_setting (argv[1])) - { - /* If there are variables we do NOT want to propogate, this - is where the test for them goes. */ - { - /* Need to keep these. Note that putenv stores a - pointer to our argv. */ - putenv (argv[1]); - } - ++argv; - --argc; - } - } - - if (strcmp (argv[1], support_objdir_elf_ldso) == 0) - { - ++argv; - --argc; - while (argv[1][0] == '-') - { - if (strcmp (argv[1], "--library-path") == 0) - { - ++argv; - --argc; - } - ++argv; - --argc; - } - } - - pristine_root_path = strdup (concat (support_objdir_root, - "/testroot.pristine", NULL)); - new_root_path = strdup (concat (support_objdir_root, - "/testroot.root", NULL)); - new_cwd_path = get_current_dir_name (); - new_child_proc = argv + 1; - - lock_fd = open (concat (pristine_root_path, "/lock.fd", NULL), - O_CREAT | O_TRUNC | O_RDWR, 0666); - if (lock_fd < 0) - FAIL_EXIT1 ("Cannot create testroot lock.\n"); - - while (flock (lock_fd, LOCK_EX) != 0) - { - if (errno != EINTR) - FAIL_EXIT1 ("Cannot lock testroot.\n"); - } - - xmkdirp (new_root_path, 0755); - - /* We look for extra setup info in a subdir in the same spot as the - test, with the same name but a ".root" extension. This is that - directory. We try to look in the source tree if the path we're - given refers to the build tree, but we rely on the path to be - absolute. This is what the glibc makefiles do. */ - command_root = concat (argv[1], ".root", NULL); - if (strncmp (command_root, support_objdir_root, - strlen (support_objdir_root)) == 0 - && command_root[strlen (support_objdir_root)] == '/') - command_root = concat (support_srcdir_root, - argv[1] + strlen (support_objdir_root), - ".root", NULL); - command_root = strdup (command_root); - - /* This cuts off the ".root" we appended above. */ - command_base = strdup (command_root); - command_base[strlen (command_base) - 5] = 0; - - /* This is the basename of the test we're running. */ - command_basename = strrchr (command_base, '/'); - if (command_basename == NULL) - command_basename = command_base; - else - ++command_basename; - - /* Shared object base directory. */ - so_base = strdup (argv[1]); - if (strrchr (so_base, '/') != NULL) - strrchr (so_base, '/')[1] = 0; - - if (file_exists (concat (command_root, "/postclean.req", NULL))) - do_postclean = 1; - - rsync (pristine_root_path, new_root_path, - file_exists (concat (command_root, "/preclean.req", NULL))); - - if (stat (command_root, &st) >= 0 - && S_ISDIR (st.st_mode)) - rsync (command_root, new_root_path, 0); - - new_objdir_path = strdup (concat (new_root_path, - support_objdir_root, NULL)); - new_srcdir_path = strdup (concat (new_root_path, - support_srcdir_root, NULL)); - - /* new_cwd_path starts with '/' so no "/" needed between the two. */ - xmkdirp (concat (new_root_path, new_cwd_path, NULL), 0755); - xmkdirp (new_srcdir_path, 0755); - xmkdirp (new_objdir_path, 0755); - - original_uid = getuid (); - original_gid = getgid (); - - /* Handle the cp/mv/rm "script" here. */ - { - char *the_line = NULL; - size_t line_len = 0; - char *fname = concat (command_root, "/", - command_basename, ".script", NULL); - char *the_words[3]; - FILE *f = fopen (fname, "r"); - - if (verbose && f) - fprintf (stderr, "running %s\n", fname); - - if (f == NULL) - { - /* Try foo.script instead of foo.root/foo.script, as a shortcut. */ - fname = concat (command_base, ".script", NULL); - f = fopen (fname, "r"); - if (verbose && f) - fprintf (stderr, "running %s\n", fname); - } - - /* Note that we do NOT look for a Makefile-generated foo.script in - the build directory. If that is ever needed, this is the place - to add it. */ - - /* This is where we "interpret" the mini-script which is .script. */ - if (f != NULL) - { - while (getline (&the_line, &line_len, f) > 0) - { - int nt = tokenize (the_line, the_words, 3); - int i; - - for (i = 1; i < nt; ++i) - { - if (memcmp (the_words[i], "$B/", 3) == 0) - the_words[i] = concat (support_objdir_root, - the_words[i] + 2, NULL); - else if (memcmp (the_words[i], "$S/", 3) == 0) - the_words[i] = concat (support_srcdir_root, - the_words[i] + 2, NULL); - else if (memcmp (the_words[i], "$I/", 3) == 0) - the_words[i] = concat (new_root_path, - support_install_prefix, - the_words[i] + 2, NULL); - else if (memcmp (the_words[i], "$L/", 3) == 0) - the_words[i] = concat (new_root_path, - support_libdir_prefix, - the_words[i] + 2, NULL); - else if (the_words[i][0] == '/') - the_words[i] = concat (new_root_path, - the_words[i], NULL); - } - - if (nt == 3 && the_words[2][strlen (the_words[2]) - 1] == '/') - { - char *r = strrchr (the_words[1], '/'); - if (r) - the_words[2] = concat (the_words[2], r + 1, NULL); - else - the_words[2] = concat (the_words[2], the_words[1], NULL); - } - - if (nt == 2 && strcmp (the_words[0], "so") == 0) - { - the_words[2] = concat (new_root_path, support_libdir_prefix, - "/", the_words[1], NULL); - the_words[1] = concat (so_base, the_words[1], NULL); - copy_one_file (the_words[1], the_words[2]); - } - else if (nt == 3 && strcmp (the_words[0], "cp") == 0) - { - copy_one_file (the_words[1], the_words[2]); - } - else if (nt == 3 && strcmp (the_words[0], "mv") == 0) - { - if (rename (the_words[1], the_words[2]) < 0) - FAIL_EXIT1 ("rename %s -> %s: %s", the_words[1], - the_words[2], strerror (errno)); - } - else if (nt == 3 && strcmp (the_words[0], "chmod") == 0) - { - long int m; - m = strtol (the_words[1], NULL, 0); - if (chmod (the_words[2], m) < 0) - FAIL_EXIT1 ("chmod %s: %s\n", - the_words[2], strerror (errno)); - - } - else if (nt == 2 && strcmp (the_words[0], "rm") == 0) - { - maybe_xunlink (the_words[1]); - } - else if (nt > 0 && the_words[0][0] != '#') - { - printf ("\033[31minvalid [%s]\033[0m\n", the_words[0]); - } - } - fclose (f); - } - } - - if (do_postclean) - { - pid_t pc_pid = fork (); - - if (pc_pid < 0) - { - FAIL_EXIT1 ("Can't fork for post-clean"); - } - else if (pc_pid > 0) - { - /* Parent. */ - int status; - waitpid (pc_pid, &status, 0); - - /* Child has exited, we can post-clean the test root. */ - printf("running post-clean rsync\n"); - rsync (pristine_root_path, new_root_path, 1); - - if (WIFEXITED (status)) - exit (WEXITSTATUS (status)); - - if (WIFSIGNALED (status)) - { - printf ("%%SIGNALLED%%\n"); - exit (77); - } - - printf ("%%EXITERROR%%\n"); - exit (78); - } - - /* Child continues. */ - } - - /* This is the last point in the program where we're still in the - "normal" namespace. */ - -#ifdef CLONE_NEWNS - /* The unshare here gives us our own spaces and capabilities. */ - if (unshare (CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS) < 0) - { - /* Older kernels may not support all the options, or security - policy may block this call. */ - if (errno == EINVAL || errno == EPERM) - FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (errno)); - else - FAIL_EXIT1 ("unable to unshare user/fs: %s", strerror (errno)); - } -#else - /* Some targets may not support unshare at all. */ - FAIL_UNSUPPORTED ("unshare support missing"); -#endif - - /* Some systems, by default, all mounts leak out of the namespace. */ - if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0) - FAIL_EXIT1 ("could not create a private mount namespace\n"); - - trymount (support_srcdir_root, new_srcdir_path); - trymount (support_objdir_root, new_objdir_path); - - xmkdirp (concat (new_root_path, "/dev", NULL), 0755); - devmount (new_root_path, "null"); - devmount (new_root_path, "zero"); - devmount (new_root_path, "urandom"); - - /* We're done with the "old" root, switch to the new one. */ - if (chroot (new_root_path) < 0) - FAIL_EXIT1 ("Can't chroot to %s - ", new_root_path); - - if (chdir (new_cwd_path) < 0) - FAIL_EXIT1 ("Can't cd to new %s - ", new_cwd_path); - - /* To complete the containerization, we need to fork () at least - once. We can't exec, nor can we somehow link the new child to - our parent. So we run the child and propogate it's exit status - up. */ - child = fork (); - if (child < 0) - FAIL_EXIT1 ("Unable to fork"); - else if (child > 0) - { - /* Parent. */ - int status; - waitpid (child, &status, 0); - - if (WIFEXITED (status)) - exit (WEXITSTATUS (status)); - - if (WIFSIGNALED (status)) - { - printf ("%%SIGNALLED%%\n"); - exit (77); - } - - printf ("%%EXITERROR%%\n"); - exit (78); - } - - /* The rest is the child process, which is now PID 1 and "in" the - new root. */ - - maybe_xmkdir ("/tmp", 0755); - - /* Now that we're pid 1 (effectively "root") we can mount /proc */ - maybe_xmkdir ("/proc", 0777); - if (mount ("proc", "/proc", "proc", 0, NULL) < 0) - FAIL_EXIT1 ("Unable to mount /proc: "); - - /* We map our original UID to the same UID in the container so we - can own our own files normally. */ - UMAP = open ("/proc/self/uid_map", O_WRONLY); - if (UMAP < 0) - FAIL_EXIT1 ("can't write to /proc/self/uid_map\n"); - - sprintf (tmp, "%lld %lld 1\n", - (long long) original_uid, (long long) original_uid); - write (UMAP, tmp, strlen (tmp)); - xclose (UMAP); - - /* We must disable setgroups () before we can map our groups, else we - get EPERM. */ - GMAP = open ("/proc/self/setgroups", O_WRONLY); - if (GMAP >= 0) - { - /* We support kernels old enough to not have this. */ - write (GMAP, "deny\n", 5); - xclose (GMAP); - } - - /* We map our original GID to the same GID in the container so we - can own our own files normally. */ - GMAP = open ("/proc/self/gid_map", O_WRONLY); - if (GMAP < 0) - FAIL_EXIT1 ("can't write to /proc/self/gid_map\n"); - - sprintf (tmp, "%lld %lld 1\n", - (long long) original_gid, (long long) original_gid); - write (GMAP, tmp, strlen (tmp)); - xclose (GMAP); - - /* Now run the child. */ - execvp (new_child_proc[0], new_child_proc); - - /* Or don't run the child? */ - FAIL_EXIT1 ("Unable to exec %s\n", new_child_proc[0]); - - /* Because gcc won't know error () never returns... */ - exit (EXIT_UNSUPPORTED); -} diff --git a/support/true-container.c b/support/true-container.c deleted file mode 100644 index 57dc57e..0000000 --- a/support/true-container.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Minimal /bin/true for in-container use. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* Implements the in-container /bin/true, which always returns true - (0). */ - -int -main (void) -{ - return 0; -} diff --git a/support/tst-support_blob_repeat.c b/support/tst-support_blob_repeat.c deleted file mode 100644 index 1978c14..0000000 --- a/support/tst-support_blob_repeat.c +++ /dev/null @@ -1,85 +0,0 @@ -/* Tests for - 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 -#include -#include - -static int -do_test (void) -{ - struct support_blob_repeat repeat - = support_blob_repeat_allocate ("5", 1, 5); - TEST_COMPARE_BLOB (repeat.start, repeat.size, "55555", 5); - support_blob_repeat_free (&repeat); - - repeat = support_blob_repeat_allocate ("ABC", 3, 3); - TEST_COMPARE_BLOB (repeat.start, repeat.size, "ABCABCABC", 9); - support_blob_repeat_free (&repeat); - - repeat = support_blob_repeat_allocate ("abc", 4, 3); - TEST_COMPARE_BLOB (repeat.start, repeat.size, "abc\0abc\0abc", 12); - support_blob_repeat_free (&repeat); - - size_t gigabyte = 1U << 30; - repeat = support_blob_repeat_allocate ("X", 1, gigabyte + 1); - if (repeat.start == NULL) - puts ("warning: not enough memory for 1 GiB mapping"); - else - { - TEST_COMPARE (repeat.size, gigabyte + 1); - { - unsigned char *p = repeat.start; - for (size_t i = 0; i < gigabyte + 1; ++i) - if (p[i] != 'X') - FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i); - - /* Check that there is no sharing across the mapping. */ - p[0] = 'Y'; - p[1U << 24] = 'Z'; - for (size_t i = 0; i < gigabyte + 1; ++i) - if (i == 0) - TEST_COMPARE (p[i], 'Y'); - else if (i == 1U << 24) - TEST_COMPARE (p[i], 'Z'); - else if (p[i] != 'X') - FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i); - } - } - support_blob_repeat_free (&repeat); - - repeat = support_blob_repeat_allocate ("012345678", 9, 10 * 1000 * 1000); - if (repeat.start == NULL) - puts ("warning: not enough memory for large mapping"); - else - { - unsigned char *p = repeat.start; - for (int i = 0; i < 10 * 1000 * 1000; ++i) - for (int j = 0; j <= 8; ++j) - if (p[i * 9 + j] != '0' + j) - { - printf ("error: element %d index %d\n", i, j); - TEST_COMPARE (p[i * 9 + j], '0' + j); - } - } - support_blob_repeat_free (&repeat); - - return 0; -} - -#include diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c index 9957087..a685256 100644 --- a/support/tst-support_capture_subprocess.c +++ b/support/tst-support_capture_subprocess.c @@ -23,20 +23,8 @@ #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'. */ @@ -54,30 +42,6 @@ transfer (const unsigned char **p, int fd) 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 { @@ -88,9 +52,11 @@ struct test int status; }; -_Noreturn static void -test_common (const struct test *test) +/* For use with support_capture_subprocess. */ +static void +callback (void *closure) { + const struct test *test = closure; bool mode_ok = false; switch (test->write_mode) { @@ -129,40 +95,6 @@ test_common (const struct test *test) 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) @@ -198,59 +130,12 @@ check_stream (const char *what, const struct xmemstream *stream, } } -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_multiple_tests (enum test_type type) +do_test (void) { const int lengths[] = {0, 1, 17, 512, 20000, -1}; - /* Test multiple combinations of support_capture_sub{process,program}. + /* Test multiple combinations of support_capture_subprocess. length_idx_stdout: Index into the lengths array above, controls how many bytes are written by the subprocess to @@ -279,35 +164,19 @@ do_multiple_tests (enum test_type type) TEST_VERIFY (strlen (test.out) == lengths[length_idx_stdout]); TEST_VERIFY (strlen (test.err) == lengths[length_idx_stderr]); - struct support_capture_subprocess result - = type == subprocess ? do_subprocess (&test) - : do_subprogram (&test); - + struct support_capture_subprocess result + = support_capture_subprocess (callback, &test); check_stream ("stdout", &result.out, test.out); check_stream ("stderr", &result.err, test.err); - - /* Allowed output for support_capture_subprocess_check. */ - int check_allow = 0; - if (lengths[length_idx_stdout] > 0) - check_allow |= sc_allow_stdout; - if (lengths[length_idx_stderr] > 0) - check_allow |= sc_allow_stderr; - if (check_allow == 0) - check_allow = sc_allow_none; - if (test.signal != 0) { TEST_VERIFY (WIFSIGNALED (result.status)); TEST_VERIFY (WTERMSIG (result.status) == test.signal); - support_capture_subprocess_check (&result, "signal", - -SIGTERM, check_allow); } else { TEST_VERIFY (WIFEXITED (result.status)); TEST_VERIFY (WEXITSTATUS (result.status) == test.status); - support_capture_subprocess_check (&result, "exit", - test.status, check_allow); } support_capture_subprocess_free (&result); free (test.out); @@ -316,54 +185,4 @@ do_multiple_tests (enum test_type type) 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 --git a/support/tst-support_descriptors.c b/support/tst-support_descriptors.c deleted file mode 100644 index 5e9e824..0000000 --- a/support/tst-support_descriptors.c +++ /dev/null @@ -1,198 +0,0 @@ -/* Tests for monitoring file descriptor usage. - 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 -#include -#include -#include -#include -#include -#include -#include -#include - -/* This is the next free descriptor that the subprocess will pick. */ -static int free_descriptor; - -static void -subprocess_no_change (void *closure) -{ - struct support_descriptors *descrs = support_descriptors_list (); - int fd = xopen ("/dev/null", O_WRONLY, 0); - TEST_COMPARE (fd, free_descriptor); - xclose (fd); - support_descriptors_free (descrs); -} - -static void -subprocess_closed_descriptor (void *closure) -{ - int fd = xopen ("/dev/null", O_WRONLY, 0); - TEST_COMPARE (fd, free_descriptor); - struct support_descriptors *descrs = support_descriptors_list (); - xclose (fd); - support_descriptors_check (descrs); /* Will report failure. */ - puts ("EOT"); - support_descriptors_free (descrs); -} - -static void -subprocess_opened_descriptor (void *closure) -{ - struct support_descriptors *descrs = support_descriptors_list (); - int fd = xopen ("/dev/null", O_WRONLY, 0); - TEST_COMPARE (fd, free_descriptor); - support_descriptors_check (descrs); /* Will report failure. */ - puts ("EOT"); - support_descriptors_free (descrs); -} - -static void -subprocess_changed_descriptor (void *closure) -{ - int fd = xopen ("/dev/null", O_WRONLY, 0); - TEST_COMPARE (fd, free_descriptor); - struct support_descriptors *descrs = support_descriptors_list (); - xclose (fd); - TEST_COMPARE (xopen ("/dev", O_DIRECTORY | O_RDONLY, 0), fd); - support_descriptors_check (descrs); /* Will report failure. */ - puts ("EOT"); - support_descriptors_free (descrs); -} - -static void -report_subprocess_output (const char *name, - struct support_capture_subprocess *proc) -{ - printf ("info: BEGIN %s output\n" - "%s" - "info: END %s output\n", - name, proc->out.buffer, name); -} - -/* Use an explicit flag to preserve failure status across - support_record_failure_reset calls. */ -static bool good = true; - -static void -test_run (void) -{ - struct support_capture_subprocess proc = support_capture_subprocess - (&subprocess_no_change, NULL); - support_capture_subprocess_check (&proc, "subprocess_no_change", - 0, sc_allow_none); - support_capture_subprocess_free (&proc); - - char *expected = xasprintf ("\nDifferences:\n" - "error: descriptor %d was closed\n" - "EOT\n", - free_descriptor); - good = good && !support_record_failure_is_failed (); - proc = support_capture_subprocess (&subprocess_closed_descriptor, NULL); - good = good && support_record_failure_is_failed (); - support_record_failure_reset (); /* Discard the reported error. */ - report_subprocess_output ("subprocess_closed_descriptor", &proc); - TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL); - support_capture_subprocess_check (&proc, "subprocess_closed_descriptor", - 0, sc_allow_stdout); - support_capture_subprocess_free (&proc); - free (expected); - - expected = xasprintf ("\nDifferences:\n" - "error: descriptor %d was opened (\"/dev/null\")\n" - "EOT\n", - free_descriptor); - good = good && !support_record_failure_is_failed (); - proc = support_capture_subprocess (&subprocess_opened_descriptor, NULL); - good = good && support_record_failure_is_failed (); - support_record_failure_reset (); /* Discard the reported error. */ - report_subprocess_output ("subprocess_opened_descriptor", &proc); - TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL); - support_capture_subprocess_check (&proc, "subprocess_opened_descriptor", - 0, sc_allow_stdout); - support_capture_subprocess_free (&proc); - free (expected); - - expected = xasprintf ("\nDifferences:\n" - "error: descriptor %d changed from \"/dev/null\"" - " to \"/dev\"\n" - "error: descriptor %d changed ino ", - free_descriptor, free_descriptor); - good = good && !support_record_failure_is_failed (); - proc = support_capture_subprocess (&subprocess_changed_descriptor, NULL); - good = good && support_record_failure_is_failed (); - support_record_failure_reset (); /* Discard the reported error. */ - report_subprocess_output ("subprocess_changed_descriptor", &proc); - TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL); - support_capture_subprocess_check (&proc, "subprocess_changed_descriptor", - 0, sc_allow_stdout); - support_capture_subprocess_free (&proc); - free (expected); -} - -static int -do_test (void) -{ - puts ("info: initial descriptor set"); - { - struct support_descriptors *descrs = support_descriptors_list (); - support_descriptors_dump (descrs, "info: ", stdout); - support_descriptors_free (descrs); - } - - free_descriptor = xopen ("/dev/null", O_WRONLY, 0); - puts ("info: descriptor set with additional free descriptor"); - { - struct support_descriptors *descrs = support_descriptors_list (); - support_descriptors_dump (descrs, "info: ", stdout); - support_descriptors_free (descrs); - } - TEST_VERIFY (free_descriptor >= 3); - xclose (free_descriptor); - - /* Initial test run without a sentinel descriptor. The presence of - such a descriptor exercises different conditions in the list - comparison in support_descriptors_check. */ - test_run (); - - /* Allocate a sentinel descriptor at the end of the descriptor list, - after free_descriptor. */ - int sentinel_fd; - { - int fd = xopen ("/dev/full", O_WRONLY, 0); - TEST_COMPARE (fd, free_descriptor); - sentinel_fd = dup (fd); - TEST_VERIFY_EXIT (sentinel_fd > fd); - xclose (fd); - } - puts ("info: descriptor set with sentinel descriptor"); - { - struct support_descriptors *descrs = support_descriptors_list (); - support_descriptors_dump (descrs, "info: ", stdout); - support_descriptors_free (descrs); - } - - /* Second test run with sentinel descriptor. */ - test_run (); - - xclose (sentinel_fd); - - return !good; -} - -#include diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c deleted file mode 100644 index 3c00475..0000000 --- a/support/tst-support_quote_string.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Test the support_quote_string function. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include - -static int -do_test (void) -{ - char *p = support_quote_string (""); - TEST_COMPARE (strlen (p), 0); - free (p); - p = support_quote_string ("X"); - TEST_COMPARE (strlen (p), 1); - TEST_COMPARE (p[0], 'X'); - free (p); - - /* Check escaping of backslash-escaped characters, and lack of - escaping for other shell meta-characters. */ - p = support_quote_string ("$()*?`@[]{}~\'\"X"); - TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0); - free (p); - - /* Check lack of escaping for letters and digits. */ -#define LETTERS_AND_DIGTS \ - "abcdefghijklmnopqrstuvwxyz" \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ - "0123456789" - p = support_quote_string (LETTERS_AND_DIGTS "@"); - TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0); - free (p); - - /* Check escaping of control characters and other non-printable - characters. */ - p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@"); - TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001" - "\\177\\200\\377@"), 0); - free (p); - - return 0; -} - -#include diff --git a/support/tst-test_compare_string.c b/support/tst-test_compare_string.c deleted file mode 100644 index 2a4b258..0000000 --- a/support/tst-test_compare_string.c +++ /dev/null @@ -1,107 +0,0 @@ -/* Basic test for the TEST_COMPARE_STRING macro. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -static void -subprocess (void *closure) -{ - /* These tests should fail. They were chosen to cover differences - in length (with the same contents), single-bit mismatches, and - mismatching null pointers. */ - TEST_COMPARE_STRING ("", NULL); /* Line 29. */ - TEST_COMPARE_STRING ("X", ""); /* Line 30. */ - TEST_COMPARE_STRING (NULL, "X"); /* Line 31. */ - TEST_COMPARE_STRING ("abcd", "abcD"); /* Line 32. */ - TEST_COMPARE_STRING ("abcd", NULL); /* Line 33. */ - TEST_COMPARE_STRING (NULL, "abcd"); /* Line 34. */ -} - -/* Same contents, different addresses. */ -char buffer_abc_1[] = "abc"; -char buffer_abc_2[] = "abc"; - -static int -do_test (void) -{ - /* This should succeed. Even if the pointers and array contents are - different, zero-length inputs are not different. */ - TEST_COMPARE_STRING (NULL, NULL); - TEST_COMPARE_STRING ("", ""); - TEST_COMPARE_STRING (buffer_abc_1, buffer_abc_2); - TEST_COMPARE_STRING (buffer_abc_1, "abc"); - - struct support_capture_subprocess proc = support_capture_subprocess - (&subprocess, NULL); - - /* Discard the reported error. */ - support_record_failure_reset (); - - puts ("info: *** subprocess output starts ***"); - fputs (proc.out.buffer, stdout); - puts ("info: *** subprocess output ends ***"); - - TEST_VERIFY - (strcmp (proc.out.buffer, -"tst-test_compare_string.c:29: error: blob comparison failed\n" -" left string: 0 bytes\n" -" right string: NULL\n" -"tst-test_compare_string.c:30: error: blob comparison failed\n" -" left string: 1 bytes\n" -" right string: 0 bytes\n" -" left (evaluated from \"X\"):\n" -" \"X\"\n" -" 58\n" -"tst-test_compare_string.c:31: error: blob comparison failed\n" -" left string: NULL\n" -" right string: 1 bytes\n" -" right (evaluated from \"X\"):\n" -" \"X\"\n" -" 58\n" -"tst-test_compare_string.c:32: error: blob comparison failed\n" -" string length: 4 bytes\n" -" left (evaluated from \"abcd\"):\n" -" \"abcd\"\n" -" 61 62 63 64\n" -" right (evaluated from \"abcD\"):\n" -" \"abcD\"\n" -" 61 62 63 44\n" -"tst-test_compare_string.c:33: error: blob comparison failed\n" -" left string: 4 bytes\n" -" right string: NULL\n" -" left (evaluated from \"abcd\"):\n" -" \"abcd\"\n" -" 61 62 63 64\n" -"tst-test_compare_string.c:34: error: blob comparison failed\n" -" left string: NULL\n" -" right string: 4 bytes\n" -" right (evaluated from \"abcd\"):\n" -" \"abcd\"\n" -" 61 62 63 64\n" - ) == 0); - - /* Check that there is no output on standard error. */ - support_capture_subprocess_check (&proc, "TEST_COMPARE_STRING", - 0, sc_allow_stdout); - - return 0; -} - -#include diff --git a/support/xcopy_file_range.c b/support/xcopy_file_range.c deleted file mode 100644 index b3501a4..0000000 --- a/support/xcopy_file_range.c +++ /dev/null @@ -1,32 +0,0 @@ -/* copy_file_range with error checking. - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -ssize_t -xcopy_file_range (int infd, off64_t *pinoff, int outfd, off64_t *poutoff, - size_t length, unsigned int flags) -{ - ssize_t status = support_copy_file_range (infd, pinoff, outfd, - poutoff, length, flags); - if (status == -1) - FAIL_EXIT1 ("cannot copy file: %m\n"); - return status; -} diff --git a/support/xdlfcn.c b/support/xdlfcn.c index b4a6b85..f34bb05 100644 --- a/support/xdlfcn.c +++ b/support/xdlfcn.c @@ -48,26 +48,6 @@ xdlsym (void *handle, const char *symbol) return sym; } -void * -xdlvsym (void *handle, const char *symbol, const char *version) -{ - /* Clear any pending errors. */ - dlerror (); - - void *sym = dlvsym (handle, symbol, version); - - if (sym == NULL) - { - const char *error = dlerror (); - if (error != NULL) - FAIL_EXIT1 ("error: dlvsym: %s\n", error); - /* If there was no error, we found a NULL symbol. Return the - NULL value in this case. */ - } - - return sym; -} - void xdlclose (void *handle) { diff --git a/support/xdlfcn.h b/support/xdlfcn.h index ab1cbb3..5ab7494 100644 --- a/support/xdlfcn.h +++ b/support/xdlfcn.h @@ -26,7 +26,6 @@ __BEGIN_DECLS /* Each of these terminates process on failure with relevant error message. */ void *xdlopen (const char *filename, int flags); void *xdlsym (void *handle, const char *symbol); -void *xdlvsym (void *handle, const char *symbol, const char *version); void xdlclose (void *handle); diff --git a/support/xmkdirp.c b/support/xmkdirp.c deleted file mode 100644 index fada045..0000000 --- a/support/xmkdirp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Error-checking replacement for "mkdir -p". - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -#include -#include -#include - -/* Equivalent of "mkdir -p". Any failures cause FAIL_EXIT1 so no - return code is needed. */ - -void -xmkdirp (const char *path, mode_t mode) -{ - struct stat s; - const char *slash_p; - int rv; - - if (path[0] == 0) - return; - - if (stat (path, &s) == 0) - { - if (S_ISDIR (s.st_mode)) - return; - errno = EEXIST; - FAIL_EXIT1 ("mkdir_p (\"%s\", 0%o): %m", path, mode); - } - - slash_p = strrchr (path, '/'); - if (slash_p != NULL) - { - while (slash_p > path && slash_p[-1] == '/') - --slash_p; - if (slash_p > path) - { - char *parent = xstrndup (path, slash_p - path); - xmkdirp (parent, mode); - free (parent); - } - } - - rv = mkdir (path, mode); - if (rv != 0) - FAIL_EXIT1 ("mkdir_p (\"%s\", 0%o): %m", path, mode); - - return; -} diff --git a/support/xposix_memalign.c b/support/xposix_memalign.c deleted file mode 100644 index 5501a08..0000000 --- a/support/xposix_memalign.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Error-checking wrapper for posix_memalign. - 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 - -void * -xposix_memalign (size_t alignment, size_t n) -{ - void *p = NULL; - - int ret = posix_memalign (&p, alignment, n); - if (ret) - { - errno = ret; - oom_error ("posix_memalign", n); - } - return p; -} diff --git a/support/xposix_spawn.c b/support/xposix_spawn.c deleted file mode 100644 index abe7657..0000000 --- a/support/xposix_spawn.c +++ /dev/null @@ -1,32 +0,0 @@ -/* 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 --git a/support/xposix_spawn_file_actions_addclose.c b/support/xposix_spawn_file_actions_addclose.c deleted file mode 100644 index eed54a6..0000000 --- a/support/xposix_spawn_file_actions_addclose.c +++ /dev/null @@ -1,29 +0,0 @@ -/* 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 --git a/support/xposix_spawn_file_actions_adddup2.c b/support/xposix_spawn_file_actions_adddup2.c deleted file mode 100644 index 43d6bcc..0000000 --- a/support/xposix_spawn_file_actions_adddup2.c +++ /dev/null @@ -1,30 +0,0 @@ -/* 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 --git a/support/xpthread_attr_setstack.c b/support/xpthread_attr_setstack.c deleted file mode 100644 index c3772e2..0000000 --- a/support/xpthread_attr_setstack.c +++ /dev/null @@ -1,26 +0,0 @@ -/* pthread_attr_setstack 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_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize) -{ - xpthread_check_return ("pthread_attr_setstack", - pthread_attr_setstack (attr, stackaddr, stacksize)); -} diff --git a/support/xpthread_rwlock_destroy.c b/support/xpthread_rwlock_destroy.c deleted file mode 100644 index 6d6e953..0000000 --- a/support/xpthread_rwlock_destroy.c +++ /dev/null @@ -1,26 +0,0 @@ -/* 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/xspawn.h b/support/xspawn.h deleted file mode 100644 index 6c6850f..0000000 --- a/support/xspawn.h +++ /dev/null @@ -1,34 +0,0 @@ -/* 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/support/xsymlink.c b/support/xsymlink.c deleted file mode 100644 index 0f3edf6..0000000 --- a/support/xsymlink.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Error-checking replacement for "symlink". - Copyright (C) 2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - -#include - -void -xsymlink (const char *target, const char *linkpath) -{ - if (symlink (target, linkpath) < 0) - FAIL_EXIT1 ("symlink (\"%s\", \"%s\")", target, linkpath); -} diff --git a/support/xthread.h b/support/xthread.h index 00e2f59..623f5ad 100644 --- a/support/xthread.h +++ b/support/xthread.h @@ -68,8 +68,6 @@ void xpthread_attr_destroy (pthread_attr_t *attr); void xpthread_attr_init (pthread_attr_t *attr); void xpthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate); -void xpthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, - size_t stacksize); void xpthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize); void xpthread_attr_setguardsize (pthread_attr_t *attr, @@ -86,7 +84,6 @@ 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/support/xunistd.h b/support/xunistd.h index f99f362..5fe5dae 100644 --- a/support/xunistd.h +++ b/support/xunistd.h @@ -43,10 +43,6 @@ void xunlink (const char *path); long xsysconf (int name); long long xlseek (int fd, long long offset, int whence); void xftruncate (int fd, long long length); -void xsymlink (const char *target, const char *linkpath); - -/* Equivalent of "mkdir -p". */ -void xmkdirp (const char *, mode_t); /* Read the link at PATH. The caller should free the returned string with free. */ @@ -64,9 +60,6 @@ void *xmmap (void *addr, size_t length, int prot, int flags, int fd); void xmprotect (void *addr, size_t length, int prot); void xmunmap (void *addr, size_t length); -ssize_t xcopy_file_range(int fd_in, loff_t *off_in, int fd_out, - loff_t *off_out, size_t len, unsigned int flags); - __END_DECLS #endif /* SUPPORT_XUNISTD_H */ diff --git a/sysdeps/aarch64/dl-dtprocnum.h b/sysdeps/aarch64/dl-dtprocnum.h deleted file mode 100644 index 4ac2adf..0000000 --- a/sysdeps/aarch64/dl-dtprocnum.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Configuration of lookup functions. AArch64 version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see - . */ - -/* Number of extra dynamic section entries for this architecture. By - default there are none. */ -#define DT_THISPROCNUM DT_AARCH64_NUM diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h index bef71ed..5889ee1 100644 --- a/sysdeps/aarch64/dl-irel.h +++ b/sysdeps/aarch64/dl-irel.h @@ -47,7 +47,7 @@ elf_irela (const ElfW(Rela) *reloc) *reloc_addr = value; } else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h index b39eae4..4935aa7 100644 --- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -27,9 +27,6 @@ #include #include -/* Translate a processor specific dynamic tag to the index in l_info array. */ -#define DT_AARCH64(x) (DT_AARCH64_##x - DT_LOPROC + DT_NUM) - /* Return nonzero iff ELF header is compatible with the running host. */ static inline int __attribute__ ((unused)) elf_machine_matches_host (const ElfW(Ehdr) *ehdr) @@ -391,37 +388,10 @@ elf_machine_lazy_rel (struct link_map *map, /* Check for unexpected PLT reloc type. */ if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1)) { - if (map->l_mach.plt == 0) - { - /* Prelinking. */ - *reloc_addr += l_addr; - return; - } - - if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL)) - { - /* Check the symbol table for variant PCS symbols. */ - const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); - const ElfW (Sym) *symtab = - (const void *)D_PTR (map, l_info[DT_SYMTAB]); - const ElfW (Sym) *sym = &symtab[symndx]; - if (__glibc_unlikely (sym->st_other & STO_AARCH64_VARIANT_PCS)) - { - /* Avoid lazy resolution of variant PCS symbols. */ - const struct r_found_version *version = NULL; - if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL) - { - const ElfW (Half) *vernum = - (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); - version = &map->l_versions[vernum[symndx] & 0x7fff]; - } - elf_machine_rela (map, reloc, sym, version, reloc_addr, - skip_ifunc); - return; - } - } - - *reloc_addr = map->l_mach.plt; + if (__builtin_expect (map->l_mach.plt, 0) == 0) + *reloc_addr += l_addr; + else + *reloc_addr = map->l_mach.plt; } else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1)) { diff --git a/sysdeps/arm/dl-irel.h b/sysdeps/arm/dl-irel.h index be6eb77..a7b6456 100644 --- a/sysdeps/arm/dl-irel.h +++ b/sysdeps/arm/dl-irel.h @@ -46,7 +46,7 @@ elf_irel (const Elf32_Rel *reloc) *reloc_addr = value; } else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/generic/dl-fileid.h b/sysdeps/generic/dl-fileid.h index e613402..a7e2fcd 100644 --- a/sysdeps/generic/dl-fileid.h +++ b/sysdeps/generic/dl-fileid.h @@ -29,8 +29,7 @@ struct r_file_id On error, returns false, with errno set. */ static inline bool _dl_get_file_id (int fd __attribute__ ((unused)), - struct r_file_id *id __attribute__ ((unused)), - struct stat64_t *st __attribute__((unused))) + struct r_file_id *id __attribute__ ((unused))) { return true; } diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index f0185ce..95dc875 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -311,14 +311,7 @@ struct rtld_global /* This is zero at program start to signal that the global scope map is allocated by rtld. Later it keeps the size of the map. It might be reset if in _dl_close if the last global object is removed. */ - unsigned int _ns_global_scope_alloc; - - /* During dlopen, this is the number of objects that still need to - be added to the global scope map. It has to be taken into - account when resizing the map, for future map additions after - recursive dlopen calls from ELF constructors. */ - unsigned int _ns_global_scope_pending_adds; - + size_t _ns_global_scope_alloc; /* Search table for unique objects. */ struct unique_sym_table { @@ -359,6 +352,11 @@ struct rtld_global /* The object to be initialized first. */ EXTERN struct link_map *_dl_initfirst; +#if HP_SMALL_TIMING_AVAIL + /* Start time on CPU clock. */ + EXTERN hp_timing_t _dl_cpuclock_offset; +#endif + /* Map of shared object to be profiled. */ EXTERN struct link_map *_dl_profile_map; @@ -854,9 +852,7 @@ libc_hidden_proto (_dl_catch_error) /* Call OPERATE (ARGS). If no error occurs, set *EXCEPTION to zero. Otherwise, store a copy of the raised exception in *EXCEPTION, - which has to be freed by _dl_exception_free. As a special case, if - EXCEPTION is null, call OPERATE (ARGS) with exception handling - disabled (so that exceptions are fatal). */ + which has to be freed by _dl_exception_free. */ int _dl_catch_exception (struct dl_exception *exception, void (*operate) (void *), void *args); libc_hidden_proto (_dl_catch_exception) @@ -910,9 +906,6 @@ enum DL_LOOKUP_RETURN_NEWEST = 2, /* Set if dl_lookup* called with GSCOPE lock held. */ DL_LOOKUP_GSCOPE_LOCK = 4, - /* Set if dl_lookup is called for non-lazy relocation processing - from _dl_relocate_object in elf/dl-reloc.c. */ - DL_LOOKUP_FOR_RELOCATE = 8, }; /* Lookup versioned symbol. */ @@ -1130,15 +1123,8 @@ extern void *_dl_open (const char *name, int mode, const void *caller, old scope, OLD can't be freed until no thread is using it. */ extern int _dl_scope_free (void *) attribute_hidden; - -/* Add module to slot information data. If DO_ADD is false, only the - required memory is allocated. Must be called with GL - (dl_load_lock) acquired. If the function has already been called - for the link map L with !do_add, then this function will not raise - an exception, otherwise it is possible that it encounters a memory - allocation failure. */ -extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add) - attribute_hidden; +/* Add module to slot information data. */ +extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden; /* Update slot information data for at least the generation of the module with the given index. */ diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h deleted file mode 100644 index 770b54c..0000000 --- a/sysdeps/generic/math-use-builtins.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Using math gcc builtins instead of generic implementation. Generic version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef MATH_USE_BUILTINS_H -#define MATH_USE_BUILTINS_H 1 - -#include /* For __GNUC_PREREQ. */ - -/* Define these macros to 1 to use __builtin_xyz instead of the - generic implementation. */ -#define USE_NEARBYINT_BUILTIN 0 -#define USE_NEARBYINTF_BUILTIN 0 -#define USE_NEARBYINTL_BUILTIN 0 -#define USE_NEARBYINTF128_BUILTIN 0 - -#define USE_RINT_BUILTIN 0 -#define USE_RINTF_BUILTIN 0 -#define USE_RINTL_BUILTIN 0 -#define USE_RINTF128_BUILTIN 0 - -#define USE_FLOOR_BUILTIN 0 -#define USE_FLOORF_BUILTIN 0 -#define USE_FLOORL_BUILTIN 0 -#define USE_FLOORF128_BUILTIN 0 - -#define USE_CEIL_BUILTIN 0 -#define USE_CEILF_BUILTIN 0 -#define USE_CEILL_BUILTIN 0 -#define USE_CEILF128_BUILTIN 0 - -#define USE_TRUNC_BUILTIN 0 -#define USE_TRUNCF_BUILTIN 0 -#define USE_TRUNCL_BUILTIN 0 -#define USE_TRUNCF128_BUILTIN 0 - -#define USE_ROUND_BUILTIN 0 -#define USE_ROUNDF_BUILTIN 0 -#define USE_ROUNDL_BUILTIN 0 -#define USE_ROUNDF128_BUILTIN 0 - -#define USE_COPYSIGNL_BUILTIN 1 -#if __GNUC_PREREQ (7, 0) -# define USE_COPYSIGNF128_BUILTIN 1 -#else -# define USE_COPYSIGNF128_BUILTIN 0 -#endif - -#endif /* math-use-builtins.h */ diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h index 260e6e4..d9f8a75 100644 --- a/sysdeps/generic/not-cancel.h +++ b/sysdeps/generic/not-cancel.h @@ -41,8 +41,6 @@ (void) __close (fd) #define __read_nocancel(fd, buf, n) \ __read (fd, buf, n) -#define __pread64_nocancel(fd, buf, count, offset) \ - __pread64 (fd, buf, count, offset) #define __write_nocancel(fd, buf, n) \ __write (fd, buf, n) #define __writev_nocancel_nostatus(fd, iov, n) \ diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c index 724c16a..082609b 100644 --- a/sysdeps/generic/unwind-dw2.c +++ b/sysdeps/generic/unwind-dw2.c @@ -843,7 +843,7 @@ execute_cfa_program (const unsigned char *insn_ptr, struct frame_state_reg_info *old_rs = fs->regs.prev; #ifdef _LIBC if (old_rs == NULL) - __libc_fatal ("Invalid DWARF unwind data.\n"); + __libc_fatal ("invalid DWARF unwind data"); else #endif { diff --git a/sysdeps/generic/utmp-equal.h b/sysdeps/generic/utmp-equal.h index 39993af..8b5c2e2 100644 --- a/sysdeps/generic/utmp-equal.h +++ b/sysdeps/generic/utmp-equal.h @@ -27,16 +27,26 @@ static int __utmp_equal (const struct utmp *entry, const struct utmp *match) { - return (entry->ut_type == INIT_PROCESS - || entry->ut_type == LOGIN_PROCESS - || entry->ut_type == USER_PROCESS - || entry->ut_type == DEAD_PROCESS) - && (match->ut_type == INIT_PROCESS - || match->ut_type == LOGIN_PROCESS - || match->ut_type == USER_PROCESS - || match->ut_type == DEAD_PROCESS) - && (entry->ut_id[0] && match->ut_id[0] - ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 - : (strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) - == 0)); + return + ( +#if _HAVE_UT_TYPE - 0 + (entry->ut_type == INIT_PROCESS + || entry->ut_type == LOGIN_PROCESS + || entry->ut_type == USER_PROCESS + || entry->ut_type == DEAD_PROCESS) + && + (match->ut_type == INIT_PROCESS + || match->ut_type == LOGIN_PROCESS + || match->ut_type == USER_PROCESS + || match->ut_type == DEAD_PROCESS) + && +#endif +#if _HAVE_UT_ID - 0 + (entry->ut_id[0] && match->ut_id[0] + ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 + : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0) +#else + strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0 +#endif + ); } diff --git a/sysdeps/gnu/bits/utmp.h b/sysdeps/gnu/bits/utmp.h new file mode 100644 index 0000000..47a6082 --- /dev/null +++ b/sysdeps/gnu/bits/utmp.h @@ -0,0 +1,126 @@ +/* The `struct utmp' type, describing entries in the utmp file. GNU version. + Copyright (C) 1993-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 + . */ + +#ifndef _UTMP_H +# error "Never include directly; use instead." +#endif + +#include +#include +#include +#include + + +#define UT_LINESIZE 32 +#define UT_NAMESIZE 32 +#define UT_HOSTSIZE 256 + + +/* The structure describing an entry in the database of + previous logins. */ +struct lastlog + { +#if __WORDSIZE_TIME64_COMPAT32 + int32_t ll_time; +#else + __time_t ll_time; +#endif + char ll_line[UT_LINESIZE]; + char ll_host[UT_HOSTSIZE]; + }; + + +/* The structure describing the status of a terminated process. This + type is used in `struct utmp' below. */ +struct exit_status + { + short int e_termination; /* Process termination status. */ + short int e_exit; /* Process exit status. */ + }; + + +/* The structure describing an entry in the user accounting database. */ +struct utmp +{ + short int ut_type; /* Type of login. */ + pid_t ut_pid; /* Process ID of login process. */ + char ut_line[UT_LINESIZE] + __attribute_nonstring__; /* Devicename. */ + char ut_id[4]; /* Inittab ID. */ + char ut_user[UT_NAMESIZE] + __attribute_nonstring__; /* Username. */ + char ut_host[UT_HOSTSIZE] + __attribute_nonstring__; /* Hostname for remote login. */ + struct exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ +/* The ut_session and ut_tv fields must be the same size when compiled + 32- and 64-bit. This allows data files and shared memory to be + shared between 32- and 64-bit applications. */ +#if __WORDSIZE_TIME64_COMPAT32 + int32_t ut_session; /* Session ID, used for windowing. */ + struct + { + int32_t tv_sec; /* Seconds. */ + int32_t tv_usec; /* Microseconds. */ + } ut_tv; /* Time entry was made. */ +#else + long int ut_session; /* Session ID, used for windowing. */ + struct timeval ut_tv; /* Time entry was made. */ +#endif + + int32_t ut_addr_v6[4]; /* Internet address of remote host. */ + char __glibc_reserved[20]; /* Reserved for future use. */ +}; + +/* Backwards compatibility hacks. */ +#define ut_name ut_user +#ifndef _NO_UT_TIME +/* We have a problem here: `ut_time' is also used otherwise. Define + _NO_UT_TIME if the compiler complains. */ +# define ut_time ut_tv.tv_sec +#endif +#define ut_xtime ut_tv.tv_sec +#define ut_addr ut_addr_v6[0] + + +/* Values for the `ut_type' field of a `struct utmp'. */ +#define EMPTY 0 /* No valid user accounting information. */ + +#define RUN_LVL 1 /* The system's runlevel. */ +#define BOOT_TIME 2 /* Time of system boot. */ +#define NEW_TIME 3 /* Time after system clock changed. */ +#define OLD_TIME 4 /* Time when system clock changed. */ + +#define INIT_PROCESS 5 /* Process spawned by the init process. */ +#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ +#define USER_PROCESS 7 /* Normal process. */ +#define DEAD_PROCESS 8 /* Terminated process. */ + +#define ACCOUNTING 9 + +/* Old Linux name for the EMPTY type. */ +#define UT_UNKNOWN EMPTY + + +/* Tell the user that we have a modern system with UT_HOST, UT_PID, + UT_TYPE, UT_ID and UT_TV fields. */ +#define _HAVE_UT_TYPE 1 +#define _HAVE_UT_PID 1 +#define _HAVE_UT_ID 1 +#define _HAVE_UT_TV 1 +#define _HAVE_UT_HOST 1 diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h index 71c743e..2a77efc 100644 --- a/sysdeps/gnu/bits/utmpx.h +++ b/sysdeps/gnu/bits/utmpx.h @@ -56,14 +56,10 @@ struct utmpx { short int ut_type; /* Type of login. */ __pid_t ut_pid; /* Process ID of login process. */ - char ut_line[__UT_LINESIZE] - __attribute_nonstring__; /* Devicename. */ - char ut_id[4] - __attribute_nonstring__; /* Inittab ID. */ - char ut_user[__UT_NAMESIZE] - __attribute_nonstring__; /* Username. */ - char ut_host[__UT_HOSTSIZE] - __attribute_nonstring__; /* Hostname for remote login. */ + char ut_line[__UT_LINESIZE]; /* Devicename. */ + char ut_id[4]; /* Inittab ID. */ + char ut_user[__UT_NAMESIZE]; /* Username. */ + char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ struct __exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS. */ diff --git a/sysdeps/i386/dl-cet.c b/sysdeps/i386/dl-cet.c new file mode 100644 index 0000000..5d9a4e8 --- /dev/null +++ b/sysdeps/i386/dl-cet.c @@ -0,0 +1,67 @@ +/* Linux/i386 CET initializers function. + Copyright (C) 2018 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + + +#define LINKAGE static inline +#define _dl_cet_check cet_check +#include +#undef _dl_cet_check + +#ifdef SHARED +void +_dl_cet_check (struct link_map *main_map, const char *program) +{ + cet_check (main_map, program); + + if ((GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) + { + /* Replace _dl_runtime_resolve and _dl_runtime_profile with + _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, + respectively if SHSTK is enabled. */ + extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; + extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; + extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; + extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; + unsigned int i; + struct link_map *l; + Elf32_Addr *got; + + if (main_map->l_info[DT_JMPREL]) + { + got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]); + if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) + got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; + else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) + got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; + } + + i = main_map->l_searchlist.r_nlist; + while (i-- > 0) + { + l = main_map->l_initfini[i]; + if (l->l_info[DT_JMPREL]) + { + got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); + if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) + got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; + else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) + got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; + } + } + } +} +#endif diff --git a/sysdeps/i386/dl-irel.h b/sysdeps/i386/dl-irel.h index bcaf066..5530318 100644 --- a/sysdeps/i386/dl-irel.h +++ b/sysdeps/i386/dl-irel.h @@ -45,7 +45,7 @@ elf_irel (const Elf32_Rel *reloc) *reloc_addr = value; } else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index f6cfb90..1afdcbd 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -67,11 +67,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) Elf32_Addr *got; extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; - extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; - extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; - /* Check if SHSTK is enabled by kernel. */ - bool shstk_enabled - = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0; if (l->l_info[DT_JMPREL] && lazy) { @@ -98,9 +93,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) end in this function. */ if (__glibc_unlikely (profile)) { - got[2] = (shstk_enabled - ? (Elf32_Addr) &_dl_runtime_profile_shstk - : (Elf32_Addr) &_dl_runtime_profile); + got[2] = (Elf32_Addr) &_dl_runtime_profile; if (GLRO(dl_profile) != NULL && _dl_name_match_p (GLRO(dl_profile), l)) @@ -111,9 +104,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) else /* This function will get called to fix up the GOT entry indicated by the offset on the stack, and then jump to the resolved address. */ - got[2] = (shstk_enabled - ? (Elf32_Addr) &_dl_runtime_resolve_shstk - : (Elf32_Addr) &_dl_runtime_resolve); + got[2] = (Elf32_Addr) &_dl_runtime_resolve; } return lazy; diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S index e35e9bd..91035fa 100644 --- a/sysdeps/i386/start.S +++ b/sysdeps/i386/start.S @@ -52,11 +52,10 @@ NULL */ -#include - -ENTRY (_start) - /* Clearing frame pointer is insufficient, use CFI. */ - cfi_undefined (eip) + .text + .globl _start + .type _start,@function +_start: /* Clear the frame pointer. The ABI suggests this be done, to mark the outermost frame obviously. */ xorl %ebp, %ebp @@ -132,7 +131,6 @@ ENTRY (_start) 1: movl (%esp), %ebx ret #endif -END (_start) /* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so meaningless since we don't support machines < 80386. */ diff --git a/sysdeps/ieee754/dbl-64/s_ceil.c b/sysdeps/ieee754/dbl-64/s_ceil.c index ee4a3ab..5a7434c 100644 --- a/sysdeps/ieee754/dbl-64/s_ceil.c +++ b/sysdeps/ieee754/dbl-64/s_ceil.c @@ -20,49 +20,66 @@ #include #include #include -#include double __ceil (double x) { -#if USE_CEIL_BUILTIN - return __builtin_ceil (x); -#else - /* Use generic implementation. */ - int64_t i0, i; - int32_t j0; - EXTRACT_WORDS64 (i0, x); - j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; - if (j0 <= 51) + int32_t i0, i1, j0; + uint32_t i, j; + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { if (j0 < 0) { - /* return 0 * sign(x) if |x| < 1 */ + /* return 0*sign(x) if |x|<1 */ if (i0 < 0) - i0 = INT64_C (0x8000000000000000); - else if (i0 != 0) - i0 = INT64_C (0x3ff0000000000000); + { + i0 = 0x80000000; i1 = 0; + } + else if ((i0 | i1) != 0) + { + i0 = 0x3ff00000; i1 = 0; + } } else { - i = INT64_C (0x000fffffffffffff) >> j0; - if ((i0 & i) == 0) - return x; /* x is integral */ + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ if (i0 > 0) - i0 += UINT64_C (0x0010000000000000) >> j0; - i0 &= ~i; + i0 += (0x00100000) >> j0; + i0 &= (~i); i1 = 0; } } - else + else if (j0 > 51) { if (j0 == 0x400) - return x + x; /* inf or NaN */ + return x + x; /* inf or NaN */ else - return x; /* x is integral */ + return x; /* x is integral */ + } + else + { + i = ((uint32_t) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + if (i0 > 0) + { + if (j0 == 20) + i0 += 1; + else + { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); } - INSERT_WORDS64 (x, i0); + INSERT_WORDS (x, i0, i1); return x; -#endif /* ! USE_CEIL_BUILTIN */ } #ifndef __ceil libm_alias_double (__ceil, ceil) diff --git a/sysdeps/ieee754/dbl-64/s_copysign.c b/sysdeps/ieee754/dbl-64/s_copysign.c index b95f157..ab81d73 100644 --- a/sysdeps/ieee754/dbl-64/s_copysign.c +++ b/sysdeps/ieee754/dbl-64/s_copysign.c @@ -10,7 +10,7 @@ * ==================================================== */ -#if defined (LIBM_SCCS) && ! defined (lint) +#if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $"; #endif @@ -21,11 +21,16 @@ static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $ */ #include +#include #include double __copysign (double x, double y) { - return __builtin_copysign (x, y); + uint32_t hx, hy; + GET_HIGH_WORD (hx, x); + GET_HIGH_WORD (hy, y); + SET_HIGH_WORD (x, (hx & 0x7fffffff) | (hy & 0x80000000)); + return x; } libm_alias_double (__copysign, copysign) diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c index 693938b..f27c6f3 100644 --- a/sysdeps/ieee754/dbl-64/s_floor.c +++ b/sysdeps/ieee754/dbl-64/s_floor.c @@ -1,24 +1,4 @@ -/* Round double to integer away from zero. - Copyright (C) 2011-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2011. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* Based on a version which carries the following copyright: */ - +/* @(#)s_floor.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -30,12 +10,6 @@ * ==================================================== */ -#include -#include -#include -#include -#include - /* * floor(x) * Return x rounded toward -inf to integral value @@ -43,41 +17,69 @@ * Bit twiddling. */ +#include +#include +#include + double __floor (double x) { -#if USE_FLOOR_BUILTIN - return __builtin_floor (x); -#else - /* Use generic implementation. */ - int64_t i0; - EXTRACT_WORDS64 (i0, x); - int32_t j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; - if (__glibc_likely (j0 < 52)) + int32_t i0, i1, j0; + uint32_t i, j; + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { if (j0 < 0) { - /* return 0 * sign (x) if |x| < 1 */ + /* return 0*sign(x) if |x|<1 */ if (i0 >= 0) - i0 = 0; - else if ((i0 & 0x7fffffffffffffffl) != 0) - i0 = 0xbff0000000000000l; + { + i0 = i1 = 0; + } + else if (((i0 & 0x7fffffff) | i1) != 0) + { + i0 = 0xbff00000; i1 = 0; + } } else { - uint64_t i = 0x000fffffffffffffl >> j0; - if ((i0 & i) == 0) - return x; /* x is integral */ + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ if (i0 < 0) - i0 += 0x0010000000000000l >> j0; - i0 &= ~i; + i0 += (0x00100000) >> j0; + i0 &= (~i); i1 = 0; + } + } + else if (j0 > 51) + { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } + else + { + i = ((uint32_t) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + if (i0 < 0) + { + if (j0 == 20) + i0 += 1; + else + { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } } - INSERT_WORDS64 (x, i0); + i1 &= (~i); } - else if (j0 == 0x400) - return x + x; /* inf or NaN */ + INSERT_WORDS (x, i0, i1); return x; -#endif /* ! USE_FLOOR_BUILTIN */ } #ifndef __floor libm_alias_double (__floor, floor) diff --git a/sysdeps/ieee754/dbl-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/s_nearbyint.c index e3fd2a8..903121d 100644 --- a/sysdeps/ieee754/dbl-64/s_nearbyint.c +++ b/sysdeps/ieee754/dbl-64/s_nearbyint.c @@ -10,6 +10,10 @@ * ==================================================== */ +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; +#endif + /* * rint(x) * Return x rounded to integral value according to the prevailing @@ -25,51 +29,48 @@ #include #include #include -#include + +static const double + TWO52[2] = { + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; double __nearbyint (double x) { -#if USE_NEARBYINT_BUILTIN - return __builtin_nearbyint (x); -#else - /* Use generic implementation. */ - static const double - TWO52[2] = { - 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ - -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ - }; fenv_t env; - int64_t i0, sx; - int32_t j0; - EXTRACT_WORDS64 (i0, x); - sx = (i0 >> 63) & 1; - j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; - if (__glibc_likely (j0 < 52)) + int32_t i0, j0, sx; + double w, t; + GET_HIGH_WORD (i0, x); + sx = (i0 >> 31) & 1; + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 52) { if (j0 < 0) { libc_feholdexcept (&env); - double w = TWO52[sx] + math_opt_barrier (x); - double t = w - TWO52[sx]; + w = TWO52[sx] + math_opt_barrier (x); + t = w - TWO52[sx]; math_force_eval (t); libc_fesetenv (&env); - return copysign (t, x); + GET_HIGH_WORD (i0, t); + SET_HIGH_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); + return t; } } else { if (j0 == 0x400) - return x + x; /* inf or NaN */ + return x + x; /* inf or NaN */ else - return x; /* x is integral */ + return x; /* x is integral */ } libc_feholdexcept (&env); - double w = TWO52[sx] + math_opt_barrier (x); - double t = w - TWO52[sx]; + w = TWO52[sx] + math_opt_barrier (x); + t = w - TWO52[sx]; math_force_eval (t); libc_fesetenv (&env); return t; -#endif /* ! USE_NEARBYINT_BUILTIN */ } libm_alias_double (__nearbyint, nearbyint) diff --git a/sysdeps/ieee754/dbl-64/s_rint.c b/sysdeps/ieee754/dbl-64/s_rint.c index 5f4ac7c..cb0f5ca 100644 --- a/sysdeps/ieee754/dbl-64/s_rint.c +++ b/sysdeps/ieee754/dbl-64/s_rint.c @@ -1,3 +1,4 @@ +/* @(#)s_rint.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -22,47 +23,41 @@ #include #include #include -#include + +static const double + TWO52[2] = { + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; double __rint (double x) { -#if USE_RINT_BUILTIN - return __builtin_rint (x); -#else - /* Use generic implementation. */ - static const double - TWO52[2] = { - 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ - -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ - }; - int64_t i0, sx; - int32_t j0; - EXTRACT_WORDS64 (i0, x); - sx = (i0 >> 63) & 1; - j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; + int32_t i0, j0, sx; + double w, t; + GET_HIGH_WORD (i0, x); + sx = (i0 >> 31) & 1; + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; if (j0 < 52) { if (j0 < 0) { - double w = TWO52[sx] + x; - double t = w - TWO52[sx]; - EXTRACT_WORDS64 (i0, t); - INSERT_WORDS64 (t, (i0 & UINT64_C (0x7fffffffffffffff)) - | (sx << 63)); + w = TWO52[sx] + x; + t = w - TWO52[sx]; + GET_HIGH_WORD (i0, t); + SET_HIGH_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); return t; } } else { if (j0 == 0x400) - return x + x; /* inf or NaN */ + return x + x; /* inf or NaN */ else - return x; /* x is integral */ + return x; /* x is integral */ } - double w = TWO52[sx] + x; + w = TWO52[sx] + x; return w - TWO52[sx]; -#endif /* ! USE_RINT_BUILTIN */ } #ifndef __rint libm_alias_double (__rint, rint) diff --git a/sysdeps/ieee754/dbl-64/s_round.c b/sysdeps/ieee754/dbl-64/s_round.c index 1f8482a..fa9e831 100644 --- a/sysdeps/ieee754/dbl-64/s_round.c +++ b/sysdeps/ieee754/dbl-64/s_round.c @@ -21,41 +21,38 @@ #include #include -#include -#include double __round (double x) { -#if USE_ROUND_BUILTIN - return __builtin_round (x); -#else - /* Use generic implementation. */ - int64_t i0, j0; + int32_t i0, j0; + uint32_t i1; - EXTRACT_WORDS64 (i0, x); - j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; - if (__glibc_likely (j0 < 52)) + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { if (j0 < 0) { - i0 &= UINT64_C (0x8000000000000000); + i0 &= 0x80000000; if (j0 == -1) - i0 |= UINT64_C (0x3ff0000000000000); + i0 |= 0x3ff00000; + i1 = 0; } else { - uint64_t i = UINT64_C (0x000fffffffffffff) >> j0; - if ((i0 & i) == 0) + uint32_t i = 0x000fffff >> j0; + if (((i0 & i) | i1) == 0) /* X is integral. */ return x; - i0 += UINT64_C (0x0008000000000000) >> j0; + i0 += 0x00080000 >> j0; i0 &= ~i; + i1 = 0; } } - else + else if (j0 > 51) { if (j0 == 0x400) /* Inf or NaN. */ @@ -63,9 +60,21 @@ __round (double x) else return x; } + else + { + uint32_t i = 0xffffffff >> (j0 - 20); + if ((i1 & i) == 0) + /* X is integral. */ + return x; + + uint32_t j = i1 + (1 << (51 - j0)); + if (j < i1) + i0 += 1; + i1 = j; + i1 &= ~i; + } - INSERT_WORDS64 (x, i0); + INSERT_WORDS (x, i0, i1); return x; -#endif /* ! USE_ROUND_BUILTIN */ } libm_alias_double (__round, round) diff --git a/sysdeps/ieee754/dbl-64/s_trunc.c b/sysdeps/ieee754/dbl-64/s_trunc.c index 708169c..6ffabb4 100644 --- a/sysdeps/ieee754/dbl-64/s_trunc.c +++ b/sysdeps/ieee754/dbl-64/s_trunc.c @@ -21,39 +21,38 @@ #include #include -#include double __trunc (double x) { -#if USE_TRUNC_BUILTIN - return __builtin_trunc (x); -#else - /* Use generic implementation. */ - int64_t i0, j0; - int64_t sx; - - EXTRACT_WORDS64 (i0, x); - sx = i0 & UINT64_C (0x8000000000000000); - j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; - if (j0 < 52) + int32_t i0, j0; + uint32_t i1; + int sx; + + EXTRACT_WORDS (i0, i1, x); + sx = i0 & 0x80000000; + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { if (j0 < 0) /* The magnitude of the number is < 1 so the result is +-0. */ - INSERT_WORDS64 (x, sx); + INSERT_WORDS (x, sx, 0); else - INSERT_WORDS64 (x, sx | (i0 & ~(UINT64_C (0x000fffffffffffff) >> j0))); + INSERT_WORDS (x, sx | (i0 & ~(0x000fffff >> j0)), 0); } - else + else if (j0 > 51) { if (j0 == 0x400) /* x is inf or NaN. */ return x + x; } + else + { + INSERT_WORDS (x, i0, i1 & ~(0xffffffffu >> (j0 - 20))); + } return x; -#endif /* ! USE_TRUNC_BUILTIN */ } #ifndef __trunc libm_alias_double (__trunc, trunc) diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c new file mode 100644 index 0000000..b99829d --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_ceil.c @@ -0,0 +1,51 @@ +/* @(#)s_ceil.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + */ + +#include +#include +#include + +double +__ceil(double x) +{ + int64_t i0,i; + int32_t j0; + EXTRACT_WORDS64(i0,x); + j0 = ((i0>>52)&0x7ff)-0x3ff; + if(j0<=51) { + if(j0<0) { + /* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=INT64_C(0x8000000000000000);} + else if(i0!=0) { i0=INT64_C(0x3ff0000000000000);} + } else { + i = INT64_C(0x000fffffffffffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(i0>0) i0 += UINT64_C(0x0010000000000000)>>j0; + i0 &= (~i); + } + } else { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + INSERT_WORDS64(x,i0); + return x; +} +#ifndef __ceil +libm_alias_double (__ceil, ceil) +#endif diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c new file mode 100644 index 0000000..f7e0a77 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_floor.c @@ -0,0 +1,71 @@ +/* Round double to integer away from zero. + Copyright (C) 2011-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2011. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* Based on a version which carries the following copyright: */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +#include +#include +#include + +/* + * floor(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + */ + + +double +__floor (double x) +{ + int64_t i0; + EXTRACT_WORDS64(i0,x); + int32_t j0 = ((i0>>52)&0x7ff)-0x3ff; + if(__builtin_expect(j0<52, 1)) { + if(j0<0) { + /* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=0;} + else if((i0&0x7fffffffffffffffl)!=0) + { i0=0xbff0000000000000l;} + } else { + uint64_t i = (0x000fffffffffffffl)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(i0<0) i0 += (0x0010000000000000l)>>j0; + i0 &= (~i); + } + INSERT_WORDS64(x,i0); + } else if (j0==0x400) + return x+x; /* inf or NaN */ + return x; +} +#ifndef __floor +libm_alias_double (__floor, floor) +#endif diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c new file mode 100644 index 0000000..a4a0817 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c @@ -0,0 +1,64 @@ +/* Adapted for use as nearbyint by Ulrich Drepper . */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include +#include +#include +#include +#include + +static const double +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +double +__nearbyint(double x) +{ + fenv_t env; + int64_t i0,sx; + int32_t j0; + EXTRACT_WORDS64(i0,x); + sx = (i0>>63)&1; + j0 = ((i0>>52)&0x7ff)-0x3ff; + if(__builtin_expect(j0<52, 1)) { + if(j0<0) { + libc_feholdexcept (&env); + double w = TWO52[sx] + math_opt_barrier (x); + double t = w-TWO52[sx]; + math_force_eval (t); + libc_fesetenv (&env); + return __copysign (t, x); + } + } else { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + libc_feholdexcept (&env); + double w = TWO52[sx] + math_opt_barrier (x); + double t = w-TWO52[sx]; + math_force_eval (t); + libc_fesetenv (&env); + return t; +} +libm_alias_double (__nearbyint, nearbyint) diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c new file mode 100644 index 0000000..622e479 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_rint.c @@ -0,0 +1,57 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include +#include +#include + +static const double +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +double +__rint(double x) +{ + int64_t i0,sx; + int32_t j0; + EXTRACT_WORDS64(i0,x); + sx = (i0>>63)&1; + j0 = ((i0>>52)&0x7ff)-0x3ff; + if(j0<52) { + if(j0<0) { + double w = TWO52[sx]+x; + double t = w-TWO52[sx]; + EXTRACT_WORDS64(i0,t); + INSERT_WORDS64(t,(i0&UINT64_C(0x7fffffffffffffff))|(sx<<63)); + return t; + } + } else { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + double w = TWO52[sx]+x; + return w-TWO52[sx]; +} +#ifndef __rint +libm_alias_double (__rint, rint) +#endif diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c new file mode 100644 index 0000000..3323621 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c @@ -0,0 +1,65 @@ +/* Round double to integer away from zero. + Copyright (C) 1997-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include +#include +#include + + +double +__round (double x) +{ + int64_t i0, j0; + + EXTRACT_WORDS64 (i0, x); + j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; + if (__glibc_likely (j0 < 52)) + { + if (j0 < 0) + { + i0 &= UINT64_C(0x8000000000000000); + if (j0 == -1) + i0 |= UINT64_C(0x3ff0000000000000); + } + else + { + uint64_t i = UINT64_C(0x000fffffffffffff) >> j0; + if ((i0 & i) == 0) + /* X is integral. */ + return x; + + i0 += UINT64_C(0x0008000000000000) >> j0; + i0 &= ~i; + } + } + else + { + if (j0 == 0x400) + /* Inf or NaN. */ + return x + x; + else + return x; + } + + INSERT_WORDS64 (x, i0); + return x; +} +libm_alias_double (__round, round) diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c new file mode 100644 index 0000000..19a09b8 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c @@ -0,0 +1,54 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 1997-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include +#include + + +double +__trunc (double x) +{ + int64_t i0, j0; + int64_t sx; + + EXTRACT_WORDS64 (i0, x); + sx = i0 & UINT64_C(0x8000000000000000); + j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; + if (j0 < 52) + { + if (j0 < 0) + /* The magnitude of the number is < 1 so the result is +-0. */ + INSERT_WORDS64 (x, sx); + else + INSERT_WORDS64 (x, sx | (i0 & ~(UINT64_C(0x000fffffffffffff) >> j0))); + } + else + { + if (j0 == 0x400) + /* x is inf or NaN. */ + return x + x; + } + + return x; +} +#ifndef __trunc +libm_alias_double (__trunc, trunc) +#endif diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h index 077df0e..9dd1560 100644 --- a/sysdeps/ieee754/float128/float128_private.h +++ b/sysdeps/ieee754/float128/float128_private.h @@ -138,21 +138,6 @@ #undef libm_alias_double_ldouble #define libm_alias_double_ldouble(func) libm_alias_float64_float128 (func) -#include -#undef USE_NEARBYINTL_BUILTIN -#define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN -#undef USE_RINTL_BUILTIN -#define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN -#undef USE_FLOORL_BUILTIN -#define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN -#undef USE_CEILL_BUILTIN -#define USE_CEILL_BUILTIN USE_CEILF128_BUILTIN -#undef USE_TRUNCL_BUILTIN -#define USE_TRUNCL_BUILTIN USE_TRUNCF128_BUILTIN -#undef USE_ROUNDL_BUILTIN -#define USE_ROUNDL_BUILTIN USE_ROUNDF128_BUILTIN -#undef USE_COPYSIGNL_BUILTIN -#define USE_COPYSIGNL_BUILTIN USE_COPYSIGNF128_BUILTIN /* IEEE function renames. */ #define __ieee754_acoshl __ieee754_acoshf128 @@ -354,13 +339,6 @@ /* Builtin renames. */ #define __builtin_copysignl __builtin_copysignf128 #define __builtin_signbitl __builtin_signbit -#define __builtin_nearbyintl __builtin_nearbyintf128 -#define __builtin_rintl __builtin_rintf128 -#define __builtin_floorl __builtin_floorf128 -#define __builtin_ceill __builtin_ceilf128 -#define __builtin_truncl __builtin_truncf128 -#define __builtin_roundl __builtin_roundf128 -#define __builtin_copysignl __builtin_copysignf128 /* Get the constant suffix from bits/floatn-compat.h. */ #define L(x) __f128 (x) diff --git a/sysdeps/ieee754/flt-32/s_ceilf.c b/sysdeps/ieee754/flt-32/s_ceilf.c index f60d0ac..f289ec2 100644 --- a/sysdeps/ieee754/flt-32/s_ceilf.c +++ b/sysdeps/ieee754/flt-32/s_ceilf.c @@ -16,50 +16,33 @@ #include #include #include -#include + float -__ceilf (float x) +__ceilf(float x) { -#if USE_CEILF_BUILTIN - return __builtin_ceilf (x); -#else - /* Use generic implementation. */ - int32_t i0, j0; - uint32_t i; + int32_t i0,j0; + uint32_t i; - GET_FLOAT_WORD (i0, x); - j0 = ((i0 >> 23) & 0xff) - 0x7f; - if (j0 < 23) - { - if (j0 < 0) - { - /* return 0 * sign (x) if |x| < 1 */ - if (i0 < 0) - i0 = 0x80000000; - else if (i0 != 0) - i0 = 0x3f800000; - } - else - { - i = (0x007fffff) >> j0; - if ((i0 & i) == 0) - return x; /* x is integral */ - if (i0 > 0) - i0 += (0x00800000) >> j0; - i0 &= (~i); + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + /* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x80000000;} + else if(i0!=0) { i0=0x3f800000;} + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(i0>0) i0 += (0x00800000)>>j0; + i0 &= (~i); + } + } else { + if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ + else return x; /* x is integral */ } - } - else - { - if (__glibc_unlikely (j0 == 0x80)) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - SET_FLOAT_WORD (x, i0); - return x; -#endif /* ! USE_CEILF_BUILTIN */ + SET_FLOAT_WORD(x,i0); + return x; } #ifndef __ceilf libm_alias_float (__ceil, ceil) diff --git a/sysdeps/ieee754/flt-32/s_copysignf.c b/sysdeps/ieee754/flt-32/s_copysignf.c index 0247abd..3c4ac7c 100644 --- a/sysdeps/ieee754/flt-32/s_copysignf.c +++ b/sysdeps/ieee754/flt-32/s_copysignf.c @@ -13,7 +13,7 @@ * ==================================================== */ -#if defined (LIBM_SCCS) && ! defined (lint) +#if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4 1995/05/10 20:46:59 jtc Exp $"; #endif @@ -24,11 +24,15 @@ static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4 1995/05/10 20:46:59 jtc Exp */ #include +#include #include -float -__copysignf (float x, float y) +float __copysignf(float x, float y) { - return __builtin_copysignf (x, y); + uint32_t ix,iy; + GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(iy,y); + SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000)); + return x; } libm_alias_float (__copysign, copysign) diff --git a/sysdeps/ieee754/flt-32/s_floorf.c b/sysdeps/ieee754/flt-32/s_floorf.c index c45816e..12aed34 100644 --- a/sysdeps/ieee754/flt-32/s_floorf.c +++ b/sysdeps/ieee754/flt-32/s_floorf.c @@ -23,49 +23,32 @@ #include #include #include -#include float -__floorf (float x) +__floorf(float x) { -#if USE_FLOORF_BUILTIN - return __builtin_floorf (x); -#else - /* Use generic implementation. */ - int32_t i0, j0; - uint32_t i; - GET_FLOAT_WORD (i0, x); - j0 = ((i0 >> 23) & 0xff) - 0x7f; - if (j0 < 23) - { - if (j0 < 0) - { - /* return 0 * sign (x) if |x| < 1 */ - if (i0 >= 0) - i0 = 0; - else if ((i0 & 0x7fffffff) != 0) - i0 = 0xbf800000; + int32_t i0,j0; + uint32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + /* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=0;} + else if((i0&0x7fffffff)!=0) + { i0=0xbf800000;} + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(i0<0) i0 += (0x00800000)>>j0; + i0 &= (~i); + } + } else { + if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ + else return x; /* x is integral */ } - else - { - i = (0x007fffff) >> j0; - if ((i0 & i) == 0) - return x; /* x is integral */ - if (i0 < 0) - i0 += (0x00800000) >> j0; - i0 &= (~i); - } - } - else - { - if (__glibc_unlikely (j0 == 0x80)) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - SET_FLOAT_WORD (x, i0); - return x; -#endif /* ! USE_FLOORF_BUILTIN */ + SET_FLOAT_WORD(x,i0); + return x; } #ifndef __floorf libm_alias_float (__floor, floor) diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c index 5969e3e..4dfe491 100644 --- a/sysdeps/ieee754/flt-32/s_nearbyintf.c +++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c @@ -20,53 +20,42 @@ #include #include #include -#include + +static const float +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; float -__nearbyintf (float x) +__nearbyintf(float x) { -#if USE_NEARBYINTF_BUILTIN - return __builtin_nearbyintf (x); -#else - /* Use generic implementation. */ - static const float - TWO23[2] = { - 8.3886080000e+06, /* 0x4b000000 */ - -8.3886080000e+06, /* 0xcb000000 */ - }; - fenv_t env; - int32_t i0, j0, sx; - float w, t; - GET_FLOAT_WORD (i0, x); - sx = (i0 >> 31) & 1; - j0 = ((i0 >> 23) & 0xff) - 0x7f; - if (j0 < 23) - { - if (j0 < 0) - { - libc_feholdexceptf (&env); - w = TWO23[sx] + math_opt_barrier (x); - t = w - TWO23[sx]; - math_force_eval (t); - libc_fesetenvf (&env); - GET_FLOAT_WORD (i0, t); - SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); - return t; + fenv_t env; + int32_t i0,j0,sx; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + libc_feholdexceptf (&env); + w = TWO23[sx] + math_opt_barrier (x); + t = w-TWO23[sx]; + math_force_eval (t); + libc_fesetenvf (&env); + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } + } else { + if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ + else return x; /* x is integral */ } - } - else - { - if (__glibc_unlikely (j0 == 0x80)) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - libc_feholdexceptf (&env); - w = TWO23[sx] + math_opt_barrier (x); - t = w - TWO23[sx]; - math_force_eval (t); - libc_fesetenvf (&env); - return t; -#endif /* ! USE_NEARBYINT_BUILTIN */ + libc_feholdexceptf (&env); + w = TWO23[sx] + math_opt_barrier (x); + t = w-TWO23[sx]; + math_force_eval (t); + libc_fesetenvf (&env); + return t; } libm_alias_float (__nearbyint, nearbyint) diff --git a/sysdeps/ieee754/flt-32/s_rintf.c b/sysdeps/ieee754/flt-32/s_rintf.c index 3463a04..db6f260 100644 --- a/sysdeps/ieee754/flt-32/s_rintf.c +++ b/sysdeps/ieee754/flt-32/s_rintf.c @@ -16,46 +16,35 @@ #include #include #include -#include + +static const float +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; float -__rintf (float x) +__rintf(float x) { -#if USE_RINTF_BUILTIN - return __builtin_rintf (x); -#else - /* Use generic implementation. */ - static const float - TWO23[2] = { - 8.3886080000e+06, /* 0x4b000000 */ - -8.3886080000e+06, /* 0xcb000000 */ - }; - int32_t i0, j0, sx; - float w, t; - GET_FLOAT_WORD (i0, x); - sx = (i0 >> 31) & 1; - j0 = ((i0 >> 23) & 0xff) - 0x7f; - if (j0 < 23) - { - if(j0 < 0) - { - w = TWO23[sx] + x; - t = w - TWO23[sx]; - GET_FLOAT_WORD (i0, t); - SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); - return t; + int32_t i0,j0,sx; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + w = TWO23[sx]+x; + t = w-TWO23[sx]; + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ } - } - else - { - if (j0 == 0x80) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - w = TWO23[sx] + x; - return w - TWO23[sx]; -#endif /* ! USE_RINTF_BUILTIN */ + w = TWO23[sx]+x; + return w-TWO23[sx]; } #ifndef __rintf libm_alias_float (__rint, rint) diff --git a/sysdeps/ieee754/flt-32/s_roundf.c b/sysdeps/ieee754/flt-32/s_roundf.c index 6fdfbbb..7c95125 100644 --- a/sysdeps/ieee754/flt-32/s_roundf.c +++ b/sysdeps/ieee754/flt-32/s_roundf.c @@ -21,16 +21,11 @@ #include #include -#include float __roundf (float x) { -#if USE_ROUNDF_BUILTIN - return __builtin_roundf (x); -#else - /* Use generic implementation. */ int32_t i0, j0; GET_FLOAT_WORD (i0, x); @@ -65,6 +60,5 @@ __roundf (float x) SET_FLOAT_WORD (x, i0); return x; -#endif /* ! USE_ROUNDF_BUILTIN */ } libm_alias_float (__round, round) diff --git a/sysdeps/ieee754/flt-32/s_truncf.c b/sysdeps/ieee754/flt-32/s_truncf.c index 71491e5..2e1464a 100644 --- a/sysdeps/ieee754/flt-32/s_truncf.c +++ b/sysdeps/ieee754/flt-32/s_truncf.c @@ -21,16 +21,11 @@ #include #include -#include float __truncf (float x) { -#if USE_TRUNCF_BUILTIN - return __builtin_truncf (x); -#else - /* Use generic implementation. */ int32_t i0, j0; int sx; @@ -53,7 +48,6 @@ __truncf (float x) } return x; -#endif /* ! USE_TRUNCF_BUILTIN */ } #ifndef __truncf libm_alias_float (__trunc, trunc) diff --git a/sysdeps/ieee754/ldbl-128/s_ceill.c b/sysdeps/ieee754/ldbl-128/s_ceill.c index df75dc3..e6aba5f 100644 --- a/sysdeps/ieee754/ldbl-128/s_ceill.c +++ b/sysdeps/ieee754/ldbl-128/s_ceill.c @@ -13,7 +13,7 @@ * ==================================================== */ -#if defined (LIBM_SCCS) && ! defined (lint) +#if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: $"; #endif @@ -27,74 +27,41 @@ static char rcsid[] = "$NetBSD: $"; #include #include #include -#include -_Float128 -__ceill (_Float128 x) +_Float128 __ceill(_Float128 x) { -#if USE_CEILL_BUILTIN - return __builtin_ceill (x); -#else - /* Use generic implementation. */ - int64_t i0, i1, j0; - uint64_t i, j; - GET_LDOUBLE_WORDS64 (i0, i1, x); - j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; - if (j0 < 48) - { - if (j0 < 0) - { - /* return 0 * sign (x) if |x| < 1 */ - if (i0 < 0) - { - i0 = 0x8000000000000000ULL; - i1 = 0; + int64_t i0,i1,j0; + uint64_t i,j; + GET_LDOUBLE_WORDS64(i0,i1,x); + j0 = ((i0>>48)&0x7fff)-0x3fff; + if(j0<48) { + if(j0<0) { + /* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x8000000000000000ULL;i1=0;} + else if((i0|i1)!=0) { i0=0x3fff000000000000ULL;i1=0;} + } else { + i = (0x0000ffffffffffffULL)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(i0>0) i0 += (0x0001000000000000LL)>>j0; + i0 &= (~i); i1=0; } - else if ((i0 | i1) != 0) - { - i0 = 0x3fff000000000000ULL; - i1 = 0; + } else if (j0>111) { + if(j0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = -1ULL>>(j0-48); + if((i1&i)==0) return x; /* x is integral */ + if(i0>0) { + if(j0==48) i0+=1; + else { + j = i1+(1LL<<(112-j0)); + if(j> j0; - if (((i0 & i) | i1) == 0) - return x; /* x is integral */ - if (i0 > 0) - i0 += (0x0001000000000000LL) >> j0; - i0 &= (~i); - i1 = 0; - } - } - else if (j0 > 111) - { - if (j0 == 0x4000) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - else - { - i = -1ULL >> (j0 - 48); - if ((i1 & i) == 0) - return x; /* x is integral */ - if (i0 > 0) - { - if (j0 == 48) - i0 += 1; - else - { - j = i1 + (1LL << (112 - j0)); - if (j < i1) - i0 += 1; /* got a carry */ - i1 = j; - } - } - i1 &= (~i); - } - SET_LDOUBLE_WORDS64 (x, i0, i1); - return x; -#endif /* ! USE_CEILL_BUILTIN */ + SET_LDOUBLE_WORDS64(x,i0,i1); + return x; } libm_alias_ldouble (__ceil, ceil) diff --git a/sysdeps/ieee754/ldbl-128/s_copysignl.c b/sysdeps/ieee754/ldbl-128/s_copysignl.c index 9b0e44c..d23e0f7 100644 --- a/sysdeps/ieee754/ldbl-128/s_copysignl.c +++ b/sysdeps/ieee754/ldbl-128/s_copysignl.c @@ -13,7 +13,7 @@ * ==================================================== */ -#if defined (LIBM_SCCS) && ! defined (lint) +#if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: $"; #endif @@ -26,21 +26,14 @@ static char rcsid[] = "$NetBSD: $"; #include #include #include -#include -_Float128 -__copysignl (_Float128 x, _Float128 y) +_Float128 __copysignl(_Float128 x, _Float128 y) { -#if USE_COPYSIGNL_BUILTIN - return __builtin_copysignl (x, y); -#else - /* Use generic implementation. */ - uint64_t hx, hy; - GET_LDOUBLE_MSW64 (hx, x); - GET_LDOUBLE_MSW64 (hy, y); - SET_LDOUBLE_MSW64 (x, (hx & 0x7fffffffffffffffULL) - | (hy & 0x8000000000000000ULL)); - return x; -#endif /* ! USE_COPYSIGNL_BUILTIN */ + uint64_t hx,hy; + GET_LDOUBLE_MSW64(hx,x); + GET_LDOUBLE_MSW64(hy,y); + SET_LDOUBLE_MSW64(x,(hx&0x7fffffffffffffffULL) + |(hy&0x8000000000000000ULL)); + return x; } libm_alias_ldouble (__copysign, copysign) diff --git a/sysdeps/ieee754/ldbl-128/s_floorl.c b/sysdeps/ieee754/ldbl-128/s_floorl.c index 4fc1099..f9c5e01 100644 --- a/sysdeps/ieee754/ldbl-128/s_floorl.c +++ b/sysdeps/ieee754/ldbl-128/s_floorl.c @@ -27,73 +27,42 @@ static char rcsid[] = "$NetBSD: $"; #include #include #include -#include -_Float128 -__floorl (_Float128 x) +_Float128 __floorl(_Float128 x) { -#if USE_FLOORL_BUILTIN - return __builtin_floorl (x); -#else - /* Use generic implementation. */ - int64_t i0, i1, j0; - uint64_t i, j; - GET_LDOUBLE_WORDS64 (i0, i1, x); - j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; - if (j0 < 48) - { - if (j0 < 0) - { - /* return 0 * sign (x) if |x| < 1 */ - if (i0 >= 0) - { - i0 = i1 = 0; + int64_t i0,i1,j0; + uint64_t i,j; + GET_LDOUBLE_WORDS64(i0,i1,x); + j0 = ((i0>>48)&0x7fff)-0x3fff; + if(j0<48) { + if(j0<0) { + /* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=i1=0;} + else if(((i0&0x7fffffffffffffffLL)|i1)!=0) + { i0=0xbfff000000000000ULL;i1=0;} + } else { + i = (0x0000ffffffffffffULL)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(i0<0) i0 += (0x0001000000000000LL)>>j0; + i0 &= (~i); i1=0; } - else if (((i0 & 0x7fffffffffffffffLL) | i1) != 0) - { - i0 = 0xbfff000000000000ULL; - i1 = 0; + } else if (j0>111) { + if(j0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = -1ULL>>(j0-48); + if((i1&i)==0) return x; /* x is integral */ + if(i0<0) { + if(j0==48) i0+=1; + else { + j = i1+(1LL<<(112-j0)); + if(j> j0; - if (((i0 & i) | i1) == 0) - return x; /* x is integral */ - if (i0 < 0) - i0 += (0x0001000000000000LL) >> j0; - i0 &= (~i); - i1 = 0; - } - } - else if (j0 > 111) - { - if (j0 == 0x4000) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - else - { - i = -1ULL >> (j0 - 48); - if ((i1 & i) == 0) - return x; /* x is integral */ - if (i0 < 0) - { - if (j0 == 48) - i0 += 1; - else - { - j = i1 + (1LL << (112 - j0)); - if (j < i1) - i0 += 1 ; /* got a carry */ - i1 = j; - } - } - i1 &= (~i); - } - SET_LDOUBLE_WORDS64 (x, i0, i1); - return x; -#endif /* ! USE_FLOORL_BUILTIN */ + SET_LDOUBLE_WORDS64(x,i0,i1); + return x; } libm_alias_ldouble (__floor, floor) diff --git a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c index 8d26786..f044cb4 100644 --- a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c +++ b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c @@ -28,54 +28,42 @@ #include #include #include -#include -_Float128 -__nearbyintl (_Float128 x) +static const _Float128 +TWO112[2]={ + L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */ + L(-5.19229685853482762853049632922009600E+33) /* 0xC06F000000000000, 0 */ +}; + +_Float128 __nearbyintl(_Float128 x) { -#if USE_NEARBYINTL_BUILTIN - return __builtin_nearbyintl (x); -#else - /* Use generic implementation. */ - static const _Float128 - TWO112[2] = { - L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */ - L(-5.19229685853482762853049632922009600E+33) /* 0xC06F000000000000, 0 */ - }; - fenv_t env; - int64_t i0, j0, sx; - uint64_t i1 __attribute__ ((unused)); - _Float128 w, t; - GET_LDOUBLE_WORDS64 (i0, i1, x); - sx = (((uint64_t) i0) >> 63); - j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; - if (j0 < 112) - { - if (j0 < 0) - { - feholdexcept (&env); - w = TWO112[sx] + math_opt_barrier (x); - t = w - TWO112[sx]; - math_force_eval (t); - fesetenv (&env); - GET_LDOUBLE_MSW64 (i0, t); - SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63)); - return t; + fenv_t env; + int64_t i0,j0,sx; + uint64_t i1 __attribute__ ((unused)); + _Float128 w,t; + GET_LDOUBLE_WORDS64(i0,i1,x); + sx = (((uint64_t)i0)>>63); + j0 = ((i0>>48)&0x7fff)-0x3fff; + if(j0<112) { + if(j0<0) { + feholdexcept (&env); + w = TWO112[sx] + math_opt_barrier (x); + t = w-TWO112[sx]; + math_force_eval (t); + fesetenv (&env); + GET_LDOUBLE_MSW64(i0,t); + SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63)); + return t; + } + } else { + if(j0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ } - } - else - { - if (j0 == 0x4000) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - feholdexcept (&env); - w = TWO112[sx] + math_opt_barrier (x); - t = w - TWO112[sx]; - math_force_eval (t); - fesetenv (&env); - return t; -#endif /* ! USE_NEARBYINTL_BUILTIN */ + feholdexcept (&env); + w = TWO112[sx] + math_opt_barrier (x); + t = w-TWO112[sx]; + math_force_eval (t); + fesetenv (&env); + return t; } libm_alias_ldouble (__nearbyint, nearbyint) diff --git a/sysdeps/ieee754/ldbl-128/s_rintl.c b/sysdeps/ieee754/ldbl-128/s_rintl.c index 260f3aa..9e6637a 100644 --- a/sysdeps/ieee754/ldbl-128/s_rintl.c +++ b/sysdeps/ieee754/ldbl-128/s_rintl.c @@ -13,7 +13,7 @@ * ==================================================== */ -#if defined (LIBM_SCCS) && ! defined (lint) +#if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: $"; #endif @@ -30,46 +30,34 @@ static char rcsid[] = "$NetBSD: $"; #include #include #include -#include -_Float128 -__rintl (_Float128 x) +static const _Float128 +TWO112[2]={ + 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */ + -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */ +}; + +_Float128 __rintl(_Float128 x) { -#if USE_RINTL_BUILTIN - return __builtin_rintl (x); -#else - /* Use generic implementation. */ - static const _Float128 - TWO112[2] = { - 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */ - -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */ - }; - int64_t i0, j0, sx; - uint64_t i1 __attribute__ ((unused)); - _Float128 w, t; - GET_LDOUBLE_WORDS64 (i0, i1, x); - sx = (((uint64_t) i0) >> 63); - j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; - if (j0 < 112) - { - if (j0 < 0) - { - w = TWO112[sx] + x; - t = w - TWO112[sx]; - GET_LDOUBLE_MSW64 (i0, t); - SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63)); - return t; + int64_t i0,j0,sx; + uint64_t i1 __attribute__ ((unused)); + _Float128 w,t; + GET_LDOUBLE_WORDS64(i0,i1,x); + sx = (((uint64_t)i0)>>63); + j0 = ((i0>>48)&0x7fff)-0x3fff; + if(j0<112) { + if(j0<0) { + w = TWO112[sx]+x; + t = w-TWO112[sx]; + GET_LDOUBLE_MSW64(i0,t); + SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63)); + return t; + } + } else { + if(j0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ } - } - else - { - if (j0 == 0x4000) - return x + x; /* inf or NaN */ - else - return x; /* x is integral */ - } - w = TWO112[sx] + x; - return w - TWO112[sx]; -#endif /* ! USE_RINTL_BUILTIN */ + w = TWO112[sx]+x; + return w-TWO112[sx]; } libm_alias_ldouble (__rint, rint) diff --git a/sysdeps/ieee754/ldbl-128/s_roundl.c b/sysdeps/ieee754/ldbl-128/s_roundl.c index 564f8ac..22789ce 100644 --- a/sysdeps/ieee754/ldbl-128/s_roundl.c +++ b/sysdeps/ieee754/ldbl-128/s_roundl.c @@ -22,16 +22,11 @@ #include #include -#include _Float128 __roundl (_Float128 x) { -#if USE_ROUNDL_BUILTIN - return __builtin_roundl (x); -#else - /* Use generic implementation. */ int32_t j0; uint64_t i1, i0; @@ -82,6 +77,5 @@ __roundl (_Float128 x) SET_LDOUBLE_WORDS64 (x, i0, i1); return x; -#endif /* ! USE_ROUNDL_BUILTIN */ } libm_alias_ldouble (__round, round) diff --git a/sysdeps/ieee754/ldbl-128/s_truncl.c b/sysdeps/ieee754/ldbl-128/s_truncl.c index aa49daa..f858ede 100644 --- a/sysdeps/ieee754/ldbl-128/s_truncl.c +++ b/sysdeps/ieee754/ldbl-128/s_truncl.c @@ -22,16 +22,11 @@ #include #include -#include _Float128 __truncl (_Float128 x) { -#if USE_TRUNCL_BUILTIN - return __builtin_truncl (x); -#else - /* Use generic implementation. */ int32_t j0; uint64_t i0, i1, sx; @@ -58,6 +53,5 @@ __truncl (_Float128 x) } return x; -#endif /* ! USE_TRUNCL_BUILTIN */ } libm_alias_ldouble (__trunc, trunc) diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile index daa2753..790f670 100644 --- a/sysdeps/ieee754/ldbl-96/Makefile +++ b/sysdeps/ieee754/ldbl-96/Makefile @@ -17,8 +17,5 @@ # . ifeq ($(subdir),math) -tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo -ifeq ($(have-ssp),yes) -CFLAGS-test-sinl-pseudo.c += -fstack-protector-all +tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 endif -endif # $(subdir) == math diff --git a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c index f6f1831..f67805f 100644 --- a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c +++ b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c @@ -209,18 +209,6 @@ __ieee754_rem_pio2l (long double x, long double *y) y[1] = y[0]; return 0; } - - if ((i0 & 0x80000000) == 0) - { - /* Pseudo-zero and unnormal representations are not valid - representations of long double. We need to avoid stack - corruption in __kernel_rem_pio2, which expects input in a - particular normal form, but those representations do not need - to be consistently handled like any particular floating-point - value. */ - y[1] = y[0] = __builtin_nanl (""); - return 0; - } /* Split the 64 bits of the mantissa into three 24-bit integers stored in a double array. */ diff --git a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c deleted file mode 100644 index b67cedb..0000000 --- a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Test sinl for pseudo-zeros and unnormals for ldbl-96 (bug 25487). - Copyright (C) 2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -static int -do_test (void) -{ - for (int i = 0; i < 64; i++) - { - uint64_t sig = i == 63 ? 0 : 1ULL << i; - long double ld; - SET_LDOUBLE_WORDS (ld, 0x4141, - sig >> 32, sig & 0xffffffffULL); - /* The requirement is that no stack overflow occurs when the - pseudo-zero or unnormal goes through range reduction. */ - volatile long double ldr; - ldr = sinl (ld); - (void) ldr; - } - return 0; -} - -#include diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 7bd1d70..b72913d 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -62,6 +62,10 @@ int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion void *__libc_stack_end = NULL; rtld_hidden_data_def(__libc_stack_end) +#if HP_TIMING_AVAIL +hp_timing_t _dl_cpuclock_offset; +#endif + /* TODO: Initialize. */ void *_dl_random attribute_relro = NULL; @@ -242,6 +246,10 @@ unfmh(); /* XXX */ /* Initialize frequently used global variable. */ GLRO(dl_pagesize) = __getpagesize (); +#if HP_TIMING_AVAIL + HP_TIMING_NOW (_dl_cpuclock_offset); +#endif + fmh(); /* XXX */ /* See hurd/hurdstartup.c; this deals with getting information diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index f89ef9a..e3fc051 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -711,11 +711,6 @@ GLIBC_2.2.6 clntudp_bufcreate F GLIBC_2.2.6 clntudp_create F GLIBC_2.2.6 clntunix_create F GLIBC_2.2.6 clock F -GLIBC_2.2.6 clock_getcpuclockid F -GLIBC_2.2.6 clock_getres F -GLIBC_2.2.6 clock_gettime F -GLIBC_2.2.6 clock_nanosleep F -GLIBC_2.2.6 clock_settime F GLIBC_2.2.6 close F GLIBC_2.2.6 closedir F GLIBC_2.2.6 closelog F diff --git a/sysdeps/mach/hurd/i386/librt.abilist b/sysdeps/mach/hurd/i386/librt.abilist index 3726e41..d5fe32b 100644 --- a/sysdeps/mach/hurd/i386/librt.abilist +++ b/sysdeps/mach/hurd/i386/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.2.6 aio_suspend F GLIBC_2.2.6 aio_suspend64 F GLIBC_2.2.6 aio_write F GLIBC_2.2.6 aio_write64 F +GLIBC_2.2.6 clock_getcpuclockid F +GLIBC_2.2.6 clock_getres F +GLIBC_2.2.6 clock_gettime F +GLIBC_2.2.6 clock_nanosleep F +GLIBC_2.2.6 clock_settime F GLIBC_2.2.6 lio_listio F GLIBC_2.2.6 lio_listio64 F GLIBC_2.2.6 shm_open F diff --git a/sysdeps/mach/hurd/res_enable_icmp.c b/sysdeps/mach/hurd/res_enable_icmp.c deleted file mode 100644 index 4b04563..0000000 --- a/sysdeps/mach/hurd/res_enable_icmp.c +++ /dev/null @@ -1,27 +0,0 @@ -/* 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/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h index 05c94e7..1e2092a 100644 --- a/sysdeps/nptl/bits/thread-shared-types.h +++ b/sysdeps/nptl/bits/thread-shared-types.h @@ -124,27 +124,7 @@ struct __pthread_mutex_s unsigned int __nusers; #endif /* KIND must stay at this position in the structure to maintain - binary compatibility with static initializers. - - Concurrency notes: - The __kind of a mutex is initialized either by the static - PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init. - - After a mutex has been initialized, the __kind of a mutex is usually not - changed. BUT it can be set to -1 in pthread_mutex_destroy or elision can - be enabled. This is done concurrently in the pthread_mutex_*lock functions - by using the macro FORCE_ELISION. This macro is only defined for - architectures which supports lock elision. - - For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and - PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set - type of a mutex. - Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set - with pthread_mutexattr_settype. - After a mutex has been initialized, the functions pthread_mutex_*lock can - enable elision - if the mutex-type and the machine supports it - by setting - the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards - the lock / unlock functions are using specific elision code-paths. */ + binary compatibility with static initializers. */ int __kind; __PTHREAD_COMPAT_PADDING_MID #if __PTHREAD_MUTEX_NUSERS_AFTER_KIND diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c index 37db30f..ec56a82 100644 --- a/sysdeps/nptl/fork.c +++ b/sysdeps/nptl/fork.c @@ -55,7 +55,7 @@ __libc_fork (void) but our current fork implementation is not. */ bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads); - __run_fork_handlers (atfork_run_prepare, multiple_threads); + __run_fork_handlers (atfork_run_prepare); /* If we are not running multiple threads, we do not have to preserve lock state. If fork runs from a signal handler, only @@ -83,6 +83,14 @@ __libc_fork (void) if (__fork_generation_pointer != NULL) *__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR; +#if HP_TIMING_AVAIL + /* The CPU clock of the thread and process have to be set to zero. */ + hp_timing_t now; + HP_TIMING_NOW (now); + THREAD_SETMEM (self, cpuclock_offset, now); + GL(dl_cpuclock_offset) = now; +#endif + #ifdef __NR_set_robust_list /* Initialize the robust mutex list setting in the kernel which has been reset during the fork. We do not check for errors because if @@ -126,7 +134,7 @@ __libc_fork (void) __rtld_lock_initialize (GL(dl_load_lock)); /* Run the handlers registered for the child. */ - __run_fork_handlers (atfork_run_child, multiple_threads); + __run_fork_handlers (atfork_run_child); } else { @@ -141,7 +149,7 @@ __libc_fork (void) } /* Run the handlers registered for the parent. */ - __run_fork_handlers (atfork_run_parent, multiple_threads); + __run_fork_handlers (atfork_run_parent); } return pid; diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h index bef2b7a..6eab61c 100644 --- a/sysdeps/nptl/fork.h +++ b/sysdeps/nptl/fork.h @@ -52,11 +52,9 @@ enum __run_fork_handler_type - atfork_run_child: run all the CHILD_HANDLER and unlocks the internal lock. - atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal - lock. - - Perform locking only if DO_LOCKING. */ -extern void __run_fork_handlers (enum __run_fork_handler_type who, - _Bool do_locking) attribute_hidden; + lock. */ +extern void __run_fork_handlers (enum __run_fork_handler_type who) + attribute_hidden; /* C library side function to register new fork handlers. */ extern int __register_atfork (void (*__prepare) (void), diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h index 6fd27f0..1a56247 100644 --- a/sysdeps/nptl/futex-internal.h +++ b/sysdeps/nptl/futex-internal.h @@ -197,7 +197,7 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private); static __always_inline __attribute__ ((__noreturn__)) void futex_fatal_error (void) { - __libc_fatal ("The futex facility returned an unexpected error code.\n"); + __libc_fatal ("The futex facility returned an unexpected error code."); } #endif /* futex-internal.h */ diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c index 7408197..e7924e0 100644 --- a/sysdeps/posix/clock_getres.c +++ b/sysdeps/posix/clock_getres.c @@ -22,7 +22,38 @@ #include #include #include -#include + + +#if HP_TIMING_AVAIL +static long int nsec; /* Clock frequency of the processor. */ + +static int +hp_timing_getres (struct timespec *res) +{ + if (__glibc_unlikely (nsec == 0)) + { + hp_timing_t freq; + + /* This can only happen if we haven't initialized the `nsec' + variable yet. Do this now. We don't have to protect this + code against multiple execution since all of them should + lead to the same result. */ + freq = __get_clockfreq (); + if (__glibc_unlikely (freq == 0)) + /* Something went wrong. */ + return -1; + + nsec = MAX (UINT64_C (1000000000) / freq, 1); + } + + /* Fill in the values. + The seconds are always zero (unless we have a 1Hz machine). */ + res->tv_sec = 0; + res->tv_nsec = nsec; + + return 0; +} +#endif static inline int realtime_getres (struct timespec *res) @@ -51,22 +82,37 @@ __clock_getres (clockid_t clock_id, struct timespec *res) switch (clock_id) { +#ifdef SYSDEP_GETRES + SYSDEP_GETRES; +#endif + +#ifndef HANDLED_REALTIME case CLOCK_REALTIME: retval = realtime_getres (res); break; +#endif /* handled REALTIME */ default: - __set_errno (EINVAL); +#ifdef SYSDEP_GETRES_CPU + SYSDEP_GETRES_CPU; +#endif +#if HP_TIMING_AVAIL + if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) + == CLOCK_THREAD_CPUTIME_ID) + retval = hp_timing_getres (res); + else +#endif + __set_errno (EINVAL); break; + +#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME + case CLOCK_PROCESS_CPUTIME_ID: + case CLOCK_THREAD_CPUTIME_ID: + retval = hp_timing_getres (res); + break; +#endif } return retval; } - -versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17); -/* clock_getres moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_getres, __clock_getres_2); -compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2); -#endif +weak_alias (__clock_getres, clock_getres) diff --git a/sysdeps/posix/dl-fileid.h b/sysdeps/posix/dl-fileid.h index b60fc50..26bef2f 100644 --- a/sysdeps/posix/dl-fileid.h +++ b/sysdeps/posix/dl-fileid.h @@ -27,16 +27,18 @@ struct r_file_id ino64_t ino; }; -/* Sample FD to fill in *ID and *ST. Returns true on success. +/* Sample FD to fill in *ID. Returns true on success. On error, returns false, with errno set. */ static inline bool -_dl_get_file_id (int fd, struct r_file_id *id, struct stat64 *st) +_dl_get_file_id (int fd, struct r_file_id *id) { - if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, st) < 0)) + struct stat64 st; + + if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, &st) < 0)) return false; - id->dev = st->st_dev; - id->ino = st->st_ino; + id->dev = st.st_dev; + id->ino = st.st_ino; return true; } diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index fae3dea..553833d 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -292,7 +292,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, canonbuf = __strdup (localcanon); \ if (canonbuf == NULL) \ { \ - __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ goto free_and_return; \ } \ @@ -489,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service, malloc_name = true; } - if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0) + if (__inet_aton (name, (struct in_addr *) at->addr) != 0) { if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) at->family = AF_INET; @@ -738,9 +737,9 @@ gaih_inet (const char *name, const struct gaih_service *service, #endif if (__nss_hosts_database == NULL) - no_more = __nss_database_lookup2 ("hosts", NULL, - "dns [!UNAVAIL=return] files", - &__nss_hosts_database); + no_more = __nss_database_lookup ("hosts", NULL, + "dns [!UNAVAIL=return] files", + &__nss_hosts_database); else no_more = 0; nip = __nss_hosts_database; diff --git a/sysdeps/powerpc/bits/fenvinline.h b/sysdeps/powerpc/bits/fenvinline.h index caec8ea..4131638 100644 --- a/sysdeps/powerpc/bits/fenvinline.h +++ b/sysdeps/powerpc/bits/fenvinline.h @@ -18,36 +18,13 @@ #if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_FPRS__ -/* Inline definitions for fegetround. */ -# define __fegetround_ISA300() \ - (__extension__ ({ \ - union { double __d; unsigned long long __ll; } __u; \ - __asm__ __volatile__ ( \ - ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ - : "=f" (__u.__d)); \ - __u.__ll & 0x0000000000000003LL; \ - })) - -# define __fegetround_ISA2() \ - (__extension__ ({ \ - int __fegetround_result; \ - __asm__ __volatile__ ("mcrfs 7,7 ; mfcr %0" \ - : "=r"(__fegetround_result) : : "cr7"); \ - __fegetround_result & 3; \ - })) - -# ifdef _ARCH_PWR9 -# define __fegetround() __fegetround_ISA300() -# elif defined __BUILTIN_CPU_SUPPORTS__ -# define __fegetround() \ - (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ - ? __fegetround_ISA300() \ - : __fegetround_ISA2() \ - ) -# else -# define __fegetround() __fegetround_ISA2() -# endif - +/* Inline definition for fegetround. */ +# define __fegetround() \ + (__extension__ ({ int __fegetround_result; \ + __asm__ __volatile__ \ + ("mcrfs 7,7 ; mfcr %0" \ + : "=r"(__fegetround_result) : : "cr7"); \ + __fegetround_result & 3; })) # define fegetround() __fegetround () # ifndef __NO_MATH_INLINES diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c index efa9c42..2daed44 100644 --- a/sysdeps/powerpc/fpu/fedisblxcpt.c +++ b/sysdeps/powerpc/fpu/fedisblxcpt.c @@ -26,24 +26,32 @@ fedisableexcept (int excepts) int result, new; /* Get current exception mask to return. */ - fe.fenv = curr.fenv = fegetenv_control (); + fe.fenv = curr.fenv = fegetenv_register (); result = fenv_reg_to_exceptions (fe.l); if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; - new = fenv_exceptions_to_reg (excepts); - - if (fenv_reg_to_exceptions (new) != excepts) - return -1; - /* Sets the new exception mask. */ - fe.l &= ~new; + if (excepts & FE_INEXACT) + fe.l &= ~(1 << (31 - FPSCR_XE)); + if (excepts & FE_DIVBYZERO) + fe.l &= ~(1 << (31 - FPSCR_ZE)); + if (excepts & FE_UNDERFLOW) + fe.l &= ~(1 << (31 - FPSCR_UE)); + if (excepts & FE_OVERFLOW) + fe.l &= ~(1 << (31 - FPSCR_OE)); + if (excepts & FE_INVALID) + fe.l &= ~(1 << (31 - FPSCR_VE)); if (fe.l != curr.l) - fesetenv_control (fe.fenv); + fesetenv_register (fe.fenv); - __TEST_AND_ENTER_NON_STOP (-1ULL, fe.l); + new = __fegetexcept (); + if (new == 0 && result != 0) + (void)__fe_mask_env (); + if ((new & excepts) != 0) + result = -1; return result; } diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c index dfcc6fb..19cfe28 100644 --- a/sysdeps/powerpc/fpu/feenablxcpt.c +++ b/sysdeps/powerpc/fpu/feenablxcpt.c @@ -26,24 +26,33 @@ feenableexcept (int excepts) int result, new; /* Get current exception mask to return. */ - fe.fenv = curr.fenv = fegetenv_control (); + fe.fenv = curr.fenv = fegetenv_register (); result = fenv_reg_to_exceptions (fe.l); if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; - new = fenv_exceptions_to_reg (excepts); - - if (fenv_reg_to_exceptions (new) != excepts) - return -1; - /* Sets the new exception mask. */ - fe.l |= new; + if (excepts & FE_INEXACT) + fe.l |= (1 << (31 - FPSCR_XE)); + if (excepts & FE_DIVBYZERO) + fe.l |= (1 << (31 - FPSCR_ZE)); + if (excepts & FE_UNDERFLOW) + fe.l |= (1 << (31 - FPSCR_UE)); + if (excepts & FE_OVERFLOW) + fe.l |= (1 << (31 - FPSCR_OE)); + if (excepts & FE_INVALID) + fe.l |= (1 << (31 - FPSCR_VE)); if (fe.l != curr.l) - fesetenv_control (fe.fenv); + fesetenv_register (fe.fenv); + + new = __fegetexcept (); + if (new != 0 && result == 0) + (void) __fe_nomask_env_priv (); - __TEST_AND_EXIT_NON_STOP (0ULL, fe.l); + if ((new & excepts) != excepts) + result = -1; return result; } diff --git a/sysdeps/powerpc/fpu/fegetexcept.c b/sysdeps/powerpc/fpu/fegetexcept.c index 6bbf11d..a053a32 100644 --- a/sysdeps/powerpc/fpu/fegetexcept.c +++ b/sysdeps/powerpc/fpu/fegetexcept.c @@ -25,7 +25,7 @@ __fegetexcept (void) fenv_union_t fe; int result = 0; - fe.fenv = fegetenv_control (); + fe.fenv = fegetenv_register (); if (fe.l & (1 << (31 - FPSCR_XE))) result |= FE_INEXACT; diff --git a/sysdeps/powerpc/fpu/fegetmode.c b/sysdeps/powerpc/fpu/fegetmode.c index 57d6d52..b83dc9f 100644 --- a/sysdeps/powerpc/fpu/fegetmode.c +++ b/sysdeps/powerpc/fpu/fegetmode.c @@ -21,6 +21,6 @@ int fegetmode (femode_t *modep) { - *modep = fegetenv_control (); + *modep = fegetenv_register (); return 0; } diff --git a/sysdeps/powerpc/fpu/feholdexcpt.c b/sysdeps/powerpc/fpu/feholdexcpt.c index 9636eca..8ec3fbf 100644 --- a/sysdeps/powerpc/fpu/feholdexcpt.c +++ b/sysdeps/powerpc/fpu/feholdexcpt.c @@ -18,6 +18,7 @@ #include #include +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) int __feholdexcept (fenv_t *envp) @@ -34,7 +35,11 @@ __feholdexcept (fenv_t *envp) if (new.l == old.l) return 0; - __TEST_AND_ENTER_NON_STOP (old.l, 0ULL); + /* If the old env had any enabled exceptions, then mask SIGFPE in the + MSR FE0/FE1 bits. This may allow the FPU to run faster because it + always takes the default action and can not generate SIGFPE. */ + if ((old.l & _FPU_MASK_ALL) != 0) + (void)__fe_mask_env (); /* Put the new state in effect. */ fesetenv_register (new.fenv); diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h index 287fc9f..4c19d12 100644 --- a/sysdeps/powerpc/fpu/fenv_libc.h +++ b/sysdeps/powerpc/fpu/fenv_libc.h @@ -27,26 +27,6 @@ extern const fenv_t *__fe_nomask_env_priv (void); extern const fenv_t *__fe_mask_env (void) attribute_hidden; -/* If the old env had any enabled exceptions and the new env has no enabled - exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the - FPU to run faster because it always takes the default action and can not - generate SIGFPE. */ -#define __TEST_AND_ENTER_NON_STOP(old, new) \ - do { \ - if (((old) & FPSCR_ENABLES_MASK) != 0 && ((new) & FPSCR_ENABLES_MASK) == 0) \ - (void) __fe_mask_env (); \ - } while (0) - -/* If the old env has no enabled exceptions and the new env has any enabled - exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the - hardware into "precise mode" and may cause the FPU to run slower on some - hardware. */ -#define __TEST_AND_EXIT_NON_STOP(old, new) \ - do { \ - if (((old) & FPSCR_ENABLES_MASK) == 0 && ((new) & FPSCR_ENABLES_MASK) != 0) \ - (void) __fe_nomask_env_priv (); \ - } while (0) - /* The sticky bits in the FPSCR indicating exceptions have occurred. */ #define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID) @@ -55,52 +35,6 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; #define fegetenv_register() \ ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; }) -/* Equivalent to fegetenv_register, but only returns bits for - status, exception enables, and mode. - Nicely, it turns out that the 'mffsl' instruction will decode to - 'mffs' on architectures older than "power9" because the additional - bits set for 'mffsl' are "don't care" for 'mffs'. 'mffs' is a superset - of 'mffsl'. */ -#define fegetenv_control() \ - ({register double __fr; \ - __asm__ __volatile__ ( \ - ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ - : "=f" (__fr)); \ - __fr; \ - }) - -#define __fe_mffscrn(rn) \ - ({register fenv_union_t __fr; \ - if (__builtin_constant_p (rn)) \ - __asm__ __volatile__ ( \ - ".machine push; .machine \"power9\"; mffscrni %0,%1; .machine pop" \ - : "=f" (__fr.fenv) : "i" (rn)); \ - else \ - { \ - __fr.l = (rn); \ - __asm__ __volatile__ ( \ - ".machine push; .machine \"power9\"; mffscrn %0,%1; .machine pop" \ - : "=f" (__fr.fenv) : "f" (__fr.fenv)); \ - } \ - __fr.fenv; \ - }) - -/* Like fegetenv_control, but also sets the rounding mode. */ -#ifdef _ARCH_PWR9 -#define fegetenv_and_set_rn(rn) __fe_mffscrn (rn) -#else -/* 'mffscrn' will decode to 'mffs' on ARCH < 3_00, which is still necessary - but not sufficient, because it does not set the rounding mode. - Explicitly set the rounding mode when 'mffscrn' actually doesn't. */ -#define fegetenv_and_set_rn(rn) \ - ({register fenv_union_t __fr; \ - __fr.fenv = __fe_mffscrn (rn); \ - if (__glibc_unlikely (!(GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00))) \ - __fesetround_inline (rn); \ - __fr.fenv; \ - }) -#endif - /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ #define fesetenv_register(env) \ do { \ @@ -114,11 +48,6 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \ } while(0) -/* Set the last 2 nibbles of the FPSCR, which contain the - exception enables and the rounding mode. - 'fegetenv_control' retrieves these bits by reading the FPSCR. */ -#define fesetenv_control(env) __builtin_mtfsf (0b00000011, (env)); - /* This very handy macro: - Sets the rounding mode to 'round to nearest'; - Sets the processor into IEEE mode; and @@ -128,9 +57,9 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; #define relax_fenv_state() \ do { \ if (GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \ - asm volatile (".machine push; .machine \"power6\"; " \ + asm (".machine push; .machine \"power6\"; " \ "mtfsfi 7,0,1; .machine pop"); \ - asm volatile ("mtfsfi 7,0"); \ + asm ("mtfsfi 7,0"); \ } while(0) /* Set/clear a particular FPSCR bit (for instance, @@ -149,12 +78,7 @@ typedef union static inline int __fesetround_inline (int round) { -#ifdef _ARCH_PWR9 - __fe_mffscrn (round); -#else - if (__glibc_likely (GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00)) - __fe_mffscrn (round); - else if ((unsigned int) round < 2) + if ((unsigned int) round < 2) { asm volatile ("mtfsb0 30"); if ((unsigned int) round == 0) @@ -170,134 +94,64 @@ __fesetround_inline (int round) else asm volatile ("mtfsb1 31"); } -#endif - return 0; -} -/* Same as __fesetround_inline, however without runtime check to use DFP - mtfsfi syntax (as relax_fenv_state) or if round value is valid. */ -static inline void -__fesetround_inline_nocheck (const int round) -{ -#ifdef _ARCH_PWR9 - __fe_mffscrn (round); -#else - if (__glibc_likely (GLRO(dl_hwcap2) & PPC_FEATURE2_ARCH_3_00)) - __fe_mffscrn (round); - else - asm volatile ("mtfsfi 7,%0" : : "i" (round)); -#endif + return 0; } -#define FPSCR_MASK(bit) (1 << (31 - (bit))) - /* Definitions of all the FPSCR bit numbers */ enum { FPSCR_FX = 0, /* exception summary */ -#define FPSCR_FX_MASK (FPSCR_MASK (FPSCR_FX)) FPSCR_FEX, /* enabled exception summary */ -#define FPSCR_FEX_MASK (FPSCR_MASK FPSCR_FEX)) FPSCR_VX, /* invalid operation summary */ -#define FPSCR_VX_MASK (FPSCR_MASK (FPSCR_VX)) FPSCR_OX, /* overflow */ -#define FPSCR_OX_MASK (FPSCR_MASK (FPSCR_OX)) FPSCR_UX, /* underflow */ -#define FPSCR_UX_MASK (FPSCR_MASK (FPSCR_UX)) FPSCR_ZX, /* zero divide */ -#define FPSCR_ZX_MASK (FPSCR_MASK (FPSCR_ZX)) FPSCR_XX, /* inexact */ -#define FPSCR_XX_MASK (FPSCR_MASK (FPSCR_XX)) FPSCR_VXSNAN, /* invalid operation for sNaN */ -#define FPSCR_VXSNAN_MASK (FPSCR_MASK (FPSCR_VXSNAN)) FPSCR_VXISI, /* invalid operation for Inf-Inf */ -#define FPSCR_VXISI_MASK (FPSCR_MASK (FPSCR_VXISI)) FPSCR_VXIDI, /* invalid operation for Inf/Inf */ -#define FPSCR_VXIDI_MASK (FPSCR_MASK (FPSCR_VXIDI)) FPSCR_VXZDZ, /* invalid operation for 0/0 */ -#define FPSCR_VXZDZ_MASK (FPSCR_MASK (FPSCR_VXZDZ)) FPSCR_VXIMZ, /* invalid operation for Inf*0 */ -#define FPSCR_VXIMZ_MASK (FPSCR_MASK (FPSCR_VXIMZ)) FPSCR_VXVC, /* invalid operation for invalid compare */ -#define FPSCR_VXVC_MASK (FPSCR_MASK (FPSCR_VXVC)) FPSCR_FR, /* fraction rounded [fraction was incremented by round] */ -#define FPSCR_FR_MASK (FPSCR_MASK (FPSCR_FR)) FPSCR_FI, /* fraction inexact */ -#define FPSCR_FI_MASK (FPSCR_MASK (FPSCR_FI)) FPSCR_FPRF_C, /* result class descriptor */ -#define FPSCR_FPRF_C_MASK (FPSCR_MASK (FPSCR_FPRF_C)) FPSCR_FPRF_FL, /* result less than (usually, less than 0) */ -#define FPSCR_FPRF_FL_MASK (FPSCR_MASK (FPSCR_FPRF_FL)) FPSCR_FPRF_FG, /* result greater than */ -#define FPSCR_FPRF_FG_MASK (FPSCR_MASK (FPSCR_FPRF_FG)) FPSCR_FPRF_FE, /* result equal to */ -#define FPSCR_FPRF_FE_MASK (FPSCR_MASK (FPSCR_FPRF_FE)) FPSCR_FPRF_FU, /* result unordered */ -#define FPSCR_FPRF_FU_MASK (FPSCR_MASK (FPSCR_FPRF_FU)) FPSCR_20, /* reserved */ FPSCR_VXSOFT, /* invalid operation set by software */ -#define FPSCR_VXSOFT_MASK (FPSCR_MASK (FPSCR_VXSOFT)) FPSCR_VXSQRT, /* invalid operation for square root */ -#define FPSCR_VXSQRT_MASK (FPSCR_MASK (FPSCR_VXSQRT)) FPSCR_VXCVI, /* invalid operation for invalid integer convert */ -#define FPSCR_VXCVI_MASK (FPSCR_MASK (FPSCR_VXCVI)) FPSCR_VE, /* invalid operation exception enable */ -#define FPSCR_VE_MASK (FPSCR_MASK (FPSCR_VE)) FPSCR_OE, /* overflow exception enable */ -#define FPSCR_OE_MASK (FPSCR_MASK (FPSCR_OE)) FPSCR_UE, /* underflow exception enable */ -#define FPSCR_UE_MASK (FPSCR_MASK (FPSCR_UE)) FPSCR_ZE, /* zero divide exception enable */ -#define FPSCR_ZE_MASK (FPSCR_MASK (FPSCR_ZE)) FPSCR_XE, /* inexact exception enable */ -#define FPSCR_XE_MASK (FPSCR_MASK (FPSCR_XE)) #ifdef _ARCH_PWR6 FPSCR_29, /* Reserved in ISA 2.05 */ -#define FPSCR_NI_MASK (FPSCR_MASK (FPSCR_29)) #else - FPSCR_NI, /* non-IEEE mode (typically, no denormalised numbers) */ -#define FPSCR_NI_MASK (FPSCR_MASK (FPSCR_NI)) + FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */ #endif /* _ARCH_PWR6 */ /* the remaining two least-significant bits keep the rounding mode */ - FPSCR_RN_hi, -#define FPSCR_RN_hi_MASK (FPSCR_MASK (FPSCR_RN_hi)) - FPSCR_RN_lo -#define FPSCR_RN_lo_MASK (FPSCR_MASK (FPSCR_RN_lo)) }; -#define FPSCR_RN_MASK (FPSCR_RN_hi_MASK|FPSCR_RN_lo_MASK) -#define FPSCR_ENABLES_MASK \ - (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK) -#define FPSCR_BASIC_EXCEPTIONS_MASK \ - (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK) -#define FPSCR_EXCEPTIONS_MASK (FPSCR_BASIC_EXCEPTIONS_MASK| \ - FPSCR_VXSNAN_MASK|FPSCR_VXISI_MASK|FPSCR_VXIDI_MASK|FPSCR_VXZDZ_MASK| \ - FPSCR_VXIMZ_MASK|FPSCR_VXVC_MASK|FPSCR_VXSOFT_MASK|FPSCR_VXSQRT_MASK| \ - FPSCR_VXCVI_MASK) -#define FPSCR_FPRF_MASK \ - (FPSCR_FPRF_C_MASK|FPSCR_FPRF_FL_MASK|FPSCR_FPRF_FG_MASK| \ - FPSCR_FPRF_FE_MASK|FPSCR_FPRF_FU_MASK) -#define FPSCR_CONTROL_MASK (FPSCR_ENABLES_MASK|FPSCR_NI_MASK|FPSCR_RN_MASK) -#define FPSCR_STATUS_MASK (FPSCR_FR_MASK|FPSCR_FI_MASK|FPSCR_FPRF_MASK) - -/* The bits in the FENV(1) ABI for exceptions correspond one-to-one with bits - in the FPSCR, albeit shifted to different but corresponding locations. - Similarly, the exception indicator bits in the FPSCR correspond one-to-one - with the exception enable bits. It is thus possible to map the FENV(1) - exceptions directly to the FPSCR enables with a simple mask and shift, - and vice versa. */ -#define FPSCR_EXCEPT_TO_ENABLE_SHIFT 22 - static inline int fenv_reg_to_exceptions (unsigned long long l) { - return (((int)l) & FPSCR_ENABLES_MASK) << FPSCR_EXCEPT_TO_ENABLE_SHIFT; -} - -static inline unsigned long long -fenv_exceptions_to_reg (int excepts) -{ - return (unsigned long long) - (excepts & FE_ALL_EXCEPT) >> FPSCR_EXCEPT_TO_ENABLE_SHIFT; + int result = 0; + if (l & (1 << (31 - FPSCR_XE))) + result |= FE_INEXACT; + if (l & (1 << (31 - FPSCR_ZE))) + result |= FE_DIVBYZERO; + if (l & (1 << (31 - FPSCR_UE))) + result |= FE_UNDERFLOW; + if (l & (1 << (31 - FPSCR_OE))) + result |= FE_OVERFLOW; + if (l & (1 << (31 - FPSCR_VE))) + result |= FE_INVALID; + return result; } #ifdef _ARCH_PWR6 diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h index e09137e..945ab98 100644 --- a/sysdeps/powerpc/fpu/fenv_private.h +++ b/sysdeps/powerpc/fpu/fenv_private.h @@ -23,31 +23,73 @@ #include #include -#ifdef _ARCH_PWR8 -/* There is no performance advantage to non-stop mode. */ -/* The odd syntax here is to innocuously reference the given variables - to prevent warnings about unused variables. */ -#define __TEST_AND_BEGIN_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0) -#define __TEST_AND_END_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0) -#else -#define __TEST_AND_BEGIN_NON_STOP __TEST_AND_ENTER_NON_STOP -#define __TEST_AND_END_NON_STOP __TEST_AND_EXIT_NON_STOP -#endif +/* Mask for the exception enable bits. */ +#define _FPU_ALL_TRAPS (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM \ + | _FPU_MASK_XM | _FPU_MASK_IM) + +/* Mask the rounding mode bits. */ +#define _FPU_MASK_RN 0xfffffffffffffffcLL + +/* Mask everything but the rounding modes and non-IEEE arithmetic flags. */ +#define _FPU_MASK_NOT_RN_NI 0xffffffff00000807LL + +/* Mask restore rounding mode and exception enabled. */ +#define _FPU_MASK_TRAPS_RN 0xffffffffffffff00LL + +/* Mask FP result flags, preserve fraction rounded/inexact bits. */ +#define _FPU_MASK_FRAC_INEX_RET_CC 0xfffffffffff80fffLL static __always_inline void -libc_feholdexcept_setround_ppc (fenv_t *envp, int r) +__libc_feholdbits_ppc (fenv_t *envp, unsigned long long mask, + unsigned long long bits) { fenv_union_t old, new; old.fenv = *envp = fegetenv_register (); - __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL); + new.l = (old.l & mask) | bits; + + /* If the old env had any enabled exceptions, then mask SIGFPE in the + MSR FE0/FE1 bits. This may allow the FPU to run faster because it + always takes the default action and can not generate SIGFPE. */ + if ((old.l & _FPU_ALL_TRAPS) != 0) + (void) __fe_mask_env (); - /* Clear everything and set the rounding mode. */ - new.l = r; fesetenv_register (new.fenv); } +static __always_inline void +libc_feholdexcept_ppc (fenv_t *envp) +{ + __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI, 0LL); +} + +static __always_inline void +libc_feholdexcept_setround_ppc (fenv_t *envp, int r) +{ + __libc_feholdbits_ppc (envp, _FPU_MASK_NOT_RN_NI & _FPU_MASK_RN, r); +} + +static __always_inline void +libc_fesetround_ppc (int r) +{ + __fesetround_inline (r); +} + +static __always_inline int +libc_fetestexcept_ppc (int e) +{ + fenv_union_t u; + u.fenv = fegetenv_register (); + return u.l & e; +} + +static __always_inline void +libc_feholdsetround_ppc (fenv_t *e, int r) +{ + __libc_feholdbits_ppc (e, _FPU_MASK_TRAPS_RN, r); +} + static __always_inline unsigned long long __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, unsigned long long new_mask) @@ -60,23 +102,22 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, /* Merge bits while masking unwanted bits from new and old env. */ new.l = (old.l & old_mask) | (new.l & new_mask); - __TEST_AND_END_NON_STOP (old.l, new.l); - __TEST_AND_BEGIN_NON_STOP (old.l, new.l); - - /* If requesting to keep status, replace control, and merge exceptions, - and exceptions haven't changed, we can just set new control instead - of the whole FPSCR. */ - if ((old_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK)) - == (FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK) && - (new_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK)) - == (FPSCR_CONTROL_MASK|FPSCR_EXCEPTIONS_MASK) && - (old.l & FPSCR_EXCEPTIONS_MASK) == (new.l & FPSCR_EXCEPTIONS_MASK)) - { - fesetenv_control (new.fenv); - } - else - /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ - fesetenv_register (new.fenv); + /* If the old env has no enabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the + hardware into "precise mode" and may cause the FPU to run slower on some + hardware. */ + if ((old.l & _FPU_ALL_TRAPS) == 0 && (new.l & _FPU_ALL_TRAPS) != 0) + (void) __fe_nomask_env_priv (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ + if ((old.l & _FPU_ALL_TRAPS) != 0 && (new.l & _FPU_ALL_TRAPS) == 0) + (void) __fe_mask_env (); + + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ + fesetenv_register (new.fenv); return old.l; } @@ -91,15 +132,14 @@ libc_fesetenv_ppc (const fenv_t *envp) static __always_inline void libc_feresetround_ppc (fenv_t *envp) { - fenv_union_t new = { .fenv = *envp }; - fegetenv_and_set_rn (new.l & FPSCR_RN_MASK); + __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, _FPU_MASK_FRAC_INEX_RET_CC); } static __always_inline int libc_feupdateenv_test_ppc (fenv_t *envp, int ex) { - return __libc_femergeenv_ppc (envp, ~FPSCR_CONTROL_MASK, - ~FPSCR_STATUS_MASK) & ex; + return __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, + _FPU_MASK_FRAC_INEX_RET_CC) & ex; } static __always_inline void @@ -134,26 +174,18 @@ libc_feupdateenv_ppc (fenv_t *e) static __always_inline void libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r) { - fenv_union_t old; - - ctx->env = old.fenv = fegetenv_and_set_rn (r); - ctx->updated_status = (r != (old.l & FPSCR_RN_MASK)); -} - -static __always_inline void -libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r) -{ fenv_union_t old, new; old.fenv = fegetenv_register (); - new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r; + new.l = (old.l & _FPU_MASK_TRAPS_RN) | r; ctx->env = old.fenv; if (__glibc_unlikely (new.l != old.l)) { - __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL); - fesetenv_control (new.fenv); + if ((old.l & _FPU_ALL_TRAPS) != 0) + (void) __fe_mask_env (); + fesetenv_register (new.fenv); ctx->updated_status = true; } else @@ -186,9 +218,6 @@ libc_feresetround_ppc_ctx (struct rm_ctx *ctx) #define libc_feholdsetround_ctx libc_feholdsetround_ppc_ctx #define libc_feholdsetroundf_ctx libc_feholdsetround_ppc_ctx #define libc_feholdsetroundl_ctx libc_feholdsetround_ppc_ctx -#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_ppc_ctx -#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ppc_ctx -#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ppc_ctx #define libc_feresetround_ctx libc_feresetround_ppc_ctx #define libc_feresetroundf_ctx libc_feresetround_ppc_ctx #define libc_feresetroundl_ctx libc_feresetround_ppc_ctx diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c index 2521141..ad9fda1 100644 --- a/sysdeps/powerpc/fpu/fesetenv.c +++ b/sysdeps/powerpc/fpu/fesetenv.c @@ -19,6 +19,8 @@ #include #include +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) + int __fesetenv (const fenv_t *envp) { @@ -26,12 +28,25 @@ __fesetenv (const fenv_t *envp) /* get the currently set exceptions. */ new.fenv = *envp; - old.fenv = fegetenv_control (); - - __TEST_AND_EXIT_NON_STOP (old.l, new.l); - __TEST_AND_ENTER_NON_STOP (old.l, new.l); - - fesetenv_register (new.fenv); + old.fenv = fegetenv_register (); + if (old.l == new.l) + return 0; + + /* If the old env has no enabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the + hardware into "precise mode" and may cause the FPU to run slower on some + hardware. */ + if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void) __fe_nomask_env_priv (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ + if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void)__fe_mask_env (); + + fesetenv_register (*envp); /* Success. */ return 0; diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c index fdaecb1..32203a2 100644 --- a/sysdeps/powerpc/fpu/fesetmode.c +++ b/sysdeps/powerpc/fpu/fesetmode.c @@ -19,6 +19,11 @@ #include #include +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM \ + | _FPU_MASK_XM | _FPU_MASK_IM) + +#define FPU_STATUS 0xbffff700ULL + int fesetmode (const femode_t *modep) { @@ -27,15 +32,18 @@ fesetmode (const femode_t *modep) /* Logic regarding enabled exceptions as in fesetenv. */ new.fenv = *modep; - old.fenv = fegetenv_control (); - new.l = (new.l & ~FPSCR_STATUS_MASK) | (old.l & FPSCR_STATUS_MASK); + old.fenv = fegetenv_register (); + new.l = (new.l & ~FPU_STATUS) | (old.l & FPU_STATUS); if (old.l == new.l) return 0; - __TEST_AND_EXIT_NON_STOP (old.l, new.l); - __TEST_AND_ENTER_NON_STOP (old.l, new.l); + if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void) __fe_nomask_env_priv (); + + if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void) __fe_mask_env (); - fesetenv_control (new.fenv); + fesetenv_register (new.fenv); return 0; } diff --git a/sysdeps/powerpc/fpu/feupdateenv.c b/sysdeps/powerpc/fpu/feupdateenv.c index fdd1565..2dbd1c4 100644 --- a/sysdeps/powerpc/fpu/feupdateenv.c +++ b/sysdeps/powerpc/fpu/feupdateenv.c @@ -20,6 +20,8 @@ #include #include +#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) + int __feupdateenv (const fenv_t *envp) { @@ -34,8 +36,19 @@ __feupdateenv (const fenv_t *envp) unchanged. */ new.l = (old.l & 0xffffffff1fffff00LL) | (new.l & 0x1ff80fff); - __TEST_AND_EXIT_NON_STOP (old.l, new.l); - __TEST_AND_ENTER_NON_STOP (old.l, new.l); + /* If the old env has no enabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put + the hardware into "precise mode" and may cause the FPU to run slower on + some hardware. */ + if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void) __fe_nomask_env_priv (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ + if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void)__fe_mask_env (); /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ fesetenv_register (new.fenv); diff --git a/sysdeps/powerpc/fpu/get-rounding-mode.h b/sysdeps/powerpc/fpu/get-rounding-mode.h deleted file mode 100644 index e2fdbbb..0000000 --- a/sysdeps/powerpc/fpu/get-rounding-mode.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Determine floating-point rounding mode within libc. powerpc64 version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _POWERPC64_GET_ROUNDING_MODE_H -#define _POWERPC64_GET_ROUNDING_MODE_H 1 - -#include -#include - -/* Return the floating-point rounding mode. */ - -static inline int -get_rounding_mode (void) -{ - return _FPU_GET_RC (); -} - -#endif /* get-rounding-mode.h */ diff --git a/sysdeps/powerpc/fpu/round_to_integer.h b/sysdeps/powerpc/fpu/round_to_integer.h deleted file mode 100644 index c70afbb..0000000 --- a/sysdeps/powerpc/fpu/round_to_integer.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Round to integer generic implementation. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see . */ - -#ifndef _ROUND_TO_INTEGER_H -#define _ROUND_TO_INTEGER_H - -#include - -enum round_mode -{ - CEIL -}; - -static inline void -set_fenv_mode (enum round_mode mode) -{ - int rmode; - switch (mode) - { - case CEIL: rmode = FE_UPWARD; break; - default: rmode = FE_TONEAREST; break; - } - __fesetround_inline_nocheck (rmode); -} - -static inline float -round_to_integer_float (enum round_mode mode, float x) -{ - /* Ensure sNaN input is converted to qNaN. */ - if (__glibc_unlikely (isnan (x))) - return x + x; - - if (fabs (x) > 0x1p+23) - return x; - - float r = x; - - /* Save current FPU rounding mode and inexact state. */ - fenv_t fe = fegetenv_register (); - set_fenv_mode (mode); - if (x > 0.0) - { - r += 0x1p+23; - r -= 0x1p+23; - r = fabs (r); - } - else if (x < 0.0) - { - r -= 0x1p+23; - r += 0x1p+23; - r = -fabs (r); - } - __builtin_mtfsf (0xff, fe); - - return r; -} - -static inline double -round_to_integer_double (enum round_mode mode, double x) -{ - /* Ensure sNaN input is converted to qNaN. */ - if (__glibc_unlikely (isnan (x))) - return x + x; - - if (fabs (x) > 0x1p+52) - return x; - - double r = x; - - /* Save current FPU rounding mode and inexact state. */ - fenv_t fe = fegetenv_register (); - set_fenv_mode (mode); - if (x > 0.0) - { - r += 0x1p+52; - r -= 0x1p+52; - r = fabs (r); - } - else if (x < 0.0) - { - r -= 0x1p+52; - r += 0x1p+52; - r = -fabs (r); - } - __builtin_mtfsf (0xff, fe); - - return r; -} - -#endif diff --git a/sysdeps/powerpc/fpu/s_ceil.c b/sysdeps/powerpc/fpu/s_ceil.c deleted file mode 100644 index 49008c7..0000000 --- a/sysdeps/powerpc/fpu/s_ceil.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Smallest integral value not less than argument. PowerPC version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see . */ - -#define NO_MATH_REDIRECT -#include -#include -#include - -double -__ceil (double x) -{ -#ifdef _ARCH_PWR5X - return __builtin_ceil (x); -#else - return round_to_integer_double (CEIL, x); -#endif -} -#ifndef __ceil -libm_alias_double (__ceil, ceil) -#endif diff --git a/sysdeps/powerpc/fpu/s_ceilf.c b/sysdeps/powerpc/fpu/s_ceilf.c deleted file mode 100644 index 8c86bf3..0000000 --- a/sysdeps/powerpc/fpu/s_ceilf.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Smallest integral value not less than argument. PowerPC version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see . */ - -#define NO_MATH_REDIRECT -#include -#include -#include - -float -__ceilf (float x) -{ -#ifdef _ARCH_PWR5X - return __builtin_ceilf (x); -#else - return round_to_integer_float (CEIL, x); -#endif -} -#ifndef __ceilf -libm_alias_float (__ceil, ceil) -#endif diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h index e0ee622..9d0698b 100644 --- a/sysdeps/powerpc/fpu_control.h +++ b/sysdeps/powerpc/fpu_control.h @@ -71,8 +71,6 @@ extern fpu_control_t __fpu_control; # define _FPU_RC_UP 0x02 # define _FPU_RC_ZERO 0x01 -# define _FPU_MASK_RC (_FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO) - # define _FPU_MASK_NI 0x04 /* non-ieee mode */ /* masking of interrupts */ @@ -98,43 +96,20 @@ typedef unsigned int fpu_control_t; /* Macros for accessing the hardware control word. */ # define _FPU_GETCW(cw) \ ({union { double __d; unsigned long long __ll; } __u; \ - __asm__ __volatile__("mffs %0" : "=f" (__u.__d)); \ + register double __fr; \ + __asm__ ("mffs %0" : "=f" (__fr)); \ + __u.__d = __fr; \ (cw) = (fpu_control_t) __u.__ll; \ (fpu_control_t) __u.__ll; \ }) -# define _FPU_GET_RC_ISA300() \ - ({union { double __d; unsigned long long __ll; } __u; \ - __asm__ __volatile__( \ - ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ - : "=f" (__u.__d)); \ - (fpu_control_t) (__u.__ll & _FPU_MASK_RC); \ - }) - -# ifdef _ARCH_PWR9 -# define _FPU_GET_RC() _FPU_GET_RC_ISA300() -# elif defined __BUILTIN_CPU_SUPPORTS__ -# define _FPU_GET_RC() \ - ({fpu_control_t __rc; \ - __rc = __glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ - ? _FPU_GET_RC_ISA300 () \ - : _FPU_GETCW (__rc) & _FPU_MASK_RC; \ - __rc; \ - }) -# else -# define _FPU_GET_RC() \ - ({fpu_control_t __rc = _FPU_GETCW (__rc) & _FPU_MASK_RC; \ - __rc; \ - }) -# endif - # define _FPU_SETCW(cw) \ { union { double __d; unsigned long long __ll; } __u; \ register double __fr; \ __u.__ll = 0xfff80000LL << 32; /* This is a QNaN. */ \ __u.__ll |= (cw) & 0xffffffffLL; \ __fr = __u.__d; \ - __asm__ __volatile__("mtfsf 255,%0" : : "f" (__fr)); \ + __asm__ ("mtfsf 255,%0" : : "f" (__fr)); \ } /* Default control word set at startup. */ diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym index 4c01615..e5bb2b3 100644 --- a/sysdeps/powerpc/nptl/tcb-offsets.sym +++ b/sysdeps/powerpc/nptl/tcb-offsets.sym @@ -21,6 +21,7 @@ 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 8317ca7..f88fed5 100644 --- a/sysdeps/powerpc/nptl/tls.h +++ b/sysdeps/powerpc/nptl/tls.h @@ -67,7 +67,8 @@ typedef struct uint32_t padding; uint32_t at_platform; #endif - uint32_t __unused; + /* Indicate if HTM capable (ISA 2.07). */ + uint32_t tm_capable; /* Reservation for AT_PLATFORM data - powerpc64. */ #ifdef __powerpc64__ uint32_t at_platform; @@ -141,6 +142,7 @@ 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; \ @@ -149,6 +151,8 @@ 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) = \ @@ -206,6 +210,13 @@ 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/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c index c7b64f9..5422fdd 100644 --- a/sysdeps/powerpc/powerpc32/backtrace.c +++ b/sysdeps/powerpc/powerpc32/backtrace.c @@ -114,8 +114,6 @@ __backtrace (void **array, int size) } if (gregset) { - if (count + 1 == size) - break; array[++count] = (void*)((*gregset)[PT_NIP]); current = (void*)((*gregset)[PT_R1]); } diff --git a/sysdeps/powerpc/powerpc32/dl-irel.h b/sysdeps/powerpc/powerpc32/dl-irel.h index 61d0e4c..a7368b2 100644 --- a/sysdeps/powerpc/powerpc32/dl-irel.h +++ b/sysdeps/powerpc/powerpc32/dl-irel.h @@ -46,7 +46,7 @@ elf_irela (const Elf32_Rela *reloc) *reloc_addr = value; } else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S new file mode 100644 index 0000000..7f2f97a --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S @@ -0,0 +1,76 @@ +/* ceil function. PowerPC32 version. + Copyright (C) 2004-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + + .section .rodata.cst4,"aM",@progbits,4 + .align 2 +.LC0: /* 2**52 */ + .long 0x59800000 + + .section ".text" +ENTRY (__ceil) +#ifdef SHARED + mflr r11 + cfi_register(lr,r11) + SETUP_GOT_ACCESS(r9,got_label) + addis r9,r9,.LC0-got_label@ha + lfs fp13,.LC0-got_label@l(r9) + mtlr r11 + cfi_same_value (lr) +#else + lis r9,.LC0@ha + lfs fp13,.LC0@l(r9) +#endif + fabs fp0,fp1 + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + mffs fp11 /* Save current FPU rounding mode and + "inexact" state. */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L10 + mtfsfi 7,2 /* Set rounding mode toward +inf. */ + ble- cr6,.L4 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L4: + bge- cr6,.L9 /* if (x < 0.0) */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr + END (__ceil) + +libm_alias_double (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S new file mode 100644 index 0000000..3f59490 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S @@ -0,0 +1,76 @@ +/* float ceil function. PowerPC32 version. + Copyright (C) 2004-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + + .section .rodata.cst4,"aM",@progbits,4 + .align 2 +.LC0: /* 2**23 */ + .long 0x4b000000 + + .section ".text" +ENTRY (__ceilf) +#ifdef SHARED + mflr r11 + cfi_register(lr,r11) + SETUP_GOT_ACCESS(r9,got_label) + addis r9,r9,.LC0-got_label@ha + lfs fp13,.LC0-got_label@l(r9) + mtlr r11 + cfi_same_value (lr) +#else + lis r9,.LC0@ha + lfs fp13,.LC0@l(r9) +#endif + fabs fp0,fp1 + fsubs fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ + mffs fp11 /* Save current FPU rounding mode and + "inexact" state. */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L10 + mtfsfi 7,2 /* Set rounding mode toward +inf. */ + ble- cr6,.L4 + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L4: + bge- cr6,.L9 /* if (x < 0.0) */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr + END (__ceilf) + +libm_alias_float (__ceil, ceil) + diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile index cf38e34..4e85021 100644 --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile @@ -26,8 +26,6 @@ libm-sysdep_routines += s_llrintf-power6 s_llrintf-ppc32 s_llrint-power6 \ s_logbf-power7 s_logbf-ppc32 e_hypot-power7 \ e_hypot-ppc32 e_hypotf-power7 e_hypotf-ppc32 -CFLAGS-s_ceil-power5+.c = -mcpu=power5+ -CFLAGS-s_ceilf-power5+.c = -mcpu=power5+ CFLAGS-s_modf-power5+.c = -mcpu=power5+ CFLAGS-s_modff-power5+.c = -mcpu=power5+ CFLAGS-s_logbl-power7.c = -mcpu=power7 diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S new file mode 100644 index 0000000..b818158 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.S @@ -0,0 +1,33 @@ +/* ceil function. PowerPC32/power5+ version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#undef hidden_def +#define hidden_def(name) +#undef weak_alias +#define weak_alias(name, alias) +#undef strong_alias +#define strong_alias(name, alias) +#undef compat_symbol +#define compat_symbol(lib, name, alias, ver) + +#define __ceil __ceil_power5plus + +#include diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c deleted file mode 100644 index 87bc66c..0000000 --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-power5+.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceil __ceil_power5plus -#include diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S new file mode 100644 index 0000000..cd2bc69 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.S @@ -0,0 +1,31 @@ +/* ceil function. PowerPC32 default version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#undef weak_alias +#define weak_alias(a,b) +#undef strong_alias +#define strong_alias(a,b) +#undef compat_symbol +#define compat_symbol(a,b,c,d) + +#define __ceil __ceil_ppc32 + +#include diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c deleted file mode 100644 index 93c0984..0000000 --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceil-ppc32.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceil __ceil_ppc32 -#include diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S new file mode 100644 index 0000000..d01aa6e --- /dev/null +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.S @@ -0,0 +1,26 @@ +/* ceilf function. PowerPC32/power5+ version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#undef weak_alias +#define weak_alias(name, alias) + +#define __ceilf __ceilf_power5plus + +#include diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c deleted file mode 100644 index a5bfa98..0000000 --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-power5+.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceilf __ceilf_power5plus -#include diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S new file mode 100644 index 0000000..264e032 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.S @@ -0,0 +1,27 @@ +/* ceilf function. PowerPC32 default version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#undef weak_alias +#define weak_alias(a,b) + +#define __ceilf __ceilf_ppc32 + +#include diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c deleted file mode 100644 index a4dcdcb..0000000 --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_ceilf-ppc32.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceilf __ceilf_ppc32 -#include diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S new file mode 100644 index 0000000..356c7a7 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceil.S @@ -0,0 +1,29 @@ +/* ceil function. PowerPC32/power5+ version. + Copyright (C) 2006-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + + .machine "power5" +EALIGN (__ceil, 4, 0) + frip fp1, fp1 + blr + END (__ceil) + +libm_alias_double (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S new file mode 100644 index 0000000..a0bcda1 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/power5+/fpu/s_ceilf.S @@ -0,0 +1,30 @@ +/* ceilf function. PowerPC32/power5+ version. + Copyright (C) 2006-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + + .machine "power5" +EALIGN (__ceilf, 4, 0) + frip fp1, fp1 /* The rounding instructions are double. */ + frsp fp1, fp1 /* But we need to set ooverflow for float. */ + blr + END (__ceilf) + +libm_alias_float (__ceil, ceil) + diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index 93097c5..5f1294e 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -90,7 +90,24 @@ 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/addmul_1.S b/sysdeps/powerpc/powerpc64/addmul_1.S index e450d6a..48e3b1b 100644 --- a/sysdeps/powerpc/powerpc64/addmul_1.S +++ b/sysdeps/powerpc/powerpc64/addmul_1.S @@ -34,27 +34,16 @@ #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, R31SAVE(r1) + std r31, -8(r1) rldicl. r0, N, 0, 62 - std r30, R30SAVE(r1) + std r30, -16(r1) cmpdi VL, r0, 2 - std r29, R29SAVE(r1) + std r29, -24(r1) addi N, N, 3 - std r28, R28SAVE(r1) + std r28, -32(r1) srdi N, N, 2 - std r27, R27SAVE(r1) - cfi_offset(r31, R31SAVE) - cfi_offset(r30, R30SAVE) - cfi_offset(r29, R29SAVE) - cfi_offset(r28, R28SAVE) - cfi_offset(r27, R27SAVE) + std r27, -40(r1) mtctr N beq cr0, L(b00) blt cr6, L(b01) @@ -210,10 +199,10 @@ L(end): mulld r0, r9, VL addic r11, r11, 1 #endif addze RP, r8 - ld r31, R31SAVE(r1) - ld r30, R30SAVE(r1) - ld r29, R29SAVE(r1) - ld r28, R28SAVE(r1) - ld r27, R27SAVE(r1) + ld r31, -8(r1) + ld r30, -16(r1) + ld r29, -24(r1) + ld r28, -32(r1) + ld r27, -40(r1) blr END(FUNC) diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c index 0acf17b..c0c4b48 100644 --- a/sysdeps/powerpc/powerpc64/backtrace.c +++ b/sysdeps/powerpc/powerpc64/backtrace.c @@ -87,8 +87,6 @@ __backtrace (void **array, int size) if (is_sigtramp_address (current->return_address)) { struct signal_frame_64 *sigframe = (struct signal_frame_64*) current; - if (count + 1 == size) - break; array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP]; current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1]; } diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile deleted file mode 100644 index 932c3c7..0000000 --- a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(subdir),math) -libm-sysdep_routines += s_ceil-power5+ \ - s_ceil-ppc64 \ - s_ceilf-power5+ \ - s_ceilf-ppc64 - -CFLAGS-s_ceil-power5+.c = -mcpu=power5+ -CFLAGS-s_ceilf-power5+.c = -mcpu=power5+ -endif diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c deleted file mode 100644 index 87bc66c..0000000 --- a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-power5+.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceil __ceil_power5plus -#include diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c deleted file mode 100644 index 8711ff3..0000000 --- a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil-ppc64.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceil __ceil_ppc64 -#include diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c deleted file mode 100644 index 1abca7e..0000000 --- a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceil.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Multiple versions of ceil. - Copyright (C) 2013-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include "init-arch.h" - -extern __typeof (__ceil) __ceil_ppc64 attribute_hidden; -extern __typeof (__ceil) __ceil_power5plus attribute_hidden; - -libc_ifunc (__ceil, - (hwcap & PPC_FEATURE_POWER5_PLUS) - ? __ceil_power5plus - : __ceil_ppc64); - -libm_alias_double (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c deleted file mode 100644 index a5bfa98..0000000 --- a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-power5+.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceilf __ceilf_power5plus -#include diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c deleted file mode 100644 index 086251d..0000000 --- a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf-ppc64.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define __ceilf __ceilf_ppc64 -#include diff --git a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c b/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c deleted file mode 100644 index 3324596..0000000 --- a/sysdeps/powerpc/powerpc64/be/fpu/multiarch/s_ceilf.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Multiple versions of ceilf. - Copyright (C) 2013-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include "init-arch.h" - -extern __typeof (__ceilf) __ceilf_ppc64 attribute_hidden; -extern __typeof (__ceilf) __ceilf_power5plus attribute_hidden; - -libc_ifunc (__ceilf, - (hwcap & PPC_FEATURE_POWER5_PLUS) - ? __ceilf_power5plus - : __ceilf_ppc64); - -libm_alias_float (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h index 2fd0ee8..ab13c04 100644 --- a/sysdeps/powerpc/powerpc64/dl-irel.h +++ b/sysdeps/powerpc/powerpc64/dl-irel.h @@ -57,7 +57,7 @@ elf_irela (const Elf64_Rela *reloc) #endif } else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile index 2805e4e..73f2f69 100644 --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile @@ -14,7 +14,8 @@ sysdep_calls := s_copysign-power6 s_copysign-ppc64 \ sysdep_routines += $(sysdep_calls) libm-sysdep_routines += s_llround-power6x \ - s_llround-power5+ s_llround-ppc64 \ + s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \ + s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \ s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \ s_floorf-ppc64 s_round-power5+ s_round-ppc64 \ s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \ diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S new file mode 100644 index 0000000..76651b6 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S @@ -0,0 +1,30 @@ +/* ceil function. PowerPC64/power5+ version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#undef weak_alias +#define weak_alias(a,b) +#undef strong_alias +#define strong_alias(a,b) +#undef compat_symbol +#define compat_symbol(a,b,c,d) + +#define __ceil __ceil_power5plus + +#include diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S new file mode 100644 index 0000000..c75c66b --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S @@ -0,0 +1,30 @@ +/* ceil function. PowerPC64 default version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#undef weak_alias +#define weak_alias(a,b) +#undef strong_alias +#define strong_alias(a,b) +#undef compat_symbol +#define compat_symbol(a,b,c,d) + +#define __ceil __ceil_ppc64 + +#include diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c new file mode 100644 index 0000000..5cde4eb --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c @@ -0,0 +1,33 @@ +/* Multiple versions of ceil. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include "init-arch.h" +#include + +extern __typeof (__ceil) __ceil_ppc64 attribute_hidden; +extern __typeof (__ceil) __ceil_power5plus attribute_hidden; + +libc_ifunc (__ceil, + (hwcap & PPC_FEATURE_POWER5_PLUS) + ? __ceil_power5plus + : __ceil_ppc64); + +libm_alias_double (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S new file mode 100644 index 0000000..b9c9e14 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S @@ -0,0 +1,24 @@ +/* ceilf function. PowerPC64/power5+ version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#undef weak_alias +#define weak_alias(a,b) + +#define __ceilf __ceilf_power5plus + +#include diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S new file mode 100644 index 0000000..ce5cc49 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S @@ -0,0 +1,24 @@ +/* ceilf function. PowerPC64 default version. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#undef weak_alias +#define weak_alias(a,b) + +#define __ceilf __ceilf_ppc64 + +#include diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c new file mode 100644 index 0000000..18697e5 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c @@ -0,0 +1,33 @@ +/* Multiple versions of ceilf. + Copyright (C) 2013-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include "init-arch.h" +#include + +extern __typeof (__ceilf) __ceilf_ppc64 attribute_hidden; +extern __typeof (__ceilf) __ceilf_power5plus attribute_hidden; + +libc_ifunc (__ceilf, + (hwcap & PPC_FEATURE_POWER5_PLUS) + ? __ceilf_power5plus + : __ceilf_ppc64); + +libm_alias_float (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S new file mode 100644 index 0000000..252d94f --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S @@ -0,0 +1,65 @@ +/* ceil function. PowerPC64 version. + Copyright (C) 2004-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + + .section ".toc","aw" +.LC0: /* 2**52 */ + .tc FD_43300000_0[TC],0x4330000000000000 + .section ".text" + +ENTRY (__ceil, 4) + CALL_MCOUNT 0 + lfd fp13,.LC0@toc(2) + fabs fp0,fp1 + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + mffs fp11 /* Save current FPU rounding mode and + "inexact" state. */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L10 + mtfsfi 7,2 /* Set rounding mode toward +inf. */ + ble- cr6,.L4 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L4: + bge- cr6,.L9 /* if (x < 0.0) */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr + END (__ceil) + +libm_alias_double (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S new file mode 100644 index 0000000..3c62077 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S @@ -0,0 +1,67 @@ +/* float ceil function. PowerPC64 version. + Copyright (C) 2004-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + + .section ".toc","aw" + .p2align 3 +.LC0: /* 2**23 */ + .long 0x4b000000 + .long 0x0 + .section ".text" + +ENTRY (__ceilf, 4) + CALL_MCOUNT 0 + lfs fp13,.LC0@toc(2) + fabs fp0,fp1 + fsubs fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ + mffs fp11 /* Save current FPU rounding mode and + "inexact" state. */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L10 + mtfsfi 7,2 /* Set rounding mode toward +inf. */ + ble- cr6,.L4 + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L4: + bge- cr6,.L9 /* if (x < 0.0) */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: + mtfsf 0xff,fp11 /* Restore previous rounding mode and + "inexact" state. */ + blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr + END (__ceilf) + +libm_alias_float (__ceil, ceil) + diff --git a/sysdeps/powerpc/powerpc64/lshift.S b/sysdeps/powerpc/powerpc64/lshift.S index 855d6f2..8b6396e 100644 --- a/sysdeps/powerpc/powerpc64/lshift.S +++ b/sysdeps/powerpc/powerpc64/lshift.S @@ -26,15 +26,11 @@ #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, U1SAVE(r1) - std U0, U0SAVE(r1) - cfi_offset(U1, U1SAVE) - cfi_offset(U0, U0SAVE) + std U1, -8(r1) + std U0, -16(r1) subfic TNC, CNT, 64 sldi r7, N, RP add UP, UP, r7 @@ -174,8 +170,8 @@ L(cj3): or r10, r12, r7 L(cj2): std r10, -32(RP) std r8, -40(RP) -L(ret): ld U1, U1SAVE(r1) - ld U0, U0SAVE(r1) +L(ret): ld U1, -8(r1) + ld U0, -16(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 cade365..953ded8 100644 --- a/sysdeps/powerpc/powerpc64/mul_1.S +++ b/sysdeps/powerpc/powerpc64/mul_1.S @@ -24,14 +24,9 @@ #define N r5 #define VL r6 -#define R26SAVE (-48) -#define R27SAVE (-40) - ENTRY_TOCLESS (__mpn_mul_1, 5) - std r27, R27SAVE(r1) - std r26, R26SAVE(r1) - cfi_offset(r27, R27SAVE) - cfi_offset(r26, R26SAVE) + std r27, -40(r1) + std r26, -48(r1) li r12, 0 ld r26, 0(UP) @@ -134,7 +129,7 @@ L(end): mulld r0, r26, VL std r0, 0(RP) std r7, 8(RP) L(ret): addze RP, r8 - ld r27, R27SAVE(r1) - ld r26, R26SAVE(r1) + ld r27, -40(r1) + ld r26, -48(r1) blr END(__mpn_mul_1) diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S new file mode 100644 index 0000000..e500932 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S @@ -0,0 +1,30 @@ +/* ceil function. PowerPC64/power5+ version. + Copyright (C) 2006-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + + .machine "power5" +ENTRY_TOCLESS (__ceil, 4) + CALL_MCOUNT 0 + frip fp1, fp1 + blr + END (__ceil) + +libm_alias_double (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S new file mode 100644 index 0000000..d0b2118 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S @@ -0,0 +1,31 @@ +/* ceilf function. PowerPC64/power5+ version. + Copyright (C) 2006-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + + .machine "power5" +ENTRY_TOCLESS (__ceilf, 4) + CALL_MCOUNT 0 + frip fp1, fp1 /* The rounding instructions are double. */ + frsp fp1, fp1 /* But we need to set ooverflow for float. */ + blr + END (__ceilf) + +libm_alias_float (__ceil, ceil) + diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h index 50e64f9..2df1d9b 100644 --- a/sysdeps/powerpc/powerpc64/sysdep.h +++ b/sysdeps/powerpc/powerpc64/sysdep.h @@ -263,7 +263,24 @@ 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 c8bf25e..8a6d236 100644 --- a/sysdeps/powerpc/sysdep.h +++ b/sysdeps/powerpc/sysdep.h @@ -21,6 +21,8 @@ */ #define _SYSDEPS_SYSDEP_H 1 #include +#include +#include #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) @@ -164,4 +166,22 @@ #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/s390/Makefile b/sysdeps/s390/Makefile index 8bc82e5..8a54f88 100644 --- a/sysdeps/s390/Makefile +++ b/sysdeps/s390/Makefile @@ -29,54 +29,3 @@ $(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules endif - -ifeq ($(subdir),string) -sysdep_routines += bzero memset memset-z900 \ - memcmp memcmp-z900 \ - mempcpy memcpy memcpy-z900 \ - memmove memmove-c \ - strstr strstr-arch13 strstr-vx strstr-c \ - memmem memmem-arch13 memmem-vx memmem-c \ - strlen strlen-vx strlen-c \ - strnlen strnlen-vx strnlen-c \ - strcpy strcpy-vx strcpy-z900 \ - stpcpy stpcpy-vx stpcpy-c \ - strncpy strncpy-vx strncpy-z900 \ - stpncpy stpncpy-vx stpncpy-c \ - strcat strcat-vx strcat-c \ - strncat strncat-vx strncat-c \ - strcmp strcmp-vx strcmp-z900 \ - strncmp strncmp-vx strncmp-c \ - strchr strchr-vx strchr-c \ - strchrnul strchrnul-vx strchrnul-c \ - strrchr strrchr-vx strrchr-c \ - strspn strspn-vx strspn-c \ - strpbrk strpbrk-vx strpbrk-c \ - strcspn strcspn-vx strcspn-c \ - memchr memchr-vx memchr-z900 \ - rawmemchr rawmemchr-vx rawmemchr-c \ - memccpy memccpy-vx memccpy-c \ - memrchr memrchr-vx memrchr-c -endif - -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 \ - wcsncpy wcsncpy-vx wcsncpy-c \ - wcpncpy wcpncpy-vx wcpncpy-c \ - wcscat wcscat-vx wcscat-c \ - wcsncat wcsncat-vx wcsncat-c \ - wcscmp wcscmp-vx wcscmp-c \ - wcsncmp wcsncmp-vx wcsncmp-c \ - wcschr wcschr-vx wcschr-c \ - wcschrnul wcschrnul-vx wcschrnul-c \ - wcsrchr wcsrchr-vx wcsrchr-c \ - wcsspn wcsspn-vx wcsspn-c \ - wcspbrk wcspbrk-vx wcspbrk-c \ - wcscspn wcscspn-vx wcscspn-c \ - wmemchr wmemchr-vx wmemchr-c \ - wmemset wmemset-vx wmemset-c \ - wmemcmp wmemcmp-vx wmemcmp-c -endif diff --git a/sysdeps/s390/bzero.c b/sysdeps/s390/bzero.c deleted file mode 100644 index 6b5d471..0000000 --- a/sysdeps/s390/bzero.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Multiple versions of bzero. - 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_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_expr_stfle_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/configure b/sysdeps/s390/configure index fa46e9e..74b415f 100644 --- a/sysdeps/s390/configure +++ b/sysdeps/s390/configure @@ -112,82 +112,6 @@ 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 : - $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 : @@ -224,77 +148,5 @@ 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 - -{ $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 3ed5a8e..1cdb021 100644 --- a/sysdeps/s390/configure.ac +++ b/sysdeps/s390/configure.ac @@ -80,61 +80,6 @@ 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 -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 @@ -161,56 +106,5 @@ 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 - -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/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h index ecb24f0..d8ba7ba 100644 --- a/sysdeps/s390/dl-irel.h +++ b/sysdeps/s390/dl-irel.h @@ -46,7 +46,7 @@ elf_irela (const ElfW(Rela) *reloc) *reloc_addr = value; } else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c index 6d76d7d..86c964c 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[19][9] +PROCINFO_CLASS const char _dl_s390_cap_flags[15][9] #endif #ifndef PROCINFO_DECL = { "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", - "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt" + "highgprs", "te", "vx", "vxd", "vxe", "gs" } #endif #if !defined SHARED || defined PROCINFO_DECL @@ -63,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[19][9] #if !defined PROCINFO_DECL && defined SHARED ._dl_s390_platforms #else -PROCINFO_CLASS const char _dl_s390_platforms[10][7] +PROCINFO_CLASS const char _dl_s390_platforms[9][7] #endif #ifndef PROCINFO_DECL = { - "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15" + "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14" } #endif #if !defined SHARED || defined PROCINFO_DECL diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h index b367bbe..b0383bf 100644 --- a/sysdeps/s390/dl-procinfo.h +++ b/sysdeps/s390/dl-procinfo.h @@ -21,9 +21,9 @@ #define _DL_PROCINFO_H 1 #include -#define _DL_HWCAP_COUNT 19 +#define _DL_HWCAP_COUNT 15 -#define _DL_PLATFORMS_COUNT 10 +#define _DL_PLATFORMS_COUNT 9 /* The kernel provides up to 32 capability bits with elf_hwcap. */ #define _DL_FIRST_PLATFORM 32 @@ -54,16 +54,10 @@ 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_VXRS_EXT2) + | HWCAP_S390_EIMM | HWCAP_S390_DFP) /* We cannot provide a general printing function. */ #define _dl_procinfo(type, word) -1 diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c index f1be1d1..3c38bc9 100644 --- a/sysdeps/s390/fpu/fegetround.c +++ b/sysdeps/s390/fpu/fegetround.c @@ -17,12 +17,17 @@ License along with the GNU C Library; if not, see . */ -#include +#include +#include int __fegetround (void) { - return get_rounding_mode (); + fexcept_t cw; + + _FPU_GETCW (cw); + + return cw & FPC_RM_MASK; } libm_hidden_def (__fegetround) weak_alias (__fegetround, fegetround) diff --git a/sysdeps/s390/fpu/feholdexcpt.c b/sysdeps/s390/fpu/feholdexcpt.c index 48af7ff..5daee56 100644 --- a/sysdeps/s390/fpu/feholdexcpt.c +++ b/sysdeps/s390/fpu/feholdexcpt.c @@ -17,11 +17,19 @@ License along with the GNU C Library; if not, see . */ -#include +#include +#include int __feholdexcept (fenv_t *envp) { - libc_feholdexcept_s390 (envp); + fexcept_t fpc; + /* Store the environment. */ + __fegetenv (envp); + /* Clear the current sticky bits as more than one exception + may be generated. */ + fpc = envp->__fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK); + /* Hold from generating fpu exceptions temporarily. */ + _FPU_SETCW ((fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT))); return 0; } libm_hidden_def (__feholdexcept) diff --git a/sysdeps/s390/fpu/fenv_private.h b/sysdeps/s390/fpu/fenv_private.h deleted file mode 100644 index 8899f8f..0000000 --- a/sysdeps/s390/fpu/fenv_private.h +++ /dev/null @@ -1,248 +0,0 @@ -/* Private floating point rounding and exceptions handling. 390/s390x version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef S390_FENV_PRIVATE_H -#define S390_FENV_PRIVATE_H 1 - -#include -#include -#include - -static __always_inline void -libc_feholdexcept_s390 (fenv_t *envp) -{ - fpu_control_t fpc, fpc_new; - - /* Store the environment. */ - _FPU_GETCW (fpc); - envp->__fpc = fpc; - - /* Clear the current exception flags and dxc field. - Hold from generating fpu exceptions temporarily. */ - fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK); - - /* Only set new environment if it has changed. */ - if (fpc_new != fpc) - _FPU_SETCW (fpc_new); -} - -#define libc_feholdexcept libc_feholdexcept_s390 -#define libc_feholdexceptf libc_feholdexcept_s390 -#define libc_feholdexceptl libc_feholdexcept_s390 - -static __always_inline void -libc_fesetround_s390 (int round) -{ - __asm__ __volatile__ ("srnm 0(%0)" : : "a" (round)); -} - -#define libc_fesetround libc_fesetround_s390 -#define libc_fesetroundf libc_fesetround_s390 -#define libc_fesetroundl libc_fesetround_s390 - -static __always_inline void -libc_feholdexcept_setround_s390 (fenv_t *envp, int r) -{ - fpu_control_t fpc, fpc_new; - - _FPU_GETCW (fpc); - envp->__fpc = fpc; - - /* Clear the current exception flags and dxc field. - Hold from generating fpu exceptions temporarily. - Reset rounding mode bits. */ - fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK - | FPC_RM_MASK); - - /* Set new rounding mode. */ - fpc_new |= (r & FPC_RM_MASK); - - /* Only set new environment if it has changed. */ - if (fpc_new != fpc) - _FPU_SETCW (fpc_new); -} - -#define libc_feholdexcept_setround libc_feholdexcept_setround_s390 -#define libc_feholdexcept_setroundf libc_feholdexcept_setround_s390 -#define libc_feholdexcept_setroundl libc_feholdexcept_setround_s390 - -static __always_inline int -libc_fetestexcept_s390 (int excepts) -{ - int res; - fexcept_t fpc; - - _FPU_GETCW (fpc); - - /* Get current exceptions. */ - res = (fpc >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT; - if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0) - /* Bits 6, 7 of dxc-byte are zero, - thus bits 0-5 of dxc-byte correspond to the flag-bits. - Evaluate flags and last dxc-exception-code. */ - res |= (fpc >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT; - - return res & excepts; -} - -#define libc_fetestexcept libc_fetestexcept_s390 -#define libc_fetestexceptf libc_fetestexcept_s390 -#define libc_fetestexceptl libc_fetestexcept_s390 - -static __always_inline void -libc_fesetenv_s390 (const fenv_t *envp) -{ - _FPU_SETCW (envp->__fpc); -} - -#define libc_fesetenv libc_fesetenv_s390 -#define libc_fesetenvf libc_fesetenv_s390 -#define libc_fesetenvl libc_fesetenv_s390 - -static __always_inline int -libc_feupdateenv_test_s390 (const fenv_t *envp, int ex) -{ - /* Get the currently raised exceptions. */ - int excepts; - fexcept_t fpc_old; - - _FPU_GETCW (fpc_old); - - /* Get current exceptions. */ - excepts = (fpc_old >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT; - if ((fpc_old & FPC_NOT_FPU_EXCEPTION) == 0) - /* Bits 6, 7 of dxc-byte are zero, - thus bits 0-5 of dxc-byte correspond to the flag-bits. - Evaluate flags and last dxc-exception-code. */ - excepts |= (fpc_old >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT; - - /* Merge the currently raised exceptions with those in envp. */ - fpu_control_t fpc_new = envp->__fpc; - fpc_new |= excepts << FPC_FLAGS_SHIFT; - - /* Install the new fpc from envp. */ - if (fpc_new != fpc_old) - _FPU_SETCW (fpc_new); - - /* Raise the exceptions if enabled in new fpc. */ - if (__glibc_unlikely ((fpc_new >> FPC_EXCEPTION_MASK_SHIFT) & excepts)) - __feraiseexcept (excepts); - - return excepts & ex; -} - -#define libc_feupdateenv_test libc_feupdateenv_test_s390 -#define libc_feupdateenv_testf libc_feupdateenv_test_s390 -#define libc_feupdateenv_testl libc_feupdateenv_test_s390 - -static __always_inline void -libc_feupdateenv_s390 (const fenv_t *envp) -{ - libc_feupdateenv_test_s390 (envp, 0); -} - -#define libc_feupdateenv libc_feupdateenv_s390 -#define libc_feupdateenvf libc_feupdateenv_s390 -#define libc_feupdateenvl libc_feupdateenv_s390 - -static __always_inline fenv_t -libc_handle_user_fenv_s390 (const fenv_t *envp) -{ - fenv_t env; - if (envp == FE_DFL_ENV) - { - env.__fpc = _FPU_DEFAULT; - } - else if (envp == FE_NOMASK_ENV) - { - env.__fpc = FPC_EXCEPTION_MASK; - } - else - env = (*envp); - - return env; -} - -/* We have support for rounding mode context. */ -#define HAVE_RM_CTX 1 - -static __always_inline void -libc_feholdsetround_s390_ctx (struct rm_ctx *ctx, int r) -{ - fpu_control_t fpc; - int round; - - _FPU_GETCW (fpc); - ctx->env.__fpc = fpc; - - /* Check whether rounding modes are different. */ - round = fpc & FPC_RM_MASK; - - /* Set the rounding mode if changed. */ - if (__glibc_unlikely (round != r)) - { - ctx->updated_status = true; - libc_fesetround_s390 (r); - } - else - ctx->updated_status = false; -} - -#define libc_feholdsetround_ctx libc_feholdsetround_s390_ctx -#define libc_feholdsetroundf_ctx libc_feholdsetround_s390_ctx -#define libc_feholdsetroundl_ctx libc_feholdsetround_s390_ctx - -static __always_inline void -libc_feresetround_s390_ctx (struct rm_ctx *ctx) -{ - /* Restore the rounding mode if updated. */ - if (__glibc_unlikely (ctx->updated_status)) - { - fpu_control_t fpc; - _FPU_GETCW (fpc); - fpc = ctx->env.__fpc | (fpc & FPC_FLAGS_MASK); - _FPU_SETCW (fpc); - } -} - -#define libc_feresetround_ctx libc_feresetround_s390_ctx -#define libc_feresetroundf_ctx libc_feresetround_s390_ctx -#define libc_feresetroundl_ctx libc_feresetround_s390_ctx - -static __always_inline void -libc_feholdsetround_noex_s390_ctx (struct rm_ctx *ctx, int r) -{ - libc_feholdexcept_setround_s390 (&ctx->env, r); -} - -#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_s390_ctx -#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_s390_ctx -#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_s390_ctx - -static __always_inline void -libc_feresetround_noex_s390_ctx (struct rm_ctx *ctx) -{ - /* Restore exception flags and rounding mode. */ - libc_fesetenv_s390 (&ctx->env); -} - -#define libc_feresetround_noex_ctx libc_feresetround_noex_s390_ctx -#define libc_feresetround_noexf_ctx libc_feresetround_noex_s390_ctx -#define libc_feresetround_noexl_ctx libc_feresetround_noex_s390_ctx - -#endif diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c index 54ba2aa..c6c275d 100644 --- a/sysdeps/s390/fpu/fesetenv.c +++ b/sysdeps/s390/fpu/fesetenv.c @@ -17,13 +17,28 @@ License along with the GNU C Library; if not, see . */ -#include +#include +#include +#include +#include int __fesetenv (const fenv_t *envp) { - fenv_t env = libc_handle_user_fenv_s390 (envp); - libc_fesetenv_s390 (&env); + fenv_t env; + + if (envp == FE_DFL_ENV) + { + env.__fpc = _FPU_DEFAULT; + } + else if (envp == FE_NOMASK_ENV) + { + env.__fpc = FPC_EXCEPTION_MASK; + } + else + env = (*envp); + + _FPU_SETCW (env.__fpc); /* Success. */ return 0; diff --git a/sysdeps/s390/fpu/fesetround.c b/sysdeps/s390/fpu/fesetround.c index 0a7fe26..d8a84d2 100644 --- a/sysdeps/s390/fpu/fesetround.c +++ b/sysdeps/s390/fpu/fesetround.c @@ -17,18 +17,21 @@ License along with the GNU C Library; if not, see . */ -#include +#include +#include int __fesetround (int round) { - if ((round | FPC_RM_MASK) != FPC_RM_MASK) + if ((round|FPC_RM_MASK) != FPC_RM_MASK) { /* ROUND is not a valid rounding mode. */ return 1; } + __asm__ __volatile__ ("srnm 0(%0)" + : + : "a" (round)); - libc_fesetround_s390 (round); return 0; } libm_hidden_def (__fesetround) diff --git a/sysdeps/s390/fpu/fetestexceptflag.c b/sysdeps/s390/fpu/fetestexceptflag.c new file mode 100644 index 0000000..784d356 --- /dev/null +++ b/sysdeps/s390/fpu/fetestexceptflag.c @@ -0,0 +1,31 @@ +/* Test exception in saved exception state. S/390 version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +int +fetestexceptflag (const fexcept_t *flagp, int excepts) +{ + /* As *flagp is obtained by an earlier call of fegetexceptflag the + bits 0-5 of dxc-byte are either zero or correspond to the + flag-bits. Evaluate flags and last dxc-exception-code. */ + return (((*flagp >> FPC_FLAGS_SHIFT) | (*flagp >> FPC_DXC_SHIFT)) + & excepts + & FE_ALL_EXCEPT); +} diff --git a/sysdeps/s390/fpu/feupdateenv.c b/sysdeps/s390/fpu/feupdateenv.c index f6b3d7d..4888e1a 100644 --- a/sysdeps/s390/fpu/feupdateenv.c +++ b/sysdeps/s390/fpu/feupdateenv.c @@ -18,13 +18,21 @@ . */ -#include +#include +#include int __feupdateenv (const fenv_t *envp) { - fenv_t env = libc_handle_user_fenv_s390 (envp); - libc_feupdateenv_s390 (&env); + fexcept_t temp; + + _FPU_GETCW (temp); + temp = (temp & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT; + + /* Raise the exceptions since the last call to feholdenv */ + /* re install saved environment. */ + __fesetenv (envp); + __feraiseexcept ((int) temp); /* Success. */ return 0; diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c index 1985b39..2a0f6dc 100644 --- a/sysdeps/s390/fpu/fgetexcptflg.c +++ b/sysdeps/s390/fpu/fgetexcptflg.c @@ -17,12 +17,24 @@ License along with the GNU C Library; if not, see . */ -#include +#include +#include int fegetexceptflag (fexcept_t *flagp, int excepts) { - *flagp = libc_fetestexcept_s390 (excepts); + fexcept_t temp, newexcepts; + + /* Get the current exceptions. */ + _FPU_GETCW (temp); + newexcepts = excepts << FPC_FLAGS_SHIFT; + if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) + /* Bits 6, 7 of dxc-byte are zero, + thus bits 0-5 of dxc-byte correspond to the flag-bits. + Evaluate flags and last dxc-exception-code. */ + newexcepts |= excepts << FPC_DXC_SHIFT; + + *flagp = temp & newexcepts; /* Success. */ return 0; diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c index 51d258c..e50684c 100644 --- a/sysdeps/s390/fpu/fsetexcptflg.c +++ b/sysdeps/s390/fpu/fsetexcptflg.c @@ -24,26 +24,29 @@ int fesetexceptflag (const fexcept_t *flagp, int excepts) { - fexcept_t fpc, fpc_new; + fexcept_t temp, newexcepts; /* Get the current environment. We have to do this since we cannot separately set the status word. */ - _FPU_GETCW (fpc); - - /* Clear the current exception bits. */ - fpc_new = fpc & ~((excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT); - if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0) + _FPU_GETCW (temp); + /* Install the new exception bits in the Accrued Exception Byte. */ + excepts = excepts & FE_ALL_EXCEPT; + newexcepts = excepts << FPC_FLAGS_SHIFT; + temp &= ~newexcepts; + if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) /* Bits 6, 7 of dxc-byte are zero, thus bits 0-5 of dxc-byte correspond to the flag-bits. Clear given exceptions in dxc-field. */ - fpc_new &= ~((excepts & FE_ALL_EXCEPT) << FPC_DXC_SHIFT); + temp &= ~(excepts << FPC_DXC_SHIFT); - /* Set exceptions from flagp in flags-field. */ - fpc_new |= (*flagp & excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT; + /* Integrate dxc-byte of flagp into flags. The dxc-byte of flagp contains + either an ieee-exception or 0 (see fegetexceptflag). */ + temp |= (*flagp | ((*flagp >> FPC_DXC_SHIFT) << FPC_FLAGS_SHIFT)) + & newexcepts; /* Store the new status word (along with the rest of the environment. Possibly new exceptions are set but they won't get executed. */ - _FPU_SETCW (fpc_new); + _FPU_SETCW (temp); /* Success. */ return 0; diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c index f2acecc..727b9b3 100644 --- a/sysdeps/s390/fpu/ftestexcept.c +++ b/sysdeps/s390/fpu/ftestexcept.c @@ -17,11 +17,23 @@ License along with the GNU C Library; if not, see . */ -#include +#include +#include int fetestexcept (int excepts) { - return libc_fetestexcept_s390 (excepts); + fexcept_t temp, res; + + /* Get current exceptions. */ + _FPU_GETCW (temp); + res = temp >> FPC_FLAGS_SHIFT; + if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) + /* Bits 6, 7 of dxc-byte are zero, + thus bits 0-5 of dxc-byte correspond to the flag-bits. + Evaluate flags and last dxc-exception-code. */ + res |= temp >> FPC_DXC_SHIFT; + + return res & excepts & FE_ALL_EXCEPT; } libm_hidden_def (fetestexcept) diff --git a/sysdeps/s390/fpu/math-barriers.h b/sysdeps/s390/fpu/math-barriers.h deleted file mode 100644 index 7c3e6b1..0000000 --- a/sysdeps/s390/fpu/math-barriers.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Control when floating-point expressions are evaluated. s390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef S390_MATH_BARRIERS_H -#define S390_MATH_BARRIERS_H 1 - -#ifdef HAVE_S390_VX_GCC_SUPPORT -# define ASM_CONSTRAINT_VR "v" -#else -# define ASM_CONSTRAINT_VR -#endif - -#define math_opt_barrier(x) \ - ({ __typeof (x) __x = (x); \ - if (__builtin_types_compatible_p (__typeof (x), _Float128)) \ - __asm__ ("# math_opt_barrier_f128 %0" : "+fm" (__x)); \ - else \ - __asm__ ("# math_opt_barrier %0" \ - : "+f" ASM_CONSTRAINT_VR "m" (__x)); \ - __x; }) -#define math_force_eval(x) \ - ({ __typeof (x) __x = (x); \ - if (__builtin_types_compatible_p (__typeof (x), _Float128)) \ - __asm__ __volatile__ ("# math_force_eval_f128 %0" \ - : : "fm" (__x)); \ - else \ - __asm__ __volatile__ ("# math_force_eval %0" \ - : : "f" ASM_CONSTRAINT_VR "m" (__x)); \ - }) - -#endif diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h deleted file mode 100644 index 4c4aad2..0000000 --- a/sysdeps/s390/fpu/math-use-builtins.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Using math gcc builtins instead of generic implementation. s390/s390x version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef MATH_USE_BUILTINS_S390_H -#define MATH_USE_BUILTINS_S390_H 1 - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT - -# include /* For __GNUC_PREREQ. */ - -/* GCC emits the z196 zarch "load fp integer" instructions for these - builtins if build with at least --march=z196 -mzarch. Otherwise a - function call to libc is emitted. */ -# define USE_NEARBYINT_BUILTIN 1 -# define USE_NEARBYINTF_BUILTIN 1 -# define USE_NEARBYINTL_BUILTIN 1 - -# define USE_RINT_BUILTIN 1 -# define USE_RINTF_BUILTIN 1 -# define USE_RINTL_BUILTIN 1 - -# define USE_FLOOR_BUILTIN 1 -# define USE_FLOORF_BUILTIN 1 -# define USE_FLOORL_BUILTIN 1 - -# define USE_CEIL_BUILTIN 1 -# define USE_CEILF_BUILTIN 1 -# define USE_CEILL_BUILTIN 1 - -# define USE_TRUNC_BUILTIN 1 -# define USE_TRUNCF_BUILTIN 1 -# define USE_TRUNCL_BUILTIN 1 - -# define USE_ROUND_BUILTIN 1 -# define USE_ROUNDF_BUILTIN 1 -# define USE_ROUNDL_BUILTIN 1 - -# if __GNUC_PREREQ (8, 0) -# define USE_NEARBYINTF128_BUILTIN 1 -# define USE_RINTF128_BUILTIN 1 -# define USE_FLOORF128_BUILTIN 1 -# define USE_CEILF128_BUILTIN 1 -# define USE_TRUNCF128_BUILTIN 1 -# define USE_ROUNDF128_BUILTIN 1 -# else -# define USE_NEARBYINTF128_BUILTIN 0 -# define USE_RINTF128_BUILTIN 0 -# define USE_FLOORF128_BUILTIN 0 -# define USE_CEILF128_BUILTIN 0 -# define USE_TRUNCF128_BUILTIN 0 -# define USE_ROUNDF128_BUILTIN 0 -# endif - -#else - -/* Disable the builtins if we do not have the z196 zarch instructions. */ -# define USE_NEARBYINT_BUILTIN 0 -# define USE_NEARBYINTF_BUILTIN 0 -# define USE_NEARBYINTL_BUILTIN 0 -# define USE_NEARBYINTF128_BUILTIN 0 - -# define USE_RINT_BUILTIN 0 -# define USE_RINTF_BUILTIN 0 -# define USE_RINTL_BUILTIN 0 -# define USE_RINTF128_BUILTIN 0 - -# define USE_FLOOR_BUILTIN 0 -# define USE_FLOORF_BUILTIN 0 -# define USE_FLOORL_BUILTIN 0 -# define USE_FLOORF128_BUILTIN 0 - -# define USE_CEIL_BUILTIN 0 -# define USE_CEILF_BUILTIN 0 -# define USE_CEILL_BUILTIN 0 -# define USE_CEILF128_BUILTIN 0 - -# define USE_TRUNC_BUILTIN 0 -# define USE_TRUNCF_BUILTIN 0 -# define USE_TRUNCL_BUILTIN 0 -# define USE_TRUNCF128_BUILTIN 0 - -# define USE_ROUND_BUILTIN 0 -# define USE_ROUNDF_BUILTIN 0 -# define USE_ROUNDL_BUILTIN 0 -# define USE_ROUNDF128_BUILTIN 0 - -#endif /* ! HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT */ - -#define USE_COPYSIGNL_BUILTIN 1 -#if __GNUC_PREREQ (7, 0) -# define USE_COPYSIGNF128_BUILTIN 1 -#else -# define USE_COPYSIGNF128_BUILTIN 0 -#endif - -#endif /* math-use-builtins.h */ diff --git a/sysdeps/s390/fpu/math_private.h b/sysdeps/s390/fpu/math_private.h deleted file mode 100644 index f3c770d..0000000 --- a/sysdeps/s390/fpu/math_private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Configure optimized libm functions. S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef S390_MATH_PRIVATE_H -#define S390_MATH_PRIVATE_H 1 - -#include -#include - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# define TOINT_INTRINSICS 1 - -static inline double_t -roundtoint (double_t x) -{ - double_t y; - /* The z196 zarch "load fp integer" (fidbra) instruction is rounding - x to the nearest integer with ties away from zero (M3-field: 1) - where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("fidbra %0,1,%1,4" : "=f" (y) : "f" (x)); - return y; -} - -static inline int32_t -converttoint (double_t x) -{ - int32_t y; - /* The z196 zarch "convert to fixed" (cfdbra) instruction is rounding - x to the nearest integer with ties away from zero (M3-field: 1) - where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("cfdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); - return y; -} -#endif - -#include -#include_next - -#endif diff --git a/sysdeps/s390/fpu/s_llrint.c b/sysdeps/s390/fpu/s_llrint.c deleted file mode 100644 index edd796a..0000000 --- a/sysdeps/s390/fpu/s_llrint.c +++ /dev/null @@ -1,50 +0,0 @@ -/* llrint() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -/* We only support s390x as on s390 a long long int refers to a register pair - of two 4byte registers instead of a 8byte register which is produced by the - instruction. - Note: On s390 this instruction would only be used if build with -mzarch. */ -# include -# include - -long long int -__llrint (double x) -{ - long long int y; - /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding - according to current rounding mode (M3-field: 0). - First convert x with suppressed inexact exception and check if the - resulting value is beyond the target limits (indicated by cc=3; - Note: a nan is also indicated by cc=3). - If the resulting value is within the target limits, redo - without suppressing the inexact exception. */ - __asm__ ("cgdbra %0,0,%1,4 \n\t" - "jo 1f \n\t" - "cgdbra %0,0,%1,0 \n\t" - "1:" - : "=&d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_double (__llrint, llrint) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_llrintf.c b/sysdeps/s390/fpu/s_llrintf.c deleted file mode 100644 index 3cbe7c5..0000000 --- a/sysdeps/s390/fpu/s_llrintf.c +++ /dev/null @@ -1,50 +0,0 @@ -/* llrintf() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -/* We only support s390x as on s390 a long long int refers to a register pair - of two 4byte registers instead of a 8byte register which is produced by the - instruction. - Note: On s390 this instruction would only be used if build with -mzarch. */ -# include -# include - -long long int -__llrintf (float x) -{ - long long int y; - /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding - according to current rounding mode (M3-field: 0). - First convert x with suppressed inexact exception and check if the - resulting value is beyond the target limits (indicated by cc=3; - Note: a nan is also indicated by cc=3). - If the resulting value is within the target limits, redo - without suppressing the inexact exception. */ - __asm__ ("cgebra %0,0,%1,4 \n\t" - "jo 1f \n\t" - "cgebra %0,0,%1,0 \n\t" - "1:" - : "=&d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_float (__llrint, llrint) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_llrintl.c b/sysdeps/s390/fpu/s_llrintl.c deleted file mode 100644 index 37eea59..0000000 --- a/sysdeps/s390/fpu/s_llrintl.c +++ /dev/null @@ -1,51 +0,0 @@ -/* llrintl() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -/* We only support s390x as on s390 a long long int refers to a register pair - of two 4byte registers instead of a 8byte register which is produced by the - instruction. - Note: On s390 this instruction would only be used if build with -mzarch. */ -# include -# include -# include - -long long int -__llrintl (_Float128 x) -{ - long long int y; - /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding - according to current rounding mode (M3-field: 0). - First convert x with suppressed inexact exception and check if the - resulting value is beyond the target limits (indicated by cc=3; - Note: a nan is also indicated by cc=3). - If the resulting value is within the target limits, redo - without suppressing the inexact exception. */ - __asm__ ("cgxbra %0,0,%1,4 \n\t" - "jo 1f \n\t" - "cgxbra %0,0,%1,0 \n\t" - "1:" - : "=&d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_ldouble (__llrint, llrint) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_llround.c b/sysdeps/s390/fpu/s_llround.c deleted file mode 100644 index f4a1b21..0000000 --- a/sysdeps/s390/fpu/s_llround.c +++ /dev/null @@ -1,42 +0,0 @@ -/* llround() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -/* We only support s390x as on s390 a long long int refers to a register pair - of two 4byte registers instead of a 8byte register which is produced by the - instruction. - Note: On s390 this instruction would only be used if build with -mzarch. */ -# include -# include - -long long int -__llround (double x) -{ - long long int y; - /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding - x to the nearest integer with "ties away from 0" rounding mode - (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("cgdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_double (__llround, llround) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_llroundf.c b/sysdeps/s390/fpu/s_llroundf.c deleted file mode 100644 index d202f4b..0000000 --- a/sysdeps/s390/fpu/s_llroundf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* llroundf() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -/* We only support s390x as on s390 a long long int refers to a register pair - of two 4byte registers instead of a 8byte register which is produced by the - instruction. - Note: On s390 this instruction would only be used if build with -mzarch. */ -# include -# include - -long long int -__llroundf (float x) -{ - long long int y; - /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding - x to the nearest integer with "ties away from 0" rounding mode - (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("cgebra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_float (__llround, llround) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_llroundl.c b/sysdeps/s390/fpu/s_llroundl.c deleted file mode 100644 index 58976cd..0000000 --- a/sysdeps/s390/fpu/s_llroundl.c +++ /dev/null @@ -1,43 +0,0 @@ -/* llroundl() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -/* We only support s390x as on s390 a long long int refers to a register pair - of two 4byte registers instead of a 8byte register which is produced by the - instruction. - Note: On s390 this instruction would only be used if build with -mzarch. */ -# include -# include -# include - -long long int -__llroundl (_Float128 x) -{ - long long int y; - /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding - x to the nearest integer with "ties away from 0" rounding mode - (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("cgxbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_ldouble (__llround, llround) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_lrint.c b/sysdeps/s390/fpu/s_lrint.c deleted file mode 100644 index 7be6066..0000000 --- a/sysdeps/s390/fpu/s_lrint.c +++ /dev/null @@ -1,55 +0,0 @@ -/* lrint() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include - -/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). - Thus we need different instructions as the target size is encoded there. - Note: On s390 this instruction is only used if build with -mzarch. */ -# ifdef __s390x__ -# define INSN "cgdbra" -# else -# define INSN "cfdbra" -# endif - -long int -__lrint (double x) -{ - long int y; - /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding - according to current rounding mode (M3-field: 0). - First convert x with suppressed inexact exception and check if the - resulting value is beyond the target limits (indicated by cc=3; - Note: a nan is also indicated by cc=3). - If the resulting value is within the target limits, redo - without suppressing the inexact exception. */ - __asm__ (INSN " %0,0,%1,4 \n\t" - "jo 1f \n\t" - INSN " %0,0,%1,0 \n\t" - "1:" - : "=&d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_double (__lrint, lrint) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_lrintf.c b/sysdeps/s390/fpu/s_lrintf.c deleted file mode 100644 index d6a2a40..0000000 --- a/sysdeps/s390/fpu/s_lrintf.c +++ /dev/null @@ -1,55 +0,0 @@ -/* lrintf() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include - -/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). - Thus we need different instructions as the target size is encoded there. - Note: On s390 this instruction is only used if build with -mzarch. */ -# ifdef __s390x__ -# define INSN "cgebra" -# else -# define INSN "cfebra" -# endif - -long int -__lrintf (float x) -{ - long int y; - /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding - according to current rounding mode (M3-field: 0). - First convert x with suppressed inexact exception and check if the - resulting value is beyond the target limits (indicated by cc=3; - Note: a nan is also indicated by cc=3). - If the resulting value is within the target limits, redo - without suppressing the inexact exception. */ - __asm__ (INSN " %0,0,%1,4 \n\t" - "jo 1f \n\t" - INSN " %0,0,%1,0 \n\t" - "1:" - : "=&d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_float (__lrint, lrint) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_lrintl.c b/sysdeps/s390/fpu/s_lrintl.c deleted file mode 100644 index 2d386ec..0000000 --- a/sysdeps/s390/fpu/s_lrintl.c +++ /dev/null @@ -1,56 +0,0 @@ -/* lrintl() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include -# include - -/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). - Thus we need different instructions as the target size is encoded there. - Note: On s390 this instruction is only used if build with -mzarch. */ -# ifdef __s390x__ -# define INSN "cgxbra" -# else -# define INSN "cfxbra" -# endif - -long int -__lrintl (_Float128 x) -{ - long int y; - /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding - according to current rounding mode (M3-field: 0). - First convert x with suppressed inexact exception and check if the - resulting value is beyond the target limits (indicated by cc=3; - Note: a nan is also indicated by cc=3). - If the resulting value is within the target limits, redo - without suppressing the inexact exception. */ - __asm__ (INSN " %0,0,%1,4 \n\t" - "jo 1f \n\t" - INSN " %0,0,%1,0 \n\t" - "1:" - : "=&d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_ldouble (__lrint, lrint) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_lround.c b/sysdeps/s390/fpu/s_lround.c deleted file mode 100644 index 9290ec3..0000000 --- a/sysdeps/s390/fpu/s_lround.c +++ /dev/null @@ -1,47 +0,0 @@ -/* lround() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include - -/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). - Thus we need different instructions as the target size is encoded there. - Note: On s390 this instruction is only used if build with -mzarch. */ -# ifdef __s390x__ -# define INSN "cgdbra" -# else -# define INSN "cfdbra" -# endif - -long int -__lround (double x) -{ - long int y; - /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding - x to the nearest integer with "ties away from 0" rounding mode - (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_double (__lround, lround) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_lroundf.c b/sysdeps/s390/fpu/s_lroundf.c deleted file mode 100644 index 097b924..0000000 --- a/sysdeps/s390/fpu/s_lroundf.c +++ /dev/null @@ -1,47 +0,0 @@ -/* lroundf() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include - -/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). - Thus we need different instructions as the target size is encoded there. - Note: On s390 this instruction is only used if build with -mzarch. */ -# ifdef __s390x__ -# define INSN "cgebra" -# else -# define INSN "cfebra" -# endif - -long int -__lroundf (float x) -{ - long int y; - /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding - x to the nearest integer with "ties away from 0" rounding mode - (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_float (__lround, lround) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_lroundl.c b/sysdeps/s390/fpu/s_lroundl.c deleted file mode 100644 index 0ef77dc..0000000 --- a/sysdeps/s390/fpu/s_lroundl.c +++ /dev/null @@ -1,48 +0,0 @@ -/* lroundl() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include -# include - -/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte). - Thus we need different instructions as the target size is encoded there. - Note: On s390 this instruction is only used if build with -mzarch. */ -# ifdef __s390x__ -# define INSN "cgxbra" -# else -# define INSN "cfxbra" -# endif - -long int -__lroundl (_Float128 x) -{ - long int y; - /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding - x to the nearest integer with "ties away from 0" rounding mode - (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc"); - return y; -} -libm_alias_ldouble (__lround, lround) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_roundeven.c b/sysdeps/s390/fpu/s_roundeven.c deleted file mode 100644 index 95a83a7..0000000 --- a/sysdeps/s390/fpu/s_roundeven.c +++ /dev/null @@ -1,39 +0,0 @@ -/* roundeven() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include - -double -__roundeven (double x) -{ - double y; - /* The z196 zarch "load fp integer" (fidbra) instruction is rounding - x to the nearest integer with "ties to even" rounding mode - (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("fidbra %0,4,%1,4" : "=f" (y) : "f" (x)); - return y; -} -hidden_def (__roundeven) -libm_alias_double (__roundeven, roundeven) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_roundevenf.c b/sysdeps/s390/fpu/s_roundevenf.c deleted file mode 100644 index c620a01..0000000 --- a/sysdeps/s390/fpu/s_roundevenf.c +++ /dev/null @@ -1,38 +0,0 @@ -/* roundevenf() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include - -float -__roundevenf (float x) -{ - float y; - /* The z196 zarch "load fp integer" (fiebra) instruction is rounding - x to the nearest integer with "ties to even" rounding mode - (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("fiebra %0,4,%1,4" : "=f" (y) : "f" (x)); - return y; -} -libm_alias_float (__roundeven, roundeven) - -#else -# include -#endif diff --git a/sysdeps/s390/fpu/s_roundevenl.c b/sysdeps/s390/fpu/s_roundevenl.c deleted file mode 100644 index 3481af2..0000000 --- a/sysdeps/s390/fpu/s_roundevenl.c +++ /dev/null @@ -1,39 +0,0 @@ -/* roundevenl() - S390 version. - Copyright (C) 2019 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT -# include -# include -# include - -_Float128 -__roundevenl (_Float128 x) -{ - _Float128 y; - /* The z196 zarch "load fp integer" (fixbra) instruction is rounding - x to the nearest integer with "ties to even" rounding mode - (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4). */ - __asm__ ("fixbra %0,4,%1,4" : "=f" (y) : "f" (x)); - return y; -} -libm_alias_ldouble (__roundeven, roundeven) - -#else -# include -#endif diff --git a/sysdeps/s390/ifunc-memccpy.h b/sysdeps/s390/ifunc-memccpy.h deleted file mode 100644 index 8f7a1d0..0000000 --- a/sysdeps/s390/ifunc-memccpy.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-memchr.h b/sysdeps/s390/ifunc-memchr.h deleted file mode 100644 index 5d1327b..0000000 --- a/sysdeps/s390/ifunc-memchr.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-memcmp.h b/sysdeps/s390/ifunc-memcmp.h deleted file mode 100644 index 536ac45..0000000 --- a/sysdeps/s390/ifunc-memcmp.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h deleted file mode 100644 index e8cd794..0000000 --- a/sysdeps/s390/ifunc-memcpy.h +++ /dev/null @@ -1,122 +0,0 @@ -/* 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 defined SHARED && defined USE_MULTIARCH && IS_IN (libc) \ - && ! defined HAVE_S390_MIN_ARCH13_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 - -#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 -# 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 - -#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 - -#if HAVE_MEMMOVE_ARCH13 -# define MEMMOVE_ARCH13 __memmove_arch13 -#else -# define MEMMOVE_ARCH13 NULL -#endif diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h deleted file mode 100644 index 48079b2..0000000 --- a/sysdeps/s390/ifunc-memmem.h +++ /dev/null @@ -1,76 +0,0 @@ -/* 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_ARCH13_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 - -#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 -# 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 - -#if HAVE_MEMMEM_ARCH13 -# define MEMMEM_ARCH13 __memmem_arch13 -#else -# define MEMMEM_ARCH13 NULL -#endif diff --git a/sysdeps/s390/ifunc-memrchr.h b/sysdeps/s390/ifunc-memrchr.h deleted file mode 100644 index 9d80d55..0000000 --- a/sysdeps/s390/ifunc-memrchr.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-memset.h b/sysdeps/s390/ifunc-memset.h deleted file mode 100644 index 32bc155..0000000 --- a/sysdeps/s390/ifunc-memset.h +++ /dev/null @@ -1,74 +0,0 @@ -/* 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 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 -#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 -# 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/ifunc-rawmemchr.h b/sysdeps/s390/ifunc-rawmemchr.h deleted file mode 100644 index bfcbeae..0000000 --- a/sysdeps/s390/ifunc-rawmemchr.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-stpcpy.h b/sysdeps/s390/ifunc-stpcpy.h deleted file mode 100644 index 9a70cd7..0000000 --- a/sysdeps/s390/ifunc-stpcpy.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-stpncpy.h b/sysdeps/s390/ifunc-stpncpy.h deleted file mode 100644 index 46e5733..0000000 --- a/sysdeps/s390/ifunc-stpncpy.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strcat.h b/sysdeps/s390/ifunc-strcat.h deleted file mode 100644 index 6fd2f7d..0000000 --- a/sysdeps/s390/ifunc-strcat.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strchr.h b/sysdeps/s390/ifunc-strchr.h deleted file mode 100644 index cfeb00e..0000000 --- a/sysdeps/s390/ifunc-strchr.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strchrnul.h b/sysdeps/s390/ifunc-strchrnul.h deleted file mode 100644 index cac817e..0000000 --- a/sysdeps/s390/ifunc-strchrnul.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strcmp.h b/sysdeps/s390/ifunc-strcmp.h deleted file mode 100644 index 86ffe68..0000000 --- a/sysdeps/s390/ifunc-strcmp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strcpy.h b/sysdeps/s390/ifunc-strcpy.h deleted file mode 100644 index 85e4555..0000000 --- a/sysdeps/s390/ifunc-strcpy.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strcspn.h b/sysdeps/s390/ifunc-strcspn.h deleted file mode 100644 index 9b70325..0000000 --- a/sysdeps/s390/ifunc-strcspn.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strlen.h b/sysdeps/s390/ifunc-strlen.h deleted file mode 100644 index f207059..0000000 --- a/sysdeps/s390/ifunc-strlen.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strncat.h b/sysdeps/s390/ifunc-strncat.h deleted file mode 100644 index bb164dc..0000000 --- a/sysdeps/s390/ifunc-strncat.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strncmp.h b/sysdeps/s390/ifunc-strncmp.h deleted file mode 100644 index 511b3e9..0000000 --- a/sysdeps/s390/ifunc-strncmp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strncpy.h b/sysdeps/s390/ifunc-strncpy.h deleted file mode 100644 index 31e87e9..0000000 --- a/sysdeps/s390/ifunc-strncpy.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strnlen.h b/sysdeps/s390/ifunc-strnlen.h deleted file mode 100644 index e923298..0000000 --- a/sysdeps/s390/ifunc-strnlen.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strpbrk.h b/sysdeps/s390/ifunc-strpbrk.h deleted file mode 100644 index 4a3138c..0000000 --- a/sysdeps/s390/ifunc-strpbrk.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strrchr.h b/sysdeps/s390/ifunc-strrchr.h deleted file mode 100644 index 7185fc3..0000000 --- a/sysdeps/s390/ifunc-strrchr.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strspn.h b/sysdeps/s390/ifunc-strspn.h deleted file mode 100644 index 1152ba1..0000000 --- a/sysdeps/s390/ifunc-strspn.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h deleted file mode 100644 index 809184d..0000000 --- a/sysdeps/s390/ifunc-strstr.h +++ /dev/null @@ -1,76 +0,0 @@ -/* 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_ARCH13_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 - -#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 -# 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 - -#if HAVE_STRSTR_ARCH13 -# define STRSTR_ARCH13 __strstr_arch13 -#else -# define STRSTR_ARCH13 NULL -#endif diff --git a/sysdeps/s390/ifunc-wcpcpy.h b/sysdeps/s390/ifunc-wcpcpy.h deleted file mode 100644 index 0d5e2ba..0000000 --- a/sysdeps/s390/ifunc-wcpcpy.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcpncpy.h b/sysdeps/s390/ifunc-wcpncpy.h deleted file mode 100644 index 0dd5633..0000000 --- a/sysdeps/s390/ifunc-wcpncpy.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcscat.h b/sysdeps/s390/ifunc-wcscat.h deleted file mode 100644 index fecae21..0000000 --- a/sysdeps/s390/ifunc-wcscat.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcschr.h b/sysdeps/s390/ifunc-wcschr.h deleted file mode 100644 index 2fe9110..0000000 --- a/sysdeps/s390/ifunc-wcschr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcschrnul.h b/sysdeps/s390/ifunc-wcschrnul.h deleted file mode 100644 index 39d4120..0000000 --- a/sysdeps/s390/ifunc-wcschrnul.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcscmp.h b/sysdeps/s390/ifunc-wcscmp.h deleted file mode 100644 index 99fe021..0000000 --- a/sysdeps/s390/ifunc-wcscmp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-wcscpy.h b/sysdeps/s390/ifunc-wcscpy.h deleted file mode 100644 index fba7c9c..0000000 --- a/sysdeps/s390/ifunc-wcscpy.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcscspn.h b/sysdeps/s390/ifunc-wcscspn.h deleted file mode 100644 index 23f3667..0000000 --- a/sysdeps/s390/ifunc-wcscspn.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcslen.h b/sysdeps/s390/ifunc-wcslen.h deleted file mode 100644 index 50d879c..0000000 --- a/sysdeps/s390/ifunc-wcslen.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcsncat.h b/sysdeps/s390/ifunc-wcsncat.h deleted file mode 100644 index 99495e0..0000000 --- a/sysdeps/s390/ifunc-wcsncat.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcsncmp.h b/sysdeps/s390/ifunc-wcsncmp.h deleted file mode 100644 index 3a22bc9..0000000 --- a/sysdeps/s390/ifunc-wcsncmp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-wcsncpy.h b/sysdeps/s390/ifunc-wcsncpy.h deleted file mode 100644 index d7beca1..0000000 --- a/sysdeps/s390/ifunc-wcsncpy.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcsnlen.h b/sysdeps/s390/ifunc-wcsnlen.h deleted file mode 100644 index b5b21da..0000000 --- a/sysdeps/s390/ifunc-wcsnlen.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcspbrk.h b/sysdeps/s390/ifunc-wcspbrk.h deleted file mode 100644 index d3b9b73..0000000 --- a/sysdeps/s390/ifunc-wcspbrk.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcsrchr.h b/sysdeps/s390/ifunc-wcsrchr.h deleted file mode 100644 index 4eec0c1..0000000 --- a/sysdeps/s390/ifunc-wcsrchr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wcsspn.h b/sysdeps/s390/ifunc-wcsspn.h deleted file mode 100644 index 1189c6b..0000000 --- a/sysdeps/s390/ifunc-wcsspn.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wmemchr.h b/sysdeps/s390/ifunc-wmemchr.h deleted file mode 100644 index 0610cfb..0000000 --- a/sysdeps/s390/ifunc-wmemchr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/ifunc-wmemcmp.h b/sysdeps/s390/ifunc-wmemcmp.h deleted file mode 100644 index 1b38a01..0000000 --- a/sysdeps/s390/ifunc-wmemcmp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/ifunc-wmemset.h b/sysdeps/s390/ifunc-wmemset.h deleted file mode 100644 index c9d1d17..0000000 --- a/sysdeps/s390/ifunc-wmemset.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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/memccpy-c.c b/sysdeps/s390/memccpy-c.c deleted file mode 100644 index 2b2f81e..0000000 --- a/sysdeps/s390/memccpy-c.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Default memccpy implementation for S/390. - 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 - . */ - -#include - -#if HAVE_MEMCCPY_C -# if HAVE_MEMCCPY_IFUNC -# define MEMCCPY MEMCCPY_C -# undef weak_alias -# define weak_alias(a, b) -#endif - -# include -#endif diff --git a/sysdeps/s390/memccpy-vx.S b/sysdeps/s390/memccpy-vx.S deleted file mode 100644 index 44f7bc5..0000000 --- a/sysdeps/s390/memccpy-vx.S +++ /dev/null @@ -1,164 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of memccpy. - 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 - . */ - -#include - -#if HAVE_MEMCCPY_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* void *memccpy (void * dest, const void *src, int c, size_t n) - Copies no more than n bytes from src to dest, - stopping when the character c is found - and returns pointer next to c in dest or null if c not found. - - Register usage: - -r0=tmp - -r1=tmp - -r2=dest - -r3=src - -r4=c - -r5=n - -r6=current_len - -v16=part of s - -v17=index of found c - -v18=c replicated - -v19=part #2 of s - -v31=save area for r6 -*/ -ENTRY(MEMCCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r5,%r5 -# endif /* !defined __s390x__ */ - - vlvgp %v31,%r6,%r7 /* Save registers. */ - clgije %r5,0,.Lnf_end /* If len == 0 then exit. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r0,%r0 /* Convert 32bit to 64bit. */ - - vlvgb %v18,%r4,0 /* Generate vector which elements are all c. - if c > 255, c will be truncated. */ - vrepb %v18,%v18,0 - lghi %r6,0 /* current_len = 0. */ - - clgrjle %r5,%r0,.Lremaining_v16 /* If maxlen <= loaded-bytes - -> Process remaining. */ - - vfeebs %v17,%v16,%v18 /* Find c. */ - vlgvb %r1,%v17,7 /* Load byte index of c. */ - clgrjl %r1,%r0,.Lfound_v16 /* Found c is within loaded bytes. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r6,15 /* current_len = 15. */ - slr %r6,%r1 /* Compute highest index to 16byte boundary. */ - - vstl %v16,%r6,0(%r2) /* Store prcessed bytes */ - ahi %r6,1 - -.Lpreloop1: - /* Now we are 16byte aligned, so we can load - a full vreg without page fault. */ - vl %v16,0(%r6,%r3) /* Load s. */ - clgijl %r5,17,.Lremaining_v16 /* If n <= 16, - process remaining bytes. */ - lgr %r7,%r5 - slgfi %r7,16 /* border_len = n - 16. */ - j .Lloop1 - -.Lloop2: - vl %v16,16(%r6,%r3) - vst %v19,0(%r6,%r2) - aghi %r6,16 - -.Lloop1: - clgrjhe %r6,%r7,.Lremaining_v16 /* If current_len >= border - then process remaining bytes. */ - vfeebs %v17,%v16,%v18 /* Find c. */ - jl .Lfound_v16 /* Jump away if c was found. */ - vl %v19,16(%r6,%r3) /* Load next s part. */ - vst %v16,0(%r6,%r2) /* Store previous part without c. */ - aghi %r6,16 - - clgrjhe %r6,%r7,.Lremaining_v19 - vfeebs %v17,%v19,%v18 - jl .Lfound_v19 - vl %v16,16(%r6,%r3) - vst %v19,0(%r6,%r2) - aghi %r6,16 - - clgrjhe %r6,%r7,.Lremaining_v16 - vfeebs %v17,%v16,%v18 - jl .Lfound_v16 - vl %v19,16(%r6,%r3) - vst %v16,0(%r6,%r2) - aghi %r6,16 - - clgrjhe %r6,%r7,.Lremaining_v19 - vfeebs %v17,%v19,%v18 - jo .Lloop2 - -.Lfound_v19: - vlr %v16,%v19 -.Lfound_v16: - /* v16 contains c. Store remaining bytes to c. currlen hasn´t - reached border, thus checking for maxlen is not needed! */ - vlgvb %r1,%v17,7 /* Load byte index of c. */ - la %r2,0(%r6,%r2) /* vstl has no support for index-register. */ -.Lfound_v16_store: - vstl %v16,%r1,0(%r2) /* Copy bytes including c. */ - la %r2,1(%r1,%r2) /* Return pointer next to c in dest. */ - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - br %r14 - -.Lremaining_v19: - vlr %v16,%v19 -.Lremaining_v16: - /* v16 contains the remaining bytes [1...16]. - Check and store remaining bytes. */ - vfeebs %v17,%v16,%v18 - slgrk %r7,%r5,%r6 /* Remaining bytes = maxlen - current_len. */ - aghi %r7,-1 /* vstl needs highest index. */ - la %r2,0(%r6,%r2) /* vstl has no index register. */ - vlgvb %r1,%v17,7 /* Load index of c or 16 if not found. */ - /* c in remaining bytes? -> Jump away (c-index <= max-index) */ - clrjle %r1,%r7,.Lfound_v16_store - vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ - -.Lnf_end: - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - lghi %r2,0 /* Return null. */ - br %r14 -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/memccpy.c b/sysdeps/s390/memccpy.c deleted file mode 100644 index bcfeb31..0000000 --- a/sysdeps/s390/memccpy.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of memccpy. - 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 - . */ - -#include - -#if HAVE_MEMCCPY_IFUNC -# include -# include - -# if HAVE_MEMCCPY_C -extern __typeof (__memccpy) MEMCCPY_C attribute_hidden; -# endif - -# 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/memchr-vx.S b/sysdeps/s390/memchr-vx.S deleted file mode 100644 index 274e797..0000000 --- a/sysdeps/s390/memchr-vx.S +++ /dev/null @@ -1,163 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version 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 - . */ - -#include -#if HAVE_MEMCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* void *memchr (const void *s, int c, size_t n) - Scans memory for character c - and returns pointer to first c. - - Register usage: - -r0=tmp - -r1=tmp - -r2=s - -r3=c - -r4=n - -r5=current_len - -v16=part of s - -v17=index of found c - -v18=c replicated -*/ -ENTRY(MEMCHR_Z13) - - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgije %r4,0,.Lnf_end /* If len == 0 then exit. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r0,%r0 /* Convert 32bit to 64bit. */ - - vlvgb %v18,%r3,0 /* Generate vector which elements are all c. - if c > 255, c will be truncated. */ - vrepb %v18,%v18,0 - lghi %r5,16 /* current_len = 16. */ - - clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n, - jump to lastcmp. */ - - vfeebs %v17,%v16,%v18 /* Find c. */ - vlgvb %r1,%v17,7 /* Load byte index of c. */ - clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ - - lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ - aghi %r0,64 - clgrjl %r0,%r4,.Lloop64 -.Llt64: - vl %v16,0(%r5,%r2) - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */ - vfeebs %v17,%v16,%v18 /* Find c. */ - jl .Lfound /* Jump away if c was found. */ - - vl %v16,0(%r5,%r2) - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp - vfeebs %v17,%v16,%v18 - jl .Lfound - - vl %v16,0(%r5,%r2) - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp - vfeebs %v17,%v16,%v18 - jl .Lfound - - vl %v16,0(%r5,%r2) - aghi %r5,16 - -.Llastcmp: - /* Use comparision result only if located within first n characters. - %r5: current_len; - %r4: n; - (current_len - n): [0...16[ - first ignored match index: vr-width - (current_len - n) ]0...16] - */ - vfeebs %v17,%v16,%v18 /* Find c. */ - slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */ - lghi %r0,16 /* Register width = 16. */ - vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */ - slr %r0,%r4 /* %r0 = first ignored match index. */ - clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */ - /* c not found within n-bytes. */ -.Lnf_end: - lghi %r2,0 /* Return null. */ - br %r14 - -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound0: - aghi %r5,16 -.Lfound: - vlgvb %r1,%v17,7 /* Load byte index of c. */ -.Lfound2: - slgfi %r5,16 /* current_len -=16 */ - algr %r5,%r1 /* Zero byte index is added to current len. */ - la %r2,0(%r5,%r2) /* Return pointer to c. */ - br %r14 - - -.Lloop64: - vl %v16,0(%r5,%r2) - vfeebs %v17,%v16,%v18 /* Find c. */ - jl .Lfound0 /* Jump away if c was found. */ - vl %v16,16(%r5,%r2) - vfeebs %v17,%v16,%v18 - jl .Lfound16 - vl %v16,32(%r5,%r2) - vfeebs %v17,%v16,%v18 - jl .Lfound32 - vl %v16,48(%r5,%r2) - vfeebs %v17,%v16,%v18 - jl .Lfound48 - - aghi %r5,64 - lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ - aghi %r0,64 - clgrjl %r0,%r4,.Lloop64 - - j .Llt64 -END(MEMCHR_Z13) - -# if ! HAVE_MEMCHR_IFUNC -strong_alias (MEMCHR_Z13, __memchr) -weak_alias (__memchr, memchr) -# endif - -# if ! HAVE_MEMCHR_Z900_G5 && defined SHARED && IS_IN (libc) -strong_alias (MEMCHR_Z13, __GI_memchr) -# endif -#endif diff --git a/sysdeps/s390/memchr-z900.S b/sysdeps/s390/memchr-z900.S deleted file mode 100644 index c016bc4..0000000 --- a/sysdeps/s390/memchr-z900.S +++ /dev/null @@ -1,63 +0,0 @@ -/* 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. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for 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 to memory area - %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_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 -1: br %r14 -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/memchr.c b/sysdeps/s390/memchr.c deleted file mode 100644 index 490f1b6..0000000 --- a/sysdeps/s390/memchr.c +++ /dev/null @@ -1,41 +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 - . */ - -#include - -#if HAVE_MEMCHR_IFUNC -# define memchr __redirect_memchr -# include -# undef memchr -# include - -# 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/memcmp-z900.S b/sysdeps/s390/memcmp-z900.S deleted file mode 100644 index c3b3677..0000000 --- a/sysdeps/s390/memcmp-z900.S +++ /dev/null @@ -1,173 +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" -#include - -/* INPUT PARAMETERS - %r2 = address of first memory area - %r3 = address of second memory area - %r4 = number of bytes to compare. */ - - .text - -#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 - 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) -END(MEMCMP_Z900_G5) -# undef LTGR -# undef AGHI -# undef BRCTG -#endif /* HAVE_MEMCMP_Z900_G5 */ - -#if HAVE_MEMCMP_Z10 -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 - srlg %r1,%r4,8 - cgijlh %r1,0,.L_Z10_12 -.L_Z10_3: - exrl %r4,.L_Z10_15 -.L_Z10_4: - ipm %r2 - sllg %r2,%r2,34 - srag %r2,%r2,62 - 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) - brctg %r1,.L_Z10_12 - j .L_Z10_3 -.L_Z10_15: - clc 0(1,%r3),0(%r2) -END(MEMCMP_Z10) -#endif /* HAVE_MEMCMP_Z10 */ - -#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 */ - -#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 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.c b/sysdeps/s390/memcmp.c deleted file mode 100644 index 6d92763..0000000 --- a/sysdeps/s390/memcmp.c +++ /dev/null @@ -1,49 +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 - . */ - -#include -#if HAVE_MEMCMP_IFUNC -# define memcmp __redirect_memcmp -# include -# undef memcmp -# include - -# 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_expr_stfle_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/memcopy.h b/sysdeps/s390/memcopy.h deleted file mode 100644 index 9a76196..0000000 --- a/sysdeps/s390/memcopy.h +++ /dev/null @@ -1,23 +0,0 @@ -/* 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/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S deleted file mode 100644 index 45eddc6..0000000 --- a/sysdeps/s390/memcpy-z900.S +++ /dev/null @@ -1,366 +0,0 @@ -/* 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. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for 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" -#include - -/* INPUT PARAMETERS - %r2 = address of destination memory area - %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__ */ - -#if HAVE_MEMCPY_Z900_G5 -ENTRY(MEMPCPY_Z900_G5) -# if defined __s390x__ - .machine "z900" -# else - .machine "g5" -# endif /* ! defined __s390x__ */ - LGR %r1,%r2 # Use as dest - la %r2,0(%r4,%r2) # Return dest + n - j .L_Z900_G5_start -END(MEMPCPY_Z900_G5) - -ENTRY(MEMCPY_Z900_G5) -# if defined __s390x__ - .machine "z900" -# 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_G5_13: - CGHI %r5,4096 # Switch to mvcle for copies >1MB - jh __memcpy_mvcle -.L_Z900_G5_12: - mvc 0(256,%r1),0(%r3) - la %r1,256(%r1) - la %r3,256(%r3) - BRCTG %r5,.L_Z900_G5_12 - j .L_Z900_G5_3 -.L_Z900_G5_15: - mvc 0(1,%r1),0(%r3) -END(MEMCPY_Z900_G5) -#endif /* HAVE_MEMCPY_Z900_G5 */ - -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 -.L_MVCLE_1: - mvcle %r2,%r4,0 # thats it, MVCLE is your friend - jo .L_MVCLE_1 - LGR %r2,%r0 # return destination address - br %r14 -END(__memcpy_mvcle) - -#undef LTGR -#undef CGHI -#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 -.L_Z196_start2: - 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_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_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. */ -strong_alias (MEMCPY_DEFAULT, memcpy) -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/memcpy.c b/sysdeps/s390/memcpy.c deleted file mode 100644 index 0ff24f1..0000000 --- a/sysdeps/s390/memcpy.c +++ /dev/null @@ -1,49 +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 - . */ - -#include - -#if HAVE_MEMCPY_IFUNC -# define memcpy __redirect_memcpy -# include -# undef memcpy -# include - -# 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_expr_stfle_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/memmem-arch13.S b/sysdeps/s390/memmem-arch13.S deleted file mode 100644 index b59d60a..0000000 --- a/sysdeps/s390/memmem-arch13.S +++ /dev/null @@ -1,161 +0,0 @@ -/* 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-c.c b/sysdeps/s390/memmem-c.c deleted file mode 100644 index 1d8ffef..0000000 --- a/sysdeps/s390/memmem-c.c +++ /dev/null @@ -1,47 +0,0 @@ -/* 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 deleted file mode 100644 index e5608be..0000000 --- a/sysdeps/s390/memmem-vx.c +++ /dev/null @@ -1,61 +0,0 @@ -/* 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 || MEMMEM_Z13_ONLY_USED_AS_FALLBACK - -# 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 || MEMMEM_Z13_ONLY_USED_AS_FALLBACK -# 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 deleted file mode 100644 index 28871cd..0000000 --- a/sysdeps/s390/memmem.c +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 - -# if HAVE_MEMMEM_ARCH13 -extern __typeof (__redirect_memmem) MEMMEM_ARCH13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (__redirect_memmem, __memmem, - (HAVE_MEMMEM_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)) - ? MEMMEM_ARCH13 - : (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX)) - ? MEMMEM_Z13 - : MEMMEM_DEFAULT - ) -weak_alias (__memmem, memmem) -#endif diff --git a/sysdeps/s390/memmove-c.c b/sysdeps/s390/memmove-c.c deleted file mode 100644 index be57109..0000000 --- a/sysdeps/s390/memmove-c.c +++ /dev/null @@ -1,37 +0,0 @@ -/* 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 deleted file mode 100644 index f6d31a4..0000000 --- a/sysdeps/s390/memmove.c +++ /dev/null @@ -1,54 +0,0 @@ -/* 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 - -# if HAVE_MEMMOVE_ARCH13 -extern __typeof (__redirect_memmove) MEMMOVE_ARCH13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (__redirect_memmove, memmove, - ({ - 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/mempcpy.S b/sysdeps/s390/mempcpy.S new file mode 100644 index 0000000..18ef292 --- /dev/null +++ b/sysdeps/s390/mempcpy.S @@ -0,0 +1,19 @@ +/* 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/mempcpy.c b/sysdeps/s390/mempcpy.c deleted file mode 100644 index b687b33..0000000 --- a/sysdeps/s390/mempcpy.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Multiple versions of mempcpy. - 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_MEMCPY_IFUNC -# define mempcpy __redirect_mempcpy -# define __mempcpy __redirect___mempcpy -# define __NO_STRING_INLINES -# define NO_MEMPCPY_STPCPY_REDIRECT -# include -# undef mempcpy -# undef __mempcpy -# include - -# 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_expr_stfle_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/memrchr-c.c b/sysdeps/s390/memrchr-c.c deleted file mode 100644 index 333c0fc..0000000 --- a/sysdeps/s390/memrchr-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default memrchr implementation for S/390. - 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 - . */ - -#include - -#if HAVE_MEMRCHR_C -# if HAVE_MEMRCHR_IFUNC -# define MEMRCHR MEMRCHR_C -# endif - -# include -#endif diff --git a/sysdeps/s390/memrchr-vx.S b/sysdeps/s390/memrchr-vx.S deleted file mode 100644 index ba832f1..0000000 --- a/sysdeps/s390/memrchr-vx.S +++ /dev/null @@ -1,168 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of memrchr. - 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 - . */ - -#include - -#if HAVE_MEMRCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* void *memrchr (const void *s, int c, size_t n) - Scans memory for character c backwards - and returns pointer to first c. - - Register usage: - -r0=tmp - -r1=tmp - -r2=s - -r3=c - -r4=n - -r5=s in loop - - -v16=part of s - -v17=index of found c - -v18=c replicated - -v20=permute pattern -*/ -ENTRY(MEMRCHR_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - clgije %r4,0,.Lnot_found - - vlvgb %v18,%r3,0 /* Generate vector which elements are all c. - If c > 255, c will be truncated. */ - vrepb %v18,%v18,0 - - llcr %r3,%r3 /* char c_char = (char) c. */ - - /* check byte n - 1. */ - llc %r0,-1(%r4,%r2) - slgfi %r4,1 - clrje %r0,%r3,.Lfound_end - jh .Lnot_found /* Return NULL if n is now 0. */ - - larl %r1,.Lpermute_mask /* Load permute mask. */ - vl %v20,0(%r1) - - /* check byte n - 2. */ - llc %r0,-1(%r4,%r2) - slgfi %r4,1 - clrje %r0,%r3,.Lfound_end - jh .Lnot_found /* Return NULL if n is now 0. */ - - clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ - -.Llt64: - /* Process n < 64 bytes. */ - clgijl %r4,16,.Llt16 /* Jump away if n < 16. */ - aghi %r4,-16 - vl %v16,0(%r4,%r2) - vfeebs %v17,%v16,%v18 - jno .Lfound0 - clgijl %r4,16,.Llt16 - aghi %r4,-16 - vl %v16,0(%r4,%r2) - vfeebs %v17,%v16,%v18 - jno .Lfound0 - clgijl %r4,16,.Llt16 - aghi %r4,-16 - vl %v16,0(%r4,%r2) - vfeebs %v17,%v16,%v18 - jno .Lfound0 -.Llt16: - clgfi %r4,0 /* if remaining bytes == 0, return NULL. */ - locghie %r2,0 - ber %r14 - - aghi %r4,-1 /* vll needs highest index. */ - vll %v16,%r4,0(%r2) /* Load remaining bytes. */ - - /* Right-shift of v16 to mask bytes after highest index. */ - lhi %r0,15 - slr %r0,%r4 /* Compute byte count for vector shift right. */ - sll %r0,3 /* Convert to bit count. */ - vlvgb %v17,%r0,7 - vsrlb %v16,%v16,%v17 /* Vector shift right by byte by number of bytes - specified in bits 1-4 of byte 7 in v17. */ - j .Lfound_permute - -.Lfound48: - aghi %r4,16 -.Lfound32: - aghi %r4,16 -.Lfound16: - aghi %r4,16 -.Lfound0: - la %r2,0(%r4,%r2) /* Set pointer to start of v16. */ - lghi %r4,15 /* Set highest index in v16 to last index. */ -.Lfound_permute: - /* Search for a c in v16 in reversed byte order. v16 contains %r4 + 1 - bytes. If v16 was not fully loaded, the bytes are already - right shifted, so that the bytes in v16 can simply be reversed. */ - vperm %v16,%v16,%v16,%v20 /* Permute v16 to reversed order. */ - vfeeb %v16,%v16,%v18 /* Find c in reversed v16. */ - vlgvb %r1,%v16,7 /* Index of c or 16 if not found. */ - - /* Return NULL if there is no c in loaded bytes. */ - clrjh %r1,%r4,.Lnot_found - - slgr %r4,%r1 -.Lfound_end: - la %r2,0(%r4,%r2) /* Return pointer to c. */ - br %r14 - -.Lnot_found: - lghi %r2,0 - br %r14 - -.Lpermute_mask: - .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 - .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 - -.Lloop64: - aghi %r4,-64 - vl %v16,48(%r4,%r2) /* Load 16bytes of memory area. */ - vfeebs %v17,%v16,%v18 /* Find c. */ - jno .Lfound48 /* Jump away if c was found. */ - vl %v16,32(%r4,%r2) - vfeebs %v17,%v16,%v18 - jno .Lfound32 - vl %v16,16(%r4,%r2) - vfeebs %v17,%v16,%v18 - jno .Lfound16 - vl %v16,0(%r4,%r2) - vfeebs %v17,%v16,%v18 - jno .Lfound0 - - clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ - j .Llt64 -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/memrchr.c b/sysdeps/s390/memrchr.c deleted file mode 100644 index d995e99..0000000 --- a/sysdeps/s390/memrchr.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of memrchr. - 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 - . */ - -#include - -#if HAVE_MEMRCHR_IFUNC -# include -# include - -# if HAVE_MEMRCHR_C -extern __typeof (__memrchr) MEMRCHR_C attribute_hidden; -# endif - -# 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/memset-z900.S b/sysdeps/s390/memset-z900.S deleted file mode 100644 index bfc659a..0000000 --- a/sysdeps/s390/memset-z900.S +++ /dev/null @@ -1,219 +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" -#include - -/* INPUT PARAMETERS - MEMSET - %r2 = address of memory area - %r3 = byte to fill memory with - %r4 = number of bytes to fill. - - INPUT PARAMETERS - BZERO - %r2 = address of memory area - %r3 = number of bytes to fill. */ - - .text - -#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(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 - .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) -END(MEMSET_Z900_G5) -# undef LTGR -# undef CGHI -# undef LGR -# undef AGHI -# undef BRCTG -#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__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - cgije %r4,0,.L_Z10_4 - stc %r3,0(%r2) - lgr %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) -#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__ - 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 - lgr %r1,%r3 # move pad byte to R1 - lgr %r3,%r4 # move length to r3 - 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 - lgr %r2,%r0 # return value is source address -.L1: - br %r14 -END(__memset_mvcle) -#endif /* HAVE_MEMSET_MVCLE */ - -#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) -/* 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) -/* 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.c b/sysdeps/s390/memset.c deleted file mode 100644 index 75b011f..0000000 --- a/sysdeps/s390/memset.c +++ /dev/null @@ -1,48 +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 - . */ - -#include -#if HAVE_MEMSET_IFUNC -# define memset __redirect_memset -# include -# undef memset -# include - -# 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_expr_stfle_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 fec3615..c893ebc 100644 --- a/sysdeps/s390/multiarch/Makefile +++ b/sysdeps/s390/multiarch/Makefile @@ -1,3 +1,49 @@ +ifeq ($(subdir),string) +sysdep_routines += strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ + memccpy memccpy-vx memccpy-c \ + memrchr memrchr-vx memrchr-c \ + mempcpy +endif + +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 \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ + wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c +endif + ifeq ($(subdir),iconvdata) override define generate-8bit-table $(make-target-directory) diff --git a/sysdeps/s390/multiarch/gconv_simple.c b/sysdeps/s390/multiarch/gconv_simple.c index 078d992..aaa1ebf 100644 --- a/sysdeps/s390/multiarch/gconv_simple.c +++ b/sysdeps/s390/multiarch/gconv_simple.c @@ -27,18 +27,17 @@ # define ICONV_C_NAME(NAME) __##NAME##_c # define ICONV_VX_NAME(NAME) __##NAME##_vx -# 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_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); \ + } # define ICONV_VX_SINGLE(NAME) \ static __typeof (NAME##_single) __##NAME##_vx_single __attribute__((alias(#NAME "_single"))); diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c index 787d406..ec3373a 100644 --- a/sysdeps/s390/multiarch/ifunc-impl-list.c +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c @@ -21,50 +21,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* Maximum number of IFUNC implementations. */ #define MAX_IFUNC 3 @@ -90,599 +46,107 @@ __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) -# endif -# if HAVE_MEMSET_Z10 + S390_IS_Z196 (stfle_bits), __memset_z196) IFUNC_IMPL_ADD (array, i, memset, - S390_IS_Z10 (stfle_bits), MEMSET_Z10) -# 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 */ - -#if HAVE_MEMCMP_IFUNC + S390_IS_Z10 (stfle_bits), __memset_z10) + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_default)) + IFUNC_IMPL (i, name, memcmp, -# if HAVE_MEMCMP_Z196 IFUNC_IMPL_ADD (array, i, memcmp, - S390_IS_Z196 (stfle_bits), MEMCMP_Z196) -# endif -# if HAVE_MEMCMP_Z10 + S390_IS_Z196 (stfle_bits), __memcmp_z196) IFUNC_IMPL_ADD (array, i, memcmp, - 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 */ - -#if HAVE_MEMCPY_IFUNC + S390_IS_Z10 (stfle_bits), __memcmp_z10) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_default)) + +#ifdef SHARED + IFUNC_IMPL (i, name, memcpy, -# if HAVE_MEMCPY_Z196 IFUNC_IMPL_ADD (array, i, memcpy, - S390_IS_Z196 (stfle_bits), MEMCPY_Z196) -# endif -# if HAVE_MEMCPY_Z10 + S390_IS_Z196 (stfle_bits), __memcpy_z196) IFUNC_IMPL_ADD (array, i, memcpy, - S390_IS_Z10 (stfle_bits), MEMCPY_Z10) -# endif -# if HAVE_MEMCPY_Z900_G5 - IFUNC_IMPL_ADD (array, i, memcpy, 1, MEMCPY_Z900_G5) -# endif - ) + S390_IS_Z10 (stfle_bits), __memcpy_z10) + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default)) IFUNC_IMPL (i, name, mempcpy, -# if HAVE_MEMCPY_Z196 IFUNC_IMPL_ADD (array, i, mempcpy, - S390_IS_Z196 (stfle_bits), MEMPCPY_Z196) -# endif -# if HAVE_MEMCPY_Z10 + S390_IS_Z196 (stfle_bits), ____mempcpy_z196) IFUNC_IMPL_ADD (array, i, mempcpy, - 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 */ - -#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) -# endif -# if HAVE_MEMMOVE_C - IFUNC_IMPL_ADD (array, i, memmove, 1, MEMMOVE_C) -# endif - ) -#endif /* HAVE_MEMMOVE_IFUNC */ - -#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) -# endif -# if HAVE_STRSTR_C - IFUNC_IMPL_ADD (array, i, strstr, 1, STRSTR_C) -# endif - ) -#endif /* HAVE_STRSTR_IFUNC */ - -#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) -# endif -# if HAVE_MEMMEM_C - IFUNC_IMPL_ADD (array, i, memmem, 1, MEMMEM_C) -# endif - ) -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ - -#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 */ + S390_IS_Z10 (stfle_bits), ____mempcpy_z10) + IFUNC_IMPL_ADD (array, i, mempcpy, 1, ____mempcpy_default)) + +#endif /* SHARED */ + +#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 (strlen); + IFUNC_VX_IMPL (wcslen); + + IFUNC_VX_IMPL (strnlen); + IFUNC_VX_IMPL (wcsnlen); + + IFUNC_VX_IMPL (strcpy); + IFUNC_VX_IMPL (wcscpy); + + IFUNC_VX_IMPL (stpcpy); + IFUNC_VX_IMPL (wcpcpy); + + IFUNC_VX_IMPL (strncpy); + IFUNC_VX_IMPL (wcsncpy); + + IFUNC_VX_IMPL (stpncpy); + IFUNC_VX_IMPL (wcpncpy); + + IFUNC_VX_IMPL (strcat); + IFUNC_VX_IMPL (wcscat); + + IFUNC_VX_IMPL (strncat); + IFUNC_VX_IMPL (wcsncat); + + IFUNC_VX_IMPL (strcmp); + IFUNC_VX_IMPL (wcscmp); + + IFUNC_VX_IMPL (strncmp); + IFUNC_VX_IMPL (wcsncmp); + + IFUNC_VX_IMPL (strchr); + IFUNC_VX_IMPL (wcschr); + + IFUNC_VX_IMPL (strchrnul); + IFUNC_VX_IMPL (wcschrnul); + + IFUNC_VX_IMPL (strrchr); + IFUNC_VX_IMPL (wcsrchr); + + IFUNC_VX_IMPL (strspn); + IFUNC_VX_IMPL (wcsspn); + + IFUNC_VX_IMPL (strpbrk); + IFUNC_VX_IMPL (wcspbrk); + + IFUNC_VX_IMPL (strcspn); + IFUNC_VX_IMPL (wcscspn); + + IFUNC_VX_IMPL (memchr); + IFUNC_VX_IMPL (wmemchr); + IFUNC_VX_IMPL (rawmemchr); + + IFUNC_VX_IMPL (memccpy); + + IFUNC_VX_IMPL (wmemset); + + IFUNC_VX_IMPL (wmemcmp); + + IFUNC_VX_IMPL (memrchr); + +#endif /* HAVE_S390_VX_ASM_SUPPORT */ return i; } diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h index db735bb..b42ed92 100644 --- a/sysdeps/s390/multiarch/ifunc-resolve.h +++ b/sysdeps/s390/multiarch/ifunc-resolve.h @@ -22,11 +22,6 @@ #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) @@ -45,15 +40,50 @@ ".machine pop" "\n" \ : "=QS" (STFLE_BITS), "+d" (reg0) \ : : "cc"); -#define s390_libc_ifunc_expr_stfle_init() \ +#define s390_libc_ifunc_init() \ unsigned long long stfle_bits = 0ULL; \ - if (__glibc_likely ((hwcap & HWCAP_S390_STFLE) \ - && (hwcap & HWCAP_S390_ZARCH) \ - && (hwcap & HWCAP_S390_HIGH_GPRS))) \ + if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE) \ + && (dl_hwcap & HWCAP_S390_ZARCH) \ + && (dl_hwcap & HWCAP_S390_HIGH_GPRS))) \ { \ 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 dl_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, \ + (dl_hwcap & HWCAP_S390_VX) \ + ? RESOLVERFUNC##_vx \ + : RESOLVERFUNC##_c, \ + unsigned long int dl_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/sysdeps/s390/multiarch/memccpy-c.c b/sysdeps/s390/multiarch/memccpy-c.c new file mode 100644 index 0000000..1f4c548 --- /dev/null +++ b/sysdeps/s390/multiarch/memccpy-c.c @@ -0,0 +1,25 @@ +/* Default memccpy implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define MEMCCPY __memccpy_c + +# include +extern __typeof (__memccpy) __memccpy_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/memccpy-vx.S b/sysdeps/s390/multiarch/memccpy-vx.S new file mode 100644 index 0000000..150aa0e --- /dev/null +++ b/sysdeps/s390/multiarch/memccpy-vx.S @@ -0,0 +1,156 @@ +/* Vector optimized 32/64 bit S/390 version of memccpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* void *memccpy (void * dest, const void *src, int c, size_t n) + Copies no more than n bytes from src to dest, + stopping when the character c is found + and returns pointer next to c in dest or null if c not found. + + Register usage: + -r0=tmp + -r1=tmp + -r2=dest + -r3=src + -r4=c + -r5=n + -r6=current_len + -v16=part of s + -v17=index of found c + -v18=c replicated + -v19=part #2 of s + -v31=save area for r6 +*/ +ENTRY(__memccpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r5,%r5 +# endif /* !defined __s390x__ */ + + vlvgp %v31,%r6,%r7 /* Save registers. */ + clgije %r5,0,.Lnf_end /* If len == 0 then exit. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r0,%r0 /* Convert 32bit to 64bit. */ + + vlvgb %v18,%r4,0 /* Generate vector which elements are all c. + if c > 255, c will be truncated. */ + vrepb %v18,%v18,0 + lghi %r6,0 /* current_len = 0. */ + + clgrjle %r5,%r0,.Lremaining_v16 /* If maxlen <= loaded-bytes + -> Process remaining. */ + + vfeebs %v17,%v16,%v18 /* Find c. */ + vlgvb %r1,%v17,7 /* Load byte index of c. */ + clgrjl %r1,%r0,.Lfound_v16 /* Found c is within loaded bytes. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r6,15 /* current_len = 15. */ + slr %r6,%r1 /* Compute highest index to 16byte boundary. */ + + vstl %v16,%r6,0(%r2) /* Store prcessed bytes */ + ahi %r6,1 + +.Lpreloop1: + /* Now we are 16byte aligned, so we can load + a full vreg without page fault. */ + vl %v16,0(%r6,%r3) /* Load s. */ + clgijl %r5,17,.Lremaining_v16 /* If n <= 16, + process remaining bytes. */ + lgr %r7,%r5 + slgfi %r7,16 /* border_len = n - 16. */ + j .Lloop1 + +.Lloop2: + vl %v16,16(%r6,%r3) + vst %v19,0(%r6,%r2) + aghi %r6,16 + +.Lloop1: + clgrjhe %r6,%r7,.Lremaining_v16 /* If current_len >= border + then process remaining bytes. */ + vfeebs %v17,%v16,%v18 /* Find c. */ + jl .Lfound_v16 /* Jump away if c was found. */ + vl %v19,16(%r6,%r3) /* Load next s part. */ + vst %v16,0(%r6,%r2) /* Store previous part without c. */ + aghi %r6,16 + + clgrjhe %r6,%r7,.Lremaining_v19 + vfeebs %v17,%v19,%v18 + jl .Lfound_v19 + vl %v16,16(%r6,%r3) + vst %v19,0(%r6,%r2) + aghi %r6,16 + + clgrjhe %r6,%r7,.Lremaining_v16 + vfeebs %v17,%v16,%v18 + jl .Lfound_v16 + vl %v19,16(%r6,%r3) + vst %v16,0(%r6,%r2) + aghi %r6,16 + + clgrjhe %r6,%r7,.Lremaining_v19 + vfeebs %v17,%v19,%v18 + jo .Lloop2 + +.Lfound_v19: + vlr %v16,%v19 +.Lfound_v16: + /* v16 contains c. Store remaining bytes to c. currlen hasn´t + reached border, thus checking for maxlen is not needed! */ + vlgvb %r1,%v17,7 /* Load byte index of c. */ + la %r2,0(%r6,%r2) /* vstl has no support for index-register. */ +.Lfound_v16_store: + vstl %v16,%r1,0(%r2) /* Copy bytes including c. */ + la %r2,1(%r1,%r2) /* Return pointer next to c in dest. */ + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + br %r14 + +.Lremaining_v19: + vlr %v16,%v19 +.Lremaining_v16: + /* v16 contains the remaining bytes [1...16]. + Check and store remaining bytes. */ + vfeebs %v17,%v16,%v18 + slgrk %r7,%r5,%r6 /* Remaining bytes = maxlen - current_len. */ + aghi %r7,-1 /* vstl needs highest index. */ + la %r2,0(%r6,%r2) /* vstl has no index register. */ + vlgvb %r1,%v17,7 /* Load index of c or 16 if not found. */ + /* c in remaining bytes? -> Jump away (c-index <= max-index) */ + clrjle %r1,%r7,.Lfound_v16_store + vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ + +.Lnf_end: + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + lghi %r2,0 /* Return null. */ + br %r14 +END(__memccpy_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/memccpy.c b/sysdeps/s390/multiarch/memccpy.c new file mode 100644 index 0000000..30aae82 --- /dev/null +++ b/sysdeps/s390/multiarch/memccpy.c @@ -0,0 +1,28 @@ +/* Multiple versions of memccpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__memccpy) +weak_alias (__memccpy, memccpy) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/memchr-vx.S b/sysdeps/s390/multiarch/memchr-vx.S new file mode 100644 index 0000000..77d31e0 --- /dev/null +++ b/sysdeps/s390/multiarch/memchr-vx.S @@ -0,0 +1,159 @@ +/* Vector optimized 32/64 bit S/390 version 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* void *memchr (const void *s, int c, size_t n) + Scans memory for character c + and returns pointer to first c. + + Register usage: + -r0=tmp + -r1=tmp + -r2=s + -r3=c + -r4=n + -r5=current_len + -v16=part of s + -v17=index of found c + -v18=c replicated +*/ +ENTRY(__memchr_vx) + + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgije %r4,0,.Lnf_end /* If len == 0 then exit. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r0,%r0 /* Convert 32bit to 64bit. */ + + vlvgb %v18,%r3,0 /* Generate vector which elements are all c. + if c > 255, c will be truncated. */ + vrepb %v18,%v18,0 + lghi %r5,16 /* current_len = 16. */ + + clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n, + jump to lastcmp. */ + + vfeebs %v17,%v16,%v18 /* Find c. */ + vlgvb %r1,%v17,7 /* Load byte index of c. */ + clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ + + lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ + aghi %r0,64 + clgrjl %r0,%r4,.Lloop64 +.Llt64: + vl %v16,0(%r5,%r2) + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */ + vfeebs %v17,%v16,%v18 /* Find c. */ + jl .Lfound /* Jump away if c was found. */ + + vl %v16,0(%r5,%r2) + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp + vfeebs %v17,%v16,%v18 + jl .Lfound + + vl %v16,0(%r5,%r2) + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp + vfeebs %v17,%v16,%v18 + jl .Lfound + + vl %v16,0(%r5,%r2) + aghi %r5,16 + +.Llastcmp: + /* Use comparision result only if located within first n characters. + %r5: current_len; + %r4: n; + (current_len - n): [0...16[ + first ignored match index: vr-width - (current_len - n) ]0...16] + */ + vfeebs %v17,%v16,%v18 /* Find c. */ + slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */ + lghi %r0,16 /* Register width = 16. */ + vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */ + slr %r0,%r4 /* %r0 = first ignored match index. */ + clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */ + /* c not found within n-bytes. */ +.Lnf_end: + lghi %r2,0 /* Return null. */ + br %r14 + +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound0: + aghi %r5,16 +.Lfound: + vlgvb %r1,%v17,7 /* Load byte index of c. */ +.Lfound2: + slgfi %r5,16 /* current_len -=16 */ + algr %r5,%r1 /* Zero byte index is added to current len. */ + la %r2,0(%r5,%r2) /* Return pointer to c. */ + br %r14 + + +.Lloop64: + vl %v16,0(%r5,%r2) + vfeebs %v17,%v16,%v18 /* Find c. */ + jl .Lfound0 /* Jump away if c was found. */ + vl %v16,16(%r5,%r2) + vfeebs %v17,%v16,%v18 + jl .Lfound16 + vl %v16,32(%r5,%r2) + vfeebs %v17,%v16,%v18 + jl .Lfound32 + vl %v16,48(%r5,%r2) + vfeebs %v17,%v16,%v18 + jl .Lfound48 + + aghi %r5,64 + lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ + aghi %r0,64 + clgrjl %r0,%r4,.Lloop64 + + j .Llt64 +END(__memchr_vx) + +# 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) */ + +#include diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/multiarch/memchr.c new file mode 100644 index 0000000..3885eba --- /dev/null +++ b/sysdeps/s390/multiarch/memchr.c @@ -0,0 +1,27 @@ +/* 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define memchr __redirect_memchr +# include +# undef memchr +# include + +s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr) + +#endif diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/multiarch/mempcpy.c new file mode 100644 index 0000000..363fe47 --- /dev/null +++ b/sysdeps/s390/multiarch/mempcpy.c @@ -0,0 +1,32 @@ +/* Multiple versions of mempcpy. + 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 + . */ + + +#if defined SHARED && IS_IN (libc) +# define mempcpy __redirect_mempcpy +# define __mempcpy __redirect___mempcpy +# define __NO_STRING_INLINES +# define NO_MEMPCPY_STPCPY_REDIRECT +# include +# undef mempcpy +# undef __mempcpy +# include + +s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy) +weak_alias (__mempcpy, mempcpy); +#endif diff --git a/sysdeps/s390/multiarch/memrchr-c.c b/sysdeps/s390/multiarch/memrchr-c.c new file mode 100644 index 0000000..1e3c914 --- /dev/null +++ b/sysdeps/s390/multiarch/memrchr-c.c @@ -0,0 +1,25 @@ +/* Default memrchr implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define MEMRCHR __memrchr_c + +# include +extern __typeof (__memrchr) __memrchr_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/memrchr-vx.S b/sysdeps/s390/multiarch/memrchr-vx.S new file mode 100644 index 0000000..8e81f5e --- /dev/null +++ b/sysdeps/s390/multiarch/memrchr-vx.S @@ -0,0 +1,160 @@ +/* Vector optimized 32/64 bit S/390 version of memrchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* void *memrchr (const void *s, int c, size_t n) + Scans memory for character c backwards + and returns pointer to first c. + + Register usage: + -r0=tmp + -r1=tmp + -r2=s + -r3=c + -r4=n + -r5=s in loop + + -v16=part of s + -v17=index of found c + -v18=c replicated + -v20=permute pattern +*/ +ENTRY(__memrchr_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + clgije %r4,0,.Lnot_found + + vlvgb %v18,%r3,0 /* Generate vector which elements are all c. + If c > 255, c will be truncated. */ + vrepb %v18,%v18,0 + + llcr %r3,%r3 /* char c_char = (char) c. */ + + /* check byte n - 1. */ + llc %r0,-1(%r4,%r2) + slgfi %r4,1 + clrje %r0,%r3,.Lfound_end + jh .Lnot_found /* Return NULL if n is now 0. */ + + larl %r1,.Lpermute_mask /* Load permute mask. */ + vl %v20,0(%r1) + + /* check byte n - 2. */ + llc %r0,-1(%r4,%r2) + slgfi %r4,1 + clrje %r0,%r3,.Lfound_end + jh .Lnot_found /* Return NULL if n is now 0. */ + + clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ + +.Llt64: + /* Process n < 64 bytes. */ + clgijl %r4,16,.Llt16 /* Jump away if n < 16. */ + aghi %r4,-16 + vl %v16,0(%r4,%r2) + vfeebs %v17,%v16,%v18 + jno .Lfound0 + clgijl %r4,16,.Llt16 + aghi %r4,-16 + vl %v16,0(%r4,%r2) + vfeebs %v17,%v16,%v18 + jno .Lfound0 + clgijl %r4,16,.Llt16 + aghi %r4,-16 + vl %v16,0(%r4,%r2) + vfeebs %v17,%v16,%v18 + jno .Lfound0 +.Llt16: + clgfi %r4,0 /* if remaining bytes == 0, return NULL. */ + locghie %r2,0 + ber %r14 + + aghi %r4,-1 /* vll needs highest index. */ + vll %v16,%r4,0(%r2) /* Load remaining bytes. */ + + /* Right-shift of v16 to mask bytes after highest index. */ + lhi %r0,15 + slr %r0,%r4 /* Compute byte count for vector shift right. */ + sll %r0,3 /* Convert to bit count. */ + vlvgb %v17,%r0,7 + vsrlb %v16,%v16,%v17 /* Vector shift right by byte by number of bytes + specified in bits 1-4 of byte 7 in v17. */ + j .Lfound_permute + +.Lfound48: + aghi %r4,16 +.Lfound32: + aghi %r4,16 +.Lfound16: + aghi %r4,16 +.Lfound0: + la %r2,0(%r4,%r2) /* Set pointer to start of v16. */ + lghi %r4,15 /* Set highest index in v16 to last index. */ +.Lfound_permute: + /* Search for a c in v16 in reversed byte order. v16 contains %r4 + 1 + bytes. If v16 was not fully loaded, the bytes are already + right shifted, so that the bytes in v16 can simply be reversed. */ + vperm %v16,%v16,%v16,%v20 /* Permute v16 to reversed order. */ + vfeeb %v16,%v16,%v18 /* Find c in reversed v16. */ + vlgvb %r1,%v16,7 /* Index of c or 16 if not found. */ + + /* Return NULL if there is no c in loaded bytes. */ + clrjh %r1,%r4,.Lnot_found + + slgr %r4,%r1 +.Lfound_end: + la %r2,0(%r4,%r2) /* Return pointer to c. */ + br %r14 + +.Lnot_found: + lghi %r2,0 + br %r14 + +.Lpermute_mask: + .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 + .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 + +.Lloop64: + aghi %r4,-64 + vl %v16,48(%r4,%r2) /* Load 16bytes of memory area. */ + vfeebs %v17,%v16,%v18 /* Find c. */ + jno .Lfound48 /* Jump away if c was found. */ + vl %v16,32(%r4,%r2) + vfeebs %v17,%v16,%v18 + jno .Lfound32 + vl %v16,16(%r4,%r2) + vfeebs %v17,%v16,%v18 + jno .Lfound16 + vl %v16,0(%r4,%r2) + vfeebs %v17,%v16,%v18 + jno .Lfound0 + + clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ + j .Llt64 +END(__memrchr_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/memrchr.c b/sysdeps/s390/multiarch/memrchr.c new file mode 100644 index 0000000..43a44ab --- /dev/null +++ b/sysdeps/s390/multiarch/memrchr.c @@ -0,0 +1,28 @@ +/* Multiple versions of memrchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__memrchr) +weak_alias (__memrchr, memrchr) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/rawmemchr-c.c b/sysdeps/s390/multiarch/rawmemchr-c.c new file mode 100644 index 0000000..f43c883 --- /dev/null +++ b/sysdeps/s390/multiarch/rawmemchr-c.c @@ -0,0 +1,34 @@ +/* Default rawmemchr implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# 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 */ + +extern __typeof (rawmemchr) __rawmemchr_c attribute_hidden; + +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/rawmemchr-vx.S b/sysdeps/s390/multiarch/rawmemchr-vx.S new file mode 100644 index 0000000..d5778be --- /dev/null +++ b/sysdeps/s390/multiarch/rawmemchr-vx.S @@ -0,0 +1,92 @@ +/* Vector optimized 32/64 bit S/390 version of rawmemchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* void *rawmemchr (const void *s, int c) + Scans memory for character c + and returns pointer to first c. + + Register usage: + -r1=tmp + -r2=s + -r3=c + -r4=tmp + -r5=current_len + -v16=part of s + -v17=index of unequal + -v18=c replicated +*/ +ENTRY(__rawmemchr_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vlvgb %v18,%r3,0 /* Generate vector which elements are all c. + If c > 255, c will be truncated. */ + vrepb %v18,%v18,0 + + vfeeb %v17,%v16,%v18 /* Vector find element equal. */ + vlgvb %r5,%v17,7 /* Load byte index of character or zero. */ + clrjl %r5,%r1,.Lend_found /* If found c is in loaded bytes, end. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 + slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ + + /* Find c in a 16byte aligned loop. */ +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfeebs %v17,%v16,%v18 /* Vector find element equal. */ + jno .Lcharacter /* Jump away if element found. */ + vl %v16,16(%r5,%r2) + vfeebs %v17,%v16,%v18 + jno .Lcharacter16 + vl %v16,32(%r5,%r2) + vfeebs %v17,%v16,%v18 + jno .Lcharacter32 + vl %v16,48(%r5,%r2) + vfeebs %v17,%v16,%v18 + jno .Lcharacter48 + + aghi %r5,64 + j .Lloop /* No character found -> loop. */ + + /* Found character. */ +.Lcharacter48: + aghi %r5,16 +.Lcharacter32: + aghi %r5,16 +.Lcharacter16: + aghi %r5,16 +.Lcharacter: + vlgvb %r1,%v17,7 /* Load byte index of character. */ + algr %r5,%r1 +.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) */ diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/multiarch/rawmemchr.c new file mode 100644 index 0000000..5fdb225 --- /dev/null +++ b/sysdeps/s390/multiarch/rawmemchr.c @@ -0,0 +1,31 @@ +/* Multiple versions of rawmemchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define __rawmemchr __redirect___rawmemchr +# include +# undef __rawmemchr +# include + +s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr + , __rawmemchr) +weak_alias (__rawmemchr, rawmemchr) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/multiarch/stpcpy-c.c new file mode 100644 index 0000000..4a1c3e5 --- /dev/null +++ b/sysdeps/s390/multiarch/stpcpy-c.c @@ -0,0 +1,35 @@ +/* Default stpcpy implementation for S/390. + 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 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) \ + __hidden_ver1 (__stpcpy_c, __GI___stpcpy, __stpcpy_c); +# 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 */ + + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/multiarch/stpcpy-vx.S new file mode 100644 index 0000000..6c17def --- /dev/null +++ b/sysdeps/s390/multiarch/stpcpy-vx.S @@ -0,0 +1,104 @@ +/* Vector optimized 32/64 bit S/390 version of stpcpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char * stpcpy (const char *dest, const char *src) + Copy string src to dest returning a pointer to its end. + + Register usage: + -r1=tmp + -r2=dest and return value + -r3=src + -r4=tmp + -r5=current_len + -v16=part of src + -v17=index of zero + -v18=part of src +*/ +ENTRY(__stpcpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, + copy bytes before and return. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r4 /* Compute highest index to 16byte boundary. */ + + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Find zero in 16byte aligned loop. */ +.Lloop: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16_0 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezbs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + j .Lloop /* No zero found -> loop. */ + +.Lfound_v16_32: + aghi %r5,32 +.Lfound_v16_0: + la %r3,0(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ + la %r2,0(%r1,%r3) /* Return pointer to zero. */ + br %r14 + +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + la %r3,16(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ + la %r2,0(%r1,%r3) /* Return pointer to zero. */ + br %r14 + +.Lfound_align: + 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) */ diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/multiarch/stpcpy.c new file mode 100644 index 0000000..654f9df --- /dev/null +++ b/sysdeps/s390/multiarch/stpcpy.c @@ -0,0 +1,35 @@ +/* Multiple versions of stpcpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define stpcpy __redirect_stpcpy +# define __stpcpy __redirect___stpcpy +/* Omit the stpcpy inline definitions because it would redefine stpcpy. */ +# define __NO_STRING_INLINES +# define NO_MEMPCPY_STPCPY_REDIRECT +# include +# undef stpcpy +# undef __stpcpy +# include + +s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy); +weak_alias (__stpcpy, stpcpy) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/stpncpy-c.c b/sysdeps/s390/multiarch/stpncpy-c.c new file mode 100644 index 0000000..45e50aa --- /dev/null +++ b/sysdeps/s390/multiarch/stpncpy-c.c @@ -0,0 +1,28 @@ +/* Default stpncpy implementation for S/390. + 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 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 +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/stpncpy-vx.S b/sysdeps/s390/multiarch/stpncpy-vx.S new file mode 100644 index 0000000..922bd7a --- /dev/null +++ b/sysdeps/s390/multiarch/stpncpy-vx.S @@ -0,0 +1,200 @@ +/* Vector optimized 32/64 bit S/390 version of stpncpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char * stpncpy (char *dest, const char *src, size_t n) + Copies at most n characters of string src to dest + returning a pointer to its end or dest+n + if src is smaller than n. + + Register usage: + -%r0 = return value + -%r1 = zero byte index + -%r2 = curr dst pointer + -%r3 = curr src pointer + -%r4 = n + -%r5 = current_len + -%r6 = loaded bytes + -%r7 = border, tmp +*/ +ENTRY(__stpncpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgfi %r4,0 + ber %r14 /* Nothing to do, if n == 0. */ + + la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */ + vlvgp %v31,%r6,%r7 /* Save registers. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r6,%r6 /* Convert 32bit to 64bit. */ + + lghi %r5,0 /* current_len = 0. */ + + clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes + -> process remaining. */ + + /* n > loaded-byte-count */ + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, + copy and return. */ + + /* Align s to 16 byte. */ + risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r7 /* Compute highest index to 16byte boundary. */ + + /* Zero not found and n > loaded-byte-count. */ + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Now we are 16byte aligned, so we can load a full vreg + without page fault. */ + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining + bytes. */ +.Llt64: + lgr %r7,%r4 + slgfi %r7,16 /* border_len = n - 16. */ + + clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border + then process remaining bytes. */ + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v18 + vfenezbs %v17,%v18,%v18 + je .Lfound_v18 + vl %v16,16(%r5,%r3) + vst %v18,0(%r5,%r2) + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v16 + vfenezbs %v17,%v16,%v16 + je .Lfound_v16 + vl %v18,16(%r5,%r3) + vst %v16,0(%r5,%r2) + aghi %r5,16 + +.Lremaining_v18: + vlr %v16,%v18 +.Lremaining_v16: + /* v16 contains the remaining bytes [1...16]. + Store remaining bytes and append string-termination. */ + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */ + aghi %r7,-1 /* vstl needs highest index. */ + la %r2,0(%r5,%r2) /* vstl has no index register. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */ + clrjle %r1,%r7,.Lfound_v16_store + vstl %v16,%r7,0(%r2) /* Store remaining bytes without null + termination! */ +.Lend: + /* Restore saved registers. */ + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lfound_v16_32: + aghi %r5,32 + j .Lfound_v16 +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + aghi %r5,16 +.Lfound_v18: + vlr %v16,%v18 +.Lfound_v16: + /* v16 contains a zero. Store remaining bytes to zero. current_len + has not reached border, thus checking for n is not needed! */ + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ +.Lfound_v16_store: + vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ + /* Fill remaining bytes with zero - remaining count always > 0. */ + algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ + slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1) */ + la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ + lgr %r0,%r2 /* Save return-pointer to found zero. */ + clgije %r4,1,.Lend /* Skip zero-filling, if found zero is last + possible character. + (1 is substracted from r4 below!). */ + aghi %r4,-2 /* mvc with exrl needs count - 1. + (additional -1, see remaining bytes above) */ + srlg %r6,%r4,8 /* Split into 256 byte blocks. */ + ltgr %r6,%r6 + je .Lzero_lt256 +.Lzero_loop256: + mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ + la %r2,256(%r2) + brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ +.Lzero_lt256: + exrl %r4,.Lmvc_lt256 + j .Lend +.Lmvc_lt256: + mvc 1(1,%r2),0(%r2) + +.Lloop64: + vl %v16,0(%r5,%r3) + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezbs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 +END(__stpncpy_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/multiarch/stpncpy.c new file mode 100644 index 0000000..f7f9d51 --- /dev/null +++ b/sysdeps/s390/multiarch/stpncpy.c @@ -0,0 +1,32 @@ +/* Multiple versions of stpncpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define stpncpy __redirect_stpncpy +# define __stpncpy __redirect___stpncpy +# include +# undef stpncpy +# undef __stpncpy +# include + +s390_vx_libc_ifunc_redirected (__redirect___stpncpy, __stpncpy) +weak_alias (__stpncpy, stpncpy) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strcat-c.c b/sysdeps/s390/multiarch/strcat-c.c new file mode 100644 index 0000000..f871faa --- /dev/null +++ b/sysdeps/s390/multiarch/strcat-c.c @@ -0,0 +1,28 @@ +/* Default strcat implementation for S/390. + 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 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 +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strcat-vx.S b/sysdeps/s390/multiarch/strcat-vx.S new file mode 100644 index 0000000..3abbbcc --- /dev/null +++ b/sysdeps/s390/multiarch/strcat-vx.S @@ -0,0 +1,161 @@ +/* Vector optimized 32/64 bit S/390 version of strcat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char * strcat (const char *dest, const char *src) + Concatenate two strings. + + Register usage: + -r0=saved dest pointer for return + -r1=tmp + -r2=dest + -r3=src + -r4=tmp + -r5=current_len + -v16=part of src + -v17=index of zero + -v18=part of src +*/ +ENTRY(__strcat_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + lgr %r0,%r2 /* Save destination pointer for return. */ + + /* STRLEN + r1 = loaded bytes (tmp) + r4 = zero byte index (tmp) + r2 = dst + */ + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ + + /* Find zero in 16byte aligned loop. */ +.Llen_loop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Llen_found /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Llen_found16 + vl %v16,32(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Llen_found32 + vl %v16,48(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Llen_found48 + + aghi %r5,64 + j .Llen_loop /* No zero -> loop. */ + +.Llen_found48: + aghi %r5,16 +.Llen_found32: + aghi %r5,16 +.Llen_found16: + aghi %r5,16 +.Llen_found: + vlgvb %r4,%v16,7 /* Load byte index of zero. */ + algr %r5,%r4 + +.Llen_end: + /* STRCPY + %r1 = loaded bytes (tmp) + %r4 = zero byte index (tmp) + %r3 = curr src pointer + %r2 = curr dst pointer + */ + la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes, + copy bytes before and return. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r4 /* Compute highest index to 16byte boundary. */ + + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Find zero in 16byte aligned loop. */ +.Lcpy_loop: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lcpy_found_v16_0 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3)/* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezbs %v17,%v18,%v18 + je .Lcpy_found_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezbs %v17,%v16,%v16 + je .Lcpy_found_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezbs %v17,%v18,%v18 + je .Lcpy_found_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + j .Lcpy_loop /* No zero -> loop. */ + +.Lcpy_found_v16_32: + aghi %r5,32 +.Lcpy_found_v16_0: + la %r4,0(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + vstl %v16,%r1,0(%r4) /* Copy characters including zero. */ + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lcpy_found_v18_48: + aghi %r5,32 +.Lcpy_found_v18_16: + la %r4,16(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + vstl %v18,%r1,0(%r4) /* Copy characters including zero. */ + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lcpy_found_align: + 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) */ diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/multiarch/strcat.c new file mode 100644 index 0000000..7d4126b --- /dev/null +++ b/sysdeps/s390/multiarch/strcat.c @@ -0,0 +1,29 @@ +/* Multiple versions of strcat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcat __redirect_strcat +# include +# undef strcat +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strchr-c.c b/sysdeps/s390/multiarch/strchr-c.c new file mode 100644 index 0000000..606cb56 --- /dev/null +++ b/sysdeps/s390/multiarch/strchr-c.c @@ -0,0 +1,29 @@ +/* Default strchr implementation for S/390. + 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 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) \ + __hidden_ver1 (__strchr_c, __GI_strchr, __strchr_c); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strchr-vx.S b/sysdeps/s390/multiarch/strchr-vx.S new file mode 100644 index 0000000..6e744fb --- /dev/null +++ b/sysdeps/s390/multiarch/strchr-vx.S @@ -0,0 +1,100 @@ +/* Vector optimized 32/64 bit S/390 version of strchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char *strchr (const char *s, int c) + Locate character in string. + + Register usage: + -r1=tmp + -r2=s + -r3=c + -r4=tmp + -r5=current_len + -v16=part of s + -v17=index of unequal + -v18=replicated c +*/ +ENTRY(__strchr_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + lghi %r5,0 /* current_len = 0. */ + + vlvgb %v18,%r3,0 /* Generate vector which elements are all c. + If c > 255, c will be truncated. */ + vrepb %v18,%v18,0 + + vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ + vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ + clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + + /* Find c/zero in 16 byte aligned loop */ +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ + jno .Lfound /* Found c/zero (cc=0|1|2). */ + vl %v16,16(%r5,%r2) + vfeezbs %v16,%v16,%v18 + jno .Lfound16 + vl %v16,32(%r5,%r2) + vfeezbs %v16,%v16,%v18 + jno .Lfound32 + vl %v16,48(%r5,%r2) + vfeezbs %v16,%v16,%v18 + jno .Lfound48 + + aghi %r5,64 + j .Lloop /* No character and no zero -> loop. */ + +.Lfound48: + la %r5,16(%r5) /* Use la since aghi would clobber cc. */ +.Lfound32: + la %r5,16(%r5) +.Lfound16: + la %r5,16(%r5) +.Lfound: + je .Lzero /* Found zero, but no c before that zero. */ + +.Lcharacter: + vlgvb %r4,%v16,7 /* Load byte index of character. */ + algr %r5,%r4 + la %r2,0(%r5,%r2) /* Return pointer to character. */ + br %r14 + +.Lzero: + llgcr %r3,%r3 /* char c_char = (char) c. */ + 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) */ diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/multiarch/strchr.c new file mode 100644 index 0000000..8aa33a5 --- /dev/null +++ b/sysdeps/s390/multiarch/strchr.c @@ -0,0 +1,32 @@ +/* Multiple versions of strchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strchr __redirect_strchr +/* Omit the strchr inline definitions because it would redefine strchr. */ +# define __NO_STRING_INLINES +# include +# undef strchr +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strchr, __strchr, strchr) +weak_alias (strchr, index) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strchrnul-c.c b/sysdeps/s390/multiarch/strchrnul-c.c new file mode 100644 index 0000000..020cebc --- /dev/null +++ b/sysdeps/s390/multiarch/strchrnul-c.c @@ -0,0 +1,26 @@ +/* Default strchrnul implementation for S/390. + 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 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 +#endif diff --git a/sysdeps/s390/multiarch/strchrnul-vx.S b/sysdeps/s390/multiarch/strchrnul-vx.S new file mode 100644 index 0000000..d561825 --- /dev/null +++ b/sysdeps/s390/multiarch/strchrnul-vx.S @@ -0,0 +1,93 @@ +/* Vector optimized 32/64 bit S/390 version of strchrnul. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char *strchrnul (const char *s, int c) + Returns pointer to first c or to \0 if c not found. + + Register usage: + -r1=tmp + -r2=s and return pointer + -r3=c + -r4=tmp + -r5=current_len + -v16=part of s + -v18=vector with c replicated in every byte +*/ +ENTRY(__strchrnul_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + lghi %r5,0 /* current_len = 0. */ + + vlvgb %v18,%r3,0 /* Generate vector which elements are all c. + If c > 255, c will be truncated. */ + vrepb %v18,%v18,0 + + vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ + vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ + clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + + /* Find c/zero in 16byte aligned loop */ +.Lloop: + vl %v16,0(%r5,%r2) /* Load s */ + vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ + jno .Lfound /* Found c/zero (cc=0|1|2). */ + vl %v16,16(%r5,%r2) + vfeezbs %v16,%v16,%v18 + jno .Lfound16 + vl %v16,32(%r5,%r2) + vfeezbs %v16,%v16,%v18 + jno .Lfound32 + vl %v16,48(%r5,%r2) + vfeezbs %v16,%v16,%v18 + jno .Lfound48 + + aghi %r5,64 + j .Lloop /* No character and no zero -> loop. */ + + /* Found character or zero */ +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound: + vlgvb %r1,%v16,7 /* Load byte index of character. */ + algr %r5,%r1 + la %r2,0(%r5,%r2) /* Return pointer to character. */ + +.Lend: + br %r14 +END(__strchrnul_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strchrnul.c b/sysdeps/s390/multiarch/strchrnul.c new file mode 100644 index 0000000..62dfc6b --- /dev/null +++ b/sysdeps/s390/multiarch/strchrnul.c @@ -0,0 +1,28 @@ +/* Multiple versions of strchrnul. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__strchrnul) +weak_alias (__strchrnul, strchrnul) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strcmp-vx.S b/sysdeps/s390/multiarch/strcmp-vx.S new file mode 100644 index 0000000..bcaeb56 --- /dev/null +++ b/sysdeps/s390/multiarch/strcmp-vx.S @@ -0,0 +1,116 @@ +/* Vector optimized 32/64 bit S/390 version 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* int strcmp (const char *s1, const char *s2) + Compare two strings + + Register usage: + -r1=loaded byte count s1 + -r2=s1 + -r3=s2 + -r4=loaded byte coutn s2, tmp + -r5=current_len + -v16=part of s1 + -v17=part of s2 + -v18=index of unequal +*/ +ENTRY(__strcmp_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + lghi %r5,0 /* current_len = 0. */ + +.Lloop: + vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ + vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ + lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */ + jo .Llt16_1 /* Jump away if vr is not fully loaded. */ + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 /* Jump away if vr is not fully loaded. */ + /* Both vrs are fully loaded. */ + aghi %r5,16 + vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r1,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezbs %v18,%v16,%v17 + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r1,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezbs %v18,%v16,%v17 + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r1,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezbs %v18,%v16,%v17 + jno .Lfound + j .Lloop + +.Llt16_1: + lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */ +.Llt16_2: + clr %r1,%r4 + locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */ + algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */ + vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ + vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ + clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded + bytes. */ + j .Lloop + +.Lfound: + je .Lend_equal + lghi %r2,1 + lghi %r1,-1 + locgrl %r2,%r1 + br %r14 +.Lend_equal: + lghi %r2,0 + br %r14 +END(__strcmp_vx) + +# 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) */ + +#include diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/multiarch/strcmp.c new file mode 100644 index 0000000..7c8b17b --- /dev/null +++ b/sysdeps/s390/multiarch/strcmp.c @@ -0,0 +1,29 @@ +/* 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcmp __redirect_strcmp +/* Omit the strcmp inline definitions because it would redefine strcmp. */ +# define __NO_STRING_INLINES +# include +# include +# undef strcmp + +s390_vx_libc_ifunc2_redirected (__redirect_strcmp, __strcmp, strcmp) + +#endif diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/multiarch/strcpy-vx.S new file mode 100644 index 0000000..52197f5 --- /dev/null +++ b/sysdeps/s390/multiarch/strcpy-vx.S @@ -0,0 +1,109 @@ +/* Vector optimized 32/64 bit S/390 version 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char * strcpy (const char *dest, const char *src) + Copy string src to dest. + + Register usage: + -r1=tmp + -r2=dest and return_value + -r3=src + -r4=tmp + -r5=current_len + -v16=part of src + -v17=index of zero + -v18=part of src +*/ +ENTRY(__strcpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, + copy bytes before and return. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r4 /* Compute highest index to 16byte boundary. */ + + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Find zero in 16byte aligned loop. */ +.Lloop: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16_0 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3)/* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezbs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + j .Lloop /* No zero found -> loop. */ + +.Lfound_v16_32: + aghi %r5,32 +.Lfound_v16_0: + la %r3,0(%r5,%r2) + vlgvb %r4,%v17,7 /* Load byte index of zero. */ + vstl %v16,%r4,0(%r3) /* Store characters including zero. */ + br %r14 + +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + la %r3,16(%r5,%r2) + vlgvb %r4,%v17,7 /* Load byte index of zero. */ + vstl %v18,%r4,0(%r3) /* Store characters including zero. */ + br %r14 + +.Lfound_align: + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + br %r14 +END(__strcpy_vx) + +/* 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) */ + +/* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory. */ +#include diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/multiarch/strcpy.c new file mode 100644 index 0000000..8f32a13 --- /dev/null +++ b/sysdeps/s390/multiarch/strcpy.c @@ -0,0 +1,27 @@ +/* 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcpy __redirect_strcpy +# include +# undef strcpy +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy) + +#endif diff --git a/sysdeps/s390/multiarch/strcspn-c.c b/sysdeps/s390/multiarch/strcspn-c.c new file mode 100644 index 0000000..7b454f5 --- /dev/null +++ b/sysdeps/s390/multiarch/strcspn-c.c @@ -0,0 +1,28 @@ +/* Default strcspn implementation for S/390. + 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 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 +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strcspn-vx.S b/sysdeps/s390/multiarch/strcspn-vx.S new file mode 100644 index 0000000..ea16687 --- /dev/null +++ b/sysdeps/s390/multiarch/strcspn-vx.S @@ -0,0 +1,281 @@ +/* Vector optimized 32/64 bit S/390 version of strcspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t strcspn (const char *s, const char * reject) + The strcspn() function calculates the length of the initial segment + of s which consists entirely of characters not in reject. + + This method checks the length of reject string. If it fits entirely + in one vector register, a fast algorithm is used, which does not need + to check multiple parts of accept-string. Otherwise a slower full + check of accept-string is used. + + register overview: + r3: pointer to start of reject-string + r2: pointer to start of search-string + r0: loaded byte count of vlbb search-string + r4: found byte index + r1: current return len + v16: search-string + v17: reject-string + v18: temp-vreg + + ONLY FOR SLOW: + v19: first reject-string + v20: zero for preparing acc-vector + v21: global mask; 1 indicates a match between + search-string-vreg and any reject-character + v22: current mask; 1 indicates a match between + search-string-vreg and any reject-character in current acc-vreg + v24: one for result-checking of former string-part + v30, v31: for re-/storing registers r6, r8, r9 + r5: current len of reject-string + r6: zero-index in search-string or 16 if no zero + or min(zero-index, loaded byte count) + r8: >0, if former reject-string-part contains a zero, + otherwise =0; + r9: loaded byte count of vlbb reject-string +*/ +ENTRY(__strcspn_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + /* + Check if reject-string fits in one vreg: + ---------------------------------------- + */ + vlbb %v17,0(%r3),6 /* Load reject. */ + lghi %r1,0 /* Zero out current len. */ + lcbb %r0,0(%r3),6 + jo .Lcheck_onbb /* Special case if reject + lays on block-boundary. */ +.Lcheck_notonbb: + vistrbs %v17,%v17 /* Fill with zeros after first zero. */ + je .Lfast /* Zero found -> reject fits in one vreg. */ + j .Lslow /* No zero -> reject exceeds one vreg. */ + + +.Lcheck_onbb: + /* Reject lays on block-boundary. */ + vfenezb %v18,%v17,%v17 /* Search zero in loaded reject bytes. */ + vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ + clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> + Reject fits in one vreg; + Fill with zeros and proceed + with FAST. */ + vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */ + j .Lcheck_notonbb /* Check if reject fits in one vreg. */ + + + /* + Search s for reject in one vreg + ------------------------------- + */ +.Lfast: + /* Complete reject-string in v17 and remaining bytes are zero. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 + unequal to any in v17 + or first zero element. */ + + vlgvb %r4,%v18,7 /* Load byte index of found element. */ + clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded + bytes, return with found element + index (=equal count). */ + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r1,16 /* current_len = 16. */ + slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ + + /* Process s in 16byte aligned loop. */ +.Lfast_loop: + vl %v16,0(%r1,%r2) /* Load search-string. */ + vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any + in v17 or first zero element. */ + jno .Lfast_loop_found + + vl %v16,16(%r1,%r2) + vfaezbs %v18,%v16,%v17,0 + jno .Lfast_loop_found16 + + vl %v16,32(%r1,%r2) + vfaezbs %v18,%v16,%v17,0 + jno .Lfast_loop_found32 + + vl %v16,48(%r1,%r2) + vfaezbs %v18,%v16,%v17,0 + jno .Lfast_loop_found48 + + aghi %r1,64 + j .Lfast_loop /* Loop if no element was unequal to reject + and not zero. */ + + /* Found equal or zero element. */ +.Lfast_loop_found48: + aghi %r1,16 +.Lfast_loop_found32: + aghi %r1,16 +.Lfast_loop_found16: + aghi %r1,16 +.Lfast_loop_found: + vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */ +.Lfast_loop_found2: + algrk %r2,%r1,%r4 /* Add found index to current len. */ + br %r14 + + + + /* + Search s for reject in multiple vregs + ------------------------------------- + */ +.Lslow: + /* Save registers. */ + vlvgg %v30,%r6,0 + vlvgp %v31,%r8,%r9 + + /* Reject in v17 without zero. */ + vlr %v19,%v17 /* Save first acc-part for a fast reload. */ + vzero %v20 /* Zero for preparing acc-vector. */ + vone %v24 /* One for checking result of former + string-part. */ + + /* Align s to 16 byte. */ + risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and + %r4 = bits 60-63 'and' 15. */ + je .Lslow_loop_str /* If s is aligned, loop aligned. */ + lghi %r0,15 + slr %r0,%r4 /* Compute highest index to load (15-x). */ + vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs + highest index, remaining bytes are 0). */ + ahi %r0,1 /* Work with loaded byte count. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of reject-string to zero. */ + vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first reject-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */ + clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ + locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ + j .Lslow_loop_acc + + + /* Process s in 16byte aligned loop. */ +.Lslow_next_str: + /* Check results of former processed str-part. */ + vfeeb %v18,%v21,%v24 /* Find first equal match in global mask + (ones in element). */ + vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */ + /* Equal-index < min(zero-index, loaded byte count) + -> Return pointer to equal element. */ + clrjl %r4,%r6,.Lslow_index_found + /* Zero-index < loaded byte count + -> Former str-part was last str-part + -> Return null */ + clrjl %r6,%r0,.Lslow_end_not_found + + /* All elements are zero (=no match) -> Proceed with next str-part. */ + vlr %v17,%v19 /* Load first part of reject (no zero). */ + algfr %r1,%r0 /* Add loaded byte count to current len. */ + +.Lslow_loop_str: + vl %v16,0(%r1,%r2) /* Load search-string. */ + lghi %r0,16 /* Loaded byte count is 16. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of reject to zero. */ + vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first reject-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end /* If first element is zero (end of string) + -> Return current length. */ + +.Lslow_loop_acc: + vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> + Character matches any rejected character in + this reject-string-part) IN=0, RT=1. */ + vlgvb %r4,%v22,0 /* Get result of first element. */ + /* First element is equal to any rejected characters? + (all other parts of reject cannot lead to a match before this one) + -> Return current len, which is pointing to this element. */ + clijh %r4,0,.Lslow_end + vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ + /* Proceed with next acc until end of acc is reached. */ + + +.Lslow_next_acc: + clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part + -> Add found index to current len + and end. */ + vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */ + aghi %r5,16 /* Increment current len of reject-string. */ + lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */ + jo .Lslow_next_acc_onbb /* Jump away if reject-string is + on block-boundary. */ +.Lslow_next_acc_notonbb: + vistrbs %v17,%v17 /* Fill with zeros after first zero. */ + jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ + +.Lslow_next_acc_prepare_zero: + /* Zero in reject-part: fill zeros with first-reject-character. */ + vlgvb %r8,%v17,0 /* Load first element of reject-part. */ + clije %r8,0,.Lslow_next_str /* Process next str-part if first + character in this part of reject + is a zero. */ + /* r8>0 -> zero found in this acc-part. */ + vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ + vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars + by comparing with 0 (v20). */ + vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ + j .Lslow_loop_acc /* Reject-string part is prepared. */ + +.Lslow_next_acc_onbb: + vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */ + vlgvb %r8,%v18,7 /* Load byte index of zero. */ + clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes + -> Prepare vreg. */ + vl %v17,0(%r5,%r3) /* Load over boundary ... */ + lghi %r8,0 /* r8=0 -> no zero in this part of acc, + check for zero is in jump-target. */ + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ + +.Lslow_end_not_found: + algfr %r1,%r6 /* Add zero-index to current len. */ + j .Lslow_end +.Lslow_index_found: + algfr %r1,%r4 /* Add found index of char to current len. */ +.Lslow_end: + lgr %r2,%r1 + /* Restore registers. */ + vlgvg %r6,%v30,0 + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + br %r14 +END(__strcspn_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/multiarch/strcspn.c new file mode 100644 index 0000000..418ffcd --- /dev/null +++ b/sysdeps/s390/multiarch/strcspn.c @@ -0,0 +1,31 @@ +/* Multiple versions of strcspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strcspn __redirect_strcspn +/* Omit the strcspn inline definitions because it would redefine strcspn. */ +# define __NO_STRING_INLINES +# include +# undef strcspn +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strcspn, __strcspn, strcspn) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/multiarch/strlen-c.c new file mode 100644 index 0000000..a2c8e43 --- /dev/null +++ b/sysdeps/s390/multiarch/strlen-c.c @@ -0,0 +1,28 @@ +/* Default strlen implementation for S/390. + 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 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) \ + __hidden_ver1 (__strlen_c, __GI_strlen, __strlen_c); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/multiarch/strlen-vx.S new file mode 100644 index 0000000..9308b33 --- /dev/null +++ b/sysdeps/s390/multiarch/strlen-vx.S @@ -0,0 +1,84 @@ +/* Vector optimized 32/64 bit S/390 version of strlen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t strlen (const char *s) + Returns length of string s. + + Register usage: + -r1=bytes to 4k-byte boundary + -r2=s + -r3=tmp + -r4=tmp + -r5=current_len and return_value + -v16=part of s +*/ +ENTRY(__strlen_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */ + clr %r4,%r1 /* If found zero within loaded bytes? */ + locgrl %r2,%r4 /* Then copy return value. */ + blr %r14 /* And return. */ + + /* Align s to 16 byte. */ + risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r3 /* Compute bytes to 16bytes boundary. */ + + /* Find zero in 16 byte aligned loop. */ +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound16 + vl %v16,32(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound32 + vl %v16,48(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound48 + + aghi %r5,64 + j .Lloop /* No zero found -> loop. */ + +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound: + 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) */ diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/multiarch/strlen.c new file mode 100644 index 0000000..0edf8b7 --- /dev/null +++ b/sysdeps/s390/multiarch/strlen.c @@ -0,0 +1,29 @@ +/* Multiple versions of strlen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strlen __redirect_strlen +# include +# include +# undef strlen + +s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strncat-c.c b/sysdeps/s390/multiarch/strncat-c.c new file mode 100644 index 0000000..9e6c245 --- /dev/null +++ b/sysdeps/s390/multiarch/strncat-c.c @@ -0,0 +1,23 @@ +/* Default strncat implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define STRNCAT __strncat_c +# define STRNCAT_PRIMARY +# include +#endif diff --git a/sysdeps/s390/multiarch/strncat-vx.S b/sysdeps/s390/multiarch/strncat-vx.S new file mode 100644 index 0000000..e6584d0 --- /dev/null +++ b/sysdeps/s390/multiarch/strncat-vx.S @@ -0,0 +1,239 @@ +/* Vector optimized 32/64 bit S/390 version of strncat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char * strncat (const char *dest, const char *src, size_t n) + Concatenate two strings - at most n characters of src. + + Register usage: + -r0=saved dest pointer for return + -r1=tmp + -r2=dest + -r3=src + -r4=n + -r5=current_len + -r6=tmp + -r7=tmp + -v16=part of src + -v17=index of zero + -v18=part of src + -v31=register save area for r6, r7 +*/ +ENTRY(__strncat_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgfi %r4,0 + ber %r14 /* Nothing to do, if n == 0. */ + lgr %r0,%r2 /* Save destination pointer for return. */ + vlvgp %v31,%r6,%r7 /* Save registers. */ + + /* STRLEN + %r1 = loaded bytes (tmp) + %r6 = zero byte index (tmp) + %r2 = dst + */ + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ + + /* Find zero in 16byte aligned loop. */ +.Llen_loop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Llen_found /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Llen_found16 + vl %v16,32(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Llen_found32 + vl %v16,48(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Llen_found48 + + aghi %r5,64 + j .Llen_loop /* No zero -> loop. */ + +.Llen_found48: + aghi %r5,16 +.Llen_found32: + aghi %r5,16 +.Llen_found16: + aghi %r5,16 +.Llen_found: + vlgvb %r1,%v16,7 /* Load byte index of zero. */ + algr %r5,%r1 + +.Llen_end: + /* STRCPY + %r1 = zero byte index (tmp) + %r6 = loaded bytes (tmp) + %r3 = curr src pointer + %r2 = curr dst pointer + %r7 = border, tmp + */ + la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r6,%r6 /* Convert 32bit to 64bit. */ + + lghi %r5,0 /* current_len = 0. */ + + clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes + -> process remaining. */ + + /* n > loaded-byte-count. */ + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded + bytes, copy and return. */ + + /* Align s to 16 byte. */ + risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r7 /* Compute highest index to 16byte boundary. */ + + /* Zero not found and n > loaded-byte-count. */ + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* + Now we are 16byte aligned, so we can load a full vreg + without page fault. + */ + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lcpy_loop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16, + process remaining bytes. */ +.Lcpy_lt64: + lgr %r7,%r4 + slgfi %r7,16 /* border_len = n - 16. */ + + /* If current_len >= border then process remaining bytes. */ + clgrjhe %r5,%r7,.Lcpy_remaining_v16 + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lcpy_found_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + aghi %r5,16 + + clgrjhe %r5,%r7,.Lcpy_remaining_v18 + vfenezbs %v17,%v18,%v18 + je .Lcpy_found_v18 + vl %v16,16(%r5,%r3) + vst %v18,0(%r5,%r2) + aghi %r5,16 + + clgrjhe %r5,%r7,.Lcpy_remaining_v16 + vfenezbs %v17,%v16,%v16 + je .Lcpy_found_v16 + vl %v18,16(%r5,%r3) + vst %v16,0(%r5,%r2) + aghi %r5,16 + +.Lcpy_remaining_v18: + vlr %v16,%v18 +.Lcpy_remaining_v16: + /* v16 contains the remaining bytes [1...16]. + Store remaining bytes and append string-termination. */ + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ + aghi %r7,-1 /* vstl needs highest index. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + la %r2,0(%r5,%r2) /* vstl has no index register. */ + /* Zero-index within remaining-bytes, store up to zero and end. */ + clgrjle %r1,%r7,.Lcpy_found_v16_store + vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ + lghi %r1,0 + stc %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */ +.Lcpy_end: + /* Restore saved registers. */ + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lcpy_found_v16_32: + aghi %r5,32 + j .Lcpy_found_v16 +.Lcpy_found_v18_48: + aghi %r5,32 +.Lcpy_found_v18_16: + aghi %r5,16 +.Lcpy_found_v18: + vlr %v16,%v18 +.Lcpy_found_v16: + /* v16 contains a zero. Store remaining bytes to zero. current_len + has not reached border, thus checking for n is not needed! */ + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + la %r2,0(%r5,%r2) +.Lcpy_found_v16_store: + vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ + j .Lcpy_end + + /* Find zero in 16byte aligned loop. */ +.Lcpy_loop64: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lcpy_found_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezbs %v17,%v18,%v18 + je .Lcpy_found_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezbs %v17,%v16,%v16 + je .Lcpy_found_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezbs %v17,%v18,%v18 + je .Lcpy_found_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lcpy_loop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Lcpy_lt64 +END(__strncat_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strncat.c b/sysdeps/s390/multiarch/strncat.c new file mode 100644 index 0000000..94b8dff --- /dev/null +++ b/sysdeps/s390/multiarch/strncat.c @@ -0,0 +1,27 @@ +/* Multiple versions of strncat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc2 (__strncat, strncat) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strncmp-c.c b/sysdeps/s390/multiarch/strncmp-c.c new file mode 100644 index 0000000..e54277e --- /dev/null +++ b/sysdeps/s390/multiarch/strncmp-c.c @@ -0,0 +1,28 @@ +/* Default strncmp implementation for S/390. + 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 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) \ + __hidden_ver1 (__strncmp_c, __GI_strncmp, __strncmp_c); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strncmp-vx.S b/sysdeps/s390/multiarch/strncmp-vx.S new file mode 100644 index 0000000..168fd65 --- /dev/null +++ b/sysdeps/s390/multiarch/strncmp-vx.S @@ -0,0 +1,137 @@ +/* Vector optimized 32/64 bit S/390 version of strncmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* int strncmp (const char *s1, const char *s2, size_t n) + Compare at most n characters of two strings. + + Register usage: + -r0=tmp + -r1=tmp + -r2=s1 + -r3=s2 + -r4=n + -r5=current_len + -v16=part of s1 + -v17=part of s2 + -v18=index of unequal +*/ +ENTRY(__strncmp_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgije %r4,0,.Lend_equal /* Nothing to do if n == 0, */ + lghi %r5,0 /* current_len = 0. */ + +.Lloop: + vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ + vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ + lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */ + jo .Llt16_1 /* Jump away if vr is not fully loaded. */ + lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ + jo .Llt16_2 /* Jump away if vr is not fully loaded. */ + aghi %r5,16 /* Both vrs are fully loaded. */ + clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */ + vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r0,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r1,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp + vfenezbs %v18,%v16,%v17 + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r0,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r1,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp + vfenezbs %v18,%v16,%v17 + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r0,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r1,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp + vfenezbs %v18,%v16,%v17 + jno .Lfound + j .Lloop + +.Llt16_1: + lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count ofs2. */ +.Llt16_2: + clr %r0,%r1 /* Compare logical. */ + locrh %r0,%r1 /* Compute minimum of bytes loaded. */ + algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */ + clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n ->last compare. */ + vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ + vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ + clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within + loaded bytes (index < loaded-bytes) */ + j .Lloop + +.Llastcmp: + /* Use comparision result only if located within first n characters. + %r0: loaded byte count in vreg; + %r5: current_len; + %r4: n; + (current_len - n): [0...16[ + First ignored match index: loaded bytes - (current_len-n): ]0...16] + */ + slgr %r5,%r4 /* %r5 = current_len - n. */ + slr %r0,%r5 /* %r0 = first ignored match index. */ + vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ + vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ + clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within + loaded bytes and below n bytes. */ + j .Lend_equal /* Miscompare after n-bytes -> end equal. */ + +.Lfound: + /* Difference or end of string. */ + je .Lend_equal + lghi %r2,1 + lghi %r1,-1 + locgrl %r2,%r1 + br %r14 +.Lend_equal: + lghi %r2,0 + br %r14 +END(__strncmp_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/multiarch/strncmp.c new file mode 100644 index 0000000..0ec472c --- /dev/null +++ b/sysdeps/s390/multiarch/strncmp.c @@ -0,0 +1,31 @@ +/* Multiple versions of strncmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strncmp __redirect_strncmp +/* Omit the strncmp inline definitions because it would redefine strncmp. */ +# define __NO_STRING_INLINES +# include +# undef strncmp +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strncpy-vx.S b/sysdeps/s390/multiarch/strncpy-vx.S new file mode 100644 index 0000000..2a37b7b --- /dev/null +++ b/sysdeps/s390/multiarch/strncpy-vx.S @@ -0,0 +1,207 @@ +/* Vector optimized 32/64 bit S/390 version 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char * strncpy (const char *dest, const char *src, size_t n) + Copy at most n characters of string src to dest. + + Register usage: + -r0=dest pointer for return + -r1=tmp, zero byte index + -r2=dest + -r3=src + -r4=n + -r5=current_len + -r6=tmp, loaded bytes + -r7=tmp, border + -v16=part of src + -v17=index of zero + -v18=part of src + -v31=register save area for r6, r7 +*/ +ENTRY(__strncpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgfi %r4,0 + ber %r14 /* Nothing to do, if n == 0. */ + lgr %r0,%r2 /* Save destination pointer for return. */ + vlvgp %v31,%r6,%r7 /* Save registers. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r6,%r6 /* Convert 32bit to 64bit. */ + + lghi %r5,0 /* current_len = 0. */ + + clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes + -> process remaining. */ + + /* n > loaded-byte-count. */ + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, + copy and return. */ + + /* Align s to 16 byte. */ + risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r7 /* Compute highest index to 16byte boundary. */ + + /* Zero not found and n > loaded-byte-count. */ + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Now we are 16byte aligned, so we can load + a full vreg without page fault. */ + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining + bytes. */ +.Llt64: + lgr %r7,%r4 + slgfi %r7,16 /* border_len = n - 16. */ + + clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border + then process remaining bytes. */ + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v18 + vfenezbs %v17,%v18,%v18 + je .Lfound_v18 + vl %v16,16(%r5,%r3) + vst %v18,0(%r5,%r2) + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v16 + vfenezbs %v17,%v16,%v16 + je .Lfound_v16 + vl %v18,16(%r5,%r3) + vst %v16,0(%r5,%r2) + aghi %r5,16 + +.Lremaining_v18: + vlr %v16,%v18 +.Lremaining_v16: + /* v16 contains the remaining bytes [1...16]. + Store remaining bytes and append string-termination. */ + vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ + slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ + aghi %r7,-1 /* vstl needs highest index. */ + la %r2,0(%r5,%r2) /* vstl has no index register. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + /* Zero in remaining bytes? -> jump away (zero-index < max-index) + Do not jump away if zero-index == max-index, + but simply copy zero with vstl below. */ + clrjl %r1,%r7,.Lfound_v16_store + vstl %v16,%r7,0(%r2) /* Store remaining bytes without null + termination!. */ +.Lend: + /* Restore saved registers. */ + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + + +.Lfound_v16_32: + aghi %r5,32 + j .Lfound_v16 +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + aghi %r5,16 +.Lfound_v18: + vlr %v16,%v18 +.Lfound_v16: + /* v16 contains a zero. Store remaining bytes to zero. current_len + has not reached border, thus checking for n is not needed! */ + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ +.Lfound_v16_store: + vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ + /* Fill remaining bytes with zero - remaining count always > 0. */ + algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ + slgr %r4,%r5 /* = n - (current_len + zero_index + 1). */ + la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ + aghi %r4,-2 /* mvc with exrl needs count - 1. + (additional -1, see remaining bytes above) */ + srlg %r6,%r4,8 /* Split into 256 byte blocks. */ + ltgr %r6,%r6 + je .Lzero_lt256 +.Lzero_loop256: + mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ + la %r2,256(%r2) + brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ +.Lzero_lt256: + exrl %r4,.Lmvc_lt256 + j .Lend +.Lmvc_lt256: + mvc 1(1,%r2),0(%r2) + +.Lloop64: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezbs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezbs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 +END(__strncpy_vx) + +# 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) */ + +/* Include strncpy-implementation in s390-32/s390-64 subdirectory. */ +#include diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/multiarch/strncpy.c new file mode 100644 index 0000000..2d4c456 --- /dev/null +++ b/sysdeps/s390/multiarch/strncpy.c @@ -0,0 +1,29 @@ +/* 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 + . */ + +#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strncpy __redirect_strncpy +/* Omit the strncpy inline definitions because it would redefine strncpy. */ +# define __NO_STRING_INLINES +# include +# undef strncpy +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strncpy, __strncpy, strncpy); + +#endif diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/multiarch/strnlen-c.c new file mode 100644 index 0000000..353e83e --- /dev/null +++ b/sysdeps/s390/multiarch/strnlen-c.c @@ -0,0 +1,30 @@ +/* Default strnlen implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define STRNLEN __strnlen_c +# ifdef SHARED +# 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 */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/multiarch/strnlen-vx.S new file mode 100644 index 0000000..fc659a9 --- /dev/null +++ b/sysdeps/s390/multiarch/strnlen-vx.S @@ -0,0 +1,134 @@ +/* Vector optimized 32/64 bit S/390 version of strnlen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t strnlen (const char *s, size_t maxlen) + Returns the number of characters in s or at most maxlen. + + Register usage: + -r1=tmp + -r2=address of string + -r3=maxlen (number of characters to be read) + -r4=tmp + -r5=current_len and return_value + -v16=part of s +*/ +ENTRY(__strnlen_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r3,%r3 +# endif /* !defined __s390x__ */ + + clgfi %r3,0 /* if maxlen == 0, return 0. */ + locgre %r2,%r3 + ber %r14 + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r1,%r1 /* Convert 32bit to 64bit. */ + + vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ + clgr %r1,%r3 + locgrh %r1,%r3 /* loaded_byte_count + = min (loaded_byte_count, maxlen) */ + + vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ + clr %r5,%r1 /* If found zero within loaded bytes? */ + locgrl %r2,%r5 /* Then copy return value. */ + blr %r14 /* And return. */ + + clgr %r1,%r3 /* If loaded_byte_count == maxlen? */ + locgre %r2,%r3 /* Then copy return value. */ + ber %r14 /* And return. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r3,.Lloop64 + + /* Find zero in max 64byte with aligned s. */ +.Llt64: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound /* Jump away if zero was found. */ + aghi %r5,16 + clgrjhe %r5,%r3,.Lfound /* current_len >= maxlen -> end. */ + vl %v16,0(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound + aghi %r5,16 + clgrjhe %r5,%r3,.Lfound + vl %v16,0(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound + aghi %r5,16 + clgrjhe %r5,%r3,.Lfound + vl %v16,0(%r5,%r2) + vfenezbs %v16,%v16,%v16 + j .Lfound + +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound: + vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */ + algr %r5,%r4 + + clgr %r5,%r3 + locgrh %r5,%r3 /* Return min (current_len, maxlen). */ + lgr %r2,%r5 + br %r14 + + /* Find zero in 16 byte aligned loop. */ +.Lloop64: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound16 + vl %v16,32(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound32 + vl %v16,48(%r5,%r2) + vfenezbs %v16,%v16,%v16 + je .Lfound48 + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r3,.Lloop64 + + j .Llt64 +END(__strnlen_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/multiarch/strnlen.c new file mode 100644 index 0000000..0f9cff5 --- /dev/null +++ b/sysdeps/s390/multiarch/strnlen.c @@ -0,0 +1,32 @@ +/* Multiple versions of strnlen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strnlen __redirect_strnlen +# define __strnlen __redirect___strnlen +# include +# undef strnlen +# undef __strnlen +# include + +s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen) +weak_alias (__strnlen, strnlen) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strpbrk-c.c b/sysdeps/s390/multiarch/strpbrk-c.c new file mode 100644 index 0000000..2c0517a --- /dev/null +++ b/sysdeps/s390/multiarch/strpbrk-c.c @@ -0,0 +1,28 @@ +/* Default strpbrk implementation for S/390. + 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 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 +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strpbrk-vx.S b/sysdeps/s390/multiarch/strpbrk-vx.S new file mode 100644 index 0000000..e19c550 --- /dev/null +++ b/sysdeps/s390/multiarch/strpbrk-vx.S @@ -0,0 +1,302 @@ +/* Vector optimized 32/64 bit S/390 version of strpbrk. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char *strpbrk (const char *s, const char * accept) + The strpbrk() function locates the first occurrence in the string s + of any of the characters in the string accept and returns a pointer + to that character or NULL if not found. + + This method checks the length of accept string. If it fits entirely + in one vector register, a fast algorithm is used, which does not need + to check multiple parts of accept-string. Otherwise a slower full + check of accept-string is used. + + register overview: + r3: pointer to start of accept-string + r2: pointer to start of search-string + r0: loaded byte count of vlbb search-string (32bit unsigned) + r4: found byte index (32bit unsigned) + r1: current return len (64bit unsigned) + v16: search-string + v17: accept-string + v18: temp-vreg + + ONLY FOR SLOW: + v19: first accept-string + v20: zero for preparing acc-vector + v21: global mask; 1 indicates a match between + search-string-vreg and any accept-character + v22: current mask; 1 indicates a match between + search-string-vreg and any accept-character in current acc-vreg + v24: one for result-checking of former string-part + v30, v31: for re-/storing registers r6, r8, r9 + r5: current len of accept-string + r6: zero-index in search-string or 16 if no zero + or min(zero-index, loaded byte count) + r8: >0, if former accept-string-part contains a zero, + otherwise =0; + r9: loaded byte count of vlbb accept-string +*/ +ENTRY(__strpbrk_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + /* + Check if accept-string fits in one vreg: + ---------------------------------------- + */ + vlbb %v17,0(%r3),6 /* Load accept. */ + lghi %r1,0 /* Zero out current len. */ + vlgvb %r0,%v17,0 /* Get first element. */ + clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */ + lcbb %r0,0(%r3),6 + jo .Lcheck_onbb /* Special case if accept lays + on block-boundary. */ +.Lcheck_notonbb: + vistrbs %v17,%v17 /* Fill with zeros after first zero. */ + je .Lfast /* Zero found -> accept fits in one vreg. */ + j .Lslow /* No zero -> accept exceeds one vreg */ + + +.Lcheck_onbb: + /* Accept lays on block-boundary. */ + vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ + vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ + clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> + Accept fits in one vreg; + Fill with zeros and proceed + with FAST. */ + vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ + j .Lcheck_notonbb /* Check if accept fits in one vreg. */ + + + /* + Search s for accept in one vreg + ------------------------------- + */ +.Lfast: + /* Complete accept-string in v17 and remaining bytes are zero. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any + in v17 or first zero element. */ + + vlgvb %r4,%v18,7 /* Load byte index of found element. */ + /* If found index is within loaded bytes, return with found + element index (=equal count). */ + clrjl %r4,%r0,.Lfast_loop_found2 + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r1,16 /* current_len = 16. */ + slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ + + /* Process s in 16byte aligned loop. */ +.Lfast_loop: + vl %v16,0(%r1,%r2) /* Load search-string. */ + vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any + in v17 or first zero element. */ + jno .Lfast_loop_found + + vl %v16,16(%r1,%r2) + vfaezbs %v18,%v16,%v17,0 + jno .Lfast_loop_found16 + + vl %v16,32(%r1,%r2) + vfaezbs %v18,%v16,%v17,0 + jno .Lfast_loop_found32 + + vl %v16,48(%r1,%r2) + vfaezbs %v18,%v16,%v17,0 + jno .Lfast_loop_found48 + + aghi %r1,64 + j .Lfast_loop /* Loop if no element was unequal to accept + and not zero. */ + + /* Found equal or zero element. */ +.Lfast_loop_found48: + aghi %r1,16 +.Lfast_loop_found32: + aghi %r1,16 +.Lfast_loop_found16: + aghi %r1,16 +.Lfast_loop_found: + vlgvb %r4,%v18,7 /* Load byte index of found element. */ +.Lfast_loop_found2: + vlgvb %r0,%v16,0(%r4) /* Get found element. */ + clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */ + algfr %r1,%r4 /* Add found index of char to current len. */ + la %r2,0(%r1,%r2) /* And return pointer to first equal char. */ + br %r14 + +.Lfast_end_null: + lghi %r2,0 /* Return null if no character is equal. */ + br %r14 + + + + + /* + Search s for accept in multiple vregs + ------------------------------------- + */ +.Lslow: + /* Save registers. */ + vlvgg %v30,%r6,0 + vlvgp %v31,%r8,%r9 + + /* accept in v17 without zero. */ + vlr %v19,%v17 /* Save first acc-part for a fast reload. */ + vzero %v20 /* Zero for preparing acc-vector. */ + vone %v24 /* One for checking result of former string. */ + + /* Align s to 16 byte. */ + risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and + %r4 = bits 60-63 'and' 15. */ + je .Lslow_loop_str /* If s is aligned, loop aligned. */ + lghi %r0,15 + slr %r0,%r4 /* Compute highest index to load (15-x). */ + vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs + highest index, remaining bytes are 0). */ + ahi %r0,1 /* Work with loaded byte count. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept-string to zero. */ + vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end_null /* If first element is zero + (end of string) -> return null */ + clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ + locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ + j .Lslow_loop_acc + + + /* Process s in 16byte aligned loop. */ +.Lslow_next_str: + /* Check results of former processed str-part. */ + vfeeb %v18,%v21,%v24 /* Find first equal match in global mask + (ones in element). */ + vlgvb %r4,%v18,7 /* Get index of first one (=equal) + or 16 if no match. */ + /* Equal-index < min(zero-index, loaded byte count) + -> return pointer to equal element. */ + clrjl %r4,%r6,.Lslow_index_found + /* Zero-index < loaded byte count + -> former str-part was last str-part + -> return null */ + clrjl %r6,%r0,.Lslow_end_null + /* All elements are zero (=no match) -> proceed with next str-part. */ + + vlr %v17,%v19 /* Load first part of accept (no zero). */ + algfr %r1,%r0 /* Add loaded byte count to current len. */ + +.Lslow_loop_str: + vl %v16,0(%r1,%r2) /* Load search-string */ + lghi %r0,16 /* Loaded byte count is 16. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept to zero. */ + vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end_null /* If first element is zero + (end of string) -> return null. */ + +.Lslow_loop_acc: + vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> + Character matches any accepted character in + this accept-string-part) IN=0, RT=1. */ + vlgvb %r4,%v22,0 /* Get result of first element. */ + /* First element is equal to any accepted characters + (all other parts of accept cannot lead to a match before this one) + -> current len is pointing to first element + -> return found */ + clijh %r4,0,.Lslow_end_found + vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ + /* Proceed with next acc until end of acc is reached. */ + + +.Lslow_next_acc: + clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part + -> add index to current_len and + end. */ + vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ + aghi %r5,16 /* Increment current len of accept-string. */ + lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ + jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is + on block-boundary. */ +.Lslow_next_acc_notonbb: + vistrbs %v17,%v17 /* Fill with zeros after first zero. */ + jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ + +.Lslow_next_acc_prepare_zero: + /* Zero in accept-part: fill zeros with first-accept-character. */ + vlgvb %r8,%v17,0 /* Load first element of acc-part. */ + clije %r8,0,.Lslow_next_str /* Proceed with next string-part, + if first char in this part of accept + is a zero. */ + /* r8>0 -> zero found in this acc-part. */ + vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ + vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars + by comparing with 0 (v20). */ + vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ + j .Lslow_loop_acc /* Accept part is prepared -> process. */ + +.Lslow_next_acc_onbb: + vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ + vlgvb %r8,%v18,7 /* Load byte index of zero. */ + clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes + -> Prepare vreg. */ + vl %v17,0(%r5,%r3) /* Load over boundary ... */ + lghi %r8,0 /* r8=0 -> no zero in this part of acc, + check for zero is in jump-target. */ + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ + +.Lslow_end_null: + lghi %r1,0 /* Return null if no character is equal. */ + j .Lslow_end + +.Lslow_loop_found: + vlgvb %r4,%v18,7 /* Load byte index of found element. */ + vlgvb %r0,%v16,0(%r4) /* Get found element. */ + clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */ + +.Lslow_index_found: + algfr %r1,%r4 /* Add found index of char to current len. */ +.Lslow_end_found: + la %r1,0(%r1,%r2) /* And return pointer to first equal char. */ + +.Lslow_end: + /* Restore registers. */ + vlgvg %r6,%v30,0 + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + lgr %r2,%r1 + br %r14 +END(__strpbrk_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/multiarch/strpbrk.c new file mode 100644 index 0000000..11afc26 --- /dev/null +++ b/sysdeps/s390/multiarch/strpbrk.c @@ -0,0 +1,31 @@ +/* Multiple versions of strpbrk. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strpbrk __redirect_strpbrk +/* Omit the strpbrk inline definitions because it would redefine strpbrk. */ +# define __NO_STRING_INLINES +# include +# undef strpbrk +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strpbrk, __strpbrk, strpbrk) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strrchr-c.c b/sysdeps/s390/multiarch/strrchr-c.c new file mode 100644 index 0000000..53ceb80 --- /dev/null +++ b/sysdeps/s390/multiarch/strrchr-c.c @@ -0,0 +1,29 @@ +/* Default strrchr implementation for S/390. + 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 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) \ + __hidden_ver1 (__strrchr_c, __GI_strrchr, __strrchr_c); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strrchr-vx.S b/sysdeps/s390/multiarch/strrchr-vx.S new file mode 100644 index 0000000..8b3b989 --- /dev/null +++ b/sysdeps/s390/multiarch/strrchr-vx.S @@ -0,0 +1,180 @@ +/* Vector optimized 32/64 bit S/390 version of strrchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char *strrchr (const char *s, int c) + Locate the last character c in string. + + Register usage: + -r0=loaded bytes in first part of s. + -r1=pointer to last occurence of c or NULL if not found. + -r2=s + -r3=c + -r4=tmp + -r5=current_len + -v16=part of s + -v17=index of found element + -v18=replicated c + -v19=part of s with last occurence of c. + -v20=permute pattern +*/ +ENTRY(__strrchr_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vlvgb %v18,%r3,0 /* Generate vector which elements are all c. + if c > 255, c will be truncated. */ + vrepb %v18,%v18,0 + + lghi %r1,-1 /* Currently no c found. */ + lghi %r5,0 /* current_len = 0. */ + + vfeezbs %v17,%v16,%v18 /* Find element equal or zero. */ + vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */ + clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */ +.Lalign: + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfeezbs %v17,%v16,%v18 /* Find element equal with zero search. */ + jno .Lfound /* Found c/zero (cc=0|1|2). */ + vl %v16,16(%r5,%r2) + vfeezbs %v17,%v16,%v18 + jno .Lfound16 + vl %v16,32(%r5,%r2) + vfeezbs %v17,%v16,%v18 + jno .Lfound32 + vl %v16,48(%r5,%r2) + vfeezbs %v17,%v16,%v18 + jno .Lfound48 + + aghi %r5,64 + j .Lloop /* No character and no zero -> loop. */ + +.Lfound48: + la %r5,16(%r5) /* Use la since aghi would clobber cc. */ +.Lfound32: + la %r5,16(%r5) +.Lfound16: + la %r5,16(%r5) +.Lfound: + je .Lzero /* Found zero, but no c before that zero. */ + /* Save this part of s to check for further matches after reaching + the end of the complete string. */ + vlr %v19,%v16 + lgr %r1,%r5 + + jh .Lzero /* Found a zero after the found c. */ + aghi %r5,16 /* Start search of next part of s. */ + j .Lloop + +.Lfound_first_part: + /* This code is only executed if the found c/zero is whithin loaded + bytes. If no c/zero was found (cc==3) the found index = 16, thus + this code is not called. + Resulting condition code of vector find element equal: + cc==0: no c, found zero + cc==1: c found, no zero + cc==2: c found, found zero after c + cc==3: no c, no zero (this case can be ignored). */ + je .Lzero /* Found zero, but no c before that zero. */ + + locgrne %r1,%r5 /* Mark c as found in first part of s. */ + vlr %v19,%v16 + + jl .Lalign /* No zero (e.g. if vr was fully loaded) + -> Align and loop afterwards. */ + + /* Found a zero in vr. If vr was not fully loaded due to block + boundary, the remaining bytes are filled with zero and we can't + rely on zero indication of condition code here! */ + + vfenezb %v17,%v16,%v16 /* Find zero. */ + vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ + clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */ + j .Lalign /* Align and loop afterwards. */ + +.Lend_searched_zero: + vlgvb %r4,%v17,7 /* Load byte index of zero. */ + algr %r5,%r4 + la %r2,0(%r5,%r2) /* Return pointer to zero. */ + br %r14 + +.Lzero: + /* Reached end of string. Check if one c was found before. */ + clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */ + + cgfi %r1,-1 /* No c found -> return NULL. */ + locghie %r2,0 + ber %r14 + + larl %r3,.Lpermute_mask /* Load permute mask. */ + vl %v20,0(%r3) + + /* c was found and is part of v19. */ + vfenezb %v17,%v19,%v19 /* Find zero. */ + vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ + + clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */ + lochine %r0,16 /* ... if v19 is not the first part of s. */ + ahi %r0,-1 /* Convert byte count to highest index. */ + + clr %r0,%r4 + locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */ + + /* Right-shift of v19 to mask bytes after zero. */ + clije %r4,15,.Lzero_permute /* No shift is needed if highest index + in vr is 15. */ + lhi %r0,15 + slr %r0,%r4 /* Compute byte count for vector shift right. */ + sll %r0,3 /* Convert to bit count. */ + vlvgb %v17,%r0,7 + vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes + specified in bits 1-4 of byte 7 in v17. */ + + /* Reverse bytes in v19. */ +.Lzero_permute: + vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */ + + /* Find c in reversed v19. */ + vfeeb %v19,%v19,%v18 /* Find c. */ + la %r2,0(%r1,%r2) + vlgvb %r3,%v19,7 /* Load byte index of c. */ + + /* Compute index in real s and return. */ + slgr %r4,%r3 + la %r2,0(%r4,%r2) /* Return pointer to zero. */ + br %r14 +.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) */ diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/multiarch/strrchr.c new file mode 100644 index 0000000..e00e25a --- /dev/null +++ b/sysdeps/s390/multiarch/strrchr.c @@ -0,0 +1,30 @@ +/* Multiple versions of strrchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strrchr __redirect_strrchr +# include +# undef strrchr +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr) +weak_alias (strrchr, rindex); + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/strspn-c.c b/sysdeps/s390/multiarch/strspn-c.c new file mode 100644 index 0000000..0efe61b --- /dev/null +++ b/sysdeps/s390/multiarch/strspn-c.c @@ -0,0 +1,28 @@ +/* Default strspn implementation for S/390. + 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 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) \ + __hidden_ver1 (__strspn_c, __GI_strspn, __strspn_c); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/strspn-vx.S b/sysdeps/s390/multiarch/strspn-vx.S new file mode 100644 index 0000000..6aa823e --- /dev/null +++ b/sysdeps/s390/multiarch/strspn-vx.S @@ -0,0 +1,256 @@ +/* Vector optimized 32/64 bit S/390 version of strspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t strspn (const char *s, const char * accept) + The strspn() function calculates the length of the initial segment + of s which consists entirely of characters in accept. + + This method checks the length of accept string. If it fits entirely + in one vector register, a fast algorithm is used, which does not need + to check multiple parts of accept-string. Otherwise a slower full + check of accept-string is used. + + register overview: + r3: pointer to start of accept-string + r2: pointer to start of search-string + r4: loaded byte count of vl search-string + r0: found byte index + r1: current return len of s + v16: search-string + v17: accept-string + v18: temp-vreg + + ONLY FOR SLOW: + v19: first accept-string + v20: zero for preparing acc-vector + v21: global mask; 1 indicates a match between + search-string-vreg and any accept-character + v22: current mask; 1 indicates a match between + search-string-vreg and any accept-character in current acc-vreg + v30, v31: for re-/storing registers r6, r8, r9 + r5: current len of accept-string + r6: zero-index in search-string or 16 if no zero + or min(zero-index, loaded byte count) + r8: >0, if former accept-string-part contains a zero, + otherwise =0; + r9: loaded byte count of vlbb accept-string +*/ +ENTRY(__strspn_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + /* + Check if accept-string fits in one vreg: + ---------------------------------------- + */ + vlbb %v17,0(%r3),6 /* Load accept. */ + lcbb %r4,0(%r3),6 + jo .Lcheck_onbb /* Special case if accept lays + on block-boundary. */ +.Lcheck_notonbb: + vistrbs %v17,%v17 /* Fill with zeros after first zero. */ + je .Lfast /* Zero found -> accept fits in one vreg. */ + j .Lslow /* No zero -> accept exceeds one vreg. */ + +.Lcheck_onbb: + /* Accept lays on block-boundary. */ + vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ + vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */ + clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count -> + Accept fits in one vreg; + Fill with zeros and proceed + with FAST. */ + vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ + j .Lcheck_notonbb /* Check if accept fits in one vreg. */ + + + /* + Search s for accept in one vreg + ------------------------------- + */ +.Lfast: + /* Complete accept-string is in v17 and remaining bytes are zero. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfaezbs %v16,%v16,%v17,8 /* Find first element in v16 + unequal to any in v17 + or first zero element. */ + vlgvb %r0,%v16,7 /* Load byte index of found element. */ + /* If found index is within loaded bytes (%r0 < %r1), + return with found element index (=equal count). */ + clr %r0,%r1 + locgrl %r2,%r0 + blr %r14 + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r1,16 /* current_len = 16. */ + slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ + +.Lfast_loop: + vl %v16,0(%r1,%r2) /* Load search-string. */ + vfaezbs %v16,%v16,%v17,8 /* Find first element in v16 + unequal to any in v17 + or first zero element. */ + jno .Lfast_loop_found + vl %v16,16(%r1,%r2) + vfaezbs %v16,%v16,%v17,8 + jno .Lfast_loop_found16 + vl %v16,32(%r1,%r2) + vfaezbs %v16,%v16,%v17,8 + jno .Lfast_loop_found32 + vl %v16,48(%r1,%r2) + vfaezbs %v16,%v16,%v17,8 + jno .Lfast_loop_found48 + + aghi %r1,64 + j .Lfast_loop /* Loop if no element was unequal to accept + and not zero. */ + + /* Found unequal or zero element. */ +.Lfast_loop_found48: + aghi %r1,16 +.Lfast_loop_found32: + aghi %r1,16 +.Lfast_loop_found16: + aghi %r1,16 +.Lfast_loop_found: + vlgvb %r0,%v16,7 /* Load byte index of found element. */ + algrk %r2,%r1,%r0 /* And add it to current len. */ + br %r14 + + + /* + Search s for accept in multiple vregs + ------------------------------------- + */ +.Lslow: + /* Save registers. */ + vlvgg %v30,%r6,0 + vlvgp %v31,%r8,%r9 + lghi %r1,0 /* current_len = 0. */ + + /* Accept in v17 without zero. */ + vlr %v19,%v17 /* Save first acc-part for a fast reload. */ + vzero %v20 /* Zero for preparing acc-vector. */ + + /* Align s to 16 byte. */ + risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and + %r0 = bits 60-63 'and' 15 */ + je .Lslow_loop_str /* If s is aligned, loop aligned */ + lghi %r4,15 + slr %r4,%r0 /* Compute highest index to load (15-x). */ + vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs + highest index, left bytes are 0). */ + ahi %r4,1 /* Work with loaded byte count. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept-string to zero. */ + vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 + if there is no zero. */ + clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */ + locrl %r6,%r4 /* Load on cc==1. */ + j .Lslow_loop_acc + + /* Process s in 16byte aligned loop. */ +.Lslow_next_str: + vlr %v17,%v19 /* Load first part of accept (no zero). */ + algfr %r1,%r4 /* Add loaded byte count to current len. */ +.Lslow_loop_str: + vl %v16,0(%r1,%r2) /* Load search-string. */ + lghi %r4,16 /* Loaded byte count is 16. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept-string to zero. */ + vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + +.Lslow_loop_acc: + vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> + character matches any accepted character in + this accept-string-part) IN=0, RT=1. */ + vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */ + vfenezb %v18,%v21,%v21 /* Find first zero in global-mask. */ + vlgvb %r0,%v18,7 /* Get first found zero-index + (= first mismatch). */ + clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index) + -> Process this string-part + with next acc-part. */ + clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count + -> All loaded bytes are matching + any accept-character + and are not zero. */ + /* All bytes are matching any characters in accept-string + and search-string is fully processed (found-index == zero-index) */ +.Lslow_add_lbc_end: + algrk %r2,%r1,%r0 /* Add matching characters to current_len. */ + /* Restore registers. */ + vlgvg %r6,%v30,0 + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + br %r14 + + + +.Lslow_next_acc: + clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part + -> Add found index to current len + and end. */ + vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ + aghi %r5,16 /* Add current_len of accept-string. */ + lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ + jo .Lslow_next_acc_onbb /* Jump away if accept-string is + on block-boundary. */ +.Lslow_next_acc_notonbb: + vistrbs %v17,%v17 /* Fill with zeros after first zero. */ + jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ + +.Lslow_next_acc_prepare_zero: + /* Zero in accept-part: fill zeros with first-accept-character. */ + vlgvb %r8,%v17,0 /* Load first element of acc-part. */ + clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character + in this part of accept-string. */ + /* r8>0 -> zero found in this acc-part. */ + vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ + vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars + by comparing with 0 (v20). */ + vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ + j .Lslow_loop_acc /* Accept part is prepared -> process. */ + +.Lslow_next_acc_onbb: + vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ + vlgvb %r8,%v18,7 /* Load byte index of zero. */ + clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes + -> Prepare vr. */ + vl %v17,0(%r5,%r3) /* Load over boundary ... */ + lghi %r8,0 /* r8=0 -> no zero in this part of acc, + 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) */ diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/multiarch/strspn.c new file mode 100644 index 0000000..bedbe98 --- /dev/null +++ b/sysdeps/s390/multiarch/strspn.c @@ -0,0 +1,31 @@ +/* Multiple versions of strspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define strspn __redirect_strspn +/* Omit the strspn inline definitions because it would redefine strspn. */ +# define __NO_STRING_INLINES +# include +# undef strspn +# include + +s390_vx_libc_ifunc2_redirected (__redirect_strspn, __strspn, strspn) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcpcpy-c.c b/sysdeps/s390/multiarch/wcpcpy-c.c new file mode 100644 index 0000000..e3282fd --- /dev/null +++ b/sysdeps/s390/multiarch/wcpcpy-c.c @@ -0,0 +1,25 @@ +/* Default wcslen implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCPCPY __wcpcpy_c + +# include +extern __typeof (__wcpcpy) __wcpcpy_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcpcpy-vx.S b/sysdeps/s390/multiarch/wcpcpy-vx.S new file mode 100644 index 0000000..bff6e85 --- /dev/null +++ b/sysdeps/s390/multiarch/wcpcpy-vx.S @@ -0,0 +1,114 @@ +/* Vector optimized 32/64 bit S/390 version of wcpcpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t * wcpcpy (const wchar_t *dest, const wchar_t *src) + Copy string src to dest returning a pointer to its end. + + Register usage: + -r0=border-len for switching to vector-instructions + -r1=tmp + -r2=dest and return value + -r3=src + -r4=tmp + -r5=current_len + -v16=part of src + -v17=index of zero + -v18=part of src +*/ +ENTRY(__wcpcpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + + tmll %r3,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, + copy bytes before and return. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r4 /* Compute highest index to 16byte boundary. */ + + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Find zero in 16byte aligned loop. */ +.Lloop: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16_0 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezfs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + j .Lloop /* No zero found -> loop. */ + +.Lfound_v16_32: + aghi %r5,32 +.Lfound_v16_0: + la %r3,0(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ + lay %r2,-3(%r1,%r3) /* Return pointer to zero. */ + br %r14 + +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + la %r3,16(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ + lay %r2,-3(%r1,%r3) /* Return pointer to zero. */ + br %r14 + +.Lfound_align: + aghi %r5,3 /* Also copy remaining bytes of zero. */ + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + lay %r2,-3(%r5,%r2) /* Return pointer to zero. */ + br %r14 + +.Lfallback: + jg __wcpcpy_c +END(__wcpcpy_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcpcpy.c b/sysdeps/s390/multiarch/wcpcpy.c new file mode 100644 index 0000000..f19d376 --- /dev/null +++ b/sysdeps/s390/multiarch/wcpcpy.c @@ -0,0 +1,28 @@ +/* Multiple versions of wcpcpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__wcpcpy) +weak_alias (__wcpcpy, wcpcpy) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/multiarch/wcpncpy-c.c new file mode 100644 index 0000000..1f44bac --- /dev/null +++ b/sysdeps/s390/multiarch/wcpncpy-c.c @@ -0,0 +1,25 @@ +/* Default wcsncpy implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCPNCPY __wcpncpy_c + +# include +extern __typeof (__wcpncpy) __wcpncpy_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcpncpy-vx.S b/sysdeps/s390/multiarch/wcpncpy-vx.S new file mode 100644 index 0000000..004f512 --- /dev/null +++ b/sysdeps/s390/multiarch/wcpncpy-vx.S @@ -0,0 +1,222 @@ +/* Vector optimized 32/64 bit S/390 version of wcpncpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t * wcpncpy (wchar_t *dest, const wchar_t *src, size_t n) + Copies at most n characters of string src to dest + returning a pointer to its end or dest+n + if src is smaller than n. + + Register usage: + -%r0 = return value + -%r1 = zero byte index + -%r2 = curr dst pointer + -%r3 = curr src pointer + -%r4 = n + -%r5 = current_len + -%r6 = loaded bytes + -%r7 = border, tmp +*/ +ENTRY(__wcpncpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgfi %r4,0 + ber %r14 /* Nothing to do, if n == 0. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + + tmll %r3,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + vlvgp %v31,%r6,%r7 /* Save registers. */ + lghi %r5,0 /* current_len = 0. */ + + lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r6,%r6 /* Convert 32bit to 64bit. */ + + /* Check range of maxlen and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + llilf %r1,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + + la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */ + + clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes + -> process remaining. */ + + /* n > loaded-byte-count */ + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, + copy and return. */ + + /* Align s to 16 byte. */ + risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r7 /* Compute highest index to 16byte boundary. */ + + /* Zero not found and n > loaded-byte-count. */ + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Now we are 16byte aligned, so we can load a full vreg + without page fault. */ + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + clgijl %r4,17,.Lremaining_v16 /* If n <=16, + process remaining bytes. */ +.Llt64: + lgr %r7,%r4 + slgfi %r7,16 /* border_len = n - 16. */ + + clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border + then process remaining bytes. */ + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v18 + vfenezfs %v17,%v18,%v18 + je .Lfound_v18 + vl %v16,16(%r5,%r3) + vst %v18,0(%r5,%r2) + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v16 + vfenezfs %v17,%v16,%v16 + je .Lfound_v16 + vl %v18,16(%r5,%r3) + vst %v16,0(%r5,%r2) + aghi %r5,16 + +.Lremaining_v18: + vlr %v16,%v18 +.Lremaining_v16: + /* v16 contains the remaining bytes [1...16]. + Store remaining bytes and append string-termination. */ + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */ + aghi %r7,-1 /* vstl needs highest index. */ + la %r2,0(%r5,%r2) /* vstl has no index register. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */ + clrjle %r1,%r7,.Lfound_v16_store + vstl %v16,%r7,0(%r2) /* Store remaining bytes without null + termination! */ +.Lend: + /* Restore saved registers. */ + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lfound_v16_32: + aghi %r5,32 + j .Lfound_v16 +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + aghi %r5,16 +.Lfound_v18: + vlr %v16,%v18 +.Lfound_v16: + /* v16 contains a zero. Store remaining bytes to zero. current_len + has not reached border, thus checking for n is not needed! */ + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ +.Lfound_v16_store: + vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ + /* Fill remaining bytes with zero - remaining byte count always > 0. */ + algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ + slgr %r4,%r5 /* = n - (currlen + zero_index + 1) */ + la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ + lay %r0,-3(%r2) /* Save return-pointer to found zero. */ + clgije %r4,1,.Lend /* Skip zero-filling, if found-zero is last + possible character. + (1 is substracted from r4 below!). */ + aghi %r4,-2 /* mvc with exrl needs count - 1. + (additional -1, see remaining bytes above) */ + srlg %r6,%r4,8 /* Split into 256 byte blocks. */ + ltgr %r6,%r6 + je .Lzero_lt256 +.Lzero_loop256: + mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ + la %r2,256(%r2) + brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ +.Lzero_lt256: + exrl %r4,.Lmvc_lt256 + j .Lend +.Lmvc_lt256: + mvc 1(1,%r2),0(%r2) + + /* Find zero in 16byte aligned loop. */ +.Lloop64: + vl %v16,0(%r5,%r3) + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezfs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 + +.Lfallback: + jg __wcpncpy_c +END(__wcpncpy_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/multiarch/wcpncpy.c new file mode 100644 index 0000000..b72265f --- /dev/null +++ b/sysdeps/s390/multiarch/wcpncpy.c @@ -0,0 +1,28 @@ +/* Multiple versions of wcpncpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__wcpncpy) +weak_alias (__wcpncpy, wcpncpy) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/multiarch/wcscat-c.c new file mode 100644 index 0000000..9a31c65 --- /dev/null +++ b/sysdeps/s390/multiarch/wcscat-c.c @@ -0,0 +1,25 @@ +/* Default wcscat implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSCAT __wcscat_c + +# include +extern __typeof (__wcscat) __wcscat_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcscat-vx.S b/sysdeps/s390/multiarch/wcscat-vx.S new file mode 100644 index 0000000..2164a8d --- /dev/null +++ b/sysdeps/s390/multiarch/wcscat-vx.S @@ -0,0 +1,175 @@ +/* Vector optimized 32/64 bit S/390 version of wcscat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t * wcscat (wchar_t *dest, const wchar_t *src) + Concatenate two strings. + + Register usage: + -r0=saved dest pointer for return + -r1=tmp + -r2=dest + -r3=src + -r4=tmp + -r5=current_len + -v16=part of src + -v17=index of zero + -v18=part of src +*/ +ENTRY(__wcscat_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + /* __wcslen_c can handle non 4byte aligned pointers, + but __wcscpy_c not. Thus if either src or dest is + not 4byte aligned, use __wcscat_c. */ + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + tmll %r3,3 /* Test if src is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + lgr %r0,%r2 /* Save destination pointer for return. */ + + /* WCSLEN + r1 = loaded bytes (tmp) + r4 = zero byte index (tmp) + r2 = dst + */ + + vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ + + /* Find zero in 16byte aligned loop. */ +.Llen_loop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Llen_found /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Llen_found16 + vl %v16,32(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Llen_found32 + vl %v16,48(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Llen_found48 + + aghi %r5,64 + j .Llen_loop /* No zero -> loop. */ + +.Llen_found48: + aghi %r5,16 +.Llen_found32: + aghi %r5,16 +.Llen_found16: + aghi %r5,16 +.Llen_found: + vlgvb %r4,%v16,7 /* Load byte index of zero. */ + algr %r5,%r4 + +.Llen_end: + /* WCSCPY + %r1 = loaded bytes (tmp) + %r4 = zero byte index (tmp) + %r3 = curr src pointer + %r2 = curr dst pointer + */ + la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes, + copy bytes before and return. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r4 /* Compute highest index to 16byte boundary. */ + + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Find zero in 16byte aligned loop. */ +.Lcpy_loop: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lcpy_found_v16_0 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ + vfenezfs %v17,%v18,%v18 + je .Lcpy_found_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezfs %v17,%v16,%v16 + je .Lcpy_found_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezfs %v17,%v18,%v18 + je .Lcpy_found_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + j .Lcpy_loop /* No zero -> loop. */ + +.Lcpy_found_v16_32: + aghi %r5,32 +.Lcpy_found_v16_0: + la %r4,0(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + vstl %v16,%r1,0(%r4) /* Copy characters including zero. */ + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lcpy_found_v18_48: + aghi %r5,32 +.Lcpy_found_v18_16: + la %r4,16(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + vstl %v18,%r1,0(%r4) /* Copy characters including zero. */ + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lcpy_found_align: + aghi %r5,3 /* Also copy remaining bytes of found zero. */ + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + 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) */ diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/multiarch/wcscat.c new file mode 100644 index 0000000..33e4f6d --- /dev/null +++ b/sysdeps/s390/multiarch/wcscat.c @@ -0,0 +1,28 @@ +/* Multiple versions of wcscat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__wcscat) +weak_alias (__wcscat, wcscat) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcschr-c.c b/sysdeps/s390/multiarch/wcschr-c.c new file mode 100644 index 0000000..8d6679c --- /dev/null +++ b/sysdeps/s390/multiarch/wcschr-c.c @@ -0,0 +1,37 @@ +/* Default wcschr implementation for S/390. + 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 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); \ + __hidden_ver1 (__wcschr_c_1, __GI___wcschr, __wcschr_c_1); +# undef libc_hidden_weak +# define libc_hidden_weak(name) +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcschr-vx.S b/sysdeps/s390/multiarch/wcschr-vx.S new file mode 100644 index 0000000..94e5df7 --- /dev/null +++ b/sysdeps/s390/multiarch/wcschr-vx.S @@ -0,0 +1,103 @@ +/* Vector optimized 32/64 bit S/390 version of wcschr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t *wcschr (const wchar_t *s, wchar_t c) + Locate character in string. + + Register usage: + -r1=tmp + -r2=s + -r3=c + -r4=tmp + -r5=current_len + -v16=part of s + -v17=index of unequal + -v18=replicated c +*/ +ENTRY(__wcschr_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + lghi %r5,0 /* current_len = 0. */ + + vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ + vrepf %v18,%v18,0 + + vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ + vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ + clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + + /* Find c/zero in 16byte aligned loop */ +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ + jno .Lfound /* Found c/zero (cc=0|1|2). */ + vl %v16,16(%r5,%r2) + vfeezfs %v16,%v16,%v18 + jno .Lfound16 + vl %v16,32(%r5,%r2) + vfeezfs %v16,%v16,%v18 + jno .Lfound32 + vl %v16,48(%r5,%r2) + vfeezfs %v16,%v16,%v18 + jno .Lfound48 + + aghi %r5,64 + j .Lloop /* No character and no zero -> loop. */ + +.Lfound48: + la %r5,16(%r5) /* Use la since aghi would clobber cc. */ +.Lfound32: + la %r5,16(%r5) +.Lfound16: + la %r5,16(%r5) +.Lfound: + je .Lzero /* Found zero, but no c before that zero. */ + +.Lcharacter: + vlgvb %r4,%v16,7 /* Load byte index of character. */ + algr %r5,%r4 + la %r2,0(%r5,%r2) /* Return pointer to character. */ + br %r14 + +.Lzero: + clije %r3,0,.Lcharacter /* Found zero and c is zero. */ + 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) */ diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/multiarch/wcschr.c new file mode 100644 index 0000000..f44138f --- /dev/null +++ b/sysdeps/s390/multiarch/wcschr.c @@ -0,0 +1,32 @@ +/* Multiple versions of wcschr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wcschr __redirect_wcschr +# define __wcschr __redirect___wcschr +# include +# undef wcschr +# undef __wcschr +# include + +s390_vx_libc_ifunc_redirected (__redirect___wcschr, __wcschr) +weak_alias (__wcschr, wcschr) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/multiarch/wcschrnul-c.c new file mode 100644 index 0000000..00e776a --- /dev/null +++ b/sysdeps/s390/multiarch/wcschrnul-c.c @@ -0,0 +1,25 @@ +/* Default wcschrnul implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSCHRNUL __wcschrnul_c + +# include +extern __typeof (__wcschrnul) __wcschrnul_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcschrnul-vx.S b/sysdeps/s390/multiarch/wcschrnul-vx.S new file mode 100644 index 0000000..ebcd32b --- /dev/null +++ b/sysdeps/s390/multiarch/wcschrnul-vx.S @@ -0,0 +1,97 @@ +/* Vector optimized 32/64 bit S/390 version of wcschrnul. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t* wcschrnul (const wchar_t *s, wchar_t c) + Returns pointer to first c or to \0 if c not found. + + Register usage: + -r1=tmp + -r2=s and return pointer + -r3=c + -r4=tmp + -r5=current_len + -v16=part of s + -v18=vector with c replicated in every byte +*/ +ENTRY(__wcschrnul_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + lghi %r5,0 /* current_len = 0. */ + + vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ + vrepf %v18,%v18,0 + + vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ + vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ + clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + + /* Find c/zero in 16byte aligned loop */ +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ + jno .Lfound /* Found c/zero (cc=0|1|2). */ + vl %v16,16(%r5,%r2) + vfeezfs %v16,%v16,%v18 + jno .Lfound16 + vl %v16,32(%r5,%r2) + vfeezfs %v16,%v16,%v18 + jno .Lfound32 + vl %v16,48(%r5,%r2) + vfeezfs %v16,%v16,%v18 + jno .Lfound48 + + aghi %r5,64 + j .Lloop /* No character and no zero -> loop. */ + + /* Found character or zero */ +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound: + vlgvb %r1,%v16,7 /* Load byte index of character. */ + algr %r5,%r1 + la %r2,0(%r5,%r2) /* Return pointer to character. */ + +.Lend: + br %r14 +.Lfallback: + jg __wcschrnul_c +END(__wcschrnul_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/multiarch/wcschrnul.c new file mode 100644 index 0000000..807d7ee --- /dev/null +++ b/sysdeps/s390/multiarch/wcschrnul.c @@ -0,0 +1,28 @@ +/* Multiple versions of wcschrnul. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__wcschrnul) +weak_alias (__wcschrnul, wcschrnul) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcscmp-c.c b/sysdeps/s390/multiarch/wcscmp-c.c new file mode 100644 index 0000000..ce0817a --- /dev/null +++ b/sysdeps/s390/multiarch/wcscmp-c.c @@ -0,0 +1,32 @@ +/* Default wcscmp implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSCMP __wcscmp_c + +# 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) \ + __hidden_ver1 (__wcscmp_c, __GI___wcscmp, __wcscmp_c); +# endif /* SHARED */ +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcscmp-vx.S b/sysdeps/s390/multiarch/wcscmp-vx.S new file mode 100644 index 0000000..14267db --- /dev/null +++ b/sysdeps/s390/multiarch/wcscmp-vx.S @@ -0,0 +1,131 @@ +/* Vector optimized 32/64 bit S/390 version of wcscmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* int wcscmp (const wchar_t *s1, const wchar_t *s2) + Compare two strings + + Register usage: + -r1=loaded byte count s1 + -r2=s1 + -r3=s2 + -r4=loaded byte coutn s2, tmp + -r5=current_len + -v16=part of s1 + -v17=part of s2 + -v18=index of unequal +*/ +ENTRY(__wcscmp_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + lghi %r5,0 /* current_len = 0. */ + +.Lloop: + vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ + vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ + lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */ + jo .Llt16_1 /* Jump away if vr is not fully loaded. */ + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 /* Jump away if vr is not fully loaded. */ + /* Both vrs are fully loaded. */ + aghi %r5,16 + vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r1,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezfs %v18,%v16,%v17 + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r1,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezfs %v18,%v16,%v17 + jno .Lfound + + vlbb %v16,0(%r5,%r2),6 + vlbb %v17,0(%r5,%r3),6 + lcbb %r1,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r4,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezfs %v18,%v16,%v17 + jno .Lfound + j .Lloop + +.Lcmp_one_char: + /* At least one of both strings is not 4-byte aligned + and there is no full character before next block-boundary. + Compare one character to get over the boundary and + proceed with normal loop! */ + vlef %v16,0(%r5,%r2),0 /* Load one character. */ + vlef %v17,0(%r5,%r3),0 + lghi %r1,4 /* Loaded byte count is 4. */ + j .Llt_cmp /* Proceed with comparision. */ + +.Llt16_1: + lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */ +.Llt16_2: + clr %r1,%r4 + locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */ + nill %r1,65532 /* Align bytes loaded to full characters. */ + jz .Lcmp_one_char /* Jump away if no full char is available. */ +.Llt_cmp: + algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */ + vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ + vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ + clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded + bytes. */ + j .Lloop + +.Lfound: + /* vfenezf found an unequal element or zero. + This instruction compares unsigned words, but wchar_t is signed. + Thus we have to compare the found element again. */ + vlgvb %r4,%v18,7 /* Extract not equal byte-index, */ + srl %r4,2 /* Convert it to character-index. */ + vlgvf %r3,%v16,0(%r4) /* Load character-values. */ + vlgvf %r4,%v17,0(%r4) + cr %r3,%r4 + je .Lend_equal + lghi %r2,1 + lghi %r1,-1 + locgrl %r2,%r1 + br %r14 +.Lend_equal: + lghi %r2,0 + br %r14 +END(__wcscmp_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/multiarch/wcscmp.c new file mode 100644 index 0000000..5ee0fd4 --- /dev/null +++ b/sysdeps/s390/multiarch/wcscmp.c @@ -0,0 +1,30 @@ +/* Multiple versions of wcscmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define __wcscmp __redirect___wcscmp +# include +# undef __wcscmp +# include + +s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp) +weak_alias (__wcscmp, wcscmp) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcscpy-c.c b/sysdeps/s390/multiarch/wcscpy-c.c new file mode 100644 index 0000000..4a510f4 --- /dev/null +++ b/sysdeps/s390/multiarch/wcscpy-c.c @@ -0,0 +1,25 @@ +/* Default wcscpy implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSCPY __wcscpy_c + +# include +extern __typeof (wcscpy) __wcscpy_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcscpy-vx.S b/sysdeps/s390/multiarch/wcscpy-vx.S new file mode 100644 index 0000000..c2e8105 --- /dev/null +++ b/sysdeps/s390/multiarch/wcscpy-vx.S @@ -0,0 +1,111 @@ +/* Vector optimized 32/64 bit S/390 version of wcscpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* char * wcscpy (const wchar_t *dest, const wchar_t *src) + Copy string src to dest. + + Register usage: + -r0=border-len for switching to vector-instructions + -r1=tmp + -r2=dest and return value + -r3=src + -r4=tmp + -r5=current_len + -v16=part of src + -v17=index of zero + -v18=part of src +*/ +ENTRY(__wcscpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + + tmll %r3,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, + copy bytes before and return. */ + + /* Align s to 16 byte. */ + risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r4 /* Compute highest index to 16byte boundary. */ + + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Find zero in 16byte aligned loop. */ +.Lloop: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16_0 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezfs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + j .Lloop /* No zero found -> loop. */ + +.Lfound_v16_32: + aghi %r5,32 +.Lfound_v16_0: + la %r3,0(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ + br %r14 + +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + la %r3,16(%r5,%r2) + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ + br %r14 + +.Lfound_align: + aghi %r5,3 /* Also copy remaining bytes of zero. */ + vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ + br %r14 + +.Lfallback: + jg __wcscpy_c +END(__wcscpy_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcscpy.c b/sysdeps/s390/multiarch/wcscpy.c new file mode 100644 index 0000000..e69baa6 --- /dev/null +++ b/sysdeps/s390/multiarch/wcscpy.c @@ -0,0 +1,27 @@ +/* Multiple versions of wcscpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc2 (__wcscpy, wcscpy) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcscspn-c.c b/sysdeps/s390/multiarch/wcscspn-c.c new file mode 100644 index 0000000..161e52e --- /dev/null +++ b/sysdeps/s390/multiarch/wcscspn-c.c @@ -0,0 +1,26 @@ +/* Default wcscscpn implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSCSPN __wcscspn_c + +# include +extern __typeof (wcscspn) __wcscspn_c; + +# include +#endif diff --git a/sysdeps/s390/multiarch/wcscspn-vx.S b/sysdeps/s390/multiarch/wcscspn-vx.S new file mode 100644 index 0000000..06bc4e2 --- /dev/null +++ b/sysdeps/s390/multiarch/wcscspn-vx.S @@ -0,0 +1,293 @@ +/* Vector optimized 32/64 bit S/390 version of wcscspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t wcscspn (const wchar_t *s, const wchar_t * reject) + The wcscspn() function calculates the length of the initial segment + of s which consists entirely of characters not in reject. + + This method checks the length of reject string. If it fits entirely + in one vector register, a fast algorithm is used, which does not need + to check multiple parts of accept-string. Otherwise a slower full + check of accept-string is used. + + register overview: + r3: pointer to start of reject-string + r2: pointer to start of search-string + r0: loaded byte count of vlbb search-string + r4: found byte index + r1: current return len + v16: search-string + v17: reject-string + v18: temp-vreg + + ONLY FOR SLOW: + v19: first reject-string + v20: zero for preparing acc-vector + v21: global mask; 1 indicates a match between + search-string-vreg and any reject-character + v22: current mask; 1 indicates a match between + search-string-vreg and any reject-character in current acc-vreg + v30, v31: for re-/storing registers r6, r8, r9 + r5: current len of reject-string + r6: zero-index in search-string or 16 if no zero + or min(zero-index, loaded byte count) + r8: >0, if former reject-string-part contains a zero, + otherwise =0; + r9: loaded byte count of vlbb reject-string +*/ +ENTRY(__wcscspn_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + /* + Check if reject-string fits in one vreg: + ---------------------------------------- + */ + vlbb %v17,0(%r3),0 /* Load reject. */ + lcbb %r0,0(%r3),0 + jo .Lcheck_onbb /* Special case if reject + lays on block-boundary. */ + +.Lcheck_notonbb: + lghi %r1,0 /* Zero out current len. */ + vistrfs %v17,%v17 /* Fill with zeros after first zero. */ + je .Lfast /* Zero found -> reject fits in one vreg. */ + j .Lslow /* No zero -> reject exceeds one vreg. */ + + +.Lcheck_onbb: + /* Reject lays on block-boundary. */ + nill %r0,65532 /* Recognize only fully loaded characters. */ + je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */ + vfenezf %v18,%v17,%v17 /* Search zero in loaded reject bytes. */ + vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ + clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> + Reject fits in one vreg; + Fill with zeros and proceed + with FAST. */ +.Lcheck_onbb2: + vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */ + j .Lcheck_notonbb /* Check if reject fits in one vreg. */ + + + /* + Search s for reject in one vreg + ------------------------------- + */ +.Lfast: + /* Complete reject-string in v17 and remaining bytes are zero. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 + unequal to any in v17 + or first zero element. */ + vlgvb %r4,%v18,7 /* Load byte index of found element. */ + clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded + bytes, return with found element + index (=equal count). */ + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r1,16 /* current_len = 16. */ + slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ + + /* Process s in 16byte aligned loop. */ +.Lfast_loop: + vl %v16,0(%r1,%r2) /* Load search-string. */ + vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any + in v17 or first zero element. */ + jno .Lfast_loop_found + + vl %v16,16(%r1,%r2) + vfaezfs %v18,%v16,%v17,0 + jno .Lfast_loop_found16 + + vl %v16,32(%r1,%r2) + vfaezfs %v18,%v16,%v17,0 + jno .Lfast_loop_found32 + + vl %v16,48(%r1,%r2) + vfaezfs %v18,%v16,%v17,0 + jno .Lfast_loop_found48 + + aghi %r1,64 + j .Lfast_loop /* Loop if no element was unequal to reject + and not zero. */ + + /* Found equal or zero element. */ +.Lfast_loop_found48: + aghi %r1,16 +.Lfast_loop_found32: + aghi %r1,16 +.Lfast_loop_found16: + aghi %r1,16 +.Lfast_loop_found: + vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */ +.Lfast_loop_found2: + algrk %r2,%r1,%r4 /* Add found index to current len. */ + srlg %r2,%r2,2 /* Convert byte-count to character-count. */ + br %r14 + + + + /* + Search s for reject in multiple vregs + ------------------------------------- + */ +.Lslow: + /* Save registers. */ + vlvgg %v30,%r6,0 + vlvgp %v31,%r8,%r9 + + /* Reject in v17 without zero. */ + vlr %v19,%v17 /* Save first acc-part for a fast reload. */ + vzero %v20 /* Zero for preparing acc-vector. */ + vone %v24 /* One for checking result of former + string-part. */ + + /* Align s to 16 byte. */ + risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and + %r4 = bits 60-63 'and' 15. */ + je .Lslow_loop_str /* If s is aligned, loop aligned. */ + lghi %r0,15 + slr %r0,%r4 /* Compute highest index to load (15-x). */ + vll %v16,%r0,0(%r2) /* Load up to 16byte boundary (vll needs + highest index, remaining bytes are 0). */ + ahi %r0,1 /* Work with loaded byte count. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of reject-string to zero. */ + vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first reject-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */ + clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ + locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ + j .Lslow_loop_acc + + + /* Process s in 16byte aligned loop. */ +.Lslow_next_str: + /* Check results of former processed str-part. */ + vfeef %v18,%v21,%v24 /* Find first equal match in global mask + (ones in element). */ + vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */ + /* Equal-index < min(zero-index, loaded byte count) + -> Return pointer to equal element. */ + clrjl %r4,%r6,.Lslow_index_found + /* Zero-index < loaded byte count + -> Former str-part was last str-part + -> Return null */ + clrjl %r6,%r0,.Lslow_end_not_found + + /* All elements are zero (=no match) -> proceed with next str-part. */ + vlr %v17,%v19 /* Load first part of reject (no zero). */ + algfr %r1,%r0 /* Add loaded byte count to current len. */ + +.Lslow_loop_str: + vl %v16,0(%r1,%r2) /* Load search-string. */ + lghi %r0,16 /* Loaded byte count is 16. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of reject to zero. */ + vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first reject-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end /* If first element is zero (end of string) + -> Return current length. */ + +.Lslow_loop_acc: + vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> + Character matches any rejected character in + this reject-string-part) IN=0, RT=1. */ + vlgvf %r4,%v22,0 /* Get result of first element. */ + /* First element is equal to any rejected characters? + (All other parts of reject cannot lead to a match before this one) + -> Return current len, which is pointing to this element. */ + clijh %r4,0,.Lslow_end + vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ + /* Proceed with next acc until end of acc is reached. */ + + +.Lslow_next_acc: + clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part + -> Add found index to current len + and end. */ + vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */ + aghi %r5,16 /* Increment current len of reject-string. */ + lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */ + jo .Lslow_next_acc_onbb /* Jump away if reject-string is + on block-boundary. */ +.Lslow_next_acc_notonbb: + vistrfs %v17,%v17 /* Fill with zeros after first zero. */ + jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ + +.Lslow_next_acc_prepare_zero: + /* Zero in reject-part: fill zeros with first-reject-character. */ + vlgvf %r8,%v17,0 /* Load first element of reject-part. */ + clije %r8,0,.Lslow_next_str /* Process next str-part if first + character in this part of reject + is a zero. */ + /* r8>0 -> zero found in this acc-part. */ + vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ + vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars + by comparing with 0 (v20). */ + vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ + j .Lslow_loop_acc /* Reject-string part is prepared. */ + +.Lslow_next_acc_onbb: + nill %r9,65532 /* Recognize only fully loaded characters. */ + je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t + loaded. */ + vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */ + vlgvb %r8,%v18,7 /* Load byte index of zero. */ + clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes + -> Prepare vreg. */ +.Lslow_next_acc_onbb2: + vl %v17,0(%r5,%r3) /* Load over boundary ... */ + lghi %r8,0 /* r8=0 -> no zero in this part of acc, + check for zero is in jump-target. */ + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ + +.Lslow_end_not_found: + algfr %r1,%r6 /* Add zero-index to current len. */ + j .Lslow_end +.Lslow_index_found: + algfr %r1,%r4 /* Add found index of char to current len. */ +.Lslow_end: + srlg %r2,%r1,2 /* Convert byte-count to character-count. */ + /* Restore registers. */ + vlgvg %r6,%v30,0 + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + br %r14 +.Lfallback: + jg __wcscspn_c +END(__wcscspn_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcscspn.c b/sysdeps/s390/multiarch/wcscspn.c new file mode 100644 index 0000000..7073275 --- /dev/null +++ b/sysdeps/s390/multiarch/wcscspn.c @@ -0,0 +1,27 @@ +/* Multiple versions of wcscspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc2 (__wcscspn, wcscspn) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcslen-c.c b/sysdeps/s390/multiarch/wcslen-c.c new file mode 100644 index 0000000..32a23e2 --- /dev/null +++ b/sysdeps/s390/multiarch/wcslen-c.c @@ -0,0 +1,25 @@ +/* Default wcslen implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSLEN __wcslen_c + +# include +extern __typeof (__wcslen) __wcslen_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcslen-vx.S b/sysdeps/s390/multiarch/wcslen-vx.S new file mode 100644 index 0000000..337cbed --- /dev/null +++ b/sysdeps/s390/multiarch/wcslen-vx.S @@ -0,0 +1,91 @@ +/* Vector optimized 32/64 bit S/390 version of wcslen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t wcslen (const wchar_t *s) + Returns length of string s. + + Register usage: + -r1=bytes to 4k-byte boundary + -r2=s + -r3=tmp + -r4=tmp + -r5=current_len and return_value + -v16=part of s +*/ +ENTRY(__wcslen_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */ + clr %r4,%r1 /* If found zero within loaded bytes? */ + locgrl %r2,%r4 /* Then copy return value. */ + jl .Lend /* And return. */ + + /* Align s to 16 byte. */ + risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r3 /* Compute bytes to 16bytes boundary. */ + + /* Find zero in 16byte aligned loop. */ +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound16 + vl %v16,32(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound32 + vl %v16,48(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound48 + + aghi %r5,64 + j .Lloop /* No zero found -> loop. */ + +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound: + vlgvb %r2,%v16,7 /* Load byte index of zero. */ + algr %r2,%r5 +.Lend: + 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) */ diff --git a/sysdeps/s390/multiarch/wcslen.c b/sysdeps/s390/multiarch/wcslen.c new file mode 100644 index 0000000..3a1d1a3 --- /dev/null +++ b/sysdeps/s390/multiarch/wcslen.c @@ -0,0 +1,28 @@ +/* Multiple versions of wcslen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__wcslen) +weak_alias (__wcslen, wcslen) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcsncat-c.c b/sysdeps/s390/multiarch/wcsncat-c.c new file mode 100644 index 0000000..2cf1a76 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncat-c.c @@ -0,0 +1,25 @@ +/* Default wcsncat implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSNCAT __wcsncat_c + +# include +extern __typeof (wcsncat) __wcsncat_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcsncat-vx.S b/sysdeps/s390/multiarch/wcsncat-vx.S new file mode 100644 index 0000000..1d39356 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncat-vx.S @@ -0,0 +1,265 @@ +/* Vector optimized 32/64 bit S/390 version of wcsncat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t * wcsncat (wchar_t *dest, const wchar_t *src, size_t n) + Concatenate two strings - at most n characters of src. + + Register usage: + -r0=saved dest pointer for return + -r1=tmp + -r2=dest + -r3=src + -r4=n + -r5=current_len + -r6=tmp + -r7=tmp + -v16=part of src + -v17=index of zero + -v18=part of src + -v31=register save area for r6, r7 +*/ +ENTRY(__wcsncat_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgfi %r4,0 + ber %r14 /* Nothing to do, if n == 0. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + /* If either src or dest is not 4byte aligned, use __wcsncat_c. */ + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + tmll %r3,3 /* Test if src is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + lgr %r0,%r2 /* Save destination pointer for return. */ + vlvgp %v31,%r6,%r7 /* Save registers. */ + + /* WCSLEN + %r1 = loaded bytes (tmp) + %r6 = zero byte index (tmp) + %r2 = dst + */ + vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ + + /* Find zero in 16byte aligned loop. */ +.Llen_loop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Llen_found /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Llen_found16 + vl %v16,32(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Llen_found32 + vl %v16,48(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Llen_found48 + + aghi %r5,64 + j .Llen_loop /* No zero -> loop. */ + +.Llen_found48: + aghi %r5,16 +.Llen_found32: + aghi %r5,16 +.Llen_found16: + aghi %r5,16 +.Llen_found: + vlgvb %r1,%v16,7 /* Load byte index of zero. */ + algr %r5,%r1 + +.Llen_end: + /* WCSNCPY + %r1 = zero byte index (tmp) + %r6 = loaded bytes (tmp) + %r3 = curr src pointer + %r2 = curr dst pointer + %r7 = border, tmp + */ + la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r6,%r6 /* Convert 32bit to 64bit. */ + + lghi %r5,0 /* current_len = 0. */ + + /* Check range of maxlen and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + llilf %r1,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + + clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes + -> process remaining. */ + + /* n > loaded-byte-count. */ + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded bytes, + copy and return. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r1 /* Compute highest index to 16byte boundary. * + + /* Zero not found and maxlen > loaded-byte-count. */ + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* + Now we are 16byte aligned, so we can load a full vreg + without page fault. + */ + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lcpy_loop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16, + process remaining bytes. */ +.Lcpy_lt64: + lgr %r7,%r4 + slgfi %r7,16 /* border_len = n - 16. */ + + clgrjhe %r5,%r7,.Lcpy_remaining_v16 + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lcpy_found_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ + aghi %r5,16 + + clgrjhe %r5,%r7,.Lcpy_remaining_v18 + vfenezfs %v17,%v18,%v18 + je .Lcpy_found_v18 + vl %v16,16(%r5,%r3) + vst %v18,0(%r5,%r2) + aghi %r5,16 + + clgrjhe %r5,%r7,.Lcpy_remaining_v16 + vfenezfs %v17,%v16,%v16 + je .Lcpy_found_v16 + vl %v18,16(%r5,%r3) + vst %v16,0(%r5,%r2) + aghi %r5,16 + +.Lcpy_remaining_v18: + vlr %v16,%v18 +.Lcpy_remaining_v16: + /* v16 contains the remaining bytes [1...16]. + Store remaining bytes and append string-termination. */ + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ + aghi %r7,-1 /* vstl needs highest index. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + la %r2,0(%r5,%r2) /* vstl has no index register. */ + /* Zero-index within remaining-bytes, store up to zero and end. */ + clgrjle %r1,%r7,.Lcpy_found_v16_store + vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ + lghi %r1,0 + st %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */ +.Lcpy_end: + /* Restore saved registers. */ + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lcpy_found_v16_32: + aghi %r5,32 + j .Lcpy_found_v16 +.Lcpy_found_v18_48: + aghi %r5,32 +.Lcpy_found_v18_16: + aghi %r5,16 +.Lcpy_found_v18: + vlr %v16,%v18 +.Lcpy_found_v16: + /* v16 contains a zero. Store remaining bytes to zero. current_len + has not reached border, thus checking for n is not needed! */ + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + la %r2,0(%r5,%r2) +.Lcpy_found_v16_store: + aghi %r1,3 /* Also copy remaining bytes of zero. */ + vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ + j .Lcpy_end + + /* Find zero in 16byte aligned loop. */ +.Lcpy_loop2: + vl %v16,16(%r5,%r3) + vst %v18,0(%r5,%r2) + aghi %r5,16 + +.Lcpy_loop64: + vl %v16,0(%r5,%r3) + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lcpy_found_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ + vfenezfs %v17,%v18,%v18 + je .Lcpy_found_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezfs %v17,%v16,%v16 + je .Lcpy_found_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezfs %v17,%v18,%v18 + je .Lcpy_found_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lcpy_loop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Lcpy_lt64 + +.Lfallback: + jg __wcsncat_c +END(__wcsncat_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcsncat.c b/sysdeps/s390/multiarch/wcsncat.c new file mode 100644 index 0000000..c49b8ff --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncat.c @@ -0,0 +1,27 @@ +/* Multiple versions of wcsncat. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc2 (__wcsncat, wcsncat) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcsncmp-c.c b/sysdeps/s390/multiarch/wcsncmp-c.c new file mode 100644 index 0000000..92ab5e8 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncmp-c.c @@ -0,0 +1,25 @@ +/* Default wcsncmp implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSNCMP __wcsncmp_c + +# include +extern __typeof (wcsncmp) __wcsncmp_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcsncmp-vx.S b/sysdeps/s390/multiarch/wcsncmp-vx.S new file mode 100644 index 0000000..34c203b --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncmp-vx.S @@ -0,0 +1,177 @@ +/* Vector optimized 32/64 bit S/390 version of wcsncmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* int wcsncmp (const wchar_t *s1, const wchar_t *s2, size_t n) + Compare at most n characters of two strings. + + Register usage: + -r0=tmp + -r1=tmp + -r2=s1 + -r3=s2 + -r4=n + -r5=current_len + -v16=part of s1 + -v17=part of s2 + -v18=index of unequal +*/ +ENTRY(__wcsncmp_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */ + + /* Check range of n and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + llilf %r1,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + + /* Check first character without vector load. */ + lghi %r5,4 /* current_len = 4 bytes. */ + /* Check s1/2[0]. */ + lt %r0,0(%r2) + l %r1,0(%r3) + je .Lend_cmp_one_char + crjne %r0,%r1,.Lend_cmp_one_char + +.Lloop: + vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ + vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ + lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */ + jo .Llt16_1 /* Jump away if vector not fully loaded. */ + lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ + jo .Llt16_2 /* Jump away if vector not fully loaded. */ + aghi %r5,16 /* Both vectors are fully loaded. */ + vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ + clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */ + jno .Lfound + + vlbb %v17,0(%r5,%r3),6 + vlbb %v16,0(%r5,%r2),6 + lcbb %r0,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r1,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezfs %v18,%v16,%v17 + clgrjhe %r5,%r4,.Llastcmp + jno .Lfound + + vlbb %v17,0(%r5,%r3),6 + vlbb %v16,0(%r5,%r2),6 + lcbb %r0,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r1,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezfs %v18,%v16,%v17 + clgrjhe %r5,%r4,.Llastcmp + jno .Lfound + + vlbb %v17,0(%r5,%r3),6 + vlbb %v16,0(%r5,%r2),6 + lcbb %r0,0(%r5,%r2),6 + jo .Llt16_1 + lcbb %r1,0(%r5,%r3),6 + jo .Llt16_2 + aghi %r5,16 + vfenezfs %v18,%v16,%v17 + clgrjhe %r5,%r4,.Llastcmp + jno .Lfound + + j .Lloop + +.Llt16_1: + lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ +.Llt16_2: + clr %r0,%r1 /* Compare logical. */ + locrh %r0,%r1 /* Compute minimum of bytes loaded. */ + nill %r0,65532 /* Align bytes loaded to full characters. */ + jz .Lcmp_one_char /* Jump away if no full char is available. */ +.Llt_cmp: + algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */ + vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ + clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n -> last compare */ + vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ + clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within + loaded bytes; (index < loaded-bytes) */ + j .Lloop + +.Lcmp_one_char: + /* At least one of both strings is not 4-byte aligned + and there is no full character before next block-boundary. + Compare one character to get over the boundary and + proceed with normal loop! */ + vlef %v16,0(%r5,%r2),0 /* Load one character. */ + lghi %r0,4 /* Loaded byte count is 4. */ + vlef %v17,0(%r5,%r3),0 + j .Llt_cmp /* Proceed with comparision. */ + +.Llastcmp: + /* Use comparision result only if located within first n characters. + %r0: loaded byte count in vreg; + %r5: current_len; + %r4: n; + (current_len - n): [0...16[ + First ignored match index: loaded bytes - (current_len-n): ]0...16] + */ + slgr %r5,%r4 /* %r5 = current_len - n. */ + slr %r0,%r5 /* %r0 = first ignored match index. */ + vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ + clrjl %r4,%r0,.Lfound2 /* Jump away if miscompare is within + loaded bytes and below n bytes. */ +.Lend_equal: + lghi %r2,0 + br %r14 + +.Lfound: + /* Difference or end of string. */ + /* vfenezf found an unequal element or zero. + This instruction compares unsigned words, but wchar_t is signed. + Thus we have to compare the found element again. */ + vlgvb %r4,%v18,7 /* Extract not equal byte-index. */ +.Lfound2: + srl %r4,2 /* And convert it to character-index. */ + vlgvf %r0,%v16,0(%r4) /* Load character-values. */ + vlgvf %r1,%v17,0(%r4) +.Lend_cmp_one_char: + cr %r0,%r1 + je .Lend_equal + lghi %r2,1 + lghi %r1,-1 + locgrl %r2,%r1 + br %r14 +END(__wcsncmp_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcsncmp.c b/sysdeps/s390/multiarch/wcsncmp.c new file mode 100644 index 0000000..ee5f08c --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncmp.c @@ -0,0 +1,27 @@ +/* Multiple versions of wcsncmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc2 (__wcsncmp, wcsncmp) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/multiarch/wcsncpy-c.c new file mode 100644 index 0000000..6b89b8c --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncpy-c.c @@ -0,0 +1,25 @@ +/* Default wcsncpy implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSNCPY __wcsncpy_c + +# include +extern __typeof (__wcsncpy) __wcsncpy_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcsncpy-vx.S b/sysdeps/s390/multiarch/wcsncpy-vx.S new file mode 100644 index 0000000..b3400d5 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncpy-vx.S @@ -0,0 +1,223 @@ +/* Vector optimized 32/64 bit S/390 version of wcsncpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t *wcsncpy (const wchar_t *dest, const wchar_t *src, size_t n) + Copy at most n characters of string src to dest. + + Register usage: + -r0=dest pointer for return + -r1=tmp, zero byte index + -r2=dest + -r3=src + -r4=n + -r5=current_len + -r6=tmp, loaded bytes + -r7=tmp, border + -v16=part of src + -v17=index of zero + -v18=part of src + -v31=register save area for r6, r7 +*/ +ENTRY(__wcsncpy_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgfi %r4,0 + ber %r14 /* Nothing to do, if n == 0. */ + + vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ + + tmll %r3,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + vlvgp %v31,%r6,%r7 /* Save registers. */ + lgr %r0,%r2 /* Save destination pointer for return. */ + + lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r6,%r6 /* Convert 32bit to 64bit. */ + + lghi %r5,0 /* current_len = 0. */ + + /* Check range of maxlen and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r4,49152 /* Test bit 0 or 1 of n. */ + lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r4,49152 /* Test bit 0 or 1 of n. */ + llilf %r1,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + + clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes + -> process remaining. */ + + /* n > loaded-byte-count. */ + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, + copy and return. */ + + /* Align s to 16 byte. */ + risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,15 /* current_len = 15. */ + slr %r5,%r7 /* Compute highest index to 16byte boundary. */ + + /* Zero not found and n > loaded-byte-count. */ + vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ + ahi %r5,1 /* Start loop at next character. */ + + /* Now we are 16byte aligned, so we can load + a full vreg without page fault. */ + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + clgijl %r4,17,.Lremaining_v16 /* If n <=16, process remaining + bytes. */ +.Llt64: + lgr %r7,%r4 + slgfi %r7,16 /* border_len = maxlen - 16. */ + + clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border + then process remaining bytes. */ + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v18 + vfenezfs %v17,%v18,%v18 + je .Lfound_v18 + vl %v16,16(%r5,%r3) + vst %v18,0(%r5,%r2) + aghi %r5,16 + + clgrjhe %r5,%r7,.Lremaining_v16 + vfenezfs %v17,%v16,%v16 + je .Lfound_v16 + vl %v18,16(%r5,%r3) + vst %v16,0(%r5,%r2) + aghi %r5,16 + +.Lremaining_v18: + vlr %v16,%v18 +.Lremaining_v16: + /* v16 contains the remaining bytes [1...16]. + Store remaining bytes and append string-termination. */ + vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ + slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ + aghi %r7,-1 /* vstl needs highest index. */ + la %r2,0(%r5,%r2) /* vstl has no index register. */ + vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ + /* Zero in remaining bytes? -> jump away (zero-index < max-index) + Do not jump away if zero-index == max-index, + but simply copy zero with vstl below. */ + clrjl %r1,%r7,.Lfound_v16_store + vstl %v16,%r7,0(%r2) /* Store remaining bytes without null + termination!. */ +.Lend: + /* Restore saved registers. */ + vlgvg %r6,%v31,0 + vlgvg %r7,%v31,1 + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + +.Lfound_v16_32: + aghi %r5,32 + j .Lfound_v16 +.Lfound_v18_48: + aghi %r5,32 +.Lfound_v18_16: + aghi %r5,16 +.Lfound_v18: + vlr %v16,%v18 +.Lfound_v16: + /* v16 contains a zero. Store remaining bytes to zero. current_len + has not reached border, thus checking for n is not needed! */ + vlgvb %r1,%v17,7 /* Load byte index of zero. */ + la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ + aghi %r1,3 /* Also copy remaining bytes of zero. */ +.Lfound_v16_store: + vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ + /* Fill remaining bytes with zero - remaining count always > 0. */ + algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ + slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1). */ + la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ + aghi %r4,-2 /* mvc with exrl needs count - 1. + (additional -1, see remaining bytes above) */ + srlg %r6,%r4,8 /* Split into 256 byte blocks. */ + ltgr %r6,%r6 + je .Lzero_lt256 +.Lzero_loop256: + mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ + la %r2,256(%r2) + brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ +.Lzero_lt256: + exrl %r4,.Lmvc_lt256 + j .Lend +.Lmvc_lt256: + mvc 1(1,%r2),0(%r2) + + /* Find zero in 16byte aligned loop. */ +.Lloop64: + vl %v16,0(%r5,%r3) /* Load s. */ + vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound_v16 /* Jump away if zero was found. */ + vl %v18,16(%r5,%r3) /* Load next part of s. */ + vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_16 + vl %v16,32(%r5,%r3) + vst %v18,16(%r5,%r2) + vfenezfs %v17,%v16,%v16 + je .Lfound_v16_32 + vl %v18,48(%r5,%r3) + vst %v16,32(%r5,%r2) + vfenezfs %v17,%v18,%v18 + je .Lfound_v18_48 + vst %v18,48(%r5,%r2) + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r4,.Lloop64 + + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 + +.Lfallback: + jg __wcsncpy_c +END(__wcsncpy_vx) + +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/multiarch/wcsncpy.c new file mode 100644 index 0000000..7209c7d --- /dev/null +++ b/sysdeps/s390/multiarch/wcsncpy.c @@ -0,0 +1,28 @@ +/* Multiple versions of wcsncpy. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__wcsncpy) +weak_alias (__wcsncpy, wcsncpy) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/multiarch/wcsnlen-c.c new file mode 100644 index 0000000..8f43f51 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsnlen-c.c @@ -0,0 +1,25 @@ +/* Default wcsnlen implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSNLEN __wcsnlen_c + +# include +extern __typeof (__wcsnlen) __wcsnlen_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcsnlen-vx.S b/sysdeps/s390/multiarch/wcsnlen-vx.S new file mode 100644 index 0000000..420f29f --- /dev/null +++ b/sysdeps/s390/multiarch/wcsnlen-vx.S @@ -0,0 +1,151 @@ +/* Vector optimized 32/64 bit S/390 version of wcsnlen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t wcsnlen (const wchar_t *s, size_t maxlen) + Returns the number of characters in s or at most maxlen. + + Register usage: + -r1=tmp + -r2=address of string + -r3=maxlen (number of characters to be read) + -r4=tmp + -r5=current_len and return_value + -v16=part of s +*/ +ENTRY(__wcsnlen_vx) + + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r3,%r3 +# endif /* !defined __s390x__ */ + + clgfi %r3,0 /* if maxlen == 0, return 0. */ + locgre %r2,%r3 + ber %r14 + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r1,%r1 /* Convert 32bit to 64bit. */ + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + /* Check range of maxlen and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r3,49152 /* Test bit 0 or 1 of maxlen. */ + lghi %r4,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r3,49152 /* Test bit 0 or 1 of maxlen. */ + llilf %r4,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r3,%r3,2 /* Convert character-count to byte-count. */ + locgrne %r3,%r4 /* Use max byte-count, if bit 0/1 was one. */ + + vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ + clgr %r1,%r3 + locgrh %r1,%r3 /* loaded_byte_count + = min (loaded_byte_count, maxlen) */ + + vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ + clrjl %r5,%r1,.Lend /* Found zero within loaded bytes -> return. */ + + clgr %r1,%r3 /* If loaded_byte_count == maxlen -> end. */ + locgre %r5,%r3 + je .Lend + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r3,.Lloop64 + + /* Find zero in max 64byte with aligned s. */ +.Llt64: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound /* Jump away if zero was found. */ + aghi %r5,16 + clgrjhe %r5,%r3,.Lfound /* If current_len >= maxlen -> end. */ + vl %v16,0(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound + aghi %r5,16 + clgrjhe %r5,%r3,.Lfound + vl %v16,0(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound + aghi %r5,16 + clgrjhe %r5,%r3,.Lfound + vl %v16,0(%r5,%r2) + vfenezfs %v16,%v16,%v16 + j .Lfound + +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound: + vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */ + algr %r5,%r4 + + clgr %r5,%r3 + locgrh %r5,%r3 /* Return min (current_len, maxlen). */ +.Lend: + srlg %r2,%r5,2 /* Convert byte-count to character-count. */ + br %r14 + + /* Find zero in 16byte aligned loop. */ +.Lloop64: + vl %v16,0(%r5,%r2) /* Load s. */ + vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ + je .Lfound /* Jump away if zero was found. */ + vl %v16,16(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound16 + vl %v16,32(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound32 + vl %v16,48(%r5,%r2) + vfenezfs %v16,%v16,%v16 + je .Lfound48 + + aghi %r5,64 + lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ + aghi %r1,64 + clgrjl %r1,%r3,.Lloop64 + + j .Llt64 + +.Lfallback: + jg __wcsnlen_c +END(__wcsnlen_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/multiarch/wcsnlen.c new file mode 100644 index 0000000..5234074 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsnlen.c @@ -0,0 +1,28 @@ +/* Multiple versions of wcsnlen. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc (__wcsnlen) +weak_alias (__wcsnlen, wcsnlen) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcspbrk-c.c b/sysdeps/s390/multiarch/wcspbrk-c.c new file mode 100644 index 0000000..6b6e7aa --- /dev/null +++ b/sysdeps/s390/multiarch/wcspbrk-c.c @@ -0,0 +1,31 @@ +/* Default wcspbrk implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSPBRK __wcspbrk_c + +# include +extern __typeof (wcspbrk) __wcspbrk_c; +# ifdef SHARED +# undef libc_hidden_def +# define libc_hidden_def(name) \ + __hidden_ver1 (__wcspbrk_c, __GI_wcspbrk, __wcspbrk_c); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcspbrk-vx.S b/sysdeps/s390/multiarch/wcspbrk-vx.S new file mode 100644 index 0000000..5c89ec5 --- /dev/null +++ b/sysdeps/s390/multiarch/wcspbrk-vx.S @@ -0,0 +1,315 @@ +/* Vector optimized 32/64 bit S/390 version of wcspbrk. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t *wcspbrk (const wchar_t *s, const wchar_t * accept) + The wcspbrk() function locates the first occurrence in the string s + of any of the characters in the string accept and returns a pointer + to that character or NULL if not found. + + This method checks the length of accept string. If it fits entirely + in one vector register, a fast algorithm is used, which does not need + to check multiple parts of accept-string. Otherwise a slower full + check of accept-string is used. + + register overview: + r3: pointer to start of accept-string + r2: pointer to start of search-string + r0: loaded byte count of vlbb search-string (32bit unsigned) + r4: found byte index (32bit unsigned) + r1: current return len (64bit unsigned) + v16: search-string + v17: accept-string + v18: temp-vreg + + ONLY FOR SLOW: + v19: first accept-string + v20: zero for preparing acc-vector + v21: global mask; 1 indicates a match between + search-string-vreg and any accept-character + v22: current mask; 1 indicates a match between + search-string-vreg and any accept-character in current acc-vreg + v24: one for result-checking of former string-part + v30, v31: for re-/storing registers r6, r8, r9 + r5: current len of accept-string + r6: zero-index in search-string or 16 if no zero + or min(zero-index, loaded byte count) + r8: >0, if former accept-string-part contains a zero, + otherwise =0; + r9: loaded byte count of vlbb accept-string +*/ +ENTRY(__wcspbrk_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + /* + Check if accept-string fits in one vreg: + ---------------------------------------- + */ + vlbb %v17,0(%r3),6 /* Load accept. */ + lcbb %r0,0(%r3),6 + jo .Lcheck_onbb /* Special case if accept lays + on block-boundary. */ + +.Lcheck_notonbb: + lghi %r1,0 /* Zero out current len. */ + vlgvf %r0,%v17,0 /* Get first element. */ + clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */ + + vistrfs %v17,%v17 /* Fill with zeros after first zero. */ + je .Lfast /* Zero found -> accept fits in one vreg. */ + j .Lslow /* No zero -> accept exceeds one vreg */ + + +.Lcheck_onbb: + /* Accept lays on block-boundary. */ + nill %r0,65532 /* Recognize only fully loaded characters. */ + je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */ + vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ + vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ + clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> + accept fits in one vreg; + Fill with zeros and proceed + with FAST. */ +.Lcheck_onbb2: + vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ + j .Lcheck_notonbb /* Check if accept fits in one vreg. */ + + + /* + Search s for accept in one vreg + ------------------------------- + */ +.Lfast: + /* Complete accept-string in v17 and remaining bytes are zero. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any + in v17 or first zero element. */ + vlgvb %r4,%v18,7 /* Load byte index of found element. */ + /* If found index is within loaded bytes, return with found + element index (=equal count). */ + clrjl %r4,%r0,.Lfast_loop_found2 + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r1,16 /* current_len = 16. */ + slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ + +.Lfast_loop: + vl %v16,0(%r1,%r2) /* Load search-string. */ + vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any + in v17 or first zero element. */ + jno .Lfast_loop_found + + vl %v16,16(%r1,%r2) + vfaezfs %v18,%v16,%v17,0 + jno .Lfast_loop_found16 + + vl %v16,32(%r1,%r2) + vfaezfs %v18,%v16,%v17,0 + jno .Lfast_loop_found32 + + vl %v16,48(%r1,%r2) + vfaezfs %v18,%v16,%v17,0 + jno .Lfast_loop_found48 + + aghi %r1,64 + j .Lfast_loop /* Loop if no element was unequal to accept + and not zero. */ + + /* Found equal or zero element. */ +.Lfast_loop_found48: + aghi %r1,16 +.Lfast_loop_found32: + aghi %r1,16 +.Lfast_loop_found16: + aghi %r1,16 +.Lfast_loop_found: + vlgvb %r4,%v18,7 /* Load byte index of found element. */ +.Lfast_loop_found2: + srlg %r5,%r4,2 /* Convert byte-index to character-index. */ + vlgvf %r0,%v16,0(%r5) /* Get found element. */ + clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */ + algfr %r1,%r4 /* Add found index of char to current len. */ + la %r2,0(%r1,%r2) /* And return pointer to first equal char. */ + br %r14 + +.Lfast_end_null: + lghi %r2,0 /* Return null if no character is equal. */ + br %r14 + + + + + /* + Search s for accept in multiple vregs + ------------------------------------- + */ +.Lslow: + /* Save registers. */ + vlvgg %v30,%r6,0 + vlvgp %v31,%r8,%r9 + + /* Accept in v17 without zero */ + vlr %v19,%v17 /* Save first acc-part for a fast reload. */ + vzero %v20 /* Zero for preparing acc-vector. */ + vone %v24 /* One for checking result of former string. */ + + /* Align s to 16 byte. */ + risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and + %r4 = bits 60-63 'and' 15. */ + je .Lslow_loop_str /* If s is aligned, loop aligned. */ + lghi %r0,15 + slr %r0,%r4 /* Compute highest index to load (15-x). */ + vll %v16,%r0,0(%r2) /* Load up to 16byte boundary; + needs highest index, left bytes are 0. */ + ahi %r0,1 /* Work with loaded byte count. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept-string to zero. */ + vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end_null /* If first element is zero + (end of string) -> return null */ + clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ + locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ + j .Lslow_loop_acc + + + /* Process s in 16byte aligned loop. */ +.Lslow_next_str: + /* Check results of former processed str-part. */ + vfeef %v18,%v21,%v24 /* Find first equal match in global mask + (ones in element). */ + vlgvb %r4,%v18,7 /* Get index of first one (=equal) + or 16 if no match. */ + /* Equal-index < min(zero-index, loaded byte count) + -> return pointer to equal element. */ + clrjl %r4,%r6,.Lslow_index_found + /* Zero-index < loaded byte count + -> former str-part was last str-part + -> return null */ + clrjl %r6,%r0,.Lslow_end_null + /* All elements are zero (=no match) -> proceed with next str-part. */ + + vlr %v17,%v19 /* Load first part of accept (no zero). */ + algfr %r1,%r0 /* Add loaded byte count to current len. */ + +.Lslow_loop_str: + vl %v16,0(%r1,%r2) /* Load search-string */ + lghi %r0,16 /* Loaded byte count is 16. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept to zero. */ + vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + clije %r6,0,.Lslow_end_null /* If first element is zero + (end of string) -> return null. */ + +.Lslow_loop_acc: + vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> + Character matches any accepted character in + this accept-string-part) IN=0, RT=1. */ + vlgvf %r4,%v22,0 /* Get result of first element. */ + /* First element is equal to any accepted characters + (all other parts of accept cannot lead to a match before this one) + -> current len is pointing to first element + -> return found */ + clijh %r4,0,.Lslow_end_found + vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ + /* Proceed with next acc until end of acc is reached. */ + + +.Lslow_next_acc: + clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part + -> add index to current len and + end. */ + vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ + aghi %r5,16 /* Increment current len of accept-string. */ + lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ + jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is + on block-boundary. */ +.Lslow_next_acc_notonbb: + vistrfs %v17,%v17 /* Fill with zeros after first zero. */ + jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ + +.Lslow_next_acc_prepare_zero: + /* Zero in accept-part: fill zeros with first-accept-character. */ + vlgvf %r8,%v17,0 /* Load first element of acc-part. */ + clije %r8,0,.Lslow_next_str /* Proceed with next string-part, + If first char in this part of accept + is a zero. */ + /* r8>0 -> zero found in this acc-part. */ + vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ + vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars + by comparing with 0 (v20). */ + vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ + j .Lslow_loop_acc /* Accept part is prepared -> process. */ + +.Lslow_next_acc_onbb: + nill %r9,65532 /* Recognize only fully loaded characters. */ + je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t. */ + vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ + vlgvb %r8,%v18,7 /* Load byte index of zero. */ + clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes + -> Prepare vreg. */ +.Lslow_next_acc_onbb2: + vl %v17,0(%r5,%r3) /* Load over boundary ... */ + lghi %r8,0 /* r8=0 -> no zero in this part of acc, + check for zero is in jump-target. */ + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ + +.Lslow_end_null: + lghi %r1,0 /* Return null if no character is equal. */ + j .Lslow_end + +.Lslow_loop_found: + vlgvb %r4,%v18,7 /* Load byte index of found element. */ + srlg %r5,%r4,2 /* Convert byte-index to character-index. */ + vlgvf %r0,%v16,0(%r5) /* Get found element. */ + clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */ + +.Lslow_index_found: + algfr %r1,%r4 /* Add found index of char to current len. */ +.Lslow_end_found: + la %r1,0(%r1,%r2) /* And return pointer to first equal char. */ + +.Lslow_end: + /* Restore registers. */ + vlgvg %r6,%v30,0 + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + lgr %r2,%r1 + br %r14 +.Lfallback: + jg __wcspbrk_c +END(__wcspbrk_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/multiarch/wcspbrk.c new file mode 100644 index 0000000..9787632 --- /dev/null +++ b/sysdeps/s390/multiarch/wcspbrk.c @@ -0,0 +1,29 @@ +/* Multiple versions of wcspbrk. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wcspbrk __redirect_wcspbrk +# include +# undef wcspbrk +# include + +s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcsrchr-c.c b/sysdeps/s390/multiarch/wcsrchr-c.c new file mode 100644 index 0000000..6152503 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsrchr-c.c @@ -0,0 +1,25 @@ +/* Default wcsrchr implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSRCHR __wcsrchr_c + +# include +extern __typeof (wcsrchr) __wcsrchr_c; +# include +#endif diff --git a/sysdeps/s390/multiarch/wcsrchr-vx.S b/sysdeps/s390/multiarch/wcsrchr-vx.S new file mode 100644 index 0000000..e40a554 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsrchr-vx.S @@ -0,0 +1,190 @@ +/* Vector optimized 32/64 bit S/390 version of wcsrchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t *wcsrchr (const wchar_t *s, wchar_t c) + Locate the last character c in string. + + Register usage: + -r0=loaded bytes in first part of s. + -r1=pointer to last occurence of c or NULL if not found. + -r2=s + -r3=c + -r4=tmp + -r5=current_len + -v16=part of s + -v17=index of found element + -v18=replicated c + -v19=part of s with last occurence of c. + -v20=permute pattern +*/ +ENTRY(__wcsrchr_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ + vrepf %v18,%v18,0 + + lghi %r1,-1 /* Currently no c found. */ + lghi %r5,0 /* current_len = 0. */ + + vfeezfs %v17,%v16,%v18 /* Find element equal or zero. */ + vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */ + clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */ +.Lalign: + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r5,16 /* current_len = 16. */ + slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ + +.Lloop: + vl %v16,0(%r5,%r2) /* Load s. */ + vfeezfs %v17,%v16,%v18 /* Find element equal with zero search. */ + jno .Lfound /* Found c/zero (cc=0|1|2). */ + vl %v16,16(%r5,%r2) + vfeezfs %v17,%v16,%v18 + jno .Lfound16 + vl %v16,32(%r5,%r2) + vfeezfs %v17,%v16,%v18 + jno .Lfound32 + vl %v16,48(%r5,%r2) + vfeezfs %v17,%v16,%v18 + jno .Lfound48 + + aghi %r5,64 + j .Lloop /* No character and no zero -> loop. */ + +.Lfound48: + la %r5,16(%r5) /* Use la since aghi would clobber cc. */ +.Lfound32: + la %r5,16(%r5) +.Lfound16: + la %r5,16(%r5) +.Lfound: + je .Lzero /* Found zero, but no c before that zero. */ + /* Save this part of s to check for further matches after reaching + the end of the complete string. */ + vlr %v19,%v16 + lgr %r1,%r5 + + jh .Lzero /* Found a zero after the found c. */ + aghi %r5,16 /* Start search of next part of s. */ + j .Lloop + +.Lfound_first_part: + /* This code is only executed if the found c/zero is whithin loaded + bytes. If no c/zero was found (cc==3) the found index = 16, thus + this code is not called. + Resulting condition code of vector find element equal: + cc==0: no c, found zero + cc==1: c found, no zero + cc==2: c found, found zero after c + cc==3: no c, no zero (this case can be ignored). */ + je .Lzero /* Found zero, but no c before that zero. */ + + locgrne %r1,%r5 /* Mark c as found in first part of s. */ + vlr %v19,%v16 + + jl .Lalign /* No zero (e.g. if vr was fully loaded) + -> Align and loop afterwards. */ + + /* Found a zero in vr. If vr was not fully loaded due to block + boundary, the remaining bytes are filled with zero and we can't + rely on zero indication of condition code here! */ + + vfenezf %v17,%v16,%v16 + vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ + clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */ + j .Lalign /* Align and loop afterwards. */ + +.Lend_searched_zero: + vlgvb %r4,%v17,7 /* Load byte index of zero. */ + algr %r5,%r4 + la %r2,0(%r5,%r2) /* Return pointer to zero. */ + br %r14 + +.Lzero: + /* Reached end of string. Check if one c was found before. */ + clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */ + + cgfi %r1,-1 /* No c found -> return NULL. */ + locghie %r2,0 + ber %r14 + + larl %r3,.Lpermute_mask /* Load permute mask. */ + vl %v20,0(%r3) + + /* c was found and is part of v19. */ + vfenezf %v17,%v19,%v19 /* Find zero. */ + vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ + ahi %r4,3 /* Found zero index is first byte, + thus highest byte index is last byte of + wchar_t zero. */ + + clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */ + lochine %r0,16 /* ... if v19 is not the first part of s. */ + ahi %r0,-1 /* Convert byte count to highest index. */ + + clr %r0,%r4 + locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */ + + /* Right-shift of v19 to mask bytes after zero. */ + clije %r4,15,.Lzero_permute /* No shift is needed if highest index + in vr is 15. */ + lhi %r0,15 + slr %r0,%r4 /* Compute byte count for vector shift left. */ + sll %r0,3 /* Convert to bit count. */ + vlvgb %v17,%r0,7 + vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes + specified in bits 1-4 of byte 7 in v17. */ + + /* Reverse bytes in v19. */ +.Lzero_permute: + vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */ + + /* Find c in reversed v19. */ + vfeef %v19,%v19,%v18 /* Find c. */ + la %r2,0(%r1,%r2) + vlgvb %r3,%v19,7 /* Load byte index of c. */ + + /* Compute index in real s and return. */ + slgr %r4,%r3 + lay %r2,-3(%r4,%r2) /* Return pointer to zero. -3 is needed, + because the found byte index is reversed in + vector-register. Thus point to first byte of + wchar_t. */ + br %r14 +.Lpermute_mask: + .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) */ diff --git a/sysdeps/s390/multiarch/wcsrchr.c b/sysdeps/s390/multiarch/wcsrchr.c new file mode 100644 index 0000000..aa0b8a8 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsrchr.c @@ -0,0 +1,27 @@ +/* Multiple versions of wcsrchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc2 (__wcsrchr, wcsrchr) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wcsspn-c.c b/sysdeps/s390/multiarch/wcsspn-c.c new file mode 100644 index 0000000..2c0bd0f --- /dev/null +++ b/sysdeps/s390/multiarch/wcsspn-c.c @@ -0,0 +1,31 @@ +/* Default wcsspn implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WCSSPN __wcsspn_c + +# include +extern __typeof (wcsspn) __wcsspn_c; +# ifdef SHARED +# undef libc_hidden_def +# define libc_hidden_def(name) \ + __hidden_ver1 (__wcsspn_c, __GI_wcsspn, __wcsspn_c); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wcsspn-vx.S b/sysdeps/s390/multiarch/wcsspn-vx.S new file mode 100644 index 0000000..548f2ad --- /dev/null +++ b/sysdeps/s390/multiarch/wcsspn-vx.S @@ -0,0 +1,270 @@ +/* Vector optimized 32/64 bit S/390 version of wcsspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* size_t wcsspn (const wchar_t *s, const wchar_t * accept) + The wcsspn() function calculates the length of the initial segment + of s which consists entirely of characters in accept. + + This method checks the length of accept string. If it fits entirely + in one vector register, a fast algorithm is used, which does not need + to check multiple parts of accept-string. Otherwise a slower full + check of accept-string is used. + + register overview: + r3: pointer to start of accept-string + r2: pointer to start of search-string + r4: loaded byte count of vl search-string + r0: found byte index + r1: current return len of s + v16: search-string + v17: accept-string + v18: temp-vreg + + ONLY FOR SLOW: + v19: first accept-string + v20: zero for preparing acc-vector + v21: global mask; 1 indicates a match between + search-string-vreg and any accept-character + v22: current mask; 1 indicates a match between + search-string-vreg and any accept-character in current acc-vreg + v30, v31: for re-/storing registers r6, r8, r9 + r5: current len of accept-string + r6: zero-index in search-string or 16 if no zero + or min(zero-index, loaded byte count) + r8: >0, if former accept-string-part contains a zero, + otherwise =0; + r9: loaded byte count of vlbb accept-string +*/ +ENTRY(__wcsspn_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + /* + Check if accept-string fits in one vreg: + ---------------------------------------- + */ + vlbb %v17,0(%r3),6 /* Load accept. */ + lcbb %r4,0(%r3),6 + jo .Lcheck_onbb /* Special case if accept lays + on block-boundary. */ +.Lcheck_notonbb: + vistrfs %v17,%v17 /* Fill with zeros after first zero. */ + je .Lfast /* Zero found -> accept fits in one vreg. */ + j .Lslow /* No zero -> accept exceeds one vreg. */ + +.Lcheck_onbb: + /* Accept lays on block-boundary. */ + nill %r4,65532 /* Recognize only fully loaded characters. */ + je .Lcheck_onbb2 /* Reload vr if no full wchar_t. */ + vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ + vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */ + clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count -> + Accept fits in one vreg; + Fill with zeros and proceed + with FAST. */ +.Lcheck_onbb2: + vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ + j .Lcheck_notonbb /* Check if accept fits in one vreg. */ + + + /* + Search s for accept in one vreg + ------------------------------- + */ +.Lfast: + /* Complete accept-string in v17 and remaining bytes are zero. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + + vfaezfs %v16,%v16,%v17,8 /* Find first element in v16 + unequal to any in v17 + or first zero element. */ + + vlgvb %r0,%v16,7 /* Load byte index of found element. */ + /* If found index is within loaded bytes (%r0 < %r1), + return with found element index (=equal count). */ + clr %r0,%r1 + srlg %r0,%r0,2 /* Convert byte-count to character-count. */ + locgrl %r2,%r0 + blr %r14 + + /* Align s to 16 byte. */ + risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + lghi %r1,16 /* current_len = 16. */ + slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ + +.Lfast_loop: + vl %v16,0(%r1,%r2) /* Load search-string. */ + vfaezfs %v16,%v16,%v17,8 /* Find first element in v16 + unequal to any in v17 + or first zero element. */ + jno .Lfast_loop_found + vl %v16,16(%r1,%r2) + vfaezfs %v16,%v16,%v17,8 + jno .Lfast_loop_found16 + vl %v16,32(%r1,%r2) + vfaezfs %v16,%v16,%v17,8 + jno .Lfast_loop_found32 + vl %v16,48(%r1,%r2) + vfaezfs %v16,%v16,%v17,8 + jno .Lfast_loop_found48 + + aghi %r1,64 + j .Lfast_loop /* Loop if no element was unequal to accept + and not zero. */ + + /* Found unequal or zero element. */ +.Lfast_loop_found48: + aghi %r1,16 +.Lfast_loop_found32: + aghi %r1,16 +.Lfast_loop_found16: + aghi %r1,16 +.Lfast_loop_found: + vlgvb %r0,%v16,7 /* Load byte index of found element. */ + algrk %r2,%r1,%r0 /* And add it to current len. */ + srlg %r2,%r2,2 /* Convert byte-count to character-count. */ + br %r14 + + + /* + Search s for accept in multiple vregs + ------------------------------------- + */ +.Lslow: + /* Save registers. */ + vlvgg %v30,%r6,0 + vlvgp %v31,%r8,%r9 + lghi %r1,0 /* Zero out current len. */ + + /* accept in v17 without zero. */ + vlr %v19,%v17 /* Save first acc-part for a fast reload. */ + vzero %v20 /* Zero for preparing acc-vector. */ + + /* Align s to 16 byte. */ + risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and + %r0 = bits 60-63 'and' 15. */ + je .Lslow_loop_str /* If s is aligned, loop aligned */ + lghi %r4,15 + slr %r4,%r0 /* Compute highest index to load (15-x). */ + vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs + highest index, remaining bytes are 0). */ + aghi %r4,1 /* Work with loaded byte count. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept-string to zero. */ + vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 + if there is no zero. */ + clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */ + locrl %r6,%r4 /* Load on cc==1. */ + j .Lslow_loop_acc + + /* Process s in 16byte aligned loop. */ +.Lslow_next_str: + vlr %v17,%v19 /* Load first part of accept (no zero). */ + algfr %r1,%r4 /* Add loaded byte count to current len. */ +.Lslow_loop_str: + vl %v16,0(%r1,%r2) /* Load search-string. */ + lghi %r4,16 /* Loaded byte count is 16. */ + vzero %v21 /* Zero out global mask. */ + lghi %r5,0 /* Set current len of accept-string to zero. */ + vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ + lghi %r8,0 /* There is no zero in first accept-part. */ + vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ + +.Lslow_loop_acc: + vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> + character matches any accepted character in + this accept-string-part) IN=0, RT=1. */ + vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */ + vfenezf %v18,%v21,%v21 /* Find first zero in global-mask. */ + vlgvb %r0,%v18,7 /* Get first found zero-index + (= first mismatch). */ + clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index) + -> Process this string-part + with next acc-part. */ + clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count + -> All loaded bytes are matching + any accept-character + and are not zero. */ + /* All bytes are matching any characters in accept-string + and search-string is fully processed (found-index == zero-index). */ +.Lslow_add_lbc_end: + algrk %r2,%r1,%r0 /* Add matching characters to current len. */ + srlg %r2,%r2,2 /* Convert byte-count to character-count. */ + /* Restore registers. */ + vlgvg %r6,%v30,0 + vlgvg %r8,%v31,0 + vlgvg %r9,%v31,1 + br %r14 + +.Lslow_next_acc: + clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part + -> Add found index to current len + and end. */ + vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ + aghi %r5,16 /* Increment current len of accept-string. */ + lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ + jo .Lslow_next_acc_onbb /* Jump away if accept-string is + on block-boundary. */ +.Lslow_next_acc_notonbb: + vistrfs %v17,%v17 /* Fill with zeros after first zero. */ + jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ + +.Lslow_next_acc_prepare_zero: + /* Zero in accept-part: fill zeros with first-accept-character. */ + vlgvf %r8,%v17,0 /* Load first element of acc-part. */ + clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character + in this part of accept-string. */ + /* r8>0 -> zero found in this acc-part. */ + vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ + vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars + by comparing with 0 (v20). */ + vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ + j .Lslow_loop_acc /* Accept part is prepared -> process. */ + +.Lslow_next_acc_onbb: + nill %r9,65532 /* Recognize only fully loaded characters. */ + je .Lslow_next_acc_onbb2 /* Reload vr, if we loaded no full + wchar_t. */ + vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ + vlgvb %r8,%v18,7 /* Load byte index of zero. */ + clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes + -> Prepare vreg. */ +.Lslow_next_acc_onbb2: + vl %v17,0(%r5,%r3) /* Load over boundary ... */ + lghi %r8,0 /* r8=0 -> no zero in this part of acc, + check for zero is in jump-target. */ + 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) */ diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/multiarch/wcsspn.c new file mode 100644 index 0000000..7743144 --- /dev/null +++ b/sysdeps/s390/multiarch/wcsspn.c @@ -0,0 +1,29 @@ +/* Multiple versions of wcsspn. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wcsspn __redirect_wcsspn +# include +# undef wcsspn +# include + +s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wmemchr-c.c b/sysdeps/s390/multiarch/wmemchr-c.c new file mode 100644 index 0000000..089392b --- /dev/null +++ b/sysdeps/s390/multiarch/wmemchr-c.c @@ -0,0 +1,37 @@ +/* Default wmemchr implementation for S/390. + 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 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) \ + strong_alias (__wmemchr_c, __wmemchr_c_1); \ + __hidden_ver1 (__wmemchr_c_1, __GI_wmemchr, __wmemchr_c_1); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wmemchr-vx.S b/sysdeps/s390/multiarch/wmemchr-vx.S new file mode 100644 index 0000000..db057b5 --- /dev/null +++ b/sysdeps/s390/multiarch/wmemchr-vx.S @@ -0,0 +1,166 @@ +/* Vector optimized 32/64 bit S/390 version of wmemchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t *wmemchr (const wchar_t *s, wchar_t c, size_t n) + Scans memory for character c + and returns pointer to first c. + + Register usage: + -r0=tmp + -r1=tmp + -r2=s + -r3=c + -r4=n + -r5=current_len + -v16=part of s + -v17=index of found c + -v18=c replicated +*/ +ENTRY(__wmemchr_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + clgije %r4,0,.Lnf_end /* If len == 0 then exit. */ + + vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ + lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ + llgfr %r0,%r0 /* Convert 32bit to 64bit. */ + + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + + vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ + vrepf %v18,%v18,0 + lghi %r5,16 /* current_len = 16. */ + + /* Check range of maxlen and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + llilf %r1,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + + clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n, + jump to lastcmp. */ + + vfeefs %v17,%v16,%v18 /* Find c. */ + vlgvb %r1,%v17,7 /* Load byte index of c. */ + clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */ + + /* Align s to 16 byte. */ + risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ + slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ + + lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ + aghi %r0,64 + clgrjl %r0,%r4,.Lloop64 +.Llt64: + vl %v16,0(%r5,%r2) + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */ + vfeefs %v17,%v16,%v18 /* Find c. */ + jl .Lfound /* Jump away if c was found. */ + + vl %v16,0(%r5,%r2) + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp + vfeefs %v17,%v16,%v18 + jl .Lfound + + vl %v16,0(%r5,%r2) + aghi %r5,16 + clgrjhe %r5,%r4,.Llastcmp + vfeefs %v17,%v16,%v18 + jl .Lfound + + vl %v16,0(%r5,%r2) + aghi %r5,16 + +.Llastcmp: + /* Use comparision result only if located within first n characters. + %r5: current_len; + %r4: n; + (current_len - n): [0...16[ + first ignored match index = vr-width - (current_len - n) ]0...16] + */ + vfeefs %v17,%v16,%v18 /* Find c. */ + slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */ + lghi %r0,16 /* Register width = 16. */ + vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */ + slr %r0,%r4 /* %r0 = first ignored match index. */ + clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */ + /* c not found within n-bytes. */ +.Lnf_end: + lghi %r2,0 /* Return null. */ + br %r14 + +.Lfound48: + aghi %r5,16 +.Lfound32: + aghi %r5,16 +.Lfound16: + aghi %r5,16 +.Lfound0: + aghi %r5,16 +.Lfound: + vlgvb %r1,%v17,7 /* Load byte index of c. */ +.Lfound2: + slgfi %r5,16 /* current_len -=16 */ + algr %r5,%r1 /* Zero byte index is added to current len. */ + la %r2,0(%r5,%r2) /* Return pointer to c. */ + br %r14 + +.Lloop64: + vl %v16,0(%r5,%r2) + vfeefs %v17,%v16,%v18 /* Find c. */ + jl .Lfound0 /* Jump away if c was found. */ + vl %v16,16(%r5,%r2) + vfeefs %v17,%v16,%v18 + jl .Lfound16 + vl %v16,32(%r5,%r2) + vfeefs %v17,%v16,%v18 + jl .Lfound32 + vl %v16,48(%r5,%r2) + vfeefs %v17,%v16,%v18 + jl .Lfound48 + + aghi %r5,64 + lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ + aghi %r0,64 + clgrjl %r0,%r4,.Lloop64 + + j .Llt64 +.Lfallback: + jg __wmemchr_c +END(__wmemchr_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/multiarch/wmemchr.c new file mode 100644 index 0000000..6b55c1d --- /dev/null +++ b/sysdeps/s390/multiarch/wmemchr.c @@ -0,0 +1,32 @@ +/* Multiple versions of wmemchr. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wmemchr __redirect_wmemchr +# define __wmemchr __redirect___wmemchr +# include +# undef wmemchr +# undef __wmemchr +# include + +s390_vx_libc_ifunc_redirected (__redirect___wmemchr, __wmemchr) +weak_alias (__wmemchr, wmemchr) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wmemcmp-c.c b/sysdeps/s390/multiarch/wmemcmp-c.c new file mode 100644 index 0000000..2fd39d5 --- /dev/null +++ b/sysdeps/s390/multiarch/wmemcmp-c.c @@ -0,0 +1,26 @@ +/* Default wmemcmp implementation for S/390. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define WMEMCMP __wmemcmp_c + +# include +extern __typeof (wmemcmp) __wmemcmp_c; + +# include +#endif diff --git a/sysdeps/s390/multiarch/wmemcmp-vx.S b/sysdeps/s390/multiarch/wmemcmp-vx.S new file mode 100644 index 0000000..e2fc21e --- /dev/null +++ b/sysdeps/s390/multiarch/wmemcmp-vx.S @@ -0,0 +1,149 @@ +/* Vector Optimized 32/64 bit S/390 version of wmemcmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* int wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n) + Compare at most n characters of two wchar_t-arrays. + + Register usage: + -r0=tmp + -r1=number of blocks + -r2=s1 + -r3=s2 + -r4=n + -r5=current_len + -v16=part of s1 + -v17=part of s2 + -v18=index of unequal +*/ +ENTRY(__wmemcmp_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */ + + /* Check range of maxlen and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + llilf %r1,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ + + lghi %r5,0 /* current_len = 0. */ + + clgijh %r4,16,.Lgt16 + +.Lremaining: + aghi %r4,-1 /* vstl needs highest index. */ + vll %v16,%r4,0(%r2) + vll %v17,%r4,0(%r3) + vfenef %v18,%v16,%v17 /* Compare not equal. */ + vlgvb %r1,%v18,7 /* Load unequal index or 16 if not found. */ + clrj %r1,%r4,12,.Lfound2 /* r1 <= r4 -> unequal within loaded + bytes. */ + +.Lend_equal: + lghi %r2,0 + br %r14 + +.Lfound: + /* vfenezf found an unequal element or zero. + This instruction compares unsigned words, but wchar_t is signed. + Thus we have to compare the found element again. */ + vlgvb %r1,%v18,7 /* Extract not equal byte-index. */ +.Lfound2: + srl %r1,2 /* And convert it to character-index. */ + vlgvf %r0,%v16,0(%r1) /* Load character-values. */ + vlgvf %r1,%v17,0(%r1) + cr %r0,%r1 + je .Lend_equal + lghi %r2,1 + lghi %r1,-1 + locgrl %r2,%r1 + br %r14 + +.Lgt16: + clgijh %r4,64,.Lpreloop64 + +.Lpreloop16: + srlg %r1,%r4,4 /* Split into 16byte blocks */ +.Lloop16: + vl %v16,0(%r5,%r2) + vl %v17,0(%r5,%r3) + aghi %r5,16 + vfenefs %v18,%v16,%v17 /* Compare not equal. */ + jno .Lfound + brctg %r1,.Lloop16 /* Loop until all blocks are processed. */ + + llgfr %r4,%r4 + nilf %r4,15 /* Get remaining bytes */ + locgre %r2,%r4 + ber %r14 + la %r2,0(%r5,%r2) + la %r3,0(%r5,%r3) + j .Lremaining + +.Lpreloop64: + srlg %r1,%r4,6 /* Split into 64byte blocks */ +.Lloop64: + vl %v16,0(%r5,%r2) + vl %v17,0(%r5,%r3) + vfenefs %v18,%v16,%v17 /* Compare not equal. */ + jno .Lfound + + vl %v16,16(%r5,%r2) + vl %v17,16(%r5,%r3) + vfenefs %v18,%v16,%v17 + jno .Lfound + + vl %v16,32(%r5,%r2) + vl %v17,32(%r5,%r3) + vfenefs %v18,%v16,%v17 + jno .Lfound + + vl %v16,48(%r5,%r2) + vl %v17,48(%r5,%r3) + aghi %r5,64 + vfenefs %v18,%v16,%v17 + jno .Lfound + + brctg %r1,.Lloop64 /* Loop until all blocks are processed. */ + + llgfr %r4,%r4 + nilf %r4,63 /* Get remaining bytes */ + locgre %r2,%r4 + ber %r14 + clgijh %r4,16,.Lpreloop16 + la %r2,0(%r5,%r2) + la %r3,0(%r5,%r3) + j .Lremaining +END(__wmemcmp_vx) +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wmemcmp.c b/sysdeps/s390/multiarch/wmemcmp.c new file mode 100644 index 0000000..a4cb440 --- /dev/null +++ b/sysdeps/s390/multiarch/wmemcmp.c @@ -0,0 +1,27 @@ +/* Multiple versions of wmemcmp. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# include +# include + +s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/multiarch/wmemset-c.c b/sysdeps/s390/multiarch/wmemset-c.c new file mode 100644 index 0000000..1969cf9 --- /dev/null +++ b/sysdeps/s390/multiarch/wmemset-c.c @@ -0,0 +1,37 @@ +/* Default wmemset implementation for S/390. + 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 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) \ + strong_alias (__wmemset_c, __wmemset_c_1); \ + __hidden_ver1 (__wmemset_c_1, __GI_wmemset, __wmemset_c_1); +# endif /* SHARED */ + +# include +#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ diff --git a/sysdeps/s390/multiarch/wmemset-vx.S b/sysdeps/s390/multiarch/wmemset-vx.S new file mode 100644 index 0000000..0c2f633 --- /dev/null +++ b/sysdeps/s390/multiarch/wmemset-vx.S @@ -0,0 +1,142 @@ +/* Vector Optimized 32/64 bit S/390 version of wmemset. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + +# include "sysdep.h" +# include "asm-syntax.h" + + .text + +/* wchar_t *wmemset(wchar_t *dest, wchar_t wc, size_t n) + Fill an array of wide-characters with a constant wide character + and returns dest. + + Register usage: + -r0=tmp + -r1=tmp + -r2=dest or current-pointer + -r3=wc + -r4=n + -r5=tmp + -v16=replicated wc + -v17,v18,v19=copy of v16 for vstm + -v31=saved dest for return +*/ +ENTRY(__wmemset_vx) + .machine "z13" + .machinemode "zarch_nohighgprs" + +# if !defined __s390x__ + llgfr %r4,%r4 +# endif /* !defined __s390x__ */ + + vlvgg %v31,%r2,0 /* Save destination pointer for return. */ + clgije %r4,0,.Lend + + vlvgf %v16,%r3,0 /* Generate vector with wchar_t wc. */ + vrepf %v16,%v16,0 + + /* Check range of maxlen and convert to byte-count. */ +# ifdef __s390x__ + tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + lghi %r5,-4 /* Max byte-count is 18446744073709551612. */ +# else + tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ + llilf %r5,4294967292 /* Max byte-count is 4294967292. */ +# endif /* !__s390x__ */ + sllg %r4,%r4,2 /* Convert character-count to byte-count. */ + locgrne %r4,%r5 /* Use max byte-count, if bit 0/1 was one. */ + + /* Align dest to 16 byte. */ + risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and + %r3 = bits 60-63 'and' 15. */ + je .Lpreloop /* If s is aligned, loop aligned. */ + tmll %r2,3 /* Test if s is 4-byte aligned? */ + jne .Lfallback /* And use common-code variant if not. */ + lghi %r1,16 + slr %r1,%r0 /* Compute byte count to load (16-x). */ + clgr %r1,%r4 + locgrh %r1,%r4 /* min (byte count, n) */ + aghik %r5,%r1,-1 /* vstl needs highest index. */ + vstl %v16,%r5,0(%r2) /* Store remaining bytes. */ + clgrje %r1,%r4,.Lend /* Return if n bytes where set. */ + slgr %r4,%r1 /* Compute remaining byte count. */ + la %r2,0(%r1,%r2) + +.Lpreloop: + /* Now we are 16-byte aligned. */ + clgijl %r4,17,.Lremaining + srlg %r1,%r4,8 /* Split into 256byte blocks */ + clgije %r1,0,.Lpreloop64 + vlr %v17,%v16 + vlr %v18,%v16 + vlr %v19,%v16 + +.Lloop256: + vstm %v16,%v19,0(%r2) + vstm %v16,%v19,64(%r2) + vstm %v16,%v19,128(%r2) + vstm %v16,%v19,192(%r2) + la %r2,256(%r2) + brctg %r1,.Lloop256 /* Loop until all blocks are processed. */ + + llgfr %r4,%r4 + nilf %r4,255 /* Get remaining bytes */ + je .Lend /* Skip store remaining bytes if zero. */ + +.Lpreloop64: + clgijl %r4,17,.Lremaining + clgijl %r4,33,.Lpreloop16 + srlg %r1,%r4,5 /* Split into 32byte blocks */ + +.Lloop32: + vst %v16,0(%r2) + vst %v16,16(%r2) + la %r2,32(%r2) + brctg %r1,.Lloop32 /* Loop until all blocks are processed. */ + + llgfr %r4,%r4 + nilf %r4,31 /* Get remaining bytes */ + je .Lend /* Skip store remaining bytes if zero. */ + +.Lpreloop16: + clgijl %r4,17,.Lremaining + srlg %r1,%r4,4 /* Split into 16byte blocks */ + +.Lloop16: + vst %v16,0(%r2) + la %r2,16(%r2) + brctg %r1,.Lloop16 /* Loop until all blocks are processed. */ + + llgfr %r4,%r4 + nilf %r4,15 /* Get remaining bytes */ + je .Lend /* Skip store remaining bytes if zero. */ + +.Lremaining: + aghi %r4,-1 /* vstl needs highest index. */ + vstl %v16,%r4,0(%r2) + +.Lend: + vlgvg %r2,%v31,0 /* Load saved dest for return value. */ + 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) */ diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/multiarch/wmemset.c new file mode 100644 index 0000000..149b481 --- /dev/null +++ b/sysdeps/s390/multiarch/wmemset.c @@ -0,0 +1,32 @@ +/* Multiple versions of wmemset. + 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 defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) +# define wmemset __redirect_wmemset +# define __wmemset __redirect___wmemset +# include +# undef wmemset +# undef __wmemset +# include + +s390_vx_libc_ifunc_redirected (__redirect___wmemset, __wmemset) +weak_alias (__wmemset, wmemset) + +#else +# include +#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ diff --git a/sysdeps/s390/rawmemchr-c.c b/sysdeps/s390/rawmemchr-c.c deleted file mode 100644 index 8b8208e..0000000 --- a/sysdeps/s390/rawmemchr-c.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Default rawmemchr implementation for S/390. - 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 - . */ - -#include - -#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 - -# include -#endif diff --git a/sysdeps/s390/rawmemchr-vx.S b/sysdeps/s390/rawmemchr-vx.S deleted file mode 100644 index f04c0e8..0000000 --- a/sysdeps/s390/rawmemchr-vx.S +++ /dev/null @@ -1,104 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of rawmemchr. - 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 - . */ - -#include - -#if HAVE_RAWMEMCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* void *rawmemchr (const void *s, int c) - Scans memory for character c - and returns pointer to first c. - - Register usage: - -r1=tmp - -r2=s - -r3=c - -r4=tmp - -r5=current_len - -v16=part of s - -v17=index of unequal - -v18=c replicated -*/ -ENTRY(RAWMEMCHR_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vlvgb %v18,%r3,0 /* Generate vector which elements are all c. - If c > 255, c will be truncated. */ - vrepb %v18,%v18,0 - - vfeeb %v17,%v16,%v18 /* Vector find element equal. */ - vlgvb %r5,%v17,7 /* Load byte index of character or zero. */ - clrjl %r5,%r1,.Lend_found /* If found c is in loaded bytes, end. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 - slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ - - /* Find c in a 16byte aligned loop. */ -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfeebs %v17,%v16,%v18 /* Vector find element equal. */ - jno .Lcharacter /* Jump away if element found. */ - vl %v16,16(%r5,%r2) - vfeebs %v17,%v16,%v18 - jno .Lcharacter16 - vl %v16,32(%r5,%r2) - vfeebs %v17,%v16,%v18 - jno .Lcharacter32 - vl %v16,48(%r5,%r2) - vfeebs %v17,%v16,%v18 - jno .Lcharacter48 - - aghi %r5,64 - j .Lloop /* No character found -> loop. */ - - /* Found character. */ -.Lcharacter48: - aghi %r5,16 -.Lcharacter32: - aghi %r5,16 -.Lcharacter16: - aghi %r5,16 -.Lcharacter: - vlgvb %r1,%v17,7 /* Load byte index of character. */ - algr %r5,%r1 -.Lend_found: - la %r2,0(%r5,%r2) /* Return pointer to character. */ - br %r14 -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/rawmemchr.c b/sysdeps/s390/rawmemchr.c deleted file mode 100644 index d9263ce..0000000 --- a/sysdeps/s390/rawmemchr.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Multiple versions of rawmemchr. - 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 - . */ - -#include - -#if HAVE_RAWMEMCHR_IFUNC -# define __rawmemchr __redirect___rawmemchr -# include -# undef __rawmemchr -# include - -# if HAVE_RAWMEMCHR_C -extern __typeof (__redirect___rawmemchr) RAWMEMCHR_C attribute_hidden; -# endif - -# if HAVE_RAWMEMCHR_Z13 -extern __typeof (__redirect___rawmemchr) RAWMEMCHR_Z13 attribute_hidden; -# endif - -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/sysdeps/s390/s390-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S new file mode 100644 index 0000000..560e04f --- /dev/null +++ b/sysdeps/s390/s390-32/bcopy.S @@ -0,0 +1,85 @@ +/* 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-32/bzero.S b/sysdeps/s390/s390-32/bzero.S new file mode 100644 index 0000000..897aa21 --- /dev/null +++ b/sysdeps/s390/s390-32/bzero.S @@ -0,0 +1,42 @@ +/* bzero -- set a block of memory to zero. IBM S390 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 + . */ + +/* + * 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 +weak_alias (__bzero, bzero) +#endif diff --git a/sysdeps/s390/s390-32/memchr.S b/sysdeps/s390/s390-32/memchr.S new file mode 100644 index 0000000..54f9b85 --- /dev/null +++ b/sysdeps/s390/s390-32/memchr.S @@ -0,0 +1,41 @@ +/* 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/memcmp.S b/sysdeps/s390/s390-32/memcmp.S new file mode 100644 index 0000000..f9ad0bc --- /dev/null +++ b/sysdeps/s390/s390-32/memcmp.S @@ -0,0 +1,66 @@ +/* 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/memcpy.S b/sysdeps/s390/s390-32/memcpy.S new file mode 100644 index 0000000..493cc18 --- /dev/null +++ b/sysdeps/s390/s390-32/memcpy.S @@ -0,0 +1,89 @@ +/* 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/memset.S b/sysdeps/s390/s390-32/memset.S new file mode 100644 index 0000000..57f08e1 --- /dev/null +++ b/sysdeps/s390/s390-32/memset.S @@ -0,0 +1,65 @@ +/* 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 new file mode 100644 index 0000000..f8aee14 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/Makefile @@ -0,0 +1,4 @@ +ifeq ($(subdir),string) +sysdep_routines += memset memset-s390 memcpy memcpy-s390 \ + memcmp memcmp-s390 +endif diff --git a/sysdeps/s390/s390-32/multiarch/memchr.c b/sysdeps/s390/s390-32/multiarch/memchr.c new file mode 100644 index 0000000..5e1610a --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/memchr.c @@ -0,0 +1,21 @@ +/* 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-32/multiarch/memcmp-s390.S b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S new file mode 100644 index 0000000..e53b508 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S @@ -0,0 +1,107 @@ +/* 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-32/multiarch/memcmp.c b/sysdeps/s390/s390-32/multiarch/memcmp.c new file mode 100644 index 0000000..1e6f318 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/memcmp.c @@ -0,0 +1,27 @@ +/* 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/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S new file mode 100644 index 0000000..aad13bd --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S @@ -0,0 +1,128 @@ +/* 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-32/multiarch/memcpy.c b/sysdeps/s390/s390-32/multiarch/memcpy.c new file mode 100644 index 0000000..c9577a8 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/memcpy.c @@ -0,0 +1,27 @@ +/* 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/sysdeps/s390/s390-32/multiarch/memset-s390.S b/sysdeps/s390/s390-32/multiarch/memset-s390.S new file mode 100644 index 0000000..b092073 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/memset-s390.S @@ -0,0 +1,116 @@ +/* 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-32/multiarch/memset.c b/sysdeps/s390/s390-32/multiarch/memset.c new file mode 100644 index 0000000..760b3e9 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/memset.c @@ -0,0 +1,26 @@ +/* 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/sysdeps/s390/s390-32/multiarch/strcmp.c b/sysdeps/s390/s390-32/multiarch/strcmp.c new file mode 100644 index 0000000..d06b0f3 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/strcmp.c @@ -0,0 +1,21 @@ +/* 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/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c new file mode 100644 index 0000000..6a22e31 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/strcpy.c @@ -0,0 +1,21 @@ +/* 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/multiarch/strncpy.c b/sysdeps/s390/s390-32/multiarch/strncpy.c new file mode 100644 index 0000000..57f9df1 --- /dev/null +++ b/sysdeps/s390/s390-32/multiarch/strncpy.c @@ -0,0 +1,21 @@ +/* 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/strcmp.S b/sysdeps/s390/s390-32/strcmp.S new file mode 100644 index 0000000..3cf3f23 --- /dev/null +++ b/sysdeps/s390/s390-32/strcmp.S @@ -0,0 +1,41 @@ +/* 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-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S new file mode 100644 index 0000000..d49136e --- /dev/null +++ b/sysdeps/s390/s390-32/strcpy.S @@ -0,0 +1,36 @@ +/* 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-32/strncpy-z900.S b/sysdeps/s390/s390-32/strncpy-z900.S deleted file mode 100644 index ebdaba0..0000000 --- a/sysdeps/s390/s390-32/strncpy-z900.S +++ /dev/null @@ -1,89 +0,0 @@ -/* strncpy - copy at most n characters from 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 (dst) - * R3 = address of source (src) - * R4 = max of bytes to copy - */ - -#include -#include "sysdep.h" -#include "asm-syntax.h" - -#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 - lhi %r1,3 - nr %r1,%r4 # last 2 bits of # bytes - srl %r4,2 - ltr %r4,%r4 # less than 4 bytes to copy ? - jz .L1 - bras %r5,.L0 # enter loop & load address of a 0 - .long 0 -.L0: icm %r0,8,0(%r3) # first byte - jz .L3 - icm %r0,4,1(%r3) # second byte - jz .L4 - icm %r0,2,2(%r3) # third byte - jz .L5 - icm %r0,1,3(%r3) # fourth byte - jz .L6 - st %r0,0(%r2,%r3) # store all four to dest. - la %r3,4(%r3) - brct %r4,.L0 -.L1: ltr %r1,%r1 - jz .Lexit -.L2: icm %r0,1,0(%r3) - stc %r0,0(%r2,%r3) - la %r3,1(%r3) - jz .L7 - brct %r1,.L2 - j .Lexit -.L3: icm %r0,4,0(%r5) -.L4: icm %r0,2,0(%r5) -.L5: icm %r0,1,0(%r5) -.L6: st %r0,0(%r2,%r3) - la %r3,4(%r3) - ahi %r4,-1 - j .L8 -.L7: ahi %r1,-1 -.L8: sll %r4,2 - alr %r4,%r1 - alr %r2,%r3 # start of dst area to be zeroed - lr %r3,%r4 - slr %r4,%r4 - slr %r5,%r5 -.L9: mvcle %r2,%r4,0 # pad dst with zeroes - jo .L9 -.Lexit: l %r2,24(%r15) # return dst pointer - br %r14 -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-32/strncpy.S b/sysdeps/s390/s390-32/strncpy.S new file mode 100644 index 0000000..9086eb1 --- /dev/null +++ b/sysdeps/s390/s390-32/strncpy.S @@ -0,0 +1,79 @@ +/* strncpy - copy at most n characters from 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 (dst) + * R3 = address of source (src) + * R4 = max of bytes to copy + */ + +#include "sysdep.h" +#include "asm-syntax.h" + +ENTRY(strncpy) + .text + st %r2,24(%r15) # save dst pointer + slr %r2,%r3 # %r3 points to src, %r2+%r3 to dst + lhi %r1,3 + nr %r1,%r4 # last 2 bits of # bytes + srl %r4,2 + ltr %r4,%r4 # less than 4 bytes to copy ? + jz .L1 + bras %r5,.L0 # enter loop & load address of a 0 + .long 0 +.L0: icm %r0,8,0(%r3) # first byte + jz .L3 + icm %r0,4,1(%r3) # second byte + jz .L4 + icm %r0,2,2(%r3) # third byte + jz .L5 + icm %r0,1,3(%r3) # fourth byte + jz .L6 + st %r0,0(%r2,%r3) # store all four to dest. + la %r3,4(%r3) + brct %r4,.L0 +.L1: ltr %r1,%r1 + jz .Lexit +.L2: icm %r0,1,0(%r3) + stc %r0,0(%r2,%r3) + la %r3,1(%r3) + jz .L7 + brct %r1,.L2 + j .Lexit +.L3: icm %r0,4,0(%r5) +.L4: icm %r0,2,0(%r5) +.L5: icm %r0,1,0(%r5) +.L6: st %r0,0(%r2,%r3) + la %r3,4(%r3) + ahi %r4,-1 + j .L8 +.L7: ahi %r1,-1 +.L8: sll %r4,2 + alr %r4,%r1 + alr %r2,%r3 # start of dst area to be zeroed + lr %r3,%r4 + slr %r4,%r4 + slr %r5,%r5 +.L9: mvcle %r2,%r4,0 # pad dst with zeroes + jo .L9 +.Lexit: l %r2,24(%r15) # return dst pointer + br %r14 +END(strncpy) +libc_hidden_builtin_def (strncpy) diff --git a/sysdeps/s390/s390-64/Implies b/sysdeps/s390/s390-64/Implies index 7603c98..a8cae95 100644 --- a/sysdeps/s390/s390-64/Implies +++ b/sysdeps/s390/s390-64/Implies @@ -1,2 +1 @@ wordsize-64 -ieee754/dbl-64/wordsize-64 diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S new file mode 100644 index 0000000..806dd15 --- /dev/null +++ b/sysdeps/s390/s390-64/bcopy.S @@ -0,0 +1,71 @@ +/* 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/sysdeps/s390/s390-64/bzero.S b/sysdeps/s390/s390-64/bzero.S new file mode 100644 index 0000000..b321665 --- /dev/null +++ b/sysdeps/s390/s390-64/bzero.S @@ -0,0 +1,41 @@ +/* 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/sysdeps/s390/s390-64/memchr.S b/sysdeps/s390/s390-64/memchr.S new file mode 100644 index 0000000..a19fcaf --- /dev/null +++ b/sysdeps/s390/s390-64/memchr.S @@ -0,0 +1,40 @@ +/* Search a character in a block of memory. 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 + . */ + +/* INPUT PARAMETERS + %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) + 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 +1: br %r14 +END(memchr) +libc_hidden_builtin_def (memchr) diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/s390-64/memcmp.S new file mode 100644 index 0000000..005b19d --- /dev/null +++ b/sysdeps/s390/s390-64/memcmp.S @@ -0,0 +1,64 @@ +/* memcmp - compare two memory blocks. 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 +#ifdef USE_MULTIARCH +ENTRY(__memcmp_default) +#else +ENTRY(memcmp) +#endif + .machine "z900" + ltgr %r4,%r4 + je .L_Z900_4 + aghi %r4,-1 + 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: + ipm %r2 + sllg %r2,%r2,34 + srag %r2,%r2,62 + br %r14 +.L_Z900_12: + clc 0(256,%r3),0(%r2) + jne .L_Z900_4 + la %r3,256(%r3) + la %r2,256(%r2) + brctg %r1,.L_Z900_12 + j .L_Z900_3 +.L_Z900_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 diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/s390-64/memcpy.S new file mode 100644 index 0000000..2e5490d --- /dev/null +++ b/sysdeps/s390/s390-64/memcpy.S @@ -0,0 +1,88 @@ +/* memcpy - copy a block from source to destination. 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 destination memory area + %r3 = address of source memory area + %r4 = number of bytes to copy. */ + + + .text +ENTRY(__mempcpy) + .machine "z900" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z900_start +END(__mempcpy) +#ifndef USE_MULTIARCH +libc_hidden_def (__mempcpy) +weak_alias (__mempcpy, mempcpy) +libc_hidden_builtin_def (mempcpy) +#endif + +ENTRY(memcpy) + .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: + br %r14 +.L_Z900_13: + cghi %r5,4096 # Switch to mvcle for copies >1MB + jh __memcpy_mvcle +.L_Z900_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: + 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. + 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 + br %r14 +END(__memcpy_mvcle) diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/s390-64/memset.S new file mode 100644 index 0000000..8799c65 --- /dev/null +++ b/sysdeps/s390/s390-64/memset.S @@ -0,0 +1,64 @@ +/* Set a block of memory to some byte value. 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 + +#ifdef USE_MULTIARCH +ENTRY(__memset_default) +#else +ENTRY(memset) +#endif + .machine "z900" + ltgr %r4,%r4 + je .L_Z900_4 + stc %r3,0(%r2) + cghi %r4,1 + lgr %r1,%r2 + je .L_Z900_4 + aghi %r4,-2 + 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: + br %r14 +.L_Z900_14: + mvc 1(256,%r1),0(%r1) + la %r1,256(%r1) + brctg %r3,.L_Z900_14 + j .L_Z900_3 +.L_Z900_18: + 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-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile new file mode 100644 index 0000000..91053b5 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/Makefile @@ -0,0 +1,4 @@ +ifeq ($(subdir),string) +sysdep_routines += memset memset-s390x memcpy memcpy-s390x \ + memcmp memcmp-s390x +endif diff --git a/sysdeps/s390/s390-64/multiarch/memchr.c b/sysdeps/s390/s390-64/multiarch/memchr.c new file mode 100644 index 0000000..5e1610a --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/memchr.c @@ -0,0 +1,21 @@ +/* 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/memcmp-s390x.S b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S new file mode 100644 index 0000000..35f9bf9 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S @@ -0,0 +1,104 @@ +/* CPU specific memcmp implementations. 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 = 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" + 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) + +ENTRY(__memcmp_z10) + .machine "z10" + ltgr %r4,%r4 + je .L_Z10_4 + aghi %r4,-1 + srlg %r1,%r4,8 + cgijlh %r1,0,.L_Z10_12 +.L_Z10_3: + exrl %r4,.L_Z10_15 +.L_Z10_4: + ipm %r2 + sllg %r2,%r2,34 + srag %r2,%r2,62 + 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) + brctg %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/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c new file mode 100644 index 0000000..1e6f318 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/memcmp.c @@ -0,0 +1,27 @@ +/* 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/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S new file mode 100644 index 0000000..6d60a70 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S @@ -0,0 +1,122 @@ +/* CPU specific memcpy implementations. 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" + 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" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z196_start: + 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" + 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" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z10_start: + 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/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c new file mode 100644 index 0000000..c9577a8 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/memcpy.c @@ -0,0 +1,27 @@ +/* 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/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/sysdeps/s390/s390-64/multiarch/memset-s390x.S new file mode 100644 index 0000000..0c5aaef --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/memset-s390x.S @@ -0,0 +1,112 @@ +/* Set a block of memory to some byte value. 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 = 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" + 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) + +ENTRY(__memset_z10) + .machine "z10" + cgije %r4,0,.L_Z10_4 + stc %r3,0(%r2) + lgr %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) + aghi %r4,2 # take back the change done by the caller + lgr %r0,%r2 # save source address + lgr %r1,%r3 # move pad byte to R1 + lgr %r3,%r4 # move length to r3 + 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 + lgr %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/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c new file mode 100644 index 0000000..760b3e9 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/memset.c @@ -0,0 +1,26 @@ +/* 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/sysdeps/s390/s390-64/multiarch/strcmp.c b/sysdeps/s390/s390-64/multiarch/strcmp.c new file mode 100644 index 0000000..d06b0f3 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/strcmp.c @@ -0,0 +1,21 @@ +/* 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-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c new file mode 100644 index 0000000..6a22e31 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/strcpy.c @@ -0,0 +1,21 @@ +/* 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-64/multiarch/strncpy.c b/sysdeps/s390/s390-64/multiarch/strncpy.c new file mode 100644 index 0000000..57f9df1 --- /dev/null +++ b/sysdeps/s390/s390-64/multiarch/strncpy.c @@ -0,0 +1,21 @@ +/* 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/strcmp.S b/sysdeps/s390/s390-64/strcmp.S new file mode 100644 index 0000000..6cf1add --- /dev/null +++ b/sysdeps/s390/s390-64/strcmp.S @@ -0,0 +1,41 @@ +/* strcmp - compare two string. 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 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 + slgr %r2,%r2 + br %r14 +1: lghi %r2,1 + br %r14 +2: lghi %r2,-1 + br %r14 +END(strcmp) +libc_hidden_builtin_def (strcmp) diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/s390-64/strcpy.S new file mode 100644 index 0000000..203c73c --- /dev/null +++ b/sysdeps/s390/s390-64/strcpy.S @@ -0,0 +1,35 @@ +/* strcpy - copy a string from source to destination. 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 + . */ + +/* INPUT PARAMETERS + %r2 = address of destination + %r3 = address of source. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(strcpy) + slgr %r0,%r0 + lgr %r1,%r2 +0: mvst %r1,%r3 + jo 0b + br %r14 +END(strcpy) +libc_hidden_builtin_def (strcpy) diff --git a/sysdeps/s390/s390-64/strncpy-z900.S b/sysdeps/s390/s390-64/strncpy-z900.S deleted file mode 100644 index 5732e6d..0000000 --- a/sysdeps/s390/s390-64/strncpy-z900.S +++ /dev/null @@ -1,100 +0,0 @@ -/* strncpy - copy at most n characters from a string from source to - destination. 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 - . */ - -/* INPUT PARAMETERS - %r2 = address of destination (dst) - %r3 = address of source (src) - %r4 = max of bytes to copy. */ - -#include -#include "sysdep.h" -#include "asm-syntax.h" - -#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 - lghi %r1,7 - ngr %r1,%r4 # last 3 bits of # bytes - srlg %r4,%r4,3 - ltgr %r4,%r4 # less than 8 bytes to copy ? - jz .L1 - bras %r5,.L0 # enter loop & load address of a 0 - .long 0 -.L0: icmh %r0,8,0(%r3) # first byte - jz .L3 - icmh %r0,4,1(%r3) # second byte - jz .L4 - icmh %r0,2,2(%r3) # third byte - jz .L5 - icmh %r0,1,3(%r3) # fourth byte - jz .L6 - icm %r0,8,4(%r3) # fifth byte - jz .L7 - icm %r0,4,5(%r3) # sixth byte - jz .L8 - icm %r0,2,6(%r3) # seventh byte - jz .L9 - icm %r0,1,7(%r3) # eigth byte - jz .L10 - stg %r0,0(%r2,%r3) # store all eight to dest. - la %r3,8(%r3) - brct %r4,.L0 -.L1: ltgr %r1,%r1 - jz .Lexit -.L2: icm %r0,1,0(%r3) - stc %r0,0(%r2,%r3) - la %r3,1(%r3) - jz .L11 - brct %r1,.L2 - j .Lexit -.L3: icmh %r0,4,0(%r5) -.L4: icmh %r0,2,0(%r5) -.L5: icmh %r0,1,0(%r5) -.L6: icm %r0,8,0(%r5) -.L7: icm %r0,4,0(%r5) -.L8: icm %r0,2,0(%r5) -.L9: icm %r0,1,0(%r5) -.L10: stg %r0,0(%r2,%r3) - la %r3,8(%r3) - aghi %r4,-1 - j .L12 -.L11: aghi %r1,-1 -.L12: sllg %r4,%r4,3 - algr %r4,%r1 - algr %r2,%r3 # start of dst area to be zeroed - lgr %r3,%r4 - slgr %r4,%r4 - slgr %r5,%r5 -.L13: mvcle %r2,%r4,0 # pad dst with zeroes - jo .L13 -.Lexit: lg %r2,48(%r15) # return dst pointer - br %r14 -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/strncpy.S b/sysdeps/s390/s390-64/strncpy.S new file mode 100644 index 0000000..be40aa3 --- /dev/null +++ b/sysdeps/s390/s390-64/strncpy.S @@ -0,0 +1,90 @@ +/* strncpy - copy at most n characters from a string from source to + destination. 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 + . */ + +/* INPUT PARAMETERS + %r2 = address of destination (dst) + %r3 = address of source (src) + %r4 = max of bytes to copy. */ + +#include "sysdep.h" +#include "asm-syntax.h" + +ENTRY(strncpy) + .text + stg %r2,48(%r15) # save dst pointer + slgr %r2,%r3 # %r3 points to src, %r2+%r3 to dst + lghi %r1,7 + ngr %r1,%r4 # last 3 bits of # bytes + srlg %r4,%r4,3 + ltgr %r4,%r4 # less than 8 bytes to copy ? + jz .L1 + bras %r5,.L0 # enter loop & load address of a 0 + .long 0 +.L0: icmh %r0,8,0(%r3) # first byte + jz .L3 + icmh %r0,4,1(%r3) # second byte + jz .L4 + icmh %r0,2,2(%r3) # third byte + jz .L5 + icmh %r0,1,3(%r3) # fourth byte + jz .L6 + icm %r0,8,4(%r3) # fifth byte + jz .L7 + icm %r0,4,5(%r3) # sixth byte + jz .L8 + icm %r0,2,6(%r3) # seventh byte + jz .L9 + icm %r0,1,7(%r3) # eigth byte + jz .L10 + stg %r0,0(%r2,%r3) # store all eight to dest. + la %r3,8(%r3) + brct %r4,.L0 +.L1: ltgr %r1,%r1 + jz .Lexit +.L2: icm %r0,1,0(%r3) + stc %r0,0(%r2,%r3) + la %r3,1(%r3) + jz .L11 + brct %r1,.L2 + j .Lexit +.L3: icmh %r0,4,0(%r5) +.L4: icmh %r0,2,0(%r5) +.L5: icmh %r0,1,0(%r5) +.L6: icm %r0,8,0(%r5) +.L7: icm %r0,4,0(%r5) +.L8: icm %r0,2,0(%r5) +.L9: icm %r0,1,0(%r5) +.L10: stg %r0,0(%r2,%r3) + la %r3,8(%r3) + aghi %r4,-1 + j .L12 +.L11: aghi %r1,-1 +.L12: sllg %r4,%r4,3 + algr %r4,%r1 + algr %r2,%r3 # start of dst area to be zeroed + lgr %r3,%r4 + slgr %r4,%r4 + slgr %r5,%r5 +.L13: mvcle %r2,%r4,0 # pad dst with zeroes + jo .L13 +.Lexit: lg %r2,48(%r15) # return dst pointer + br %r14 +END(strncpy) +libc_hidden_builtin_def (strncpy) diff --git a/sysdeps/s390/stpcpy-c.c b/sysdeps/s390/stpcpy-c.c deleted file mode 100644 index 76ec884..0000000 --- a/sysdeps/s390/stpcpy-c.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Default stpcpy implementation for S/390. - 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 - . */ - -#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) \ - strong_alias (__stpcpy_c, __stpcpy_c_1); \ - __hidden_ver1 (__stpcpy_c_1, __GI_stpcpy, __stpcpy_c_1); -# endif -# endif - -# include -#endif diff --git a/sysdeps/s390/stpcpy-vx.S b/sysdeps/s390/stpcpy-vx.S deleted file mode 100644 index d2db02d..0000000 --- a/sysdeps/s390/stpcpy-vx.S +++ /dev/null @@ -1,116 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of stpcpy. - 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 - . */ - -#include - -#if HAVE_STPCPY_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char * stpcpy (const char *dest, const char *src) - Copy string src to dest returning a pointer to its end. - - Register usage: - -r1=tmp - -r2=dest and return value - -r3=src - -r4=tmp - -r5=current_len - -v16=part of src - -v17=index of zero - -v18=part of src -*/ -ENTRY(STPCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, - copy bytes before and return. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r4 /* Compute highest index to 16byte boundary. */ - - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Find zero in 16byte aligned loop. */ -.Lloop: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16_0 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezbs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - j .Lloop /* No zero found -> loop. */ - -.Lfound_v16_32: - aghi %r5,32 -.Lfound_v16_0: - la %r3,0(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ - la %r2,0(%r1,%r3) /* Return pointer to zero. */ - br %r14 - -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - la %r3,16(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ - la %r2,0(%r1,%r3) /* Return pointer to zero. */ - br %r14 - -.Lfound_align: - vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ - la %r2,0(%r5,%r2) /* Return pointer to zero. */ - br %r14 -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/stpcpy.c b/sysdeps/s390/stpcpy.c deleted file mode 100644 index 670604e..0000000 --- a/sysdeps/s390/stpcpy.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Multiple versions of stpcpy. - 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 - . */ - -#include - -#if HAVE_STPCPY_IFUNC -# define stpcpy __redirect_stpcpy -# define __stpcpy __redirect___stpcpy -/* Omit the stpcpy inline definitions because it would redefine stpcpy. */ -# define __NO_STRING_INLINES -# define NO_MEMPCPY_STPCPY_REDIRECT -# include -# undef stpcpy -# undef __stpcpy -# include - -# if HAVE_STPCPY_C -extern __typeof (__redirect_stpcpy) STPCPY_C attribute_hidden; -# endif - -# 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/sysdeps/s390/stpncpy-c.c b/sysdeps/s390/stpncpy-c.c deleted file mode 100644 index e5d1ae8..0000000 --- a/sysdeps/s390/stpncpy-c.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Default stpncpy implementation for S/390. - 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 - . */ - -#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 diff --git a/sysdeps/s390/stpncpy-vx.S b/sysdeps/s390/stpncpy-vx.S deleted file mode 100644 index 3dccc10..0000000 --- a/sysdeps/s390/stpncpy-vx.S +++ /dev/null @@ -1,211 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of stpncpy. - 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 - . */ - -#include - -#if HAVE_STPNCPY_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char * stpncpy (char *dest, const char *src, size_t n) - Copies at most n characters of string src to dest - returning a pointer to its end or dest+n - if src is smaller than n. - - Register usage: - -%r0 = return value - -%r1 = zero byte index - -%r2 = curr dst pointer - -%r3 = curr src pointer - -%r4 = n - -%r5 = current_len - -%r6 = loaded bytes - -%r7 = border, tmp -*/ -ENTRY(STPNCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgfi %r4,0 - ber %r14 /* Nothing to do, if n == 0. */ - - la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */ - vlvgp %v31,%r6,%r7 /* Save registers. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r6,%r6 /* Convert 32bit to 64bit. */ - - lghi %r5,0 /* current_len = 0. */ - - clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes - -> process remaining. */ - - /* n > loaded-byte-count */ - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, - copy and return. */ - - /* Align s to 16 byte. */ - risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r7 /* Compute highest index to 16byte boundary. */ - - /* Zero not found and n > loaded-byte-count. */ - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Now we are 16byte aligned, so we can load a full vreg - without page fault. */ - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining - bytes. */ -.Llt64: - lgr %r7,%r4 - slgfi %r7,16 /* border_len = n - 16. */ - - clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border - then process remaining bytes. */ - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v18 - vfenezbs %v17,%v18,%v18 - je .Lfound_v18 - vl %v16,16(%r5,%r3) - vst %v18,0(%r5,%r2) - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v16 - vfenezbs %v17,%v16,%v16 - je .Lfound_v16 - vl %v18,16(%r5,%r3) - vst %v16,0(%r5,%r2) - aghi %r5,16 - -.Lremaining_v18: - vlr %v16,%v18 -.Lremaining_v16: - /* v16 contains the remaining bytes [1...16]. - Store remaining bytes and append string-termination. */ - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */ - aghi %r7,-1 /* vstl needs highest index. */ - la %r2,0(%r5,%r2) /* vstl has no index register. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */ - clrjle %r1,%r7,.Lfound_v16_store - vstl %v16,%r7,0(%r2) /* Store remaining bytes without null - termination! */ -.Lend: - /* Restore saved registers. */ - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lfound_v16_32: - aghi %r5,32 - j .Lfound_v16 -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - aghi %r5,16 -.Lfound_v18: - vlr %v16,%v18 -.Lfound_v16: - /* v16 contains a zero. Store remaining bytes to zero. current_len - has not reached border, thus checking for n is not needed! */ - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ -.Lfound_v16_store: - vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ - /* Fill remaining bytes with zero - remaining count always > 0. */ - algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ - slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1) */ - la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ - lgr %r0,%r2 /* Save return-pointer to found zero. */ - clgije %r4,1,.Lend /* Skip zero-filling, if found zero is last - possible character. - (1 is substracted from r4 below!). */ - aghi %r4,-2 /* mvc with exrl needs count - 1. - (additional -1, see remaining bytes above) */ - srlg %r6,%r4,8 /* Split into 256 byte blocks. */ - ltgr %r6,%r6 - je .Lzero_lt256 -.Lzero_loop256: - mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ - la %r2,256(%r2) - brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ -.Lzero_lt256: - exrl %r4,.Lmvc_lt256 - j .Lend -.Lmvc_lt256: - mvc 1(1,%r2),0(%r2) - -.Lloop64: - vl %v16,0(%r5,%r3) - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezbs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - j .Llt64 -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/stpncpy.c b/sysdeps/s390/stpncpy.c deleted file mode 100644 index 250dc68..0000000 --- a/sysdeps/s390/stpncpy.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Multiple versions of stpncpy. - 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 - . */ - -#include - -#if HAVE_STPNCPY_IFUNC -# define stpncpy __redirect_stpncpy -# define __stpncpy __redirect___stpncpy -# include -# undef stpncpy -# undef __stpncpy -# include - -# if HAVE_STPNCPY_C -extern __typeof (__redirect_stpncpy) STPNCPY_C attribute_hidden; -# endif - -# 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/sysdeps/s390/strcat-c.c b/sysdeps/s390/strcat-c.c deleted file mode 100644 index 7accc6c..0000000 --- a/sysdeps/s390/strcat-c.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Default strcat implementation for S/390. - 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 - . */ - -#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 diff --git a/sysdeps/s390/strcat-vx.S b/sysdeps/s390/strcat-vx.S deleted file mode 100644 index 218e301..0000000 --- a/sysdeps/s390/strcat-vx.S +++ /dev/null @@ -1,170 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strcat. - 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 - . */ - -#include -#if HAVE_STRCAT_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char * strcat (const char *dest, const char *src) - Concatenate two strings. - - Register usage: - -r0=saved dest pointer for return - -r1=tmp - -r2=dest - -r3=src - -r4=tmp - -r5=current_len - -v16=part of src - -v17=index of zero - -v18=part of src -*/ -ENTRY(STRCAT_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - lgr %r0,%r2 /* Save destination pointer for return. */ - - /* STRLEN - r1 = loaded bytes (tmp) - r4 = zero byte index (tmp) - r2 = dst - */ - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ - - /* Find zero in 16byte aligned loop. */ -.Llen_loop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Llen_found /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Llen_found16 - vl %v16,32(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Llen_found32 - vl %v16,48(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Llen_found48 - - aghi %r5,64 - j .Llen_loop /* No zero -> loop. */ - -.Llen_found48: - aghi %r5,16 -.Llen_found32: - aghi %r5,16 -.Llen_found16: - aghi %r5,16 -.Llen_found: - vlgvb %r4,%v16,7 /* Load byte index of zero. */ - algr %r5,%r4 - -.Llen_end: - /* STRCPY - %r1 = loaded bytes (tmp) - %r4 = zero byte index (tmp) - %r3 = curr src pointer - %r2 = curr dst pointer - */ - la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes, - copy bytes before and return. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r4 /* Compute highest index to 16byte boundary. */ - - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Find zero in 16byte aligned loop. */ -.Lcpy_loop: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lcpy_found_v16_0 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3)/* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezbs %v17,%v18,%v18 - je .Lcpy_found_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezbs %v17,%v16,%v16 - je .Lcpy_found_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezbs %v17,%v18,%v18 - je .Lcpy_found_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - j .Lcpy_loop /* No zero -> loop. */ - -.Lcpy_found_v16_32: - aghi %r5,32 -.Lcpy_found_v16_0: - la %r4,0(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - vstl %v16,%r1,0(%r4) /* Copy characters including zero. */ - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lcpy_found_v18_48: - aghi %r5,32 -.Lcpy_found_v18_16: - la %r4,16(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - vstl %v18,%r1,0(%r4) /* Copy characters including zero. */ - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lcpy_found_align: - vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 -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/strcat.c b/sysdeps/s390/strcat.c deleted file mode 100644 index d378519..0000000 --- a/sysdeps/s390/strcat.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Multiple versions of strcat. - 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 - . */ - -#include - -#if HAVE_STRCAT_IFUNC -# define strcat __redirect_strcat -# include -# undef strcat -# include - -# 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 - -s390_libc_ifunc_expr (__redirect_strcat, strcat, - (HAVE_STRCAT_Z13 && (hwcap & HWCAP_S390_VX)) - ? STRCAT_Z13 - : STRCAT_DEFAULT - ) -#endif diff --git a/sysdeps/s390/strchr-c.c b/sysdeps/s390/strchr-c.c deleted file mode 100644 index 3d3579a..0000000 --- a/sysdeps/s390/strchr-c.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Default strchr implementation for S/390. - 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 - . */ - -#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 -# endif - -# include -#endif diff --git a/sysdeps/s390/strchr-vx.S b/sysdeps/s390/strchr-vx.S deleted file mode 100644 index 6ffa06f..0000000 --- a/sysdeps/s390/strchr-vx.S +++ /dev/null @@ -1,112 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strchr. - 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 - . */ - -#include - -#if HAVE_STRCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char *strchr (const char *s, int c) - Locate character in string. - - Register usage: - -r1=tmp - -r2=s - -r3=c - -r4=tmp - -r5=current_len - -v16=part of s - -v17=index of unequal - -v18=replicated c -*/ -ENTRY(STRCHR_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - lghi %r5,0 /* current_len = 0. */ - - vlvgb %v18,%r3,0 /* Generate vector which elements are all c. - If c > 255, c will be truncated. */ - vrepb %v18,%v18,0 - - vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ - vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ - clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - - /* Find c/zero in 16 byte aligned loop */ -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ - jno .Lfound /* Found c/zero (cc=0|1|2). */ - vl %v16,16(%r5,%r2) - vfeezbs %v16,%v16,%v18 - jno .Lfound16 - vl %v16,32(%r5,%r2) - vfeezbs %v16,%v16,%v18 - jno .Lfound32 - vl %v16,48(%r5,%r2) - vfeezbs %v16,%v16,%v18 - jno .Lfound48 - - aghi %r5,64 - j .Lloop /* No character and no zero -> loop. */ - -.Lfound48: - la %r5,16(%r5) /* Use la since aghi would clobber cc. */ -.Lfound32: - la %r5,16(%r5) -.Lfound16: - la %r5,16(%r5) -.Lfound: - je .Lzero /* Found zero, but no c before that zero. */ - -.Lcharacter: - vlgvb %r4,%v16,7 /* Load byte index of character. */ - algr %r5,%r4 - la %r2,0(%r5,%r2) /* Return pointer to character. */ - br %r14 - -.Lzero: - llgcr %r3,%r3 /* char c_char = (char) c. */ - clije %r3,0,.Lcharacter /* Found zero and c is zero. */ - lghi %r2,0 /* Return null if character not found. */ - br %r14 -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/strchr.c b/sysdeps/s390/strchr.c deleted file mode 100644 index a106c61..0000000 --- a/sysdeps/s390/strchr.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Multiple versions of strchr. - 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 - . */ - -#include - -#if HAVE_STRCHR_IFUNC -# define strchr __redirect_strchr -/* Omit the strchr inline definitions because it would redefine strchr. */ -# define __NO_STRING_INLINES -# include -# undef strchr -# include - -# if HAVE_STRCHR_C -extern __typeof (__redirect_strchr) STRCHR_C attribute_hidden; -# endif - -# 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/sysdeps/s390/strchrnul-c.c b/sysdeps/s390/strchrnul-c.c deleted file mode 100644 index 585273f..0000000 --- a/sysdeps/s390/strchrnul-c.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Default strchrnul implementation for S/390. - 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 - . */ - -#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/strchrnul-vx.S b/sysdeps/s390/strchrnul-vx.S deleted file mode 100644 index 0cd587b..0000000 --- a/sysdeps/s390/strchrnul-vx.S +++ /dev/null @@ -1,101 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strchrnul. - 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 - . */ - -#include - -#if HAVE_STRCHRNUL_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char *strchrnul (const char *s, int c) - Returns pointer to first c or to \0 if c not found. - - Register usage: - -r1=tmp - -r2=s and return pointer - -r3=c - -r4=tmp - -r5=current_len - -v16=part of s - -v18=vector with c replicated in every byte -*/ -ENTRY(STRCHRNUL_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - lghi %r5,0 /* current_len = 0. */ - - vlvgb %v18,%r3,0 /* Generate vector which elements are all c. - If c > 255, c will be truncated. */ - vrepb %v18,%v18,0 - - vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ - vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ - clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - - /* Find c/zero in 16byte aligned loop */ -.Lloop: - vl %v16,0(%r5,%r2) /* Load s */ - vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ - jno .Lfound /* Found c/zero (cc=0|1|2). */ - vl %v16,16(%r5,%r2) - vfeezbs %v16,%v16,%v18 - jno .Lfound16 - vl %v16,32(%r5,%r2) - vfeezbs %v16,%v16,%v18 - jno .Lfound32 - vl %v16,48(%r5,%r2) - vfeezbs %v16,%v16,%v18 - jno .Lfound48 - - aghi %r5,64 - j .Lloop /* No character and no zero -> loop. */ - - /* Found character or zero */ -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound: - vlgvb %r1,%v16,7 /* Load byte index of character. */ - algr %r5,%r1 - la %r2,0(%r5,%r2) /* Return pointer to character. */ - -.Lend: - br %r14 -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/strchrnul.c b/sysdeps/s390/strchrnul.c deleted file mode 100644 index e9fefe1..0000000 --- a/sysdeps/s390/strchrnul.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of strchrnul. - 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 - . */ - -#include - -#if HAVE_STRCHRNUL_IFUNC -# include -# include - -# if HAVE_STRCHRNUL_C -extern __typeof (__strchrnul) STRCHRNUL_C attribute_hidden; -# endif - -# 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/sysdeps/s390/strcmp-vx.S b/sysdeps/s390/strcmp-vx.S deleted file mode 100644 index 801ad9d..0000000 --- a/sysdeps/s390/strcmp-vx.S +++ /dev/null @@ -1,119 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version 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 - . */ - -#include -#if HAVE_STRCMP_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* int strcmp (const char *s1, const char *s2) - Compare two strings - - Register usage: - -r1=loaded byte count s1 - -r2=s1 - -r3=s2 - -r4=loaded byte coutn s2, tmp - -r5=current_len - -v16=part of s1 - -v17=part of s2 - -v18=index of unequal -*/ -ENTRY(STRCMP_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - lghi %r5,0 /* current_len = 0. */ - -.Lloop: - vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ - vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ - lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */ - jo .Llt16_1 /* Jump away if vr is not fully loaded. */ - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 /* Jump away if vr is not fully loaded. */ - /* Both vrs are fully loaded. */ - aghi %r5,16 - vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r1,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezbs %v18,%v16,%v17 - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r1,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezbs %v18,%v16,%v17 - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r1,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezbs %v18,%v16,%v17 - jno .Lfound - j .Lloop - -.Llt16_1: - lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */ -.Llt16_2: - clr %r1,%r4 - locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */ - algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */ - vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ - vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ - clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded - bytes. */ - j .Lloop - -.Lfound: - je .Lend_equal - lghi %r2,1 - lghi %r1,-1 - locgrl %r2,%r1 - br %r14 -.Lend_equal: - lghi %r2,0 - br %r14 -END(STRCMP_Z13) - -# if ! HAVE_STRCMP_IFUNC -strong_alias (STRCMP_Z13, strcmp) -# endif - -# if ! HAVE_STRCMP_Z900_G5 && defined SHARED && IS_IN (libc) -strong_alias (STRCMP_Z13, __GI_strcmp) -# endif -#endif diff --git a/sysdeps/s390/strcmp-z900.S b/sysdeps/s390/strcmp-z900.S deleted file mode 100644 index 67b3c8b..0000000 --- a/sysdeps/s390/strcmp-z900.S +++ /dev/null @@ -1,59 +0,0 @@ -/* strcmp - compare two string. 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 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_Z900_G5) - SLGR %r0,%r0 -0: clst %r2,%r3 - jo 0b - jp 1f - jm 2f - SLGR %r2,%r2 - br %r14 -1: LGHI %r2,1 - br %r14 -2: LGHI %r2,-1 - br %r14 -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/strcmp.c b/sysdeps/s390/strcmp.c deleted file mode 100644 index 9efa30a..0000000 --- a/sysdeps/s390/strcmp.c +++ /dev/null @@ -1,42 +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 - . */ - -#include - -#if HAVE_STRCMP_IFUNC -# define strcmp __redirect_strcmp -/* Omit the strcmp inline definitions because it would redefine strcmp. */ -# define __NO_STRING_INLINES -# include -# include -# undef 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/sysdeps/s390/strcpy-vx.S b/sysdeps/s390/strcpy-vx.S deleted file mode 100644 index 844d23e..0000000 --- a/sysdeps/s390/strcpy-vx.S +++ /dev/null @@ -1,109 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version 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 - . */ - -#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. - - Register usage: - -r1=tmp - -r2=dest and return_value - -r3=src - -r4=tmp - -r5=current_len - -v16=part of src - -v17=index of zero - -v18=part of src -*/ -ENTRY(STRCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, - copy bytes before and return. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r4 /* Compute highest index to 16byte boundary. */ - - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Find zero in 16byte aligned loop. */ -.Lloop: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16_0 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3)/* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezbs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - j .Lloop /* No zero found -> loop. */ - -.Lfound_v16_32: - aghi %r5,32 -.Lfound_v16_0: - la %r3,0(%r5,%r2) - vlgvb %r4,%v17,7 /* Load byte index of zero. */ - vstl %v16,%r4,0(%r3) /* Store characters including zero. */ - br %r14 - -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - la %r3,16(%r5,%r2) - vlgvb %r4,%v17,7 /* Load byte index of zero. */ - vstl %v18,%r4,0(%r3) /* Store characters including zero. */ - br %r14 - -.Lfound_align: - vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ - br %r14 -END(STRCPY_Z13) - -# if ! HAVE_STRCPY_IFUNC -strong_alias (STRCPY_Z13, strcpy) -# endif - -# if ! HAVE_STRCPY_Z900_G5 && defined SHARED && IS_IN (libc) -strong_alias (STRCPY_Z13, __GI_strcpy) -# endif -#endif diff --git a/sysdeps/s390/strcpy-z900.S b/sysdeps/s390/strcpy-z900.S deleted file mode 100644 index 42798b1..0000000 --- a/sysdeps/s390/strcpy-z900.S +++ /dev/null @@ -1,56 +0,0 @@ -/* 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. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for 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 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_Z900_G5) - SLGR %r0,%r0 - LGR %r1,%r2 -0: mvst %r1,%r3 - jo 0b - br %r14 -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/strcpy.c b/sysdeps/s390/strcpy.c deleted file mode 100644 index f4e28e2..0000000 --- a/sysdeps/s390/strcpy.c +++ /dev/null @@ -1,40 +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 - . */ - -#include - -#if HAVE_STRCPY_IFUNC -# define strcpy __redirect_strcpy -# include -# undef strcpy -# include - -# 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/sysdeps/s390/strcspn-c.c b/sysdeps/s390/strcspn-c.c deleted file mode 100644 index 9f51f92..0000000 --- a/sysdeps/s390/strcspn-c.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Default strcspn implementation for S/390. - 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 - . */ - -#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 diff --git a/sysdeps/s390/strcspn-vx.S b/sysdeps/s390/strcspn-vx.S deleted file mode 100644 index ff5b1be..0000000 --- a/sysdeps/s390/strcspn-vx.S +++ /dev/null @@ -1,292 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strcspn. - 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 - . */ - -#include - -#if HAVE_STRCSPN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t strcspn (const char *s, const char * reject) - The strcspn() function calculates the length of the initial segment - of s which consists entirely of characters not in reject. - - This method checks the length of reject string. If it fits entirely - in one vector register, a fast algorithm is used, which does not need - to check multiple parts of accept-string. Otherwise a slower full - check of accept-string is used. - - register overview: - r3: pointer to start of reject-string - r2: pointer to start of search-string - r0: loaded byte count of vlbb search-string - r4: found byte index - r1: current return len - v16: search-string - v17: reject-string - v18: temp-vreg - - ONLY FOR SLOW: - v19: first reject-string - v20: zero for preparing acc-vector - v21: global mask; 1 indicates a match between - search-string-vreg and any reject-character - v22: current mask; 1 indicates a match between - search-string-vreg and any reject-character in current acc-vreg - v24: one for result-checking of former string-part - v30, v31: for re-/storing registers r6, r8, r9 - r5: current len of reject-string - r6: zero-index in search-string or 16 if no zero - or min(zero-index, loaded byte count) - r8: >0, if former reject-string-part contains a zero, - otherwise =0; - r9: loaded byte count of vlbb reject-string -*/ -ENTRY(STRCSPN_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - /* - Check if reject-string fits in one vreg: - ---------------------------------------- - */ - vlbb %v17,0(%r3),6 /* Load reject. */ - lghi %r1,0 /* Zero out current len. */ - lcbb %r0,0(%r3),6 - jo .Lcheck_onbb /* Special case if reject - lays on block-boundary. */ -.Lcheck_notonbb: - vistrbs %v17,%v17 /* Fill with zeros after first zero. */ - je .Lfast /* Zero found -> reject fits in one vreg. */ - j .Lslow /* No zero -> reject exceeds one vreg. */ - - -.Lcheck_onbb: - /* Reject lays on block-boundary. */ - vfenezb %v18,%v17,%v17 /* Search zero in loaded reject bytes. */ - vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ - clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> - Reject fits in one vreg; - Fill with zeros and proceed - with FAST. */ - vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */ - j .Lcheck_notonbb /* Check if reject fits in one vreg. */ - - - /* - Search s for reject in one vreg - ------------------------------- - */ -.Lfast: - /* Complete reject-string in v17 and remaining bytes are zero. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 - unequal to any in v17 - or first zero element. */ - - vlgvb %r4,%v18,7 /* Load byte index of found element. */ - clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded - bytes, return with found element - index (=equal count). */ - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r1,16 /* current_len = 16. */ - slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ - - /* Process s in 16byte aligned loop. */ -.Lfast_loop: - vl %v16,0(%r1,%r2) /* Load search-string. */ - vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any - in v17 or first zero element. */ - jno .Lfast_loop_found - - vl %v16,16(%r1,%r2) - vfaezbs %v18,%v16,%v17,0 - jno .Lfast_loop_found16 - - vl %v16,32(%r1,%r2) - vfaezbs %v18,%v16,%v17,0 - jno .Lfast_loop_found32 - - vl %v16,48(%r1,%r2) - vfaezbs %v18,%v16,%v17,0 - jno .Lfast_loop_found48 - - aghi %r1,64 - j .Lfast_loop /* Loop if no element was unequal to reject - and not zero. */ - - /* Found equal or zero element. */ -.Lfast_loop_found48: - aghi %r1,16 -.Lfast_loop_found32: - aghi %r1,16 -.Lfast_loop_found16: - aghi %r1,16 -.Lfast_loop_found: - vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */ -.Lfast_loop_found2: - algrk %r2,%r1,%r4 /* Add found index to current len. */ - br %r14 - - - - /* - Search s for reject in multiple vregs - ------------------------------------- - */ -.Lslow: - /* Save registers. */ - vlvgg %v30,%r6,0 - vlvgp %v31,%r8,%r9 - - /* Reject in v17 without zero. */ - vlr %v19,%v17 /* Save first acc-part for a fast reload. */ - vzero %v20 /* Zero for preparing acc-vector. */ - vone %v24 /* One for checking result of former - string-part. */ - - /* Align s to 16 byte. */ - risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and - %r4 = bits 60-63 'and' 15. */ - je .Lslow_loop_str /* If s is aligned, loop aligned. */ - lghi %r0,15 - slr %r0,%r4 /* Compute highest index to load (15-x). */ - vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs - highest index, remaining bytes are 0). */ - ahi %r0,1 /* Work with loaded byte count. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of reject-string to zero. */ - vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first reject-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */ - clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ - locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ - j .Lslow_loop_acc - - - /* Process s in 16byte aligned loop. */ -.Lslow_next_str: - /* Check results of former processed str-part. */ - vfeeb %v18,%v21,%v24 /* Find first equal match in global mask - (ones in element). */ - vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */ - /* Equal-index < min(zero-index, loaded byte count) - -> Return pointer to equal element. */ - clrjl %r4,%r6,.Lslow_index_found - /* Zero-index < loaded byte count - -> Former str-part was last str-part - -> Return null */ - clrjl %r6,%r0,.Lslow_end_not_found - - /* All elements are zero (=no match) -> Proceed with next str-part. */ - vlr %v17,%v19 /* Load first part of reject (no zero). */ - algfr %r1,%r0 /* Add loaded byte count to current len. */ - -.Lslow_loop_str: - vl %v16,0(%r1,%r2) /* Load search-string. */ - lghi %r0,16 /* Loaded byte count is 16. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of reject to zero. */ - vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first reject-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end /* If first element is zero (end of string) - -> Return current length. */ - -.Lslow_loop_acc: - vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> - Character matches any rejected character in - this reject-string-part) IN=0, RT=1. */ - vlgvb %r4,%v22,0 /* Get result of first element. */ - /* First element is equal to any rejected characters? - (all other parts of reject cannot lead to a match before this one) - -> Return current len, which is pointing to this element. */ - clijh %r4,0,.Lslow_end - vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ - /* Proceed with next acc until end of acc is reached. */ - - -.Lslow_next_acc: - clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part - -> Add found index to current len - and end. */ - vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */ - aghi %r5,16 /* Increment current len of reject-string. */ - lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */ - jo .Lslow_next_acc_onbb /* Jump away if reject-string is - on block-boundary. */ -.Lslow_next_acc_notonbb: - vistrbs %v17,%v17 /* Fill with zeros after first zero. */ - jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ - -.Lslow_next_acc_prepare_zero: - /* Zero in reject-part: fill zeros with first-reject-character. */ - vlgvb %r8,%v17,0 /* Load first element of reject-part. */ - clije %r8,0,.Lslow_next_str /* Process next str-part if first - character in this part of reject - is a zero. */ - /* r8>0 -> zero found in this acc-part. */ - vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ - vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars - by comparing with 0 (v20). */ - vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ - j .Lslow_loop_acc /* Reject-string part is prepared. */ - -.Lslow_next_acc_onbb: - vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */ - vlgvb %r8,%v18,7 /* Load byte index of zero. */ - clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes - -> Prepare vreg. */ - vl %v17,0(%r5,%r3) /* Load over boundary ... */ - lghi %r8,0 /* r8=0 -> no zero in this part of acc, - check for zero is in jump-target. */ - j .Lslow_next_acc_notonbb /* ... and search for zero in - fully loaded vreg again. */ - -.Lslow_end_not_found: - algfr %r1,%r6 /* Add zero-index to current len. */ - j .Lslow_end -.Lslow_index_found: - algfr %r1,%r4 /* Add found index of char to current len. */ -.Lslow_end: - lgr %r2,%r1 - /* Restore registers. */ - vlgvg %r6,%v30,0 - vlgvg %r8,%v31,0 - vlgvg %r9,%v31,1 - br %r14 -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/strcspn.c b/sysdeps/s390/strcspn.c deleted file mode 100644 index a3f35d3..0000000 --- a/sysdeps/s390/strcspn.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Multiple versions of strcspn. - 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 - . */ - -#include - -#if HAVE_STRCSPN_IFUNC -# define strcspn __redirect_strcspn -/* Omit the strcspn inline definitions because it would redefine strcspn. */ -# define __NO_STRING_INLINES -# include -# undef strcspn -# include - -# 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 - -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/sysdeps/s390/strlen-c.c b/sysdeps/s390/strlen-c.c deleted file mode 100644 index b456970..0000000 --- a/sysdeps/s390/strlen-c.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Default strlen implementation for S/390. - 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 - . */ - -#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 -# endif - -# include -#endif diff --git a/sysdeps/s390/strlen-vx.S b/sysdeps/s390/strlen-vx.S deleted file mode 100644 index 39ef431..0000000 --- a/sysdeps/s390/strlen-vx.S +++ /dev/null @@ -1,93 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strlen. - 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 - . */ - -#include -#if HAVE_STRLEN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t strlen (const char *s) - Returns length of string s. - - Register usage: - -r1=bytes to 4k-byte boundary - -r2=s - -r3=tmp - -r4=tmp - -r5=current_len and return_value - -v16=part of s -*/ -ENTRY(STRLEN_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */ - clr %r4,%r1 /* If found zero within loaded bytes? */ - locgrl %r2,%r4 /* Then copy return value. */ - blr %r14 /* And return. */ - - /* Align s to 16 byte. */ - risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r3 /* Compute bytes to 16bytes boundary. */ - - /* Find zero in 16 byte aligned loop. */ -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound16 - vl %v16,32(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound32 - vl %v16,48(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound48 - - aghi %r5,64 - j .Lloop /* No zero found -> loop. */ - -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound: - vlgvb %r2,%v16,7 /* Load byte index of zero. */ - algr %r2,%r5 - br %r14 -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/strlen.c b/sysdeps/s390/strlen.c deleted file mode 100644 index 6ba0fe8..0000000 --- a/sysdeps/s390/strlen.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Multiple versions of strlen. - 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 - . */ - -#include - -#if HAVE_STRLEN_IFUNC -# define strlen __redirect_strlen -# include -# include -# undef 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 - -s390_libc_ifunc_expr (__redirect_strlen, strlen, - (HAVE_STRLEN_Z13 && (hwcap & HWCAP_S390_VX)) - ? STRLEN_Z13 - : STRLEN_DEFAULT - ) -#endif diff --git a/sysdeps/s390/strncat-c.c b/sysdeps/s390/strncat-c.c deleted file mode 100644 index 86df898..0000000 --- a/sysdeps/s390/strncat-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default strncat implementation for S/390. - 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 - . */ - -#include - -#if HAVE_STRNCAT_C -# if HAVE_STRNCAT_IFUNC -# define STRNCAT STRNCAT_C -# define STRNCAT_PRIMARY -# endif -# include -#endif diff --git a/sysdeps/s390/strncat-vx.S b/sysdeps/s390/strncat-vx.S deleted file mode 100644 index 76345e7..0000000 --- a/sysdeps/s390/strncat-vx.S +++ /dev/null @@ -1,252 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strncat. - 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 - . */ - -#include -#if HAVE_STRNCAT_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char * strncat (const char *dest, const char *src, size_t n) - Concatenate two strings - at most n characters of src. - - Register usage: - -r0=saved dest pointer for return - -r1=tmp - -r2=dest - -r3=src - -r4=n - -r5=current_len - -r6=tmp - -r7=tmp - -v16=part of src - -v17=index of zero - -v18=part of src - -v31=register save area for r6, r7 -*/ -ENTRY(STRNCAT_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgfi %r4,0 - ber %r14 /* Nothing to do, if n == 0. */ - lgr %r0,%r2 /* Save destination pointer for return. */ - vlvgp %v31,%r6,%r7 /* Save registers. */ - - /* STRLEN - %r1 = loaded bytes (tmp) - %r6 = zero byte index (tmp) - %r2 = dst - */ - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ - - /* Find zero in 16byte aligned loop. */ -.Llen_loop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Llen_found /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Llen_found16 - vl %v16,32(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Llen_found32 - vl %v16,48(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Llen_found48 - - aghi %r5,64 - j .Llen_loop /* No zero -> loop. */ - -.Llen_found48: - aghi %r5,16 -.Llen_found32: - aghi %r5,16 -.Llen_found16: - aghi %r5,16 -.Llen_found: - vlgvb %r1,%v16,7 /* Load byte index of zero. */ - algr %r5,%r1 - -.Llen_end: - /* STRCPY - %r1 = zero byte index (tmp) - %r6 = loaded bytes (tmp) - %r3 = curr src pointer - %r2 = curr dst pointer - %r7 = border, tmp - */ - la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r6,%r6 /* Convert 32bit to 64bit. */ - - lghi %r5,0 /* current_len = 0. */ - - clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes - -> process remaining. */ - - /* n > loaded-byte-count. */ - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded - bytes, copy and return. */ - - /* Align s to 16 byte. */ - risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r7 /* Compute highest index to 16byte boundary. */ - - /* Zero not found and n > loaded-byte-count. */ - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* - Now we are 16byte aligned, so we can load a full vreg - without page fault. - */ - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lcpy_loop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16, - process remaining bytes. */ -.Lcpy_lt64: - lgr %r7,%r4 - slgfi %r7,16 /* border_len = n - 16. */ - - /* If current_len >= border then process remaining bytes. */ - clgrjhe %r5,%r7,.Lcpy_remaining_v16 - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lcpy_found_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - aghi %r5,16 - - clgrjhe %r5,%r7,.Lcpy_remaining_v18 - vfenezbs %v17,%v18,%v18 - je .Lcpy_found_v18 - vl %v16,16(%r5,%r3) - vst %v18,0(%r5,%r2) - aghi %r5,16 - - clgrjhe %r5,%r7,.Lcpy_remaining_v16 - vfenezbs %v17,%v16,%v16 - je .Lcpy_found_v16 - vl %v18,16(%r5,%r3) - vst %v16,0(%r5,%r2) - aghi %r5,16 - -.Lcpy_remaining_v18: - vlr %v16,%v18 -.Lcpy_remaining_v16: - /* v16 contains the remaining bytes [1...16]. - Store remaining bytes and append string-termination. */ - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ - aghi %r7,-1 /* vstl needs highest index. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - la %r2,0(%r5,%r2) /* vstl has no index register. */ - /* Zero-index within remaining-bytes, store up to zero and end. */ - clgrjle %r1,%r7,.Lcpy_found_v16_store - vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ - lghi %r1,0 - stc %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */ -.Lcpy_end: - /* Restore saved registers. */ - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lcpy_found_v16_32: - aghi %r5,32 - j .Lcpy_found_v16 -.Lcpy_found_v18_48: - aghi %r5,32 -.Lcpy_found_v18_16: - aghi %r5,16 -.Lcpy_found_v18: - vlr %v16,%v18 -.Lcpy_found_v16: - /* v16 contains a zero. Store remaining bytes to zero. current_len - has not reached border, thus checking for n is not needed! */ - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - la %r2,0(%r5,%r2) -.Lcpy_found_v16_store: - vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ - j .Lcpy_end - - /* Find zero in 16byte aligned loop. */ -.Lcpy_loop64: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lcpy_found_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezbs %v17,%v18,%v18 - je .Lcpy_found_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezbs %v17,%v16,%v16 - je .Lcpy_found_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezbs %v17,%v18,%v18 - je .Lcpy_found_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lcpy_loop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - j .Lcpy_lt64 -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/strncat.c b/sysdeps/s390/strncat.c deleted file mode 100644 index b4b3656..0000000 --- a/sysdeps/s390/strncat.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Multiple versions of strncat. - 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 - . */ - -#include - -#if HAVE_STRNCAT_IFUNC -# include -# include - -# if HAVE_STRNCAT_C -extern __typeof (__strncat) STRNCAT_C attribute_hidden; -# endif - -# if HAVE_STRNCAT_Z13 -extern __typeof (__strncat) STRNCAT_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (__strncat, strncat, - (HAVE_STRNCAT_Z13 && (hwcap & HWCAP_S390_VX)) - ? STRNCAT_Z13 - : STRNCAT_DEFAULT - ) -#endif diff --git a/sysdeps/s390/strncmp-c.c b/sysdeps/s390/strncmp-c.c deleted file mode 100644 index c7ffdb0..0000000 --- a/sysdeps/s390/strncmp-c.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Default strncmp implementation for S/390. - 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 - . */ - -#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 -# endif - -# include -#endif diff --git a/sysdeps/s390/strncmp-vx.S b/sysdeps/s390/strncmp-vx.S deleted file mode 100644 index f557afb..0000000 --- a/sysdeps/s390/strncmp-vx.S +++ /dev/null @@ -1,148 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strncmp. - 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 - . */ - -#include - -#if HAVE_STRNCMP_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* int strncmp (const char *s1, const char *s2, size_t n) - Compare at most n characters of two strings. - - Register usage: - -r0=tmp - -r1=tmp - -r2=s1 - -r3=s2 - -r4=n - -r5=current_len - -v16=part of s1 - -v17=part of s2 - -v18=index of unequal -*/ -ENTRY(STRNCMP_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgije %r4,0,.Lend_equal /* Nothing to do if n == 0, */ - lghi %r5,0 /* current_len = 0. */ - -.Lloop: - vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ - vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ - lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */ - jo .Llt16_1 /* Jump away if vr is not fully loaded. */ - lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ - jo .Llt16_2 /* Jump away if vr is not fully loaded. */ - aghi %r5,16 /* Both vrs are fully loaded. */ - clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */ - vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r0,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r1,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp - vfenezbs %v18,%v16,%v17 - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r0,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r1,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp - vfenezbs %v18,%v16,%v17 - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r0,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r1,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp - vfenezbs %v18,%v16,%v17 - jno .Lfound - j .Lloop - -.Llt16_1: - lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count ofs2. */ -.Llt16_2: - clr %r0,%r1 /* Compare logical. */ - locrh %r0,%r1 /* Compute minimum of bytes loaded. */ - algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */ - clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n ->last compare. */ - vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ - vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ - clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within - loaded bytes (index < loaded-bytes) */ - j .Lloop - -.Llastcmp: - /* Use comparision result only if located within first n characters. - %r0: loaded byte count in vreg; - %r5: current_len; - %r4: n; - (current_len - n): [0...16[ - First ignored match index: loaded bytes - (current_len-n): ]0...16] - */ - slgr %r5,%r4 /* %r5 = current_len - n. */ - slr %r0,%r5 /* %r0 = first ignored match index. */ - vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ - vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ - clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within - loaded bytes and below n bytes. */ - j .Lend_equal /* Miscompare after n-bytes -> end equal. */ - -.Lfound: - /* Difference or end of string. */ - je .Lend_equal - lghi %r2,1 - lghi %r1,-1 - locgrl %r2,%r1 - br %r14 -.Lend_equal: - lghi %r2,0 - br %r14 -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/strncmp.c b/sysdeps/s390/strncmp.c deleted file mode 100644 index 7135127..0000000 --- a/sysdeps/s390/strncmp.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Multiple versions of strncmp. - 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 - . */ - -#include - -#if HAVE_STRNCMP_IFUNC -# define strncmp __redirect_strncmp -/* Omit the strncmp inline definitions because it would redefine strncmp. */ -# define __NO_STRING_INLINES -# include -# undef strncmp -# include - -# 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 - -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/sysdeps/s390/strncpy-vx.S b/sysdeps/s390/strncpy-vx.S deleted file mode 100644 index be09ddf..0000000 --- a/sysdeps/s390/strncpy-vx.S +++ /dev/null @@ -1,208 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version 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 - . */ - -#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. - - Register usage: - -r0=dest pointer for return - -r1=tmp, zero byte index - -r2=dest - -r3=src - -r4=n - -r5=current_len - -r6=tmp, loaded bytes - -r7=tmp, border - -v16=part of src - -v17=index of zero - -v18=part of src - -v31=register save area for r6, r7 -*/ -ENTRY(STRNCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgfi %r4,0 - ber %r14 /* Nothing to do, if n == 0. */ - lgr %r0,%r2 /* Save destination pointer for return. */ - vlvgp %v31,%r6,%r7 /* Save registers. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r6,%r6 /* Convert 32bit to 64bit. */ - - lghi %r5,0 /* current_len = 0. */ - - clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes - -> process remaining. */ - - /* n > loaded-byte-count. */ - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, - copy and return. */ - - /* Align s to 16 byte. */ - risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r7 /* Compute highest index to 16byte boundary. */ - - /* Zero not found and n > loaded-byte-count. */ - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Now we are 16byte aligned, so we can load - a full vreg without page fault. */ - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining - bytes. */ -.Llt64: - lgr %r7,%r4 - slgfi %r7,16 /* border_len = n - 16. */ - - clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border - then process remaining bytes. */ - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v18 - vfenezbs %v17,%v18,%v18 - je .Lfound_v18 - vl %v16,16(%r5,%r3) - vst %v18,0(%r5,%r2) - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v16 - vfenezbs %v17,%v16,%v16 - je .Lfound_v16 - vl %v18,16(%r5,%r3) - vst %v16,0(%r5,%r2) - aghi %r5,16 - -.Lremaining_v18: - vlr %v16,%v18 -.Lremaining_v16: - /* v16 contains the remaining bytes [1...16]. - Store remaining bytes and append string-termination. */ - vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ - slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ - aghi %r7,-1 /* vstl needs highest index. */ - la %r2,0(%r5,%r2) /* vstl has no index register. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - /* Zero in remaining bytes? -> jump away (zero-index < max-index) - Do not jump away if zero-index == max-index, - but simply copy zero with vstl below. */ - clrjl %r1,%r7,.Lfound_v16_store - vstl %v16,%r7,0(%r2) /* Store remaining bytes without null - termination!. */ -.Lend: - /* Restore saved registers. */ - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - - -.Lfound_v16_32: - aghi %r5,32 - j .Lfound_v16 -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - aghi %r5,16 -.Lfound_v18: - vlr %v16,%v18 -.Lfound_v16: - /* v16 contains a zero. Store remaining bytes to zero. current_len - has not reached border, thus checking for n is not needed! */ - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ -.Lfound_v16_store: - vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ - /* Fill remaining bytes with zero - remaining count always > 0. */ - algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ - slgr %r4,%r5 /* = n - (current_len + zero_index + 1). */ - la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ - aghi %r4,-2 /* mvc with exrl needs count - 1. - (additional -1, see remaining bytes above) */ - srlg %r6,%r4,8 /* Split into 256 byte blocks. */ - ltgr %r6,%r6 - je .Lzero_lt256 -.Lzero_loop256: - mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ - la %r2,256(%r2) - brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ -.Lzero_lt256: - exrl %r4,.Lmvc_lt256 - j .Lend -.Lmvc_lt256: - mvc 1(1,%r2),0(%r2) - -.Lloop64: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezbs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezbs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - j .Llt64 -END(STRNCPY_Z13) - -# if ! HAVE_STRNCPY_IFUNC -strong_alias (STRNCPY_Z13, strncpy) -# endif - -# if ! HAVE_STRNCPY_Z900_G5 && defined SHARED && IS_IN (libc) -strong_alias (STRNCPY_Z13, __GI_strncpy) -# endif -#endif diff --git a/sysdeps/s390/strncpy.c b/sysdeps/s390/strncpy.c deleted file mode 100644 index ec8a264..0000000 --- a/sysdeps/s390/strncpy.c +++ /dev/null @@ -1,42 +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 - . */ - -#include - -#if HAVE_STRNCPY_IFUNC -# define strncpy __redirect_strncpy -/* Omit the strncpy inline definitions because it would redefine strncpy. */ -# define __NO_STRING_INLINES -# include -# undef strncpy -# include - -# 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/sysdeps/s390/strnlen-c.c b/sysdeps/s390/strnlen-c.c deleted file mode 100644 index c2d887f..0000000 --- a/sysdeps/s390/strnlen-c.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Default strnlen implementation for S/390. - 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 - . */ - -#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 -# endif - -# include -#endif diff --git a/sysdeps/s390/strnlen-vx.S b/sysdeps/s390/strnlen-vx.S deleted file mode 100644 index 0b8fe3d..0000000 --- a/sysdeps/s390/strnlen-vx.S +++ /dev/null @@ -1,147 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strnlen. - 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 - . */ - -#include - -#if HAVE_STRNLEN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t strnlen (const char *s, size_t maxlen) - Returns the number of characters in s or at most maxlen. - - Register usage: - -r1=tmp - -r2=address of string - -r3=maxlen (number of characters to be read) - -r4=tmp - -r5=current_len and return_value - -v16=part of s -*/ -ENTRY(STRNLEN_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r3,%r3 -# endif /* !defined __s390x__ */ - - clgfi %r3,0 /* if maxlen == 0, return 0. */ - locgre %r2,%r3 - ber %r14 - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r1,%r1 /* Convert 32bit to 64bit. */ - - vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ - clgr %r1,%r3 - locgrh %r1,%r3 /* loaded_byte_count - = min (loaded_byte_count, maxlen) */ - - vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ - clr %r5,%r1 /* If found zero within loaded bytes? */ - locgrl %r2,%r5 /* Then copy return value. */ - blr %r14 /* And return. */ - - clgr %r1,%r3 /* If loaded_byte_count == maxlen? */ - locgre %r2,%r3 /* Then copy return value. */ - ber %r14 /* And return. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r3,.Lloop64 - - /* Find zero in max 64byte with aligned s. */ -.Llt64: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound /* Jump away if zero was found. */ - aghi %r5,16 - clgrjhe %r5,%r3,.Lfound /* current_len >= maxlen -> end. */ - vl %v16,0(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound - aghi %r5,16 - clgrjhe %r5,%r3,.Lfound - vl %v16,0(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound - aghi %r5,16 - clgrjhe %r5,%r3,.Lfound - vl %v16,0(%r5,%r2) - vfenezbs %v16,%v16,%v16 - j .Lfound - -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound: - vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */ - algr %r5,%r4 - - clgr %r5,%r3 - locgrh %r5,%r3 /* Return min (current_len, maxlen). */ - lgr %r2,%r5 - br %r14 - - /* Find zero in 16 byte aligned loop. */ -.Lloop64: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound16 - vl %v16,32(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound32 - vl %v16,48(%r5,%r2) - vfenezbs %v16,%v16,%v16 - je .Lfound48 - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r3,.Lloop64 - - j .Llt64 -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/strnlen.c b/sysdeps/s390/strnlen.c deleted file mode 100644 index aa4953d..0000000 --- a/sysdeps/s390/strnlen.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Multiple versions of strnlen. - 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 - . */ - -#include - -#if HAVE_STRNLEN_IFUNC -# define strnlen __redirect_strnlen -# define __strnlen __redirect___strnlen -# include -# undef strnlen -# undef __strnlen -# include - -# if HAVE_STRNLEN_C -extern __typeof (__redirect_strnlen) STRNLEN_C attribute_hidden; -# endif - -# 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/sysdeps/s390/strpbrk-c.c b/sysdeps/s390/strpbrk-c.c deleted file mode 100644 index 70cc5db..0000000 --- a/sysdeps/s390/strpbrk-c.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Default strpbrk implementation for S/390. - 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 - . */ - -#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 diff --git a/sysdeps/s390/strpbrk-vx.S b/sysdeps/s390/strpbrk-vx.S deleted file mode 100644 index 0fc7dc1..0000000 --- a/sysdeps/s390/strpbrk-vx.S +++ /dev/null @@ -1,313 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strpbrk. - 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 - . */ - -#include - -#if HAVE_STRPBRK_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char *strpbrk (const char *s, const char * accept) - The strpbrk() function locates the first occurrence in the string s - of any of the characters in the string accept and returns a pointer - to that character or NULL if not found. - - This method checks the length of accept string. If it fits entirely - in one vector register, a fast algorithm is used, which does not need - to check multiple parts of accept-string. Otherwise a slower full - check of accept-string is used. - - register overview: - r3: pointer to start of accept-string - r2: pointer to start of search-string - r0: loaded byte count of vlbb search-string (32bit unsigned) - r4: found byte index (32bit unsigned) - r1: current return len (64bit unsigned) - v16: search-string - v17: accept-string - v18: temp-vreg - - ONLY FOR SLOW: - v19: first accept-string - v20: zero for preparing acc-vector - v21: global mask; 1 indicates a match between - search-string-vreg and any accept-character - v22: current mask; 1 indicates a match between - search-string-vreg and any accept-character in current acc-vreg - v24: one for result-checking of former string-part - v30, v31: for re-/storing registers r6, r8, r9 - r5: current len of accept-string - r6: zero-index in search-string or 16 if no zero - or min(zero-index, loaded byte count) - r8: >0, if former accept-string-part contains a zero, - otherwise =0; - r9: loaded byte count of vlbb accept-string -*/ -ENTRY(STRPBRK_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - /* - Check if accept-string fits in one vreg: - ---------------------------------------- - */ - vlbb %v17,0(%r3),6 /* Load accept. */ - lghi %r1,0 /* Zero out current len. */ - vlgvb %r0,%v17,0 /* Get first element. */ - clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */ - lcbb %r0,0(%r3),6 - jo .Lcheck_onbb /* Special case if accept lays - on block-boundary. */ -.Lcheck_notonbb: - vistrbs %v17,%v17 /* Fill with zeros after first zero. */ - je .Lfast /* Zero found -> accept fits in one vreg. */ - j .Lslow /* No zero -> accept exceeds one vreg */ - - -.Lcheck_onbb: - /* Accept lays on block-boundary. */ - vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ - vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ - clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> - Accept fits in one vreg; - Fill with zeros and proceed - with FAST. */ - vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ - j .Lcheck_notonbb /* Check if accept fits in one vreg. */ - - - /* - Search s for accept in one vreg - ------------------------------- - */ -.Lfast: - /* Complete accept-string in v17 and remaining bytes are zero. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any - in v17 or first zero element. */ - - vlgvb %r4,%v18,7 /* Load byte index of found element. */ - /* If found index is within loaded bytes, return with found - element index (=equal count). */ - clrjl %r4,%r0,.Lfast_loop_found2 - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r1,16 /* current_len = 16. */ - slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ - - /* Process s in 16byte aligned loop. */ -.Lfast_loop: - vl %v16,0(%r1,%r2) /* Load search-string. */ - vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any - in v17 or first zero element. */ - jno .Lfast_loop_found - - vl %v16,16(%r1,%r2) - vfaezbs %v18,%v16,%v17,0 - jno .Lfast_loop_found16 - - vl %v16,32(%r1,%r2) - vfaezbs %v18,%v16,%v17,0 - jno .Lfast_loop_found32 - - vl %v16,48(%r1,%r2) - vfaezbs %v18,%v16,%v17,0 - jno .Lfast_loop_found48 - - aghi %r1,64 - j .Lfast_loop /* Loop if no element was unequal to accept - and not zero. */ - - /* Found equal or zero element. */ -.Lfast_loop_found48: - aghi %r1,16 -.Lfast_loop_found32: - aghi %r1,16 -.Lfast_loop_found16: - aghi %r1,16 -.Lfast_loop_found: - vlgvb %r4,%v18,7 /* Load byte index of found element. */ -.Lfast_loop_found2: - vlgvb %r0,%v16,0(%r4) /* Get found element. */ - clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */ - algfr %r1,%r4 /* Add found index of char to current len. */ - la %r2,0(%r1,%r2) /* And return pointer to first equal char. */ - br %r14 - -.Lfast_end_null: - lghi %r2,0 /* Return null if no character is equal. */ - br %r14 - - - - - /* - Search s for accept in multiple vregs - ------------------------------------- - */ -.Lslow: - /* Save registers. */ - vlvgg %v30,%r6,0 - vlvgp %v31,%r8,%r9 - - /* accept in v17 without zero. */ - vlr %v19,%v17 /* Save first acc-part for a fast reload. */ - vzero %v20 /* Zero for preparing acc-vector. */ - vone %v24 /* One for checking result of former string. */ - - /* Align s to 16 byte. */ - risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and - %r4 = bits 60-63 'and' 15. */ - je .Lslow_loop_str /* If s is aligned, loop aligned. */ - lghi %r0,15 - slr %r0,%r4 /* Compute highest index to load (15-x). */ - vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs - highest index, remaining bytes are 0). */ - ahi %r0,1 /* Work with loaded byte count. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept-string to zero. */ - vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end_null /* If first element is zero - (end of string) -> return null */ - clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ - locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ - j .Lslow_loop_acc - - - /* Process s in 16byte aligned loop. */ -.Lslow_next_str: - /* Check results of former processed str-part. */ - vfeeb %v18,%v21,%v24 /* Find first equal match in global mask - (ones in element). */ - vlgvb %r4,%v18,7 /* Get index of first one (=equal) - or 16 if no match. */ - /* Equal-index < min(zero-index, loaded byte count) - -> return pointer to equal element. */ - clrjl %r4,%r6,.Lslow_index_found - /* Zero-index < loaded byte count - -> former str-part was last str-part - -> return null */ - clrjl %r6,%r0,.Lslow_end_null - /* All elements are zero (=no match) -> proceed with next str-part. */ - - vlr %v17,%v19 /* Load first part of accept (no zero). */ - algfr %r1,%r0 /* Add loaded byte count to current len. */ - -.Lslow_loop_str: - vl %v16,0(%r1,%r2) /* Load search-string */ - lghi %r0,16 /* Loaded byte count is 16. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept to zero. */ - vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end_null /* If first element is zero - (end of string) -> return null. */ - -.Lslow_loop_acc: - vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> - Character matches any accepted character in - this accept-string-part) IN=0, RT=1. */ - vlgvb %r4,%v22,0 /* Get result of first element. */ - /* First element is equal to any accepted characters - (all other parts of accept cannot lead to a match before this one) - -> current len is pointing to first element - -> return found */ - clijh %r4,0,.Lslow_end_found - vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ - /* Proceed with next acc until end of acc is reached. */ - - -.Lslow_next_acc: - clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part - -> add index to current_len and - end. */ - vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ - aghi %r5,16 /* Increment current len of accept-string. */ - lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ - jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is - on block-boundary. */ -.Lslow_next_acc_notonbb: - vistrbs %v17,%v17 /* Fill with zeros after first zero. */ - jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ - -.Lslow_next_acc_prepare_zero: - /* Zero in accept-part: fill zeros with first-accept-character. */ - vlgvb %r8,%v17,0 /* Load first element of acc-part. */ - clije %r8,0,.Lslow_next_str /* Proceed with next string-part, - if first char in this part of accept - is a zero. */ - /* r8>0 -> zero found in this acc-part. */ - vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ - vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars - by comparing with 0 (v20). */ - vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ - j .Lslow_loop_acc /* Accept part is prepared -> process. */ - -.Lslow_next_acc_onbb: - vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ - vlgvb %r8,%v18,7 /* Load byte index of zero. */ - clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes - -> Prepare vreg. */ - vl %v17,0(%r5,%r3) /* Load over boundary ... */ - lghi %r8,0 /* r8=0 -> no zero in this part of acc, - check for zero is in jump-target. */ - j .Lslow_next_acc_notonbb /* ... and search for zero in - fully loaded vreg again. */ - -.Lslow_end_null: - lghi %r1,0 /* Return null if no character is equal. */ - j .Lslow_end - -.Lslow_loop_found: - vlgvb %r4,%v18,7 /* Load byte index of found element. */ - vlgvb %r0,%v16,0(%r4) /* Get found element. */ - clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */ - -.Lslow_index_found: - algfr %r1,%r4 /* Add found index of char to current len. */ -.Lslow_end_found: - la %r1,0(%r1,%r2) /* And return pointer to first equal char. */ - -.Lslow_end: - /* Restore registers. */ - vlgvg %r6,%v30,0 - vlgvg %r8,%v31,0 - vlgvg %r9,%v31,1 - lgr %r2,%r1 - br %r14 -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/strpbrk.c b/sysdeps/s390/strpbrk.c deleted file mode 100644 index 41ce00a..0000000 --- a/sysdeps/s390/strpbrk.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Multiple versions of strpbrk. - 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 - . */ - -#include - -#if HAVE_STRPBRK_IFUNC -# define strpbrk __redirect_strpbrk -/* Omit the strpbrk inline definitions because it would redefine strpbrk. */ -# define __NO_STRING_INLINES -# include -# undef strpbrk -# include - -# 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 - -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/sysdeps/s390/strrchr-c.c b/sysdeps/s390/strrchr-c.c deleted file mode 100644 index 615f16d..0000000 --- a/sysdeps/s390/strrchr-c.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Default strrchr implementation for S/390. - 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 - . */ - -#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 -# endif - -# include -#endif diff --git a/sysdeps/s390/strrchr-vx.S b/sysdeps/s390/strrchr-vx.S deleted file mode 100644 index 5f4ac14..0000000 --- a/sysdeps/s390/strrchr-vx.S +++ /dev/null @@ -1,192 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strrchr. - 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 - . */ - -#include - -#if HAVE_STRRCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char *strrchr (const char *s, int c) - Locate the last character c in string. - - Register usage: - -r0=loaded bytes in first part of s. - -r1=pointer to last occurence of c or NULL if not found. - -r2=s - -r3=c - -r4=tmp - -r5=current_len - -v16=part of s - -v17=index of found element - -v18=replicated c - -v19=part of s with last occurence of c. - -v20=permute pattern -*/ -ENTRY(STRRCHR_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vlvgb %v18,%r3,0 /* Generate vector which elements are all c. - if c > 255, c will be truncated. */ - vrepb %v18,%v18,0 - - lghi %r1,-1 /* Currently no c found. */ - lghi %r5,0 /* current_len = 0. */ - - vfeezbs %v17,%v16,%v18 /* Find element equal or zero. */ - vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */ - clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */ -.Lalign: - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfeezbs %v17,%v16,%v18 /* Find element equal with zero search. */ - jno .Lfound /* Found c/zero (cc=0|1|2). */ - vl %v16,16(%r5,%r2) - vfeezbs %v17,%v16,%v18 - jno .Lfound16 - vl %v16,32(%r5,%r2) - vfeezbs %v17,%v16,%v18 - jno .Lfound32 - vl %v16,48(%r5,%r2) - vfeezbs %v17,%v16,%v18 - jno .Lfound48 - - aghi %r5,64 - j .Lloop /* No character and no zero -> loop. */ - -.Lfound48: - la %r5,16(%r5) /* Use la since aghi would clobber cc. */ -.Lfound32: - la %r5,16(%r5) -.Lfound16: - la %r5,16(%r5) -.Lfound: - je .Lzero /* Found zero, but no c before that zero. */ - /* Save this part of s to check for further matches after reaching - the end of the complete string. */ - vlr %v19,%v16 - lgr %r1,%r5 - - jh .Lzero /* Found a zero after the found c. */ - aghi %r5,16 /* Start search of next part of s. */ - j .Lloop - -.Lfound_first_part: - /* This code is only executed if the found c/zero is whithin loaded - bytes. If no c/zero was found (cc==3) the found index = 16, thus - this code is not called. - Resulting condition code of vector find element equal: - cc==0: no c, found zero - cc==1: c found, no zero - cc==2: c found, found zero after c - cc==3: no c, no zero (this case can be ignored). */ - je .Lzero /* Found zero, but no c before that zero. */ - - locgrne %r1,%r5 /* Mark c as found in first part of s. */ - vlr %v19,%v16 - - jl .Lalign /* No zero (e.g. if vr was fully loaded) - -> Align and loop afterwards. */ - - /* Found a zero in vr. If vr was not fully loaded due to block - boundary, the remaining bytes are filled with zero and we can't - rely on zero indication of condition code here! */ - - vfenezb %v17,%v16,%v16 /* Find zero. */ - vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ - clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */ - j .Lalign /* Align and loop afterwards. */ - -.Lend_searched_zero: - vlgvb %r4,%v17,7 /* Load byte index of zero. */ - algr %r5,%r4 - la %r2,0(%r5,%r2) /* Return pointer to zero. */ - br %r14 - -.Lzero: - /* Reached end of string. Check if one c was found before. */ - clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */ - - cgfi %r1,-1 /* No c found -> return NULL. */ - locghie %r2,0 - ber %r14 - - larl %r3,.Lpermute_mask /* Load permute mask. */ - vl %v20,0(%r3) - - /* c was found and is part of v19. */ - vfenezb %v17,%v19,%v19 /* Find zero. */ - vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ - - clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */ - lochine %r0,16 /* ... if v19 is not the first part of s. */ - ahi %r0,-1 /* Convert byte count to highest index. */ - - clr %r0,%r4 - locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */ - - /* Right-shift of v19 to mask bytes after zero. */ - clije %r4,15,.Lzero_permute /* No shift is needed if highest index - in vr is 15. */ - lhi %r0,15 - slr %r0,%r4 /* Compute byte count for vector shift right. */ - sll %r0,3 /* Convert to bit count. */ - vlvgb %v17,%r0,7 - vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes - specified in bits 1-4 of byte 7 in v17. */ - - /* Reverse bytes in v19. */ -.Lzero_permute: - vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */ - - /* Find c in reversed v19. */ - vfeeb %v19,%v19,%v18 /* Find c. */ - la %r2,0(%r1,%r2) - vlgvb %r3,%v19,7 /* Load byte index of c. */ - - /* Compute index in real s and return. */ - slgr %r4,%r3 - la %r2,0(%r4,%r2) /* Return pointer to zero. */ - br %r14 -.Lpermute_mask: - .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 - .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 -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/strrchr.c b/sysdeps/s390/strrchr.c deleted file mode 100644 index 9a8cecf..0000000 --- a/sysdeps/s390/strrchr.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Multiple versions of strrchr. - 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 - . */ - -#include - -#if HAVE_STRRCHR_IFUNC -# define strrchr __redirect_strrchr -# include -# undef strrchr -# include - -# 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 - -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/sysdeps/s390/strspn-c.c b/sysdeps/s390/strspn-c.c deleted file mode 100644 index 506f668..0000000 --- a/sysdeps/s390/strspn-c.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Default strspn implementation for S/390. - 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 - . */ - -#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 -# endif - -# include -#endif diff --git a/sysdeps/s390/strspn-vx.S b/sysdeps/s390/strspn-vx.S deleted file mode 100644 index ae5529b..0000000 --- a/sysdeps/s390/strspn-vx.S +++ /dev/null @@ -1,267 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of strspn. - 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 - . */ - -#include - -#if HAVE_STRSPN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t strspn (const char *s, const char * accept) - The strspn() function calculates the length of the initial segment - of s which consists entirely of characters in accept. - - This method checks the length of accept string. If it fits entirely - in one vector register, a fast algorithm is used, which does not need - to check multiple parts of accept-string. Otherwise a slower full - check of accept-string is used. - - register overview: - r3: pointer to start of accept-string - r2: pointer to start of search-string - r4: loaded byte count of vl search-string - r0: found byte index - r1: current return len of s - v16: search-string - v17: accept-string - v18: temp-vreg - - ONLY FOR SLOW: - v19: first accept-string - v20: zero for preparing acc-vector - v21: global mask; 1 indicates a match between - search-string-vreg and any accept-character - v22: current mask; 1 indicates a match between - search-string-vreg and any accept-character in current acc-vreg - v30, v31: for re-/storing registers r6, r8, r9 - r5: current len of accept-string - r6: zero-index in search-string or 16 if no zero - or min(zero-index, loaded byte count) - r8: >0, if former accept-string-part contains a zero, - otherwise =0; - r9: loaded byte count of vlbb accept-string -*/ -ENTRY(STRSPN_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - /* - Check if accept-string fits in one vreg: - ---------------------------------------- - */ - vlbb %v17,0(%r3),6 /* Load accept. */ - lcbb %r4,0(%r3),6 - jo .Lcheck_onbb /* Special case if accept lays - on block-boundary. */ -.Lcheck_notonbb: - vistrbs %v17,%v17 /* Fill with zeros after first zero. */ - je .Lfast /* Zero found -> accept fits in one vreg. */ - j .Lslow /* No zero -> accept exceeds one vreg. */ - -.Lcheck_onbb: - /* Accept lays on block-boundary. */ - vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ - vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */ - clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count -> - Accept fits in one vreg; - Fill with zeros and proceed - with FAST. */ - vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ - j .Lcheck_notonbb /* Check if accept fits in one vreg. */ - - - /* - Search s for accept in one vreg - ------------------------------- - */ -.Lfast: - /* Complete accept-string is in v17 and remaining bytes are zero. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfaezbs %v16,%v16,%v17,8 /* Find first element in v16 - unequal to any in v17 - or first zero element. */ - vlgvb %r0,%v16,7 /* Load byte index of found element. */ - /* If found index is within loaded bytes (%r0 < %r1), - return with found element index (=equal count). */ - clr %r0,%r1 - locgrl %r2,%r0 - blr %r14 - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r1,16 /* current_len = 16. */ - slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ - -.Lfast_loop: - vl %v16,0(%r1,%r2) /* Load search-string. */ - vfaezbs %v16,%v16,%v17,8 /* Find first element in v16 - unequal to any in v17 - or first zero element. */ - jno .Lfast_loop_found - vl %v16,16(%r1,%r2) - vfaezbs %v16,%v16,%v17,8 - jno .Lfast_loop_found16 - vl %v16,32(%r1,%r2) - vfaezbs %v16,%v16,%v17,8 - jno .Lfast_loop_found32 - vl %v16,48(%r1,%r2) - vfaezbs %v16,%v16,%v17,8 - jno .Lfast_loop_found48 - - aghi %r1,64 - j .Lfast_loop /* Loop if no element was unequal to accept - and not zero. */ - - /* Found unequal or zero element. */ -.Lfast_loop_found48: - aghi %r1,16 -.Lfast_loop_found32: - aghi %r1,16 -.Lfast_loop_found16: - aghi %r1,16 -.Lfast_loop_found: - vlgvb %r0,%v16,7 /* Load byte index of found element. */ - algrk %r2,%r1,%r0 /* And add it to current len. */ - br %r14 - - - /* - Search s for accept in multiple vregs - ------------------------------------- - */ -.Lslow: - /* Save registers. */ - vlvgg %v30,%r6,0 - vlvgp %v31,%r8,%r9 - lghi %r1,0 /* current_len = 0. */ - - /* Accept in v17 without zero. */ - vlr %v19,%v17 /* Save first acc-part for a fast reload. */ - vzero %v20 /* Zero for preparing acc-vector. */ - - /* Align s to 16 byte. */ - risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and - %r0 = bits 60-63 'and' 15 */ - je .Lslow_loop_str /* If s is aligned, loop aligned */ - lghi %r4,15 - slr %r4,%r0 /* Compute highest index to load (15-x). */ - vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs - highest index, left bytes are 0). */ - ahi %r4,1 /* Work with loaded byte count. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept-string to zero. */ - vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 - if there is no zero. */ - clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */ - locrl %r6,%r4 /* Load on cc==1. */ - j .Lslow_loop_acc - - /* Process s in 16byte aligned loop. */ -.Lslow_next_str: - vlr %v17,%v19 /* Load first part of accept (no zero). */ - algfr %r1,%r4 /* Add loaded byte count to current len. */ -.Lslow_loop_str: - vl %v16,0(%r1,%r2) /* Load search-string. */ - lghi %r4,16 /* Loaded byte count is 16. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept-string to zero. */ - vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - -.Lslow_loop_acc: - vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> - character matches any accepted character in - this accept-string-part) IN=0, RT=1. */ - vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */ - vfenezb %v18,%v21,%v21 /* Find first zero in global-mask. */ - vlgvb %r0,%v18,7 /* Get first found zero-index - (= first mismatch). */ - clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index) - -> Process this string-part - with next acc-part. */ - clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count - -> All loaded bytes are matching - any accept-character - and are not zero. */ - /* All bytes are matching any characters in accept-string - and search-string is fully processed (found-index == zero-index) */ -.Lslow_add_lbc_end: - algrk %r2,%r1,%r0 /* Add matching characters to current_len. */ - /* Restore registers. */ - vlgvg %r6,%v30,0 - vlgvg %r8,%v31,0 - vlgvg %r9,%v31,1 - br %r14 - - - -.Lslow_next_acc: - clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part - -> Add found index to current len - and end. */ - vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ - aghi %r5,16 /* Add current_len of accept-string. */ - lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ - jo .Lslow_next_acc_onbb /* Jump away if accept-string is - on block-boundary. */ -.Lslow_next_acc_notonbb: - vistrbs %v17,%v17 /* Fill with zeros after first zero. */ - jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ - -.Lslow_next_acc_prepare_zero: - /* Zero in accept-part: fill zeros with first-accept-character. */ - vlgvb %r8,%v17,0 /* Load first element of acc-part. */ - clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character - in this part of accept-string. */ - /* r8>0 -> zero found in this acc-part. */ - vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ - vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars - by comparing with 0 (v20). */ - vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ - j .Lslow_loop_acc /* Accept part is prepared -> process. */ - -.Lslow_next_acc_onbb: - vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ - vlgvb %r8,%v18,7 /* Load byte index of zero. */ - clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes - -> Prepare vr. */ - vl %v17,0(%r5,%r3) /* Load over boundary ... */ - lghi %r8,0 /* r8=0 -> no zero in this part of acc, - Check for zero is in jump-target. */ - j .Lslow_next_acc_notonbb /* ... and search for zero in - fully loaded vreg again. */ -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/strspn.c b/sysdeps/s390/strspn.c deleted file mode 100644 index 91401fd..0000000 --- a/sysdeps/s390/strspn.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Multiple versions of strspn. - 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 - . */ - -#include - -#if HAVE_STRSPN_IFUNC -# define strspn __redirect_strspn -/* Omit the strspn inline definitions because it would redefine strspn. */ -# define __NO_STRING_INLINES -# include -# undef strspn -# include - -# 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 - -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/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S deleted file mode 100644 index faa9698..0000000 --- a/sysdeps/s390/strstr-arch13.S +++ /dev/null @@ -1,179 +0,0 @@ -/* 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 %v18,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-c.c b/sysdeps/s390/strstr-c.c deleted file mode 100644 index 53717bf..0000000 --- a/sysdeps/s390/strstr-c.c +++ /dev/null @@ -1,32 +0,0 @@ -/* 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 deleted file mode 100644 index f69159f..0000000 --- a/sysdeps/s390/strstr-vx.c +++ /dev/null @@ -1,52 +0,0 @@ -/* 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 || 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 || STRSTR_Z13_ONLY_USED_AS_FALLBACK -# 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 deleted file mode 100644 index d2969fd..0000000 --- a/sysdeps/s390/strstr.c +++ /dev/null @@ -1,46 +0,0 @@ -/* 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 - -# if HAVE_STRSTR_ARCH13 -extern __typeof (__redirect_strstr) STRSTR_ARCH13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (__redirect_strstr, strstr, - (HAVE_STRSTR_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)) - ? STRSTR_ARCH13 - : (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX)) - ? STRSTR_Z13 - : STRSTR_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wcpcpy-c.c b/sysdeps/s390/wcpcpy-c.c deleted file mode 100644 index ed1539c..0000000 --- a/sysdeps/s390/wcpcpy-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcslen implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCPCPY_C -# if HAVE_WCPCPY_IFUNC || HAVE_WCPCPY_Z13 -# define WCPCPY WCPCPY_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcpcpy-vx.S b/sysdeps/s390/wcpcpy-vx.S deleted file mode 100644 index 5154ad4..0000000 --- a/sysdeps/s390/wcpcpy-vx.S +++ /dev/null @@ -1,120 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcpcpy. - 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 - . */ - -#include -#if HAVE_WCPCPY_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t * wcpcpy (const wchar_t *dest, const wchar_t *src) - Copy string src to dest returning a pointer to its end. - - Register usage: - -r0=border-len for switching to vector-instructions - -r1=tmp - -r2=dest and return value - -r3=src - -r4=tmp - -r5=current_len - -v16=part of src - -v17=index of zero - -v18=part of src -*/ -ENTRY(WCPCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - - tmll %r3,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, - copy bytes before and return. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r4 /* Compute highest index to 16byte boundary. */ - - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Find zero in 16byte aligned loop. */ -.Lloop: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16_0 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezfs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - j .Lloop /* No zero found -> loop. */ - -.Lfound_v16_32: - aghi %r5,32 -.Lfound_v16_0: - la %r3,0(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ - lay %r2,-3(%r1,%r3) /* Return pointer to zero. */ - br %r14 - -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - la %r3,16(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ - lay %r2,-3(%r1,%r3) /* Return pointer to zero. */ - br %r14 - -.Lfound_align: - aghi %r5,3 /* Also copy remaining bytes of zero. */ - vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ - lay %r2,-3(%r5,%r2) /* Return pointer to zero. */ - br %r14 - -.Lfallback: - 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/wcpcpy.c b/sysdeps/s390/wcpcpy.c deleted file mode 100644 index 34ac68b..0000000 --- a/sysdeps/s390/wcpcpy.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcpcpy. - 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 - . */ - -#include - -#if HAVE_WCPCPY_IFUNC -# include -# include - -# if HAVE_WCPCPY_C -extern __typeof (__wcpcpy) WCPCPY_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcpncpy-c.c b/sysdeps/s390/wcpncpy-c.c deleted file mode 100644 index d033592..0000000 --- a/sysdeps/s390/wcpncpy-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcsncpy implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCPNCPY_C -# if HAVE_WCPNCPY_IFUNC || HAVE_WCPNCPY_Z13 -# define WCPNCPY WCPNCPY_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcpncpy-vx.S b/sysdeps/s390/wcpncpy-vx.S deleted file mode 100644 index 7b5e4ad..0000000 --- a/sysdeps/s390/wcpncpy-vx.S +++ /dev/null @@ -1,228 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcpncpy. - 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 - . */ - -#include -#if HAVE_WCPNCPY_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t * wcpncpy (wchar_t *dest, const wchar_t *src, size_t n) - Copies at most n characters of string src to dest - returning a pointer to its end or dest+n - if src is smaller than n. - - Register usage: - -%r0 = return value - -%r1 = zero byte index - -%r2 = curr dst pointer - -%r3 = curr src pointer - -%r4 = n - -%r5 = current_len - -%r6 = loaded bytes - -%r7 = border, tmp -*/ -ENTRY(WCPNCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgfi %r4,0 - ber %r14 /* Nothing to do, if n == 0. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - - tmll %r3,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - vlvgp %v31,%r6,%r7 /* Save registers. */ - lghi %r5,0 /* current_len = 0. */ - - lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r6,%r6 /* Convert 32bit to 64bit. */ - - /* Check range of maxlen and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - llilf %r1,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r4,%r4,2 /* Convert character-count to byte-count. */ - locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ - - la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */ - - clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes - -> process remaining. */ - - /* n > loaded-byte-count */ - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, - copy and return. */ - - /* Align s to 16 byte. */ - risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r7 /* Compute highest index to 16byte boundary. */ - - /* Zero not found and n > loaded-byte-count. */ - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Now we are 16byte aligned, so we can load a full vreg - without page fault. */ - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - clgijl %r4,17,.Lremaining_v16 /* If n <=16, - process remaining bytes. */ -.Llt64: - lgr %r7,%r4 - slgfi %r7,16 /* border_len = n - 16. */ - - clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border - then process remaining bytes. */ - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v18 - vfenezfs %v17,%v18,%v18 - je .Lfound_v18 - vl %v16,16(%r5,%r3) - vst %v18,0(%r5,%r2) - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v16 - vfenezfs %v17,%v16,%v16 - je .Lfound_v16 - vl %v18,16(%r5,%r3) - vst %v16,0(%r5,%r2) - aghi %r5,16 - -.Lremaining_v18: - vlr %v16,%v18 -.Lremaining_v16: - /* v16 contains the remaining bytes [1...16]. - Store remaining bytes and append string-termination. */ - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */ - aghi %r7,-1 /* vstl needs highest index. */ - la %r2,0(%r5,%r2) /* vstl has no index register. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */ - clrjle %r1,%r7,.Lfound_v16_store - vstl %v16,%r7,0(%r2) /* Store remaining bytes without null - termination! */ -.Lend: - /* Restore saved registers. */ - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lfound_v16_32: - aghi %r5,32 - j .Lfound_v16 -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - aghi %r5,16 -.Lfound_v18: - vlr %v16,%v18 -.Lfound_v16: - /* v16 contains a zero. Store remaining bytes to zero. current_len - has not reached border, thus checking for n is not needed! */ - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ -.Lfound_v16_store: - vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ - /* Fill remaining bytes with zero - remaining byte count always > 0. */ - algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ - slgr %r4,%r5 /* = n - (currlen + zero_index + 1) */ - la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ - lay %r0,-3(%r2) /* Save return-pointer to found zero. */ - clgije %r4,1,.Lend /* Skip zero-filling, if found-zero is last - possible character. - (1 is substracted from r4 below!). */ - aghi %r4,-2 /* mvc with exrl needs count - 1. - (additional -1, see remaining bytes above) */ - srlg %r6,%r4,8 /* Split into 256 byte blocks. */ - ltgr %r6,%r6 - je .Lzero_lt256 -.Lzero_loop256: - mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ - la %r2,256(%r2) - brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ -.Lzero_lt256: - exrl %r4,.Lmvc_lt256 - j .Lend -.Lmvc_lt256: - mvc 1(1,%r2),0(%r2) - - /* Find zero in 16byte aligned loop. */ -.Lloop64: - vl %v16,0(%r5,%r3) - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezfs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - j .Llt64 - -.Lfallback: - 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/wcpncpy.c b/sysdeps/s390/wcpncpy.c deleted file mode 100644 index 08d097d..0000000 --- a/sysdeps/s390/wcpncpy.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcpncpy. - 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 - . */ - -#include - -#if HAVE_WCPNCPY_IFUNC -# include -# include - -# if HAVE_WCPNCPY_C -extern __typeof (__wcpncpy) WCPNCPY_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcscat-c.c b/sysdeps/s390/wcscat-c.c deleted file mode 100644 index bc1a50b..0000000 --- a/sysdeps/s390/wcscat-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcscat implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSCAT_C -# if HAVE_WCSCAT_IFUNC || HAVE_WCSCAT_Z13 -# define WCSCAT WCSCAT_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcscat-vx.S b/sysdeps/s390/wcscat-vx.S deleted file mode 100644 index 4e40d69..0000000 --- a/sysdeps/s390/wcscat-vx.S +++ /dev/null @@ -1,181 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcscat. - 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 - . */ - -#include -#if HAVE_WCSCAT_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t * wcscat (wchar_t *dest, const wchar_t *src) - Concatenate two strings. - - Register usage: - -r0=saved dest pointer for return - -r1=tmp - -r2=dest - -r3=src - -r4=tmp - -r5=current_len - -v16=part of src - -v17=index of zero - -v18=part of src -*/ -ENTRY(WCSCAT_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - /* __wcslen_c can handle non 4byte aligned pointers, - but __wcscpy_c not. Thus if either src or dest is - not 4byte aligned, use __wcscat_c. */ - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - tmll %r3,3 /* Test if src is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - lgr %r0,%r2 /* Save destination pointer for return. */ - - /* WCSLEN - r1 = loaded bytes (tmp) - r4 = zero byte index (tmp) - r2 = dst - */ - - vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ - - /* Find zero in 16byte aligned loop. */ -.Llen_loop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Llen_found /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Llen_found16 - vl %v16,32(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Llen_found32 - vl %v16,48(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Llen_found48 - - aghi %r5,64 - j .Llen_loop /* No zero -> loop. */ - -.Llen_found48: - aghi %r5,16 -.Llen_found32: - aghi %r5,16 -.Llen_found16: - aghi %r5,16 -.Llen_found: - vlgvb %r4,%v16,7 /* Load byte index of zero. */ - algr %r5,%r4 - -.Llen_end: - /* WCSCPY - %r1 = loaded bytes (tmp) - %r4 = zero byte index (tmp) - %r3 = curr src pointer - %r2 = curr dst pointer - */ - la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes, - copy bytes before and return. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r4 /* Compute highest index to 16byte boundary. */ - - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Find zero in 16byte aligned loop. */ -.Lcpy_loop: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lcpy_found_v16_0 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ - vfenezfs %v17,%v18,%v18 - je .Lcpy_found_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezfs %v17,%v16,%v16 - je .Lcpy_found_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezfs %v17,%v18,%v18 - je .Lcpy_found_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - j .Lcpy_loop /* No zero -> loop. */ - -.Lcpy_found_v16_32: - aghi %r5,32 -.Lcpy_found_v16_0: - la %r4,0(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - vstl %v16,%r1,0(%r4) /* Copy characters including zero. */ - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lcpy_found_v18_48: - aghi %r5,32 -.Lcpy_found_v18_16: - la %r4,16(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - vstl %v18,%r1,0(%r4) /* Copy characters including zero. */ - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lcpy_found_align: - aghi %r5,3 /* Also copy remaining bytes of found zero. */ - vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 -.Lfallback: - 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/wcscat.c b/sysdeps/s390/wcscat.c deleted file mode 100644 index 3741210..0000000 --- a/sysdeps/s390/wcscat.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcscat. - 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 - . */ - -#include - -#if HAVE_WCSCAT_IFUNC -# include -# include - -# if HAVE_WCSCAT_C -extern __typeof (__wcscat) WCSCAT_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcschr-c.c b/sysdeps/s390/wcschr-c.c deleted file mode 100644 index 4908492..0000000 --- a/sysdeps/s390/wcschr-c.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Default wcschr implementation for S/390. - 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 - . */ - -#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); -# else -# define libc_hidden_def(name) -# endif -# endif -# endif - -# include -#endif diff --git a/sysdeps/s390/wcschr-vx.S b/sysdeps/s390/wcschr-vx.S deleted file mode 100644 index dd24998..0000000 --- a/sysdeps/s390/wcschr-vx.S +++ /dev/null @@ -1,115 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcschr. - 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 - . */ - -#include -#if HAVE_WCSCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t *wcschr (const wchar_t *s, wchar_t c) - Locate character in string. - - Register usage: - -r1=tmp - -r2=s - -r3=c - -r4=tmp - -r5=current_len - -v16=part of s - -v17=index of unequal - -v18=replicated c -*/ -ENTRY(WCSCHR_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - lghi %r5,0 /* current_len = 0. */ - - vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ - vrepf %v18,%v18,0 - - vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ - vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ - clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - - /* Find c/zero in 16byte aligned loop */ -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ - jno .Lfound /* Found c/zero (cc=0|1|2). */ - vl %v16,16(%r5,%r2) - vfeezfs %v16,%v16,%v18 - jno .Lfound16 - vl %v16,32(%r5,%r2) - vfeezfs %v16,%v16,%v18 - jno .Lfound32 - vl %v16,48(%r5,%r2) - vfeezfs %v16,%v16,%v18 - jno .Lfound48 - - aghi %r5,64 - j .Lloop /* No character and no zero -> loop. */ - -.Lfound48: - la %r5,16(%r5) /* Use la since aghi would clobber cc. */ -.Lfound32: - la %r5,16(%r5) -.Lfound16: - la %r5,16(%r5) -.Lfound: - je .Lzero /* Found zero, but no c before that zero. */ - -.Lcharacter: - vlgvb %r4,%v16,7 /* Load byte index of character. */ - algr %r5,%r4 - la %r2,0(%r5,%r2) /* Return pointer to character. */ - br %r14 - -.Lzero: - clije %r3,0,.Lcharacter /* Found zero and c is zero. */ - lghi %r2,0 /* Return null if character not found. */ - br %r14 -.Lfallback: - 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/wcschr.c b/sysdeps/s390/wcschr.c deleted file mode 100644 index 9923864..0000000 --- a/sysdeps/s390/wcschr.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Multiple versions of wcschr. - 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 - . */ - -#include - -#if HAVE_WCSCHR_IFUNC -# define wcschr __redirect_wcschr -# define __wcschr __redirect___wcschr -# include -# undef wcschr -# undef __wcschr -# include - -# if HAVE_WCSCHR_C -extern __typeof (__redirect___wcschr) WCSCHR_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcschrnul-c.c b/sysdeps/s390/wcschrnul-c.c deleted file mode 100644 index 410cee1..0000000 --- a/sysdeps/s390/wcschrnul-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcschrnul implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSCHRNUL_C -# if HAVE_WCSCHRNUL_IFUNC || HAVE_WCSCHRNUL_Z13 -# define WCSCHRNUL WCSCHRNUL_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcschrnul-vx.S b/sysdeps/s390/wcschrnul-vx.S deleted file mode 100644 index 4ffb937..0000000 --- a/sysdeps/s390/wcschrnul-vx.S +++ /dev/null @@ -1,103 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcschrnul. - 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 - . */ - -#include -#if HAVE_WCSCHRNUL_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t* wcschrnul (const wchar_t *s, wchar_t c) - Returns pointer to first c or to \0 if c not found. - - Register usage: - -r1=tmp - -r2=s and return pointer - -r3=c - -r4=tmp - -r5=current_len - -v16=part of s - -v18=vector with c replicated in every byte -*/ -ENTRY(WCSCHRNUL_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - lghi %r5,0 /* current_len = 0. */ - - vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ - vrepf %v18,%v18,0 - - vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ - vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ - clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - - /* Find c/zero in 16byte aligned loop */ -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ - jno .Lfound /* Found c/zero (cc=0|1|2). */ - vl %v16,16(%r5,%r2) - vfeezfs %v16,%v16,%v18 - jno .Lfound16 - vl %v16,32(%r5,%r2) - vfeezfs %v16,%v16,%v18 - jno .Lfound32 - vl %v16,48(%r5,%r2) - vfeezfs %v16,%v16,%v18 - jno .Lfound48 - - aghi %r5,64 - j .Lloop /* No character and no zero -> loop. */ - - /* Found character or zero */ -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound: - vlgvb %r1,%v16,7 /* Load byte index of character. */ - algr %r5,%r1 - la %r2,0(%r5,%r2) /* Return pointer to character. */ - -.Lend: - br %r14 -.Lfallback: - 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/wcschrnul.c b/sysdeps/s390/wcschrnul.c deleted file mode 100644 index ab5aaf0..0000000 --- a/sysdeps/s390/wcschrnul.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcschrnul. - 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 - . */ - -#include - -#if HAVE_WCSCHRNUL_IFUNC -# include -# include - -# if HAVE_WCSCHRNUL_C -extern __typeof (__wcschrnul) WCSCHRNUL_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcscmp-c.c b/sysdeps/s390/wcscmp-c.c deleted file mode 100644 index 643ba7a..0000000 --- a/sysdeps/s390/wcscmp-c.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Default wcscmp implementation for S/390. - 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 - . */ - -#include - -#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 -# endif - -# include -#endif diff --git a/sysdeps/s390/wcscmp-vx.S b/sysdeps/s390/wcscmp-vx.S deleted file mode 100644 index a2789d8..0000000 --- a/sysdeps/s390/wcscmp-vx.S +++ /dev/null @@ -1,141 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcscmp. - 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 - . */ - -#include -#if HAVE_WCSCMP_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* int wcscmp (const wchar_t *s1, const wchar_t *s2) - Compare two strings - - Register usage: - -r1=loaded byte count s1 - -r2=s1 - -r3=s2 - -r4=loaded byte coutn s2, tmp - -r5=current_len - -v16=part of s1 - -v17=part of s2 - -v18=index of unequal -*/ -ENTRY(WCSCMP_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - lghi %r5,0 /* current_len = 0. */ - -.Lloop: - vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ - vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ - lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */ - jo .Llt16_1 /* Jump away if vr is not fully loaded. */ - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 /* Jump away if vr is not fully loaded. */ - /* Both vrs are fully loaded. */ - aghi %r5,16 - vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r1,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezfs %v18,%v16,%v17 - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r1,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezfs %v18,%v16,%v17 - jno .Lfound - - vlbb %v16,0(%r5,%r2),6 - vlbb %v17,0(%r5,%r3),6 - lcbb %r1,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r4,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezfs %v18,%v16,%v17 - jno .Lfound - j .Lloop - -.Lcmp_one_char: - /* At least one of both strings is not 4-byte aligned - and there is no full character before next block-boundary. - Compare one character to get over the boundary and - proceed with normal loop! */ - vlef %v16,0(%r5,%r2),0 /* Load one character. */ - vlef %v17,0(%r5,%r3),0 - lghi %r1,4 /* Loaded byte count is 4. */ - j .Llt_cmp /* Proceed with comparision. */ - -.Llt16_1: - lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */ -.Llt16_2: - clr %r1,%r4 - locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */ - nill %r1,65532 /* Align bytes loaded to full characters. */ - jz .Lcmp_one_char /* Jump away if no full char is available. */ -.Llt_cmp: - algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */ - vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ - vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ - clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded - bytes. */ - j .Lloop - -.Lfound: - /* vfenezf found an unequal element or zero. - This instruction compares unsigned words, but wchar_t is signed. - Thus we have to compare the found element again. */ - vlgvb %r4,%v18,7 /* Extract not equal byte-index, */ - srl %r4,2 /* Convert it to character-index. */ - vlgvf %r3,%v16,0(%r4) /* Load character-values. */ - vlgvf %r4,%v17,0(%r4) - cr %r3,%r4 - je .Lend_equal - lghi %r2,1 - lghi %r1,-1 - locgrl %r2,%r1 - br %r14 -.Lend_equal: - lghi %r2,0 - br %r14 -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/wcscmp.c b/sysdeps/s390/wcscmp.c deleted file mode 100644 index 769c735..0000000 --- a/sysdeps/s390/wcscmp.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Multiple versions of wcscmp. - 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 - . */ - -#include - -#if HAVE_WCSCMP_IFUNC -# define __wcscmp __redirect___wcscmp -# include -# undef __wcscmp -# include - -# if HAVE_WCSCMP_C -extern __typeof (__redirect___wcscmp) WCSCMP_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcscpy-c.c b/sysdeps/s390/wcscpy-c.c deleted file mode 100644 index db2967f..0000000 --- a/sysdeps/s390/wcscpy-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcscpy implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSCPY_C -# if HAVE_WCSCPY_IFUNC || HAVE_WCSCPY_Z13 -# define WCSCPY WCSCPY_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcscpy-vx.S b/sysdeps/s390/wcscpy-vx.S deleted file mode 100644 index 8fe12f4..0000000 --- a/sysdeps/s390/wcscpy-vx.S +++ /dev/null @@ -1,116 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcscpy. - 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 - . */ - -#include -#if HAVE_WCSCPY_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* char * wcscpy (const wchar_t *dest, const wchar_t *src) - Copy string src to dest. - - Register usage: - -r0=border-len for switching to vector-instructions - -r1=tmp - -r2=dest and return value - -r3=src - -r4=tmp - -r5=current_len - -v16=part of src - -v17=index of zero - -v18=part of src -*/ -ENTRY(WCSCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - - tmll %r3,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, - copy bytes before and return. */ - - /* Align s to 16 byte. */ - risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r4 /* Compute highest index to 16byte boundary. */ - - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Find zero in 16byte aligned loop. */ -.Lloop: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16_0 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezfs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - j .Lloop /* No zero found -> loop. */ - -.Lfound_v16_32: - aghi %r5,32 -.Lfound_v16_0: - la %r3,0(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ - br %r14 - -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - la %r3,16(%r5,%r2) - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ - br %r14 - -.Lfound_align: - aghi %r5,3 /* Also copy remaining bytes of zero. */ - vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ - br %r14 - -.Lfallback: - jg WCSCPY_C -END(WCSCPY_Z13) - -# if ! HAVE_WCSCPY_IFUNC -strong_alias (WCSCPY_Z13, wcscpy) -# endif -#endif diff --git a/sysdeps/s390/wcscpy.c b/sysdeps/s390/wcscpy.c deleted file mode 100644 index 51f0732..0000000 --- a/sysdeps/s390/wcscpy.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Multiple versions of wcscpy. - 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 - . */ - -#include - -#if HAVE_WCSCPY_IFUNC -# include -# include - -# if HAVE_WCSCPY_C -extern __typeof (wcscpy) WCSCPY_C attribute_hidden; -# endif - -# if HAVE_WCSCPY_Z13 -extern __typeof (wcscpy) WCSCPY_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (wcscpy, wcscpy, - (HAVE_WCSCPY_Z13 && (hwcap & HWCAP_S390_VX)) - ? WCSCPY_Z13 - : WCSCPY_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wcscspn-c.c b/sysdeps/s390/wcscspn-c.c deleted file mode 100644 index d47cb6b..0000000 --- a/sysdeps/s390/wcscspn-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcscscpn implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSCSPN_C -# if HAVE_WCSCSPN_IFUNC || HAVE_WCSCSPN_Z13 -# define WCSCSPN WCSCSPN_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcscspn-vx.S b/sysdeps/s390/wcscspn-vx.S deleted file mode 100644 index 882cb93..0000000 --- a/sysdeps/s390/wcscspn-vx.S +++ /dev/null @@ -1,298 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcscspn. - 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 - . */ - -#include -#if HAVE_WCSCSPN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t wcscspn (const wchar_t *s, const wchar_t * reject) - The wcscspn() function calculates the length of the initial segment - of s which consists entirely of characters not in reject. - - This method checks the length of reject string. If it fits entirely - in one vector register, a fast algorithm is used, which does not need - to check multiple parts of accept-string. Otherwise a slower full - check of accept-string is used. - - register overview: - r3: pointer to start of reject-string - r2: pointer to start of search-string - r0: loaded byte count of vlbb search-string - r4: found byte index - r1: current return len - v16: search-string - v17: reject-string - v18: temp-vreg - - ONLY FOR SLOW: - v19: first reject-string - v20: zero for preparing acc-vector - v21: global mask; 1 indicates a match between - search-string-vreg and any reject-character - v22: current mask; 1 indicates a match between - search-string-vreg and any reject-character in current acc-vreg - v30, v31: for re-/storing registers r6, r8, r9 - r5: current len of reject-string - r6: zero-index in search-string or 16 if no zero - or min(zero-index, loaded byte count) - r8: >0, if former reject-string-part contains a zero, - otherwise =0; - r9: loaded byte count of vlbb reject-string -*/ -ENTRY(WCSCSPN_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - /* - Check if reject-string fits in one vreg: - ---------------------------------------- - */ - vlbb %v17,0(%r3),0 /* Load reject. */ - lcbb %r0,0(%r3),0 - jo .Lcheck_onbb /* Special case if reject - lays on block-boundary. */ - -.Lcheck_notonbb: - lghi %r1,0 /* Zero out current len. */ - vistrfs %v17,%v17 /* Fill with zeros after first zero. */ - je .Lfast /* Zero found -> reject fits in one vreg. */ - j .Lslow /* No zero -> reject exceeds one vreg. */ - - -.Lcheck_onbb: - /* Reject lays on block-boundary. */ - nill %r0,65532 /* Recognize only fully loaded characters. */ - je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */ - vfenezf %v18,%v17,%v17 /* Search zero in loaded reject bytes. */ - vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ - clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> - Reject fits in one vreg; - Fill with zeros and proceed - with FAST. */ -.Lcheck_onbb2: - vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */ - j .Lcheck_notonbb /* Check if reject fits in one vreg. */ - - - /* - Search s for reject in one vreg - ------------------------------- - */ -.Lfast: - /* Complete reject-string in v17 and remaining bytes are zero. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 - unequal to any in v17 - or first zero element. */ - vlgvb %r4,%v18,7 /* Load byte index of found element. */ - clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded - bytes, return with found element - index (=equal count). */ - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r1,16 /* current_len = 16. */ - slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ - - /* Process s in 16byte aligned loop. */ -.Lfast_loop: - vl %v16,0(%r1,%r2) /* Load search-string. */ - vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any - in v17 or first zero element. */ - jno .Lfast_loop_found - - vl %v16,16(%r1,%r2) - vfaezfs %v18,%v16,%v17,0 - jno .Lfast_loop_found16 - - vl %v16,32(%r1,%r2) - vfaezfs %v18,%v16,%v17,0 - jno .Lfast_loop_found32 - - vl %v16,48(%r1,%r2) - vfaezfs %v18,%v16,%v17,0 - jno .Lfast_loop_found48 - - aghi %r1,64 - j .Lfast_loop /* Loop if no element was unequal to reject - and not zero. */ - - /* Found equal or zero element. */ -.Lfast_loop_found48: - aghi %r1,16 -.Lfast_loop_found32: - aghi %r1,16 -.Lfast_loop_found16: - aghi %r1,16 -.Lfast_loop_found: - vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */ -.Lfast_loop_found2: - algrk %r2,%r1,%r4 /* Add found index to current len. */ - srlg %r2,%r2,2 /* Convert byte-count to character-count. */ - br %r14 - - - - /* - Search s for reject in multiple vregs - ------------------------------------- - */ -.Lslow: - /* Save registers. */ - vlvgg %v30,%r6,0 - vlvgp %v31,%r8,%r9 - - /* Reject in v17 without zero. */ - vlr %v19,%v17 /* Save first acc-part for a fast reload. */ - vzero %v20 /* Zero for preparing acc-vector. */ - vone %v24 /* One for checking result of former - string-part. */ - - /* Align s to 16 byte. */ - risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and - %r4 = bits 60-63 'and' 15. */ - je .Lslow_loop_str /* If s is aligned, loop aligned. */ - lghi %r0,15 - slr %r0,%r4 /* Compute highest index to load (15-x). */ - vll %v16,%r0,0(%r2) /* Load up to 16byte boundary (vll needs - highest index, remaining bytes are 0). */ - ahi %r0,1 /* Work with loaded byte count. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of reject-string to zero. */ - vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first reject-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */ - clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ - locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ - j .Lslow_loop_acc - - - /* Process s in 16byte aligned loop. */ -.Lslow_next_str: - /* Check results of former processed str-part. */ - vfeef %v18,%v21,%v24 /* Find first equal match in global mask - (ones in element). */ - vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */ - /* Equal-index < min(zero-index, loaded byte count) - -> Return pointer to equal element. */ - clrjl %r4,%r6,.Lslow_index_found - /* Zero-index < loaded byte count - -> Former str-part was last str-part - -> Return null */ - clrjl %r6,%r0,.Lslow_end_not_found - - /* All elements are zero (=no match) -> proceed with next str-part. */ - vlr %v17,%v19 /* Load first part of reject (no zero). */ - algfr %r1,%r0 /* Add loaded byte count to current len. */ - -.Lslow_loop_str: - vl %v16,0(%r1,%r2) /* Load search-string. */ - lghi %r0,16 /* Loaded byte count is 16. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of reject to zero. */ - vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first reject-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end /* If first element is zero (end of string) - -> Return current length. */ - -.Lslow_loop_acc: - vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> - Character matches any rejected character in - this reject-string-part) IN=0, RT=1. */ - vlgvf %r4,%v22,0 /* Get result of first element. */ - /* First element is equal to any rejected characters? - (All other parts of reject cannot lead to a match before this one) - -> Return current len, which is pointing to this element. */ - clijh %r4,0,.Lslow_end - vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ - /* Proceed with next acc until end of acc is reached. */ - - -.Lslow_next_acc: - clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part - -> Add found index to current len - and end. */ - vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */ - aghi %r5,16 /* Increment current len of reject-string. */ - lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */ - jo .Lslow_next_acc_onbb /* Jump away if reject-string is - on block-boundary. */ -.Lslow_next_acc_notonbb: - vistrfs %v17,%v17 /* Fill with zeros after first zero. */ - jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ - -.Lslow_next_acc_prepare_zero: - /* Zero in reject-part: fill zeros with first-reject-character. */ - vlgvf %r8,%v17,0 /* Load first element of reject-part. */ - clije %r8,0,.Lslow_next_str /* Process next str-part if first - character in this part of reject - is a zero. */ - /* r8>0 -> zero found in this acc-part. */ - vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ - vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars - by comparing with 0 (v20). */ - vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ - j .Lslow_loop_acc /* Reject-string part is prepared. */ - -.Lslow_next_acc_onbb: - nill %r9,65532 /* Recognize only fully loaded characters. */ - je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t - loaded. */ - vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */ - vlgvb %r8,%v18,7 /* Load byte index of zero. */ - clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes - -> Prepare vreg. */ -.Lslow_next_acc_onbb2: - vl %v17,0(%r5,%r3) /* Load over boundary ... */ - lghi %r8,0 /* r8=0 -> no zero in this part of acc, - check for zero is in jump-target. */ - j .Lslow_next_acc_notonbb /* ... and search for zero in - fully loaded vreg again. */ - -.Lslow_end_not_found: - algfr %r1,%r6 /* Add zero-index to current len. */ - j .Lslow_end -.Lslow_index_found: - algfr %r1,%r4 /* Add found index of char to current len. */ -.Lslow_end: - srlg %r2,%r1,2 /* Convert byte-count to character-count. */ - /* Restore registers. */ - vlgvg %r6,%v30,0 - vlgvg %r8,%v31,0 - vlgvg %r9,%v31,1 - br %r14 -.Lfallback: - jg WCSCSPN_C -END(WCSCSPN_Z13) - -# if ! HAVE_WCSCSPN_IFUNC -strong_alias (WCSCSPN_Z13, wcscspn) -# endif -#endif diff --git a/sysdeps/s390/wcscspn.c b/sysdeps/s390/wcscspn.c deleted file mode 100644 index 0ce31b8..0000000 --- a/sysdeps/s390/wcscspn.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Multiple versions of wcscspn. - 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 - . */ - -#include - -#if HAVE_WCSCSPN_IFUNC -# include -# include - -# if HAVE_WCSCSPN_C -extern __typeof (wcscspn) WCSCSPN_C attribute_hidden; -# endif - -# if HAVE_WCSCSPN_Z13 -extern __typeof (wcscspn) WCSCSPN_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (wcscspn, wcscspn, - (HAVE_WCSCSPN_Z13 && (hwcap & HWCAP_S390_VX)) - ? WCSCSPN_Z13 - : WCSCSPN_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wcslen-c.c b/sysdeps/s390/wcslen-c.c deleted file mode 100644 index 45399cf..0000000 --- a/sysdeps/s390/wcslen-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcslen implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSLEN_C -# if HAVE_WCSLEN_IFUNC || HAVE_WCSLEN_Z13 -# define WCSLEN WCSLEN_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcslen-vx.S b/sysdeps/s390/wcslen-vx.S deleted file mode 100644 index 114f7ef..0000000 --- a/sysdeps/s390/wcslen-vx.S +++ /dev/null @@ -1,97 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcslen. - 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 - . */ - -#include -#if HAVE_WCSLEN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t wcslen (const wchar_t *s) - Returns length of string s. - - Register usage: - -r1=bytes to 4k-byte boundary - -r2=s - -r3=tmp - -r4=tmp - -r5=current_len and return_value - -v16=part of s -*/ -ENTRY(WCSLEN_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */ - clr %r4,%r1 /* If found zero within loaded bytes? */ - locgrl %r2,%r4 /* Then copy return value. */ - jl .Lend /* And return. */ - - /* Align s to 16 byte. */ - risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r3 /* Compute bytes to 16bytes boundary. */ - - /* Find zero in 16byte aligned loop. */ -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound16 - vl %v16,32(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound32 - vl %v16,48(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound48 - - aghi %r5,64 - j .Lloop /* No zero found -> loop. */ - -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound: - vlgvb %r2,%v16,7 /* Load byte index of zero. */ - algr %r2,%r5 -.Lend: - srlg %r2,%r2,2 /* Convert byte-count to character-count. */ - br %r14 -.Lfallback: - 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/wcslen.c b/sysdeps/s390/wcslen.c deleted file mode 100644 index a5eee83..0000000 --- a/sysdeps/s390/wcslen.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcslen. - 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 - . */ - -#include - -#if HAVE_WCSLEN_IFUNC -# include -# include - -# if HAVE_WCSLEN_C -extern __typeof (__wcslen) WCSLEN_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcsncat-c.c b/sysdeps/s390/wcsncat-c.c deleted file mode 100644 index 5782d5c..0000000 --- a/sysdeps/s390/wcsncat-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcsncat implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSNCAT_C -# if HAVE_WCSNCAT_IFUNC || HAVE_WCSNCAT_Z13 -# define WCSNCAT WCSNCAT_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcsncat-vx.S b/sysdeps/s390/wcsncat-vx.S deleted file mode 100644 index 7c89d3d..0000000 --- a/sysdeps/s390/wcsncat-vx.S +++ /dev/null @@ -1,270 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcsncat. - 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 - . */ - -#include -#if HAVE_WCSNCAT_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t * wcsncat (wchar_t *dest, const wchar_t *src, size_t n) - Concatenate two strings - at most n characters of src. - - Register usage: - -r0=saved dest pointer for return - -r1=tmp - -r2=dest - -r3=src - -r4=n - -r5=current_len - -r6=tmp - -r7=tmp - -v16=part of src - -v17=index of zero - -v18=part of src - -v31=register save area for r6, r7 -*/ -ENTRY(WCSNCAT_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgfi %r4,0 - ber %r14 /* Nothing to do, if n == 0. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - /* If either src or dest is not 4byte aligned, use __wcsncat_c. */ - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - tmll %r3,3 /* Test if src is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - lgr %r0,%r2 /* Save destination pointer for return. */ - vlvgp %v31,%r6,%r7 /* Save registers. */ - - /* WCSLEN - %r1 = loaded bytes (tmp) - %r6 = zero byte index (tmp) - %r2 = dst - */ - vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ - - /* Find zero in 16byte aligned loop. */ -.Llen_loop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Llen_found /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Llen_found16 - vl %v16,32(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Llen_found32 - vl %v16,48(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Llen_found48 - - aghi %r5,64 - j .Llen_loop /* No zero -> loop. */ - -.Llen_found48: - aghi %r5,16 -.Llen_found32: - aghi %r5,16 -.Llen_found16: - aghi %r5,16 -.Llen_found: - vlgvb %r1,%v16,7 /* Load byte index of zero. */ - algr %r5,%r1 - -.Llen_end: - /* WCSNCPY - %r1 = zero byte index (tmp) - %r6 = loaded bytes (tmp) - %r3 = curr src pointer - %r2 = curr dst pointer - %r7 = border, tmp - */ - la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r6,%r6 /* Convert 32bit to 64bit. */ - - lghi %r5,0 /* current_len = 0. */ - - /* Check range of maxlen and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - llilf %r1,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r4,%r4,2 /* Convert character-count to byte-count. */ - locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ - - clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes - -> process remaining. */ - - /* n > loaded-byte-count. */ - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded bytes, - copy and return. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r1 /* Compute highest index to 16byte boundary. * - - /* Zero not found and maxlen > loaded-byte-count. */ - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* - Now we are 16byte aligned, so we can load a full vreg - without page fault. - */ - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lcpy_loop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16, - process remaining bytes. */ -.Lcpy_lt64: - lgr %r7,%r4 - slgfi %r7,16 /* border_len = n - 16. */ - - clgrjhe %r5,%r7,.Lcpy_remaining_v16 - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lcpy_found_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ - aghi %r5,16 - - clgrjhe %r5,%r7,.Lcpy_remaining_v18 - vfenezfs %v17,%v18,%v18 - je .Lcpy_found_v18 - vl %v16,16(%r5,%r3) - vst %v18,0(%r5,%r2) - aghi %r5,16 - - clgrjhe %r5,%r7,.Lcpy_remaining_v16 - vfenezfs %v17,%v16,%v16 - je .Lcpy_found_v16 - vl %v18,16(%r5,%r3) - vst %v16,0(%r5,%r2) - aghi %r5,16 - -.Lcpy_remaining_v18: - vlr %v16,%v18 -.Lcpy_remaining_v16: - /* v16 contains the remaining bytes [1...16]. - Store remaining bytes and append string-termination. */ - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ - aghi %r7,-1 /* vstl needs highest index. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - la %r2,0(%r5,%r2) /* vstl has no index register. */ - /* Zero-index within remaining-bytes, store up to zero and end. */ - clgrjle %r1,%r7,.Lcpy_found_v16_store - vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ - lghi %r1,0 - st %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */ -.Lcpy_end: - /* Restore saved registers. */ - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lcpy_found_v16_32: - aghi %r5,32 - j .Lcpy_found_v16 -.Lcpy_found_v18_48: - aghi %r5,32 -.Lcpy_found_v18_16: - aghi %r5,16 -.Lcpy_found_v18: - vlr %v16,%v18 -.Lcpy_found_v16: - /* v16 contains a zero. Store remaining bytes to zero. current_len - has not reached border, thus checking for n is not needed! */ - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - la %r2,0(%r5,%r2) -.Lcpy_found_v16_store: - aghi %r1,3 /* Also copy remaining bytes of zero. */ - vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ - j .Lcpy_end - - /* Find zero in 16byte aligned loop. */ -.Lcpy_loop2: - vl %v16,16(%r5,%r3) - vst %v18,0(%r5,%r2) - aghi %r5,16 - -.Lcpy_loop64: - vl %v16,0(%r5,%r3) - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lcpy_found_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ - vfenezfs %v17,%v18,%v18 - je .Lcpy_found_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezfs %v17,%v16,%v16 - je .Lcpy_found_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezfs %v17,%v18,%v18 - je .Lcpy_found_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lcpy_loop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - j .Lcpy_lt64 - -.Lfallback: - jg WCSNCAT_C -END(WCSNCAT_Z13) - -# if ! HAVE_WCSNCAT_IFUNC -strong_alias (WCSNCAT_Z13, wcsncat) -# endif -#endif diff --git a/sysdeps/s390/wcsncat.c b/sysdeps/s390/wcsncat.c deleted file mode 100644 index 722429f..0000000 --- a/sysdeps/s390/wcsncat.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Multiple versions of wcsncat. - 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 - . */ - -#include - -#if HAVE_WCSNCAT_IFUNC -# include -# include - -# if HAVE_WCSNCAT_C -extern __typeof (wcsncat) WCSNCAT_C attribute_hidden; -# endif - -# if HAVE_WCSNCAT_Z13 -extern __typeof (wcsncat) WCSNCAT_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (wcsncat, wcsncat, - (HAVE_WCSNCAT_Z13 && (hwcap & HWCAP_S390_VX)) - ? WCSNCAT_Z13 - : WCSNCAT_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wcsncmp-c.c b/sysdeps/s390/wcsncmp-c.c deleted file mode 100644 index a9ccb8d..0000000 --- a/sysdeps/s390/wcsncmp-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcsncmp implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSNCMP_C -# if HAVE_WCSNCMP_IFUNC -# define WCSNCMP WCSNCMP_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcsncmp-vx.S b/sysdeps/s390/wcsncmp-vx.S deleted file mode 100644 index 9bdd21a..0000000 --- a/sysdeps/s390/wcsncmp-vx.S +++ /dev/null @@ -1,182 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcsncmp. - 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 - . */ - -#include -#if HAVE_WCSNCMP_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* int wcsncmp (const wchar_t *s1, const wchar_t *s2, size_t n) - Compare at most n characters of two strings. - - Register usage: - -r0=tmp - -r1=tmp - -r2=s1 - -r3=s2 - -r4=n - -r5=current_len - -v16=part of s1 - -v17=part of s2 - -v18=index of unequal -*/ -ENTRY(WCSNCMP_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */ - - /* Check range of n and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - llilf %r1,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r4,%r4,2 /* Convert character-count to byte-count. */ - locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ - - /* Check first character without vector load. */ - lghi %r5,4 /* current_len = 4 bytes. */ - /* Check s1/2[0]. */ - lt %r0,0(%r2) - l %r1,0(%r3) - je .Lend_cmp_one_char - crjne %r0,%r1,.Lend_cmp_one_char - -.Lloop: - vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ - vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ - lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */ - jo .Llt16_1 /* Jump away if vector not fully loaded. */ - lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ - jo .Llt16_2 /* Jump away if vector not fully loaded. */ - aghi %r5,16 /* Both vectors are fully loaded. */ - vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ - clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */ - jno .Lfound - - vlbb %v17,0(%r5,%r3),6 - vlbb %v16,0(%r5,%r2),6 - lcbb %r0,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r1,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezfs %v18,%v16,%v17 - clgrjhe %r5,%r4,.Llastcmp - jno .Lfound - - vlbb %v17,0(%r5,%r3),6 - vlbb %v16,0(%r5,%r2),6 - lcbb %r0,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r1,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezfs %v18,%v16,%v17 - clgrjhe %r5,%r4,.Llastcmp - jno .Lfound - - vlbb %v17,0(%r5,%r3),6 - vlbb %v16,0(%r5,%r2),6 - lcbb %r0,0(%r5,%r2),6 - jo .Llt16_1 - lcbb %r1,0(%r5,%r3),6 - jo .Llt16_2 - aghi %r5,16 - vfenezfs %v18,%v16,%v17 - clgrjhe %r5,%r4,.Llastcmp - jno .Lfound - - j .Lloop - -.Llt16_1: - lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ -.Llt16_2: - clr %r0,%r1 /* Compare logical. */ - locrh %r0,%r1 /* Compute minimum of bytes loaded. */ - nill %r0,65532 /* Align bytes loaded to full characters. */ - jz .Lcmp_one_char /* Jump away if no full char is available. */ -.Llt_cmp: - algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */ - vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ - clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n -> last compare */ - vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ - clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within - loaded bytes; (index < loaded-bytes) */ - j .Lloop - -.Lcmp_one_char: - /* At least one of both strings is not 4-byte aligned - and there is no full character before next block-boundary. - Compare one character to get over the boundary and - proceed with normal loop! */ - vlef %v16,0(%r5,%r2),0 /* Load one character. */ - lghi %r0,4 /* Loaded byte count is 4. */ - vlef %v17,0(%r5,%r3),0 - j .Llt_cmp /* Proceed with comparision. */ - -.Llastcmp: - /* Use comparision result only if located within first n characters. - %r0: loaded byte count in vreg; - %r5: current_len; - %r4: n; - (current_len - n): [0...16[ - First ignored match index: loaded bytes - (current_len-n): ]0...16] - */ - slgr %r5,%r4 /* %r5 = current_len - n. */ - slr %r0,%r5 /* %r0 = first ignored match index. */ - vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ - clrjl %r4,%r0,.Lfound2 /* Jump away if miscompare is within - loaded bytes and below n bytes. */ -.Lend_equal: - lghi %r2,0 - br %r14 - -.Lfound: - /* Difference or end of string. */ - /* vfenezf found an unequal element or zero. - This instruction compares unsigned words, but wchar_t is signed. - Thus we have to compare the found element again. */ - vlgvb %r4,%v18,7 /* Extract not equal byte-index. */ -.Lfound2: - srl %r4,2 /* And convert it to character-index. */ - vlgvf %r0,%v16,0(%r4) /* Load character-values. */ - vlgvf %r1,%v17,0(%r4) -.Lend_cmp_one_char: - cr %r0,%r1 - je .Lend_equal - lghi %r2,1 - lghi %r1,-1 - locgrl %r2,%r1 - br %r14 -END(WCSNCMP_Z13) - -# if ! HAVE_WCSNCMP_IFUNC -strong_alias (WCSNCMP_Z13, wcsncmp) -# endif -#endif diff --git a/sysdeps/s390/wcsncmp.c b/sysdeps/s390/wcsncmp.c deleted file mode 100644 index 101db44..0000000 --- a/sysdeps/s390/wcsncmp.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Multiple versions of wcsncmp. - 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 - . */ - -#include - -#if HAVE_WCSNCMP_IFUNC -# include -# include - -# if HAVE_WCSNCMP_C -extern __typeof (wcsncmp) WCSNCMP_C attribute_hidden; -# endif - -# if HAVE_WCSNCMP_Z13 -extern __typeof (wcsncmp) WCSNCMP_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (wcsncmp, wcsncmp, - (HAVE_WCSNCMP_Z13 && (hwcap & HWCAP_S390_VX)) - ? WCSNCMP_Z13 - : WCSNCMP_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wcsncpy-c.c b/sysdeps/s390/wcsncpy-c.c deleted file mode 100644 index 4d0ddb0..0000000 --- a/sysdeps/s390/wcsncpy-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcsncpy implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSNCPY_C -# if HAVE_WCSNCPY_IFUNC || HAVE_WCSNCPY_Z13 -# define WCSNCPY WCSNCPY_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcsncpy-vx.S b/sysdeps/s390/wcsncpy-vx.S deleted file mode 100644 index 9bcbdbf..0000000 --- a/sysdeps/s390/wcsncpy-vx.S +++ /dev/null @@ -1,228 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcsncpy. - 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 - . */ - -#include -#if HAVE_WCSNCPY_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t *wcsncpy (const wchar_t *dest, const wchar_t *src, size_t n) - Copy at most n characters of string src to dest. - - Register usage: - -r0=dest pointer for return - -r1=tmp, zero byte index - -r2=dest - -r3=src - -r4=n - -r5=current_len - -r6=tmp, loaded bytes - -r7=tmp, border - -v16=part of src - -v17=index of zero - -v18=part of src - -v31=register save area for r6, r7 -*/ -ENTRY(WCSNCPY_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgfi %r4,0 - ber %r14 /* Nothing to do, if n == 0. */ - - vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ - - tmll %r3,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - vlvgp %v31,%r6,%r7 /* Save registers. */ - lgr %r0,%r2 /* Save destination pointer for return. */ - - lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r6,%r6 /* Convert 32bit to 64bit. */ - - lghi %r5,0 /* current_len = 0. */ - - /* Check range of maxlen and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r4,49152 /* Test bit 0 or 1 of n. */ - lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r4,49152 /* Test bit 0 or 1 of n. */ - llilf %r1,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r4,%r4,2 /* Convert character-count to byte-count. */ - locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ - - clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes - -> process remaining. */ - - /* n > loaded-byte-count. */ - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, - copy and return. */ - - /* Align s to 16 byte. */ - risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,15 /* current_len = 15. */ - slr %r5,%r7 /* Compute highest index to 16byte boundary. */ - - /* Zero not found and n > loaded-byte-count. */ - vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ - ahi %r5,1 /* Start loop at next character. */ - - /* Now we are 16byte aligned, so we can load - a full vreg without page fault. */ - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - clgijl %r4,17,.Lremaining_v16 /* If n <=16, process remaining - bytes. */ -.Llt64: - lgr %r7,%r4 - slgfi %r7,16 /* border_len = maxlen - 16. */ - - clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border - then process remaining bytes. */ - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v18 - vfenezfs %v17,%v18,%v18 - je .Lfound_v18 - vl %v16,16(%r5,%r3) - vst %v18,0(%r5,%r2) - aghi %r5,16 - - clgrjhe %r5,%r7,.Lremaining_v16 - vfenezfs %v17,%v16,%v16 - je .Lfound_v16 - vl %v18,16(%r5,%r3) - vst %v16,0(%r5,%r2) - aghi %r5,16 - -.Lremaining_v18: - vlr %v16,%v18 -.Lremaining_v16: - /* v16 contains the remaining bytes [1...16]. - Store remaining bytes and append string-termination. */ - vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ - slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ - aghi %r7,-1 /* vstl needs highest index. */ - la %r2,0(%r5,%r2) /* vstl has no index register. */ - vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ - /* Zero in remaining bytes? -> jump away (zero-index < max-index) - Do not jump away if zero-index == max-index, - but simply copy zero with vstl below. */ - clrjl %r1,%r7,.Lfound_v16_store - vstl %v16,%r7,0(%r2) /* Store remaining bytes without null - termination!. */ -.Lend: - /* Restore saved registers. */ - vlgvg %r6,%v31,0 - vlgvg %r7,%v31,1 - lgr %r2,%r0 /* Load saved dest-ptr. */ - br %r14 - -.Lfound_v16_32: - aghi %r5,32 - j .Lfound_v16 -.Lfound_v18_48: - aghi %r5,32 -.Lfound_v18_16: - aghi %r5,16 -.Lfound_v18: - vlr %v16,%v18 -.Lfound_v16: - /* v16 contains a zero. Store remaining bytes to zero. current_len - has not reached border, thus checking for n is not needed! */ - vlgvb %r1,%v17,7 /* Load byte index of zero. */ - la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ - aghi %r1,3 /* Also copy remaining bytes of zero. */ -.Lfound_v16_store: - vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ - /* Fill remaining bytes with zero - remaining count always > 0. */ - algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ - slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1). */ - la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ - aghi %r4,-2 /* mvc with exrl needs count - 1. - (additional -1, see remaining bytes above) */ - srlg %r6,%r4,8 /* Split into 256 byte blocks. */ - ltgr %r6,%r6 - je .Lzero_lt256 -.Lzero_loop256: - mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ - la %r2,256(%r2) - brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ -.Lzero_lt256: - exrl %r4,.Lmvc_lt256 - j .Lend -.Lmvc_lt256: - mvc 1(1,%r2),0(%r2) - - /* Find zero in 16byte aligned loop. */ -.Lloop64: - vl %v16,0(%r5,%r3) /* Load s. */ - vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound_v16 /* Jump away if zero was found. */ - vl %v18,16(%r5,%r3) /* Load next part of s. */ - vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_16 - vl %v16,32(%r5,%r3) - vst %v18,16(%r5,%r2) - vfenezfs %v17,%v16,%v16 - je .Lfound_v16_32 - vl %v18,48(%r5,%r3) - vst %v16,32(%r5,%r2) - vfenezfs %v17,%v18,%v18 - je .Lfound_v18_48 - vst %v18,48(%r5,%r2) - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r4,.Lloop64 - - vl %v16,0(%r5,%r3) /* Load s. */ - j .Llt64 - -.Lfallback: - 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/wcsncpy.c b/sysdeps/s390/wcsncpy.c deleted file mode 100644 index e011de7..0000000 --- a/sysdeps/s390/wcsncpy.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcsncpy. - 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 - . */ - -#include - -#if HAVE_WCSNCPY_IFUNC -# include -# include - -# if HAVE_WCSNCPY_C -extern __typeof (__wcsncpy) WCSNCPY_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcsnlen-c.c b/sysdeps/s390/wcsnlen-c.c deleted file mode 100644 index 7495a6f..0000000 --- a/sysdeps/s390/wcsnlen-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcsnlen implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSNLEN_C -# if HAVE_WCSNLEN_IFUNC || HAVE_WCSNLEN_Z13 -# define WCSNLEN WCSNLEN_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcsnlen-vx.S b/sysdeps/s390/wcsnlen-vx.S deleted file mode 100644 index 47f4ca8..0000000 --- a/sysdeps/s390/wcsnlen-vx.S +++ /dev/null @@ -1,157 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcsnlen. - 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 - . */ - -#include -#if HAVE_WCSNLEN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t wcsnlen (const wchar_t *s, size_t maxlen) - Returns the number of characters in s or at most maxlen. - - Register usage: - -r1=tmp - -r2=address of string - -r3=maxlen (number of characters to be read) - -r4=tmp - -r5=current_len and return_value - -v16=part of s -*/ -ENTRY(WCSNLEN_Z13) - - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r3,%r3 -# endif /* !defined __s390x__ */ - - clgfi %r3,0 /* if maxlen == 0, return 0. */ - locgre %r2,%r3 - ber %r14 - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r1,%r1 /* Convert 32bit to 64bit. */ - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - /* Check range of maxlen and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r3,49152 /* Test bit 0 or 1 of maxlen. */ - lghi %r4,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r3,49152 /* Test bit 0 or 1 of maxlen. */ - llilf %r4,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r3,%r3,2 /* Convert character-count to byte-count. */ - locgrne %r3,%r4 /* Use max byte-count, if bit 0/1 was one. */ - - vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ - clgr %r1,%r3 - locgrh %r1,%r3 /* loaded_byte_count - = min (loaded_byte_count, maxlen) */ - - vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ - clrjl %r5,%r1,.Lend /* Found zero within loaded bytes -> return. */ - - clgr %r1,%r3 /* If loaded_byte_count == maxlen -> end. */ - locgre %r5,%r3 - je .Lend - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r3,.Lloop64 - - /* Find zero in max 64byte with aligned s. */ -.Llt64: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound /* Jump away if zero was found. */ - aghi %r5,16 - clgrjhe %r5,%r3,.Lfound /* If current_len >= maxlen -> end. */ - vl %v16,0(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound - aghi %r5,16 - clgrjhe %r5,%r3,.Lfound - vl %v16,0(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound - aghi %r5,16 - clgrjhe %r5,%r3,.Lfound - vl %v16,0(%r5,%r2) - vfenezfs %v16,%v16,%v16 - j .Lfound - -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound: - vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */ - algr %r5,%r4 - - clgr %r5,%r3 - locgrh %r5,%r3 /* Return min (current_len, maxlen). */ -.Lend: - srlg %r2,%r5,2 /* Convert byte-count to character-count. */ - br %r14 - - /* Find zero in 16byte aligned loop. */ -.Lloop64: - vl %v16,0(%r5,%r2) /* Load s. */ - vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ - je .Lfound /* Jump away if zero was found. */ - vl %v16,16(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound16 - vl %v16,32(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound32 - vl %v16,48(%r5,%r2) - vfenezfs %v16,%v16,%v16 - je .Lfound48 - - aghi %r5,64 - lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ - aghi %r1,64 - clgrjl %r1,%r3,.Lloop64 - - j .Llt64 - -.Lfallback: - 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/wcsnlen.c b/sysdeps/s390/wcsnlen.c deleted file mode 100644 index b5c8ad9..0000000 --- a/sysdeps/s390/wcsnlen.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcsnlen. - 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 - . */ - -#include - -#if HAVE_WCSNLEN_IFUNC -# include -# include - -# if HAVE_WCSNLEN_C -extern __typeof (__wcsnlen) WCSNLEN_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wcspbrk-c.c b/sysdeps/s390/wcspbrk-c.c deleted file mode 100644 index e79c6a8..0000000 --- a/sysdeps/s390/wcspbrk-c.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Default wcspbrk implementation for S/390. - 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 - . */ - -#include - -#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); -# else -# define libc_hidden_def(name) -# endif -# endif -# endif - -# include -#endif diff --git a/sysdeps/s390/wcspbrk-vx.S b/sysdeps/s390/wcspbrk-vx.S deleted file mode 100644 index 5870c46..0000000 --- a/sysdeps/s390/wcspbrk-vx.S +++ /dev/null @@ -1,325 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcspbrk. - 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 - . */ - -#include -#if HAVE_WCSPBRK_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t *wcspbrk (const wchar_t *s, const wchar_t * accept) - The wcspbrk() function locates the first occurrence in the string s - of any of the characters in the string accept and returns a pointer - to that character or NULL if not found. - - This method checks the length of accept string. If it fits entirely - in one vector register, a fast algorithm is used, which does not need - to check multiple parts of accept-string. Otherwise a slower full - check of accept-string is used. - - register overview: - r3: pointer to start of accept-string - r2: pointer to start of search-string - r0: loaded byte count of vlbb search-string (32bit unsigned) - r4: found byte index (32bit unsigned) - r1: current return len (64bit unsigned) - v16: search-string - v17: accept-string - v18: temp-vreg - - ONLY FOR SLOW: - v19: first accept-string - v20: zero for preparing acc-vector - v21: global mask; 1 indicates a match between - search-string-vreg and any accept-character - v22: current mask; 1 indicates a match between - search-string-vreg and any accept-character in current acc-vreg - v24: one for result-checking of former string-part - v30, v31: for re-/storing registers r6, r8, r9 - r5: current len of accept-string - r6: zero-index in search-string or 16 if no zero - or min(zero-index, loaded byte count) - r8: >0, if former accept-string-part contains a zero, - otherwise =0; - r9: loaded byte count of vlbb accept-string -*/ -ENTRY(WCSPBRK_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - /* - Check if accept-string fits in one vreg: - ---------------------------------------- - */ - vlbb %v17,0(%r3),6 /* Load accept. */ - lcbb %r0,0(%r3),6 - jo .Lcheck_onbb /* Special case if accept lays - on block-boundary. */ - -.Lcheck_notonbb: - lghi %r1,0 /* Zero out current len. */ - vlgvf %r0,%v17,0 /* Get first element. */ - clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */ - - vistrfs %v17,%v17 /* Fill with zeros after first zero. */ - je .Lfast /* Zero found -> accept fits in one vreg. */ - j .Lslow /* No zero -> accept exceeds one vreg */ - - -.Lcheck_onbb: - /* Accept lays on block-boundary. */ - nill %r0,65532 /* Recognize only fully loaded characters. */ - je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */ - vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ - vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ - clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> - accept fits in one vreg; - Fill with zeros and proceed - with FAST. */ -.Lcheck_onbb2: - vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ - j .Lcheck_notonbb /* Check if accept fits in one vreg. */ - - - /* - Search s for accept in one vreg - ------------------------------- - */ -.Lfast: - /* Complete accept-string in v17 and remaining bytes are zero. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any - in v17 or first zero element. */ - vlgvb %r4,%v18,7 /* Load byte index of found element. */ - /* If found index is within loaded bytes, return with found - element index (=equal count). */ - clrjl %r4,%r0,.Lfast_loop_found2 - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r1,16 /* current_len = 16. */ - slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ - -.Lfast_loop: - vl %v16,0(%r1,%r2) /* Load search-string. */ - vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any - in v17 or first zero element. */ - jno .Lfast_loop_found - - vl %v16,16(%r1,%r2) - vfaezfs %v18,%v16,%v17,0 - jno .Lfast_loop_found16 - - vl %v16,32(%r1,%r2) - vfaezfs %v18,%v16,%v17,0 - jno .Lfast_loop_found32 - - vl %v16,48(%r1,%r2) - vfaezfs %v18,%v16,%v17,0 - jno .Lfast_loop_found48 - - aghi %r1,64 - j .Lfast_loop /* Loop if no element was unequal to accept - and not zero. */ - - /* Found equal or zero element. */ -.Lfast_loop_found48: - aghi %r1,16 -.Lfast_loop_found32: - aghi %r1,16 -.Lfast_loop_found16: - aghi %r1,16 -.Lfast_loop_found: - vlgvb %r4,%v18,7 /* Load byte index of found element. */ -.Lfast_loop_found2: - srlg %r5,%r4,2 /* Convert byte-index to character-index. */ - vlgvf %r0,%v16,0(%r5) /* Get found element. */ - clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */ - algfr %r1,%r4 /* Add found index of char to current len. */ - la %r2,0(%r1,%r2) /* And return pointer to first equal char. */ - br %r14 - -.Lfast_end_null: - lghi %r2,0 /* Return null if no character is equal. */ - br %r14 - - - - - /* - Search s for accept in multiple vregs - ------------------------------------- - */ -.Lslow: - /* Save registers. */ - vlvgg %v30,%r6,0 - vlvgp %v31,%r8,%r9 - - /* Accept in v17 without zero */ - vlr %v19,%v17 /* Save first acc-part for a fast reload. */ - vzero %v20 /* Zero for preparing acc-vector. */ - vone %v24 /* One for checking result of former string. */ - - /* Align s to 16 byte. */ - risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and - %r4 = bits 60-63 'and' 15. */ - je .Lslow_loop_str /* If s is aligned, loop aligned. */ - lghi %r0,15 - slr %r0,%r4 /* Compute highest index to load (15-x). */ - vll %v16,%r0,0(%r2) /* Load up to 16byte boundary; - needs highest index, left bytes are 0. */ - ahi %r0,1 /* Work with loaded byte count. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept-string to zero. */ - vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end_null /* If first element is zero - (end of string) -> return null */ - clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ - locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ - j .Lslow_loop_acc - - - /* Process s in 16byte aligned loop. */ -.Lslow_next_str: - /* Check results of former processed str-part. */ - vfeef %v18,%v21,%v24 /* Find first equal match in global mask - (ones in element). */ - vlgvb %r4,%v18,7 /* Get index of first one (=equal) - or 16 if no match. */ - /* Equal-index < min(zero-index, loaded byte count) - -> return pointer to equal element. */ - clrjl %r4,%r6,.Lslow_index_found - /* Zero-index < loaded byte count - -> former str-part was last str-part - -> return null */ - clrjl %r6,%r0,.Lslow_end_null - /* All elements are zero (=no match) -> proceed with next str-part. */ - - vlr %v17,%v19 /* Load first part of accept (no zero). */ - algfr %r1,%r0 /* Add loaded byte count to current len. */ - -.Lslow_loop_str: - vl %v16,0(%r1,%r2) /* Load search-string */ - lghi %r0,16 /* Loaded byte count is 16. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept to zero. */ - vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - clije %r6,0,.Lslow_end_null /* If first element is zero - (end of string) -> return null. */ - -.Lslow_loop_acc: - vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> - Character matches any accepted character in - this accept-string-part) IN=0, RT=1. */ - vlgvf %r4,%v22,0 /* Get result of first element. */ - /* First element is equal to any accepted characters - (all other parts of accept cannot lead to a match before this one) - -> current len is pointing to first element - -> return found */ - clijh %r4,0,.Lslow_end_found - vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ - /* Proceed with next acc until end of acc is reached. */ - - -.Lslow_next_acc: - clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part - -> add index to current len and - end. */ - vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ - aghi %r5,16 /* Increment current len of accept-string. */ - lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ - jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is - on block-boundary. */ -.Lslow_next_acc_notonbb: - vistrfs %v17,%v17 /* Fill with zeros after first zero. */ - jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ - -.Lslow_next_acc_prepare_zero: - /* Zero in accept-part: fill zeros with first-accept-character. */ - vlgvf %r8,%v17,0 /* Load first element of acc-part. */ - clije %r8,0,.Lslow_next_str /* Proceed with next string-part, - If first char in this part of accept - is a zero. */ - /* r8>0 -> zero found in this acc-part. */ - vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ - vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars - by comparing with 0 (v20). */ - vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ - j .Lslow_loop_acc /* Accept part is prepared -> process. */ - -.Lslow_next_acc_onbb: - nill %r9,65532 /* Recognize only fully loaded characters. */ - je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t. */ - vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ - vlgvb %r8,%v18,7 /* Load byte index of zero. */ - clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes - -> Prepare vreg. */ -.Lslow_next_acc_onbb2: - vl %v17,0(%r5,%r3) /* Load over boundary ... */ - lghi %r8,0 /* r8=0 -> no zero in this part of acc, - check for zero is in jump-target. */ - j .Lslow_next_acc_notonbb /* ... and search for zero in - fully loaded vreg again. */ - -.Lslow_end_null: - lghi %r1,0 /* Return null if no character is equal. */ - j .Lslow_end - -.Lslow_loop_found: - vlgvb %r4,%v18,7 /* Load byte index of found element. */ - srlg %r5,%r4,2 /* Convert byte-index to character-index. */ - vlgvf %r0,%v16,0(%r5) /* Get found element. */ - clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */ - -.Lslow_index_found: - algfr %r1,%r4 /* Add found index of char to current len. */ -.Lslow_end_found: - la %r1,0(%r1,%r2) /* And return pointer to first equal char. */ - -.Lslow_end: - /* Restore registers. */ - vlgvg %r6,%v30,0 - vlgvg %r8,%v31,0 - vlgvg %r9,%v31,1 - lgr %r2,%r1 - br %r14 -.Lfallback: - 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/wcspbrk.c b/sysdeps/s390/wcspbrk.c deleted file mode 100644 index 84ab911..0000000 --- a/sysdeps/s390/wcspbrk.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcspbrk. - 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 - . */ - -#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 - -# if HAVE_WCSPBRK_Z13 -extern __typeof (__redirect_wcspbrk) WCSPBRK_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (__redirect_wcspbrk, wcspbrk, - (HAVE_WCSPBRK_Z13 && (hwcap & HWCAP_S390_VX)) - ? WCSPBRK_Z13 - : WCSPBRK_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wcsrchr-c.c b/sysdeps/s390/wcsrchr-c.c deleted file mode 100644 index 65164a8..0000000 --- a/sysdeps/s390/wcsrchr-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wcsrchr implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WCSRCHR_C -# if HAVE_WCSRCHR_IFUNC || HAVE_WCSRCHR_Z13 -# define WCSRCHR WCSRCHR_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wcsrchr-vx.S b/sysdeps/s390/wcsrchr-vx.S deleted file mode 100644 index c7b6585..0000000 --- a/sysdeps/s390/wcsrchr-vx.S +++ /dev/null @@ -1,195 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcsrchr. - 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 - . */ - -#include -#if HAVE_WCSRCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t *wcsrchr (const wchar_t *s, wchar_t c) - Locate the last character c in string. - - Register usage: - -r0=loaded bytes in first part of s. - -r1=pointer to last occurence of c or NULL if not found. - -r2=s - -r3=c - -r4=tmp - -r5=current_len - -v16=part of s - -v17=index of found element - -v18=replicated c - -v19=part of s with last occurence of c. - -v20=permute pattern -*/ -ENTRY(WCSRCHR_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ - vrepf %v18,%v18,0 - - lghi %r1,-1 /* Currently no c found. */ - lghi %r5,0 /* current_len = 0. */ - - vfeezfs %v17,%v16,%v18 /* Find element equal or zero. */ - vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */ - clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */ -.Lalign: - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r5,16 /* current_len = 16. */ - slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ - -.Lloop: - vl %v16,0(%r5,%r2) /* Load s. */ - vfeezfs %v17,%v16,%v18 /* Find element equal with zero search. */ - jno .Lfound /* Found c/zero (cc=0|1|2). */ - vl %v16,16(%r5,%r2) - vfeezfs %v17,%v16,%v18 - jno .Lfound16 - vl %v16,32(%r5,%r2) - vfeezfs %v17,%v16,%v18 - jno .Lfound32 - vl %v16,48(%r5,%r2) - vfeezfs %v17,%v16,%v18 - jno .Lfound48 - - aghi %r5,64 - j .Lloop /* No character and no zero -> loop. */ - -.Lfound48: - la %r5,16(%r5) /* Use la since aghi would clobber cc. */ -.Lfound32: - la %r5,16(%r5) -.Lfound16: - la %r5,16(%r5) -.Lfound: - je .Lzero /* Found zero, but no c before that zero. */ - /* Save this part of s to check for further matches after reaching - the end of the complete string. */ - vlr %v19,%v16 - lgr %r1,%r5 - - jh .Lzero /* Found a zero after the found c. */ - aghi %r5,16 /* Start search of next part of s. */ - j .Lloop - -.Lfound_first_part: - /* This code is only executed if the found c/zero is whithin loaded - bytes. If no c/zero was found (cc==3) the found index = 16, thus - this code is not called. - Resulting condition code of vector find element equal: - cc==0: no c, found zero - cc==1: c found, no zero - cc==2: c found, found zero after c - cc==3: no c, no zero (this case can be ignored). */ - je .Lzero /* Found zero, but no c before that zero. */ - - locgrne %r1,%r5 /* Mark c as found in first part of s. */ - vlr %v19,%v16 - - jl .Lalign /* No zero (e.g. if vr was fully loaded) - -> Align and loop afterwards. */ - - /* Found a zero in vr. If vr was not fully loaded due to block - boundary, the remaining bytes are filled with zero and we can't - rely on zero indication of condition code here! */ - - vfenezf %v17,%v16,%v16 - vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ - clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */ - j .Lalign /* Align and loop afterwards. */ - -.Lend_searched_zero: - vlgvb %r4,%v17,7 /* Load byte index of zero. */ - algr %r5,%r4 - la %r2,0(%r5,%r2) /* Return pointer to zero. */ - br %r14 - -.Lzero: - /* Reached end of string. Check if one c was found before. */ - clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */ - - cgfi %r1,-1 /* No c found -> return NULL. */ - locghie %r2,0 - ber %r14 - - larl %r3,.Lpermute_mask /* Load permute mask. */ - vl %v20,0(%r3) - - /* c was found and is part of v19. */ - vfenezf %v17,%v19,%v19 /* Find zero. */ - vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ - ahi %r4,3 /* Found zero index is first byte, - thus highest byte index is last byte of - wchar_t zero. */ - - clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */ - lochine %r0,16 /* ... if v19 is not the first part of s. */ - ahi %r0,-1 /* Convert byte count to highest index. */ - - clr %r0,%r4 - locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */ - - /* Right-shift of v19 to mask bytes after zero. */ - clije %r4,15,.Lzero_permute /* No shift is needed if highest index - in vr is 15. */ - lhi %r0,15 - slr %r0,%r4 /* Compute byte count for vector shift left. */ - sll %r0,3 /* Convert to bit count. */ - vlvgb %v17,%r0,7 - vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes - specified in bits 1-4 of byte 7 in v17. */ - - /* Reverse bytes in v19. */ -.Lzero_permute: - vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */ - - /* Find c in reversed v19. */ - vfeef %v19,%v19,%v18 /* Find c. */ - la %r2,0(%r1,%r2) - vlgvb %r3,%v19,7 /* Load byte index of c. */ - - /* Compute index in real s and return. */ - slgr %r4,%r3 - lay %r2,-3(%r4,%r2) /* Return pointer to zero. -3 is needed, - because the found byte index is reversed in - vector-register. Thus point to first byte of - wchar_t. */ - br %r14 -.Lpermute_mask: - .byte 0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B - .byte 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03 -.Lfallback: - jg WCSRCHR_C -END(WCSRCHR_Z13) - -# if ! HAVE_WCSRCHR_IFUNC -strong_alias (WCSRCHR_Z13, wcsrchr) -# endif -#endif diff --git a/sysdeps/s390/wcsrchr.c b/sysdeps/s390/wcsrchr.c deleted file mode 100644 index eb70f27..0000000 --- a/sysdeps/s390/wcsrchr.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Multiple versions of wcsrchr. - 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 - . */ - -#include - -#if HAVE_WCSRCHR_IFUNC -# include -# include - -# if HAVE_WCSRCHR_C -extern __typeof (wcsrchr) WCSRCHR_C attribute_hidden; -# endif - -# if HAVE_WCSRCHR_Z13 -extern __typeof (wcsrchr) WCSRCHR_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (wcsrchr, wcsrchr, - (HAVE_WCSRCHR_Z13 && (hwcap & HWCAP_S390_VX)) - ? WCSRCHR_Z13 - : WCSRCHR_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wcsspn-c.c b/sysdeps/s390/wcsspn-c.c deleted file mode 100644 index db3bdb9..0000000 --- a/sysdeps/s390/wcsspn-c.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Default wcsspn implementation for S/390. - 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 - . */ - -#include - -#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); -# else -# define libc_hidden_def(name) -# endif -# endif -# endif - -# include -#endif diff --git a/sysdeps/s390/wcsspn-vx.S b/sysdeps/s390/wcsspn-vx.S deleted file mode 100644 index 61f7d6d..0000000 --- a/sysdeps/s390/wcsspn-vx.S +++ /dev/null @@ -1,280 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wcsspn. - 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 - . */ - -#include -#if HAVE_WCSSPN_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* size_t wcsspn (const wchar_t *s, const wchar_t * accept) - The wcsspn() function calculates the length of the initial segment - of s which consists entirely of characters in accept. - - This method checks the length of accept string. If it fits entirely - in one vector register, a fast algorithm is used, which does not need - to check multiple parts of accept-string. Otherwise a slower full - check of accept-string is used. - - register overview: - r3: pointer to start of accept-string - r2: pointer to start of search-string - r4: loaded byte count of vl search-string - r0: found byte index - r1: current return len of s - v16: search-string - v17: accept-string - v18: temp-vreg - - ONLY FOR SLOW: - v19: first accept-string - v20: zero for preparing acc-vector - v21: global mask; 1 indicates a match between - search-string-vreg and any accept-character - v22: current mask; 1 indicates a match between - search-string-vreg and any accept-character in current acc-vreg - v30, v31: for re-/storing registers r6, r8, r9 - r5: current len of accept-string - r6: zero-index in search-string or 16 if no zero - or min(zero-index, loaded byte count) - r8: >0, if former accept-string-part contains a zero, - otherwise =0; - r9: loaded byte count of vlbb accept-string -*/ -ENTRY(WCSSPN_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - /* - Check if accept-string fits in one vreg: - ---------------------------------------- - */ - vlbb %v17,0(%r3),6 /* Load accept. */ - lcbb %r4,0(%r3),6 - jo .Lcheck_onbb /* Special case if accept lays - on block-boundary. */ -.Lcheck_notonbb: - vistrfs %v17,%v17 /* Fill with zeros after first zero. */ - je .Lfast /* Zero found -> accept fits in one vreg. */ - j .Lslow /* No zero -> accept exceeds one vreg. */ - -.Lcheck_onbb: - /* Accept lays on block-boundary. */ - nill %r4,65532 /* Recognize only fully loaded characters. */ - je .Lcheck_onbb2 /* Reload vr if no full wchar_t. */ - vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ - vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */ - clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count -> - Accept fits in one vreg; - Fill with zeros and proceed - with FAST. */ -.Lcheck_onbb2: - vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ - j .Lcheck_notonbb /* Check if accept fits in one vreg. */ - - - /* - Search s for accept in one vreg - ------------------------------- - */ -.Lfast: - /* Complete accept-string in v17 and remaining bytes are zero. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - - vfaezfs %v16,%v16,%v17,8 /* Find first element in v16 - unequal to any in v17 - or first zero element. */ - - vlgvb %r0,%v16,7 /* Load byte index of found element. */ - /* If found index is within loaded bytes (%r0 < %r1), - return with found element index (=equal count). */ - clr %r0,%r1 - srlg %r0,%r0,2 /* Convert byte-count to character-count. */ - locgrl %r2,%r0 - blr %r14 - - /* Align s to 16 byte. */ - risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - lghi %r1,16 /* current_len = 16. */ - slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ - -.Lfast_loop: - vl %v16,0(%r1,%r2) /* Load search-string. */ - vfaezfs %v16,%v16,%v17,8 /* Find first element in v16 - unequal to any in v17 - or first zero element. */ - jno .Lfast_loop_found - vl %v16,16(%r1,%r2) - vfaezfs %v16,%v16,%v17,8 - jno .Lfast_loop_found16 - vl %v16,32(%r1,%r2) - vfaezfs %v16,%v16,%v17,8 - jno .Lfast_loop_found32 - vl %v16,48(%r1,%r2) - vfaezfs %v16,%v16,%v17,8 - jno .Lfast_loop_found48 - - aghi %r1,64 - j .Lfast_loop /* Loop if no element was unequal to accept - and not zero. */ - - /* Found unequal or zero element. */ -.Lfast_loop_found48: - aghi %r1,16 -.Lfast_loop_found32: - aghi %r1,16 -.Lfast_loop_found16: - aghi %r1,16 -.Lfast_loop_found: - vlgvb %r0,%v16,7 /* Load byte index of found element. */ - algrk %r2,%r1,%r0 /* And add it to current len. */ - srlg %r2,%r2,2 /* Convert byte-count to character-count. */ - br %r14 - - - /* - Search s for accept in multiple vregs - ------------------------------------- - */ -.Lslow: - /* Save registers. */ - vlvgg %v30,%r6,0 - vlvgp %v31,%r8,%r9 - lghi %r1,0 /* Zero out current len. */ - - /* accept in v17 without zero. */ - vlr %v19,%v17 /* Save first acc-part for a fast reload. */ - vzero %v20 /* Zero for preparing acc-vector. */ - - /* Align s to 16 byte. */ - risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and - %r0 = bits 60-63 'and' 15. */ - je .Lslow_loop_str /* If s is aligned, loop aligned */ - lghi %r4,15 - slr %r4,%r0 /* Compute highest index to load (15-x). */ - vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs - highest index, remaining bytes are 0). */ - aghi %r4,1 /* Work with loaded byte count. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept-string to zero. */ - vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 - if there is no zero. */ - clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */ - locrl %r6,%r4 /* Load on cc==1. */ - j .Lslow_loop_acc - - /* Process s in 16byte aligned loop. */ -.Lslow_next_str: - vlr %v17,%v19 /* Load first part of accept (no zero). */ - algfr %r1,%r4 /* Add loaded byte count to current len. */ -.Lslow_loop_str: - vl %v16,0(%r1,%r2) /* Load search-string. */ - lghi %r4,16 /* Loaded byte count is 16. */ - vzero %v21 /* Zero out global mask. */ - lghi %r5,0 /* Set current len of accept-string to zero. */ - vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ - lghi %r8,0 /* There is no zero in first accept-part. */ - vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ - -.Lslow_loop_acc: - vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> - character matches any accepted character in - this accept-string-part) IN=0, RT=1. */ - vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */ - vfenezf %v18,%v21,%v21 /* Find first zero in global-mask. */ - vlgvb %r0,%v18,7 /* Get first found zero-index - (= first mismatch). */ - clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index) - -> Process this string-part - with next acc-part. */ - clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count - -> All loaded bytes are matching - any accept-character - and are not zero. */ - /* All bytes are matching any characters in accept-string - and search-string is fully processed (found-index == zero-index). */ -.Lslow_add_lbc_end: - algrk %r2,%r1,%r0 /* Add matching characters to current len. */ - srlg %r2,%r2,2 /* Convert byte-count to character-count. */ - /* Restore registers. */ - vlgvg %r6,%v30,0 - vlgvg %r8,%v31,0 - vlgvg %r9,%v31,1 - br %r14 - -.Lslow_next_acc: - clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part - -> Add found index to current len - and end. */ - vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ - aghi %r5,16 /* Increment current len of accept-string. */ - lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ - jo .Lslow_next_acc_onbb /* Jump away if accept-string is - on block-boundary. */ -.Lslow_next_acc_notonbb: - vistrfs %v17,%v17 /* Fill with zeros after first zero. */ - jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ - -.Lslow_next_acc_prepare_zero: - /* Zero in accept-part: fill zeros with first-accept-character. */ - vlgvf %r8,%v17,0 /* Load first element of acc-part. */ - clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character - in this part of accept-string. */ - /* r8>0 -> zero found in this acc-part. */ - vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ - vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars - by comparing with 0 (v20). */ - vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ - j .Lslow_loop_acc /* Accept part is prepared -> process. */ - -.Lslow_next_acc_onbb: - nill %r9,65532 /* Recognize only fully loaded characters. */ - je .Lslow_next_acc_onbb2 /* Reload vr, if we loaded no full - wchar_t. */ - vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ - vlgvb %r8,%v18,7 /* Load byte index of zero. */ - clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes - -> Prepare vreg. */ -.Lslow_next_acc_onbb2: - vl %v17,0(%r5,%r3) /* Load over boundary ... */ - lghi %r8,0 /* r8=0 -> no zero in this part of acc, - check for zero is in jump-target. */ - j .Lslow_next_acc_notonbb /* ... and search for zero in - fully loaded vreg again. */ -.Lfallback: - 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/wcsspn.c b/sysdeps/s390/wcsspn.c deleted file mode 100644 index e916b1e..0000000 --- a/sysdeps/s390/wcsspn.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Multiple versions of wcsspn. - 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 - . */ - -#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 - -# if HAVE_WCSSPN_Z13 -extern __typeof (__redirect_wcsspn) WCSSPN_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (__redirect_wcsspn, wcsspn, - (HAVE_WCSSPN_Z13 && (hwcap & HWCAP_S390_VX)) - ? WCSSPN_Z13 - : WCSSPN_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wmemchr-c.c b/sysdeps/s390/wmemchr-c.c deleted file mode 100644 index bb2526e..0000000 --- a/sysdeps/s390/wmemchr-c.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Default wmemchr implementation for S/390. - 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 - . */ - -#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); -# else -# define libc_hidden_def(name) -# endif -# endif -# endif - -# include -#endif diff --git a/sysdeps/s390/wmemchr-vx.S b/sysdeps/s390/wmemchr-vx.S deleted file mode 100644 index 72e9ef5..0000000 --- a/sysdeps/s390/wmemchr-vx.S +++ /dev/null @@ -1,178 +0,0 @@ -/* Vector optimized 32/64 bit S/390 version of wmemchr. - 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 - . */ - -#include -#if HAVE_WMEMCHR_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t *wmemchr (const wchar_t *s, wchar_t c, size_t n) - Scans memory for character c - and returns pointer to first c. - - Register usage: - -r0=tmp - -r1=tmp - -r2=s - -r3=c - -r4=n - -r5=current_len - -v16=part of s - -v17=index of found c - -v18=c replicated -*/ -ENTRY(WMEMCHR_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - clgije %r4,0,.Lnf_end /* If len == 0 then exit. */ - - vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ - lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ - llgfr %r0,%r0 /* Convert 32bit to 64bit. */ - - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - - vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ - vrepf %v18,%v18,0 - lghi %r5,16 /* current_len = 16. */ - - /* Check range of maxlen and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - llilf %r1,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r4,%r4,2 /* Convert character-count to byte-count. */ - locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ - - clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n, - jump to lastcmp. */ - - vfeefs %v17,%v16,%v18 /* Find c. */ - vlgvb %r1,%v17,7 /* Load byte index of c. */ - clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */ - - /* Align s to 16 byte. */ - risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ - slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ - - lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ - aghi %r0,64 - clgrjl %r0,%r4,.Lloop64 -.Llt64: - vl %v16,0(%r5,%r2) - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */ - vfeefs %v17,%v16,%v18 /* Find c. */ - jl .Lfound /* Jump away if c was found. */ - - vl %v16,0(%r5,%r2) - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp - vfeefs %v17,%v16,%v18 - jl .Lfound - - vl %v16,0(%r5,%r2) - aghi %r5,16 - clgrjhe %r5,%r4,.Llastcmp - vfeefs %v17,%v16,%v18 - jl .Lfound - - vl %v16,0(%r5,%r2) - aghi %r5,16 - -.Llastcmp: - /* Use comparision result only if located within first n characters. - %r5: current_len; - %r4: n; - (current_len - n): [0...16[ - first ignored match index = vr-width - (current_len - n) ]0...16] - */ - vfeefs %v17,%v16,%v18 /* Find c. */ - slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */ - lghi %r0,16 /* Register width = 16. */ - vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */ - slr %r0,%r4 /* %r0 = first ignored match index. */ - clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */ - /* c not found within n-bytes. */ -.Lnf_end: - lghi %r2,0 /* Return null. */ - br %r14 - -.Lfound48: - aghi %r5,16 -.Lfound32: - aghi %r5,16 -.Lfound16: - aghi %r5,16 -.Lfound0: - aghi %r5,16 -.Lfound: - vlgvb %r1,%v17,7 /* Load byte index of c. */ -.Lfound2: - slgfi %r5,16 /* current_len -=16 */ - algr %r5,%r1 /* Zero byte index is added to current len. */ - la %r2,0(%r5,%r2) /* Return pointer to c. */ - br %r14 - -.Lloop64: - vl %v16,0(%r5,%r2) - vfeefs %v17,%v16,%v18 /* Find c. */ - jl .Lfound0 /* Jump away if c was found. */ - vl %v16,16(%r5,%r2) - vfeefs %v17,%v16,%v18 - jl .Lfound16 - vl %v16,32(%r5,%r2) - vfeefs %v17,%v16,%v18 - jl .Lfound32 - vl %v16,48(%r5,%r2) - vfeefs %v17,%v16,%v18 - jl .Lfound48 - - aghi %r5,64 - lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ - aghi %r0,64 - clgrjl %r0,%r4,.Lloop64 - - j .Llt64 -.Lfallback: - 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/wmemchr.c b/sysdeps/s390/wmemchr.c deleted file mode 100644 index 0d2fbb2..0000000 --- a/sysdeps/s390/wmemchr.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Multiple versions of wmemchr. - 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 - . */ - -#include - -#if HAVE_WMEMCHR_IFUNC -# define wmemchr __redirect_wmemchr -# define __wmemchr __redirect___wmemchr -# include -# undef wmemchr -# undef __wmemchr -# include - -# if HAVE_WMEMCHR_C -extern __typeof (__redirect___wmemchr) WMEMCHR_C attribute_hidden; -# endif - -# 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/sysdeps/s390/wmemcmp-c.c b/sysdeps/s390/wmemcmp-c.c deleted file mode 100644 index 0c73636..0000000 --- a/sysdeps/s390/wmemcmp-c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Default wmemcmp implementation for S/390. - 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 - . */ - -#include - -#if HAVE_WMEMCMP_C -# if HAVE_WMEMCMP_IFUNC -# define WMEMCMP WMEMCMP_C -# endif - -# include -#endif diff --git a/sysdeps/s390/wmemcmp-vx.S b/sysdeps/s390/wmemcmp-vx.S deleted file mode 100644 index 87ae21b..0000000 --- a/sysdeps/s390/wmemcmp-vx.S +++ /dev/null @@ -1,154 +0,0 @@ -/* Vector Optimized 32/64 bit S/390 version of wmemcmp. - 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 - . */ - -#include -#if HAVE_WMEMCMP_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* int wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n) - Compare at most n characters of two wchar_t-arrays. - - Register usage: - -r0=tmp - -r1=number of blocks - -r2=s1 - -r3=s2 - -r4=n - -r5=current_len - -v16=part of s1 - -v17=part of s2 - -v18=index of unequal -*/ -ENTRY(WMEMCMP_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */ - - /* Check range of maxlen and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - llilf %r1,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r4,%r4,2 /* Convert character-count to byte-count. */ - locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ - - lghi %r5,0 /* current_len = 0. */ - - clgijh %r4,16,.Lgt16 - -.Lremaining: - aghi %r4,-1 /* vstl needs highest index. */ - vll %v16,%r4,0(%r2) - vll %v17,%r4,0(%r3) - vfenef %v18,%v16,%v17 /* Compare not equal. */ - vlgvb %r1,%v18,7 /* Load unequal index or 16 if not found. */ - clrj %r1,%r4,12,.Lfound2 /* r1 <= r4 -> unequal within loaded - bytes. */ - -.Lend_equal: - lghi %r2,0 - br %r14 - -.Lfound: - /* vfenezf found an unequal element or zero. - This instruction compares unsigned words, but wchar_t is signed. - Thus we have to compare the found element again. */ - vlgvb %r1,%v18,7 /* Extract not equal byte-index. */ -.Lfound2: - srl %r1,2 /* And convert it to character-index. */ - vlgvf %r0,%v16,0(%r1) /* Load character-values. */ - vlgvf %r1,%v17,0(%r1) - cr %r0,%r1 - je .Lend_equal - lghi %r2,1 - lghi %r1,-1 - locgrl %r2,%r1 - br %r14 - -.Lgt16: - clgijh %r4,64,.Lpreloop64 - -.Lpreloop16: - srlg %r1,%r4,4 /* Split into 16byte blocks */ -.Lloop16: - vl %v16,0(%r5,%r2) - vl %v17,0(%r5,%r3) - aghi %r5,16 - vfenefs %v18,%v16,%v17 /* Compare not equal. */ - jno .Lfound - brctg %r1,.Lloop16 /* Loop until all blocks are processed. */ - - llgfr %r4,%r4 - nilf %r4,15 /* Get remaining bytes */ - locgre %r2,%r4 - ber %r14 - la %r2,0(%r5,%r2) - la %r3,0(%r5,%r3) - j .Lremaining - -.Lpreloop64: - srlg %r1,%r4,6 /* Split into 64byte blocks */ -.Lloop64: - vl %v16,0(%r5,%r2) - vl %v17,0(%r5,%r3) - vfenefs %v18,%v16,%v17 /* Compare not equal. */ - jno .Lfound - - vl %v16,16(%r5,%r2) - vl %v17,16(%r5,%r3) - vfenefs %v18,%v16,%v17 - jno .Lfound - - vl %v16,32(%r5,%r2) - vl %v17,32(%r5,%r3) - vfenefs %v18,%v16,%v17 - jno .Lfound - - vl %v16,48(%r5,%r2) - vl %v17,48(%r5,%r3) - aghi %r5,64 - vfenefs %v18,%v16,%v17 - jno .Lfound - - brctg %r1,.Lloop64 /* Loop until all blocks are processed. */ - - llgfr %r4,%r4 - nilf %r4,63 /* Get remaining bytes */ - locgre %r2,%r4 - ber %r14 - clgijh %r4,16,.Lpreloop16 - la %r2,0(%r5,%r2) - la %r3,0(%r5,%r3) - j .Lremaining -END(WMEMCMP_Z13) - -# if ! HAVE_WMEMCMP_IFUNC -strong_alias (WMEMCMP_Z13, wmemcmp) -# endif -#endif diff --git a/sysdeps/s390/wmemcmp.c b/sysdeps/s390/wmemcmp.c deleted file mode 100644 index 6c8ca5f..0000000 --- a/sysdeps/s390/wmemcmp.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Multiple versions of wmemcmp. - 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 - . */ - -#include - -#if HAVE_WMEMCMP_IFUNC -# include -# include - -# if HAVE_WMEMCMP_C -extern __typeof (wmemcmp) WMEMCMP_C attribute_hidden; -# endif - -# if HAVE_WMEMCMP_Z13 -extern __typeof (wmemcmp) WMEMCMP_Z13 attribute_hidden; -# endif - -s390_libc_ifunc_expr (wmemcmp, wmemcmp, - (HAVE_WMEMCMP_Z13 && (hwcap & HWCAP_S390_VX)) - ? WMEMCMP_Z13 - : WMEMCMP_DEFAULT - ) -#endif diff --git a/sysdeps/s390/wmemset-c.c b/sysdeps/s390/wmemset-c.c deleted file mode 100644 index 01e6254..0000000 --- a/sysdeps/s390/wmemset-c.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Default wmemset implementation for S/390. - 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 - . */ - -#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); -# else -# define libc_hidden_def(name) -# endif -# endif -# endif - -# include -#endif diff --git a/sysdeps/s390/wmemset-vx.S b/sysdeps/s390/wmemset-vx.S deleted file mode 100644 index 4b6050b..0000000 --- a/sysdeps/s390/wmemset-vx.S +++ /dev/null @@ -1,154 +0,0 @@ -/* Vector Optimized 32/64 bit S/390 version of wmemset. - 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 - . */ - -#include -#if HAVE_WMEMSET_Z13 - -# include "sysdep.h" -# include "asm-syntax.h" - - .text - -/* wchar_t *wmemset(wchar_t *dest, wchar_t wc, size_t n) - Fill an array of wide-characters with a constant wide character - and returns dest. - - Register usage: - -r0=tmp - -r1=tmp - -r2=dest or current-pointer - -r3=wc - -r4=n - -r5=tmp - -v16=replicated wc - -v17,v18,v19=copy of v16 for vstm - -v31=saved dest for return -*/ -ENTRY(WMEMSET_Z13) - .machine "z13" - .machinemode "zarch_nohighgprs" - -# if !defined __s390x__ - llgfr %r4,%r4 -# endif /* !defined __s390x__ */ - - vlvgg %v31,%r2,0 /* Save destination pointer for return. */ - clgije %r4,0,.Lend - - vlvgf %v16,%r3,0 /* Generate vector with wchar_t wc. */ - vrepf %v16,%v16,0 - - /* Check range of maxlen and convert to byte-count. */ -# ifdef __s390x__ - tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - lghi %r5,-4 /* Max byte-count is 18446744073709551612. */ -# else - tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ - llilf %r5,4294967292 /* Max byte-count is 4294967292. */ -# endif /* !__s390x__ */ - sllg %r4,%r4,2 /* Convert character-count to byte-count. */ - locgrne %r4,%r5 /* Use max byte-count, if bit 0/1 was one. */ - - /* Align dest to 16 byte. */ - risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and - %r3 = bits 60-63 'and' 15. */ - je .Lpreloop /* If s is aligned, loop aligned. */ - tmll %r2,3 /* Test if s is 4-byte aligned? */ - jne .Lfallback /* And use common-code variant if not. */ - lghi %r1,16 - slr %r1,%r0 /* Compute byte count to load (16-x). */ - clgr %r1,%r4 - locgrh %r1,%r4 /* min (byte count, n) */ - aghik %r5,%r1,-1 /* vstl needs highest index. */ - vstl %v16,%r5,0(%r2) /* Store remaining bytes. */ - clgrje %r1,%r4,.Lend /* Return if n bytes where set. */ - slgr %r4,%r1 /* Compute remaining byte count. */ - la %r2,0(%r1,%r2) - -.Lpreloop: - /* Now we are 16-byte aligned. */ - clgijl %r4,17,.Lremaining - srlg %r1,%r4,8 /* Split into 256byte blocks */ - clgije %r1,0,.Lpreloop64 - vlr %v17,%v16 - vlr %v18,%v16 - vlr %v19,%v16 - -.Lloop256: - vstm %v16,%v19,0(%r2) - vstm %v16,%v19,64(%r2) - vstm %v16,%v19,128(%r2) - vstm %v16,%v19,192(%r2) - la %r2,256(%r2) - brctg %r1,.Lloop256 /* Loop until all blocks are processed. */ - - llgfr %r4,%r4 - nilf %r4,255 /* Get remaining bytes */ - je .Lend /* Skip store remaining bytes if zero. */ - -.Lpreloop64: - clgijl %r4,17,.Lremaining - clgijl %r4,33,.Lpreloop16 - srlg %r1,%r4,5 /* Split into 32byte blocks */ - -.Lloop32: - vst %v16,0(%r2) - vst %v16,16(%r2) - la %r2,32(%r2) - brctg %r1,.Lloop32 /* Loop until all blocks are processed. */ - - llgfr %r4,%r4 - nilf %r4,31 /* Get remaining bytes */ - je .Lend /* Skip store remaining bytes if zero. */ - -.Lpreloop16: - clgijl %r4,17,.Lremaining - srlg %r1,%r4,4 /* Split into 16byte blocks */ - -.Lloop16: - vst %v16,0(%r2) - la %r2,16(%r2) - brctg %r1,.Lloop16 /* Loop until all blocks are processed. */ - - llgfr %r4,%r4 - nilf %r4,15 /* Get remaining bytes */ - je .Lend /* Skip store remaining bytes if zero. */ - -.Lremaining: - aghi %r4,-1 /* vstl needs highest index. */ - vstl %v16,%r4,0(%r2) - -.Lend: - vlgvg %r2,%v31,0 /* Load saved dest for return value. */ - br %r14 -.Lfallback: - srlg %r4,%r4,2 /* Convert byte-count to character-count. */ - 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/wmemset.c b/sysdeps/s390/wmemset.c deleted file mode 100644 index 6118754..0000000 --- a/sysdeps/s390/wmemset.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Multiple versions of wmemset. - 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 - . */ - -#include - -#if HAVE_WMEMSET_IFUNC -# define wmemset __redirect_wmemset -# define __wmemset __redirect___wmemset -# include -# undef wmemset -# undef __wmemset -# include - -# if HAVE_WMEMSET_C -extern __typeof (__redirect___wmemset) WMEMSET_C attribute_hidden; -# endif - -# 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/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile index a1004e8..3f0c096 100644 --- a/sysdeps/sparc/Makefile +++ b/sysdeps/sparc/Makefile @@ -16,14 +16,5 @@ CPPFLAGS-crti.S += -fPIC CPPFLAGS-crtn.S += -fPIC endif -ifeq ($(subdir),elf) - -# Lazy binding on SPARC rewrites the PLT sequence. See the Solaris -# Linker and Libraries Guide, section SPARC: Procedure Linkage Table. -# -test-xfail-check-wx-segment = * - -endif # $(subdir) == elf - # The assembler on SPARC needs the -fPIC flag even when it's assembler code. ASFLAGS-.os += -fPIC diff --git a/sysdeps/sparc/sparc32/dl-irel.h b/sysdeps/sparc/sparc32/dl-irel.h index cf47cda..ffca368 100644 --- a/sysdeps/sparc/sparc32/dl-irel.h +++ b/sysdeps/sparc/sparc32/dl-irel.h @@ -56,7 +56,7 @@ elf_irela (const Elf32_Rela *reloc) else if (r_type == R_SPARC_NONE) ; else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/sparc/sparc64/dl-irel.h b/sysdeps/sparc/sparc64/dl-irel.h index 446fed1..c5cd305 100644 --- a/sysdeps/sparc/sparc64/dl-irel.h +++ b/sysdeps/sparc/sparc64/dl-irel.h @@ -59,7 +59,7 @@ elf_irela (const Elf64_Rela *reloc) else if (r_type == R_SPARC_NONE) ; else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c index 80f68b6..febea74 100644 --- a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c +++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-generic.c @@ -1,2 +1,2 @@ #define __ceil __ceil_generic -#include +#include diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c index 59822e0..a03a009 100644 --- a/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c +++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c @@ -20,4 +20,4 @@ #define __ceil __ceil_vis3 -#include +#include diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c index c92b600..0f3361a 100644 --- a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c +++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-generic.c @@ -1,2 +1,2 @@ #define __floor __floor_generic -#include +#include diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c index 35564b9..d997416 100644 --- a/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c +++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c @@ -20,4 +20,4 @@ #define __floor __floor_vis3 -#include +#include diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c index c198ebb..00abd2a 100644 --- a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c +++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-generic.c @@ -1,2 +1,2 @@ #define __trunc __trunc_generic -#include +#include diff --git a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c index 766bb22..a89916b 100644 --- a/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c +++ b/sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c @@ -20,4 +20,4 @@ #define __trunc __trunc_vis3 -#include +#include diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c index 3ad8ea8..96df78a 100644 --- a/sysdeps/unix/clock_gettime.c +++ b/sysdeps/unix/clock_gettime.c @@ -17,9 +17,75 @@ . */ #include +#include #include #include -#include +#include +#include + + +#if HP_TIMING_AVAIL +/* Clock frequency of the processor. We make it a 64-bit variable + because some jokers are already playing with processors with more + than 4GHz. */ +static hp_timing_t freq; + + +/* This function is defined in the thread library. */ +extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, + struct timespec *tp) + __attribute__ ((__weak__)); + +static int +hp_timing_gettime (clockid_t clock_id, struct timespec *tp) +{ + hp_timing_t tsc; + + if (__glibc_unlikely (freq == 0)) + { + /* This can only happen if we haven't initialized the `freq' + variable yet. Do this now. We don't have to protect this + code against multiple execution since all of them should + lead to the same result. */ + freq = __get_clockfreq (); + if (__glibc_unlikely (freq == 0)) + /* Something went wrong. */ + return -1; + } + + if (clock_id != CLOCK_PROCESS_CPUTIME_ID + && __pthread_clock_gettime != NULL) + return __pthread_clock_gettime (clock_id, freq, tp); + + /* Get the current counter. */ + HP_TIMING_NOW (tsc); + + /* Compute the offset since the start time of the process. */ + tsc -= GL(dl_cpuclock_offset); + + /* Compute the seconds. */ + tp->tv_sec = tsc / freq; + + /* And the nanoseconds. This computation should be stable until + we get machines with about 16GHz frequency. */ + tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq; + + return 0; +} +#endif + + +static inline int +realtime_gettime (struct timespec *tp) +{ + struct timeval tv; + int retval = __gettimeofday (&tv, NULL); + if (retval == 0) + /* Convert into `timespec'. */ + TIMEVAL_TO_TIMESPEC (&tv, tp); + return retval; +} + /* Get current value of CLOCK and store it in TP. */ int @@ -29,6 +95,11 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp) switch (clock_id) { +#ifdef SYSDEP_GETTIME + SYSDEP_GETTIME; +#endif + +#ifndef HANDLED_REALTIME case CLOCK_REALTIME: { struct timeval tv; @@ -37,20 +108,29 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp) TIMEVAL_TO_TIMESPEC (&tv, tp); } break; +#endif default: - __set_errno (EINVAL); +#ifdef SYSDEP_GETTIME_CPU + SYSDEP_GETTIME_CPU (clock_id, tp); +#endif +#if HP_TIMING_AVAIL + if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) + == CLOCK_THREAD_CPUTIME_ID) + retval = hp_timing_gettime (clock_id, tp); + else +#endif + __set_errno (EINVAL); + break; + +#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME + case CLOCK_PROCESS_CPUTIME_ID: + retval = hp_timing_gettime (clock_id, tp); break; +#endif } return retval; } +weak_alias (__clock_gettime, clock_gettime) libc_hidden_def (__clock_gettime) - -versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17); -/* clock_gettime moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_gettime, __clock_gettime_2); -compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2); -#endif diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c index 6513e2d..97b3d6b 100644 --- a/sysdeps/unix/clock_nanosleep.c +++ b/sysdeps/unix/clock_nanosleep.c @@ -19,8 +19,22 @@ #include #include #include +#include #include -#include + +#if HP_TIMING_AVAIL +# define CPUCLOCK_P(clock) \ + ((clock) == CLOCK_PROCESS_CPUTIME_ID \ + || ((clock) & ((1 << CLOCK_IDFIELD_SIZE) - 1)) == CLOCK_THREAD_CPUTIME_ID) +#else +# define CPUCLOCK_P(clock) 0 +#endif + +#ifndef INVALID_CLOCK_P +# define INVALID_CLOCK_P(cl) \ + ((cl) < CLOCK_REALTIME || (cl) > CLOCK_THREAD_CPUTIME_ID) +#endif + /* This implementation assumes that these is only a `nanosleep' system call. So we have to remap all other activities. */ @@ -37,7 +51,14 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL; /* POSIX specifies EINVAL for this case. */ - if (clock_id < CLOCK_REALTIME || clock_id > CLOCK_THREAD_CPUTIME_ID) +#ifdef SYSDEP_NANOSLEEP + SYSDEP_NANOSLEEP; +#endif + + if (CPUCLOCK_P (clock_id)) + return ENOTSUP; + + if (INVALID_CLOCK_P (clock_id)) return EINVAL; /* If we got an absolute time, remap it. */ @@ -50,7 +71,7 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, assert (sizeof (sec) >= sizeof (now.tv_sec)); /* Get the current time for this clock. */ - if (__clock_gettime (clock_id, &now) != 0) + if (__builtin_expect (__clock_gettime (clock_id, &now), 0) != 0) return errno; /* Compute the difference. */ @@ -69,19 +90,12 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, /* Make sure we are not modifying the struct pointed to by REM. */ rem = NULL; } - else if (flags != 0) + else if (__builtin_expect (flags, 0) != 0) return EINVAL; else if (clock_id != CLOCK_REALTIME) /* Not supported. */ return ENOTSUP; - return __nanosleep (req, rem), 0 ? errno : 0; + return __builtin_expect (__nanosleep (req, rem), 0) ? errno : 0; } - -versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17); -/* clock_nanosleep moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_nanosleep, __clock_nanosleep_2); -compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2); -#endif +weak_alias (__clock_nanosleep, clock_nanosleep) diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c index 123b6f4..38813ed 100644 --- a/sysdeps/unix/clock_settime.c +++ b/sysdeps/unix/clock_settime.c @@ -18,13 +18,62 @@ #include #include #include -#include +#include + + +#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME +/* Clock frequency of the processor. We make it a 64-bit variable + because some jokers are already playing with processors with more + than 4GHz. */ +static hp_timing_t freq; + + +/* This function is defined in the thread library. */ +extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset) + __attribute__ ((__weak__)); + + +static int +hp_timing_settime (clockid_t clock_id, const struct timespec *tp) +{ + hp_timing_t tsc; + hp_timing_t usertime; + + /* First thing is to get the current time. */ + HP_TIMING_NOW (tsc); + + if (__glibc_unlikely (freq == 0)) + { + /* This can only happen if we haven't initialized the `freq' + variable yet. Do this now. We don't have to protect this + code against multiple execution since all of them should lead + to the same result. */ + freq = __get_clockfreq (); + if (__glibc_unlikely (freq == 0)) + /* Something went wrong. */ + return -1; + } + + /* Convert the user-provided time into CPU ticks. */ + usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull; + + /* Determine the offset and use it as the new base value. */ + if (clock_id == CLOCK_PROCESS_CPUTIME_ID + || __pthread_clock_settime == NULL) + GL(dl_cpuclock_offset) = tsc - usertime; + else + __pthread_clock_settime (clock_id, tsc - usertime); + + return 0; +} +#endif + /* Set CLOCK to value TP. */ int __clock_settime (clockid_t clock_id, const struct timespec *tp) { - int retval = -1; + int retval; /* Make sure the time cvalue is OK. */ if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000) @@ -35,27 +84,43 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp) switch (clock_id) { +#define HANDLE_REALTIME \ + do { \ + struct timeval tv; \ + TIMESPEC_TO_TIMEVAL (&tv, tp); \ + \ + retval = __settimeofday (&tv, NULL); \ + } while (0) + +#ifdef SYSDEP_SETTIME + SYSDEP_SETTIME; +#endif + +#ifndef HANDLED_REALTIME case CLOCK_REALTIME: - { - struct timeval tv; - TIMESPEC_TO_TIMEVAL (&tv, tp); - retval = __settimeofday (&tv, NULL); - } + HANDLE_REALTIME; break; +#endif default: - __set_errno (EINVAL); +#ifdef SYSDEP_SETTIME_CPU + SYSDEP_SETTIME_CPU; +#endif +#ifndef HANDLED_CPUTIME +# if HP_TIMING_AVAIL + if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID + || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID) + retval = hp_timing_settime (clock_id, tp); + else +# endif + { + __set_errno (EINVAL); + retval = -1; + } +#endif break; } return retval; } -libc_hidden_def (__clock_settime) - -versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17); -/* clock_settime moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_settime, __clock_settime_2); -compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2); -#endif +weak_alias (__clock_settime, clock_settime) diff --git a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h index 9b63b7f..15859c3 100644 --- a/sysdeps/unix/confstr.h +++ b/sysdeps/unix/confstr.h @@ -1 +1 @@ -#define CS_PATH "/usr/bin" +#define CS_PATH "/bin:/usr/bin" diff --git a/sysdeps/unix/getlogin_r.c b/sysdeps/unix/getlogin_r.c index 180c0bb..444df7e 100644 --- a/sysdeps/unix/getlogin_r.c +++ b/sysdeps/unix/getlogin_r.c @@ -64,8 +64,8 @@ __getlogin_r (char *name, size_t name_len) held so that our search is thread-safe. */ __libc_lock_lock (__libc_utmp_lock); - __libc_setutent (); - result = __libc_getutline_r (&line, &buffer, &ut); + (*__libc_utmp_jump_table->setutent) (); + result = (*__libc_utmp_jump_table->getutline_r) (&line, &buffer, &ut); if (result < 0) { if (errno == ESRCH) @@ -74,7 +74,8 @@ __getlogin_r (char *name, size_t name_len) else result = errno; } - __libc_endutent (); + (*__libc_utmp_jump_table->endutent) (); + __libc_utmp_jump_table = &__libc_utmp_unknown_functions; __libc_lock_unlock (__libc_utmp_lock); if (result == 0) diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index fb4ccd6..f71cc39 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -161,7 +161,6 @@ inhibit-glue = yes ifeq ($(subdir),dirent) sysdep_routines += getdirentries getdirentries64 -tests-internal += tst-readdir64-compat endif ifeq ($(subdir),nis) @@ -174,8 +173,7 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ close_nocancel fcntl_nocancel nanosleep_nocancel \ open_nocancel open64_nocancel \ openat_nocancel openat64_nocancel \ - pause_nocancel read_nocancel pread64_nocancel \ - waitpid_nocancel write_nocancel + pause_nocancel read_nocancel waitpid_nocancel write_nocancel sysdep_headers += bits/fcntl-linux.h diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 95759be..336c13b 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -176,7 +176,6 @@ libc { __syscall_rt_sigqueueinfo; __open_nocancel; __read_nocancel; - __pread64_nocancel; __close_nocancel; __sigtimedwait; # functions used by nscd diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist index 6945b7c..9a9e4ce 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist @@ -45,6 +45,7 @@ GLIBC_2.17 __read F GLIBC_2.17 __res_state F GLIBC_2.17 __send F GLIBC_2.17 __sigaction F +GLIBC_2.17 __vfork F GLIBC_2.17 __wait F GLIBC_2.17 __write F GLIBC_2.17 _pthread_cleanup_pop F @@ -215,6 +216,7 @@ GLIBC_2.17 siglongjmp F GLIBC_2.17 sigwait F GLIBC_2.17 system F GLIBC_2.17 tcdrain F +GLIBC_2.17 vfork F GLIBC_2.17 wait F GLIBC_2.17 waitpid F GLIBC_2.17 write F diff --git a/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c b/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c new file mode 100644 index 0000000..2b277f2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c @@ -0,0 +1,54 @@ +/* vfork ABI-compatibility entry points for libpthread. + Copyright (C) 2014-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 + +/* libpthread used to have its own vfork implementation that differed + from libc's only in having a pointless micro-optimization. There + is no longer any use to having a separate copy in libpthread, but + the historical ABI requires it. For static linking, there is no + need to provide anything here--the libc version will be linked in. + For shared library ABI compatibility, there must be __vfork and + vfork symbols in libpthread.so. */ + +#if HAVE_IFUNC +# include +#elif (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \ + || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)) + +/* Thankfully, on AArch64 we can rely on the compiler generating + a tail call here. */ + +extern void __libc_vfork (void); + +void +vfork_compat (void) +{ + __libc_vfork (); +} + +# if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) +compat_symbol (libpthread, vfork_compat, vfork, GLIBC_2_0); +# endif + +# if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20) +strong_alias (vfork_compat, vfork_compat2) +compat_symbol (libpthread, vfork_compat2, __vfork, GLIBC_2_1_2); +# endif + +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h index 26344cd..402d257 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h @@ -48,6 +48,7 @@ /* 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/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 77f0432..e22b916 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -1863,11 +1863,6 @@ GLIBC_2.2 __xpg_sigpause F GLIBC_2.2 _flushlbf F GLIBC_2.2 _res_hconf D 0x48 GLIBC_2.2 bind_textdomain_codeset F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 dcngettext F GLIBC_2.2 dngettext F GLIBC_2.2 fgetpos F diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist index 2d9b958..b413007 100644 --- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -154,7 +155,7 @@ GLIBC_2.1 sem_wait F GLIBC_2.1.1 sem_close F GLIBC_2.1.1 sem_open F GLIBC_2.1.1 sem_unlink F -GLIBC_2.1.2 __libpthread_version_placeholder F +GLIBC_2.1.2 __vfork F GLIBC_2.11 pthread_sigqueue F GLIBC_2.12 pthread_getname_np F GLIBC_2.12 pthread_mutex_consistent F diff --git a/sysdeps/unix/sysv/linux/alpha/librt.abilist b/sysdeps/unix/sysv/linux/alpha/librt.abilist index 71f86e0..d7a049c 100644 --- a/sysdeps/unix/sysv/linux/alpha/librt.abilist +++ b/sysdeps/unix/sysv/linux/alpha/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/alpha/pt-vfork.S b/sysdeps/unix/sysv/linux/alpha/pt-vfork.S new file mode 100644 index 0000000..7ecaa78 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/pt-vfork.S @@ -0,0 +1,43 @@ +/* vfork ABI-compatibility entry points for libpthread. + Copyright (C) 2014-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 + +/* libpthread used to have its own vfork implementation that differed + from libc's only in having a pointless micro-optimization. There + is no longer any use to having a separate copy in libpthread, but + the historical ABI requires it. For static linking, there is no + need to provide anything here--the libc version will be linked in. + For shared library ABI compatibility, there must be __vfork and + vfork symbols in libpthread.so. */ + +#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \ + || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)) + +#include + +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) +compat_symbol (libpthread, __libc_vfork, vfork, GLIBC_2_0); +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20) +strong_alias (__libc_vfork, __vfork_compat) +compat_symbol (libpthread, __vfork_compat, __vfork, GLIBC_2_1_2); +#endif diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index e748ec2..a231812 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -759,11 +759,6 @@ GLIBC_2.4 clntudp_bufcreate F GLIBC_2.4 clntudp_create F GLIBC_2.4 clntunix_create F GLIBC_2.4 clock F -GLIBC_2.4 clock_getcpuclockid F -GLIBC_2.4 clock_getres F -GLIBC_2.4 clock_gettime F -GLIBC_2.4 clock_nanosleep F -GLIBC_2.4 clock_settime F GLIBC_2.4 clone F GLIBC_2.4 close F GLIBC_2.4 closedir F diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist index ee3d029..af82a4c 100644 --- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist @@ -74,6 +74,7 @@ GLIBC_2.4 __read F GLIBC_2.4 __res_state F GLIBC_2.4 __send F GLIBC_2.4 __sigaction F +GLIBC_2.4 __vfork F GLIBC_2.4 __wait F GLIBC_2.4 __write F GLIBC_2.4 _pthread_cleanup_pop F @@ -238,6 +239,7 @@ GLIBC_2.4 siglongjmp F GLIBC_2.4 sigwait F GLIBC_2.4 system F GLIBC_2.4 tcdrain F +GLIBC_2.4 vfork F GLIBC_2.4 wait F GLIBC_2.4 waitpid F GLIBC_2.4 write F diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist index 3c0647b..cfbbd27 100644 --- a/sysdeps/unix/sysv/linux/arm/librt.abilist +++ b/sysdeps/unix/sysv/linux/arm/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.4 aio_suspend F GLIBC_2.4 aio_suspend64 F GLIBC_2.4 aio_write F GLIBC_2.4 aio_write64 F +GLIBC_2.4 clock_getcpuclockid F +GLIBC_2.4 clock_getres F +GLIBC_2.4 clock_gettime F +GLIBC_2.4 clock_nanosleep F +GLIBC_2.4 clock_settime F GLIBC_2.4 lio_listio F GLIBC_2.4 lio_listio64 F GLIBC_2.4 mq_close F diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h index 76c953c..2694942 100644 --- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h @@ -288,8 +288,7 @@ struct f_owner_ex #ifdef __USE_GNU /* Hint values for F_{GET,SET}_RW_HINT. */ -# define RWH_WRITE_LIFE_NOT_SET 0 -# define RWF_WRITE_LIFE_NOT_SET RWH_WRITE_LIFE_NOT_SET +# define RWF_WRITE_LIFE_NOT_SET 0 # define RWH_WRITE_LIFE_NONE 1 # define RWH_WRITE_LIFE_SHORT 2 # define RWH_WRITE_LIFE_MEDIUM 3 diff --git a/sysdeps/unix/sysv/linux/bits/posix_opt.h b/sysdeps/unix/sysv/linux/bits/posix_opt.h index 3d19b86..2339d4a 100644 --- a/sysdeps/unix/sysv/linux/bits/posix_opt.h +++ b/sysdeps/unix/sysv/linux/bits/posix_opt.h @@ -188,7 +188,4 @@ /* Typed memory objects are not available. */ #define _POSIX_TYPED_MEMORY_OBJECTS -1 -/* Streams are not available. */ -#define _XOPEN_STREAMS -1 - #endif /* bits/posix_opt.h */ diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h index c3fbb21..fa409f0 100644 --- a/sysdeps/unix/sysv/linux/bits/socket.h +++ b/sysdeps/unix/sysv/linux/bits/socket.h @@ -85,8 +85,7 @@ 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_XDP 44 /* XDP sockets. */ -#define PF_MAX 45 /* For now.. */ +#define PF_MAX 44 /* For now.. */ /* Address families. */ #define AF_UNSPEC PF_UNSPEC @@ -136,7 +135,6 @@ 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. @@ -166,7 +164,6 @@ 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/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h deleted file mode 100644 index aaccfdc..0000000 --- a/sysdeps/unix/sysv/linux/bits/statx.h +++ /dev/null @@ -1,39 +0,0 @@ -/* 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. */ - -/* Use "" to work around incorrect macro expansion of the - __has_include argument (GCC PR 80005). */ -#ifdef __has_include -# if __has_include ("linux/stat.h") -# include "linux/stat.h" -# ifdef STATX_TYPE -# define __statx_timestamp_defined 1 -# define __statx_defined 1 -# endif -# endif -#endif - -#include diff --git a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c index 877f4f3..190a479 100644 --- a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c +++ b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c @@ -20,7 +20,6 @@ #include #include #include "kernel-posix-cpu-timers.h" -#include int __clock_getcpuclockid (pid_t pid, clockid_t *clock_id) @@ -46,11 +45,4 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id) else return INTERNAL_SYSCALL_ERRNO (r, err); } - -versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17); -/* clock_getcpuclockid moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_getcpuclockid, __clock_getcpuclockid_2); -compat_symbol (libc, __clock_getcpuclockid_2, clock_getcpuclockid, GLIBC_2_2); -#endif +weak_alias (__clock_getcpuclockid, clock_getcpuclockid) diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c index 1fbb638..5d94f59 100644 --- a/sysdeps/unix/sysv/linux/clock_getres.c +++ b/sysdeps/unix/sysv/linux/clock_getres.c @@ -26,19 +26,26 @@ #endif #include -#include - -/* Get resolution of clock. */ -int -__clock_getres (clockid_t clock_id, struct timespec *res) -{ - return INLINE_VSYSCALL (clock_getres, 2, clock_id, res); -} - -versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17); -/* clock_getres moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_getres, __clock_getres_2); -compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2); -#endif +#define SYSCALL_GETRES \ + retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, res); \ + break + +/* The REALTIME and MONOTONIC clock are definitely supported in the + kernel. */ +#define SYSDEP_GETRES \ + SYSDEP_GETRES_CPUTIME \ + case CLOCK_REALTIME: \ + case CLOCK_MONOTONIC: \ + case CLOCK_MONOTONIC_RAW: \ + case CLOCK_REALTIME_COARSE: \ + case CLOCK_MONOTONIC_COARSE: \ + SYSCALL_GETRES + +/* We handled the REALTIME clock here. */ +#define HANDLED_REALTIME 1 +#define HANDLED_CPUTIME 1 + +#define SYSDEP_GETRES_CPU SYSCALL_GETRES +#define SYSDEP_GETRES_CPUTIME /* Default catches them too. */ + +#include diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index 3f8feb3..d837fa3 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -26,20 +26,22 @@ #endif #include -#include - -/* Get current value of CLOCK and store it in TP. */ -int -__clock_gettime (clockid_t clock_id, struct timespec *tp) -{ - return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); -} -libc_hidden_def (__clock_gettime) - -versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17); -/* clock_gettime moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_gettime, __clock_gettime_2); -compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2); -#endif +/* The REALTIME and MONOTONIC clock are definitely supported in the + kernel. */ +#define SYSDEP_GETTIME \ + SYSDEP_GETTIME_CPUTIME; \ + case CLOCK_REALTIME: \ + case CLOCK_MONOTONIC: \ + retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ + break + +/* We handled the REALTIME clock here. */ +#define HANDLED_REALTIME 1 +#define HANDLED_CPUTIME 1 + +#define SYSDEP_GETTIME_CPU(clock_id, tp) \ + retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ + break +#define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */ + +#include diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c index a90da63..93d5d6e 100644 --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,7 +21,6 @@ #include #include "kernel-posix-cpu-timers.h" -#include /* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -52,11 +51,4 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, return (INTERNAL_SYSCALL_ERROR_P (r, err) ? INTERNAL_SYSCALL_ERRNO (r, err) : 0); } - -versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17); -/* clock_nanosleep moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_nanosleep, __clock_nanosleep_2); -compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2); -#endif +weak_alias (__clock_nanosleep, clock_nanosleep) diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c index 21efc6c..5f3f22f 100644 --- a/sysdeps/unix/sysv/linux/clock_settime.c +++ b/sysdeps/unix/sysv/linux/clock_settime.c @@ -18,29 +18,21 @@ #include #include #include -#include #include "kernel-posix-cpu-timers.h" -/* Set CLOCK to value TP. */ -int -__clock_settime (clockid_t clock_id, const struct timespec *tp) -{ - /* Make sure the time cvalue is OK. */ - if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000) - { - __set_errno (EINVAL); - return -1; - } - - return INLINE_SYSCALL_CALL (clock_settime, clock_id, tp); -} -libc_hidden_def (__clock_settime) - -versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17); -/* clock_settime moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_settime, __clock_settime_2); -compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2); -#endif + +/* The REALTIME clock is definitely supported in the kernel. */ +#define SYSDEP_SETTIME \ + case CLOCK_REALTIME: \ + retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp); \ + break + +/* We handled the REALTIME clock here. */ +#define HANDLED_REALTIME 1 + +#define HANDLED_CPUTIME 1 +#define SYSDEP_SETTIME_CPU \ + retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp) + +#include diff --git a/sysdeps/unix/sysv/linux/copy_file_range.c b/sysdeps/unix/sysv/linux/copy_file_range.c index b88b7c9..7b1a50f 100644 --- a/sysdeps/unix/sysv/linux/copy_file_range.c +++ b/sysdeps/unix/sysv/linux/copy_file_range.c @@ -20,16 +20,27 @@ #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 - return SYSCALL_CANCEL (copy_file_range, infd, pinoff, outfd, poutoff, - length, flags); -#else - __set_errno (ENOSYS); - return -1; + 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); #endif } diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c index bc140b5..3bde0cf 100644 --- a/sysdeps/unix/sysv/linux/getdents64.c +++ b/sysdeps/unix/sysv/linux/getdents64.c @@ -33,80 +33,41 @@ strong_alias (__getdents64, __getdents) # include # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) -# include -# include +# include -static ssize_t -handle_overflow (int fd, __off64_t offset, ssize_t count) +/* kernel definition of as of 3.2. */ +struct compat_linux_dirent { - /* If this is the first entry in the buffer, we can report the - error. */ - if (count == 0) - { - __set_errno (EOVERFLOW); - return -1; - } - - /* Otherwise, seek to the overflowing entry, so that the next call - will report the error, and return the data read so far.. */ - if (__lseek64 (fd, offset, SEEK_SET) != 0) - return -1; - return count; -} + /* Both d_ino and d_off are compat_ulong_t which are defined in all + architectures as 'u32'. */ + uint32_t d_ino; + uint32_t d_off; + unsigned short d_reclen; + char d_name[1]; +}; ssize_t __old_getdents64 (int fd, char *buf, size_t nbytes) { - /* We do not move the individual directory entries. This is only - possible if the target type (struct __old_dirent64) is smaller - than the source type. */ - _Static_assert (offsetof (struct __old_dirent64, d_name) - <= offsetof (struct dirent64, d_name), - "__old_dirent64 is larger than dirent64"); - _Static_assert (__alignof__ (struct __old_dirent64) - <= __alignof__ (struct dirent64), - "alignment of __old_dirent64 is larger than dirent64"); + ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes); - ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); - if (retval > 0) + /* The kernel added the d_type value after the name. Change this now. */ + if (retval != -1) { - char *p = buf; - char *end = buf + retval; - while (p < end) - { - struct dirent64 *source = (struct dirent64 *) p; - - /* Copy out the fixed-size data. */ - __ino_t ino = source->d_ino; - __off64_t offset = source->d_off; - unsigned int reclen = source->d_reclen; - unsigned char type = source->d_type; + union + { + struct compat_linux_dirent k; + struct dirent u; + } *kbuf = (void *) buf; - /* Check for ino_t overflow. */ - if (__glibc_unlikely (ino != source->d_ino)) - return handle_overflow (fd, offset, p - buf); - - /* Convert to the target layout. Use a separate struct and - memcpy to side-step aliasing issues. */ - struct __old_dirent64 result; - result.d_ino = ino; - result.d_off = offset; - result.d_reclen = reclen; - result.d_type = type; - - /* Write the fixed-sized part of the result to the - buffer. */ - size_t result_name_offset = offsetof (struct __old_dirent64, d_name); - memcpy (p, &result, result_name_offset); - - /* Adjust the position of the name if necessary. Copy - everything until the end of the record, including the - terminating NUL byte. */ - if (result_name_offset != offsetof (struct dirent64, d_name)) - memmove (p + result_name_offset, source->d_name, - reclen - offsetof (struct dirent64, d_name)); + while ((char *) kbuf < buf + retval) + { + char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1); + memmove (kbuf->u.d_name, kbuf->k.d_name, + strlen (kbuf->k.d_name) + 1); + kbuf->u.d_type = d_type; - p += reclen; + kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen); } } return retval; diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c index ee0190e..2e20f03 100644 --- a/sysdeps/unix/sysv/linux/gethostid.c +++ b/sysdeps/unix/sysv/linux/gethostid.c @@ -102,12 +102,12 @@ gethostid (void) { int ret = __gethostbyname_r (hostname, &hostbuf, tmpbuf.data, tmpbuf.length, &hp, &herr); - if (ret == 0 && hp != NULL) + if (ret == 0) break; else { /* Enlarge the buffer on ERANGE. */ - if (ret != 0 && herr == NETDB_INTERNAL && errno == ERANGE) + if (herr == NETDB_INTERNAL && errno == ERANGE) { if (!scratch_buffer_grow (&tmpbuf)) return 0; diff --git a/sysdeps/unix/sysv/linux/hppa/Makefile b/sysdeps/unix/sysv/linux/hppa/Makefile index c89ec83..e1637f5 100644 --- a/sysdeps/unix/sysv/linux/hppa/Makefile +++ b/sysdeps/unix/sysv/linux/hppa/Makefile @@ -3,14 +3,9 @@ ifeq ($(subdir),stdlib) gen-as-const-headers += ucontext_i.sym endif -ifeq ($(subdir),elf) # Supporting non-executable stacks on HPPA requires changes to both # the Linux kernel and glibc. The kernel currently needs an executable # stack for syscall restarts and signal returns. +ifeq ($(subdir),elf) test-xfail-check-execstack = yes - -# On hppa, the PLT is executable because it contains an executable -# trampoline used during lazy binding. -test-xfail-check-wx-segment = * - -endif # $(subdir) == elf +endif diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index d34f040..24b11b1 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -615,11 +615,6 @@ GLIBC_2.2 clntudp_bufcreate F GLIBC_2.2 clntudp_create F GLIBC_2.2 clntunix_create F GLIBC_2.2 clock F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 clone F GLIBC_2.2 close F GLIBC_2.2 closedir F diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist index e9b3be6..bcba07f 100644 --- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist @@ -46,6 +46,7 @@ GLIBC_2.2 __read F GLIBC_2.2 __res_state F GLIBC_2.2 __send F GLIBC_2.2 __sigaction F +GLIBC_2.2 __vfork F GLIBC_2.2 __wait F GLIBC_2.2 __write F GLIBC_2.2 _pthread_cleanup_pop F @@ -191,6 +192,7 @@ GLIBC_2.2 siglongjmp F GLIBC_2.2 sigwait F GLIBC_2.2 system F GLIBC_2.2 tcdrain F +GLIBC_2.2 vfork F GLIBC_2.2 wait F GLIBC_2.2 waitpid F GLIBC_2.2 write F diff --git a/sysdeps/unix/sysv/linux/hppa/librt.abilist b/sysdeps/unix/sysv/linux/hppa/librt.abilist index bb03781..595f1b7 100644 --- a/sysdeps/unix/sysv/linux/hppa/librt.abilist +++ b/sysdeps/unix/sysv/linux/hppa/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/hppa/localplt.data b/sysdeps/unix/sysv/linux/hppa/localplt.data index 867413f..5f3475d 100644 --- a/sysdeps/unix/sysv/linux/hppa/localplt.data +++ b/sysdeps/unix/sysv/linux/hppa/localplt.data @@ -10,6 +10,7 @@ libc.so: __sigsetjmp libc.so: _IO_funlockfile libc.so: __errno_location libm.so: matherr +libpthread.so: __errno_location # The main malloc is interposed into the dynamic linker, for # allocations after the initial link (when dlopen is used). ld.so: malloc diff --git a/sysdeps/unix/sysv/linux/hppa/pt-vfork.S b/sysdeps/unix/sysv/linux/hppa/pt-vfork.S new file mode 100644 index 0000000..45f7620 --- /dev/null +++ b/sysdeps/unix/sysv/linux/hppa/pt-vfork.S @@ -0,0 +1,82 @@ +/* Copyright (C) 2005-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 +#define _ERRNO_H 1 +#include +#include + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +.Lthread_start: ASM_LINE_SEP + + /* r26, r25, r24, r23 are free since vfork has no arguments */ +ENTRY(__vfork) + /* We must not create a frame. When the child unwinds to call + exec it will clobber the same frame that the parent + needs to unwind. */ + + /* Save the PIC register. */ +#ifdef PIC + copy %r19, %r25 /* parent */ +#endif + + /* Syscall saves and restores all register states */ + ble 0x100(%sr2,%r0) + ldi __NR_vfork,%r20 + + /* Check for error */ + ldi -4096,%r1 + comclr,>>= %r1,%ret0,%r0 /* Note: unsigned compare. */ + b,n .Lerror + + /* Return, and DO NOT restore rp. The child may have called + functions that updated the frame's rp. This works because + the kernel ensures rp is preserved across the vfork + syscall. */ + bv,n %r0(%rp) + +.Lerror: + /* Now we need a stack to call a function. We are assured + that there is no child now, so it's safe to create + a frame. */ + stw %rp, -20(%sp) + .cfi_offset 2, -20 + stwm %r3, 64(%sp) + .cfi_def_cfa_offset -64 + .cfi_offset 3, 0 + stw %sp, -4(%sp) + + sub %r0,%ret0,%r3 + SYSCALL_ERROR_HANDLER + /* Restore the PIC register (in delay slot) on error */ +#ifdef PIC + copy %r25, %r19 /* parent */ +#else + nop +#endif + /* Write syscall return into errno location */ + stw %r3, 0(%ret0) + ldw -84(%sp), %rp + bv %r0(%rp) + ldwm -64(%sp), %r3 +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) +weak_alias (__vfork, vfork) diff --git a/sysdeps/unix/sysv/linux/i386/get_clockfreq.c b/sysdeps/unix/sysv/linux/i386/get_clockfreq.c new file mode 100644 index 0000000..633f186 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/get_clockfreq.c @@ -0,0 +1,88 @@ +/* Get frequency of the system processor. i386/Linux version. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +hp_timing_t +__get_clockfreq (void) +{ + /* We read the information from the /proc filesystem. It contains at + least one line like + cpu MHz : 497.840237 + or also + cpu MHz : 497.841 + We search for this line and convert the number in an integer. */ + static hp_timing_t result; + int fd; + + /* If this function was called before, we know the result. */ + if (result != 0) + return result; + + fd = __open ("/proc/cpuinfo", O_RDONLY); + if (__glibc_likely (fd != -1)) + { + /* XXX AFAIK the /proc filesystem can generate "files" only up + to a size of 4096 bytes. */ + char buf[4096]; + ssize_t n; + + n = __read (fd, buf, sizeof buf); + if (__builtin_expect (n, 1) > 0) + { + char *mhz = memmem (buf, n, "cpu MHz", 7); + + if (__glibc_likely (mhz != NULL)) + { + char *endp = buf + n; + int seen_decpoint = 0; + int ndigits = 0; + + /* Search for the beginning of the string. */ + while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') + ++mhz; + + while (mhz < endp && *mhz != '\n') + { + if (*mhz >= '0' && *mhz <= '9') + { + result *= 10; + result += *mhz - '0'; + if (seen_decpoint) + ++ndigits; + } + else if (*mhz == '.') + seen_decpoint = 1; + + ++mhz; + } + + /* Compensate for missing digits at the end. */ + while (ndigits++ < 6) + result *= 10; + } + } + + __close (fd); + } + + return result; +} diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 48e838f..9762c81 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -1869,11 +1869,6 @@ GLIBC_2.2 _flushlbf F GLIBC_2.2 _res_hconf D 0x30 GLIBC_2.2 alphasort64 F GLIBC_2.2 bind_textdomain_codeset F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 dcngettext F GLIBC_2.2 dngettext F GLIBC_2.2 fgetpos F diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist index 7199aae..bece86d 100644 --- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -154,7 +155,7 @@ GLIBC_2.1 sem_wait F GLIBC_2.1.1 sem_close F GLIBC_2.1.1 sem_open F GLIBC_2.1.1 sem_unlink F -GLIBC_2.1.2 __libpthread_version_placeholder F +GLIBC_2.1.2 __vfork F GLIBC_2.11 pthread_sigqueue F GLIBC_2.12 pthread_getname_np F GLIBC_2.12 pthread_mutex_consistent F diff --git a/sysdeps/unix/sysv/linux/i386/librt.abilist b/sysdeps/unix/sysv/linux/i386/librt.abilist index bb03781..595f1b7 100644 --- a/sysdeps/unix/sysv/linux/i386/librt.abilist +++ b/sysdeps/unix/sysv/linux/i386/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c b/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c new file mode 100644 index 0000000..f9d683a --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c @@ -0,0 +1,87 @@ +/* Get frequency of the system processor. IA-64/Linux version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + + +hp_timing_t +__get_clockfreq (void) +{ + /* We read the information from the /proc filesystem. It contains at + least one line like + itc MHz : 733.390988 + We search for this line and convert the number in an integer. */ + static hp_timing_t result; + int fd; + + /* If this function was called before, we know the result. */ + if (result != 0) + return result; + + fd = __open ("/proc/cpuinfo", O_RDONLY); + if (__builtin_expect (fd != -1, 1)) + { + /* XXX AFAIK the /proc filesystem can generate "files" only up + to a size of 4096 bytes. */ + char buf[4096]; + ssize_t n; + + n = __read (fd, buf, sizeof buf); + if (__builtin_expect (n, 1) > 0) + { + char *mhz = memmem (buf, n, "itc MHz", 7); + + if (__builtin_expect (mhz != NULL, 1)) + { + char *endp = buf + n; + int seen_decpoint = 0; + int ndigits = 0; + + /* Search for the beginning of the string. */ + while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') + ++mhz; + + while (mhz < endp && *mhz != '\n') + { + if (*mhz >= '0' && *mhz <= '9') + { + result *= 10; + result += *mhz - '0'; + if (seen_decpoint) + ++ndigits; + } + else if (*mhz == '.') + seen_decpoint = 1; + + ++mhz; + } + + /* Compensate for missing digits at the end. */ + while (ndigits++ < 6) + result *= 10; + } + } + + __close (fd); + } + + return result; +} diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index e9fe069..50c94ad 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -627,11 +627,6 @@ GLIBC_2.2 clntudp_bufcreate F GLIBC_2.2 clntudp_create F GLIBC_2.2 clntunix_create F GLIBC_2.2 clock F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 close F GLIBC_2.2 closedir F GLIBC_2.2 closelog F diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist index e8a6564..ccc9449 100644 --- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist @@ -46,6 +46,7 @@ GLIBC_2.2 __read F GLIBC_2.2 __res_state F GLIBC_2.2 __send F GLIBC_2.2 __sigaction F +GLIBC_2.2 __vfork F GLIBC_2.2 __wait F GLIBC_2.2 __write F GLIBC_2.2 _pthread_cleanup_pop F @@ -191,6 +192,7 @@ GLIBC_2.2 siglongjmp F GLIBC_2.2 sigwait F GLIBC_2.2 system F GLIBC_2.2 tcdrain F +GLIBC_2.2 vfork F GLIBC_2.2 wait F GLIBC_2.2 waitpid F GLIBC_2.2 write F diff --git a/sysdeps/unix/sysv/linux/ia64/librt.abilist b/sysdeps/unix/sysv/linux/ia64/librt.abilist index 08384c9..804622a 100644 --- a/sysdeps/unix/sysv/linux/ia64/librt.abilist +++ b/sysdeps/unix/sysv/linux/ia64/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/ia64/pt-vfork.S b/sysdeps/unix/sysv/linux/ia64/pt-vfork.S new file mode 100644 index 0000000..61f3e38 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/pt-vfork.S @@ -0,0 +1,48 @@ +/* vfork ABI-compatibility entry points for libpthread. IA64 version. + Copyright (C) 2014-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 + +/* libpthread used to have its own vfork implementation that differed + from libc's only in having a pointless micro-optimization. There + is no longer any use to having a separate copy in libpthread, but + the historical ABI requires it. For static linking, there is no + need to provide anything here--the libc version will be linked in. + For shared library ABI compatibility, there must be __vfork and + vfork symbols in libpthread.so. */ + +#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \ + || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)) + +LOCAL_LEAF (vfork_compat) + br __libc_vfork + ;; +END (vfork_compat) + +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) +weak_alias (vfork_compat, vfork) +compat_symbol (libpthread, vfork_compat, vfork, GLIBC_2_0); +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20) +strong_alias (vfork_compat, __vfork_compat) +compat_symbol (libpthread, __vfork_compat, __vfork, GLIBC_2_1_2); +#endif diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c index 782fc5e..e3d0898 100644 --- a/sysdeps/unix/sysv/linux/if_index.c +++ b/sysdeps/unix/sysv/linux/if_index.c @@ -38,6 +38,11 @@ __if_nametoindex (const char *ifname) return 0; #else struct ifreq ifr; + int fd = __opensock (); + + if (fd < 0) + return 0; + if (strlen (ifname) >= IFNAMSIZ) { __set_errno (ENODEV); @@ -45,12 +50,6 @@ __if_nametoindex (const char *ifname) } strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - - int fd = __opensock (); - - if (fd < 0) - return 0; - if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0) { int saved_errno = errno; diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 7a74835..5543d92 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -111,6 +111,10 @@ # 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/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 98f07b7..f57be98 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -748,11 +748,6 @@ GLIBC_2.4 clntudp_bufcreate F GLIBC_2.4 clntudp_create F GLIBC_2.4 clntunix_create F GLIBC_2.4 clock F -GLIBC_2.4 clock_getcpuclockid F -GLIBC_2.4 clock_getres F -GLIBC_2.4 clock_gettime F -GLIBC_2.4 clock_nanosleep F -GLIBC_2.4 clock_settime F GLIBC_2.4 clone F GLIBC_2.4 close F GLIBC_2.4 closedir F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist index ee3d029..af82a4c 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist @@ -74,6 +74,7 @@ GLIBC_2.4 __read F GLIBC_2.4 __res_state F GLIBC_2.4 __send F GLIBC_2.4 __sigaction F +GLIBC_2.4 __vfork F GLIBC_2.4 __wait F GLIBC_2.4 __write F GLIBC_2.4 _pthread_cleanup_pop F @@ -238,6 +239,7 @@ GLIBC_2.4 siglongjmp F GLIBC_2.4 sigwait F GLIBC_2.4 system F GLIBC_2.4 tcdrain F +GLIBC_2.4 vfork F GLIBC_2.4 wait F GLIBC_2.4 waitpid F GLIBC_2.4 write F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist index 3c0647b..cfbbd27 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.4 aio_suspend F GLIBC_2.4 aio_suspend64 F GLIBC_2.4 aio_write F GLIBC_2.4 aio_write64 F +GLIBC_2.4 clock_getcpuclockid F +GLIBC_2.4 clock_getres F +GLIBC_2.4 clock_gettime F +GLIBC_2.4 clock_nanosleep F +GLIBC_2.4 clock_settime F GLIBC_2.4 lio_listio F GLIBC_2.4 lio_listio64 F GLIBC_2.4 mq_close F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 6a60d78..ddc7ebc 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -1825,11 +1825,6 @@ GLIBC_2.2 _flushlbf F GLIBC_2.2 _res_hconf D 0x30 GLIBC_2.2 alphasort64 F GLIBC_2.2 bind_textdomain_codeset F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 dcngettext F GLIBC_2.2 dngettext F GLIBC_2.2 fgetpos F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist index 7199aae..bece86d 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -154,7 +155,7 @@ GLIBC_2.1 sem_wait F GLIBC_2.1.1 sem_close F GLIBC_2.1.1 sem_open F GLIBC_2.1.1 sem_unlink F -GLIBC_2.1.2 __libpthread_version_placeholder F +GLIBC_2.1.2 __vfork F GLIBC_2.11 pthread_sigqueue F GLIBC_2.12 pthread_getname_np F GLIBC_2.12 pthread_mutex_consistent F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist index bb03781..595f1b7 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/m68k/pt-vfork.c b/sysdeps/unix/sysv/linux/m68k/pt-vfork.c new file mode 100644 index 0000000..5fbc652 --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/pt-vfork.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h index 1c49f09..e8e2ac6 100644 --- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h @@ -58,6 +58,11 @@ # 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/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist index e0fbe68..5067375 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist @@ -45,6 +45,7 @@ GLIBC_2.18 __read F GLIBC_2.18 __res_state F GLIBC_2.18 __send F GLIBC_2.18 __sigaction F +GLIBC_2.18 __vfork F GLIBC_2.18 __wait F GLIBC_2.18 __write F GLIBC_2.18 _pthread_cleanup_pop F @@ -217,6 +218,7 @@ GLIBC_2.18 siglongjmp F GLIBC_2.18 sigwait F GLIBC_2.18 system F GLIBC_2.18 tcdrain F +GLIBC_2.18 vfork F GLIBC_2.18 wait F GLIBC_2.18 waitpid F GLIBC_2.18 write F diff --git a/sysdeps/unix/sysv/linux/microblaze/librt.abilist b/sysdeps/unix/sysv/linux/microblaze/librt.abilist index 889dfbc..fb85d87 100644 --- a/sysdeps/unix/sysv/linux/microblaze/librt.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/librt.abilist @@ -14,6 +14,11 @@ GLIBC_2.18 aio_suspend F GLIBC_2.18 aio_suspend64 F GLIBC_2.18 aio_write F GLIBC_2.18 aio_write64 F +GLIBC_2.18 clock_getcpuclockid F +GLIBC_2.18 clock_getres F +GLIBC_2.18 clock_gettime F +GLIBC_2.18 clock_nanosleep F +GLIBC_2.18 clock_settime F GLIBC_2.18 lio_listio F GLIBC_2.18 lio_listio64 F GLIBC_2.18 mq_close F diff --git a/sysdeps/unix/sysv/linux/microblaze/pt-vfork.S b/sysdeps/unix/sysv/linux/microblaze/pt-vfork.S new file mode 100644 index 0000000..74bc1cd --- /dev/null +++ b/sysdeps/unix/sysv/linux/microblaze/pt-vfork.S @@ -0,0 +1,49 @@ +/* vfork ABI-compatibility entry points for libpthread. + Copyright (C) 2014-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 + +/* libpthread used to have its own vfork implementation that differed + from libc's only in having a pointless micro-optimization. There + is no longer any use to having a separate copy in libpthread, but + the historical ABI requires it. For static linking, there is no + need to provide anything here--the libc version will be linked in. + For shared library ABI compatibility, there must be __vfork and + vfork symbols in libpthread.so. + + As of GCC 7, microblaze can *not* rely on the compiler to generate + a tail call from this vfork to __libc_vfork. */ + +#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \ + || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)) + +ENTRY (vfork_compat) + bri __libc_vfork@PLT +END (vfork_compat) + +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) +compat_symbol (libpthread, vfork_compat, vfork, GLIBC_2_0) +#endif + +#if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20) +strong_alias (vfork_compat, vfork_compat2) +compat_symbol (libpthread, vfork_compat2, __vfork, GLIBC_2_1_2) +#endif diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 34a2458..dda9797 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -1612,11 +1612,6 @@ GLIBC_2.2 capget F GLIBC_2.2 capset F GLIBC_2.2 cbc_crypt F GLIBC_2.2 clntunix_create F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 creat64 F GLIBC_2.2 dcngettext F GLIBC_2.2 des_setparity F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist index f60b22e..0214496 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -139,6 +140,7 @@ GLIBC_2.2 __pthread_rwlock_unlock F GLIBC_2.2 __pthread_rwlock_wrlock F GLIBC_2.2 __pwrite64 F GLIBC_2.2 __res_state F +GLIBC_2.2 __vfork F GLIBC_2.2 lseek64 F GLIBC_2.2 open64 F GLIBC_2.2 pread F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist b/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist index 1539c1c..84837c8 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.2 aio_suspend F GLIBC_2.2 aio_suspend64 F GLIBC_2.2 aio_write F GLIBC_2.2 aio_write64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 lio_listio F GLIBC_2.2 lio_listio64 F GLIBC_2.2 shm_open F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 176a572..42e930d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -1610,11 +1610,6 @@ GLIBC_2.2 capget F GLIBC_2.2 capset F GLIBC_2.2 cbc_crypt F GLIBC_2.2 clntunix_create F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 creat64 F GLIBC_2.2 dcngettext F GLIBC_2.2 des_setparity F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist index f60b22e..0214496 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -139,6 +140,7 @@ GLIBC_2.2 __pthread_rwlock_unlock F GLIBC_2.2 __pthread_rwlock_wrlock F GLIBC_2.2 __pwrite64 F GLIBC_2.2 __res_state F +GLIBC_2.2 __vfork F GLIBC_2.2 lseek64 F GLIBC_2.2 open64 F GLIBC_2.2 pread F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist b/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist index 1539c1c..84837c8 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.2 aio_suspend F GLIBC_2.2 aio_suspend64 F GLIBC_2.2 aio_write F GLIBC_2.2 aio_write64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 lio_listio F GLIBC_2.2 lio_listio64 F GLIBC_2.2 shm_open F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 5a66ffd..f89b44f 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -1611,11 +1611,6 @@ GLIBC_2.2 capget F GLIBC_2.2 capset F GLIBC_2.2 cbc_crypt F GLIBC_2.2 clntunix_create F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 creat64 F GLIBC_2.2 dcngettext F GLIBC_2.2 des_setparity F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index a817f33..1486af1 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -1607,11 +1607,6 @@ GLIBC_2.2 capget F GLIBC_2.2 capset F GLIBC_2.2 cbc_crypt F GLIBC_2.2 clntunix_create F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 creat64 F GLIBC_2.2 dcngettext F GLIBC_2.2 des_setparity F diff --git a/sysdeps/unix/sysv/linux/mips/pt-vfork.S b/sysdeps/unix/sysv/linux/mips/pt-vfork.S new file mode 100644 index 0000000..65cc382 --- /dev/null +++ b/sysdeps/unix/sysv/linux/mips/pt-vfork.S @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c index 6afc3a1..f31ccb5 100644 --- a/sysdeps/unix/sysv/linux/netlink_assert_response.c +++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c @@ -72,12 +72,12 @@ __netlink_assert_response (int fd, ssize_t result) char message[200]; if (family < 0) __snprintf (message, sizeof (message), - "Unexpected error %d on netlink descriptor %d.\n", + "Unexpected error %d on netlink descriptor %d", error_code, fd); else __snprintf (message, sizeof (message), "Unexpected error %d on netlink descriptor %d" - " (address family %d).\n", + " (address family %d)", error_code, fd, family); __libc_fatal (message); } diff --git a/sysdeps/unix/sysv/linux/nios2/pt-vfork.S b/sysdeps/unix/sysv/linux/nios2/pt-vfork.S new file mode 100644 index 0000000..147427a --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/pt-vfork.S @@ -0,0 +1 @@ +# Nios2 does not require a stub for vfork in libpthread. diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h index e58db47..09de92d 100644 --- a/sysdeps/unix/sysv/linux/not-cancel.h +++ b/sysdeps/unix/sysv/linux/not-cancel.h @@ -43,9 +43,6 @@ __typeof (openat64) __openat64_nocancel; /* Non cancellable read syscall. */ __typeof (__read) __read_nocancel; -/* Non cancellable pread syscall (LFS version). */ -__typeof (__pread64) __pread64_nocancel; - /* Uncancelable write. */ __typeof (__write) __write_nocancel; @@ -87,7 +84,6 @@ hidden_proto (__open64_nocancel) hidden_proto (__openat_nocancel) hidden_proto (__openat64_nocancel) hidden_proto (__read_nocancel) -hidden_proto (__pread64_nocancel) hidden_proto (__write_nocancel) hidden_proto (__close_nocancel) hidden_proto (__waitpid_nocancel) diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c index fc82bd1..906882a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c @@ -127,26 +127,6 @@ 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/force-elision.h b/sysdeps/unix/sysv/linux/powerpc/force-elision.h index d8f5a4b..fe5d6ce 100644 --- a/sysdeps/unix/sysv/linux/powerpc/force-elision.h +++ b/sysdeps/unix/sysv/linux/powerpc/force-elision.h @@ -18,45 +18,9 @@ /* Automatically enable elision for existing user lock kinds. */ #define FORCE_ELISION(m, s) \ - if (__pthread_force_elision) \ + if (__pthread_force_elision \ + && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ { \ - /* See concurrency notes regarding __kind in \ - struct __pthread_mutex_s in \ - sysdeps/nptl/bits/thread-shared-types.h. \ - \ - There are the following cases for the kind of a mutex \ - (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ - PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ - only one of both flags can be set): \ - - both flags are not set: \ - This is the first lock operation for this mutex. Enable \ - elision as it is not enabled so far. \ - Note: It can happen that multiple threads are calling e.g. \ - pthread_mutex_lock at the same time as the first lock \ - operation for this mutex. Then elision is enabled for this \ - mutex by multiple threads. Storing with relaxed MO is enough \ - as all threads will store the same new value for the kind of \ - the mutex. But we have to ensure that we always use the \ - elision path regardless if this thread has enabled elision or \ - another one. \ - \ - - PTHREAD_MUTEX_ELISION_NP flag is set: \ - Elision was already enabled for this mutex by a previous lock \ - operation. See case above. Just use the elision path. \ - \ - - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ - Elision was explicitly disabled by pthread_mutexattr_settype. \ - Do not use the elision path. \ - Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ - changed after mutex initialization. */ \ - int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ - if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ - { \ - mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ - atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ - } \ - if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ - { \ - s; \ - } \ + mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ + s; \ } diff --git a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c new file mode 100644 index 0000000..3a22160 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c @@ -0,0 +1,107 @@ +/* Get frequency of the system processor. powerpc/Linux version. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + +hp_timing_t +__get_clockfreq (void) +{ + hp_timing_t result = 0L; + +#ifdef SHARED + /* The vDSO does not return an error (it clear cr0.so on returning). */ + INTERNAL_SYSCALL_DECL (err); + result = + INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0); +#else + /* We read the information from the /proc filesystem. /proc/cpuinfo + contains at least one line like: + timebase : 33333333 + We search for this line and convert the number into an integer. */ + int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY); + if (__glibc_likely (fd != -1)) + return result; + + /* The timebase will be in the 1st 1024 bytes for systems with up + to 8 processors. If the first read returns less then 1024 + bytes read, we have the whole cpuinfo and can start the scan. + Otherwise we will have to read more to insure we have the + timebase value in the scan. */ + char buf[1024]; + ssize_t n; + + n = __read_nocancel (fd, buf, sizeof (buf)); + if (n == sizeof (buf)) + { + /* We are here because the 1st read returned exactly sizeof + (buf) bytes. This implies that we are not at EOF and may + not have read the timebase value yet. So we need to read + more bytes until we know we have EOF. We copy the lower + half of buf to the upper half and read sizeof (buf)/2 + bytes into the lower half of buf and repeat until we + reach EOF. We can assume that the timebase will be in + the last 512 bytes of cpuinfo, so two 512 byte half_bufs + will be sufficient to contain the timebase and will + handle the case where the timebase spans the half_buf + boundry. */ + const ssize_t half_buf = sizeof (buf) / 2; + while (n >= half_buf) + { + memcpy (buf, buf + half_buf, half_buf); + n = __read_nocancel (fd, buf + half_buf, half_buf); + } + if (n >= 0) + n += half_buf; + } + __close_nocancel (fd); + + if (__glibc_likely (n > 0)) + { + char *mhz = memmem (buf, n, "timebase", 7); + + if (__glibc_likely (mhz != NULL)) + { + char *endp = buf + n; + + /* Search for the beginning of the string. */ + while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') + ++mhz; + + while (mhz < endp && *mhz != '\n') + { + if (*mhz >= '0' && *mhz <= '9') + { + result *= 10; + result += *mhz - '0'; + } + + ++mhz; + } + } + } +#endif + + return result; +} diff --git a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c index 1177ccb..6435e1f 100644 --- a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c +++ b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c @@ -17,90 +17,11 @@ . */ #include -#include - #include -#include -#include uint64_t __get_timebase_freq (void) { - hp_timing_t result = 0L; - -#ifdef SHARED - /* The vDSO does not return an error (it clear cr0.so on returning). */ - INTERNAL_SYSCALL_DECL (err); - result = - INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0); -#else - /* We read the information from the /proc filesystem. /proc/cpuinfo - contains at least one line like: - timebase : 33333333 - We search for this line and convert the number into an integer. */ - int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY); - if (__glibc_likely (fd != -1)) - return result; - - /* The timebase will be in the 1st 1024 bytes for systems with up - to 8 processors. If the first read returns less then 1024 - bytes read, we have the whole cpuinfo and can start the scan. - Otherwise we will have to read more to insure we have the - timebase value in the scan. */ - char buf[1024]; - ssize_t n; - - n = __read_nocancel (fd, buf, sizeof (buf)); - if (n == sizeof (buf)) - { - /* We are here because the 1st read returned exactly sizeof - (buf) bytes. This implies that we are not at EOF and may - not have read the timebase value yet. So we need to read - more bytes until we know we have EOF. We copy the lower - half of buf to the upper half and read sizeof (buf)/2 - bytes into the lower half of buf and repeat until we - reach EOF. We can assume that the timebase will be in - the last 512 bytes of cpuinfo, so two 512 byte half_bufs - will be sufficient to contain the timebase and will - handle the case where the timebase spans the half_buf - boundry. */ - const ssize_t half_buf = sizeof (buf) / 2; - while (n >= half_buf) - { - memcpy (buf, buf + half_buf, half_buf); - n = __read_nocancel (fd, buf + half_buf, half_buf); - } - if (n >= 0) - n += half_buf; - } - __close_nocancel (fd); - - if (__glibc_likely (n > 0)) - { - char *mhz = memmem (buf, n, "timebase", 7); - - if (__glibc_likely (mhz != NULL)) - { - char *endp = buf + n; - - /* Search for the beginning of the string. */ - while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') - ++mhz; - - while (mhz < endp && *mhz != '\n') - { - if (*mhz >= '0' && *mhz <= '9') - { - result *= 10; - result += *mhz - '0'; - } - - ++mhz; - } - } - } -#endif - - return result; + return (uint64_t) __get_clockfreq (); } weak_alias (__get_timebase_freq, __ppc_get_timebase_freq) diff --git a/sysdeps/unix/sysv/linux/powerpc/not-errno.h b/sysdeps/unix/sysv/linux/powerpc/not-errno.h new file mode 100644 index 0000000..27da21b --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/not-errno.h @@ -0,0 +1,30 @@ +/* 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/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index d5e121b..45839ed 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -1830,11 +1830,6 @@ GLIBC_2.2 __xstat64 F GLIBC_2.2 _flushlbf F GLIBC_2.2 _res_hconf D 0x30 GLIBC_2.2 bind_textdomain_codeset F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 dcngettext F GLIBC_2.2 dngettext F GLIBC_2.2 fgetpos F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist index c7d9b78..09e8447 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -154,7 +155,7 @@ GLIBC_2.1 sem_wait F GLIBC_2.1.1 sem_close F GLIBC_2.1.1 sem_open F GLIBC_2.1.1 sem_unlink F -GLIBC_2.1.2 __libpthread_version_placeholder F +GLIBC_2.1.2 __vfork F GLIBC_2.11 pthread_sigqueue F GLIBC_2.12 pthread_getname_np F GLIBC_2.12 pthread_mutex_consistent F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist index bb03781..595f1b7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 3dfddbd..344e5ae 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -1834,11 +1834,6 @@ GLIBC_2.2 __xstat64 F GLIBC_2.2 _flushlbf F GLIBC_2.2 _res_hconf D 0x30 GLIBC_2.2 bind_textdomain_codeset F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 dcngettext F GLIBC_2.2 dngettext F GLIBC_2.2 fgetpos F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index ec5c525..f7277d5 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -109,6 +109,7 @@ 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/arch-pkey.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h deleted file mode 100644 index 25d080c..0000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-pkey.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Helper functions for manipulating memory protection keys, for powerpc64. - Copyright (C) 2017-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _ARCH_PKEY_H -#define _ARCH_PKEY_H - -/* Read and write access bits in the AMR register. Needs to be - translated from and to PKEY_DISABLE_* flags. */ -#define PKEY_AMR_READ 1UL -#define PKEY_AMR_WRITE 2UL - -/* Return the value of the AMR register. */ -static inline unsigned long int -pkey_read (void) -{ - unsigned long int result; - __asm__ volatile ("mfspr %0, 13" : "=r" (result)); - return result; -} - -/* Overwrite the AMR register with VALUE. */ -static inline void -pkey_write (unsigned long int value) -{ - __asm__ volatile ("isync; mtspr 13, %0; isync" : : "r" (value)); -} - -/* Number of the largest supported key. This depends on the width of - the AMR register. */ -#define PKEY_MAX (sizeof (unsigned long int) * 8 / 2 - 1) -_Static_assert (PKEY_MAX == 15 || PKEY_MAX == 31, "PKEY_MAX value"); - -/* Translate key number into AMR index position. */ -static inline int -pkey_index (int key) -{ - return 2 * (PKEY_MAX - key); -} - -#endif /* _ARCH_PKEY_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index 06ce341..8c1781a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist @@ -670,11 +670,6 @@ GLIBC_2.3 clntudp_bufcreate F GLIBC_2.3 clntudp_create F GLIBC_2.3 clntunix_create F GLIBC_2.3 clock F -GLIBC_2.3 clock_getcpuclockid F -GLIBC_2.3 clock_getres F -GLIBC_2.3 clock_gettime F -GLIBC_2.3 clock_nanosleep F -GLIBC_2.3 clock_settime F GLIBC_2.3 clone F GLIBC_2.3 close F GLIBC_2.3 closedir F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist index 6945b7c..9a9e4ce 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist @@ -45,6 +45,7 @@ GLIBC_2.17 __read F GLIBC_2.17 __res_state F GLIBC_2.17 __send F GLIBC_2.17 __sigaction F +GLIBC_2.17 __vfork F GLIBC_2.17 __wait F GLIBC_2.17 __write F GLIBC_2.17 _pthread_cleanup_pop F @@ -215,6 +216,7 @@ GLIBC_2.17 siglongjmp F GLIBC_2.17 sigwait F GLIBC_2.17 system F GLIBC_2.17 tcdrain F +GLIBC_2.17 vfork F GLIBC_2.17 wait F GLIBC_2.17 waitpid F GLIBC_2.17 write F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist index 3500cce..8300958 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist @@ -68,6 +68,7 @@ GLIBC_2.3 __read F GLIBC_2.3 __res_state F GLIBC_2.3 __send F GLIBC_2.3 __sigaction F +GLIBC_2.3 __vfork F GLIBC_2.3 __wait F GLIBC_2.3 __write F GLIBC_2.3 _pthread_cleanup_pop F @@ -213,6 +214,7 @@ GLIBC_2.3 siglongjmp F GLIBC_2.3 sigwait F GLIBC_2.3 system F GLIBC_2.3 tcdrain F +GLIBC_2.3 vfork F GLIBC_2.3 wait F GLIBC_2.3 waitpid F GLIBC_2.3 write F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/librt.abilist index 6a5bd96..e76b7eb 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/librt.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.3 aio_suspend F GLIBC_2.3 aio_suspend64 F GLIBC_2.3 aio_write F GLIBC_2.3 aio_write64 F +GLIBC_2.3 clock_getcpuclockid F +GLIBC_2.3 clock_getres F +GLIBC_2.3 clock_gettime F +GLIBC_2.3 clock_nanosleep F +GLIBC_2.3 clock_settime F GLIBC_2.3 lio_listio F GLIBC_2.3 lio_listio64 F GLIBC_2.3 shm_open F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c deleted file mode 100644 index 856ba06..0000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_get.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Reading the per-thread memory protection key, powerpc64 version. - Copyright (C) 2017-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -int -pkey_get (int key) -{ - if (key < 0 || key > PKEY_MAX) - { - __set_errno (EINVAL); - return -1; - } - unsigned int index = pkey_index (key); - unsigned long int amr = pkey_read (); - unsigned int bits = (amr >> index) & 3; - - /* Translate from AMR values. PKEY_AMR_READ standing alone is not - currently representable. */ - if (bits & PKEY_AMR_READ) - return PKEY_DISABLE_ACCESS; - else if (bits == PKEY_AMR_WRITE) - return PKEY_DISABLE_WRITE; - return 0; -} diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c deleted file mode 100644 index 20b372e..0000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/pkey_set.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Changing the per-thread memory protection key, powerpc64 version. - Copyright (C) 2017-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -int -pkey_set (int key, unsigned int rights) -{ - if (key < 0 || key > PKEY_MAX || rights > 3) - { - __set_errno (EINVAL); - return -1; - } - - /* Translate to AMR bit values. */ - unsigned long int bits; - if (rights & PKEY_DISABLE_ACCESS) - /* The PKEY_DISABLE_WRITE bit does not matter. */ - bits = PKEY_AMR_READ | PKEY_AMR_WRITE; - else if (rights == PKEY_DISABLE_WRITE) - bits = PKEY_AMR_WRITE; - else - bits = 0; - - unsigned int index = pkey_index (key); - unsigned long int mask = 3UL << index; - unsigned long int amr = pkey_read (); - amr = (amr & ~mask) | (bits << index); - pkey_write (amr); - return 0; -} diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index 1f17f7b..0956cf0 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -131,6 +131,7 @@ 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 bbab613..2da9172 100644 --- a/sysdeps/unix/sysv/linux/powerpc/syscall.S +++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S @@ -18,6 +18,7 @@ #include ENTRY (syscall) + ABORT_TRANSACTION mr r0,r3 mr r3,r4 mr r4,r5 diff --git a/sysdeps/unix/sysv/linux/pread64_nocancel.c b/sysdeps/unix/sysv/linux/pread64_nocancel.c deleted file mode 100644 index dab6126..0000000 --- a/sysdeps/unix/sysv/linux/pread64_nocancel.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Linux pread64() syscall implementation -- non-cancellable. - 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 - -#ifndef __NR_pread64 -# define __NR_pread64 __NR_pread -#endif - -ssize_t -__pread64_nocancel (int fd, void *buf, size_t count, off64_t offset) -{ - return INLINE_SYSCALL_CALL (pread64, fd, buf, count, SYSCALL_LL64_PRW (offset)); -} -hidden_def (__pread64_nocancel) diff --git a/sysdeps/unix/sysv/linux/preadv2.c b/sysdeps/unix/sysv/linux/preadv2.c index bb08cbc..c8bf076 100644 --- a/sysdeps/unix/sysv/linux/preadv2.c +++ b/sysdeps/unix/sysv/linux/preadv2.c @@ -32,7 +32,7 @@ preadv2 (int fd, const struct iovec *vector, int count, off_t offset, # ifdef __NR_preadv2 ssize_t result = SYSCALL_CANCEL (preadv2, fd, vector, count, LO_HI_LONG (offset), flags); - if (result >= 0 || errno != ENOSYS) + if (result >= 0) return result; # endif /* Trying to emulate the preadv2 syscall flags is troublesome: diff --git a/sysdeps/unix/sysv/linux/preadv64v2.c b/sysdeps/unix/sysv/linux/preadv64v2.c index b72a047..d7400a0 100644 --- a/sysdeps/unix/sysv/linux/preadv64v2.c +++ b/sysdeps/unix/sysv/linux/preadv64v2.c @@ -30,7 +30,7 @@ preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset, #ifdef __NR_preadv64v2 ssize_t result = SYSCALL_CANCEL (preadv64v2, fd, vector, count, LO_HI_LONG (offset), flags); - if (result >= 0 || errno != ENOSYS) + if (result >= 0) return result; #endif /* Trying to emulate the preadv2 syscall flags is troublesome: diff --git a/sysdeps/unix/sysv/linux/pwritev2.c b/sysdeps/unix/sysv/linux/pwritev2.c index 26333eb..29c2264 100644 --- a/sysdeps/unix/sysv/linux/pwritev2.c +++ b/sysdeps/unix/sysv/linux/pwritev2.c @@ -28,7 +28,7 @@ pwritev2 (int fd, const struct iovec *vector, int count, off_t offset, # ifdef __NR_pwritev2 ssize_t result = SYSCALL_CANCEL (pwritev2, fd, vector, count, LO_HI_LONG (offset), flags); - if (result >= 0 || errno != ENOSYS) + if (result >= 0) return result; # endif /* Trying to emulate the pwritev2 syscall flags is troublesome: diff --git a/sysdeps/unix/sysv/linux/pwritev64v2.c b/sysdeps/unix/sysv/linux/pwritev64v2.c index 17ea905..42da321 100644 --- a/sysdeps/unix/sysv/linux/pwritev64v2.c +++ b/sysdeps/unix/sysv/linux/pwritev64v2.c @@ -30,7 +30,7 @@ pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset, #ifdef __NR_pwritev64v2 ssize_t result = SYSCALL_CANCEL (pwritev64v2, fd, vector, count, LO_HI_LONG (offset), flags); - if (result >= 0 || errno != ENOSYS) + if (result >= 0) return result; #endif /* Trying to emulate the pwritev2 syscall flags is troublesome: diff --git a/sysdeps/unix/sysv/linux/riscv/pt-vfork.S b/sysdeps/unix/sysv/linux/riscv/pt-vfork.S new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/pt-vfork.S @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h index 6b9b595..2564712 100644 --- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h @@ -39,7 +39,3 @@ #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/sysdeps/unix/sysv/linux/s390/bits/utmp.h b/sysdeps/unix/sysv/linux/s390/bits/utmp.h index 82e8d17..b3fa362 100644 --- a/sysdeps/unix/sysv/linux/s390/bits/utmp.h +++ b/sysdeps/unix/sysv/linux/s390/bits/utmp.h @@ -61,8 +61,7 @@ struct utmp pid_t ut_pid; /* Process ID of login process. */ char ut_line[UT_LINESIZE] __attribute_nonstring__; /* Devicename. */ - char ut_id[4] - __attribute_nonstring__; /* Inittab ID. */ + char ut_id[4]; /* Inittab ID. */ char ut_user[UT_NAMESIZE] __attribute_nonstring__; /* Username. */ char ut_host[UT_HOSTSIZE] diff --git a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h index 3818ed3..3d3036c 100644 --- a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h +++ b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h @@ -56,14 +56,10 @@ struct utmpx { short int ut_type; /* Type of login. */ __pid_t ut_pid; /* Process ID of login process. */ - char ut_line[__UT_LINESIZE] - __attribute_nonstring__; /* Devicename. */ - char ut_id[4] - __attribute_nonstring__; /* Inittab ID. */ - char ut_user[__UT_NAMESIZE] - __attribute_nonstring__; /* Username. */ - char ut_host[__UT_HOSTSIZE] - __attribute_nonstring__; /* Hostname for remote login. */ + char ut_line[__UT_LINESIZE]; /* Devicename. */ + char ut_id[4]; /* Inittab ID. */ + char ut_user[__UT_NAMESIZE]; /* Username. */ + char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ struct __exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS. */ diff --git a/sysdeps/unix/sysv/linux/s390/force-elision.h b/sysdeps/unix/sysv/linux/s390/force-elision.h index 71f3236..d8a1b99 100644 --- a/sysdeps/unix/sysv/linux/s390/force-elision.h +++ b/sysdeps/unix/sysv/linux/s390/force-elision.h @@ -18,45 +18,9 @@ /* Automatically enable elision for existing user lock kinds. */ #define FORCE_ELISION(m, s) \ - if (__pthread_force_elision) \ + if (__pthread_force_elision \ + && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ { \ - /* See concurrency notes regarding __kind in \ - struct __pthread_mutex_s in \ - sysdeps/nptl/bits/thread-shared-types.h. \ - \ - There are the following cases for the kind of a mutex \ - (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ - PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ - only one of both flags can be set): \ - - both flags are not set: \ - This is the first lock operation for this mutex. Enable \ - elision as it is not enabled so far. \ - Note: It can happen that multiple threads are calling e.g. \ - pthread_mutex_lock at the same time as the first lock \ - operation for this mutex. Then elision is enabled for this \ - mutex by multiple threads. Storing with relaxed MO is enough \ - as all threads will store the same new value for the kind of \ - the mutex. But we have to ensure that we always use the \ - elision path regardless if this thread has enabled elision or \ - another one. \ - \ - - PTHREAD_MUTEX_ELISION_NP flag is set: \ - Elision was already enabled for this mutex by a previous lock \ - operation. See case above. Just use the elision path. \ - \ - - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ - Elision was explicitly disabled by pthread_mutexattr_settype. \ - Do not use the elision path. \ - Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ - changed after mutex initialization. */ \ - int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ - if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ - { \ - mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ - atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ - } \ - if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ - { \ - s; \ - } \ + mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ + s; \ } diff --git a/sysdeps/unix/sysv/linux/s390/pt-vfork.S b/sysdeps/unix/sysv/linux/s390/pt-vfork.S new file mode 100644 index 0000000..65cc382 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/pt-vfork.S @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 02ff949..3a5ec2a 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -1829,11 +1829,6 @@ GLIBC_2.2 _flushlbf F GLIBC_2.2 _res_hconf D 0x30 GLIBC_2.2 alphasort64 F GLIBC_2.2 bind_textdomain_codeset F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 dcngettext F GLIBC_2.2 dngettext F GLIBC_2.2 fgetpos F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist index f093634..d05468f 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -154,7 +155,7 @@ GLIBC_2.1 sem_wait F GLIBC_2.1.1 sem_close F GLIBC_2.1.1 sem_open F GLIBC_2.1.1 sem_unlink F -GLIBC_2.1.2 __libpthread_version_placeholder F +GLIBC_2.1.2 __vfork F GLIBC_2.11 pthread_sigqueue F GLIBC_2.12 pthread_getname_np F GLIBC_2.12 pthread_mutex_consistent F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist index bb03781..595f1b7 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 96693d4..3b54655 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -632,11 +632,6 @@ GLIBC_2.2 clntudp_bufcreate F GLIBC_2.2 clntudp_create F GLIBC_2.2 clntunix_create F GLIBC_2.2 clock F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 clone F GLIBC_2.2 close F GLIBC_2.2 closedir F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist index 47204f1..e8161aa 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist @@ -48,6 +48,7 @@ GLIBC_2.2 __read F GLIBC_2.2 __res_state F GLIBC_2.2 __send F GLIBC_2.2 __sigaction F +GLIBC_2.2 __vfork F GLIBC_2.2 __wait F GLIBC_2.2 __write F GLIBC_2.2 _pthread_cleanup_pop F @@ -193,6 +194,7 @@ GLIBC_2.2 siglongjmp F GLIBC_2.2 sigwait F GLIBC_2.2 system F GLIBC_2.2 tcdrain F +GLIBC_2.2 vfork F GLIBC_2.2 wait F GLIBC_2.2 waitpid F GLIBC_2.2 write F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist index 5905498..41be3bb 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.2 aio_suspend F GLIBC_2.2 aio_suspend64 F GLIBC_2.2 aio_write F GLIBC_2.2 aio_write64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 lio_listio F GLIBC_2.2 lio_listio64 F GLIBC_2.2 shm_open F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index b126bda..1f4e648 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -618,11 +618,6 @@ GLIBC_2.2 clntudp_bufcreate F GLIBC_2.2 clntudp_create F GLIBC_2.2 clntunix_create F GLIBC_2.2 clock F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 clone F GLIBC_2.2 close F GLIBC_2.2 closedir F diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist index e9b3be6..bcba07f 100644 --- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist @@ -46,6 +46,7 @@ GLIBC_2.2 __read F GLIBC_2.2 __res_state F GLIBC_2.2 __send F GLIBC_2.2 __sigaction F +GLIBC_2.2 __vfork F GLIBC_2.2 __wait F GLIBC_2.2 __write F GLIBC_2.2 _pthread_cleanup_pop F @@ -191,6 +192,7 @@ GLIBC_2.2 siglongjmp F GLIBC_2.2 sigwait F GLIBC_2.2 system F GLIBC_2.2 tcdrain F +GLIBC_2.2 vfork F GLIBC_2.2 wait F GLIBC_2.2 waitpid F GLIBC_2.2 write F diff --git a/sysdeps/unix/sysv/linux/sh/librt.abilist b/sysdeps/unix/sysv/linux/sh/librt.abilist index bb03781..595f1b7 100644 --- a/sysdeps/unix/sysv/linux/sh/librt.abilist +++ b/sysdeps/unix/sysv/linux/sh/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/sh/pt-vfork.S b/sysdeps/unix/sysv/linux/sh/pt-vfork.S new file mode 100644 index 0000000..65cc382 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/pt-vfork.S @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/sparc/pt-vfork.S b/sysdeps/unix/sysv/linux/sparc/pt-vfork.S new file mode 100644 index 0000000..65cc382 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/pt-vfork.S @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 63b78d8..d308ac8 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -1826,11 +1826,6 @@ GLIBC_2.2 __xstat64 F GLIBC_2.2 _flushlbf F GLIBC_2.2 _res_hconf D 0x30 GLIBC_2.2 bind_textdomain_codeset F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 dcngettext F GLIBC_2.2 dngettext F GLIBC_2.2 fgetpos F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist index 2d9b958..b413007 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist @@ -114,6 +114,7 @@ GLIBC_2.0 siglongjmp F GLIBC_2.0 sigwait F GLIBC_2.0 system F GLIBC_2.0 tcdrain F +GLIBC_2.0 vfork F GLIBC_2.0 wait F GLIBC_2.0 waitpid F GLIBC_2.0 write F @@ -154,7 +155,7 @@ GLIBC_2.1 sem_wait F GLIBC_2.1.1 sem_close F GLIBC_2.1.1 sem_open F GLIBC_2.1.1 sem_unlink F -GLIBC_2.1.2 __libpthread_version_placeholder F +GLIBC_2.1.2 __vfork F GLIBC_2.11 pthread_sigqueue F GLIBC_2.12 pthread_getname_np F GLIBC_2.12 pthread_mutex_consistent F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist index 38f0aad..cb874f4 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c b/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c new file mode 100644 index 0000000..6838a77 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c @@ -0,0 +1,250 @@ +/* Get frequency of the system processor. sparc64 version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static hp_timing_t +__get_clockfreq_via_cpuinfo (void) +{ + hp_timing_t result; + int fd; + + result = 0; + + fd = __open ("/proc/cpuinfo", O_RDONLY); + if (fd != -1) + { + char buf[8192]; + ssize_t n; + + n = __read (fd, buf, sizeof buf); + if (n > 0) + { + char *mhz = memmem (buf, n, "Cpu0ClkTck", 7); + + if (mhz != NULL) + { + char *endp = buf + n; + + /* Search for the beginning of the string. */ + while (mhz < endp + && (*mhz < '0' || *mhz > '9') + && (*mhz < 'a' || *mhz > 'f') + && *mhz != '\n') + ++mhz; + + while (mhz < endp && *mhz != '\n') + { + if ((*mhz >= '0' && *mhz <= '9') || + (*mhz >= 'a' && *mhz <= 'f')) + { + result <<= 4; + if (*mhz >= '0' && *mhz <= '9') + result += *mhz - '0'; + else + result += (*mhz - 'a') + 10; + } + ++mhz; + } + } + } + + __close (fd); + } + + return result; +} + +static hp_timing_t +__get_clockfreq_via_proc_openprom (void) +{ + hp_timing_t result; + int obp_fd; + + result = 0; + + obp_fd = __open ("/proc/openprom", O_RDONLY); + if (obp_fd != -1) + { + unsigned long int buf[4096 / sizeof (unsigned long int)]; + struct dirent64 *dirp = (struct dirent64 *) buf; + ssize_t len; + + while ((len = __getdents64 (obp_fd, (char *) dirp, sizeof (buf))) > 0) + { + struct dirent64 *this_dirp = dirp; + + while (len > 0) + { + char node[strlen ("/proc/openprom/") + + _D_ALLOC_NAMLEN (this_dirp) + + strlen ("/clock-frequency")]; + char *prop; + int fd; + + /* Note that + strlen("/clock-frequency") > strlen("/device_type") + */ + __stpcpy (prop = __stpcpy (__stpcpy (node, "/proc/openprom/"), + this_dirp->d_name), + "/device_type"); + fd = __open (node, O_RDONLY); + if (fd != -1) + { + char type_string[128]; + int ret; + + ret = __read (fd, type_string, sizeof (type_string)); + if (ret > 0 && strncmp (type_string, "'cpu'", 5) == 0) + { + int clkfreq_fd; + + __stpcpy (prop, "/clock-frequency"); + clkfreq_fd = __open (node, O_RDONLY); + if (clkfreq_fd != -1) + { + if (__read (clkfreq_fd, type_string, + sizeof (type_string)) > 0) + result = (hp_timing_t) + strtoumax (type_string, NULL, 16); + __close (clkfreq_fd); + } + } + __close (fd); + } + + if (result != 0) + break; + + len -= this_dirp->d_reclen; + this_dirp = (struct dirent64 *) + ((char *) this_dirp + this_dirp->d_reclen); + } + if (result != 0) + break; + } + __close (obp_fd); + } + + return result; +} + +static void set_obp_int (struct openpromio *op, int val) +{ + char *cp = op->oprom_array; + int *ip = (int *) cp; + + *ip = val; +} + +static int get_obp_int (struct openpromio *op) +{ + char *cp = op->oprom_array; + int *ip = (int *) cp; + + return *ip; +} + +static hp_timing_t +__get_clockfreq_via_dev_openprom (void) +{ + hp_timing_t result; + int obp_dev_fd; + + result = 0; + + obp_dev_fd = __open ("/dev/openprom", O_RDONLY); + if (obp_dev_fd != -1) + { + char obp_buf[8192]; + struct openpromio *obp_cmd = (struct openpromio *)obp_buf; + int ret; + + obp_cmd->oprom_size = + sizeof (obp_buf) - sizeof (unsigned int); + set_obp_int (obp_cmd, 0); + ret = __ioctl (obp_dev_fd, OPROMCHILD, (char *) obp_cmd); + if (ret == 0) + { + int cur_node = get_obp_int (obp_cmd); + + while (cur_node != 0 && cur_node != -1) + { + obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int); + strcpy (obp_cmd->oprom_array, "device_type"); + ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd); + if (ret == 0 + && strncmp (obp_cmd->oprom_array, "cpu", 3) == 0) + { + obp_cmd->oprom_size = (sizeof (obp_buf) + - sizeof (unsigned int)); + strcpy (obp_cmd->oprom_array, "clock-frequency"); + ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd); + if (ret == 0) + result = (hp_timing_t) get_obp_int (obp_cmd); + } + obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int); + set_obp_int (obp_cmd, cur_node); + ret = __ioctl (obp_dev_fd, OPROMNEXT, (char *) obp_cmd); + if (ret < 0) + break; + cur_node = get_obp_int (obp_cmd); + } + } + } + + return result; +} + +hp_timing_t +__get_clockfreq (void) +{ + static hp_timing_t result; + + /* If this function was called before, we know the result. */ + if (result != 0) + return result; + + /* We first read the information from the /proc/cpuinfo file. + It contains at least one line like + Cpu0ClkTick : 000000002cb41780 + We search for this line and convert the number in an integer. */ + result = __get_clockfreq_via_cpuinfo (); + if (result != 0) + return result; + + /* If that did not work, try to find an OpenPROM node + with device_type equal to 'cpu' using /dev/openprom + and fetch the clock-frequency property from there. */ + result = __get_clockfreq_via_dev_openprom (); + if (result != 0) + return result; + + /* Finally, try the same lookup as above but using /proc/openprom. */ + result = __get_clockfreq_via_proc_openprom (); + + return result; +} diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index a899eb6..6731ebf 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -660,11 +660,6 @@ GLIBC_2.2 clntudp_bufcreate F GLIBC_2.2 clntudp_create F GLIBC_2.2 clntunix_create F GLIBC_2.2 clock F -GLIBC_2.2 clock_getcpuclockid F -GLIBC_2.2 clock_getres F -GLIBC_2.2 clock_gettime F -GLIBC_2.2 clock_nanosleep F -GLIBC_2.2 clock_settime F GLIBC_2.2 clone F GLIBC_2.2 close F GLIBC_2.2 closedir F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist index e8a6564..ccc9449 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist @@ -46,6 +46,7 @@ GLIBC_2.2 __read F GLIBC_2.2 __res_state F GLIBC_2.2 __send F GLIBC_2.2 __sigaction F +GLIBC_2.2 __vfork F GLIBC_2.2 __wait F GLIBC_2.2 __write F GLIBC_2.2 _pthread_cleanup_pop F @@ -191,6 +192,7 @@ GLIBC_2.2 siglongjmp F GLIBC_2.2 sigwait F GLIBC_2.2 system F GLIBC_2.2 tcdrain F +GLIBC_2.2 vfork F GLIBC_2.2 wait F GLIBC_2.2 waitpid F GLIBC_2.2 write F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist index 71f86e0..d7a049c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist @@ -15,6 +15,11 @@ GLIBC_2.1 aio_write F GLIBC_2.1 aio_write64 F GLIBC_2.1 lio_listio F GLIBC_2.1 lio_listio64 F +GLIBC_2.2 clock_getcpuclockid F +GLIBC_2.2 clock_getres F +GLIBC_2.2 clock_gettime F +GLIBC_2.2 clock_nanosleep F +GLIBC_2.2 clock_settime F GLIBC_2.2 shm_open F GLIBC_2.2 shm_unlink F GLIBC_2.2 timer_create F diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c index 85239ce..cf0213e 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -101,7 +101,7 @@ maybe_script_execute (struct posix_spawn_args *args) ptrdiff_t argc = args->argc; /* Construct an argument list for the shell. */ - char *new_argv[argc + 2]; + char *new_argv[argc + 1]; new_argv[0] = (char *) _PATH_BSHELL; new_argv[1] = (char *) args->file; if (argc > 1) diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list index 9105ce4..5306d53 100644 --- a/sysdeps/unix/sysv/linux/syscall-names.list +++ b/sysdeps/unix/sysv/linux/syscall-names.list @@ -16,13 +16,14 @@ # License along with the GNU C Library; if not, see # . -# This file contains the list of system call names. It has to remain in -# alphabetical order. Lines which start with # are treated as comments. -# This file can list all potential system calls. The names are only -# used if the installed kernel headers also provide them. +# This file contains the list of system call names names. It has to +# remain in alphabetica order. Lines which start with # are treated +# as comments. This file can list all potential system calls. The +# names are only used if the installed kernel headers also provide +# them. -# The list of system calls is current as of Linux 5.6. -kernel 5.6 +# The list of system calls is current as of Linux 4.17. +kernel 4.17 FAST_atomic_update FAST_cmpxchg @@ -51,7 +52,6 @@ bdflush bind bpf break -breakpoint brk cachectl cacheflush @@ -63,18 +63,12 @@ chown chown32 chroot clock_adjtime -clock_adjtime64 clock_getres -clock_getres_time64 clock_gettime -clock_gettime64 clock_nanosleep -clock_nanosleep_time64 clock_settime -clock_settime64 clone clone2 -clone3 close cmpxchg_badaddr connect @@ -121,14 +115,9 @@ finit_module flistxattr flock fork -fp_udfiex_crtl free_hugepages fremovexattr -fsconfig fsetxattr -fsmount -fsopen -fspick fstat fstat64 fstatat64 @@ -139,13 +128,11 @@ ftime ftruncate ftruncate64 futex -futex_time64 futimesat get_kernel_syms get_mempolicy get_robust_list get_thread_area -get_tls getcpu getcwd getdents @@ -199,13 +186,8 @@ inotify_rm_watch io_cancel io_destroy io_getevents -io_pgetevents -io_pgetevents_time64 io_setup io_submit -io_uring_enter -io_uring_register -io_uring_setup ioctl ioperm iopl @@ -252,7 +234,6 @@ mmap mmap2 modify_ldt mount -move_mount move_pages mprotect mpx @@ -260,9 +241,7 @@ mq_getsetattr mq_notify mq_open mq_timedreceive -mq_timedreceive_time64 mq_timedsend -mq_timedsend_time64 mq_unlink mremap msgctl @@ -281,7 +260,6 @@ nfsservctl ni_syscall nice old_adjtimex -old_getpagesize oldfstat oldlstat oldolduname @@ -290,9 +268,7 @@ oldumount olduname open open_by_handle_at -open_tree openat -openat2 osf_adjtime osf_afs_syscall osf_alt_plock @@ -411,9 +387,6 @@ perf_event_open perfctr perfmonctl personality -pidfd_getfd -pidfd_open -pidfd_send_signal pipe pipe2 pivot_root @@ -422,7 +395,6 @@ pkey_free pkey_mprotect poll ppoll -ppoll_time64 prctl pread64 preadv @@ -433,7 +405,6 @@ process_vm_writev prof profil pselect6 -pselect6_time64 ptrace putpmsg pwrite64 @@ -451,7 +422,6 @@ reboot recv recvfrom recvmmsg -recvmmsg_time64 recvmsg remap_file_pages removexattr @@ -460,9 +430,7 @@ renameat renameat2 request_key restart_syscall -riscv_flush_icache rmdir -rseq rt_sigaction rt_sigpending rt_sigprocmask @@ -470,7 +438,6 @@ rt_sigqueueinfo rt_sigreturn rt_sigsuspend rt_sigtimedwait -rt_sigtimedwait_time64 rt_tgsigqueueinfo rtas s390_guarded_storage @@ -486,7 +453,6 @@ sched_getattr sched_getparam sched_getscheduler sched_rr_get_interval -sched_rr_get_interval_time64 sched_set_affinity sched_setaffinity sched_setattr @@ -500,7 +466,6 @@ semctl semget semop semtimedop -semtimedop_time64 send sendfile sendfile64 @@ -511,7 +476,6 @@ set_mempolicy set_robust_list set_thread_area set_tid_address -set_tls setdomainname setfsgid setfsgid32 @@ -599,21 +563,16 @@ timer_create timer_delete timer_getoverrun timer_gettime -timer_gettime64 timer_settime -timer_settime64 timerfd timerfd_create timerfd_gettime -timerfd_gettime64 timerfd_settime -timerfd_settime64 times tkill truncate truncate64 tuxcall -udftrap ugetrlimit ulimit umask @@ -625,12 +584,9 @@ unlinkat unshare uselib userfaultfd -usr26 -usr32 ustat utime utimensat -utimensat_time64 utimes utrap_install vfork diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c index a06c2ff..a916e70 100644 --- a/sysdeps/unix/sysv/linux/tcsetattr.c +++ b/sysdeps/unix/sysv/linux/tcsetattr.c @@ -45,7 +45,6 @@ __tcsetattr (int fd, int optional_actions, const struct termios *termios_p) { struct __kernel_termios k_termios; unsigned long int cmd; - int retval; switch (optional_actions) { @@ -76,36 +75,7 @@ __tcsetattr (int fd, int optional_actions, const struct termios *termios_p) memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], __KERNEL_NCCS * sizeof (cc_t)); - retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); - - if (retval == 0 && cmd == TCSETS) - { - /* The Linux kernel has a bug which silently ignore the invalid - c_cflag on pty. We have to check it here. */ - int save = errno; - retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios); - if (retval) - { - /* We cannot verify if the setting is ok. We don't return - an error (?). */ - __set_errno (save); - retval = 0; - } - else if ((termios_p->c_cflag & (PARENB | CREAD)) - != (k_termios.c_cflag & (PARENB | CREAD)) - || ((termios_p->c_cflag & CSIZE) - && ((termios_p->c_cflag & CSIZE) - != (k_termios.c_cflag & CSIZE)))) - { - /* It looks like the Linux kernel silently changed the - PARENB/CREAD/CSIZE bits in c_cflag. Report it as an - error. */ - __set_errno (EINVAL); - retval = -1; - } - } - - return retval; + return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); } weak_alias (__tcsetattr, tcsetattr) libc_hidden_def (tcsetattr) diff --git a/sysdeps/unix/sysv/linux/tst-clone3.c b/sysdeps/unix/sysv/linux/tst-clone3.c index 9f1ed63..784ce18 100644 --- a/sysdeps/unix/sysv/linux/tst-clone3.c +++ b/sysdeps/unix/sysv/linux/tst-clone3.c @@ -27,7 +27,6 @@ #include /* For _STACK_GROWS_{UP,DOWN}. */ #include -#include /* Test if clone call with CLONE_THREAD does not call exit_group. The 'f' function returns '1', which will be used by clone thread to call the @@ -43,14 +42,11 @@ f (void *a) /* Futex wait for TID argument, similar to pthread_join internal implementation. */ -#define wait_tid(ctid_ptr, ctid_val) \ - do { \ - __typeof (*(ctid_ptr)) __tid; \ - /* We need acquire MO here so that we synchronize with the \ - kernel's store to 0 when the clone terminates. */ \ - while ((__tid = atomic_load_explicit (ctid_ptr, \ - memory_order_acquire)) != 0) \ - futex_wait (ctid_ptr, ctid_val); \ +#define wait_tid(tid) \ + do { \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + futex_wait (&(tid), __tid); \ } while (0) static inline int @@ -68,11 +64,7 @@ do_test (void) clone_flags |= CLONE_VM | CLONE_SIGHAND; /* We will used ctid to call on futex to wait for thread exit. */ clone_flags |= CLONE_CHILD_CLEARTID; - /* Initialize with a known value. ctid is set to zero by the kernel after the - cloned thread has exited. */ -#define CTID_INIT_VAL 1 - pid_t ctid = CTID_INIT_VAL; - pid_t tid; + pid_t ctid, tid; #ifdef __ia64__ extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base, @@ -94,7 +86,8 @@ do_test (void) if (tid == -1) FAIL_EXIT1 ("clone failed: %m"); - wait_tid (&ctid, CTID_INIT_VAL); + ctid = tid; + wait_tid (ctid); return 2; } diff --git a/sysdeps/unix/sysv/linux/tst-pkey.c b/sysdeps/unix/sysv/linux/tst-pkey.c index 40d7e9f..5f721d4 100644 --- a/sysdeps/unix/sysv/linux/tst-pkey.c +++ b/sysdeps/unix/sysv/linux/tst-pkey.c @@ -37,7 +37,7 @@ static pthread_barrier_t barrier; /* The keys used for testing. These have been allocated with access rights set based on their array index. */ -enum { key_count = 3 }; +enum { key_count = 4 }; static int keys[key_count]; static volatile int *pages[key_count]; @@ -111,16 +111,14 @@ check_page_access (int page, bool write) } static volatile sig_atomic_t sigusr1_handler_ran; -/* Used to check the behavior in signal handlers. In x86 all access are - revoked during signal handling. In PowerPC the key permissions are - inherited by the interrupted thread. This test accept both approaches. */ + +/* Used to check that access is revoked in signal handlers. */ static void sigusr1_handler (int signum) { TEST_COMPARE (signum, SIGUSR1); for (int i = 0; i < key_count; ++i) - TEST_VERIFY (pkey_get (keys[i]) == PKEY_DISABLE_ACCESS - || pkey_get (keys[i]) == i); + TEST_COMPARE (pkey_get (keys[i]), PKEY_DISABLE_ACCESS); sigusr1_handler_ran = 1; } @@ -199,10 +197,6 @@ do_test (void) if (errno == EINVAL) FAIL_UNSUPPORTED ("CPU does not support memory protection keys: %m"); - if (errno == ENOSPC) - FAIL_UNSUPPORTED - ("no keys available or kernel does not support memory" - " protection keys"); FAIL_EXIT1 ("pkey_alloc: %m"); } TEST_COMPARE (pkey_get (keys[0]), 0); diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c deleted file mode 100644 index 43c4a84..0000000 --- a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Test readdir64 compatibility symbol. - 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 -#include -#include -#include -#include -#include -#include -#include - -/* Copied from . */ -struct __old_dirent64 - { - __ino_t d_ino; - __off64_t d_off; - unsigned short int d_reclen; - unsigned char d_type; - char d_name[256]; - }; - -typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *); - -#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) -struct __old_dirent64 *compat_readdir64 (DIR *); -compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1); -#endif - -static int -do_test (void) -{ -#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) - - /* Directory stream using the non-compat readdir64 symbol. The test - checks against this. */ - DIR *dir_reference = opendir ("."); - TEST_VERIFY_EXIT (dir_reference != NULL); - DIR *dir_test = opendir ("."); - TEST_VERIFY_EXIT (dir_test != NULL); - - /* This loop assumes that the enumeration order is consistent for - two different handles. Nothing should write to the current - directory (in the source tree) while this test runs, so there - should not be any difference due to races. */ - size_t count = 0; - while (true) - { - errno = 0; - struct dirent64 *entry_reference = readdir64 (dir_reference); - if (entry_reference == NULL && errno != 0) - FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count); - struct __old_dirent64 *entry_test = compat_readdir64 (dir_test); - if (entry_reference == NULL) - { - if (errno == EOVERFLOW) - { - TEST_VERIFY (entry_reference->d_ino - != (__ino_t) entry_reference->d_ino); - printf ("info: inode number overflow at entry %zu\n", count); - break; - } - if (errno != 0) - FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count); - } - - /* Check that both streams end at the same time. */ - if (entry_reference == NULL) - { - TEST_VERIFY (entry_test == NULL); - break; - } - else - TEST_VERIFY_EXIT (entry_test != NULL); - - /* Check that the entries are the same. */ - TEST_COMPARE_BLOB (entry_reference->d_name, - strlen (entry_reference->d_name), - entry_test->d_name, strlen (entry_test->d_name)); - TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino); - TEST_COMPARE (entry_reference->d_off, entry_test->d_off); - TEST_COMPARE (entry_reference->d_type, entry_test->d_type); - TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen); - - ++count; - } - printf ("info: %zu directory entries found\n", count); - TEST_VERIFY (count >= 3); /* ".", "..", and some source files. */ - - TEST_COMPARE (closedir (dir_test), 0); - TEST_COMPARE (closedir (dir_reference), 0); -#endif - return 0; -} - -#include diff --git a/sysdeps/unix/sysv/linux/x86/force-elision.h b/sysdeps/unix/sysv/linux/x86/force-elision.h index 61282d6..dd659c9 100644 --- a/sysdeps/unix/sysv/linux/x86/force-elision.h +++ b/sysdeps/unix/sysv/linux/x86/force-elision.h @@ -18,45 +18,9 @@ /* Automatically enable elision for existing user lock kinds. */ #define FORCE_ELISION(m, s) \ - if (__pthread_force_elision) \ + if (__pthread_force_elision \ + && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ { \ - /* See concurrency notes regarding __kind in \ - struct __pthread_mutex_s in \ - sysdeps/nptl/bits/thread-shared-types.h. \ - \ - There are the following cases for the kind of a mutex \ - (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ - PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ - only one of both flags can be set): \ - - both flags are not set: \ - This is the first lock operation for this mutex. Enable \ - elision as it is not enabled so far. \ - Note: It can happen that multiple threads are calling e.g. \ - pthread_mutex_lock at the same time as the first lock \ - operation for this mutex. Then elision is enabled for this \ - mutex by multiple threads. Storing with relaxed MO is enough \ - as all threads will store the same new value for the kind of \ - the mutex. But we have to ensure that we always use the \ - elision path regardless if this thread has enabled elision or \ - another one. \ - \ - - PTHREAD_MUTEX_ELISION_NP flag is set: \ - Elision was already enabled for this mutex by a previous lock \ - operation. See case above. Just use the elision path. \ - \ - - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ - Elision was explicitly disabled by pthread_mutexattr_settype. \ - Do not use the elision path. \ - Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ - changed after mutex initialization. */ \ - int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ - if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ - { \ - mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ - atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ - } \ - if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ - { \ - s; \ - } \ + mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ + s; \ } diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h index ac694c0..1943691 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h @@ -31,8 +31,7 @@ environment variable, LD_PREFER_MAP_32BIT_EXEC. */ #define EXTRA_LD_ENVVARS \ case 21: \ - if (!__libc_enable_secure \ - && memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ + if (memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ GLRO(dl_x86_cpu_features).feature[index_arch_Prefer_MAP_32BIT_EXEC] \ |= bit_arch_Prefer_MAP_32BIT_EXEC; \ break; diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 0ebb018..816e4a7 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -621,11 +621,6 @@ GLIBC_2.2.5 clntudp_bufcreate F GLIBC_2.2.5 clntudp_create F GLIBC_2.2.5 clntunix_create F GLIBC_2.2.5 clock F -GLIBC_2.2.5 clock_getcpuclockid F -GLIBC_2.2.5 clock_getres F -GLIBC_2.2.5 clock_gettime F -GLIBC_2.2.5 clock_nanosleep F -GLIBC_2.2.5 clock_settime F GLIBC_2.2.5 clone F GLIBC_2.2.5 close F GLIBC_2.2.5 closedir F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist index 4fbb72f..931c827 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist @@ -46,6 +46,7 @@ GLIBC_2.2.5 __read F GLIBC_2.2.5 __res_state F GLIBC_2.2.5 __send F GLIBC_2.2.5 __sigaction F +GLIBC_2.2.5 __vfork F GLIBC_2.2.5 __wait F GLIBC_2.2.5 __write F GLIBC_2.2.5 _pthread_cleanup_pop F @@ -192,6 +193,7 @@ GLIBC_2.2.5 siglongjmp F GLIBC_2.2.5 sigwait F GLIBC_2.2.5 system F GLIBC_2.2.5 tcdrain F +GLIBC_2.2.5 vfork F GLIBC_2.2.5 wait F GLIBC_2.2.5 waitpid F GLIBC_2.2.5 write F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist b/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist index 95e3f22..e2e8b60 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist @@ -13,6 +13,11 @@ GLIBC_2.2.5 aio_suspend F GLIBC_2.2.5 aio_suspend64 F GLIBC_2.2.5 aio_write F GLIBC_2.2.5 aio_write64 F +GLIBC_2.2.5 clock_getcpuclockid F +GLIBC_2.2.5 clock_getres F +GLIBC_2.2.5 clock_gettime F +GLIBC_2.2.5 clock_nanosleep F +GLIBC_2.2.5 clock_settime F GLIBC_2.2.5 lio_listio F GLIBC_2.2.5 lio_listio64 F GLIBC_2.2.5 shm_open F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 0b6b3fa..6fee16a 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -660,11 +660,6 @@ GLIBC_2.16 clntudp_create F GLIBC_2.16 clntunix_create F GLIBC_2.16 clock F GLIBC_2.16 clock_adjtime F -GLIBC_2.16 clock_getcpuclockid F -GLIBC_2.16 clock_getres F -GLIBC_2.16 clock_gettime F -GLIBC_2.16 clock_nanosleep F -GLIBC_2.16 clock_settime F GLIBC_2.16 clone F GLIBC_2.16 close F GLIBC_2.16 closedir F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist index eec4b99..c09c9b0 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist @@ -45,6 +45,7 @@ GLIBC_2.16 __read F GLIBC_2.16 __res_state F GLIBC_2.16 __send F GLIBC_2.16 __sigaction F +GLIBC_2.16 __vfork F GLIBC_2.16 __wait F GLIBC_2.16 __write F GLIBC_2.16 _pthread_cleanup_pop F @@ -215,6 +216,7 @@ GLIBC_2.16 siglongjmp F GLIBC_2.16 sigwait F GLIBC_2.16 system F GLIBC_2.16 tcdrain F +GLIBC_2.16 vfork F GLIBC_2.16 wait F GLIBC_2.16 waitpid F GLIBC_2.16 write F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist index 66969fb..94e84e4 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist @@ -14,6 +14,11 @@ GLIBC_2.16 aio_suspend F GLIBC_2.16 aio_suspend64 F GLIBC_2.16 aio_write F GLIBC_2.16 aio_write64 F +GLIBC_2.16 clock_getcpuclockid F +GLIBC_2.16 clock_getres F +GLIBC_2.16 clock_gettime F +GLIBC_2.16 clock_nanosleep F +GLIBC_2.16 clock_settime F GLIBC_2.16 lio_listio F GLIBC_2.16 lio_listio64 F GLIBC_2.16 mq_close F diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index 43ad4a7..337b0b6 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -19,17 +19,12 @@ ifeq ($(subdir),elf) sysdep-dl-routines += dl-cet tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \ - tst-cet-legacy-3 tst-cet-legacy-4 \ - tst-cet-legacy-5a tst-cet-legacy-6a + tst-cet-legacy-3 tst-cet-legacy-4 ifneq (no,$(have-tunables)) -tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c \ - tst-cet-legacy-5b tst-cet-legacy-6b +tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c endif modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \ - tst-cet-legacy-mod-4 tst-cet-legacy-mod-5a \ - tst-cet-legacy-mod-5b tst-cet-legacy-mod-5c \ - tst-cet-legacy-mod-6a tst-cet-legacy-mod-6b \ - tst-cet-legacy-mod-6c + tst-cet-legacy-mod-4 CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch CFLAGS-tst-cet-legacy-2a.c += -fcf-protection @@ -40,16 +35,6 @@ CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch CFLAGS-tst-cet-legacy-4a.c += -fcf-protection CFLAGS-tst-cet-legacy-4b.c += -fcf-protection CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none -CFLAGS-tst-cet-legacy-5a.c += -fcf-protection -CFLAGS-tst-cet-legacy-5b.c += -fcf-protection -CFLAGS-tst-cet-legacy-mod-5a.c += -fcf-protection=none -CFLAGS-tst-cet-legacy-mod-5b.c += -fcf-protection -CFLAGS-tst-cet-legacy-mod-5c.c += -fcf-protection -CFLAGS-tst-cet-legacy-6a.c += -fcf-protection -CFLAGS-tst-cet-legacy-6b.c += -fcf-protection -CFLAGS-tst-cet-legacy-mod-6a.c += -fcf-protection=none -CFLAGS-tst-cet-legacy-mod-6b.c += -fcf-protection -CFLAGS-tst-cet-legacy-mod-6c.c += -fcf-protection $(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \ $(objpfx)tst-cet-legacy-mod-2.so @@ -59,17 +44,6 @@ $(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl) $(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so $(objpfx)tst-cet-legacy-4: $(libdl) $(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so -$(objpfx)tst-cet-legacy-5a: $(libdl) -$(objpfx)tst-cet-legacy-5a.out: $(objpfx)tst-cet-legacy-mod-5a.so \ - $(objpfx)tst-cet-legacy-mod-5b.so -$(objpfx)tst-cet-legacy-mod-5a.so: $(objpfx)tst-cet-legacy-mod-5c.so -$(objpfx)tst-cet-legacy-mod-5b.so: $(objpfx)tst-cet-legacy-mod-5c.so -$(objpfx)tst-cet-legacy-6a: $(libdl) -$(objpfx)tst-cet-legacy-6a.out: $(objpfx)tst-cet-legacy-mod-6a.so \ - $(objpfx)tst-cet-legacy-mod-6b.so -$(objpfx)tst-cet-legacy-mod-6a.so: $(objpfx)tst-cet-legacy-mod-6c.so -$(objpfx)tst-cet-legacy-mod-6b.so: $(objpfx)tst-cet-legacy-mod-6c.so -LDFLAGS-tst-cet-legacy-mod-6c.so = -Wl,--enable-new-dtags,-z,nodelete ifneq (no,$(have-tunables)) $(objpfx)tst-cet-legacy-4a: $(libdl) $(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so @@ -80,14 +54,6 @@ tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on $(objpfx)tst-cet-legacy-4c: $(libdl) $(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off -$(objpfx)tst-cet-legacy-5b: $(libdl) -$(objpfx)tst-cet-legacy-5b.out: $(objpfx)tst-cet-legacy-mod-5a.so \ - $(objpfx)tst-cet-legacy-mod-5b.so -tst-cet-legacy-5b-ENV = GLIBC_TUNABLES=glibc.tune.x86_ibt=off:glibc.tune.x86_shstk=off -$(objpfx)tst-cet-legacy-6b: $(libdl) -$(objpfx)tst-cet-legacy-6b.out: $(objpfx)tst-cet-legacy-mod-6a.so \ - $(objpfx)tst-cet-legacy-mod-6b.so -tst-cet-legacy-6b-ENV = GLIBC_TUNABLES=glibc.tune.x86_ibt=off:glibc.tune.x86_shstk=off endif endif diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c index 4695ac8..ea0b64f 100644 --- a/sysdeps/x86/cpu-features.c +++ b/sysdeps/x86/cpu-features.c @@ -316,13 +316,7 @@ init_cpu_features (struct cpu_features *cpu_features) | bit_arch_Fast_Unaligned_Copy | bit_arch_Prefer_PMINUB_for_stringop); break; - } - /* Disable TSX on some Haswell processors to avoid TSX on kernels that - weren't updated with the latest microcode package (which disables - broken feature by default). */ - switch (model) - { case 0x3f: /* Xeon E7 v3 with stepping >= 4 has working TSX. */ if (stepping >= 4) diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h index 9ab890d..26c3131 100644 --- a/sysdeps/x86/dl-prop.h +++ b/sysdeps/x86/dl-prop.h @@ -49,10 +49,6 @@ _dl_process_cet_property_note (struct link_map *l, const ElfW(Addr) align) { #if CET_ENABLED - /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before. */ - if (l->l_cet != lc_unknown) - return; - /* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in 32-bit objects and to 8 bytes in 64-bit objects. Skip notes with incorrect alignment. */ @@ -61,9 +57,6 @@ _dl_process_cet_property_note (struct link_map *l, const ElfW(Addr) start = (ElfW(Addr)) note; - unsigned int feature_1 = 0; - unsigned int last_type = 0; - while ((ElfW(Addr)) (note + 1) - start < size) { /* Find the NT_GNU_PROPERTY_TYPE_0 note. */ @@ -71,18 +64,10 @@ _dl_process_cet_property_note (struct link_map *l, && note->n_type == NT_GNU_PROPERTY_TYPE_0 && memcmp (note + 1, "GNU", 4) == 0) { - /* Stop if we see more than one GNU property note which may - be generated by the older linker. */ - if (l->l_cet != lc_unknown) - return; - - /* Check CET status now. */ - l->l_cet = lc_none; - /* Check for invalid property. */ if (note->n_descsz < 8 || (note->n_descsz % sizeof (ElfW(Addr))) != 0) - return; + break; /* Start and end of property array. */ unsigned char *ptr = (unsigned char *) (note + 1) + 4; @@ -93,15 +78,9 @@ _dl_process_cet_property_note (struct link_map *l, unsigned int type = *(unsigned int *) ptr; unsigned int datasz = *(unsigned int *) (ptr + 4); - /* Property type must be in ascending order. */ - if (type < last_type) - return; - ptr += 8; if ((ptr + datasz) > ptr_end) - return; - - last_type = type; + break; if (type == GNU_PROPERTY_X86_FEATURE_1_AND) { @@ -110,18 +89,14 @@ _dl_process_cet_property_note (struct link_map *l, we stop the search regardless if its size is correct or not. There is no point to continue if this note is ill-formed. */ - if (datasz != 4) - return; - - feature_1 = *(unsigned int *) ptr; - - /* Keep searching for the next GNU property note - generated by the older linker. */ - break; - } - else if (type > GNU_PROPERTY_X86_FEATURE_1_AND) - { - /* Stop since property type is in ascending order. */ + if (datasz == 4) + { + unsigned int feature_1 = *(unsigned int *) ptr; + if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT)) + l->l_cet |= lc_ibt; + if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) + l->l_cet |= lc_shstk; + } return; } @@ -137,12 +112,6 @@ _dl_process_cet_property_note (struct link_map *l, + ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz, align)); } - - /* We get here only if there is one or no GNU property note. */ - if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT)) - l->l_cet |= lc_ibt; - if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) - l->l_cet |= lc_shstk; #endif } diff --git a/sysdeps/x86/fpu/finclude/math-vector-fortran.h b/sysdeps/x86/fpu/finclude/math-vector-fortran.h deleted file mode 100644 index 36051cc..0000000 --- a/sysdeps/x86/fpu/finclude/math-vector-fortran.h +++ /dev/null @@ -1,43 +0,0 @@ -! Platform-specific declarations of SIMD math functions for Fortran. -*- f90 -*- -! 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 -! . - -!GCC$ builtin (cos) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (cosf) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (sin) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (sinf) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (sincos) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (sincosf) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (log) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (logf) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (exp) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (expf) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (pow) attributes simd (notinbranch) if('x86_64') -!GCC$ builtin (powf) attributes simd (notinbranch) if('x86_64') - -!GCC$ builtin (cos) attributes simd (notinbranch) if('x32') -!GCC$ builtin (cosf) attributes simd (notinbranch) if('x32') -!GCC$ builtin (sin) attributes simd (notinbranch) if('x32') -!GCC$ builtin (sinf) attributes simd (notinbranch) if('x32') -!GCC$ builtin (sincos) attributes simd (notinbranch) if('x32') -!GCC$ builtin (sincosf) attributes simd (notinbranch) if('x32') -!GCC$ builtin (log) attributes simd (notinbranch) if('x32') -!GCC$ builtin (logf) attributes simd (notinbranch) if('x32') -!GCC$ builtin (exp) attributes simd (notinbranch) if('x32') -!GCC$ builtin (expf) attributes simd (notinbranch) if('x32') -!GCC$ builtin (pow) attributes simd (notinbranch) if('x32') -!GCC$ builtin (powf) attributes simd (notinbranch) if('x32') diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h index 9367ed0..ef1206a 100644 --- a/sysdeps/x86/link_map.h +++ b/sysdeps/x86/link_map.h @@ -19,9 +19,8 @@ /* If this object is enabled with CET. */ enum { - lc_unknown = 0, /* Unknown CET status. */ - lc_none = 1 << 0, /* Not enabled with CET. */ - lc_ibt = 1 << 1, /* Enabled with IBT. */ - lc_shstk = 1 << 2, /* Enabled with STSHK. */ + lc_none = 0, /* Not enabled with CET. */ + lc_ibt = 1 << 0, /* Enabled with IBT. */ + lc_shstk = 1 << 1, /* Enabled with STSHK. */ lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both. */ - } l_cet:3; + } l_cet:2; diff --git a/sysdeps/x86/tst-cet-legacy-5.c b/sysdeps/x86/tst-cet-legacy-5.c deleted file mode 100644 index fbf640f..0000000 --- a/sysdeps/x86/tst-cet-legacy-5.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Check compatibility of CET-enabled executable with dlopened legacy - shared object. - 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 void -do_test_1 (const char *modname, bool fail) -{ - int (*fp) (void); - void *h; - - h = dlopen (modname, RTLD_LAZY); - if (h == NULL) - { - if (fail) - { - const char *err = dlerror (); - if (strstr (err, "shadow stack isn't enabled") == NULL) - { - printf ("incorrect dlopen '%s' error: %s\n", modname, - dlerror ()); - exit (1); - } - - return; - } - - printf ("cannot open '%s': %s\n", modname, dlerror ()); - exit (1); - } - - fp = dlsym (h, "test"); - if (fp == NULL) - { - printf ("cannot get symbol 'test': %s\n", dlerror ()); - exit (1); - } - - if (fp () != 0) - { - puts ("test () != 0"); - exit (1); - } - - dlclose (h); -} - -static int -do_test (void) -{ - do_test_1 ("tst-cet-legacy-mod-5a.so", true); - do_test_1 ("tst-cet-legacy-mod-5b.so", false); - return 0; -} - -#include diff --git a/sysdeps/x86/tst-cet-legacy-5a.c b/sysdeps/x86/tst-cet-legacy-5a.c deleted file mode 100644 index fc5a609..0000000 --- a/sysdeps/x86/tst-cet-legacy-5a.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-5.c" diff --git a/sysdeps/x86/tst-cet-legacy-5b.c b/sysdeps/x86/tst-cet-legacy-5b.c deleted file mode 100644 index fc5a609..0000000 --- a/sysdeps/x86/tst-cet-legacy-5b.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-5.c" diff --git a/sysdeps/x86/tst-cet-legacy-6.c b/sysdeps/x86/tst-cet-legacy-6.c deleted file mode 100644 index 9151225..0000000 --- a/sysdeps/x86/tst-cet-legacy-6.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Check compatibility of CET-enabled executable with dlopened legacy - shared object. - 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 void -do_test_1 (const char *modname, bool fail) -{ - int (*fp) (void); - void *h; - - h = dlopen (modname, RTLD_LAZY); - if (h == NULL) - { - if (fail) - { - const char *err = dlerror (); - if (strstr (err, "shadow stack isn't enabled") == NULL) - { - printf ("incorrect dlopen '%s' error: %s\n", modname, - dlerror ()); - exit (1); - } - - return; - } - - printf ("cannot open '%s': %s\n", modname, dlerror ()); - exit (1); - } - - fp = dlsym (h, "test"); - if (fp == NULL) - { - printf ("cannot get symbol 'test': %s\n", dlerror ()); - exit (1); - } - - if (fp () != 0) - { - puts ("test () != 0"); - exit (1); - } - - dlclose (h); -} - -static int -do_test (void) -{ - do_test_1 ("tst-cet-legacy-mod-6a.so", true); - do_test_1 ("tst-cet-legacy-mod-6b.so", false); - return 0; -} - -#include diff --git a/sysdeps/x86/tst-cet-legacy-6a.c b/sysdeps/x86/tst-cet-legacy-6a.c deleted file mode 100644 index 2d1546d..0000000 --- a/sysdeps/x86/tst-cet-legacy-6a.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-6.c" diff --git a/sysdeps/x86/tst-cet-legacy-6b.c b/sysdeps/x86/tst-cet-legacy-6b.c deleted file mode 100644 index 2d1546d..0000000 --- a/sysdeps/x86/tst-cet-legacy-6b.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-6.c" diff --git a/sysdeps/x86/tst-cet-legacy-mod-5.c b/sysdeps/x86/tst-cet-legacy-mod-5.c deleted file mode 100644 index 3c1071c..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-5.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Check compatibility of CET-enabled executable with dlopened legacy - shared object. - 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 - -extern void foo (void); - -int -test (void) -{ - foo (); - return 0; -} diff --git a/sysdeps/x86/tst-cet-legacy-mod-5a.c b/sysdeps/x86/tst-cet-legacy-mod-5a.c deleted file mode 100644 index daa43e4..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-5a.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-mod-5.c" diff --git a/sysdeps/x86/tst-cet-legacy-mod-5b.c b/sysdeps/x86/tst-cet-legacy-mod-5b.c deleted file mode 100644 index daa43e4..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-5b.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-mod-5.c" diff --git a/sysdeps/x86/tst-cet-legacy-mod-5c.c b/sysdeps/x86/tst-cet-legacy-mod-5c.c deleted file mode 100644 index e529a42..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-5c.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Check compatibility of CET-enabled executable with dlopened legacy - shared object. - 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 - -static int called = 0; - -static void -__attribute__ ((constructor)) -init (void) -{ - called = 1; -} - -void -foo (void) -{ - if (!called) - abort (); -} diff --git a/sysdeps/x86/tst-cet-legacy-mod-6.c b/sysdeps/x86/tst-cet-legacy-mod-6.c deleted file mode 100644 index 3c1071c..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-6.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Check compatibility of CET-enabled executable with dlopened legacy - shared object. - 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 - -extern void foo (void); - -int -test (void) -{ - foo (); - return 0; -} diff --git a/sysdeps/x86/tst-cet-legacy-mod-6a.c b/sysdeps/x86/tst-cet-legacy-mod-6a.c deleted file mode 100644 index c89b8fe..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-6a.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-mod-6.c" diff --git a/sysdeps/x86/tst-cet-legacy-mod-6b.c b/sysdeps/x86/tst-cet-legacy-mod-6b.c deleted file mode 100644 index c89b8fe..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-6b.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-mod-6.c" diff --git a/sysdeps/x86/tst-cet-legacy-mod-6c.c b/sysdeps/x86/tst-cet-legacy-mod-6c.c deleted file mode 100644 index e529a42..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-6c.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Check compatibility of CET-enabled executable with dlopened legacy - shared object. - 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 - -static int called = 0; - -static void -__attribute__ ((constructor)) -init (void) -{ - called = 1; -} - -void -foo (void) -{ - if (!called) - abort (); -} diff --git a/sysdeps/x86/tst-cet-legacy-mod-6d.c b/sysdeps/x86/tst-cet-legacy-mod-6d.c deleted file mode 100644 index eb233a1..0000000 --- a/sysdeps/x86/tst-cet-legacy-mod-6d.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cet-legacy-mod-6c.c" diff --git a/sysdeps/x86_64/dl-irel.h b/sysdeps/x86_64/dl-irel.h index 33f100d..6ecc50f 100644 --- a/sysdeps/x86_64/dl-irel.h +++ b/sysdeps/x86_64/dl-irel.h @@ -45,7 +45,7 @@ elf_irela (const ElfW(Rela) *reloc) *reloc_addr = value; } else - __libc_fatal ("Unexpected reloc type in static binary.\n"); + __libc_fatal ("unexpected reloc type in static binary"); } #endif /* dl-irel.h */ diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c b/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c index ada28ba..6a5ea3f 100644 --- a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c +++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c @@ -1,2 +1,2 @@ #define __ceil __ceil_c -#include +#include diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c b/sysdeps/x86_64/fpu/multiarch/s_floor-c.c index 002d122..68733b6 100644 --- a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c +++ b/sysdeps/x86_64/fpu/multiarch/s_floor-c.c @@ -1,3 +1,3 @@ #undef __floor #define __floor __floor_c -#include +#include diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-c.c b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-c.c index 4fdeb11..f897a2a 100644 --- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-c.c +++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-c.c @@ -1,3 +1,3 @@ #undef __nearbyint #define __nearbyint __nearbyint_c -#include +#include diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-c.c b/sysdeps/x86_64/fpu/multiarch/s_rint-c.c index b010150..162a630 100644 --- a/sysdeps/x86_64/fpu/multiarch/s_rint-c.c +++ b/sysdeps/x86_64/fpu/multiarch/s_rint-c.c @@ -1,3 +1,3 @@ #undef __rint #define __rint __rint_c -#include +#include diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c b/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c index 8aa499f..6204ae3 100644 --- a/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c +++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-c.c @@ -1,2 +1,2 @@ #define __trunc __trunc_c -#include +#include diff --git a/time/Makefile b/time/Makefile index 6a68481..ec3e39d 100644 --- a/time/Makefile +++ b/time/Makefile @@ -36,18 +36,14 @@ routines := offtime asctime clock ctime ctime_r difftime \ stime dysize timegm ftime \ getdate strptime strptime_l \ strftime wcsftime strftime_l wcsftime_l \ - timespec_get \ - clock_getcpuclockid clock_getres \ - clock_gettime clock_settime clock_nanosleep - + timespec_get aux := era alt_digit lc-time-cleanup tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \ tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \ tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \ - tst-tzname tst-y2039 \ - tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 + tst-tzname tst-y2039 include ../Rules diff --git a/time/Versions b/time/Versions index 8788e19..fd83818 100644 --- a/time/Versions +++ b/time/Versions @@ -49,10 +49,6 @@ libc { GLIBC_2.2 { # w* wcsftime; - - # c*; actually in librt in version 2.2, moved to libc in 2.17 - clock_getres; clock_gettime; clock_settime; clock_getcpuclockid; - clock_nanosleep; } GLIBC_2.3 { # these internal names are used by libstdc++ @@ -69,13 +65,4 @@ libc { GLIBC_2.16 { timespec_get; } - GLIBC_2.17 { - # c* - clock_getres; clock_gettime; clock_settime; clock_getcpuclockid; - clock_nanosleep; - } - GLIBC_PRIVATE { - # same as clock_gettime; used in other libraries - __clock_gettime; - } } diff --git a/time/clock_getcpuclockid.c b/time/clock_getcpuclockid.c deleted file mode 100644 index 81b8624..0000000 --- a/time/clock_getcpuclockid.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Get a clockid_t for the process CPU clock of a given process. Generic. - Copyright (C) 2000-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include - -int -__clock_getcpuclockid (pid_t pid, clockid_t *clock_id) -{ - /* We don't allow any process ID but our own. */ - if (pid != 0 && pid != getpid ()) - return EPERM; - -#ifdef CLOCK_PROCESS_CPUTIME_ID - /* Store the number. */ - *clock_id = CLOCK_PROCESS_CPUTIME_ID; - - return 0; -#else - /* We don't have a timer for that. */ - return ENOENT; -#endif -} -versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17); -/* clock_getcpuclockid moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_getcpuclockid, __clock_getcpuclockid_2); -compat_symbol (libc, __clock_getcpuclockid_2, clock_getcpuclockid, GLIBC_2_2); -#endif diff --git a/time/clock_getres.c b/time/clock_getres.c deleted file mode 100644 index e831539..0000000 --- a/time/clock_getres.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Get the resolution of a clock. Stub version. - Copyright (C) 1999-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -/* Get resolution of clock. */ -int -__clock_getres (clockid_t clock_id, struct timespec *res) -{ - __set_errno (ENOSYS); - return -1; -} - -versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17); -/* clock_getres moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_getres, __clock_getres_2); -compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2); -#endif - -stub_warning (clock_getres) diff --git a/time/clock_gettime.c b/time/clock_gettime.c deleted file mode 100644 index 4a5f808..0000000 --- a/time/clock_gettime.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Get the current value of a clock. Stub version. - Copyright (C) 1999-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -/* Get current value of CLOCK and store it in TP. */ -int -__clock_gettime (clockid_t clock_id, struct timespec *tp) -{ - __set_errno (ENOSYS); - return -1; -} -libc_hidden_def (__clock_gettime) - -versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17); -/* clock_gettime moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_gettime, __clock_gettime_2); -compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2); -#endif - -stub_warning (clock_gettime) diff --git a/time/clock_nanosleep.c b/time/clock_nanosleep.c deleted file mode 100644 index a314b16..0000000 --- a/time/clock_nanosleep.c +++ /dev/null @@ -1,46 +0,0 @@ -/* High-resolution sleep with the specified clock. Stub version. - Copyright (C) 2000-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -int -__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, - struct timespec *rem) -{ - if (__builtin_expect (req->tv_nsec, 0) < 0 - || __builtin_expect (req->tv_nsec, 0) >= 1000000000) - return EINVAL; - - if (flags != TIMER_ABSTIME && flags != 0) - return EINVAL; - - /* Not implemented. */ - return ENOSYS; -} - -versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17); -/* clock_nanosleep moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_nanosleep, __clock_nanosleep_2); -compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2); -#endif - -stub_warning (clock_nanosleep) diff --git a/time/clock_settime.c b/time/clock_settime.c deleted file mode 100644 index 2091239..0000000 --- a/time/clock_settime.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Set a clock to a given value. Stub version. - Copyright (C) 1999-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include - -/* Set CLOCK to value TP. */ -int -__clock_settime (clockid_t clock_id, const struct timespec *tp) -{ - __set_errno (ENOSYS); - return -1; -} -libc_hidden_def (__clock_settime) - -versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17); -/* clock_settime moved to libc in version 2.17; - old binaries may expect the symbol version it had in librt. */ -#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17) -strong_alias (__clock_settime, __clock_settime_2); -compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2); -#endif - -stub_warning (clock_settime) diff --git a/time/tst-clock.c b/time/tst-clock.c deleted file mode 100644 index bec76d0..0000000 --- a/time/tst-clock.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Test program for POSIX clock_* functions. - Copyright (C) 2000-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2000. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for 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 - - -/* We want to see output immediately. */ -#define STDOUT_UNBUFFERED - -/* We expect to run at least 10 seconds. */ -#define TIMEOUT 15 - -static int -clock_test (clockid_t cl) -{ - struct timespec old_ts; - struct timespec ts; - struct timespec waitit; - int result = 0; - int i; - - memset (&ts, '\0', sizeof ts); - - waitit.tv_sec = 0; - waitit.tv_nsec = 500000000; - - /* Get and print resolution of the clock. */ - if (clock_getres (cl, &ts) == 0) - { - if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000) - { - printf ("clock %d: nanosecond value of resolution wrong\n", cl); - result = 1; - } - else - printf ("clock %d: resolution = %jd.%09jd secs\n", - cl, (intmax_t) ts.tv_sec, (intmax_t) ts.tv_nsec); - } - else - { - printf ("clock %d: cannot get resolution\n", cl); - result = 1; - } - - memset (&ts, '\0', sizeof ts); - memset (&old_ts, '\0', sizeof old_ts); - - /* Next get the current time value a few times. */ - for (i = 0; i < 10; ++i) - { - if (clock_gettime (cl, &ts) == 0) - { - if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000) - { - printf ("clock %d: nanosecond value of time wrong (try %d)\n", - cl, i); - result = 1; - } - else - { - printf ("clock %d: time = %jd.%09jd secs\n", - cl, (intmax_t) ts.tv_sec, (intmax_t) ts.tv_nsec); - - if (memcmp (&ts, &old_ts, sizeof ts) == 0) - { - printf ("clock %d: time hasn't changed (try %d)\n", cl, i); - result = 1; - - old_ts = ts; - } - } - } - else - { - printf ("clock %d: cannot get time (try %d)\n", cl, i); - result = 1; - } - - /* Wait a bit before the next iteration. */ - nanosleep (&waitit, NULL); - } - - return result; -} - -static int -do_test (void) -{ - clockid_t cl; - int result; - - result = clock_test (CLOCK_REALTIME); - - if (clock_getcpuclockid (0, &cl) == 0) - /* XXX It's not yet a bug when this fails. */ - clock_test (cl); - else - printf("CPU clock unavailble, skipping test\n"); - - return result; -} -#define TEST_FUNCTION do_test () - - -#include "../test-skeleton.c" diff --git a/time/tst-clock2.c b/time/tst-clock2.c deleted file mode 100644 index 4c8fb9f..0000000 --- a/time/tst-clock2.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Test setting the monotonic clock. */ - -#include -#include - -#if defined CLOCK_MONOTONIC && defined _POSIX_MONOTONIC_CLOCK - -# include -# include - -static int -do_test (void) -{ - if (sysconf (_SC_MONOTONIC_CLOCK) <= 0) - return 0; - - struct timespec ts; - if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) - { - puts ("clock_gettime(CLOCK_MONOTONIC) failed"); - return 1; - } - - /* Setting the monotonic clock must fail. */ - if (clock_settime (CLOCK_MONOTONIC, &ts) != -1) - { - puts ("clock_settime(CLOCK_MONOTONIC) did not fail"); - return 1; - } - if (errno != EINVAL) - { - printf ("clock_settime(CLOCK_MONOTONIC) set errno to %d, expected %d\n", - errno, EINVAL); - return 1; - } - return 0; -} -# define TEST_FUNCTION do_test () - -#else -# define TEST_FUNCTION 0 -#endif -#include "../test-skeleton.c" diff --git a/time/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c deleted file mode 100644 index eb2b906..0000000 --- a/time/tst-clock_nanosleep.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2003-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include - - -/* Test that clock_nanosleep() does sleep. */ -static int -do_test (void) -{ - /* Current time. */ - struct timeval tv1; - (void) gettimeofday (&tv1, NULL); - - struct timespec ts; - ts.tv_sec = 1; - ts.tv_nsec = 0; - TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts)); - - /* At least one second must have passed. */ - struct timeval tv2; - (void) gettimeofday (&tv2, NULL); - - tv2.tv_sec -= tv1.tv_sec; - tv2.tv_usec -= tv1.tv_usec; - if (tv2.tv_usec < 0) - --tv2.tv_sec; - - if (tv2.tv_sec < 1) - { - puts ("clock_nanosleep didn't sleep long enough"); - return 1; - } - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/time/tst-cpuclock1.c b/time/tst-cpuclock1.c deleted file mode 100644 index f6d76e3..0000000 --- a/time/tst-cpuclock1.c +++ /dev/null @@ -1,321 +0,0 @@ -/* Test program for process CPU clocks. - Copyright (C) 2004-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* This function is intended to rack up both user and system time. */ -static void -chew_cpu (void) -{ - while (1) - { - static volatile char buf[4096]; - for (int i = 0; i < 100; ++i) - for (size_t j = 0; j < sizeof buf; ++j) - buf[j] = 0xaa; - int nullfd = open ("/dev/null", O_WRONLY); - for (int i = 0; i < 100; ++i) - for (size_t j = 0; j < sizeof buf; ++j) - buf[j] = 0xbb; - write (nullfd, (char *) buf, sizeof buf); - close (nullfd); - if (getppid () == 1) - _exit (2); - } -} - -static int -do_test (void) -{ - int result = 0; - clockid_t cl; - int e; - pid_t dead_child, child; - - /* Fork a child and let it die, to give us a PID known not be valid - (assuming PIDs don't wrap around during the test). */ - { - dead_child = fork (); - if (dead_child == 0) - _exit (0); - if (dead_child < 0) - { - perror ("fork"); - return 1; - } - int x; - if (wait (&x) != dead_child) - { - perror ("wait"); - return 2; - } - } - - /* POSIX says we should get ESRCH for this. */ - e = clock_getcpuclockid (dead_child, &cl); - if (e != ENOSYS && e != ESRCH && e != EPERM) - { - printf ("clock_getcpuclockid on dead PID %d => %s\n", - dead_child, strerror (e)); - result = 1; - } - - /* Now give us a live child eating up CPU time. */ - child = fork (); - if (child == 0) - { - chew_cpu (); - _exit (1); - } - if (child < 0) - { - perror ("fork"); - return 1; - } - - e = clock_getcpuclockid (child, &cl); - if (e == EPERM) - { - puts ("clock_getcpuclockid does not support other processes"); - goto done; - } - if (e != 0) - { - printf ("clock_getcpuclockid on live PID %d => %s\n", - child, strerror (e)); - result = 1; - goto done; - } - - const clockid_t child_clock = cl; - struct timespec res; - if (clock_getres (child_clock, &res) < 0) - { - printf ("clock_getres on live PID %d clock %lx => %s\n", - child, (unsigned long int) child_clock, strerror (errno)); - result = 1; - goto done; - } - printf ("live PID %d clock %lx resolution %ju.%.9ju\n", - child, (unsigned long int) child_clock, - (uintmax_t) res.tv_sec, (uintmax_t) res.tv_nsec); - - struct timespec before, after; - if (clock_gettime (child_clock, &before) < 0) - { - printf ("clock_gettime on live PID %d clock %lx => %s\n", - child, (unsigned long int) child_clock, strerror (errno)); - result = 1; - goto done; - } - /* Should be close to 0.0. */ - printf ("live PID %d before sleep => %ju.%.9ju\n", - child, (uintmax_t) before.tv_sec, (uintmax_t) before.tv_nsec); - - struct timespec sleeptime = { .tv_nsec = 500000000 }; - if (nanosleep (&sleeptime, NULL) != 0) - { - perror ("nanosleep"); - result = 1; - goto done; - } - - if (clock_gettime (child_clock, &after) < 0) - { - printf ("clock_gettime on live PID %d clock %lx => %s\n", - child, (unsigned long int) child_clock, strerror (errno)); - result = 1; - goto done; - } - /* Should be close to 0.5. */ - printf ("live PID %d after sleep => %ju.%.9ju\n", - child, (uintmax_t) after.tv_sec, (uintmax_t) after.tv_nsec); - - struct timespec diff = { .tv_sec = after.tv_sec - before.tv_sec, - .tv_nsec = after.tv_nsec - before.tv_nsec }; - if (diff.tv_nsec < 0) - { - --diff.tv_sec; - diff.tv_nsec += 1000000000; - } - if (diff.tv_sec != 0 - || diff.tv_nsec > 600000000 - || diff.tv_nsec < 100000000) - { - printf ("before - after %ju.%.9ju outside reasonable range\n", - (uintmax_t) diff.tv_sec, (uintmax_t) diff.tv_nsec); - result = 1; - } - - sleeptime.tv_nsec = 100000000; - e = clock_nanosleep (child_clock, 0, &sleeptime, NULL); - if (e == EINVAL || e == ENOTSUP || e == ENOSYS) - { - printf ("clock_nanosleep not supported for other process clock: %s\n", - strerror (e)); - } - else if (e != 0) - { - printf ("clock_nanosleep on other process clock: %s\n", strerror (e)); - result = 1; - } - else - { - struct timespec afterns; - if (clock_gettime (child_clock, &afterns) < 0) - { - printf ("clock_gettime on live PID %d clock %lx => %s\n", - child, (unsigned long int) child_clock, strerror (errno)); - result = 1; - } - else - { - struct timespec d = { .tv_sec = afterns.tv_sec - after.tv_sec, - .tv_nsec = afterns.tv_nsec - after.tv_nsec }; - if (d.tv_nsec < 0) - { - --d.tv_sec; - d.tv_nsec += 1000000000; - } - if (d.tv_sec > 0 - || d.tv_nsec < sleeptime.tv_nsec - || d.tv_nsec > sleeptime.tv_nsec * 2) - { - printf ("nanosleep time %ju.%.9ju outside reasonable range\n", - (uintmax_t) d.tv_sec, (uintmax_t) d.tv_nsec); - result = 1; - } - } - } - - if (kill (child, SIGKILL) != 0) - { - perror ("kill"); - result = 2; - goto done; - } - - /* Wait long enough to let the child finish dying. */ - - sleeptime.tv_nsec = 200000000; - if (nanosleep (&sleeptime, NULL) != 0) - { - perror ("nanosleep"); - result = 1; - goto done; - } - - struct timespec dead; - if (clock_gettime (child_clock, &dead) < 0) - { - printf ("clock_gettime on dead PID %d clock %lx => %s\n", - child, (unsigned long int) child_clock, strerror (errno)); - result = 1; - goto done; - } - /* Should be close to 0.6. */ - printf ("dead PID %d => %ju.%.9ju\n", - child, (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec); - - diff.tv_sec = dead.tv_sec - after.tv_sec; - diff.tv_nsec = dead.tv_nsec - after.tv_nsec; - if (diff.tv_nsec < 0) - { - --diff.tv_sec; - diff.tv_nsec += 1000000000; - } - if (diff.tv_sec != 0 || diff.tv_nsec > 200000000) - { - printf ("dead - after %ju.%.9ju outside reasonable range\n", - (uintmax_t) diff.tv_sec, (uintmax_t) diff.tv_nsec); - result = 1; - } - - /* Now reap the child and verify that its clock is no longer valid. */ - { - int x; - if (waitpid (child, &x, 0) != child) - { - perror ("waitpid"); - result = 1; - } - } - - if (clock_gettime (child_clock, &dead) == 0) - { - printf ("clock_gettime on reaped PID %d clock %lx => %ju%.9ju\n", - child, (unsigned long int) child_clock, - (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec); - result = 1; - } - else - { - if (errno != EINVAL) - result = 1; - printf ("clock_gettime on reaped PID %d clock %lx => %s\n", - child, (unsigned long int) child_clock, strerror (errno)); - } - - if (clock_getres (child_clock, &dead) == 0) - { - printf ("clock_getres on reaped PID %d clock %lx => %ju%.9ju\n", - child, (unsigned long int) child_clock, - (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec); - result = 1; - } - else - { - if (errno != EINVAL) - result = 1; - printf ("clock_getres on reaped PID %d clock %lx => %s\n", - child, (unsigned long int) child_clock, strerror (errno)); - } - - return result; - - done: - { - if (kill (child, SIGKILL) != 0 && errno != ESRCH) - { - perror ("kill"); - return 2; - } - int x; - if (waitpid (child, &x, 0) != child && errno != ECHILD) - { - perror ("waitpid"); - return 2; - } - } - - return result; -} - - -#define TIMEOUT 5 -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/time/tzfile.c b/time/tzfile.c index ea6e940..2a385b9 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -410,8 +410,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) /* First "register" all timezone names. */ for (i = 0; i < num_types; ++i) - if (__tzstring (&zone_names[types[i].idx]) == NULL) - goto ret_free_transitions; + (void) __tzstring (&zone_names[types[i].idx]); /* Find the standard and daylight time offsets used by the rule file. We choose the offsets in the types of each flavor that are