core/glibc/glibc-2.26-7.patch
2018-01-19 15:12:35 +01:00

26900 lines
880 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/ChangeLog b/ChangeLog
index 8dbfc7eaff..73777b3b86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,1195 @@
+2018-01-16 Florian Weimer <fweimer@redhat.com>
+
+ * nptl/Makefile [$(have-cxx-thread_local)] (tests-unsupported):
+ Move tst-thread-exit-clobber ...
+ [$(CXX)] (tests-unsupported): ... to here.
+
+2018-01-16 Florian Weimer <fweimer@redhat.com>
+
+ * nptl/Makefile (CFLAGS-tst-minstack-throw.o): Compile in C++11
+ mode with GNU extensions.
+
+2018-01-15 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22636]
+ * nptl/tst-minstack-throw.cc: New file.
+ * nptl/Makefile (tests): Add tst-minstack-throw.
+ (LDLIBS-tst-minstack-throw): Link with libstdc++.
+ [!CXX] (tests-unsupported): Add tst-minstack-throw.
+
+2018-01-11 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22636]
+ * nptl/Makefile (tests): Add tst-minstack-cancel, tst-minstack-exit.
+ * nptl/tst-minstack-cancel.c, nptl/tst-minstack-exit.c: New files.
+
+2018-01-10 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22636]
+ * sysdeps/nptl/unwind-forcedunwind.c (pthread_cancel_init): Open
+ libgcc.so with RTLD_NOW, to avoid lazy binding during unwind.
+
+2018-01-08 Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+ [BZ #22637]
+ * nptl/descr.h (stackblock, stackblock_size): Update comments.
+ * nptl/allocatestack.c (allocate_stack): Add guardsize to stacksize.
+ * nptl/nptl-init.c (__pthread_get_minstack): Remove guardsize from
+ stacksize.
+ * nptl/pthread_getattr_np.c (pthread_getattr_np): Likewise.
+
+2018-01-08 Florian Weimer <fweimer@redhat.com>
+
+ * nptl/tst-thread-exit-clobber.cc: New file.
+ * nptl/Makefile (CFLAGS-tst-thread-exit-clobber.o): Compile in
+ C++11 mode.
+ (LDLIBS-tst-thread-exit-clobber): Link with libstdc++.
+ (tests): Add tst-thread-exit-clobber.
+ [!CXX] (tests-unsupported): Add tst-thread-exit-clobber.
+
+2018-01-12 Dmitry V. Levin <ldv@altlinux.org>
+
+ [BZ #22679]
+ CVE-2018-1000001
+ * sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Fall back to
+ generic_getcwd if the path returned by getcwd syscall is not absolute.
+ * io/tst-getcwd-abspath.c: New test.
+ * io/Makefile (tests): Add tst-getcwd-abspath.
+
+2017-12-19 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+ James Clarke <jrtc27@jrtc27.com>
+
+ [BZ #22603]
+ * sysdeps/ia64/memchr.S (__memchr): Avoid overflow in pointer
+ addition.
+
+2018-01-08 Dmitry V. Levin <ldv@altlinux.org>
+
+ * sysdeps/unix/sysv/linux/tst-ttyname.c (do_in_chroot_1): Skip the
+ test instead of failing in case of ENOENT returned by posix_openpt.
+
+2017-12-29 Aurelien Jarno <aurelien@aurel32.net>
+
+ [BZ #22611]
+ * malloc/tst-realloc.c (do_test): Remove the test checking that errno
+ is unchanged on success.
+
+2017-12-30 Aurelien Jarno <aurelien@aurel32.net>
+ Dmitry V. Levin <ldv@altlinux.org>
+
+ [BZ #22625]
+ CVE-2017-16997
+ * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic
+ string token expansion. Check for NULL pointer or empty string possibly
+ returned by expand_dynamic_string_token.
+ (decompose_rpath): Check for empty path after dynamic string
+ token expansion.
+
+2017-12-18 Dmitry V. Levin <ldv@altlinux.org>
+
+ [BZ #22627]
+ * elf/dl-load.c (_dl_init_paths): Remove _dl_dst_substitute preparatory
+ code and invocation.
+
+2017-11-18 Florian Weimer <fweimer@redhat.com>
+
+ * sysdeps/unix/sysv/linux/tst-ttyname.c
+ (become_root_in_mount_ns): Remove.
+ (do_in_chroot_1): Call support_enter_mount_namespace.
+ (do_in_chroot_2): Likewise.
+ (do_test): Call support_become_root early.
+
+2017-11-15 Luke Shumaker <lukeshu@parabola.nu>
+
+ [BZ #22145]
+ * sysdeps/unix/sysv/linux/tst-ttyname.c: New file.
+ * sysdeps/unix/sysv/linux/Makefile: Add tst-ttyname to tests.
+
+2017-11-15 Luke Shumaker <lukeshu@parabola.nu>
+
+ [BZ #22145]
+ * sysdeps/unix/sysv/linux/ttyname.c (ttyname):
+ Defer is_pty check until end of the function.
+ * sysdeps/unix/sysv/linux/ttyname_r.c (__ttyname_r): Likewise.
+
+2017-11-15 Luke Shumaker <lukeshu@parabola.nu>
+
+ [BZ #22145]
+ * sysdeps/unix/sysv/linux/ttyname.h (is_mytty): New function.
+ * sysdeps/unix/sysv/linux/ttyname.c (getttyname): Call is_mytty.
+ (ttyname): Likewise.
+ * sysdeps/unix/sysv/linux/ttyname_r.c (getttyname_r): Likewise.
+ (__ttyname_r): Likewise.
+
+2017-11-15 Luke Shumaker <lukeshu@parabola.nu>
+
+ * sysdeps/unix/sysv/linux/ttyname.h (is_pty): Change return type from
+ int to bool.
+
+2017-11-15 Luke Shumaker <lukeshu@parabola.nu>
+
+ * sysdeps/unix/sysv/linux/ttyname.h (is_pty): Update doc reference.
+
+2017-11-15 Luke Shumaker <lukeshu@parabola.nu>
+
+ * manual/terminal.texi (Is It a Terminal):
+ Mention ENODEV for ttyname and ttyname_r.
+
+2017-12-14 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22607]
+ CVE-2017-1000409
+ * elf/dl-load.c (_dl_init_paths): Compute number of components in
+ the expanded path string.
+
+2017-12-14 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22606]
+ CVE-2017-1000408
+ * elf/dl-load.c (system_dirs): Update comment.
+ (nsystem_dirs_len): Use array_length.
+ (_dl_init_paths): Use nsystem_dirs_len to compute the array size.
+
+2017-11-02 Florian Weimer <fweimer@redhat.com>
+
+ Add array_length and array_end macros.
+ * include/array_length.h: New file.
+
+2017-10-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * sysdeps/i386/fpu/libm-test-ulps: Regenerated for GCC 7 with
+ "-O2 -march=i586".
+
+2017-12-13 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ * sysdeps/ia64/fpu/libm-test-ulps: Update.
+
+2017-12-12 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #21672]
+ * nptl/allocatestack.c [_STACK_GROWS_DOWN] (setup_stack_prot):
+ Set to use !NEED_SEPARATE_REGISTER_STACK as well.
+ (advise_stack_range): New function.
+ * nptl/pthread_create.c (START_THREAD_DEFN): Move logic to mark
+ stack non required to advise_stack_range at allocatestack.c
+
+2017-12-12 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+ Sergei Trofimovich <slyfox@inbox.ru>
+
+ [BZ #21908]
+ * sysdeps/unix/sysv/linux/m68k/mmap_internal.h (MMAP2_PAGE_SHIFT):
+ Rename to MMAP2_PAGE_UNIT.
+ * sysdeps/unix/sysv/linux/ia64/mmap_internal.h: New file.
+ * sysdeps/unix/sysv/linux/mmap.c: Include mmap_internal iff
+ __OFF_T_MATCHES_OFF64_T is not defined.
+ * sysdeps/unix/sysv/linux/mmap_internal.h (page_unit): Declare as
+ uint64_t.
+ (MMAP2_PAGE_UNIT) [MMAP2_PAGE_UNIT == -1]: Redefine to page_unit.
+ (page_unit) [MMAP2_PAGE_UNIT != -1]: Remove definition.
+
+2017-12-12 James Clarke <jrtc27@jrtc27.com>
+
+ * sysdeps/unix/sysv/linux/ia64/ipc_priv.h: New file defining
+ __IPC_64 to 0 to avoid IPC_64 being set.
+
+2017-10-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #22052]
+ * malloc/hooks.c (realloc_check): Use DIAG_IGNORE_NEEDS_COMMENT
+ to silence -O3 -Wall warning with GCC 7.
+
+2017-11-30 Arjun Shankar <arjun@redhat.com>
+
+ [BZ #22375]
+ CVE-2017-17426
+ * malloc/malloc.c (__libc_malloc): Use checked_request2size
+ instead of request2size.
+
+2017-11-02 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22332]
+ * posix/tst-glob-tilde.c (do_noescape): New variable.
+ (one_test): Process it.
+ (do_test): Set do_noescape. Add unescaping test case.
+
+2017-10-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ [BZ #22332]
+ * posix/glob.c (__glob): Fix buffer overflow during GLOB_TILDE
+ unescaping.
+
+2017-10-23 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (_int_malloc): Add SINGLE_THREAD_P path.
+
+2017-10-23 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (__libc_malloc): Add SINGLE_THREAD_P path.
+ (__libc_realloc): Likewise.
+ (_mid_memalign): Likewise.
+ (__libc_calloc): Likewise.
+
+2017-10-20 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (sysdep-cancel.h): Add include.
+
+2017-10-20 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (_int_free): Add SINGLE_THREAD_P fast paths.
+
+2017-10-19 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (_int_free): Fix deadlock bug in consistency check.
+
+2017-08-31 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/malloc.c (_int_free): Remove locked variable and related
+ asserts.
+
+2017-08-31 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/malloc.c (top_check): Change return type to void. Remove
+ internal_function.
+ * malloc/hooks.c (top_check): Likewise.
+ (malloc_check, realloc_check, memalign_check): Adjust.
+
+2017-08-30 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/malloc.c (ARENA_CORRUPTION_BIT, arena_is_corrupt)
+ (set_arena_corrupt): Remove definitions.
+ (mtrim): Do not check for corrupt arena.
+ * malloc/arena.c (arena_lock, reused_arena, arena_get_retry):
+ Likewise.
+
+2017-08-30 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21754]
+ * malloc/arena.c (TUNABLE_CALLBACK set_mallopt_check): Do not set
+ check_action.
+ (ptmalloc_init): Do not set or use check_action.
+ * malloc/hooks.c (malloc_check_get_size, realloc_check): Adjust
+ call to malloc_printerr. Remove return statement.
+ (free_check): Likewise. Remove arena unlock.
+ (top_check): Update comment. Adjust call to malloc_printerr.
+ Remove heap repair code.
+ * malloc/malloc.c (unlink): Adjust calls to malloc_printerr.
+ (DEFAULT_CHECK_ACTION, check_action): Remove definitions.
+ (sysmalloc): Adjust call to malloc_printerr.
+ (munmap_chunk, __libc_realloc): Likewise. Remove return
+ statement.
+ (_int_malloc, int_realloc): Likewise. Remove errstr variable.
+ Remove errout label and corresponding gotos.
+ (_int_free): Likewise. Remove arena unlock.
+ (do_set_mallopt_check): Do not set check_action.
+ (malloc_printerr): Adjust parameter list. Do not mark arena as
+ corrupt.
+ * manual/memory.texi (Malloc Tunable Parameters): Remove TODO
+ comment.
+ * manual/probes.texi (Memory Allocation Probes): Remove
+ memory_mallopt_check_action.
+
+2017-08-30 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21754]
+ * malloc/malloc.c (malloc_printerr): Always terminate the process,
+ without printing a backtrace. Do not leak any information in the
+ error message.
+ * manual/memory.texi (Heap Consistency Checking): Update.
+ * manual/tunables.texi (Memory Allocation Tunables): Likewise.
+
+2017-11-17 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
+
+ * sysdeps/powerpc/bits/hwcap.h (PPC_FEATURE2_HTM_NO_SUSPEND): New
+ macro.
+
+2017-08-09 Andreas Schwab <schwab@suse.de>
+
+ * nptl/Makefile (tests) [$(build-shared) = yes]: Add
+ tst-compat-forwarder.
+ (modules-names): Add tst-compat-forwarder-mod.
+ ($(objpfx)tst-compat-forwarder): Depend on
+ $(objpfx)tst-compat-forwarder-mod.so.
+ * nptl/tst-compat-forwarder.c: New file.
+ * nptl/tst-compat-forwarder-mod.c: New file.
+
+2017-08-09 Andreas Schwab <schwab@suse.de>
+
+ * sysdeps/unix/sysv/linux/s390/pt-longjmp.c: Update reference to
+ renamed alias.
+
+2017-08-08 Andreas Schwab <schwab@suse.de>
+
+ [BZ #21041]
+ * nptl/pt-longjmp.c (longjmp, siglongjmp): Don't use IFUNC resolver.
+ * nptl/pt-system.c (system): Likewise.
+
+2017-11-21 Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+
+ * sysdeps/powerpc/powerpc64/power7/memcpy.S: Replace
+ lxvd2x/stxvd2x with lvx/stvx.
+ * sysdeps/powerpc/powerpc64/power7/memmove.S: Likewise.
+
+2017-10-04 Florian Weimer <fweimer@redhat.com>
+
+ * scripts/check-local-headers.sh: Ignore nspr4 header file
+ directory in addition to nspr.
+
+2017-10-04 Guido Trentalancia <guido@trentalancia.net>
+
+ [BZ #17956]
+ * configure.ac (--enable-nss-crypt): Use NSPR include directory.
+ * configure: Regenerate.
+ * crypt/Makefile (nss-cpp-flags): New variable.
+ (CPPFLAGS-sha256-crypt.c, CPPFLAGS-sha512-crypt.c)
+ (CPPFLAGS-md5-crypt.c): Use it.
+ * scripts/check-local-headers.sh: Ignore nspr header file
+ directory.
+
+2017-10-18 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (malloc_state): Use int for have_fastchunks since
+ not all targets support atomics on bool.
+
+2017-10-17 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (FASTCHUNKS_BIT): Remove.
+ (have_fastchunks): Remove.
+ (clear_fastchunks): Remove.
+ (set_fastchunks): Remove.
+ (malloc_state): Add have_fastchunks.
+ (malloc_init_state): Use have_fastchunks.
+ (do_check_malloc_state): Remove incorrect invariant checks.
+ (_int_malloc): Use have_fastchunks.
+ (_int_free): Likewise.
+ (malloc_consolidate): Likewise.
+
+2017-10-17 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * malloc/malloc.c (tcache_put): Inline.
+ (tcache_get): Inline.
+
+2017-10-13 James Clarke <jrtc27@jrtc27.com>
+
+ * sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela):
+ Assign sym_map to be map for local symbols, as TLS relocations
+ use sym_map to determine whether the symbol is defined and to
+ extract the TLS information.
+ * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise.
+ * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise.
+
+2017-08-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * sysdeps/x86_64/fpu/libm-test-ulps: Regenerated.
+
+2017-11-07 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #22298]
+ * nptl/allocatestack.c (allocate_stack): Check if
+ __PTHREAD_MUTEX_HAVE_PREV is non-zero, instead if
+ __PTHREAD_MUTEX_HAVE_PREV is defined.
+ * nptl/descr.h (pthread): Likewise.
+ * nptl/nptl-init.c (__pthread_initialize_minimal_internal):
+ Likewise.
+ * nptl/pthread_create.c (START_THREAD_DEFN): Likewise.
+ * sysdeps/nptl/fork.c (__libc_fork): Likewise.
+ * sysdeps/nptl/pthread.h (PTHREAD_MUTEX_INITIALIZER): Likewise.
+ * sysdeps/nptl/bits/thread-shared-types.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION): New
+ defines.
+ (__pthread_internal_list): Check __PTHREAD_MUTEX_USE_UNION instead
+ of __WORDSIZE for internal layout.
+ (__pthread_mutex_s): Check __PTHREAD_MUTEX_NUSERS_AFTER_KIND instead
+ of __WORDSIZE for internal __nusers layout and __PTHREAD_MUTEX_USE_UNION
+ instead of __WORDSIZE whether to use an union for __spins and __list
+ fields.
+ (__PTHREAD_MUTEX_HAVE_PREV): Define also for __PTHREAD_MUTEX_USE_UNION
+ case.
+ * sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION): New
+ defines.
+ * sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/arm/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/mips/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/s390/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/sh/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/tile/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+ * sysdeps/x86/nptl/bits/pthreadtypes-arch.h
+ (__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
+ Likewise.
+
+ * nptl/pthreadP.h (ASSERT_PTHREAD_STRING,
+ ASSERT_PTHREAD_INTERNAL_OFFSET): New macro.
+ * nptl/pthread_mutex_init.c (__pthread_mutex_init): Add build time
+ checks for internal pthread_mutex_t offsets.
+ * sysdeps/aarch64/nptl/pthread-offsets.h
+ (__PTHREAD_MUTEX_NUSERS_OFFSET, __PTHREAD_MUTEX_KIND_OFFSET,
+ __PTHREAD_MUTEX_SPINS_OFFSET, __PTHREAD_MUTEX_ELISION_OFFSET,
+ __PTHREAD_MUTEX_LIST_OFFSET): New macro.
+ * sysdeps/alpha/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/arm/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/hppa/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/i386/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/ia64/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/m68k/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/microblaze/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/mips/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/nios2/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/powerpc/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/s390/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/sh/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/sparc/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/tile/nptl/pthread-offsets.h: Likewise.
+ * sysdeps/x86_64/nptl/pthread-offsets.h: Likewise.
+
+ * sysdeps/unix/sysv/linux/spawni.c (__spawnix): Use 0 instead of
+ WNOHANG in waitpid call.
+
+ [BZ #22273]
+ * sysdeps/unix/sysv/linux/spawni.c (__spawnix): Handle the case where
+ the auxiliary process is terminated by a signal before calling _exit
+ or execve.
+
+2017-09-13 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ * sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c: New file.
+ * sysdeps/unix/sysv/linux/alpha/Makefile
+ [$(subdir) = csu] (sysdep_routines): Remove rule.
+
+2017-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ * sysdeps/unix/sysv/linux/arm/glob64.c: Remove file.
+ * sysdeps/unix/sysv/linux/i386/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/m68k/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/wordsize-64/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/x32/glob.c: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise.
+ * sysdeps/wordsize-64/glob.c: Likewise.
+ * sysdeps/wordsize-64/glob64.c: Likewise.
+ * sysdeps/wordsize-64/globfree.c: Likewise.
+ * sysdeps/wordsize-64/globfree64.c: Likewise.
+ * sysdeps/unix/sysv/linux/glob.c: New file.
+ * sysdeps/unix/sysv/linux/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/globfree.c: Likewise.
+ * sysdeps/unix/sysv/linux/globfree64.c: Likewise.
+ * sysdeps/unix/sysv/linux/s390/s390-32/glob64.c: Likewise.
+ * sysdeps/unix/sysv/linux/oldglob.c [SHLIB_COMPAT]: Also
+ adds !GLOB_NO_OLD_VERSION as an extra condition.
+ * sysdeps/unix/sysv/linux/i386/alphasort64.c: Include olddirent.h
+ using relative path instead of absolute one.
+ * sysdeps/unix/sysv/linux/i386/getdents64.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/readdir64.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/versionsort64.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/olddirent.h: Move to ...
+ * sysdeps/unix/sysv/linux//olddirent.h: ... here.
+
+2017-10-26 Valery Reznic <valery_reznic@yahoo.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #22299]
+ * sysdeps/x86/cpu-features.c (init_cpu_features): Don't set
+ GLRO(dl_platform) to NULL.
+ * sysdeps/x86_64/Makefile (tests): Add tst-platform-1.
+ (modules-names): Add tst-platformmod-1 and
+ x86_64/tst-platformmod-2.
+ (CFLAGS-tst-platform-1.c): New.
+ (CFLAGS-tst-platformmod-1.c): Likewise.
+ (CFLAGS-tst-platformmod-2.c): Likewise.
+ (LDFLAGS-tst-platformmod-2.so): Likewise.
+ ($(objpfx)tst-platform-1): Likewise.
+ ($(objpfx)tst-platform-1.out): Likewise.
+ (tst-platform-1-ENV): Likewise.
+ ($(objpfx)x86_64/tst-platformmod-2.os): Likewise.
+ * sysdeps/x86_64/tst-platform-1.c: New file.
+ * sysdeps/x86_64/tst-platformmod-1.c: Likewise.
+ * sysdeps/x86_64/tst-platformmod-2.c: Likewise.
+
+2017-10-23 Alexey Makhalov <amakhalov@vmware.com>
+
+ * elf/dl-tunables.c (do_tunable_update_val): Range checking fix.
+ * scripts/gen-tunables.awk: Set unspecified minval and/or maxval
+ values to correct default value for given type.
+
+2017-10-19 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #22322]
+ * sysdeps/mips/bits/long-double.h: Move to ....
+ * sysdeps/mips/ieee754/bits/long-double.h: ... here.
+
+2017-10-17 Romain Naour <romain.naour@gmail.com> (tiny change)
+
+ [BZ #22296]
+ * math/math.h: Let signbit use the builtin in C++ mode with gcc
+ < 6.x
+
+2017-10-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #21265]
+ * sysdeps/x86/cpu-features-offsets.sym (XSAVE_STATE_SIZE_OFFSET):
+ New.
+ * sysdeps/x86/cpu-features.c: Include <libc-pointer-arith.h>.
+ (get_common_indeces): Set xsave_state_size, xsave_state_full_size
+ and bit_arch_XSAVEC_Usable if needed.
+ (init_cpu_features): Remove bit_arch_Use_dl_runtime_resolve_slow
+ and bit_arch_Use_dl_runtime_resolve_opt.
+ * sysdeps/x86/cpu-features.h (bit_arch_Use_dl_runtime_resolve_opt):
+ Removed.
+ (bit_arch_Use_dl_runtime_resolve_slow): Likewise.
+ (bit_arch_Prefer_No_AVX512): Updated.
+ (bit_arch_MathVec_Prefer_No_AVX512): Likewise.
+ (bit_arch_XSAVEC_Usable): New.
+ (STATE_SAVE_OFFSET): Likewise.
+ (STATE_SAVE_MASK): Likewise.
+ [__ASSEMBLER__]: Include <cpu-features-offsets.h>.
+ (cpu_features): Add xsave_state_size and xsave_state_full_size.
+ (index_arch_Use_dl_runtime_resolve_opt): Removed.
+ (index_arch_Use_dl_runtime_resolve_slow): Likewise.
+ (index_arch_XSAVEC_Usable): New.
+ * sysdeps/x86/cpu-tunables.c (TUNABLE_CALLBACK (set_hwcaps)):
+ Support XSAVEC_Usable. Remove Use_dl_runtime_resolve_slow.
+ * sysdeps/x86_64/Makefile (tst-x86_64-1-ENV): New if tunables
+ is enabled.
+ * sysdeps/x86_64/dl-machine.h (elf_machine_runtime_setup):
+ Replace _dl_runtime_resolve_sse, _dl_runtime_resolve_avx,
+ _dl_runtime_resolve_avx_slow, _dl_runtime_resolve_avx_opt,
+ _dl_runtime_resolve_avx512 and _dl_runtime_resolve_avx512_opt
+ with _dl_runtime_resolve_fxsave, _dl_runtime_resolve_xsave and
+ _dl_runtime_resolve_xsavec.
+ * sysdeps/x86_64/dl-trampoline.S (DL_RUNTIME_UNALIGNED_VEC_SIZE):
+ Removed.
+ (DL_RUNTIME_RESOLVE_REALIGN_STACK): Check STATE_SAVE_ALIGNMENT
+ instead of VEC_SIZE.
+ (REGISTER_SAVE_BND0): Removed.
+ (REGISTER_SAVE_BND1): Likewise.
+ (REGISTER_SAVE_BND3): Likewise.
+ (REGISTER_SAVE_RAX): Always defined to 0.
+ (VMOV): Removed.
+ (_dl_runtime_resolve_avx): Likewise.
+ (_dl_runtime_resolve_avx_slow): Likewise.
+ (_dl_runtime_resolve_avx_opt): Likewise.
+ (_dl_runtime_resolve_avx512): Likewise.
+ (_dl_runtime_resolve_avx512_opt): Likewise.
+ (_dl_runtime_resolve_sse): Likewise.
+ (_dl_runtime_resolve_sse_vex): Likewise.
+ (USE_FXSAVE): New.
+ (_dl_runtime_resolve_fxsave): Likewise.
+ (USE_XSAVE): Likewise.
+ (_dl_runtime_resolve_xsave): Likewise.
+ (USE_XSAVEC): Likewise.
+ (_dl_runtime_resolve_xsavec): Likewise.
+ * sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve_avx512):
+ Removed.
+ (_dl_runtime_resolve_avx512_opt): Likewise.
+ (_dl_runtime_resolve_avx): Likewise.
+ (_dl_runtime_resolve_avx_opt): Likewise.
+ (_dl_runtime_resolve_sse): Likewise.
+ (_dl_runtime_resolve_sse_vex): Likewise.
+ (_dl_runtime_resolve_fxsave): New.
+ (_dl_runtime_resolve_xsave): Likewise.
+ (_dl_runtime_resolve_xsavec): Likewise.
+
+2017-10-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #22093]
+ * sysdeps/x86/cpu-features.c (init_cpu_features): Initialize
+ GLRO(dl_hwcap) to HWCAP_X86_64 for x86-64.
+ * sysdeps/x86/dl-hwcap.h (HWCAP_COUNT): Updated.
+ (HWCAP_IMPORTANT): Likewise.
+ (HWCAP_X86_64): New enum.
+ (HWCAP_X86_AVX512_1): Updated.
+ * sysdeps/x86/dl-procinfo.c (_dl_x86_hwcap_flags): Add "x86_64".
+ * sysdeps/x86_64/Makefile (tests): Add tst-x86_64-1.
+ (modules-names): Add x86_64/tst-x86_64mod-1.
+ (LDFLAGS-tst-x86_64mod-1.so): New.
+ ($(objpfx)tst-x86_64-1): Likewise.
+ ($(objpfx)x86_64/tst-x86_64mod-1.os): Likewise.
+ (tst-x86_64-1-clean): Likewise.
+ * sysdeps/x86_64/tst-x86_64-1.c: New file.
+ * sysdeps/x86_64/tst-x86_64mod-1.c: Likewise.
+
+2017-10-21 Florian Weimer <fweimer@redhat.com>
+
+ * posix/Makefile (tests): Add tst-glob-tilde.
+ (tests-special): Add tst-glob-tilde-mem.out
+ (tst-glob-tilde-ENV): Set MALLOC_TRACE.
+ (tst-glob-tilde-mem.out): Add mtrace check.
+ * posix/tst-glob-tilde.c: New file.
+
+2017-10-20 Paul Eggert <eggert@cs.ucla.edu>
+
+ [BZ #22320]
+ CVE-2017-15670
+ * posix/glob.c (__glob): Fix one-byte overflow.
+
+2017-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #1062]
+ [BZ #22325]
+ CVE-2017-15671
+ * posix/Makefile (routines): Add globfree, globfree64, and
+ glob_pattern_p.
+ * posix/flexmember.h: New file.
+ * posix/glob_internal.h: Likewise.
+ * posix/glob_pattern_p.c: Likewise.
+ * posix/globfree.c: Likewise.
+ * posix/globfree64.c: Likewise.
+ * sysdeps/gnu/globfree64.c: Likewise.
+ * sysdeps/unix/sysv/linux/alpha/globfree.c: Likewise.
+ * sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise.
+ * sysdeps/unix/sysv/linux/oldglob.c: Likewise.
+ * sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise.
+ * sysdeps/wordsize-64/globfree.c: Likewise.
+ * sysdeps/wordsize-64/globfree64.c: Likewise.
+ * posix/glob.c (HAVE_CONFIG_H): Use !_LIBC instead.
+ [NDEBUG): Remove comments.
+ (GLOB_ONLY_P, _AMIGA, VMS): Remove define.
+ (dirent_type): New type. Use uint_fast8_t not
+ uint8_t, as C99 does not require uint8_t.
+ (DT_UNKNOWN, DT_DIR, DT_LNK): New macros.
+ (struct readdir_result): Use dirent_type. Do not define skip_entry
+ unless it is needed; this saves a byte on platforms lacking d_ino.
+ (readdir_result_type, readdir_result_skip_entry):
+ New functions, replacing ...
+ (readdir_result_might_be_symlink, readdir_result_might_be_dir):
+ these functions, which were removed. This makes the callers
+ easier to read. All callers changed.
+ (D_INO_TO_RESULT): Now empty if there is no d_ino.
+ (size_add_wrapv, glob_use_alloca): New static functions.
+ (glob, glob_in_dir): Check for size_t overflow in several places,
+ and fix some size_t checks that were not quite right.
+ Remove old code using SHELL since Bash no longer
+ uses this.
+ (glob, prefix_array): Separate MS code better.
+ (glob_in_dir): Remove old Amiga and VMS code.
+ (globfree, __glob_pattern_type, __glob_pattern_p): Move to
+ separate files.
+ (glob_in_dir): Do not rely on undefined behavior in accessing
+ struct members beyond their bounds. Use a flexible array member
+ instead
+ (link_stat): Rename from link_exists2_p and return -1/0 instead of
+ 0/1. Caller changed.
+ (glob): Fix memory leaks.
+ * posix/glob64 (globfree64): Move to separate file.
+ * sysdeps/gnu/glob64.c (NO_GLOB_PATTERN_P): Remove define.
+ (globfree64): Remove hidden alias.
+ * sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Add
+ oldglob.
+ * sysdeps/unix/sysv/linux/alpha/glob.c (__new_globfree): Move to
+ separate file.
+ * sysdeps/unix/sysv/linux/i386/glob64.c (NO_GLOB_PATTERN_P): Remove
+ define.
+ Move compat code to separate file.
+ * sysdeps/wordsize-64/glob.c (globfree): Move definitions to
+ separate file.
+
+2017-08-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #18822]
+ * sysdeps/unix/sysv/linux/i386/glob64.c (__old_glob64): Add
+ libc_hidden_proto and libc_hidden_def.
+
+2017-10-20 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22321]
+ sysconf: Fix missing definition of UIO_MAXIOV on Linux.
+ * sysdeps/posix/sysconf.c: Include <sys/uio.h>.
+ * sysdeps/unix/sysv/linux/Makefile (tests): Add tst-sysconf-iov_max.
+ (tst-sysconf-iov_max): Link with tst-sysconf-iov_max-uapi.o.
+ * sysdeps/unix/sysv/linux/tst-sysconf-iov_max.c: New file.
+ * sysdeps/unix/sysv/linux/tst-sysconf-iov_max-uapi.c: Likewise.
+
+2017-10-11 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22078]
+ Avoid large NSS buffers with many addresses, aliases.
+ * nss/nss_files/files-hosts.c (gethostbyname3_multi): Rewrite
+ using dynarrays and struct alloc_buffer.
+ * nss/Makefile (tests): Add tst-nss-files-hosts-multi.
+ (tst-nss-files-hosts-multi): Link with -ldl.
+ * nss/tst-nss-files-hosts-multi.c: New file.
+
+2017-10-11 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #18023]
+ * nss/nss_files/files-hosts.c (gethostbyname3_multi): Use struct
+ scratch_buffer. Eliminate gotos.
+
+2017-10-10 Florian Weimer <fweimer@redhat.com>
+
+ * nss/nss_files/files-hosts.c (gethostbyname3_multi): New
+ function.
+ (_nss_files_gethostbyname3_r): Call it.
+
+2017-09-21 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ * sysdeps/ieee754/ldbl-128/e_lgammal_r.c (__ieee754_lgammal_r):
+ Remove conditionals on LDBL_MANT_DIG.
+ * sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c
+ (__ieee754_lgammal_r): Likewise.
+
+2017-09-21 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ * sysdeps/ieee754/ldbl-128ibm/e_expl.c: Remove definitions of
+ _Float128 and L().
+ * sysdeps/ieee754/ldbl-128ibm/e_j0l.c: Remove definitions of
+ _Float128 and L(). Replace _Float128 with long double and L(x)
+ with xL, throughout the file.
+ * sysdeps/ieee754/ldbl-128ibm/e_j1l.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/t_expl.h: Likewise.
+
+2017-09-21 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ * sysdeps/ieee754/ldbl-128ibm/e_expl.c: Include tables from
+ sysdeps/ieee754/ldbl-128ibm.
+ * sysdeps/ieee754/ldbl-128ibm/e_j0l.c: Copy contents from the
+ equivalent implementation in sysdeps/ieee754/ldbl-128/ instead
+ of including it. Keep _Float128 and L() intact. These will be
+ reviewed by a separate patch.
+ * sysdeps/ieee754/ldbl-128ibm/e_j1l.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/t_expl.h: Likewise.
+
+2017-09-21 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ * sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+ (__finitef128): Define to __redirect___finitef128.
+ * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+ (__isinff128): Define to __redirect___isinff128.
+ * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+ (__isnanf128): Define to __redirect___isnanf128.
+
+2017-09-21 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ * sysdeps/powerpc/powerpc64le/Makefile
+ (CFLAGS-tst-strtod-nan-locale.c): New variable.
+ (CFLAGS-tst-wcstod-nan-locale.c): New variable.
+
+2017-10-10 Steve Ellcey <sellcey@cavium.com>
+
+ * sysdeps/unix/sysv/linux/aarch64/cpu-features.c (get_midr_from_mcpu):
+ Use strcmp instead of tunable_is_name.
+
+2017-10-10 Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+ * sysdeps/aarch64/multiarch/Makefile (sysdep_routines): Add
+ memmove_falkor.
+ * sysdeps/aarch64/multiarch/ifunc-impl-list.c
+ (__libc_ifunc_impl_list): Likewise.
+ * sysdeps/aarch64/multiarch/memmove.c: Likewise.
+ * sysdeps/aarch64/multiarch/memmove_falkor.S: New file.
+
+ * benchtests/bench-memmove-walk.c: New file.
+ * benchtests/Makefile (string-benchset): Add it.
+
+ * benchtests/bench-memset-walk.c: New file.
+ * benchtests/Makefile (string-benchset): Add it.
+
+ * benchtests/bench-memcpy-walk.c: New file.
+ * benchtests/Makefile (string-benchset): Add it.
+
+ * po/sv.po: Update translations.
+ * po/fr.po: Likewise.
+
+ * sysdeps/aarch64/multiarch/memcpy_falkor.S: Fix code style in
+ comments.
+
+ * manual/tunables.texi (Tunable glibc.tune.cpu): Add falkor.
+ * sysdeps/aarch64/multiarch/Makefile (sysdep_routines): Add
+ memcpy_falkor.
+ * sysdeps/aarch64/multiarch/ifunc-impl-list.c (MAX_IFUNC):
+ Bump.
+ (__libc_ifunc_impl_list): Add __memcpy_falkor.
+ * sysdeps/aarch64/multiarch/memcpy.c: Likewise.
+ * sysdeps/aarch64/multiarch/memcpy_falkor.S: New file.
+ * sysdeps/unix/sysv/linux/aarch64/cpu-features.c (cpu_list):
+ Add falkor.
+ * sysdeps/unix/sysv/linux/aarch64/cpu-features.h (IS_FALKOR):
+ New macro.
+
+2017-10-06 Carlos O'Donell <carlos@redhat.com>
+
+ [BZ #22111]
+ * malloc/malloc.c (tcache_shutting_down): Use bool type.
+ (tcache_thread_freeres): Set tcache_shutting_down before
+ freeing the tcache.
+ * malloc/Makefile (tests): Add tst-malloc-tcache-leak.
+ * malloc/tst-malloc-tcache-leak.c: New file.
+
+2017-10-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * math/test-math-iscanonical.cc (error): Replace bool with int.
+ (do_test): Return errors != 0.
+
+2017-10-03 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ [BZ #22235]
+ * math/math.h: Trivial fix for unbalanced parentheses in comment.
+ * math/Makefile [CXX] (tests): Add test-math-iscanonical.cc.
+ (CFLAGS-test-math-iscanonical.cc): New variable.
+ * math/test-math-iscanonical.cc: New file.
+ * sysdeps/ieee754/ldbl-96/bits/iscanonical.h (iscanonical):
+ Provide a C++ implementation based on function overloading,
+ rather than using __MATH_TG, which uses C-only builtins.
+ * sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h (iscanonical):
+ Likewise.
+ * sysdeps/powerpc/powerpc64le/Makefile
+ (CFLAGS-test-math-iscanonical.cc): New variable.
+
+2017-08-22 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #21987]
+ * sysdeps/unix/sysv/linux/sparc/bits/long-double.h: Remove file
+ and copy to ...
+ * sysdeps/unix/sysv/linux/sparc/sparc32/bits/long-double.h:
+ ... here.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/bits/long-double.h:
+ ... and here.
+
+2017-09-28 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #22225]
+ * sysdeps/ieee754/dbl-64/s_nearbyint.c (__nearbyint): Use
+ math_opt_barrier on argument when doing arithmetic on it.
+ * sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c (__nearbyint):
+ Likewise. Use math_force_eval not math_opt_barrier after
+ arithmetic.
+ * sysdeps/ieee754/flt-32/s_nearbyintf.c (__nearbyintf): Use
+ math_opt_barrier on argument when doing arithmetic on it.
+ * sysdeps/ieee754/ldbl-128/s_nearbyintl.c (__nearbyintl):
+ Likewise.
+
+2017-09-22 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ [BZ #22146]
+ math/math.h: Let fpclassify use the builtin in C++ mode, even
+ when optimazing for size.
+
+2017-08-22 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
+ * include/libc-symbols.h: [!defined HAVE_GCC_IFUNC] (__ifunc):
+ Change the return type of the ifunc resolver to match the return
+ type of the target function.
+
+2017-08-22 Martin Sebor <msebor@redhat.com>
+
+ * include/libc-symbols.h (__ifunc_resolver): Declare resolver
+ to return a pointer to the same type as the target function.
+
+2017-08-03 Alan Modra <amodra@gmail.com>
+
+ * sysdeps/powerpc/mod-tlsopt-powerpc.c: Extract from
+ tst-tlsopt-powerpc.c with function name change and no test harness.
+ * sysdeps/powerpc/tst-tlsopt-powerpc.c: Remove body of test.
+ Call tls_get_addr_opt_test.
+ * sysdeps/powerpc/Makefile (LDFLAGS-tst-tlsopt-powerpc): Don't define.
+ (modules-names): Add mod-tlsopt-powerpc.
+ (mod-tlsopt-powerpc.so-no-z-defs): Define.
+ (tst-tlsopt-powerpc): Depend on .so.
+ * sysdeps/powerpc/powerpc64/tls-macros.h (__TLS_GET_ADDR): Don't
+ define. Expand use in TLS_GD and TLS_LD.
+
+2017-09-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #21982]
+ * string/stratcliff.c (do_test): Declare size, nchars, inner,
+ middle and outer with size_t instead of int. Repleace %d and
+ %Zd with %zu in printf. Update "MAX (0, nchars - 128)" and
+ "MAX (outer, nchars - 64)" to support unsigned outer and
+ nchars. Also exit loop when outer == 0.
+
+2017-09-08 Markus Trippelsdorf <markus@trippelsdorf.de>
+
+ * sysdeps/x86_64/fpu/libm-test-ulps: Update for AMD Ryzen.
+
+2017-09-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * resolv/tst-resolv-qtypes.c (domain): Changed to
+ "const char domain[] =".
+
+2017-08-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #22051]
+ * Makerules (build-module-helper-objlist): Filter out
+ $(elf-objpfx)sofini.os.
+ (build-shlib-objlist): Append $(elf-objpfx)sofini.os if it is
+ needed.
+
+2017-08-30 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/dynarray_emplace_enlarge.c
+ (__libc_dynarray_emplace_enlarge): Set errno on overflow.
+ * malloc/dynarray_resize.c (__libc_dynarray_resize): Likewise.
+ * malloc/tst-dynarray.c (test_long_overflow): New function.
+ (do_test): Call it.
+
+2017-09-06 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/dynarray_emplace_enlarge.c
+ (__libc_dynarray_emplace_enlarge): Add missing else.
+
+2017-09-06 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22096]
+ * resolv/resolv_conf.c (__resolv_conf_attach): Do not free conf in
+ case of failure to obtain the global conf object.
+
+2017-09-06 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #22095]
+ * resolv/res_init.c (res_vinit_1): Avoid memory leak in case of
+ dynarray allocation failure.
+
+2017-09-06 Florian Weimer <fweimer@redhat.com>
+
+ Remove dead PTR IPv4-to-IPv6 mapping code from nss_dns.
+ * resolv/nss_dns/dns-host.c (getanswer_r): Remove dead code.
+ * resolv/tst-res_use_inet6.c (response_ptr_v4, response_ptr_v6):
+ New functions.
+ (response): Call them. Add 'p', '6' flag processing.
+ (test_reverse): New function.
+ (test_get2_any): Call it.
+ (test_no_inet6): Add 'p' test.
+ (test_inet6): Likewise.
+
+2017-09-06 Florian Weimer <fweimer@redhat.com>
+
+ Enhance tst-res_use_inet6 to test IPv4-to-IPv6 address mapping.
+ * resolv/tst-res_use_inet6.c (response): Process flags embedded in
+ the QNAME.
+ (test_gai): Adjust query names. Add additional tests.
+ (test_get2_any, test_get2_no_inet6, test_get2_inet6): Split from
+ test_get2. Adjust query names. Add additional tests.
+ (test_no_inet6): New function, extracted from threadfunc.
+ (threadfunc): Call test_get2_any, test_get2_inet6, test_no_inet6.
+ Add additional tests.
+
+2017-09-01 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21915]
+ [BZ #21922]
+ * sysdeps/posix/getaddrinfo.c (gethosts): Look at NSS function
+ result to determine success or failure, not the errno value.
+ * nss/Makefile (tests): Add tst-nss-files-hosts-erange.
+ (tst-nss-files-hosts-erange): Link with -ldl.
+ * nss/tst-nss-files-hosts-erange.c: New file.
+ * nss/tst-resolv-basic.c (response): Handle nodata.example.
+ (do_test): Add NO_DATA tests.
+ * resolv/tst-resolv-basic.c (test_nodata_nxdomain): New function.
+ (do_test): Call it.
+
+2017-09-01 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21922]
+ * sysdeps/posix/getaddrinfo.c (gaih_inet): Report EAI_NODATA error
+ coming from gethostbyname2_r.
+
+2017-09-01 Florian Weimer <fweimer@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c (gaih_inet): Only use h_errno if
+ status indicates it is set.
+
+2017-09-01 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #20532]
+ * sysdeps/posix/getaddrinfo.c (gaih_inet): Make reporting of NSS
+ function lookup failures more reliable.
+
+2017-09-01 Florian Weimer <fweimer@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c (gethosts): Use h_errno directly.
+ (getcanonname): Likewise.
+ (gaih_inet): Likewise.
+
+2017-09-01 Florian Weimer <fweimer@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c (gethosts): Use errno directly.
+ (getcanonname): Likewise.
+ (gaih_inet): Likewise.
+
+2017-08-08 Florian Weimer <fweimer@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c (gaih_inet): Remove unreachable
+ return statement.
+
+2017-08-22 Joseph Myers <joseph@codesourcery.com>
+
+ * assert/Makefile [$(have-cxx-thread_local)]: Move conditional
+ variable definitions above inclusion of ../Rules.
+
+2017-08-28 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
+ [BZ #21930]
+ * math/math.h [defined __cplusplus && defined __SUPPORT_SNAN__]
+ (iszero): New C++ implementation that does not use
+ fpclassify/__MATH_TG/__builtin_types_compatible_p, when
+ signaling nans are enabled, since __builtin_types_compatible_p
+ is a C-only feature.
+ * math/test-math-iszero.cc: When __HAVE_DISTINCT_FLOAT128 is
+ defined, include ieee754_float128.h for access to the union and
+ member ieee854_float128.ieee.
+ [__HAVE_DISTINCT_FLOAT128] (do_test): Call check_float128.
+ [__HAVE_DISTINCT_FLOAT128] (check_float128): New function.
+ * sysdeps/powerpc/powerpc64le/Makefile [subdir == math]
+ (CXXFLAGS-test-math-iszero.cc): Add -mfloat128 to the build
+ options of test-math-zero on powerpc64le.
+
+2017-08-24 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
+ * math/math.h [defined __cplusplus] (issignaling): In the long
+ double case, call __issignalingl only if __NO_LONG_DOUBLE_MATH
+ is not defined. Call __issignaling, otherwise.
+
+2017-08-22 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
+ * math/math.h [defined __cplusplus] (issignaling): Provide a C++
+ definition for issignaling that does not rely on __MATH_TG,
+ since __MATH_TG uses __builtin_types_compatible_p, which is only
+ available in C mode.
+ (CFLAGS-test-math-issignaling.cc): New variable.
+ * math/Makefile [CXX] (tests): Add test-math-issignaling.
+ * math/test-math-issignaling.cc: New test for C++ implementation
+ of type-generic issignaling.
+ * sysdeps/powerpc/powerpc64le/Makefile [subdir == math]
+ (CXXFLAGS-test-math-issignaling.cc): Add -mfloat128 to the build
+ options of test-math-issignaling on powerpc64le.
+
+2017-08-16 Andreas Schwab <schwab@suse.de>
+
+ [BZ #16750]
+ CVE-2009-5064
+ * elf/ldd.bash.in: Never run file directly.
+
+2017-08-10 Florian Weimer <fweimer@redhat.com>
+
+ * inet/net-internal.h (__inet6_scopeid_pton): Remove
+ attribute_hidden, internal_function.
+ * inet/inet6_scopeid_pton.c (__inet6_scopeid_pton): Remove
+ internal_function.
+
+2017-08-21 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21972]
+ * assert/assert.h (assert): Use static_cast (bool) for C++.
+ Use the ternary operator in the warning branch for GNU C.
+ * assert/Makefile (tests): Add tst-assert-c++, tst-assert-g++.
+ (CFLAGS-tst-assert-c++.o): Compile in C++11 mode.
+ (CFLAGS-tst-assert-g++.o): Compile in GnU C++11 mode.
+ (LDLIBS-tst-assert-c++, LDLIBS-tst-assert-g++): Link with libstdc++.
+ * assert/tst-assert-c++.cc, assert/tst-assert-g++.cc: New files.
+
+2017-08-18 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
+ * misc/sys/cdefs.h (__HAVE_GENERIC_SELECTION): Define to 0, if
+ in C++ mode.
+
+2017-08-18 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
+ [BZ #21930]
+ * math/math.h (isinf): Check if in C or C++ mode before using
+ __builtin_types_compatible_p, since this is a C mode feature.
+
+2017-08-10 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
+ [BZ #21941]
+ * sysdeps/powerpc/fpu/math_private.h (__ieee754_sqrtf128): Since
+ xssqrtqp requires operands to be in Vector Registers
+ (Altivec/VMX), replace the register constraint 'wq' with 'v'.
+ * sysdeps/powerpc/powerpc64le/power9/fpu/e_sqrtf128.c
+ (__ieee754_sqrtf128): Likewise.
+
+2017-08-11 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21242]
+ * assert/assert.h [__GNUC__ && !__STRICT_ANSI__] (assert):
+ Suppress pedantic warning resulting from statement expression.
+ (__ASSERT_FUNCTION): Add missing __extension__.
+
+2017-08-10 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/malloc.c (get_max_fast): Reimplement as an inline
+ function which calls __builtin_unreachable.
+
+2017-08-09 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21932]
+ * nss/getXXbyYY_r.c (REENTRANT_NAME): Call __resolv_context_put
+ before early return.
+
+2017-08-09 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #21780]
+ * sysdeps/posix/preadv2.c (preadv2): Use ENOTSUP instead of
+ EOPNOTSUPP.
+ * sysdeps/posix/preadv64v2.c (preadv64v2): Likewise.
+ * sysdeps/posix/pwritev2.c (pwritev2): Likewise.
+ * sysdeps/posix/pwritev64v2.c (pwritev64v2): Likewise.
+ * sysdeps/unix/sysv/linux/preadv2.c (preadv2): Likewise.
+ * sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
+ * sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
+ * sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.
+
+2017-08-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #21871]
+ * sysdeps/x86/cpu-features.c (init_cpu_features): Set
+ bit_arch_Use_dl_runtime_resolve_opt only with AVX512F.
+
+2017-08-03 Aurelien Jarno <aurelien@aurel32.net>
+
+ * stdlib/getentropy.c (getentropy): Change return type to int.
+
+2017-08-03 Aurelien Jarno <aurelien@aurel32.net>
+
+ * sysdeps/i386/i686/fpu/multiarch/libm-test-ulps: Regenerated.
+
+2017-08-03 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #21885]
+ * sysdeps/posix/getaddrinfo.c (gethosts): Release resolver context
+ on memory allocation failure.
+
2017-08-02 Siddhesh Poyarekar <siddhesh@sourceware.org>
* version.h (RELEASE): Set to "stable"
diff --git a/Makerules b/Makerules
index 9bb707c168..828a445f24 100644
--- a/Makerules
+++ b/Makerules
@@ -686,14 +686,17 @@ $(build-module-helper) -o $@ $(shlib-lds-flags) \
$(call after-link,$@)
endef
+# sofini.os must be placed last since it terminates .eh_frame section.
build-module-helper-objlist = \
$(patsubst %_pic.a,$(whole-archive) %_pic.a $(no-whole-archive),\
$(filter-out %.lds $(map-file) $(+preinit) $(+postinit) \
+ $(elf-objpfx)sofini.os \
$(link-libc-deps),$^))
build-module-objlist = $(build-module-helper-objlist) $(LDLIBS-$(@F:%.so=%).so)
build-shlib-objlist = $(build-module-helper-objlist) \
- $(LDLIBS-$(@F:lib%.so=%).so)
+ $(LDLIBS-$(@F:lib%.so=%).so) \
+ $(filter $(elf-objpfx)sofini.os,$^)
# Don't try to use -lc when making libc.so itself.
# Also omits crti.o and crtn.o, which we do not want
diff --git a/NEWS b/NEWS
index 8295f20c0a..afa170f86e 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,107 @@ See the end for copying conditions.
Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
+Version 2.26.1
+
+Major new features:
+
+* In order to support faster and safer process termination the malloc API
+ family of functions will no longer print a failure address and stack
+ backtrace after detecting heap corruption. The goal is to minimize the
+ amount of work done after corruption is detected and to avoid potential
+ security issues in continued process execution. Reducing shutdown time
+ leads to lower overall process restart latency, so there is benefit both
+ from a security and performance perspective.
+
+Security related changes:
+
+ CVE-2009-5064: The ldd script would sometimes run the program under
+ examination directly, without preventing code execution through the
+ dynamic linker. (The glibc project disputes that this is a security
+ vulnerability; only trusted binaries must be examined using the ldd
+ script.)
+
+ CVE-2017-15670: The glob function, when invoked with GLOB_TILDE,
+ suffered from a one-byte overflow during ~ operator processing (either
+ on the stack or the heap, depending on the length of the user name).
+ Reported by Tim Rühsen.
+
+ CVE-2017-15671: The glob function, when invoked with GLOB_TILDE,
+ would sometimes fail to free memory allocated during ~ operator
+ processing, leading to a memory leak and, potentially, to a denial
+ of service.
+
+ CVE-2017-15804: The glob function, when invoked with GLOB_TILDE and
+ without GLOB_NOESCAPE, could write past the end of a buffer while
+ unescaping user names. Reported by Tim Rühsen.
+
+ CVE-2017-17426: The malloc function, when called with an object size near
+ the value SIZE_MAX, would return a pointer to a buffer which is too small,
+ instead of NULL. This was a regression introduced with the new malloc
+ thread cache in glibc 2.26. Reported by Iain Buclaw.
+
+ CVE-2017-1000408: Incorrect array size computation in _dl_init_paths leads
+ to the allocation of too much memory. (This is not a security bug per se,
+ it is mentioned here only because of the CVE assignment.) Reported by
+ Qualys.
+
+ CVE-2017-1000409: Buffer overflow in _dl_init_paths due to miscomputation
+ of the number of search path components. (This is not a security
+ vulnerability per se because no trust boundary is crossed if the fix for
+ CVE-2017-1000366 has been applied, but it is mentioned here only because
+ of the CVE assignment.) Reported by Qualys.
+
+ CVE-2017-16997: Incorrect handling of RPATH or RUNPATH containing $ORIGIN
+ for AT_SECURE or SUID binaries could be used to load libraries from the
+ current directory.
+
+ CVE-2018-1000001: Buffer underflow in realpath function when getcwd function
+ succeeds without returning an absolute path due to unexpected behaviour
+ of the Linux kernel getcwd syscall. Reported by halfdog.
+
+The following bugs are resolved with this release:
+
+ [16750] ldd: Never run file directly.
+ [17956] crypt: Use NSPR header files in addition to NSS header files
+ [20532] getaddrinfo: More robust handling of dlopen failures
+ [21242] assert: Suppress pedantic warning caused by statement expression
+ [21265] x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve
+ [21780] posix: Set p{read,write}v2 to return ENOTSUP
+ [21871] x86-64: Use _dl_runtime_resolve_opt only with AVX512F
+ [21885] getaddrinfo: Release resolver context on error in gethosts
+ [21915] getaddrinfo: incorrect result handling for NSS service modules
+ [21922] getaddrinfo with AF_INET(6) returns EAI_NONAME, not EAI_NODATA
+ [21930] Do not use __builtin_types_compatible_p in C++ mode
+ [21932] Unpaired __resolv_context_get in generic get*_r implementation
+ [21941] powerpc: Restrict xssqrtqp operands to Vector Registers
+ [21972] assert macro requires operator== (int) for its argument type
+ [21982] string: stratcliff.c: error: assuming signed overflow does not
+ occur with -O3
+ [21987] Fix sparc32 bits/long-double.h
+ [22051] libc: zero terminator in the middle of glibc's .eh_frame
+ [22052] malloc failed to compile with GCC 7 and -O3
+ [22078] nss_files performance issue in hosts multi mode
+ [22093] x86: Add x86_64 to x86-64 HWCAP
+ [22095] resolv: Fix memory leak with OOM during resolv.conf parsing
+ [22096] resolv: __resolv_conf_attach must not free passed conf object
+ [22111] malloc: per thread cache is not returned when thread exits
+ [22145] ttyname gives up too early in the face of namespaces
+ [22146] Let fpclassify use the builtin when optimizing for size in C++ mode
+ [22225] math: nearbyint arithmetic moved before feholdexcept
+ [22235] Add C++ versions of iscanonical for ldbl-96 and ldbl-128ibm
+ [22296] Let signbit use the builtin in C++ mode with gcc < 6.x
+ [22299] x86-64: Don't set GLRO(dl_platform) to NULL
+ [22320] glob: Fix one-byte overflow (CVE-2017-15670)
+ [22321] sysconf: Fix missing definition of UIO_MAXIOV on Linux
+ [22322] libc: [mips64] wrong bits/long-double.h installed
+ [22325] glibc: Memory leak in glob with GLOB_TILDE (CVE-2017-15671)
+ [22375] malloc returns pointer from tcache instead of NULL (CVE-2017-17426)
+ [22636] PTHREAD_STACK_MIN is too small on x86-64
+ [22627] $ORIGIN in $LD_LIBRARY_PATH is substituted twice
+ [22637] nptl: Fix stack guard size accounting
+ [22679] getcwd(3) can succeed without returning an absolute path
+ (CVE-2018-1000001)
+
Version 2.26
Major new features:
diff --git a/assert/Makefile b/assert/Makefile
index 1c3be9b01f..222ab516f0 100644
--- a/assert/Makefile
+++ b/assert/Makefile
@@ -25,6 +25,15 @@ include ../Makeconfig
headers := assert.h
routines := assert assert-perr __assert
-tests := test-assert test-assert-perr
+tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++
+
+ifeq ($(have-cxx-thread_local),yes)
+CFLAGS-tst-assert-c++.o = -std=c++11
+LDLIBS-tst-assert-c++ = -lstdc++
+CFLAGS-tst-assert-g++.o = -std=gnu++11
+LDLIBS-tst-assert-g++ = -lstdc++
+else
+tests-unsupported += tst-assert-c++ tst-assert-g++
+endif
include ../Rules
diff --git a/assert/assert.h b/assert/assert.h
index 22f019537c..640c95c063 100644
--- a/assert/assert.h
+++ b/assert/assert.h
@@ -85,19 +85,29 @@ __END_DECLS
/* When possible, define assert so that it does not add extra
parentheses around EXPR. Otherwise, those added parentheses would
suppress warnings we'd expect to be detected by gcc's -Wparentheses. */
-# if !defined __GNUC__ || defined __STRICT_ANSI__
+# if defined __cplusplus
+# define assert(expr) \
+ (static_cast <bool> (expr) \
+ ? void (0) \
+ : __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
+# elif !defined __GNUC__ || defined __STRICT_ANSI__
# define assert(expr) \
((expr) \
? __ASSERT_VOID_CAST (0) \
: __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
# else
+/* The first occurrence of EXPR is not evaluated due to the sizeof,
+ but will trigger any pedantic warnings masked by the __extension__
+ for the second occurrence. The ternary operator is required to
+ support function pointers and bit fields in this context, and to
+ suppress the evaluation of variable length arrays. */
# define assert(expr) \
- ({ \
+ ((void) sizeof ((expr) ? 1 : 0), __extension__ ({ \
if (expr) \
; /* empty */ \
else \
__assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION); \
- })
+ }))
# endif
# ifdef __USE_GNU
@@ -113,7 +123,7 @@ __END_DECLS
C9x has a similar variable called __func__, but prefer the GCC one since
it demangles C++ function names. */
# if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4)
-# define __ASSERT_FUNCTION __PRETTY_FUNCTION__
+# define __ASSERT_FUNCTION __extension__ __PRETTY_FUNCTION__
# else
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
# define __ASSERT_FUNCTION __func__
diff --git a/assert/tst-assert-c++.cc b/assert/tst-assert-c++.cc
new file mode 100644
index 0000000000..12a5e690cb
--- /dev/null
+++ b/assert/tst-assert-c++.cc
@@ -0,0 +1,78 @@
+/* Tests for interactions between C++ and assert.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+
+/* The C++ standard requires that if the assert argument is a constant
+ subexpression, then the assert itself is one, too. */
+constexpr int
+check_constexpr ()
+{
+ return (assert (true), 1);
+}
+
+/* Objects of this class can be contextually converted to bool, but
+ cannot be compared to int. */
+struct no_int
+{
+ no_int () = default;
+ no_int (const no_int &) = delete;
+
+ explicit operator bool () const
+ {
+ return true;
+ }
+
+ bool operator! () const; /* No definition. */
+ template <class T> bool operator== (T) const; /* No definition. */
+ template <class T> bool operator!= (T) const; /* No definition. */
+};
+
+/* This class tests that operator== is not used by assert. */
+struct bool_and_int
+{
+ bool_and_int () = default;
+ bool_and_int (const no_int &) = delete;
+
+ explicit operator bool () const
+ {
+ return true;
+ }
+
+ bool operator! () const; /* No definition. */
+ template <class T> bool operator== (T) const; /* No definition. */
+ template <class T> bool operator!= (T) const; /* No definition. */
+};
+
+static int
+do_test ()
+{
+ {
+ no_int value;
+ assert (value);
+ }
+
+ {
+ bool_and_int value;
+ assert (value);
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/assert/tst-assert-g++.cc b/assert/tst-assert-g++.cc
new file mode 100644
index 0000000000..8c06402825
--- /dev/null
+++ b/assert/tst-assert-g++.cc
@@ -0,0 +1,19 @@
+/* Tests for interactions between C++ and assert. GNU C++11 version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <tst-assert-c++.cc>
diff --git a/configure b/configure
index d8e1c50e11..47d8c75248 100755
--- a/configure
+++ b/configure
@@ -3547,8 +3547,12 @@ if test x$nss_crypt = xyes; then
if test $? -ne 0; then
as_fn_error $? "cannot find include directory with nss-config" "$LINENO" 5
fi
+ nspr_includes=-I$(nspr-config --includedir 2>/dev/null)
+ if test $? -ne 0; then
+ as_fn_error $? "cannot find include directory with nspr-config" "$LINENO" 5
+ fi
old_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $nss_includes"
+ CFLAGS="$CFLAGS $nss_includes $nspr_includes"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
diff --git a/configure.ac b/configure.ac
index 77456aa8d9..e8a1ab3562 100644
--- a/configure.ac
+++ b/configure.ac
@@ -330,8 +330,12 @@ if test x$nss_crypt = xyes; then
if test $? -ne 0; then
AC_MSG_ERROR([cannot find include directory with nss-config])
fi
+ nspr_includes=-I$(nspr-config --includedir 2>/dev/null)
+ if test $? -ne 0; then
+ AC_MSG_ERROR([cannot find include directory with nspr-config])
+ fi
old_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $nss_includes"
+ CFLAGS="$CFLAGS $nss_includes $nspr_includes"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>
diff --git a/crypt/Makefile b/crypt/Makefile
index 0280fba8a7..8bbbf2a121 100644
--- a/crypt/Makefile
+++ b/crypt/Makefile
@@ -37,9 +37,11 @@ routines += $(libcrypt-routines)
endif
ifeq ($(nss-crypt),yes)
-CPPFLAGS-sha256-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
-CPPFLAGS-sha512-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
-CPPFLAGS-md5-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
+nss-cpp-flags := -DUSE_NSS \
+ -I$(shell nss-config --includedir) -I$(shell nspr-config --includedir)
+CPPFLAGS-sha256-crypt.c = $(nss-cpp-flags)
+CPPFLAGS-sha512-crypt.c = $(nss-cpp-flags)
+CPPFLAGS-md5-crypt.c = $(nss-cpp-flags)
LDLIBS-crypt.so = -lfreebl3
else
libcrypt-routines += md5 sha256 sha512
diff --git a/elf/dl-load.c b/elf/dl-load.c
index c1b6d4ba0f..7397c1882c 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -37,6 +37,7 @@
#include <sysdep.h>
#include <stap-probe.h>
#include <libc-pointer-arith.h>
+#include <array_length.h>
#include <dl-dst.h>
#include <dl-load.h>
@@ -103,7 +104,9 @@ static size_t ncapstr attribute_relro;
static size_t max_capstrlen attribute_relro;
-/* Get the generated information about the trusted directories. */
+/* Get the generated information about the trusted directories. Use
+ an array of concatenated strings to avoid relocations. See
+ gen-trusted-dirs.awk. */
#include "trusted-dirs.h"
static const char system_dirs[] = SYSTEM_DIRS;
@@ -111,9 +114,7 @@ static const size_t system_dirs_len[] =
{
SYSTEM_DIRS_LEN
};
-#define nsystem_dirs_len \
- (sizeof (system_dirs_len) / sizeof (system_dirs_len[0]))
-
+#define nsystem_dirs_len array_length (system_dirs_len)
static bool
is_trusted_path (const char *path, size_t len)
@@ -433,31 +434,40 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
{
char *cp;
size_t nelems = 0;
- char *to_free;
while ((cp = __strsep (&rpath, sep)) != NULL)
{
struct r_search_path_elem *dirp;
+ char *to_free = NULL;
+ size_t len = 0;
- to_free = cp = expand_dynamic_string_token (l, cp, 1);
+ /* `strsep' can pass an empty string. */
+ if (*cp != '\0')
+ {
+ to_free = cp = expand_dynamic_string_token (l, cp, 1);
- size_t len = strlen (cp);
+ /* expand_dynamic_string_token can return NULL in case of empty
+ path or memory allocation failure. */
+ if (cp == NULL)
+ continue;
- /* `strsep' can pass an empty string. This has to be
- interpreted as `use the current directory'. */
- if (len == 0)
- {
- static const char curwd[] = "./";
- cp = (char *) curwd;
- }
+ /* Compute the length after dynamic string token expansion and
+ ignore empty paths. */
+ len = strlen (cp);
+ if (len == 0)
+ {
+ free (to_free);
+ continue;
+ }
- /* Remove trailing slashes (except for "/"). */
- while (len > 1 && cp[len - 1] == '/')
- --len;
+ /* Remove trailing slashes (except for "/"). */
+ while (len > 1 && cp[len - 1] == '/')
+ --len;
- /* Now add one if there is none so far. */
- if (len > 0 && cp[len - 1] != '/')
- cp[len++] = '/';
+ /* Now add one if there is none so far. */
+ if (len > 0 && cp[len - 1] != '/')
+ cp[len++] = '/';
+ }
/* Make sure we don't use untrusted directories if we run SUID. */
if (__glibc_unlikely (check_trusted) && !is_trusted_path (cp, len))
@@ -621,6 +631,14 @@ decompose_rpath (struct r_search_path_struct *sps,
necessary. */
free (copy);
+ /* There is no path after expansion. */
+ if (result[0] == NULL)
+ {
+ free (result);
+ sps->dirs = (struct r_search_path_elem **) -1;
+ return false;
+ }
+
sps->dirs = result;
/* The caller will change this value if we haven't used a real malloc. */
sps->malloced = 1;
@@ -688,9 +706,8 @@ _dl_init_paths (const char *llp)
+ ncapstr * sizeof (enum r_dir_status))
/ sizeof (struct r_search_path_elem));
- rtld_search_dirs.dirs[0] = (struct r_search_path_elem *)
- malloc ((sizeof (system_dirs) / sizeof (system_dirs[0]))
- * round_size * sizeof (struct r_search_path_elem));
+ rtld_search_dirs.dirs[0] = malloc (nsystem_dirs_len * round_size
+ * sizeof (*rtld_search_dirs.dirs[0]));
if (rtld_search_dirs.dirs[0] == NULL)
{
errstring = N_("cannot create cache for search path");
@@ -776,37 +793,14 @@ _dl_init_paths (const char *llp)
if (llp != NULL && *llp != '\0')
{
- size_t nllp;
- const char *cp = llp;
- char *llp_tmp;
-
-#ifdef SHARED
- /* Expand DSTs. */
- size_t cnt = DL_DST_COUNT (llp, 1);
- if (__glibc_likely (cnt == 0))
- llp_tmp = strdupa (llp);
- else
- {
- /* Determine the length of the substituted string. */
- size_t total = DL_DST_REQUIRED (l, llp, strlen (llp), cnt);
-
- /* Allocate the necessary memory. */
- llp_tmp = (char *) alloca (total + 1);
- llp_tmp = _dl_dst_substitute (l, llp, llp_tmp, 1);
- }
-#else
- llp_tmp = strdupa (llp);
-#endif
+ char *llp_tmp = strdupa (llp);
/* Decompose the LD_LIBRARY_PATH contents. First determine how many
elements it has. */
- nllp = 1;
- while (*cp)
- {
- if (*cp == ':' || *cp == ';')
- ++nllp;
- ++cp;
- }
+ size_t nllp = 1;
+ for (const char *cp = llp_tmp; *cp != '\0'; ++cp)
+ if (*cp == ':' || *cp == ';')
+ ++nllp;
env_path_list.dirs = (struct r_search_path_elem **)
malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 231fb8ca93..d9975ef2d0 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -88,18 +88,11 @@ get_next_env (char **envp, char **name, size_t *namelen, char **val,
return NULL;
}
-#define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type, __default_min, \
- __default_max) \
+#define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type) \
({ \
__type min = (__cur)->type.min; \
__type max = (__cur)->type.max; \
\
- if (min == max) \
- { \
- min = __default_min; \
- max = __default_max; \
- } \
- \
if ((__type) (__val) >= min && (__type) (val) <= max) \
{ \
(__cur)->val.numval = val; \
@@ -119,17 +112,17 @@ do_tunable_update_val (tunable_t *cur, const void *valp)
{
case TUNABLE_TYPE_INT_32:
{
- TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t, INT32_MIN, INT32_MAX);
+ TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t);
break;
}
case TUNABLE_TYPE_UINT_64:
{
- TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t, 0, UINT64_MAX);
+ TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
break;
}
case TUNABLE_TYPE_SIZE_T:
{
- TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t, 0, SIZE_MAX);
+ TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
break;
}
case TUNABLE_TYPE_STRING:
diff --git a/elf/ldd.bash.in b/elf/ldd.bash.in
index 7dd1fccf24..686785e235 100644
--- a/elf/ldd.bash.in
+++ b/elf/ldd.bash.in
@@ -164,18 +164,6 @@ warning: you do not have execution permission for" "\`$file'" >&2
fi
done
case $ret in
- 0)
- # If the program exits with exit code 5, it means the process has been
- # invoked with __libc_enable_secure. Fall back to running it through
- # the dynamic linker.
- try_trace "$file"
- rc=$?
- if [ $rc = 5 ]; then
- try_trace "$RTLD" "$file"
- rc=$?
- fi
- [ $rc = 0 ] || result=1
- ;;
1)
# This can be a non-ELF binary or no binary at all.
nonelf "$file" || {
@@ -183,7 +171,7 @@ warning: you do not have execution permission for" "\`$file'" >&2
result=1
}
;;
- 2)
+ 0|2)
try_trace "$RTLD" "$file" || result=1
;;
*)
diff --git a/include/array_length.h b/include/array_length.h
new file mode 100644
index 0000000000..cb4a8b2a56
--- /dev/null
+++ b/include/array_length.h
@@ -0,0 +1,36 @@
+/* The array_length and array_end macros.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _ARRAY_LENGTH_H
+#define _ARRAY_LENGTH_H
+
+/* array_length (VAR) is the number of elements in the array VAR. VAR
+ must evaluate to an array, not a pointer. */
+#define array_length(var) \
+ __extension__ ({ \
+ _Static_assert (!__builtin_types_compatible_p \
+ (__typeof (var), __typeof (&(var)[0])), \
+ "argument must be an array"); \
+ sizeof (var) / sizeof ((var)[0]); \
+ })
+
+/* array_end (VAR) is a pointer one past the end of the array VAR.
+ VAR must evaluate to an array, not a pointer. */
+#define array_end(var) (&(var)[array_length (var)])
+
+#endif /* _ARRAY_LENGTH_H */
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 3310e3a678..5bf57703a9 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -782,7 +782,8 @@ for linking")
/* Helper / base macros for indirect function symbols. */
#define __ifunc_resolver(type_name, name, expr, arg, init, classifier) \
- classifier inhibit_stack_protector void *name##_ifunc (arg) \
+ classifier inhibit_stack_protector \
+ __typeof (type_name) *name##_ifunc (arg) \
{ \
init (); \
__typeof (type_name) *res = expr; \
@@ -809,7 +810,7 @@ for linking")
# define __ifunc(type_name, name, expr, arg, init) \
extern __typeof (type_name) name; \
- void *name##_ifunc (arg) __asm__ (#name); \
+ __typeof (type_name) *name##_ifunc (arg) __asm__ (#name); \
__ifunc_resolver (type_name, name, expr, arg, init,) \
__asm__ (".type " #name ", %gnu_indirect_function");
diff --git a/inet/inet6_scopeid_pton.c b/inet/inet6_scopeid_pton.c
index e09b1cb34d..cc8803fa10 100644
--- a/inet/inet6_scopeid_pton.c
+++ b/inet/inet6_scopeid_pton.c
@@ -28,7 +28,7 @@
/* Parse SOURCE as a scope ID for ADDRESS. Return 0 on success and -1
on error. */
-internal_function int
+int
__inet6_scopeid_pton (const struct in6_addr *address, const char *scope,
uint32_t *result)
{
diff --git a/inet/net-internal.h b/inet/net-internal.h
index 2b2632c7ba..b2135893e8 100644
--- a/inet/net-internal.h
+++ b/inet/net-internal.h
@@ -25,8 +25,7 @@
#include <sys/time.h>
int __inet6_scopeid_pton (const struct in6_addr *address,
- const char *scope, uint32_t *result)
- internal_function attribute_hidden;
+ const char *scope, uint32_t *result);
libc_hidden_proto (__inet6_scopeid_pton)
diff --git a/io/Makefile b/io/Makefile
index 2f26bf56db..f0bdc838bb 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -70,7 +70,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
tst-posix_fallocate tst-posix_fallocate64 \
- tst-fts tst-fts-lfs tst-open-tmpfile
+ tst-fts tst-fts-lfs tst-open-tmpfile tst-getcwd-abspath
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)ftwtest.out
diff --git a/io/tst-getcwd-abspath.c b/io/tst-getcwd-abspath.c
new file mode 100644
index 0000000000..3a3636f2ed
--- /dev/null
+++ b/io/tst-getcwd-abspath.c
@@ -0,0 +1,66 @@
+/* BZ #22679 getcwd(3) should not succeed without returning an absolute path.
+
+ 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+static char *chroot_dir;
+
+/* The actual test. Run it in a subprocess, so that the test harness
+ can remove the temporary directory in --direct mode. */
+static void
+getcwd_callback (void *closure)
+{
+ xchroot (chroot_dir);
+
+ errno = 0;
+ char *cwd = getcwd (NULL, 0);
+ TEST_COMPARE (errno, ENOENT);
+ TEST_VERIFY (cwd == NULL);
+
+ errno = 0;
+ cwd = realpath (".", NULL);
+ TEST_COMPARE (errno, ENOENT);
+ TEST_VERIFY (cwd == NULL);
+
+ _exit (0);
+}
+
+static int
+do_test (void)
+{
+ support_become_root ();
+ if (!support_can_chroot ())
+ return EXIT_UNSUPPORTED;
+
+ chroot_dir = support_create_temp_directory ("tst-getcwd-abspath-");
+ support_isolate_in_subprocess (getcwd_callback, NULL);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/malloc/Makefile b/malloc/Makefile
index 3fa395b949..9e23db9343 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -34,6 +34,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-interpose-nothread \
tst-interpose-thread \
tst-alloc_buffer \
+ tst-malloc-tcache-leak \
tests-static := \
tst-interpose-static-nothread \
@@ -242,3 +243,5 @@ tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace
$(objpfx)tst-dynarray-fail-mem.out: $(objpfx)tst-dynarray-fail.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@; \
$(evaluate-test)
+
+$(objpfx)tst-malloc-tcache-leak: $(shared-thread-library)
diff --git a/malloc/arena.c b/malloc/arena.c
index dc14fae152..afd423240a 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -116,7 +116,7 @@ int __malloc_initialized = -1;
} while (0)
#define arena_lock(ptr, size) do { \
- if (ptr && !arena_is_corrupt (ptr)) \
+ if (ptr) \
__libc_lock_lock (ptr->mutex); \
else \
ptr = arena_get2 ((size), NULL); \
@@ -215,8 +215,7 @@ void
TUNABLE_CALLBACK (set_mallopt_check) (tunable_val_t *valp)
{
int32_t value = (int32_t) valp->numval;
- do_set_mallopt_check (value);
- if (check_action != 0)
+ if (value != 0)
__malloc_check_init ();
}
@@ -397,12 +396,8 @@ ptmalloc_init (void)
}
}
}
- if (s && s[0])
- {
- __libc_mallopt (M_CHECK_ACTION, (int) (s[0] - '0'));
- if (check_action != 0)
- __malloc_check_init ();
- }
+ if (s && s[0] != '\0' && s[0] != '0')
+ __malloc_check_init ();
#endif
#if HAVE_MALLOC_INIT_HOOK
@@ -837,7 +832,7 @@ reused_arena (mstate avoid_arena)
result = next_to_use;
do
{
- if (!arena_is_corrupt (result) && !__libc_lock_trylock (result->mutex))
+ if (!__libc_lock_trylock (result->mutex))
goto out;
/* FIXME: This is a data race, see _int_new_arena. */
@@ -850,18 +845,6 @@ reused_arena (mstate avoid_arena)
if (result == avoid_arena)
result = result->next;
- /* Make sure that the arena we get is not corrupted. */
- mstate begin = result;
- while (arena_is_corrupt (result) || result == avoid_arena)
- {
- result = result->next;
- if (result == begin)
- /* We looped around the arena list. We could not find any
- arena that was either not corrupted or not the one we
- wanted to avoid. */
- return NULL;
- }
-
/* No arena available without contention. Wait for the next in line. */
LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);
__libc_lock_lock (result->mutex);
@@ -958,10 +941,6 @@ arena_get_retry (mstate ar_ptr, size_t bytes)
if (ar_ptr != &main_arena)
{
__libc_lock_unlock (ar_ptr->mutex);
- /* Don't touch the main arena if it is corrupt. */
- if (arena_is_corrupt (&main_arena))
- return NULL;
-
ar_ptr = &main_arena;
__libc_lock_lock (ar_ptr->mutex);
}
diff --git a/malloc/dynarray_emplace_enlarge.c b/malloc/dynarray_emplace_enlarge.c
index dfc70017ce..a15245f4cb 100644
--- a/malloc/dynarray_emplace_enlarge.c
+++ b/malloc/dynarray_emplace_enlarge.c
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <dynarray.h>
+#include <errno.h>
#include <malloc-internal.h>
#include <stdlib.h>
#include <string.h>
@@ -32,7 +33,7 @@ __libc_dynarray_emplace_enlarge (struct dynarray_header *list,
size. */
if (element_size < 4)
new_allocated = 16;
- if (element_size < 8)
+ else if (element_size < 8)
new_allocated = 8;
else
new_allocated = 4;
@@ -43,8 +44,11 @@ __libc_dynarray_emplace_enlarge (struct dynarray_header *list,
{
new_allocated = list->allocated + list->allocated / 2 + 1;
if (new_allocated <= list->allocated)
- /* Overflow. */
- return false;
+ {
+ /* Overflow. */
+ __set_errno (ENOMEM);
+ return false;
+ }
}
size_t new_size;
diff --git a/malloc/dynarray_resize.c b/malloc/dynarray_resize.c
index e6dc9fbc68..63c981bf61 100644
--- a/malloc/dynarray_resize.c
+++ b/malloc/dynarray_resize.c
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <dynarray.h>
+#include <errno.h>
#include <malloc-internal.h>
#include <stdlib.h>
#include <string.h>
@@ -38,7 +39,11 @@ __libc_dynarray_resize (struct dynarray_header *list, size_t size,
size_t new_size_bytes;
if (check_mul_overflow_size_t (size, element_size, &new_size_bytes))
- return false;
+ {
+ /* Overflow. */
+ __set_errno (ENOMEM);
+ return false;
+ }
void *new_array;
if (list->array == scratch)
{
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 1d80be20d2..2c6cebc889 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -121,12 +121,7 @@ malloc_check_get_size (mchunkptr p)
size -= c)
{
if (c <= 0 || size < (c + 2 * SIZE_SZ))
- {
- malloc_printerr (check_action, "malloc_check_get_size: memory corruption",
- chunk2mem (p),
- chunk_is_mmapped (p) ? NULL : arena_for_chunk (p));
- return 0;
- }
+ malloc_printerr ("malloc_check_get_size: memory corruption");
}
/* chunk2mem size. */
@@ -232,17 +227,11 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
return p;
}
-/* Check for corruption of the top chunk, and try to recover if
- necessary. */
-
-static int
-internal_function
+/* Check for corruption of the top chunk. */
+static void
top_check (void)
{
mchunkptr t = top (&main_arena);
- char *brk, *new_brk;
- INTERNAL_SIZE_T front_misalign, sbrk_size;
- unsigned long pagesz = GLRO (dl_pagesize);
if (t == initial_top (&main_arena) ||
(!chunk_is_mmapped (t) &&
@@ -250,34 +239,9 @@ top_check (void)
prev_inuse (t) &&
(!contiguous (&main_arena) ||
(char *) t + chunksize (t) == mp_.sbrk_base + main_arena.system_mem)))
- return 0;
-
- malloc_printerr (check_action, "malloc: top chunk is corrupt", t,
- &main_arena);
-
- /* Try to set up a new top chunk. */
- brk = MORECORE (0);
- front_misalign = (unsigned long) chunk2mem (brk) & MALLOC_ALIGN_MASK;
- if (front_misalign > 0)
- front_misalign = MALLOC_ALIGNMENT - front_misalign;
- sbrk_size = front_misalign + mp_.top_pad + MINSIZE;
- sbrk_size += pagesz - ((unsigned long) (brk + sbrk_size) & (pagesz - 1));
- new_brk = (char *) (MORECORE (sbrk_size));
- if (new_brk == (char *) (MORECORE_FAILURE))
- {
- __set_errno (ENOMEM);
- return -1;
- }
- /* Call the `morecore' hook if necessary. */
- void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
- if (hook)
- (*hook)();
- main_arena.system_mem = (new_brk - mp_.sbrk_base) + sbrk_size;
-
- top (&main_arena) = (mchunkptr) (brk + front_misalign);
- set_head (top (&main_arena), (sbrk_size - front_misalign) | PREV_INUSE);
+ return;
- return 0;
+ malloc_printerr ("malloc: top chunk is corrupt");
}
static void *
@@ -292,7 +256,8 @@ malloc_check (size_t sz, const void *caller)
}
__libc_lock_lock (main_arena.mutex);
- victim = (top_check () >= 0) ? _int_malloc (&main_arena, sz + 1) : NULL;
+ top_check ();
+ victim = _int_malloc (&main_arena, sz + 1);
__libc_lock_unlock (main_arena.mutex);
return mem2mem_check (victim, sz);
}
@@ -308,13 +273,7 @@ free_check (void *mem, const void *caller)
__libc_lock_lock (main_arena.mutex);
p = mem2chunk_check (mem, NULL);
if (!p)
- {
- __libc_lock_unlock (main_arena.mutex);
-
- malloc_printerr (check_action, "free(): invalid pointer", mem,
- &main_arena);
- return;
- }
+ malloc_printerr ("free(): invalid pointer");
if (chunk_is_mmapped (p))
{
__libc_lock_unlock (main_arena.mutex);
@@ -349,11 +308,7 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
const mchunkptr oldp = mem2chunk_check (oldmem, &magic_p);
__libc_lock_unlock (main_arena.mutex);
if (!oldp)
- {
- malloc_printerr (check_action, "realloc(): invalid pointer", oldmem,
- &main_arena);
- return malloc_check (bytes, NULL);
- }
+ malloc_printerr ("realloc(): invalid pointer");
const INTERNAL_SIZE_T oldsize = chunksize (oldp);
checked_request2size (bytes + 1, nb);
@@ -374,8 +329,8 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
else
{
/* Must alloc, copy, free. */
- if (top_check () >= 0)
- newmem = _int_malloc (&main_arena, bytes + 1);
+ top_check ();
+ newmem = _int_malloc (&main_arena, bytes + 1);
if (newmem)
{
memcpy (newmem, oldmem, oldsize - 2 * SIZE_SZ);
@@ -386,19 +341,24 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
}
else
{
- if (top_check () >= 0)
- {
- INTERNAL_SIZE_T nb;
- checked_request2size (bytes + 1, nb);
- newmem = _int_realloc (&main_arena, oldp, oldsize, nb);
- }
+ top_check ();
+ INTERNAL_SIZE_T nb;
+ checked_request2size (bytes + 1, nb);
+ newmem = _int_realloc (&main_arena, oldp, oldsize, nb);
}
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about magic_p may be used uninitialized. But we never
+ reach here if magic_p is uninitialized. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Wmaybe-uninitialized");
+#endif
/* mem2chunk_check changed the magic byte in the old chunk.
If newmem is NULL, then the old chunk will still be used though,
so we need to invert that change here. */
if (newmem == NULL)
*magic_p ^= 0xFF;
+ DIAG_POP_NEEDS_COMMENT;
__libc_lock_unlock (main_arena.mutex);
@@ -441,8 +401,8 @@ memalign_check (size_t alignment, size_t bytes, const void *caller)
}
__libc_lock_lock (main_arena.mutex);
- mem = (top_check () >= 0) ? _int_memalign (&main_arena, alignment, bytes + 1) :
- NULL;
+ top_check ();
+ mem = _int_memalign (&main_arena, alignment, bytes + 1);
__libc_lock_unlock (main_arena.mutex);
return mem2mem_check (mem, bytes);
}
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 54e406bcb6..6a52c288de 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -243,6 +243,9 @@
#include <malloc/malloc-internal.h>
+/* For SINGLE_THREAD_P. */
+#include <sysdep-cancel.h>
+
/*
Debugging:
@@ -1019,10 +1022,10 @@ static void* _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T,
static void* _int_memalign(mstate, size_t, size_t);
static void* _mid_memalign(size_t, size_t, void *);
-static void malloc_printerr(int action, const char *str, void *ptr, mstate av);
+static void malloc_printerr(const char *str) __attribute__ ((noreturn));
static void* internal_function mem2mem_check(void *p, size_t sz);
-static int internal_function top_check(void);
+static void top_check (void);
static void internal_function munmap_chunk(mchunkptr p);
#if HAVE_MREMAP
static mchunkptr internal_function mremap_chunk(mchunkptr p, size_t new_size);
@@ -1403,11 +1406,11 @@ typedef struct malloc_chunk *mbinptr;
/* 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 (check_action, "corrupted size vs. prev_size", P, AV); \
+ 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 (check_action, "corrupted double-linked list", P, AV); \
+ malloc_printerr ("corrupted double-linked list"); \
else { \
FD->bk = BK; \
BK->fd = FD; \
@@ -1415,9 +1418,7 @@ typedef struct malloc_chunk *mbinptr;
&& __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 (check_action, \
- "corrupted double-linked list (not small)", \
- P, AV); \
+ 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; \
@@ -1612,27 +1613,6 @@ typedef struct malloc_chunk *mfastbinptr;
#define FASTBIN_CONSOLIDATION_THRESHOLD (65536UL)
-/*
- Since the lowest 2 bits in max_fast don't matter in size comparisons,
- they are used as flags.
- */
-
-/*
- FASTCHUNKS_BIT held in max_fast indicates that there are probably
- some fastbin chunks. It is set true on entering a chunk into any
- fastbin, and cleared only in malloc_consolidate.
-
- The truth value is inverted so that have_fastchunks will be true
- upon startup (since statics are zero-filled), simplifying
- initialization checks.
- */
-
-#define FASTCHUNKS_BIT (1U)
-
-#define have_fastchunks(M) (((M)->flags & FASTCHUNKS_BIT) == 0)
-#define clear_fastchunks(M) catomic_or (&(M)->flags, FASTCHUNKS_BIT)
-#define set_fastchunks(M) catomic_and (&(M)->flags, ~FASTCHUNKS_BIT)
-
/*
NONCONTIGUOUS_BIT indicates that MORECORE does not return contiguous
regions. Otherwise, contiguity is exploited in merging together,
@@ -1649,14 +1629,8 @@ typedef struct malloc_chunk *mfastbinptr;
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
-/* ARENA_CORRUPTION_BIT is set if a memory corruption was detected on the
- arena. Such an arena is no longer used to allocate chunks. Chunks
- allocated in that arena before detecting corruption are not freed. */
-
-#define ARENA_CORRUPTION_BIT (4U)
-
-#define arena_is_corrupt(A) (((A)->flags & ARENA_CORRUPTION_BIT))
-#define set_arena_corrupt(A) ((A)->flags |= ARENA_CORRUPTION_BIT)
+/* Maximum size of memory handled in fastbins. */
+static INTERNAL_SIZE_T global_max_fast;
/*
Set value of max_fast.
@@ -1668,13 +1642,36 @@ typedef struct malloc_chunk *mfastbinptr;
#define set_max_fast(s) \
global_max_fast = (((s) == 0) \
? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
-#define get_max_fast() global_max_fast
+static inline INTERNAL_SIZE_T
+get_max_fast (void)
+{
+ /* Tell the GCC optimizers that global_max_fast is never larger
+ than MAX_FAST_SIZE. This avoids out-of-bounds array accesses in
+ _int_malloc after constant propagation of the size parameter.
+ (The code never executes because malloc preserves the
+ global_max_fast invariant, but the optimizers may not recognize
+ this.) */
+ if (global_max_fast > MAX_FAST_SIZE)
+ __builtin_unreachable ();
+ return global_max_fast;
+}
/*
----------- Internal state representation and initialization -----------
*/
+/*
+ have_fastchunks indicates that there are probably some fastbin chunks.
+ It is set true on entering a chunk into any fastbin, and cleared early in
+ malloc_consolidate. The value is approximate since it may be set when there
+ are no fastbin chunks, or it may be clear even if there are fastbin chunks
+ available. Given it's sole purpose is to reduce number of redundant calls to
+ malloc_consolidate, it does not affect correctness. As a result we can safely
+ use relaxed atomic accesses.
+ */
+
+
struct malloc_state
{
/* Serialize access. */
@@ -1683,6 +1680,10 @@ struct malloc_state
/* Flags (formerly in max_fast). */
int flags;
+ /* Set if the fastbin chunks contain recently inserted free blocks. */
+ /* Note this is a bool but not all targets support atomics on booleans. */
+ int have_fastchunks;
+
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
@@ -1797,9 +1798,6 @@ static struct malloc_par mp_ =
#endif
};
-/* Maximum size of memory handled in fastbins. */
-static INTERNAL_SIZE_T global_max_fast;
-
/*
Initialize a malloc_state struct.
@@ -1829,7 +1827,7 @@ malloc_init_state (mstate av)
set_noncontiguous (av);
if (av == &main_arena)
set_max_fast (DEFAULT_MXFAST);
- av->flags |= FASTCHUNKS_BIT;
+ atomic_store_relaxed (&av->have_fastchunks, false);
av->top = initial_top (av);
}
@@ -1880,15 +1878,6 @@ void *weak_variable (*__memalign_hook)
void weak_variable (*__after_morecore_hook) (void) = NULL;
-/* ---------------- Error behavior ------------------------------------ */
-
-#ifndef DEFAULT_CHECK_ACTION
-# define DEFAULT_CHECK_ACTION 3
-#endif
-
-static int check_action = DEFAULT_CHECK_ACTION;
-
-
/* ------------------ Testing support ----------------------------------*/
static int perturb_byte;
@@ -2194,11 +2183,6 @@ do_check_malloc_state (mstate av)
}
}
- if (total != 0)
- assert (have_fastchunks (av));
- else if (!have_fastchunks (av))
- assert (total == 0);
-
/* check normal bins */
for (i = 1; i < NBINS; ++i)
{
@@ -2566,11 +2550,8 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
set_head (old_top, (size + old_size) | PREV_INUSE);
else if (contiguous (av) && old_size && brk < old_end)
- {
- /* Oops! Someone else killed our space.. Can't touch anything. */
- malloc_printerr (3, "break adjusted to free malloc space", brk,
- av);
- }
+ /* Oops! Someone else killed our space.. Can't touch anything. */
+ malloc_printerr ("break adjusted to free malloc space");
/*
Otherwise, make adjustments:
@@ -2861,11 +2842,7 @@ munmap_chunk (mchunkptr p)
(in the moment at least) so we combine the two values into one before
the bit test. */
if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0))
- {
- malloc_printerr (check_action, "munmap_chunk(): invalid pointer",
- chunk2mem (p), NULL);
- return;
- }
+ malloc_printerr ("munmap_chunk(): invalid pointer");
atomic_decrement (&mp_.n_mmaps);
atomic_add (&mp_.mmapped_mem, -total_size);
@@ -2940,12 +2917,12 @@ typedef struct tcache_perthread_struct
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
-static __thread char tcache_shutting_down = 0;
+static __thread bool tcache_shutting_down = false;
static __thread tcache_perthread_struct *tcache = NULL;
/* Caller must ensure that we know tc_idx is valid and there's room
for more chunks. */
-static void
+static __always_inline void
tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
@@ -2957,7 +2934,7 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
/* Caller must ensure that we know tc_idx is valid and there's
available chunks to remove. */
-static void *
+static __always_inline void *
tcache_get (size_t tc_idx)
{
tcache_entry *e = tcache->entries[tc_idx];
@@ -2977,8 +2954,12 @@ tcache_thread_freeres (void)
if (!tcache)
return;
+ /* Disable the tcache and prevent it from being reinitialized. */
tcache = NULL;
+ tcache_shutting_down = true;
+ /* Free all of the entries and the tcache itself back to the arena
+ heap for coalescing. */
for (i = 0; i < TCACHE_MAX_BINS; ++i)
{
while (tcache_tmp->entries[i])
@@ -2990,8 +2971,6 @@ tcache_thread_freeres (void)
}
__libc_free (tcache_tmp);
-
- tcache_shutting_down = 1;
}
text_set_element (__libc_thread_subfreeres, tcache_thread_freeres);
@@ -3050,7 +3029,8 @@ __libc_malloc (size_t bytes)
return (*hook)(bytes, RETURN_ADDRESS (0));
#if USE_TCACHE
/* int_free also calls request2size, be careful to not pad twice. */
- size_t tbytes = request2size (bytes);
+ size_t tbytes;
+ checked_request2size (bytes, tbytes);
size_t tc_idx = csize2tidx (tbytes);
MAYBE_INIT_TCACHE ();
@@ -3066,6 +3046,14 @@ __libc_malloc (size_t bytes)
DIAG_POP_NEEDS_COMMENT;
#endif
+ if (SINGLE_THREAD_P)
+ {
+ victim = _int_malloc (&main_arena, bytes);
+ assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
+ &main_arena == arena_for_chunk (mem2chunk (victim)));
+ return victim;
+ }
+
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
@@ -3177,11 +3165,7 @@ __libc_realloc (void *oldmem, size_t bytes)
if ((__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0)
|| __builtin_expect (misaligned_chunk (oldp), 0))
&& !DUMPED_MAIN_ARENA_CHUNK (oldp))
- {
- malloc_printerr (check_action, "realloc(): invalid pointer", oldmem,
- ar_ptr);
- return NULL;
- }
+ malloc_printerr ("realloc(): invalid pointer");
checked_request2size (bytes, nb);
@@ -3226,6 +3210,15 @@ __libc_realloc (void *oldmem, size_t bytes)
return newmem;
}
+ if (SINGLE_THREAD_P)
+ {
+ newp = _int_realloc (ar_ptr, oldp, oldsize, nb);
+ assert (!newp || chunk_is_mmapped (mem2chunk (newp)) ||
+ ar_ptr == arena_for_chunk (mem2chunk (newp)));
+
+ return newp;
+ }
+
__libc_lock_lock (ar_ptr->mutex);
newp = _int_realloc (ar_ptr, oldp, oldsize, nb);
@@ -3301,6 +3294,15 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
alignment = a;
}
+ if (SINGLE_THREAD_P)
+ {
+ p = _int_memalign (&main_arena, alignment, bytes);
+ assert (!p || chunk_is_mmapped (mem2chunk (p)) ||
+ &main_arena == arena_for_chunk (mem2chunk (p)));
+
+ return p;
+ }
+
arena_get (ar_ptr, bytes + alignment + MINSIZE);
p = _int_memalign (ar_ptr, alignment, bytes);
@@ -3393,7 +3395,11 @@ __libc_calloc (size_t n, size_t elem_size)
MAYBE_INIT_TCACHE ();
- arena_get (av, sz);
+ if (SINGLE_THREAD_P)
+ av = &main_arena;
+ else
+ arena_get (av, sz);
+
if (av)
{
/* Check if we hand out the top chunk, in which case there may be no
@@ -3423,19 +3429,21 @@ __libc_calloc (size_t n, size_t elem_size)
}
mem = _int_malloc (av, sz);
-
assert (!mem || chunk_is_mmapped (mem2chunk (mem)) ||
av == arena_for_chunk (mem2chunk (mem)));
- if (mem == 0 && av != NULL)
+ if (!SINGLE_THREAD_P)
{
- LIBC_PROBE (memory_calloc_retry, 1, sz);
- av = arena_get_retry (av, sz);
- mem = _int_malloc (av, sz);
- }
+ if (mem == 0 && av != NULL)
+ {
+ LIBC_PROBE (memory_calloc_retry, 1, sz);
+ av = arena_get_retry (av, sz);
+ mem = _int_malloc (av, sz);
+ }
- if (av != NULL)
- __libc_lock_unlock (av->mutex);
+ if (av != NULL)
+ __libc_lock_unlock (av->mutex);
+ }
/* Allocation failed even after a retry. */
if (mem == 0)
@@ -3527,8 +3535,6 @@ _int_malloc (mstate av, size_t bytes)
size_t tcache_unsorted_count; /* count of unsorted chunks processed */
#endif
- const char *errstr = NULL;
-
/*
Convert request size to internal form by adding SIZE_SZ bytes
overhead plus possibly more to obtain necessary alignment and/or
@@ -3570,42 +3576,50 @@ _int_malloc (mstate av, size_t bytes)
{
idx = fastbin_index (nb);
mfastbinptr *fb = &fastbin (av, idx);
- mchunkptr pp = *fb;
- REMOVE_FB (fb, victim, pp);
- if (victim != 0)
- {
- if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
- {
- errstr = "malloc(): memory corruption (fast)";
- errout:
- malloc_printerr (check_action, errstr, chunk2mem (victim), av);
- return NULL;
- }
- check_remalloced_chunk (av, victim, nb);
-#if USE_TCACHE
- /* While we're here, if we see other chunks of the same size,
- stash them in the tcache. */
- size_t tc_idx = csize2tidx (nb);
- if (tcache && tc_idx < mp_.tcache_bins)
- {
- mchunkptr tc_victim;
+ mchunkptr pp;
+ victim = *fb;
- /* While bin not empty and tcache not full, copy chunks over. */
- while (tcache->counts[tc_idx] < mp_.tcache_count
- && (pp = *fb) != NULL)
+ if (victim != NULL)
+ {
+ if (SINGLE_THREAD_P)
+ *fb = victim->fd;
+ else
+ REMOVE_FB (fb, pp, victim);
+ if (__glibc_likely (victim != NULL))
+ {
+ size_t victim_idx = fastbin_index (chunksize (victim));
+ if (__builtin_expect (victim_idx != idx, 0))
+ malloc_printerr ("malloc(): memory corruption (fast)");
+ check_remalloced_chunk (av, victim, nb);
+#if USE_TCACHE
+ /* While we're here, if we see other chunks of the same size,
+ stash them in the tcache. */
+ size_t tc_idx = csize2tidx (nb);
+ if (tcache && tc_idx < mp_.tcache_bins)
{
- REMOVE_FB (fb, tc_victim, pp);
- if (tc_victim != 0)
+ mchunkptr tc_victim;
+
+ /* While bin not empty and tcache not full, copy chunks. */
+ while (tcache->counts[tc_idx] < mp_.tcache_count
+ && (tc_victim = *fb) != NULL)
{
+ if (SINGLE_THREAD_P)
+ *fb = tc_victim->fd;
+ else
+ {
+ REMOVE_FB (fb, pp, tc_victim);
+ if (__glibc_unlikely (tc_victim == NULL))
+ break;
+ }
tcache_put (tc_victim, tc_idx);
- }
+ }
}
- }
#endif
- void *p = chunk2mem (victim);
- alloc_perturb (p, bytes);
- return p;
- }
+ void *p = chunk2mem (victim);
+ alloc_perturb (p, bytes);
+ return p;
+ }
+ }
}
/*
@@ -3628,11 +3642,9 @@ _int_malloc (mstate av, size_t bytes)
else
{
bck = victim->bk;
- if (__glibc_unlikely (bck->fd != victim))
- {
- errstr = "malloc(): smallbin double linked list corrupted";
- goto errout;
- }
+ if (__glibc_unlikely (bck->fd != victim))
+ malloc_printerr
+ ("malloc(): smallbin double linked list corrupted");
set_inuse_bit_at_offset (victim, nb);
bin->bk = bck;
bck->fd = bin;
@@ -3687,7 +3699,7 @@ _int_malloc (mstate av, size_t bytes)
else
{
idx = largebin_index (nb);
- if (have_fastchunks (av))
+ if (atomic_load_relaxed (&av->have_fastchunks))
malloc_consolidate (av);
}
@@ -3723,8 +3735,7 @@ _int_malloc (mstate av, size_t bytes)
if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (chunksize_nomask (victim)
> av->system_mem, 0))
- malloc_printerr (check_action, "malloc(): memory corruption",
- chunk2mem (victim), av);
+ malloc_printerr ("malloc(): memory corruption");
size = chunksize (victim);
/*
@@ -3929,11 +3940,8 @@ _int_malloc (mstate av, size_t bytes)
have to perform a complete insert here. */
bck = unsorted_chunks (av);
fwd = bck->fd;
- if (__glibc_unlikely (fwd->bk != bck))
- {
- errstr = "malloc(): corrupted unsorted chunks";
- goto errout;
- }
+ if (__glibc_unlikely (fwd->bk != bck))
+ malloc_printerr ("malloc(): corrupted unsorted chunks");
remainder->bk = bck;
remainder->fd = fwd;
bck->fd = remainder;
@@ -4036,11 +4044,8 @@ _int_malloc (mstate av, size_t bytes)
have to perform a complete insert here. */
bck = unsorted_chunks (av);
fwd = bck->fd;
- if (__glibc_unlikely (fwd->bk != bck))
- {
- errstr = "malloc(): corrupted unsorted chunks 2";
- goto errout;
- }
+ if (__glibc_unlikely (fwd->bk != bck))
+ malloc_printerr ("malloc(): corrupted unsorted chunks 2");
remainder->bk = bck;
remainder->fd = fwd;
bck->fd = remainder;
@@ -4102,7 +4107,7 @@ _int_malloc (mstate av, size_t bytes)
/* When we are using atomic ops to free fast chunks we can get
here for all block sizes. */
- else if (have_fastchunks (av))
+ else if (atomic_load_relaxed (&av->have_fastchunks))
{
malloc_consolidate (av);
/* restore original bin index */
@@ -4141,9 +4146,6 @@ _int_free (mstate av, mchunkptr p, int have_lock)
mchunkptr bck; /* misc temp for linking */
mchunkptr fwd; /* misc temp for linking */
- const char *errstr = NULL;
- int locked = 0;
-
size = chunksize (p);
/* Little security check which won't hurt performance: the
@@ -4152,21 +4154,11 @@ _int_free (mstate av, mchunkptr p, int have_lock)
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)
|| __builtin_expect (misaligned_chunk (p), 0))
- {
- errstr = "free(): invalid pointer";
- errout:
- if (!have_lock && locked)
- __libc_lock_unlock (av->mutex);
- malloc_printerr (check_action, errstr, chunk2mem (p), av);
- return;
- }
+ malloc_printerr ("free(): invalid pointer");
/* We know that each chunk is at least MINSIZE bytes in size or a
multiple of MALLOC_ALIGNMENT. */
if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size)))
- {
- errstr = "free(): invalid size";
- goto errout;
- }
+ malloc_printerr ("free(): invalid size");
check_inuse_chunk(av, p);
@@ -4205,60 +4197,59 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|| __builtin_expect (chunksize (chunk_at_offset (p, size))
>= av->system_mem, 0))
{
+ bool fail = true;
/* We might not have a lock at this point and concurrent modifications
- of system_mem might have let to a false positive. Redo the test
- after getting the lock. */
- if (have_lock
- || ({ assert (locked == 0);
- __libc_lock_lock (av->mutex);
- locked = 1;
- chunksize_nomask (chunk_at_offset (p, size)) <= 2 * SIZE_SZ
- || chunksize (chunk_at_offset (p, size)) >= av->system_mem;
- }))
- {
- errstr = "free(): invalid next size (fast)";
- goto errout;
- }
- if (! have_lock)
+ of system_mem might result in a false positive. Redo the test after
+ getting the lock. */
+ if (!have_lock)
{
+ __libc_lock_lock (av->mutex);
+ fail = (chunksize_nomask (chunk_at_offset (p, size)) <= 2 * SIZE_SZ
+ || chunksize (chunk_at_offset (p, size)) >= av->system_mem);
__libc_lock_unlock (av->mutex);
- locked = 0;
}
+
+ if (fail)
+ malloc_printerr ("free(): invalid next size (fast)");
}
free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
- set_fastchunks(av);
+ atomic_store_relaxed (&av->have_fastchunks, true);
unsigned int idx = fastbin_index(size);
fb = &fastbin (av, idx);
/* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */
mchunkptr old = *fb, old2;
- unsigned int old_idx = ~0u;
- do
- {
- /* Check that the top of the bin is not the record we are going to add
- (i.e., double free). */
- if (__builtin_expect (old == p, 0))
- {
- errstr = "double free or corruption (fasttop)";
- goto errout;
- }
- /* Check that size of fastbin chunk at the top is the same as
- size of the chunk that we are adding. We can dereference OLD
- only if we have the lock, otherwise it might have already been
- deallocated. See use of OLD_IDX below for the actual check. */
- if (have_lock && old != NULL)
- old_idx = fastbin_index(chunksize(old));
- p->fd = old2 = old;
- }
- while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2);
- if (have_lock && old != NULL && __builtin_expect (old_idx != idx, 0))
+ if (SINGLE_THREAD_P)
{
- errstr = "invalid fastbin entry (free)";
- goto errout;
+ /* Check that the top of the bin is not the record we are going to
+ add (i.e., double free). */
+ if (__builtin_expect (old == p, 0))
+ malloc_printerr ("double free or corruption (fasttop)");
+ p->fd = old;
+ *fb = p;
}
+ else
+ do
+ {
+ /* Check that the top of the bin is not the record we are going to
+ add (i.e., double free). */
+ if (__builtin_expect (old == p, 0))
+ malloc_printerr ("double free or corruption (fasttop)");
+ p->fd = old2 = old;
+ }
+ while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2))
+ != old2);
+
+ /* Check that size of fastbin chunk at the top is the same as
+ size of the chunk that we are adding. We can dereference OLD
+ only if we have the lock, otherwise it might have already been
+ allocated again. */
+ if (have_lock && old != NULL
+ && __builtin_expect (fastbin_index (chunksize (old)) != idx, 0))
+ malloc_printerr ("invalid fastbin entry (free)");
}
/*
@@ -4266,42 +4257,33 @@ _int_free (mstate av, mchunkptr p, int have_lock)
*/
else if (!chunk_is_mmapped(p)) {
- if (! have_lock) {
+
+ /* If we're single-threaded, don't lock the arena. */
+ if (SINGLE_THREAD_P)
+ have_lock = true;
+
+ if (!have_lock)
__libc_lock_lock (av->mutex);
- locked = 1;
- }
nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the
top block. */
if (__glibc_unlikely (p == av->top))
- {
- errstr = "double free or corruption (top)";
- goto errout;
- }
+ malloc_printerr ("double free or corruption (top)");
/* Or whether the next chunk is beyond the boundaries of the arena. */
if (__builtin_expect (contiguous (av)
&& (char *) nextchunk
>= ((char *) av->top + chunksize(av->top)), 0))
- {
- errstr = "double free or corruption (out)";
- goto errout;
- }
+ malloc_printerr ("double free or corruption (out)");
/* Or whether the block is actually not marked used. */
if (__glibc_unlikely (!prev_inuse(nextchunk)))
- {
- errstr = "double free or corruption (!prev)";
- goto errout;
- }
+ malloc_printerr ("double free or corruption (!prev)");
nextsize = chunksize(nextchunk);
if (__builtin_expect (chunksize_nomask (nextchunk) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (nextsize >= av->system_mem, 0))
- {
- errstr = "free(): invalid next size (normal)";
- goto errout;
- }
+ malloc_printerr ("free(): invalid next size (normal)");
free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
@@ -4333,10 +4315,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
bck = unsorted_chunks(av);
fwd = bck->fd;
if (__glibc_unlikely (fwd->bk != bck))
- {
- errstr = "free(): corrupted unsorted chunks";
- goto errout;
- }
+ malloc_printerr ("free(): corrupted unsorted chunks");
p->fd = fwd;
p->bk = bck;
if (!in_smallbin_range(size))
@@ -4379,7 +4358,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
*/
if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
- if (have_fastchunks(av))
+ if (atomic_load_relaxed (&av->have_fastchunks))
malloc_consolidate(av);
if (av == &main_arena) {
@@ -4398,10 +4377,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
}
}
- if (! have_lock) {
- assert (locked);
+ if (!have_lock)
__libc_lock_unlock (av->mutex);
- }
}
/*
If the chunk was allocated via mmap, release via munmap().
@@ -4450,7 +4427,7 @@ static void malloc_consolidate(mstate av)
*/
if (get_max_fast () != 0) {
- clear_fastchunks(av);
+ atomic_store_relaxed (&av->have_fastchunks, false);
unsorted_bin = unsorted_chunks(av);
@@ -4549,17 +4526,10 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
INTERNAL_SIZE_T* s; /* copy source */
INTERNAL_SIZE_T* d; /* copy destination */
- const char *errstr = NULL;
-
/* oldmem size */
if (__builtin_expect (chunksize_nomask (oldp) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (oldsize >= av->system_mem, 0))
- {
- errstr = "realloc(): invalid old size";
- errout:
- malloc_printerr (check_action, errstr, chunk2mem (oldp), av);
- return NULL;
- }
+ malloc_printerr ("realloc(): invalid old size");
check_inuse_chunk (av, oldp);
@@ -4570,10 +4540,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
INTERNAL_SIZE_T nextsize = chunksize (next);
if (__builtin_expect (chunksize_nomask (next) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (nextsize >= av->system_mem, 0))
- {
- errstr = "realloc(): invalid next size";
- goto errout;
- }
+ malloc_printerr ("realloc(): invalid next size");
if ((unsigned long) (oldsize) >= (unsigned long) (nb))
{
@@ -4798,10 +4765,6 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
static int
mtrim (mstate av, size_t pad)
{
- /* Don't touch corrupt arenas. */
- if (arena_is_corrupt (av))
- return 0;
-
/* Ensure initialization/consolidation */
malloc_consolidate (av);
@@ -5113,8 +5076,6 @@ static inline int
__always_inline
do_set_mallopt_check (int32_t value)
{
- LIBC_PROBE (memory_mallopt_check_action, 2, value, check_action);
- check_action = value;
return 1;
}
@@ -5388,32 +5349,10 @@ libc_hidden_def (__libc_mallopt)
extern char **__libc_argv attribute_hidden;
static void
-malloc_printerr (int action, const char *str, void *ptr, mstate ar_ptr)
+malloc_printerr (const char *str)
{
- /* Avoid using this arena in future. We do not attempt to synchronize this
- with anything else because we minimally want to ensure that __libc_message
- gets its resources safely without stumbling on the current corruption. */
- if (ar_ptr)
- set_arena_corrupt (ar_ptr);
-
- if ((action & 5) == 5)
- __libc_message ((action & 2) ? (do_abort | do_backtrace) : do_message,
- "%s\n", str);
- else if (action & 1)
- {
- char buf[2 * sizeof (uintptr_t) + 1];
-
- buf[sizeof (buf) - 1] = '\0';
- char *cp = _itoa_word ((uintptr_t) ptr, &buf[sizeof (buf) - 1], 16, 0);
- while (cp > buf)
- *--cp = '0';
-
- __libc_message ((action & 2) ? (do_abort | do_backtrace) : do_message,
- "*** Error in `%s': %s: 0x%s ***\n",
- __libc_argv[0] ? : "<unknown>", str, cp);
- }
- else if (action & 2)
- abort ();
+ __libc_message (do_abort, "%s\n", str);
+ __builtin_unreachable ();
}
/* We need a wrapper function for one of the additions of POSIX. */
diff --git a/malloc/tst-dynarray.c b/malloc/tst-dynarray.c
index 2206d75e31..d11f7bb8a3 100644
--- a/malloc/tst-dynarray.c
+++ b/malloc/tst-dynarray.c
@@ -18,6 +18,9 @@
#include "tst-dynarray-shared.h"
+#include <errno.h>
+#include <stdint.h>
+
#define DYNARRAY_STRUCT dynarray_long
#define DYNARRAY_ELEMENT long
#define DYNARRAY_PREFIX dynarray_long_
@@ -463,6 +466,31 @@ test_long_init (void)
}
}
+/* Test overflow in resize. */
+static void
+test_long_overflow (void)
+{
+ {
+ struct dynarray_long dyn;
+ dynarray_long_init (&dyn);
+ errno = EINVAL;
+ TEST_VERIFY (!dynarray_long_resize
+ (&dyn, (SIZE_MAX / sizeof (long)) + 1));
+ TEST_VERIFY (errno == ENOMEM);
+ TEST_VERIFY (dynarray_long_has_failed (&dyn));
+ }
+
+ {
+ struct dynarray_long_noscratch dyn;
+ dynarray_long_noscratch_init (&dyn);
+ errno = EINVAL;
+ TEST_VERIFY (!dynarray_long_noscratch_resize
+ (&dyn, (SIZE_MAX / sizeof (long)) + 1));
+ TEST_VERIFY (errno == ENOMEM);
+ TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn));
+ }
+}
+
/* Test NUL-terminated string construction with the add function and
the simple finalize function. */
static void
@@ -538,6 +566,7 @@ do_test (void)
test_int ();
test_str ();
test_long_init ();
+ test_long_overflow ();
test_zstr ();
return 0;
}
diff --git a/malloc/tst-malloc-tcache-leak.c b/malloc/tst-malloc-tcache-leak.c
new file mode 100644
index 0000000000..22c679b65b
--- /dev/null
+++ b/malloc/tst-malloc-tcache-leak.c
@@ -0,0 +1,112 @@
+/* Bug 22111: Test that threads do not leak their per thread cache.
+ Copyright (C) 2015-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* The point of this test is to start and exit a large number of
+ threads, while at the same time looking to see if the used
+ memory grows with each round of threads run. If the memory
+ grows above some linear bound we declare the test failed and
+ that the malloc implementation is leaking memory with each
+ thread. This is a good indicator that the thread local cache
+ is leaking chunks. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xthread.h>
+
+void *
+worker (void *data)
+{
+ void *ret;
+ /* Allocate an arbitrary amount of memory that is known to fit into
+ the thread local cache (tcache). If we have at least 64 bins
+ (default e.g. TCACHE_MAX_BINS) we should be able to allocate 32
+ bytes and force malloc to fill the tcache. We are assuming tcahce
+ init happens at the first small alloc, but it might in the future
+ be deferred to some other point. Therefore to future proof this
+ test we include a full alloc/free/alloc cycle for the thread. We
+ need a compiler barrier to avoid the removal of the useless
+ alloc/free. We send some memory back to main to have the memory
+ freed after the thread dies, as just another check that the chunks
+ that were previously in the tcache are still OK to free after
+ thread death. */
+ ret = xmalloc (32);
+ __asm__ volatile ("" ::: "memory");
+ free (ret);
+ return (void *) xmalloc (32);
+}
+
+static int
+do_test (void)
+{
+ pthread_t *thread;
+ struct mallinfo info_before, info_after;
+ void *retval;
+
+ /* This is an arbitrary choice. We choose a total of THREADS
+ threads created and joined. This gives us enough iterations to
+ show a leak. */
+ int threads = 100000;
+
+ /* Avoid there being 0 malloc'd data at this point by allocating the
+ pthread_t required to run the test. */
+ thread = (pthread_t *) xcalloc (1, sizeof (pthread_t));
+
+ info_before = mallinfo ();
+
+ assert (info_before.uordblks != 0);
+
+ printf ("INFO: %d (bytes) are in use before starting threads.\n",
+ info_before.uordblks);
+
+ for (int loop = 0; loop < threads; loop++)
+ {
+ *thread = xpthread_create (NULL, worker, NULL);
+ retval = xpthread_join (*thread);
+ free (retval);
+ }
+
+ info_after = mallinfo ();
+ printf ("INFO: %d (bytes) are in use after all threads joined.\n",
+ info_after.uordblks);
+
+ /* We need to compare the memory in use before and the memory in use
+ after starting and joining THREADS threads. We almost always grow
+ memory slightly, but not much. Consider that if even 1-byte leaked
+ per thread we'd have THREADS bytes of additional memory, and in
+ general the in-use at the start of main is quite low. We will
+ always leak a full malloc chunk, and never just 1-byte, therefore
+ anything above "+ threads" from the start (constant offset) is a
+ leak. Obviously this assumes no thread-related malloc'd internal
+ libc data structures persist beyond the thread death, and any that
+ did would limit the number of times you could call pthread_create,
+ which is a QoI we'd want to detect and fix. */
+ if (info_after.uordblks > (info_before.uordblks + threads))
+ FAIL_EXIT1 ("Memory usage after threads is too high.\n");
+
+ /* Did not detect excessive memory usage. */
+ free (thread);
+ exit (0);
+}
+
+#include <support/test-driver.c>
diff --git a/malloc/tst-realloc.c b/malloc/tst-realloc.c
index 31a58bd026..d942c6e536 100644
--- a/malloc/tst-realloc.c
+++ b/malloc/tst-realloc.c
@@ -66,10 +66,6 @@ do_test (void)
if (p == NULL)
merror ("realloc (NULL, 10) failed.");
- /* errno should be clear on success (POSIX). */
- if (p != NULL && save != 0)
- merror ("errno is set but should not be");
-
free (p);
p = calloc (20, 1);
diff --git a/manual/memory.texi b/manual/memory.texi
index 82f473806c..51a5f4e83c 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1104,7 +1104,6 @@ When calling @code{mallopt}, the @var{param} argument specifies the
parameter to be set, and @var{value} the new value to be set. Possible
choices for @var{param}, as defined in @file{malloc.h}, are:
-@comment TODO: @item M_CHECK_ACTION
@vtable @code
@item M_MMAP_MAX
The maximum number of chunks to allocate with @code{mmap}. Setting this
@@ -1309,17 +1308,15 @@ The block was already freed.
Another possibility to check for and guard against bugs in the use of
@code{malloc}, @code{realloc} and @code{free} is to set the environment
-variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set, a
-special (less efficient) implementation is used which is designed to be
-tolerant against simple errors, such as double calls of @code{free} with
-the same argument, or overruns of a single byte (off-by-one bugs). Not
-all such errors can be protected against, however, and memory leaks can
-result. If @code{MALLOC_CHECK_} is set to @code{0}, any detected heap
-corruption is silently ignored; if set to @code{1}, a diagnostic is
-printed on @code{stderr}; if set to @code{2}, @code{abort} is called
-immediately. This can be useful because otherwise a crash may happen
-much later, and the true cause for the problem is then very hard to
-track down.
+variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set to a
+non-zero value, a special (less efficient) implementation is used which
+is designed to be tolerant against simple errors, such as double calls
+of @code{free} with the same argument, or overruns of a single byte
+(off-by-one bugs). Not all such errors can be protected against,
+however, and memory leaks can result.
+
+Any detected heap corruption results in immediate termination of the
+process.
There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries
it could possibly be exploited since diverging from the normal programs
diff --git a/manual/probes.texi b/manual/probes.texi
index 96acaed206..8ab67562d7 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -195,13 +195,6 @@ this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic
threshold adjustment was already disabled.
@end deftp
-@deftp Probe memory_mallopt_check_action (int @var{$arg1}, int @var{$arg2})
-This probe is triggered shortly after the @code{memory_mallopt} probe,
-when the parameter to be changed is @code{M_CHECK_ACTION}. Argument
-@var{$arg1} is the requested value, and @var{$arg2} is the previous
-value of this @code{malloc} parameter.
-@end deftp
-
@deftp Probe memory_mallopt_perturb (int @var{$arg1}, int @var{$arg2})
This probe is triggered shortly after the @code{memory_mallopt} probe,
when the parameter to be changed is @code{M_PERTURB}. Argument
diff --git a/manual/terminal.texi b/manual/terminal.texi
index 4fef5045b8..4aace48b14 100644
--- a/manual/terminal.texi
+++ b/manual/terminal.texi
@@ -109,6 +109,11 @@ The @var{filedes} is not associated with a terminal.
@item ERANGE
The buffer length @var{len} is too small to store the string to be
returned.
+
+@item ENODEV
+The @var{filedes} is associated with a terminal device that is a slave
+pseudo-terminal, but the file name associated with that device could
+not be determined. This is a GNU extension.
@end table
@end deftypefun
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 4c658bf3df..b09e3fe791 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -71,27 +71,13 @@ following tunables in the @code{malloc} namespace:
This tunable supersedes the @env{MALLOC_CHECK_} environment variable and is
identical in features.
-Setting this tunable enables a special (less efficient) memory allocator for
-the malloc family of functions that is designed to be tolerant against simple
-errors such as double calls of free with the same argument, or overruns of a
-single byte (off-by-one bugs). Not all such errors can be protected against,
-however, and memory leaks can result. The following list describes the values
-that this tunable can take and the effect they have on malloc functionality:
-
-@itemize @bullet
-@item @code{0} Ignore all errors. The default allocator continues to be in
-use, but all errors are silently ignored.
-@item @code{1} Report errors. The alternate allocator is selected and heap
-corruption, if detected, is reported as diagnostic messages to @code{stderr}
-and the program continues execution.
-@item @code{2} Abort on errors. The alternate allocator is selected and if
-heap corruption is detected, the program is ended immediately by calling
-@code{abort}.
-@item @code{3} Fully enabled. The alternate allocator is selected and is fully
-functional. That is, if heap corruption is detected, a verbose diagnostic
-message is printed to @code{stderr} and the program is ended by calling
-@code{abort}.
-@end itemize
+Setting this tunable to a non-zero value enables a special (less
+efficient) memory allocator for the malloc family of functions that is
+designed to be tolerant against simple errors such as double calls of
+free with the same argument, or overruns of a single byte (off-by-one
+bugs). Not all such errors can be protected against, however, and memory
+leaks can result. Any detected heap corruption results in immediate
+termination of the process.
Like @env{MALLOC_CHECK_}, @code{glibc.malloc.check} has a problem in that it
diverges from normal program behavior by writing to @code{stderr}, which could
@@ -267,7 +253,7 @@ This tunable is specific to i386 and x86-64.
@deftp Tunable glibc.tune.cpu
The @code{glibc.tune.cpu=xxx} tunable allows the user to tell @theglibc{} to
assume that the CPU is @code{xxx} where xxx may have one of these values:
-@code{generic}, @code{thunderxt88}.
+@code{generic}, @code{falkor}, @code{thunderxt88}.
This tunable is specific to aarch64.
@end deftp
diff --git a/math/Makefile b/math/Makefile
index e09b0c0545..2c17c68eda 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -203,7 +203,8 @@ tests-static = test-fpucw-static test-fpucw-ieee-static \
test-signgam-ullong-static test-signgam-ullong-init-static
ifneq (,$(CXX))
-tests += test-math-isinff test-math-iszero
+tests += test-math-isinff test-math-iszero test-math-issignaling \
+ test-math-iscanonical
endif
ifneq (no,$(PERL))
@@ -350,6 +351,8 @@ CFLAGS-test-signgam-ullong-init-static.c = -std=c99
CFLAGS-test-math-isinff.cc = -std=gnu++11
CFLAGS-test-math-iszero.cc = -std=gnu++11
+CFLAGS-test-math-issignaling.cc = -std=gnu++11
+CFLAGS-test-math-iscanonical.cc = -std=gnu++11
CFLAGS-test-iszero-excess-precision.c = -fexcess-precision=standard
CFLAGS-test-iseqsig-excess-precision.c = -fexcess-precision=standard
diff --git a/math/math.h b/math/math.h
index e21708045a..ba26624835 100644
--- a/math/math.h
+++ b/math/math.h
@@ -402,7 +402,13 @@ enum
/* Return number of classification appropriate for X. */
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \
- && !defined __OPTIMIZE_SIZE__
+ && (!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
+ libstdc++, only to let its configure test work when it is built
+ with -Os. No further use of this definition of fpclassify is
+ expected in C++ mode, since libstdc++ provides its own version
+ of fpclassify in cmath (which undefines fpclassify). */
# define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \
FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
# else
@@ -412,6 +418,15 @@ enum
/* Return nonzero value if sign of X is negative. */
# 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
+ __builtin_types_compatible_p, which is a C-only builtin.
+ The check for __cplusplus allows the use of the builtin instead of
+ __MATH_TG. This is provided for libstdc++, only to let its configure
+ test work. No further use of this definition of signbit is expected
+ in C++ mode, since libstdc++ provides its own version of signbit
+ in cmath (which undefines signbit). */
+# define signbit(x) __builtin_signbitl (x)
# elif __GNUC_PREREQ (4,0)
# define signbit(x) __MATH_TG ((x), __builtin_signbit, (x))
# else
@@ -442,8 +457,12 @@ enum
/* Return nonzero value if X is positive or negative infinity. */
# if __HAVE_DISTINCT_FLOAT128 && !__GNUC_PREREQ (7,0) \
- && !defined __SUPPORT_SNAN__
- /* __builtin_isinf_sign is broken for float128 only before GCC 7.0. */
+ && !defined __SUPPORT_SNAN__ && !defined __cplusplus
+ /* Since __builtin_isinf_sign is broken for float128 before GCC 7.0,
+ use the helper function, __isinff128, with older compilers. This is
+ only provided for C mode, because in C++ mode, GCC has no support
+ for __builtin_types_compatible_p (and when in C++ mode, this macro is
+ not used anyway, because libstdc++ headers undefine it). */
# define isinf(x) \
(__builtin_types_compatible_p (__typeof (x), _Float128) \
? __isinff128 (x) : __builtin_isinf_sign (x))
@@ -470,7 +489,32 @@ enum
# include <bits/iscanonical.h>
/* Return nonzero value if X is a signaling NaN. */
-# define issignaling(x) __MATH_TG ((x), __issignaling, (x))
+# ifndef __cplusplus
+# define issignaling(x) __MATH_TG ((x), __issignaling, (x))
+# else
+ /* In C++ mode, __MATH_TG cannot be used, because it relies on
+ __builtin_types_compatible_p, which is a C-only builtin. On the
+ other hand, overloading provides the means to distinguish between
+ the floating-point types. The overloading resolution will match
+ the correct parameter (regardless of type qualifiers (i.e.: const
+ and volatile)). */
+extern "C++" {
+inline int issignaling (float __val) { return __issignalingf (__val); }
+inline int issignaling (double __val) { return __issignaling (__val); }
+inline int
+issignaling (long double __val)
+{
+# ifdef __NO_LONG_DOUBLE_MATH
+ return __issignaling (__val);
+# else
+ return __issignalingl (__val);
+# endif
+}
+# if __HAVE_DISTINCT_FLOAT128
+inline int issignaling (_Float128 __val) { return __issignalingf128 (__val); }
+# endif
+} /* extern C++ */
+# endif
/* Return nonzero value if X is subnormal. */
# define issubnormal(x) (fpclassify (x) == FP_SUBNORMAL)
@@ -484,15 +528,40 @@ enum
# endif
# else /* __cplusplus */
extern "C++" {
+# ifdef __SUPPORT_SNAN__
+inline int
+iszero (float __val)
+{
+ return __fpclassifyf (__val) == FP_ZERO;
+}
+inline int
+iszero (double __val)
+{
+ return __fpclassify (__val) == FP_ZERO;
+}
+inline int
+iszero (long double __val)
+{
+# ifdef __NO_LONG_DOUBLE_MATH
+ return __fpclassify (__val) == FP_ZERO;
+# else
+ return __fpclassifyl (__val) == FP_ZERO;
+# endif
+}
+# if __HAVE_DISTINCT_FLOAT128
+inline int
+iszero (_Float128 __val)
+{
+ return __fpclassifyf128 (__val) == FP_ZERO;
+}
+# endif
+# else
template <class __T> inline bool
iszero (__T __val)
{
-# ifdef __SUPPORT_SNAN__
- return fpclassify (__val) == FP_ZERO;
-# else
return __val == 0;
-# endif
}
+# endif
} /* extern C++ */
# endif /* __cplusplus */
#endif /* Use IEC_60559_BFP_EXT. */
diff --git a/math/test-math-iscanonical.cc b/math/test-math-iscanonical.cc
new file mode 100644
index 0000000000..4cfb1c5055
--- /dev/null
+++ b/math/test-math-iscanonical.cc
@@ -0,0 +1,48 @@
+/* Test for the C++ implementation of iscanonical.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define _GNU_SOURCE 1
+#include <math.h>
+#include <stdio.h>
+
+static int errors;
+
+template <class T>
+static void
+check_type ()
+{
+ T val = 0;
+
+ /* Check if iscanonical is available in C++ mode (bug 22235). */
+ if (iscanonical (val) == 0)
+ errors++;
+}
+
+static int
+do_test (void)
+{
+ check_type<float> ();
+ check_type<double> ();
+ check_type<long double> ();
+#if __HAVE_DISTINCT_FLOAT128
+ check_type<_Float128> ();
+#endif
+ return errors != 0;
+}
+
+#include <support/test-driver.c>
diff --git a/math/test-math-issignaling.cc b/math/test-math-issignaling.cc
new file mode 100644
index 0000000000..22ae9e1bca
--- /dev/null
+++ b/math/test-math-issignaling.cc
@@ -0,0 +1,113 @@
+/* Test for the C++ implementation of issignaling.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define _GNU_SOURCE 1
+#include <math.h>
+#include <stdio.h>
+
+#include <limits>
+
+/* There is no signaling_NaN for _Float128 in std::numeric_limits.
+ Include ieee754_float128.h and use the bitfields in the union
+ ieee854_float128.ieee_nan to build a signaling NaN. */
+#if __HAVE_DISTINCT_FLOAT128
+# include <ieee754_float128.h>
+#endif
+
+static bool errors;
+
+static void
+check (int actual, int expected, const char *actual_expr, int line)
+{
+ if (actual != expected)
+ {
+ errors = true;
+ printf ("%s:%d: error: %s\n", __FILE__, line, actual_expr);
+ printf ("%s:%d: expected: %d\n", __FILE__, line, expected);
+ printf ("%s:%d: actual: %d\n", __FILE__, line, actual);
+ }
+}
+
+#define CHECK(actual, expected) \
+ check ((actual), (expected), #actual, __LINE__)
+
+template <class T>
+static void
+check_type ()
+{
+ typedef std::numeric_limits<T> limits;
+ CHECK (issignaling (T{0}), 0);
+ if (limits::has_infinity)
+ {
+ CHECK (issignaling (limits::infinity ()), 0);
+ CHECK (issignaling (-limits::infinity ()), 0);
+ }
+ if (limits::has_quiet_NaN)
+ CHECK (issignaling (limits::quiet_NaN ()), 0);
+ if (limits::has_signaling_NaN)
+ CHECK (issignaling (limits::signaling_NaN ()), 1);
+}
+
+#if __HAVE_DISTINCT_FLOAT128
+static void
+check_float128 ()
+{
+ ieee854_float128 q;
+
+ q.d = 0;
+ CHECK (issignaling (q.d), 0);
+
+ /* Infinity. */
+ q.ieee.negative = 0;
+ q.ieee.exponent = 0x7FFF;
+ q.ieee.mantissa0 = 0x0000;
+ q.ieee.mantissa1 = 0x00000000;
+ q.ieee.mantissa2 = 0x00000000;
+ q.ieee.mantissa3 = 0x00000000;
+ CHECK (issignaling (q.d), 0);
+
+ /* Quiet NaN. */
+ q.ieee_nan.quiet_nan = 1;
+ q.ieee_nan.mantissa0 = 0x0000;
+ CHECK (issignaling (q.d), 0);
+
+ /* Still a quiet NaN. */
+ q.ieee_nan.quiet_nan = 1;
+ q.ieee_nan.mantissa0 = 0x4000;
+ CHECK (issignaling (q.d), 0);
+
+ /* Signaling NaN. */
+ q.ieee_nan.quiet_nan = 0;
+ q.ieee_nan.mantissa0 = 0x4000;
+ CHECK (issignaling (q.d), 1);
+}
+#endif
+
+static int
+do_test (void)
+{
+ check_type<float> ();
+ check_type<double> ();
+ check_type<long double> ();
+#if __HAVE_DISTINCT_FLOAT128
+ check_float128 ();
+#endif
+ return errors;
+}
+
+#include <support/test-driver.c>
diff --git a/math/test-math-iszero.cc b/math/test-math-iszero.cc
index 027e972654..5c07261626 100644
--- a/math/test-math-iszero.cc
+++ b/math/test-math-iszero.cc
@@ -22,6 +22,13 @@
#include <limits>
+/* Support for _Float128 in std::numeric_limits is limited.
+ Include ieee754_float128.h and use the bitfields in the union
+ ieee854_float128.ieee_nan to build corner-case inputs. */
+#if __HAVE_DISTINCT_FLOAT128
+# include <ieee754_float128.h>
+#endif
+
static bool errors;
static void
@@ -72,12 +79,84 @@ check_type ()
std::numeric_limits<T>::has_denorm == std::denorm_absent);
}
+#if __HAVE_DISTINCT_FLOAT128
+static void
+check_float128 ()
+{
+ ieee854_float128 q;
+
+ q.d = 0.0Q;
+ CHECK (iszero (q.d), 1);
+ q.d = -0.0Q;
+ CHECK (iszero (q.d), 1);
+ q.d = 1.0Q;
+ CHECK (iszero (q.d), 0);
+ q.d = -1.0Q;
+ CHECK (iszero (q.d), 0);
+
+ /* Normal min. */
+ q.ieee.negative = 0;
+ q.ieee.exponent = 0x0001;
+ q.ieee.mantissa0 = 0x0000;
+ q.ieee.mantissa1 = 0x00000000;
+ q.ieee.mantissa2 = 0x00000000;
+ q.ieee.mantissa3 = 0x00000000;
+ CHECK (iszero (q.d), 0);
+ q.ieee.negative = 1;
+ CHECK (iszero (q.d), 0);
+
+ /* Normal max. */
+ q.ieee.negative = 0;
+ q.ieee.exponent = 0x7FFE;
+ q.ieee.mantissa0 = 0xFFFF;
+ q.ieee.mantissa1 = 0xFFFFFFFF;
+ q.ieee.mantissa2 = 0xFFFFFFFF;
+ q.ieee.mantissa3 = 0xFFFFFFFF;
+ CHECK (iszero (q.d), 0);
+ q.ieee.negative = 1;
+ CHECK (iszero (q.d), 0);
+
+ /* Infinity. */
+ q.ieee.negative = 0;
+ q.ieee.exponent = 0x7FFF;
+ q.ieee.mantissa0 = 0x0000;
+ q.ieee.mantissa1 = 0x00000000;
+ q.ieee.mantissa2 = 0x00000000;
+ q.ieee.mantissa3 = 0x00000000;
+ CHECK (iszero (q.d), 0);
+
+ /* Quiet NaN. */
+ q.ieee_nan.quiet_nan = 1;
+ q.ieee_nan.mantissa0 = 0x0000;
+ CHECK (iszero (q.d), 0);
+
+ /* Signaling NaN. */
+ q.ieee_nan.quiet_nan = 0;
+ q.ieee_nan.mantissa0 = 0x4000;
+ CHECK (iszero (q.d), 0);
+
+ /* Denormal min. */
+ q.ieee.negative = 0;
+ q.ieee.exponent = 0x0000;
+ q.ieee.mantissa0 = 0x0000;
+ q.ieee.mantissa1 = 0x00000000;
+ q.ieee.mantissa2 = 0x00000000;
+ q.ieee.mantissa3 = 0x00000001;
+ CHECK (iszero (q.d), 0);
+ q.ieee.negative = 1;
+ CHECK (iszero (q.d), 0);
+}
+#endif
+
static int
do_test (void)
{
check_type<float> ();
check_type<double> ();
check_type<long double> ();
+#if __HAVE_DISTINCT_FLOAT128
+ check_float128 ();
+#endif
return errors;
}
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 06523bfe9c..0c808216a4 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -464,17 +464,18 @@
# define __glibc_macro_warning(msg)
#endif
-/* Support for generic selection (ISO C11) is available in GCC since
- version 4.9. Previous versions do not provide generic selection,
- even though they might set __STDC_VERSION__ to 201112L, when in
- -std=c11 mode. Thus, we must check for !defined __GNUC__ when
- testing __STDC_VERSION__ for generic selection support.
+/* Generic selection (ISO C11) is a C-only feature, available in GCC
+ since version 4.9. Previous versions do not provide generic
+ selection, even though they might set __STDC_VERSION__ to 201112L,
+ when in -std=c11 mode. Thus, we must check for !defined __GNUC__
+ when testing __STDC_VERSION__ for generic selection support.
On the other hand, Clang also defines __GNUC__, so a clang-specific
check is required to enable the use of generic selection. */
-#if __GNUC_PREREQ (4, 9) \
- || __glibc_clang_has_extension (c_generic_selections) \
- || (!defined __GNUC__ && defined __STDC_VERSION__ \
- && __STDC_VERSION__ >= 201112L)
+#if !defined __cplusplus \
+ && (__GNUC_PREREQ (4, 9) \
+ || __glibc_clang_has_extension (c_generic_selections) \
+ || (!defined __GNUC__ && defined __STDC_VERSION__ \
+ && __STDC_VERSION__ >= 201112L))
# define __HAVE_GENERIC_SELECTION 1
#else
# define __HAVE_GENERIC_SELECTION 0
diff --git a/nptl/Makefile b/nptl/Makefile
index 5cb1bb2c3d..0b01e18106 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -227,6 +227,10 @@ CFLAGS-pt-system.c = -fexceptions
LDLIBS-tst-once5 = -lstdc++
CFLAGS-tst-thread_local1.o = -std=gnu++11
LDLIBS-tst-thread_local1 = -lstdc++
+CFLAGS-tst-thread-exit-clobber.o = -std=gnu++11
+LDLIBS-tst-thread-exit-clobber = -lstdc++
+CFLAGS-tst-minstack-throw.o = -std=gnu++11
+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 \
@@ -302,7 +306,9 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
c89 gnu89 c99 gnu99 c11 gnu11) \
tst-bad-schedattr \
tst-thread_local1 tst-mutex-errorcheck tst-robust10 \
- tst-robust-fork tst-create-detached tst-memstream
+ tst-robust-fork tst-create-detached tst-memstream \
+ tst-thread-exit-clobber tst-minstack-cancel tst-minstack-exit \
+ tst-minstack-throw
tests-internal := tst-typesizes \
tst-rwlock19 tst-rwlock20 \
@@ -367,7 +373,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
+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)
@@ -379,7 +385,7 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
- tst-join7mod
+ tst-join7mod tst-compat-forwarder-mod
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \
tst-cleanup4aux.o tst-cleanupx4aux.o
test-extras += tst-cleanup4aux tst-cleanupx4aux
@@ -453,7 +459,8 @@ endif
ifeq (,$(CXX))
# These tests require a C++ compiler and runtime.
-tests-unsupported += tst-cancel24 tst-cancel24-static tst-once5
+tests-unsupported += tst-cancel24 tst-cancel24-static tst-once5 \
+ tst-thread-exit-clobber tst-minstack-throw
endif
# These tests require a C++ compiler and runtime with thread_local support.
ifneq ($(have-cxx-thread_local),yes)
@@ -718,6 +725,8 @@ $(objpfx)tst-oddstacklimit.out: $(objpfx)tst-oddstacklimit $(objpfx)tst-basic1
$(evaluate-test)
endif
+$(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
+
# The tests here better do not run in parallel
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
.NOTPARALLEL:
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index ce2e24af95..e351ce9d99 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -356,7 +356,7 @@ setup_stack_prot (char *mem, size_t size, char *guard, size_t guardsize,
const int prot)
{
char *guardend = guard + guardsize;
-#if _STACK_GROWS_DOWN
+#if _STACK_GROWS_DOWN && !defined(NEED_SEPARATE_REGISTER_STACK)
/* As defined at guard_position, for architectures with downward stack
the guard page is always at start of the allocated area. */
if (__mprotect (guardend, size - guardsize, prot) != 0)
@@ -372,6 +372,33 @@ setup_stack_prot (char *mem, size_t size, char *guard, size_t guardsize,
return 0;
}
+/* Mark the memory of the stack as usable to the kernel. It frees everything
+ except for the space used for the TCB itself. */
+static inline void
+__always_inline
+advise_stack_range (void *mem, size_t size, uintptr_t pd, size_t guardsize)
+{
+ uintptr_t sp = (uintptr_t) CURRENT_STACK_FRAME;
+ size_t pagesize_m1 = __getpagesize () - 1;
+#if _STACK_GROWS_DOWN && !defined(NEED_SEPARATE_REGISTER_STACK)
+ size_t freesize = (sp - (uintptr_t) mem) & ~pagesize_m1;
+ assert (freesize < size);
+ if (freesize > PTHREAD_STACK_MIN)
+ __madvise (mem, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
+#else
+ /* Page aligned start of memory to free (higher than or equal
+ to current sp plus the minimum stack size). */
+ uintptr_t freeblock = (sp + PTHREAD_STACK_MIN + pagesize_m1) & ~pagesize_m1;
+ uintptr_t free_end = (pd - guardsize) & ~pagesize_m1;
+ if (free_end > freeblock)
+ {
+ size_t freesize = free_end - freeblock;
+ assert (freesize < size);
+ __madvise ((void*) freeblock, freesize, MADV_DONTNEED);
+ }
+#endif
+}
+
/* Returns a usable stack for a new thread either by allocating a
new stack or reusing a cached stack of sufficient size.
ATTR must be non-NULL and point to a valid pthread_attr.
@@ -506,6 +533,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* Make sure the size of the stack is enough for the guard and
eventually the thread descriptor. */
guardsize = (attr->guardsize + pagesize_m1) & ~pagesize_m1;
+ if (guardsize < attr->guardsize || size + guardsize < guardsize)
+ /* Arithmetic overflow. */
+ return EINVAL;
+ size += guardsize;
if (__builtin_expect (size < ((guardsize + __static_tls_size
+ MINIMAL_REST_STACK + pagesize_m1)
& ~pagesize_m1),
@@ -727,7 +758,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
- offsetof (pthread_mutex_t,
__data.__list.__next));
pd->robust_head.list_op_pending = NULL;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+#if __PTHREAD_MUTEX_HAVE_PREV
pd->robust_prev = &pd->robust_head;
#endif
pd->robust_head.list = &pd->robust_head;
diff --git a/nptl/descr.h b/nptl/descr.h
index c5ad0c8dba..82dab056e2 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -169,7 +169,7 @@ struct pthread
pid_t pid_ununsed;
/* List of robust mutexes the thread is holding. */
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+#if __PTHREAD_MUTEX_HAVE_PREV
void *robust_prev;
struct robust_list_head robust_head;
@@ -380,9 +380,9 @@ struct pthread
/* Machine-specific unwind info. */
struct _Unwind_Exception exc;
- /* If nonzero pointer to area allocated for the stack and its
- size. */
+ /* If nonzero, pointer to the area allocated for the stack and guard. */
void *stackblock;
+ /* Size of the stackblock area including the guard. */
size_t stackblock_size;
/* Size of the included guard area. */
size_t guardsize;
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 29216077a2..e5c0bdfbeb 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -297,7 +297,7 @@ __pthread_initialize_minimal_internal (void)
/* Initialize the robust mutex data. */
{
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+#if __PTHREAD_MUTEX_HAVE_PREV
pd->robust_prev = &pd->robust_head;
#endif
pd->robust_head.list = &pd->robust_head;
@@ -473,8 +473,5 @@ strong_alias (__pthread_initialize_minimal_internal,
size_t
__pthread_get_minstack (const pthread_attr_t *attr)
{
- struct pthread_attr *iattr = (struct pthread_attr *) attr;
-
- return (GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN
- + iattr->guardsize);
+ return GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN;
}
diff --git a/nptl/pt-longjmp.c b/nptl/pt-longjmp.c
index 2ef757e687..8f3c6b3a09 100644
--- a/nptl/pt-longjmp.c
+++ b/nptl/pt-longjmp.c
@@ -25,21 +25,14 @@
symbol 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
- longjmp and siglongjmp symbols in libpthread.so; so we define them using
- IFUNC to redirect to the libc function. */
+ longjmp and siglongjmp symbols in libpthread.so.
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
-
-# if HAVE_IFUNC
-
-# undef INIT_ARCH
-# define INIT_ARCH()
-# define DEFINE_LONGJMP(name) libc_ifunc (name, &__libc_longjmp)
-
-extern __typeof(longjmp) longjmp_ifunc;
-extern __typeof(siglongjmp) siglongjmp_ifunc;
+ With an IFUNC resolver, it would be possible to avoid the indirection,
+ but the IFUNC resolver might run before the __libc_longjmp symbol has
+ been relocated, in which case the IFUNC resolver would not be able to
+ provide the correct address. */
-# else /* !HAVE_IFUNC */
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
static void __attribute__ ((noreturn, used))
longjmp_compat (jmp_buf env, int val)
@@ -47,14 +40,10 @@ longjmp_compat (jmp_buf env, int val)
__libc_longjmp (env, val);
}
-# define DEFINE_LONGJMP(name) strong_alias (longjmp_compat, name)
-
-# endif /* HAVE_IFUNC */
-
-DEFINE_LONGJMP (longjmp_ifunc)
-compat_symbol (libpthread, longjmp_ifunc, longjmp, GLIBC_2_0);
+strong_alias (longjmp_compat, longjmp_alias)
+compat_symbol (libpthread, longjmp_alias, longjmp, GLIBC_2_0);
-strong_alias (longjmp_ifunc, siglongjmp_ifunc)
-compat_symbol (libpthread, siglongjmp_ifunc, siglongjmp, GLIBC_2_0);
+strong_alias (longjmp_alias, siglongjmp_alias)
+compat_symbol (libpthread, siglongjmp_alias, siglongjmp, GLIBC_2_0);
#endif
diff --git a/nptl/pt-system.c b/nptl/pt-system.c
index f8ca6ba0d9..b30ddf2b39 100644
--- a/nptl/pt-system.c
+++ b/nptl/pt-system.c
@@ -25,29 +25,21 @@
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 a
- 'system' symbol in libpthread.so; so we define it using IFUNC to
- redirect to the libc function. */
+ 'system' symbol in libpthread.so.
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
-
-# if HAVE_IFUNC
-
-extern __typeof(system) system_ifunc;
-# undef INIT_ARCH
-# define INIT_ARCH()
-libc_ifunc (system_ifunc, &__libc_system)
+ With an IFUNC resolver, it would be possible to avoid the indirection,
+ but the IFUNC resolver might run before the __libc_system symbol has
+ been relocated, in which case the IFUNC resolver would not be able to
+ provide the correct address. */
-# else /* !HAVE_IFUNC */
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
static int __attribute__ ((used))
system_compat (const char *line)
{
return __libc_system (line);
}
-strong_alias (system_compat, system_ifunc)
-
-# endif /* HAVE_IFUNC */
-
-compat_symbol (libpthread, system_ifunc, system, GLIBC_2_0);
+strong_alias (system_compat, system_alias)
+compat_symbol (libpthread, system_alias, system, GLIBC_2_0);
#endif
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 6e7d6ff09e..c5ae04692e 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -647,4 +647,10 @@ check_stacksize_attr (size_t st)
return EINVAL;
}
+#define ASSERT_PTHREAD_STRING(x) __STRING (x)
+#define ASSERT_PTHREAD_INTERNAL_OFFSET(type, member, offset) \
+ _Static_assert (offsetof (type, member) == offset, \
+ "offset of " #member " field of " #type " != " \
+ ASSERT_PTHREAD_STRING (offset))
+
#endif /* pthreadP.h */
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 2f8ada34d6..791587218b 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -520,7 +520,7 @@ START_THREAD_DEFN
#ifndef __ASSUME_SET_ROBUST_LIST
/* If this thread has any robust mutexes locked, handle them now. */
-# ifdef __PTHREAD_MUTEX_HAVE_PREV
+# if __PTHREAD_MUTEX_HAVE_PREV
void *robust = pd->robust_head.list;
# else
__pthread_slist_t *robust = pd->robust_list.__next;
@@ -538,7 +538,7 @@ START_THREAD_DEFN
__list.__next));
robust = *((void **) robust);
-# ifdef __PTHREAD_MUTEX_HAVE_PREV
+# if __PTHREAD_MUTEX_HAVE_PREV
this->__list.__prev = NULL;
# endif
this->__list.__next = NULL;
@@ -551,31 +551,8 @@ START_THREAD_DEFN
}
#endif
- /* Mark the memory of the stack as usable to the kernel. We free
- everything except for the space used for the TCB itself. */
- size_t pagesize_m1 = __getpagesize () - 1;
-#ifdef _STACK_GROWS_DOWN
- char *sp = CURRENT_STACK_FRAME;
- size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1;
- assert (freesize < pd->stackblock_size);
- if (freesize > PTHREAD_STACK_MIN)
- __madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
-#else
- /* Page aligned start of memory to free (higher than or equal
- to current sp plus the minimum stack size). */
- void *freeblock = (void*)((size_t)(CURRENT_STACK_FRAME
- + PTHREAD_STACK_MIN
- + pagesize_m1)
- & ~pagesize_m1);
- char *free_end = (char *) (((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
- /* Is there any space to free? */
- if (free_end > (char *)freeblock)
- {
- size_t freesize = (size_t)(free_end - (char *)freeblock);
- assert (freesize < pd->stackblock_size);
- __madvise (freeblock, freesize, MADV_DONTNEED);
- }
-#endif
+ advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
+ pd->guardsize);
/* If the thread is detached free the TCB. */
if (IS_DETACHED (pd))
diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c
index 06093b3d92..210a3f8a1f 100644
--- a/nptl/pthread_getattr_np.c
+++ b/nptl/pthread_getattr_np.c
@@ -57,9 +57,12 @@ pthread_getattr_np (pthread_t thread_id, pthread_attr_t *attr)
/* The sizes are subject to alignment. */
if (__glibc_likely (thread->stackblock != NULL))
{
- iattr->stacksize = thread->stackblock_size;
+ /* The stack size reported to the user should not include the
+ guard size. */
+ iattr->stacksize = thread->stackblock_size - thread->guardsize;
#if _STACK_GROWS_DOWN
- iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
+ iattr->stackaddr = (char *) thread->stackblock
+ + thread->stackblock_size;
#else
iattr->stackaddr = (char *) thread->stackblock;
#endif
diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
index 6f2fc808ff..e1f911bf29 100644
--- a/nptl/pthread_mutex_init.c
+++ b/nptl/pthread_mutex_init.c
@@ -23,6 +23,7 @@
#include <kernel-features.h>
#include "pthreadP.h"
#include <atomic.h>
+#include <pthread-offsets.h>
#include <stap-probe.h>
@@ -58,6 +59,18 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
const struct pthread_mutexattr *imutexattr;
assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T);
+ ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__nusers,
+ __PTHREAD_MUTEX_NUSERS_OFFSET);
+ ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__kind,
+ __PTHREAD_MUTEX_KIND_OFFSET);
+ ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__spins,
+ __PTHREAD_MUTEX_SPINS_OFFSET);
+#if __PTHREAD_MUTEX_LOCK_ELISION
+ ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__elision,
+ __PTHREAD_MUTEX_ELISION_OFFSET);
+#endif
+ ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__list,
+ __PTHREAD_MUTEX_LIST_OFFSET);
imutexattr = ((const struct pthread_mutexattr *) mutexattr
?: &default_mutexattr);
diff --git a/nptl/tst-compat-forwarder-mod.c b/nptl/tst-compat-forwarder-mod.c
new file mode 100644
index 0000000000..823bfa22de
--- /dev/null
+++ b/nptl/tst-compat-forwarder-mod.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Call the function system through a statically initialized pointer. */
+
+#include <stdlib.h>
+
+int (*system_function) (const char *) = system;
+
+void
+call_system (void)
+{
+ system_function (NULL);
+}
diff --git a/nptl/tst-compat-forwarder.c b/nptl/tst-compat-forwarder.c
new file mode 100644
index 0000000000..f96806b7fe
--- /dev/null
+++ b/nptl/tst-compat-forwarder.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Test that the compat forwaders in libpthread work correctly. */
+
+#include <support/test-driver.h>
+
+extern void call_system (void);
+
+int
+do_test (void)
+{
+ /* Calling the system function from a shared library that is not linked
+ against libpthread, when the main program is linked against
+ libpthread, should not crash. */
+ call_system ();
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-minstack-cancel.c b/nptl/tst-minstack-cancel.c
new file mode 100644
index 0000000000..a306320e88
--- /dev/null
+++ b/nptl/tst-minstack-cancel.c
@@ -0,0 +1,48 @@
+/* Test cancellation with a minimal stack size.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Note: This test is similar to tst-minstack-exit, but is separate to
+ avoid spurious test passes due to warm-up effects. */
+
+#include <limits.h>
+#include <unistd.h>
+#include <support/check.h>
+#include <support/xthread.h>
+
+static void *
+threadfunc (void *closure)
+{
+ while (1)
+ pause ();
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ pthread_attr_t attr;
+ xpthread_attr_init (&attr);
+ xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+ pthread_t thr = xpthread_create (&attr, threadfunc, NULL);
+ xpthread_cancel (thr);
+ TEST_VERIFY (xpthread_join (thr) == PTHREAD_CANCELED);
+ xpthread_attr_destroy (&attr);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-minstack-exit.c b/nptl/tst-minstack-exit.c
new file mode 100644
index 0000000000..9c7e9a4dfe
--- /dev/null
+++ b/nptl/tst-minstack-exit.c
@@ -0,0 +1,46 @@
+/* Test that pthread_exit works with the minimum stack size.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Note: This test is similar to tst-minstack-cancel, but is separate
+ to avoid spurious test passes due to warm-up effects. */
+
+#include <limits.h>
+#include <unistd.h>
+#include <support/check.h>
+#include <support/xthread.h>
+
+static void *
+threadfunc (void *closure)
+{
+ pthread_exit (threadfunc);
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ pthread_attr_t attr;
+ xpthread_attr_init (&attr);
+ xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+ pthread_t thr = xpthread_create (&attr, threadfunc, NULL);
+ TEST_VERIFY (xpthread_join (thr) == threadfunc);
+ xpthread_attr_destroy (&attr);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-minstack-throw.cc b/nptl/tst-minstack-throw.cc
new file mode 100644
index 0000000000..b0a897b0c6
--- /dev/null
+++ b/nptl/tst-minstack-throw.cc
@@ -0,0 +1,87 @@
+/* Test that throwing C++ exceptions works with the minimum stack size.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdexcept>
+
+#include <limits.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xthread.h>
+
+/* Throw a std::runtime_exception. */
+__attribute__ ((noinline, noclone, weak))
+void
+do_throw_exception ()
+{
+ throw std::runtime_error ("test exception");
+}
+
+/* Class with a destructor, to trigger unwind handling. */
+struct class_with_destructor
+{
+ class_with_destructor ();
+ ~class_with_destructor ();
+};
+
+__attribute__ ((noinline, noclone, weak))
+class_with_destructor::class_with_destructor ()
+{
+}
+
+__attribute__ ((noinline, noclone, weak))
+class_with_destructor::~class_with_destructor ()
+{
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+function_with_destructed_object ()
+{
+ class_with_destructor obj;
+ do_throw_exception ();
+}
+
+static void *
+threadfunc (void *closure)
+{
+ try
+ {
+ function_with_destructed_object ();
+ FAIL_EXIT1 ("no exception thrown");
+ }
+ catch (std::exception &e)
+ {
+ TEST_COMPARE (strcmp (e.what (), "test exception"), 0);
+ return reinterpret_cast<void *> (threadfunc);
+ }
+ FAIL_EXIT1 ("no exception caught");
+}
+
+static int
+do_test (void)
+{
+ pthread_attr_t attr;
+ xpthread_attr_init (&attr);
+ xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+ pthread_t thr = xpthread_create (&attr, threadfunc, NULL);
+ TEST_VERIFY (xpthread_join (thr) == threadfunc);
+ xpthread_attr_destroy (&attr);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-thread-exit-clobber.cc b/nptl/tst-thread-exit-clobber.cc
new file mode 100644
index 0000000000..b9be25a65b
--- /dev/null
+++ b/nptl/tst-thread-exit-clobber.cc
@@ -0,0 +1,243 @@
+/* Test that pthread_exit does not clobber callee-saved registers.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <support/check.h>
+#include <support/xthread.h>
+
+/* This test attempts to check that callee-saved registers are
+ restored to their original values when destructors are run after
+ pthread_exit is called. GCC PR 83641 causes this test to fail.
+
+ The constants have been chosen randomly and are magic values which
+ are used to detect whether registers have been clobbered. The idea
+ is that these values are hidden behind a compiler barrier and only
+ present in .rodata initially, so that it is less likely that they
+ are in a register by accident.
+
+ The checker class can be stored in registers, and the magic values
+ are directly loaded into these registers. The checker destructor
+ is eventually invoked by pthread_exit and calls one of the
+ check_magic functions to verify that the class contents (that is,
+ register value) is correct.
+
+ These tests are performed both for unsigned int and double values,
+ to cover different calling conventions. */
+
+template <class T>
+struct values
+{
+ T v0;
+ T v1;
+ T v2;
+ T v3;
+ T v4;
+};
+
+static const values<unsigned int> magic_values =
+ {
+ 0x57f7fc72,
+ 0xe582daba,
+ 0x5f6ac994,
+ 0x35efddb7,
+ 0x1fbf5a74,
+ };
+
+static const values<double> magic_values_double =
+ {
+ 0.6764041905675465,
+ 0.9533336788140494,
+ 0.6091161359041452,
+ 0.7668653957125336,
+ 0.010374520235509666,
+ };
+
+/* Special index value which tells check_magic that no check should be
+ performed. */
+enum { no_check = -1 };
+
+/* Check that VALUE is the magic value for INDEX, behind a compiler
+ barrier. */
+__attribute__ ((noinline, noclone, weak))
+void
+check_magic (int index, unsigned int value)
+{
+ switch (index)
+ {
+ case 0:
+ TEST_COMPARE (value, magic_values.v0);
+ break;
+ case 1:
+ TEST_COMPARE (value, magic_values.v1);
+ break;
+ case 2:
+ TEST_COMPARE (value, magic_values.v2);
+ break;
+ case 3:
+ TEST_COMPARE (value, magic_values.v3);
+ break;
+ case 4:
+ TEST_COMPARE (value, magic_values.v4);
+ break;
+ case no_check:
+ break;
+ default:
+ FAIL_EXIT1 ("invalid magic value index %d", index);
+ }
+}
+
+/* Check that VALUE is the magic value for INDEX, behind a compiler
+ barrier. Double variant. */
+__attribute__ ((noinline, noclone, weak))
+void
+check_magic (int index, double value)
+{
+ switch (index)
+ {
+ case 0:
+ TEST_VERIFY (value == magic_values_double.v0);
+ break;
+ case 1:
+ TEST_VERIFY (value == magic_values_double.v1);
+ break;
+ case 2:
+ TEST_VERIFY (value == magic_values_double.v2);
+ break;
+ case 3:
+ TEST_VERIFY (value == magic_values_double.v3);
+ break;
+ case 4:
+ TEST_VERIFY (value == magic_values_double.v4);
+ break;
+ case no_check:
+ break;
+ default:
+ FAIL_EXIT1 ("invalid magic value index %d", index);
+ }
+}
+
+/* Store a magic value and check, via the destructor, that it has the
+ expected value. */
+template <class T, int I>
+struct checker
+{
+ T value;
+
+ checker (T v)
+ : value (v)
+ {
+ }
+
+ ~checker ()
+ {
+ check_magic (I, value);
+ }
+};
+
+/* The functions call_pthread_exit_0, call_pthread_exit_1,
+ call_pthread_exit are used to call pthread_exit indirectly, with
+ the intent of clobbering the register values. */
+
+__attribute__ ((noinline, noclone, weak))
+void
+call_pthread_exit_0 (const values<unsigned int> *pvalues)
+{
+ checker<unsigned int, no_check> c0 (pvalues->v0);
+ checker<unsigned int, no_check> c1 (pvalues->v1);
+ checker<unsigned int, no_check> c2 (pvalues->v2);
+ checker<unsigned int, no_check> c3 (pvalues->v3);
+ checker<unsigned int, no_check> c4 (pvalues->v4);
+
+ pthread_exit (NULL);
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+call_pthread_exit_1 (const values<double> *pvalues)
+{
+ checker<double, no_check> c0 (pvalues->v0);
+ checker<double, no_check> c1 (pvalues->v1);
+ checker<double, no_check> c2 (pvalues->v2);
+ checker<double, no_check> c3 (pvalues->v3);
+ checker<double, no_check> c4 (pvalues->v4);
+
+ values<unsigned int> other_values = { 0, };
+ call_pthread_exit_0 (&other_values);
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+call_pthread_exit ()
+{
+ values<double> other_values = { 0, };
+ call_pthread_exit_1 (&other_values);
+}
+
+/* Create on-stack objects and check that their values are restored by
+ pthread_exit. If Nested is true, call pthread_exit indirectly via
+ call_pthread_exit. */
+template <class T, bool Nested>
+__attribute__ ((noinline, noclone, weak))
+void *
+threadfunc (void *closure)
+{
+ const values<T> *pvalues = static_cast<const values<T> *> (closure);
+
+ checker<T, 0> c0 (pvalues->v0);
+ checker<T, 1> c1 (pvalues->v1);
+ checker<T, 2> c2 (pvalues->v2);
+ checker<T, 3> c3 (pvalues->v3);
+ checker<T, 4> c4 (pvalues->v4);
+
+ if (Nested)
+ call_pthread_exit ();
+ else
+ pthread_exit (NULL);
+
+ /* This should not be reached. */
+ return const_cast<char *> ("");
+}
+
+static int
+do_test ()
+{
+ puts ("info: unsigned int, direct pthread_exit call");
+ pthread_t thr
+ = xpthread_create (NULL, &threadfunc<unsigned int, false>,
+ const_cast<values<unsigned int> *> (&magic_values));
+ TEST_VERIFY (xpthread_join (thr) == NULL);
+
+ puts ("info: double, direct pthread_exit call");
+ thr = xpthread_create (NULL, &threadfunc<double, false>,
+ const_cast<values<double> *> (&magic_values_double));
+ TEST_VERIFY (xpthread_join (thr) == NULL);
+
+ puts ("info: unsigned int, indirect pthread_exit call");
+ thr = xpthread_create (NULL, &threadfunc<unsigned int, true>,
+ const_cast<values<unsigned int> *> (&magic_values));
+ TEST_VERIFY (xpthread_join (thr) == NULL);
+
+ puts ("info: double, indirect pthread_exit call");
+ thr = xpthread_create (NULL, &threadfunc<double, true>,
+ const_cast<values<double> *> (&magic_values_double));
+ TEST_VERIFY (xpthread_join (thr) == NULL);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nss/Makefile b/nss/Makefile
index d9f6d41181..8efb2a56fa 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -58,6 +58,12 @@ tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \
tst-nss-test5
xtests = bug-erange
+# Tests which need libdl
+ifeq (yes,$(build-shared))
+tests += tst-nss-files-hosts-erange
+tests += tst-nss-files-hosts-multi
+endif
+
# If we have a thread library then we can test cancellation against
# some routines like getpwuid_r.
ifeq (yes,$(have-thread-library))
@@ -154,3 +160,6 @@ $(patsubst %,$(objpfx)%.out,$(tests)) : \
ifeq (yes,$(have-thread-library))
$(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
endif
+
+$(objpfx)tst-nss-files-hosts-erange: $(libdl)
+$(objpfx)tst-nss-files-hosts-multi: $(libdl)
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 6c547ea1ca..bce80e05dd 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -234,6 +234,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
H_ERRNO_VAR_P))
{
case -1:
+# ifdef NEED__RES
+ __resolv_context_put (res_ctx);
+# endif
return errno;
case 1:
#ifdef NEED_H_ERRNO
@@ -253,7 +256,12 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result
H_ERRNO_VAR);
if (nscd_status >= 0)
- return nscd_status;
+ {
+# ifdef NEED__RES
+ __resolv_context_put (res_ctx);
+# endif
+ return nscd_status;
+ }
}
#endif
diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c
index bccb6a5780..6f7cc4d94b 100644
--- a/nss/nss_files/files-hosts.c
+++ b/nss/nss_files/files-hosts.c
@@ -22,6 +22,8 @@
#include <arpa/nameser.h>
#include <netdb.h>
#include <resolv/resolv-internal.h>
+#include <scratch_buffer.h>
+#include <alloc_buffer.h>
/* Get implementation for some internal functions. */
@@ -115,228 +117,250 @@ DB_LOOKUP (hostbyaddr, ,,,
}, const void *addr, socklen_t len, int af)
#undef EXTRA_ARGS_VALUE
-enum nss_status
-_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
- char *buffer, size_t buflen, int *errnop,
- int *herrnop, int32_t *ttlp, char **canonp)
-{
- FILE *stream = NULL;
- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data);
- buffer += pad;
- buflen = buflen > pad ? buflen - pad : 0;
+/* Type of the address and alias arrays. */
+#define DYNARRAY_STRUCT array
+#define DYNARRAY_ELEMENT char *
+#define DYNARRAY_PREFIX array_
+#include <malloc/dynarray-skeleton.c>
- /* Open file. */
- enum nss_status status = internal_setent (&stream);
+static enum nss_status
+gethostbyname3_multi (FILE * stream, const char *name, int af,
+ struct hostent *result, char *buffer, size_t buflen,
+ int *errnop, int *herrnop, int flags)
+{
+ assert (af == AF_INET || af == AF_INET6);
+
+ /* We have to get all host entries from the file. */
+ struct scratch_buffer tmp_buffer;
+ scratch_buffer_init (&tmp_buffer);
+ struct hostent tmp_result_buf;
+ struct array addresses;
+ array_init (&addresses);
+ struct array aliases;
+ array_init (&aliases);
+ enum nss_status status;
+
+ /* Preserve the addresses and aliases encountered so far. */
+ for (size_t i = 0; result->h_addr_list[i] != NULL; ++i)
+ array_add (&addresses, result->h_addr_list[i]);
+ for (size_t i = 0; result->h_aliases[i] != NULL; ++i)
+ array_add (&aliases, result->h_aliases[i]);
+
+ /* The output buffer re-uses now-unused space at the end of the
+ buffer, starting with the aliases array. It comes last in the
+ data produced by internal_getent. (The alias names themselves
+ are still located in the line read in internal_getent, which is
+ stored at the beginning of the buffer.) */
+ struct alloc_buffer outbuf;
+ {
+ char *bufferend = (char *) result->h_aliases;
+ outbuf = alloc_buffer_create (bufferend, buffer + buflen - bufferend);
+ }
- if (status == NSS_STATUS_SUCCESS)
+ while (true)
{
- /* XXX Is using _res to determine whether we want to convert IPv4
- addresses to IPv6 addresses really the right thing to do? */
- int flags = (res_use_inet6 () ? AI_V4MAPPED : 0);
-
- while ((status = internal_getent (stream, result, buffer, buflen, errnop,
- herrnop, af, flags))
- == NSS_STATUS_SUCCESS)
+ status = internal_getent (stream, &tmp_result_buf, tmp_buffer.data,
+ tmp_buffer.length, errnop, herrnop, af,
+ flags);
+ /* Enlarge the buffer if necessary. */
+ if (status == NSS_STATUS_TRYAGAIN && *herrnop == NETDB_INTERNAL
+ && *errnop == ERANGE)
{
- LOOKUP_NAME_CASE (h_name, h_aliases)
+ if (!scratch_buffer_grow (&tmp_buffer))
+ {
+ *errnop = ENOMEM;
+ /* *herrnop and status already have the right value. */
+ break;
+ }
+ /* Loop around and retry with a larger buffer. */
}
-
- if (status == NSS_STATUS_SUCCESS
- && _res_hconf.flags & HCONF_FLAG_MULTI)
+ else if (status == NSS_STATUS_SUCCESS)
{
- /* We have to get all host entries from the file. */
- size_t tmp_buflen = MIN (buflen, 4096);
- char tmp_buffer_stack[tmp_buflen]
- __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));
- char *tmp_buffer = tmp_buffer_stack;
- struct hostent tmp_result_buf;
- int naddrs = 1;
- int naliases = 0;
- char *bufferend;
- bool tmp_buffer_malloced = false;
-
- while (result->h_aliases[naliases] != NULL)
- ++naliases;
-
- bufferend = (char *) &result->h_aliases[naliases + 1];
-
- again:
- while ((status = internal_getent (stream, &tmp_result_buf, tmp_buffer,
- tmp_buflen, errnop, herrnop, af,
- flags))
- == NSS_STATUS_SUCCESS)
+ /* A line was read. Check that it matches the search
+ criteria. */
+
+ int matches = 1;
+ struct hostent *old_result = result;
+ result = &tmp_result_buf;
+ /* The following piece is a bit clumsy but we want to use
+ the `LOOKUP_NAME_CASE' value. The optimizer should do
+ its job. */
+ do
{
- int matches = 1;
- struct hostent *old_result = result;
- result = &tmp_result_buf;
- /* The following piece is a bit clumsy but we want to use the
- `LOOKUP_NAME_CASE' value. The optimizer should do its
- job. */
- do
- {
- LOOKUP_NAME_CASE (h_name, h_aliases)
- result = old_result;
- }
- while ((matches = 0));
+ LOOKUP_NAME_CASE (h_name, h_aliases)
+ result = old_result;
+ }
+ while ((matches = 0));
- if (matches)
+ /* If the line matches, we need to copy the addresses and
+ aliases, so that we can reuse tmp_buffer for the next
+ line. */
+ if (matches)
+ {
+ /* Record the addresses. */
+ for (size_t i = 0; tmp_result_buf.h_addr_list[i] != NULL; ++i)
{
- /* We could be very clever and try to recycle a few bytes
- in the buffer instead of generating new arrays. But
- we are not doing this here since it's more work than
- it's worth. Simply let the user provide a bit bigger
- buffer. */
- char **new_h_addr_list;
- char **new_h_aliases;
- int newaliases = 0;
- size_t newstrlen = 0;
- int cnt;
-
- /* Count the new aliases and the length of the strings. */
- while (tmp_result_buf.h_aliases[newaliases] != NULL)
+ /* Allocate the target space in the output buffer,
+ depending on the address family. */
+ void *target;
+ if (af == AF_INET)
{
- char *cp = tmp_result_buf.h_aliases[newaliases];
- ++newaliases;
- newstrlen += strlen (cp) + 1;
+ assert (tmp_result_buf.h_length == 4);
+ target = alloc_buffer_alloc (&outbuf, struct in_addr);
}
- /* If the real name is different add it also to the
- aliases. This means that there is a duplication
- in the alias list but this is really the user's
- problem. */
- if (strcmp (old_result->h_name,
- tmp_result_buf.h_name) != 0)
+ else if (af == AF_INET6)
{
- ++newaliases;
- newstrlen += strlen (tmp_result_buf.h_name) + 1;
+ assert (tmp_result_buf.h_length == 16);
+ target = alloc_buffer_alloc (&outbuf, struct in6_addr);
}
+ else
+ __builtin_unreachable ();
- /* Make sure bufferend is aligned. */
- assert ((bufferend - (char *) 0) % sizeof (char *) == 0);
-
- /* Now we can check whether the buffer is large enough.
- 16 is the maximal size of the IP address. */
- if (bufferend + 16 + (naddrs + 2) * sizeof (char *)
- + roundup (newstrlen, sizeof (char *))
- + (naliases + newaliases + 1) * sizeof (char *)
- >= buffer + buflen)
+ if (target == NULL)
{
+ /* Request a larger output buffer. */
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
status = NSS_STATUS_TRYAGAIN;
- goto out;
+ break;
}
+ memcpy (target, tmp_result_buf.h_addr_list[i],
+ tmp_result_buf.h_length);
+ array_add (&addresses, target);
+ }
- new_h_addr_list =
- (char **) (bufferend
- + roundup (newstrlen, sizeof (char *))
- + 16);
- new_h_aliases =
- (char **) ((char *) new_h_addr_list
- + (naddrs + 2) * sizeof (char *));
+ /* Record the aliases. */
+ for (size_t i = 0; tmp_result_buf.h_aliases[i] != NULL; ++i)
+ {
+ char *alias = tmp_result_buf.h_aliases[i];
+ array_add (&aliases,
+ alloc_buffer_copy_string (&outbuf, alias));
+ }
- /* Copy the old data in the new arrays. */
- for (cnt = 0; cnt < naddrs; ++cnt)
- new_h_addr_list[cnt] = old_result->h_addr_list[cnt];
+ /* If the real name is different add, it also to the
+ aliases. This means that there is a duplication in
+ the alias list but this is really the user's
+ problem. */
+ {
+ char *new_name = tmp_result_buf.h_name;
+ if (strcmp (old_result->h_name, new_name) != 0)
+ array_add (&aliases,
+ alloc_buffer_copy_string (&outbuf, new_name));
+ }
+
+ /* Report memory allocation failures during the
+ expansion of the temporary arrays. */
+ if (array_has_failed (&addresses) || array_has_failed (&aliases))
+ {
+ *errnop = ENOMEM;
+ *herrnop = NETDB_INTERNAL;
+ status = NSS_STATUS_UNAVAIL;
+ break;
+ }
- for (cnt = 0; cnt < naliases; ++cnt)
- new_h_aliases[cnt] = old_result->h_aliases[cnt];
+ /* Request a larger output buffer if we ran out of room. */
+ if (alloc_buffer_has_failed (&outbuf))
+ {
+ *errnop = ERANGE;
+ *herrnop = NETDB_INTERNAL;
+ status = NSS_STATUS_TRYAGAIN;
+ break;
+ }
- /* Store the new strings. */
- cnt = 0;
- while (tmp_result_buf.h_aliases[cnt] != NULL)
- {
- new_h_aliases[naliases++] = bufferend;
- bufferend = (__stpcpy (bufferend,
- tmp_result_buf.h_aliases[cnt])
- + 1);
- ++cnt;
- }
+ result = old_result;
+ } /* If match was found. */
- if (cnt < newaliases)
- {
- new_h_aliases[naliases++] = bufferend;
- bufferend = __stpcpy (bufferend,
- tmp_result_buf.h_name) + 1;
- }
+ /* If no match is found, loop around and fetch another
+ line. */
- /* Final NULL pointer. */
- new_h_aliases[naliases] = NULL;
+ } /* status == NSS_STATUS_SUCCESS. */
+ else
+ /* internal_getent returned an error. */
+ break;
+ } /* while (true) */
- /* Round up the buffer end address. */
- bufferend += (sizeof (char *)
- - ((bufferend - (char *) 0)
- % sizeof (char *))) % sizeof (char *);
+ /* Propagate the NSS_STATUS_TRYAGAIN error to the caller. It means
+ that we may not have loaded the complete result.
+ NSS_STATUS_NOTFOUND, however, means that we reached the end of
+ the file successfully. */
+ if (status != NSS_STATUS_TRYAGAIN)
+ status = NSS_STATUS_SUCCESS;
- /* Now the new address. */
- new_h_addr_list[naddrs++] =
- memcpy (bufferend, tmp_result_buf.h_addr,
- tmp_result_buf.h_length);
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ /* Copy the address and alias arrays into the output buffer and
+ add NULL terminators. The pointed-to elements were directly
+ written into the output buffer above and do not need to be
+ copied again. */
+ size_t addresses_count = array_size (&addresses);
+ size_t aliases_count = array_size (&aliases);
+ char **out_addresses = alloc_buffer_alloc_array
+ (&outbuf, char *, addresses_count + 1);
+ char **out_aliases = alloc_buffer_alloc_array
+ (&outbuf, char *, aliases_count + 1);
+ if (out_addresses == NULL || out_aliases == NULL)
+ {
+ /* The output buffer is not large enough. */
+ *errnop = ERANGE;
+ *herrnop = NETDB_INTERNAL;
+ status = NSS_STATUS_TRYAGAIN;
+ /* Fall through to function exit. */
+ }
+ else
+ {
+ /* Everything is allocated in place. Make the copies and
+ adjust the array pointers. */
+ memcpy (out_addresses, array_begin (&addresses),
+ addresses_count * sizeof (char *));
+ out_addresses[addresses_count] = NULL;
+ memcpy (out_aliases, array_begin (&aliases),
+ aliases_count * sizeof (char *));
+ out_aliases[aliases_count] = NULL;
+
+ result->h_addr_list = out_addresses;
+ result->h_aliases = out_aliases;
- /* Also here a final NULL pointer. */
- new_h_addr_list[naddrs] = NULL;
+ status = NSS_STATUS_SUCCESS;
+ }
+ }
- /* Store the new array pointers. */
- old_result->h_aliases = new_h_aliases;
- old_result->h_addr_list = new_h_addr_list;
+ scratch_buffer_free (&tmp_buffer);
+ array_free (&addresses);
+ array_free (&aliases);
+ return status;
+}
- /* Compute the new buffer end. */
- bufferend = (char *) &new_h_aliases[naliases + 1];
- assert (bufferend <= buffer + buflen);
+enum nss_status
+_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
+ char *buffer, size_t buflen, int *errnop,
+ int *herrnop, int32_t *ttlp, char **canonp)
+{
+ FILE *stream = NULL;
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data);
+ buffer += pad;
+ buflen = buflen > pad ? buflen - pad : 0;
- result = old_result;
- }
- }
+ /* Open file. */
+ enum nss_status status = internal_setent (&stream);
- if (status == NSS_STATUS_TRYAGAIN)
- {
- size_t newsize = 2 * tmp_buflen;
- if (tmp_buffer_malloced)
- {
- char *newp = realloc (tmp_buffer, newsize);
- if (newp != NULL)
- {
- assert ((((uintptr_t) newp)
- & (__alignof__ (struct hostent_data) - 1))
- == 0);
- tmp_buffer = newp;
- tmp_buflen = newsize;
- goto again;
- }
- }
- else if (!__libc_use_alloca (buflen + newsize))
- {
- tmp_buffer = malloc (newsize);
- if (tmp_buffer != NULL)
- {
- assert ((((uintptr_t) tmp_buffer)
- & (__alignof__ (struct hostent_data) - 1))
- == 0);
- tmp_buffer_malloced = true;
- tmp_buflen = newsize;
- goto again;
- }
- }
- else
- {
- tmp_buffer
- = extend_alloca (tmp_buffer, tmp_buflen,
- newsize
- + __alignof__ (struct hostent_data));
- tmp_buffer = (char *) (((uintptr_t) tmp_buffer
- + __alignof__ (struct hostent_data)
- - 1)
- & ~(__alignof__ (struct hostent_data)
- - 1));
- goto again;
- }
- }
- else
- status = NSS_STATUS_SUCCESS;
- out:
- if (tmp_buffer_malloced)
- free (tmp_buffer);
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ /* XXX Is using _res to determine whether we want to convert IPv4
+ addresses to IPv6 addresses really the right thing to do? */
+ int flags = (res_use_inet6 () ? AI_V4MAPPED : 0);
+
+ while ((status = internal_getent (stream, result, buffer, buflen, errnop,
+ herrnop, af, flags))
+ == NSS_STATUS_SUCCESS)
+ {
+ LOOKUP_NAME_CASE (h_name, h_aliases)
}
+ if (status == NSS_STATUS_SUCCESS
+ && _res_hconf.flags & HCONF_FLAG_MULTI)
+ status = gethostbyname3_multi
+ (stream, name, af, result, buffer, buflen, errnop, herrnop, flags);
+
internal_endent (&stream);
}
diff --git a/nss/tst-nss-files-hosts-erange.c b/nss/tst-nss-files-hosts-erange.c
new file mode 100644
index 0000000000..beb7aa9fa0
--- /dev/null
+++ b/nss/tst-nss-files-hosts-erange.c
@@ -0,0 +1,109 @@
+/* Parse /etc/hosts in multi mode with a trailing long line (bug 21915).
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <gnu/lib-names.h>
+#include <netdb.h>
+#include <nss.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/namespace.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+
+struct support_chroot *chroot_env;
+
+#define X10 "XXXXXXXXXX"
+#define X100 X10 X10 X10 X10 X10 X10 X10 X10 X10 X10
+#define X1000 X100 X100 X100 X100 X100 X100 X100 X100 X100 X100
+
+static void
+prepare (int argc, char **argv)
+{
+ chroot_env = support_chroot_create
+ ((struct support_chroot_configuration)
+ {
+ .resolv_conf = "",
+ .hosts =
+ "127.0.0.1 localhost localhost.localdomain\n"
+ "::1 localhost localhost.localdomain\n"
+ "192.0.2.1 example.com\n"
+ "#" X1000 X100 "\n",
+ .host_conf = "multi on\n",
+ });
+}
+
+static int
+do_test (void)
+{
+ support_become_root ();
+ if (!support_can_chroot ())
+ return EXIT_UNSUPPORTED;
+
+ __nss_configure_lookup ("hosts", "files");
+ if (dlopen (LIBNSS_FILES_SO, RTLD_LAZY) == NULL)
+ FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
+
+ xchroot (chroot_env->path_chroot);
+
+ errno = ERANGE;
+ h_errno = NETDB_INTERNAL;
+ check_hostent ("gethostbyname example.com",
+ gethostbyname ("example.com"),
+ "name: example.com\n"
+ "address: 192.0.2.1\n");
+ errno = ERANGE;
+ h_errno = NETDB_INTERNAL;
+ check_hostent ("gethostbyname2 AF_INET example.com",
+ gethostbyname2 ("example.com", AF_INET),
+ "name: example.com\n"
+ "address: 192.0.2.1\n");
+ {
+ struct addrinfo hints =
+ {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = IPPROTO_TCP,
+ };
+ errno = ERANGE;
+ h_errno = NETDB_INTERNAL;
+ struct addrinfo *ai;
+ int ret = getaddrinfo ("example.com", "80", &hints, &ai);
+ check_addrinfo ("example.com AF_UNSPEC", ai, ret,
+ "address: STREAM/TCP 192.0.2.1 80\n");
+ if (ret == 0)
+ freeaddrinfo (ai);
+
+ hints.ai_family = AF_INET;
+ errno = ERANGE;
+ h_errno = NETDB_INTERNAL;
+ ret = getaddrinfo ("example.com", "80", &hints, &ai);
+ check_addrinfo ("example.com AF_INET", ai, ret,
+ "address: STREAM/TCP 192.0.2.1 80\n");
+ if (ret == 0)
+ freeaddrinfo (ai);
+ }
+
+ support_chroot_free (chroot_env);
+ return 0;
+}
+
+#define PREPARE prepare
+#include <support/test-driver.c>
diff --git a/nss/tst-nss-files-hosts-multi.c b/nss/tst-nss-files-hosts-multi.c
new file mode 100644
index 0000000000..195a19be4f
--- /dev/null
+++ b/nss/tst-nss-files-hosts-multi.c
@@ -0,0 +1,331 @@
+/* Parse /etc/hosts in multi mode with many addresses/aliases.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <gnu/lib-names.h>
+#include <netdb.h>
+#include <nss.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/test-driver.h>
+#include <support/xmemstream.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <sys/resource.h>
+
+struct support_chroot *chroot_env;
+
+static void
+prepare (int argc, char **argv)
+{
+ chroot_env = support_chroot_create
+ ((struct support_chroot_configuration)
+ {
+ .resolv_conf = "",
+ .hosts = "", /* See write_hosts below. */
+ .host_conf = "multi on\n",
+ });
+}
+
+/* Create the /etc/hosts file from outside the chroot. */
+static void
+write_hosts (int count)
+{
+ TEST_VERIFY (count > 0 && count <= 65535);
+ FILE *fp = xfopen (chroot_env->path_hosts, "w");
+ fputs ("127.0.0.1 localhost localhost.localdomain\n"
+ "::1 localhost localhost.localdomain\n",
+ fp);
+ for (int i = 0; i < count; ++i)
+ {
+ fprintf (fp, "10.4.%d.%d www4.example.com\n",
+ (i / 256) & 0xff, i & 0xff);
+ fprintf (fp, "10.46.%d.%d www.example.com\n",
+ (i / 256) & 0xff, i & 0xff);
+ fprintf (fp, "192.0.2.1 alias.example.com v4-%d.example.com\n", i);
+ fprintf (fp, "2001:db8::6:%x www6.example.com\n", i);
+ fprintf (fp, "2001:db8::46:%x www.example.com\n", i);
+ fprintf (fp, "2001:db8::1 alias.example.com v6-%d.example.com\n", i);
+ }
+ xfclose (fp);
+}
+
+/* Parameters of a single test. */
+struct test_params
+{
+ const char *name; /* Name to query. */
+ const char *marker; /* Address marker for the name. */
+ int count; /* Number of addresses/aliases. */
+ int family; /* AF_INET, AF_INET_6 or AF_UNSPEC. */
+ bool canonname; /* True if AI_CANONNAME should be enabled. */
+};
+
+/* Expected result of gethostbyname/gethostbyname2. */
+static char *
+expected_ghbn (const struct test_params *params)
+{
+ TEST_VERIFY (params->family == AF_INET || params->family == AF_INET6);
+
+ struct xmemstream expected;
+ xopen_memstream (&expected);
+ if (strcmp (params->name, "alias.example.com") == 0)
+ {
+ fprintf (expected.out, "name: %s\n", params->name);
+ char af;
+ if (params->family == AF_INET)
+ af = '4';
+ else
+ af = '6';
+ for (int i = 0; i < params->count; ++i)
+ fprintf (expected.out, "alias: v%c-%d.example.com\n", af, i);
+
+ for (int i = 0; i < params->count; ++i)
+ if (params->family == AF_INET)
+ fputs ("address: 192.0.2.1\n", expected.out);
+ else
+ fputs ("address: 2001:db8::1\n", expected.out);
+ }
+ else /* www/www4/www6 name. */
+ {
+ bool do_ipv4 = params->family == AF_INET
+ && strncmp (params->name, "www6", 4) != 0;
+ bool do_ipv6 = params->family == AF_INET6
+ && strncmp (params->name, "www4", 4) != 0;
+ if (do_ipv4 || do_ipv6)
+ {
+ fprintf (expected.out, "name: %s\n", params->name);
+ if (do_ipv4)
+ for (int i = 0; i < params->count; ++i)
+ fprintf (expected.out, "address: 10.%s.%d.%d\n",
+ params->marker, i / 256, i % 256);
+ if (do_ipv6)
+ for (int i = 0; i < params->count; ++i)
+ fprintf (expected.out, "address: 2001:db8::%s:%x\n",
+ params->marker, i);
+ }
+ else
+ fputs ("error: HOST_NOT_FOUND\n", expected.out);
+ }
+ xfclose_memstream (&expected);
+ return expected.buffer;
+}
+
+/* Expected result of getaddrinfo. */
+static char *
+expected_gai (const struct test_params *params)
+{
+ bool do_ipv4 = false;
+ bool do_ipv6 = false;
+ if (params->family == AF_UNSPEC)
+ do_ipv4 = do_ipv6 = true;
+ else if (params->family == AF_INET)
+ do_ipv4 = true;
+ else if (params->family == AF_INET6)
+ do_ipv6 = true;
+
+ struct xmemstream expected;
+ xopen_memstream (&expected);
+ if (strcmp (params->name, "alias.example.com") == 0)
+ {
+ if (params->canonname)
+ fprintf (expected.out,
+ "flags: AI_CANONNAME\n"
+ "canonname: %s\n",
+ params->name);
+
+ if (do_ipv4)
+ for (int i = 0; i < params->count; ++i)
+ fputs ("address: STREAM/TCP 192.0.2.1 80\n", expected.out);
+ if (do_ipv6)
+ for (int i = 0; i < params->count; ++i)
+ fputs ("address: STREAM/TCP 2001:db8::1 80\n", expected.out);
+ }
+ else /* www/www4/www6 name. */
+ {
+ if (strncmp (params->name, "www4", 4) == 0)
+ do_ipv6 = false;
+ else if (strncmp (params->name, "www6", 4) == 0)
+ do_ipv4 = false;
+ /* Otherwise, we have www as the name, so we do both. */
+
+ if (do_ipv4 || do_ipv6)
+ {
+ if (params->canonname)
+ fprintf (expected.out,
+ "flags: AI_CANONNAME\n"
+ "canonname: %s\n",
+ params->name);
+
+ if (do_ipv4)
+ for (int i = 0; i < params->count; ++i)
+ fprintf (expected.out, "address: STREAM/TCP 10.%s.%d.%d 80\n",
+ params->marker, i / 256, i % 256);
+ if (do_ipv6)
+ for (int i = 0; i < params->count; ++i)
+ fprintf (expected.out,
+ "address: STREAM/TCP 2001:db8::%s:%x 80\n",
+ params->marker, i);
+ }
+ else
+ fputs ("error: Name or service not known\n", expected.out);
+ }
+ xfclose_memstream (&expected);
+ return expected.buffer;
+}
+
+static void
+run_gbhn_gai (struct test_params *params)
+{
+ char *ctx = xasprintf ("name=%s marker=%s count=%d family=%d",
+ params->name, params->marker, params->count,
+ params->family);
+ if (test_verbose > 0)
+ printf ("info: %s\n", ctx);
+
+ /* Check gethostbyname, gethostbyname2. */
+ if (params->family == AF_INET)
+ {
+ char *expected = expected_ghbn (params);
+ check_hostent (ctx, gethostbyname (params->name), expected);
+ free (expected);
+ }
+ if (params->family != AF_UNSPEC)
+ {
+ char *expected = expected_ghbn (params);
+ check_hostent (ctx, gethostbyname2 (params->name, params->family),
+ expected);
+ free (expected);
+ }
+
+ /* Check getaddrinfo. */
+ for (int do_canonical = 0; do_canonical < 2; ++do_canonical)
+ {
+ params->canonname = do_canonical;
+ char *expected = expected_gai (params);
+ struct addrinfo hints =
+ {
+ .ai_family = params->family,
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = IPPROTO_TCP,
+ };
+ if (do_canonical)
+ hints.ai_flags |= AI_CANONNAME;
+ struct addrinfo *ai;
+ int ret = getaddrinfo (params->name, "80", &hints, &ai);
+ check_addrinfo (ctx, ai, ret, expected);
+ if (ret == 0)
+ freeaddrinfo (ai);
+ free (expected);
+ }
+
+ free (ctx);
+}
+
+/* Callback for the subprocess which runs the test in a chroot. */
+static void
+subprocess (void *closure)
+{
+ struct test_params *params = closure;
+
+ xchroot (chroot_env->path_chroot);
+
+ static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC, -1 };
+ static const char *const names[] =
+ {
+ "www.example.com", "www4.example.com", "www6.example.com",
+ "alias.example.com",
+ NULL
+ };
+ static const char *const names_marker[] = { "46", "4", "6", "" };
+
+ for (int family_idx = 0; families[family_idx] >= 0; ++family_idx)
+ {
+ params->family = families[family_idx];
+ for (int names_idx = 0; names[names_idx] != NULL; ++names_idx)
+ {
+ params->name = names[names_idx];
+ params->marker = names_marker[names_idx];
+ run_gbhn_gai (params);
+ }
+ }
+}
+
+/* Run the test for a specific number of addresses/aliases. */
+static void
+run_test (int count)
+{
+ write_hosts (count);
+
+ struct test_params params =
+ {
+ .count = count,
+ };
+
+ support_isolate_in_subprocess (subprocess, &params);
+}
+
+static int
+do_test (void)
+{
+ support_become_root ();
+ if (!support_can_chroot ())
+ return EXIT_UNSUPPORTED;
+
+ /* This test should not use gigabytes of memory. */
+ {
+ struct rlimit limit;
+ if (getrlimit (RLIMIT_AS, &limit) != 0)
+ {
+ printf ("getrlimit (RLIMIT_AS) failed: %m\n");
+ return 1;
+ }
+ long target = 200 * 1024 * 1024;
+ if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target)
+ {
+ limit.rlim_cur = target;
+ if (setrlimit (RLIMIT_AS, &limit) != 0)
+ {
+ printf ("setrlimit (RLIMIT_AS) failed: %m\n");
+ return 1;
+ }
+ }
+ }
+
+ __nss_configure_lookup ("hosts", "files");
+ if (dlopen (LIBNSS_FILES_SO, RTLD_LAZY) == NULL)
+ FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
+
+ /* Run the tests with a few different address/alias counts. */
+ for (int count = 1; count <= 111; ++count)
+ run_test (count);
+ run_test (1111);
+ run_test (22222);
+
+ support_chroot_free (chroot_env);
+ return 0;
+}
+
+#define PREPARE prepare
+#include <support/test-driver.c>
diff --git a/po/fr.po b/po/fr.po
index 5a79695125..6764655d25 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -5920,7 +5920,7 @@ msgstr "Le fichier existe"
#. TRANS also when you rename a file with @code{rename} (@pxref{Renaming Files}).
#: sysdeps/gnu/errlist.c:211
msgid "Invalid cross-device link"
-msgstr "Lien croisé de périphéque invalide"
+msgstr "Lien physique inter-périphérique invalide"
#. TRANS The wrong type of device was given to a function that expects a
#. TRANS particular sort of device.
diff --git a/po/sv.po b/po/sv.po
index 0ebfec5b7f..d10bfad482 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -5,12 +5,12 @@
# Jan Djärv <jan.h.d@swipnet.se>, 1996, 1998, 2001, 2002, 2003, 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015.
# Göran Uddeborg <goeran@uddeborg.se>, 2016, 2017.
#
-# $Revision: 1.7 $
+# $Revision: 1.10 $
msgid ""
msgstr ""
-"Project-Id-Version: libc 2.25-pre1\n"
-"POT-Creation-Date: 2017-01-11 17:27+0530\n"
-"PO-Revision-Date: 2017-05-30 12:14+0200\n"
+"Project-Id-Version: libc 2.25.90\n"
+"POT-Creation-Date: 2017-07-25 12:32+0530\n"
+"PO-Revision-Date: 2017-08-20 18:21+0200\n"
"Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
@@ -478,19 +478,19 @@ msgstr "FEL I DYNAMISK LÄNKARE!!!"
msgid "error while loading shared libraries"
msgstr "fel när delade bibliotek laddades"
-#: elf/dl-fptr.c:88 sysdeps/hppa/dl-fptr.c:94
+#: elf/dl-fptr.c:88 sysdeps/hppa/dl-fptr.c:95
msgid "cannot map pages for fdesc table"
msgstr "kan inte minnesmappa sidor för fdesc-tabell"
-#: elf/dl-fptr.c:192 sysdeps/hppa/dl-fptr.c:207
+#: elf/dl-fptr.c:192 sysdeps/hppa/dl-fptr.c:213
msgid "cannot map pages for fptr table"
msgstr "kan inte minnesmappa sidor för fptr-tabell"
-#: elf/dl-fptr.c:221 sysdeps/hppa/dl-fptr.c:236
+#: elf/dl-fptr.c:221 sysdeps/hppa/dl-fptr.c:242
msgid "internal error: symidx out of range of fptr table"
msgstr "internt fel: symidx är utanför intervallet för fptr-tabellen"
-#: elf/dl-hwcaps.c:184 elf/dl-hwcaps.c:196
+#: elf/dl-hwcaps.c:191 elf/dl-hwcaps.c:203
msgid "cannot create capability list"
msgstr "kan inte skapa egenskapslista"
@@ -670,20 +670,20 @@ msgstr "ogiltig målnamnrymd för dlmopen()"
msgid "cannot allocate memory in static TLS block"
msgstr "kan inte allokera minne i statiskt TLS-block"
-#: elf/dl-reloc.c:212
+#: elf/dl-reloc.c:206
msgid "cannot make segment writable for relocation"
msgstr "kan inte göra segment skrivbart för relokering"
-#: elf/dl-reloc.c:283
+#: elf/dl-reloc.c:277
#, c-format
msgid "%s: out of memory to store relocation results for %s\n"
msgstr "%s: slut på minne för att lagra relokeringsresultat för %s\n"
-#: elf/dl-reloc.c:299
+#: elf/dl-reloc.c:293
msgid "cannot restore segment prot after reloc"
msgstr "kan inte återställa segmenträttigheter efter relokering"
-#: elf/dl-reloc.c:330
+#: elf/dl-reloc.c:324
msgid "cannot apply additional memory protection after relocation"
msgstr "kan inte applicera extra minnesskydd efter relokering"
@@ -959,14 +959,14 @@ msgstr "Försök med \"ldd --help\" för mer information."
msgid "missing file arguments"
msgstr "filargument saknas"
-#. TRANS No such file or directory. This is a ``file doesn't exist'' error
+#. TRANS This is a ``file doesn't exist'' error
#. TRANS for ordinary files that are referenced in contexts where they are
#. TRANS expected to already exist.
#: elf/ldd.bash.in:147 sysdeps/gnu/errlist.c:37
msgid "No such file or directory"
msgstr "Filen eller katalogen finns inte"
-#: elf/ldd.bash.in:150 inet/rcmd.c:475
+#: elf/ldd.bash.in:150 inet/rcmd.c:480
msgid "not regular file"
msgstr "inte en normal fil"
@@ -1540,68 +1540,68 @@ msgstr "vid insättning i sökträd"
msgid "cannot generate output file"
msgstr "kan inte generera utfil"
-#: inet/rcmd.c:155
+#: inet/rcmd.c:157
msgid "rcmd: Cannot allocate memory\n"
msgstr "rcmd: Kan inte allokera minne\n"
-#: inet/rcmd.c:170
+#: inet/rcmd.c:174
msgid "rcmd: socket: All ports in use\n"
msgstr "rcmd: uttag (socket): Alla portar används\n"
-#: inet/rcmd.c:198
+#: inet/rcmd.c:202
#, c-format
msgid "connect to address %s: "
msgstr "anslut till adress %s: "
-#: inet/rcmd.c:211
+#: inet/rcmd.c:215
#, c-format
msgid "Trying %s...\n"
msgstr "Provar %s...\n"
-#: inet/rcmd.c:247
+#: inet/rcmd.c:251
#, c-format
msgid "rcmd: write (setting up stderr): %m\n"
msgstr "rcmd: write: (sätter upp standard fel): %m\n"
-#: inet/rcmd.c:263
+#: inet/rcmd.c:267
#, c-format
msgid "rcmd: poll (setting up stderr): %m\n"
msgstr "rcmd: poll (sätter upp standard fel): %m\n"
-#: inet/rcmd.c:266
+#: inet/rcmd.c:270
msgid "poll: protocol failure in circuit setup\n"
msgstr "poll: protokollfel i förbindelseuppsättning\n"
-#: inet/rcmd.c:298
+#: inet/rcmd.c:302
msgid "socket: protocol failure in circuit setup\n"
msgstr "uttag (socket): protokollfel i förbindelseuppsättning\n"
-#: inet/rcmd.c:322
+#: inet/rcmd.c:326
#, c-format
msgid "rcmd: %s: short read"
msgstr "rcmd: %s: läsning gav för lite data"
-#: inet/rcmd.c:473
+#: inet/rcmd.c:478
msgid "lstat failed"
msgstr "misslyckades ta status (lstat)"
-#: inet/rcmd.c:480
+#: inet/rcmd.c:485
msgid "cannot open"
msgstr "kan inte öppna"
-#: inet/rcmd.c:482
+#: inet/rcmd.c:487
msgid "fstat failed"
msgstr "misslyckades ta status (fstat)"
-#: inet/rcmd.c:484
+#: inet/rcmd.c:489
msgid "bad owner"
msgstr "felaktig ägare"
-#: inet/rcmd.c:486
+#: inet/rcmd.c:491
msgid "writeable by other than owner"
msgstr "skrivbar för andra än ägaren"
-#: inet/rcmd.c:488
+#: inet/rcmd.c:493
msgid "hard linked somewhere"
msgstr "hårdlänkad någonstans"
@@ -3143,7 +3143,7 @@ msgstr "Okänt systemfel"
msgid "unable to free arguments"
msgstr "kan inte avallokera argument"
-#: nis/nis_error.h:1 nis/ypclnt.c:817 nis/ypclnt.c:905 posix/regcomp.c:137
+#: nis/nis_error.h:1 nis/ypclnt.c:824 nis/ypclnt.c:913 posix/regcomp.c:137
#: sysdeps/gnu/errlist.c:21
msgid "Success"
msgstr "Lyckat"
@@ -3184,8 +3184,8 @@ msgstr "Generiskt systemfel"
msgid "First/next chain broken"
msgstr "Första/Nästa-kedja bruten"
-#. TRANS Permission denied; the file permissions do not allow the attempted operation.
-#: nis/nis_error.h:11 nis/ypclnt.c:862 sysdeps/gnu/errlist.c:158
+#. TRANS The file permissions do not allow the attempted operation.
+#: nis/nis_error.h:11 nis/ypclnt.c:869 sysdeps/gnu/errlist.c:158
msgid "Permission denied"
msgstr "Åtkomst nekas"
@@ -3337,128 +3337,128 @@ msgstr "Kan inte skapa process hos server"
msgid "Master server busy, full dump rescheduled."
msgstr "Huvudserver är upptagen, full dump åter schemalagd."
-#: nis/nis_local_names.c:121
+#: nis/nis_local_names.c:122
#, c-format
msgid "LOCAL entry for UID %d in directory %s not unique\n"
msgstr "LOCAL-post för UID %d i katalog %s är inte unik\n"
-#: nis/nis_print.c:51
+#: nis/nis_print.c:52
msgid "UNKNOWN"
msgstr "OKÄND"
-#: nis/nis_print.c:109
+#: nis/nis_print.c:110
msgid "BOGUS OBJECT\n"
msgstr "SKENOBJEKT\n"
-#: nis/nis_print.c:112
+#: nis/nis_print.c:113
msgid "NO OBJECT\n"
msgstr "INGET OBJEKT\n"
-#: nis/nis_print.c:115
+#: nis/nis_print.c:116
msgid "DIRECTORY\n"
msgstr "KATALOG\n"
-#: nis/nis_print.c:118
+#: nis/nis_print.c:119
msgid "GROUP\n"
msgstr "GRUPP\n"
-#: nis/nis_print.c:121
+#: nis/nis_print.c:122
msgid "TABLE\n"
msgstr "TABELL\n"
-#: nis/nis_print.c:124
+#: nis/nis_print.c:125
msgid "ENTRY\n"
msgstr "POST\n"
-#: nis/nis_print.c:127
+#: nis/nis_print.c:128
msgid "LINK\n"
msgstr "LÄNK\n"
-#: nis/nis_print.c:130
+#: nis/nis_print.c:131
msgid "PRIVATE\n"
msgstr "PRIVAT\n"
-#: nis/nis_print.c:133
+#: nis/nis_print.c:134
msgid "(Unknown object)\n"
msgstr "(Okänt objekt)\n"
-#: nis/nis_print.c:167
+#: nis/nis_print.c:168
#, c-format
msgid "Name : `%s'\n"
msgstr "Namn: \"%s\"\n"
-#: nis/nis_print.c:168
+#: nis/nis_print.c:169
#, c-format
msgid "Type : %s\n"
msgstr "Typ: %s\n"
-#: nis/nis_print.c:173
+#: nis/nis_print.c:174
msgid "Master Server :\n"
msgstr "Huvudserver:\n"
-#: nis/nis_print.c:175
+#: nis/nis_print.c:176
msgid "Replicate :\n"
msgstr "Replikera:\n"
-#: nis/nis_print.c:176
+#: nis/nis_print.c:177
#, c-format
msgid "\tName : %s\n"
msgstr "\tNamn : %s\n"
-#: nis/nis_print.c:177
+#: nis/nis_print.c:178
msgid "\tPublic Key : "
msgstr "\tPublik nyckel: "
-#: nis/nis_print.c:181
+#: nis/nis_print.c:182
msgid "None.\n"
msgstr "Ingen.\n"
-#: nis/nis_print.c:184
+#: nis/nis_print.c:185
#, c-format
msgid "Diffie-Hellmann (%d bits)\n"
msgstr "Diffie-Hellmann (%d bitar)\n"
-#: nis/nis_print.c:189
+#: nis/nis_print.c:190
#, c-format
msgid "RSA (%d bits)\n"
msgstr "RSA (%d bitar)\n"
-#: nis/nis_print.c:192
+#: nis/nis_print.c:193
msgid "Kerberos.\n"
msgstr "Kerberos.\n"
-#: nis/nis_print.c:195
+#: nis/nis_print.c:196
#, c-format
msgid "Unknown (type = %d, bits = %d)\n"
msgstr "Okänd (typ = %d, bitar = %d)\n"
-#: nis/nis_print.c:206
+#: nis/nis_print.c:207
#, c-format
msgid "\tUniversal addresses (%u)\n"
msgstr "\tUniversella adresser (%u)\n"
-#: nis/nis_print.c:228
+#: nis/nis_print.c:229
msgid "Time to live : "
msgstr "Livslängd: "
-#: nis/nis_print.c:230
+#: nis/nis_print.c:231
msgid "Default Access rights :\n"
msgstr "Standard åtkomsträttigheter:\n"
-#: nis/nis_print.c:239
+#: nis/nis_print.c:240
#, c-format
msgid "\tType : %s\n"
msgstr "\tTyp : %s\n"
-#: nis/nis_print.c:240
+#: nis/nis_print.c:241
msgid "\tAccess rights: "
msgstr "\tRättigheter : "
-#: nis/nis_print.c:254
+#: nis/nis_print.c:255
msgid "Group Flags :"
msgstr "Gruppflaggor: "
-#: nis/nis_print.c:257
+#: nis/nis_print.c:258
msgid ""
"\n"
"Group Members :\n"
@@ -3466,95 +3466,95 @@ msgstr ""
"\n"
"Gruppmedlemmar:\n"
-#: nis/nis_print.c:269
+#: nis/nis_print.c:270
#, c-format
msgid "Table Type : %s\n"
msgstr "Tabelltyp : %s\n"
-#: nis/nis_print.c:270
+#: nis/nis_print.c:271
#, c-format
msgid "Number of Columns : %d\n"
msgstr "Antal kolumner : %d\n"
-#: nis/nis_print.c:271
+#: nis/nis_print.c:272
#, c-format
msgid "Character Separator : %c\n"
msgstr "Teckenseparator : %c\n"
-#: nis/nis_print.c:272
+#: nis/nis_print.c:273
#, c-format
msgid "Search Path : %s\n"
msgstr "Sökväg : %s\n"
-#: nis/nis_print.c:273
+#: nis/nis_print.c:274
msgid "Columns :\n"
msgstr "Kolumner :\n"
-#: nis/nis_print.c:276
+#: nis/nis_print.c:277
#, c-format
msgid "\t[%d]\tName : %s\n"
msgstr "\t[%d]\tNamn : %s\n"
-#: nis/nis_print.c:278
+#: nis/nis_print.c:279
msgid "\t\tAttributes : "
msgstr "\t\tAttribut : "
-#: nis/nis_print.c:280
+#: nis/nis_print.c:281
msgid "\t\tAccess Rights : "
msgstr "\t\tRättigheter : "
-#: nis/nis_print.c:290
+#: nis/nis_print.c:291
msgid "Linked Object Type : "
msgstr "Länkad objekttyp : "
-#: nis/nis_print.c:292
+#: nis/nis_print.c:293
#, c-format
msgid "Linked to : %s\n"
msgstr "Länkad till: %s\n"
-#: nis/nis_print.c:302
+#: nis/nis_print.c:303
#, c-format
msgid "\tEntry data of type %s\n"
msgstr "\tPostdata av typ %s\n"
-#: nis/nis_print.c:305
+#: nis/nis_print.c:306
#, c-format
msgid "\t[%u] - [%u bytes] "
msgstr "\t[%u] - [%u byte] "
-#: nis/nis_print.c:308
+#: nis/nis_print.c:309
msgid "Encrypted data\n"
msgstr "Krypterat data\n"
-#: nis/nis_print.c:310
+#: nis/nis_print.c:311
msgid "Binary data\n"
msgstr "Binärdata\n"
-#: nis/nis_print.c:326
+#: nis/nis_print.c:327
#, c-format
msgid "Object Name : %s\n"
msgstr "Objektnamn : %s\n"
-#: nis/nis_print.c:327
+#: nis/nis_print.c:328
#, c-format
msgid "Directory : %s\n"
msgstr "Katalog : %s\n"
-#: nis/nis_print.c:328
+#: nis/nis_print.c:329
#, c-format
msgid "Owner : %s\n"
msgstr "Ägare : %s\n"
-#: nis/nis_print.c:329
+#: nis/nis_print.c:330
#, c-format
msgid "Group : %s\n"
msgstr "Grupp : %s\n"
-#: nis/nis_print.c:330
+#: nis/nis_print.c:331
msgid "Access Rights : "
msgstr "Rättigheter : "
-#: nis/nis_print.c:332
+#: nis/nis_print.c:333
#, c-format
msgid ""
"\n"
@@ -3563,90 +3563,90 @@ msgstr ""
"\n"
"Livslängd : "
-#: nis/nis_print.c:335
+#: nis/nis_print.c:336
#, c-format
msgid "Creation Time : %s"
msgstr "Skapad : %s"
-#: nis/nis_print.c:337
+#: nis/nis_print.c:338
#, c-format
msgid "Mod. Time : %s"
msgstr "Ändr. tid : %s"
-#: nis/nis_print.c:338
+#: nis/nis_print.c:339
msgid "Object Type : "
msgstr "Objekttyp : "
-#: nis/nis_print.c:358
+#: nis/nis_print.c:359
#, c-format
msgid " Data Length = %u\n"
msgstr " Datalängd = %u\n"
-#: nis/nis_print.c:372
+#: nis/nis_print.c:373
#, c-format
msgid "Status : %s\n"
msgstr "Status : %s\n"
-#: nis/nis_print.c:373
+#: nis/nis_print.c:374
#, c-format
msgid "Number of objects : %u\n"
msgstr "Antal objekt : %u\n"
-#: nis/nis_print.c:377
+#: nis/nis_print.c:378
#, c-format
msgid "Object #%d:\n"
msgstr "Objekt nr %d:\n"
-#: nis/nis_print_group_entry.c:116
+#: nis/nis_print_group_entry.c:117
#, c-format
msgid "Group entry for \"%s.%s\" group:\n"
msgstr "Gruppost för \"%s.%s\" grupp:\n"
-#: nis/nis_print_group_entry.c:124
+#: nis/nis_print_group_entry.c:125
msgid " Explicit members:\n"
msgstr " Explicita medlemmar:\n"
-#: nis/nis_print_group_entry.c:129
+#: nis/nis_print_group_entry.c:130
msgid " No explicit members\n"
msgstr " Inga explicita medlemmar\n"
-#: nis/nis_print_group_entry.c:132
+#: nis/nis_print_group_entry.c:133
msgid " Implicit members:\n"
msgstr " Implicita medlemmar:\n"
-#: nis/nis_print_group_entry.c:137
+#: nis/nis_print_group_entry.c:138
msgid " No implicit members\n"
msgstr " Inga implicita medlemmar\n"
-#: nis/nis_print_group_entry.c:140
+#: nis/nis_print_group_entry.c:141
msgid " Recursive members:\n"
msgstr " Rekursiva medlemmar:\n"
-#: nis/nis_print_group_entry.c:145
+#: nis/nis_print_group_entry.c:146
msgid " No recursive members\n"
msgstr " Inga rekursiva medlemmar\n"
-#: nis/nis_print_group_entry.c:148
+#: nis/nis_print_group_entry.c:149
msgid " Explicit nonmembers:\n"
msgstr " Explicita icke-medlemmar:\n"
-#: nis/nis_print_group_entry.c:153
+#: nis/nis_print_group_entry.c:154
msgid " No explicit nonmembers\n"
msgstr " Inga explicita icke-medlemmar\n"
-#: nis/nis_print_group_entry.c:156
+#: nis/nis_print_group_entry.c:157
msgid " Implicit nonmembers:\n"
msgstr " Implicita icke-medlemmar:\n"
-#: nis/nis_print_group_entry.c:161
+#: nis/nis_print_group_entry.c:162
msgid " No implicit nonmembers\n"
msgstr " Inga implicita icke-medlemmar\n"
-#: nis/nis_print_group_entry.c:164
+#: nis/nis_print_group_entry.c:165
msgid " Recursive nonmembers:\n"
msgstr " Rekursiva icke-medlemmar:\n"
-#: nis/nis_print_group_entry.c:169
+#: nis/nis_print_group_entry.c:170
msgid " No recursive nonmembers\n"
msgstr " Inga rekursiva icke-medlemmar\n"
@@ -3688,100 +3688,100 @@ msgstr "netname2user: LOCAL-post för %s i katalog %s är inte unik"
msgid "netname2user: should not have uid 0"
msgstr "netname2user: borde inte ha uid 0"
-#: nis/ypclnt.c:820
+#: nis/ypclnt.c:827
msgid "Request arguments bad"
msgstr "Argument för förfrågan felaktiga"
-#: nis/ypclnt.c:823
+#: nis/ypclnt.c:830
msgid "RPC failure on NIS operation"
msgstr "RPC-fel vid NIS-operation"
-#: nis/ypclnt.c:826
+#: nis/ypclnt.c:833
msgid "Can't bind to server which serves this domain"
msgstr "Kan inte ansluta till servern som betjänar denna domän"
-#: nis/ypclnt.c:829
+#: nis/ypclnt.c:836
msgid "No such map in server's domain"
msgstr "Ingen sådan tabell i serverns domän"
-#: nis/ypclnt.c:832
+#: nis/ypclnt.c:839
msgid "No such key in map"
msgstr "Ingen sådan nyckel i tabellen"
-#: nis/ypclnt.c:835
+#: nis/ypclnt.c:842
msgid "Internal NIS error"
msgstr "Internt NIS-fel"
-#: nis/ypclnt.c:838
+#: nis/ypclnt.c:845
msgid "Local resource allocation failure"
msgstr "Allokeringsfel för lokal resurs"
-#: nis/ypclnt.c:841
+#: nis/ypclnt.c:848
msgid "No more records in map database"
msgstr "Inga fler poster i tabelldatabasen"
-#: nis/ypclnt.c:844
+#: nis/ypclnt.c:851
msgid "Can't communicate with portmapper"
msgstr "Kan inte kommunicera med portmapper"
-#: nis/ypclnt.c:847
+#: nis/ypclnt.c:854
msgid "Can't communicate with ypbind"
msgstr "Kan inte kommunicera med ypbind"
-#: nis/ypclnt.c:850
+#: nis/ypclnt.c:857
msgid "Can't communicate with ypserv"
msgstr "Kan inte kommunicera med ypserv"
-#: nis/ypclnt.c:853
+#: nis/ypclnt.c:860
msgid "Local domain name not set"
msgstr "Lokalt domännamn inte satt"
-#: nis/ypclnt.c:856
+#: nis/ypclnt.c:863
msgid "NIS map database is bad"
msgstr "NIS tabelldatabas är felaktig"
-#: nis/ypclnt.c:859
+#: nis/ypclnt.c:866
msgid "NIS client/server version mismatch - can't supply service"
msgstr "NIS versionsskillnad klient/server - kan inte betjäna"
-#: nis/ypclnt.c:865
+#: nis/ypclnt.c:872
msgid "Database is busy"
msgstr "Databasen är upptagen"
-#: nis/ypclnt.c:868
+#: nis/ypclnt.c:875
msgid "Unknown NIS error code"
msgstr "Okänd NIS-felkod"
-#: nis/ypclnt.c:908
+#: nis/ypclnt.c:916
msgid "Internal ypbind error"
msgstr "Internt ypbind-fel"
-#: nis/ypclnt.c:911
+#: nis/ypclnt.c:919
msgid "Domain not bound"
msgstr "Domän inte bunden"
-#: nis/ypclnt.c:914
+#: nis/ypclnt.c:922
msgid "System resource allocation failure"
msgstr "Allokeringsfel för systemresurs"
-#: nis/ypclnt.c:917
+#: nis/ypclnt.c:925
msgid "Unknown ypbind error"
msgstr "Okänt ypbind-fel"
-#: nis/ypclnt.c:958
+#: nis/ypclnt.c:966
msgid "yp_update: cannot convert host to netname\n"
msgstr "yp_update: kan inte omvandla värd till nätnamn\n"
-#: nis/ypclnt.c:976
+#: nis/ypclnt.c:984
msgid "yp_update: cannot get server address\n"
msgstr "yp_update: kan inte hämta serveradress\n"
-#: nscd/aicache.c:84 nscd/hstcache.c:485
+#: nscd/aicache.c:85 nscd/hstcache.c:485
#, c-format
msgid "Haven't found \"%s\" in hosts cache!"
msgstr "Hittar inte \"%s\" i värdcache!"
-#: nscd/aicache.c:86 nscd/hstcache.c:487
+#: nscd/aicache.c:87 nscd/hstcache.c:487
#, c-format
msgid "Reloading \"%s\" in hosts cache!"
msgstr "Omladdar \"%s\" i värdcache!"
@@ -3815,269 +3815,264 @@ msgstr "beskär %s cache; tid %ld"
msgid "considering %s entry \"%s\", timeout %<PRIu64>"
msgstr "överväger %s-post \"%s\", tidsgräns %<PRIu64>"
-#: nscd/connections.c:548
+#: nscd/connections.c:537
#, c-format
msgid "invalid persistent database file \"%s\": %s"
msgstr "ogiltig persistent databasfil \"%s\": %s"
-#: nscd/connections.c:556
+#: nscd/connections.c:545
msgid "uninitialized header"
msgstr "oinitierat huvud"
-#: nscd/connections.c:561
+#: nscd/connections.c:550
msgid "header size does not match"
msgstr "huvudstorlek stämmer inte"
-#: nscd/connections.c:571
+#: nscd/connections.c:560
msgid "file size does not match"
msgstr "filstorlek stämmer inte"
-#: nscd/connections.c:588
+#: nscd/connections.c:577
msgid "verification failed"
msgstr "verifikation misslyckades"
-#: nscd/connections.c:602
+#: nscd/connections.c:591
#, c-format
msgid "suggested size of table for database %s larger than the persistent database's table"
msgstr "föreslagen storlek på tabellen för databas %s är större än den persistenta databasens tabell"
-#: nscd/connections.c:613 nscd/connections.c:697
+#: nscd/connections.c:602 nscd/connections.c:686
#, c-format
msgid "cannot create read-only descriptor for \"%s\"; no mmap"
msgstr "kan inte skapa läsbar filidentifierare för \"%s\", ingen mmap"
-#: nscd/connections.c:629
+#: nscd/connections.c:618
#, c-format
msgid "cannot access '%s'"
msgstr "kan inte komma åt \"%s\""
-#: nscd/connections.c:677
+#: nscd/connections.c:666
#, c-format
msgid "database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"
msgstr "databas för %s korrupt eller använd av flera samtidigt; ta bort %s manuellt om det behövs och starta om"
-#: nscd/connections.c:683
+#: nscd/connections.c:672
#, c-format
msgid "cannot create %s; no persistent database used"
msgstr "kan inte skapa %s; ingen persistent databas används"
-#: nscd/connections.c:686
+#: nscd/connections.c:675
#, c-format
msgid "cannot create %s; no sharing possible"
msgstr "kan inte skapa %s; ingen delning möjlig"
-#: nscd/connections.c:757
+#: nscd/connections.c:746
#, c-format
msgid "cannot write to database file %s: %s"
msgstr "kan inte skriva till databasfil %s: %s"
-#: nscd/connections.c:796
-#, c-format
-msgid "cannot set socket to close on exec: %s; disabling paranoia mode"
-msgstr "kan inte sätta uttag (socket) att stängas vid programstart: %s; kopplar ur paranoialäge"
-
-#: nscd/connections.c:831
+#: nscd/connections.c:802
#, c-format
msgid "cannot open socket: %s"
msgstr "kan inte öppna uttag (socket): %s"
-#: nscd/connections.c:850
+#: nscd/connections.c:821
#, c-format
msgid "cannot enable socket to accept connections: %s"
msgstr "kan inte få uttag (socket) att acceptera förbindelser: %s"
-#: nscd/connections.c:907
+#: nscd/connections.c:878
#, c-format
msgid "disabled inotify-based monitoring for file `%s': %s"
msgstr "avaktiverade inotify-baserad övervakning för filen ”%s”: %s"
-#: nscd/connections.c:911
+#: nscd/connections.c:882
#, c-format
msgid "monitoring file `%s` (%d)"
msgstr "övervakar filen ”%s” (%d)"
-#: nscd/connections.c:924
+#: nscd/connections.c:895
#, c-format
msgid "disabled inotify-based monitoring for directory `%s': %s"
msgstr "avaktiverade inotify-baserad övervakning av katalogen ”%s”: %s"
-#: nscd/connections.c:928
+#: nscd/connections.c:899
#, c-format
msgid "monitoring directory `%s` (%d)"
msgstr "övervakar katalogen ”%s” (%d)"
-#: nscd/connections.c:956
+#: nscd/connections.c:927
#, c-format
msgid "monitoring file %s for database %s"
msgstr "övervakar filen %s för databas %s"
-#: nscd/connections.c:966
+#: nscd/connections.c:937
#, c-format
msgid "stat failed for file `%s'; will try again later: %s"
msgstr "stat misslyckades för filen ”%s”; kommer försöka igen senare: %s"
-#: nscd/connections.c:1085
+#: nscd/connections.c:1056
#, c-format
msgid "provide access to FD %d, for %s"
msgstr "ge åtkomst till FD %d, för %s"
-#: nscd/connections.c:1097
+#: nscd/connections.c:1068
#, c-format
msgid "cannot handle old request version %d; current version is %d"
msgstr "kan inte hantera äldre förfrågansversion %d, nuvarande version är %d"
-#: nscd/connections.c:1119
+#: nscd/connections.c:1090
#, c-format
msgid "request from %ld not handled due to missing permission"
msgstr "begäran från %ld inte hanterad för att rättigheter saknas"
-#: nscd/connections.c:1124
+#: nscd/connections.c:1095
#, c-format
msgid "request from '%s' [%ld] not handled due to missing permission"
msgstr "begäran från \"%s\" [%ld] inte hanterad för att rättigheter saknas"
-#: nscd/connections.c:1129
+#: nscd/connections.c:1100
msgid "request not handled due to missing permission"
msgstr "begäran inte hanterad för att rättigheter saknas"
-#: nscd/connections.c:1167 nscd/connections.c:1220
+#: nscd/connections.c:1138 nscd/connections.c:1191
#, c-format
msgid "cannot write result: %s"
msgstr "kan inte skriva resultat: %s"
-#: nscd/connections.c:1311
+#: nscd/connections.c:1282
#, c-format
msgid "error getting caller's id: %s"
msgstr "kunde inte hämta anropandes identitet: %s"
-#: nscd/connections.c:1371
+#: nscd/connections.c:1342
#, c-format
msgid "cannot open /proc/self/cmdline: %s; disabling paranoia mode"
msgstr "kan inte öppna /proc/slef/cmdline: %s, kopplar ur paranoialäge"
-#: nscd/connections.c:1385
+#: nscd/connections.c:1356
#, c-format
msgid "cannot read /proc/self/cmdline: %s; disabling paranoia mode"
msgstr "kan inte läsa /proc/self/cmdline: %s, kopplar ur paranoialäge"
-#: nscd/connections.c:1425
+#: nscd/connections.c:1396
#, c-format
msgid "cannot change to old UID: %s; disabling paranoia mode"
msgstr "kan inte byta till föregående UID: %s; kopplar ur paranoialäge"
-#: nscd/connections.c:1435
+#: nscd/connections.c:1406
#, c-format
msgid "cannot change to old GID: %s; disabling paranoia mode"
msgstr "kan inte byta till föregående GID: %s; kopplar ur paranoialäge"
-#: nscd/connections.c:1448
+#: nscd/connections.c:1419
#, c-format
msgid "cannot change to old working directory: %s; disabling paranoia mode"
msgstr "kan inte byta till föregående arbetskatalog: %s; kopplar ur paranoialäge"
-#: nscd/connections.c:1494
+#: nscd/connections.c:1465
#, c-format
msgid "re-exec failed: %s; disabling paranoia mode"
msgstr "återstart misslyckades: %s; kopplar ur paranoialäge"
-#: nscd/connections.c:1503
+#: nscd/connections.c:1474
#, c-format
msgid "cannot change current working directory to \"/\": %s"
msgstr "kan inte byta aktuell katalog till \"/\": %s"
-#: nscd/connections.c:1696
+#: nscd/connections.c:1657
#, c-format
msgid "short read while reading request: %s"
msgstr "fattas data vid läsning av begäran: %s"
-#: nscd/connections.c:1729
+#: nscd/connections.c:1690
#, c-format
msgid "key length in request too long: %d"
msgstr "nyckellängd i begäran för lång: %d"
-#: nscd/connections.c:1742
+#: nscd/connections.c:1703
#, c-format
msgid "short read while reading request key: %s"
msgstr "fattas data vid läsning av begäransnyckel: %s"
-#: nscd/connections.c:1752
+#: nscd/connections.c:1713
#, c-format
msgid "handle_request: request received (Version = %d) from PID %ld"
msgstr "handle_request: begäran mottagen (Version = %d) från PID %ld"
-#: nscd/connections.c:1757
+#: nscd/connections.c:1718
#, c-format
msgid "handle_request: request received (Version = %d)"
msgstr "handle_request: begäran mottagen (Version = %d)"
-#: nscd/connections.c:1897
+#: nscd/connections.c:1858
#, c-format
msgid "ignored inotify event for `%s` (file exists)"
msgstr "ignorerade inotify-händelse för ”%s” (filen finns)"
-#: nscd/connections.c:1902
+#: nscd/connections.c:1863
#, c-format
msgid "monitored file `%s` was %s, removing watch"
msgstr "den övervakade filen ”%s” var %s, tar bort vakten"
-#: nscd/connections.c:1910 nscd/connections.c:1952
+#: nscd/connections.c:1871 nscd/connections.c:1913
#, c-format
msgid "failed to remove file watch `%s`: %s"
msgstr "misslyckades att ta bort filvakt ”%s”: %s"
-#: nscd/connections.c:1925
+#: nscd/connections.c:1886
#, c-format
msgid "monitored file `%s` was written to"
msgstr "den övervakade filen ”%s” skrevs till"
-#: nscd/connections.c:1949
+#: nscd/connections.c:1910
#, c-format
msgid "monitored parent directory `%s` was %s, removing watch on `%s`"
msgstr "den övervakade föräldrakatalogen ”%s” var %s, tar bort vakten av ”%s”"
-#: nscd/connections.c:1975
+#: nscd/connections.c:1936
#, c-format
msgid "monitored file `%s` was %s, adding watch"
msgstr "den övervakade filen ”%s” var %s, lägger till vakt"
-#: nscd/connections.c:1987
+#: nscd/connections.c:1948
#, c-format
msgid "failed to add file watch `%s`: %s"
msgstr "misslyckades med att lägga till filvakt ”%s”: %s"
-#: nscd/connections.c:2181 nscd/connections.c:2362
+#: nscd/connections.c:2126 nscd/connections.c:2291
#, c-format
msgid "disabled inotify-based monitoring after read error %d"
msgstr "avaktiverade inotify-baserad övervakning efter läsfel %d"
-#: nscd/connections.c:2477
+#: nscd/connections.c:2406
msgid "could not initialize conditional variable"
msgstr "kan inte initiera villkorsvariabel"
-#: nscd/connections.c:2485
+#: nscd/connections.c:2414
msgid "could not start clean-up thread; terminating"
msgstr "kunde inte starta städtråd; avslutar"
-#: nscd/connections.c:2499
+#: nscd/connections.c:2428
msgid "could not start any worker thread; terminating"
msgstr "kunde inte starta någon arbetstråd; avslutar"
-#: nscd/connections.c:2554 nscd/connections.c:2556 nscd/connections.c:2572
-#: nscd/connections.c:2582 nscd/connections.c:2600 nscd/connections.c:2611
-#: nscd/connections.c:2621
+#: nscd/connections.c:2483 nscd/connections.c:2485 nscd/connections.c:2501
+#: nscd/connections.c:2511 nscd/connections.c:2529 nscd/connections.c:2540
+#: nscd/connections.c:2550
#, c-format
msgid "Failed to run nscd as user '%s'"
msgstr "Misslyckades att köra nscd som användare \"%s\""
-#: nscd/connections.c:2574
+#: nscd/connections.c:2503
msgid "initial getgrouplist failed"
msgstr "första getgrouplist misslyckades"
-#: nscd/connections.c:2583
+#: nscd/connections.c:2512
msgid "getgrouplist failed"
msgstr "getgrouplist misslyckades"
-#: nscd/connections.c:2601
+#: nscd/connections.c:2530
msgid "setgroups failed"
msgstr "setgroups misslyckades"
@@ -4760,62 +4755,41 @@ msgstr "odefinierad"
msgid "Unrecognized variable `%s'"
msgstr "Okänd variabel \"%s\""
-#: posix/getopt.c:592 posix/getopt.c:621
+#: posix/getopt.c:277
#, c-format
-msgid "%s: option '%s' is ambiguous; possibilities:"
-msgstr "%s: flaggan \"%s\" är tvetydig; alternativ:"
+msgid "%s: option '%s%s' is ambiguous\n"
+msgstr "%s: flaggan ”%s%s” är tvetydig\n"
-#: posix/getopt.c:662 posix/getopt.c:666
+#: posix/getopt.c:283
#, c-format
-msgid "%s: option '--%s' doesn't allow an argument\n"
-msgstr "%s: flaggan \"--%s\" tar inget argument\n"
+msgid "%s: option '%s%s' is ambiguous; possibilities:"
+msgstr "%s: flaggan ”%s%s” är tvetydig; alternativ:"
-#: posix/getopt.c:675 posix/getopt.c:680
+#: posix/getopt.c:318
#, c-format
-msgid "%s: option '%c%s' doesn't allow an argument\n"
-msgstr "%s: flaggan \"%c%s\" tar inget argument\n"
+msgid "%s: unrecognized option '%s%s'\n"
+msgstr "%s: okänd flagga ”%s%s”\n"
-#: posix/getopt.c:723 posix/getopt.c:742
+#: posix/getopt.c:344
#, c-format
-msgid "%s: option '--%s' requires an argument\n"
-msgstr "%s: flaggan \"--%s\" kräver ett argument\n"
+msgid "%s: option '%s%s' doesn't allow an argument\n"
+msgstr "%s: flaggan ”%s%s” tar inget argument\n"
-#: posix/getopt.c:780 posix/getopt.c:783
+#: posix/getopt.c:359
#, c-format
-msgid "%s: unrecognized option '--%s'\n"
-msgstr "%s: okänd flagga \"--%s\"\n"
+msgid "%s: option '%s%s' requires an argument\n"
+msgstr "%s: flaggan ”%s%s” kräver ett argument\n"
-#: posix/getopt.c:791 posix/getopt.c:794
-#, c-format
-msgid "%s: unrecognized option '%c%s'\n"
-msgstr "%s: okänd flagga \"%c%s\"\n"
-
-#: posix/getopt.c:843 posix/getopt.c:846
+#: posix/getopt.c:620
#, c-format
msgid "%s: invalid option -- '%c'\n"
msgstr "%s: ogiltig flagga -- \"%c\"\n"
-#: posix/getopt.c:899 posix/getopt.c:916 posix/getopt.c:1126
-#: posix/getopt.c:1144
+#: posix/getopt.c:635 posix/getopt.c:681
#, c-format
msgid "%s: option requires an argument -- '%c'\n"
msgstr "%s: flaggan kräver ett argument -- \"%c\"\n"
-#: posix/getopt.c:972 posix/getopt.c:988
-#, c-format
-msgid "%s: option '-W %s' is ambiguous\n"
-msgstr "%s: flaggan \"-W %s\" är tvetydig\n"
-
-#: posix/getopt.c:1012 posix/getopt.c:1030
-#, c-format
-msgid "%s: option '-W %s' doesn't allow an argument\n"
-msgstr "%s: flaggan \"-W %s\" tar inget argument\n"
-
-#: posix/getopt.c:1051 posix/getopt.c:1069
-#, c-format
-msgid "%s: option '-W %s' requires an argument\n"
-msgstr "%s: flaggan \"-W %s\" kräver ett argument\n"
-
#: posix/regcomp.c:140
msgid "No match"
msgstr "Ingen träff"
@@ -4884,7 +4858,7 @@ msgstr "Obalanserade ) eller \\)"
msgid "No previous regular expression"
msgstr "Inget föregående reguljärt uttryck"
-#: posix/wordexp.c:1852
+#: posix/wordexp.c:1822
msgid "parameter null or not set"
msgstr "parameter är tom eller inte satt"
@@ -5069,7 +5043,7 @@ msgstr "Buffertplats för utdata tillgängligt"
msgid "Input message available"
msgstr "Inkommande meddelande tillgängligt"
-#: stdio-common/psiginfo-data.h:46 timezone/zdump.c:541 timezone/zic.c:483
+#: stdio-common/psiginfo-data.h:46 timezone/zdump.c:381 timezone/zic.c:520
msgid "I/O error"
msgstr "I/O-fel"
@@ -5149,170 +5123,170 @@ msgstr "Realtidssignal %d"
msgid "Unknown signal %d"
msgstr "Okänd signal %d"
-#: sunrpc/auth_unix.c:111 sunrpc/clnt_tcp.c:123 sunrpc/clnt_udp.c:135
-#: sunrpc/clnt_unix.c:124 sunrpc/svc_tcp.c:188 sunrpc/svc_tcp.c:233
-#: sunrpc/svc_udp.c:160 sunrpc/svc_unix.c:188 sunrpc/svc_unix.c:229
-#: sunrpc/xdr.c:627 sunrpc/xdr.c:787 sunrpc/xdr_array.c:101
-#: sunrpc/xdr_rec.c:152 sunrpc/xdr_ref.c:78
+#: sunrpc/auth_unix.c:112 sunrpc/clnt_tcp.c:124 sunrpc/clnt_udp.c:139
+#: sunrpc/clnt_unix.c:125 sunrpc/svc_tcp.c:189 sunrpc/svc_tcp.c:234
+#: sunrpc/svc_udp.c:161 sunrpc/svc_unix.c:189 sunrpc/svc_unix.c:230
+#: sunrpc/xdr.c:628 sunrpc/xdr.c:788 sunrpc/xdr_array.c:102
+#: sunrpc/xdr_rec.c:153 sunrpc/xdr_ref.c:79
msgid "out of memory\n"
msgstr "minnet slut\n"
-#: sunrpc/auth_unix.c:349
+#: sunrpc/auth_unix.c:350
msgid "auth_unix.c: Fatal marshalling problem"
msgstr "auth_unix.c: Fatalt kodningsproblem"
-#: sunrpc/clnt_perr.c:95 sunrpc/clnt_perr.c:111
+#: sunrpc/clnt_perr.c:96 sunrpc/clnt_perr.c:112
#, c-format
msgid "%s: %s; low version = %lu, high version = %lu"
msgstr "%s: %s; undre version = %lu, övre version = %lu"
-#: sunrpc/clnt_perr.c:102
+#: sunrpc/clnt_perr.c:103
#, c-format
msgid "%s: %s; why = %s\n"
msgstr "%s: %s; varför = %s\n"
-#: sunrpc/clnt_perr.c:104
+#: sunrpc/clnt_perr.c:105
#, c-format
msgid "%s: %s; why = (unknown authentication error - %d)\n"
msgstr "%s: %s; varför = (okänt fel vid äkthetskontroll - %d)\n"
-#: sunrpc/clnt_perr.c:153
+#: sunrpc/clnt_perr.c:154
msgid "RPC: Success"
msgstr "RPC: Lyckat"
-#: sunrpc/clnt_perr.c:156
+#: sunrpc/clnt_perr.c:157
msgid "RPC: Can't encode arguments"
msgstr "RPC: Kan inte koda argumentet"
-#: sunrpc/clnt_perr.c:160
+#: sunrpc/clnt_perr.c:161
msgid "RPC: Can't decode result"
msgstr "RPC: Kan inte avkoda resultatet"
-#: sunrpc/clnt_perr.c:164
+#: sunrpc/clnt_perr.c:165
msgid "RPC: Unable to send"
msgstr "RPC: Kan inte skicka"
-#: sunrpc/clnt_perr.c:168
+#: sunrpc/clnt_perr.c:169
msgid "RPC: Unable to receive"
msgstr "RPC: Kan inte ta emot"
-#: sunrpc/clnt_perr.c:172
+#: sunrpc/clnt_perr.c:173
msgid "RPC: Timed out"
msgstr "RPC: Tiden löpte ut"
-#: sunrpc/clnt_perr.c:176
+#: sunrpc/clnt_perr.c:177
msgid "RPC: Incompatible versions of RPC"
msgstr "RPC: Inkompatibla versioner av RPC"
-#: sunrpc/clnt_perr.c:180
+#: sunrpc/clnt_perr.c:181
msgid "RPC: Authentication error"
msgstr "RPC: Fel vid äkthetskontroll"
-#: sunrpc/clnt_perr.c:184
+#: sunrpc/clnt_perr.c:185
msgid "RPC: Program unavailable"
msgstr "RPC: Programmet otillgängligt"
-#: sunrpc/clnt_perr.c:188
+#: sunrpc/clnt_perr.c:189
msgid "RPC: Program/version mismatch"
msgstr "RPC: Program/version-inkompatibilitet"
-#: sunrpc/clnt_perr.c:192
+#: sunrpc/clnt_perr.c:193
msgid "RPC: Procedure unavailable"
msgstr "RPC: Procedur inte tillgänglig"
-#: sunrpc/clnt_perr.c:196
+#: sunrpc/clnt_perr.c:197
msgid "RPC: Server can't decode arguments"
msgstr "RPC: Server kan inte avkoda argumenten"
-#: sunrpc/clnt_perr.c:200
+#: sunrpc/clnt_perr.c:201
msgid "RPC: Remote system error"
msgstr "RPC: Fjärrsystemsfel"
-#: sunrpc/clnt_perr.c:204
+#: sunrpc/clnt_perr.c:205
msgid "RPC: Unknown host"
msgstr "RPC: Okänd värdmaskin"
-#: sunrpc/clnt_perr.c:208
+#: sunrpc/clnt_perr.c:209
msgid "RPC: Unknown protocol"
msgstr "RPC: Okänt protokoll"
-#: sunrpc/clnt_perr.c:212
+#: sunrpc/clnt_perr.c:213
msgid "RPC: Port mapper failure"
msgstr "RPC: Fel i portöversättare"
-#: sunrpc/clnt_perr.c:216
+#: sunrpc/clnt_perr.c:217
msgid "RPC: Program not registered"
msgstr "RPC: Programmet inte registrerat"
-#: sunrpc/clnt_perr.c:220
+#: sunrpc/clnt_perr.c:221
msgid "RPC: Failed (unspecified error)"
msgstr "RPC: Misslyckades (ospecificerat fel)"
-#: sunrpc/clnt_perr.c:261
+#: sunrpc/clnt_perr.c:262
msgid "RPC: (unknown error code)"
msgstr "RPC: (okänd felkod)"
-#: sunrpc/clnt_perr.c:333
+#: sunrpc/clnt_perr.c:334
msgid "Authentication OK"
msgstr "Äkthetskontroll OK"
-#: sunrpc/clnt_perr.c:336
+#: sunrpc/clnt_perr.c:337
msgid "Invalid client credential"
msgstr "Ogiltiga klientreferenser"
-#: sunrpc/clnt_perr.c:340
+#: sunrpc/clnt_perr.c:341
msgid "Server rejected credential"
msgstr "Server förkastade kreditiv"
-#: sunrpc/clnt_perr.c:344
+#: sunrpc/clnt_perr.c:345
msgid "Invalid client verifier"
msgstr "Ogiltig klientverifierare"
-#: sunrpc/clnt_perr.c:348
+#: sunrpc/clnt_perr.c:349
msgid "Server rejected verifier"
msgstr "Server förkastade verifierare"
-#: sunrpc/clnt_perr.c:352
+#: sunrpc/clnt_perr.c:353
msgid "Client credential too weak"
msgstr "Klientens referenser är för svaga"
-#: sunrpc/clnt_perr.c:356
+#: sunrpc/clnt_perr.c:357
msgid "Invalid server verifier"
msgstr "Ogiltig serververifierare"
-#: sunrpc/clnt_perr.c:360
+#: sunrpc/clnt_perr.c:361
msgid "Failed (unspecified error)"
msgstr "Misslyckades (ospecificerat fel)"
-#: sunrpc/clnt_raw.c:115
+#: sunrpc/clnt_raw.c:116
msgid "clnt_raw.c: fatal header serialization error"
msgstr "clnt_raw.c: fatalt fel vid serialisering"
-#: sunrpc/pm_getmaps.c:77
+#: sunrpc/pm_getmaps.c:78
msgid "pmap_getmaps.c: rpc problem"
msgstr "pmap_getmaps.c rpc problem"
-#: sunrpc/pmap_clnt.c:127
+#: sunrpc/pmap_clnt.c:128
msgid "Cannot register service"
msgstr "Kan inte registrera tjänst"
-#: sunrpc/pmap_rmt.c:244
+#: sunrpc/pmap_rmt.c:245
msgid "Cannot create socket for broadcast rpc"
msgstr "Kan inte skapa uttag (socket) för utsändnings-rpc"
-#: sunrpc/pmap_rmt.c:251
+#: sunrpc/pmap_rmt.c:252
msgid "Cannot set socket option SO_BROADCAST"
msgstr "Kan inte sätta uttagsflaggan (socket option) SO_BROADCAST"
-#: sunrpc/pmap_rmt.c:303
+#: sunrpc/pmap_rmt.c:304
msgid "Cannot send broadcast packet"
msgstr "Kan inte skicka utsändningspaket"
-#: sunrpc/pmap_rmt.c:328
+#: sunrpc/pmap_rmt.c:329
msgid "Broadcast poll problem"
msgstr "Problem med poll vid utsändning"
-#: sunrpc/pmap_rmt.c:341
+#: sunrpc/pmap_rmt.c:342
msgid "Cannot receive reply to broadcast"
msgstr "Kan inte ta emot svar på utsändning"
@@ -5595,11 +5569,11 @@ msgstr "tom teckensträng"
msgid "preprocessor error"
msgstr "preprocessorfel"
-#: sunrpc/svc_run.c:71
+#: sunrpc/svc_run.c:72
msgid "svc_run: - out of memory"
msgstr "svc_run: - minnet slut"
-#: sunrpc/svc_run.c:91
+#: sunrpc/svc_run.c:92
msgid "svc_run: - poll failed"
msgstr "svc_run: - poll misslyckades"
@@ -5631,204 +5605,204 @@ msgstr "problem att svara till prog %d\n"
msgid "never registered prog %d\n"
msgstr "aldrig registrerat prog %d\n"
-#: sunrpc/svc_tcp.c:164
+#: sunrpc/svc_tcp.c:165
msgid "svc_tcp.c - tcp socket creation problem"
msgstr "svc_tcp.c - problem att skapa tcp-uttag (socket)"
-#: sunrpc/svc_tcp.c:179
+#: sunrpc/svc_tcp.c:180
msgid "svc_tcp.c - cannot getsockname or listen"
msgstr "svc_tcp.c - kan inte anropa getsockname eller listen"
-#: sunrpc/svc_udp.c:135
+#: sunrpc/svc_udp.c:136
msgid "svcudp_create: socket creation problem"
msgstr "svcudp_create: problem att skapa uttag (socket)"
-#: sunrpc/svc_udp.c:149
+#: sunrpc/svc_udp.c:150
msgid "svcudp_create - cannot getsockname"
msgstr "svcudp_create - kan inte anropa getsockname"
-#: sunrpc/svc_udp.c:181
+#: sunrpc/svc_udp.c:182
msgid "svcudp_create: xp_pad is too small for IP_PKTINFO\n"
msgstr "svcudp_create: xp_pad är för liten för IP_PKTINFO\n"
-#: sunrpc/svc_udp.c:480
+#: sunrpc/svc_udp.c:481
msgid "enablecache: cache already enabled"
msgstr "enablecache: cache redan påslagen"
-#: sunrpc/svc_udp.c:486
+#: sunrpc/svc_udp.c:487
msgid "enablecache: could not allocate cache"
msgstr "enablecache: kunde inte allokera cache"
-#: sunrpc/svc_udp.c:495
+#: sunrpc/svc_udp.c:496
msgid "enablecache: could not allocate cache data"
msgstr "enablecache: kunde inte allokera cache-data"
-#: sunrpc/svc_udp.c:503
+#: sunrpc/svc_udp.c:504
msgid "enablecache: could not allocate cache fifo"
msgstr "enablecache: kunde inte allokera cache-fifo"
-#: sunrpc/svc_udp.c:539
+#: sunrpc/svc_udp.c:540
msgid "cache_set: victim not found"
msgstr "cache_set: offer hittades inte"
-#: sunrpc/svc_udp.c:550
+#: sunrpc/svc_udp.c:551
msgid "cache_set: victim alloc failed"
msgstr "cache_set: offerallokering misslyckades"
-#: sunrpc/svc_udp.c:557
+#: sunrpc/svc_udp.c:558
msgid "cache_set: could not allocate new rpc_buffer"
msgstr "cache_set: kunde inte allokera ny rpc-buffert"
-#: sunrpc/svc_unix.c:162
+#: sunrpc/svc_unix.c:163
msgid "svc_unix.c - AF_UNIX socket creation problem"
msgstr "svc_unix.c - problem att skapa AF_UNIX uttag (socket)"
-#: sunrpc/svc_unix.c:178
+#: sunrpc/svc_unix.c:179
msgid "svc_unix.c - cannot getsockname or listen"
msgstr "svc_unix.c - kan inte anropa getsockname eller listen"
-#: sysdeps/generic/siglist.h:28
+#: sysdeps/generic/siglist.h:29
msgid "Hangup"
msgstr "Avringd"
-#: sysdeps/generic/siglist.h:29
+#: sysdeps/generic/siglist.h:30
msgid "Interrupt"
msgstr "Avbruten (SIGINT)"
-#: sysdeps/generic/siglist.h:30
+#: sysdeps/generic/siglist.h:31
msgid "Quit"
msgstr "Lämnad"
-#: sysdeps/generic/siglist.h:31
+#: sysdeps/generic/siglist.h:32
msgid "Illegal instruction"
msgstr "Otillåten instruktion"
-#: sysdeps/generic/siglist.h:32
+#: sysdeps/generic/siglist.h:33
msgid "Trace/breakpoint trap"
msgstr "Spårningsfälla"
-#: sysdeps/generic/siglist.h:33
+#: sysdeps/generic/siglist.h:34
msgid "Aborted"
msgstr "Avbruten (SIGABRT)"
-#: sysdeps/generic/siglist.h:34
+#: sysdeps/generic/siglist.h:35
msgid "Floating point exception"
msgstr "Flyttalsfel"
-#: sysdeps/generic/siglist.h:35
+#: sysdeps/generic/siglist.h:36
msgid "Killed"
msgstr "Dödad"
-#: sysdeps/generic/siglist.h:36
+#: sysdeps/generic/siglist.h:37
msgid "Bus error"
msgstr "Bussfel"
-#: sysdeps/generic/siglist.h:37
+#: sysdeps/generic/siglist.h:38
+msgid "Bad system call"
+msgstr "Felaktigt systemanrop"
+
+#: sysdeps/generic/siglist.h:39
msgid "Segmentation fault"
msgstr "Segmenteringsfel"
-#. TRANS Broken pipe; there is no process reading from the other end of a pipe.
+#. TRANS There is no process reading from the other end of a pipe.
#. TRANS Every library function that returns this error code also generates a
#. TRANS @code{SIGPIPE} signal; this signal terminates the program if not handled
#. TRANS or blocked. Thus, your program will never actually see @code{EPIPE}
#. TRANS unless it has handled or blocked @code{SIGPIPE}.
-#: sysdeps/generic/siglist.h:38 sysdeps/gnu/errlist.c:360
+#: sysdeps/generic/siglist.h:40 sysdeps/gnu/errlist.c:360
msgid "Broken pipe"
msgstr "Brutet rör"
-#: sysdeps/generic/siglist.h:39
+#: sysdeps/generic/siglist.h:41
msgid "Alarm clock"
msgstr "Alarmklocka"
-#: sysdeps/generic/siglist.h:40
+#: sysdeps/generic/siglist.h:42
msgid "Terminated"
msgstr "Avslutad"
-#: sysdeps/generic/siglist.h:41
+#: sysdeps/generic/siglist.h:43
msgid "Urgent I/O condition"
msgstr "Akut I/O-tillstånd"
-#: sysdeps/generic/siglist.h:42
+#: sysdeps/generic/siglist.h:44
msgid "Stopped (signal)"
msgstr "Stoppad (signal)"
-#: sysdeps/generic/siglist.h:43
+#: sysdeps/generic/siglist.h:45
msgid "Stopped"
msgstr "Stoppad"
-#: sysdeps/generic/siglist.h:44
+#: sysdeps/generic/siglist.h:46
msgid "Continued"
msgstr "Återupptagen"
-#: sysdeps/generic/siglist.h:45
+#: sysdeps/generic/siglist.h:47
msgid "Child exited"
msgstr "Barnprocess avslutad"
-#: sysdeps/generic/siglist.h:46
+#: sysdeps/generic/siglist.h:48
msgid "Stopped (tty input)"
msgstr "Stoppad (terminalläsning)"
-#: sysdeps/generic/siglist.h:47
+#: sysdeps/generic/siglist.h:49
msgid "Stopped (tty output)"
msgstr "Stoppad (terminalskrivning)"
-#: sysdeps/generic/siglist.h:48
+#: sysdeps/generic/siglist.h:50
msgid "I/O possible"
msgstr "I/O möjligt"
-#: sysdeps/generic/siglist.h:49
+#: sysdeps/generic/siglist.h:51
msgid "CPU time limit exceeded"
msgstr "Begränsning av CPU-tid överskriden"
-#: sysdeps/generic/siglist.h:50
+#: sysdeps/generic/siglist.h:52
msgid "File size limit exceeded"
msgstr "Begränsning av filstorlek överskriden"
-#: sysdeps/generic/siglist.h:51
+#: sysdeps/generic/siglist.h:53
msgid "Virtual timer expired"
msgstr "Alarmklocka - virtuell tid"
-#: sysdeps/generic/siglist.h:52
+#: sysdeps/generic/siglist.h:54
msgid "Profiling timer expired"
msgstr "Profileringsklocka"
-#: sysdeps/generic/siglist.h:53
+#: sysdeps/generic/siglist.h:55
msgid "User defined signal 1"
msgstr "Användarsignal 1"
-#: sysdeps/generic/siglist.h:54
+#: sysdeps/generic/siglist.h:56
msgid "User defined signal 2"
msgstr "Användarsignal 2"
-#: sysdeps/generic/siglist.h:58
-msgid "EMT trap"
-msgstr "Emulatorfälla"
+#: sysdeps/generic/siglist.h:57
+msgid "Window changed"
+msgstr "Ändrat fönster"
#: sysdeps/generic/siglist.h:61
-msgid "Bad system call"
-msgstr "Felaktigt systemanrop"
+msgid "EMT trap"
+msgstr "Emulatorfälla"
#: sysdeps/generic/siglist.h:64
msgid "Stack fault"
msgstr "Stackfel"
#: sysdeps/generic/siglist.h:67
-msgid "Information request"
-msgstr "Informationsbegäran"
-
-#: sysdeps/generic/siglist.h:69
msgid "Power failure"
msgstr "Strömavbrott"
-#: sysdeps/generic/siglist.h:72
+#: sysdeps/generic/siglist.h:70
+msgid "Information request"
+msgstr "Informationsbegäran"
+
+#: sysdeps/generic/siglist.h:73
msgid "Resource lost"
msgstr "Förlorad resurs"
-#: sysdeps/generic/siglist.h:75
-msgid "Window changed"
-msgstr "Ändrat fönster"
-
-#. TRANS Operation not permitted; only the owner of the file (or other resource)
+#. TRANS Only the owner of the file (or other resource)
#. TRANS or processes with special privileges can perform the operation.
#: sysdeps/gnu/errlist.c:26
msgid "Operation not permitted"
@@ -5839,7 +5813,7 @@ msgstr "Operationen inte tillåten"
msgid "No such process"
msgstr "Processen finns inte"
-#. TRANS Interrupted function call; an asynchronous signal occurred and prevented
+#. TRANS An asynchronous signal occurred and prevented
#. TRANS completion of the call. When this happens, you should try the call
#. TRANS again.
#. TRANS
@@ -5850,12 +5824,12 @@ msgstr "Processen finns inte"
msgid "Interrupted system call"
msgstr "Avbrutet systemanrop"
-#. TRANS Input/output error; usually used for physical read or write errors.
+#. TRANS Usually used for physical read or write errors.
#: sysdeps/gnu/errlist.c:70
msgid "Input/output error"
msgstr "In/ut-fel"
-#. TRANS No such device or address. The system tried to use the device
+#. TRANS The system tried to use the device
#. TRANS represented by a file you specified, and it couldn't find the device.
#. TRANS This can mean that the device file was installed incorrectly, or that
#. TRANS the physical device is missing or not correctly attached to the
@@ -5864,7 +5838,7 @@ msgstr "In/ut-fel"
msgid "No such device or address"
msgstr "Enheten eller adressen finns inte"
-#. TRANS Argument list too long; used when the arguments passed to a new program
+#. TRANS Used when the arguments passed to a new program
#. TRANS being executed with one of the @code{exec} functions (@pxref{Executing a
#. TRANS File}) occupy too much memory space. This condition never arises on
#. TRANS @gnuhurdsystems{}.
@@ -5878,21 +5852,21 @@ msgstr "Argumentlistan för lång"
msgid "Exec format error"
msgstr "Formatfel på körbar fil"
-#. TRANS Bad file descriptor; for example, I/O on a descriptor that has been
+#. TRANS For example, I/O on a descriptor that has been
#. TRANS closed or reading from a descriptor open only for writing (or vice
#. TRANS versa).
#: sysdeps/gnu/errlist.c:116
msgid "Bad file descriptor"
msgstr "Felaktig filidentifierare"
-#. TRANS There are no child processes. This error happens on operations that are
+#. TRANS This error happens on operations that are
#. TRANS supposed to manipulate child processes, when there aren't any processes
#. TRANS to manipulate.
#: sysdeps/gnu/errlist.c:127
msgid "No child processes"
msgstr "Inga barnprocesser"
-#. TRANS Deadlock avoided; allocating a system resource would have resulted in a
+#. TRANS Allocating a system resource would have resulted in a
#. TRANS deadlock situation. The system does not guarantee that it will notice
#. TRANS all such situations. This error means you got lucky and the system
#. TRANS noticed; it might just hang. @xref{File Locks}, for an example.
@@ -5900,13 +5874,13 @@ msgstr "Inga barnprocesser"
msgid "Resource deadlock avoided"
msgstr "Resursdödläge undveks"
-#. TRANS No memory available. The system cannot allocate more virtual memory
+#. TRANS The system cannot allocate more virtual memory
#. TRANS because its capacity is full.
#: sysdeps/gnu/errlist.c:149
msgid "Cannot allocate memory"
msgstr "Kan inte allokera minne"
-#. TRANS Bad address; an invalid pointer was detected.
+#. TRANS An invalid pointer was detected.
#. TRANS On @gnuhurdsystems{}, this error never happens; you get a signal instead.
#: sysdeps/gnu/errlist.c:168
msgid "Bad address"
@@ -5919,14 +5893,14 @@ msgstr "Felaktig adress"
msgid "Block device required"
msgstr "Blockenhet krävs"
-#. TRANS Resource busy; a system resource that can't be shared is already in use.
+#. TRANS A system resource that can't be shared is already in use.
#. TRANS For example, if you try to delete a file that is the root of a currently
#. TRANS mounted filesystem, you get this error.
#: sysdeps/gnu/errlist.c:190
msgid "Device or resource busy"
msgstr "Enhet eller resurs upptagen"
-#. TRANS File exists; an existing file was specified in a context where it only
+#. TRANS An existing file was specified in a context where it only
#. TRANS makes sense to specify a new file.
#: sysdeps/gnu/errlist.c:200
msgid "File exists"
@@ -5950,13 +5924,13 @@ msgstr "Enheten finns inte"
msgid "Not a directory"
msgstr "Inte en katalog"
-#. TRANS File is a directory; you cannot open a directory for writing,
+#. TRANS You cannot open a directory for writing,
#. TRANS or create or remove hard links to it.
#: sysdeps/gnu/errlist.c:240
msgid "Is a directory"
msgstr "Är en katalog"
-#. TRANS Invalid argument. This is used to indicate various kinds of problems
+#. TRANS This is used to indicate various kinds of problems
#. TRANS with passing the wrong argument to a library function.
#: sysdeps/gnu/errlist.c:250
msgid "Invalid argument"
@@ -5995,12 +5969,12 @@ msgstr "Olämplig ioctl för enheten"
msgid "Text file busy"
msgstr "Kodfil upptagen"
-#. TRANS File too big; the size of a file would be larger than allowed by the system.
+#. TRANS The size of a file would be larger than allowed by the system.
#: sysdeps/gnu/errlist.c:308
msgid "File too large"
msgstr "För stor fil"
-#. TRANS No space left on device; write operation on a file failed because the
+#. TRANS Write operation on a file failed because the
#. TRANS disk is full.
#: sysdeps/gnu/errlist.c:318
msgid "No space left on device"
@@ -6016,26 +5990,26 @@ msgstr "Otillåten sökning"
msgid "Read-only file system"
msgstr "Skrivskyddat filsystem"
-#. TRANS Too many links; the link count of a single file would become too large.
+#. TRANS The link count of a single file would become too large.
#. TRANS @code{rename} can cause this error if the file being renamed already has
#. TRANS as many links as it can take (@pxref{Renaming Files}).
#: sysdeps/gnu/errlist.c:347
msgid "Too many links"
msgstr "För många länkar"
-#. TRANS Domain error; used by mathematical functions when an argument value does
+#. TRANS Used by mathematical functions when an argument value does
#. TRANS not fall into the domain over which the function is defined.
#: sysdeps/gnu/errlist.c:370
msgid "Numerical argument out of domain"
msgstr "Numeriskt argument är utanför området"
-#. TRANS Range error; used by mathematical functions when the result value is
+#. TRANS Used by mathematical functions when the result value is
#. TRANS not representable because of overflow or underflow.
#: sysdeps/gnu/errlist.c:380
msgid "Numerical result out of range"
msgstr "Numeriskt resultat är utanför giltigt intervall"
-#. TRANS Resource temporarily unavailable; the call might work if you try again
+#. TRANS The call might work if you try again
#. TRANS later. The macro @code{EWOULDBLOCK} is another name for @code{EAGAIN};
#. TRANS they are always the same in @theglibc{}.
#. TRANS
@@ -6223,76 +6197,75 @@ msgstr "Destinationsadress krävs"
msgid "Cannot send after transport endpoint shutdown"
msgstr "Kan inte skicka efter att transportslutpunkten stängts"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:677
+#: sysdeps/gnu/errlist.c:676
msgid "Too many references: cannot splice"
msgstr "För många referenser: kan inte skarva"
#. TRANS A socket operation with a specified timeout received no response during
#. TRANS the timeout period.
-#: sysdeps/gnu/errlist.c:687
+#: sysdeps/gnu/errlist.c:686
msgid "Connection timed out"
msgstr "Förbindelsens tidsgräns löpte ut"
#. TRANS A remote host refused to allow the network connection (typically because
#. TRANS it is not running the requested service).
-#: sysdeps/gnu/errlist.c:697
+#: sysdeps/gnu/errlist.c:696
msgid "Connection refused"
msgstr "Förbindelsen förvägrad"
#. TRANS Too many levels of symbolic links were encountered in looking up a file name.
#. TRANS This often indicates a cycle of symbolic links.
-#: sysdeps/gnu/errlist.c:707
+#: sysdeps/gnu/errlist.c:706
msgid "Too many levels of symbolic links"
msgstr "För många nivåer av symboliska länkar"
#. TRANS Filename too long (longer than @code{PATH_MAX}; @pxref{Limits for
#. TRANS Files}) or host name too long (in @code{gethostname} or
#. TRANS @code{sethostname}; @pxref{Host Identification}).
-#: sysdeps/gnu/errlist.c:718
+#: sysdeps/gnu/errlist.c:717
msgid "File name too long"
msgstr "För långt filnamn"
#. TRANS The remote host for a requested network connection is down.
-#: sysdeps/gnu/errlist.c:727
+#: sysdeps/gnu/errlist.c:726
msgid "Host is down"
msgstr "Värddator är nere"
#. TRANS The remote host for a requested network connection is not reachable.
-#: sysdeps/gnu/errlist.c:736
+#: sysdeps/gnu/errlist.c:735
msgid "No route to host"
msgstr "Ingen väg till värd"
#. TRANS Directory not empty, where an empty directory was expected. Typically,
#. TRANS this error occurs when you are trying to delete a directory.
-#: sysdeps/gnu/errlist.c:746
+#: sysdeps/gnu/errlist.c:745
msgid "Directory not empty"
msgstr "Katalog inte tom"
#. TRANS This means that the per-user limit on new process would be exceeded by
#. TRANS an attempted @code{fork}. @xref{Limits on Resources}, for details on
#. TRANS the @code{RLIMIT_NPROC} limit.
-#: sysdeps/gnu/errlist.c:757
+#: sysdeps/gnu/errlist.c:756
msgid "Too many processes"
msgstr "För många processer"
#. TRANS The file quota system is confused because there are too many users.
#. TRANS @c This can probably happen in a GNU system when using NFS.
-#: sysdeps/gnu/errlist.c:767
+#: sysdeps/gnu/errlist.c:766
msgid "Too many users"
msgstr "För många användare"
#. TRANS The user's disk quota was exceeded.
-#: sysdeps/gnu/errlist.c:776
+#: sysdeps/gnu/errlist.c:775
msgid "Disk quota exceeded"
msgstr "Diskkvot överskriden"
-#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS This indicates an internal confusion in the
#. TRANS file system which is due to file system rearrangements on the server host
#. TRANS for NFS file systems or corruption in other file systems.
#. TRANS Repairing this condition usually requires unmounting, possibly repairing
#. TRANS and remounting the file system.
-#: sysdeps/gnu/errlist.c:789
+#: sysdeps/gnu/errlist.c:788
msgid "Stale file handle"
msgstr "Förlegat filhandtag"
@@ -6300,72 +6273,65 @@ msgstr "Förlegat filhandtag"
#. TRANS already specifies an NFS-mounted file.
#. TRANS (This is an error on some operating systems, but we expect it to work
#. TRANS properly on @gnuhurdsystems{}, making this error code impossible.)
-#: sysdeps/gnu/errlist.c:801
+#: sysdeps/gnu/errlist.c:800
msgid "Object is remote"
msgstr "Är ett fjärrobjekt"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:810
+#: sysdeps/gnu/errlist.c:808
msgid "RPC struct is bad"
msgstr "RPC-strukturen är felaktig"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:819
+#: sysdeps/gnu/errlist.c:816
msgid "RPC version wrong"
msgstr "RPC-versionen är felaktig"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:828
+#: sysdeps/gnu/errlist.c:824
msgid "RPC program not available"
msgstr "RPC-programmet inte tillgängligt"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:837
+#: sysdeps/gnu/errlist.c:832
msgid "RPC program version wrong"
msgstr "RPC-programversionen är felaktig"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:846
+#: sysdeps/gnu/errlist.c:840
msgid "RPC bad procedure for program"
msgstr "Felaktig RPC-procedur för programmet"
-#. TRANS No locks available. This is used by the file locking facilities; see
+#. TRANS This is used by the file locking facilities; see
#. TRANS @ref{File Locks}. This error is never generated by @gnuhurdsystems{}, but
#. TRANS it can result from an operation to an NFS server running another
#. TRANS operating system.
-#: sysdeps/gnu/errlist.c:858
+#: sysdeps/gnu/errlist.c:852
msgid "No locks available"
msgstr "Inga lås tillgängliga"
-#. TRANS Inappropriate file type or format. The file was the wrong type for the
+#. TRANS The file was the wrong type for the
#. TRANS operation, or a data file had the wrong format.
#. TRANS
#. TRANS On some systems @code{chmod} returns this error if you try to set the
#. TRANS sticky bit on a non-directory file; @pxref{Setting Permissions}.
-#: sysdeps/gnu/errlist.c:871
+#: sysdeps/gnu/errlist.c:865
msgid "Inappropriate file type or format"
msgstr "Filtyp eller format olämplig"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:880
+#: sysdeps/gnu/errlist.c:873
msgid "Authentication error"
msgstr "Autentiseringsfel"
-#. TRANS ???
-#: sysdeps/gnu/errlist.c:889
+#: sysdeps/gnu/errlist.c:881
msgid "Need authenticator"
msgstr "Behöver autentiserare"
-#. TRANS Function not implemented. This indicates that the function called is
+#. TRANS This indicates that the function called is
#. TRANS not implemented at all, either in the C library itself or in the
#. TRANS operating system. When you get this error, you can be sure that this
#. TRANS particular function will always fail with @code{ENOSYS} unless you
#. TRANS install a new version of the C library or the operating system.
-#: sysdeps/gnu/errlist.c:902
+#: sysdeps/gnu/errlist.c:894
msgid "Function not implemented"
msgstr "Funktion inte implementerad"
-#. TRANS Not supported. A function returns this error when certain parameter
+#. TRANS A function returns this error when certain parameter
#. TRANS values are valid, but the functionality they request is not available.
#. TRANS This can mean that the function does not implement a particular command
#. TRANS or option value or flag bit at all. For functions that operate on some
@@ -6377,13 +6343,13 @@ msgstr "Funktion inte implementerad"
#. TRANS
#. TRANS If the entire function is not available at all in the implementation,
#. TRANS it returns @code{ENOSYS} instead.
-#: sysdeps/gnu/errlist.c:922
+#: sysdeps/gnu/errlist.c:914
msgid "Not supported"
msgstr "Stöds ej"
#. TRANS While decoding a multibyte character the function came along an invalid
#. TRANS or an incomplete sequence of bytes or the given wide character is invalid.
-#: sysdeps/gnu/errlist.c:932
+#: sysdeps/gnu/errlist.c:924
msgid "Invalid or incomplete multibyte or wide character"
msgstr "Ogiltigt eller ofullständigt flerbyte- eller brett tecken"
@@ -6393,276 +6359,276 @@ msgstr "Ogiltigt eller ofullständigt flerbyte- eller brett tecken"
#. TRANS error because functions such as @code{read} and @code{write} translate
#. TRANS it into a @code{SIGTTIN} or @code{SIGTTOU} signal. @xref{Job Control},
#. TRANS for information on process groups and these signals.
-#: sysdeps/gnu/errlist.c:946
+#: sysdeps/gnu/errlist.c:938
msgid "Inappropriate operation for background process"
msgstr "Operation för bakgrundsprocess olämplig"
#. TRANS On @gnuhurdsystems{}, opening a file returns this error when the file is
#. TRANS translated by a program and the translator program dies while starting
#. TRANS up, before it has connected to the file.
-#: sysdeps/gnu/errlist.c:957
+#: sysdeps/gnu/errlist.c:949
msgid "Translator died"
msgstr "Översättaren dog"
#. TRANS The experienced user will know what is wrong.
#. TRANS @c This error code is a joke. Its perror text is part of the joke.
#. TRANS @c Don't change it.
-#: sysdeps/gnu/errlist.c:968
+#: sysdeps/gnu/errlist.c:960
msgid "?"
msgstr "?"
#. TRANS You did @strong{what}?
-#: sysdeps/gnu/errlist.c:977
+#: sysdeps/gnu/errlist.c:969
msgid "You really blew it this time"
msgstr "Du strulade till det den här gången"
#. TRANS Go home and have a glass of warm, dairy-fresh milk.
-#: sysdeps/gnu/errlist.c:986
+#: sysdeps/gnu/errlist.c:978
msgid "Computer bought the farm"
msgstr "Datorn packade ihop"
#. TRANS This error code has no purpose.
-#: sysdeps/gnu/errlist.c:995
+#: sysdeps/gnu/errlist.c:987
msgid "Gratuitous error"
msgstr "Omotiverat fel"
-#: sysdeps/gnu/errlist.c:1003
+#: sysdeps/gnu/errlist.c:995
msgid "Bad message"
msgstr "Felaktigt meddelande"
-#: sysdeps/gnu/errlist.c:1011
+#: sysdeps/gnu/errlist.c:1003
msgid "Identifier removed"
msgstr "Identifierare borttagen"
-#: sysdeps/gnu/errlist.c:1019
+#: sysdeps/gnu/errlist.c:1011
msgid "Multihop attempted"
msgstr "Flerhopp försöktes"
-#: sysdeps/gnu/errlist.c:1027
+#: sysdeps/gnu/errlist.c:1019
msgid "No data available"
msgstr "Inga data tillgängliga"
-#: sysdeps/gnu/errlist.c:1035
+#: sysdeps/gnu/errlist.c:1027
msgid "Link has been severed"
msgstr "Länken har brutits"
-#: sysdeps/gnu/errlist.c:1043
+#: sysdeps/gnu/errlist.c:1035
msgid "No message of desired type"
msgstr "Inget meddelande av önskad typ"
-#: sysdeps/gnu/errlist.c:1051
+#: sysdeps/gnu/errlist.c:1043
msgid "Out of streams resources"
msgstr "Stream-resurserna är slut"
-#: sysdeps/gnu/errlist.c:1059
+#: sysdeps/gnu/errlist.c:1051
msgid "Device not a stream"
msgstr "Enheten är inte en stream"
-#: sysdeps/gnu/errlist.c:1067
+#: sysdeps/gnu/errlist.c:1059
msgid "Value too large for defined data type"
msgstr "Värdet för stort för definierad datatyp"
-#: sysdeps/gnu/errlist.c:1075
+#: sysdeps/gnu/errlist.c:1067
msgid "Protocol error"
msgstr "Protokollfel"
-#: sysdeps/gnu/errlist.c:1083
+#: sysdeps/gnu/errlist.c:1075
msgid "Timer expired"
msgstr "Klockan ringde"
-#. TRANS Operation canceled; an asynchronous operation was canceled before it
+#. TRANS An asynchronous operation was canceled before it
#. TRANS completed. @xref{Asynchronous I/O}. When you call @code{aio_cancel},
#. TRANS the normal result is for the operations affected to complete with this
#. TRANS error; @pxref{Cancel AIO Operations}.
-#: sysdeps/gnu/errlist.c:1095
+#: sysdeps/gnu/errlist.c:1087
msgid "Operation canceled"
msgstr "Operationen avbruten"
-#: sysdeps/gnu/errlist.c:1103
+#: sysdeps/gnu/errlist.c:1095
msgid "Interrupted system call should be restarted"
msgstr "Avbrutet systemanrop borde omstartas"
-#: sysdeps/gnu/errlist.c:1111
+#: sysdeps/gnu/errlist.c:1103
msgid "Channel number out of range"
msgstr "Kanalnummer utanför giltigt intervall"
-#: sysdeps/gnu/errlist.c:1119
+#: sysdeps/gnu/errlist.c:1111
msgid "Level 2 not synchronized"
msgstr "Nivå 2 inte synkroniserad"
-#: sysdeps/gnu/errlist.c:1127
+#: sysdeps/gnu/errlist.c:1119
msgid "Level 3 halted"
msgstr "Nivå 3 stannad"
-#: sysdeps/gnu/errlist.c:1135
+#: sysdeps/gnu/errlist.c:1127
msgid "Level 3 reset"
msgstr "Nivå 3 omstartad"
-#: sysdeps/gnu/errlist.c:1143
+#: sysdeps/gnu/errlist.c:1135
msgid "Link number out of range"
msgstr "Länkantal utanför giltigt intervall"
-#: sysdeps/gnu/errlist.c:1151
+#: sysdeps/gnu/errlist.c:1143
msgid "Protocol driver not attached"
msgstr "Styrprogram för protokoll inte anslutet"
-#: sysdeps/gnu/errlist.c:1159
+#: sysdeps/gnu/errlist.c:1151
msgid "No CSI structure available"
msgstr "Inga CSI-strukturer tillgängliga"
-#: sysdeps/gnu/errlist.c:1167
+#: sysdeps/gnu/errlist.c:1159
msgid "Level 2 halted"
msgstr "Nivå 2 stannad"
-#: sysdeps/gnu/errlist.c:1175
+#: sysdeps/gnu/errlist.c:1167
msgid "Invalid exchange"
msgstr "Ogiltig växel"
-#: sysdeps/gnu/errlist.c:1183
+#: sysdeps/gnu/errlist.c:1175
msgid "Invalid request descriptor"
-msgstr "Ogiltig begärandeidendiferare"
+msgstr "Ogiltig begärandeidentifierare"
-#: sysdeps/gnu/errlist.c:1191
+#: sysdeps/gnu/errlist.c:1183
msgid "Exchange full"
msgstr "Växeln full"
-#: sysdeps/gnu/errlist.c:1199
+#: sysdeps/gnu/errlist.c:1191
msgid "No anode"
msgstr "Ingen anod"
-#: sysdeps/gnu/errlist.c:1207
+#: sysdeps/gnu/errlist.c:1199
msgid "Invalid request code"
msgstr "Ogiltig begärandekod"
-#: sysdeps/gnu/errlist.c:1215
+#: sysdeps/gnu/errlist.c:1207
msgid "Invalid slot"
msgstr "Ogiltig plats"
-#: sysdeps/gnu/errlist.c:1223
+#: sysdeps/gnu/errlist.c:1215
msgid "File locking deadlock error"
msgstr "Fillåsning gav dödläge"
-#: sysdeps/gnu/errlist.c:1231
+#: sysdeps/gnu/errlist.c:1223
msgid "Bad font file format"
msgstr "Felaktigt format på typsnittsfil"
-#: sysdeps/gnu/errlist.c:1239
+#: sysdeps/gnu/errlist.c:1231
msgid "Machine is not on the network"
msgstr "Maskinen finns inte på nätverket"
-#: sysdeps/gnu/errlist.c:1247
+#: sysdeps/gnu/errlist.c:1239
msgid "Package not installed"
msgstr "Paketet är inte installerat"
-#: sysdeps/gnu/errlist.c:1255
+#: sysdeps/gnu/errlist.c:1247
msgid "Advertise error"
msgstr "Annonseringsfel"
-#: sysdeps/gnu/errlist.c:1263
+#: sysdeps/gnu/errlist.c:1255
msgid "Srmount error"
msgstr "Srmount-fel"
-#: sysdeps/gnu/errlist.c:1271
+#: sysdeps/gnu/errlist.c:1263
msgid "Communication error on send"
msgstr "Kommunikationsfel vid sändning"
-#: sysdeps/gnu/errlist.c:1279
+#: sysdeps/gnu/errlist.c:1271
msgid "RFS specific error"
msgstr "RFS-specifikt fel"
-#: sysdeps/gnu/errlist.c:1287
+#: sysdeps/gnu/errlist.c:1279
msgid "Name not unique on network"
msgstr "Namnet inte unikt i nätverket"
-#: sysdeps/gnu/errlist.c:1295
+#: sysdeps/gnu/errlist.c:1287
msgid "File descriptor in bad state"
msgstr "Filidentifierare i felaktigt tillstånd"
-#: sysdeps/gnu/errlist.c:1303
+#: sysdeps/gnu/errlist.c:1295
msgid "Remote address changed"
msgstr "Fjärradress ändrades"
-#: sysdeps/gnu/errlist.c:1311
+#: sysdeps/gnu/errlist.c:1303
msgid "Can not access a needed shared library"
msgstr "Kan inte komma åt ett nödvändigt delat bibliotek"
-#: sysdeps/gnu/errlist.c:1319
+#: sysdeps/gnu/errlist.c:1311
msgid "Accessing a corrupted shared library"
msgstr "Öppnar ett korrupt delat bibliotek"
-#: sysdeps/gnu/errlist.c:1327
+#: sysdeps/gnu/errlist.c:1319
msgid ".lib section in a.out corrupted"
msgstr ".lib-sektion i a.out korrupt"
-#: sysdeps/gnu/errlist.c:1335
+#: sysdeps/gnu/errlist.c:1327
msgid "Attempting to link in too many shared libraries"
msgstr "Försöker att länka in för många delade bibliotek"
-#: sysdeps/gnu/errlist.c:1343
+#: sysdeps/gnu/errlist.c:1335
msgid "Cannot exec a shared library directly"
msgstr "Kan inte köra ett delat bibliotek direkt"
-#: sysdeps/gnu/errlist.c:1351
+#: sysdeps/gnu/errlist.c:1343
msgid "Streams pipe error"
msgstr "Streams-rörfel"
-#: sysdeps/gnu/errlist.c:1359
+#: sysdeps/gnu/errlist.c:1351
msgid "Structure needs cleaning"
msgstr "Strukturen behöver städas"
-#: sysdeps/gnu/errlist.c:1367
+#: sysdeps/gnu/errlist.c:1359
msgid "Not a XENIX named type file"
msgstr "Inte en XENIX-namngiven fil"
-#: sysdeps/gnu/errlist.c:1375
+#: sysdeps/gnu/errlist.c:1367
msgid "No XENIX semaphores available"
msgstr "Inga XENIX-semaforer tillgängliga"
-#: sysdeps/gnu/errlist.c:1383
+#: sysdeps/gnu/errlist.c:1375
msgid "Is a named type file"
msgstr "Är av typ namnfil"
-#: sysdeps/gnu/errlist.c:1391
+#: sysdeps/gnu/errlist.c:1383
msgid "Remote I/O error"
msgstr "I/O-fel på fjärrmaskin"
-#: sysdeps/gnu/errlist.c:1399
+#: sysdeps/gnu/errlist.c:1391
msgid "No medium found"
msgstr "Inget medium funnet"
-#: sysdeps/gnu/errlist.c:1407
+#: sysdeps/gnu/errlist.c:1399
msgid "Wrong medium type"
msgstr "Fel medietyp"
-#: sysdeps/gnu/errlist.c:1415
+#: sysdeps/gnu/errlist.c:1407
msgid "Required key not available"
msgstr "Obligatorisk nyckel inte tillgänglig"
-#: sysdeps/gnu/errlist.c:1423
+#: sysdeps/gnu/errlist.c:1415
msgid "Key has expired"
msgstr "Nyckeln har gått ut"
-#: sysdeps/gnu/errlist.c:1431
+#: sysdeps/gnu/errlist.c:1423
msgid "Key has been revoked"
msgstr "Nyckeln har återkallats"
-#: sysdeps/gnu/errlist.c:1439
+#: sysdeps/gnu/errlist.c:1431
msgid "Key was rejected by service"
msgstr "Nyckeln accepterades inte av tjänsten"
-#: sysdeps/gnu/errlist.c:1447
+#: sysdeps/gnu/errlist.c:1439
msgid "Owner died"
msgstr "Ägaren dog"
-#: sysdeps/gnu/errlist.c:1455
+#: sysdeps/gnu/errlist.c:1447
msgid "State not recoverable"
msgstr "Det går inte att återhämta från tillståndet"
-#: sysdeps/gnu/errlist.c:1463
+#: sysdeps/gnu/errlist.c:1455
msgid "Operation not possible due to RF-kill"
msgstr "Operationen inte möjlig p.g.a. RF-kill"
-#: sysdeps/gnu/errlist.c:1471
+#: sysdeps/gnu/errlist.c:1463
msgid "Memory page has hardware error"
msgstr "Minnessida har hårdvarufel"
@@ -6767,73 +6733,90 @@ msgstr "kan inte öppna \"%s\""
msgid "cannot read header from `%s'"
msgstr "kan inte läsa huvud från \"%s\""
-#: timezone/zdump.c:494
+#: timezone/zdump.c:338
msgid "has fewer than 3 characters"
msgstr "har färre än 3 tecken"
-#: timezone/zdump.c:496
+#: timezone/zdump.c:340
msgid "has more than 6 characters"
msgstr "har fler än 6 tecken"
-#: timezone/zdump.c:498
+#: timezone/zdump.c:342
msgid "has characters other than ASCII alphanumerics, '-' or '+'"
msgstr "har andra tecken än ASCII alfanumeriska, ”-” eller ”+”"
-#: timezone/zdump.c:503
+#: timezone/zdump.c:347
#, c-format
msgid "%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"
msgstr "%s: varning: zon \"%s\" förkortning \"%s\": %s\n"
-#: timezone/zdump.c:553
+#: timezone/zdump.c:393
#, c-format
msgid ""
-"%s: usage: %s [--version] [--help] [-{vV}] [-{ct} [lo,]hi] zonename ...\n"
+"%s: usage: %s OPTIONS ZONENAME ...\n"
+"Options include:\n"
+" -c [L,]U Start at year L (default -500), end before year U (default 2500)\n"
+" -t [L,]U Start at time L, end before time U (in seconds since 1970)\n"
+" -i List transitions briefly (format is experimental)\n"
+" -v List transitions verbosely\n"
+" -V List transitions a bit less verbosely\n"
+" --help Output this help\n"
+" --version Output version info\n"
"\n"
"Report bugs to %s.\n"
msgstr ""
-"%s: användning: %s [ --version ] [ --help ] [ -{vV} ] [ -{ct} [start,]slut] zonnamn ...\n"
+"%s: användning: %s FLAGGOR ZONNAMN …\n"
+"Flaggorna inkluderar:\n"
+" -c [L,]Ö Starta vid år L (standard -500), och sluta före år Ö (standard 2500)\n"
+" -t [L,]Ö Starta vid tid L, och sluta före tid Ö (i sekunder sedan 1970)\n"
+" -i Lista övergångar kort (formatet är experimentellt)\n"
+" -v Lista övergångar utförligt\n"
+" -V Lista övergångar lite mindre utförligt\n"
+" --help Skriv ut denna hjälp\n"
+" --version Skriv ut versionsinformation\n"
+"\n"
"Rapportera fel till %s.\n"
"Rapportera fel eller synpunkter på översättningen till <tp-sv@listor.tp-sv.se>.\n"
-#: timezone/zdump.c:635
+#: timezone/zdump.c:479
#, c-format
msgid "%s: wild -c argument %s\n"
msgstr "%s: argument \"%s\" till flaggan -c har fel format\n"
-#: timezone/zdump.c:668
+#: timezone/zdump.c:512
#, c-format
msgid "%s: wild -t argument %s\n"
msgstr "%s: argument \"%s\" till flaggan -t har fel format\n"
-#: timezone/zic.c:361
+#: timezone/zic.c:398
#, c-format
msgid "%s: Memory exhausted: %s\n"
msgstr "%s: Minnet slut: %s\n"
-#: timezone/zic.c:369
+#: timezone/zic.c:406
msgid "size overflow"
msgstr "för stor storlek"
-#: timezone/zic.c:416
-msgid "int overflow"
-msgstr "för stort heltal"
+#: timezone/zic.c:454
+msgid "integer overflow"
+msgstr "heltalsspill"
-#: timezone/zic.c:451
+#: timezone/zic.c:488
#, c-format
-msgid "\"%s\", line %d: "
-msgstr "\"%s\", rad %d: "
+msgid "\"%s\", line %<PRIdMAX>: "
+msgstr "”%s”, rad %<PRIdMAX>: "
-#: timezone/zic.c:454
+#: timezone/zic.c:491
#, c-format
-msgid " (rule from \"%s\", line %d)"
-msgstr " (regel från \"%s\", rad %d)"
+msgid " (rule from \"%s\", line %<PRIdMAX>)"
+msgstr " (regel från ”%s”, rad %<PRIdMAX>)"
-#: timezone/zic.c:473
+#: timezone/zic.c:510
#, c-format
msgid "warning: "
msgstr "varning: "
-#: timezone/zic.c:498
+#: timezone/zic.c:535
#, c-format
msgid ""
"%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n"
@@ -6849,361 +6832,382 @@ msgstr ""
"Rapportera fel till %s.\n"
"Rapportera fel eller synpunkter på översättningen till <tp-sv@listor.tp-sv.se>.\n"
-#: timezone/zic.c:534
+#: timezone/zic.c:558
+#, c-format
+msgid "%s: Can't chdir to %s: %s\n"
+msgstr "%s: Kan inte byta katalog till %s: %s\n"
+
+#: timezone/zic.c:590
msgid "wild compilation-time specification of zic_t"
msgstr "definitionen av zic_t vid kompilering är orimlig"
-#: timezone/zic.c:554
+#: timezone/zic.c:610
#, c-format
msgid "%s: More than one -d option specified\n"
msgstr "%s: Flaggan -d given mer än en gång\n"
-#: timezone/zic.c:564
+#: timezone/zic.c:620
#, c-format
msgid "%s: More than one -l option specified\n"
msgstr "%s: Flaggan -l given mer än en gång\n"
-#: timezone/zic.c:574
+#: timezone/zic.c:630
#, c-format
msgid "%s: More than one -p option specified\n"
msgstr "%s: Flaggan -p given mer än en gång\n"
-#: timezone/zic.c:584
+#: timezone/zic.c:640
#, c-format
msgid "%s: More than one -y option specified\n"
msgstr "%s: Flaggan -y given mer än en gång\n"
-#: timezone/zic.c:594
+#: timezone/zic.c:650
#, c-format
msgid "%s: More than one -L option specified\n"
msgstr "%s: Flaggan -L given mer än en gång\n"
-#: timezone/zic.c:603
+#: timezone/zic.c:659
msgid "-s ignored"
msgstr "-s ignoreras"
-#: timezone/zic.c:641
+#: timezone/zic.c:698
msgid "link to link"
msgstr "länk till länk"
-#: timezone/zic.c:644 timezone/zic.c:648
+#: timezone/zic.c:701 timezone/zic.c:705
msgid "command line"
msgstr "kommandorad"
-#: timezone/zic.c:664
+#: timezone/zic.c:721
msgid "empty file name"
msgstr "tomt filnamn"
-#: timezone/zic.c:667
+#: timezone/zic.c:724
#, c-format
msgid "file name '%s' begins with '/'"
msgstr "filnamnet ”%s” börjar med ”/”"
-#: timezone/zic.c:676
+#: timezone/zic.c:734
#, c-format
msgid "file name '%s' contains '%.*s' component"
msgstr "filnamnet ”%s” innehåller en komponent ”%.*s”"
-#: timezone/zic.c:682
+#: timezone/zic.c:740
#, c-format
msgid "file name '%s' component contains leading '-'"
msgstr "en komponent i filnamnet ”%s” innehåller en inledande ”-”"
-#: timezone/zic.c:685
+#: timezone/zic.c:743
#, c-format
msgid "file name '%s' contains overlength component '%.*s...'"
msgstr "filnamnet ”%s” innehåller en för lång komponent ”%.*s…”"
-#: timezone/zic.c:713
+#: timezone/zic.c:771
#, c-format
msgid "file name '%s' contains byte '%c'"
msgstr "filnamnet ”%s” innehåller en byte ”%c”"
-#: timezone/zic.c:714
+#: timezone/zic.c:772
#, c-format
msgid "file name '%s' contains byte '\\%o'"
msgstr "filnamnet ”%s” innehåller en byte ”\\%o”"
-#: timezone/zic.c:757
+#: timezone/zic.c:842
+#, c-format
+msgid "%s: link from %s/%s failed: %s\n"
+msgstr "%s: länk från %s/%s misslyckades: %s\n"
+
+#: timezone/zic.c:852 timezone/zic.c:1815
+#, c-format
+msgid "%s: Can't remove %s/%s: %s\n"
+msgstr "%s: Kan inte ta bort %s/%s: %s\n"
+
+#: timezone/zic.c:874
#, c-format
-msgid "%s: link from %s failed: %s"
-msgstr "%s: länk från %s misslyckades: %s"
+msgid "symbolic link used because hard link failed: %s"
+msgstr "symbolisk länk använd eftersom en hård länk misslyckades: %s"
-#: timezone/zic.c:792
-msgid "hard link failed, symbolic link used"
-msgstr "hård länk misslyckades, använder symbolisk länk"
+#: timezone/zic.c:882
+#, c-format
+msgid "%s: Can't read %s/%s: %s\n"
+msgstr "%s: Kan inte läsa %s/%s: %s\n"
-#: timezone/zic.c:802
+#: timezone/zic.c:889 timezone/zic.c:1828
#, c-format
-msgid "%s: Can't read %s: %s\n"
-msgstr "%s: Kan inte läsa %s: %s\n"
+msgid "%s: Can't create %s/%s: %s\n"
+msgstr "%s: Kan inte skapa %s/%s: %s\n"
-#: timezone/zic.c:810 timezone/zic.c:1701
+#: timezone/zic.c:898
#, c-format
-msgid "%s: Can't create %s: %s\n"
-msgstr "%s: Kan inte skapa %s: %s\n"
+msgid "copy used because hard link failed: %s"
+msgstr "kopiering använd eftersom en hård länk misslyckades: %s"
-#: timezone/zic.c:818
-msgid "link failed, copy used"
-msgstr "länka misslyckades, kopia skapad"
+#: timezone/zic.c:901
+#, c-format
+msgid "copy used because symbolic link failed: %s"
+msgstr "kopiering använd eftersom en symbolisk länk misslyckades: %s"
-#: timezone/zic.c:913 timezone/zic.c:915
+#: timezone/zic.c:1013 timezone/zic.c:1015
msgid "same rule name in multiple files"
msgstr "samma regelnamn i flera filer"
-#: timezone/zic.c:956
+#: timezone/zic.c:1056
msgid "unruly zone"
msgstr "besvärlig zon"
-#: timezone/zic.c:963
+#: timezone/zic.c:1063
#, c-format
msgid "%s in ruleless zone"
msgstr "%s i zon utan regler"
-#: timezone/zic.c:983
+#: timezone/zic.c:1083
msgid "standard input"
msgstr "standard in"
-#: timezone/zic.c:988
+#: timezone/zic.c:1088
#, c-format
msgid "%s: Can't open %s: %s\n"
msgstr "%s: Kan inte öppna %s: %s\n"
-#: timezone/zic.c:999
+#: timezone/zic.c:1099
msgid "line too long"
msgstr "för lång rad"
-#: timezone/zic.c:1019
+#: timezone/zic.c:1119
msgid "input line of unknown type"
msgstr "inrad av okänd typ"
-#: timezone/zic.c:1034
+#: timezone/zic.c:1134
#, c-format
msgid "%s: Leap line in non leap seconds file %s"
msgstr "%s: \"Leap\"-rad i fil %s som inte är skottsekundsfil"
-#: timezone/zic.c:1042 timezone/zic.c:1447 timezone/zic.c:1469
+#: timezone/zic.c:1142 timezone/zic.c:1547 timezone/zic.c:1569
#, c-format
msgid "%s: panic: Invalid l_value %d\n"
msgstr "%s: panik: Ogiltigt l_value %d\n"
-#: timezone/zic.c:1051
+#: timezone/zic.c:1151
msgid "expected continuation line not found"
msgstr "förväntad fortsättningsrad inte funnen"
-#: timezone/zic.c:1093 timezone/zic.c:2826
+#: timezone/zic.c:1193 timezone/zic.c:2976
msgid "time overflow"
msgstr "för stort tidsvärde"
-#: timezone/zic.c:1098
+#: timezone/zic.c:1198
msgid "values over 24 hours not handled by pre-2007 versions of zic"
msgstr "värden större än 24 timmar hanteras inte av zic-versioner före 2007"
-#: timezone/zic.c:1109
+#: timezone/zic.c:1209
msgid "wrong number of fields on Rule line"
msgstr "fel antal fält på \"Rule\"-rad"
-#: timezone/zic.c:1113
+#: timezone/zic.c:1213
msgid "nameless rule"
msgstr "namnlös regel"
-#: timezone/zic.c:1118
+#: timezone/zic.c:1218
msgid "invalid saved time"
msgstr "ogiltig sparad tid"
-#: timezone/zic.c:1135
+#: timezone/zic.c:1235
msgid "wrong number of fields on Zone line"
msgstr "fel antal fält på \"Zone\"-rad"
-#: timezone/zic.c:1140
+#: timezone/zic.c:1240
#, c-format
msgid "\"Zone %s\" line and -l option are mutually exclusive"
msgstr "\"Zone %s\"-rad och flaggan -l är ömsesidigt uteslutande"
-#: timezone/zic.c:1146
+#: timezone/zic.c:1246
#, c-format
msgid "\"Zone %s\" line and -p option are mutually exclusive"
msgstr "\"Zone %s\"-rad och flaggan -p är ömsesidigt uteslutande"
-#: timezone/zic.c:1154
+#: timezone/zic.c:1253
#, c-format
-msgid "duplicate zone name %s (file \"%s\", line %d)"
-msgstr "dubblerat zonnamn %s (fil \"%s\", rad %d)"
+msgid "duplicate zone name %s (file \"%s\", line %<PRIdMAX>)"
+msgstr "dubblerat zonnamn %s (filen ”%s”, rad %<PRIdMAX>)"
-#: timezone/zic.c:1167
+#: timezone/zic.c:1267
msgid "wrong number of fields on Zone continuation line"
msgstr "fel antal fält på \"Zone\"-fortsättningsrad"
-#: timezone/zic.c:1207
+#: timezone/zic.c:1307
msgid "invalid UT offset"
msgstr "ogiltigt UT-tillägg"
-#: timezone/zic.c:1211
+#: timezone/zic.c:1311
msgid "invalid abbreviation format"
msgstr "ogiltigt förkortningsformat"
-#: timezone/zic.c:1220
+#: timezone/zic.c:1320
#, c-format
msgid "format '%s' not handled by pre-2015 versions of zic"
msgstr "formatet ”%s” hanteras inte av versioner av zic före 2015"
-#: timezone/zic.c:1247
+#: timezone/zic.c:1347
msgid "Zone continuation line end time is not after end time of previous line"
msgstr "Zon-fortsättningsradens sluttid är inte efter sluttiden på föregående rad"
-#: timezone/zic.c:1274
+#: timezone/zic.c:1374
msgid "wrong number of fields on Leap line"
msgstr "fel antal fält på \"Leap\"-rad"
-#: timezone/zic.c:1283
+#: timezone/zic.c:1383
msgid "invalid leaping year"
msgstr "ogiltigt skottår"
-#: timezone/zic.c:1303 timezone/zic.c:1401
+#: timezone/zic.c:1403 timezone/zic.c:1501
msgid "invalid month name"
msgstr "ogiltigt månadsnamn"
-#: timezone/zic.c:1316 timezone/zic.c:1514 timezone/zic.c:1528
+#: timezone/zic.c:1416 timezone/zic.c:1614 timezone/zic.c:1628
msgid "invalid day of month"
msgstr "ogiltig dag i månaden"
-#: timezone/zic.c:1321
+#: timezone/zic.c:1421
msgid "time too small"
msgstr "tid för kort"
-#: timezone/zic.c:1325
+#: timezone/zic.c:1425
msgid "time too large"
msgstr "tid för lång"
-#: timezone/zic.c:1329 timezone/zic.c:1430
+#: timezone/zic.c:1429 timezone/zic.c:1530
msgid "invalid time of day"
msgstr "ogiltig tid på dagen"
-#: timezone/zic.c:1348
+#: timezone/zic.c:1448
msgid "illegal CORRECTION field on Leap line"
msgstr "otillåtet \"CORRECTION\"-fält på \"Leap\"-rad"
-#: timezone/zic.c:1353
+#: timezone/zic.c:1453
msgid "illegal Rolling/Stationary field on Leap line"
msgstr "otillåtet \"Rolling/Stationary\"-fält på \"Leap\"-rad"
-#: timezone/zic.c:1359
+#: timezone/zic.c:1459
msgid "leap second precedes Big Bang"
msgstr "skottsekund föregår Big Bang"
-#: timezone/zic.c:1372
+#: timezone/zic.c:1472
msgid "wrong number of fields on Link line"
msgstr "fel antal fält på \"Link\"-rad"
-#: timezone/zic.c:1376
+#: timezone/zic.c:1476
msgid "blank FROM field on Link line"
msgstr "tomt \"FROM\"-fält på \"Link\"-rad"
-#: timezone/zic.c:1451
+#: timezone/zic.c:1551
msgid "invalid starting year"
msgstr "ogiltigt startår"
-#: timezone/zic.c:1473
+#: timezone/zic.c:1573
msgid "invalid ending year"
msgstr "ogiltigt slutår"
-#: timezone/zic.c:1477
+#: timezone/zic.c:1577
msgid "starting year greater than ending year"
msgstr "startår är större än slutår"
-#: timezone/zic.c:1484
+#: timezone/zic.c:1584
msgid "typed single year"
msgstr "satte typ på endast ett år"
-#: timezone/zic.c:1519
+#: timezone/zic.c:1619
msgid "invalid weekday name"
msgstr "ogiltigt veckodagsnamn"
-#: timezone/zic.c:1638
+#: timezone/zic.c:1743
+#, c-format
+msgid "reference clients mishandle more than %d transition times"
+msgstr "referensklienter hanterar fler än %d övergångstider felaktigt"
+
+#: timezone/zic.c:1747
msgid "pre-2014 clients may mishandle more than 1200 transition times"
msgstr "klienter från före 2014 kan hantera fler än 1200 övergångstider felaktigt"
-#: timezone/zic.c:1691
-#, c-format
-msgid "%s: Can't remove %s: %s\n"
-msgstr "%s: Kan inte ta bort %s: %s\n"
+#: timezone/zic.c:1858
+msgid "too many transition times"
+msgstr "för många övergångstider"
-#: timezone/zic.c:1918
+#: timezone/zic.c:2047
#, c-format
msgid "%%z UTC offset magnitude exceeds 99:59:59"
msgstr "%%z storleken på avståndet från UTC överstiger 99.59.59"
-#: timezone/zic.c:2291
+#: timezone/zic.c:2424
msgid "no POSIX environment variable for zone"
msgstr "ingen POSIX-miljövariabel för zon"
-#: timezone/zic.c:2297
+#: timezone/zic.c:2430
#, c-format
msgid "%s: pre-%d clients may mishandle distant timestamps"
msgstr "%s: klienter före %d kan hantera avlägsna tidsstämplar felaktigt"
-#: timezone/zic.c:2428
+#: timezone/zic.c:2566
msgid "two rules for same instant"
msgstr "två regler för samma tillfälle"
-#: timezone/zic.c:2485
+#: timezone/zic.c:2627
msgid "can't determine time zone abbreviation to use just after until time"
msgstr "kan inte avgöra tidszonsförkortning att använda just efter \"until\"-tid"
-#: timezone/zic.c:2531 timezone/zic.c:2593
+#: timezone/zic.c:2725
msgid "too many local time types"
msgstr "för många lokala tidstyper"
-#: timezone/zic.c:2597
+#: timezone/zic.c:2729
msgid "UT offset out of range"
msgstr "UT-offset utanför giltigt intervall"
-#: timezone/zic.c:2621
+#: timezone/zic.c:2753
msgid "too many leap seconds"
msgstr "för många skottsekunder"
-#: timezone/zic.c:2627
+#: timezone/zic.c:2759
msgid "repeated leap second moment"
msgstr "upprepat skottsekundstillfälle"
-#: timezone/zic.c:2677
+#: timezone/zic.c:2830
msgid "Wild result from command execution"
msgstr "Vilt resultat från kommandokörning"
-#: timezone/zic.c:2678
+#: timezone/zic.c:2831
#, c-format
msgid "%s: command was '%s', result was %d\n"
msgstr "%s: kommandot var \"%s\", resultatet blev %d\n"
-#: timezone/zic.c:2810
+#: timezone/zic.c:2961
msgid "Odd number of quotation marks"
msgstr "Ojämnt antal citationstecken"
-#: timezone/zic.c:2896
+#: timezone/zic.c:3046
msgid "use of 2/29 in non leap-year"
msgstr "använder 29/2 i icke-skottår"
-#: timezone/zic.c:2931
+#: timezone/zic.c:3081
msgid "rule goes past start/end of month; will not work with pre-2004 versions of zic"
msgstr "regeln går utanför start/slut på månad; fungerar inte med versioner av zic före 2004"
-#: timezone/zic.c:2958
+#: timezone/zic.c:3108
msgid "time zone abbreviation has fewer than 3 characters"
msgstr "tidszonsförkortning har färre än 3 tecken"
-#: timezone/zic.c:2960
+#: timezone/zic.c:3110
msgid "time zone abbreviation has too many characters"
msgstr "tidszonsförkortning har för många tecken"
-#: timezone/zic.c:2962
+#: timezone/zic.c:3112
msgid "time zone abbreviation differs from POSIX standard"
msgstr "tidszonsförkortning skiljer sig från POSIX-standarden"
-#: timezone/zic.c:2968
+#: timezone/zic.c:3118
msgid "too many, or too long, time zone abbreviations"
msgstr "för många eller för långa tidszonsförkortningar"
-#: timezone/zic.c:3004
+#: timezone/zic.c:3161
#, c-format
msgid "%s: Can't create directory %s: %s"
msgstr "%s: Kan inte skapa katalog %s: %s"
diff --git a/posix/Makefile b/posix/Makefile
index 33abcaed7a..d35b7921b1 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -45,7 +45,7 @@ routines := \
getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \
getresuid getresgid setresuid setresgid \
pathconf sysconf fpathconf \
- glob glob64 fnmatch regex \
+ glob glob64 globfree globfree64 glob_pattern_p fnmatch regex \
confstr \
getopt getopt1 \
sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \
@@ -93,7 +93,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \
tst-fnmatch3 bug-regex36 tst-getaddrinfo5 \
tst-posix_spawn-fd tst-posix_spawn-setsid \
tst-posix_fadvise tst-posix_fadvise64 \
- tst-sysconf-empty-chroot
+ tst-sysconf-empty-chroot tst-glob-tilde
tests-internal := bug-regex5 bug-regex20 bug-regex33 \
tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3
xtests := bug-ga2
@@ -141,7 +141,8 @@ tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
$(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
$(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
$(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
- $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
+ $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out \
+ $(objpfx)tst-glob-tilde-mem.out
xtests-special += $(objpfx)bug-ga2-mem.out
endif
@@ -350,6 +351,12 @@ $(objpfx)bug-glob2-mem.out: $(objpfx)bug-glob2.out
$(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \
$(evaluate-test)
+tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace
+
+$(objpfx)tst-glob-tilde-mem.out: $(objpfx)tst-glob-tilde.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-glob-tilde.mtrace > $@; \
+ $(evaluate-test)
+
$(inst_libexecdir)/getconf: $(inst_bindir)/getconf \
$(objpfx)getconf.speclist FORCE
$(addprefix $(..)./scripts/mkinstalldirs ,\
diff --git a/posix/flexmember.h b/posix/flexmember.h
new file mode 100644
index 0000000000..107c1f09e9
--- /dev/null
+++ b/posix/flexmember.h
@@ -0,0 +1,45 @@
+/* Sizes of structs with flexible array members.
+
+ Copyright 2016-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>.
+
+ Written by Paul Eggert. */
+
+#include <stddef.h>
+
+/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below.
+ On older platforms without _Alignof, use a pessimistic bound that is
+ safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1.
+ On newer platforms, use _Alignof to get a tighter bound. */
+
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
+# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1))
+#else
+# define FLEXALIGNOF(type) _Alignof (type)
+#endif
+
+/* Upper bound on the size of a struct of type TYPE with a flexible
+ array member named MEMBER that is followed by N bytes of other data.
+ This is not simply sizeof (TYPE) + N, since it may require
+ alignment on unusually picky C11 platforms, and
+ FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms.
+ Yield a value less than N if and only if arithmetic overflow occurs. */
+
+#define FLEXSIZEOF(type, member, n) \
+ ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \
+ & ~ (FLEXALIGNOF (type) - 1))
diff --git a/posix/glob.c b/posix/glob.c
index c653809118..b2273ea7bc 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -15,7 +15,7 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#ifdef HAVE_CONFIG_H
+#ifndef _LIBC
# include <config.h>
#endif
@@ -27,29 +27,15 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-
-/* Outcomment the following line for production quality code. */
-/* #define NDEBUG 1 */
#include <assert.h>
+#include <unistd.h>
-#include <stdio.h> /* Needed on stupid SunOS for assert. */
-
-#if !defined _LIBC || !defined GLOB_ONLY_P
-#if defined HAVE_UNISTD_H || defined _LIBC
-# include <unistd.h>
-# ifndef POSIX
-# ifdef _POSIX_VERSION
-# define POSIX
-# endif
-# endif
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# define WINDOWS32
#endif
-#include <pwd.h>
-
-#if defined HAVE_STDINT_H || defined _LIBC
-# include <stdint.h>
-#elif !defined UINTPTR_MAX
-# define UINTPTR_MAX (~((size_t) 0))
+#ifndef WINDOWS32
+# include <pwd.h>
#endif
#include <errno.h>
@@ -57,24 +43,7 @@
# define __set_errno(val) errno = (val)
#endif
-#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
-# include <dirent.h>
-#else
-# define dirent direct
-# ifdef HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# ifdef HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# ifdef HAVE_NDIR_H
-# include <ndir.h>
-# endif
-# ifdef HAVE_VMSDIR_H
-# include "vmsdir.h"
-# endif /* HAVE_VMSDIR_H */
-#endif
-
+#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
@@ -87,27 +56,29 @@
# define opendir(name) __opendir (name)
# define readdir(str) __readdir64 (str)
# define getpwnam_r(name, bufp, buf, len, res) \
- __getpwnam_r (name, bufp, buf, len, res)
+ __getpwnam_r (name, bufp, buf, len, res)
# ifndef __stat64
# define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
# endif
# define struct_stat64 struct stat64
+# define FLEXIBLE_ARRAY_MEMBER
#else /* !_LIBC */
-# include "getlogin_r.h"
-# include "mempcpy.h"
-# include "stat-macros.h"
-# include "strdup.h"
-# define __stat64(fname, buf) stat (fname, buf)
-# define struct_stat64 struct stat
-# define __stat(fname, buf) stat (fname, buf)
-# define __alloca alloca
-# define __readdir readdir
-# define __readdir64 readdir64
-# define __glob_pattern_p glob_pattern_p
+# define __getlogin_r(buf, len) getlogin_r (buf, len)
+# define __stat64(fname, buf) stat (fname, buf)
+# define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
+# define struct_stat64 struct stat
+# ifndef __MVS__
+# define __alloca alloca
+# endif
+# define __readdir readdir
+# define COMPILE_GLOB64
#endif /* _LIBC */
#include <fnmatch.h>
+#include <flexmember.h>
+#include <glob_internal.h>
+
#ifdef _SC_GETPW_R_SIZE_MAX
# define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX)
#else
@@ -121,61 +92,59 @@
static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
+typedef uint_fast8_t dirent_type;
+
+#if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
+/* Any distinct values will do here.
+ Undef any existing macros out of the way. */
+# undef DT_UNKNOWN
+# undef DT_DIR
+# undef DT_LNK
+# define DT_UNKNOWN 0
+# define DT_DIR 1
+# define DT_LNK 2
+#endif
+
/* A representation of a directory entry which does not depend on the
layout of struct dirent, or the size of ino_t. */
struct readdir_result
{
const char *name;
-# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
- uint8_t type;
-# endif
+#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
+ dirent_type type;
+#endif
+#if defined _LIBC || defined D_INO_IN_DIRENT
bool skip_entry;
+#endif
};
-# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
-/* Initializer based on the d_type member of struct dirent. */
-# define D_TYPE_TO_RESULT(source) (source)->d_type,
-
-/* True if the directory entry D might be a symbolic link. */
-static bool
-readdir_result_might_be_symlink (struct readdir_result d)
-{
- return d.type == DT_UNKNOWN || d.type == DT_LNK;
-}
-
-/* True if the directory entry D might be a directory. */
-static bool
-readdir_result_might_be_dir (struct readdir_result d)
-{
- return d.type == DT_DIR || readdir_result_might_be_symlink (d);
-}
-# else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
-# define D_TYPE_TO_RESULT(source)
-
-/* If we do not have type information, symbolic links and directories
- are always a possibility. */
-
-static bool
-readdir_result_might_be_symlink (struct readdir_result d)
+/* Initialize and return type member of struct readdir_result. */
+static dirent_type
+readdir_result_type (struct readdir_result d)
{
- return true;
+#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
+# define D_TYPE_TO_RESULT(source) (source)->d_type,
+ return d.type;
+#else
+# define D_TYPE_TO_RESULT(source)
+ return DT_UNKNOWN;
+#endif
}
+/* Initialize and return skip_entry member of struct readdir_result. */
static bool
-readdir_result_might_be_dir (struct readdir_result d)
+readdir_result_skip_entry (struct readdir_result d)
{
- return true;
-}
-
-# endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
-
-# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
/* Initializer for skip_entry. POSIX does not require that the d_ino
field be present, and some systems do not provide it. */
-# define D_INO_TO_RESULT(source) false,
-# else
-# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
-# endif
+#if defined _LIBC || defined D_INO_IN_DIRENT
+# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
+ return d.skip_entry;
+#else
+# define D_INO_TO_RESULT(source)
+ return false;
+#endif
+}
/* Construct an initializer for a struct readdir_result object from a
struct dirent *. No copy of the name is made. */
@@ -186,8 +155,6 @@ readdir_result_might_be_dir (struct readdir_result d)
D_INO_TO_RESULT (source) \
}
-#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
-
/* Call gl_readdir on STREAM. This macro can be overridden to reduce
type safety if an old interface version needs to be supported. */
#ifndef GL_READDIR
@@ -225,18 +192,55 @@ convert_dirent64 (const struct dirent64 *source)
}
#endif
+#ifndef _LIBC
+/* The results of opendir() in this file are not used with dirfd and fchdir,
+ and we do not leak fds to any single-threaded code that could use stdio,
+ therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
+ FIXME - if the kernel ever adds support for multi-thread safety for
+ avoiding standard fds, then we should use opendir_safer. */
+# ifdef GNULIB_defined_opendir
+# undef opendir
+# endif
+# ifdef GNULIB_defined_closedir
+# undef closedir
+# endif
-#ifndef attribute_hidden
-# define attribute_hidden
+/* Just use malloc. */
+# define __libc_use_alloca(n) false
+# define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
+# define extend_alloca_account(buf, len, newlen, avar) \
+ ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
#endif
+/* Set *R = A + B. Return true if the answer is mathematically
+ incorrect due to overflow; in this case, *R is the low order
+ bits of the correct answer. */
+
+static bool
+size_add_wrapv (size_t a, size_t b, size_t *r)
+{
+#if 5 <= __GNUC__ && !defined __ICC
+ return __builtin_add_overflow (a, b, r);
+#else
+ *r = a + b;
+ return *r < a;
+#endif
+}
+
+static bool
+glob_use_alloca (size_t alloca_used, size_t len)
+{
+ size_t size;
+ return (!size_add_wrapv (alloca_used, len, &size)
+ && __libc_use_alloca (size));
+}
+
static int glob_in_dir (const char *pattern, const char *directory,
int flags, int (*errfunc) (const char *, int),
glob_t *pglob, size_t alloca_used);
extern int __glob_pattern_type (const char *pattern, int quote)
attribute_hidden;
-#if !defined _LIBC || !defined GLOB_ONLY_P
static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
static int collated_compare (const void *, const void *) __THROWNL;
@@ -265,16 +269,15 @@ next_brace_sub (const char *cp, int flags)
return *cp != '\0' ? cp : NULL;
}
-#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
/* Do glob searching for PATTERN, placing results in PGLOB.
The bits defined above may be set in FLAGS.
If a directory cannot be opened or read and ERRFUNC is not nil,
it is called with the pathname that caused the error, and the
- `errno' value from the failing call; if it returns non-zero
- `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
+ 'errno' value from the failing call; if it returns non-zero
+ 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
- Otherwise, `glob' returns zero. */
+ Otherwise, 'glob' returns zero. */
int
#ifdef GLOB_ATTRIBUTE
GLOB_ATTRIBUTE
@@ -292,9 +295,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
int malloc_dirname = 0;
glob_t dirs;
int retval = 0;
-#ifdef _LIBC
size_t alloca_used = 0;
-#endif
if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
{
@@ -308,7 +309,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
flags |= GLOB_ONLYDIR;
if (!(flags & GLOB_DOOFFS))
- /* Have to do this so `globfree' knows where to start freeing. It
+ /* Have to do this so 'globfree' knows where to start freeing. It
also makes all the code that uses gl_offs simpler. */
pglob->gl_offs = 0;
@@ -372,14 +373,12 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
size_t rest_len;
char *onealt;
size_t pattern_len = strlen (pattern) - 1;
-#ifdef _LIBC
- int alloca_onealt = __libc_use_alloca (alloca_used + pattern_len);
+ int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
if (alloca_onealt)
onealt = alloca_account (pattern_len, alloca_used);
else
-#endif
{
- onealt = (char *) malloc (pattern_len);
+ onealt = malloc (pattern_len);
if (onealt == NULL)
return GLOB_NOSPACE;
}
@@ -392,11 +391,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
next = next_brace_sub (begin + 1, flags);
if (next == NULL)
{
- /* It is an illegal expression. */
+ /* It is an invalid expression. */
illegal_brace:
-#ifdef _LIBC
if (__glibc_unlikely (!alloca_onealt))
-#endif
free (onealt);
flags &= ~GLOB_BRACE;
goto no_brace;
@@ -437,9 +434,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
/* If we got an error, return it. */
if (result && result != GLOB_NOMATCH)
{
-#ifdef _LIBC
if (__glibc_unlikely (!alloca_onealt))
-#endif
free (onealt);
if (!(flags & GLOB_APPEND))
{
@@ -458,9 +453,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
assert (next != NULL);
}
-#ifdef _LIBC
if (__glibc_unlikely (!alloca_onealt))
-#endif
free (onealt);
if (pglob->gl_pathc != firstc)
@@ -476,14 +469,16 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
/* Find the filename. */
filename = strrchr (pattern, '/');
+
#if defined __MSDOS__ || defined WINDOWS32
- /* The case of "d:pattern". Since `:' is not allowed in
+ /* The case of "d:pattern". Since ':' is not allowed in
file names, we can safely assume that wherever it
happens in pattern, it signals the filename part. This
is so we could some day support patterns like "[a-z]:foo". */
if (filename == NULL)
filename = strchr (pattern, ':');
#endif /* __MSDOS__ || WINDOWS32 */
+
dirname_modified = 0;
if (filename == NULL)
{
@@ -508,11 +503,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
}
filename = pattern;
-#ifdef _AMIGA
- dirname = (char *) "";
-#else
dirname = (char *) ".";
-#endif
dirlen = 0;
}
}
@@ -536,22 +527,21 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
char *drive_spec;
++dirlen;
- drive_spec = (char *) __alloca (dirlen + 1);
+ drive_spec = __alloca (dirlen + 1);
*((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
/* For now, disallow wildcards in the drive spec, to
prevent infinite recursion in glob. */
if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
return GLOB_NOMATCH;
- /* If this is "d:pattern", we need to copy `:' to DIRNAME
+ /* If this is "d:pattern", we need to copy ':' to DIRNAME
as well. If it's "d:/pattern", don't remove the slash
from "d:/", since "d:" and "d:/" are not the same.*/
}
#endif
-#ifdef _LIBC
- if (__libc_use_alloca (alloca_used + dirlen + 1))
+
+ if (glob_use_alloca (alloca_used, dirlen + 1))
newp = alloca_account (dirlen + 1, alloca_used);
else
-#endif
{
newp = malloc (dirlen + 1);
if (newp == NULL)
@@ -562,14 +552,17 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
dirname = newp;
++filename;
- if (filename[0] == '\0'
#if defined __MSDOS__ || defined WINDOWS32
- && dirname[dirlen - 1] != ':'
- && (dirlen < 3 || dirname[dirlen - 2] != ':'
- || dirname[dirlen - 1] != '/')
+ bool drive_root = (dirlen > 1
+ && (dirname[dirlen - 1] == ':'
+ || (dirlen > 2 && dirname[dirlen - 2] == ':'
+ && dirname[dirlen - 1] == '/')));
+#else
+ bool drive_root = false;
#endif
- && dirlen > 1)
- /* "pattern/". Expand "pattern", appending slashes. */
+
+ if (filename[0] == '\0' && dirlen > 1 && !drive_root)
+ /* "pattern/". Expand "pattern", appending slashes. */
{
int orig_flags = flags;
if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
@@ -602,7 +595,6 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
}
}
-#ifndef VMS
if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
{
if (dirname[1] == '\0' || dirname[1] == '/'
@@ -612,100 +604,127 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
/* Look up home directory. */
char *home_dir = getenv ("HOME");
int malloc_home_dir = 0;
-# ifdef _AMIGA
- if (home_dir == NULL || home_dir[0] == '\0')
- home_dir = "SYS:";
-# else
-# ifdef WINDOWS32
- if (home_dir == NULL || home_dir[0] == '\0')
- home_dir = "c:/users/default"; /* poor default */
-# else
if (home_dir == NULL || home_dir[0] == '\0')
{
+#ifdef WINDOWS32
+ /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
+ preference to HOME, because the user can change HOME. */
+ const char *home_drive = getenv ("HOMEDRIVE");
+ const char *home_path = getenv ("HOMEPATH");
+
+ if (home_drive != NULL && home_path != NULL)
+ {
+ size_t home_drive_len = strlen (home_drive);
+ size_t home_path_len = strlen (home_path);
+ char *mem = alloca (home_drive_len + home_path_len + 1);
+
+ memcpy (mem, home_drive, home_drive_len);
+ memcpy (mem + home_drive_len, home_path, home_path_len + 1);
+ home_dir = mem;
+ }
+ else
+ home_dir = "c:/users/default"; /* poor default */
+#else
int success;
char *name;
+ int malloc_name = 0;
size_t buflen = GET_LOGIN_NAME_MAX () + 1;
if (buflen == 0)
- /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
+ /* 'sysconf' does not support _SC_LOGIN_NAME_MAX. Try
a moderate value. */
buflen = 20;
- name = alloca_account (buflen, alloca_used);
+ if (glob_use_alloca (alloca_used, buflen))
+ name = alloca_account (buflen, alloca_used);
+ else
+ {
+ name = malloc (buflen);
+ if (name == NULL)
+ {
+ retval = GLOB_NOSPACE;
+ goto out;
+ }
+ malloc_name = 1;
+ }
success = __getlogin_r (name, buflen) == 0;
if (success)
{
struct passwd *p;
-# if defined HAVE_GETPWNAM_R || defined _LIBC
- long int pwbuflen = GETPW_R_SIZE_MAX ();
+ char *malloc_pwtmpbuf = NULL;
char *pwtmpbuf;
+# if defined HAVE_GETPWNAM_R || defined _LIBC
+ long int pwbuflenmax = GETPW_R_SIZE_MAX ();
+ size_t pwbuflen = pwbuflenmax;
struct passwd pwbuf;
- int malloc_pwtmpbuf = 0;
int save = errno;
-# ifndef _LIBC
- if (pwbuflen == -1)
- /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
+# ifndef _LIBC
+ if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX))
+ /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.
Try a moderate value. */
pwbuflen = 1024;
-# endif
- if (__libc_use_alloca (alloca_used + pwbuflen))
+# endif
+ if (glob_use_alloca (alloca_used, pwbuflen))
pwtmpbuf = alloca_account (pwbuflen, alloca_used);
else
{
pwtmpbuf = malloc (pwbuflen);
if (pwtmpbuf == NULL)
{
+ if (__glibc_unlikely (malloc_name))
+ free (name);
retval = GLOB_NOSPACE;
goto out;
}
- malloc_pwtmpbuf = 1;
+ malloc_pwtmpbuf = pwtmpbuf;
}
while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
!= 0)
{
+ size_t newlen;
+ bool v;
if (errno != ERANGE)
{
p = NULL;
break;
}
-
- if (!malloc_pwtmpbuf
- && __libc_use_alloca (alloca_used
- + 2 * pwbuflen))
+ v = size_add_wrapv (pwbuflen, pwbuflen, &newlen);
+ if (!v && malloc_pwtmpbuf == NULL
+ && glob_use_alloca (alloca_used, newlen))
pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen,
- 2 * pwbuflen,
- alloca_used);
+ newlen, alloca_used);
else
{
- char *newp = realloc (malloc_pwtmpbuf
- ? pwtmpbuf : NULL,
- 2 * pwbuflen);
+ char *newp = (v ? NULL
+ : realloc (malloc_pwtmpbuf, newlen));
if (newp == NULL)
{
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ free (malloc_pwtmpbuf);
+ if (__glibc_unlikely (malloc_name))
+ free (name);
retval = GLOB_NOSPACE;
goto out;
}
- pwtmpbuf = newp;
- pwbuflen = 2 * pwbuflen;
- malloc_pwtmpbuf = 1;
+ malloc_pwtmpbuf = pwtmpbuf = newp;
}
+ pwbuflen = newlen;
__set_errno (save);
}
-# else
+# else
p = getpwnam (name);
-# endif
+# endif
+ if (__glibc_unlikely (malloc_name))
+ free (name);
if (p != NULL)
{
- if (!malloc_pwtmpbuf)
+ if (malloc_pwtmpbuf == NULL)
home_dir = p->pw_dir;
else
{
size_t home_dir_len = strlen (p->pw_dir) + 1;
- if (__libc_use_alloca (alloca_used + home_dir_len))
+ if (glob_use_alloca (alloca_used, home_dir_len))
home_dir = alloca_account (home_dir_len,
alloca_used);
else
@@ -720,26 +739,32 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
malloc_home_dir = 1;
}
memcpy (home_dir, p->pw_dir, home_dir_len);
-
- free (pwtmpbuf);
}
}
+ free (malloc_pwtmpbuf);
}
+ else
+ {
+ if (__glibc_unlikely (malloc_name))
+ free (name);
+ }
+#endif /* WINDOWS32 */
}
if (home_dir == NULL || home_dir[0] == '\0')
{
+ if (__glibc_unlikely (malloc_home_dir))
+ free (home_dir);
if (flags & GLOB_TILDE_CHECK)
{
- if (__glibc_unlikely (malloc_home_dir))
- free (home_dir);
retval = GLOB_NOMATCH;
goto out;
}
else
- home_dir = (char *) "~"; /* No luck. */
+ {
+ home_dir = (char *) "~"; /* No luck. */
+ malloc_home_dir = 0;
+ }
}
-# endif /* WINDOWS32 */
-# endif
/* Now construct the full directory. */
if (dirname[1] == '\0')
{
@@ -754,8 +779,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
{
char *newp;
size_t home_len = strlen (home_dir);
- int use_alloca = __libc_use_alloca (alloca_used
- + home_len + dirlen);
+ int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
if (use_alloca)
newp = alloca_account (home_len + dirlen, alloca_used);
else
@@ -779,12 +803,15 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
dirname = newp;
dirlen += home_len - 1;
malloc_dirname = !use_alloca;
+
+ if (__glibc_unlikely (malloc_home_dir))
+ free (home_dir);
}
dirname_modified = 1;
}
-# if !defined _AMIGA && !defined WINDOWS32
else
{
+#ifndef WINDOWS32
char *end_name = strchr (dirname, '/');
char *user_name;
int malloc_user_name = 0;
@@ -806,7 +833,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
else
{
char *newp;
- if (__libc_use_alloca (alloca_used + (end_name - dirname)))
+ if (glob_use_alloca (alloca_used, end_name - dirname))
newp = alloca_account (end_name - dirname, alloca_used);
else
{
@@ -823,11 +850,11 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
char *p = mempcpy (newp, dirname + 1,
unescape - dirname - 1);
char *q = unescape;
- while (*q != '\0')
+ while (q != end_name)
{
if (*q == '\\')
{
- if (q[1] == '\0')
+ if (q + 1 == end_name)
{
/* "~fo\\o\\" unescape to user_name "foo\\",
but "~fo\\o\\/" unescape to user_name
@@ -843,7 +870,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
*p = '\0';
}
else
- *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
+ *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
= '\0';
user_name = newp;
}
@@ -851,20 +878,21 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
/* Look up specific user's home directory. */
{
struct passwd *p;
+ char *malloc_pwtmpbuf = NULL;
# if defined HAVE_GETPWNAM_R || defined _LIBC
- long int buflen = GETPW_R_SIZE_MAX ();
+ long int buflenmax = GETPW_R_SIZE_MAX ();
+ size_t buflen = buflenmax;
char *pwtmpbuf;
- int malloc_pwtmpbuf = 0;
struct passwd pwbuf;
int save = errno;
# ifndef _LIBC
- if (buflen == -1)
- /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
+ if (! (0 <= buflenmax && buflenmax <= SIZE_MAX))
+ /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
moderate value. */
buflen = 1024;
# endif
- if (__libc_use_alloca (alloca_used + buflen))
+ if (glob_use_alloca (alloca_used, buflen))
pwtmpbuf = alloca_account (buflen, alloca_used);
else
{
@@ -877,32 +905,32 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
retval = GLOB_NOSPACE;
goto out;
}
- malloc_pwtmpbuf = 1;
+ malloc_pwtmpbuf = pwtmpbuf;
}
while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
{
+ size_t newlen;
+ bool v;
if (errno != ERANGE)
{
p = NULL;
break;
}
- if (!malloc_pwtmpbuf
- && __libc_use_alloca (alloca_used + 2 * buflen))
+ v = size_add_wrapv (buflen, buflen, &newlen);
+ if (!v && malloc_pwtmpbuf == NULL
+ && glob_use_alloca (alloca_used, newlen))
pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen,
- 2 * buflen, alloca_used);
+ newlen, alloca_used);
else
{
- char *newp = realloc (malloc_pwtmpbuf ? pwtmpbuf : NULL,
- 2 * buflen);
+ char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen);
if (newp == NULL)
{
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ free (malloc_pwtmpbuf);
goto nomem_getpw;
}
- pwtmpbuf = newp;
- malloc_pwtmpbuf = 1;
+ malloc_pwtmpbuf = pwtmpbuf = newp;
}
__set_errno (save);
}
@@ -923,7 +951,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
free (dirname);
malloc_dirname = 0;
- if (__libc_use_alloca (alloca_used + home_len + rest_len + 1))
+ if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
dirname = alloca_account (home_len + rest_len + 1,
alloca_used);
else
@@ -931,8 +959,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
dirname = malloc (home_len + rest_len + 1);
if (dirname == NULL)
{
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ free (malloc_pwtmpbuf);
retval = GLOB_NOSPACE;
goto out;
}
@@ -944,24 +971,24 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
dirlen = home_len + rest_len;
dirname_modified = 1;
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ free (malloc_pwtmpbuf);
}
else
{
- if (__glibc_unlikely (malloc_pwtmpbuf))
- free (pwtmpbuf);
+ free (malloc_pwtmpbuf);
if (flags & GLOB_TILDE_CHECK)
- /* We have to regard it as an error if we cannot find the
- home directory. */
- return GLOB_NOMATCH;
+ {
+ /* We have to regard it as an error if we cannot find the
+ home directory. */
+ retval = GLOB_NOMATCH;
+ goto out;
+ }
}
}
+#endif /* !WINDOWS32 */
}
-# endif /* Not Amiga && not WINDOWS32. */
}
-#endif /* Not VMS. */
/* Now test whether we looked for "~" or "~NAME". In this case we
can give the answer now. */
@@ -980,19 +1007,18 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
size_t newcount = pglob->gl_pathc + pglob->gl_offs;
char **new_gl_pathv;
- if (newcount > UINTPTR_MAX - (1 + 1)
- || newcount + 1 + 1 > ~((size_t) 0) / sizeof (char *))
+ if (newcount > SIZE_MAX / sizeof (char *) - 2)
{
nospace:
free (pglob->gl_pathv);
pglob->gl_pathv = NULL;
pglob->gl_pathc = 0;
- return GLOB_NOSPACE;
+ retval = GLOB_NOSPACE;
+ goto out;
}
- new_gl_pathv
- = (char **) realloc (pglob->gl_pathv,
- (newcount + 1 + 1) * sizeof (char *));
+ new_gl_pathv = realloc (pglob->gl_pathv,
+ (newcount + 2) * sizeof (char *));
if (new_gl_pathv == NULL)
goto nospace;
pglob->gl_pathv = new_gl_pathv;
@@ -1006,12 +1032,19 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
p[0] = '/';
p[1] = '\0';
+ if (__glibc_unlikely (malloc_dirname))
+ free (dirname);
}
else
{
- pglob->gl_pathv[newcount] = strdup (dirname);
- if (pglob->gl_pathv[newcount] == NULL)
- goto nospace;
+ if (__glibc_unlikely (malloc_dirname))
+ pglob->gl_pathv[newcount] = dirname;
+ else
+ {
+ pglob->gl_pathv[newcount] = strdup (dirname);
+ if (pglob->gl_pathv[newcount] == NULL)
+ goto nospace;
+ }
}
pglob->gl_pathv[++newcount] = NULL;
++pglob->gl_pathc;
@@ -1021,7 +1054,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
}
/* Not found. */
- return GLOB_NOMATCH;
+ retval = GLOB_NOMATCH;
+ goto out;
}
meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
@@ -1067,7 +1101,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
if (status != 0)
{
if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
- return status;
+ {
+ retval = status;
+ goto out;
+ }
goto no_matches;
}
@@ -1078,19 +1115,6 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
{
size_t old_pathc;
-#ifdef SHELL
- {
- /* Make globbing interruptible in the bash shell. */
- extern int interrupt_state;
-
- if (interrupt_state)
- {
- globfree (&dirs);
- return GLOB_ABORTED;
- }
- }
-#endif /* SHELL. */
-
old_pathc = pglob->gl_pathc;
status = glob_in_dir (filename, dirs.gl_pathv[i],
((flags | GLOB_APPEND)
@@ -1105,7 +1129,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
globfree (&dirs);
globfree (pglob);
pglob->gl_pathc = 0;
- return status;
+ retval = status;
+ goto out;
}
/* Stick the directory on the front of each name. */
@@ -1116,13 +1141,14 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
globfree (&dirs);
globfree (pglob);
pglob->gl_pathc = 0;
- return GLOB_NOSPACE;
+ retval = GLOB_NOSPACE;
+ goto out;
}
}
flags |= GLOB_MAGCHAR;
- /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
+ /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
But if we have not found any matching entry and the GLOB_NOCHECK
flag was set we must return the input pattern itself. */
if (pglob->gl_pathc + pglob->gl_offs == oldcount)
@@ -1134,28 +1160,28 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
size_t newcount = pglob->gl_pathc + pglob->gl_offs;
char **new_gl_pathv;
- if (newcount > UINTPTR_MAX - 2
- || newcount + 2 > ~((size_t) 0) / sizeof (char *))
+ if (newcount > SIZE_MAX / sizeof (char *) - 2)
{
nospace2:
globfree (&dirs);
- return GLOB_NOSPACE;
+ retval = GLOB_NOSPACE;
+ goto out;
}
- new_gl_pathv = (char **) realloc (pglob->gl_pathv,
- (newcount + 2)
- * sizeof (char *));
+ new_gl_pathv = realloc (pglob->gl_pathv,
+ (newcount + 2) * sizeof (char *));
if (new_gl_pathv == NULL)
goto nospace2;
pglob->gl_pathv = new_gl_pathv;
- pglob->gl_pathv[newcount] = __strdup (pattern);
+ pglob->gl_pathv[newcount] = strdup (pattern);
if (pglob->gl_pathv[newcount] == NULL)
{
globfree (&dirs);
globfree (pglob);
pglob->gl_pathc = 0;
- return GLOB_NOSPACE;
+ retval = GLOB_NOSPACE;
+ goto out;
}
++pglob->gl_pathc;
@@ -1167,7 +1193,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
else
{
globfree (&dirs);
- return GLOB_NOMATCH;
+ retval = GLOB_NOMATCH;
+ goto out;
}
}
@@ -1213,7 +1240,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
flags = orig_flags;
goto no_matches;
}
- return status;
+ retval = status;
+ goto out;
}
if (dirlen > 0)
@@ -1225,7 +1253,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
{
globfree (pglob);
pglob->gl_pathc = 0;
- return GLOB_NOSPACE;
+ retval = GLOB_NOSPACE;
+ goto out;
}
}
}
@@ -1250,7 +1279,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
{
globfree (pglob);
pglob->gl_pathc = 0;
- return GLOB_NOSPACE;
+ retval = GLOB_NOSPACE;
+ goto out;
}
strcpy (&new[len - 2], "/");
pglob->gl_pathv[i] = new;
@@ -1276,32 +1306,12 @@ libc_hidden_def (glob)
#endif
-#if !defined _LIBC || !defined GLOB_ONLY_P
-
-/* Free storage allocated in PGLOB by a previous `glob' call. */
-void
-globfree (glob_t *pglob)
-{
- if (pglob->gl_pathv != NULL)
- {
- size_t i;
- for (i = 0; i < pglob->gl_pathc; ++i)
- free (pglob->gl_pathv[pglob->gl_offs + i]);
- free (pglob->gl_pathv);
- pglob->gl_pathv = NULL;
- }
-}
-#if defined _LIBC && !defined globfree
-libc_hidden_def (globfree)
-#endif
-
-
/* Do a collated comparison of A and B. */
static int
collated_compare (const void *a, const void *b)
{
- const char *const s1 = *(const char *const * const) a;
- const char *const s2 = *(const char *const * const) b;
+ char *const *ps1 = a; char *s1 = *ps1;
+ char *const *ps2 = b; char *s2 = *ps2;
if (s1 == s2)
return 0;
@@ -1322,28 +1332,24 @@ prefix_array (const char *dirname, char **array, size_t n)
{
size_t i;
size_t dirlen = strlen (dirname);
-#if defined __MSDOS__ || defined WINDOWS32
- int sep_char = '/';
-# define DIRSEP_CHAR sep_char
-#else
-# define DIRSEP_CHAR '/'
-#endif
+ char dirsep_char = '/';
if (dirlen == 1 && dirname[0] == '/')
/* DIRNAME is just "/", so normal prepending would get us "//foo".
We want "/foo" instead, so don't prepend any chars from DIRNAME. */
dirlen = 0;
+
#if defined __MSDOS__ || defined WINDOWS32
- else if (dirlen > 1)
+ if (dirlen > 1)
{
if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
/* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
--dirlen;
else if (dirname[dirlen - 1] == ':')
{
- /* DIRNAME is "d:". Use `:' instead of `/'. */
+ /* DIRNAME is "d:". Use ':' instead of '/'. */
--dirlen;
- sep_char = ':';
+ dirsep_char = ':';
}
}
#endif
@@ -1351,7 +1357,7 @@ prefix_array (const char *dirname, char **array, size_t n)
for (i = 0; i < n; ++i)
{
size_t eltlen = strlen (array[i]) + 1;
- char *new = (char *) malloc (dirlen + 1 + eltlen);
+ char *new = malloc (dirlen + 1 + eltlen);
if (new == NULL)
{
while (i > 0)
@@ -1361,7 +1367,7 @@ prefix_array (const char *dirname, char **array, size_t n)
{
char *endp = mempcpy (new, dirname, dirlen);
- *endp++ = DIRSEP_CHAR;
+ *endp++ = dirsep_char;
mempcpy (endp, array[i], eltlen);
}
free (array[i]);
@@ -1371,103 +1377,57 @@ prefix_array (const char *dirname, char **array, size_t n)
return 0;
}
-
-/* We must not compile this function twice. */
-#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
-int
-__glob_pattern_type (const char *pattern, int quote)
-{
- const char *p;
- int ret = 0;
-
- for (p = pattern; *p != '\0'; ++p)
- switch (*p)
- {
- case '?':
- case '*':
- return 1;
-
- case '\\':
- if (quote)
- {
- if (p[1] != '\0')
- ++p;
- ret |= 2;
- }
- break;
-
- case '[':
- ret |= 4;
- break;
-
- case ']':
- if (ret & 4)
- return 1;
- break;
- }
-
- return ret;
-}
-
-/* Return nonzero if PATTERN contains any metacharacters.
- Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
-int
-__glob_pattern_p (const char *pattern, int quote)
-{
- return __glob_pattern_type (pattern, quote) == 1;
-}
-# ifdef _LIBC
-weak_alias (__glob_pattern_p, glob_pattern_p)
-# endif
-#endif
-
-#endif /* !GLOB_ONLY_P */
-
-
/* We put this in a separate function mainly to allow the memory
allocated with alloca to be recycled. */
-#if !defined _LIBC || !defined GLOB_ONLY_P
static int
__attribute_noinline__
-link_exists2_p (const char *dir, size_t dirlen, const char *fname,
- glob_t *pglob
-# ifndef _LIBC
- , int flags
+link_stat (const char *dir, size_t dirlen, const char *fname,
+ glob_t *pglob
+# if !defined _LIBC && !HAVE_FSTATAT
+ , int flags
# endif
- )
+ )
{
size_t fnamelen = strlen (fname);
- char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1);
+ char *fullname = __alloca (dirlen + 1 + fnamelen + 1);
struct stat st;
-# ifndef _LIBC
- struct_stat64 st64;
-# endif
mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1),
fname, fnamelen + 1);
-# ifdef _LIBC
- return (*pglob->gl_stat) (fullname, &st) == 0;
-# else
- return ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
- ? (*pglob->gl_stat) (fullname, &st)
- : __stat64 (fullname, &st64)) == 0);
+# if !defined _LIBC && !HAVE_FSTATAT
+ if (__builtin_expect ((flags & GLOB_ALTDIRFUNC) == 0, 1))
+ {
+ struct_stat64 st64;
+ return __stat64 (fullname, &st64);
+ }
# endif
+ return (*pglob->gl_stat) (fullname, &st);
}
-# ifdef _LIBC
-# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \
- (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) \
- ? link_exists2_p (dirname, dirnamelen, fname, pglob) \
- : ({ struct stat64 st64; \
- __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0; }))
+
+/* Return true if DIR/FNAME exists. */
+static int
+link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname,
+ glob_t *pglob, int flags)
+{
+ int status;
+# if defined _LIBC || HAVE_FSTATAT
+ if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
+ status = link_stat (dir, dirlen, fname, pglob);
+ else
+ {
+ /* dfd cannot be -1 here, because dirfd never returns -1 on
+ glibc, or on hosts that have fstatat. */
+ struct_stat64 st64;
+ status = __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0);
+ }
# else
-# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \
- link_exists2_p (dirname, dirnamelen, fname, pglob, flags)
+ status = link_stat (dir, dirlen, fname, pglob, flags);
# endif
-#endif
-
+ return status == 0 || errno == EOVERFLOW;
+}
-/* Like `glob', but PATTERN is a final pathname component,
+/* Like 'glob', but PATTERN is a final pathname component,
and matches are searched for in DIRECTORY.
The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
The GLOB_APPEND flag is assumed to be set (always appends). */
@@ -1478,25 +1438,25 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
{
size_t dirlen = strlen (directory);
void *stream = NULL;
- struct globnames
- {
- struct globnames *next;
- size_t count;
- char *name[64];
- };
-#define INITIAL_COUNT sizeof (init_names.name) / sizeof (init_names.name[0])
- struct globnames init_names;
- struct globnames *names = &init_names;
- struct globnames *names_alloca = &init_names;
+# define GLOBNAMES_MEMBERS(nnames) \
+ struct globnames *next; size_t count; char *name[nnames];
+ struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
+ struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
+ struct globnames *init_names = (struct globnames *) &init_names_buf;
+ struct globnames *names = init_names;
+ struct globnames *names_alloca = init_names;
size_t nfound = 0;
size_t cur = 0;
int meta;
int save;
+ int result;
- alloca_used += sizeof (init_names);
+ alloca_used += sizeof init_names_buf;
- init_names.next = NULL;
- init_names.count = INITIAL_COUNT;
+ init_names->next = NULL;
+ init_names->count = ((sizeof init_names_buf
+ - offsetof (struct globnames, name))
+ / sizeof init_names->name[0]);
meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
@@ -1516,14 +1476,16 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
struct_stat64 st64;
} ust;
size_t patlen = strlen (pattern);
- int alloca_fullname = __libc_use_alloca (alloca_used
- + dirlen + 1 + patlen + 1);
+ size_t fullsize;
+ bool alloca_fullname
+ = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
+ && glob_use_alloca (alloca_used, fullsize));
char *fullname;
if (alloca_fullname)
- fullname = alloca_account (dirlen + 1 + patlen + 1, alloca_used);
+ fullname = alloca_account (fullsize, alloca_used);
else
{
- fullname = malloc (dirlen + 1 + patlen + 1);
+ fullname = malloc (fullsize);
if (fullname == NULL)
return GLOB_NOSPACE;
}
@@ -1531,9 +1493,11 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
"/", 1),
pattern, patlen + 1);
- if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
+ if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
? (*pglob->gl_stat) (fullname, &ust.st)
- : __stat64 (fullname, &ust.st64)) == 0)
+ : __stat64 (fullname, &ust.st64))
+ == 0)
+ || errno == EOVERFLOW)
/* We found this file to be existing. Now tell the rest
of the function to copy this name into the result. */
flags |= GLOB_NOCHECK;
@@ -1555,16 +1519,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
}
else
{
-#ifdef _LIBC
int dfd = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
? -1 : dirfd ((DIR *) stream));
-#endif
int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
- | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
-#if defined _AMIGA || defined VMS
- | FNM_CASEFOLD
-#endif
- );
+ | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
flags |= GLOB_MAGCHAR;
while (1)
@@ -1584,19 +1542,24 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
}
if (d.name == NULL)
break;
- if (d.skip_entry)
+ if (readdir_result_skip_entry (d))
continue;
/* If we shall match only directories use the information
provided by the dirent call if possible. */
- if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d))
- continue;
+ if (flags & GLOB_ONLYDIR)
+ switch (readdir_result_type (d))
+ {
+ case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
+ default: continue;
+ }
if (fnmatch (pattern, d.name, fnm_flags) == 0)
{
/* If the file we found is a symlink we have to
make sure the target file exists. */
- if (!readdir_result_might_be_symlink (d)
+ dirent_type type = readdir_result_type (d);
+ if (! (type == DT_LNK || type == DT_UNKNOWN)
|| link_exists_p (dfd, directory, dirlen, d.name,
pglob, flags))
{
@@ -1604,10 +1567,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
{
struct globnames *newnames;
size_t count = names->count * 2;
- size_t size = (sizeof (struct globnames)
- + ((count - INITIAL_COUNT)
- * sizeof (char *)));
- if (__libc_use_alloca (alloca_used + size))
+ size_t nameoff = offsetof (struct globnames, name);
+ size_t size = FLEXSIZEOF (struct globnames, name,
+ count * sizeof (char *));
+ if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
+ < names->count)
+ goto memory_error;
+ if (glob_use_alloca (alloca_used, size))
newnames = names_alloca
= alloca_account (size, alloca_used);
else if ((newnames = malloc (size))
@@ -1623,6 +1589,8 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
goto memory_error;
++cur;
++nfound;
+ if (SIZE_MAX - pglob->gl_offs <= nfound)
+ goto memory_error;
}
}
}
@@ -1633,29 +1601,27 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
{
size_t len = strlen (pattern);
nfound = 1;
- names->name[cur] = (char *) malloc (len + 1);
+ names->name[cur] = malloc (len + 1);
if (names->name[cur] == NULL)
goto memory_error;
*((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
}
- int result = GLOB_NOMATCH;
+ result = GLOB_NOMATCH;
if (nfound != 0)
{
+ char **new_gl_pathv;
result = 0;
- if (pglob->gl_pathc > UINTPTR_MAX - pglob->gl_offs
- || pglob->gl_pathc + pglob->gl_offs > UINTPTR_MAX - nfound
- || pglob->gl_pathc + pglob->gl_offs + nfound > UINTPTR_MAX - 1
- || (pglob->gl_pathc + pglob->gl_offs + nfound + 1
- > UINTPTR_MAX / sizeof (char *)))
+ if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
+ < pglob->gl_offs + nfound + 1)
goto memory_error;
- char **new_gl_pathv;
new_gl_pathv
- = (char **) realloc (pglob->gl_pathv,
- (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
- * sizeof (char *));
+ = realloc (pglob->gl_pathv,
+ (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
+ * sizeof (char *));
+
if (new_gl_pathv == NULL)
{
memory_error:
@@ -1671,7 +1637,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
and this is the block assigned to OLD here. */
if (names == NULL)
{
- assert (old == &init_names);
+ assert (old == init_names);
break;
}
cur = names->count;
@@ -1697,7 +1663,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
and this is the block assigned to OLD here. */
if (names == NULL)
{
- assert (old == &init_names);
+ assert (old == init_names);
break;
}
cur = names->count;
diff --git a/posix/glob64.c b/posix/glob64.c
index 6cb3d654a8..a515a1c12f 100644
--- a/posix/glob64.c
+++ b/posix/glob64.c
@@ -43,10 +43,4 @@ glob64 (const char *pattern, int flags,
}
libc_hidden_def (glob64)
-void
-globfree64 (glob64_t *pglob)
-{
-}
-libc_hidden_def (globfree64)
-
stub_warning (glob64)
diff --git a/posix/glob_internal.h b/posix/glob_internal.h
new file mode 100644
index 0000000000..12c93660b7
--- /dev/null
+++ b/posix/glob_internal.h
@@ -0,0 +1,57 @@
+/* Shared definition for glob and glob_pattern_p.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GLOB_INTERNAL_H
+# define GLOB_INTERNAL_H
+
+static inline int
+__glob_pattern_type (const char *pattern, int quote)
+{
+ const char *p;
+ int ret = 0;
+
+ for (p = pattern; *p != '\0'; ++p)
+ switch (*p)
+ {
+ case '?':
+ case '*':
+ return 1;
+
+ case '\\':
+ if (quote)
+ {
+ if (p[1] != '\0')
+ ++p;
+ ret |= 2;
+ }
+ break;
+
+ case '[':
+ ret |= 4;
+ break;
+
+ case ']':
+ if (ret & 4)
+ return 1;
+ break;
+ }
+
+ return ret;
+}
+
+#endif /* GLOB_INTERNAL_H */
diff --git a/posix/glob_pattern_p.c b/posix/glob_pattern_p.c
new file mode 100644
index 0000000000..a17d337182
--- /dev/null
+++ b/posix/glob_pattern_p.c
@@ -0,0 +1,33 @@
+/* Return nonzero if PATTERN contains any metacharacters.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include <glob.h>
+#include "glob_internal.h"
+
+/* Return nonzero if PATTERN contains any metacharacters.
+ Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
+int
+__glob_pattern_p (const char *pattern, int quote)
+{
+ return __glob_pattern_type (pattern, quote) == 1;
+}
+weak_alias (__glob_pattern_p, glob_pattern_p)
diff --git a/posix/globfree.c b/posix/globfree.c
new file mode 100644
index 0000000000..042e29d9b0
--- /dev/null
+++ b/posix/globfree.c
@@ -0,0 +1,41 @@
+/* Frees the dynamically allocated storage from an earlier call to glob.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include <glob.h>
+#include <stdlib.h>
+
+/* Free storage allocated in PGLOB by a previous `glob' call. */
+void
+globfree (glob_t *pglob)
+{
+ if (pglob->gl_pathv != NULL)
+ {
+ size_t i;
+ for (i = 0; i < pglob->gl_pathc; ++i)
+ free (pglob->gl_pathv[pglob->gl_offs + i]);
+ free (pglob->gl_pathv);
+ pglob->gl_pathv = NULL;
+ }
+}
+#ifndef globfree
+libc_hidden_def (globfree)
+#endif
diff --git a/posix/globfree64.c b/posix/globfree64.c
new file mode 100644
index 0000000000..c9f8908a4e
--- /dev/null
+++ b/posix/globfree64.c
@@ -0,0 +1,31 @@
+/* Frees the dynamically allocated storage from an earlier call to glob.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include <glob.h>
+#include <stdlib.h>
+
+/* Free storage allocated in PGLOB by a previous `glob' call. */
+void
+globfree64 (glob64_t *pglob)
+{
+}
+libc_hidden_def (globfree64)
diff --git a/posix/tst-glob-tilde.c b/posix/tst-glob-tilde.c
new file mode 100644
index 0000000000..6886f4371f
--- /dev/null
+++ b/posix/tst-glob-tilde.c
@@ -0,0 +1,143 @@
+/* Check for GLOB_TIDLE heap allocation issues (bugs 22320, 22325, 22332).
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <glob.h>
+#include <mcheck.h>
+#include <nss.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+
+/* Flag which indicates whether to pass the GLOB_ONLYDIR flag. */
+static int do_onlydir;
+
+/* Flag which indicates whether to pass the GLOB_NOCHECK flag. */
+static int do_nocheck;
+
+/* Flag which indicates whether to pass the GLOB_MARK flag. */
+static int do_mark;
+
+/* Flag which indicates whether to pass the GLOB_NOESCAPE flag. */
+static int do_noescape;
+
+static void
+one_test (const char *prefix, const char *middle, const char *suffix)
+{
+ char *pattern = xasprintf ("%s%s%s", prefix, middle, suffix);
+ int flags = GLOB_TILDE;
+ if (do_onlydir)
+ flags |= GLOB_ONLYDIR;
+ if (do_nocheck)
+ flags |= GLOB_NOCHECK;
+ if (do_mark)
+ flags |= GLOB_MARK;
+ if (do_noescape)
+ flags |= GLOB_NOESCAPE;
+ glob_t gl;
+ /* This glob call might result in crashes or memory leaks. */
+ if (glob (pattern, flags, NULL, &gl) == 0)
+ globfree (&gl);
+ free (pattern);
+}
+
+enum
+ {
+ /* The largest base being tested. */
+ largest_base_size = 500000,
+
+ /* The actual size is the base size plus a variable whose absolute
+ value is not greater than this. This helps malloc to trigger
+ overflows. */
+ max_size_skew = 16,
+
+ /* The maximum string length supported by repeating_string
+ below. */
+ repeat_size = largest_base_size + max_size_skew,
+ };
+
+/* Used to construct strings which repeat a single character 'x'. */
+static char *repeat;
+
+/* Return a string of SIZE characters. */
+const char *
+repeating_string (int size)
+{
+ TEST_VERIFY (size >= 0);
+ TEST_VERIFY (size <= repeat_size);
+ const char *repeated_shifted = repeat + repeat_size - size;
+ TEST_VERIFY (strlen (repeated_shifted) == size);
+ return repeated_shifted;
+}
+
+static int
+do_test (void)
+{
+ /* Avoid network-based NSS modules and initialize nss_files with a
+ dummy lookup. This has to come before mtrace because NSS does
+ not free all memory. */
+ __nss_configure_lookup ("passwd", "files");
+ (void) getpwnam ("root");
+
+ mtrace ();
+
+ repeat = xmalloc (repeat_size + 1);
+ memset (repeat, 'x', repeat_size);
+ repeat[repeat_size] = '\0';
+
+ /* These numbers control the size of the user name. The values
+ cover the minimum (0), a typical size (8), a large
+ stack-allocated size (100000), and a somewhat large
+ heap-allocated size (largest_base_size). */
+ static const int base_sizes[] = { 0, 8, 100, 100000, largest_base_size, -1 };
+
+ for (do_onlydir = 0; do_onlydir < 2; ++do_onlydir)
+ for (do_nocheck = 0; do_nocheck < 2; ++do_nocheck)
+ for (do_mark = 0; do_mark < 2; ++do_mark)
+ for (do_noescape = 0; do_noescape < 2; ++do_noescape)
+ for (int base_idx = 0; base_sizes[base_idx] >= 0; ++base_idx)
+ {
+ for (int size_skew = -max_size_skew; size_skew <= max_size_skew;
+ ++size_skew)
+ {
+ int size = base_sizes[base_idx] + size_skew;
+ if (size < 0)
+ continue;
+
+ const char *user_name = repeating_string (size);
+ one_test ("~", user_name, "/a/b");
+ one_test ("~", user_name, "x\\x\\x////x\\a");
+ }
+
+ const char *user_name = repeating_string (base_sizes[base_idx]);
+ one_test ("~", user_name, "");
+ one_test ("~", user_name, "/");
+ one_test ("~", user_name, "/a");
+ one_test ("~", user_name, "/*/*");
+ one_test ("~", user_name, "\\/");
+ one_test ("/~", user_name, "");
+ one_test ("*/~", user_name, "/a/b");
+ }
+
+ free (repeat);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 7cd54ab504..1e85e4f08f 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -889,19 +889,6 @@ getanswer_r (struct resolv_context *ctx,
/* bind would put multiple PTR records as aliases, but we don't do
that. */
result->h_name = bp;
- if (have_to_map)
- {
- n = strlen (bp) + 1; /* for the \0 */
- if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
- {
- ++had_error;
- break;
- }
- bp += n;
- linebuflen -= n;
- if (map_v4v6_hostent (result, &bp, &linebuflen))
- goto too_small;
- }
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
case T_A:
diff --git a/resolv/res_init.c b/resolv/res_init.c
index fa46ce7813..4e1f9fe8de 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -446,6 +446,11 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
(&parser->nameserver_list);
if (p != NULL)
*p = sa;
+ else
+ {
+ free (sa);
+ return false;
+ }
}
continue;
}
diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
index f391d30c27..e0f296d02e 100644
--- a/resolv/resolv_conf.c
+++ b/resolv/resolv_conf.c
@@ -600,10 +600,7 @@ __resolv_conf_attach (struct __res_state *resp, struct resolv_conf *conf)
struct resolv_conf_global *global_copy = get_locked_global ();
if (global_copy == NULL)
- {
- free (conf);
- return false;
- }
+ return false;
/* Try to find an unused index in the array. */
size_t index;
diff --git a/resolv/tst-res_use_inet6.c b/resolv/tst-res_use_inet6.c
index 6f3db08892..d819f921d6 100644
--- a/resolv/tst-res_use_inet6.c
+++ b/resolv/tst-res_use_inet6.c
@@ -16,21 +16,121 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <ctype.h>
#include <netdb.h>
#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <support/check.h>
#include <support/check_nss.h>
#include <support/resolv_test.h>
+#include <support/support.h>
#include <support/xthread.h>
+/* Handle IPv4 reverse lookup responses. Product a PTR record
+ A-B-C-D.v4.example. */
+static void
+response_ptr_v4 (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+ int bytes[4];
+ int offset = -1;
+ TEST_VERIFY (sscanf (qname, "%d.%d.%d.%d.in-addr.arpa%n",
+ bytes + 0, bytes + 1, bytes + 2, bytes + 3,
+ &offset) == 4);
+ TEST_VERIFY (offset == strlen (qname));
+ resolv_response_init (b, (struct resolv_response_flags) {});
+ resolv_response_add_question (b, qname, qclass, qtype);
+ resolv_response_section (b, ns_s_an);
+ resolv_response_open_record (b, qname, qclass, T_PTR, 0);
+ char *name = xasprintf ("%d-%d-%d-%d.v4.example",
+ bytes[3], bytes[2], bytes[1], bytes[0]);
+ resolv_response_add_name (b, name);
+ free (name);
+ resolv_response_close_record (b);
+}
+
+/* Handle IPv6 reverse lookup responses. Produce a PTR record
+ <32 hex digits>.v6.example. */
+static void
+response_ptr_v6 (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+
+ TEST_VERIFY_EXIT (strlen (qname) > 64);
+
+ char bytes[33];
+ for (int i = 0; i < 64; ++i)
+ if ((i % 2) == 0)
+ {
+ TEST_VERIFY (isxdigit ((unsigned char) qname[i]));
+ bytes[31 - i / 2] = qname[i];
+ }
+ else
+ TEST_VERIFY_EXIT (qname[i] == '.');
+ bytes[32] = '\0';
+
+ resolv_response_init (b, (struct resolv_response_flags) {});
+ resolv_response_add_question (b, qname, qclass, qtype);
+ resolv_response_section (b, ns_s_an);
+ resolv_response_open_record (b, qname, qclass, T_PTR, 0);
+ char *name = xasprintf ("%s.v6.example", bytes);
+ resolv_response_add_name (b, name);
+ free (name);
+ resolv_response_close_record (b);
+}
+
+/* Produce a response based on QNAME: Certain characters in the first
+ label of QNAME trigger the inclusion of resource records:
+
+ 'a' A record (IPv4 address)
+ 'q' AAAA record (quad A record, IPv6 address)
+ 'p' PTR record
+ 'm' record type must match QTYPE (no additional records)
+ '6' stop flag processing if QTYPE == AAAA
+
+ For 'a' and 'q', QTYPE is ignored for record type selection if 'm'
+ is not specified.
+
+ in-addr.arpa and ip6.arpa queries are handled separately in
+ response_ptr_v4 and response_ptr_v6. */
static void
response (const struct resolv_response_context *ctx,
struct resolv_response_builder *b,
const char *qname, uint16_t qclass, uint16_t qtype)
{
- bool include_both = strcmp (qname, "both.example") == 0;
- bool include_a = qtype == T_A || include_both;
- bool include_aaaa = qtype == T_AAAA || include_both;
+ if (strstr (qname, ".in-addr.arpa") != NULL)
+ return response_ptr_v4 (ctx, b, qname, qclass, qtype);
+ else if (strstr (qname, ".ip6.arpa") != NULL)
+ return response_ptr_v6 (ctx, b, qname, qclass, qtype);
+
+ bool include_a = false;
+ bool include_aaaa = false;
+ bool include_match = false;
+ bool include_ptr = false;
+ for (const char *p = qname; *p != '.' && *p != '\0'; ++p)
+ {
+ if (*p == 'a')
+ include_a = true;
+ else if (*p == 'q')
+ include_aaaa = true;
+ else if (*p == 'm')
+ include_match = true;
+ else if (*p == 'p')
+ include_ptr = true;
+ else if (*p == '6' && qtype == T_AAAA)
+ break;
+ }
+ if (include_match)
+ {
+ if (qtype == T_A)
+ include_aaaa = false;
+ else if (qtype == T_AAAA)
+ include_a = false;
+ }
resolv_response_init (b, (struct resolv_response_flags) {});
resolv_response_add_question (b, qname, qclass, qtype);
@@ -44,11 +144,17 @@ response (const struct resolv_response_context *ctx,
}
if (include_aaaa)
{
- char ipv6[16]
- = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
- resolv_response_open_record (b, qname, qclass, T_AAAA, 0);
- resolv_response_add_data (b, &ipv6, sizeof (ipv6));
- resolv_response_close_record (b);
+ char ipv6[16]
+ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ resolv_response_open_record (b, qname, qclass, T_AAAA, 0);
+ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
+ resolv_response_close_record (b);
+ }
+ if (include_ptr)
+ {
+ resolv_response_open_record (b, qname, qclass, T_PTR, 0);
+ resolv_response_add_name (b, "ptr-target.example");
+ resolv_response_close_record (b);
}
}
@@ -64,16 +170,21 @@ test_gai (void)
.ai_protocol = IPPROTO_TCP,
};
struct addrinfo *ai;
- int ret = getaddrinfo ("www1.example", "80", &hints, &ai);
- check_addrinfo ("getaddrinfo AF_UNSPEC www1.example", ai, ret,
+ int ret = getaddrinfo ("qam.example", "80", &hints, &ai);
+ check_addrinfo ("getaddrinfo AF_UNSPEC qam.example", ai, ret,
"address: STREAM/TCP 192.0.2.17 80\n"
"address: STREAM/TCP 2001:db8::1 80\n");
if (ret == 0)
freeaddrinfo (ai);
- ret = getaddrinfo ("both.example", "80", &hints, &ai);
+ ret = getaddrinfo ("am.example", "80", &hints, &ai);
+ check_addrinfo ("getaddrinfo AF_UNSPEC am.example", ai, ret,
+ "address: STREAM/TCP 192.0.2.17 80\n");
+ if (ret == 0)
+ freeaddrinfo (ai);
+ ret = getaddrinfo ("qa.example", "80", &hints, &ai);
/* Combined A/AAAA responses currently result in address
duplication. */
- check_addrinfo ("getaddrinfo AF_UNSPEC both.example", ai, ret,
+ check_addrinfo ("getaddrinfo AF_UNSPEC qa.example", ai, ret,
"address: STREAM/TCP 192.0.2.17 80\n"
"address: STREAM/TCP 192.0.2.17 80\n"
"address: STREAM/TCP 2001:db8::1 80\n"
@@ -89,13 +200,18 @@ test_gai (void)
.ai_protocol = IPPROTO_TCP,
};
struct addrinfo *ai;
- int ret = getaddrinfo ("www1.example", "80", &hints, &ai);
- check_addrinfo ("getaddrinfo AF_INET www1.example", ai, ret,
+ int ret = getaddrinfo ("qam.example", "80", &hints, &ai);
+ check_addrinfo ("getaddrinfo AF_INET qam.example", ai, ret,
+ "address: STREAM/TCP 192.0.2.17 80\n");
+ if (ret == 0)
+ freeaddrinfo (ai);
+ ret = getaddrinfo ("am.example", "80", &hints, &ai);
+ check_addrinfo ("getaddrinfo AF_INET am.example", ai, ret,
"address: STREAM/TCP 192.0.2.17 80\n");
if (ret == 0)
freeaddrinfo (ai);
- ret = getaddrinfo ("both.example", "80", &hints, &ai);
- check_addrinfo ("getaddrinfo AF_INET both.example", ai, ret,
+ ret = getaddrinfo ("qa.example", "80", &hints, &ai);
+ check_addrinfo ("getaddrinfo AF_INET qa.example", ai, ret,
"address: STREAM/TCP 192.0.2.17 80\n");
if (ret == 0)
freeaddrinfo (ai);
@@ -108,40 +224,196 @@ test_gai (void)
.ai_protocol = IPPROTO_TCP,
};
struct addrinfo *ai;
- int ret = getaddrinfo ("www1.example", "80", &hints, &ai);
+ int ret = getaddrinfo ("qa.example", "80", &hints, &ai);
check_addrinfo ("getaddrinfo (AF_INET6)", ai, ret,
"address: STREAM/TCP 2001:db8::1 80\n");
if (ret == 0)
freeaddrinfo (ai);
- ret = getaddrinfo ("both.example", "80", &hints, &ai);
- check_addrinfo ("getaddrinfo AF_INET6 both.example", ai, ret,
+ ret = getaddrinfo ("am.example", "80", &hints, &ai);
+ check_addrinfo ("getaddrinfo AF_INET6 am.example", ai, ret,
+ "error: No address associated with hostname\n");
+ if (ret == 0)
+ freeaddrinfo (ai);
+ ret = getaddrinfo ("qam.example", "80", &hints, &ai);
+ check_addrinfo ("getaddrinfo AF_INET6 qam.example", ai, ret,
"address: STREAM/TCP 2001:db8::1 80\n");
if (ret == 0)
freeaddrinfo (ai);
}
}
-/* Test that gethostbyname2 is not influenced by RES_USE_INET6. */
+/* Test gethostbyaddr and getnameinfo. The results are independent of
+ RES_USE_INET6. */
static void
-test_get2 (void)
+test_reverse (void)
{
- check_hostent ("gethostbyname2 AF_INET www1.example",
- gethostbyname2 ("www1.example", AF_INET),
- "name: www1.example\n"
+ {
+ char ipv4[4] = { 192, 0, 2, 17 };
+ check_hostent ("gethostbyaddr AF_INET",
+ gethostbyaddr (ipv4, sizeof (ipv4), AF_INET),
+ "name: 192-0-2-17.v4.example\n"
+ "address: 192.0.2.17\n");
+ }
+ {
+ char ipv6[16]
+ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ check_hostent ("gethostbyaddr AF_INET",
+ gethostbyaddr (ipv6, sizeof (ipv6), AF_INET6),
+ "name: 20010db8000000000000000000000001.v6.example\n"
+ "address: 2001:db8::1\n");
+ }
+
+ {
+ struct sockaddr_in addr =
+ {
+ .sin_family = AF_INET,
+ .sin_addr = { .s_addr = htonl (0xc0000211) },
+ .sin_port = htons (80)
+ };
+ char host[NI_MAXHOST];
+ char service[NI_MAXSERV];
+ int ret = getnameinfo ((struct sockaddr *) &addr, sizeof (addr),
+ host, sizeof (host), service, sizeof (service),
+ NI_NUMERICSERV);
+ TEST_VERIFY (ret == 0);
+ TEST_VERIFY (strcmp (host, "192-0-2-17.v4.example") == 0);
+ TEST_VERIFY (strcmp (service, "80") == 0);
+ }
+ {
+ char ipv6[16]
+ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ struct sockaddr_in6 addr =
+ {
+ .sin6_family = AF_INET6,
+ .sin6_port = htons (80),
+ };
+ TEST_VERIFY (sizeof (ipv6) == sizeof (addr.sin6_addr));
+ memcpy (&addr.sin6_addr, ipv6, sizeof (addr.sin6_addr));
+ char host[NI_MAXHOST];
+ char service[NI_MAXSERV];
+ int ret = getnameinfo ((struct sockaddr *) &addr, sizeof (addr),
+ host, sizeof (host), service, sizeof (service),
+ NI_NUMERICSERV);
+ TEST_VERIFY (ret == 0);
+ TEST_VERIFY
+ (strcmp (host, "20010db8000000000000000000000001.v6.example") == 0);
+ TEST_VERIFY (strcmp (service, "80") == 0);
+ }
+}
+
+/* Test that gethostbyname2 is mostly not influenced by
+ RES_USE_INET6. */
+static void
+test_get2_any (void)
+{
+ check_hostent ("gethostbyname2 AF_INET am.example",
+ gethostbyname2 ("am.example", AF_INET),
+ "name: am.example\n"
+ "address: 192.0.2.17\n");
+ check_hostent ("gethostbyname2 AF_INET a.example",
+ gethostbyname2 ("a.example", AF_INET),
+ "name: a.example\n"
"address: 192.0.2.17\n");
- check_hostent ("gethostbyname2 AF_INET both.example",
- gethostbyname2 ("both.example", AF_INET),
- "name: both.example\n"
+ check_hostent ("gethostbyname2 AF_INET qm.example",
+ gethostbyname2 ("qm.example", AF_INET),
+ "error: NO_ADDRESS\n");
+ check_hostent ("gethostbyname2 AF_INET q.example",
+ gethostbyname2 ("q.example", AF_INET),
+ "error: NO_RECOVERY\n");
+ check_hostent ("gethostbyname2 AF_INET qam.example",
+ gethostbyname2 ("qam.example", AF_INET),
+ "name: qam.example\n"
+ "address: 192.0.2.17\n");
+ check_hostent ("gethostbyname2 AF_INET qa.example",
+ gethostbyname2 ("qa.example", AF_INET),
+ "name: qa.example\n"
"address: 192.0.2.17\n");
- check_hostent ("gethostbyname2 AF_INET6 www1.example",
- gethostbyname2 ("www1.example", AF_INET6),
- "name: www1.example\n"
+ check_hostent ("gethostbyname2 AF_INET6 qm.example",
+ gethostbyname2 ("qm.example", AF_INET6),
+ "name: qm.example\n"
+ "address: 2001:db8::1\n");
+ check_hostent ("gethostbyname2 AF_INET6 q.example",
+ gethostbyname2 ("q.example", AF_INET6),
+ "name: q.example\n"
+ "address: 2001:db8::1\n");
+ check_hostent ("gethostbyname2 AF_INET6 qam.example",
+ gethostbyname2 ("qam.example", AF_INET6),
+ "name: qam.example\n"
"address: 2001:db8::1\n");
- check_hostent ("gethostbyname2 AF_INET6 both.example",
- gethostbyname2 ("both.example", AF_INET6),
- "name: both.example\n"
+ check_hostent ("gethostbyname2 AF_INET6 qa.example",
+ gethostbyname2 ("qa.example", AF_INET6),
+ "name: qa.example\n"
"address: 2001:db8::1\n");
+ /* Additional AF_INET6 tests depend on RES_USE_INET6; see below. */
+
+ test_reverse ();
+}
+
+/* gethostbyname2 tests with RES_USE_INET6 disabled. */
+static void
+test_get2_no_inet6 (void)
+{
+ test_get2_any ();
+
+ check_hostent ("gethostbyname2 AF_INET6 am.example",
+ gethostbyname2 ("am.example", AF_INET6),
+ "error: NO_ADDRESS\n");
+ check_hostent ("gethostbyname2 AF_INET6 a.example",
+ gethostbyname2 ("a.example", AF_INET6),
+ "error: NO_RECOVERY\n");
+}
+
+/* gethostbyname2 tests with RES_USE_INET6 enabled. */
+static void
+test_get2_inet6 (void)
+{
+ test_get2_any ();
+
+ check_hostent ("gethostbyname2 AF_INET6 am.example",
+ gethostbyname2 ("am.example", AF_INET6),
+ "name: am.example\n"
+ "address: ::ffff:192.0.2.17\n");
+ check_hostent ("gethostbyname2 AF_INET6 a.example",
+ gethostbyname2 ("a.example", AF_INET6),
+ "error: NO_RECOVERY\n");
+}
+
+/* Collection of tests which assume no RES_USE_INET6 flag. */
+static void
+test_no_inet6 (void)
+{
+ check_hostent ("gethostbyname (\"a.example\")",
+ gethostbyname ("a.example"),
+ "name: a.example\n"
+ "address: 192.0.2.17\n");
+ check_hostent ("gethostbyname (\"qa.example\")",
+ gethostbyname ("qa.example"),
+ "name: qa.example\n"
+ "address: 192.0.2.17\n");
+ check_hostent ("gethostbyname (\"am.example\")",
+ gethostbyname ("am.example"),
+ "name: am.example\n"
+ "address: 192.0.2.17\n");
+ check_hostent ("gethostbyname (\"amp.example\")",
+ gethostbyname ("amp.example"),
+ "name: amp.example\n"
+ "address: 192.0.2.17\n");
+ check_hostent ("gethostbyname (\"qam.example\")",
+ gethostbyname ("qam.example"),
+ "name: qam.example\n"
+ "address: 192.0.2.17\n");
+ check_hostent ("gethostbyname (\"q.example\")",
+ gethostbyname ("q.example"),
+ "error: NO_RECOVERY\n");
+ check_hostent ("gethostbyname (\"qm.example\")",
+ gethostbyname ("qm.example"),
+ "error: NO_ADDRESS\n");
+ test_get2_no_inet6 ();
+ test_get2_no_inet6 ();
+ test_gai ();
+ test_get2_no_inet6 ();
+ test_get2_no_inet6 ();
}
static void *
@@ -153,28 +425,64 @@ threadfunc (void *ignored)
.response_callback = response
});
- check_hostent ("gethostbyname (\"www1.example\")",
- gethostbyname ("www1.example"),
- "name: www1.example\n"
- "address: 192.0.2.17\n");
- check_hostent ("gethostbyname (\"both.example\")",
- gethostbyname ("both.example"),
- "name: both.example\n"
- "address: 192.0.2.17\n");
- test_get2 ();
- test_gai ();
+ TEST_VERIFY ((_res.options & RES_USE_INET6) == 0);
+ test_no_inet6 ();
_res.options |= RES_USE_INET6;
- check_hostent ("gethostbyname (\"www1.example\")",
- gethostbyname ("www1.example"),
- "name: www1.example\n"
+ check_hostent ("gethostbyname (\"a.inet6.example\")",
+ gethostbyname ("a.inet6.example"),
+ "error: NO_RECOVERY\n");
+ check_hostent ("gethostbyname (\"am.inet6.example\")",
+ gethostbyname ("am.inet6.example"),
+ "name: am.inet6.example\n"
+ "address: ::ffff:192.0.2.17\n");
+ check_hostent ("gethostbyname (\"qa.inet6.example\")",
+ gethostbyname ("qa.inet6.example"),
+ "name: qa.inet6.example\n"
"address: 2001:db8::1\n");
- check_hostent ("gethostbyname (\"both.example\")",
- gethostbyname ("both.example"),
- "name: both.example\n"
+ check_hostent ("gethostbyname (\"qam.inet6.example\")",
+ gethostbyname ("qam.inet6.example"),
+ "name: qam.inet6.example\n"
"address: 2001:db8::1\n");
- test_get2 ();
+ check_hostent ("gethostbyname (\"q.inet6.example\")",
+ gethostbyname ("q.inet6.example"),
+ "name: q.inet6.example\n"
+ "address: 2001:db8::1\n");
+ check_hostent ("gethostbyname (\"qm.inet6.example\")",
+ gethostbyname ("qm.inet6.example"),
+ "name: qm.inet6.example\n"
+ "address: 2001:db8::1\n");
+ check_hostent ("gethostbyname (\"amp.inet6.example\")",
+ gethostbyname ("amp.inet6.example"),
+ "error: NO_RECOVERY\n");
+ check_hostent ("gethostbyname (\"qmp.inet6.example\")",
+ gethostbyname ("qmp.inet6.example"),
+ "name: qmp.inet6.example\n"
+ "address: 2001:db8::1\n");
+ check_hostent ("gethostbyname (\"ap.inet6.example\")",
+ gethostbyname ("ap.inet6.example"),
+ "error: NO_RECOVERY\n");
+ check_hostent ("gethostbyname (\"6ap.inet6.example\")",
+ gethostbyname ("6ap.inet6.example"),
+ "name: 6ap.inet6.example\n"
+ "address: ::ffff:192.0.2.17\n");
+ check_hostent ("gethostbyname (\"am6p.inet6.example\")",
+ gethostbyname ("am6p.inet6.example"),
+ "name: am6p.inet6.example\n"
+ "address: ::ffff:192.0.2.17\n");
+ check_hostent ("gethostbyname (\"qp.inet6.example\")",
+ gethostbyname ("qp.inet6.example"),
+ "name: qp.inet6.example\n"
+ "address: 2001:db8::1\n");
+ test_get2_inet6 ();
+ test_get2_inet6 ();
test_gai ();
+ test_get2_inet6 ();
+ test_get2_inet6 ();
+
+ TEST_VERIFY (_res.options & RES_USE_INET6);
+ _res.options &= ~RES_USE_INET6;
+ test_no_inet6 ();
resolv_test_end (obj);
diff --git a/resolv/tst-resolv-basic.c b/resolv/tst-resolv-basic.c
index 64eedbbd81..66a0e8a165 100644
--- a/resolv/tst-resolv-basic.c
+++ b/resolv/tst-resolv-basic.c
@@ -50,7 +50,7 @@ response (const struct resolv_response_context *ctx,
qname_compare = qname + 2;
else
qname_compare = qname;
- enum {www, alias, nxdomain, long_name} requested_qname;
+ enum {www, alias, nxdomain, long_name, nodata} requested_qname;
if (strcmp (qname_compare, "www.example") == 0)
requested_qname = www;
else if (strcmp (qname_compare, "alias.example") == 0)
@@ -59,6 +59,8 @@ response (const struct resolv_response_context *ctx,
requested_qname = nxdomain;
else if (strcmp (qname_compare, LONG_NAME) == 0)
requested_qname = long_name;
+ else if (strcmp (qname_compare, "nodata.example") == 0)
+ requested_qname = nodata;
else
{
support_record_failure ();
@@ -87,6 +89,8 @@ response (const struct resolv_response_context *ctx,
resolv_response_close_record (b);
resolv_response_open_record (b, "www.example", qclass, qtype, 0);
break;
+ case nodata:
+ return;
case nxdomain:
FAIL_EXIT1 ("unreachable");
}
@@ -267,6 +271,55 @@ test_bug_21295 (void)
}
}
+/* Run tests which do not expect any data. */
+static void
+test_nodata_nxdomain (void)
+{
+ /* Iterate through different address families. */
+ int families[] = { AF_UNSPEC, AF_INET, AF_INET6, -1 };
+ for (int i = 0; families[i] >= 0; ++i)
+ /* If do_tcp, prepend "t." to the name to trigger TCP
+ fallback. */
+ for (int do_tcp = 0; do_tcp < 2; ++do_tcp)
+ /* If do_nxdomain, trigger an NXDOMAIN error (DNS failure),
+ otherwise use a NODATA response (empty but successful
+ answer). */
+ for (int do_nxdomain = 0; do_nxdomain < 2; ++do_nxdomain)
+ {
+ int family = families[i];
+ char *name = xasprintf ("%s%s.example",
+ do_tcp ? "t." : "",
+ do_nxdomain ? "nxdomain" : "nodata");
+
+ if (family != AF_UNSPEC)
+ {
+ if (do_nxdomain)
+ check_h (name, family, "error: HOST_NOT_FOUND\n");
+ else
+ check_h (name, family, "error: NO_ADDRESS\n");
+ }
+
+ const char *expected;
+ if (do_nxdomain)
+ expected = "error: Name or service not known\n";
+ else
+ expected = "error: No address associated with hostname\n";
+
+ check_ai (name, "80", family, expected);
+
+ struct addrinfo hints =
+ {
+ .ai_family = family,
+ .ai_flags = AI_V4MAPPED | AI_ALL,
+ };
+ check_ai_hints (name, "80", hints, expected);
+ hints.ai_flags |= AI_CANONNAME;
+ check_ai_hints (name, "80", hints, expected);
+
+ free (name);
+ }
+}
+
static int
do_test (void)
{
@@ -439,29 +492,8 @@ do_test (void)
"address: DGRAM/UDP 2001:db8::4 80\n"
"address: RAW/IP 2001:db8::4 80\n");
- check_h ("nxdomain.example", AF_INET,
- "error: HOST_NOT_FOUND\n");
- check_h ("nxdomain.example", AF_INET6,
- "error: HOST_NOT_FOUND\n");
- check_ai ("nxdomain.example", "80", AF_UNSPEC,
- "error: Name or service not known\n");
- check_ai ("nxdomain.example", "80", AF_INET,
- "error: Name or service not known\n");
- check_ai ("nxdomain.example", "80", AF_INET6,
- "error: Name or service not known\n");
-
- check_h ("t.nxdomain.example", AF_INET,
- "error: HOST_NOT_FOUND\n");
- check_h ("t.nxdomain.example", AF_INET6,
- "error: HOST_NOT_FOUND\n");
- check_ai ("t.nxdomain.example", "80", AF_UNSPEC,
- "error: Name or service not known\n");
- check_ai ("t.nxdomain.example", "80", AF_INET,
- "error: Name or service not known\n");
- check_ai ("t.nxdomain.example", "80", AF_INET6,
- "error: Name or service not known\n");
-
test_bug_21295 ();
+ test_nodata_nxdomain ();
resolv_test_end (aux);
diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c
index 06ea3dbd14..da3325f80c 100644
--- a/resolv/tst-resolv-qtypes.c
+++ b/resolv/tst-resolv-qtypes.c
@@ -50,7 +50,7 @@ response (const struct resolv_response_context *ctx,
resolv_response_close_record (b);
}
-static const char * const domain = "www.example.com";
+static const char domain[] = "www.example.com";
static int
wrap_res_query (int type, unsigned char *answer, int answer_length)
diff --git a/scripts/backport-support.sh b/scripts/backport-support.sh
index 2ece7ce575..4057e42d3c 100644
--- a/scripts/backport-support.sh
+++ b/scripts/backport-support.sh
@@ -1,6 +1,6 @@
#!/bin/bash
# Create a patch which backports the support/ subdirectory.
-# Copyright (C) 2017 Free Software Foundation, Inc.
+# 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
diff --git a/scripts/check-local-headers.sh b/scripts/check-local-headers.sh
index 7859f613b2..0cde6e8e92 100755
--- a/scripts/check-local-headers.sh
+++ b/scripts/check-local-headers.sh
@@ -33,7 +33,7 @@ exec ${AWK} -v includedir="$includedir" '
BEGIN {
status = 0
exclude = "^" includedir \
- "/(.*-.*-.*/|.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|mach_debug/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs|ihash\\.h)|cthreads\\.h|gd|nss3/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)"
+ "/(.*-.*-.*/|.*-.*/|)(asm[-/]|arch|linux/|selinux/|mach/|mach_debug/|device/|hurd/(((hurd|ioctl)_types|paths)\\.h|ioctls\\.defs|ihash\\.h)|cthreads\\.h|gd|nss3/|nspr4?/|c\\+\\+/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)"
}
/^[^ ]/ && $1 ~ /.*:/ { obj = $1 }
{
diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
index ccdd0c6c71..622199061a 100644
--- a/scripts/gen-tunables.awk
+++ b/scripts/gen-tunables.awk
@@ -1,6 +1,14 @@
# Generate dl-tunable-list.h from dl-tunables.list
BEGIN {
+ min_of["STRING"]="0"
+ max_of["STRING"]="0"
+ min_of["INT_32"]="INT32_MIN"
+ max_of["INT_32"]="INT32_MAX"
+ min_of["UINT_64"]="0"
+ max_of["UINT_64"]="UINT64_MAX"
+ min_of["SIZE_T"]="0"
+ max_of["SIZE_T"]="SIZE_MAX"
tunable=""
ns=""
top_ns=""
@@ -43,10 +51,10 @@ $1 == "}" {
types[top_ns,ns,tunable] = "STRING"
}
if (!minvals[top_ns,ns,tunable]) {
- minvals[top_ns,ns,tunable] = "0"
+ minvals[top_ns,ns,tunable] = min_of[types[top_ns,ns,tunable]]
}
if (!maxvals[top_ns,ns,tunable]) {
- maxvals[top_ns,ns,tunable] = "0"
+ maxvals[top_ns,ns,tunable] = max_of[types[top_ns,ns,tunable]]
}
if (!env_alias[top_ns,ns,tunable]) {
env_alias[top_ns,ns,tunable] = "NULL"
diff --git a/stdlib/getentropy.c b/stdlib/getentropy.c
index a71d4cd8f5..a88bbf8de3 100644
--- a/stdlib/getentropy.c
+++ b/stdlib/getentropy.c
@@ -21,7 +21,7 @@
/* Write LENGTH bytes of randomness starting at BUFFER. Return 0 on
success and -1 on failure. */
-ssize_t
+int
getentropy (void *buffer, size_t length)
{
__set_errno (ENOSYS);
diff --git a/string/stratcliff.c b/string/stratcliff.c
index e28b0c5058..4320336c9a 100644
--- a/string/stratcliff.c
+++ b/string/stratcliff.c
@@ -58,8 +58,8 @@
int
do_test (void)
{
- int size = sysconf (_SC_PAGESIZE);
- int nchars = size / sizeof (CHAR);
+ size_t size = sysconf (_SC_PAGESIZE);
+ size_t nchars = size / sizeof (CHAR);
CHAR *adr;
CHAR *dest;
int result = 0;
@@ -80,7 +80,17 @@ do_test (void)
}
else
{
- int inner, middle, outer;
+ size_t inner, middle, outer, nchars64, max128;
+
+ if (nchars > 64)
+ nchars64 = nchars - 64;
+ else
+ nchars64 = 0;
+
+ if (nchars > 128)
+ max128 = nchars - 128;
+ else
+ max128 = 0;
mprotect (adr, size, PROT_NONE);
mprotect (adr + 2 * nchars, size, PROT_NONE);
@@ -93,59 +103,65 @@ do_test (void)
MEMSET (adr, L('T'), nchars);
/* strlen/wcslen test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if (STRLEN (&adr[outer]) != (size_t) (inner - outer))
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STRLEN), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* strnlen/wcsnlen test */
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if (STRNLEN (&adr[outer], inner - outer + 1)
!= (size_t) (inner - outer))
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STRNLEN), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner <= nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner <= nchars; ++inner)
{
if (STRNLEN (&adr[outer], inner - outer)
!= (size_t) (inner - outer))
{
- printf ("%s flunked bounded for outer = %d, inner = %d\n",
+ printf ("%s flunked bounded for outer = %zu, inner = %zu\n",
STRINGIFY (STRNLEN), outer, inner);
result = 1;
}
}
+ if (outer == 0)
+ break;
}
/* strchr/wcschr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
for (inner = middle; inner < nchars; ++inner)
{
@@ -158,8 +174,8 @@ do_test (void)
|| (inner != middle
&& (cp - &adr[outer]) != middle - outer))
{
- printf ("%s flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRCHR), outer, middle, inner);
result = 1;
}
@@ -168,6 +184,8 @@ do_test (void)
adr[middle] = L('T');
}
}
+ if (outer == 0)
+ break;
}
/* Special test. */
@@ -180,9 +198,9 @@ do_test (void)
}
/* strrchr/wcsrchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
for (inner = middle; inner < nchars; ++inner)
{
@@ -195,8 +213,8 @@ do_test (void)
|| (inner != middle
&& (cp - &adr[outer]) != middle - outer))
{
- printf ("%s flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRRCHR), outer, middle, inner);
result = 1;
}
@@ -205,12 +223,14 @@ do_test (void)
adr[middle] = L('T');
}
}
+ if (outer == 0)
+ break;
}
/* memchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('V');
@@ -218,32 +238,36 @@ do_test (void)
if (cp - &adr[outer] != middle - outer)
{
- printf ("%s flunked for outer = %d, middle = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu\n",
STRINGIFY (MEMCHR), outer, middle);
result = 1;
}
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
CHAR *cp = MEMCHR (&adr[outer], L('V'), nchars - outer);
if (cp != NULL)
{
- printf ("%s flunked for outer = %d\n",
+ printf ("%s flunked for outer = %zu\n",
STRINGIFY (MEMCHR), outer);
result = 1;
}
+ if (outer == 0)
+ break;
}
/* These functions only exist for single-byte characters. */
#ifndef WCSTEST
/* rawmemchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('V');
@@ -251,19 +275,21 @@ do_test (void)
if (cp - &adr[outer] != middle - outer)
{
- printf ("%s flunked for outer = %d, middle = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu\n",
STRINGIFY (rawmemchr), outer, middle);
result = 1;
}
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
/* memrchr test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('V');
@@ -271,44 +297,50 @@ do_test (void)
if (cp - &adr[outer] != middle - outer)
{
- printf ("%s flunked for outer = %d, middle = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu\n",
STRINGIFY (memrchr), outer, middle);
result = 1;
}
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer);
if (cp != NULL)
{
- printf ("%s flunked for outer = %d\n",
+ printf ("%s flunked for outer = %zu\n",
STRINGIFY (memrchr), outer);
result = 1;
}
+ if (outer == 0)
+ break;
}
#endif
/* strcpy/wcscpy test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if (STRCPY (dest, &adr[outer]) != dest
|| STRLEN (dest) != (size_t) (inner - outer))
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STRCPY), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* strcmp/wcscmp tests */
@@ -322,14 +354,14 @@ do_test (void)
if (STRCMP (adr + middle, dest + nchars - outer) <= 0)
{
- printf ("%s 1 flunked for outer = %d, middle = %d\n",
+ printf ("%s 1 flunked for outer = %zu, middle = %zu\n",
STRINGIFY (STRCMP), outer, middle);
result = 1;
}
if (STRCMP (dest + nchars - outer, adr + middle) >= 0)
{
- printf ("%s 2 flunked for outer = %d, middle = %d\n",
+ printf ("%s 2 flunked for outer = %zu, middle = %zu\n",
STRINGIFY (STRCMP), outer, middle);
result = 1;
}
@@ -348,16 +380,16 @@ do_test (void)
{
if (STRNCMP (adr + middle, dest + nchars - outer, inner) != 0)
{
- printf ("%s 1 flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s 1 flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRNCMP), outer, middle, inner);
result = 1;
}
if (STRNCMP (dest + nchars - outer, adr + middle, inner) != 0)
{
- printf ("%s 2 flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s 2 flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STRNCMP), outer, middle, inner);
result = 1;
}
@@ -365,14 +397,14 @@ do_test (void)
if (STRNCMP (adr + middle, dest + nchars - outer, outer) >= 0)
{
- printf ("%s 1 flunked for outer = %d, middle = %d, full\n",
+ printf ("%s 1 flunked for outer = %zu, middle = %zu, full\n",
STRINGIFY (STRNCMP), outer, middle);
result = 1;
}
if (STRNCMP (dest + nchars - outer, adr + middle, outer) <= 0)
{
- printf ("%s 2 flunked for outer = %d, middle = %d, full\n",
+ printf ("%s 2 flunked for outer = %zu, middle = %zu, full\n",
STRINGIFY (STRNCMP), outer, middle);
result = 1;
}
@@ -380,7 +412,7 @@ do_test (void)
/* strncpy/wcsncpy tests */
adr[nchars - 1] = L('T');
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
size_t len;
@@ -389,17 +421,19 @@ do_test (void)
if (STRNCPY (dest, &adr[outer], len) != dest
|| MEMCMP (dest, &adr[outer], len) != 0)
{
- printf ("outer %s flunked for outer = %d, len = %Zd\n",
+ printf ("outer %s flunked for outer = %zu, len = %zu\n",
STRINGIFY (STRNCPY), outer, len);
result = 1;
}
}
+ if (outer == 0)
+ break;
}
adr[nchars - 1] = L('\0');
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
size_t len;
@@ -413,8 +447,8 @@ do_test (void)
|| (inner - outer < len
&& STRLEN (dest) != (inner - outer)))
{
- printf ("%s flunked for outer = %d, inner = %d, "
- "len = %Zd\n",
+ printf ("%s flunked for outer = %zu, inner = %zu, "
+ "len = %zu\n",
STRINGIFY (STRNCPY), outer, inner, len);
result = 1;
}
@@ -424,8 +458,8 @@ do_test (void)
|| (inner - outer < len
&& STRLEN (dest + 1) != (inner - outer)))
{
- printf ("%s+1 flunked for outer = %d, inner = %d, "
- "len = %Zd\n",
+ printf ("%s+1 flunked for outer = %zu, inner = %zu, "
+ "len = %zu\n",
STRINGIFY (STRNCPY), outer, inner, len);
result = 1;
}
@@ -433,29 +467,33 @@ do_test (void)
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* stpcpy/wcpcpy test */
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+ for (inner = MAX (outer, nchars64); inner < nchars; ++inner)
{
adr[inner] = L('\0');
if ((STPCPY (dest, &adr[outer]) - dest) != inner - outer)
{
- printf ("%s flunked for outer = %d, inner = %d\n",
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
STRINGIFY (STPCPY), outer, inner);
result = 1;
}
adr[inner] = L('T');
}
+ if (outer == 0)
+ break;
}
/* stpncpy/wcpncpy test */
adr[nchars - 1] = L('T');
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars; outer >= max128; --outer)
{
size_t len;
@@ -464,17 +502,19 @@ do_test (void)
if (STPNCPY (dest, &adr[outer], len) != dest + len
|| MEMCMP (dest, &adr[outer], len) != 0)
{
- printf ("outer %s flunked for outer = %d, len = %Zd\n",
+ printf ("outer %s flunked for outer = %zu, len = %zu\n",
STRINGIFY (STPNCPY), outer, len);
result = 1;
}
}
+ if (outer == 0)
+ break;
}
adr[nchars - 1] = L('\0');
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+ for (outer = nchars - 1; outer >= max128; --outer)
{
- for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+ for (middle = MAX (outer, nchars64); middle < nchars; ++middle)
{
adr[middle] = L('\0');
@@ -483,8 +523,8 @@ do_test (void)
if ((STPNCPY (dest, &adr[outer], inner) - dest)
!= MIN (inner, middle - outer))
{
- printf ("%s flunked for outer = %d, middle = %d, "
- "inner = %d\n",
+ printf ("%s flunked for outer = %zu, middle = %zu, "
+ "inner = %zu\n",
STRINGIFY (STPNCPY), outer, middle, inner);
result = 1;
}
@@ -492,66 +532,84 @@ do_test (void)
adr[middle] = L('T');
}
+ if (outer == 0)
+ break;
}
/* memcpy/wmemcpy test */
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
- for (inner = 0; inner < nchars - outer; ++inner)
- if (MEMCPY (dest, &adr[outer], inner) != dest)
- {
- printf ("%s flunked for outer = %d, inner = %d\n",
- STRINGIFY (MEMCPY), outer, inner);
- result = 1;
- }
+ for (outer = nchars; outer >= max128; --outer)
+ {
+ for (inner = 0; inner < nchars - outer; ++inner)
+ if (MEMCPY (dest, &adr[outer], inner) != dest)
+ {
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
+ STRINGIFY (MEMCPY), outer, inner);
+ result = 1;
+ }
+ if (outer == 0)
+ break;
+ }
/* mempcpy/wmempcpy test */
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
- for (inner = 0; inner < nchars - outer; ++inner)
- if (MEMPCPY (dest, &adr[outer], inner) != dest + inner)
- {
- printf ("%s flunked for outer = %d, inner = %d\n",
- STRINGIFY (MEMPCPY), outer, inner);
- result = 1;
- }
+ for (outer = nchars; outer >= max128; --outer)
+ {
+ for (inner = 0; inner < nchars - outer; ++inner)
+ if (MEMPCPY (dest, &adr[outer], inner) != dest + inner)
+ {
+ printf ("%s flunked for outer = %zu, inner = %zu\n",
+ STRINGIFY (MEMPCPY), outer, inner);
+ result = 1;
+ }
+ if (outer == 0)
+ break;
+ }
/* This function only exists for single-byte characters. */
#ifndef WCSTEST
/* memccpy test */
memset (adr, '\0', nchars);
- for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
- for (inner = 0; inner < nchars - outer; ++inner)
- if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
- {
- printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
- outer, inner);
- result = 1;
- }
- for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
- for (middle = 0; middle < nchars - outer; ++middle)
- {
- memset (dest, L('\2'), middle + 1);
- for (inner = 0; inner < middle; ++inner)
+ for (outer = nchars; outer >= max128; --outer)
+ {
+ for (inner = 0; inner < nchars - outer; ++inner)
+ if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
{
- adr[outer + inner] = L('\1');
-
- if (memccpy (dest, &adr[outer], '\1', middle + 128)
- != dest + inner + 1)
- {
- printf ("\
-memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
- outer, middle, inner);
- result = 1;
- }
- else if (dest[inner + 1] != L('\2'))
- {
- printf ("\
-memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
- outer, middle, inner);
- result = 1;
- }
- adr[outer + inner] = L('\0');
+ printf ("memccpy flunked full copy for outer = %zu, inner = %zu\n",
+ outer, inner);
+ result = 1;
}
- }
+ if (outer == 0)
+ break;
+ }
+ for (outer = nchars - 1; outer >= max128; --outer)
+ {
+ for (middle = 0; middle < nchars - outer; ++middle)
+ {
+ memset (dest, L('\2'), middle + 1);
+ for (inner = 0; inner < middle; ++inner)
+ {
+ adr[outer + inner] = L('\1');
+
+ if (memccpy (dest, &adr[outer], '\1', middle + 128)
+ != dest + inner + 1)
+ {
+ printf ("\
+ memccpy flunked partial copy for outer = %zu, middle = %zu, inner = %zu\n",
+ outer, middle, inner);
+ result = 1;
+ }
+ else if (dest[inner + 1] != L('\2'))
+ {
+ printf ("\
+ memccpy copied too much for outer = %zu, middle = %zu, inner = %zu\n",
+ outer, middle, inner);
+ result = 1;
+ }
+ adr[outer + inner] = L('\0');
+ }
+ }
+ if (outer == 0)
+ break;
+ }
#endif
}
diff --git a/support/Makefile b/support/Makefile
index 2ace3fa8cc..1bda81e55e 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -1,5 +1,5 @@
# Makefile for support library, used only at build and test time
-# Copyright (C) 2016-2017 Free Software Foundation, Inc.
+# 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
@@ -32,15 +32,18 @@ libsupport-routines = \
check_netent \
delayed_exit \
ignore_stderr \
+ next_to_fault \
oom_error \
resolv_test \
set_fortify_handler \
+ support-xfstat \
support-xstat \
support_become_root \
support_can_chroot \
support_capture_subprocess \
support_capture_subprocess_check \
support_chroot \
+ support_enter_mount_namespace \
support_enter_network_namespace \
support_format_address_family \
support_format_addrinfo \
@@ -52,6 +55,7 @@ libsupport-routines = \
support_record_failure \
support_run_diff \
support_shared_allocate \
+ support_test_compare_failure \
support_write_file_string \
support_test_main \
support_test_verify_impl \
@@ -65,12 +69,15 @@ libsupport-routines = \
xchroot \
xclose \
xconnect \
+ xdlfcn \
xdup2 \
xfclose \
xfopen \
xfork \
+ xftruncate \
xgetsockname \
xlisten \
+ xlseek \
xmalloc \
xmemstream \
xmkdir \
@@ -83,8 +90,8 @@ libsupport-routines = \
xpthread_attr_destroy \
xpthread_attr_init \
xpthread_attr_setdetachstate \
- xpthread_attr_setstacksize \
xpthread_attr_setguardsize \
+ xpthread_attr_setstacksize \
xpthread_barrier_destroy \
xpthread_barrier_init \
xpthread_barrier_wait \
@@ -108,19 +115,26 @@ libsupport-routines = \
xpthread_once \
xpthread_rwlock_init \
xpthread_rwlock_rdlock \
- xpthread_rwlock_wrlock \
xpthread_rwlock_unlock \
+ xpthread_rwlock_wrlock \
xpthread_rwlockattr_init \
xpthread_rwlockattr_setkind_np \
xpthread_sigmask \
xpthread_spin_lock \
xpthread_spin_unlock \
+ xraise \
+ xreadlink \
xrealloc \
xrecvfrom \
xsendto \
xsetsockopt \
+ xsigaction \
+ xsignal \
xsocket \
xstrdup \
+ xstrndup \
+ xsysconf \
+ xunlink \
xwaitpid \
xwrite \
@@ -137,6 +151,8 @@ tests = \
tst-support_capture_subprocess \
tst-support_format_dns_packet \
tst-support_record_failure \
+ tst-test_compare \
+ tst-xreadlink \
ifeq ($(run-built-tests),yes)
tests-special = \
diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
index 43caf9bce4..b0886ba1d1 100644
--- a/support/capture_subprocess.h
+++ b/support/capture_subprocess.h
@@ -1,5 +1,5 @@
/* Capture output from a subprocess.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/check.c b/support/check.c
index 592f2bc856..78f2b3cde1 100644
--- a/support/check.c
+++ b/support/check.c
@@ -1,5 +1,5 @@
/* Support code for reporting test results.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -18,6 +18,7 @@
#include <support/check.h>
+#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -26,9 +27,11 @@
static void
print_failure (const char *file, int line, const char *format, va_list ap)
{
+ int saved_errno = errno;
printf ("error: %s:%d: ", file, line);
vprintf (format, ap);
puts ("");
+ errno = saved_errno;
}
int
diff --git a/support/check.h b/support/check.h
index bdcd12952a..2192f38941 100644
--- a/support/check.h
+++ b/support/check.h
@@ -1,5 +1,5 @@
/* Functionality for reporting test results.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -86,6 +86,61 @@ void support_test_verify_exit_impl (int status, const char *file, int line,
does not support reporting failures from a DSO. */
void support_record_failure (void);
+/* Static assertion, under a common name for both C++ and C11. */
+#ifdef __cplusplus
+# define support_static_assert static_assert
+#else
+# define support_static_assert _Static_assert
+#endif
+
+/* Compare the two integers LEFT and RIGHT and report failure if they
+ are different. */
+#define TEST_COMPARE(left, right) \
+ ({ \
+ /* + applies the integer promotions, for bitfield support. */ \
+ typedef __typeof__ (+ (left)) __left_type; \
+ typedef __typeof__ (+ (right)) __right_type; \
+ __left_type __left_value = (left); \
+ __right_type __right_value = (right); \
+ int __left_is_positive = __left_value > 0; \
+ int __right_is_positive = __right_value > 0; \
+ /* Prevent use with floating-point types. */ \
+ support_static_assert ((__left_type) 1.0 == (__left_type) 1.5, \
+ "left value has floating-point type"); \
+ support_static_assert ((__right_type) 1.0 == (__right_type) 1.5, \
+ "right value has floating-point type"); \
+ /* Prevent accidental use with larger-than-long long types. */ \
+ support_static_assert (sizeof (__left_value) <= sizeof (long long), \
+ "left value fits into long long"); \
+ support_static_assert (sizeof (__right_value) <= sizeof (long long), \
+ "right value fits into long long"); \
+ /* Compare the value. */ \
+ if (__left_value != __right_value \
+ || __left_is_positive != __right_is_positive) \
+ /* Pass the sign for printing the correct value. */ \
+ support_test_compare_failure \
+ (__FILE__, __LINE__, \
+ #left, __left_value, __left_is_positive, sizeof (__left_type), \
+ #right, __right_value, __right_is_positive, sizeof (__right_type)); \
+ })
+
+/* Internal implementation of TEST_COMPARE. LEFT_POSITIVE and
+ RIGHT_POSITIVE are used to store the sign separately, so that both
+ unsigned long long and long long arguments fit into LEFT_VALUE and
+ RIGHT_VALUE, and the function can still print the original value.
+ LEFT_SIZE and RIGHT_SIZE specify the size of the argument in bytes,
+ for hexadecimal formatting. */
+void support_test_compare_failure (const char *file, int line,
+ const char *left_expr,
+ long long left_value,
+ int left_positive,
+ int left_size,
+ const char *right_expr,
+ long long right_value,
+ int right_positive,
+ int right_size);
+
+
/* Internal function called by the test driver. */
int support_report_failure (int status)
__attribute__ ((weak, warn_unused_result));
diff --git a/support/check_addrinfo.c b/support/check_addrinfo.c
index 55895ace3c..91ad7c56bd 100644
--- a/support/check_addrinfo.c
+++ b/support/check_addrinfo.c
@@ -1,5 +1,5 @@
/* Compare struct addrinfo values against a formatted string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
diff --git a/support/check_dns_packet.c b/support/check_dns_packet.c
index d2a31bed7b..6c1277bd67 100644
--- a/support/check_dns_packet.c
+++ b/support/check_dns_packet.c
@@ -1,5 +1,5 @@
/* Check that a DNS packet buffer has the expected contents.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
diff --git a/support/check_hostent.c b/support/check_hostent.c
index 890d672d50..56384f9b03 100644
--- a/support/check_hostent.c
+++ b/support/check_hostent.c
@@ -1,5 +1,5 @@
/* Compare struct hostent values against a formatted string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
diff --git a/support/check_netent.c b/support/check_netent.c
index daa3083fd1..cbcbfb14e5 100644
--- a/support/check_netent.c
+++ b/support/check_netent.c
@@ -1,5 +1,5 @@
/* Compare struct netent values against a formatted string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
diff --git a/support/check_nss.h b/support/check_nss.h
index 2893f2c295..6aa28fa24e 100644
--- a/support/check_nss.h
+++ b/support/check_nss.h
@@ -1,5 +1,5 @@
/* Test verification functions for NSS- and DNS-related data.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/delayed_exit.c b/support/delayed_exit.c
index 67442f95df..2780d9a6fe 100644
--- a/support/delayed_exit.c
+++ b/support/delayed_exit.c
@@ -1,5 +1,5 @@
/* Time-triggered process termination.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/format_nss.h b/support/format_nss.h
index fb4597c238..e55354e788 100644
--- a/support/format_nss.h
+++ b/support/format_nss.h
@@ -1,5 +1,5 @@
/* String formatting functions for NSS- and DNS-related data.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/ignore_stderr.c b/support/ignore_stderr.c
index 7b77a2cd56..450333ad38 100644
--- a/support/ignore_stderr.c
+++ b/support/ignore_stderr.c
@@ -1,5 +1,5 @@
/* Avoid all the buffer overflow messages on stderr.
- Copyright (C) 2015-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/namespace.h b/support/namespace.h
index 859c2fda3f..3c3842a49b 100644
--- a/support/namespace.h
+++ b/support/namespace.h
@@ -1,5 +1,5 @@
/* Entering namespaces for test case isolation.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -51,6 +51,11 @@ bool support_can_chroot (void);
has sufficient privileges. */
bool support_enter_network_namespace (void);
+/* Enter a mount namespace and mark / as private (not shared). If
+ this function returns true, mount operations in this process will
+ not affect the host system afterwards. */
+bool support_enter_mount_namespace (void);
+
/* Return true if support_enter_network_namespace managed to enter a
UTS namespace. */
bool support_in_uts_namespace (void);
@@ -66,7 +71,9 @@ struct support_chroot_configuration
{
/* File contents. The files are not created if the field is
NULL. */
- const char *resolv_conf;
+ const char *resolv_conf; /* /etc/resolv.conf. */
+ const char *hosts; /* /etc/hosts. */
+ const char *host_conf; /* /etc/host.conf. */
};
/* The result of the creation of a chroot. */
@@ -78,8 +85,11 @@ struct support_chroot
/* Path to the chroot directory. */
char *path_chroot;
- /* Path to the /etc/resolv.conf file. */
- char *path_resolv_conf;
+ /* Paths to files in the chroot. These are absolute and outside of
+ the chroot. */
+ char *path_resolv_conf; /* /etc/resolv.conf. */
+ char *path_hosts; /* /etc/hosts. */
+ char *path_host_conf; /* /etc/host.conf. */
};
/* Create a chroot environment. The returned data should be freed
diff --git a/support/next_to_fault.c b/support/next_to_fault.c
new file mode 100644
index 0000000000..1971bf7cd7
--- /dev/null
+++ b/support/next_to_fault.c
@@ -0,0 +1,52 @@
+/* Memory allocation next to an unmapped page.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/next_to_fault.h>
+#include <support/xunistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+
+struct support_next_to_fault
+support_next_to_fault_allocate (size_t size)
+{
+ long page_size = sysconf (_SC_PAGE_SIZE);
+ TEST_VERIFY_EXIT (page_size > 0);
+ struct support_next_to_fault result;
+ result.region_size = roundup (size, page_size) + page_size;
+ if (size + page_size <= size || result.region_size <= size)
+ FAIL_EXIT1 ("support_next_to_fault_allocate (%zu): overflow", size);
+ result.region_start
+ = xmmap (NULL, result.region_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1);
+ /* Unmap the page after the allocation. */
+ xmprotect (result.region_start + (result.region_size - page_size),
+ page_size, PROT_NONE);
+ /* Align the allocation within the region so that it ends just
+ before the PROT_NONE page. */
+ result.buffer = result.region_start + result.region_size - page_size - size;
+ result.length = size;
+ return result;
+}
+
+void
+support_next_to_fault_free (struct support_next_to_fault *ntf)
+{
+ xmunmap (ntf->region_start, ntf->region_size);
+ *ntf = (struct support_next_to_fault) { NULL, };
+}
diff --git a/support/next_to_fault.h b/support/next_to_fault.h
new file mode 100644
index 0000000000..75759b586c
--- /dev/null
+++ b/support/next_to_fault.h
@@ -0,0 +1,48 @@
+/* Memory allocation next to an unmapped page.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef SUPPORT_NEXT_TO_FAULT_H
+#define SUPPORT_NEXT_TO_FAULT_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/* The memory region created by next_to_fault_allocate. */
+struct support_next_to_fault
+{
+ /* The user data. */
+ char *buffer;
+ size_t length;
+
+ /* The entire allocated region. */
+ void *region_start;
+ size_t region_size;
+};
+
+/* Allocate a buffer of SIZE bytes just before a page which is mapped
+ with PROT_NONE (so that overrunning the buffer will cause a
+ fault). */
+struct support_next_to_fault support_next_to_fault_allocate (size_t size);
+
+/* Deallocate the memory region allocated by
+ next_to_fault_allocate. */
+void support_next_to_fault_free (struct support_next_to_fault *);
+
+#endif /* SUPPORT_NEXT_TO_FAULT_H */
diff --git a/support/oom_error.c b/support/oom_error.c
index 7816978273..fd87fe2305 100644
--- a/support/oom_error.c
+++ b/support/oom_error.c
@@ -1,5 +1,5 @@
/* Reporting out-of-memory errors.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/resolv_test.c b/support/resolv_test.c
index 1625dcf43a..3f2a09f36f 100644
--- a/support/resolv_test.c
+++ b/support/resolv_test.c
@@ -1,5 +1,5 @@
/* DNS test framework and libresolv redirection.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -43,15 +43,99 @@ enum
max_response_length = 65536
};
-/* List of pointers to be freed. The hash table implementation
- (struct hsearch_data) does not provide a way to deallocate all
- objects, so this approach is used to avoid memory leaks. */
-struct to_be_freed
+/* Used for locating domain names containing for the purpose of
+ forming compression references. */
+struct compressed_name
{
- struct to_be_freed *next;
- void *ptr;
+ uint16_t offset;
+ unsigned char length;
+ unsigned char name[]; /* Without terminating NUL. */
};
+static struct compressed_name *
+allocate_compressed_name (const unsigned char *encoded, unsigned int offset)
+{
+ /* Compute the length of the domain name. */
+ size_t length;
+ {
+ const unsigned char *p;
+ for (p = encoded; *p != '\0';)
+ {
+ /* No compression references are allowed. */
+ TEST_VERIFY (*p <= 63);
+ /* Skip over the label. */
+ p += 1 + *p;
+ }
+ length = p - encoded;
+ ++length; /* For the terminating NUL byte. */
+ }
+ TEST_VERIFY_EXIT (length <= 255);
+
+ struct compressed_name *result
+ = xmalloc (offsetof (struct compressed_name, name) + length);
+ result->offset = offset;
+ result->length = length;
+ memcpy (result->name, encoded, length);
+ return result;
+}
+
+/* Convert CH to lower case. Only change letters in the ASCII
+ range. */
+static inline unsigned char
+ascii_tolower (unsigned char ch)
+{
+ if ('A' <= ch && ch <= 'Z')
+ return ch - 'A' + 'a';
+ else
+ return ch;
+}
+
+/* Compare both names, for use with tsearch. The order is arbitrary,
+ but the comparison is case-insenstive. */
+static int
+compare_compressed_name (const void *left, const void *right)
+{
+ const struct compressed_name *crleft = left;
+ const struct compressed_name *crright = right;
+
+ if (crleft->length != crright->length)
+ /* The operands are converted to int before the subtraction. */
+ return crleft->length - crright->length;
+
+ const unsigned char *nameleft = crleft->name;
+ const unsigned char *nameright = crright->name;
+
+ while (true)
+ {
+ int lenleft = *nameleft++;
+ int lenright = *nameright++;
+
+ /* Labels must not e compression references. */
+ TEST_VERIFY (lenleft <= 63);
+ TEST_VERIFY (lenright <= 63);
+
+ if (lenleft != lenright)
+ return left - right;
+ if (lenleft == 0)
+ /* End of name reached without spotting a difference. */
+ return 0;
+ /* Compare the label in a case-insenstive manner. */
+ const unsigned char *endnameleft = nameleft + lenleft;
+ while (nameleft < endnameleft)
+ {
+ int l = *nameleft++;
+ int r = *nameright++;
+ if (l != r)
+ {
+ l = ascii_tolower (l);
+ r = ascii_tolower (r);
+ if (l != r)
+ return l - r;
+ }
+ }
+ }
+}
+
struct resolv_response_builder
{
const unsigned char *query_buffer;
@@ -67,11 +151,8 @@ struct resolv_response_builder
written RDATA sub-structure. 0 if no RDATA is being written. */
size_t current_rdata_offset;
- /* Hash table for locating targets for label compression. */
- struct hsearch_data compression_offsets;
- /* List of pointers which need to be freed. Used for domain names
- involved in label compression. */
- struct to_be_freed *to_be_freed;
+ /* tsearch tree for locating targets for label compression. */
+ void *compression_offsets;
/* Must be last. Not zeroed for performance reasons. */
unsigned char buffer[max_response_length];
@@ -79,18 +160,6 @@ struct resolv_response_builder
/* Response builder. */
-/* Add a pointer to the list of pointers to be freed when B is
- deallocated. */
-static void
-response_push_pointer_to_free (struct resolv_response_builder *b, void *ptr)
-{
- if (ptr == NULL)
- return;
- struct to_be_freed *e = xmalloc (sizeof (*e));
- *e = (struct to_be_freed) {b->to_be_freed, ptr};
- b->to_be_freed = e;
-}
-
void
resolv_response_init (struct resolv_response_builder *b,
struct resolv_response_flags flags)
@@ -194,120 +263,88 @@ void
resolv_response_add_name (struct resolv_response_builder *b,
const char *const origname)
{
- /* Normalized name. */
- char *name;
- /* Normalized name with case preserved. */
- char *name_case;
- {
- size_t namelen = strlen (origname);
- /* Remove trailing dots. FIXME: Handle trailing quoted dots. */
- while (namelen > 0 && origname[namelen - 1] == '.')
- --namelen;
- name = xmalloc (namelen + 1);
- name_case = xmalloc (namelen + 1);
- /* Copy and convert to lowercase. FIXME: This needs to normalize
- escaping as well. */
- for (size_t i = 0; i < namelen; ++i)
- {
- char ch = origname[i];
- name_case[i] = ch;
- if ('A' <= ch && ch <= 'Z')
- ch = ch - 'A' + 'a';
- name[i] = ch;
- }
- name[namelen] = 0;
- name_case[namelen] = 0;
- }
- char *name_start = name;
- char *name_case_start = name_case;
+ unsigned char encoded_name[NS_MAXDNAME];
+ if (ns_name_pton (origname, encoded_name, sizeof (encoded_name)) < 0)
+ FAIL_EXIT1 ("ns_name_pton (\"%s\"): %m", origname);
- bool compression = false;
- while (*name)
+ /* Copy the encoded name into the output buffer, apply compression
+ where possible. */
+ for (const unsigned char *name = encoded_name; ;)
{
- /* Search for a previous name we can reference. */
- ENTRY new_entry =
+ if (*name == '\0')
{
- .key = name,
- .data = (void *) (uintptr_t) b->offset,
- };
+ /* We have reached the end of the name. Add the terminating
+ NUL byte. */
+ response_add_byte (b, '\0');
+ break;
+ }
- /* If the label can be a compression target because it is at a
- reachable offset, add it to the hash table. */
- ACTION action;
- if (b->offset < (1 << 12))
- action = ENTER;
- else
- action = FIND;
+ /* Set to the compression target if compression is possible. */
+ struct compressed_name *crname_target;
- /* Search for known compression offsets in the hash table. */
- ENTRY *e;
- if (hsearch_r (new_entry, action, &e, &b->compression_offsets) == 0)
- {
- if (action == FIND && errno == ESRCH)
- /* Fall through. */
- e = NULL;
- else
- FAIL_EXIT1 ("hsearch_r failure in name compression: %m");
- }
+ /* Compression references can only reach the beginning of the
+ packet. */
+ enum { compression_limit = 1 << 12 };
+
+ {
+ /* The trailing part of the name to be looked up in the tree
+ with the compression targets. */
+ struct compressed_name *crname
+ = allocate_compressed_name (name, b->offset);
+
+ if (b->offset < compression_limit)
+ {
+ /* Add the name to the tree, for future compression
+ references. */
+ void **ptr = tsearch (crname, &b->compression_offsets,
+ compare_compressed_name);
+ if (ptr == NULL)
+ FAIL_EXIT1 ("tsearch out of memory");
+ crname_target = *ptr;
+
+ if (crname_target != crname)
+ /* The new name was not actually added to the tree.
+ Deallocate it. */
+ free (crname);
+ else
+ /* Signal that the tree did not yet contain the name,
+ but keep the allocation because it is now part of the
+ tree. */
+ crname_target = NULL;
+ }
+ else
+ {
+ /* This name cannot be reached by a compression reference.
+ No need to add it to the tree for future reference. */
+ void **ptr = tfind (crname, &b->compression_offsets,
+ compare_compressed_name);
+ if (ptr != NULL)
+ crname_target = *ptr;
+ else
+ crname_target = NULL;
+ TEST_VERIFY (crname_target != crname);
+ /* Not added to the tree. */
+ free (crname);
+ }
+ }
- /* The name is known. Reference the previous location. */
- if (e != NULL && e->data != new_entry.data)
+ if (crname_target != NULL)
{
- size_t old_offset = (uintptr_t) e->data;
+ /* The name is known. Reference the previous location. */
+ unsigned int old_offset = crname_target->offset;
+ TEST_VERIFY_EXIT (old_offset < compression_limit);
response_add_byte (b, 0xC0 | (old_offset >> 8));
response_add_byte (b, old_offset);
- compression = true;
break;
}
-
- /* The name does not exist yet. Write one label. First, add
- room for the label length. */
- size_t buffer_label_offset = b->offset;
- response_add_byte (b, 0);
-
- /* Copy the label. */
- while (true)
+ else
{
- char ch = *name_case;
- if (ch == '\0')
- break;
- ++name;
- ++name_case;
- if (ch == '.')
- break;
- /* FIXME: Handle escaping. */
- response_add_byte (b, ch);
+ /* The name is new. Add this label. */
+ unsigned int len = 1 + *name;
+ resolv_response_add_data (b, name, len);
+ name += len;
}
-
- /* Patch in the label length. */
- size_t label_length = b->offset - buffer_label_offset - 1;
- if (label_length == 0)
- FAIL_EXIT1 ("empty label in name compression: %s", origname);
- if (label_length > 63)
- FAIL_EXIT1 ("label too long in name compression: %s", origname);
- b->buffer[buffer_label_offset] = label_length;
-
- /* Continue with the tail of the name and the next label. */
- }
-
- if (compression)
- {
- /* If we found an immediate match for the name, we have not put
- it into the hash table, and can free it immediately. */
- if (name == name_start)
- free (name_start);
- else
- response_push_pointer_to_free (b, name_start);
- }
- else
- {
- /* Terminate the sequence of labels. With compression, this is
- implicit in the compression reference. */
- response_add_byte (b, 0);
- response_push_pointer_to_free (b, name_start);
}
-
- free (name_case_start);
}
void
@@ -403,22 +440,13 @@ response_builder_allocate
memset (b, 0, offsetof (struct resolv_response_builder, buffer));
b->query_buffer = query_buffer;
b->query_length = query_length;
- TEST_VERIFY_EXIT (hcreate_r (10000, &b->compression_offsets) != 0);
return b;
}
static void
response_builder_free (struct resolv_response_builder *b)
{
- struct to_be_freed *current = b->to_be_freed;
- while (current != NULL)
- {
- struct to_be_freed *next = current->next;
- free (current->ptr);
- free (current);
- current = next;
- }
- hdestroy_r (&b->compression_offsets);
+ tdestroy (b->compression_offsets, free);
free (b);
}
diff --git a/support/resolv_test.h b/support/resolv_test.h
index b953dc1200..4c2e6c1b41 100644
--- a/support/resolv_test.h
+++ b/support/resolv_test.h
@@ -1,5 +1,5 @@
/* DNS test framework and libresolv redirection.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/run_diff.h b/support/run_diff.h
index f65b5dd22c..6e949226fa 100644
--- a/support/run_diff.h
+++ b/support/run_diff.h
@@ -1,5 +1,5 @@
/* Invoke the system diff tool to compare two strings.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/set_fortify_handler.c b/support/set_fortify_handler.c
index f434a8082a..c2dacbb179 100644
--- a/support/set_fortify_handler.c
+++ b/support/set_fortify_handler.c
@@ -1,5 +1,5 @@
/* Set signal handler for use in fortify tests.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support-xfstat.c b/support/support-xfstat.c
new file mode 100644
index 0000000000..f69253af09
--- /dev/null
+++ b/support/support-xfstat.c
@@ -0,0 +1,28 @@
+/* fstat64 with error checking.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/xunistd.h>
+#include <sys/stat.h>
+
+void
+xfstat (int fd, struct stat64 *result)
+{
+ if (fstat64 (fd, result) != 0)
+ FAIL_EXIT1 ("fstat64 (%d): %m", fd);
+}
diff --git a/support/support-xstat.c b/support/support-xstat.c
index 86a81ec601..fc10c6dcb7 100644
--- a/support/support-xstat.c
+++ b/support/support-xstat.c
@@ -1,5 +1,5 @@
/* stat64 with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support.h b/support/support.h
index 4b5f04c2cc..bc5827ed87 100644
--- a/support/support.h
+++ b/support/support.h
@@ -1,5 +1,5 @@
/* Common extra functions.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -68,6 +68,7 @@ void *xrealloc (void *p, size_t n);
char *xasprintf (const char *format, ...)
__attribute__ ((format (printf, 1, 2), malloc));
char *xstrdup (const char *);
+char *xstrndup (const char *, size_t);
__END_DECLS
diff --git a/support/support_become_root.c b/support/support_become_root.c
index 3fa0bd4ac0..6947dbaa80 100644
--- a/support/support_become_root.c
+++ b/support/support_become_root.c
@@ -1,5 +1,5 @@
/* Acquire root privileges.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -18,18 +18,80 @@
#include <support/namespace.h>
+#include <errno.h>
+#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xunistd.h>
#include <unistd.h>
+#ifdef CLONE_NEWUSER
+/* The necessary steps to allow file creation in user namespaces. */
+static void
+setup_uid_gid_mapping (uid_t original_uid, gid_t original_gid)
+{
+ int fd = open64 ("/proc/self/uid_map", O_WRONLY);
+ if (fd < 0)
+ {
+ printf ("warning: could not open /proc/self/uid_map: %m\n"
+ "warning: file creation may not be possible\n");
+ return;
+ }
+
+ /* We map our original UID to the same UID in the container so we
+ own our own files normally. Without that, file creation could
+ fail with EOVERFLOW (sic!). */
+ char buf[100];
+ int ret = snprintf (buf, sizeof (buf), "%llu %llu 1\n",
+ (unsigned long long) original_uid,
+ (unsigned long long) original_uid);
+ TEST_VERIFY_EXIT (ret < sizeof (buf));
+ xwrite (fd, buf, ret);
+ xclose (fd);
+
+ /* Linux 3.19 introduced the setgroups file. We need write "deny" to this
+ file otherwise writing to gid_map will fail with EPERM. */
+ fd = open64 ("/proc/self/setgroups", O_WRONLY, 0);
+ if (fd < 0)
+ {
+ if (errno != ENOENT)
+ FAIL_EXIT1 ("open64 (\"/proc/self/setgroups\", 0x%x, 0%o): %m",
+ O_WRONLY, 0);
+ /* This kernel doesn't expose the setgroups file so simply move on. */
+ }
+ else
+ {
+ xwrite (fd, "deny\n", strlen ("deny\n"));
+ xclose (fd);
+ }
+
+ /* Now map our own GID, like we did for the user ID. */
+ fd = xopen ("/proc/self/gid_map", O_WRONLY, 0);
+ ret = snprintf (buf, sizeof (buf), "%llu %llu 1\n",
+ (unsigned long long) original_gid,
+ (unsigned long long) original_gid);
+ TEST_VERIFY_EXIT (ret < sizeof (buf));
+ xwrite (fd, buf, ret);
+ xclose (fd);
+}
+#endif /* CLONE_NEWUSER */
+
bool
support_become_root (void)
{
#ifdef CLONE_NEWUSER
+ uid_t original_uid = getuid ();
+ gid_t original_gid = getgid ();
+
if (unshare (CLONE_NEWUSER | CLONE_NEWNS) == 0)
- /* Even if we do not have UID zero, we have extended privileges at
- this point. */
- return true;
+ {
+ setup_uid_gid_mapping (original_uid, original_gid);
+ /* Even if we do not have UID zero, we have extended privileges at
+ this point. */
+ return true;
+ }
#endif
if (setuid (0) != 0)
{
diff --git a/support/support_can_chroot.c b/support/support_can_chroot.c
index 0dfd2deb54..8922576d19 100644
--- a/support/support_can_chroot.c
+++ b/support/support_can_chroot.c
@@ -1,5 +1,5 @@
/* Return true if the process can perform a chroot operation.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
@@ -21,9 +21,9 @@
#include <support/check.h>
#include <support/namespace.h>
#include <support/support.h>
+#include <support/xunistd.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <xunistd.h>
static void
callback (void *closure)
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 030f124252..6d2029e13b 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -1,5 +1,5 @@
/* Capture output from a subprocess.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_capture_subprocess_check.c b/support/support_capture_subprocess_check.c
index e1cf73b6a5..ff5ee89fb0 100644
--- a/support/support_capture_subprocess_check.c
+++ b/support/support_capture_subprocess_check.c
@@ -1,5 +1,5 @@
/* Verify capture output from a subprocess.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_chroot.c b/support/support_chroot.c
index c0807b313a..6356b1af6c 100644
--- a/support/support_chroot.c
+++ b/support/support_chroot.c
@@ -1,5 +1,5 @@
/* Setup a chroot environment for use within tests.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
@@ -24,30 +24,38 @@
#include <support/test-driver.h>
#include <support/xunistd.h>
+/* If CONTENTS is not NULL, write it to the file at DIRECTORY/RELPATH,
+ and store the name in *ABSPATH. If CONTENTS is NULL, store NULL in
+ *ABSPATH. */
+static void
+write_file (const char *directory, const char *relpath, const char *contents,
+ char **abspath)
+{
+ if (contents != NULL)
+ {
+ *abspath = xasprintf ("%s/%s", directory, relpath);
+ add_temp_file (*abspath);
+ support_write_file_string (*abspath, contents);
+ }
+ else
+ *abspath = NULL;
+}
+
struct support_chroot *
support_chroot_create (struct support_chroot_configuration conf)
{
struct support_chroot *chroot = xmalloc (sizeof (*chroot));
-
- chroot->path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
- if (mkdtemp (chroot->path_chroot) == NULL)
- FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", chroot->path_chroot);
- add_temp_file (chroot->path_chroot);
+ chroot->path_chroot = support_create_temp_directory ("tst-resolv-res_init-");
/* Create the /etc directory in the chroot environment. */
char *path_etc = xasprintf ("%s/etc", chroot->path_chroot);
xmkdir (path_etc, 0777);
add_temp_file (path_etc);
- if (conf.resolv_conf != NULL)
- {
- /* Create an empty resolv.conf file. */
- chroot->path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc);
- add_temp_file (chroot->path_resolv_conf);
- support_write_file_string (chroot->path_resolv_conf, conf.resolv_conf);
- }
- else
- chroot->path_resolv_conf = NULL;
+ write_file (path_etc, "resolv.conf", conf.resolv_conf,
+ &chroot->path_resolv_conf);
+ write_file (path_etc, "hosts", conf.hosts, &chroot->path_hosts);
+ write_file (path_etc, "host.conf", conf.host_conf, &chroot->path_host_conf);
free (path_etc);
@@ -67,5 +75,7 @@ support_chroot_free (struct support_chroot *chroot)
{
free (chroot->path_chroot);
free (chroot->path_resolv_conf);
+ free (chroot->path_hosts);
+ free (chroot->path_host_conf);
free (chroot);
}
diff --git a/support/support_enter_mount_namespace.c b/support/support_enter_mount_namespace.c
new file mode 100644
index 0000000000..ba68e990f2
--- /dev/null
+++ b/support/support_enter_mount_namespace.c
@@ -0,0 +1,47 @@
+/* Enter a mount namespace.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/namespace.h>
+
+#include <sched.h>
+#include <stdio.h>
+#ifdef CLONE_NEWNS
+# include <sys/mount.h>
+#endif /* CLONE_NEWNS */
+
+bool
+support_enter_mount_namespace (void)
+{
+#ifdef CLONE_NEWNS
+ if (unshare (CLONE_NEWNS) == 0)
+ {
+ /* On some systems, / is marked as MS_SHARED, which means that
+ mounts within the namespace leak to the rest of the system,
+ which is not what we want. */
+ if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0)
+ {
+ printf ("warning: making the mount namespace private failed: %m\n");
+ return false;
+ }
+ return true;
+ }
+ else
+ printf ("warning: unshare (CLONE_NEWNS) failed: %m\n");
+#endif /* CLONE_NEWNS */
+ return false;
+}
diff --git a/support/support_enter_network_namespace.c b/support/support_enter_network_namespace.c
index 28b0ee29cf..1d874df885 100644
--- a/support/support_enter_network_namespace.c
+++ b/support/support_enter_network_namespace.c
@@ -1,5 +1,5 @@
/* Enter a network namespace.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_format_address_family.c b/support/support_format_address_family.c
index 5d42c42a45..2acb9afffd 100644
--- a/support/support_format_address_family.c
+++ b/support/support_format_address_family.c
@@ -1,5 +1,5 @@
/* Convert an address family to a string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_format_addrinfo.c b/support/support_format_addrinfo.c
index eedb030591..c5e00e516a 100644
--- a/support/support_format_addrinfo.c
+++ b/support/support_format_addrinfo.c
@@ -1,5 +1,5 @@
/* Convert struct addrinfo values to a string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -21,6 +21,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <support/support.h>
#include <support/xmemstream.h>
diff --git a/support/support_format_dns_packet.c b/support/support_format_dns_packet.c
index 2992c57971..1170eafb0f 100644
--- a/support/support_format_dns_packet.c
+++ b/support/support_format_dns_packet.c
@@ -1,5 +1,5 @@
/* Convert a DNS packet to a human-readable representation.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -20,6 +20,7 @@
#include <arpa/inet.h>
#include <resolv.h>
+#include <stdbool.h>
#include <support/check.h>
#include <support/support.h>
#include <support/xmemstream.h>
diff --git a/support/support_format_herrno.c b/support/support_format_herrno.c
index 493d6ae962..3d2dc8b27a 100644
--- a/support/support_format_herrno.c
+++ b/support/support_format_herrno.c
@@ -1,5 +1,5 @@
/* Convert a h_errno error code to a string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_format_hostent.c b/support/support_format_hostent.c
index 5b5f26082e..a4a62afe0a 100644
--- a/support/support_format_hostent.c
+++ b/support/support_format_hostent.c
@@ -1,5 +1,5 @@
/* Convert a struct hostent object to a string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -19,7 +19,9 @@
#include <support/format_nss.h>
#include <arpa/inet.h>
+#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <support/support.h>
#include <support/xmemstream.h>
@@ -41,10 +43,15 @@ support_format_hostent (struct hostent *h)
{
if (h == NULL)
{
- char *value = support_format_herrno (h_errno);
- char *result = xasprintf ("error: %s\n", value);
- free (value);
- return result;
+ if (h_errno == NETDB_INTERNAL)
+ return xasprintf ("error: NETDB_INTERNAL (errno %d, %m)\n", errno);
+ else
+ {
+ char *value = support_format_herrno (h_errno);
+ char *result = xasprintf ("error: %s\n", value);
+ free (value);
+ return result;
+ }
}
struct xmemstream mem;
diff --git a/support/support_format_netent.c b/support/support_format_netent.c
index 020f5720d9..0d15e78440 100644
--- a/support/support_format_netent.c
+++ b/support/support_format_netent.c
@@ -1,5 +1,5 @@
/* Convert a struct netent object to a string.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -20,6 +20,7 @@
#include <arpa/inet.h>
#include <stdio.h>
+#include <stdlib.h>
#include <support/support.h>
#include <support/xmemstream.h>
diff --git a/support/support_isolate_in_subprocess.c b/support/support_isolate_in_subprocess.c
index cf48614383..25edc00385 100644
--- a/support/support_isolate_in_subprocess.c
+++ b/support/support_isolate_in_subprocess.c
@@ -1,5 +1,5 @@
/* Run a function in a subprocess.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_record_failure.c b/support/support_record_failure.c
index 684055c746..356798f556 100644
--- a/support/support_record_failure.c
+++ b/support/support_record_failure.c
@@ -1,5 +1,5 @@
/* Global test failure counter.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_run_diff.c b/support/support_run_diff.c
index f5155de727..f24f6c3281 100644
--- a/support/support_run_diff.c
+++ b/support/support_run_diff.c
@@ -1,5 +1,5 @@
/* Invoke the system diff tool to compare two strings.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_shared_allocate.c b/support/support_shared_allocate.c
index 61d088e8cf..8ab43c4b38 100644
--- a/support/support_shared_allocate.c
+++ b/support/support_shared_allocate.c
@@ -1,5 +1,5 @@
/* Allocate a memory region shared across processes.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/support_test_compare_failure.c b/support/support_test_compare_failure.c
new file mode 100644
index 0000000000..8eb51c439d
--- /dev/null
+++ b/support/support_test_compare_failure.c
@@ -0,0 +1,58 @@
+/* Reporting a numeric comparison failure.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <support/check.h>
+
+static void
+report (const char *which, const char *expr, long long value, int positive,
+ int size)
+{
+ printf (" %s: ", which);
+ if (positive)
+ printf ("%llu", (unsigned long long) value);
+ else
+ printf ("%lld", value);
+ unsigned long long mask
+ = (~0ULL) >> (8 * (sizeof (unsigned long long) - size));
+ printf (" (0x%llx); from: %s\n", (unsigned long long) value & mask, expr);
+}
+
+void
+support_test_compare_failure (const char *file, int line,
+ const char *left_expr,
+ long long left_value,
+ int left_positive,
+ int left_size,
+ const char *right_expr,
+ long long right_value,
+ int right_positive,
+ int right_size)
+{
+ int saved_errno = errno;
+ support_record_failure ();
+ if (left_size != right_size)
+ printf ("%s:%d: numeric comparison failure (widths %d and %d)\n",
+ file, line, left_size * 8, right_size * 8);
+ else
+ printf ("%s:%d: numeric comparison failure\n", file, line);
+ report (" left", left_expr, left_value, left_positive, left_size);
+ report ("right", right_expr, right_value, right_positive, right_size);
+ errno = saved_errno;
+}
diff --git a/support/support_test_main.c b/support/support_test_main.c
index 3c411a467b..396385729b 100644
--- a/support/support_test_main.c
+++ b/support/support_test_main.c
@@ -1,5 +1,5 @@
/* Main worker function for the test driver.
- Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/support/support_test_verify_impl.c b/support/support_test_verify_impl.c
index 55ab2111b3..5ff5555a6a 100644
--- a/support/support_test_verify_impl.c
+++ b/support/support_test_verify_impl.c
@@ -1,5 +1,5 @@
/* Implementation of the TEST_VERIFY and TEST_VERIFY_EXIT macros.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -18,14 +18,17 @@
#include <support/check.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
void
support_test_verify_impl (const char *file, int line, const char *expr)
{
+ int saved_errno = errno;
support_record_failure ();
printf ("error: %s:%d: not true: %s\n", file, line, expr);
+ errno = saved_errno;
}
void
diff --git a/support/support_write_file_string.c b/support/support_write_file_string.c
index 48e89597f3..7505679401 100644
--- a/support/support_write_file_string.c
+++ b/support/support_write_file_string.c
@@ -1,5 +1,5 @@
/* Write a string to a file.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
@@ -19,7 +19,7 @@
#include <fcntl.h>
#include <string.h>
#include <support/check.h>
-#include <xunistd.h>
+#include <support/xunistd.h>
void
support_write_file_string (const char *path, const char *contents)
diff --git a/support/temp_file-internal.h b/support/temp_file-internal.h
index fb6cceb065..4cee3c0c35 100644
--- a/support/temp_file-internal.h
+++ b/support/temp_file-internal.h
@@ -1,5 +1,5 @@
/* Internal weak declarations for temporary file handling.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/temp_file.c b/support/temp_file.c
index fdb2477ab9..0bbc7f9972 100644
--- a/support/temp_file.c
+++ b/support/temp_file.c
@@ -1,5 +1,5 @@
/* Temporary file handling for tests.
- Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -86,6 +86,19 @@ create_temp_file (const char *base, char **filename)
return fd;
}
+char *
+support_create_temp_directory (const char *base)
+{
+ char *path = xasprintf ("%s/%sXXXXXX", test_dir, base);
+ if (mkdtemp (path) == NULL)
+ {
+ printf ("error: mkdtemp (\"%s\"): %m", path);
+ exit (1);
+ }
+ add_temp_file (path);
+ return path;
+}
+
/* Helper functions called by the test skeleton follow. */
void
diff --git a/support/temp_file.h b/support/temp_file.h
index 6fed8df1ea..c7795cc577 100644
--- a/support/temp_file.h
+++ b/support/temp_file.h
@@ -1,5 +1,5 @@
/* Declarations for temporary file handling.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -32,6 +32,11 @@ void add_temp_file (const char *name);
*FILENAME. */
int create_temp_file (const char *base, char **filename);
+/* Create a temporary directory and schedule it for deletion. BASE is
+ used as a prefix for the unique directory name, which the function
+ returns. The caller should free this string. */
+char *support_create_temp_directory (const char *base);
+
__END_DECLS
#endif /* SUPPORT_TEMP_FILE_H */
diff --git a/support/test-driver.c b/support/test-driver.c
index 47c387c2b4..09c8783e4f 100644
--- a/support/test-driver.c
+++ b/support/test-driver.c
@@ -1,5 +1,5 @@
/* Main function for test programs.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/test-driver.h b/support/test-driver.h
index a8fe9c3565..1708d68d60 100644
--- a/support/test-driver.h
+++ b/support/test-driver.h
@@ -1,5 +1,5 @@
/* Interfaces for the test driver.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/tst-support-namespace.c b/support/tst-support-namespace.c
index dbe7cc07c8..e20423c4a3 100644
--- a/support/tst-support-namespace.c
+++ b/support/tst-support-namespace.c
@@ -1,5 +1,5 @@
/* Test entering namespaces.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c
index 5672fba0f7..a685256091 100644
--- a/support/tst-support_capture_subprocess.c
+++ b/support/tst-support_capture_subprocess.c
@@ -1,5 +1,5 @@
/* Test capturing output from a subprocess.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/tst-support_format_dns_packet.c b/support/tst-support_format_dns_packet.c
index 9c8589c09c..b1135eebc6 100644
--- a/support/tst-support_format_dns_packet.c
+++ b/support/tst-support_format_dns_packet.c
@@ -1,5 +1,5 @@
/* Tests for the support_format_dns_packet function.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/tst-support_record_failure-2.sh b/support/tst-support_record_failure-2.sh
index 2c9372cc29..09cd96290a 100644
--- a/support/tst-support_record_failure-2.sh
+++ b/support/tst-support_record_failure-2.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Test failure recording (with and without --direct).
-# Copyright (C) 2016-2017 Free Software Foundation, Inc.
+# 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
diff --git a/support/tst-support_record_failure.c b/support/tst-support_record_failure.c
index e739e739c3..8757f2da02 100644
--- a/support/tst-support_record_failure.c
+++ b/support/tst-support_record_failure.c
@@ -1,5 +1,5 @@
/* Test support_record_failure state sharing.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/tst-test_compare.c b/support/tst-test_compare.c
new file mode 100644
index 0000000000..123ba1bc3c
--- /dev/null
+++ b/support/tst-test_compare.c
@@ -0,0 +1,116 @@
+/* Basic test for the TEST_COMPARE macro.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <support/check.h>
+#include <support/capture_subprocess.h>
+
+static void
+subprocess (void *closure)
+{
+ char ch = 1;
+ /* These tests should fail. */
+ TEST_COMPARE (ch, -1); /* Line 28. */
+ TEST_COMPARE (2LL, -2LL); /* Line 29. */
+ TEST_COMPARE (3LL, (short) -3); /* Line 30. */
+}
+
+struct bitfield
+{
+ int i2 : 2;
+ int i3 : 3;
+ unsigned int u2 : 2;
+ unsigned int u3 : 3;
+ int i31 : 31;
+ unsigned int u31 : 31 ;
+ long long int i63 : 63;
+ unsigned long long int u63 : 63;
+};
+
+/* Functions which return signed sizes are common, so test that these
+ results can readily checked using TEST_COMPARE. */
+
+static int
+return_ssize_t (void)
+{
+ return 4;
+}
+
+static int
+return_int (void)
+{
+ return 4;
+}
+
+
+static int
+do_test (void)
+{
+ /* This should succeed. */
+ TEST_COMPARE (1, 1);
+ TEST_COMPARE (2LL, 2U);
+ {
+ char i8 = 3;
+ unsigned short u16 = 3;
+ TEST_COMPARE (i8, u16);
+ }
+ TEST_COMPARE (return_ssize_t (), sizeof (char[4]));
+ TEST_COMPARE (return_int (), sizeof (char[4]));
+
+ struct bitfield bitfield = { 0 };
+ TEST_COMPARE (bitfield.i2, bitfield.i3);
+ TEST_COMPARE (bitfield.u2, bitfield.u3);
+ TEST_COMPARE (bitfield.u2, bitfield.i3);
+ TEST_COMPARE (bitfield.u3, bitfield.i3);
+ TEST_COMPARE (bitfield.i2, bitfield.u3);
+ TEST_COMPARE (bitfield.i3, bitfield.u2);
+ TEST_COMPARE (bitfield.i63, bitfield.i63);
+ TEST_COMPARE (bitfield.u63, bitfield.u63);
+ TEST_COMPARE (bitfield.i31, bitfield.i63);
+ TEST_COMPARE (bitfield.i63, bitfield.i31);
+
+ struct support_capture_subprocess proc = support_capture_subprocess
+ (&subprocess, NULL);
+
+ /* Discard the reported error. */
+ support_record_failure_reset ();
+
+ puts ("info: *** subprocess output starts ***");
+ fputs (proc.out.buffer, stdout);
+ puts ("info: *** subprocess output ends ***");
+
+ TEST_VERIFY
+ (strcmp (proc.out.buffer,
+ "tst-test_compare.c:28: numeric comparison failure\n"
+ " left: 1 (0x1); from: ch\n"
+ " right: -1 (0xffffffff); from: -1\n"
+ "tst-test_compare.c:29: numeric comparison failure\n"
+ " left: 2 (0x2); from: 2LL\n"
+ " right: -2 (0xfffffffffffffffe); from: -2LL\n"
+ "tst-test_compare.c:30: numeric comparison failure"
+ " (widths 64 and 32)\n"
+ " left: 3 (0x3); from: 3LL\n"
+ " right: -3 (0xfffffffd); from: (short) -3\n") == 0);
+
+ /* Check that there is no output on standard error. */
+ support_capture_subprocess_check (&proc, "TEST_COMPARE", 0, sc_allow_stdout);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/support/tst-xreadlink.c b/support/tst-xreadlink.c
new file mode 100644
index 0000000000..b142207228
--- /dev/null
+++ b/support/tst-xreadlink.c
@@ -0,0 +1,72 @@
+/* Test the xreadlink function.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+
+static int
+do_test (void)
+{
+ char *dir = support_create_temp_directory ("tst-xreadlink-");
+ char *symlink_name = xasprintf ("%s/symlink", dir);
+ add_temp_file (symlink_name);
+
+ /* The limit 10000 is arbitrary and simply there to prevent an
+ attempt to exhaust all available disk space. */
+ for (int size = 1; size < 10000; ++size)
+ {
+ char *contents = xmalloc (size + 1);
+ for (int i = 0; i < size; ++i)
+ contents[i] = 'a' + (rand () % 26);
+ contents[size] = '\0';
+ if (symlink (contents, symlink_name) != 0)
+ {
+ if (errno == ENAMETOOLONG)
+ {
+ printf ("info: ENAMETOOLONG failure at %d bytes\n", size);
+ free (contents);
+ break;
+ }
+ FAIL_EXIT1 ("symlink (%d bytes): %m", size);
+ }
+
+ char *readlink_result = xreadlink (symlink_name);
+ TEST_VERIFY (strcmp (readlink_result, contents) == 0);
+ free (readlink_result);
+ xunlink (symlink_name);
+ free (contents);
+ }
+
+ /* Create an empty file to suppress the temporary file deletion
+ warning. */
+ xclose (xopen (symlink_name, O_WRONLY | O_CREAT, 0));
+
+ free (symlink_name);
+ free (dir);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/support/write_message.c b/support/write_message.c
index f03ed931d6..a3e2f90535 100644
--- a/support/write_message.c
+++ b/support/write_message.c
@@ -1,5 +1,5 @@
/* Write a message to standard output.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -18,12 +18,15 @@
#include <support/support.h>
+#include <errno.h>
#include <string.h>
#include <unistd.h>
void
write_message (const char *message)
{
+ int saved_errno = errno;
ssize_t unused __attribute__ ((unused));
unused = write (STDOUT_FILENO, message, strlen (message));
+ errno = saved_errno;
}
diff --git a/support/xaccept.c b/support/xaccept.c
index 7b25af3b05..fd65fc6c3a 100644
--- a/support/xaccept.c
+++ b/support/xaccept.c
@@ -1,5 +1,5 @@
/* accept with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xaccept4.c b/support/xaccept4.c
index 67dd95e9fb..ada3c92267 100644
--- a/support/xaccept4.c
+++ b/support/xaccept4.c
@@ -1,5 +1,5 @@
/* accept4 with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xasprintf.c b/support/xasprintf.c
index 5157680fa2..e593ec5e82 100644
--- a/support/xasprintf.c
+++ b/support/xasprintf.c
@@ -1,5 +1,5 @@
/* Error-checking wrapper for asprintf.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xbind.c b/support/xbind.c
index cfc6dd8fa8..938e7c07d6 100644
--- a/support/xbind.c
+++ b/support/xbind.c
@@ -1,5 +1,5 @@
/* bind with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xcalloc.c b/support/xcalloc.c
index 135f42dab2..403569041f 100644
--- a/support/xcalloc.c
+++ b/support/xcalloc.c
@@ -1,5 +1,5 @@
/* Error-checking wrapper for calloc.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xchroot.c b/support/xchroot.c
index abcc299e00..d4759a1bd1 100644
--- a/support/xchroot.c
+++ b/support/xchroot.c
@@ -1,5 +1,5 @@
/* chroot with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xclose.c b/support/xclose.c
index c931e08421..702bef6c6e 100644
--- a/support/xclose.c
+++ b/support/xclose.c
@@ -1,5 +1,5 @@
/* close with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xconnect.c b/support/xconnect.c
index 0266dbc643..341805d80d 100644
--- a/support/xconnect.c
+++ b/support/xconnect.c
@@ -1,5 +1,5 @@
/* connect with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xdlfcn.c b/support/xdlfcn.c
new file mode 100644
index 0000000000..f34bb059c0
--- /dev/null
+++ b/support/xdlfcn.c
@@ -0,0 +1,59 @@
+/* Support functionality for using dlopen/dlclose/dlsym.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+#include <support/check.h>
+#include <support/xdlfcn.h>
+
+void *
+xdlopen (const char *filename, int flags)
+{
+ void *dso = dlopen (filename, flags);
+
+ if (dso == NULL)
+ FAIL_EXIT1 ("error: dlopen: %s\n", dlerror ());
+
+ /* Clear any errors. */
+ dlerror ();
+
+ return dso;
+}
+
+void *
+xdlsym (void *handle, const char *symbol)
+{
+ void *sym = dlsym (handle, symbol);
+
+ if (sym == NULL)
+ FAIL_EXIT1 ("error: dlsym: %s\n", dlerror ());
+
+ /* Clear any errors. */
+ dlerror ();
+
+ return sym;
+}
+
+void
+xdlclose (void *handle)
+{
+ if (dlclose (handle) != 0)
+ FAIL_EXIT1 ("error: dlclose: %s\n", dlerror ());
+
+ /* Clear any errors. */
+ dlerror ();
+}
diff --git a/support/xdlfcn.h b/support/xdlfcn.h
new file mode 100644
index 0000000000..5ab7494e70
--- /dev/null
+++ b/support/xdlfcn.h
@@ -0,0 +1,34 @@
+/* Support functionality for using dlopen/dlclose/dlsym.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef SUPPORT_DLOPEN_H
+#define SUPPORT_DLOPEN_H
+
+#include <dlfcn.h>
+
+__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 xdlclose (void *handle);
+
+
+__END_DECLS
+
+#endif /* SUPPORT_DLOPEN_H */
diff --git a/support/xdup2.c b/support/xdup2.c
index dc08c94518..b8c4c223fb 100644
--- a/support/xdup2.c
+++ b/support/xdup2.c
@@ -1,5 +1,5 @@
/* dup2 with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xfclose.c b/support/xfclose.c
index 2737f05044..39d46f042a 100644
--- a/support/xfclose.c
+++ b/support/xfclose.c
@@ -1,5 +1,5 @@
/* fclose with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xfopen.c b/support/xfopen.c
index 14532a09f3..fb931cf22b 100644
--- a/support/xfopen.c
+++ b/support/xfopen.c
@@ -1,5 +1,5 @@
/* fopen with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xfork.c b/support/xfork.c
index aa52ba62c5..dffa2a13d0 100644
--- a/support/xfork.c
+++ b/support/xfork.c
@@ -1,5 +1,5 @@
/* fork with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xftruncate.c b/support/xftruncate.c
new file mode 100644
index 0000000000..27c7e12ba2
--- /dev/null
+++ b/support/xftruncate.c
@@ -0,0 +1,27 @@
+/* ftruncate with error checking.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/xunistd.h>
+
+void
+xftruncate (int fd, long long length)
+{
+ if (ftruncate64 (fd, length) != 0)
+ FAIL_EXIT1 ("ftruncate64 (%d, %lld): %m", fd, length);
+}
diff --git a/support/xgetsockname.c b/support/xgetsockname.c
index c3bd884f8d..797194f79d 100644
--- a/support/xgetsockname.c
+++ b/support/xgetsockname.c
@@ -1,5 +1,5 @@
/* getsockname with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xlisten.c b/support/xlisten.c
index 1953e5900a..aa70091adb 100644
--- a/support/xlisten.c
+++ b/support/xlisten.c
@@ -1,5 +1,5 @@
/* listen with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xlseek.c b/support/xlseek.c
new file mode 100644
index 0000000000..2422939908
--- /dev/null
+++ b/support/xlseek.c
@@ -0,0 +1,29 @@
+/* lseek with error checking.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/xunistd.h>
+
+long long
+xlseek (int fd, long long offset, int whence)
+{
+ long long result = lseek64 (fd, offset, whence);
+ if (result < 0)
+ FAIL_EXIT1 ("lseek64 (%d, %lld, %d): %m", fd, offset, whence);
+ return result;
+}
diff --git a/support/xmalloc.c b/support/xmalloc.c
index 450f699789..78317e2b12 100644
--- a/support/xmalloc.c
+++ b/support/xmalloc.c
@@ -1,5 +1,5 @@
/* Error-checking wrapper for malloc.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xmemstream.c b/support/xmemstream.c
index bce6dc9170..df5fbc489a 100644
--- a/support/xmemstream.c
+++ b/support/xmemstream.c
@@ -1,5 +1,5 @@
/* Error-checking wrappers for memstream functions.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xmemstream.h b/support/xmemstream.h
index e5ba231e4d..2d4a577f29 100644
--- a/support/xmemstream.h
+++ b/support/xmemstream.h
@@ -1,5 +1,5 @@
/* Error-checking wrappers for memstream functions.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xmkdir.c b/support/xmkdir.c
index ea17d49391..7e67f783de 100644
--- a/support/xmkdir.c
+++ b/support/xmkdir.c
@@ -1,5 +1,5 @@
/* mkdir with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xmmap.c b/support/xmmap.c
index 435b1eb733..d580c07013 100644
--- a/support/xmmap.c
+++ b/support/xmmap.c
@@ -1,5 +1,5 @@
/* mmap with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xmprotect.c b/support/xmprotect.c
index 9410251c32..e6870988e0 100644
--- a/support/xmprotect.c
+++ b/support/xmprotect.c
@@ -1,5 +1,5 @@
/* mprotect with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xmunmap.c b/support/xmunmap.c
index 6ef5a4a468..e8e5bc2d59 100644
--- a/support/xmunmap.c
+++ b/support/xmunmap.c
@@ -1,5 +1,5 @@
/* munmap with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xopen.c b/support/xopen.c
index 7f033a03a7..3d888e8862 100644
--- a/support/xopen.c
+++ b/support/xopen.c
@@ -1,5 +1,5 @@
/* open64 with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpipe.c b/support/xpipe.c
index 89a64a55c1..b8529df620 100644
--- a/support/xpipe.c
+++ b/support/xpipe.c
@@ -1,5 +1,5 @@
/* pipe with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpoll.c b/support/xpoll.c
index bec2521ffc..b24bf32fc5 100644
--- a/support/xpoll.c
+++ b/support/xpoll.c
@@ -1,5 +1,5 @@
/* poll with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_attr_destroy.c b/support/xpthread_attr_destroy.c
index 664c809e9f..52aa2602fe 100644
--- a/support/xpthread_attr_destroy.c
+++ b/support/xpthread_attr_destroy.c
@@ -1,5 +1,5 @@
/* pthread_attr_destroy with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_attr_init.c b/support/xpthread_attr_init.c
index 2e30ade9ab..c7aa903db2 100644
--- a/support/xpthread_attr_init.c
+++ b/support/xpthread_attr_init.c
@@ -1,5 +1,5 @@
/* pthread_attr_init with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_attr_setdetachstate.c b/support/xpthread_attr_setdetachstate.c
index b544dbaa42..6e845acc97 100644
--- a/support/xpthread_attr_setdetachstate.c
+++ b/support/xpthread_attr_setdetachstate.c
@@ -1,5 +1,5 @@
/* pthread_attr_setdetachstate with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_attr_setguardsize.c b/support/xpthread_attr_setguardsize.c
index 35fed5d9ec..964ec058c9 100644
--- a/support/xpthread_attr_setguardsize.c
+++ b/support/xpthread_attr_setguardsize.c
@@ -1,5 +1,5 @@
/* pthread_attr_setguardsize with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_attr_setstacksize.c b/support/xpthread_attr_setstacksize.c
index 02d06310a9..c5517c0c66 100644
--- a/support/xpthread_attr_setstacksize.c
+++ b/support/xpthread_attr_setstacksize.c
@@ -1,5 +1,5 @@
/* pthread_attr_setstacksize with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_barrier_destroy.c b/support/xpthread_barrier_destroy.c
index efc0719a63..1dae148b46 100644
--- a/support/xpthread_barrier_destroy.c
+++ b/support/xpthread_barrier_destroy.c
@@ -1,5 +1,5 @@
/* pthread_barrier_destroy with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_barrier_init.c b/support/xpthread_barrier_init.c
index b32dad1315..4a2975ad12 100644
--- a/support/xpthread_barrier_init.c
+++ b/support/xpthread_barrier_init.c
@@ -1,5 +1,5 @@
/* pthread_barrier_init with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_barrier_wait.c b/support/xpthread_barrier_wait.c
index 7cee44d0a3..61690c5e7c 100644
--- a/support/xpthread_barrier_wait.c
+++ b/support/xpthread_barrier_wait.c
@@ -1,5 +1,5 @@
/* pthread_barrier_wait with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_cancel.c b/support/xpthread_cancel.c
index 3af16f9b54..26e864ea3e 100644
--- a/support/xpthread_cancel.c
+++ b/support/xpthread_cancel.c
@@ -1,5 +1,5 @@
/* pthread_cancel with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_check_return.c b/support/xpthread_check_return.c
index 3094d82e9c..1658db4b62 100644
--- a/support/xpthread_check_return.c
+++ b/support/xpthread_check_return.c
@@ -1,5 +1,5 @@
/* Return value checking for pthread functions, exit variant.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_cond_wait.c b/support/xpthread_cond_wait.c
index b0e9b2a232..08ec683b66 100644
--- a/support/xpthread_cond_wait.c
+++ b/support/xpthread_cond_wait.c
@@ -1,5 +1,5 @@
/* pthread_cond_wait with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_create.c b/support/xpthread_create.c
index 98c63e54c3..24b8456db9 100644
--- a/support/xpthread_create.c
+++ b/support/xpthread_create.c
@@ -1,5 +1,5 @@
/* pthread_create with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_detach.c b/support/xpthread_detach.c
index 2088af2f57..c65f2d7db1 100644
--- a/support/xpthread_detach.c
+++ b/support/xpthread_detach.c
@@ -1,5 +1,5 @@
/* pthread_detach with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_join.c b/support/xpthread_join.c
index f23bb9a5ae..29acbd283a 100644
--- a/support/xpthread_join.c
+++ b/support/xpthread_join.c
@@ -1,5 +1,5 @@
/* pthread_join with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutex_consistent.c b/support/xpthread_mutex_consistent.c
index 52364be365..d337163609 100644
--- a/support/xpthread_mutex_consistent.c
+++ b/support/xpthread_mutex_consistent.c
@@ -1,5 +1,5 @@
/* pthread_mutex_consistent with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutex_destroy.c b/support/xpthread_mutex_destroy.c
index f11f8f0acd..d03f016629 100644
--- a/support/xpthread_mutex_destroy.c
+++ b/support/xpthread_mutex_destroy.c
@@ -1,5 +1,5 @@
/* pthread_mutex_destroy with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutex_init.c b/support/xpthread_mutex_init.c
index 2d16d1b9d9..40855954a8 100644
--- a/support/xpthread_mutex_init.c
+++ b/support/xpthread_mutex_init.c
@@ -1,5 +1,5 @@
/* pthread_mutex_init with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutex_lock.c b/support/xpthread_mutex_lock.c
index af727b45f3..4257960aaa 100644
--- a/support/xpthread_mutex_lock.c
+++ b/support/xpthread_mutex_lock.c
@@ -1,5 +1,5 @@
/* pthread_mutex_lock with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutex_unlock.c b/support/xpthread_mutex_unlock.c
index 161b41edf6..5c385c6934 100644
--- a/support/xpthread_mutex_unlock.c
+++ b/support/xpthread_mutex_unlock.c
@@ -1,5 +1,5 @@
/* pthread_mutex_unlock with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutexattr_destroy.c b/support/xpthread_mutexattr_destroy.c
index c699e32b41..f352a7ad93 100644
--- a/support/xpthread_mutexattr_destroy.c
+++ b/support/xpthread_mutexattr_destroy.c
@@ -1,5 +1,5 @@
/* pthread_mutexattr_destroy with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutexattr_init.c b/support/xpthread_mutexattr_init.c
index fa93fab178..fe231581e3 100644
--- a/support/xpthread_mutexattr_init.c
+++ b/support/xpthread_mutexattr_init.c
@@ -1,5 +1,5 @@
/* pthread_mutexattr_init with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutexattr_setprotocol.c b/support/xpthread_mutexattr_setprotocol.c
index 353f75e3d7..e2f544d38c 100644
--- a/support/xpthread_mutexattr_setprotocol.c
+++ b/support/xpthread_mutexattr_setprotocol.c
@@ -1,5 +1,5 @@
/* pthread_mutexattr_setprotocol with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutexattr_setpshared.c b/support/xpthread_mutexattr_setpshared.c
index 242da1aeca..2380560d79 100644
--- a/support/xpthread_mutexattr_setpshared.c
+++ b/support/xpthread_mutexattr_setpshared.c
@@ -1,5 +1,5 @@
/* pthread_mutexattr_setpshared with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutexattr_setrobust.c b/support/xpthread_mutexattr_setrobust.c
index d7d6fa8630..7886c72a77 100644
--- a/support/xpthread_mutexattr_setrobust.c
+++ b/support/xpthread_mutexattr_setrobust.c
@@ -1,5 +1,5 @@
/* pthread_mutexattr_setrobust with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_mutexattr_settype.c b/support/xpthread_mutexattr_settype.c
index cf22170b56..91f790c9e5 100644
--- a/support/xpthread_mutexattr_settype.c
+++ b/support/xpthread_mutexattr_settype.c
@@ -1,5 +1,5 @@
/* pthread_mutexattr_settype with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_once.c b/support/xpthread_once.c
index 70d58dbab2..b22c1ce3dd 100644
--- a/support/xpthread_once.c
+++ b/support/xpthread_once.c
@@ -1,5 +1,5 @@
/* pthread_once with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_rwlock_init.c b/support/xpthread_rwlock_init.c
index 824288c90e..e6c38115d8 100644
--- a/support/xpthread_rwlock_init.c
+++ b/support/xpthread_rwlock_init.c
@@ -1,5 +1,5 @@
/* pthread_rwlock_init with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_rwlock_rdlock.c b/support/xpthread_rwlock_rdlock.c
index 96330a5637..a88068fc86 100644
--- a/support/xpthread_rwlock_rdlock.c
+++ b/support/xpthread_rwlock_rdlock.c
@@ -1,5 +1,5 @@
/* pthread_rwlock_rdlock with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_rwlock_unlock.c b/support/xpthread_rwlock_unlock.c
index eaa136b3ec..7eb282fd18 100644
--- a/support/xpthread_rwlock_unlock.c
+++ b/support/xpthread_rwlock_unlock.c
@@ -1,5 +1,5 @@
/* pthread_rwlock_unlock with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_rwlock_wrlock.c b/support/xpthread_rwlock_wrlock.c
index 8d25d5b818..0de37146c3 100644
--- a/support/xpthread_rwlock_wrlock.c
+++ b/support/xpthread_rwlock_wrlock.c
@@ -1,5 +1,5 @@
/* pthread_rwlock_wrlock with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_rwlockattr_init.c b/support/xpthread_rwlockattr_init.c
index 48baf247f3..96ac47d777 100644
--- a/support/xpthread_rwlockattr_init.c
+++ b/support/xpthread_rwlockattr_init.c
@@ -1,5 +1,5 @@
/* pthread_rwlockattr_init with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_rwlockattr_setkind_np.c b/support/xpthread_rwlockattr_setkind_np.c
index 958aace9f6..34aa3df0a9 100644
--- a/support/xpthread_rwlockattr_setkind_np.c
+++ b/support/xpthread_rwlockattr_setkind_np.c
@@ -1,5 +1,5 @@
/* pthread_rwlockattr_setkind_np with error checking.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_sigmask.c b/support/xpthread_sigmask.c
index 0ba9ca02dc..1fb91dcc20 100644
--- a/support/xpthread_sigmask.c
+++ b/support/xpthread_sigmask.c
@@ -1,5 +1,5 @@
/* pthread_sigmask with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_spin_lock.c b/support/xpthread_spin_lock.c
index 6975215b17..4cadbf70f9 100644
--- a/support/xpthread_spin_lock.c
+++ b/support/xpthread_spin_lock.c
@@ -1,5 +1,5 @@
/* pthread_spin_lock with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xpthread_spin_unlock.c b/support/xpthread_spin_unlock.c
index 4f19a44c48..194613993a 100644
--- a/support/xpthread_spin_unlock.c
+++ b/support/xpthread_spin_unlock.c
@@ -1,5 +1,5 @@
/* pthread_spin_unlock with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xraise.c b/support/xraise.c
new file mode 100644
index 0000000000..1901e741eb
--- /dev/null
+++ b/support/xraise.c
@@ -0,0 +1,27 @@
+/* Error-checking wrapper for raise.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/xsignal.h>
+
+void
+xraise (int sig)
+{
+ if (raise (sig) != 0)
+ FAIL_EXIT1 ("raise (%d): %m" , sig);
+}
diff --git a/support/xreadlink.c b/support/xreadlink.c
new file mode 100644
index 0000000000..c6386491db
--- /dev/null
+++ b/support/xreadlink.c
@@ -0,0 +1,44 @@
+/* Error-checking, allocating wrapper for readlink.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <scratch_buffer.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <xunistd.h>
+
+char *
+xreadlink (const char *path)
+{
+ struct scratch_buffer buf;
+ scratch_buffer_init (&buf);
+
+ while (true)
+ {
+ ssize_t count = readlink (path, buf.data, buf.length);
+ if (count < 0)
+ FAIL_EXIT1 ("readlink (\"%s\"): %m", path);
+ if (count < buf.length)
+ {
+ char *result = xstrndup (buf.data, count);
+ scratch_buffer_free (&buf);
+ return result;
+ }
+ if (!scratch_buffer_grow (&buf))
+ FAIL_EXIT1 ("scratch_buffer_grow in xreadlink");
+ }
+}
diff --git a/support/xrealloc.c b/support/xrealloc.c
index 00c313880c..4d9987c9bb 100644
--- a/support/xrealloc.c
+++ b/support/xrealloc.c
@@ -1,5 +1,5 @@
/* Error-checking wrapper for realloc.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xrecvfrom.c b/support/xrecvfrom.c
index 17809c4dd2..a1011a5062 100644
--- a/support/xrecvfrom.c
+++ b/support/xrecvfrom.c
@@ -1,5 +1,5 @@
/* recvfrom with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xsendto.c b/support/xsendto.c
index 20bddf6965..f51530793e 100644
--- a/support/xsendto.c
+++ b/support/xsendto.c
@@ -1,5 +1,5 @@
/* sendto with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xsetsockopt.c b/support/xsetsockopt.c
index 9931882e75..b7c07f21f9 100644
--- a/support/xsetsockopt.c
+++ b/support/xsetsockopt.c
@@ -1,5 +1,5 @@
/* setsockopt with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xsigaction.c b/support/xsigaction.c
new file mode 100644
index 0000000000..51657de2b7
--- /dev/null
+++ b/support/xsigaction.c
@@ -0,0 +1,27 @@
+/* Error-checking wrapper for sigaction.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/xsignal.h>
+
+void
+xsigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
+{
+ if (sigaction (sig, newact, oldact))
+ FAIL_EXIT1 ("sigaction (%d): %m" , sig);
+}
diff --git a/support/xsignal.c b/support/xsignal.c
new file mode 100644
index 0000000000..e7369f0324
--- /dev/null
+++ b/support/xsignal.c
@@ -0,0 +1,29 @@
+/* Error-checking wrapper for signal.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/xsignal.h>
+
+sighandler_t
+xsignal (int sig, sighandler_t handler)
+{
+ sighandler_t result = signal (sig, handler);
+ if (result == SIG_ERR)
+ FAIL_EXIT1 ("signal (%d, %p): %m", sig, handler);
+ return result;
+}
diff --git a/support/xsignal.h b/support/xsignal.h
index 3dc0d9d5ce..9ab8d1bfdd 100644
--- a/support/xsignal.h
+++ b/support/xsignal.h
@@ -1,5 +1,5 @@
/* Support functionality for using signals.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -24,6 +24,14 @@
__BEGIN_DECLS
+/* The following functions call the corresponding libc functions and
+ terminate the process on error. */
+
+void xraise (int sig);
+sighandler_t xsignal (int sig, sighandler_t handler);
+void xsigaction (int sig, const struct sigaction *newact,
+ struct sigaction *oldact);
+
/* The following functions call the corresponding libpthread functions
and terminate the process on error. */
diff --git a/support/xsocket.c b/support/xsocket.c
index c1deaee924..20282fb810 100644
--- a/support/xsocket.c
+++ b/support/xsocket.c
@@ -1,5 +1,5 @@
/* socket with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xsocket.h b/support/xsocket.h
index d6724948d8..9673abdf54 100644
--- a/support/xsocket.h
+++ b/support/xsocket.h
@@ -1,5 +1,5 @@
/* Error-checking wrappers for socket functions.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xstdio.h b/support/xstdio.h
index bcc2e863bf..e7d0274474 100644
--- a/support/xstdio.h
+++ b/support/xstdio.h
@@ -1,5 +1,5 @@
/* Error-checking wrappers for stdio functions.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xstrdup.c b/support/xstrdup.c
index d6a8c04baf..89eee8584e 100644
--- a/support/xstrdup.c
+++ b/support/xstrdup.c
@@ -1,5 +1,5 @@
/* strdup with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xstrndup.c b/support/xstrndup.c
new file mode 100644
index 0000000000..e85fddd439
--- /dev/null
+++ b/support/xstrndup.c
@@ -0,0 +1,30 @@
+/* strndup with error checking.
+ 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/support.h>
+
+#include <string.h>
+
+char *
+xstrndup (const char *s, size_t length)
+{
+ char *p = strndup (s, length);
+ if (p == NULL)
+ oom_error ("strndup", length);
+ return p;
+}
diff --git a/support/xsysconf.c b/support/xsysconf.c
new file mode 100644
index 0000000000..afefc2d098
--- /dev/null
+++ b/support/xsysconf.c
@@ -0,0 +1,36 @@
+/* Error-checking wrapper for sysconf.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+
+long
+xsysconf (int name)
+{
+ /* Detect errors by a changed errno value, in case -1 is a valid
+ value. Make sure that the caller does not see the zero value for
+ errno. */
+ int old_errno = errno;
+ errno = 0;
+ long result = sysconf (name);
+ if (errno != 0)
+ FAIL_EXIT1 ("sysconf (%d): %m", name);
+ errno = old_errno;
+ return result;
+}
diff --git a/support/xthread.h b/support/xthread.h
index 472763ebe8..79358e7c99 100644
--- a/support/xthread.h
+++ b/support/xthread.h
@@ -1,5 +1,5 @@
/* Support functionality for using threads.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xunistd.h b/support/xunistd.h
index c947bfd8fb..5fe5dae818 100644
--- a/support/xunistd.h
+++ b/support/xunistd.h
@@ -1,5 +1,5 @@
/* POSIX-specific extra functions.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
@@ -36,8 +36,17 @@ void xpipe (int[2]);
void xdup2 (int, int);
int xopen (const char *path, int flags, mode_t);
void xstat (const char *path, struct stat64 *);
+void xfstat (int fd, struct stat64 *);
void xmkdir (const char *path, mode_t);
void xchroot (const char *path);
+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);
+
+/* Read the link at PATH. The caller should free the returned string
+ with free. */
+char *xreadlink (const char *path);
/* Close the file descriptor. Ignore EINTR errors, but terminate the
process on other errors. */
diff --git a/support/xunlink.c b/support/xunlink.c
new file mode 100644
index 0000000000..2ff9296fca
--- /dev/null
+++ b/support/xunlink.c
@@ -0,0 +1,27 @@
+/* Error-checking wrapper for unlink.
+ Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/xunistd.h>
+
+void
+xunlink (const char *path)
+{
+ if (unlink (path) != 0)
+ FAIL_EXIT1 ("unlink (\"%s\"): %m", path);
+}
diff --git a/support/xwaitpid.c b/support/xwaitpid.c
index 204795e4c0..1cb039ca17 100644
--- a/support/xwaitpid.c
+++ b/support/xwaitpid.c
@@ -1,5 +1,5 @@
/* waitpid with error checking.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/support/xwrite.c b/support/xwrite.c
index 134e8ee4c1..bbaae9130a 100644
--- a/support/xwrite.c
+++ b/support/xwrite.c
@@ -1,5 +1,5 @@
/* write with error checking and retries.
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ 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
diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
index 78d52c717d..9aa1e79a80 100644
--- a/sysdeps/aarch64/multiarch/Makefile
+++ b/sysdeps/aarch64/multiarch/Makefile
@@ -1,3 +1,4 @@
ifeq ($(subdir),string)
-sysdep_routines += memcpy_generic memcpy_thunderx
+sysdep_routines += memcpy_generic memcpy_thunderx memcpy_falkor \
+ memmove_falkor
endif
diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
index 32056bcec3..2cb74d5b43 100644
--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
@@ -25,7 +25,7 @@
#include <stdio.h>
/* Maximum number of IFUNC implementations. */
-#define MAX_IFUNC 2
+#define MAX_IFUNC 3
size_t
__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
@@ -40,9 +40,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
/* Support sysdeps/aarch64/multiarch/memcpy.c and memmove.c. */
IFUNC_IMPL (i, name, memcpy,
IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_thunderx)
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_falkor)
IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic))
IFUNC_IMPL (i, name, memmove,
IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_thunderx)
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_falkor)
IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic))
return i;
diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
index 9f73efbba7..b395df1c63 100644
--- a/sysdeps/aarch64/multiarch/memcpy.c
+++ b/sysdeps/aarch64/multiarch/memcpy.c
@@ -30,9 +30,14 @@ extern __typeof (__redirect_memcpy) __libc_memcpy;
extern __typeof (__redirect_memcpy) __memcpy_generic attribute_hidden;
extern __typeof (__redirect_memcpy) __memcpy_thunderx attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_falkor attribute_hidden;
libc_ifunc (__libc_memcpy,
- IS_THUNDERX (midr) ? __memcpy_thunderx : __memcpy_generic);
+ (IS_THUNDERX (midr)
+ ? __memcpy_thunderx
+ : (IS_FALKOR (midr)
+ ? __memcpy_falkor
+ : __memcpy_generic)));
# undef memcpy
strong_alias (__libc_memcpy, memcpy);
diff --git a/sysdeps/aarch64/multiarch/memcpy_falkor.S b/sysdeps/aarch64/multiarch/memcpy_falkor.S
new file mode 100644
index 0000000000..dea4f225ee
--- /dev/null
+++ b/sysdeps/aarch64/multiarch/memcpy_falkor.S
@@ -0,0 +1,184 @@
+/* Optimized memcpy for Qualcomm Falkor processor.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Assumptions:
+
+ ARMv8-a, AArch64, falkor, unaligned accesses. */
+
+#define dstin x0
+#define src x1
+#define count x2
+#define dst x3
+#define srcend x4
+#define dstend x5
+#define A_l x6
+#define A_lw w6
+#define A_h x7
+#define A_hw w7
+#define tmp1 x14
+
+/* Copies are split into 3 main cases:
+
+ 1. Small copies of up to 32 bytes
+ 2. Medium copies of 33..128 bytes which are fully unrolled
+ 3. Large copies of more than 128 bytes.
+
+ Large copies align the sourceto a quad word and use an unrolled loop
+ processing 64 bytes per iteration.
+
+ FALKOR-SPECIFIC DESIGN:
+
+ The smallest copies (32 bytes or less) focus on optimal pipeline usage,
+ which is why the redundant copies of 0-3 bytes have been replaced with
+ conditionals, since the former would unnecessarily break across multiple
+ issue groups. The medium copy group has been enlarged to 128 bytes since
+ bumping up the small copies up to 32 bytes allows us to do that without
+ cost and also allows us to reduce the size of the prep code before loop64.
+
+ All copies are done only via two registers r6 and r7. This is to ensure
+ that all loads hit a single hardware prefetcher which can get correctly
+ trained to prefetch a single stream.
+
+ The non-temporal stores help optimize cache utilization. */
+
+#if IS_IN (libc)
+ENTRY_ALIGN (__memcpy_falkor, 6)
+
+ cmp count, 32
+ add srcend, src, count
+ add dstend, dstin, count
+ b.ls L(copy32)
+ ldp A_l, A_h, [src]
+ cmp count, 128
+ stp A_l, A_h, [dstin]
+ b.hi L(copy_long)
+
+ /* Medium copies: 33..128 bytes. */
+ sub tmp1, count, 1
+ ldp A_l, A_h, [src, 16]
+ stp A_l, A_h, [dstin, 16]
+ tbz tmp1, 6, 1f
+ ldp A_l, A_h, [src, 32]
+ stp A_l, A_h, [dstin, 32]
+ ldp A_l, A_h, [src, 48]
+ stp A_l, A_h, [dstin, 48]
+ ldp A_l, A_h, [srcend, -64]
+ stp A_l, A_h, [dstend, -64]
+ ldp A_l, A_h, [srcend, -48]
+ stp A_l, A_h, [dstend, -48]
+1:
+ ldp A_l, A_h, [srcend, -32]
+ stp A_l, A_h, [dstend, -32]
+ ldp A_l, A_h, [srcend, -16]
+ stp A_l, A_h, [dstend, -16]
+ ret
+
+ .p2align 4
+ /* Small copies: 0..32 bytes. */
+L(copy32):
+ /* 16-32 */
+ cmp count, 16
+ b.lo 1f
+ ldp A_l, A_h, [src]
+ stp A_l, A_h, [dstin]
+ ldp A_l, A_h, [srcend, -16]
+ stp A_l, A_h, [dstend, -16]
+ ret
+ .p2align 4
+1:
+ /* 8-15 */
+ tbz count, 3, 1f
+ ldr A_l, [src]
+ str A_l, [dstin]
+ ldr A_l, [srcend, -8]
+ str A_l, [dstend, -8]
+ ret
+ .p2align 4
+1:
+ /* 4-7 */
+ tbz count, 2, 1f
+ ldr A_lw, [src]
+ str A_lw, [dstin]
+ ldr A_lw, [srcend, -4]
+ str A_lw, [dstend, -4]
+ ret
+ .p2align 4
+1:
+ /* 2-3 */
+ tbz count, 1, 1f
+ ldrh A_lw, [src]
+ strh A_lw, [dstin]
+ ldrh A_lw, [srcend, -2]
+ strh A_lw, [dstend, -2]
+ ret
+ .p2align 4
+1:
+ /* 0-1 */
+ tbz count, 0, 1f
+ ldrb A_lw, [src]
+ strb A_lw, [dstin]
+1:
+ ret
+
+ /* Align SRC to 16 bytes and copy; that way at least one of the
+ accesses is aligned throughout the copy sequence.
+
+ The count is off by 0 to 15 bytes, but this is OK because we trim
+ off the last 64 bytes to copy off from the end. Due to this the
+ loop never runs out of bounds. */
+ .p2align 6
+L(copy_long):
+ sub count, count, 64 + 16
+ and tmp1, src, 15
+ bic src, src, 15
+ sub dst, dstin, tmp1
+ add count, count, tmp1
+
+L(loop64):
+ ldp A_l, A_h, [src, 16]!
+ stnp A_l, A_h, [dst, 16]
+ ldp A_l, A_h, [src, 16]!
+ subs count, count, 64
+ stnp A_l, A_h, [dst, 32]
+ ldp A_l, A_h, [src, 16]!
+ stnp A_l, A_h, [dst, 48]
+ ldp A_l, A_h, [src, 16]!
+ stnp A_l, A_h, [dst, 64]
+ add dst, dst, 64
+ b.hi L(loop64)
+
+ /* Write the last full set of 64 bytes. The remainder is at most 64
+ bytes, so it is safe to always copy 64 bytes from the end even if
+ there is just 1 byte left. */
+L(last64):
+ ldp A_l, A_h, [srcend, -64]
+ stnp A_l, A_h, [dstend, -64]
+ ldp A_l, A_h, [srcend, -48]
+ stnp A_l, A_h, [dstend, -48]
+ ldp A_l, A_h, [srcend, -32]
+ stnp A_l, A_h, [dstend, -32]
+ ldp A_l, A_h, [srcend, -16]
+ stnp A_l, A_h, [dstend, -16]
+ ret
+
+END (__memcpy_falkor)
+libc_hidden_builtin_def (__memcpy_falkor)
+#endif
diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
index 34c6b29bd5..016f03ee50 100644
--- a/sysdeps/aarch64/multiarch/memmove.c
+++ b/sysdeps/aarch64/multiarch/memmove.c
@@ -30,9 +30,14 @@ extern __typeof (__redirect_memmove) __libc_memmove;
extern __typeof (__redirect_memmove) __memmove_generic attribute_hidden;
extern __typeof (__redirect_memmove) __memmove_thunderx attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_falkor attribute_hidden;
libc_ifunc (__libc_memmove,
- IS_THUNDERX (midr) ? __memmove_thunderx : __memmove_generic);
+ (IS_THUNDERX (midr)
+ ? __memmove_thunderx
+ : (IS_FALKOR (midr)
+ ? __memmove_falkor
+ : __memmove_generic)));
# undef memmove
strong_alias (__libc_memmove, memmove);
diff --git a/sysdeps/aarch64/multiarch/memmove_falkor.S b/sysdeps/aarch64/multiarch/memmove_falkor.S
new file mode 100644
index 0000000000..3a4e6a2a8e
--- /dev/null
+++ b/sysdeps/aarch64/multiarch/memmove_falkor.S
@@ -0,0 +1,232 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Assumptions: ARMv8-a, AArch64, falkor, unaligned accesses. */
+
+#define dstin x0
+#define src x1
+#define count x2
+#define dstlen x3
+#define dst x3
+#define srcend x4
+#define dstend x5
+#define A_l x6
+#define A_lw w6
+#define A_h x7
+#define A_hw w7
+#define B_l x8
+#define B_lw w8
+#define B_h x9
+#define C_l x10
+#define C_h x11
+#define D_l x12
+#define D_h x13
+#define E_l src
+#define E_h count
+#define F_l srcend
+#define F_h dst
+#define tmp1 x14
+
+/* Alias with A_l and A_h to train the prefetcher. */
+#define Q_l x22
+#define Q_h x23
+
+/* RATIONALE:
+
+ The copy has 4 distinct parts:
+ * Small copies of 16 bytes and under
+ * Medium sized copies of 17-96 bytes
+ * Large copies where the source address is higher than the destination
+ (forward copies)
+ * Large copies where the destination address is higher than the source
+ (copy backward, or move).
+
+ We use only two registerpairs x6,x7 and x22,x23 for the copies and copy 32
+ bytes at a time to correctly train the hardware prefetcher for better
+ throughput. */
+ENTRY_ALIGN (__memmove_falkor, 6)
+
+ sub tmp1, dstin, src
+ add srcend, src, count
+ add dstend, dstin, count
+ cmp count, 96
+ ccmp tmp1, count, 2, hi
+ b.lo L(move_long)
+
+ cmp count, 16
+ b.ls L(copy16)
+ cmp count, 96
+ b.hi L(copy_long)
+
+ /* Medium copies: 17..96 bytes. */
+ sub tmp1, count, 1
+ ldp A_l, A_h, [src]
+ tbnz tmp1, 6, L(copy96)
+ ldp D_l, D_h, [srcend, -16]
+ tbz tmp1, 5, 1f
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [srcend, -32]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstend, -32]
+1:
+ stp A_l, A_h, [dstin]
+ stp D_l, D_h, [dstend, -16]
+ ret
+
+ .p2align 4
+ /* Small copies: 0..16 bytes. */
+L(copy16):
+ cmp count, 8
+ b.lo 1f
+ ldr A_l, [src]
+ ldr A_h, [srcend, -8]
+ str A_l, [dstin]
+ str A_h, [dstend, -8]
+ ret
+ .p2align 4
+1:
+ /* 4-7 */
+ tbz count, 2, 1f
+ ldr A_lw, [src]
+ ldr A_hw, [srcend, -4]
+ str A_lw, [dstin]
+ str A_hw, [dstend, -4]
+ ret
+ .p2align 4
+1:
+ /* 2-3 */
+ tbz count, 1, 1f
+ ldrh A_lw, [src]
+ ldrh A_hw, [srcend, -2]
+ strh A_lw, [dstin]
+ strh A_hw, [dstend, -2]
+ ret
+ .p2align 4
+1:
+ /* 0-1 */
+ tbz count, 0, 1f
+ ldrb A_lw, [src]
+ strb A_lw, [dstin]
+1: ret
+
+ .p2align 4
+ /* Copy 64..96 bytes. Copy 64 bytes from the start and
+ 32 bytes from the end. */
+L(copy96):
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [src, 32]
+ ldp D_l, D_h, [src, 48]
+ ldp E_l, E_h, [srcend, -32]
+ ldp F_l, F_h, [srcend, -16]
+ stp A_l, A_h, [dstin]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstin, 32]
+ stp D_l, D_h, [dstin, 48]
+ stp E_l, E_h, [dstend, -32]
+ stp F_l, F_h, [dstend, -16]
+ ret
+
+ /* Align SRC to 16 byte alignment so that we don't cross cache line
+ boundaries on both loads and stores. There are at least 96 bytes
+ to copy, so copy 16 bytes unaligned and then align. The loop
+ copies 32 bytes per iteration and prefetches one iteration ahead. */
+
+ .p2align 4
+L(copy_long):
+ sub count, count, 64 + 16 /* Test and readjust count. */
+ mov B_l, Q_l
+ mov B_h, Q_h
+ ldp A_l, A_h, [src]
+ and tmp1, src, 15
+ bic src, src, 15
+ sub dst, dstin, tmp1
+ add count, count, tmp1 /* Count is now 16 too large. */
+ ldp Q_l, Q_h, [src, 16]!
+ stp A_l, A_h, [dstin]
+ ldp A_l, A_h, [src, 16]!
+
+L(loop64):
+ subs count, count, 32
+ stp Q_l, Q_h, [dst, 16]
+ ldp Q_l, Q_h, [src, 16]!
+ stp A_l, A_h, [dst, 32]!
+ ldp A_l, A_h, [src, 16]!
+ b.hi L(loop64)
+
+ /* Write the last full set of 32 bytes. The remainder is at most 32
+ bytes, so it is safe to always copy 32 bytes from the end even if
+ there is just 1 byte left. */
+L(last64):
+ ldp C_l, C_h, [srcend, -32]
+ stp Q_l, Q_h, [dst, 16]
+ ldp Q_l, Q_h, [srcend, -16]
+ stp A_l, A_h, [dst, 32]
+ stp C_l, C_h, [dstend, -32]
+ stp Q_l, Q_h, [dstend, -16]
+ mov Q_l, B_l
+ mov Q_h, B_h
+ ret
+
+ .p2align 4
+L(move_long):
+ cbz tmp1, 3f
+
+ mov B_l, Q_l
+ mov B_h, Q_h
+
+ /* Align SRCEND to 16 byte alignment so that we don't cross cache line
+ boundaries on both loads and stores. There are at least 96 bytes
+ to copy, so copy 16 bytes unaligned and then align. The loop
+ copies 32 bytes per iteration and prefetches one iteration ahead. */
+
+ ldp A_l, A_h, [srcend, -16]
+ and tmp1, srcend, 15
+ sub srcend, srcend, tmp1
+ ldp Q_l, Q_h, [srcend, -16]!
+ stp A_l, A_h, [dstend, -16]
+ sub count, count, tmp1
+ ldp A_l, A_h, [srcend, -16]!
+ sub dstend, dstend, tmp1
+ sub count, count, 64
+
+1:
+ subs count, count, 32
+ stp Q_l, Q_h, [dstend, -16]
+ ldp Q_l, Q_h, [srcend, -16]!
+ stp A_l, A_h, [dstend, -32]!
+ ldp A_l, A_h, [srcend, -16]!
+ b.hi 1b
+
+ /* Write the last full set of 32 bytes. The remainder is at most 32
+ bytes, so it is safe to always copy 32 bytes from the start even if
+ there is just 1 byte left. */
+2:
+ ldp C_l, C_h, [src, 16]
+ stp Q_l, Q_h, [dstend, -16]
+ ldp Q_l, Q_h, [src]
+ stp A_l, A_h, [dstend, -32]
+ stp C_l, C_h, [dstin, 16]
+ stp Q_l, Q_h, [dstin]
+ mov Q_l, B_l
+ mov Q_h, B_h
+3: ret
+
+END (__memmove_falkor)
+libc_hidden_builtin_def (__memmove_falkor)
diff --git a/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h b/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
index d13a75db07..9ab23d0474 100644
--- a/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
@@ -45,6 +45,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0
+#define __PTHREAD_MUTEX_USE_UNION 0
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/aarch64/nptl/pthread-offsets.h b/sysdeps/aarch64/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..16c6b0d9fd
--- /dev/null
+++ b/sysdeps/aarch64/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+#define __PTHREAD_MUTEX_KIND_OFFSET 16
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 24
diff --git a/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h b/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
index b6f6cb1347..429df10c0c 100644
--- a/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
@@ -33,6 +33,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0
+#define __PTHREAD_MUTEX_USE_UNION 0
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/alpha/nptl/pthread-offsets.h b/sysdeps/alpha/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..16c6b0d9fd
--- /dev/null
+++ b/sysdeps/alpha/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+#define __PTHREAD_MUTEX_KIND_OFFSET 16
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 24
diff --git a/sysdeps/arm/nptl/bits/pthreadtypes-arch.h b/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
index 3f9eca4645..3911c8183d 100644
--- a/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/arm/nptl/bits/pthreadtypes-arch.h
@@ -34,6 +34,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 1
+#define __PTHREAD_MUTEX_USE_UNION 1
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/arm/nptl/pthread-offsets.h b/sysdeps/arm/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..9617354dc7
--- /dev/null
+++ b/sysdeps/arm/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+#define __PTHREAD_MUTEX_KIND_OFFSET 12
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 20
diff --git a/sysdeps/gnu/glob64.c b/sysdeps/gnu/glob64.c
index d1e4e6f0d5..52e97e2f6a 100644
--- a/sysdeps/gnu/glob64.c
+++ b/sysdeps/gnu/glob64.c
@@ -15,11 +15,8 @@
#undef __stat
#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
-#define NO_GLOB_PATTERN_P 1
-
#define COMPILE_GLOB64 1
#include <posix/glob.c>
libc_hidden_def (glob64)
-libc_hidden_def (globfree64)
diff --git a/sysdeps/gnu/globfree64.c b/sysdeps/gnu/globfree64.c
new file mode 100644
index 0000000000..f092d0bf8b
--- /dev/null
+++ b/sysdeps/gnu/globfree64.c
@@ -0,0 +1,10 @@
+#include <dirent.h>
+#include <glob.h>
+#include <sys/stat.h>
+
+#define glob_t glob64_t
+#define globfree(pglob) globfree64 (pglob)
+
+#include <posix/globfree.c>
+
+libc_hidden_def (globfree64)
diff --git a/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h b/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
index c1585625d1..865a14ee4a 100644
--- a/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
@@ -48,6 +48,8 @@
pthread_mutex_t is larger than Linuxthreads. */
#define __PTHREAD_COMPAT_PADDING_END int __reserved[2];
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 1
+#define __PTHREAD_MUTEX_USE_UNION 1
#define __LOCK_ALIGNMENT __attribute__ ((__aligned__(16)))
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/hppa/nptl/pthread-offsets.h b/sysdeps/hppa/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..8ae01b9d95
--- /dev/null
+++ b/sysdeps/hppa/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 32
+#define __PTHREAD_MUTEX_KIND_OFFSET 12
+#define __PTHREAD_MUTEX_SPINS_OFFSET 36
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 36
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index ed685de35d..a269c7c343 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -2693,30 +2693,30 @@ ldouble: 2
Function: "y1_downward":
double: 2
-float: 2
+float: 3
float128: 4
idouble: 2
-ifloat: 2
+ifloat: 3
ifloat128: 4
ildouble: 7
ldouble: 7
Function: "y1_towardzero":
double: 2
-float: 2
+float: 3
float128: 2
idouble: 2
-ifloat: 2
+ifloat: 3
ifloat128: 2
ildouble: 5
ldouble: 5
Function: "y1_upward":
double: 1
-float: 2
+float: 3
float128: 5
idouble: 1
-ifloat: 2
+ifloat: 3
ifloat128: 5
ildouble: 7
ldouble: 7
diff --git a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
index 81dd1a09ea..053f5ec972 100644
--- a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
+++ b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps
@@ -58,7 +58,7 @@ double: 1
float128: 2
idouble: 1
ifloat128: 2
-ildouble: 4
+ildouble: 5
ldouble: 3
Function: "asin":
@@ -1154,8 +1154,8 @@ float128: 4
idouble: 3
ifloat: 3
ifloat128: 4
-ildouble: 7
-ldouble: 7
+ildouble: 8
+ldouble: 8
Function: Imaginary part of "clog10_upward":
double: 1
@@ -2013,8 +2013,8 @@ double: 3
float: 4
idouble: 3
ifloat: 4
-ildouble: 5
-ldouble: 5
+ildouble: 6
+ldouble: 6
Function: "hypot":
double: 1
@@ -2205,8 +2205,8 @@ float128: 8
idouble: 3
ifloat: 4
ifloat128: 8
-ildouble: 5
-ldouble: 5
+ildouble: 6
+ldouble: 6
Function: "log":
double: 1
diff --git a/sysdeps/i386/nptl/pthread-offsets.h b/sysdeps/i386/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..9617354dc7
--- /dev/null
+++ b/sysdeps/i386/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+#define __PTHREAD_MUTEX_KIND_OFFSET 12
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 20
diff --git a/sysdeps/ia64/fpu/libm-test-ulps b/sysdeps/ia64/fpu/libm-test-ulps
index 2776ba7fae..543cebcb63 100644
--- a/sysdeps/ia64/fpu/libm-test-ulps
+++ b/sysdeps/ia64/fpu/libm-test-ulps
@@ -1,508 +1,2396 @@
# Begin of automatic generation
# Maximal error of functions:
-Function: "asin_downward":
+Function: "acos":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+
+Function: "acos_downward":
double: 1
float: 1
+float128: 1
idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ifloat128: 1
-Function: "asin_towardzero":
+Function: "acos_towardzero":
double: 1
float: 1
+float128: 1
idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ifloat128: 1
-Function: "asin_upward":
+Function: "acos_upward":
double: 1
float: 1
+float128: 1
idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ifloat128: 1
-Function: Real part of "cacos":
+Function: "acosh":
double: 1
-float: 2
+float128: 2
idouble: 1
-ifloat: 2
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Imaginary part of "cacos":
-double: 1
-float: 2
-idouble: 1
-ifloat: 2
-ildouble: 2
-ldouble: 2
+Function: "acosh_downward":
+float128: 3
+ifloat128: 3
-Function: Real part of "cacosh":
-double: 1
-float: 2
-idouble: 1
-ifloat: 2
-ildouble: 2
-ldouble: 2
+Function: "acosh_towardzero":
+float128: 2
+ifloat128: 2
-Function: Imaginary part of "cacosh":
+Function: "acosh_upward":
+float128: 2
+ifloat128: 2
+
+Function: "asin":
+float128: 1
+ifloat128: 1
+
+Function: "asin_downward":
double: 1
-float: 2
+float: 1
+float128: 2
idouble: 1
-ifloat: 2
+ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Real part of "casin":
+Function: "asin_towardzero":
double: 1
float: 1
+float128: 1
idouble: 1
ifloat: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
-Function: Imaginary part of "casin":
+Function: "asin_upward":
double: 1
-float: 2
+float: 1
+float128: 2
idouble: 1
-ifloat: 2
-ildouble: 2
-ldouble: 2
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
-Function: Real part of "casinh":
+Function: "asinh":
double: 1
-float: 2
+float128: 3
idouble: 1
-ifloat: 2
-ildouble: 2
-ldouble: 2
+ifloat128: 3
-Function: Imaginary part of "casinh":
+Function: "asinh_downward":
+float128: 4
+ifloat128: 4
+
+Function: "asinh_towardzero":
+float128: 2
+ifloat128: 2
+
+Function: "asinh_upward":
+float128: 4
+ifloat128: 4
+
+Function: "atan":
+float128: 1
+ifloat128: 1
+
+Function: "atan2":
+float128: 1
+ifloat128: 1
+
+Function: "atan2_downward":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Imaginary part of "catan":
-double: 1
+Function: "atan2_towardzero":
float: 1
-idouble: 1
+float128: 3
ifloat: 1
+ifloat128: 3
ildouble: 1
ldouble: 1
-Function: Real part of "catanh":
+Function: "atan2_upward":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Real part of "ccos":
+Function: "atan_downward":
double: 1
+float: 1
+float128: 2
idouble: 1
+ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Imaginary part of "ccos":
-double: 1
+Function: "atan_towardzero":
float: 1
-idouble: 1
+float128: 1
ifloat: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
-Function: Real part of "ccosh":
+Function: "atan_upward":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
-Function: Imaginary part of "ccosh":
-double: 1
+Function: "atanh":
+float128: 3
+ifloat128: 3
+
+Function: "atanh_downward":
float: 1
-idouble: 1
+float128: 4
ifloat: 1
-ildouble: 1
-ldouble: 1
+ifloat128: 4
-Function: Real part of "cexp":
-double: 2
+Function: "atanh_towardzero":
float: 1
-idouble: 2
+float128: 2
+ifloat: 1
+ifloat128: 2
+
+Function: "atanh_upward":
+float: 1
+float128: 4
+ifloat: 1
+ifloat128: 4
+
+Function: "cabs":
+float128: 1
+ifloat128: 1
+
+Function: "cabs_downward":
+double: 1
+float: 1
+float128: 1
+idouble: 1
ifloat: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
-Function: Imaginary part of "cexp":
+Function: "cabs_towardzero":
double: 1
-float: 2
+float: 1
+float128: 1
idouble: 1
-ifloat: 2
+ifloat: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
-Function: Real part of "clog":
+Function: "cabs_upward":
double: 1
float: 1
+float128: 1
idouble: 1
ifloat: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
-Function: Imaginary part of "clog":
+Function: Real part of "cacos":
double: 1
+float: 2
+float128: 2
idouble: 1
+ifloat: 2
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Real part of "clog10":
+Function: Imaginary part of "cacos":
double: 2
float: 2
+float128: 2
idouble: 2
ifloat: 2
-ildouble: 1
-ldouble: 1
+ifloat128: 2
+ildouble: 2
+ldouble: 2
-Function: Imaginary part of "clog10":
+Function: Real part of "cacos_downward":
double: 1
float: 1
+float128: 3
idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
-Function: "cos":
-double: 1
-idouble: 1
+Function: Imaginary part of "cacos_downward":
+double: 5
+float: 6
+float128: 6
+idouble: 5
+ifloat: 6
+ifloat128: 6
+ildouble: 5
+ldouble: 5
-Function: "cos_downward":
+Function: Real part of "cacos_towardzero":
double: 1
float: 1
+float128: 3
idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
-Function: "cos_towardzero":
+Function: Imaginary part of "cacos_towardzero":
+double: 4
+float: 5
+float128: 5
+idouble: 4
+ifloat: 5
+ifloat128: 5
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "cacos_upward":
+double: 2
+float: 2
+float128: 3
+idouble: 2
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacos_upward":
+double: 5
+float: 5
+float128: 7
+idouble: 5
+ifloat: 5
+ifloat128: 7
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "cacosh":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cacosh":
double: 1
-float: 1
+float: 2
+float128: 2
idouble: 1
-ifloat: 1
+ifloat: 2
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: "cos_upward":
-ildouble: 1
-ldouble: 1
+Function: Real part of "cacosh_downward":
+double: 4
+float: 5
+float128: 5
+idouble: 4
+ifloat: 5
+ifloat128: 5
+ildouble: 4
+ldouble: 4
-Function: Real part of "cpow":
+Function: Imaginary part of "cacosh_downward":
double: 2
-float: 5
+float: 2
+float128: 4
idouble: 2
-ifloat: 5
+ifloat: 2
+ifloat128: 4
ildouble: 3
ldouble: 3
-Function: Imaginary part of "cpow":
-float: 2
-ifloat: 2
+Function: Real part of "cacosh_towardzero":
+double: 4
+float: 5
+float128: 5
+idouble: 4
+ifloat: 5
+ifloat128: 5
ildouble: 4
ldouble: 4
-Function: Real part of "csin":
+Function: Imaginary part of "cacosh_towardzero":
double: 1
float: 1
+float128: 3
idouble: 1
ifloat: 1
-ildouble: 1
-ldouble: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
-Function: Imaginary part of "csin":
-float: 1
-ifloat: 1
+Function: Real part of "cacosh_upward":
+double: 4
+float: 3
+float128: 6
+idouble: 4
+ifloat: 3
+ifloat128: 6
+ildouble: 4
+ldouble: 4
-Function: Real part of "csinh":
+Function: Imaginary part of "cacosh_upward":
+double: 3
+float: 2
+float128: 4
+idouble: 3
+ifloat: 2
+ifloat128: 4
+ildouble: 3
+ldouble: 3
+
+Function: "carg":
+float128: 2
+ifloat128: 2
+
+Function: "carg_downward":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Imaginary part of "csinh":
-double: 1
-float: 1
-idouble: 1
-ifloat: 1
-
-Function: Real part of "csqrt":
-double: 1
+Function: "carg_towardzero":
float: 1
-idouble: 1
+float128: 3
ifloat: 1
+ifloat128: 3
ildouble: 1
ldouble: 1
-Function: Imaginary part of "csqrt":
+Function: "carg_upward":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
-Function: Real part of "ctan":
+Function: Real part of "casin":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
-ildouble: 2
-ldouble: 2
+ifloat128: 2
+ildouble: 1
+ldouble: 1
-Function: Imaginary part of "ctan":
+Function: Imaginary part of "casin":
double: 2
-float: 1
+float: 2
+float128: 2
idouble: 2
-ifloat: 1
-ildouble: 2
-ldouble: 2
-
-Function: Real part of "ctan_downward":
-double: 4
-float: 4
-idouble: 4
-ifloat: 4
+ifloat: 2
+ifloat128: 2
ildouble: 2
ldouble: 2
-Function: Imaginary part of "ctan_downward":
+Function: Real part of "casin_downward":
double: 3
float: 2
+float128: 3
idouble: 3
ifloat: 2
-ildouble: 2
-ldouble: 2
+ifloat128: 3
+ildouble: 3
+ldouble: 3
-Function: Real part of "ctan_towardzero":
-double: 2
-float: 1
-idouble: 2
-ifloat: 1
-ildouble: 2
-ldouble: 2
+Function: Imaginary part of "casin_downward":
+double: 5
+float: 6
+float128: 6
+idouble: 5
+ifloat: 6
+ifloat128: 6
+ildouble: 5
+ldouble: 5
-Function: Imaginary part of "ctan_towardzero":
+Function: Real part of "casin_towardzero":
double: 3
float: 2
+float128: 3
idouble: 3
ifloat: 2
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "casin_towardzero":
+double: 4
+float: 5
+float128: 5
+idouble: 4
+ifloat: 5
+ifloat128: 5
ildouble: 4
ldouble: 4
-Function: Real part of "ctan_upward":
+Function: Real part of "casin_upward":
double: 2
-float: 3
+float: 1
+float128: 3
idouble: 2
-ifloat: 3
-ildouble: 5
+ifloat: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "casin_upward":
+double: 5
+float: 5
+float128: 7
+idouble: 5
+ifloat: 5
+ifloat128: 7
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "casinh":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "casinh":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casinh_downward":
+double: 5
+float: 6
+float128: 6
+idouble: 5
+ifloat: 6
+ifloat128: 6
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "casinh_downward":
+double: 3
+float: 2
+float128: 3
+idouble: 3
+ifloat: 2
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "casinh_towardzero":
+double: 4
+float: 5
+float128: 5
+idouble: 4
+ifloat: 5
+ifloat128: 5
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "casinh_towardzero":
+double: 3
+float: 2
+float128: 3
+idouble: 3
+ifloat: 2
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "casinh_upward":
+double: 5
+float: 5
+float128: 7
+idouble: 5
+ifloat: 5
+ifloat128: 7
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "casinh_upward":
+double: 2
+float: 1
+float128: 3
+idouble: 2
+ifloat: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catan_downward":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_downward":
+double: 2
+float: 1
+float128: 2
+idouble: 2
+ifloat: 1
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan_towardzero":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_towardzero":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan_upward":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_upward":
+double: 2
+float: 2
+float128: 3
+idouble: 2
+ifloat: 2
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "catanh":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catanh":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+
+Function: Real part of "catanh_downward":
+double: 2
+float: 1
+float128: 2
+idouble: 2
+ifloat: 1
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "catanh_downward":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh_towardzero":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "catanh_towardzero":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh_upward":
+double: 4
+float: 4
+float128: 4
+idouble: 4
+ifloat: 4
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_upward":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt":
+float128: 1
+ifloat128: 1
+
+Function: "cbrt_downward":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt_towardzero":
+float: 1
+float128: 1
+ifloat: 1
+ifloat128: 1
+
+Function: "cbrt_upward":
+float: 1
+float128: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos_downward":
+double: 3
+float: 1
+float128: 2
+idouble: 3
+ifloat: 1
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ccos_downward":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ccos_towardzero":
+double: 3
+float: 1
+float128: 2
+idouble: 3
+ifloat: 1
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ccos_towardzero":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ccos_upward":
+double: 1
+float: 2
+float128: 3
+idouble: 1
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ccos_upward":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh_downward":
+double: 3
+float: 2
+float128: 2
+idouble: 3
+ifloat: 2
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ccosh_downward":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ccosh_towardzero":
+double: 3
+float: 2
+float128: 2
+idouble: 3
+ifloat: 2
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "ccosh_towardzero":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ccosh_upward":
+double: 1
+float: 2
+float128: 3
+idouble: 1
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ccosh_upward":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cexp":
+double: 2
+float: 1
+float128: 1
+idouble: 2
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cexp":
+double: 1
+float: 2
+float128: 1
+idouble: 1
+ifloat: 2
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp_downward":
+double: 4
+float: 2
+float128: 2
+idouble: 4
+ifloat: 2
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cexp_downward":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "cexp_towardzero":
+double: 4
+float: 2
+float128: 2
+idouble: 4
+ifloat: 2
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cexp_towardzero":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "cexp_upward":
+double: 2
+float: 2
+float128: 3
+idouble: 2
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cexp_upward":
+double: 3
+float: 2
+float128: 3
+idouble: 3
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "clog":
+double: 2
+float: 3
+float128: 2
+idouble: 2
+ifloat: 3
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog10":
+double: 3
+float: 4
+float128: 2
+idouble: 3
+ifloat: 4
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog10":
+double: 2
+float: 1
+float128: 2
+idouble: 2
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog10_downward":
+double: 4
+float: 4
+float128: 3
+idouble: 4
+ifloat: 4
+ifloat128: 3
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "clog10_downward":
+double: 2
+float: 2
+float128: 3
+idouble: 2
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "clog10_towardzero":
+double: 5
+float: 5
+float128: 4
+idouble: 5
+ifloat: 5
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "clog10_towardzero":
+double: 2
+float: 2
+float128: 3
+idouble: 2
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "clog10_upward":
+double: 4
+float: 5
+float128: 4
+idouble: 4
+ifloat: 5
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "clog10_upward":
+double: 2
+float: 2
+float128: 3
+idouble: 2
+ifloat: 2
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "clog_downward":
+double: 3
+float: 3
+float128: 3
+idouble: 3
+ifloat: 3
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "clog_downward":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog_towardzero":
+double: 3
+float: 4
+float128: 3
+idouble: 3
+ifloat: 4
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "clog_towardzero":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog_upward":
+double: 2
+float: 3
+float128: 4
+idouble: 2
+ifloat: 3
+ifloat128: 4
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "clog_upward":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+
+Function: "cos_downward":
+double: 1
+float: 1
+float128: 3
+idouble: 1
+ifloat: 1
+ifloat128: 3
+ildouble: 1
+ldouble: 1
+
+Function: "cos_towardzero":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cos_upward":
+double: 1
+float128: 2
+idouble: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: "cosh":
+float128: 1
+ifloat128: 1
+
+Function: "cosh_downward":
+float128: 2
+ifloat128: 1
+
+Function: "cosh_towardzero":
+float128: 2
+ifloat128: 1
+
+Function: "cosh_upward":
+float128: 3
+ifloat128: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 5
+float128: 4
+idouble: 2
+ifloat: 5
+ifloat128: 4
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "cpow":
+float: 2
+float128: 1
+ifloat: 2
+ifloat128: 1
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "cpow_downward":
+double: 5
+float: 8
+float128: 6
+idouble: 5
+ifloat: 8
+ifloat128: 6
+ildouble: 7
+ldouble: 7
+
+Function: Imaginary part of "cpow_downward":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow_towardzero":
+double: 5
+float: 8
+float128: 6
+idouble: 5
+ifloat: 8
+ifloat128: 6
+ildouble: 7
+ldouble: 7
+
+Function: Imaginary part of "cpow_towardzero":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow_upward":
+double: 4
+float: 1
+float128: 3
+idouble: 4
+ifloat: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cpow_upward":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csin":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+float: 1
+float128: 1
+ifloat: 1
+ifloat128: 1
+
+Function: Real part of "csin_downward":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "csin_downward":
+double: 3
+float: 1
+float128: 2
+idouble: 3
+ifloat: 1
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csin_towardzero":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "csin_towardzero":
+double: 3
+float: 1
+float128: 2
+idouble: 3
+ifloat: 1
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csin_upward":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csin_upward":
+double: 1
+float: 2
+float128: 3
+idouble: 1
+ifloat: 2
+ifloat128: 3
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh_downward":
+double: 3
+float: 1
+float128: 2
+idouble: 3
+ifloat: 1
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "csinh_downward":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csinh_towardzero":
+double: 3
+float: 1
+float128: 2
+idouble: 3
+ifloat: 1
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "csinh_towardzero":
+double: 3
+float: 3
+float128: 2
+idouble: 3
+ifloat: 3
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csinh_upward":
+double: 1
+float: 2
+float128: 3
+idouble: 1
+ifloat: 2
+ifloat128: 3
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh_upward":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csqrt":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "csqrt":
+double: 2
+float: 2
+float128: 2
+idouble: 2
+ifloat: 2
+ifloat128: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csqrt_downward":
+double: 4
+float: 4
+float128: 4
+idouble: 4
+ifloat: 4
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "csqrt_downward":
+double: 3
+float: 3
+float128: 3
+idouble: 3
+ifloat: 3
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csqrt_towardzero":
+double: 3
+float: 3
+float128: 3
+idouble: 3
+ifloat: 3
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Imaginary part of "csqrt_towardzero":
+double: 3
+float: 3
+float128: 3
+idouble: 3
+ifloat: 3
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "csqrt_upward":
+double: 4
+float: 4
+float128: 4
+idouble: 4
+ifloat: 4
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "csqrt_upward":
+double: 3
+float: 2
+float128: 3
+idouble: 3
+ifloat: 2
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ctan":
+double: 1
+float: 1
+float128: 3
+idouble: 1
+ifloat: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ctan":
+double: 2
+float: 1
+float128: 3
+idouble: 2
+ifloat: 1
+ifloat128: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ctan_downward":
+double: 4
+float: 4
+float128: 4
+idouble: 4
+ifloat: 4
+ifloat128: 4
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ctan_downward":
+double: 3
+float: 2
+float128: 5
+idouble: 3
+ifloat: 2
+ifloat128: 5
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ctan_towardzero":
+double: 2
+float: 2
+float128: 4
+idouble: 2
+ifloat: 2
+ifloat128: 4
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ctan_towardzero":
+double: 3
+float: 2
+float128: 5
+idouble: 3
+ifloat: 2
+ifloat128: 5
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "ctan_upward":
+double: 2
+float: 3
+float128: 5
+idouble: 2
+ifloat: 3
+ifloat128: 5
+ildouble: 5
ldouble: 5
Function: Imaginary part of "ctan_upward":
double: 6
float: 2
+float128: 5
idouble: 6
ifloat: 2
+ifloat128: 5
ildouble: 7
ldouble: 7
Function: Real part of "ctanh":
double: 2
float: 1
+float128: 3
idouble: 2
ifloat: 1
+ifloat128: 3
ildouble: 1
ldouble: 1
Function: Imaginary part of "ctanh":
double: 2
float: 1
+float128: 3
idouble: 2
ifloat: 1
+ifloat128: 3
ildouble: 2
ldouble: 2
Function: Real part of "ctanh_downward":
double: 3
float: 2
+float128: 5
idouble: 3
ifloat: 2
+ifloat128: 5
ildouble: 1
ldouble: 1
Function: Imaginary part of "ctanh_downward":
double: 4
float: 4
+float128: 4
idouble: 4
ifloat: 4
+ifloat128: 4
ildouble: 2
ldouble: 2
Function: Real part of "ctanh_towardzero":
double: 3
float: 2
+float128: 5
idouble: 3
ifloat: 2
+ifloat128: 5
ildouble: 4
ldouble: 4
Function: Imaginary part of "ctanh_towardzero":
double: 2
float: 1
+float128: 3
idouble: 2
ifloat: 1
+ifloat128: 3
ildouble: 1
ldouble: 1
Function: Real part of "ctanh_upward":
double: 6
float: 2
+float128: 5
idouble: 6
ifloat: 2
+ifloat128: 5
ildouble: 7
ldouble: 7
Function: Imaginary part of "ctanh_upward":
double: 2
float: 3
+float128: 5
idouble: 2
ifloat: 3
+ifloat128: 5
ildouble: 5
ldouble: 5
-Function: "expm1":
+Function: "erf":
+float128: 1
+ifloat128: 1
+
+Function: "erf_downward":
+float128: 2
+ifloat128: 2
+
+Function: "erf_towardzero":
+float128: 1
+ifloat128: 1
+
+Function: "erf_upward":
+float128: 2
+ifloat128: 2
+
+Function: "erfc":
+float128: 2
+ifloat128: 2
+
+Function: "erfc_downward":
+double: 1
+float128: 5
+idouble: 1
+ifloat128: 5
+
+Function: "erfc_towardzero":
+double: 1
+float128: 4
+idouble: 1
+ifloat128: 4
+
+Function: "erfc_upward":
+double: 1
+float128: 5
+idouble: 1
+ifloat128: 5
+
+Function: "exp":
+float: 1
+float128: 1
+ifloat: 1
+ifloat128: 1
+
+Function: "exp10":
+float128: 2
+ifloat128: 2
+
+Function: "exp10_downward":
+float128: 3
+ifloat128: 3
+
+Function: "exp10_towardzero":
+float128: 3
+ifloat128: 3
+
+Function: "exp10_upward":
+float128: 3
+ifloat128: 3
+
+Function: "exp2":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp2_downward":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp2_towardzero":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp2_upward":
+double: 1
+float128: 2
+idouble: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: "expm1":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "expm1_downward":
+float128: 2
+ifloat128: 2
+ildouble: 1
+ldouble: 1
+
+Function: "expm1_towardzero":
+float128: 4
+ifloat128: 4
+
+Function: "expm1_upward":
+float128: 3
+ifloat128: 3
+
+Function: "gamma":
+float: 1
+ifloat: 1
+
+Function: "gamma_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "gamma_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "gamma_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "hypot":
+float128: 1
+ifloat128: 1
+
+Function: "hypot_downward":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "hypot_towardzero":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
-Function: "expm1_downward":
+Function: "hypot_upward":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
Function: "j0":
double: 2
float: 2
+float128: 2
idouble: 2
ifloat: 2
+ifloat128: 2
ildouble: 2
ldouble: 2
+Function: "j0_downward":
+double: 6
+float: 4
+float128: 4
+idouble: 6
+ifloat: 4
+ifloat128: 4
+ildouble: 3
+ldouble: 3
+
+Function: "j0_towardzero":
+double: 2
+float: 1
+float128: 2
+idouble: 2
+ifloat: 1
+ifloat128: 2
+ildouble: 5
+ldouble: 5
+
+Function: "j0_upward":
+double: 3
+float: 2
+float128: 5
+idouble: 3
+ifloat: 2
+ifloat128: 5
+ildouble: 5
+ldouble: 5
+
Function: "j1":
double: 1
float: 2
+float128: 4
idouble: 1
ifloat: 2
+ifloat128: 4
ildouble: 1
ldouble: 1
+Function: "j1_downward":
+double: 3
+float: 2
+float128: 4
+idouble: 3
+ifloat: 2
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: "j1_towardzero":
+double: 3
+float: 2
+float128: 4
+idouble: 3
+ifloat: 2
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: "j1_upward":
+double: 3
+float: 4
+float128: 3
+idouble: 3
+ifloat: 4
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
Function: "jn":
double: 4
float: 4
+float128: 7
idouble: 4
ifloat: 4
+ifloat128: 7
+ildouble: 4
+ldouble: 4
+
+Function: "jn_downward":
+double: 4
+float: 5
+float128: 8
+idouble: 4
+ifloat: 5
+ifloat128: 8
ildouble: 4
ldouble: 4
+Function: "jn_towardzero":
+double: 4
+float: 5
+float128: 8
+idouble: 4
+ifloat: 5
+ifloat128: 8
+ildouble: 5
+ldouble: 5
+
+Function: "jn_upward":
+double: 5
+float: 4
+float128: 7
+idouble: 5
+ifloat: 4
+ifloat128: 7
+ildouble: 5
+ldouble: 5
+
+Function: "lgamma":
+float: 1
+float128: 5
+ifloat: 1
+ifloat128: 5
+
+Function: "lgamma_downward":
+double: 1
+float: 1
+float128: 8
+idouble: 1
+ifloat: 1
+ifloat128: 8
+
+Function: "lgamma_towardzero":
+double: 1
+float: 1
+float128: 5
+idouble: 1
+ifloat: 1
+ifloat128: 5
+
+Function: "lgamma_upward":
+double: 1
+float: 1
+float128: 8
+idouble: 1
+ifloat: 1
+ifloat128: 8
+
+Function: "log":
+float128: 1
+ifloat128: 1
+
+Function: "log10":
+float128: 1
+ifloat128: 1
+
+Function: "log10_downward":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log10_towardzero":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log10_upward":
+double: 1
+float: 1
+float128: 1
+idouble: 1
+ifloat: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log1p":
+float128: 2
+ifloat128: 2
+
+Function: "log1p_downward":
+double: 1
+float128: 3
+idouble: 1
+ifloat128: 3
+
+Function: "log1p_towardzero":
+double: 1
+float128: 3
+idouble: 1
+ifloat128: 3
+
+Function: "log1p_upward":
+double: 1
+float128: 2
+idouble: 1
+ifloat128: 2
+
+Function: "log2":
+float128: 2
+ifloat128: 2
+
+Function: "log2_downward":
+float128: 3
+ifloat128: 3
+
+Function: "log2_towardzero":
+float128: 1
+ifloat128: 1
+
+Function: "log2_upward":
+float128: 1
+ifloat128: 1
+
+Function: "log_downward":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+
+Function: "log_towardzero":
+double: 1
+float128: 2
+idouble: 1
+ifloat128: 2
+
+Function: "log_upward":
+double: 1
+float128: 1
+idouble: 1
+ifloat128: 1
+
+Function: "pow":
+float128: 2
+ifloat128: 2
+
Function: "pow_downward":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
Function: "pow_towardzero":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
+ildouble: 1
+ldouble: 1
Function: "pow_upward":
double: 1
float: 1
+float128: 2
idouble: 1
ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
Function: "sin":
double: 1
+float128: 1
idouble: 1
+ifloat128: 1
Function: "sin_downward":
double: 1
+float: 1
+float128: 3
idouble: 1
+ifloat: 1
+ifloat128: 3
ildouble: 1
ldouble: 1
Function: "sin_towardzero":
double: 1
+float: 1
+float128: 2
idouble: 1
+ifloat: 1
+ifloat128: 2
ildouble: 1
ldouble: 1
Function: "sin_upward":
double: 1
+float: 1
+float128: 3
idouble: 1
+ifloat: 1
+ifloat128: 3
ildouble: 1
ldouble: 1
Function: "sincos":
double: 1
+float128: 1
idouble: 1
+ifloat128: 1
+
+Function: "sincos_downward":
+double: 1
+float: 1
+float128: 3
+idouble: 1
+ifloat: 1
+ifloat128: 3
+
+Function: "sincos_towardzero":
+double: 1
+float: 1
+float128: 2
+idouble: 1
+ifloat: 1
+ifloat128: 2
+
+Function: "sincos_upward":
+double: 1
+float: 1
+float128: 3
+idouble: 1
+ifloat: 1
+ifloat128: 3
+
+Function: "sinh":
+float128: 2
+ifloat128: 2
+
+Function: "sinh_downward":
+float128: 3
+ifloat128: 3
+
+Function: "sinh_towardzero":
+float128: 3
+ifloat128: 3
+
+Function: "sinh_upward":
+float128: 4
+ifloat128: 4
+
+Function: "tan":
+float128: 1
+ifloat128: 1
+ildouble: 1
+ldouble: 1
Function: "tan_downward":
+float128: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
Function: "tan_towardzero":
+float128: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
Function: "tan_upward":
+float128: 1
+ifloat128: 1
ildouble: 1
ldouble: 1
+Function: "tanh":
+float128: 2
+ifloat128: 2
+
+Function: "tanh_downward":
+float128: 4
+ifloat128: 4
+
+Function: "tanh_towardzero":
+float128: 3
+ifloat128: 3
+
+Function: "tanh_upward":
+float128: 3
+ifloat128: 3
+
Function: "tgamma":
+float128: 4
+ifloat128: 4
+ildouble: 1
+ldouble: 1
+
+Function: "tgamma_downward":
+double: 1
+float: 1
+float128: 5
+idouble: 1
+ifloat: 1
+ifloat128: 5
+ildouble: 1
+ldouble: 1
+
+Function: "tgamma_towardzero":
+double: 1
+float: 1
+float128: 5
+idouble: 1
+ifloat: 1
+ifloat128: 5
+ildouble: 1
+ldouble: 1
+
+Function: "tgamma_upward":
+double: 1
+float: 1
+float128: 4
+idouble: 1
+ifloat: 1
+ifloat128: 4
ildouble: 1
ldouble: 1
Function: "y0":
double: 2
float: 1
+float128: 3
idouble: 2
ifloat: 1
+ifloat128: 3
ildouble: 1
ldouble: 1
+Function: "y0_downward":
+double: 4
+float: 4
+float128: 4
+idouble: 4
+ifloat: 4
+ifloat128: 4
+ildouble: 4
+ldouble: 4
+
+Function: "y0_towardzero":
+double: 3
+float: 3
+float128: 3
+idouble: 3
+ifloat: 3
+ifloat128: 3
+ildouble: 5
+ldouble: 5
+
+Function: "y0_upward":
+double: 4
+float: 5
+float128: 3
+idouble: 4
+ifloat: 5
+ifloat128: 3
+ildouble: 3
+ldouble: 3
+
Function: "y1":
double: 3
float: 2
+float128: 2
idouble: 3
ifloat: 2
+ifloat128: 2
ildouble: 2
ldouble: 2
+Function: "y1_downward":
+double: 9
+float: 2
+float128: 4
+idouble: 9
+ifloat: 2
+ifloat128: 4
+ildouble: 3
+ldouble: 3
+
+Function: "y1_towardzero":
+double: 3
+float: 2
+float128: 2
+idouble: 3
+ifloat: 2
+ifloat128: 2
+ildouble: 3
+ldouble: 3
+
+Function: "y1_upward":
+double: 4
+float: 2
+float128: 5
+idouble: 4
+ifloat: 2
+ifloat128: 5
+ildouble: 7
+ldouble: 7
+
Function: "yn":
double: 3
float: 3
+float128: 5
idouble: 3
ifloat: 3
-ildouble: 2
-ldouble: 2
+ifloat128: 5
+ildouble: 3
+ldouble: 3
+
+Function: "yn_downward":
+double: 4
+float: 4
+float128: 5
+idouble: 4
+ifloat: 4
+ifloat128: 5
+ildouble: 4
+ldouble: 4
+
+Function: "yn_towardzero":
+double: 3
+float: 3
+float128: 5
+idouble: 3
+ifloat: 3
+ifloat128: 5
+ildouble: 5
+ldouble: 5
+
+Function: "yn_upward":
+double: 4
+float: 5
+float128: 5
+idouble: 4
+ifloat: 5
+ifloat128: 5
+ildouble: 3
+ldouble: 3
# end of automatic generation
diff --git a/sysdeps/ia64/memchr.S b/sysdeps/ia64/memchr.S
index d60cf7bd87..9a0abc6f0a 100644
--- a/sysdeps/ia64/memchr.S
+++ b/sysdeps/ia64/memchr.S
@@ -67,6 +67,10 @@ ENTRY(__memchr)
.body
mov ret0 = str
add last = str, in2 // last byte
+ ;;
+ cmp.ltu p6, p0 = last, str
+ ;;
+(p6) mov last = -1
and tmp = 7, str // tmp = str % 8
cmp.ne p7, p0 = r0, r0 // clear p7
extr.u chr = in1, 0, 8 // chr = (unsigned char) in1
diff --git a/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h b/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
index 631cb33d09..2a3bc75b20 100644
--- a/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
@@ -33,6 +33,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0
+#define __PTHREAD_MUTEX_USE_UNION 0
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/ia64/nptl/pthread-offsets.h b/sysdeps/ia64/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..16c6b0d9fd
--- /dev/null
+++ b/sysdeps/ia64/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+#define __PTHREAD_MUTEX_KIND_OFFSET 16
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 24
diff --git a/sysdeps/ieee754/dbl-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/s_nearbyint.c
index dec0c5d6ee..6e3f8316b1 100644
--- a/sysdeps/ieee754/dbl-64/s_nearbyint.c
+++ b/sysdeps/ieee754/dbl-64/s_nearbyint.c
@@ -48,7 +48,7 @@ __nearbyint (double x)
if (j0 < 0)
{
libc_feholdexcept (&env);
- w = TWO52[sx] + x;
+ w = TWO52[sx] + math_opt_barrier (x);
t = w - TWO52[sx];
math_force_eval (t);
libc_fesetenv (&env);
@@ -65,7 +65,7 @@ __nearbyint (double x)
return x; /* x is integral */
}
libc_feholdexcept (&env);
- w = TWO52[sx] + x;
+ w = TWO52[sx] + math_opt_barrier (x);
t = w - TWO52[sx];
math_force_eval (t);
libc_fesetenv (&env);
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c
index 8293819981..7d135b54e4 100644
--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c
@@ -42,9 +42,9 @@ __nearbyint(double x)
if(__builtin_expect(j0<52, 1)) {
if(j0<0) {
libc_feholdexcept (&env);
- double w = TWO52[sx]+x;
+ double w = TWO52[sx] + math_opt_barrier (x);
double t = w-TWO52[sx];
- math_opt_barrier(t);
+ math_force_eval (t);
libc_fesetenv (&env);
return __copysign (t, x);
}
@@ -53,9 +53,9 @@ __nearbyint(double x)
else return x; /* x is integral */
}
libc_feholdexcept (&env);
- double w = TWO52[sx]+x;
+ double w = TWO52[sx] + math_opt_barrier (x);
double t = w-TWO52[sx];
- math_opt_barrier (t);
+ math_force_eval (t);
libc_fesetenv (&env);
return t;
}
diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c
index 5aebefafcf..b06df6b3c8 100644
--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c
+++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c
@@ -37,7 +37,7 @@ __nearbyintf(float x)
if(j0<23) {
if(j0<0) {
libc_feholdexceptf (&env);
- w = TWO23[sx]+x;
+ w = TWO23[sx] + math_opt_barrier (x);
t = w-TWO23[sx];
math_force_eval (t);
libc_fesetenvf (&env);
@@ -50,7 +50,7 @@ __nearbyintf(float x)
else return x; /* x is integral */
}
libc_feholdexceptf (&env);
- w = TWO23[sx]+x;
+ w = TWO23[sx] + math_opt_barrier (x);
t = w-TWO23[sx];
math_force_eval (t);
libc_fesetenvf (&env);
diff --git a/sysdeps/ieee754/ldbl-128/e_lgammal_r.c b/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
index bef2601bce..a80c9eaf33 100644
--- a/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
+++ b/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
@@ -73,11 +73,7 @@
#include <float.h>
static const _Float128 PIL = L(3.1415926535897932384626433832795028841972E0);
-#if LDBL_MANT_DIG == 106
-static const _Float128 MAXLGM = L(0x5.d53649e2d469dbc1f01e99fd66p+1012);
-#else
static const _Float128 MAXLGM = L(1.0485738685148938358098967157129705071571E4928);
-#endif
static const _Float128 one = 1;
static const _Float128 huge = LDBL_MAX;
@@ -777,7 +773,7 @@ __ieee754_lgammal_r (_Float128 x, int *signgamp)
if (x < 0)
{
- if (x < -2 && x > (LDBL_MANT_DIG == 106 ? -48 : -50))
+ if (x < -2 && x > -50)
return __lgamma_negl (x, signgamp);
q = -x;
p = __floorl (q);
diff --git a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
index 1565a8183f..98a33d24a7 100644
--- a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
+++ b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
@@ -45,7 +45,7 @@ _Float128 __nearbyintl(_Float128 x)
if(j0<112) {
if(j0<0) {
feholdexcept (&env);
- w = TWO112[sx]+x;
+ w = TWO112[sx] + math_opt_barrier (x);
t = w-TWO112[sx];
math_force_eval (t);
fesetenv (&env);
@@ -58,7 +58,7 @@ _Float128 __nearbyintl(_Float128 x)
else return x; /* x is integral */
}
feholdexcept (&env);
- w = TWO112[sx]+x;
+ w = TWO112[sx] + math_opt_barrier (x);
t = w-TWO112[sx];
math_force_eval (t);
fesetenv (&env);
diff --git a/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h b/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
index 7ddb368d26..f756857c03 100644
--- a/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
+++ b/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
@@ -37,5 +37,22 @@ extern int __iscanonicall (long double __x)
conversion, before being discarded; in IBM long double, there are
encodings that are not consistently handled as corresponding to any
particular value of the type, and we return 0 for those. */
-# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
-#endif
+# ifndef __cplusplus
+# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
+# else
+/* In C++ mode, __MATH_TG cannot be used, because it relies on
+ __builtin_types_compatible_p, which is a C-only builtin. On the
+ other hand, overloading provides the means to distinguish between
+ the floating-point types. The overloading resolution will match
+ the correct parameter (regardless of type qualifiers (i.e.: const
+ and volatile)). */
+extern "C++" {
+inline int iscanonical (float __val) { return __iscanonicalf (__val); }
+inline int iscanonical (double __val) { return __iscanonical (__val); }
+inline int iscanonical (long double __val) { return __iscanonicall (__val); }
+# if __HAVE_DISTINCT_FLOAT128
+inline int iscanonical (_Float128 __val) { return __iscanonicalf128 (__val); }
+# endif
+}
+# endif /* __cplusplus */
+#endif /* __NO_LONG_DOUBLE_MATH */
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_expl.c b/sysdeps/ieee754/ldbl-128ibm/e_expl.c
index 10df6bb7d5..9185e7cb5c 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_expl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_expl.c
@@ -66,10 +66,8 @@
#include <inttypes.h>
#include <math_private.h>
-#define _Float128 long double
-#define L(x) x ## L
-#include <sysdeps/ieee754/ldbl-128/t_expl.h>
+#include "t_expl.h"
static const long double C[] = {
/* Smallest integer x for which e^x overflows. */
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_j0l.c b/sysdeps/ieee754/ldbl-128ibm/e_j0l.c
index 00bce29284..0a7fe32354 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_j0l.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_j0l.c
@@ -1,5 +1,864 @@
-/* Looks like we can use ieee854 e_j0l.c as is for IBM extended format. */
-#define _Float128 long double
-#define L(x) x ## L
-#include <sysdeps/ieee754/ldbl-128/e_j0l.c>
+/* Bessel function of order zero. IBM Extended Precision version.
+ Copyright 2001 by Stephen L. Moshier (moshier@na-net.ornl.gov).
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file was copied from sysdeps/ieee754/ldbl-128/e_j0l.c. */
+
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+
+/* 1 / sqrt(pi) */
+static const long double ONEOSQPI = 5.6418958354775628694807945156077258584405E-1L;
+/* 2 / pi */
+static const long double TWOOPI = 6.3661977236758134307553505349005744813784E-1L;
+static const long double zero = 0;
+
+/* J0(x) = 1 - x^2/4 + x^2 x^2 R(x^2)
+ Peak relative error 3.4e-37
+ 0 <= x <= 2 */
+#define NJ0_2N 6
+static const long double J0_2N[NJ0_2N + 1] = {
+ 3.133239376997663645548490085151484674892E16L,
+ -5.479944965767990821079467311839107722107E14L,
+ 6.290828903904724265980249871997551894090E12L,
+ -3.633750176832769659849028554429106299915E10L,
+ 1.207743757532429576399485415069244807022E8L,
+ -2.107485999925074577174305650549367415465E5L,
+ 1.562826808020631846245296572935547005859E2L,
+};
+#define NJ0_2D 6
+static const long double J0_2D[NJ0_2D + 1] = {
+ 2.005273201278504733151033654496928968261E18L,
+ 2.063038558793221244373123294054149790864E16L,
+ 1.053350447931127971406896594022010524994E14L,
+ 3.496556557558702583143527876385508882310E11L,
+ 8.249114511878616075860654484367133976306E8L,
+ 1.402965782449571800199759247964242790589E6L,
+ 1.619910762853439600957801751815074787351E3L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2),
+ 0 <= 1/x <= .0625
+ Peak relative error 3.3e-36 */
+#define NP16_IN 9
+static const long double P16_IN[NP16_IN + 1] = {
+ -1.901689868258117463979611259731176301065E-16L,
+ -1.798743043824071514483008340803573980931E-13L,
+ -6.481746687115262291873324132944647438959E-11L,
+ -1.150651553745409037257197798528294248012E-8L,
+ -1.088408467297401082271185599507222695995E-6L,
+ -5.551996725183495852661022587879817546508E-5L,
+ -1.477286941214245433866838787454880214736E-3L,
+ -1.882877976157714592017345347609200402472E-2L,
+ -9.620983176855405325086530374317855880515E-2L,
+ -1.271468546258855781530458854476627766233E-1L,
+};
+#define NP16_ID 9
+static const long double P16_ID[NP16_ID + 1] = {
+ 2.704625590411544837659891569420764475007E-15L,
+ 2.562526347676857624104306349421985403573E-12L,
+ 9.259137589952741054108665570122085036246E-10L,
+ 1.651044705794378365237454962653430805272E-7L,
+ 1.573561544138733044977714063100859136660E-5L,
+ 8.134482112334882274688298469629884804056E-4L,
+ 2.219259239404080863919375103673593571689E-2L,
+ 2.976990606226596289580242451096393862792E-1L,
+ 1.713895630454693931742734911930937246254E0L,
+ 3.231552290717904041465898249160757368855E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ 0.0625 <= 1/x <= 0.125
+ Peak relative error 2.4e-35 */
+#define NP8_16N 10
+static const long double P8_16N[NP8_16N + 1] = {
+ -2.335166846111159458466553806683579003632E-15L,
+ -1.382763674252402720401020004169367089975E-12L,
+ -3.192160804534716696058987967592784857907E-10L,
+ -3.744199606283752333686144670572632116899E-8L,
+ -2.439161236879511162078619292571922772224E-6L,
+ -9.068436986859420951664151060267045346549E-5L,
+ -1.905407090637058116299757292660002697359E-3L,
+ -2.164456143936718388053842376884252978872E-2L,
+ -1.212178415116411222341491717748696499966E-1L,
+ -2.782433626588541494473277445959593334494E-1L,
+ -1.670703190068873186016102289227646035035E-1L,
+};
+#define NP8_16D 10
+static const long double P8_16D[NP8_16D + 1] = {
+ 3.321126181135871232648331450082662856743E-14L,
+ 1.971894594837650840586859228510007703641E-11L,
+ 4.571144364787008285981633719513897281690E-9L,
+ 5.396419143536287457142904742849052402103E-7L,
+ 3.551548222385845912370226756036899901549E-5L,
+ 1.342353874566932014705609788054598013516E-3L,
+ 2.899133293006771317589357444614157734385E-2L,
+ 3.455374978185770197704507681491574261545E-1L,
+ 2.116616964297512311314454834712634820514E0L,
+ 5.850768316827915470087758636881584174432E0L,
+ 5.655273858938766830855753983631132928968E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ 0.125 <= 1/x <= 0.1875
+ Peak relative error 2.7e-35 */
+#define NP5_8N 10
+static const long double P5_8N[NP5_8N + 1] = {
+ -1.270478335089770355749591358934012019596E-12L,
+ -4.007588712145412921057254992155810347245E-10L,
+ -4.815187822989597568124520080486652009281E-8L,
+ -2.867070063972764880024598300408284868021E-6L,
+ -9.218742195161302204046454768106063638006E-5L,
+ -1.635746821447052827526320629828043529997E-3L,
+ -1.570376886640308408247709616497261011707E-2L,
+ -7.656484795303305596941813361786219477807E-2L,
+ -1.659371030767513274944805479908858628053E-1L,
+ -1.185340550030955660015841796219919804915E-1L,
+ -8.920026499909994671248893388013790366712E-3L,
+};
+#define NP5_8D 9
+static const long double P5_8D[NP5_8D + 1] = {
+ 1.806902521016705225778045904631543990314E-11L,
+ 5.728502760243502431663549179135868966031E-9L,
+ 6.938168504826004255287618819550667978450E-7L,
+ 4.183769964807453250763325026573037785902E-5L,
+ 1.372660678476925468014882230851637878587E-3L,
+ 2.516452105242920335873286419212708961771E-2L,
+ 2.550502712902647803796267951846557316182E-1L,
+ 1.365861559418983216913629123778747617072E0L,
+ 3.523825618308783966723472468855042541407E0L,
+ 3.656365803506136165615111349150536282434E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 3.5e-35
+ 0.1875 <= 1/x <= 0.25 */
+#define NP4_5N 9
+static const long double P4_5N[NP4_5N + 1] = {
+ -9.791405771694098960254468859195175708252E-10L,
+ -1.917193059944531970421626610188102836352E-7L,
+ -1.393597539508855262243816152893982002084E-5L,
+ -4.881863490846771259880606911667479860077E-4L,
+ -8.946571245022470127331892085881699269853E-3L,
+ -8.707474232568097513415336886103899434251E-2L,
+ -4.362042697474650737898551272505525973766E-1L,
+ -1.032712171267523975431451359962375617386E0L,
+ -9.630502683169895107062182070514713702346E-1L,
+ -2.251804386252969656586810309252357233320E-1L,
+};
+#define NP4_5D 9
+static const long double P4_5D[NP4_5D + 1] = {
+ 1.392555487577717669739688337895791213139E-8L,
+ 2.748886559120659027172816051276451376854E-6L,
+ 2.024717710644378047477189849678576659290E-4L,
+ 7.244868609350416002930624752604670292469E-3L,
+ 1.373631762292244371102989739300382152416E-1L,
+ 1.412298581400224267910294815260613240668E0L,
+ 7.742495637843445079276397723849017617210E0L,
+ 2.138429269198406512028307045259503811861E1L,
+ 2.651547684548423476506826951831712762610E1L,
+ 1.167499382465291931571685222882909166935E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 2.3e-36
+ 0.25 <= 1/x <= 0.3125 */
+#define NP3r2_4N 9
+static const long double P3r2_4N[NP3r2_4N + 1] = {
+ -2.589155123706348361249809342508270121788E-8L,
+ -3.746254369796115441118148490849195516593E-6L,
+ -1.985595497390808544622893738135529701062E-4L,
+ -5.008253705202932091290132760394976551426E-3L,
+ -6.529469780539591572179155511840853077232E-2L,
+ -4.468736064761814602927408833818990271514E-1L,
+ -1.556391252586395038089729428444444823380E0L,
+ -2.533135309840530224072920725976994981638E0L,
+ -1.605509621731068453869408718565392869560E0L,
+ -2.518966692256192789269859830255724429375E-1L,
+};
+#define NP3r2_4D 9
+static const long double P3r2_4D[NP3r2_4D + 1] = {
+ 3.682353957237979993646169732962573930237E-7L,
+ 5.386741661883067824698973455566332102029E-5L,
+ 2.906881154171822780345134853794241037053E-3L,
+ 7.545832595801289519475806339863492074126E-2L,
+ 1.029405357245594877344360389469584526654E0L,
+ 7.565706120589873131187989560509757626725E0L,
+ 2.951172890699569545357692207898667665796E1L,
+ 5.785723537170311456298467310529815457536E1L,
+ 5.095621464598267889126015412522773474467E1L,
+ 1.602958484169953109437547474953308401442E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 1.0e-35
+ 0.3125 <= 1/x <= 0.375 */
+#define NP2r7_3r2N 9
+static const long double P2r7_3r2N[NP2r7_3r2N + 1] = {
+ -1.917322340814391131073820537027234322550E-7L,
+ -1.966595744473227183846019639723259011906E-5L,
+ -7.177081163619679403212623526632690465290E-4L,
+ -1.206467373860974695661544653741899755695E-2L,
+ -1.008656452188539812154551482286328107316E-1L,
+ -4.216016116408810856620947307438823892707E-1L,
+ -8.378631013025721741744285026537009814161E-1L,
+ -6.973895635309960850033762745957946272579E-1L,
+ -1.797864718878320770670740413285763554812E-1L,
+ -4.098025357743657347681137871388402849581E-3L,
+};
+#define NP2r7_3r2D 8
+static const long double P2r7_3r2D[NP2r7_3r2D + 1] = {
+ 2.726858489303036441686496086962545034018E-6L,
+ 2.840430827557109238386808968234848081424E-4L,
+ 1.063826772041781947891481054529454088832E-2L,
+ 1.864775537138364773178044431045514405468E-1L,
+ 1.665660052857205170440952607701728254211E0L,
+ 7.723745889544331153080842168958348568395E0L,
+ 1.810726427571829798856428548102077799835E1L,
+ 1.986460672157794440666187503833545388527E1L,
+ 8.645503204552282306364296517220055815488E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 1.3e-36
+ 0.3125 <= 1/x <= 0.4375 */
+#define NP2r3_2r7N 9
+static const long double P2r3_2r7N[NP2r3_2r7N + 1] = {
+ -1.594642785584856746358609622003310312622E-6L,
+ -1.323238196302221554194031733595194539794E-4L,
+ -3.856087818696874802689922536987100372345E-3L,
+ -5.113241710697777193011470733601522047399E-2L,
+ -3.334229537209911914449990372942022350558E-1L,
+ -1.075703518198127096179198549659283422832E0L,
+ -1.634174803414062725476343124267110981807E0L,
+ -1.030133247434119595616826842367268304880E0L,
+ -1.989811539080358501229347481000707289391E-1L,
+ -3.246859189246653459359775001466924610236E-3L,
+};
+#define NP2r3_2r7D 8
+static const long double P2r3_2r7D[NP2r3_2r7D + 1] = {
+ 2.267936634217251403663034189684284173018E-5L,
+ 1.918112982168673386858072491437971732237E-3L,
+ 5.771704085468423159125856786653868219522E-2L,
+ 8.056124451167969333717642810661498890507E-1L,
+ 5.687897967531010276788680634413789328776E0L,
+ 2.072596760717695491085444438270778394421E1L,
+ 3.801722099819929988585197088613160496684E1L,
+ 3.254620235902912339534998592085115836829E1L,
+ 1.104847772130720331801884344645060675036E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 1.2e-35
+ 0.4375 <= 1/x <= 0.5 */
+#define NP2_2r3N 8
+static const long double P2_2r3N[NP2_2r3N + 1] = {
+ -1.001042324337684297465071506097365389123E-4L,
+ -6.289034524673365824853547252689991418981E-3L,
+ -1.346527918018624234373664526930736205806E-1L,
+ -1.268808313614288355444506172560463315102E0L,
+ -5.654126123607146048354132115649177406163E0L,
+ -1.186649511267312652171775803270911971693E1L,
+ -1.094032424931998612551588246779200724257E1L,
+ -3.728792136814520055025256353193674625267E0L,
+ -3.000348318524471807839934764596331810608E-1L,
+};
+#define NP2_2r3D 8
+static const long double P2_2r3D[NP2_2r3D + 1] = {
+ 1.423705538269770974803901422532055612980E-3L,
+ 9.171476630091439978533535167485230575894E-2L,
+ 2.049776318166637248868444600215942828537E0L,
+ 2.068970329743769804547326701946144899583E1L,
+ 1.025103500560831035592731539565060347709E2L,
+ 2.528088049697570728252145557167066708284E2L,
+ 2.992160327587558573740271294804830114205E2L,
+ 1.540193761146551025832707739468679973036E2L,
+ 2.779516701986912132637672140709452502650E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 2.2e-35
+ 0 <= 1/x <= .0625 */
+#define NQ16_IN 10
+static const long double Q16_IN[NQ16_IN + 1] = {
+ 2.343640834407975740545326632205999437469E-18L,
+ 2.667978112927811452221176781536278257448E-15L,
+ 1.178415018484555397390098879501969116536E-12L,
+ 2.622049767502719728905924701288614016597E-10L,
+ 3.196908059607618864801313380896308968673E-8L,
+ 2.179466154171673958770030655199434798494E-6L,
+ 8.139959091628545225221976413795645177291E-5L,
+ 1.563900725721039825236927137885747138654E-3L,
+ 1.355172364265825167113562519307194840307E-2L,
+ 3.928058355906967977269780046844768588532E-2L,
+ 1.107891967702173292405380993183694932208E-2L,
+};
+#define NQ16_ID 9
+static const long double Q16_ID[NQ16_ID + 1] = {
+ 3.199850952578356211091219295199301766718E-17L,
+ 3.652601488020654842194486058637953363918E-14L,
+ 1.620179741394865258354608590461839031281E-11L,
+ 3.629359209474609630056463248923684371426E-9L,
+ 4.473680923894354600193264347733477363305E-7L,
+ 3.106368086644715743265603656011050476736E-5L,
+ 1.198239259946770604954664925153424252622E-3L,
+ 2.446041004004283102372887804475767568272E-2L,
+ 2.403235525011860603014707768815113698768E-1L,
+ 9.491006790682158612266270665136910927149E-1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ };
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 5.1e-36
+ 0.0625 <= 1/x <= 0.125 */
+#define NQ8_16N 11
+static const long double Q8_16N[NQ8_16N + 1] = {
+ 1.001954266485599464105669390693597125904E-17L,
+ 7.545499865295034556206475956620160007849E-15L,
+ 2.267838684785673931024792538193202559922E-12L,
+ 3.561909705814420373609574999542459912419E-10L,
+ 3.216201422768092505214730633842924944671E-8L,
+ 1.731194793857907454569364622452058554314E-6L,
+ 5.576944613034537050396518509871004586039E-5L,
+ 1.051787760316848982655967052985391418146E-3L,
+ 1.102852974036687441600678598019883746959E-2L,
+ 5.834647019292460494254225988766702933571E-2L,
+ 1.290281921604364618912425380717127576529E-1L,
+ 7.598886310387075708640370806458926458301E-2L,
+};
+#define NQ8_16D 11
+static const long double Q8_16D[NQ8_16D + 1] = {
+ 1.368001558508338469503329967729951830843E-16L,
+ 1.034454121857542147020549303317348297289E-13L,
+ 3.128109209247090744354764050629381674436E-11L,
+ 4.957795214328501986562102573522064468671E-9L,
+ 4.537872468606711261992676606899273588899E-7L,
+ 2.493639207101727713192687060517509774182E-5L,
+ 8.294957278145328349785532236663051405805E-4L,
+ 1.646471258966713577374948205279380115839E-2L,
+ 1.878910092770966718491814497982191447073E-1L,
+ 1.152641605706170353727903052525652504075E0L,
+ 3.383550240669773485412333679367792932235E0L,
+ 3.823875252882035706910024716609908473970E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.9e-35
+ 0.125 <= 1/x <= 0.1875 */
+#define NQ5_8N 10
+static const long double Q5_8N[NQ5_8N + 1] = {
+ 1.750399094021293722243426623211733898747E-13L,
+ 6.483426211748008735242909236490115050294E-11L,
+ 9.279430665656575457141747875716899958373E-9L,
+ 6.696634968526907231258534757736576340266E-7L,
+ 2.666560823798895649685231292142838188061E-5L,
+ 6.025087697259436271271562769707550594540E-4L,
+ 7.652807734168613251901945778921336353485E-3L,
+ 5.226269002589406461622551452343519078905E-2L,
+ 1.748390159751117658969324896330142895079E-1L,
+ 2.378188719097006494782174902213083589660E-1L,
+ 8.383984859679804095463699702165659216831E-2L,
+};
+#define NQ5_8D 10
+static const long double Q5_8D[NQ5_8D + 1] = {
+ 2.389878229704327939008104855942987615715E-12L,
+ 8.926142817142546018703814194987786425099E-10L,
+ 1.294065862406745901206588525833274399038E-7L,
+ 9.524139899457666250828752185212769682191E-6L,
+ 3.908332488377770886091936221573123353489E-4L,
+ 9.250427033957236609624199884089916836748E-3L,
+ 1.263420066165922645975830877751588421451E-1L,
+ 9.692527053860420229711317379861733180654E-1L,
+ 3.937813834630430172221329298841520707954E0L,
+ 7.603126427436356534498908111445191312181E0L,
+ 5.670677653334105479259958485084550934305E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.2e-35
+ 0.1875 <= 1/x <= 0.25 */
+#define NQ4_5N 10
+static const long double Q4_5N[NQ4_5N + 1] = {
+ 2.233870042925895644234072357400122854086E-11L,
+ 5.146223225761993222808463878999151699792E-9L,
+ 4.459114531468296461688753521109797474523E-7L,
+ 1.891397692931537975547242165291668056276E-5L,
+ 4.279519145911541776938964806470674565504E-4L,
+ 5.275239415656560634702073291768904783989E-3L,
+ 3.468698403240744801278238473898432608887E-2L,
+ 1.138773146337708415188856882915457888274E-1L,
+ 1.622717518946443013587108598334636458955E-1L,
+ 7.249040006390586123760992346453034628227E-2L,
+ 1.941595365256460232175236758506411486667E-3L,
+};
+#define NQ4_5D 9
+static const long double Q4_5D[NQ4_5D + 1] = {
+ 3.049977232266999249626430127217988047453E-10L,
+ 7.120883230531035857746096928889676144099E-8L,
+ 6.301786064753734446784637919554359588859E-6L,
+ 2.762010530095069598480766869426308077192E-4L,
+ 6.572163250572867859316828886203406361251E-3L,
+ 8.752566114841221958200215255461843397776E-2L,
+ 6.487654992874805093499285311075289932664E-1L,
+ 2.576550017826654579451615283022812801435E0L,
+ 5.056392229924022835364779562707348096036E0L,
+ 4.179770081068251464907531367859072157773E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 1.4e-36
+ 0.25 <= 1/x <= 0.3125 */
+#define NQ3r2_4N 10
+static const long double Q3r2_4N[NQ3r2_4N + 1] = {
+ 6.126167301024815034423262653066023684411E-10L,
+ 1.043969327113173261820028225053598975128E-7L,
+ 6.592927270288697027757438170153763220190E-6L,
+ 2.009103660938497963095652951912071336730E-4L,
+ 3.220543385492643525985862356352195896964E-3L,
+ 2.774405975730545157543417650436941650990E-2L,
+ 1.258114008023826384487378016636555041129E-1L,
+ 2.811724258266902502344701449984698323860E-1L,
+ 2.691837665193548059322831687432415014067E-1L,
+ 7.949087384900985370683770525312735605034E-2L,
+ 1.229509543620976530030153018986910810747E-3L,
+};
+#define NQ3r2_4D 9
+static const long double Q3r2_4D[NQ3r2_4D + 1] = {
+ 8.364260446128475461539941389210166156568E-9L,
+ 1.451301850638956578622154585560759862764E-6L,
+ 9.431830010924603664244578867057141839463E-5L,
+ 3.004105101667433434196388593004526182741E-3L,
+ 5.148157397848271739710011717102773780221E-2L,
+ 4.901089301726939576055285374953887874895E-1L,
+ 2.581760991981709901216967665934142240346E0L,
+ 7.257105880775059281391729708630912791847E0L,
+ 1.006014717326362868007913423810737369312E1L,
+ 5.879416600465399514404064187445293212470E0L,
+ /* 1.000000000000000000000000000000000000000E0*/
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.8e-36
+ 0.3125 <= 1/x <= 0.375 */
+#define NQ2r7_3r2N 9
+static const long double Q2r7_3r2N[NQ2r7_3r2N + 1] = {
+ 7.584861620402450302063691901886141875454E-8L,
+ 9.300939338814216296064659459966041794591E-6L,
+ 4.112108906197521696032158235392604947895E-4L,
+ 8.515168851578898791897038357239630654431E-3L,
+ 8.971286321017307400142720556749573229058E-2L,
+ 4.885856732902956303343015636331874194498E-1L,
+ 1.334506268733103291656253500506406045846E0L,
+ 1.681207956863028164179042145803851824654E0L,
+ 8.165042692571721959157677701625853772271E-1L,
+ 9.805848115375053300608712721986235900715E-2L,
+};
+#define NQ2r7_3r2D 9
+static const long double Q2r7_3r2D[NQ2r7_3r2D + 1] = {
+ 1.035586492113036586458163971239438078160E-6L,
+ 1.301999337731768381683593636500979713689E-4L,
+ 5.993695702564527062553071126719088859654E-3L,
+ 1.321184892887881883489141186815457808785E-1L,
+ 1.528766555485015021144963194165165083312E0L,
+ 9.561463309176490874525827051566494939295E0L,
+ 3.203719484883967351729513662089163356911E1L,
+ 5.497294687660930446641539152123568668447E1L,
+ 4.391158169390578768508675452986948391118E1L,
+ 1.347836630730048077907818943625789418378E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 2.2e-35
+ 0.375 <= 1/x <= 0.4375 */
+#define NQ2r3_2r7N 9
+static const long double Q2r3_2r7N[NQ2r3_2r7N + 1] = {
+ 4.455027774980750211349941766420190722088E-7L,
+ 4.031998274578520170631601850866780366466E-5L,
+ 1.273987274325947007856695677491340636339E-3L,
+ 1.818754543377448509897226554179659122873E-2L,
+ 1.266748858326568264126353051352269875352E-1L,
+ 4.327578594728723821137731555139472880414E-1L,
+ 6.892532471436503074928194969154192615359E-1L,
+ 4.490775818438716873422163588640262036506E-1L,
+ 8.649615949297322440032000346117031581572E-2L,
+ 7.261345286655345047417257611469066147561E-4L,
+};
+#define NQ2r3_2r7D 8
+static const long double Q2r3_2r7D[NQ2r3_2r7D + 1] = {
+ 6.082600739680555266312417978064954793142E-6L,
+ 5.693622538165494742945717226571441747567E-4L,
+ 1.901625907009092204458328768129666975975E-2L,
+ 2.958689532697857335456896889409923371570E-1L,
+ 2.343124711045660081603809437993368799568E0L,
+ 9.665894032187458293568704885528192804376E0L,
+ 2.035273104990617136065743426322454881353E1L,
+ 2.044102010478792896815088858740075165531E1L,
+ 8.445937177863155827844146643468706599304E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.1e-36
+ 0.4375 <= 1/x <= 0.5 */
+#define NQ2_2r3N 9
+static const long double Q2_2r3N[NQ2_2r3N + 1] = {
+ 2.817566786579768804844367382809101929314E-6L,
+ 2.122772176396691634147024348373539744935E-4L,
+ 5.501378031780457828919593905395747517585E-3L,
+ 6.355374424341762686099147452020466524659E-2L,
+ 3.539652320122661637429658698954748337223E-1L,
+ 9.571721066119617436343740541777014319695E-1L,
+ 1.196258777828426399432550698612171955305E0L,
+ 6.069388659458926158392384709893753793967E-1L,
+ 9.026746127269713176512359976978248763621E-2L,
+ 5.317668723070450235320878117210807236375E-4L,
+};
+#define NQ2_2r3D 8
+static const long double Q2_2r3D[NQ2_2r3D + 1] = {
+ 3.846924354014260866793741072933159380158E-5L,
+ 3.017562820057704325510067178327449946763E-3L,
+ 8.356305620686867949798885808540444210935E-2L,
+ 1.068314930499906838814019619594424586273E0L,
+ 6.900279623894821067017966573640732685233E0L,
+ 2.307667390886377924509090271780839563141E1L,
+ 3.921043465412723970791036825401273528513E1L,
+ 3.167569478939719383241775717095729233436E1L,
+ 1.051023841699200920276198346301543665909E1L,
+ /* 1.000000000000000000000000000000000000000E0*/
+};
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Bessel function of the first kind, order zero. */
+
+long double
+__ieee754_j0l (long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! isfinite (x))
+ {
+ if (x != x)
+ return x + x;
+ else
+ return 0;
+ }
+ if (x == 0)
+ return 1;
+
+ xx = fabsl (x);
+ if (xx <= 2)
+ {
+ if (xx < 0x1p-57L)
+ return 1;
+ /* 0 <= x <= 2 */
+ z = xx * xx;
+ p = z * z * neval (z, J0_2N, NJ0_2N) / deval (z, J0_2D, NJ0_2D);
+ p -= 0.25L * z;
+ p += 1;
+ return p;
+ }
+
+ /* X = x - pi/4
+ cos(X) = cos(x) cos(pi/4) + sin(x) sin(pi/4)
+ = 1/sqrt(2) * (cos(x) + sin(x))
+ sin(X) = sin(x) cos(pi/4) - cos(x) sin(pi/4)
+ = 1/sqrt(2) * (sin(x) - cos(x))
+ sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ cf. Fdlibm. */
+ __sincosl (xx, &s, &c);
+ ss = s - c;
+ cc = s + c;
+ if (xx <= LDBL_MAX / 2)
+ {
+ z = -__cosl (xx + xx);
+ if ((s * c) < 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+
+ if (xx > 0x1p256L)
+ return ONEOSQPI * cc / __ieee754_sqrtl (xx);
+
+ xinv = 1 / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1 + z * p;
+ q = z * xinv * q;
+ q = q - 0.125L * xinv;
+ z = ONEOSQPI * (p * cc - q * ss) / __ieee754_sqrtl (xx);
+ return z;
+}
+strong_alias (__ieee754_j0l, __j0l_finite)
+
+
+/* Y0(x) = 2/pi * log(x) * J0(x) + R(x^2)
+ Peak absolute error 1.7e-36 (relative where Y0 > 1)
+ 0 <= x <= 2 */
+#define NY0_2N 7
+static long double Y0_2N[NY0_2N + 1] = {
+ -1.062023609591350692692296993537002558155E19L,
+ 2.542000883190248639104127452714966858866E19L,
+ -1.984190771278515324281415820316054696545E18L,
+ 4.982586044371592942465373274440222033891E16L,
+ -5.529326354780295177243773419090123407550E14L,
+ 3.013431465522152289279088265336861140391E12L,
+ -7.959436160727126750732203098982718347785E9L,
+ 8.230845651379566339707130644134372793322E6L,
+};
+#define NY0_2D 7
+static long double Y0_2D[NY0_2D + 1] = {
+ 1.438972634353286978700329883122253752192E20L,
+ 1.856409101981569254247700169486907405500E18L,
+ 1.219693352678218589553725579802986255614E16L,
+ 5.389428943282838648918475915779958097958E13L,
+ 1.774125762108874864433872173544743051653E11L,
+ 4.522104832545149534808218252434693007036E8L,
+ 8.872187401232943927082914504125234454930E5L,
+ 1.251945613186787532055610876304669413955E3L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+static const long double U0 = -7.3804295108687225274343927948483016310862e-02L;
+
+/* Bessel function of the second kind, order zero. */
+
+long double
+ __ieee754_y0l(long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! isfinite (x))
+ return 1 / (x + x * x);
+ if (x <= 0)
+ {
+ if (x < 0)
+ return (zero / (zero * x));
+ return -1 / zero; /* -inf and divide by zero exception. */
+ }
+ xx = fabsl (x);
+ if (xx <= 0x1p-57)
+ return U0 + TWOOPI * __ieee754_logl (x);
+ if (xx <= 2)
+ {
+ /* 0 <= x <= 2 */
+ z = xx * xx;
+ p = neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D);
+ p = TWOOPI * __ieee754_logl (x) * __ieee754_j0l (x) + p;
+ return p;
+ }
+
+ /* X = x - pi/4
+ cos(X) = cos(x) cos(pi/4) + sin(x) sin(pi/4)
+ = 1/sqrt(2) * (cos(x) + sin(x))
+ sin(X) = sin(x) cos(pi/4) - cos(x) sin(pi/4)
+ = 1/sqrt(2) * (sin(x) - cos(x))
+ sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ cf. Fdlibm. */
+ __sincosl (x, &s, &c);
+ ss = s - c;
+ cc = s + c;
+ if (xx <= LDBL_MAX / 2)
+ {
+ z = -__cosl (x + x);
+ if ((s * c) < 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+
+ if (xx > 0x1p256L)
+ return ONEOSQPI * ss / __ieee754_sqrtl (x);
+
+ xinv = 1 / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1 + z * p;
+ q = z * xinv * q;
+ q = q - 0.125L * xinv;
+ z = ONEOSQPI * (p * ss + q * cc) / __ieee754_sqrtl (x);
+ return z;
+}
+strong_alias (__ieee754_y0l, __y0l_finite)
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_j1l.c b/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
index da9fd9eeca..5956c97b82 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
@@ -1,4 +1,884 @@
-/* Looks like we can use ieee854 e_j1l.c as is for IBM extended format. */
-#define _Float128 long double
-#define L(x) x ## L
-#include <sysdeps/ieee754/ldbl-128/e_j1l.c>
+/* Bessel function of order one. IBM Extended Precision version.
+ Copyright 2001 by Stephen L. Moshier (moshier@na-net.onrl.gov).
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file was copied from sysdeps/ieee754/ldbl-128/e_j0l.c. */
+
+
+#include <errno.h>
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+
+/* 1 / sqrt(pi) */
+static const long double ONEOSQPI = 5.6418958354775628694807945156077258584405E-1L;
+/* 2 / pi */
+static const long double TWOOPI = 6.3661977236758134307553505349005744813784E-1L;
+static const long double zero = 0;
+
+/* J1(x) = .5x + x x^2 R(x^2)
+ Peak relative error 1.9e-35
+ 0 <= x <= 2 */
+#define NJ0_2N 6
+static const long double J0_2N[NJ0_2N + 1] = {
+ -5.943799577386942855938508697619735179660E16L,
+ 1.812087021305009192259946997014044074711E15L,
+ -2.761698314264509665075127515729146460895E13L,
+ 2.091089497823600978949389109350658815972E11L,
+ -8.546413231387036372945453565654130054307E8L,
+ 1.797229225249742247475464052741320612261E6L,
+ -1.559552840946694171346552770008812083969E3L
+};
+#define NJ0_2D 6
+static const long double J0_2D[NJ0_2D + 1] = {
+ 9.510079323819108569501613916191477479397E17L,
+ 1.063193817503280529676423936545854693915E16L,
+ 5.934143516050192600795972192791775226920E13L,
+ 2.168000911950620999091479265214368352883E11L,
+ 5.673775894803172808323058205986256928794E8L,
+ 1.080329960080981204840966206372671147224E6L,
+ 1.411951256636576283942477881535283304912E3L,
+ /* 1.000000000000000000000000000000000000000E0L */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ 0 <= 1/x <= .0625
+ Peak relative error 3.6e-36 */
+#define NP16_IN 9
+static const long double P16_IN[NP16_IN + 1] = {
+ 5.143674369359646114999545149085139822905E-16L,
+ 4.836645664124562546056389268546233577376E-13L,
+ 1.730945562285804805325011561498453013673E-10L,
+ 3.047976856147077889834905908605310585810E-8L,
+ 2.855227609107969710407464739188141162386E-6L,
+ 1.439362407936705484122143713643023998457E-4L,
+ 3.774489768532936551500999699815873422073E-3L,
+ 4.723962172984642566142399678920790598426E-2L,
+ 2.359289678988743939925017240478818248735E-1L,
+ 3.032580002220628812728954785118117124520E-1L,
+};
+#define NP16_ID 9
+static const long double P16_ID[NP16_ID + 1] = {
+ 4.389268795186898018132945193912677177553E-15L,
+ 4.132671824807454334388868363256830961655E-12L,
+ 1.482133328179508835835963635130894413136E-9L,
+ 2.618941412861122118906353737117067376236E-7L,
+ 2.467854246740858470815714426201888034270E-5L,
+ 1.257192927368839847825938545925340230490E-3L,
+ 3.362739031941574274949719324644120720341E-2L,
+ 4.384458231338934105875343439265370178858E-1L,
+ 2.412830809841095249170909628197264854651E0L,
+ 4.176078204111348059102962617368214856874E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ 0.0625 <= 1/x <= 0.125
+ Peak relative error 1.9e-36 */
+#define NP8_16N 11
+static const long double P8_16N[NP8_16N + 1] = {
+ 2.984612480763362345647303274082071598135E-16L,
+ 1.923651877544126103941232173085475682334E-13L,
+ 4.881258879388869396043760693256024307743E-11L,
+ 6.368866572475045408480898921866869811889E-9L,
+ 4.684818344104910450523906967821090796737E-7L,
+ 2.005177298271593587095982211091300382796E-5L,
+ 4.979808067163957634120681477207147536182E-4L,
+ 6.946005761642579085284689047091173581127E-3L,
+ 5.074601112955765012750207555985299026204E-2L,
+ 1.698599455896180893191766195194231825379E-1L,
+ 1.957536905259237627737222775573623779638E-1L,
+ 2.991314703282528370270179989044994319374E-2L,
+};
+#define NP8_16D 10
+static const long double P8_16D[NP8_16D + 1] = {
+ 2.546869316918069202079580939942463010937E-15L,
+ 1.644650111942455804019788382157745229955E-12L,
+ 4.185430770291694079925607420808011147173E-10L,
+ 5.485331966975218025368698195861074143153E-8L,
+ 4.062884421686912042335466327098932678905E-6L,
+ 1.758139661060905948870523641319556816772E-4L,
+ 4.445143889306356207566032244985607493096E-3L,
+ 6.391901016293512632765621532571159071158E-2L,
+ 4.933040207519900471177016015718145795434E-1L,
+ 1.839144086168947712971630337250761842976E0L,
+ 2.715120873995490920415616716916149586579E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ 0.125 <= 1/x <= 0.1875
+ Peak relative error 1.3e-36 */
+#define NP5_8N 10
+static const long double P5_8N[NP5_8N + 1] = {
+ 2.837678373978003452653763806968237227234E-12L,
+ 9.726641165590364928442128579282742354806E-10L,
+ 1.284408003604131382028112171490633956539E-7L,
+ 8.524624695868291291250573339272194285008E-6L,
+ 3.111516908953172249853673787748841282846E-4L,
+ 6.423175156126364104172801983096596409176E-3L,
+ 7.430220589989104581004416356260692450652E-2L,
+ 4.608315409833682489016656279567605536619E-1L,
+ 1.396870223510964882676225042258855977512E0L,
+ 1.718500293904122365894630460672081526236E0L,
+ 5.465927698800862172307352821870223855365E-1L
+};
+#define NP5_8D 10
+static const long double P5_8D[NP5_8D + 1] = {
+ 2.421485545794616609951168511612060482715E-11L,
+ 8.329862750896452929030058039752327232310E-9L,
+ 1.106137992233383429630592081375289010720E-6L,
+ 7.405786153760681090127497796448503306939E-5L,
+ 2.740364785433195322492093333127633465227E-3L,
+ 5.781246470403095224872243564165254652198E-2L,
+ 6.927711353039742469918754111511109983546E-1L,
+ 4.558679283460430281188304515922826156690E0L,
+ 1.534468499844879487013168065728837900009E1L,
+ 2.313927430889218597919624843161569422745E1L,
+ 1.194506341319498844336768473218382828637E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.4e-36
+ 0.1875 <= 1/x <= 0.25 */
+#define NP4_5N 10
+static const long double P4_5N[NP4_5N + 1] = {
+ 1.846029078268368685834261260420933914621E-10L,
+ 3.916295939611376119377869680335444207768E-8L,
+ 3.122158792018920627984597530935323997312E-6L,
+ 1.218073444893078303994045653603392272450E-4L,
+ 2.536420827983485448140477159977981844883E-3L,
+ 2.883011322006690823959367922241169171315E-2L,
+ 1.755255190734902907438042414495469810830E-1L,
+ 5.379317079922628599870898285488723736599E-1L,
+ 7.284904050194300773890303361501726561938E-1L,
+ 3.270110346613085348094396323925000362813E-1L,
+ 1.804473805689725610052078464951722064757E-2L,
+};
+#define NP4_5D 9
+static const long double P4_5D[NP4_5D + 1] = {
+ 1.575278146806816970152174364308980863569E-9L,
+ 3.361289173657099516191331123405675054321E-7L,
+ 2.704692281550877810424745289838790693708E-5L,
+ 1.070854930483999749316546199273521063543E-3L,
+ 2.282373093495295842598097265627962125411E-2L,
+ 2.692025460665354148328762368240343249830E-1L,
+ 1.739892942593664447220951225734811133759E0L,
+ 5.890727576752230385342377570386657229324E0L,
+ 9.517442287057841500750256954117735128153E0L,
+ 6.100616353935338240775363403030137736013E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 3.0e-36
+ 0.25 <= 1/x <= 0.3125 */
+#define NP3r2_4N 9
+static const long double P3r2_4N[NP3r2_4N + 1] = {
+ 8.240803130988044478595580300846665863782E-8L,
+ 1.179418958381961224222969866406483744580E-5L,
+ 6.179787320956386624336959112503824397755E-4L,
+ 1.540270833608687596420595830747166658383E-2L,
+ 1.983904219491512618376375619598837355076E-1L,
+ 1.341465722692038870390470651608301155565E0L,
+ 4.617865326696612898792238245990854646057E0L,
+ 7.435574801812346424460233180412308000587E0L,
+ 4.671327027414635292514599201278557680420E0L,
+ 7.299530852495776936690976966995187714739E-1L,
+};
+#define NP3r2_4D 9
+static const long double P3r2_4D[NP3r2_4D + 1] = {
+ 7.032152009675729604487575753279187576521E-7L,
+ 1.015090352324577615777511269928856742848E-4L,
+ 5.394262184808448484302067955186308730620E-3L,
+ 1.375291438480256110455809354836988584325E-1L,
+ 1.836247144461106304788160919310404376670E0L,
+ 1.314378564254376655001094503090935880349E1L,
+ 4.957184590465712006934452500894672343488E1L,
+ 9.287394244300647738855415178790263465398E1L,
+ 7.652563275535900609085229286020552768399E1L,
+ 2.147042473003074533150718117770093209096E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.0e-35
+ 0.3125 <= 1/x <= 0.375 */
+#define NP2r7_3r2N 9
+static const long double P2r7_3r2N[NP2r7_3r2N + 1] = {
+ 4.599033469240421554219816935160627085991E-7L,
+ 4.665724440345003914596647144630893997284E-5L,
+ 1.684348845667764271596142716944374892756E-3L,
+ 2.802446446884455707845985913454440176223E-2L,
+ 2.321937586453963310008279956042545173930E-1L,
+ 9.640277413988055668692438709376437553804E-1L,
+ 1.911021064710270904508663334033003246028E0L,
+ 1.600811610164341450262992138893970224971E0L,
+ 4.266299218652587901171386591543457861138E-1L,
+ 1.316470424456061252962568223251247207325E-2L,
+};
+#define NP2r7_3r2D 8
+static const long double P2r7_3r2D[NP2r7_3r2D + 1] = {
+ 3.924508608545520758883457108453520099610E-6L,
+ 4.029707889408829273226495756222078039823E-4L,
+ 1.484629715787703260797886463307469600219E-2L,
+ 2.553136379967180865331706538897231588685E-1L,
+ 2.229457223891676394409880026887106228740E0L,
+ 1.005708903856384091956550845198392117318E1L,
+ 2.277082659664386953166629360352385889558E1L,
+ 2.384726835193630788249826630376533988245E1L,
+ 9.700989749041320895890113781610939632410E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.7e-36
+ 0.3125 <= 1/x <= 0.4375 */
+#define NP2r3_2r7N 9
+static const long double P2r3_2r7N[NP2r3_2r7N + 1] = {
+ 3.916766777108274628543759603786857387402E-6L,
+ 3.212176636756546217390661984304645137013E-4L,
+ 9.255768488524816445220126081207248947118E-3L,
+ 1.214853146369078277453080641911700735354E-1L,
+ 7.855163309847214136198449861311404633665E-1L,
+ 2.520058073282978403655488662066019816540E0L,
+ 3.825136484837545257209234285382183711466E0L,
+ 2.432569427554248006229715163865569506873E0L,
+ 4.877934835018231178495030117729800489743E-1L,
+ 1.109902737860249670981355149101343427885E-2L,
+};
+#define NP2r3_2r7D 8
+static const long double P2r3_2r7D[NP2r3_2r7D + 1] = {
+ 3.342307880794065640312646341190547184461E-5L,
+ 2.782182891138893201544978009012096558265E-3L,
+ 8.221304931614200702142049236141249929207E-2L,
+ 1.123728246291165812392918571987858010949E0L,
+ 7.740482453652715577233858317133423434590E0L,
+ 2.737624677567945952953322566311201919139E1L,
+ 4.837181477096062403118304137851260715475E1L,
+ 3.941098643468580791437772701093795299274E1L,
+ 1.245821247166544627558323920382547533630E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.7e-35
+ 0.4375 <= 1/x <= 0.5 */
+#define NP2_2r3N 8
+static const long double P2_2r3N[NP2_2r3N + 1] = {
+ 3.397930802851248553545191160608731940751E-4L,
+ 2.104020902735482418784312825637833698217E-2L,
+ 4.442291771608095963935342749477836181939E-1L,
+ 4.131797328716583282869183304291833754967E0L,
+ 1.819920169779026500146134832455189917589E1L,
+ 3.781779616522937565300309684282401791291E1L,
+ 3.459605449728864218972931220783543410347E1L,
+ 1.173594248397603882049066603238568316561E1L,
+ 9.455702270242780642835086549285560316461E-1L,
+};
+#define NP2_2r3D 8
+static const long double P2_2r3D[NP2_2r3D + 1] = {
+ 2.899568897241432883079888249845707400614E-3L,
+ 1.831107138190848460767699919531132426356E-1L,
+ 3.999350044057883839080258832758908825165E0L,
+ 3.929041535867957938340569419874195303712E1L,
+ 1.884245613422523323068802689915538908291E2L,
+ 4.461469948819229734353852978424629815929E2L,
+ 5.004998753999796821224085972610636347903E2L,
+ 2.386342520092608513170837883757163414100E2L,
+ 3.791322528149347975999851588922424189957E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 8.0e-36
+ 0 <= 1/x <= .0625 */
+#define NQ16_IN 10
+static const long double Q16_IN[NQ16_IN + 1] = {
+ -3.917420835712508001321875734030357393421E-18L,
+ -4.440311387483014485304387406538069930457E-15L,
+ -1.951635424076926487780929645954007139616E-12L,
+ -4.318256438421012555040546775651612810513E-10L,
+ -5.231244131926180765270446557146989238020E-8L,
+ -3.540072702902043752460711989234732357653E-6L,
+ -1.311017536555269966928228052917534882984E-4L,
+ -2.495184669674631806622008769674827575088E-3L,
+ -2.141868222987209028118086708697998506716E-2L,
+ -6.184031415202148901863605871197272650090E-2L,
+ -1.922298704033332356899546792898156493887E-2L,
+};
+#define NQ16_ID 9
+static const long double Q16_ID[NQ16_ID + 1] = {
+ 3.820418034066293517479619763498400162314E-17L,
+ 4.340702810799239909648911373329149354911E-14L,
+ 1.914985356383416140706179933075303538524E-11L,
+ 4.262333682610888819476498617261895474330E-9L,
+ 5.213481314722233980346462747902942182792E-7L,
+ 3.585741697694069399299005316809954590558E-5L,
+ 1.366513429642842006385029778105539457546E-3L,
+ 2.745282599850704662726337474371355160594E-2L,
+ 2.637644521611867647651200098449903330074E-1L,
+ 1.006953426110765984590782655598680488746E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ };
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.9e-36
+ 0.0625 <= 1/x <= 0.125 */
+#define NQ8_16N 11
+static const long double Q8_16N[NQ8_16N + 1] = {
+ -2.028630366670228670781362543615221542291E-17L,
+ -1.519634620380959966438130374006858864624E-14L,
+ -4.540596528116104986388796594639405114524E-12L,
+ -7.085151756671466559280490913558388648274E-10L,
+ -6.351062671323970823761883833531546885452E-8L,
+ -3.390817171111032905297982523519503522491E-6L,
+ -1.082340897018886970282138836861233213972E-4L,
+ -2.020120801187226444822977006648252379508E-3L,
+ -2.093169910981725694937457070649605557555E-2L,
+ -1.092176538874275712359269481414448063393E-1L,
+ -2.374790947854765809203590474789108718733E-1L,
+ -1.365364204556573800719985118029601401323E-1L,
+};
+#define NQ8_16D 11
+static const long double Q8_16D[NQ8_16D + 1] = {
+ 1.978397614733632533581207058069628242280E-16L,
+ 1.487361156806202736877009608336766720560E-13L,
+ 4.468041406888412086042576067133365913456E-11L,
+ 7.027822074821007443672290507210594648877E-9L,
+ 6.375740580686101224127290062867976007374E-7L,
+ 3.466887658320002225888644977076410421940E-5L,
+ 1.138625640905289601186353909213719596986E-3L,
+ 2.224470799470414663443449818235008486439E-2L,
+ 2.487052928527244907490589787691478482358E-1L,
+ 1.483927406564349124649083853892380899217E0L,
+ 4.182773513276056975777258788903489507705E0L,
+ 4.419665392573449746043880892524360870944E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.5e-35
+ 0.125 <= 1/x <= 0.1875 */
+#define NQ5_8N 10
+static const long double Q5_8N[NQ5_8N + 1] = {
+ -3.656082407740970534915918390488336879763E-13L,
+ -1.344660308497244804752334556734121771023E-10L,
+ -1.909765035234071738548629788698150760791E-8L,
+ -1.366668038160120210269389551283666716453E-6L,
+ -5.392327355984269366895210704976314135683E-5L,
+ -1.206268245713024564674432357634540343884E-3L,
+ -1.515456784370354374066417703736088291287E-2L,
+ -1.022454301137286306933217746545237098518E-1L,
+ -3.373438906472495080504907858424251082240E-1L,
+ -4.510782522110845697262323973549178453405E-1L,
+ -1.549000892545288676809660828213589804884E-1L,
+};
+#define NQ5_8D 10
+static const long double Q5_8D[NQ5_8D + 1] = {
+ 3.565550843359501079050699598913828460036E-12L,
+ 1.321016015556560621591847454285330528045E-9L,
+ 1.897542728662346479999969679234270605975E-7L,
+ 1.381720283068706710298734234287456219474E-5L,
+ 5.599248147286524662305325795203422873725E-4L,
+ 1.305442352653121436697064782499122164843E-2L,
+ 1.750234079626943298160445750078631894985E-1L,
+ 1.311420542073436520965439883806946678491E0L,
+ 5.162757689856842406744504211089724926650E0L,
+ 9.527760296384704425618556332087850581308E0L,
+ 6.604648207463236667912921642545100248584E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.3e-35
+ 0.1875 <= 1/x <= 0.25 */
+#define NQ4_5N 10
+static const long double Q4_5N[NQ4_5N + 1] = {
+ -4.079513568708891749424783046520200903755E-11L,
+ -9.326548104106791766891812583019664893311E-9L,
+ -8.016795121318423066292906123815687003356E-7L,
+ -3.372350544043594415609295225664186750995E-5L,
+ -7.566238665947967882207277686375417983917E-4L,
+ -9.248861580055565402130441618521591282617E-3L,
+ -6.033106131055851432267702948850231270338E-2L,
+ -1.966908754799996793730369265431584303447E-1L,
+ -2.791062741179964150755788226623462207560E-1L,
+ -1.255478605849190549914610121863534191666E-1L,
+ -4.320429862021265463213168186061696944062E-3L,
+};
+#define NQ4_5D 9
+static const long double Q4_5D[NQ4_5D + 1] = {
+ 3.978497042580921479003851216297330701056E-10L,
+ 9.203304163828145809278568906420772246666E-8L,
+ 8.059685467088175644915010485174545743798E-6L,
+ 3.490187375993956409171098277561669167446E-4L,
+ 8.189109654456872150100501732073810028829E-3L,
+ 1.072572867311023640958725265762483033769E-1L,
+ 7.790606862409960053675717185714576937994E-1L,
+ 3.016049768232011196434185423512777656328E0L,
+ 5.722963851442769787733717162314477949360E0L,
+ 4.510527838428473279647251350931380867663E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 2.1e-35
+ 0.25 <= 1/x <= 0.3125 */
+#define NQ3r2_4N 9
+static const long double Q3r2_4N[NQ3r2_4N + 1] = {
+ -1.087480809271383885936921889040388133627E-8L,
+ -1.690067828697463740906962973479310170932E-6L,
+ -9.608064416995105532790745641974762550982E-5L,
+ -2.594198839156517191858208513873961837410E-3L,
+ -3.610954144421543968160459863048062977822E-2L,
+ -2.629866798251843212210482269563961685666E-1L,
+ -9.709186825881775885917984975685752956660E-1L,
+ -1.667521829918185121727268867619982417317E0L,
+ -1.109255082925540057138766105229900943501E0L,
+ -1.812932453006641348145049323713469043328E-1L,
+};
+#define NQ3r2_4D 9
+static const long double Q3r2_4D[NQ3r2_4D + 1] = {
+ 1.060552717496912381388763753841473407026E-7L,
+ 1.676928002024920520786883649102388708024E-5L,
+ 9.803481712245420839301400601140812255737E-4L,
+ 2.765559874262309494758505158089249012930E-2L,
+ 4.117921827792571791298862613287549140706E-1L,
+ 3.323769515244751267093378361930279161413E0L,
+ 1.436602494405814164724810151689705353670E1L,
+ 3.163087869617098638064881410646782408297E1L,
+ 3.198181264977021649489103980298349589419E1L,
+ 1.203649258862068431199471076202897823272E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.6e-36
+ 0.3125 <= 1/x <= 0.375 */
+#define NQ2r7_3r2N 9
+static const long double Q2r7_3r2N[NQ2r7_3r2N + 1] = {
+ -1.723405393982209853244278760171643219530E-7L,
+ -2.090508758514655456365709712333460087442E-5L,
+ -9.140104013370974823232873472192719263019E-4L,
+ -1.871349499990714843332742160292474780128E-2L,
+ -1.948930738119938669637865956162512983416E-1L,
+ -1.048764684978978127908439526343174139788E0L,
+ -2.827714929925679500237476105843643064698E0L,
+ -3.508761569156476114276988181329773987314E0L,
+ -1.669332202790211090973255098624488308989E0L,
+ -1.930796319299022954013840684651016077770E-1L,
+};
+#define NQ2r7_3r2D 9
+static const long double Q2r7_3r2D[NQ2r7_3r2D + 1] = {
+ 1.680730662300831976234547482334347983474E-6L,
+ 2.084241442440551016475972218719621841120E-4L,
+ 9.445316642108367479043541702688736295579E-3L,
+ 2.044637889456631896650179477133252184672E-1L,
+ 2.316091982244297350829522534435350078205E0L,
+ 1.412031891783015085196708811890448488865E1L,
+ 4.583830154673223384837091077279595496149E1L,
+ 7.549520609270909439885998474045974122261E1L,
+ 5.697605832808113367197494052388203310638E1L,
+ 1.601496240876192444526383314589371686234E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 9.5e-36
+ 0.375 <= 1/x <= 0.4375 */
+#define NQ2r3_2r7N 9
+static const long double Q2r3_2r7N[NQ2r3_2r7N + 1] = {
+ -8.603042076329122085722385914954878953775E-7L,
+ -7.701746260451647874214968882605186675720E-5L,
+ -2.407932004380727587382493696877569654271E-3L,
+ -3.403434217607634279028110636919987224188E-2L,
+ -2.348707332185238159192422084985713102877E-1L,
+ -7.957498841538254916147095255700637463207E-1L,
+ -1.258469078442635106431098063707934348577E0L,
+ -8.162415474676345812459353639449971369890E-1L,
+ -1.581783890269379690141513949609572806898E-1L,
+ -1.890595651683552228232308756569450822905E-3L,
+};
+#define NQ2r3_2r7D 8
+static const long double Q2r3_2r7D[NQ2r3_2r7D + 1] = {
+ 8.390017524798316921170710533381568175665E-6L,
+ 7.738148683730826286477254659973968763659E-4L,
+ 2.541480810958665794368759558791634341779E-2L,
+ 3.878879789711276799058486068562386244873E-1L,
+ 3.003783779325811292142957336802456109333E0L,
+ 1.206480374773322029883039064575464497400E1L,
+ 2.458414064785315978408974662900438351782E1L,
+ 2.367237826273668567199042088835448715228E1L,
+ 9.231451197519171090875569102116321676763E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.4e-36
+ 0.4375 <= 1/x <= 0.5 */
+#define NQ2_2r3N 9
+static const long double Q2_2r3N[NQ2_2r3N + 1] = {
+ -5.552507516089087822166822364590806076174E-6L,
+ -4.135067659799500521040944087433752970297E-4L,
+ -1.059928728869218962607068840646564457980E-2L,
+ -1.212070036005832342565792241385459023801E-1L,
+ -6.688350110633603958684302153362735625156E-1L,
+ -1.793587878197360221340277951304429821582E0L,
+ -2.225407682237197485644647380483725045326E0L,
+ -1.123402135458940189438898496348239744403E0L,
+ -1.679187241566347077204805190763597299805E-1L,
+ -1.458550613639093752909985189067233504148E-3L,
+};
+#define NQ2_2r3D 8
+static const long double Q2_2r3D[NQ2_2r3D + 1] = {
+ 5.415024336507980465169023996403597916115E-5L,
+ 4.179246497380453022046357404266022870788E-3L,
+ 1.136306384261959483095442402929502368598E-1L,
+ 1.422640343719842213484515445393284072830E0L,
+ 8.968786703393158374728850922289204805764E0L,
+ 2.914542473339246127533384118781216495934E1L,
+ 4.781605421020380669870197378210457054685E1L,
+ 3.693865837171883152382820584714795072937E1L,
+ 1.153220502744204904763115556224395893076E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Bessel function of the first kind, order one. */
+
+long double
+__ieee754_j1l (long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! isfinite (x))
+ {
+ if (x != x)
+ return x + x;
+ else
+ return 0;
+ }
+ if (x == 0)
+ return x;
+ xx = fabsl (x);
+ if (xx <= 0x1p-58L)
+ {
+ long double ret = x * 0.5L;
+ math_check_force_underflow (ret);
+ if (ret == 0)
+ __set_errno (ERANGE);
+ return ret;
+ }
+ if (xx <= 2)
+ {
+ /* 0 <= x <= 2 */
+ z = xx * xx;
+ p = xx * z * neval (z, J0_2N, NJ0_2N) / deval (z, J0_2D, NJ0_2D);
+ p += 0.5L * xx;
+ if (x < 0)
+ p = -p;
+ return p;
+ }
+
+ /* X = x - 3 pi/4
+ cos(X) = cos(x) cos(3 pi/4) + sin(x) sin(3 pi/4)
+ = 1/sqrt(2) * (-cos(x) + sin(x))
+ sin(X) = sin(x) cos(3 pi/4) - cos(x) sin(3 pi/4)
+ = -1/sqrt(2) * (sin(x) + cos(x))
+ cf. Fdlibm. */
+ __sincosl (xx, &s, &c);
+ ss = -s - c;
+ cc = s - c;
+ if (xx <= LDBL_MAX / 2)
+ {
+ z = __cosl (xx + xx);
+ if ((s * c) > 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+
+ if (xx > 0x1p256L)
+ {
+ z = ONEOSQPI * cc / __ieee754_sqrtl (xx);
+ if (x < 0)
+ z = -z;
+ return z;
+ }
+
+ xinv = 1 / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1 + z * p;
+ q = z * q;
+ q = q * xinv + 0.375L * xinv;
+ z = ONEOSQPI * (p * cc - q * ss) / __ieee754_sqrtl (xx);
+ if (x < 0)
+ z = -z;
+ return z;
+}
+strong_alias (__ieee754_j1l, __j1l_finite)
+
+
+/* Y1(x) = 2/pi * (log(x) * J1(x) - 1/x) + x R(x^2)
+ Peak relative error 6.2e-38
+ 0 <= x <= 2 */
+#define NY0_2N 7
+static long double Y0_2N[NY0_2N + 1] = {
+ -6.804415404830253804408698161694720833249E19L,
+ 1.805450517967019908027153056150465849237E19L,
+ -8.065747497063694098810419456383006737312E17L,
+ 1.401336667383028259295830955439028236299E16L,
+ -1.171654432898137585000399489686629680230E14L,
+ 5.061267920943853732895341125243428129150E11L,
+ -1.096677850566094204586208610960870217970E9L,
+ 9.541172044989995856117187515882879304461E5L,
+};
+#define NY0_2D 7
+static long double Y0_2D[NY0_2D + 1] = {
+ 3.470629591820267059538637461549677594549E20L,
+ 4.120796439009916326855848107545425217219E18L,
+ 2.477653371652018249749350657387030814542E16L,
+ 9.954678543353888958177169349272167762797E13L,
+ 2.957927997613630118216218290262851197754E11L,
+ 6.748421382188864486018861197614025972118E8L,
+ 1.173453425218010888004562071020305709319E6L,
+ 1.450335662961034949894009554536003377187E3L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+
+/* Bessel function of the second kind, order one. */
+
+long double
+__ieee754_y1l (long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! isfinite (x))
+ return 1 / (x + x * x);
+ if (x <= 0)
+ {
+ if (x < 0)
+ return (zero / (zero * x));
+ return -1 / zero; /* -inf and divide by zero exception. */
+ }
+ xx = fabsl (x);
+ if (xx <= 0x1p-114)
+ {
+ z = -TWOOPI / x;
+ if (isinf (z))
+ __set_errno (ERANGE);
+ return z;
+ }
+ if (xx <= 2)
+ {
+ /* 0 <= x <= 2 */
+ SET_RESTORE_ROUNDL (FE_TONEAREST);
+ z = xx * xx;
+ p = xx * neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D);
+ p = -TWOOPI / xx + p;
+ p = TWOOPI * __ieee754_logl (x) * __ieee754_j1l (x) + p;
+ return p;
+ }
+
+ /* X = x - 3 pi/4
+ cos(X) = cos(x) cos(3 pi/4) + sin(x) sin(3 pi/4)
+ = 1/sqrt(2) * (-cos(x) + sin(x))
+ sin(X) = sin(x) cos(3 pi/4) - cos(x) sin(3 pi/4)
+ = -1/sqrt(2) * (sin(x) + cos(x))
+ cf. Fdlibm. */
+ __sincosl (xx, &s, &c);
+ ss = -s - c;
+ cc = s - c;
+ if (xx <= LDBL_MAX / 2)
+ {
+ z = __cosl (xx + xx);
+ if ((s * c) > 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+
+ if (xx > 0x1p256L)
+ return ONEOSQPI * ss / __ieee754_sqrtl (xx);
+
+ xinv = 1 / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1 + z * p;
+ q = z * q;
+ q = q * xinv + 0.375L * xinv;
+ z = ONEOSQPI * (p * ss + q * cc) / __ieee754_sqrtl (xx);
+ return z;
+}
+strong_alias (__ieee754_y1l, __y1l_finite)
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c b/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c
index 8ac8283bd8..f881b8c0a4 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c
@@ -1,5 +1,992 @@
-/* Looks like we can use ieee854 e_lgammal_r.c as is for IBM extended format. */
-#define _Float128 long double
-#define L(x) x ## L
-#include <sysdeps/ieee754/ldbl-128/e_lgammal_r.c>
+/* Natural logarithm of gamma function. IBM Extended Precision version.
+ Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file was copied from sysdeps/ieee754/ldbl-128/e_lgammal_r.c. */
+
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+
+static const long double PIL = 3.1415926535897932384626433832795028841972E0L;
+static const long double MAXLGM = 0x5.d53649e2d469dbc1f01e99fd66p+1012L;
+static const long double one = 1;
+static const long double huge = LDBL_MAX;
+
+/* log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x P(1/x^2)
+ 1/x <= 0.0741 (x >= 13.495...)
+ Peak relative error 1.5e-36 */
+static const long double ls2pi = 9.1893853320467274178032973640561763986140E-1L;
+#define NRASY 12
+static const long double RASY[NRASY + 1] =
+{
+ 8.333333333333333333333333333310437112111E-2L,
+ -2.777777777777777777777774789556228296902E-3L,
+ 7.936507936507936507795933938448586499183E-4L,
+ -5.952380952380952041799269756378148574045E-4L,
+ 8.417508417507928904209891117498524452523E-4L,
+ -1.917526917481263997778542329739806086290E-3L,
+ 6.410256381217852504446848671499409919280E-3L,
+ -2.955064066900961649768101034477363301626E-2L,
+ 1.796402955865634243663453415388336954675E-1L,
+ -1.391522089007758553455753477688592767741E0L,
+ 1.326130089598399157988112385013829305510E1L,
+ -1.420412699593782497803472576479997819149E2L,
+ 1.218058922427762808938869872528846787020E3L
+};
+
+
+/* log gamma(x+13) = log gamma(13) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 12.5 <= x+13 <= 13.5
+ Peak relative error 1.1e-36 */
+static const long double lgam13a = 1.9987213134765625E1L;
+static const long double lgam13b = 1.3608962611495173623870550785125024484248E-6L;
+#define NRN13 7
+static const long double RN13[NRN13 + 1] =
+{
+ 8.591478354823578150238226576156275285700E11L,
+ 2.347931159756482741018258864137297157668E11L,
+ 2.555408396679352028680662433943000804616E10L,
+ 1.408581709264464345480765758902967123937E9L,
+ 4.126759849752613822953004114044451046321E7L,
+ 6.133298899622688505854211579222889943778E5L,
+ 3.929248056293651597987893340755876578072E3L,
+ 6.850783280018706668924952057996075215223E0L
+};
+#define NRD13 6
+static const long double RD13[NRD13 + 1] =
+{
+ 3.401225382297342302296607039352935541669E11L,
+ 8.756765276918037910363513243563234551784E10L,
+ 8.873913342866613213078554180987647243903E9L,
+ 4.483797255342763263361893016049310017973E8L,
+ 1.178186288833066430952276702931512870676E7L,
+ 1.519928623743264797939103740132278337476E5L,
+ 7.989298844938119228411117593338850892311E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+12) = log gamma(12) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 11.5 <= x+12 <= 12.5
+ Peak relative error 4.1e-36 */
+static const long double lgam12a = 1.75023040771484375E1L;
+static const long double lgam12b = 3.7687254483392876529072161996717039575982E-6L;
+#define NRN12 7
+static const long double RN12[NRN12 + 1] =
+{
+ 4.709859662695606986110997348630997559137E11L,
+ 1.398713878079497115037857470168777995230E11L,
+ 1.654654931821564315970930093932954900867E10L,
+ 9.916279414876676861193649489207282144036E8L,
+ 3.159604070526036074112008954113411389879E7L,
+ 5.109099197547205212294747623977502492861E5L,
+ 3.563054878276102790183396740969279826988E3L,
+ 6.769610657004672719224614163196946862747E0L
+};
+#define NRD12 6
+static const long double RD12[NRD12 + 1] =
+{
+ 1.928167007860968063912467318985802726613E11L,
+ 5.383198282277806237247492369072266389233E10L,
+ 5.915693215338294477444809323037871058363E9L,
+ 3.241438287570196713148310560147925781342E8L,
+ 9.236680081763754597872713592701048455890E6L,
+ 1.292246897881650919242713651166596478850E5L,
+ 7.366532445427159272584194816076600211171E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+11) = log gamma(11) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 10.5 <= x+11 <= 11.5
+ Peak relative error 1.8e-35 */
+static const long double lgam11a = 1.5104400634765625E1L;
+static const long double lgam11b = 1.1938309890295225709329251070371882250744E-5L;
+#define NRN11 7
+static const long double RN11[NRN11 + 1] =
+{
+ 2.446960438029415837384622675816736622795E11L,
+ 7.955444974446413315803799763901729640350E10L,
+ 1.030555327949159293591618473447420338444E10L,
+ 6.765022131195302709153994345470493334946E8L,
+ 2.361892792609204855279723576041468347494E7L,
+ 4.186623629779479136428005806072176490125E5L,
+ 3.202506022088912768601325534149383594049E3L,
+ 6.681356101133728289358838690666225691363E0L
+};
+#define NRD11 6
+static const long double RD11[NRD11 + 1] =
+{
+ 1.040483786179428590683912396379079477432E11L,
+ 3.172251138489229497223696648369823779729E10L,
+ 3.806961885984850433709295832245848084614E9L,
+ 2.278070344022934913730015420611609620171E8L,
+ 7.089478198662651683977290023829391596481E6L,
+ 1.083246385105903533237139380509590158658E5L,
+ 6.744420991491385145885727942219463243597E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+10) = log gamma(10) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 9.5 <= x+10 <= 10.5
+ Peak relative error 5.4e-37 */
+static const long double lgam10a = 1.280181884765625E1L;
+static const long double lgam10b = 8.6324252196112077178745667061642811492557E-6L;
+#define NRN10 7
+static const long double RN10[NRN10 + 1] =
+{
+ -1.239059737177249934158597996648808363783E14L,
+ -4.725899566371458992365624673357356908719E13L,
+ -7.283906268647083312042059082837754850808E12L,
+ -5.802855515464011422171165179767478794637E11L,
+ -2.532349691157548788382820303182745897298E10L,
+ -5.884260178023777312587193693477072061820E8L,
+ -6.437774864512125749845840472131829114906E6L,
+ -2.350975266781548931856017239843273049384E4L
+};
+#define NRD10 7
+static const long double RD10[NRD10 + 1] =
+{
+ -5.502645997581822567468347817182347679552E13L,
+ -1.970266640239849804162284805400136473801E13L,
+ -2.819677689615038489384974042561531409392E12L,
+ -2.056105863694742752589691183194061265094E11L,
+ -8.053670086493258693186307810815819662078E9L,
+ -1.632090155573373286153427982504851867131E8L,
+ -1.483575879240631280658077826889223634921E6L,
+ -4.002806669713232271615885826373550502510E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+9) = log gamma(9) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 8.5 <= x+9 <= 9.5
+ Peak relative error 3.6e-36 */
+static const long double lgam9a = 1.06045989990234375E1L;
+static const long double lgam9b = 3.9037218127284172274007216547549861681400E-6L;
+#define NRN9 7
+static const long double RN9[NRN9 + 1] =
+{
+ -4.936332264202687973364500998984608306189E13L,
+ -2.101372682623700967335206138517766274855E13L,
+ -3.615893404644823888655732817505129444195E12L,
+ -3.217104993800878891194322691860075472926E11L,
+ -1.568465330337375725685439173603032921399E10L,
+ -4.073317518162025744377629219101510217761E8L,
+ -4.983232096406156139324846656819246974500E6L,
+ -2.036280038903695980912289722995505277253E4L
+};
+#define NRD9 7
+static const long double RD9[NRD9 + 1] =
+{
+ -2.306006080437656357167128541231915480393E13L,
+ -9.183606842453274924895648863832233799950E12L,
+ -1.461857965935942962087907301194381010380E12L,
+ -1.185728254682789754150068652663124298303E11L,
+ -5.166285094703468567389566085480783070037E9L,
+ -1.164573656694603024184768200787835094317E8L,
+ -1.177343939483908678474886454113163527909E6L,
+ -3.529391059783109732159524500029157638736E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+8) = log gamma(8) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 7.5 <= x+8 <= 8.5
+ Peak relative error 2.4e-37 */
+static const long double lgam8a = 8.525146484375E0L;
+static const long double lgam8b = 1.4876690414300165531036347125050759667737E-5L;
+#define NRN8 8
+static const long double RN8[NRN8 + 1] =
+{
+ 6.600775438203423546565361176829139703289E11L,
+ 3.406361267593790705240802723914281025800E11L,
+ 7.222460928505293914746983300555538432830E10L,
+ 8.102984106025088123058747466840656458342E9L,
+ 5.157620015986282905232150979772409345927E8L,
+ 1.851445288272645829028129389609068641517E7L,
+ 3.489261702223124354745894067468953756656E5L,
+ 2.892095396706665774434217489775617756014E3L,
+ 6.596977510622195827183948478627058738034E0L
+};
+#define NRD8 7
+static const long double RD8[NRD8 + 1] =
+{
+ 3.274776546520735414638114828622673016920E11L,
+ 1.581811207929065544043963828487733970107E11L,
+ 3.108725655667825188135393076860104546416E10L,
+ 3.193055010502912617128480163681842165730E9L,
+ 1.830871482669835106357529710116211541839E8L,
+ 5.790862854275238129848491555068073485086E6L,
+ 9.305213264307921522842678835618803553589E4L,
+ 6.216974105861848386918949336819572333622E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+7) = log gamma(7) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 6.5 <= x+7 <= 7.5
+ Peak relative error 3.2e-36 */
+static const long double lgam7a = 6.5792388916015625E0L;
+static const long double lgam7b = 1.2320408538495060178292903945321122583007E-5L;
+#define NRN7 8
+static const long double RN7[NRN7 + 1] =
+{
+ 2.065019306969459407636744543358209942213E11L,
+ 1.226919919023736909889724951708796532847E11L,
+ 2.996157990374348596472241776917953749106E10L,
+ 3.873001919306801037344727168434909521030E9L,
+ 2.841575255593761593270885753992732145094E8L,
+ 1.176342515359431913664715324652399565551E7L,
+ 2.558097039684188723597519300356028511547E5L,
+ 2.448525238332609439023786244782810774702E3L,
+ 6.460280377802030953041566617300902020435E0L
+};
+#define NRD7 7
+static const long double RD7[NRD7 + 1] =
+{
+ 1.102646614598516998880874785339049304483E11L,
+ 6.099297512712715445879759589407189290040E10L,
+ 1.372898136289611312713283201112060238351E10L,
+ 1.615306270420293159907951633566635172343E9L,
+ 1.061114435798489135996614242842561967459E8L,
+ 3.845638971184305248268608902030718674691E6L,
+ 7.081730675423444975703917836972720495507E4L,
+ 5.423122582741398226693137276201344096370E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+6) = log gamma(6) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 5.5 <= x+6 <= 6.5
+ Peak relative error 6.2e-37 */
+static const long double lgam6a = 4.7874908447265625E0L;
+static const long double lgam6b = 8.9805548349424770093452324304839959231517E-7L;
+#define NRN6 8
+static const long double RN6[NRN6 + 1] =
+{
+ -3.538412754670746879119162116819571823643E13L,
+ -2.613432593406849155765698121483394257148E13L,
+ -8.020670732770461579558867891923784753062E12L,
+ -1.322227822931250045347591780332435433420E12L,
+ -1.262809382777272476572558806855377129513E11L,
+ -7.015006277027660872284922325741197022467E9L,
+ -2.149320689089020841076532186783055727299E8L,
+ -3.167210585700002703820077565539658995316E6L,
+ -1.576834867378554185210279285358586385266E4L
+};
+#define NRD6 8
+static const long double RD6[NRD6 + 1] =
+{
+ -2.073955870771283609792355579558899389085E13L,
+ -1.421592856111673959642750863283919318175E13L,
+ -4.012134994918353924219048850264207074949E12L,
+ -6.013361045800992316498238470888523722431E11L,
+ -5.145382510136622274784240527039643430628E10L,
+ -2.510575820013409711678540476918249524123E9L,
+ -6.564058379709759600836745035871373240904E7L,
+ -7.861511116647120540275354855221373571536E5L,
+ -2.821943442729620524365661338459579270561E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+5) = log gamma(5) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 4.5 <= x+5 <= 5.5
+ Peak relative error 3.4e-37 */
+static const long double lgam5a = 3.17803955078125E0L;
+static const long double lgam5b = 1.4279566695619646941601297055408873990961E-5L;
+#define NRN5 9
+static const long double RN5[NRN5 + 1] =
+{
+ 2.010952885441805899580403215533972172098E11L,
+ 1.916132681242540921354921906708215338584E11L,
+ 7.679102403710581712903937970163206882492E10L,
+ 1.680514903671382470108010973615268125169E10L,
+ 2.181011222911537259440775283277711588410E9L,
+ 1.705361119398837808244780667539728356096E8L,
+ 7.792391565652481864976147945997033946360E6L,
+ 1.910741381027985291688667214472560023819E5L,
+ 2.088138241893612679762260077783794329559E3L,
+ 6.330318119566998299106803922739066556550E0L
+};
+#define NRD5 8
+static const long double RD5[NRD5 + 1] =
+{
+ 1.335189758138651840605141370223112376176E11L,
+ 1.174130445739492885895466097516530211283E11L,
+ 4.308006619274572338118732154886328519910E10L,
+ 8.547402888692578655814445003283720677468E9L,
+ 9.934628078575618309542580800421370730906E8L,
+ 6.847107420092173812998096295422311820672E7L,
+ 2.698552646016599923609773122139463150403E6L,
+ 5.526516251532464176412113632726150253215E4L,
+ 4.772343321713697385780533022595450486932E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+4) = log gamma(4) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 3.5 <= x+4 <= 4.5
+ Peak relative error 6.7e-37 */
+static const long double lgam4a = 1.791748046875E0L;
+static const long double lgam4b = 1.1422353055000812477358380702272722990692E-5L;
+#define NRN4 9
+static const long double RN4[NRN4 + 1] =
+{
+ -1.026583408246155508572442242188887829208E13L,
+ -1.306476685384622809290193031208776258809E13L,
+ -7.051088602207062164232806511992978915508E12L,
+ -2.100849457735620004967624442027793656108E12L,
+ -3.767473790774546963588549871673843260569E11L,
+ -4.156387497364909963498394522336575984206E10L,
+ -2.764021460668011732047778992419118757746E9L,
+ -1.036617204107109779944986471142938641399E8L,
+ -1.895730886640349026257780896972598305443E6L,
+ -1.180509051468390914200720003907727988201E4L
+};
+#define NRD4 9
+static const long double RD4[NRD4 + 1] =
+{
+ -8.172669122056002077809119378047536240889E12L,
+ -9.477592426087986751343695251801814226960E12L,
+ -4.629448850139318158743900253637212801682E12L,
+ -1.237965465892012573255370078308035272942E12L,
+ -1.971624313506929845158062177061297598956E11L,
+ -1.905434843346570533229942397763361493610E10L,
+ -1.089409357680461419743730978512856675984E9L,
+ -3.416703082301143192939774401370222822430E7L,
+ -4.981791914177103793218433195857635265295E5L,
+ -2.192507743896742751483055798411231453733E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+3) = log gamma(3) + x P(x)/Q(x)
+ -0.25 <= x <= 0.5
+ 2.75 <= x+3 <= 3.5
+ Peak relative error 6.0e-37 */
+static const long double lgam3a = 6.93145751953125E-1L;
+static const long double lgam3b = 1.4286068203094172321214581765680755001344E-6L;
+
+#define NRN3 9
+static const long double RN3[NRN3 + 1] =
+{
+ -4.813901815114776281494823863935820876670E11L,
+ -8.425592975288250400493910291066881992620E11L,
+ -6.228685507402467503655405482985516909157E11L,
+ -2.531972054436786351403749276956707260499E11L,
+ -6.170200796658926701311867484296426831687E10L,
+ -9.211477458528156048231908798456365081135E9L,
+ -8.251806236175037114064561038908691305583E8L,
+ -4.147886355917831049939930101151160447495E7L,
+ -1.010851868928346082547075956946476932162E6L,
+ -8.333374463411801009783402800801201603736E3L
+};
+#define NRD3 9
+static const long double RD3[NRD3 + 1] =
+{
+ -5.216713843111675050627304523368029262450E11L,
+ -8.014292925418308759369583419234079164391E11L,
+ -5.180106858220030014546267824392678611990E11L,
+ -1.830406975497439003897734969120997840011E11L,
+ -3.845274631904879621945745960119924118925E10L,
+ -4.891033385370523863288908070309417710903E9L,
+ -3.670172254411328640353855768698287474282E8L,
+ -1.505316381525727713026364396635522516989E7L,
+ -2.856327162923716881454613540575964890347E5L,
+ -1.622140448015769906847567212766206894547E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+2.5) = log gamma(2.5) + x P(x)/Q(x)
+ -0.125 <= x <= 0.25
+ 2.375 <= x+2.5 <= 2.75 */
+static const long double lgam2r5a = 2.8466796875E-1L;
+static const long double lgam2r5b = 1.4901722919159632494669682701924320137696E-5L;
+#define NRN2r5 8
+static const long double RN2r5[NRN2r5 + 1] =
+{
+ -4.676454313888335499356699817678862233205E9L,
+ -9.361888347911187924389905984624216340639E9L,
+ -7.695353600835685037920815799526540237703E9L,
+ -3.364370100981509060441853085968900734521E9L,
+ -8.449902011848163568670361316804900559863E8L,
+ -1.225249050950801905108001246436783022179E8L,
+ -9.732972931077110161639900388121650470926E6L,
+ -3.695711763932153505623248207576425983573E5L,
+ -4.717341584067827676530426007495274711306E3L
+};
+#define NRD2r5 8
+static const long double RD2r5[NRD2r5 + 1] =
+{
+ -6.650657966618993679456019224416926875619E9L,
+ -1.099511409330635807899718829033488771623E10L,
+ -7.482546968307837168164311101447116903148E9L,
+ -2.702967190056506495988922973755870557217E9L,
+ -5.570008176482922704972943389590409280950E8L,
+ -6.536934032192792470926310043166993233231E7L,
+ -4.101991193844953082400035444146067511725E6L,
+ -1.174082735875715802334430481065526664020E5L,
+ -9.932840389994157592102947657277692978511E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+2) = x P(x)/Q(x)
+ -0.125 <= x <= +0.375
+ 1.875 <= x+2 <= 2.375
+ Peak relative error 4.6e-36 */
+#define NRN2 9
+static const long double RN2[NRN2 + 1] =
+{
+ -3.716661929737318153526921358113793421524E9L,
+ -1.138816715030710406922819131397532331321E10L,
+ -1.421017419363526524544402598734013569950E10L,
+ -9.510432842542519665483662502132010331451E9L,
+ -3.747528562099410197957514973274474767329E9L,
+ -8.923565763363912474488712255317033616626E8L,
+ -1.261396653700237624185350402781338231697E8L,
+ -9.918402520255661797735331317081425749014E6L,
+ -3.753996255897143855113273724233104768831E5L,
+ -4.778761333044147141559311805999540765612E3L
+};
+#define NRD2 9
+static const long double RD2[NRD2 + 1] =
+{
+ -8.790916836764308497770359421351673950111E9L,
+ -2.023108608053212516399197678553737477486E10L,
+ -1.958067901852022239294231785363504458367E10L,
+ -1.035515043621003101254252481625188704529E10L,
+ -3.253884432621336737640841276619272224476E9L,
+ -6.186383531162456814954947669274235815544E8L,
+ -6.932557847749518463038934953605969951466E7L,
+ -4.240731768287359608773351626528479703758E6L,
+ -1.197343995089189188078944689846348116630E5L,
+ -1.004622911670588064824904487064114090920E3L
+/* 1.0E0 */
+};
+
+
+/* log gamma(x+1.75) = log gamma(1.75) + x P(x)/Q(x)
+ -0.125 <= x <= +0.125
+ 1.625 <= x+1.75 <= 1.875
+ Peak relative error 9.2e-37 */
+static const long double lgam1r75a = -8.441162109375E-2L;
+static const long double lgam1r75b = 1.0500073264444042213965868602268256157604E-5L;
+#define NRN1r75 8
+static const long double RN1r75[NRN1r75 + 1] =
+{
+ -5.221061693929833937710891646275798251513E7L,
+ -2.052466337474314812817883030472496436993E8L,
+ -2.952718275974940270675670705084125640069E8L,
+ -2.132294039648116684922965964126389017840E8L,
+ -8.554103077186505960591321962207519908489E7L,
+ -1.940250901348870867323943119132071960050E7L,
+ -2.379394147112756860769336400290402208435E6L,
+ -1.384060879999526222029386539622255797389E5L,
+ -2.698453601378319296159355612094598695530E3L
+};
+#define NRD1r75 8
+static const long double RD1r75[NRD1r75 + 1] =
+{
+ -2.109754689501705828789976311354395393605E8L,
+ -5.036651829232895725959911504899241062286E8L,
+ -4.954234699418689764943486770327295098084E8L,
+ -2.589558042412676610775157783898195339410E8L,
+ -7.731476117252958268044969614034776883031E7L,
+ -1.316721702252481296030801191240867486965E7L,
+ -1.201296501404876774861190604303728810836E6L,
+ -5.007966406976106636109459072523610273928E4L,
+ -6.155817990560743422008969155276229018209E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+x0) = y0 + x^2 P(x)/Q(x)
+ -0.0867 <= x <= +0.1634
+ 1.374932... <= x+x0 <= 1.625032...
+ Peak relative error 4.0e-36 */
+static const long double x0a = 1.4616241455078125L;
+static const long double x0b = 7.9994605498412626595423257213002588621246E-6L;
+static const long double y0a = -1.21490478515625E-1L;
+static const long double y0b = 4.1879797753919044854428223084178486438269E-6L;
+#define NRN1r5 8
+static const long double RN1r5[NRN1r5 + 1] =
+{
+ 6.827103657233705798067415468881313128066E5L,
+ 1.910041815932269464714909706705242148108E6L,
+ 2.194344176925978377083808566251427771951E6L,
+ 1.332921400100891472195055269688876427962E6L,
+ 4.589080973377307211815655093824787123508E5L,
+ 8.900334161263456942727083580232613796141E4L,
+ 9.053840838306019753209127312097612455236E3L,
+ 4.053367147553353374151852319743594873771E2L,
+ 5.040631576303952022968949605613514584950E0L
+};
+#define NRD1r5 8
+static const long double RD1r5[NRD1r5 + 1] =
+{
+ 1.411036368843183477558773688484699813355E6L,
+ 4.378121767236251950226362443134306184849E6L,
+ 5.682322855631723455425929877581697918168E6L,
+ 3.999065731556977782435009349967042222375E6L,
+ 1.653651390456781293163585493620758410333E6L,
+ 4.067774359067489605179546964969435858311E5L,
+ 5.741463295366557346748361781768833633256E4L,
+ 4.226404539738182992856094681115746692030E3L,
+ 1.316980975410327975566999780608618774469E2L,
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+1.25) = log gamma(1.25) + x P(x)/Q(x)
+ -.125 <= x <= +.125
+ 1.125 <= x+1.25 <= 1.375
+ Peak relative error = 4.9e-36 */
+static const long double lgam1r25a = -9.82818603515625E-2L;
+static const long double lgam1r25b = 1.0023929749338536146197303364159774377296E-5L;
+#define NRN1r25 9
+static const long double RN1r25[NRN1r25 + 1] =
+{
+ -9.054787275312026472896002240379580536760E4L,
+ -8.685076892989927640126560802094680794471E4L,
+ 2.797898965448019916967849727279076547109E5L,
+ 6.175520827134342734546868356396008898299E5L,
+ 5.179626599589134831538516906517372619641E5L,
+ 2.253076616239043944538380039205558242161E5L,
+ 5.312653119599957228630544772499197307195E4L,
+ 6.434329437514083776052669599834938898255E3L,
+ 3.385414416983114598582554037612347549220E2L,
+ 4.907821957946273805080625052510832015792E0L
+};
+#define NRD1r25 8
+static const long double RD1r25[NRD1r25 + 1] =
+{
+ 3.980939377333448005389084785896660309000E5L,
+ 1.429634893085231519692365775184490465542E6L,
+ 2.145438946455476062850151428438668234336E6L,
+ 1.743786661358280837020848127465970357893E6L,
+ 8.316364251289743923178092656080441655273E5L,
+ 2.355732939106812496699621491135458324294E5L,
+ 3.822267399625696880571810137601310855419E4L,
+ 3.228463206479133236028576845538387620856E3L,
+ 1.152133170470059555646301189220117965514E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x + 1) = x P(x)/Q(x)
+ 0.0 <= x <= +0.125
+ 1.0 <= x+1 <= 1.125
+ Peak relative error 1.1e-35 */
+#define NRN1 8
+static const long double RN1[NRN1 + 1] =
+{
+ -9.987560186094800756471055681088744738818E3L,
+ -2.506039379419574361949680225279376329742E4L,
+ -1.386770737662176516403363873617457652991E4L,
+ 1.439445846078103202928677244188837130744E4L,
+ 2.159612048879650471489449668295139990693E4L,
+ 1.047439813638144485276023138173676047079E4L,
+ 2.250316398054332592560412486630769139961E3L,
+ 1.958510425467720733041971651126443864041E2L,
+ 4.516830313569454663374271993200291219855E0L
+};
+#define NRD1 7
+static const long double RD1[NRD1 + 1] =
+{
+ 1.730299573175751778863269333703788214547E4L,
+ 6.807080914851328611903744668028014678148E4L,
+ 1.090071629101496938655806063184092302439E5L,
+ 9.124354356415154289343303999616003884080E4L,
+ 4.262071638655772404431164427024003253954E4L,
+ 1.096981664067373953673982635805821283581E4L,
+ 1.431229503796575892151252708527595787588E3L,
+ 7.734110684303689320830401788262295992921E1L
+ /* 1.0E0 */
+};
+
+
+/* log gamma(x + 1) = x P(x)/Q(x)
+ -0.125 <= x <= 0
+ 0.875 <= x+1 <= 1.0
+ Peak relative error 7.0e-37 */
+#define NRNr9 8
+static const long double RNr9[NRNr9 + 1] =
+{
+ 4.441379198241760069548832023257571176884E5L,
+ 1.273072988367176540909122090089580368732E6L,
+ 9.732422305818501557502584486510048387724E5L,
+ -5.040539994443998275271644292272870348684E5L,
+ -1.208719055525609446357448132109723786736E6L,
+ -7.434275365370936547146540554419058907156E5L,
+ -2.075642969983377738209203358199008185741E5L,
+ -2.565534860781128618589288075109372218042E4L,
+ -1.032901669542994124131223797515913955938E3L,
+};
+#define NRDr9 8
+static const long double RDr9[NRDr9 + 1] =
+{
+ -7.694488331323118759486182246005193998007E5L,
+ -3.301918855321234414232308938454112213751E6L,
+ -5.856830900232338906742924836032279404702E6L,
+ -5.540672519616151584486240871424021377540E6L,
+ -3.006530901041386626148342989181721176919E6L,
+ -9.350378280513062139466966374330795935163E5L,
+ -1.566179100031063346901755685375732739511E5L,
+ -1.205016539620260779274902967231510804992E4L,
+ -2.724583156305709733221564484006088794284E2L
+/* 1.0E0 */
+};
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+long double
+__ieee754_lgammal_r (long double x, int *signgamp)
+{
+ long double p, q, w, z, nx;
+ int i, nn;
+
+ *signgamp = 1;
+
+ if (! isfinite (x))
+ return x * x;
+
+ if (x == 0)
+ {
+ if (signbit (x))
+ *signgamp = -1;
+ }
+
+ if (x < 0)
+ {
+ if (x < -2 && x > -48)
+ return __lgamma_negl (x, signgamp);
+ q = -x;
+ p = __floorl (q);
+ if (p == q)
+ return (one / __fabsl (p - p));
+ long double halfp = p * 0.5L;
+ if (halfp == __floorl (halfp))
+ *signgamp = -1;
+ else
+ *signgamp = 1;
+ if (q < 0x1p-120L)
+ return -__logl (q);
+ z = q - p;
+ if (z > 0.5L)
+ {
+ p += 1;
+ z = p - q;
+ }
+ z = q * __sinl (PIL * z);
+ w = __ieee754_lgammal_r (q, &i);
+ z = __logl (PIL / z) - w;
+ return (z);
+ }
+
+ if (x < 13.5L)
+ {
+ p = 0;
+ nx = __floorl (x + 0.5L);
+ nn = nx;
+ switch (nn)
+ {
+ case 0:
+ /* log gamma (x + 1) = log(x) + log gamma(x) */
+ if (x < 0x1p-120L)
+ return -__logl (x);
+ else if (x <= 0.125)
+ {
+ p = x * neval (x, RN1, NRN1) / deval (x, RD1, NRD1);
+ }
+ else if (x <= 0.375)
+ {
+ z = x - 0.25L;
+ p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25);
+ p += lgam1r25b;
+ p += lgam1r25a;
+ }
+ else if (x <= 0.625)
+ {
+ z = x + (1 - x0a);
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x <= 0.875)
+ {
+ z = x - 0.75L;
+ p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else
+ {
+ z = x - 1;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ p = p - __logl (x);
+ break;
+
+ case 1:
+ if (x < 0.875L)
+ {
+ if (x <= 0.625)
+ {
+ z = x + (1 - x0a);
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x <= 0.875)
+ {
+ z = x - 0.75L;
+ p = z * neval (z, RN1r75, NRN1r75)
+ / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else
+ {
+ z = x - 1;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ p = p - __logl (x);
+ }
+ else if (x < 1)
+ {
+ z = x - 1;
+ p = z * neval (z, RNr9, NRNr9) / deval (z, RDr9, NRDr9);
+ }
+ else if (x == 1)
+ p = 0;
+ else if (x <= 1.125L)
+ {
+ z = x - 1;
+ p = z * neval (z, RN1, NRN1) / deval (z, RD1, NRD1);
+ }
+ else if (x <= 1.375)
+ {
+ z = x - 1.25L;
+ p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25);
+ p += lgam1r25b;
+ p += lgam1r25a;
+ }
+ else
+ {
+ /* 1.375 <= x+x0 <= 1.625 */
+ z = x - x0a;
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ break;
+
+ case 2:
+ if (x < 1.625L)
+ {
+ z = x - x0a;
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x < 1.875L)
+ {
+ z = x - 1.75L;
+ p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else if (x == 2)
+ p = 0;
+ else if (x < 2.375L)
+ {
+ z = x - 2;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ else
+ {
+ z = x - 2.5L;
+ p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5);
+ p += lgam2r5b;
+ p += lgam2r5a;
+ }
+ break;
+
+ case 3:
+ if (x < 2.75)
+ {
+ z = x - 2.5L;
+ p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5);
+ p += lgam2r5b;
+ p += lgam2r5a;
+ }
+ else
+ {
+ z = x - 3;
+ p = z * neval (z, RN3, NRN3) / deval (z, RD3, NRD3);
+ p += lgam3b;
+ p += lgam3a;
+ }
+ break;
+
+ case 4:
+ z = x - 4;
+ p = z * neval (z, RN4, NRN4) / deval (z, RD4, NRD4);
+ p += lgam4b;
+ p += lgam4a;
+ break;
+
+ case 5:
+ z = x - 5;
+ p = z * neval (z, RN5, NRN5) / deval (z, RD5, NRD5);
+ p += lgam5b;
+ p += lgam5a;
+ break;
+
+ case 6:
+ z = x - 6;
+ p = z * neval (z, RN6, NRN6) / deval (z, RD6, NRD6);
+ p += lgam6b;
+ p += lgam6a;
+ break;
+
+ case 7:
+ z = x - 7;
+ p = z * neval (z, RN7, NRN7) / deval (z, RD7, NRD7);
+ p += lgam7b;
+ p += lgam7a;
+ break;
+
+ case 8:
+ z = x - 8;
+ p = z * neval (z, RN8, NRN8) / deval (z, RD8, NRD8);
+ p += lgam8b;
+ p += lgam8a;
+ break;
+
+ case 9:
+ z = x - 9;
+ p = z * neval (z, RN9, NRN9) / deval (z, RD9, NRD9);
+ p += lgam9b;
+ p += lgam9a;
+ break;
+
+ case 10:
+ z = x - 10;
+ p = z * neval (z, RN10, NRN10) / deval (z, RD10, NRD10);
+ p += lgam10b;
+ p += lgam10a;
+ break;
+
+ case 11:
+ z = x - 11;
+ p = z * neval (z, RN11, NRN11) / deval (z, RD11, NRD11);
+ p += lgam11b;
+ p += lgam11a;
+ break;
+
+ case 12:
+ z = x - 12;
+ p = z * neval (z, RN12, NRN12) / deval (z, RD12, NRD12);
+ p += lgam12b;
+ p += lgam12a;
+ break;
+
+ case 13:
+ z = x - 13;
+ p = z * neval (z, RN13, NRN13) / deval (z, RD13, NRD13);
+ p += lgam13b;
+ p += lgam13a;
+ break;
+ }
+ return p;
+ }
+
+ if (x > MAXLGM)
+ return (*signgamp * huge * huge);
+
+ if (x > 0x1p120L)
+ return x * (__logl (x) - 1);
+ q = ls2pi - x;
+ q = (x - 0.5L) * __logl (x) + q;
+ if (x > 1.0e18L)
+ return (q);
+
+ p = 1 / (x * x);
+ q += neval (p, RASY, NRASY) / x;
+ return (q);
+}
+strong_alias (__ieee754_lgammal_r, __lgammal_r_finite)
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c b/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c
index 64bfc46414..317d238057 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c
@@ -1,10 +1,102 @@
-/* Looks like we can use ieee854 s_cbrtl.c as is for IBM extended format. */
+/* Implementation of cbrtl. IBM Extended Precision version.
+ Cephes Math Library Release 2.2: January, 1991
+ Copyright 1984, 1991 by Stephen L. Moshier
+ Adapted for glibc October, 2001.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file was copied from sysdeps/ieee754/ldbl-128/e_j0l.c. */
+
+
#include <math_ldbl_opt.h>
-#undef weak_alias
-#define weak_alias(n,a)
+#include <math.h>
+#include <math_private.h>
+
+static const long double CBRT2 = 1.259921049894873164767210607278228350570251L;
+static const long double CBRT4 = 1.587401051968199474751705639272308260391493L;
+static const long double CBRT2I = 0.7937005259840997373758528196361541301957467L;
+static const long double CBRT4I = 0.6299605249474365823836053036391141752851257L;
+
+
+long double
+__cbrtl (long double x)
+{
+ int e, rem, sign;
+ long double z;
+
+ if (!isfinite (x))
+ return x + x;
+
+ if (x == 0)
+ return (x);
+
+ if (x > 0)
+ sign = 1;
+ else
+ {
+ sign = -1;
+ x = -x;
+ }
+
+ z = x;
+ /* extract power of 2, leaving mantissa between 0.5 and 1 */
+ x = __frexpl (x, &e);
+
+ /* Approximate cube root of number between .5 and 1,
+ peak relative error = 1.2e-6 */
+ x = ((((1.3584464340920900529734e-1L * x
+ - 6.3986917220457538402318e-1L) * x
+ + 1.2875551670318751538055e0L) * x
+ - 1.4897083391357284957891e0L) * x
+ + 1.3304961236013647092521e0L) * x + 3.7568280825958912391243e-1L;
+
+ /* exponent divided by 3 */
+ if (e >= 0)
+ {
+ rem = e;
+ e /= 3;
+ rem -= 3 * e;
+ if (rem == 1)
+ x *= CBRT2;
+ else if (rem == 2)
+ x *= CBRT4;
+ }
+ else
+ { /* argument less than 1 */
+ e = -e;
+ rem = e;
+ e /= 3;
+ rem -= 3 * e;
+ if (rem == 1)
+ x *= CBRT2I;
+ else if (rem == 2)
+ x *= CBRT4I;
+ e = -e;
+ }
+
+ /* multiply by power of 2 */
+ x = __ldexpl (x, e);
+
+ /* Newton iteration */
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333L;
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333L;
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333L;
-#define _Float128 long double
-#define L(x) x ## L
+ if (sign < 0)
+ x = -x;
+ return (x);
+}
-#include <sysdeps/ieee754/ldbl-128/s_cbrtl.c>
long_double_symbol (libm, __cbrtl, cbrtl);
diff --git a/sysdeps/ieee754/ldbl-128ibm/t_expl.h b/sysdeps/ieee754/ldbl-128ibm/t_expl.h
new file mode 100644
index 0000000000..e2fe4dd2ef
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/t_expl.h
@@ -0,0 +1,970 @@
+/* Accurate table for expl().
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* __expl_table basically consists of four tables, T_EXPL_ARG{1,2} and
+ T_EXPL_RES{1,2}. All tables use positive and negative indexes, the 0 points
+ are marked by T_EXPL_* defines.
+ For ARG1 and RES1 tables lets B be 89 and S 256.0, for ARG2 and RES2 B is 65
+ and S 32768.0.
+ These table have the property that, for all integers -B <= i <= B
+ expl(__expl_table[T_EXPL_ARGN+2*i]+__expl_table[T_EXPL_ARGN+2*i+1]+r) ==
+ __expl_table[T_EXPL_RESN+i], __expl_table[T_EXPL_RESN+i] is some exact number
+ with the low 58 bits of the mantissa 0,
+ __expl_table[T_EXPL_ARGN+2*i] == i/S+s
+ where absl(s) <= 2^-54 and absl(r) <= 2^-212. */
+
+
+static const long double __expl_table [] = {
+ -3.47656250000000000584188889839535373E-01L, /* bffd640000000000002b1b04213cf000 */
+ 6.90417668990715641167244540876988960E-32L, /* 3f97667c3fdb588a6ae1af8748357a17 */
+ -3.43749999999999981853132895957607418E-01L, /* bffd5ffffffffffffac4ff5f4050b000 */
+ -7.16021898043268093462818380603370350E-33L, /* bf94296c8219427edc1431ac2498583e */
+ -3.39843750000000013418643523138766329E-01L, /* bffd5c000000000003de1f027a30e000 */
+ 8.16920774283317801641347327589583265E-32L, /* 3f97a82b65774bdca1b4440d749ed8d3 */
+ -3.35937500000000014998092453039303051E-01L, /* bffd5800000000000452a9f4d8857000 */
+ -6.55865578425428447938248396879359670E-32L, /* bf97548b7d240f3d034b395e6eecfac8 */
+ -3.32031250000000000981984049529998541E-01L, /* bffd540000000000004875277cda5000 */
+ 6.91213046334032232108944519541512737E-32L, /* 3f9766e5f925338a19045c94443b66e1 */
+ -3.28124999999999986646017645350399708E-01L, /* bffd4ffffffffffffc26a667bf44d000 */
+ -6.16281060996110316602421505683742661E-32L, /* bf973ffdcdcffb6fbffc86b2b8d42f5d */
+ -3.24218749999999991645717430645867963E-01L, /* bffd4bfffffffffffd97901063e48000 */
+ -7.90797211087760527593856542417304137E-32L, /* bf979a9afaaca1ada6a8ed1c80584d60 */
+ -3.20312499999999998918211610690789652E-01L, /* bffd47ffffffffffffb02d9856d71000 */
+ 8.64024799457616856987630373786503376E-32L, /* 3f97c0a098623f95579d5d9b2b67342d */
+ -3.16406249999999998153974811017181883E-01L, /* bffd43ffffffffffff77c991f1076000 */
+ -2.73176610180696076418536105483668404E-32L, /* bf961baeccb32f9b1fcbb8e60468e95a */
+ -3.12500000000000011420976192575972779E-01L, /* bffd400000000000034ab8240483d000 */
+ 7.16573502812389453744433792609989420E-32L, /* 3f977410f4c2cfc4335f28446c0fb363 */
+ -3.08593750000000001735496343854851414E-01L, /* bffd3c000000000000800e995c176000 */
+ -1.56292999645122272621237565671593071E-32L, /* bf95449b9cbdaff6ac1246adb2c826ac */
+ -3.04687499999999982592401295899221626E-01L, /* bffd37fffffffffffafb8bc1e061a000 */
+ 6.48993208584888904958594509625158417E-32L, /* 3f9750f9fe8366d82d77afa0031a92e1 */
+ -3.00781249999999999230616898937763959E-01L, /* bffd33ffffffffffffc73ac39da54000 */
+ 6.57082437496961397305801409357792029E-32L, /* 3f97552d3cb598ea80135cf3feb27ec4 */
+ -2.96874999999999998788769281703245722E-01L, /* bffd2fffffffffffffa6a07fa5021000 */
+ -3.26588297198283968096426564544269170E-32L, /* bf9653260fc1802f46b629aee171809b */
+ -2.92968750000000015318089182805941695E-01L, /* bffd2c0000000000046a468614bd6000 */
+ -1.73291974845198589684358727559290718E-32L, /* bf9567e9d158f52e483c8d8dcb5961dd */
+ -2.89062500000000007736778942676309681E-01L, /* bffd280000000000023adf9f4c3d3000 */
+ -6.83629745986675744404029225571026236E-32L, /* bf9762f5face6281c1daf1c6aedbdb45 */
+ -2.85156250000000001367091555763661937E-01L, /* bffd2400000000000064dfa11e3fb000 */
+ -5.44898442619766878281110054067026237E-32L, /* bf971aed6d2db9f542986a785edae072 */
+ -2.81249999999999986958718100227029406E-01L, /* bffd1ffffffffffffc3db9265ca9d000 */
+ 1.13007318374506125723591889451107046E-32L, /* 3f94d569fe387f456a97902907ac3856 */
+ -2.77343750000000000356078829380495179E-01L, /* bffd1c0000000000001a462390083000 */
+ -4.98979365468978332358409063436543102E-32L, /* bf970315bbf3e0d14b5c94c900702d4c */
+ -2.73437499999999990276993957508540484E-01L, /* bffd17fffffffffffd32919bcdc94000 */
+ -8.79390484115892344533724650295100871E-32L, /* bf97c89b0b89cc19c3ab2b60da9bbbc3 */
+ -2.69531250000000002434203866460082225E-01L, /* bffd14000000000000b39ccf9e130000 */
+ 9.44060754687026590886751809927191596E-32L, /* 3f97ea2f32cfecca5c64a26137a9210f */
+ -2.65624999999999997296320716986257179E-01L, /* bffd0fffffffffffff3880f13a2bc000 */
+ 2.07142664067265697791007875348396921E-32L, /* 3f95ae37ee685b9122fbe377bd205ee4 */
+ -2.61718750000000010237478733739017956E-01L, /* bffd0c000000000002f3648179d40000 */
+ -6.10552936159265665298996309192680256E-32L, /* bf973d0467d31e407515a3cca0f3b4e2 */
+ -2.57812500000000011948220522778370303E-01L, /* bffd08000000000003719f81275bd000 */
+ 6.72477169058908902499239631466443836E-32L, /* 3f975d2b8c475d3160cf72d227d8e6f9 */
+ -2.53906249999999991822993360536596860E-01L, /* bffd03fffffffffffda4a4b62f818000 */
+ -2.44868296623215865054704392917190994E-32L, /* bf95fc92516c6d057d29fc2528855976 */
+ -2.49999999999999986862019457428548084E-01L, /* bffcfffffffffffff86d2d20d5ff4000 */
+ -3.85302898949105073614122724961613078E-32L, /* bf96901f147cb7d643af71b6129ce929 */
+ -2.46093750000000000237554160737318435E-01L, /* bffcf8000000000000230e8ade26b000 */
+ -1.52823675242678363494345369284988589E-32L, /* bf953d6700c5f3fc303f79d0ec8c680a */
+ -2.42187500000000003023380963205457065E-01L, /* bffcf0000000000001be2c1a78bb0000 */
+ -7.78402037952209709489481182714311699E-34L, /* bf9102ab1f3998e887f0ee4cf940faa5 */
+ -2.38281249999999995309623303145485725E-01L, /* bffce7fffffffffffd4bd2940f43f000 */
+ -3.54307216794236899443913216397197696E-32L, /* bf966fef03ab69c3f289436205b21d02 */
+ -2.34374999999999998425804947623207526E-01L, /* bffcdfffffffffffff17b097a6092000 */
+ -2.86038428948386602859761879407549696E-32L, /* bf96290a0eba0131efe3a05fe188f2e3 */
+ -2.30468749999999993822207406785200832E-01L, /* bffcd7fffffffffffc70519834eae000 */
+ -2.54339521031747516806893838749365762E-32L, /* bf96081f0ad7f9107ae6cddb32c178ab */
+ -2.26562499999999997823524030344489884E-01L, /* bffccffffffffffffebecf10093df000 */
+ 4.31904611473158635644635628922959401E-32L, /* 3f96c083f0b1faa7c4c686193e38d67c */
+ -2.22656250000000004835132405125162742E-01L, /* bffcc8000000000002c98a233f19f000 */
+ 2.54709791629335691650310168420597566E-33L, /* 3f92a735903f5eed07a716ab931e20d9 */
+ -2.18749999999999988969454021829236626E-01L, /* bffcbffffffffffff9a42dc14ce36000 */
+ -3.77236096429336082213752014054909454E-32L, /* bf9687be8e5b2fca54d3e81157eac660 */
+ -2.14843750000000010613256919115758495E-01L, /* bffcb80000000000061e3d828ecac000 */
+ -4.55194148712216691177097854305964738E-32L, /* bf96d8b35c776aa3e1a4768271380503 */
+ -2.10937499999999993204656148110447201E-01L, /* bffcaffffffffffffc152f2aea118000 */
+ -2.95044199165561453749332254271716417E-32L, /* bf96326433b00b2439094d9bef22ddd1 */
+ -2.07031250000000012233944895423355677E-01L, /* bffca80000000000070d695ee0e94000 */
+ 1.93146788688385419095981415411012357E-32L, /* 3f959126729135a5e390d4bb802a0bde */
+ -2.03125000000000008030983633336321863E-01L, /* bffca0000000000004a129fbc51af000 */
+ 2.37361904671826193563212931215900137E-32L, /* 3f95ecfb3c4ba1b97ea3ad45cbb1e68a */
+ -1.99218750000000001763815712796132779E-01L, /* bffc98000000000001044b12d9950000 */
+ -3.63171243370923753295192486732883239E-33L, /* bf932db5fb3f27c38e0fa7bbcfc64f55 */
+ -1.95312500000000004883660234506677272E-01L, /* bffc90000000000002d0b3779d1f9000 */
+ -3.19989507343607877747980892249711601E-33L, /* bf9309d63de96bb3ef744c865f22f1bd */
+ -1.91406250000000013720152363227519348E-01L, /* bffc88000000000007e8bcb387121000 */
+ -1.89295754093147174148371614722178860E-32L, /* bf958926e2e67dfe812c508290add2e7 */
+ -1.87500000000000000182342082774432620E-01L, /* bffc800000000000001ae8b06a39f000 */
+ -2.96812835183184815200854214892983927E-32L, /* bf96343a62d156bbe71f55d14ca4b6e5 */
+ -1.83593750000000012410147185883290345E-01L, /* bffc78000000000007276a1adda8d000 */
+ -2.02191931237489669058466239995304587E-32L, /* bf95a3efab92d26ec2df90df036a117f */
+ -1.79687499999999997439177363346082917E-01L, /* bffc6ffffffffffffe8616db2927d000 */
+ -9.92752326937775530007399526834009465E-33L, /* bf949c5f88ed17041e1a3f1829d543cd */
+ -1.75781249999999995824373974504785174E-01L, /* bffc67fffffffffffd97c94f13ea3000 */
+ 1.44184772065335613487885714828816178E-32L, /* 3f952b75c63476e7fcc2f5841c27bcce */
+ -1.71874999999999986685050259043077809E-01L, /* bffc5ffffffffffff8530f6bc531a000 */
+ -3.49007014971241147689894940544402482E-32L, /* bf966a6dfaa012aea8ffe6d90b02330f */
+ -1.67968749999999997316058782350439701E-01L, /* bffc57fffffffffffe73eb914f2aa000 */
+ 3.34025733574205019081305778794376391E-32L, /* 3f965adf4572561fd5456a6c13d8babf */
+ -1.64062499999999993322730602128318480E-01L, /* bffc4ffffffffffffc269be4f68f3000 */
+ -1.83345916769684984022099095506340635E-32L, /* bf957ccb69026cb2f6024c211576d5f4 */
+ -1.60156249999999992419000744447607979E-01L, /* bffc47fffffffffffba13df21784a000 */
+ 2.73442789798110494773517431626534726E-32L, /* 3f961bf58ff22c9b30f1e2b39f26d7d5 */
+ -1.56249999999999987665010524130393080E-01L, /* bffc3ffffffffffff8e3ad45e7508000 */
+ 2.02695576464836145806428118889332191E-32L, /* 3f95a4fb7435a4a2f71de81eb8ae75d1 */
+ -1.52343749999999989905291167951491803E-01L, /* bffc37fffffffffffa2e48aecfc24000 */
+ -3.61436631548815190395331054871041524E-32L, /* bf967756567ebd108075ae527cc2e7f0 */
+ -1.48437500000000006686107754967759751E-01L, /* bffc30000000000003dab20261b3c000 */
+ -2.15524270159131591469319477922198390E-32L, /* bf95bfa05b82ef3a708c4f0395e9fcf6 */
+ -1.44531250000000005132889939177166485E-01L, /* bffc28000000000002f57b1969e7b000 */
+ 2.74741116529653547935086189244019604E-32L, /* 3f961d4eb77c1185d34fe1b04a3f3cf5 */
+ -1.40625000000000000707469094533647325E-01L, /* bffc2000000000000068676d3d5c4000 */
+ 4.40607097220049957013547629906723266E-33L, /* 3f936e0ac425daf795b42913cf0ef881 */
+ -1.36718749999999995713752139187543306E-01L, /* bffc17fffffffffffd87762255991000 */
+ -3.73751317180116492404578048203389108E-32L, /* bf9684202491e9cbb7ceb67d9ff7e0c9 */
+ -1.32812500000000007198453630478482191E-01L, /* bffc10000000000004264de3a4379000 */
+ -3.97050085179660203884930593717220728E-32L, /* bf969c52048de14be3c9c1971e50869c */
+ -1.28906250000000006070486371645733082E-01L, /* bffc080000000000037fd87db2cb0000 */
+ 3.59610068058504988294019521946586131E-32L, /* 3f967570c10687cb8e9ebd0b280abf5a */
+ -1.25000000000000003700729208608337966E-01L, /* bffc00000000000002222198bbc74000 */
+ 3.23464851393124362331846965931995969E-33L, /* 3f930cb95da3bfc847e593716c91d57a */
+ -1.21093750000000013729038501177102555E-01L, /* bffbf000000000000fd418d1f5fda000 */
+ 2.45242487730722066611358741283977619E-32L, /* 3f95fd5945ad86a464292e26ac192a84 */
+ -1.17187499999999999765305306880205578E-01L, /* bffbdfffffffffffffbabaf869845000 */
+ -1.14557520298960389903199646350205537E-32L, /* bf94dbda735322179d9bcf392e1dd06d */
+ -1.13281250000000009579647893740755690E-01L, /* bffbd000000000000b0b69bae7ab9000 */
+ 2.37873962873837390105423621772752350E-32L, /* 3f95ee0b7e0bd5ac1f6fab1e2a71abc3 */
+ -1.09375000000000008981153004560108539E-01L, /* bffbc000000000000a5ac4bc1d2c3000 */
+ 1.53152444860014076105003555837231015E-32L, /* 3f953e15ce931e12ef9a152522e32bdd */
+ -1.05468749999999992399063850363228723E-01L, /* bffbaffffffffffff73c998091408000 */
+ -8.75920903597804862471749360196688834E-33L, /* bf946bd7e310a01bae5687ebdc47fcc5 */
+ -1.01562500000000007685885179918350550E-01L, /* bffba0000000000008dc7910a648c000 */
+ -4.63820993797174451904075397785059501E-33L, /* bf938153d0e54001a472da180fb5e8aa */
+ -9.76562499999999887262211517861331814E-02L, /* bffb8ffffffffffff300915aa6fd6000 */
+ -2.63767025974952608658936466715705903E-33L, /* bf92b64215bb8d520be5404620d38088 */
+ -9.37499999999999939650246024457439795E-02L, /* bffb7ffffffffffff90aca26bd0fc000 */
+ -1.72047822349322956713582039121348377E-32L, /* bf9565545015c5b9b56d02cfefca2c7d */
+ -8.98437500000000033088896383977486369E-02L, /* bffb70000000000003d09ca1e3cbe000 */
+ 3.04831994420989436248526129869697270E-33L, /* 3f92fa7d30d2ed90e7ebbd6231fd08b1 */
+ -8.59374999999999947312400115121319225E-02L, /* bffb5ffffffffffff9ecefc03376e000 */
+ 1.50416954438393392150792422537312281E-32L, /* 3f9538675ee99bd722fad0023c09c915 */
+ -8.20312500000000054182280847004695514E-02L, /* bffb500000000000063f2dbd40200000 */
+ 2.68399664523430004488075638997207289E-33L, /* 3f92bdf49766629882c49a3da88928ed */
+ -7.81250000000000114767533968079748798E-02L, /* bffb4000000000000d3b56f81ba70000 */
+ 1.72318124201659121296305402819694281E-32L, /* 3f9565e407aaabfb359e8a567d760de3 */
+ -7.42187500000000035531829472486812869E-02L, /* bffb3000000000000418b6e9b5388000 */
+ 2.09401756478514117051383998628099655E-32L, /* 3f95b2e91221fcd74be0a86d8ad658d2 */
+ -7.03124999999999987474933134860732535E-02L, /* bffb1ffffffffffffe8e53453d2ac000 */
+ 2.28515798224350800271565551341211666E-32L, /* 3f95da9bd6adf00894f05b5cc5530125 */
+ -6.64062500000000042267533361089054159E-02L, /* bffb10000000000004df8473dbcf2000 */
+ 1.97576478800281368377376002585430031E-32L, /* 3f959a59acbddb2f53bd3096b66370e9 */
+ -6.25000000000000066329769382774201686E-02L, /* bffb00000000000007a5b5914e336000 */
+ -1.46422615813786836245343723048221678E-33L, /* bf91e69295f069fc0c4a9db181ea25a3 */
+ -5.85937500000000002823707957982406053E-02L, /* bffae0000000000000a6aeab10592000 */
+ 9.25637741701318872896718218457555829E-33L, /* 3f94807eb021f1f40a37d4015b1eb76b */
+ -5.46875000000000081586888005226044448E-02L, /* bffac0000000000012d00a3171e3a000 */
+ -4.87144542459404765480424673678105050E-33L, /* bf9394b42faba6b7036fe7b36269daf3 */
+ -5.07812499999999927720348253140567013E-02L, /* bffa9fffffffffffef555cc8dd914000 */
+ -3.01901021987395945826043649523451725E-33L, /* bf92f59e7e3025691f290f8f67277faf */
+ -4.68749999999999935349476738962633103E-02L, /* bffa7ffffffffffff117b4ea2b876000 */
+ 1.21521638219189777347767475937119750E-32L, /* 3f94f8c7f88c5b56674b94d984ac8ecb */
+ -4.29687500000000056305562847814228219E-02L, /* bffa6000000000000cfbb19be30c0000 */
+ -1.18643699217679276275559592978275214E-32L, /* bf94ecd39f0833a876550e83eb012b99 */
+ -3.90624999999999962692914526031373542E-02L, /* bffa3ffffffffffff765c743922f9000 */
+ -4.91277156857520035712509544689973679E-33L, /* bf939823189996193872e58ac0dececb */
+ -3.51562500000000108152468207687602886E-02L, /* bffa20000000000018f031e41177f000 */
+ 1.18599806302656253755207072755609820E-32L, /* 3f94eca4f23e787fab73ce8f6b9b8d64 */
+ -3.12500000000000077376981036742289578E-02L, /* bffa00000000000011d787e0b386f000 */
+ 9.97730386477005171963635210799577079E-33L, /* 3f949e70e498c46a0173ac0d46c699fc */
+ -2.73437500000000139436129596418623235E-02L, /* bff9c00000000000404db66e70a08000 */
+ 2.25755321633070123579875157841633859E-33L, /* 3f927719b1a93074bdf9f3c2cb784785 */
+ -2.34375000000000088003629211828324876E-02L, /* bff98000000000002895a27d45feb000 */
+ 2.84374279216848803102126617873942975E-33L, /* 3f92d87f70e749d6da6c260b68dc210b */
+ -1.95312500000000107408831063404855424E-02L, /* bff9400000000000318898ba69f71000 */
+ 2.47348089686935458989103979140011912E-33L, /* 3f929afa3de45086fe909fdddb41edce */
+ -1.56250000000000081443917555362290635E-02L, /* bff9000000000000258f335e9cdd6000 */
+ -2.43379314483517422161458863218426254E-33L, /* bf9294621c8a9ccacf2b020ec19cad27 */
+ -1.17187500000000051490597418161403184E-02L, /* bff88000000000002f7ddfa26221f000 */
+ 1.83405297208145390679150568810924707E-33L, /* 3f9230bbfc5d5fe1b534fbcda0465bb9 */
+ -7.81249999999999715861805208310174953E-03L, /* bff7ffffffffffffcb95f3fff157d000 */
+ 3.51548384878710915171654413641872451E-34L, /* 3f8fd349b76c22966f77a39fc37ed704 */
+ -3.90625000000000309326013918295097128E-03L, /* bff7000000000000390f820c8e153000 */
+ 6.38058004651791109324060099097251911E-36L, /* 3f8a0f665d3ac25a1ac94d688273dbcd */
+#define T_EXPL_ARG1 (2*89)
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 3.90625000000000245479958859972588985E-03L, /* 3ff70000000000002d48769ac9874000 */
+ -6.58439598384342854976169982902779828E-36L, /* bf8a1811b923e6c626b07ef29761482a */
+ 7.81250000000001311374391093664996358E-03L, /* 3ff800000000000078f3f3cd89111000 */
+ 2.60265650555493781464273319671555602E-33L, /* 3f92b070c3b635b87af426735a71fc87 */
+ 1.17187500000000269581156218247101912E-02L, /* 3ff8800000000000f8a50d02fe20d000 */
+ 1.00961747974945520631836275894919326E-33L, /* 3f914f80c1a4f8042044fe3b757b030b */
+ 1.56249999999999797878275270751825475E-02L, /* 3ff8ffffffffffff45935b69da62e000 */
+ 2.03174577741375590087897353146748580E-33L, /* 3f925194e863496e0f6e91cbf6b22e26 */
+ 1.95312499999999760319884511789111533E-02L, /* 3ff93fffffffffff917790ff9a8f4000 */
+ 4.62788519658803722282100289809515007E-33L, /* 3f9380783ba81295feeb3e4879d7d52d */
+ 2.34374999999999822953909016349145918E-02L, /* 3ff97fffffffffffae5a163bd3cd5000 */
+ -3.19499956304699705390404384504876533E-33L, /* bf93096e2037ced8194cf344c692f8d6 */
+ 2.73437500000000137220327275871555682E-02L, /* 3ff9c000000000003f481dea5dd51000 */
+ -2.25757776523031994464630107442723424E-33L, /* bf92771abcf988a02b414bf2614e3734 */
+ 3.12499999999999790857640618332718621E-02L, /* 3ff9ffffffffffff9f8cd40b51509000 */
+ -4.22479470489989916319395454536511458E-33L, /* bf935efb7245612f371deca17cb7b30c */
+ 3.51562499999999840753382405747597346E-02L, /* 3ffa1fffffffffffdb47bd275f722000 */
+ 1.08459658374118041980976756063083500E-34L, /* 3f8e2055d18b7117c9db1c318b1e889b */
+ 3.90624999999999989384433621470426757E-02L, /* 3ffa3ffffffffffffd8d5e18b042e000 */
+ -7.41674226146122000759491297811091830E-33L, /* bf94341454e48029e5b0205d91baffdc */
+ 4.29687500000000107505739500500200462E-02L, /* 3ffa60000000000018ca04cd9085c000 */
+ -4.74689012756713017494437969420919847E-34L, /* bf903b7c268103c6f7fbaaa24142e287 */
+ 4.68749999999999978700749928325717352E-02L, /* 3ffa7ffffffffffffb16b6d5479e3000 */
+ -1.06208165308448830117773486334902917E-32L, /* bf94b92be4b3b5b5a596a0a5187cc955 */
+ 5.07812499999999815072625435955786253E-02L, /* 3ffa9fffffffffffd55bd086d5cbc000 */
+ -9.37038897148383660401929567549111394E-33L, /* bf94853b111b0175b491c80d00419416 */
+ 5.46874999999999809511553152189867394E-02L, /* 3ffabfffffffffffd4138bfa74a61000 */
+ 1.06642963074562437340498606682822123E-32L, /* 3f94bafa3fe991b39255d563dfa05d89 */
+ 5.85937500000000184331996330905145551E-02L, /* 3ffae000000000002a810a5f2f8bf000 */
+ -1.76639977694797200820296641773791945E-34L, /* bf8ed596f07ce4408f1705c8ec16864c */
+ 6.25000000000000021544696744852045001E-02L, /* 3ffb000000000000027be32045e2b000 */
+ 1.68616371995798354366633034788947149E-32L, /* 3f955e33d7440794d8a1b25233d086ab */
+ 6.64062499999999965563110718495802889E-02L, /* 3ffb0ffffffffffffc079a38a3fed000 */
+ -1.82463217667830160048872113565316215E-32L, /* bf957af6163bcdb97cefab44a942482a */
+ 7.03124999999999759989183341261898222E-02L, /* 3ffb1fffffffffffe454218acea05000 */
+ -1.07843770101525495515646940862541503E-32L, /* bf94bff72aada26d94e76e71c07e0580 */
+ 7.42187499999999898968873730710101412E-02L, /* 3ffb2ffffffffffff45a166496dc1000 */
+ 1.28629441689592874462780757154138223E-32L, /* 3f950b2724597b8b93ce1e9d1cf4d035 */
+ 7.81249999999999957198938523510804668E-02L, /* 3ffb3ffffffffffffb10bc52adbc5000 */
+ 1.13297573459968118467100063135856856E-33L, /* 3f91787eea895b3c245899cf34ad0abd */
+ 8.20312500000000199911640621145851159E-02L, /* 3ffb500000000000170c59a661a89000 */
+ -1.51161335208135146756554123073528707E-32L, /* bf9539f326c5ca84e7db5401566f3775 */
+ 8.59375000000000134175373433347670743E-02L, /* 3ffb6000000000000f78287547af0000 */
+ 1.09763629458404270323909815379924900E-32L, /* 3f94c7f0b61b6e3e27d44b9f5bbc7e9d */
+ 8.98437500000000036533922600308306335E-02L, /* 3ffb70000000000004364a83b7a14000 */
+ 3.11459653680110433194288029777718358E-33L, /* 3f9302c0248136d65cebeab69488d949 */
+ 9.37500000000000184977946245216914691E-02L, /* 3ffb800000000000155395d870b17000 */
+ -4.66656154468277949130395786965043927E-33L, /* bf9383aec9b993b6db492b1ede786d8a */
+ 9.76562500000000237839723100419376084E-02L, /* 3ffb9000000000001b6bca237f6c4000 */
+ -1.03028043424658760249140747856831301E-32L, /* bf94abf6352e3d2bb398e47919a343fb */
+ 1.01562500000000012345545575236836572E-01L, /* 3ffba000000000000e3bc30cd9a1f000 */
+ 2.15755372310795701322789783729456319E-32L, /* 3f95c01b3b819edd9d07548fafd61550 */
+ 1.05468749999999976493840484471911438E-01L, /* 3ffbafffffffffffe4e634cd77985000 */
+ 1.78771847038773333029677216592309083E-32L, /* 3f95734b6ae650f33dd43c49a1df9fc0 */
+ 1.09375000000000002267015055992785402E-01L, /* 3ffbc00000000000029d1ad08de7b000 */
+ 6.23263106693943817730045115112427717E-33L, /* 3f9402e4b39ce2198a45e1d045868cd6 */
+ 1.13281250000000022354208618429577398E-01L, /* 3ffbd0000000000019c5cc3f9d2b5000 */
+ 5.40514416644786448581426756221178868E-33L, /* 3f93c10ab4021472c662f69435de9269 */
+ 1.17187500000000013252367133076817603E-01L, /* 3ffbe000000000000f47688cc561b000 */
+ -7.12412585457324989451327215568641325E-33L, /* bf9427ecb343a8d1758990565fcfbf45 */
+ 1.21093750000000020759863992944300792E-01L, /* 3ffbf0000000000017ef3af97bf04000 */
+ 6.26591408357572503875647872077266444E-33L, /* 3f940446a09a2da771b45fc075514d12 */
+ 1.25000000000000004739659392396765618E-01L, /* 3ffc00000000000002bb7344ecd89000 */
+ -1.55611398459729463981000080101758830E-32L, /* bf95433135febefa9e6aa4db39e263d2 */
+ 1.28906249999999982360888081057894783E-01L, /* 3ffc07fffffffffff5d4ed3154361000 */
+ -1.77531518652835570781208599686606474E-32L, /* bf9570b7f225ea076f97f418d11359c1 */
+ 1.32812500000000010568583998727400436E-01L, /* 3ffc1000000000000617a5d09526a000 */
+ 2.12104021624990594668286391598300893E-32L, /* 3f95b885d767a1048d93055927a27adc */
+ 1.36718749999999998434125157367005292E-01L, /* 3ffc17ffffffffffff18eaebc7970000 */
+ 2.50454798592543203967309921276955297E-32L, /* 3f9604164e5598528a76faff26cd1c97 */
+ 1.40625000000000015550032422969330356E-01L, /* 3ffc20000000000008f6c79d8928c000 */
+ 7.80972982879849783680252962992639832E-33L, /* 3f9444674acf2b3225c7647e0d95edf3 */
+ 1.44531250000000012402535562111122522E-01L, /* 3ffc28000000000007264a8bc1ff1000 */
+ 2.79662468716455159585514763921671876E-32L, /* 3f96226b095bd78aa650faf95a221993 */
+ 1.48437500000000007761020440087419948E-01L, /* 3ffc3000000000000479530ff8fe3000 */
+ 2.15518492972728435680556239996258527E-32L, /* 3f95bf9d49295e73a957906a029768cb */
+ 1.52343750000000001733189947520484032E-01L, /* 3ffc38000000000000ffc6109f71f000 */
+ 8.34032236093545825619420380704500188E-33L, /* 3f945a71851226a1d0ce5e656693153e */
+ 1.56249999999999988073295321246958484E-01L, /* 3ffc3ffffffffffff91fedd62ae0f000 */
+ 2.44119337150624789345260194989620908E-32L, /* 3f95fb041a57bc1c1280680ac1620bea */
+ 1.60156250000000002076894210913572460E-01L, /* 3ffc48000000000001327ed84a199000 */
+ -7.36124501128859978061216696286151753E-33L, /* bf9431c62f01e59d2c1e00f195a0037f */
+ 1.64062500000000000950861276373482172E-01L, /* 3ffc500000000000008c5285fba85000 */
+ -4.80566184447001164583855800470217373E-33L, /* bf938f3d1fcafd390f22f80e6c19421f */
+ 1.67968749999999989878071706155265999E-01L, /* 3ffc57fffffffffffa2a445c548c5000 */
+ -4.42154428718618459799673088733365064E-32L, /* bf96cb28cf1c1b28006d53ffe633b22a */
+ 1.71874999999999999459734108403218175E-01L, /* 3ffc5fffffffffffffb04554e9dd4000 */
+ -3.29736288190321377985697972236270628E-32L, /* bf96566af0ebc852e84be12859b24a31 */
+ 1.75781249999999997987525759778901845E-01L, /* 3ffc67fffffffffffed702df6ffff000 */
+ -1.28800728638468399687523924685844352E-32L, /* bf950b8236b88ca0c1b739dc91a7e3fc */
+ 1.79687500000000004929565820437175783E-01L, /* 3ffc70000000000002d779bb32d2e000 */
+ 1.60624461317978482424582320675174225E-32L, /* 3f954d9a9cc0c963fd081f3dc922d04e */
+ 1.83593750000000016873727045739708856E-01L, /* 3ffc78000000000009ba1f6263c9a000 */
+ -3.83390389582056606880506003118452558E-32L, /* bf968e22a5d826f77f19ee788474df22 */
+ 1.87500000000000013443068740761666872E-01L, /* 3ffc80000000000007bfd8c72a1bf000 */
+ -2.74141662712926256150154726565203091E-32L, /* bf961caf5ac59c7f941f928e324c2cc1 */
+ 1.91406249999999981494101786848611970E-01L, /* 3ffc87fffffffffff55502eeae001000 */
+ 3.68992437075565165346469517256118001E-32L, /* 3f967f2f03f9096793372a27b92ad79d */
+ 1.95312499999999989069921848800501648E-01L, /* 3ffc8ffffffffffff9b3015280394000 */
+ 3.69712249337856518452988332367785220E-32L, /* 3f967fee5fdb5bd501ff93516999faa0 */
+ 1.99218750000000021148042946919300804E-01L, /* 3ffc9800000000000c30e67939095000 */
+ 2.50142536781142175091322844848566649E-32L, /* 3f9603c34ae58e10b300b07137ee618a */
+ 2.03124999999999977732559198825437141E-01L, /* 3ffc9ffffffffffff329e7df079e4000 */
+ -2.41951877287895024779300892731537816E-32L, /* bf95f683aefe6965f080df8f59dd34a1 */
+ 2.07031249999999996744030653771913124E-01L, /* 3ffca7fffffffffffe1f80f4b73ca000 */
+ -1.94346475904454000031592792989765585E-32L, /* bf9593a44f87870a3d100d498501ecc7 */
+ 2.10937500000000000251399259834392298E-01L, /* 3ffcb000000000000025199873310000 */
+ -1.33528748788094249098998693871759411E-33L, /* bf91bbb9b25c813668d6103d08acac35 */
+ 2.14843749999999993936323609611875097E-01L, /* 3ffcb7fffffffffffc8128c866236000 */
+ 1.14839877977014974625242788556545292E-32L, /* 3f94dd06b4655c9b83a1305b240e7a42 */
+ 2.18750000000000015181732784749663837E-01L, /* 3ffcc0000000000008c06da5fff24000 */
+ 1.42689085313142539755499441881408391E-32L, /* 3f95285a87dfa7ea7dad5b3be8c669f4 */
+ 2.22656249999999992172647770539596569E-01L, /* 3ffcc7fffffffffffb7ce2fe531f6000 */
+ -3.34421462850496887359128610229650547E-32L, /* bf965b487962b5c2d9056ca6ac0c2e5c */
+ 2.26562499999999989595607223847082419E-01L, /* 3ffccffffffffffffa0095277be5c000 */
+ -3.08983588107248752517344356508205569E-32L, /* bf9640dded57157f8eded311213bdbcd */
+ 2.30468749999999979130462438434567117E-01L, /* 3ffcd7fffffffffff3f8332996560000 */
+ -3.01407539802851697849105682795217019E-32L, /* bf9638ffde35dbdfe1a1ffe45185de5d */
+ 2.34375000000000012194252337217891971E-01L, /* 3ffce0000000000007078dd402c86000 */
+ -8.46879710915628592284714319904522657E-33L, /* bf945fc7b29a2ac6c9eff9eb258a510f */
+ 2.38281249999999982991877076137149870E-01L, /* 3ffce7fffffffffff6320b486eece000 */
+ -2.93563878880439245627127095245798544E-32L, /* bf9630daaa4f40ff05caf29ace2ea7d4 */
+ 2.42187499999999981447559841442773990E-01L, /* 3ffceffffffffffff54e24a09a8d5000 */
+ -4.56766746558806021264215486909850481E-32L, /* bf96da556dee11f3113e5a3467b908e6 */
+ 2.46093749999999991067720539980207318E-01L, /* 3ffcf7fffffffffffad9d405dcb5d000 */
+ 2.14033004219908074003010247652128251E-32L, /* 3f95bc8776e8f9ae098884aa664cc3df */
+ 2.50000000000000016613825838126835953E-01L, /* 3ffd00000000000004c9e24c12bb3000 */
+ 2.57617532593749185996714235009382870E-32L, /* 3f960b867cc01178c0ec68226c6cb47d */
+ 2.53906250000000013372004437827044321E-01L, /* 3ffd04000000000003daae05b3168000 */
+ 7.20177123439204414298152646284640101E-32L, /* 3f9775eff59ddad7e7530b83934af87f */
+ 2.57812499999999995765234725413886085E-01L, /* 3ffd07fffffffffffec7878bad9d5000 */
+ 6.51253187532920882777046064603770602E-32L, /* 3f975226659ca241402e71c2011583b0 */
+ 2.61718750000000007647689994011222248E-01L, /* 3ffd0c000000000002344cc793a0f000 */
+ 3.02370610028725823590045201871491395E-32L, /* 3f9639ffe55fa2fa011674448b4e5b96 */
+ 2.65624999999999986893899042596554269E-01L, /* 3ffd0ffffffffffffc38f0c0a1e9f000 */
+ -2.07683715950724761146070082510569258E-32L, /* bf95af579a92e872fef81abfdf06bae8 */
+ 2.69531249999999979842788204900639327E-01L, /* 3ffd13fffffffffffa30a908d67db000 */
+ 8.71465252506557329027658736641075706E-32L, /* 3f97c47d99e19830447a42b1c0ffac61 */
+ 2.73437500000000006712165837793818271E-01L, /* 3ffd18000000000001ef453a58edb000 */
+ -6.62704045767568912140550474455810301E-32L, /* bf9758187a204dcb06ece46588aeeaba */
+ 2.77343749999999994411329302988535617E-01L, /* 3ffd1bfffffffffffe63a0fec9c9e000 */
+ -4.87273466291944117406493607771338767E-32L, /* bf96fa0381b0844a0be46bac2d673f0c */
+ 2.81250000000000012677892447379453135E-01L, /* 3ffd20000000000003a7769e125d6000 */
+ -8.55871796664700790726282049552906783E-32L, /* bf97bc64e01332cf7616b0091b8dff2c */
+ 2.85156249999999998558643013736363981E-01L, /* 3ffd23ffffffffffff95a5894bccf000 */
+ -1.33068334720606220176455289635046875E-32L, /* bf95145f43290ecf5b7adcb24697bc73 */
+ 2.89062500000000008831431235621753924E-01L, /* 3ffd280000000000028ba504fac59000 */
+ -9.34157398616814623985483776710704237E-32L, /* bf97e50ad1115b941fcb5f0c88a428f7 */
+ 2.92968750000000019840235286110877063E-01L, /* 3ffd2c000000000005b7f372d184f000 */
+ 4.99302093775173155906059132992249671E-33L, /* 3f939ecdcfb97bad3f8dbec5df5ec67d */
+ 2.96875000000000015867911730971630513E-01L, /* 3ffd3000000000000492d860c79db000 */
+ 7.86107787827057767235127454590866211E-33L, /* 3f944689517ee8f16cdb97d6a6938f32 */
+ 3.00781250000000015814100002286124758E-01L, /* 3ffd340000000000048edfe73a17d000 */
+ -1.65419431293024229981937172317171504E-32L, /* bf9557900e3efca16c89646b57f68dc0 */
+ 3.04687499999999985213157159965287195E-01L, /* 3ffd37fffffffffffbbcec6f99b36000 */
+ 9.68753602893894024018934325652944198E-32L, /* 3f97f70170e5458660c33a7e8d43d049 */
+ 3.08593749999999989969324338045156215E-01L, /* 3ffd3bfffffffffffd1bdde4d0fb1000 */
+ 7.10268609610294706092252562643261106E-32L, /* 3f9770cae45cdf615010401a4b37d8d4 */
+ 3.12500000000000002971606591018488854E-01L, /* 3ffd40000000000000db440fbc06b000 */
+ 6.38924218802905979887732294952782964E-32L, /* 3f974bbf988bb5622bd8fbaa46e8b811 */
+ 3.16406250000000006594921047402056305E-01L, /* 3ffd44000000000001e69e8954814000 */
+ 3.96079878754651470094149874444850097E-32L, /* 3f969b5017b9fa7a1e86975258c73d3d */
+ 3.20312500000000006713799366908329147E-01L, /* 3ffd48000000000001ef64159c065000 */
+ -1.86401314975634286055150437995880517E-32L, /* bf958323f0434911794e5fb8bfe136ba */
+ 3.24218749999999987061246567584951210E-01L, /* 3ffd4bfffffffffffc4549db9b928000 */
+ -3.18643523744758601387071062700407431E-32L, /* bf964ae5fa7e26c2c3981bed12e14372 */
+ 3.28124999999999991782776266707412953E-01L, /* 3ffd4ffffffffffffda1ad0840ca8000 */
+ -4.46964199751314296839915534813144652E-32L, /* bf96d0277729ffd74727150df6d15547 */
+ 3.32031250000000000393816557756032682E-01L, /* 3ffd540000000000001d0efc04fad000 */
+ -9.03246333902065439930373230002688649E-33L, /* bf947731a008748cc6dee948839ef7ae */
+ 3.35937499999999983810482995064392173E-01L, /* 3ffd57fffffffffffb556cab8ae61000 */
+ 5.27742727066129518825981597650621794E-32L, /* 3f9712050a6ddbf1cabf1b971f4b5d0b */
+ 3.39843750000000004310441349760912471E-01L, /* 3ffd5c0000000000013e0def5ddc4000 */
+ -3.85927263474732591932884416445586106E-32L, /* bf9690c51088ef3db9ca000829c450c2 */
+ 3.43749999999999990248130003997484364E-01L, /* 3ffd5ffffffffffffd3070624a0af000 */
+ 9.62005170171527308106468341512327487E-34L, /* 3f913fae595cea84432eb01430817fca */
+ 3.47656250000000004085726414568625697E-01L, /* 3ffd640000000000012d79309e291000 */
+ -6.59664093705705297250259434519072507E-32L, /* bf97568465eafb0e662e64a5dbfaf35f */
+
+ -1.98364257812501251077851763965418372E-03L, /* bff6040000000001cd90f658cf0b1000 */
+ -3.71984513103117734260309047540278737E-34L, /* bf8fee73c54483194782aac4a6154d11 */
+ -1.95312500000000378520649630233891879E-03L, /* bff60000000000008ba643bb5e2e8000 */
+ -1.12194202736719050440745599339855038E-34L, /* bf8e2a436aeff7bc529873354f47a3f5 */
+ -1.92260742187499397430259771221991482E-03L, /* bff5f7fffffffffe4361cb51170da000 */
+ -2.30068299876822157331268484824540848E-34L, /* bf8f31d02f85cfe8c0cc02276ce0f437 */
+ -1.89208984375001137424603270262074989E-03L, /* bff5f0000000000347456ed490c23000 */
+ -1.15012507244426243338260435466985403E-34L, /* bf8e31c174d5677a937a34ad8d2a70b4 */
+ -1.86157226562500172319250342061336738E-03L, /* bff5e800000000007f262fa3617b4000 */
+ -3.12438344643346437509767736937785561E-34L, /* bf8f9f4d426a2457c273d34ef7d9bde9 */
+ -1.83105468749999505256246872355430379E-03L, /* bff5dffffffffffe92f18c1c2b6fa000 */
+ -5.91130415288336591179087455220308942E-35L, /* bf8d3a4c80b42dc036bae446c9807f78 */
+ -1.80053710937499445182387245573120522E-03L, /* bff5d7fffffffffe669dea82b4a4c000 */
+ -1.92396289352411531324908916321392100E-34L, /* bf8eff7a2123fb573ba9778550d669bd */
+ -1.77001953125000387737631542516323906E-03L, /* bff5d000000000011e19915c3ddb7000 */
+ 7.91101758977203355387806553469731354E-36L, /* 3f8a507f5a70faaccf469e3461873dea */
+ -1.73950195312500034854670281415554486E-03L, /* bff5c8000000000019b7dc6ef97bd000 */
+ 1.55906551582436824067407021178835755E-34L, /* 3f8e9e7880333e34955aebcde3cfb053 */
+ -1.70898437499998955782591472611429852E-03L, /* bff5bffffffffffcfd80e88aa6b96000 */
+ 8.22951661962611381718215899498500357E-35L, /* 3f8db58e6031a779b59f6ece191de7cc */
+ -1.67846679687500586652037711131708544E-03L, /* bff5b80000000001b0df6fd21c133000 */
+ -8.96642618848426299713145894522897419E-35L, /* bf8ddcbcab46d531801bfae4121f2f8a */
+ -1.64794921875000109499161354039904782E-03L, /* bff5b0000000000050cbce8915575000 */
+ -2.88077905394253859590587789680486639E-34L, /* bf8f7eebd4dd860ef73b674d5e707959 */
+ -1.61743164062501133830507079150388351E-03L, /* bff5a80000000003449e8700c3e82000 */
+ -3.68271725851639066312899986829350273E-34L, /* bf8fe9845fe20a5fe74059e0cae185d6 */
+ -1.58691406249999015546015764131101956E-03L, /* bff59ffffffffffd2999e668cdd28000 */
+ 8.48197657099957029953716507898788812E-35L, /* 3f8dc2faaebb97392e451b07b28c4b12 */
+ -1.55639648437500317366570219290722587E-03L, /* bff5980000000000ea2cd9a40d256000 */
+ -3.45156704719737676412949957712570373E-36L, /* bf8925a079505516c8e317ac1ff53255 */
+ -1.52587890625000568759013197767046039E-03L, /* bff5900000000001a3ab8a3f6b698000 */
+ -1.01902948542497496574967177677556729E-34L, /* bf8e0ee78d94d9b5ad3d63ae35c9b554 */
+ -1.49536132812500945889014955936485340E-03L, /* bff5880000000002b9f1621b57743000 */
+ -3.32264697086631598830366079048117140E-34L, /* bf8fb9a7d14c32289204fbb0c9eb20e0 */
+ -1.46484374999999931883259902869504725E-03L, /* bff57fffffffffffcdbd1c90e1b4a000 */
+ -1.76487524793892929381101031660811433E-34L, /* bf8ed52f2f724bc1ae870b18356337b4 */
+ -1.43432617187498876325946983333888768E-03L, /* bff577fffffffffcc2dff8faa5570000 */
+ -3.54550084538495708816233114576143814E-34L, /* bf8fd74724576915868c1e8ce9f430f1 */
+ -1.40380859374999215367421282192718062E-03L, /* bff56ffffffffffdbd0b18aac65ed000 */
+ -1.90585907028351204486765167064669639E-34L, /* bf8efaaa0c0e23e50c11b2120348054f */
+ -1.37329101562499692341771212945644892E-03L, /* bff567ffffffffff1cfd00f1b0577000 */
+ -3.59631150411372589637918252836880320E-34L, /* bf8fde08239ac74942a46298ea4fb715 */
+ -1.34277343749999137467356674296739172E-03L, /* bff55ffffffffffd839030b05d53d000 */
+ -1.49571076125940368185068762485268117E-35L, /* bf8b3e1a3d5c684b27a9f835b1d8d3c9 */
+ -1.31225585937499247038404301859788734E-03L, /* bff557fffffffffdd469936e691e3000 */
+ 3.10375845385355395586146533282311300E-34L, /* 3f8f9c8f6d63b7a4145716ffd92491fb */
+ -1.28173828124999024755581675764821898E-03L, /* bff54ffffffffffd306589b0ab21d000 */
+ -1.98541096105909793397376077900810019E-34L, /* bf8f07e808bbb1e35106c294ffbb9687 */
+ -1.25122070312500340204619591143332523E-03L, /* bff5480000000000fb06d5f16ad2c000 */
+ 3.62884195935761446237911443317457521E-34L, /* 3f8fe25b17d623178a386a6fa6c5afb2 */
+ -1.22070312499999591578388993012071279E-03L, /* bff53ffffffffffed2a356c440074000 */
+ -2.96756662615653130862526710937493307E-35L, /* bf8c3b90d8ff2a991e5bd16718fb0645 */
+ -1.19018554687498821966212632349422735E-03L, /* bff537fffffffffc9ac3b585dda89000 */
+ 1.44659971891167323357060028901142644E-34L, /* 3f8e809279ab249edf1dad9fe13fb0bf */
+ -1.15966796875000160938908064907298384E-03L, /* bff530000000000076c0800db9639000 */
+ 2.50088010538742402346270685365928513E-34L, /* 3f8f4c6c8a483b60201d30c1a83c3cb7 */
+ -1.12915039062500267151512523291939657E-03L, /* bff5280000000000c51f7e7315137000 */
+ 7.56402096465615210500092443924888831E-35L, /* 3f8d922c1e485d99aea2668ed32b55a6 */
+ -1.09863281249998665006360103291051571E-03L, /* bff51ffffffffffc26f2d4c9ce2ba000 */
+ 1.43982174467233642713619821353592061E-34L, /* 3f8e7ec530b3d92b6303bec1c81214d1 */
+ -1.06811523437500522742248711752028025E-03L, /* bff518000000000181b7380f10446000 */
+ 5.41265133745862349181293024531133174E-35L, /* 3f8d1fc9313d018b30e790e06b6be723 */
+ -1.03759765624999980942114138999770552E-03L, /* bff50ffffffffffff1f01130490e1000 */
+ 1.21525139612685854366189534669623436E-34L, /* 3f8e4311b96b6fcde412caf3f0d86fb9 */
+ -1.00708007812499602697537601515759439E-03L, /* bff507fffffffffedad7afcce7051000 */
+ 1.00020246351201558505328236381833392E-34L, /* 3f8e09e640992512b1300744a7e984ed */
+ -9.76562499999992592487302113340463694E-04L, /* bff4fffffffffffbbad8151f8adf6000 */
+ -1.64984406575162932060422892046851002E-34L, /* bf8eb69a919986e8054b86fc34300f24 */
+ -9.46044921874989085824996924138179594E-04L, /* bff4effffffffff9b55a204fd9792000 */
+ -9.29539174108308550334255350011347171E-35L, /* bf8dee3a50ed896b4656fa577a1df3d7 */
+ -9.15527343750013735214860599791540029E-04L, /* bff4e00000000007eaf5bf103f82d000 */
+ 3.07557018309280519949818825519490586E-35L, /* 3f8c470cfbef77d32c74cb8042f6ee81 */
+ -8.85009765625012292294986105781516428E-04L, /* bff4d000000000071605c65403b97000 */
+ 4.77499983783821950338363358545463558E-35L, /* 3f8cfbc3dc18884c4c4f9e07d90d7bd3 */
+ -8.54492187499986941239470706817188192E-04L, /* bff4bffffffffff878ddf9cab264a000 */
+ -1.60128240346239526958630011447901568E-34L, /* bf8ea9b1a21e19e2d5bd84b0fbffcf95 */
+ -8.23974609374996290174598690241743810E-04L, /* bff4affffffffffddc86c249ebe06000 */
+ 1.61677540391961912631535763471935882E-34L, /* 3f8eadd00841366b0dc2bc262c2c8c36 */
+ -7.93457031249988696952538334288757473E-04L, /* bff49ffffffffff97bf6f0aa85a5f000 */
+ 1.22318577008381887076634753347515709E-34L, /* 3f8e452db5b5d250878f71040da06d14 */
+ -7.62939453124996723316499040007097041E-04L, /* bff48ffffffffffe1c7265b431108000 */
+ -1.03845161748762410745671891558398468E-34L, /* bf8e14115ad884c96d1a820c73647220 */
+ -7.32421874999998242520117923997325794E-04L, /* bff47ffffffffffefca4498b7aa8a000 */
+ 5.64005211953031009549514026639438083E-35L, /* 3f8d2be06950f68f1a6d8ff829a6928e */
+ -7.01904296874999772890934814265622012E-04L, /* bff46fffffffffffde7c0fe5d8041000 */
+ 5.90245467325173644235991233229525762E-35L, /* 3f8d39d40cc49002189243c194b1db0e */
+ -6.71386718750008699269643939210658742E-04L, /* bff460000000000503c91d798b60c000 */
+ -5.20515801723324452151498579012322191E-35L, /* bf8d14c0f08a6a9285b32b8bda003eb5 */
+ -6.40869140625005499535275057463709988E-04L, /* bff45000000000032b969184e9751000 */
+ -6.69469163285461870099846471658294534E-35L, /* bf8d63f36bab7b24d936c9380e3d3fa6 */
+ -6.10351562499999293780097329596079841E-04L, /* bff43fffffffffff97c7c433e35ed000 */
+ -1.16941808547394177991845382085515086E-34L, /* bf8e36e27886f10b234a7dd8fc588bf0 */
+ -5.79833984375000068291972326409994795E-04L, /* bff43000000000000a13ff6dcf2bf000 */
+ 1.17885044988246219185041488459766001E-34L, /* 3f8e3964677e001a00412aab52790842 */
+ -5.49316406249990904622170867910987793E-04L, /* bff41ffffffffffac1c25739c716b000 */
+ -3.31875702128137033065075734368960972E-35L, /* bf8c60e928d8982c3c99aef4f885a121 */
+ -5.18798828125011293653756992177727236E-04L, /* bff410000000000682a62cff36775000 */
+ -5.69971237642088463334239430962628187E-35L, /* bf8d2f0c76f8757d61cd1abc7ea7d066 */
+ -4.88281249999990512232251384917893121E-04L, /* bff3fffffffffff50fb48992320df000 */
+ 1.02144616714408655325510171265051108E-35L, /* 3f8ab279a3626612710b9b3ac71734ac */
+ -4.57763671874997554564967307956493434E-04L, /* bff3dffffffffffd2e3c272e3cca9000 */
+ -8.25484058867957231164162481843653503E-35L, /* bf8db6e71158e7bf93e2e683f07aa841 */
+ -4.27246093749991203999790346349633286E-04L, /* bff3bffffffffff5dbe103cba0eb2000 */
+ -3.51191203319375193921924105905691755E-35L, /* bf8c757356d0f3dd7fbefc0dd419ab50 */
+ -3.96728515624986649402960638705483281E-04L, /* bff39ffffffffff09b996882706ec000 */
+ -5.51925962073095883016589497244931171E-36L, /* bf89d586d49f22289cfc860bebb99056 */
+ -3.66210937499999945095511981300980754E-04L, /* bff37fffffffffffefcb88bfc7df6000 */
+ -2.11696465278144529364423332249588595E-35L, /* bf8bc23a84d28e5496c874ef9833be25 */
+ -3.35693359374992480958458008559640163E-04L, /* bff35ffffffffff754c548a8798f2000 */
+ -8.58941791799705081104736787493668352E-35L, /* bf8dc8b1192fb7c3662826d43acb7c68 */
+ -3.05175781250009811036303273640122156E-04L, /* bff340000000000b4fb4f1aad1c76000 */
+ -8.61173897858769926480551302277426632E-35L, /* bf8dc9e0eabb1c0b33051011b64769fa */
+ -2.74658203124987298321920308390303850E-04L, /* bff31ffffffffff15b2056ac252fd000 */
+ 3.35152809454778381053519808988046631E-37L, /* 3f85c82fb59ff8d7c80d44e635420ab1 */
+ -2.44140624999999992770514819575735516E-04L, /* bff2fffffffffffffbbb82d6a7636000 */
+ 3.54445837111124472730013879165516908E-35L, /* 3f8c78e955b01378be647b1c92aa9a77 */
+ -2.13623046875012756463165168672749438E-04L, /* bff2c0000000001d6a1635fea6bbf000 */
+ 1.50050816288650121729916777279129473E-35L, /* 3f8b3f1f6f616a61129a58e131cbd31d */
+ -1.83105468749991323078784464300306893E-04L, /* bff27fffffffffebfe0cbd0c82399000 */
+ -9.14919506501448661140572099029756008E-37L, /* bf873754bacaa9d9513b6127e791eb47 */
+ -1.52587890625013337032336300236461546E-04L, /* bff240000000001ec0cb57f2cc995000 */
+ 2.84906084373176180870418394956384516E-35L, /* 3f8c2ef6d03a7e6ab087c4f099e4de89 */
+ -1.22070312499990746786116828458007518E-04L, /* bff1ffffffffffd553bbb49f35a34000 */
+ 6.71618008964968339584520728412444537E-36L, /* 3f8a1dacb99c60071fc9cd2349495bf0 */
+ -9.15527343750029275602791047595142231E-05L, /* bff180000000000d8040cd6ecde28000 */
+ -1.95753652091078750312541716951402172E-35L, /* bf8ba0526cfb24d8d59122f1c7a09a14 */
+ -6.10351562499913258461494008080572701E-05L, /* bff0ffffffffffaffebbb92d7f6a9000 */
+ 5.69868489273961111703398456218119973E-36L, /* 3f89e4ca5df09ef4a4386dd5b3bf0331 */
+ -3.05175781250092882818419203884960853E-05L, /* bff0000000000055ab55de88fac1d000 */
+ 9.03341100018476837609128961872915953E-36L, /* 3f8a803d229fa3a0e834a63abb06662b */
+#define T_EXPL_ARG2 (2*T_EXPL_ARG1 + 2 + 2*65)
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 3.05175781249814607084128277672749162E-05L, /* 3feffffffffffeaa02abb9102f499000 */
+ 1.00271855391179733380665816525889949E-36L, /* 3f8755351afa042ac3f58114824d4c10 */
+ 6.10351562500179243748093427073421439E-05L, /* 3ff1000000000052a95de07a4c26d000 */
+ 1.67231624299180373502350811501181670E-36L, /* 3f881c87a53691cae9d77f4e40d66616 */
+ 9.15527343749970728685313252158399200E-05L, /* 3ff17ffffffffff28040cc2acde28000 */
+ 2.43665747834893104318707597514407880E-36L, /* 3f889e9366c7c6c6a2ecb78dc9b0509e */
+ 1.22070312500027751961838150070880064E-04L, /* 3ff200000000003ffddde6c153b53000 */
+ -1.73322146370624186623546452226755405E-35L, /* bf8b709d8d658ed5dbbe943de56ee84e */
+ 1.52587890624995916105682628143179430E-04L, /* 3ff23ffffffffff6954b56e285d23000 */
+ 1.23580432650945898349135528000443828E-35L, /* 3f8b06d396601dde16de7d7bc27346e6 */
+ 1.83105468750008670314358488289621794E-04L, /* 3ff2800000000013fe0cdc8c823b7000 */
+ 4.30446229148833293310207915930740796E-35L, /* 3f8cc9ba9bfe554a4f7f2fece291eb23 */
+ 2.13623046875005741337455947623248132E-04L, /* 3ff2c0000000000d3d1662de21a3f000 */
+ -3.96110759869520786681660669615255057E-35L, /* bf8ca5379b04ff4a31aab0ceacc917e6 */
+ 2.44140624999981493573336463433440506E-04L, /* 3ff2ffffffffffd553bbdf48e0534000 */
+ -1.39617373942387888957350179316792928E-35L, /* bf8b28eeedc286015802b63f96b8c5cd */
+ 2.74658203124984920706309918754626834E-04L, /* 3ff31fffffffffee9d60c8439ec1d000 */
+ -3.16168080483901830349738314447356223E-36L, /* bf890cf74f81c77a611abc1243812444 */
+ 3.05175781250008648918265055410966055E-04L, /* 3ff3400000000009f8b5c9a346636000 */
+ 8.54421306185008998867856704677221443E-35L, /* 3f8dc649cd40922fc08adc6b6b20ead0 */
+ 3.35693359374988945462612499316774515E-04L, /* 3ff35ffffffffff34146c540f15b2000 */
+ 7.96443137431639500475160850431097078E-35L, /* 3f8da77638ed3148fc4d99d1c9e13446 */
+ 3.66210937500027690542093987739604535E-04L, /* 3ff380000000001fecce34bea89c4000 */
+ 2.14507323877752361258862577769090367E-35L, /* 3f8bc834e554d38894cf91957b0253d3 */
+ 3.96728515625003928083564943615052121E-04L, /* 3ff3a00000000004875d9a4acf6ab000 */
+ 4.88358523466632050664019922448605508E-35L, /* 3f8d03a7eaeef1a9f78c71a12c44dd28 */
+ 4.27246093750017799227172345607351585E-04L, /* 3ff3c00000000014856794c3ee850000 */
+ 6.66520494592631402182216588784828935E-35L, /* 3f8d6262118fcdb59b8f16108f5f1a6c */
+ 4.57763671875002108342364320152138181E-04L, /* 3ff3e000000000026e45d855410b9000 */
+ 7.21799615960261390920033272189522298E-35L, /* 3f8d7fc645cff8879462296af975c9fd */
+ 4.88281249999999768797631616370963356E-04L, /* 3ff3ffffffffffffbbc2d7cc004df000 */
+ -5.30564629906905979452258114088325361E-35L, /* bf8d1a18b71929a30d67a217a27ae851 */
+ 5.18798828124997339054881383202487041E-04L, /* 3ff40ffffffffffe775055eea5851000 */
+ -4.03682911253647925867848180522846377E-35L, /* bf8cad44f0f3e5199d8a589d9332acad */
+ 5.49316406249980511907933706754958501E-04L, /* 3ff41ffffffffff4c410b29bb62fb000 */
+ -2.08166843948323917121806956728438051E-35L, /* bf8bbab8cf691403249fe5b699e25143 */
+ 5.79833984374989593561576568548497165E-04L, /* 3ff42ffffffffffa0047df328d817000 */
+ -1.72745033420153042445343706432627539E-34L, /* bf8ecb3c2d7d3a9e6e960576be901fdf */
+ 6.10351562500008540711511259540838154E-04L, /* 3ff4400000000004ec62f54f8c271000 */
+ 7.41889382604319545724663095428976499E-35L, /* 3f8d8a74c002c81a47c93b8e05d15f8e */
+ 6.40869140625020444702875407535884986E-04L, /* 3ff450000000000bc91b09718515d000 */
+ -4.47321009727305792048065440180490107E-35L, /* bf8cdbac5c8fe70822081d8993eb5cb6 */
+ 6.71386718750007531635964622352684074E-04L, /* 3ff460000000000457792973db05c000 */
+ 5.13698959677949336513874456684462092E-35L, /* 3f8d112114436949c5ef38d8049004ab */
+ 7.01904296875006634673332887754430334E-04L, /* 3ff4700000000003d31adf2cb8b1d000 */
+ -8.25665755717729437292989870760751482E-35L, /* bf8db6ffcc8ef71f8e648e3a8b160f5a */
+ 7.32421874999998244664170215504673504E-04L, /* 3ff47ffffffffffefcf5498bd5c8a000 */
+ -5.64005234937832153139057628112753364E-35L, /* bf8d2be06a1dfe90e7bf90fba7c12a98 */
+ 7.62939453125017456345986752604096408E-04L, /* 3ff490000000000a101a1b093d4a8000 */
+ -1.11084094120417622468550608896588329E-34L, /* bf8e274feabd2d94f6694507a46accb1 */
+ 7.93457031249987558617598988993908016E-04L, /* 3ff49ffffffffff8d3f9dcab74bbf000 */
+ -1.22966480225449015129079129940978828E-34L, /* bf8e46e6a65eef8fa9e42eddf3da305e */
+ 8.23974609374997378723747633335135819E-04L, /* 3ff4affffffffffe7d2afbaa55b26000 */
+ -1.62270010016794279091906973366704963E-34L, /* bf8eaf633f057ebdb664a34566401c4e */
+ 8.54492187500023938282350821569920958E-04L, /* 3ff4c0000000000dccaabce399e59000 */
+ -1.39076361712838158775374263169606160E-34L, /* bf8e71ba779364b3bbdba7841f2c4ca1 */
+ 8.85009765624987932362186815286691297E-04L, /* 3ff4cffffffffff90b218886edc2a000 */
+ 4.07328275060905585228261577392403980E-35L, /* 3f8cb1254dbb6ea4b8cfa5ed4cf28d24 */
+ 9.15527343749975579461305518559161974E-04L, /* 3ff4dffffffffff1ec2a21f25df33000 */
+ 1.16855112459192484947855553716334015E-35L, /* 3f8af10bf319e9f5270cf249eeffbe5c */
+ 9.46044921875016761584725882821122521E-04L, /* 3ff4f00000000009a992c46c16d71000 */
+ 9.51660680007524262741115611071680436E-35L, /* 3f8df9fd56e81f8edf133843910ee831 */
+ 9.76562499999974118878133088548272636E-04L, /* 3ff4fffffffffff1149edc46a6df6000 */
+ -5.65271128977550656964071208289181661E-36L, /* bf89e0e12689dd721aa2314c81eb6429 */
+ 1.00708007812498671732140389760347830E-03L, /* 3ff507fffffffffc2be94b90ed091000 */
+ -1.43355074891483635310132767255371379E-34L, /* bf8e7d1a688c247b16022daab1316d55 */
+ 1.03759765625002637786192745235343007E-03L, /* 3ff51000000000079a57b966bc158000 */
+ 2.95905815240957629366749917020106928E-34L, /* 3f8f895387fc73bb38f8a1b254c01a60 */
+ 1.06811523437500860568717813047520763E-03L, /* 3ff51800000000027afcd5b35f5e6000 */
+ -5.98328495358586628195372356742878314E-35L, /* bf8d3e204130013bf6328f1b70ff8c76 */
+ 1.09863281250001439958487251556220070E-03L, /* 3ff5200000000004268077c6c66bd000 */
+ 2.41371837889426603334113000868144760E-34L, /* 3f8f40d6948edf864054ccf151f9815e */
+ 1.12915039062501298413451613770002366E-03L, /* 3ff5280000000003be0f5dd8fe81b000 */
+ -1.28815268997394164973472617519705703E-34L, /* bf8e567321172ea089dce4bc8354ecb7 */
+ 1.15966796874997272036339054191407232E-03L, /* 3ff52ffffffffff8231e3bcfff1e8000 */
+ 1.02996064554316248496839462594377804E-34L, /* 3f8e11cf7d402789244f68e2d4f985b1 */
+ 1.19018554687502744121802585360546796E-03L, /* 3ff5380000000007e8cdf3f8f6c20000 */
+ -1.43453217726255628994625761307322163E-34L, /* bf8e7d5d3370d85a374f5f4802fc517a */
+ 1.22070312499997743541996266398850614E-03L, /* 3ff53ffffffffff97f0722561f454000 */
+ -1.41086259180534339713692694428211646E-34L, /* bf8e77125519ff76244dfec5fbd58402 */
+ 1.25122070312501024092560690174507039E-03L, /* 3ff5480000000002f3a59d8820691000 */
+ 3.84102646020099293168698506729765213E-34L, /* 3f8ffe8f5b86f9c3569c8f26e19b1f50 */
+ 1.28173828124997986521442660131425390E-03L, /* 3ff54ffffffffffa3250a764439d9000 */
+ 1.44644589735033114377952806106652650E-34L, /* 3f8e808801b80dcf38323cdbfdca2549 */
+ 1.31225585937501665804856968749058137E-03L, /* 3ff5580000000004cd25a414c6d62000 */
+ 1.67474574742200577294563576414361377E-34L, /* 3f8ebd394a151dbda4f81d5d83c0f1e9 */
+ 1.34277343749997290265837386401818888E-03L, /* 3ff55ffffffffff83091b042cfd59000 */
+ -1.55650565030381326742591837551559103E-34L, /* bf8e9dca490d7fecfadba9625ffb91c5 */
+ 1.37329101562497720784949380297774268E-03L, /* 3ff567fffffffff96e3c7312f5ccf000 */
+ 1.65279335325630026116581677369221748E-34L, /* 3f8eb763496f5bd7404f2298b402074f */
+ 1.40380859374999099958354100336136647E-03L, /* 3ff56ffffffffffd67e2f09f2a381000 */
+ 1.89919944388961890195706641264717076E-34L, /* 3f8ef8e4d0ffdfeba982aa8829501389 */
+ 1.43432617187497484122173130998160625E-03L, /* 3ff577fffffffff8bf9c1d71af8a8000 */
+ 2.57638517142061429772064578590009568E-34L, /* 3f8f5675d82c1cc4ada70fd3a957b89a */
+ 1.46484374999999929342158925502052945E-03L, /* 3ff57fffffffffffcbdd1c7671b46000 */
+ 1.76487201934184070490166772482073801E-34L, /* 3f8ed52ef732458f6e4c5c07504f33cc */
+ 1.49536132812502318451070466256902933E-03L, /* 3ff5880000000006aeb7066c8ad43000 */
+ 2.38068367275295804321313550609246656E-34L, /* 3f8f3c7277ae6fc390ace5e06c0b025b */
+ 1.52587890625000448053340248672949543E-03L, /* 3ff59000000000014a9ae2104b3bc000 */
+ 1.01174455568392813258454590274740959E-34L, /* 3f8e0cf7c434762991bb38e12acee215 */
+ 1.55639648437501113499837053523090913E-03L, /* 3ff5980000000003359e2c204355e000 */
+ -2.82398418808099749023517211651363693E-35L, /* bf8c2c4c2971d88caa95e15fb1ccb1a1 */
+ 1.58691406249999937955142588308171026E-03L, /* 3ff59fffffffffffd2380ecbc87c2000 */
+ -1.27361695572422741562701199136538047E-34L, /* bf8e5295e0e206dfb0f0266c07225448 */
+ 1.61743164062498000531048954475329309E-03L, /* 3ff5a7fffffffffa3ca6fe61ed94c000 */
+ -1.22606548862580061633942923016222044E-34L, /* bf8e45f1b17bb61039d21a351bb207b8 */
+ 1.64794921875001835451453858682255576E-03L, /* 3ff5b000000000054a52fa20f6565000 */
+ 1.39132339594152335892305491425264583E-34L, /* 3f8e71e0904c5449b414ee49b191cef2 */
+ 1.67846679687501263995029340691547953E-03L, /* 3ff5b80000000003a4a9e912c910b000 */
+ 6.67245854693585315412242764786197029E-35L, /* 3f8d62c4ccac1e7511a617d469468ccd */
+ 1.70898437500002646861403514115369655E-03L, /* 3ff5c00000000007a109fbaa7e015000 */
+ 6.87367172354719289559624829652240928E-36L, /* 3f8a245fa835eceb42bae8128d9336db */
+ 1.73950195312501174308226096992992128E-03L, /* 3ff5c80000000003627c8d637a005000 */
+ -2.20824271875474985927385878948759352E-34L, /* bf8f25869b1cbefb25e735992f232f57 */
+ 1.77001953124997491747605207736194513E-03L, /* 3ff5cffffffffff8c53c84b6883b8000 */
+ 3.43123048533596296514343180408963705E-34L, /* 3f8fc816b91d173ddadbbf09b1287906 */
+ 1.80053710937497698911127570705069398E-03L, /* 3ff5d7fffffffff95e1899f4a8430000 */
+ 3.99231237340890073475077494556136100E-35L, /* 3f8ca889148f62fa854da5674df41279 */
+ 1.83105468750002267094899598630423914E-03L, /* 3ff5e0000000000688d21e62ba674000 */
+ -3.22274595655810623999007524769365273E-34L, /* bf8fac605cb9ae01eb719675ced25560 */
+ 1.86157226562500499224728040579690330E-03L, /* 3ff5e80000000001705ce28a6d89e000 */
+ 3.07094985075881613489605622068441083E-34L, /* 3f8f98330225ec7e2c8f3c0d1c432b91 */
+ 1.89208984374998234666824993196980949E-03L, /* 3ff5effffffffffae969fdc7cd8cf000 */
+ -3.06287628722973914692165056776495733E-34L, /* bf8f9720477d9cfa10e464df7f91020c */
+ 1.92260742187501225343755557292811682E-03L, /* 3ff5f800000000038824e428ed49a000 */
+ 6.30049124729794620592961282769623368E-35L, /* 3f8d4efdd7cd4336d88a6aa49e1e96bc */
+ 1.95312499999998514894032051116231258E-03L, /* 3ff5fffffffffffbb82f6a04f1ae0000 */
+ -6.14610057507500948543216998736262902E-35L, /* bf8d46c862d39255370e7974d48daa7e */
+ 1.98364257812501222021119324146882732E-03L, /* 3ff6040000000001c2d8a1aa5188d000 */
+ 3.71942298418113774118754986159801984E-34L, /* 3f8fee6567d9940495519ffe62cbc9a4 */
+
+ 7.06341639425619532977052017486130353E-01L, /* 3ffe69a59c8245a9ac00000000000000 */
+ 7.09106182437398424589503065362805501E-01L, /* 3ffe6b0ff72deb89d000000000000000 */
+ 7.11881545564596485142772053222870454E-01L, /* 3ffe6c7bbce9a6d93000000000000000 */
+ 7.14667771155948150507697391731198877E-01L, /* 3ffe6de8ef213d71e000000000000000 */
+ 7.17464901725936049503573599395167548E-01L, /* 3ffe6f578f41e1a9e400000000000000 */
+ 7.20272979955439790478166628417966422E-01L, /* 3ffe70c79eba33c06c00000000000000 */
+ 7.23092048692387218133958981525211129E-01L, /* 3ffe72391efa434c7400000000000000 */
+ 7.25922150952408251622927082280511968E-01L, /* 3ffe73ac117390acd800000000000000 */
+ 7.28763329919491220643124052003258839E-01L, /* 3ffe752077990e79d000000000000000 */
+ 7.31615628946641782803794740175362676E-01L, /* 3ffe769652df22f7e000000000000000 */
+ 7.34479091556544505525749855223693885E-01L, /* 3ffe780da4bba98c4800000000000000 */
+ 7.37353761442226890432394270646909717E-01L, /* 3ffe79866ea5f432d400000000000000 */
+ 7.40239682467726090031590047146892175E-01L, /* 3ffe7b00b216ccf53000000000000000 */
+ 7.43136898668758316688354170764796436E-01L, /* 3ffe7c7c70887763c000000000000000 */
+ 7.46045454253390638577059235103661194E-01L, /* 3ffe7df9ab76b20fd000000000000000 */
+ 7.48965393602715662213498148958024103E-01L, /* 3ffe7f78645eb8076400000000000000 */
+ 7.51896761271528629722027403659012634E-01L, /* 3ffe80f89cbf42526400000000000000 */
+ 7.54839601989007347171423134568613023E-01L, /* 3ffe827a561889716000000000000000 */
+ 7.57793960659394638668118204805068672E-01L, /* 3ffe83fd91ec46ddc000000000000000 */
+ 7.60759882362683631518152083117456641E-01L, /* 3ffe858251bdb68b8c00000000000000 */
+ 7.63737412355305483879774897104653064E-01L, /* 3ffe87089711986c9400000000000000 */
+ 7.66726596070820082262642358728044201E-01L, /* 3ffe8890636e31f54400000000000000 */
+ 7.69727479120609181517664865168626420E-01L, /* 3ffe8a19b85b4fa2d800000000000000 */
+ 7.72740107294572486917871856348938309E-01L, /* 3ffe8ba4976246833800000000000000 */
+ 7.75764526561826289752232810315035749E-01L, /* 3ffe8d31020df5be4400000000000000 */
+ 7.78800783071404878477039801509818062E-01L, /* 3ffe8ebef9eac820b000000000000000 */
+ 7.81848923152964780936002853195532225E-01L, /* 3ffe904e8086b5a87800000000000000 */
+ 7.84908993317491698871180005880887620E-01L, /* 3ffe91df97714512d800000000000000 */
+ 7.87981040258010162480317717381694820E-01L, /* 3ffe9372403b8d6bcc00000000000000 */
+ 7.91065110850296016042904057030682452E-01L, /* 3ffe95067c78379f2800000000000000 */
+ 7.94161252153591734614934694036492147E-01L, /* 3ffe969c4dbb800b4800000000000000 */
+ 7.97269511411324433014513601847284008E-01L, /* 3ffe9833b59b38154400000000000000 */
+ 8.00389936051826789142893403550260700E-01L, /* 3ffe99ccb5aec7bec800000000000000 */
+ 8.03522573689060742863077280162542593E-01L, /* 3ffe9b674f8f2f3d7c00000000000000 */
+ 8.06667472123343942680406826184480451E-01L, /* 3ffe9d0384d70893f800000000000000 */
+ 8.09824679342079301047618855591281317E-01L, /* 3ffe9ea15722892c7800000000000000 */
+ 8.12994243520486992160556383169023320E-01L, /* 3ffea040c80f8374f000000000000000 */
+ 8.16176213022339780422953481320291758E-01L, /* 3ffea1e1d93d687d0000000000000000 */
+ 8.19370636400700819157449927843117621E-01L, /* 3ffea3848c4d49954c00000000000000 */
+ 8.22577562398664585696650419777142815E-01L, /* 3ffea528e2e1d9f09800000000000000 */
+ 8.25797039950100647542896581398963463E-01L, /* 3ffea6cede9f70467c00000000000000 */
+ 8.29029118180400342863478613253391813E-01L, /* 3ffea876812c0877bc00000000000000 */
+ 8.32273846407226292054559735333896242E-01L, /* 3ffeaa1fcc2f45343800000000000000 */
+ 8.35531274141265073440720811959181447E-01L, /* 3ffeabcac15271a2a400000000000000 */
+ 8.38801451086982535754188461396552157E-01L, /* 3ffead7762408309bc00000000000000 */
+ 8.42084427143382358016410194068157580E-01L, /* 3ffeaf25b0a61a7b4c00000000000000 */
+ 8.45380252404767357221615498019673396E-01L, /* 3ffeb0d5ae318680c400000000000000 */
+ 8.48688977161503960155997106085123960E-01L, /* 3ffeb2875c92c4c99400000000000000 */
+ 8.52010651900789478530029441571969073E-01L, /* 3ffeb43abd7b83db1c00000000000000 */
+ 8.55345327307422548246407245642330963E-01L, /* 3ffeb5efd29f24c26400000000000000 */
+ 8.58693054264576483003423845730139874E-01L, /* 3ffeb7a69db2bcc77800000000000000 */
+ 8.62053883854575708767242758767679334E-01L, /* 3ffeb95f206d17228000000000000000 */
+ 8.65427867359675251357487013592617586E-01L, /* 3ffebb195c86b6b29000000000000000 */
+ 8.68815056262843166123843730019871145E-01L, /* 3ffebcd553b9d7b62000000000000000 */
+ 8.72215502248546159513864495238522068E-01L, /* 3ffebe9307c271855000000000000000 */
+ 8.75629257203538208242932228131394368E-01L, /* 3ffec0527a5e384ddc00000000000000 */
+ 8.79056373217652342599848225290770642E-01L, /* 3ffec213ad4c9ed0d800000000000000 */
+ 8.82496902584595399599010079327854328E-01L, /* 3ffec3d6a24ed8221800000000000000 */
+ 8.85950897802745995779361010136199184E-01L, /* 3ffec59b5b27d9696800000000000000 */
+ 8.89418411575955636383383762222365476E-01L, /* 3ffec761d99c5ba58800000000000000 */
+ 8.92899496814352794382685374330321793E-01L, /* 3ffec92a1f72dd70d400000000000000 */
+ 8.96394206635150403439382671422208659E-01L, /* 3ffecaf42e73a4c7d800000000000000 */
+ 8.99902594363456265202927397695020773E-01L, /* 3ffeccc00868c0d18800000000000000 */
+ 9.03424713533086704009278378180169966E-01L, /* 3ffece8daf1e0ba94c00000000000000 */
+ 9.06960617887383580004723171441582963E-01L, /* 3ffed05d24612c2af000000000000000 */
+ 9.10510361380034133338412516422977205E-01L, /* 3ffed22e6a0197c02c00000000000000 */
+ 9.14073998175894436579724811053893063E-01L, /* 3ffed40181d094303400000000000000 */
+ 9.17651582651815816982221463149471674E-01L, /* 3ffed5d66da13970f400000000000000 */
+ 9.21243169397474526149949269893113524E-01L, /* 3ffed7ad2f48737a2000000000000000 */
+ 9.24848813216204823639543519675498828E-01L, /* 3ffed985c89d041a3000000000000000 */
+ 9.28468569125835141431224428743007593E-01L, /* 3ffedb603b7784cd1800000000000000 */
+ 9.32102492359527579068867453315760940E-01L, /* 3ffedd3c89b26894e000000000000000 */
+ 9.35750638366620729469147477175283711E-01L, /* 3ffedf1ab529fdd41c00000000000000 */
+ 9.39413062813475779888605643463961314E-01L, /* 3ffee0fabfbc702a3c00000000000000 */
+ 9.43089821584325888048638830696290825E-01L, /* 3ffee2dcab49ca51b400000000000000 */
+ 9.46780970782128888929563004239753354E-01L, /* 3ffee4c079b3f8000400000000000000 */
+ 9.50486566729423443256052905780961737E-01L, /* 3ffee6a62cdec7c7b000000000000000 */
+ 9.54206665969188322362626308859034907E-01L, /* 3ffee88dc6afecfbfc00000000000000 */
+ 9.57941325265705301283958306157728657E-01L, /* 3ffeea77490f0196b000000000000000 */
+ 9.61690601605425299247542625380447134E-01L, /* 3ffeec62b5e5881fb000000000000000 */
+ 9.65454552197837823079851204965962097E-01L, /* 3ffeee500f1eed967000000000000000 */
+ 9.69233234476344074348475032820715569E-01L, /* 3ffef03f56a88b5d7800000000000000 */
+ 9.73026706099133165128733935489435680E-01L, /* 3ffef2308e71a927a800000000000000 */
+ 9.76835024950062025261843245971249416E-01L, /* 3ffef423b86b7ee79000000000000000 */
+ 9.80658249139538557015427500118676107E-01L, /* 3ffef618d68936c09c00000000000000 */
+ 9.84496437005408397968864164795377292E-01L, /* 3ffef80feabfeefa4800000000000000 */
+ 9.88349647113845042323276857132441364E-01L, /* 3ffefa08f706bbf53800000000000000 */
+ 9.92217938260243514925207364285597578E-01L, /* 3ffefc03fd56aa225000000000000000 */
+ 9.96101369470117486981664001177705359E-01L, /* 3ffefe00ffaabffbbc00000000000000 */
+#define T_EXPL_RES1 (T_EXPL_ARG2 + 2 + 2*65 + 89)
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+ 1.00391388933834757590801700644078664E+00L, /* 3fff0100802ab5577800000000000000 */
+ 1.00784309720644799091004983893071767E+00L, /* 3fff0202015600445c00000000000000 */
+ 1.01178768355933151879000320150225889E+00L, /* 3fff0304848362076c00000000000000 */
+ 1.01574770858668572692806719715008512E+00L, /* 3fff04080ab55de39000000000000000 */
+ 1.01972323271377413034244341361045372E+00L, /* 3fff050c94ef7a206c00000000000000 */
+ 1.02371431660235789884438872832106426E+00L, /* 3fff06122436410dd000000000000000 */
+ 1.02772102115162167201845022646011785E+00L, /* 3fff0718b98f42085000000000000000 */
+ 1.03174340749910264936062276319717057E+00L, /* 3fff08205601127ec800000000000000 */
+ 1.03578153702162378824169763902318664E+00L, /* 3fff0928fa934ef90800000000000000 */
+ 1.03983547133622999947277776300325058E+00L, /* 3fff0a32a84e9c1f5800000000000000 */
+ 1.04390527230112850620713516036630608E+00L, /* 3fff0b3d603ca7c32800000000000000 */
+ 1.04799100201663270004459604933799710E+00L, /* 3fff0c49236829e8bc00000000000000 */
+ 1.05209272282610977189420964350574650E+00L, /* 3fff0d55f2dce5d1e800000000000000 */
+ 1.05621049731693195106174698594259098E+00L, /* 3fff0e63cfa7ab09d000000000000000 */
+ 1.06034438832143151909548350886325352E+00L, /* 3fff0f72bad65671b800000000000000 */
+ 1.06449445891785943185681162503897212E+00L, /* 3fff1082b577d34ed800000000000000 */
+ 1.06866077243134810492719566354935523E+00L, /* 3fff1193c09c1c595c00000000000000 */
+ 1.07284339243487741866189821848820429E+00L, /* 3fff12a5dd543ccc4c00000000000000 */
+ 1.07704238275024494209120007326419000E+00L, /* 3fff13b90cb25176a400000000000000 */
+ 1.08125780744903959851299646288680378E+00L, /* 3fff14cd4fc989cd6400000000000000 */
+ 1.08548973085361949442173568058933597E+00L, /* 3fff15e2a7ae28fecc00000000000000 */
+ 1.08973821753809324563988525369495619E+00L, /* 3fff16f9157587069400000000000000 */
+ 1.09400333232930546678574046381982043E+00L, /* 3fff18109a3611c35000000000000000 */
+ 1.09828514030782586896606289883493446E+00L, /* 3fff192937074e0cd800000000000000 */
+ 1.10258370680894224324930519287590869E+00L, /* 3fff1a42ed01d8cbc800000000000000 */
+ 1.10689909742365749645287564817408565E+00L, /* 3fff1b5dbd3f68122400000000000000 */
+ 1.11123137799969046168868658241990488E+00L, /* 3fff1c79a8dacc350c00000000000000 */
+ 1.11558061464248076122274255794764031E+00L, /* 3fff1d96b0eff0e79400000000000000 */
+ 1.11994687371619722204840741142106708E+00L, /* 3fff1eb4d69bde569c00000000000000 */
+ 1.12433022184475073235176978414529003E+00L, /* 3fff1fd41afcba45e800000000000000 */
+ 1.12873072591281087273529237791080959E+00L, /* 3fff20f47f31c92e4800000000000000 */
+ 1.13314845306682632219974493636982515E+00L, /* 3fff2216045b6f5cd000000000000000 */
+ 1.13758347071604959399593326452304609E+00L, /* 3fff2338ab9b32134800000000000000 */
+ 1.14203584653356560174586320499656722E+00L, /* 3fff245c7613b8a9b000000000000000 */
+ 1.14650564845732405583333957110880874E+00L, /* 3fff258164e8cdb0d800000000000000 */
+ 1.15099294469117646722011727433709893E+00L, /* 3fff26a7793f60164400000000000000 */
+ 1.15549780370591653744227755851170514E+00L, /* 3fff27ceb43d84490400000000000000 */
+ 1.16002029424032515603215642840950750E+00L, /* 3fff28f7170a755fd800000000000000 */
+ 1.16456048530221917269855680387991015E+00L, /* 3fff2a20a2ce96406400000000000000 */
+ 1.16911844616950438835445424956560601E+00L, /* 3fff2b4b58b372c79400000000000000 */
+ 1.17369424639123270948104504896036815E+00L, /* 3fff2c7739e3c0f32c00000000000000 */
+ 1.17828795578866324378353169777255971E+00L, /* 3fff2da4478b620c7400000000000000 */
+ 1.18289964445632783673900689791480545E+00L, /* 3fff2ed282d763d42400000000000000 */
+ 1.18752938276310060494722620205720887E+00L, /* 3fff3001ecf601af7000000000000000 */
+ 1.19217724135327157730657177125976887E+00L, /* 3fff31328716a5d63c00000000000000 */
+ 1.19684329114762477708211463323095813E+00L, /* 3fff32645269ea829000000000000000 */
+ 1.20152760334452030077656559114984702E+00L, /* 3fff339750219b212c00000000000000 */
+ 1.20623024942098072687102217059873510E+00L, /* 3fff34cb8170b5835400000000000000 */
+ 1.21095130113378179892436037334846333E+00L, /* 3fff3600e78b6b11d000000000000000 */
+ 1.21569083052054743854242246925423387E+00L, /* 3fff373783a722012400000000000000 */
+ 1.22044890990084875515009343871497549E+00L, /* 3fff386f56fa7686e800000000000000 */
+ 1.22522561187730755216662714701669756E+00L, /* 3fff39a862bd3c106400000000000000 */
+ 1.23002100933670455162882717559114099E+00L, /* 3fff3ae2a8287e7a8000000000000000 */
+ 1.23483517545109100499445276000187732E+00L, /* 3fff3c1e2876834aa800000000000000 */
+ 1.23966818367890557750499169742397498E+00L, /* 3fff3d5ae4e2cae92c00000000000000 */
+ 1.24452010776609517384017067342938390E+00L, /* 3fff3e98deaa11dcbc00000000000000 */
+ 1.24939102174724003813111039562500082E+00L, /* 3fff3fd8170a52071800000000000000 */
+ 1.25428099994668373895478907797951251E+00L, /* 3fff41188f42c3e32000000000000000 */
+ 1.25919011697966698459794088194030337E+00L, /* 3fff425a4893dfc3f800000000000000 */
+ 1.26411844775346637881341393949696794E+00L, /* 3fff439d443f5f159000000000000000 */
+ 1.26906606746853711786826579555054195E+00L, /* 3fff44e183883d9e4800000000000000 */
+ 1.27403305161966090564007458851847332E+00L, /* 3fff462707b2bac20c00000000000000 */
+ 1.27901947599709753244923149395617656E+00L, /* 3fff476dd2045ac67800000000000000 */
+ 1.28402541668774150540599521264084615E+00L, /* 3fff48b5e3c3e8186800000000000000 */
+ 1.28905095007628295311619126550795045E+00L, /* 3fff49ff3e397492bc00000000000000 */
+ 1.29409615284637330434591717676084954E+00L, /* 3fff4b49e2ae5ac67400000000000000 */
+ 1.29916110198179535206719492634874769E+00L, /* 3fff4c95d26d3f440800000000000000 */
+ 1.30424587476763775839572190307080746E+00L, /* 3fff4de30ec211e60000000000000000 */
+ 1.30935054879147461104338390214252286E+00L, /* 3fff4f3198fa0f1cf800000000000000 */
+ 1.31447520194454914310711046709911898E+00L, /* 3fff50817263c13cd000000000000000 */
+ 1.31961991242296217130558488861424848E+00L, /* 3fff51d29c4f01cb3000000000000000 */
+ 1.32478475872886558573071624778094701E+00L, /* 3fff5325180cfacf7800000000000000 */
+ 1.32996981967165983640200010995613411E+00L, /* 3fff5478e6f02823d000000000000000 */
+ 1.33517517436919680440254865061433520E+00L, /* 3fff55ce0a4c58c7bc00000000000000 */
+ 1.34040090224898678084031189428060316E+00L, /* 3fff57248376b033d800000000000000 */
+ 1.34564708304941055283521222918352578E+00L, /* 3fff587c53c5a7af0400000000000000 */
+ 1.35091379682093615244298234756570309E+00L, /* 3fff59d57c910fa4e000000000000000 */
+ 1.35620112392734021300455538039386738E+00L, /* 3fff5b2fff3210fd9400000000000000 */
+ 1.36150914504693443252136830778908916E+00L, /* 3fff5c8bdd032e770800000000000000 */
+ 1.36683794117379636690046140756749082E+00L, /* 3fff5de9176045ff5400000000000000 */
+ 1.37218759361900544124779344201670028E+00L, /* 3fff5f47afa69210a800000000000000 */
+ 1.37755818401188367960941150158760138E+00L, /* 3fff60a7a734ab0e8800000000000000 */
+ 1.38294979430124120867162673675920814E+00L, /* 3fff6208ff6a88a46000000000000000 */
+ 1.38836250675662681297595213436579797E+00L, /* 3fff636bb9a983258400000000000000 */
+ 1.39379640396958309755959248832368758E+00L, /* 3fff64cfd75454ee7c00000000000000 */
+ 1.39925156885490681313299887733592186E+00L, /* 3fff663559cf1bc7c400000000000000 */
+ 1.40472808465191417726103395580139477E+00L, /* 3fff679c427f5a49f400000000000000 */
+ 1.41022603492571069194738697660795879E+00L, /* 3fff690492cbf9432c00000000000000 */
+ 1.41574550356846662335641440222389065E+00L, /* 3fff6a6e4c1d491e1800000000000000 */
+
+ 9.98018323540573404351050612604012713E-01L, /* 3ffefefc41f8d4bdb000000000000000 */
+ 9.98048781107475468932221929208026268E-01L, /* 3ffeff003ff556aa8800000000000000 */
+ 9.98079239603882895082165305211674422E-01L, /* 3ffeff043df9d4986000000000000000 */
+ 9.98109699029824021243584297735651489E-01L, /* 3ffeff083c064e972c00000000000000 */
+ 9.98140159385327269125909310787392315E-01L, /* 3ffeff0c3a1ac4b6ec00000000000000 */
+ 9.98170620670420977171843901487591211E-01L, /* 3ffeff10383737079400000000000000 */
+ 9.98201082885133511579667242585856002E-01L, /* 3ffeff14365ba5991c00000000000000 */
+ 9.98231546029493238547658506831794512E-01L, /* 3ffeff183488107b7c00000000000000 */
+ 9.98262010103528552029672482603928074E-01L, /* 3ffeff1c32bc77beb000000000000000 */
+ 9.98292475107267818223988342651864514E-01L, /* 3ffeff2030f8db72b000000000000000 */
+ 9.98322941040739375573309644096298143E-01L, /* 3ffeff242f3d3ba77000000000000000 */
+ 9.98353407903971645787066790944663808E-01L, /* 3ffeff282d89986cf000000000000000 */
+ 9.98383875696992967307963340317655820E-01L, /* 3ffeff2c2bddf1d32400000000000000 */
+ 9.98414344419831761845429696222709026E-01L, /* 3ffeff302a3a47ea0c00000000000000 */
+ 9.98444814072516340086593800151604228E-01L, /* 3ffeff34289e9ac19800000000000000 */
+ 9.98475284655075123740886056111776270E-01L, /* 3ffeff38270aea69c800000000000000 */
+ 9.98505756167536479006585636852832977E-01L, /* 3ffeff3c257f36f29400000000000000 */
+ 9.98536228609928799837547330753295682E-01L, /* 3ffeff4023fb806bf800000000000000 */
+ 9.98566701982280452432050310562772211E-01L, /* 3ffeff44227fc6e5ec00000000000000 */
+ 9.98597176284619802988373749030870385E-01L, /* 3ffeff48210c0a706800000000000000 */
+ 9.98627651516975245460372434536111541E-01L, /* 3ffeff4c1fa04b1b6800000000000000 */
+ 9.98658127679375173801901155457017012E-01L, /* 3ffeff501e3c88f6e800000000000000 */
+ 9.98688604771847954211239084543194622E-01L, /* 3ffeff541ce0c412e000000000000000 */
+ 9.98719082794421980642241010173165705E-01L, /* 3ffeff581b8cfc7f4c00000000000000 */
+ 9.98749561747125619293186105096538085E-01L, /* 3ffeff5c1a41324c2400000000000000 */
+ 9.98780041629987291873504773320746608E-01L, /* 3ffeff6018fd65896800000000000000 */
+ 9.98810522443035364581476187595399097E-01L, /* 3ffeff6417c196471000000000000000 */
+ 9.98841004186298203615379520670103375E-01L, /* 3ffeff68168dc4951400000000000000 */
+ 9.98871486859804230684645176552294288E-01L, /* 3ffeff6c1561f0837400000000000000 */
+ 9.98901970463581839743127943620493170E-01L, /* 3ffeff70143e1a222c00000000000000 */
+ 9.98932454997659369233531378995394334E-01L, /* 3ffeff74132241813000000000000000 */
+ 9.98962940462065268620861502313346136E-01L, /* 3ffeff78120e66b08400000000000000 */
+ 9.98993426856827904103397486323956400E-01L, /* 3ffeff7c110289c02000000000000000 */
+ 9.99023914181975669634994119405746460E-01L, /* 3ffeff800ffeaac00000000000000000 */
+ 9.99054402437536959169506189937237650E-01L, /* 3ffeff840f02c9c02000000000000000 */
+ 9.99084891623540138905212870668037795E-01L, /* 3ffeff880e0ee6d07800000000000000 */
+ 9.99115381740013658307120181234495249E-01L, /* 3ffeff8c0d2302010c00000000000000 */
+ 9.99145872786985911329082910015131347E-01L, /* 3ffeff900c3f1b61d800000000000000 */
+ 9.99176364764485236413804614130640402E-01L, /* 3ffeff940b633302d000000000000000 */
+ 9.99206857672540083026291313217370771E-01L, /* 3ffeff980a8f48f3f800000000000000 */
+ 9.99237351511178817364822180024930276E-01L, /* 3ffeff9c09c35d454800000000000000 */
+ 9.99267846280429861138827618560753763E-01L, /* 3ffeffa008ff7006c000000000000000 */
+ 9.99298341980321608302162417203362565E-01L, /* 3ffeffa4084381485c00000000000000 */
+ 9.99328838610882452808681364331278019E-01L, /* 3ffeffa8078f911a1800000000000000 */
+ 9.99359336172140816367814863951934967E-01L, /* 3ffeffac06e39f8bf400000000000000 */
+ 9.99389834664125092933417704443854745E-01L, /* 3ffeffb0063facadec00000000000000 */
+ 9.99420334086863676459344674185558688E-01L, /* 3ffeffb405a3b88ffc00000000000000 */
+ 9.99450834440384988655026177184481639E-01L, /* 3ffeffb8050fc3422400000000000000 */
+ 9.99481335724717395718741386190231424E-01L, /* 3ffeffbc0483ccd45c00000000000000 */
+ 9.99511837939889374871071936468069907E-01L, /* 3ffeffc003ffd556ac00000000000000 */
+ 9.99542341085929264554721385138691403E-01L, /* 3ffeffc40383dcd90800000000000000 */
+ 9.99572845162865514234695751838444266E-01L, /* 3ffeffc8030fe36b7400000000000000 */
+ 9.99603350170726517864849824945849832E-01L, /* 3ffeffcc02a3e91dec00000000000000 */
+ 9.99633856109540669399038392839429434E-01L, /* 3ffeffd0023fee006c00000000000000 */
+ 9.99664362979336418302267475155531429E-01L, /* 3ffeffd401e3f222f800000000000000 */
+ 9.99694870780142130772816244643763639E-01L, /* 3ffeffd8018ff5958800000000000000 */
+ 9.99725379511986284031266336569387931E-01L, /* 3ffeffdc0143f8682400000000000000 */
+ 9.99755889174897216520321308053098619E-01L, /* 3ffeffe000fffaaac000000000000000 */
+ 9.99786399768903377704987178731244057E-01L, /* 3ffeffe400c3fc6d6000000000000000 */
+ 9.99816911294033217050269968240172602E-01L, /* 3ffeffe8008ffdc00800000000000000 */
+ 9.99847423750315072998873233700578567E-01L, /* 3ffeffec0063feb2ac00000000000000 */
+ 9.99877937137777450526954226006637327E-01L, /* 3ffefff0003fff555800000000000000 */
+ 9.99908451456448688077216502279043198E-01L, /* 3ffefff40023ffb80000000000000000 */
+ 9.99938966706357262870241697783058044E-01L, /* 3ffefff8000fffeaac00000000000000 */
+ 9.99969482887531541104308985268289689E-01L, /* 3ffefffc0003fffd5400000000000000 */
+#define T_EXPL_RES2 (T_EXPL_RES1 + 1 + 89 + 65)
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+ 1.00003051804379100575559391472779680E+00L, /* 3fff0002000200015400000000000000 */
+ 1.00006103701893306334724798034585547E+00L, /* 3fff00040008000aac00000000000000 */
+ 1.00009155692545448346209013834595680E+00L, /* 3fff0006001200240000000000000000 */
+ 1.00012207776338379883185325525118969E+00L, /* 3fff0008002000555800000000000000 */
+ 1.00015259953274932014366527255333494E+00L, /* 3fff000a003200a6ac00000000000000 */
+ 1.00018312223357958012925905677548144E+00L, /* 3fff000c004801200400000000000000 */
+ 1.00021364586590294498691378066723701E+00L, /* 3fff000e006201c95c00000000000000 */
+ 1.00024417042974783642605984823603649E+00L, /* 3fff0010008002aab400000000000000 */
+ 1.00027469592514273166727889474714175E+00L, /* 3fff001200a203cc1000000000000000 */
+ 1.00030522235211605242000132420798764E+00L, /* 3fff001400c805357000000000000000 */
+ 1.00033574971069616488250630936818197E+00L, /* 3fff001600f206eed000000000000000 */
+ 1.00036627800091160178652671675081365E+00L, /* 3fff0018012009003800000000000000 */
+ 1.00039680722279067381919048784766346E+00L, /* 3fff001a01520b71a000000000000000 */
+ 1.00042733737636191371223048918182030E+00L, /* 3fff001c01880e4b1000000000000000 */
+ 1.00045786846165368766392589350289200E+00L, /* 3fff001e01c211948400000000000000 */
+ 1.00048840047869447289485833607614040E+00L, /* 3fff0020020015560000000000000000 */
+ 1.00051893342751269111445822090900037E+00L, /* 3fff0022024219978400000000000000 */
+ 1.00054946730813676403215595200890675E+00L, /* 3fff002402881e611000000000000000 */
+ 1.00058000212059516886853316464112140E+00L, /* 3fff002602d223baa800000000000000 */
+ 1.00061053786491632733302026281307917E+00L, /* 3fff0028032029ac4c00000000000000 */
+ 1.00064107454112866113504765053221490E+00L, /* 3fff002a0372303dfc00000000000000 */
+ 1.00067161214926059198404573180596344E+00L, /* 3fff002c03c83777b800000000000000 */
+ 1.00070215068934059710059614189958666E+00L, /* 3fff002e04223f618400000000000000 */
+ 1.00073269016139709819412928482051939E+00L, /* 3fff0030048048036000000000000000 */
+ 1.00076323056545857248522679583402351E+00L, /* 3fff003204e251655000000000000000 */
+ 1.00079377190155338617216784768970683E+00L, /* 3fff003405485b8f5000000000000000 */
+ 1.00082431416971007198668530691065826E+00L, /* 3fff003605b266896800000000000000 */
+ 1.00085485736995705163820957750431262E+00L, /* 3fff00380620725b9800000000000000 */
+ 1.00088540150232269132501983222027775E+00L, /* 3fff003a06927f0ddc00000000000000 */
+ 1.00091594656683552377884893758164253E+00L, /* 3fff003c07088ca83c00000000000000 */
+ 1.00094649256352402622027852885366883E+00L, /* 3fff003e07829b32bc00000000000000 */
+ 1.00097703949241650933643654752813745E+00L, /* 3fff00400800aab55400000000000000 */
+ 1.00100758735354156137020709138596430E+00L, /* 3fff00420882bb381000000000000000 */
+ 1.00103813614692760403102056443458423E+00L, /* 3fff00440908ccc2f000000000000000 */
+ 1.00106868587260300351715613942360505E+00L, /* 3fff00460992df5df000000000000000 */
+ 1.00109923653059629256034668287611566E+00L, /* 3fff00480a20f3111800000000000000 */
+ 1.00112978812093589287002259879955091E+00L, /* 3fff004a0ab307e46800000000000000 */
+ 1.00116034064365022615561429120134562E+00L, /* 3fff004c0b491ddfe000000000000000 */
+ 1.00119089409876788066000585786241572E+00L, /* 3fff004e0be3350b8c00000000000000 */
+ 1.00122144848631711155917400901671499E+00L, /* 3fff00500c814d6f6000000000000000 */
+ 1.00125200380632656260715407370298635E+00L, /* 3fff00520d2367136c00000000000000 */
+ 1.00128256005882454449107399341301061E+00L, /* 3fff00540dc981ffa800000000000000 */
+ 1.00131311724383964545381786592770368E+00L, /* 3fff00560e739e3c2000000000000000 */
+ 1.00134367536140017618251363273884635E+00L, /* 3fff00580f21bbd0cc00000000000000 */
+ 1.00137423441153472492004539162735455E+00L, /* 3fff005a0fd3dac5b800000000000000 */
+ 1.00140479439427171337584354660066310E+00L, /* 3fff005c1089fb22e400000000000000 */
+ 1.00143535530963956325933850166620687E+00L, /* 3fff005e11441cf05000000000000000 */
+ 1.00146591715766680730226312334707472E+00L, /* 3fff0060120240360400000000000000 */
+ 1.00149647993838186721404781565070152E+00L, /* 3fff006212c464fc0000000000000000 */
+ 1.00152704365181316470412298258452211E+00L, /* 3fff0064138a8b4a4400000000000000 */
+ 1.00155760829798923250422149067162536E+00L, /* 3fff00661454b328d800000000000000 */
+ 1.00158817387693849232377374391944613E+00L, /* 3fff00681522dc9fbc00000000000000 */
+ 1.00161874038868942138336137759324629E+00L, /* 3fff006a15f507b6f400000000000000 */
+ 1.00164930783327055241471725821611471E+00L, /* 3fff006c16cb34768800000000000000 */
+ 1.00167987621071025161612055853765924E+00L, /* 3fff006e17a562e67400000000000000 */
+ 1.00171044552103705171930414508096874E+00L, /* 3fff00701883930ec000000000000000 */
+ 1.00174101576427937443369842185347807E+00L, /* 3fff00721965c4f76c00000000000000 */
+ 1.00177158694046569697988502412044909E+00L, /* 3fff00741a4bf8a87c00000000000000 */
+ 1.00180215904962455208959681840497069E+00L, /* 3fff00761b362e29f800000000000000 */
+ 1.00183273209178441698341543997230474E+00L, /* 3fff00781c246583e400000000000000 */
+ 1.00186330606697365785962006157205906E+00L, /* 3fff007a1d169ebe3c00000000000000 */
+ 1.00189388097522080744994354972732253E+00L, /* 3fff007c1e0cd9e10800000000000000 */
+ 1.00192445681655439848611877096118405E+00L, /* 3fff007e1f0716f45000000000000000 */
+ 1.00195503359100279716642489802325144E+00L, /* 3fff0080200556001000000000000000 */
+ 1.00198561129859459173374602869444061E+00L, /* 3fff00822107970c5400000000000000 */
+};
diff --git a/sysdeps/ieee754/ldbl-96/bits/iscanonical.h b/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
index 4a4f4ad024..cfa36a0c2a 100644
--- a/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
+++ b/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
@@ -34,4 +34,21 @@ extern int __iscanonicall (long double __x)
conversion, before being discarded; in extended precision, there
are encodings that are not consistently handled as corresponding to
any particular value of the type, and we return 0 for those. */
-#define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
+#ifndef __cplusplus
+# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
+#else
+/* In C++ mode, __MATH_TG cannot be used, because it relies on
+ __builtin_types_compatible_p, which is a C-only builtin. On the
+ other hand, overloading provides the means to distinguish between
+ the floating-point types. The overloading resolution will match
+ the correct parameter (regardless of type qualifiers (i.e.: const
+ and volatile)). */
+extern "C++" {
+inline int iscanonical (float __val) { return __iscanonicalf (__val); }
+inline int iscanonical (double __val) { return __iscanonical (__val); }
+inline int iscanonical (long double __val) { return __iscanonicall (__val); }
+# if __HAVE_DISTINCT_FLOAT128
+inline int iscanonical (_Float128 __val) { return __iscanonicalf128 (__val); }
+# endif
+}
+#endif /* __cplusplus */
diff --git a/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h b/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
index 845b9e6c2b..966cc7569f 100644
--- a/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
@@ -35,6 +35,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 1
+#define __PTHREAD_MUTEX_USE_UNION 1
#define __LOCK_ALIGNMENT __attribute__ ((__aligned__ (4)))
#define __ONCE_ALIGNMENT __attribute__ ((__aligned__ (4)))
diff --git a/sysdeps/m68k/nptl/pthread-offsets.h b/sysdeps/m68k/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..9617354dc7
--- /dev/null
+++ b/sysdeps/m68k/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+#define __PTHREAD_MUTEX_KIND_OFFSET 12
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 20
diff --git a/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h b/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
index d687e2c076..e44f2dcb6a 100644
--- a/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
@@ -35,6 +35,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 1
+#define __PTHREAD_MUTEX_USE_UNION 1
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/microblaze/nptl/pthread-offsets.h b/sysdeps/microblaze/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..9617354dc7
--- /dev/null
+++ b/sysdeps/microblaze/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+#define __PTHREAD_MUTEX_KIND_OFFSET 12
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 20
diff --git a/sysdeps/mips/bits/long-double.h b/sysdeps/mips/ieee754/bits/long-double.h
similarity index 100%
rename from sysdeps/mips/bits/long-double.h
rename to sysdeps/mips/ieee754/bits/long-double.h
diff --git a/sysdeps/mips/nptl/bits/pthreadtypes-arch.h b/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
index 6aa1bda172..f03389acc6 100644
--- a/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/mips/nptl/bits/pthreadtypes-arch.h
@@ -42,6 +42,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (_MIPS_SIM != _ABI64)
+#define __PTHREAD_MUTEX_USE_UNION (_MIPS_SIM != _ABI64)
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/mips/nptl/pthread-offsets.h b/sysdeps/mips/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..0ac3eda3fb
--- /dev/null
+++ b/sysdeps/mips/nptl/pthread-offsets.h
@@ -0,0 +1,13 @@
+#if _MIPS_SIM == _ABI64
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+# define __PTHREAD_MUTEX_KIND_OFFSET 16
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 24
+#else
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+# define __PTHREAD_MUTEX_KIND_OFFSET 12
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 20
+#endif
diff --git a/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h b/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
index e2732f9771..83f8684604 100644
--- a/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
@@ -35,6 +35,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 1
+#define __PTHREAD_MUTEX_USE_UNION 1
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/nios2/nptl/pthread-offsets.h b/sysdeps/nios2/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..9617354dc7
--- /dev/null
+++ b/sysdeps/nios2/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+#define __PTHREAD_MUTEX_KIND_OFFSET 12
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 20
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
index 68b82b6bd6..da4358a965 100644
--- a/sysdeps/nptl/bits/thread-shared-types.h
+++ b/sysdeps/nptl/bits/thread-shared-types.h
@@ -42,6 +42,25 @@
the internal structure.
__PTHREAD_MUTEX_LOCK_ELISION - 1 if the architecture supports lock
elision or 0 otherwise.
+ __PTHREAD_MUTEX_NUSERS_AFTER_KIND - control where to put __nusers. The
+ preferred value for new architectures
+ is 0.
+ __PTHREAD_MUTEX_USE_UNION - control whether internal __spins and
+ __list will be place inside a union for
+ linuxthreads compatibility.
+ The preferred value for new architectures
+ is 0.
+
+ For a new port the preferred values for the required defines are:
+
+ #define __PTHREAD_COMPAT_PADDING_MID
+ #define __PTHREAD_COMPAT_PADDING_END
+ #define __PTHREAD_MUTEX_LOCK_ELISION 0
+ #define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0
+ #define __PTHREAD_MUTEX_USE_UNION 0
+
+ __PTHREAD_MUTEX_LOCK_ELISION can be set to 1 if the hardware plans to
+ eventually support lock elision using transactional memory.
The additional macro defines any constraint for the lock alignment
inside the thread structures:
@@ -59,7 +78,7 @@
/* Common definition of pthread_mutex_t. */
-#if __WORDSIZE == 64
+#if !__PTHREAD_MUTEX_USE_UNION
typedef struct __pthread_internal_list
{
struct __pthread_internal_list *__prev;
@@ -74,7 +93,7 @@ typedef struct __pthread_internal_slist
/* Lock elision support. */
#if __PTHREAD_MUTEX_LOCK_ELISION
-# if __WORDSIZE == 64
+# if !__PTHREAD_MUTEX_USE_UNION
# define __PTHREAD_SPINS_DATA \
short __spins; \
short __elision
@@ -101,24 +120,27 @@ struct __pthread_mutex_s
int __lock __LOCK_ALIGNMENT;
unsigned int __count;
int __owner;
-#if __WORDSIZE == 64
+#if !__PTHREAD_MUTEX_NUSERS_AFTER_KIND
unsigned int __nusers;
#endif
/* KIND must stay at this position in the structure to maintain
binary compatibility with static initializers. */
int __kind;
__PTHREAD_COMPAT_PADDING_MID
-#if __WORDSIZE == 64
+#if __PTHREAD_MUTEX_NUSERS_AFTER_KIND
+ unsigned int __nusers;
+#endif
+#if !__PTHREAD_MUTEX_USE_UNION
__PTHREAD_SPINS_DATA;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
#else
- unsigned int __nusers;
__extension__ union
{
__PTHREAD_SPINS_DATA;
__pthread_slist_t __list;
};
+# define __PTHREAD_MUTEX_HAVE_PREV 0
#endif
__PTHREAD_COMPAT_PADDING_END
};
diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
index 4bb87e2331..48676c2f48 100644
--- a/sysdeps/nptl/fork.c
+++ b/sysdeps/nptl/fork.c
@@ -166,7 +166,7 @@ __libc_fork (void)
inherit the correct value from the parent. We do not need to clear
the pending operation because it must have been zero when fork was
called. */
-# ifdef __PTHREAD_MUTEX_HAVE_PREV
+# if __PTHREAD_MUTEX_HAVE_PREV
self->robust_prev = &self->robust_head;
# endif
self->robust_head.list = &self->robust_head;
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index 632ea7bc36..2b2b386ab3 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -83,7 +83,7 @@ enum
#endif
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+#if __PTHREAD_MUTEX_HAVE_PREV
# define PTHREAD_MUTEX_INITIALIZER \
{ { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } }
# ifdef __USE_GNU
diff --git a/sysdeps/nptl/unwind-forcedunwind.c b/sysdeps/nptl/unwind-forcedunwind.c
index 33a1975f5e..ace58b2468 100644
--- a/sysdeps/nptl/unwind-forcedunwind.c
+++ b/sysdeps/nptl/unwind-forcedunwind.c
@@ -49,7 +49,7 @@ pthread_cancel_init (void)
return;
}
- handle = __libc_dlopen (LIBGCC_S_SO);
+ handle = __libc_dlopen_mode (LIBGCC_S_SO, RTLD_NOW | __RTLD_DLOPEN);
if (handle == NULL
|| (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index efa7118498..2c4b6d6793 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -241,46 +241,43 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
#define gethosts(_family, _type) \
{ \
- int herrno; \
struct hostent th; \
- struct hostent *h; \
char *localcanon = NULL; \
no_data = 0; \
- while (1) { \
- rc = 0; \
- status = DL_CALL_FCT (fct, (name, _family, &th, \
- tmpbuf->data, tmpbuf->length, \
- &rc, &herrno, NULL, &localcanon)); \
- if (rc != ERANGE || herrno != NETDB_INTERNAL) \
- break; \
- if (!scratch_buffer_grow (tmpbuf)) \
- { \
- result = -EAI_MEMORY; \
- goto free_and_return; \
- } \
- } \
- if (status == NSS_STATUS_SUCCESS && rc == 0) \
- h = &th; \
- else \
- h = NULL; \
- if (rc != 0) \
+ while (1) \
{ \
- if (herrno == NETDB_INTERNAL) \
+ status = DL_CALL_FCT (fct, (name, _family, &th, \
+ tmpbuf->data, tmpbuf->length, \
+ &errno, &h_errno, NULL, &localcanon)); \
+ if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
+ || errno != ERANGE) \
+ break; \
+ if (!scratch_buffer_grow (tmpbuf)) \
+ { \
+ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
+ __resolv_context_put (res_ctx); \
+ result = -EAI_MEMORY; \
+ goto free_and_return; \
+ } \
+ } \
+ if (status == NSS_STATUS_NOTFOUND \
+ || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
+ { \
+ if (h_errno == NETDB_INTERNAL) \
{ \
- __set_h_errno (herrno); \
__resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
__resolv_context_put (res_ctx); \
result = -EAI_SYSTEM; \
goto free_and_return; \
} \
- if (herrno == TRY_AGAIN) \
+ if (h_errno == TRY_AGAIN) \
no_data = EAI_AGAIN; \
else \
- no_data = herrno == NO_DATA; \
+ no_data = h_errno == NO_DATA; \
} \
- else if (h != NULL) \
+ else if (status == NSS_STATUS_SUCCESS) \
{ \
- if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
+ if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
{ \
__resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
__resolv_context_put (res_ctx); \
@@ -332,10 +329,8 @@ getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name)
if (cfct != NULL)
{
char buf[256];
- int herrno;
- int rc;
if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
- &s, &rc, &herrno)) != NSS_STATUS_SUCCESS)
+ &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
/* If the canonical name cannot be determined, use the passed
string. */
s = (char *) name;
@@ -351,7 +346,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
const struct gaih_typeproto *tp = gaih_inet_typeproto;
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
struct gaih_addrtuple *at = NULL;
- int rc;
bool got_ipv6 = false;
const char *canon = NULL;
const char *orig_name = name;
@@ -393,7 +387,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
st = (struct gaih_servtuple *)
alloca_account (sizeof (struct gaih_servtuple), alloca_used);
- if ((rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf)))
+ int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
+ if (__glibc_unlikely (rc != 0))
return rc;
}
else
@@ -418,13 +413,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
alloca_account (sizeof (struct gaih_servtuple),
alloca_used);
- if ((rc = gaih_inet_serv (service->name,
- tp, req, newp, tmpbuf)))
- {
- if (rc)
- continue;
- return rc;
- }
+ if (gaih_inet_serv (service->name,
+ tp, req, newp, tmpbuf) != 0)
+ continue;
*pst = newp;
pst = &(newp->next);
@@ -497,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
idn_flags |= IDNA_USE_STD3_ASCII_RULES;
char *p = NULL;
- rc = __idna_to_ascii_lz (name, &p, idn_flags);
+ int rc = __idna_to_ascii_lz (name, &p, idn_flags);
if (rc != IDNA_SUCCESS)
{
/* No need to jump to free_and_return here. */
@@ -598,14 +589,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
int rc;
struct hostent th;
struct hostent *h;
- int herrno;
while (1)
{
rc = __gethostbyname2_r (name, AF_INET, &th,
tmpbuf->data, tmpbuf->length,
- &h, &herrno);
- if (rc != ERANGE || herrno != NETDB_INTERNAL)
+ &h, &h_errno);
+ if (rc != ERANGE || h_errno != NETDB_INTERNAL)
break;
if (!scratch_buffer_grow (tmpbuf))
{
@@ -627,15 +617,20 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
*pat = addrmem;
}
+ else
+ {
+ if (h_errno == NO_DATA)
+ result = -EAI_NODATA;
+ else
+ result = -EAI_NONAME;
+ goto free_and_return;
+ }
}
else
{
- if (herrno == NETDB_INTERNAL)
- {
- __set_h_errno (herrno);
- result = -EAI_SYSTEM;
- }
- else if (herrno == TRY_AGAIN)
+ if (h_errno == NETDB_INTERNAL)
+ result = -EAI_SYSTEM;
+ else if (h_errno == TRY_AGAIN)
result = -EAI_AGAIN;
else
/* We made requests but they turned out no data.
@@ -658,8 +653,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
/* Try to use nscd. */
struct nscd_ai_result *air = NULL;
- int herrno;
- int err = __nscd_getai (name, &air, &herrno);
+ int err = __nscd_getai (name, &air, &h_errno);
if (air != NULL)
{
/* Transform into gaih_addrtuple list. */
@@ -750,9 +744,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
goto free_and_return;
else if (__nss_not_use_nscd_hosts == 0)
{
- if (herrno == NETDB_INTERNAL && errno == ENOMEM)
+ if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
result = -EAI_MEMORY;
- else if (herrno == TRY_AGAIN)
+ else if (h_errno == TRY_AGAIN)
result = -EAI_AGAIN;
else
result = -EAI_SYSTEM;
@@ -791,24 +785,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (fct4 != NULL)
{
- int herrno;
-
while (1)
{
- rc = 0;
status = DL_CALL_FCT (fct4, (name, pat,
tmpbuf->data, tmpbuf->length,
- &rc, &herrno,
+ &errno, &h_errno,
NULL));
if (status == NSS_STATUS_SUCCESS)
break;
if (status != NSS_STATUS_TRYAGAIN
- || rc != ERANGE || herrno != NETDB_INTERNAL)
+ || errno != ERANGE || h_errno != NETDB_INTERNAL)
{
- if (herrno == TRY_AGAIN)
+ if (h_errno == TRY_AGAIN)
no_data = EAI_AGAIN;
else
- no_data = herrno == NO_DATA;
+ no_data = h_errno == NO_DATA;
break;
}
@@ -938,13 +929,17 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
else
{
+ /* Could not locate any of the lookup functions.
+ The NSS lookup code does not consistently set
+ errno, so we need to supply our own error
+ code here. The root cause could either be a
+ resource allocation failure, or a missing
+ service function in the DSO (so it should not
+ be listed in /etc/nsswitch.conf). Assume the
+ former, and return EBUSY. */
status = NSS_STATUS_UNAVAIL;
- /* Could not load any of the lookup functions. Indicate
- an internal error if the failure was due to a system
- error other than the file not being found. We use the
- errno from the last failed callback. */
- if (errno != 0 && errno != ENOENT)
- __set_h_errno (NETDB_INTERNAL);
+ __set_h_errno (NETDB_INTERNAL);
+ __set_errno (EBUSY);
}
}
@@ -960,7 +955,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
__resolv_context_enable_inet6 (res_ctx, res_enable_inet6);
__resolv_context_put (res_ctx);
- if (h_errno == NETDB_INTERNAL)
+ /* If we have a failure which sets errno, report it using
+ EAI_SYSTEM. */
+ if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
+ && h_errno == NETDB_INTERNAL)
{
result = -EAI_SYSTEM;
goto free_and_return;
diff --git a/sysdeps/posix/preadv2.c b/sysdeps/posix/preadv2.c
index 2a7cf11e27..d27f7028ed 100644
--- a/sysdeps/posix/preadv2.c
+++ b/sysdeps/posix/preadv2.c
@@ -28,7 +28,7 @@ preadv2 (int fd, const struct iovec *vector, int count, OFF_T offset,
{
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
diff --git a/sysdeps/posix/preadv64v2.c b/sysdeps/posix/preadv64v2.c
index e084f3f9e1..ce7cb40bf2 100644
--- a/sysdeps/posix/preadv64v2.c
+++ b/sysdeps/posix/preadv64v2.c
@@ -25,7 +25,7 @@ preadv64v2 (int fd, const struct iovec *vector, int count, OFF_T offset,
{
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
diff --git a/sysdeps/posix/pwritev2.c b/sysdeps/posix/pwritev2.c
index 5b7650c4fc..7ec8cbc407 100644
--- a/sysdeps/posix/pwritev2.c
+++ b/sysdeps/posix/pwritev2.c
@@ -28,7 +28,7 @@ pwritev2 (int fd, const struct iovec *vector, int count, OFF_T offset,
{
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
diff --git a/sysdeps/posix/pwritev64v2.c b/sysdeps/posix/pwritev64v2.c
index 0f2f9ef863..be98aeed9d 100644
--- a/sysdeps/posix/pwritev64v2.c
+++ b/sysdeps/posix/pwritev64v2.c
@@ -26,7 +26,7 @@ pwritev64v2 (int fd, const struct iovec *vector, int count, OFF_T offset,
{
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c
index a95e1b3f05..254f87c437 100644
--- a/sysdeps/posix/sysconf.c
+++ b/sysdeps/posix/sysconf.c
@@ -29,6 +29,7 @@
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
+#include <sys/uio.h>
#include <regex.h>
#define NEED_SPEC_ARRAY 0
diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
index 0d9206bec4..6aa683b03f 100644
--- a/sysdeps/powerpc/Makefile
+++ b/sysdeps/powerpc/Makefile
@@ -8,9 +8,11 @@ sysdep-dl-routines += dl-machine hwcapinfo
sysdep_routines += dl-machine hwcapinfo
# extra shared linker files to link only into dl-allobjs.so
sysdep-rtld-routines += dl-machine hwcapinfo
-# Don't optimize GD tls sequence to LE.
-LDFLAGS-tst-tlsopt-powerpc += -Wl,--no-tls-optimize
+
+modules-names += mod-tlsopt-powerpc
+mod-tlsopt-powerpc.so-no-z-defs = yes
tests += tst-tlsopt-powerpc
+$(objpfx)tst-tlsopt-powerpc: $(objpfx)mod-tlsopt-powerpc.so
ifneq (no,$(multi-arch))
tests-static += tst-tlsifunc-static
diff --git a/sysdeps/powerpc/bits/hwcap.h b/sysdeps/powerpc/bits/hwcap.h
index dfc71c29bb..0668ca041e 100644
--- a/sysdeps/powerpc/bits/hwcap.h
+++ b/sysdeps/powerpc/bits/hwcap.h
@@ -72,3 +72,5 @@
128-bit */
#define PPC_FEATURE2_DARN 0x00200000 /* darn instruction. */
#define PPC_FEATURE2_SCV 0x00100000 /* scv syscall. */
+#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 /* TM without suspended
+ state. */
diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h
index d8fd4923ac..396fd0562e 100644
--- a/sysdeps/powerpc/fpu/math_private.h
+++ b/sysdeps/powerpc/fpu/math_private.h
@@ -30,7 +30,7 @@ extern __always_inline _Float128
__ieee754_sqrtf128 (_Float128 __x)
{
_Float128 __z;
- asm ("xssqrtqp %0,%1" : "=wq" (__z) : "wq" (__x));
+ asm ("xssqrtqp %0,%1" : "=v" (__z) : "v" (__x));
return __z;
}
#endif
diff --git a/sysdeps/powerpc/mod-tlsopt-powerpc.c b/sysdeps/powerpc/mod-tlsopt-powerpc.c
new file mode 100644
index 0000000000..ee0db12a73
--- /dev/null
+++ b/sysdeps/powerpc/mod-tlsopt-powerpc.c
@@ -0,0 +1,49 @@
+/* shared library to test for __tls_get_addr optimization. */
+#include <stdio.h>
+
+#include "../../elf/tls-macros.h"
+#include "dl-tls.h"
+
+/* common 'int' variable in TLS. */
+COMMON_INT_DEF(foo);
+
+
+int
+tls_get_addr_opt_test (void)
+{
+ int result = 0;
+
+ /* Get variable using general dynamic model. */
+ int *ap = TLS_GD (foo);
+ if (*ap != 0)
+ {
+ printf ("foo = %d\n", *ap);
+ result = 1;
+ }
+
+ tls_index *tls_arg;
+#ifdef __powerpc64__
+ register unsigned long thread_pointer __asm__ ("r13");
+ asm ("addi %0,2,foo@got@tlsgd" : "=r" (tls_arg));
+#else
+ register unsigned long thread_pointer __asm__ ("r2");
+ asm ("bcl 20,31,1f\n1:\t"
+ "mflr %0\n\t"
+ "addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t"
+ "addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n\t"
+ "addi %0,%0,foo@got@tlsgd" : "=b" (tls_arg));
+#endif
+
+ if (tls_arg->ti_module != 0)
+ {
+ printf ("tls_index not optimized, binutils too old?\n");
+ result = 1;
+ }
+ else if (tls_arg->ti_offset + thread_pointer != (unsigned long) ap)
+ {
+ printf ("tls_index->ti_offset wrong value\n");
+ result = 1;
+ }
+
+ return result;
+}
diff --git a/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h b/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
index f29119b794..8158cb5abd 100644
--- a/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
@@ -42,6 +42,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 1
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64)
+#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64)
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/powerpc/nptl/pthread-offsets.h b/sysdeps/powerpc/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..bdda1f197e
--- /dev/null
+++ b/sysdeps/powerpc/nptl/pthread-offsets.h
@@ -0,0 +1,15 @@
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+# define __PTHREAD_MUTEX_KIND_OFFSET 16
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 24
+#else
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+# define __PTHREAD_MUTEX_KIND_OFFSET 12
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 20
+#endif
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index 1f8437ed9c..c19b3b7a16 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -310,7 +310,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
against local symbols. */
if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF)
- value = map->l_addr;
+ {
+ sym_map = map;
+ value = map->l_addr;
+ }
else
{
sym_map = RESOLVE_MAP (&sym, version, r_type);
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
index a5ec36b72f..7efc84b56a 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
@@ -17,8 +17,16 @@
<http://www.gnu.org/licenses/>. */
#define __finite __redirect___finite
+
+/* The following definitions, although not related to the 'double'
+ version of 'finite', are required to guarantee macro expansions
+ (e.g.: from __finitef to __redirect_finitef) in include/math.h, thus
+ compensating for the unintended macro expansions in
+ math/bits/mathcalls-helper-functions.h. */
#define __finitef __redirect___finitef
#define __finitel __redirect___finitel
+#define __finitef128 __redirect___finitef128
+
#include <math.h>
#include <math_ldbl_opt.h>
#include <shlib-compat.h>
@@ -30,6 +38,7 @@ extern __typeof (__finite) __finite_power8 attribute_hidden;
#undef __finite
#undef __finitef
#undef __finitel
+#undef __finitef128
libc_ifunc_redirected (__redirect___finite, __finite,
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
index 9c6789c7bd..b79bdd5edd 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
@@ -17,8 +17,16 @@
<http://www.gnu.org/licenses/>. */
#define __isinf __redirect___isinf
+
+/* The following definitions, although not related to the 'double'
+ version of 'isinf', are required to guarantee macro expansions
+ (e.g.: from __isinff to __redirect_isinff) in include/math.h, thus
+ compensating for the unintended macro expansions in
+ math/bits/mathcalls-helper-functions.h. */
#define __isinff __redirect___isinff
#define __isinfl __redirect___isinfl
+#define __isinff128 __redirect___isinff128
+
#include <math.h>
#include <math_ldbl_opt.h>
#include <shlib-compat.h>
@@ -30,6 +38,7 @@ extern __typeof (__isinf) __isinf_power8 attribute_hidden;
#undef __isinf
#undef __isinff
#undef __isinfl
+#undef __isinff128
libc_ifunc_redirected (__redirect___isinf, __isinf,
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
index 3cfe1793da..a8127e89f7 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
@@ -17,8 +17,16 @@
<http://www.gnu.org/licenses/>. */
#define __isnan __redirect___isnan
+
+/* The following definitions, although not related to the 'double'
+ version of 'isnan', are required to guarantee macro expansions
+ (e.g.: from __isnanf to __redirect_isnanf) in include/math.h, thus
+ compensating for the unintended macro expansions in
+ math/bits/mathcalls-helper-functions.h. */
#define __isnanf __redirect___isnanf
#define __isnanl __redirect___isnanl
+#define __isnanf128 __redirect___isnanf128
+
#include <math.h>
#include <math_ldbl_opt.h>
#include <shlib-compat.h>
@@ -33,6 +41,7 @@ extern __typeof (__isnan) __isnan_power8 attribute_hidden;
#undef __isnan
#undef __isnanf
#undef __isnanl
+#undef __isnanf128
libc_ifunc_redirected (__redirect___isnan, __isnan,
(hwcap2 & PPC_FEATURE2_ARCH_2_07)
diff --git a/sysdeps/powerpc/powerpc64/power7/memcpy.S b/sysdeps/powerpc/powerpc64/power7/memcpy.S
index 641c7e2118..c9b6507d1b 100644
--- a/sysdeps/powerpc/powerpc64/power7/memcpy.S
+++ b/sysdeps/powerpc/powerpc64/power7/memcpy.S
@@ -91,63 +91,63 @@ L(aligned_copy):
srdi 12,cnt,7
cmpdi 12,0
beq L(aligned_tail)
- lxvd2x 6,0,src
- lxvd2x 7,src,6
+ lvx 6,0,src
+ lvx 7,src,6
mtctr 12
b L(aligned_128loop)
.align 4
L(aligned_128head):
/* for the 2nd + iteration of this loop. */
- lxvd2x 6,0,src
- lxvd2x 7,src,6
+ lvx 6,0,src
+ lvx 7,src,6
L(aligned_128loop):
- lxvd2x 8,src,7
- lxvd2x 9,src,8
- stxvd2x 6,0,dst
+ lvx 8,src,7
+ lvx 9,src,8
+ stvx 6,0,dst
addi src,src,64
- stxvd2x 7,dst,6
- stxvd2x 8,dst,7
- stxvd2x 9,dst,8
- lxvd2x 6,0,src
- lxvd2x 7,src,6
+ stvx 7,dst,6
+ stvx 8,dst,7
+ stvx 9,dst,8
+ lvx 6,0,src
+ lvx 7,src,6
addi dst,dst,64
- lxvd2x 8,src,7
- lxvd2x 9,src,8
+ lvx 8,src,7
+ lvx 9,src,8
addi src,src,64
- stxvd2x 6,0,dst
- stxvd2x 7,dst,6
- stxvd2x 8,dst,7
- stxvd2x 9,dst,8
+ stvx 6,0,dst
+ stvx 7,dst,6
+ stvx 8,dst,7
+ stvx 9,dst,8
addi dst,dst,64
bdnz L(aligned_128head)
L(aligned_tail):
mtocrf 0x01,cnt
bf 25,32f
- lxvd2x 6,0,src
- lxvd2x 7,src,6
- lxvd2x 8,src,7
- lxvd2x 9,src,8
+ lvx 6,0,src
+ lvx 7,src,6
+ lvx 8,src,7
+ lvx 9,src,8
addi src,src,64
- stxvd2x 6,0,dst
- stxvd2x 7,dst,6
- stxvd2x 8,dst,7
- stxvd2x 9,dst,8
+ stvx 6,0,dst
+ stvx 7,dst,6
+ stvx 8,dst,7
+ stvx 9,dst,8
addi dst,dst,64
32:
bf 26,16f
- lxvd2x 6,0,src
- lxvd2x 7,src,6
+ lvx 6,0,src
+ lvx 7,src,6
addi src,src,32
- stxvd2x 6,0,dst
- stxvd2x 7,dst,6
+ stvx 6,0,dst
+ stvx 7,dst,6
addi dst,dst,32
16:
bf 27,8f
- lxvd2x 6,0,src
+ lvx 6,0,src
addi src,src,16
- stxvd2x 6,0,dst
+ stvx 6,0,dst
addi dst,dst,16
8:
bf 28,4f
diff --git a/sysdeps/powerpc/powerpc64/power7/memmove.S b/sysdeps/powerpc/powerpc64/power7/memmove.S
index 93baa69ee2..667c6e2092 100644
--- a/sysdeps/powerpc/powerpc64/power7/memmove.S
+++ b/sysdeps/powerpc/powerpc64/power7/memmove.S
@@ -92,63 +92,63 @@ L(aligned_copy):
srdi 12,r5,7
cmpdi 12,0
beq L(aligned_tail)
- lxvd2x 6,0,r4
- lxvd2x 7,r4,6
+ lvx 6,0,r4
+ lvx 7,r4,6
mtctr 12
b L(aligned_128loop)
.align 4
L(aligned_128head):
/* for the 2nd + iteration of this loop. */
- lxvd2x 6,0,r4
- lxvd2x 7,r4,6
+ lvx 6,0,r4
+ lvx 7,r4,6
L(aligned_128loop):
- lxvd2x 8,r4,7
- lxvd2x 9,r4,8
- stxvd2x 6,0,r11
+ lvx 8,r4,7
+ lvx 9,r4,8
+ stvx 6,0,r11
addi r4,r4,64
- stxvd2x 7,r11,6
- stxvd2x 8,r11,7
- stxvd2x 9,r11,8
- lxvd2x 6,0,r4
- lxvd2x 7,r4,6
+ stvx 7,r11,6
+ stvx 8,r11,7
+ stvx 9,r11,8
+ lvx 6,0,r4
+ lvx 7,r4,6
addi r11,r11,64
- lxvd2x 8,r4,7
- lxvd2x 9,r4,8
+ lvx 8,r4,7
+ lvx 9,r4,8
addi r4,r4,64
- stxvd2x 6,0,r11
- stxvd2x 7,r11,6
- stxvd2x 8,r11,7
- stxvd2x 9,r11,8
+ stvx 6,0,r11
+ stvx 7,r11,6
+ stvx 8,r11,7
+ stvx 9,r11,8
addi r11,r11,64
bdnz L(aligned_128head)
L(aligned_tail):
mtocrf 0x01,r5
bf 25,32f
- lxvd2x 6,0,r4
- lxvd2x 7,r4,6
- lxvd2x 8,r4,7
- lxvd2x 9,r4,8
+ lvx 6,0,r4
+ lvx 7,r4,6
+ lvx 8,r4,7
+ lvx 9,r4,8
addi r4,r4,64
- stxvd2x 6,0,r11
- stxvd2x 7,r11,6
- stxvd2x 8,r11,7
- stxvd2x 9,r11,8
+ stvx 6,0,r11
+ stvx 7,r11,6
+ stvx 8,r11,7
+ stvx 9,r11,8
addi r11,r11,64
32:
bf 26,16f
- lxvd2x 6,0,r4
- lxvd2x 7,r4,6
+ lvx 6,0,r4
+ lvx 7,r4,6
addi r4,r4,32
- stxvd2x 6,0,r11
- stxvd2x 7,r11,6
+ stvx 6,0,r11
+ stvx 7,r11,6
addi r11,r11,32
16:
bf 27,8f
- lxvd2x 6,0,r4
+ lvx 6,0,r4
addi r4,r4,16
- stxvd2x 6,0,r11
+ stvx 6,0,r11
addi r11,r11,16
8:
bf 28,4f
@@ -488,63 +488,63 @@ L(aligned_copy_bwd):
srdi r12,r5,7
cmpdi r12,0
beq L(aligned_tail_bwd)
- lxvd2x v6,r4,r6
- lxvd2x v7,r4,r7
+ lvx v6,r4,r6
+ lvx v7,r4,r7
mtctr 12
b L(aligned_128loop_bwd)
.align 4
L(aligned_128head_bwd):
/* for the 2nd + iteration of this loop. */
- lxvd2x v6,r4,r6
- lxvd2x v7,r4,r7
+ lvx v6,r4,r6
+ lvx v7,r4,r7
L(aligned_128loop_bwd):
- lxvd2x v8,r4,r8
- lxvd2x v9,r4,r9
- stxvd2x v6,r11,r6
+ lvx v8,r4,r8
+ lvx v9,r4,r9
+ stvx v6,r11,r6
subi r4,r4,64
- stxvd2x v7,r11,r7
- stxvd2x v8,r11,r8
- stxvd2x v9,r11,r9
- lxvd2x v6,r4,r6
- lxvd2x v7,r4,7
+ stvx v7,r11,r7
+ stvx v8,r11,r8
+ stvx v9,r11,r9
+ lvx v6,r4,r6
+ lvx v7,r4,7
subi r11,r11,64
- lxvd2x v8,r4,r8
- lxvd2x v9,r4,r9
+ lvx v8,r4,r8
+ lvx v9,r4,r9
subi r4,r4,64
- stxvd2x v6,r11,r6
- stxvd2x v7,r11,r7
- stxvd2x v8,r11,r8
- stxvd2x v9,r11,r9
+ stvx v6,r11,r6
+ stvx v7,r11,r7
+ stvx v8,r11,r8
+ stvx v9,r11,r9
subi r11,r11,64
bdnz L(aligned_128head_bwd)
L(aligned_tail_bwd):
mtocrf 0x01,r5
bf 25,32f
- lxvd2x v6,r4,r6
- lxvd2x v7,r4,r7
- lxvd2x v8,r4,r8
- lxvd2x v9,r4,r9
+ lvx v6,r4,r6
+ lvx v7,r4,r7
+ lvx v8,r4,r8
+ lvx v9,r4,r9
subi r4,r4,64
- stxvd2x v6,r11,r6
- stxvd2x v7,r11,r7
- stxvd2x v8,r11,r8
- stxvd2x v9,r11,r9
+ stvx v6,r11,r6
+ stvx v7,r11,r7
+ stvx v8,r11,r8
+ stvx v9,r11,r9
subi r11,r11,64
32:
bf 26,16f
- lxvd2x v6,r4,r6
- lxvd2x v7,r4,r7
+ lvx v6,r4,r6
+ lvx v7,r4,r7
subi r4,r4,32
- stxvd2x v6,r11,r6
- stxvd2x v7,r11,r7
+ stvx v6,r11,r6
+ stvx v7,r11,r7
subi r11,r11,32
16:
bf 27,8f
- lxvd2x v6,r4,r6
+ lvx v6,r4,r6
subi r4,r4,16
- stxvd2x v6,r11,r6
+ stvx v6,r11,r6
subi r11,r11,16
8:
bf 28,4f
diff --git a/sysdeps/powerpc/powerpc64/tls-macros.h b/sysdeps/powerpc/powerpc64/tls-macros.h
index 42a95ec5c1..79a0b2579c 100644
--- a/sysdeps/powerpc/powerpc64/tls-macros.h
+++ b/sysdeps/powerpc/powerpc64/tls-macros.h
@@ -18,13 +18,11 @@
__result; \
})
-#define __TLS_GET_ADDR "__tls_get_addr"
-
/* PowerPC64 Local Dynamic TLS access. */
#define TLS_LD(x) \
({ int * __result; \
asm ("addi 3,2," #x "@got@tlsld\n\t" \
- "bl " __TLS_GET_ADDR "\n\t" \
+ "bl __tls_get_addr\n\t" \
"nop \n\t" \
"addis %0,3," #x "@dtprel@ha\n\t" \
"addi %0,%0," #x "@dtprel@l" \
@@ -36,7 +34,7 @@
#define TLS_GD(x) \
({ register int *__result __asm__ ("r3"); \
asm ("addi 3,2," #x "@got@tlsgd\n\t" \
- "bl " __TLS_GET_ADDR "\n\t" \
+ "bl __tls_get_addr\n\t" \
"nop " \
: "=r" (__result) : \
: __TLS_CALL_CLOBBERS); \
diff --git a/sysdeps/powerpc/powerpc64le/Makefile b/sysdeps/powerpc/powerpc64le/Makefile
index 77617b670a..f554a791b7 100644
--- a/sysdeps/powerpc/powerpc64le/Makefile
+++ b/sysdeps/powerpc/powerpc64le/Makefile
@@ -16,7 +16,10 @@ $(foreach suf,$(all-object-suffixes),%f128_r$(suf)): CFLAGS += -mfloat128
$(foreach suf,$(all-object-suffixes),$(objpfx)test-float128%$(suf)): CFLAGS += -mfloat128
$(foreach suf,$(all-object-suffixes),$(objpfx)test-ifloat128%$(suf)): CFLAGS += -mfloat128
CFLAGS-libm-test-support-float128.c += -mfloat128
-$(objpfx)test-float128% $(objpfx)test-ifloat128%: \
+CFLAGS-test-math-iscanonical.cc += -mfloat128
+CFLAGS-test-math-issignaling.cc += -mfloat128
+CFLAGS-test-math-iszero.cc += -mfloat128
+$(objpfx)test-float128% $(objpfx)test-ifloat128% $(objpfx)test-math-iszero: \
gnulib-tests += $(f128-loader-link)
endif
@@ -31,12 +34,15 @@ CFLAGS-bug-strtod.c += -mfloat128
CFLAGS-bug-strtod2.c += -mfloat128
CFLAGS-tst-strtod-round.c += -mfloat128
CFLAGS-tst-wcstod-round.c += -mfloat128
+CFLAGS-tst-strtod-nan-locale.c += -mfloat128
+CFLAGS-tst-wcstod-nan-locale.c += -mfloat128
CFLAGS-tst-strtod6.c += -mfloat128
CFLAGS-tst-strfrom.c += -mfloat128
CFLAGS-tst-strfrom-locale.c += -mfloat128
CFLAGS-strfrom-skeleton.c += -mfloat128
$(foreach test,bug-strtod bug-strtod2 bug-strtod2 tst-strtod-round \
tst-wcstod-round tst-strtod6 tst-strrom tst-strfrom-locale \
+tst-strtod-nan-locale tst-wcstod-nan-locale \
strfrom-skeleton,$(objpfx)$(test)): gnulib-tests += $(f128-loader-link)
# When building glibc with support for _Float128, the powers of ten tables in
diff --git a/sysdeps/powerpc/powerpc64le/power9/fpu/e_sqrtf128.c b/sysdeps/powerpc/powerpc64le/power9/fpu/e_sqrtf128.c
index 769d3f8922..59fd8269f5 100644
--- a/sysdeps/powerpc/powerpc64le/power9/fpu/e_sqrtf128.c
+++ b/sysdeps/powerpc/powerpc64le/power9/fpu/e_sqrtf128.c
@@ -30,7 +30,7 @@ __float128
__ieee754_sqrtf128 (__float128 a)
{
__float128 z;
- asm ("xssqrtqp %0,%1" : "=wq" (z) : "wq" (a));
+ asm ("xssqrtqp %0,%1" : "=v" (z) : "v" (a));
return z;
}
strong_alias (__ieee754_sqrtf128, __sqrtf128_finite)
diff --git a/sysdeps/powerpc/tst-tlsopt-powerpc.c b/sysdeps/powerpc/tst-tlsopt-powerpc.c
index 8ae928a3f4..cc682b2ed0 100644
--- a/sysdeps/powerpc/tst-tlsopt-powerpc.c
+++ b/sysdeps/powerpc/tst-tlsopt-powerpc.c
@@ -1,51 +1,11 @@
/* glibc test for __tls_get_addr optimization. */
-#include <stdio.h>
-
-#include "../../elf/tls-macros.h"
-#include "dl-tls.h"
-
-/* common 'int' variable in TLS. */
-COMMON_INT_DEF(foo);
-
static int
do_test (void)
{
- int result = 0;
-
- /* Get variable using general dynamic model. */
- int *ap = TLS_GD (foo);
- if (*ap != 0)
- {
- printf ("foo = %d\n", *ap);
- result = 1;
- }
-
- tls_index *tls_arg;
-#ifdef __powerpc64__
- register unsigned long thread_pointer __asm__ ("r13");
- asm ("addi %0,2,foo@got@tlsgd" : "=r" (tls_arg));
-#else
- register unsigned long thread_pointer __asm__ ("r2");
- asm ("bcl 20,31,1f\n1:\t"
- "mflr %0\n\t"
- "addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t"
- "addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n\t"
- "addi %0,%0,foo@got@tlsgd" : "=b" (tls_arg));
-#endif
-
- if (tls_arg->ti_module != 0)
- {
- printf ("tls_index not optimized, binutils too old?\n");
- result = 1;
- }
- else if (tls_arg->ti_offset + thread_pointer != (unsigned long) ap)
- {
- printf ("tls_index->ti_offset wrong value\n");
- result = 1;
- }
+ extern int tls_get_addr_opt_test (void);
- return result;
+ return tls_get_addr_opt_test ();
}
#include <support/test-driver.c>
diff --git a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
index 3a9ac57625..1ae277367d 100644
--- a/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/s390/nptl/bits/pthreadtypes-arch.h
@@ -45,6 +45,8 @@
#else
#define __PTHREAD_MUTEX_LOCK_ELISION 0
#endif
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64)
+#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64)
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/s390/nptl/pthread-offsets.h b/sysdeps/s390/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..bdda1f197e
--- /dev/null
+++ b/sysdeps/s390/nptl/pthread-offsets.h
@@ -0,0 +1,15 @@
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+# define __PTHREAD_MUTEX_KIND_OFFSET 16
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 24
+#else
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+# define __PTHREAD_MUTEX_KIND_OFFSET 12
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 20
+#endif
diff --git a/sysdeps/sh/nptl/bits/pthreadtypes-arch.h b/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
index b2615fe314..e707751aa6 100644
--- a/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/sh/nptl/bits/pthreadtypes-arch.h
@@ -34,6 +34,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 1
+#define __PTHREAD_MUTEX_USE_UNION 1
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/sh/nptl/pthread-offsets.h b/sysdeps/sh/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..9617354dc7
--- /dev/null
+++ b/sysdeps/sh/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+#define __PTHREAD_MUTEX_KIND_OFFSET 12
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 20
diff --git a/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h b/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
index 1e188cf91f..0f96f3711e 100644
--- a/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
@@ -43,6 +43,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64)
+#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64)
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/sparc/nptl/pthread-offsets.h b/sysdeps/sparc/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..bdda1f197e
--- /dev/null
+++ b/sysdeps/sparc/nptl/pthread-offsets.h
@@ -0,0 +1,15 @@
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+# define __PTHREAD_MUTEX_KIND_OFFSET 16
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 24
+#else
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+# define __PTHREAD_MUTEX_KIND_OFFSET 12
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 20
+#endif
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 436e4e6cc3..debf67bd1b 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -376,6 +376,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF)
{
+ sym_map = map;
value = map->l_addr;
}
else
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index c2871dca3a..e1ec7a532c 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -403,6 +403,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF)
{
+ sym_map = map;
value = map->l_addr;
}
else
diff --git a/sysdeps/tile/nptl/bits/pthreadtypes-arch.h b/sysdeps/tile/nptl/bits/pthreadtypes-arch.h
index 145ee42ddb..054474f770 100644
--- a/sysdeps/tile/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/tile/nptl/bits/pthreadtypes-arch.h
@@ -43,6 +43,8 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64)
+#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64)
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/tile/nptl/pthread-offsets.h b/sysdeps/tile/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..bdda1f197e
--- /dev/null
+++ b/sysdeps/tile/nptl/pthread-offsets.h
@@ -0,0 +1,15 @@
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+# define __PTHREAD_MUTEX_KIND_OFFSET 16
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 24
+#else
+# define __PTHREAD_MUTEX_NUSERS_OFFSET 16
+# define __PTHREAD_MUTEX_KIND_OFFSET 12
+# define __PTHREAD_MUTEX_SPINS_OFFSET 20
+# define __PTHREAD_MUTEX_ELISION_OFFSET 22
+# define __PTHREAD_MUTEX_LIST_OFFSET 20
+#endif
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 9d6a2de870..b1fe960d00 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -50,7 +50,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
bits/siginfo-arch.h bits/siginfo-consts-arch.h
tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
- tst-quota tst-sync_file_range test-errno-linux
+ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
+ test-errno-linux
# Generate the list of SYS_* macros for the system calls (__NR_* macros).
@@ -120,7 +121,11 @@ ifndef no_deps
-include $(objpfx)bits/syscall.d
endif
generated += bits/syscall.h bits/syscall.d
-endif
+
+# Separate object file for access to the constant from the UAPI header.
+$(objpfx)tst-sysconf-iov_max: $(objpfx)tst-sysconf-iov_max-uapi.o
+
+endif # $(subdir) == misc
ifeq ($(subdir),time)
sysdep_headers += sys/timex.h bits/timex.h
@@ -162,7 +167,7 @@ endif
ifeq ($(subdir),posix)
sysdep_headers += bits/initspin.h
-sysdep_routines += sched_getcpu
+sysdep_routines += sched_getcpu oldglob
tests += tst-affinity tst-affinity-pid
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
index 0275d11c7f..0c7e13f4fa 100644
--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
@@ -28,6 +28,7 @@ struct cpu_list
};
static struct cpu_list cpu_list[] = {
+ {"falkor", 0x510FC000},
{"thunderxt88", 0x430F0A10},
{"generic", 0x0}
};
@@ -36,7 +37,7 @@ static uint64_t
get_midr_from_mcpu (const char *mcpu)
{
for (int i = 0; i < sizeof (cpu_list) / sizeof (struct cpu_list); i++)
- if (tunable_is_name (mcpu, cpu_list[i].name) == 0)
+ if (strcmp (mcpu, cpu_list[i].name) == 0)
return cpu_list[i].midr;
return UINT64_MAX;
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
index c92b650984..73cb53da9a 100644
--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
@@ -41,6 +41,9 @@
#define IS_THUNDERX(midr) (MIDR_IMPLEMENTOR(midr) == 'C' \
&& MIDR_PARTNUM(midr) == 0x0a1)
+#define IS_FALKOR(midr) (MIDR_IMPLEMENTOR(midr) == 'Q' \
+ && MIDR_PARTNUM(midr) == 0xc00)
+
struct cpu_features
{
uint64_t midr_el1;
diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
index 47bd189f94..50f4fb1183 100644
--- a/sysdeps/unix/sysv/linux/alpha/Makefile
+++ b/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -1,7 +1,3 @@
-ifeq ($(subdir),posix)
-sysdep_routines += oldglob
-endif
-
ifeq ($(subdir),stdlib)
gen-as-const-headers += ucontext-offsets.sym
endif
diff --git a/sysdeps/unix/sysv/linux/alpha/glob.c b/sysdeps/unix/sysv/linux/alpha/glob.c
index 2d7d287a25..1b813c1cfd 100644
--- a/sysdeps/unix/sysv/linux/alpha/glob.c
+++ b/sysdeps/unix/sysv/linux/alpha/glob.c
@@ -42,10 +42,6 @@ extern void __new_globfree (glob_t *__pglob);
#undef globfree64
versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);
-versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
libc_hidden_ver (__new_glob, glob)
-libc_hidden_ver (__new_globfree, globfree)
weak_alias (__new_glob, glob64)
-weak_alias (__new_globfree, globfree64)
-libc_hidden_ver (__new_globfree, globfree64)
diff --git a/sysdeps/unix/sysv/linux/alpha/globfree.c b/sysdeps/unix/sysv/linux/alpha/globfree.c
new file mode 100644
index 0000000000..98cf1c200b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/globfree.c
@@ -0,0 +1,37 @@
+/* Compat globfree. Linux/alpha version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define globfree64 __no_globfree64_decl
+#include <sys/types.h>
+#include <glob.h>
+#include <shlib-compat.h>
+
+#define globfree(pglob) \
+ __new_globfree (pglob)
+
+extern void __new_globfree (glob_t *__pglob);
+
+#include <posix/globfree.c>
+
+#undef globfree64
+
+versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
+libc_hidden_ver (__new_globfree, globfree)
+
+weak_alias (__new_globfree, globfree64)
+libc_hidden_ver (__new_globfree, globfree64)
diff --git a/sysdeps/unix/sysv/linux/arm/glob64.c b/sysdeps/unix/sysv/linux/arm/glob64.c
deleted file mode 100644
index 82a9a296a7..0000000000
--- a/sysdeps/unix/sysv/linux/arm/glob64.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c
index 3b556fd450..f485de88a5 100644
--- a/sysdeps/unix/sysv/linux/getcwd.c
+++ b/sysdeps/unix/sysv/linux/getcwd.c
@@ -76,7 +76,7 @@ __getcwd (char *buf, size_t size)
int retval;
retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size);
- if (retval >= 0)
+ if (retval > 0 && path[0] == '/')
{
#ifndef NO_ALLOCATION
if (buf == NULL && size == 0)
@@ -92,10 +92,10 @@ __getcwd (char *buf, size_t size)
return buf;
}
- /* The system call cannot handle paths longer than a page.
- Neither can the magic symlink in /proc/self. Just use the
+ /* The system call either cannot handle paths longer than a page
+ or can succeed without returning an absolute path. Just use the
generic implementation right away. */
- if (errno == ENAMETOOLONG)
+ if (retval >= 0 || errno == ENAMETOOLONG)
{
#ifndef NO_ALLOCATION
if (buf == NULL && size == 0)
diff --git a/sysdeps/unix/sysv/linux/glob.c b/sysdeps/unix/sysv/linux/glob.c
new file mode 100644
index 0000000000..057ae7fe25
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/glob.c
@@ -0,0 +1,28 @@
+/* Find pathnames matching a pattern. Linux version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#define glob64 __no_glob64_decl
+#include <posix/glob.c>
+#undef glob64
+
+#if XSTAT_IS_XSTAT64
+weak_alias (glob, glob64)
+#endif
diff --git a/sysdeps/unix/sysv/linux/glob64.c b/sysdeps/unix/sysv/linux/glob64.c
new file mode 100644
index 0000000000..428bbacb11
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/glob64.c
@@ -0,0 +1,51 @@
+/* Find pathnames matching a pattern. Linux version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#if !XSTAT_IS_XSTAT64
+# include <glob.h>
+# include <dirent.h>
+# include <sys/stat.h>
+
+# define dirent dirent64
+# define __readdir(dirp) __readdir64 (dirp)
+
+# define glob_t glob64_t
+# define glob(pattern, flags, errfunc, pglob) \
+ __glob64 (pattern, flags, errfunc, pglob)
+# define globfree(pglob) globfree64 (pglob)
+
+# undef stat
+# define stat stat64
+
+# define COMPILE_GLOB64 1
+
+# include <posix/glob.c>
+
+# include "shlib-compat.h"
+
+# ifdef GLOB_NO_OLD_VERSION
+strong_alias (__glob64, glob64)
+libc_hidden_def (glob64)
+# else
+versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
+libc_hidden_ver (__glob64, glob64)
+# endif
+#endif /* XSTAT_IS_XSTAT64 */
diff --git a/sysdeps/unix/sysv/linux/globfree.c b/sysdeps/unix/sysv/linux/globfree.c
new file mode 100644
index 0000000000..48d4aec332
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/globfree.c
@@ -0,0 +1,30 @@
+/* Frees the dynamically allocated storage from an earlier call to glob.
+ Linux version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#define globfree64 __no_globfree64_decl
+#include <posix/globfree.c>
+#undef globfree64
+
+#if XSTAT_IS_XSTAT64
+weak_alias (globfree, globfree64)
+libc_hidden_ver (globfree, globfree64)
+#endif
diff --git a/sysdeps/unix/sysv/linux/globfree64.c b/sysdeps/unix/sysv/linux/globfree64.c
new file mode 100644
index 0000000000..0020466372
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/globfree64.c
@@ -0,0 +1,36 @@
+/* Frees the dynamically allocated storage from an earlier call to glob.
+ Linux version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#if !XSTAT_IS_XSTAT64
+
+# include <glob.h>
+
+# define glob_t glob64_t
+# define globfree(pglob) globfree64 (pglob)
+
+# undef stat
+# define stat stat64
+
+# include <posix/globfree.c>
+
+libc_hidden_def (globfree64)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/alphasort64.c b/sysdeps/unix/sysv/linux/i386/alphasort64.c
index d5fd47a9ae..04b29b6e0e 100644
--- a/sysdeps/unix/sysv/linux/i386/alphasort64.c
+++ b/sysdeps/unix/sysv/linux/i386/alphasort64.c
@@ -30,7 +30,7 @@ versioned_symbol (libc, __alphasort64, alphasort64, GLIBC_2_2);
#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
int
__old_alphasort64 (const struct __old_dirent64 **a,
diff --git a/sysdeps/unix/sysv/linux/i386/getdents64.c b/sysdeps/unix/sysv/linux/i386/getdents64.c
index e8b257f059..2010bbf8df 100644
--- a/sysdeps/unix/sysv/linux/i386/getdents64.c
+++ b/sysdeps/unix/sysv/linux/i386/getdents64.c
@@ -28,7 +28,7 @@
#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
#define __GETDENTS __old_getdents64
#define DIRENT_TYPE struct __old_dirent64
diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/i386/glob64.c
deleted file mode 100644
index f68195137e..0000000000
--- a/sysdeps/unix/sysv/linux/i386/glob64.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Two glob variants with 64-bit support, for dirent64 and __olddirent64.
- Copyright (C) 1998-2017 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <dirent.h>
-#include <glob.h>
-#include <sys/stat.h>
-
-#define dirent dirent64
-#define __readdir(dirp) __readdir64 (dirp)
-
-#define glob_t glob64_t
-#define glob(pattern, flags, errfunc, pglob) \
- __glob64 (pattern, flags, errfunc, pglob)
-#define globfree(pglob) globfree64 (pglob)
-
-#undef stat
-#define stat stat64
-#undef __stat
-#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
-
-#define NO_GLOB_PATTERN_P 1
-
-#define COMPILE_GLOB64 1
-
-#include <posix/glob.c>
-
-#include "shlib-compat.h"
-
-libc_hidden_def (globfree64)
-
-versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
-libc_hidden_ver (__glob64, glob64)
-
-#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
-
-int __old_glob64 (const char *__pattern, int __flags,
- int (*__errfunc) (const char *, int),
- glob64_t *__pglob);
-
-#undef dirent
-#define dirent __old_dirent64
-#undef GL_READDIR
-# define GL_READDIR(pglob, stream) \
- ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
-#undef __readdir
-#define __readdir(dirp) __old_readdir64 (dirp)
-#undef glob
-#define glob(pattern, flags, errfunc, pglob) \
- __old_glob64 (pattern, flags, errfunc, pglob)
-#define convert_dirent __old_convert_dirent
-#define glob_in_dir __old_glob_in_dir
-#define GLOB_ATTRIBUTE attribute_compat_text_section
-
-#define GLOB_ONLY_P 1
-
-#include <posix/glob.c>
-
-compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1);
-#endif
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64.c b/sysdeps/unix/sysv/linux/i386/readdir64.c
index f80b6a7ba2..bd2375f9a6 100644
--- a/sysdeps/unix/sysv/linux/i386/readdir64.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64.c
@@ -31,7 +31,7 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
#define __READDIR attribute_compat_text_section __old_readdir64
#define __GETDENTS __old_getdents64
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
index 344fd53d02..8c0262d1dc 100644
--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
@@ -31,7 +31,7 @@ versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
#define __READDIR_R attribute_compat_text_section __old_readdir64_r
#define __GETDENTS __old_getdents64
diff --git a/sysdeps/unix/sysv/linux/i386/versionsort64.c b/sysdeps/unix/sysv/linux/i386/versionsort64.c
index 3e1c6ea35b..87f2f9578d 100644
--- a/sysdeps/unix/sysv/linux/i386/versionsort64.c
+++ b/sysdeps/unix/sysv/linux/i386/versionsort64.c
@@ -30,7 +30,7 @@ versioned_symbol (libc, __versionsort64, versionsort64, GLIBC_2_2);
#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
int
__old_versionsort64 (const struct __old_dirent64 **a,
diff --git a/sysdeps/unix/sysv/linux/ia64/ipc_priv.h b/sysdeps/unix/sysv/linux/ia64/ipc_priv.h
new file mode 100644
index 0000000000..e602eea455
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/ipc_priv.h
@@ -0,0 +1,21 @@
+/* Old SysV permission definition for Linux. IA64 version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/ipc.h> /* For __key_t */
+
+#define __IPC_64 0x0
diff --git a/sysdeps/unix/sysv/linux/ia64/mmap_internal.h b/sysdeps/unix/sysv/linux/ia64/mmap_internal.h
new file mode 100644
index 0000000000..dbaaa3f904
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/mmap_internal.h
@@ -0,0 +1,29 @@
+/* Common mmap definition for Linux implementation. Linux/ia64 version.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef MMAP_IA64_INTERNAL_LINUX_H
+#define MMAP_IA64_INTERNAL_LINUX_H
+
+/* Linux allows PAGE_SHIFT in range of [12-16] and expect
+ mmap2 offset to be provided in based on the configured pagesize.
+ Determine the shift dynamically with getpagesize. */
+#define MMAP2_PAGE_UNIT -1
+
+#include_next <mmap_internal.h>
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/m68k/glob64.c b/sysdeps/unix/sysv/linux/m68k/glob64.c
deleted file mode 100644
index 82a9a296a7..0000000000
--- a/sysdeps/unix/sysv/linux/m68k/glob64.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/m68k/mmap_internal.h b/sysdeps/unix/sysv/linux/m68k/mmap_internal.h
index bd8bd3843b..9fe9d9127d 100644
--- a/sysdeps/unix/sysv/linux/m68k/mmap_internal.h
+++ b/sysdeps/unix/sysv/linux/m68k/mmap_internal.h
@@ -22,7 +22,7 @@
/* ColdFire and Sun 3 kernels have PAGE_SHIFT set to 13 and expect
mmap2 offset to be provided in 8K pages. Determine the shift
dynamically with getpagesize. */
-#define MMAP2_PAGE_SHIFT -1
+#define MMAP2_PAGE_UNIT -1
#include_next <mmap_internal.h>
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c b/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
deleted file mode 100644
index 33918ea6a5..0000000000
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* glob64 is in glob.c */
diff --git a/sysdeps/unix/sysv/linux/mmap.c b/sysdeps/unix/sysv/linux/mmap.c
index 98c2f88eb8..59292b6d79 100644
--- a/sysdeps/unix/sysv/linux/mmap.c
+++ b/sysdeps/unix/sysv/linux/mmap.c
@@ -21,9 +21,9 @@
#include <sys/mman.h>
#include <sysdep.h>
#include <stdint.h>
-#include <mmap_internal.h>
#ifndef __OFF_T_MATCHES_OFF64_T
+# include <mmap_internal.h>
/* An architecture may override this. */
# ifndef MMAP_ADJUST_OFFSET
diff --git a/sysdeps/unix/sysv/linux/mmap_internal.h b/sysdeps/unix/sysv/linux/mmap_internal.h
index 499e389605..47c099183c 100644
--- a/sysdeps/unix/sysv/linux/mmap_internal.h
+++ b/sysdeps/unix/sysv/linux/mmap_internal.h
@@ -27,13 +27,13 @@
#endif
#if MMAP2_PAGE_UNIT == -1
-static int page_unit;
-
+static uint64_t page_unit;
# define MMAP_CHECK_PAGE_UNIT() \
if (page_unit == 0) \
page_unit = __getpagesize ();
+# undef MMAP2_PAGE_UNIT
+# define MMAP2_PAGE_UNIT page_unit
#else
-# define page_unit MMAP2_PAGE_UNIT
# define MMAP_CHECK_PAGE_UNIT()
#endif
diff --git a/sysdeps/unix/sysv/linux/i386/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h
similarity index 100%
rename from sysdeps/unix/sysv/linux/i386/olddirent.h
rename to sysdeps/unix/sysv/linux/olddirent.h
diff --git a/sysdeps/unix/sysv/linux/oldglob.c b/sysdeps/unix/sysv/linux/oldglob.c
new file mode 100644
index 0000000000..5402450f55
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/oldglob.c
@@ -0,0 +1,43 @@
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) \
+ && !defined(GLOB_NO_OLD_VERSION)
+
+#include <dirent.h>
+#include <glob.h>
+#include <sys/stat.h>
+
+#include <olddirent.h>
+
+int __old_glob64 (const char *__pattern, int __flags,
+ int (*__errfunc) (const char *, int),
+ glob64_t *__pglob);
+libc_hidden_proto (__old_glob64);
+
+#define dirent __old_dirent64
+#define GL_READDIR(pglob, stream) \
+ ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
+#undef __readdir
+#define __readdir(dirp) __old_readdir64 (dirp)
+
+#define glob_t glob64_t
+#define glob(pattern, flags, errfunc, pglob) \
+ __old_glob64 (pattern, flags, errfunc, pglob)
+#define globfree(pglob) globfree64(pglob)
+
+#define convert_dirent __old_convert_dirent
+#define glob_in_dir __old_glob_in_dir
+
+#undef stat
+#define stat stat64
+#undef __stat
+#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
+
+#define GLOB_ATTRIBUTE attribute_compat_text_section
+
+#include <posix/glob.c>
+
+libc_hidden_def (__old_glob64);
+
+compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
deleted file mode 100644
index 82a9a296a7..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/preadv2.c b/sysdeps/unix/sysv/linux/preadv2.c
index 11fe85eaa8..137e2dd791 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:
@@ -46,7 +46,7 @@ preadv2 (int fd, const struct iovec *vector, int count, off_t offset,
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
return preadv (fd, vector, count, offset);
diff --git a/sysdeps/unix/sysv/linux/preadv64v2.c b/sysdeps/unix/sysv/linux/preadv64v2.c
index 9d7f8c9893..8f413253f4 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:
@@ -44,7 +44,7 @@ preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
return preadv64 (fd, vector, count, offset);
diff --git a/sysdeps/unix/sysv/linux/pwritev2.c b/sysdeps/unix/sysv/linux/pwritev2.c
index 72f0471f96..8e5032fe2f 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:
@@ -42,7 +42,7 @@ pwritev2 (int fd, const struct iovec *vector, int count, off_t offset,
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
return pwritev (fd, vector, count, offset);
diff --git a/sysdeps/unix/sysv/linux/pwritev64v2.c b/sysdeps/unix/sysv/linux/pwritev64v2.c
index def9a0bc57..d2800c6657 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:
@@ -44,7 +44,7 @@ pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
if (flags != 0)
{
- __set_errno (EOPNOTSUPP);
+ __set_errno (ENOTSUP);
return -1;
}
return pwritev64 (fd, vector, count, offset);
diff --git a/sysdeps/unix/sysv/linux/s390/pt-longjmp.c b/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
index d324237edd..0221ac2cf5 100644
--- a/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
+++ b/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
@@ -26,8 +26,8 @@
/* In glibc release 2.19 new versions of longjmp-functions were introduced,
but were reverted before 2.20. Thus both versions are the same function. */
-strong_alias (longjmp_ifunc, __v2longjmp)
+strong_alias (longjmp_alias, __v2longjmp)
compat_symbol (libpthread, __v2longjmp, longjmp, GLIBC_2_19);
-strong_alias (siglongjmp_ifunc, __v2siglongjmp)
+strong_alias (siglongjmp_alias, __v2siglongjmp)
compat_symbol (libpthread, __v2siglongjmp, siglongjmp, GLIBC_2_19);
#endif /* SHLIB_COMPAT (libpthread, GLIBC_2_19, GLIBC_2_20)) */
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c b/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
new file mode 100644
index 0000000000..d220e22e30
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
@@ -0,0 +1,2 @@
+#define GLOB_NO_OLD_VERSION
+#include <sysdeps/unix/sysv/linux/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c b/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
new file mode 100644
index 0000000000..56d7d12ea6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
@@ -0,0 +1,2 @@
+#define GLOB_NO_OLD_VERSION
+#include <sysdeps/unix/sysv/linux/oldglob.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/long-double.h b/sysdeps/unix/sysv/linux/sparc/sparc32/bits/long-double.h
similarity index 100%
rename from sysdeps/unix/sysv/linux/sparc/bits/long-double.h
rename to sysdeps/unix/sysv/linux/sparc/sparc32/bits/long-double.h
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c b/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
deleted file mode 100644
index 82a9a296a7..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/long-double.h b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/long-double.h
new file mode 100644
index 0000000000..094e05124b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/long-double.h
@@ -0,0 +1,26 @@
+/* Properties of long double type. SPARC version.
+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <bits/wordsize.h>
+
+#if !defined __NO_LONG_DOUBLE_MATH && __WORDSIZE == 32
+# define __LONG_DOUBLE_MATH_OPTIONAL 1
+# ifndef __LONG_DOUBLE_128__
+# define __NO_LONG_DOUBLE_MATH 1
+# endif
+#endif
diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
index c56f894a82..7d23df84d2 100644
--- a/sysdeps/unix/sysv/linux/spawni.c
+++ b/sysdeps/unix/sysv/linux/spawni.c
@@ -17,7 +17,6 @@
<http://www.gnu.org/licenses/>. */
#include <spawn.h>
-#include <assert.h>
#include <fcntl.h>
#include <paths.h>
#include <string.h>
@@ -268,7 +267,6 @@ __spawni_child (void *arguments)
__sigprocmask (SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
? &attr->__ss : &args->oldmask, 0);
- args->err = 0;
args->exec (args->file, args->argv, args->envp);
/* This is compatibility function required to enable posix_spawn run
@@ -339,7 +337,7 @@ __spawnix (pid_t * pid, const char *file,
/* Child must set args.err to something non-negative - we rely on
the parent and child sharing VM. */
- args.err = -1;
+ args.err = 0;
args.file = file;
args.exec = exec;
args.fa = file_actions;
@@ -362,12 +360,26 @@ __spawnix (pid_t * pid, const char *file,
new_pid = CLONE (__spawni_child, STACK (stack, stack_size), stack_size,
CLONE_VM | CLONE_VFORK | SIGCHLD, &args);
+ /* It needs to collect the case where the auxiliary process was created
+ but failed to execute the file (due either any preparation step or
+ for execve itself). */
if (new_pid > 0)
{
+ /* Also, it handles the unlikely case where the auxiliary process was
+ terminated before calling execve as if it was successfully. The
+ args.err is set to 0 as default and changed to a positive value
+ only in case of failure, so in case of premature termination
+ due a signal args.err will remain zeroed and it will be up to
+ caller to actually collect it. */
ec = args.err;
- assert (ec >= 0);
- if (ec != 0)
- __waitpid (new_pid, NULL, 0);
+ if (ec > 0)
+ /* There still an unlikely case where the child is cancelled after
+ setting args.err, due to a positive error value. Also there is
+ possible pid reuse race (where the kernel allocated the same pid
+ to an unrelated process). Unfortunately due synchronization
+ issues where the kernel might not have the process collected
+ the waitpid below can not use WNOHANG. */
+ __waitpid (new_pid, NULL, 0);
}
else
ec = -new_pid;
diff --git a/sysdeps/unix/sysv/linux/tst-sysconf-iov_max-uapi.c b/sysdeps/unix/sysv/linux/tst-sysconf-iov_max-uapi.c
new file mode 100644
index 0000000000..1240b846e6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sysconf-iov_max-uapi.c
@@ -0,0 +1,27 @@
+/* Check IOV_MAX definition: Helper function to capture UAPI header value.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Use a separate function to avoid header compatibility issues. */
+
+#include <linux/uio.h>
+
+long
+uio_maxiov_value (void)
+{
+ return UIO_MAXIOV;
+}
diff --git a/sysdeps/unix/sysv/linux/tst-sysconf-iov_max.c b/sysdeps/unix/sysv/linux/tst-sysconf-iov_max.c
new file mode 100644
index 0000000000..dfdf3da484
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sysconf-iov_max.c
@@ -0,0 +1,40 @@
+/* Check IOV_MAX definition for consistency (bug 22321).
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Defined in tst-sysconf-iov_max-uapi.c. */
+long uio_maxiov_value (void);
+
+
+#include <limits.h>
+#include <support/check.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+ TEST_VERIFY (_XOPEN_IOV_MAX == 16); /* Value required by POSIX. */
+ TEST_VERIFY (uio_maxiov_value () >= _XOPEN_IOV_MAX);
+ TEST_VERIFY (IOV_MAX == uio_maxiov_value ());
+ TEST_VERIFY (UIO_MAXIOV == uio_maxiov_value ());
+ TEST_VERIFY (sysconf (_SC_UIO_MAXIOV) == uio_maxiov_value ());
+ TEST_VERIFY (sysconf (_SC_IOV_MAX) == uio_maxiov_value ());
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/tst-ttyname.c b/sysdeps/unix/sysv/linux/tst-ttyname.c
new file mode 100644
index 0000000000..6848a6d3e2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-ttyname.c
@@ -0,0 +1,577 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+
+/* generic utilities */
+
+#define VERIFY(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ printf ("error: %s:%d: %s: %m\n", \
+ __FILE__, __LINE__, #expr); \
+ exit (1); \
+ } \
+ } while (0)
+
+static void
+touch (const char *path, mode_t mode)
+{
+ xclose (xopen (path, O_WRONLY|O_CREAT|O_NOCTTY, mode));
+}
+
+static size_t
+trim_prefix (char *str, size_t str_len, const char *prefix)
+{
+ size_t prefix_len = strlen (prefix);
+ if (str_len > prefix_len && memcmp (str, prefix, prefix_len) == 0)
+ {
+ memmove (str, str + prefix_len, str_len - prefix_len);
+ return str_len - prefix_len;
+ }
+ return str_len;
+}
+
+/* returns a pointer to static storage */
+static char *
+proc_fd_readlink (const char *linkname)
+{
+ static char target[PATH_MAX+1];
+ ssize_t target_len = readlink (linkname, target, PATH_MAX);
+ VERIFY (target_len > 0);
+ target_len = trim_prefix (target, target_len, "(unreachable)");
+ target[target_len] = '\0';
+ return target;
+}
+
+/* plain ttyname runner */
+
+struct result
+{
+ const char *name;
+ int err;
+};
+
+/* strings in result structure are in static storage */
+static struct result
+run_ttyname (int fd)
+{
+ struct result ret;
+ errno = 0;
+ ret.name = ttyname (fd);
+ ret.err = errno;
+ return ret;
+}
+
+static bool
+eq_ttyname (struct result actual, struct result expected)
+{
+ char *actual_name, *expected_name;
+
+ if ((actual.err == expected.err) &&
+ (!actual.name == !expected.name) &&
+ (actual.name ? strcmp (actual.name, expected.name) == 0 : true))
+ {
+ if (expected.name)
+ expected_name = xasprintf ("\"%s\"", expected.name);
+ else
+ expected_name = xstrdup ("NULL");
+
+ printf ("info: ttyname: PASS {name=%s, errno=%d}\n",
+ expected_name, expected.err);
+
+ free (expected_name);
+ return true;
+ }
+
+ if (actual.name)
+ actual_name = xasprintf ("\"%s\"", actual.name);
+ else
+ actual_name = xstrdup ("NULL");
+
+ if (expected.name)
+ expected_name = xasprintf ("\"%s\"", expected.name);
+ else
+ expected_name = xstrdup ("NULL");
+
+ printf ("error: ttyname: actual {name=%s, errno=%d} != expected {name=%s, errno=%d}\n",
+ actual_name, actual.err,
+ expected_name, expected.err);
+
+ free (actual_name);
+ free (expected_name);
+ return false;
+}
+
+/* ttyname_r runner */
+
+struct result_r
+{
+ const char *name;
+ int ret;
+ int err;
+};
+
+/* strings in result structure are in static storage */
+static struct result_r
+run_ttyname_r (int fd)
+{
+ static char buf[TTY_NAME_MAX];
+
+ struct result_r ret;
+ errno = 0;
+ ret.ret = ttyname_r (fd, buf, TTY_NAME_MAX);
+ ret.err = errno;
+ if (ret.ret == 0)
+ ret.name = buf;
+ else
+ ret.name = NULL;
+ return ret;
+}
+
+static bool
+eq_ttyname_r (struct result_r actual, struct result_r expected)
+{
+ char *actual_name, *expected_name;
+
+ if ((actual.err == expected.err) &&
+ (actual.ret == expected.ret) &&
+ (!actual.name == !expected.name) &&
+ (actual.name ? strcmp (actual.name, expected.name) == 0 : true))
+ {
+ if (expected.name)
+ expected_name = xasprintf ("\"%s\"", expected.name);
+ else
+ expected_name = xstrdup ("NULL");
+
+ printf ("info: ttyname_r: PASS {name=%s, ret=%d, errno=%d}\n",
+ expected_name, expected.ret, expected.err);
+
+ free (expected_name);
+ return true;
+ }
+
+ if (actual.name)
+ actual_name = xasprintf ("\"%s\"", actual.name);
+ else
+ actual_name = xstrdup ("NULL");
+
+ if (expected.name)
+ expected_name = xasprintf ("\"%s\"", expected.name);
+ else
+ expected_name = xstrdup ("NULL");
+
+ printf ("error: ttyname_r: actual {name=%s, ret=%d, errno=%d} != expected {name=%s, ret=%d, errno=%d}\n",
+ actual_name, actual.ret, actual.err,
+ expected_name, expected.ret, expected.err);
+
+ free (actual_name);
+ free (expected_name);
+ return false;
+}
+
+/* combined runner */
+
+static bool
+doit (int fd, const char *testname, struct result_r expected_r)
+{
+ struct result expected = {.name=expected_r.name, .err=expected_r.ret};
+ bool ret = true;
+
+ printf ("info: testcase: %s\n", testname);
+
+ if (!eq_ttyname (run_ttyname (fd), expected))
+ ret = false;
+ if (!eq_ttyname_r (run_ttyname_r (fd), expected_r))
+ ret = false;
+
+ if (!ret)
+ support_record_failure ();
+
+ return ret;
+}
+
+/* chroot setup */
+
+static char *chrootdir;
+
+static void
+prepare (int argc, char **argv)
+{
+ chrootdir = xasprintf ("%s/tst-ttyname-XXXXXX", test_dir);
+ if (mkdtemp (chrootdir) == NULL)
+ FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", chrootdir);
+ add_temp_file (chrootdir);
+}
+#define PREPARE prepare
+
+/* These chroot setup functions put the TTY at at "/console" (where it
+ won't be found by ttyname), and create "/dev/console" as an
+ ordinary file. This way, it's easier to write test-cases that
+ expect ttyname to fail; test-cases that expect it to succeed need
+ to explicitly remount it at "/dev/console". */
+
+static int
+do_in_chroot_1 (int (*cb)(const char *, int))
+{
+ printf ("info: entering chroot 1\n");
+
+ /* Open the PTS that we'll be testing on. */
+ int master;
+ char *slavename;
+ master = posix_openpt (O_RDWR|O_NOCTTY|O_NONBLOCK);
+ if (master < 0)
+ {
+ if (errno == ENOENT)
+ FAIL_UNSUPPORTED ("posix_openpt: %m");
+ else
+ FAIL_EXIT1 ("posix_openpt: %m");
+ }
+ VERIFY ((slavename = ptsname (master)));
+ VERIFY (unlockpt (master) == 0);
+ if (strncmp (slavename, "/dev/pts/", 9) != 0)
+ FAIL_UNSUPPORTED ("slave pseudo-terminal is not under /dev/pts/: %s",
+ slavename);
+ int slave = xopen (slavename, O_RDWR, 0);
+ if (!doit (slave, "basic smoketest",
+ (struct result_r){.name=slavename, .ret=0, .err=0}))
+ return 1;
+
+ pid_t pid = xfork ();
+ if (pid == 0)
+ {
+ xclose (master);
+
+ if (!support_enter_mount_namespace ())
+ FAIL_UNSUPPORTED ("could not enter new mount namespace");
+
+ VERIFY (mount ("tmpfs", chrootdir, "tmpfs", 0, "mode=755") == 0);
+ VERIFY (chdir (chrootdir) == 0);
+
+ xmkdir ("proc", 0755);
+ xmkdir ("dev", 0755);
+ xmkdir ("dev/pts", 0755);
+
+ VERIFY (mount ("/proc", "proc", NULL, MS_BIND|MS_REC, NULL) == 0);
+ VERIFY (mount ("devpts", "dev/pts", "devpts",
+ MS_NOSUID|MS_NOEXEC,
+ "newinstance,ptmxmode=0666,mode=620") == 0);
+ VERIFY (symlink ("pts/ptmx", "dev/ptmx") == 0);
+
+ touch ("console", 0);
+ touch ("dev/console", 0);
+ VERIFY (mount (slavename, "console", NULL, MS_BIND, NULL) == 0);
+
+ xchroot (".");
+
+ char *linkname = xasprintf ("/proc/self/fd/%d", slave);
+ char *target = proc_fd_readlink (linkname);
+ VERIFY (strcmp (target, slavename) == 0);
+ free (linkname);
+
+ _exit (cb (slavename, slave));
+ }
+ int status;
+ xwaitpid (pid, &status, 0);
+ VERIFY (WIFEXITED (status));
+ xclose (master);
+ xclose (slave);
+ return WEXITSTATUS (status);
+}
+
+static int
+do_in_chroot_2 (int (*cb)(const char *, int))
+{
+ printf ("info: entering chroot 2\n");
+
+ int pid_pipe[2];
+ xpipe (pid_pipe);
+ int exit_pipe[2];
+ xpipe (exit_pipe);
+
+ /* Open the PTS that we'll be testing on. */
+ int master;
+ char *slavename;
+ VERIFY ((master = posix_openpt (O_RDWR|O_NOCTTY|O_NONBLOCK)) >= 0);
+ VERIFY ((slavename = ptsname (master)));
+ VERIFY (unlockpt (master) == 0);
+ if (strncmp (slavename, "/dev/pts/", 9) != 0)
+ FAIL_UNSUPPORTED ("slave pseudo-terminal is not under /dev/pts/: %s",
+ slavename);
+ /* wait until in a new mount ns to open the slave */
+
+ /* enable `wait`ing on grandchildren */
+ VERIFY (prctl (PR_SET_CHILD_SUBREAPER, 1) == 0);
+
+ pid_t pid = xfork (); /* outer child */
+ if (pid == 0)
+ {
+ xclose (master);
+ xclose (pid_pipe[0]);
+ xclose (exit_pipe[1]);
+
+ if (!support_enter_mount_namespace ())
+ FAIL_UNSUPPORTED ("could not enter new mount namespace");
+
+ int slave = xopen (slavename, O_RDWR, 0);
+ if (!doit (slave, "basic smoketest",
+ (struct result_r){.name=slavename, .ret=0, .err=0}))
+ _exit (1);
+
+ VERIFY (mount ("tmpfs", chrootdir, "tmpfs", 0, "mode=755") == 0);
+ VERIFY (chdir (chrootdir) == 0);
+
+ xmkdir ("proc", 0755);
+ xmkdir ("dev", 0755);
+ xmkdir ("dev/pts", 0755);
+
+ VERIFY (mount ("devpts", "dev/pts", "devpts",
+ MS_NOSUID|MS_NOEXEC,
+ "newinstance,ptmxmode=0666,mode=620") == 0);
+ VERIFY (symlink ("pts/ptmx", "dev/ptmx") == 0);
+
+ touch ("console", 0);
+ touch ("dev/console", 0);
+ VERIFY (mount (slavename, "console", NULL, MS_BIND, NULL) == 0);
+
+ xchroot (".");
+
+ if (unshare (CLONE_NEWNS | CLONE_NEWPID) < 0)
+ FAIL_UNSUPPORTED ("could not enter new PID namespace");
+ pid = xfork (); /* inner child */
+ if (pid == 0)
+ {
+ xclose (pid_pipe[1]);
+
+ /* wait until the outer child has exited */
+ char c;
+ VERIFY (read (exit_pipe[0], &c, 1) == 0);
+ xclose (exit_pipe[0]);
+
+ VERIFY (mount ("proc", "/proc", "proc",
+ MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) == 0);
+
+ char *linkname = xasprintf ("/proc/self/fd/%d", slave);
+ char *target = proc_fd_readlink (linkname);
+ VERIFY (strcmp (target, strrchr (slavename, '/')) == 0);
+ free (linkname);
+
+ _exit (cb (slavename, slave));
+ }
+ xwrite (pid_pipe[1], &pid, sizeof pid);
+ _exit (0);
+ }
+ xclose (pid_pipe[1]);
+ xclose (exit_pipe[0]);
+ xclose (exit_pipe[1]);
+
+ /* wait for the outer child */
+ int status;
+ xwaitpid (pid, &status, 0);
+ VERIFY (WIFEXITED (status));
+ int ret = WEXITSTATUS (status);
+ if (ret != 0)
+ return ret;
+
+ /* set 'pid' to the inner child */
+ VERIFY (read (pid_pipe[0], &pid, sizeof pid) == sizeof pid);
+ xclose (pid_pipe[0]);
+
+ /* wait for the inner child */
+ xwaitpid (pid, &status, 0);
+ VERIFY (WIFEXITED (status));
+ xclose (master);
+ return WEXITSTATUS (status);
+}
+
+/* main test */
+
+static int
+run_chroot_tests (const char *slavename, int slave)
+{
+ struct stat st;
+ bool ok = true;
+
+ /* There are 3 groups of tests here. The first group fairly
+ generically does things known to mess up ttyname, and verifies
+ that ttyname copes correctly. The remaining groups are
+ increasingly convoluted, as we target specific parts of ttyname
+ to try to confuse. */
+
+ /* Basic tests that it doesn't get confused by multiple devpts
+ instances. */
+ {
+ VERIFY (stat (slavename, &st) < 0); /* sanity check */
+ if (!doit (slave, "no conflict, no match",
+ (struct result_r){.name=NULL, .ret=ENODEV, .err=ENODEV}))
+ ok = false;
+ VERIFY (mount ("/console", "/dev/console", NULL, MS_BIND, NULL) == 0);
+ if (!doit (slave, "no conflict, console",
+ (struct result_r){.name="/dev/console", .ret=0, .err=0}))
+ ok = false;
+ VERIFY (umount ("/dev/console") == 0);
+
+ /* keep creating PTYs until we we get a name collision */
+ while (stat (slavename, &st) < 0)
+ posix_openpt (O_RDWR|O_NOCTTY|O_NONBLOCK);
+ VERIFY (stat (slavename, &st) == 0);
+
+ if (!doit (slave, "conflict, no match",
+ (struct result_r){.name=NULL, .ret=ENODEV, .err=ENODEV}))
+ ok = false;
+ VERIFY (mount ("/console", "/dev/console", NULL, MS_BIND, NULL) == 0);
+ if (!doit (slave, "conflict, console",
+ (struct result_r){.name="/dev/console", .ret=0, .err=0}))
+ ok = false;
+ VERIFY (umount ("/dev/console") == 0);
+ }
+
+ /* The first tests kinda assumed that they hit certain code-paths
+ based on assuming that the readlink target is 'slavename', but
+ that's not quite always true. They're still a good preliminary
+ sanity check, so keep them, but let's add tests that make sure
+ that those code-paths are hit by doing a readlink ourself. */
+ {
+ char *linkname = xasprintf ("/proc/self/fd/%d", slave);
+ char *target = proc_fd_readlink (linkname);
+ free (linkname);
+ /* Depeding on how we set up the chroot, the kernel may or may not
+ trim the leading path to the target (it may give us "/6",
+ instead of "/dev/pts/6"). We test it both ways (do_in_chroot_1
+ and do_in_chroot_2). This test group relies on the target
+ existing, so guarantee that it does exist by creating it if
+ necessary. */
+ if (stat (target, &st) < 0)
+ {
+ VERIFY (errno == ENOENT);
+ touch (target, 0);
+ }
+
+ VERIFY (mount ("/console", "/dev/console", NULL, MS_BIND, NULL) == 0);
+ VERIFY (mount ("/console", target, NULL, MS_BIND, NULL) == 0);
+ if (!doit (slave, "with readlink target",
+ (struct result_r){.name=target, .ret=0, .err=0}))
+ ok = false;
+ VERIFY (umount (target) == 0);
+ VERIFY (umount ("/dev/console") == 0);
+
+ VERIFY (mount ("/console", "/dev/console", NULL, MS_BIND, NULL) == 0);
+ VERIFY (mount (slavename, target, NULL, MS_BIND, NULL) == 0);
+ if (!doit (slave, "with readlink trap; fallback",
+ (struct result_r){.name="/dev/console", .ret=0, .err=0}))
+ ok = false;
+ VERIFY (umount (target) == 0);
+ VERIFY (umount ("/dev/console") == 0);
+
+ VERIFY (mount (slavename, target, NULL, MS_BIND, NULL) == 0);
+ if (!doit (slave, "with readlink trap; no fallback",
+ (struct result_r){.name=NULL, .ret=ENODEV, .err=ENODEV}))
+ ok = false;
+ VERIFY (umount (target) == 0);
+ }
+
+ /* This test makes sure that everything still works OK if readdir
+ finds a pseudo-match before and/or after the actual match. Now,
+ to do that, we need to control that readdir finds the
+ pseudo-matches before and after the actual match; and there's no
+ good way to control that order in absence of whitebox testing.
+ So, just create 3 files, then use opendir/readdir to see what
+ order they are in, and assign meaning based on that order, not by
+ name; assigning the first to be a pseudo-match, the second to be
+ the actual match, and the third to be a pseudo-match. This
+ assumes that (on tmpfs) ordering within the directory is stable
+ in the absence of modification, which seems reasonably safe. */
+ {
+ /* since we're testing the fallback search, disable the readlink
+ happy-path */
+ VERIFY (umount2 ("/proc", MNT_DETACH) == 0);
+
+ touch ("/dev/console1", 0);
+ touch ("/dev/console2", 0);
+ touch ("/dev/console3", 0);
+
+ char *c[3];
+ int ci = 0;
+ DIR *dirstream = opendir ("/dev");
+ VERIFY (dirstream != NULL);
+ struct dirent *d;
+ while ((d = readdir (dirstream)) != NULL && ci < 3)
+ {
+ if (strcmp (d->d_name, "console1") &&
+ strcmp (d->d_name, "console2") &&
+ strcmp (d->d_name, "console3") )
+ continue;
+ c[ci++] = xasprintf ("/dev/%s", d->d_name);
+ }
+ VERIFY (ci == 3);
+ VERIFY (closedir (dirstream) == 0);
+
+ VERIFY (mount (slavename, c[0], NULL, MS_BIND, NULL) == 0);
+ VERIFY (mount ("/console", c[1], NULL, MS_BIND, NULL) == 0);
+ VERIFY (mount (slavename, c[2], NULL, MS_BIND, NULL) == 0);
+ VERIFY (umount2 ("/dev/pts", MNT_DETACH) == 0);
+ if (!doit (slave, "with search-path trap",
+ (struct result_r){.name=c[1], .ret=0, .err=0}))
+ ok = false;
+ for (int i = 0; i < 3; i++)
+ {
+ VERIFY (umount (c[i]) == 0);
+ VERIFY (unlink (c[i]) == 0);
+ free (c[i]);
+ }
+ }
+
+ return ok ? 0 : 1;
+}
+
+static int
+do_test (void)
+{
+ support_become_root ();
+
+ int ret1 = do_in_chroot_1 (run_chroot_tests);
+ if (ret1 == EXIT_UNSUPPORTED)
+ return ret1;
+
+ int ret2 = do_in_chroot_2 (run_chroot_tests);
+ if (ret2 == EXIT_UNSUPPORTED)
+ return ret2;
+
+ return ret1 | ret2;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/ttyname.c b/sysdeps/unix/sysv/linux/ttyname.c
index 5909cb765f..f4c955f25b 100644
--- a/sysdeps/unix/sysv/linux/ttyname.c
+++ b/sysdeps/unix/sysv/linux/ttyname.c
@@ -35,16 +35,14 @@
char *__ttyname;
#endif
-static char *getttyname (const char *dev, dev_t mydev,
- ino64_t myino, int save, int *dostat)
- internal_function;
-
+static char *getttyname (const char *dev, const struct stat64 *mytty,
+ int save, int *dostat);
libc_freeres_ptr (static char *getttyname_name);
static char *
-internal_function attribute_compat_text_section
-getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat)
+attribute_compat_text_section
+getttyname (const char *dev, const struct stat64 *mytty, int save, int *dostat)
{
static size_t namelen;
struct stat64 st;
@@ -65,7 +63,7 @@ getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat)
*((char *) __mempcpy (getttyname_name, dev, devlen - 1)) = '/';
while ((d = __readdir64 (dirstream)) != NULL)
- if ((d->d_fileno == myino || *dostat)
+ if ((d->d_fileno == mytty->st_ino || *dostat)
&& strcmp (d->d_name, "stdin")
&& strcmp (d->d_name, "stdout")
&& strcmp (d->d_name, "stderr"))
@@ -87,12 +85,7 @@ getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat)
}
memcpy (&getttyname_name[devlen], d->d_name, dlen);
if (__xstat64 (_STAT_VER, getttyname_name, &st) == 0
-#ifdef _STATBUF_ST_RDEV
- && S_ISCHR (st.st_mode) && st.st_rdev == mydev
-#else
- && d->d_fileno == myino && st.st_dev == mydev
-#endif
- )
+ && is_mytty (mytty, &st))
{
(void) __closedir (dirstream);
#if 0
@@ -122,6 +115,7 @@ ttyname (int fd)
char procname[30];
struct stat64 st, st1;
int dostat = 0;
+ int doispty = 0;
char *name;
int save = errno;
struct termios term;
@@ -169,30 +163,15 @@ ttyname (int fd)
/* Verify readlink result, fall back on iterating through devices. */
if (ttyname_buf[0] == '/'
&& __xstat64 (_STAT_VER, ttyname_buf, &st1) == 0
-#ifdef _STATBUF_ST_RDEV
- && S_ISCHR (st1.st_mode)
- && st1.st_rdev == st.st_rdev
-#endif
- && st1.st_ino == st.st_ino
- && st1.st_dev == st.st_dev)
+ && is_mytty (&st, &st1))
return ttyname_buf;
- /* If the link doesn't exist, then it points to a device in another
- namespace. */
- if (is_pty (&st))
- {
- __set_errno (ENODEV);
- return NULL;
- }
+ doispty = 1;
}
if (__xstat64 (_STAT_VER, "/dev/pts", &st1) == 0 && S_ISDIR (st1.st_mode))
{
-#ifdef _STATBUF_ST_RDEV
- name = getttyname ("/dev/pts", st.st_rdev, st.st_ino, save, &dostat);
-#else
- name = getttyname ("/dev/pts", st.st_dev, st.st_ino, save, &dostat);
-#endif
+ name = getttyname ("/dev/pts", &st, save, &dostat);
}
else
{
@@ -202,21 +181,23 @@ ttyname (int fd)
if (!name && dostat != -1)
{
-#ifdef _STATBUF_ST_RDEV
- name = getttyname ("/dev", st.st_rdev, st.st_ino, save, &dostat);
-#else
- name = getttyname ("/dev", st.st_dev, st.st_ino, save, &dostat);
-#endif
+ name = getttyname ("/dev", &st, save, &dostat);
}
if (!name && dostat != -1)
{
dostat = 1;
-#ifdef _STATBUF_ST_RDEV
- name = getttyname ("/dev", st.st_rdev, st.st_ino, save, &dostat);
-#else
- name = getttyname ("/dev", st.st_dev, st.st_ino, save, &dostat);
-#endif
+ name = getttyname ("/dev", &st, save, &dostat);
+ }
+
+ if (!name && doispty && is_pty (&st))
+ {
+ /* We failed to figure out the TTY's name, but we can at least
+ signal that we did verify that it really is a PTY slave.
+ This happens when we have inherited the file descriptor from
+ a different mount namespace. */
+ __set_errno (ENODEV);
+ return NULL;
}
return name;
diff --git a/sysdeps/unix/sysv/linux/ttyname.h b/sysdeps/unix/sysv/linux/ttyname.h
index 2e415e4e9c..48181330a9 100644
--- a/sysdeps/unix/sysv/linux/ttyname.h
+++ b/sysdeps/unix/sysv/linux/ttyname.h
@@ -16,13 +16,15 @@
not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h>
+#include <stdbool.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/stat.h>
/* Return true if this is a UNIX98 pty device, as defined in
- linux/Documentation/devices.txt. */
-static inline int
+ linux/Documentation/devices.txt (on linux < 4.10) or
+ linux/Documentation/admin-guide/devices.txt (on linux >= 4.10). */
+static inline bool
is_pty (struct stat64 *sb)
{
#ifdef _STATBUF_ST_RDEV
@@ -32,3 +34,15 @@ is_pty (struct stat64 *sb)
return false;
#endif
}
+
+static inline bool
+is_mytty (const struct stat64 *mytty, const struct stat64 *maybe)
+{
+ return (maybe->st_ino == mytty->st_ino
+ && maybe->st_dev == mytty->st_dev
+#ifdef _STATBUF_ST_RDEV
+ && S_ISCHR (maybe->st_mode)
+ && maybe->st_rdev == mytty->st_rdev
+#endif
+ );
+}
diff --git a/sysdeps/unix/sysv/linux/ttyname_r.c b/sysdeps/unix/sysv/linux/ttyname_r.c
index dc863526ba..00eefc2c5c 100644
--- a/sysdeps/unix/sysv/linux/ttyname_r.c
+++ b/sysdeps/unix/sysv/linux/ttyname_r.c
@@ -31,12 +31,12 @@
#include "ttyname.h"
static int getttyname_r (char *buf, size_t buflen,
- dev_t mydev, ino64_t myino, int save,
- int *dostat) internal_function;
+ const struct stat64 *mytty, int save,
+ int *dostat);
static int
-internal_function attribute_compat_text_section
-getttyname_r (char *buf, size_t buflen, dev_t mydev, ino64_t myino,
+attribute_compat_text_section
+getttyname_r (char *buf, size_t buflen, const struct stat64 *mytty,
int save, int *dostat)
{
struct stat64 st;
@@ -52,7 +52,7 @@ getttyname_r (char *buf, size_t buflen, dev_t mydev, ino64_t myino,
}
while ((d = __readdir64 (dirstream)) != NULL)
- if ((d->d_fileno == myino || *dostat)
+ if ((d->d_fileno == mytty->st_ino || *dostat)
&& strcmp (d->d_name, "stdin")
&& strcmp (d->d_name, "stdout")
&& strcmp (d->d_name, "stderr"))
@@ -72,12 +72,7 @@ getttyname_r (char *buf, size_t buflen, dev_t mydev, ino64_t myino,
cp[0] = '\0';
if (__xstat64 (_STAT_VER, buf, &st) == 0
-#ifdef _STATBUF_ST_RDEV
- && S_ISCHR (st.st_mode) && st.st_rdev == mydev
-#else
- && d->d_fileno == myino && st.st_dev == mydev
-#endif
- )
+ && is_mytty (mytty, &st))
{
(void) __closedir (dirstream);
__set_errno (save);
@@ -100,6 +95,7 @@ __ttyname_r (int fd, char *buf, size_t buflen)
char procname[30];
struct stat64 st, st1;
int dostat = 0;
+ int doispty = 0;
int save = errno;
/* Test for the absolute minimal size. This makes life easier inside
@@ -151,22 +147,10 @@ __ttyname_r (int fd, char *buf, size_t buflen)
/* Verify readlink result, fall back on iterating through devices. */
if (buf[0] == '/'
&& __xstat64 (_STAT_VER, buf, &st1) == 0
-#ifdef _STATBUF_ST_RDEV
- && S_ISCHR (st1.st_mode)
- && st1.st_rdev == st.st_rdev
-#endif
- && st1.st_ino == st.st_ino
- && st1.st_dev == st.st_dev)
+ && is_mytty (&st, &st1))
return 0;
- /* If the link doesn't exist, then it points to a device in another
- * namespace.
- */
- if (is_pty (&st))
- {
- __set_errno (ENODEV);
- return ENODEV;
- }
+ doispty = 1;
}
/* Prepare the result buffer. */
@@ -175,13 +159,8 @@ __ttyname_r (int fd, char *buf, size_t buflen)
if (__xstat64 (_STAT_VER, buf, &st1) == 0 && S_ISDIR (st1.st_mode))
{
-#ifdef _STATBUF_ST_RDEV
- ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save,
+ ret = getttyname_r (buf, buflen, &st, save,
&dostat);
-#else
- ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save,
- &dostat);
-#endif
}
else
{
@@ -193,26 +172,26 @@ __ttyname_r (int fd, char *buf, size_t buflen)
{
buf[sizeof ("/dev/") - 1] = '\0';
buflen += sizeof ("pts/") - 1;
-#ifdef _STATBUF_ST_RDEV
- ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save,
- &dostat);
-#else
- ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save,
+ ret = getttyname_r (buf, buflen, &st, save,
&dostat);
-#endif
}
if (ret && dostat != -1)
{
buf[sizeof ("/dev/") - 1] = '\0';
dostat = 1;
-#ifdef _STATBUF_ST_RDEV
- ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino,
+ ret = getttyname_r (buf, buflen, &st,
save, &dostat);
-#else
- ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino,
- save, &dostat);
-#endif
+ }
+
+ if (ret && doispty && is_pty (&st))
+ {
+ /* We failed to figure out the TTY's name, but we can at least
+ signal that we did verify that it really is a PTY slave.
+ This happens when we have inherited the file descriptor from
+ a different mount namespace. */
+ __set_errno (ENODEV);
+ return ENODEV;
}
return ret;
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/glob64.c b/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
deleted file mode 100644
index eab7703d5c..0000000000
--- a/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
+++ /dev/null
@@ -1,2 +0,0 @@
-/* This file is here so sysdeps/gnu/glob64.c doesn't take precedence. */
-#include <sysdeps/wordsize-64/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/glob.c b/sysdeps/unix/sysv/linux/x86_64/x32/glob.c
deleted file mode 100644
index e5427475f6..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/x32/glob.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/wordsize-64/glob.c>
diff --git a/sysdeps/wordsize-64/glob.c b/sysdeps/wordsize-64/glob.c
deleted file mode 100644
index 082faf1c70..0000000000
--- a/sysdeps/wordsize-64/glob.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#define glob64 __no_glob64_decl
-#define globfree64 __no_globfree64_decl
-#include <posix/glob.c>
-#undef glob64
-#undef globfree64
-weak_alias (glob, glob64)
-weak_alias (globfree, globfree64)
-libc_hidden_ver (globfree, globfree64)
diff --git a/sysdeps/wordsize-64/glob64.c b/sysdeps/wordsize-64/glob64.c
deleted file mode 100644
index 33918ea6a5..0000000000
--- a/sysdeps/wordsize-64/glob64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* glob64 is in glob.c */
diff --git a/sysdeps/x86/cpu-features-offsets.sym b/sysdeps/x86/cpu-features-offsets.sym
index f6739fae81..33dd094e37 100644
--- a/sysdeps/x86/cpu-features-offsets.sym
+++ b/sysdeps/x86/cpu-features-offsets.sym
@@ -15,6 +15,7 @@ CPUID_ECX_OFFSET offsetof (struct cpuid_registers, ecx)
CPUID_EDX_OFFSET offsetof (struct cpuid_registers, edx)
FAMILY_OFFSET offsetof (struct cpu_features, family)
MODEL_OFFSET offsetof (struct cpu_features, model)
+XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size)
FEATURE_OFFSET offsetof (struct cpu_features, feature)
FEATURE_SIZE sizeof (unsigned int)
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 1d087ea732..87aaa8683c 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -19,6 +19,7 @@
#include <cpuid.h>
#include <cpu-features.h>
#include <dl-hwcap.h>
+#include <libc-pointer-arith.h>
#if HAVE_TUNABLES
# define TUNABLE_NAMESPACE tune
@@ -103,6 +104,76 @@ get_common_indeces (struct cpu_features *cpu_features,
}
}
}
+
+ /* For _dl_runtime_resolve, set xsave_state_size to xsave area
+ size + integer register save size and align it to 64 bytes. */
+ if (cpu_features->max_cpuid >= 0xd)
+ {
+ unsigned int eax, ebx, ecx, edx;
+
+ __cpuid_count (0xd, 0, eax, ebx, ecx, edx);
+ if (ebx != 0)
+ {
+ unsigned int xsave_state_full_size
+ = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64);
+
+ cpu_features->xsave_state_size
+ = xsave_state_full_size;
+ cpu_features->xsave_state_full_size
+ = xsave_state_full_size;
+
+ __cpuid_count (0xd, 1, eax, ebx, ecx, edx);
+
+ /* Check if XSAVEC is available. */
+ if ((eax & (1 << 1)) != 0)
+ {
+ unsigned int xstate_comp_offsets[32];
+ unsigned int xstate_comp_sizes[32];
+ unsigned int i;
+
+ xstate_comp_offsets[0] = 0;
+ xstate_comp_offsets[1] = 160;
+ xstate_comp_offsets[2] = 576;
+ xstate_comp_sizes[0] = 160;
+ xstate_comp_sizes[1] = 256;
+
+ for (i = 2; i < 32; i++)
+ {
+ if ((STATE_SAVE_MASK & (1 << i)) != 0)
+ {
+ __cpuid_count (0xd, i, eax, ebx, ecx, edx);
+ xstate_comp_sizes[i] = eax;
+ }
+ else
+ {
+ ecx = 0;
+ xstate_comp_sizes[i] = 0;
+ }
+
+ if (i > 2)
+ {
+ xstate_comp_offsets[i]
+ = (xstate_comp_offsets[i - 1]
+ + xstate_comp_sizes[i -1]);
+ if ((ecx & (1 << 1)) != 0)
+ xstate_comp_offsets[i]
+ = ALIGN_UP (xstate_comp_offsets[i], 64);
+ }
+ }
+
+ /* Use XSAVEC. */
+ unsigned int size
+ = xstate_comp_offsets[31] + xstate_comp_sizes[31];
+ if (size)
+ {
+ cpu_features->xsave_state_size
+ = ALIGN_UP (size + STATE_SAVE_OFFSET, 64);
+ cpu_features->feature[index_arch_XSAVEC_Usable]
+ |= bit_arch_XSAVEC_Usable;
+ }
+ }
+ }
+ }
}
}
@@ -242,20 +313,6 @@ init_cpu_features (struct cpu_features *cpu_features)
else
cpu_features->feature[index_arch_Prefer_No_AVX512]
|= bit_arch_Prefer_No_AVX512;
-
- /* To avoid SSE transition penalty, use _dl_runtime_resolve_slow.
- If XGETBV suports ECX == 1, use _dl_runtime_resolve_opt. */
- cpu_features->feature[index_arch_Use_dl_runtime_resolve_slow]
- |= bit_arch_Use_dl_runtime_resolve_slow;
- if (cpu_features->max_cpuid >= 0xd)
- {
- unsigned int eax;
-
- __cpuid_count (0xd, 1, eax, ebx, ecx, edx);
- if ((eax & (1 << 2)) != 0)
- cpu_features->feature[index_arch_Use_dl_runtime_resolve_opt]
- |= bit_arch_Use_dl_runtime_resolve_opt;
- }
}
/* This spells out "AuthenticAMD". */
else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
@@ -332,8 +389,6 @@ no_cpuid:
#endif
/* Reuse dl_platform, dl_hwcap and dl_hwcap_mask for x86. */
- GLRO(dl_platform) = NULL;
- GLRO(dl_hwcap) = 0;
#if !HAVE_TUNABLES && defined SHARED
/* The glibc.tune.hwcap_mask tunable is initialized already, so no need to do
this. */
@@ -341,15 +396,18 @@ no_cpuid:
#endif
#ifdef __x86_64__
+ GLRO(dl_hwcap) = HWCAP_X86_64;
if (cpu_features->kind == arch_kind_intel)
{
+ const char *platform = NULL;
+
if (CPU_FEATURES_ARCH_P (cpu_features, AVX512F_Usable)
&& CPU_FEATURES_CPU_P (cpu_features, AVX512CD))
{
if (CPU_FEATURES_CPU_P (cpu_features, AVX512ER))
{
if (CPU_FEATURES_CPU_P (cpu_features, AVX512PF))
- GLRO(dl_platform) = "xeon_phi";
+ platform = "xeon_phi";
}
else
{
@@ -360,7 +418,7 @@ no_cpuid:
}
}
- if (GLRO(dl_platform) == NULL
+ if (platform == NULL
&& CPU_FEATURES_ARCH_P (cpu_features, AVX2_Usable)
&& CPU_FEATURES_ARCH_P (cpu_features, FMA_Usable)
&& CPU_FEATURES_CPU_P (cpu_features, BMI1)
@@ -368,9 +426,13 @@ no_cpuid:
&& CPU_FEATURES_CPU_P (cpu_features, LZCNT)
&& CPU_FEATURES_CPU_P (cpu_features, MOVBE)
&& CPU_FEATURES_CPU_P (cpu_features, POPCNT))
- GLRO(dl_platform) = "haswell";
+ platform = "haswell";
+
+ if (platform != NULL)
+ GLRO(dl_platform) = platform;
}
#else
+ GLRO(dl_hwcap) = 0;
if (CPU_FEATURES_CPU_P (cpu_features, SSE2))
GLRO(dl_hwcap) |= HWCAP_X86_SSE2;
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 3ed67f5800..1d88f7a68c 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -37,9 +37,8 @@
#define bit_arch_Prefer_No_VZEROUPPER (1 << 17)
#define bit_arch_Fast_Unaligned_Copy (1 << 18)
#define bit_arch_Prefer_ERMS (1 << 19)
-#define bit_arch_Use_dl_runtime_resolve_opt (1 << 20)
-#define bit_arch_Use_dl_runtime_resolve_slow (1 << 21)
-#define bit_arch_Prefer_No_AVX512 (1 << 22)
+#define bit_arch_Prefer_No_AVX512 (1 << 20)
+#define bit_arch_XSAVEC_Usable (1 << 21)
/* CPUID Feature flags. */
@@ -88,6 +87,15 @@
/* The current maximum size of the feature integer bit array. */
#define FEATURE_INDEX_MAX 1
+/* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need
+ space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be
+ aligned to 16 bytes for fxsave and 64 bytes for xsave. */
+#define STATE_SAVE_OFFSET (8 * 7 + 8)
+
+/* Save SSE, AVX, AVX512, mask and bound registers. */
+#define STATE_SAVE_MASK \
+ ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7))
+
#ifdef __ASSEMBLER__
# include <cpu-features-offsets.h>
@@ -123,8 +131,6 @@
# define index_arch_Prefer_No_VZEROUPPER FEATURE_INDEX_1*FEATURE_SIZE
# define index_arch_Fast_Unaligned_Copy FEATURE_INDEX_1*FEATURE_SIZE
# define index_arch_Prefer_ERMS FEATURE_INDEX_1*FEATURE_SIZE
-# define index_arch_Use_dl_runtime_resolve_opt FEATURE_INDEX_1*FEATURE_SIZE
-# define index_arch_Use_dl_runtime_resolve_slow FEATURE_INDEX_1*FEATURE_SIZE
# define index_arch_Prefer_No_AVX512 FEATURE_INDEX_1*FEATURE_SIZE
@@ -214,6 +220,18 @@ struct cpu_features
} cpuid[COMMON_CPUID_INDEX_MAX];
unsigned int family;
unsigned int model;
+ /* The state size for XSAVEC or XSAVE. The type must be unsigned long
+ int so that we use
+
+ sub xsave_state_size_offset(%rip) %RSP_LP
+
+ in _dl_runtime_resolve. */
+ unsigned long int xsave_state_size;
+ /* The full state size for XSAVE when XSAVEC is disabled by
+
+ GLIBC_TUNABLES=glibc.tune.hwcaps=-XSAVEC_Usable
+ */
+ unsigned int xsave_state_full_size;
unsigned int feature[FEATURE_INDEX_MAX];
/* Data cache size for use in memory and string routines, typically
L1 size. */
@@ -326,9 +344,8 @@ extern const struct cpu_features *__get_cpu_features (void)
# define index_arch_Prefer_No_VZEROUPPER FEATURE_INDEX_1
# define index_arch_Fast_Unaligned_Copy FEATURE_INDEX_1
# define index_arch_Prefer_ERMS FEATURE_INDEX_1
-# define index_arch_Use_dl_runtime_resolve_opt FEATURE_INDEX_1
-# define index_arch_Use_dl_runtime_resolve_slow FEATURE_INDEX_1
# define index_arch_Prefer_No_AVX512 FEATURE_INDEX_1
+# define index_arch_XSAVEC_Usable FEATURE_INDEX_1
#endif /* !__ASSEMBLER__ */
diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
index 872dd1267f..0488f03d32 100644
--- a/sysdeps/x86/cpu-tunables.c
+++ b/sysdeps/x86/cpu-tunables.c
@@ -240,6 +240,16 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
Slow_SSE4_2, SSE4_2,
disable, 11);
break;
+ case 13:
+ if (disable)
+ {
+ /* Update xsave_state_size to XSAVE state size. */
+ cpu_features->xsave_state_size
+ = cpu_features->xsave_state_full_size;
+ CHECK_GLIBC_IFUNC_ARCH_OFF (n, cpu_features,
+ XSAVEC_Usable, 13);
+ }
+ break;
case 14:
if (disable)
{
@@ -308,13 +318,6 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
disable, 26);
}
break;
- case 27:
- {
- CHECK_GLIBC_IFUNC_ARCH_BOTH (n, cpu_features,
- Use_dl_runtime_resolve_slow,
- disable, 27);
- }
- break;
}
p += len + 1;
}
diff --git a/sysdeps/x86/dl-hwcap.h b/sysdeps/x86/dl-hwcap.h
index c95668415a..38627e9eef 100644
--- a/sysdeps/x86/dl-hwcap.h
+++ b/sysdeps/x86/dl-hwcap.h
@@ -24,15 +24,16 @@
# define HWCAP_PLATFORMS_START 0
# define HWCAP_PLATFORMS_COUNT 4
# define HWCAP_START 0
-# define HWCAP_COUNT 2
-# define HWCAP_IMPORTANT (HWCAP_X86_SSE2 | HWCAP_X86_AVX512_1)
+# define HWCAP_COUNT 3
+# define HWCAP_IMPORTANT \
+ (HWCAP_X86_SSE2 | HWCAP_X86_64 | HWCAP_X86_AVX512_1)
#elif defined __x86_64__
/* For 64 bit, only cover x86-64 platforms and capabilities. */
# define HWCAP_PLATFORMS_START 2
# define HWCAP_PLATFORMS_COUNT 4
# define HWCAP_START 1
-# define HWCAP_COUNT 2
-# define HWCAP_IMPORTANT (HWCAP_X86_AVX512_1)
+# define HWCAP_COUNT 3
+# define HWCAP_IMPORTANT (HWCAP_X86_64 | HWCAP_X86_AVX512_1)
#else
/* For 32 bit, only cover i586, i686 and SSE2. */
# define HWCAP_PLATFORMS_START 0
@@ -45,7 +46,8 @@
enum
{
HWCAP_X86_SSE2 = 1 << 0,
- HWCAP_X86_AVX512_1 = 1 << 1
+ HWCAP_X86_64 = 1 << 1,
+ HWCAP_X86_AVX512_1 = 1 << 2
};
static inline const char *
diff --git a/sysdeps/x86/dl-procinfo.c b/sysdeps/x86/dl-procinfo.c
index 43ab8fe25b..0192feb850 100644
--- a/sysdeps/x86/dl-procinfo.c
+++ b/sysdeps/x86/dl-procinfo.c
@@ -58,11 +58,11 @@ PROCINFO_CLASS struct cpu_features _dl_x86_cpu_features
#if !defined PROCINFO_DECL && defined SHARED
._dl_x86_hwcap_flags
#else
-PROCINFO_CLASS const char _dl_x86_hwcap_flags[2][9]
+PROCINFO_CLASS const char _dl_x86_hwcap_flags[3][9]
#endif
#ifndef PROCINFO_DECL
= {
- "sse2", "avx512_1"
+ "sse2", "x86_64", "avx512_1"
}
#endif
#if !defined SHARED || defined PROCINFO_DECL
diff --git a/sysdeps/x86/nptl/bits/pthreadtypes-arch.h b/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
index fd86806800..74d5f6d6e8 100644
--- a/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/x86/nptl/bits/pthreadtypes-arch.h
@@ -51,6 +51,13 @@
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 1
+#ifdef __x86_64__
+# define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0
+# define __PTHREAD_MUTEX_USE_UNION 0
+#else
+# define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 1
+# define __PTHREAD_MUTEX_USE_UNION 1
+#endif
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
index 132470d9cb..a7e26ac485 100644
--- a/sysdeps/x86_64/Makefile
+++ b/sysdeps/x86_64/Makefile
@@ -52,6 +52,31 @@ $(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o
CFLAGS-tst-quad1pie.c = $(PIE-ccflag)
CFLAGS-tst-quad2pie.c = $(PIE-ccflag)
+tests += tst-x86_64-1
+modules-names += x86_64/tst-x86_64mod-1
+LDFLAGS-tst-x86_64mod-1.so = -Wl,-soname,tst-x86_64mod-1.so
+ifneq (no,$(have-tunables))
+# Test the state size for XSAVE when XSAVEC is disabled.
+tst-x86_64-1-ENV = GLIBC_TUNABLES=glibc.tune.hwcaps=-XSAVEC_Usable
+endif
+
+$(objpfx)tst-x86_64-1: $(objpfx)x86_64/tst-x86_64mod-1.so
+
+ifneq (no,$(have-tunables))
+tests += tst-platform-1
+modules-names += tst-platformmod-1 x86_64/tst-platformmod-2
+CFLAGS-tst-platform-1.c = -mno-avx
+CFLAGS-tst-platformmod-1.c = -mno-avx
+CFLAGS-tst-platformmod-2.c = -mno-avx
+LDFLAGS-tst-platformmod-2.so = -Wl,-soname,tst-platformmod-2.so
+$(objpfx)tst-platform-1: $(objpfx)tst-platformmod-1.so
+$(objpfx)tst-platform-1.out: $(objpfx)x86_64/tst-platformmod-2.so
+# Turn off AVX512F_Usable and AVX2_Usable so that GLRO(dl_platform) is
+# always set to x86_64.
+tst-platform-1-ENV = LD_PRELOAD=$(objpfx)\$$PLATFORM/tst-platformmod-2.so \
+ GLIBC_TUNABLES=glibc.tune.hwcaps=-AVX512F_Usable,-AVX2_Usable
+endif
+
tests += tst-audit3 tst-audit4 tst-audit5 tst-audit6 tst-audit7 \
tst-audit10 tst-sse tst-avx tst-avx512
test-extras += tst-audit4-aux tst-audit10-aux \
@@ -122,3 +147,19 @@ endif
ifeq ($(subdir),csu)
gen-as-const-headers += tlsdesc.sym rtld-offsets.sym
endif
+
+$(objpfx)x86_64/tst-x86_64mod-1.os: $(objpfx)tst-x86_64mod-1.os
+ $(make-target-directory)
+ rm -f $@
+ ln $< $@
+
+do-tests-clean common-mostlyclean: tst-x86_64-1-clean
+
+.PHONY: tst-x86_64-1-clean
+tst-x86_64-1-clean:
+ -rm -rf $(objpfx)x86_64
+
+$(objpfx)x86_64/tst-platformmod-2.os: $(objpfx)tst-platformmod-2.os
+ $(make-target-directory)
+ rm -f $@
+ ln $< $@
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 6a04cbcdc9..905a37a5cc 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -66,12 +66,9 @@ static inline int __attribute__ ((unused, always_inline))
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
Elf64_Addr *got;
- extern void _dl_runtime_resolve_sse (ElfW(Word)) attribute_hidden;
- extern void _dl_runtime_resolve_avx (ElfW(Word)) attribute_hidden;
- extern void _dl_runtime_resolve_avx_slow (ElfW(Word)) attribute_hidden;
- extern void _dl_runtime_resolve_avx_opt (ElfW(Word)) attribute_hidden;
- extern void _dl_runtime_resolve_avx512 (ElfW(Word)) attribute_hidden;
- extern void _dl_runtime_resolve_avx512_opt (ElfW(Word)) attribute_hidden;
+ extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden;
+ extern void _dl_runtime_resolve_xsave (ElfW(Word)) attribute_hidden;
+ extern void _dl_runtime_resolve_xsavec (ElfW(Word)) attribute_hidden;
extern void _dl_runtime_profile_sse (ElfW(Word)) attribute_hidden;
extern void _dl_runtime_profile_avx (ElfW(Word)) attribute_hidden;
extern void _dl_runtime_profile_avx512 (ElfW(Word)) attribute_hidden;
@@ -120,29 +117,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
/* 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. */
- if (HAS_ARCH_FEATURE (AVX512F_Usable))
- {
- if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt))
- *(ElfW(Addr) *) (got + 2)
- = (ElfW(Addr)) &_dl_runtime_resolve_avx512_opt;
- else
- *(ElfW(Addr) *) (got + 2)
- = (ElfW(Addr)) &_dl_runtime_resolve_avx512;
- }
- else if (HAS_ARCH_FEATURE (AVX_Usable))
- {
- if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt))
- *(ElfW(Addr) *) (got + 2)
- = (ElfW(Addr)) &_dl_runtime_resolve_avx_opt;
- else if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_slow))
- *(ElfW(Addr) *) (got + 2)
- = (ElfW(Addr)) &_dl_runtime_resolve_avx_slow;
- else
- *(ElfW(Addr) *) (got + 2)
- = (ElfW(Addr)) &_dl_runtime_resolve_avx;
- }
+ if (GLRO(dl_x86_cpu_features).xsave_state_size != 0)
+ *(ElfW(Addr) *) (got + 2)
+ = (HAS_ARCH_FEATURE (XSAVEC_Usable)
+ ? (ElfW(Addr)) &_dl_runtime_resolve_xsavec
+ : (ElfW(Addr)) &_dl_runtime_resolve_xsave);
else
- *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve_sse;
+ *(ElfW(Addr) *) (got + 2)
+ = (ElfW(Addr)) &_dl_runtime_resolve_fxsave;
}
}
diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S
index c14c61aa58..a645572e44 100644
--- a/sysdeps/x86_64/dl-trampoline.S
+++ b/sysdeps/x86_64/dl-trampoline.S
@@ -34,41 +34,24 @@
# define DL_STACK_ALIGNMENT 8
#endif
-#ifndef DL_RUNTIME_UNALIGNED_VEC_SIZE
-/* The maximum size in bytes of unaligned vector load and store in the
- dynamic linker. Since SSE optimized memory/string functions with
- aligned SSE register load and store are used in the dynamic linker,
- we must set this to 8 so that _dl_runtime_resolve_sse will align the
- stack before calling _dl_fixup. */
-# define DL_RUNTIME_UNALIGNED_VEC_SIZE 8
-#endif
-
-/* True if _dl_runtime_resolve should align stack to VEC_SIZE bytes. */
+/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align
+ stack to 16 bytes before calling _dl_fixup. */
#define DL_RUNTIME_RESOLVE_REALIGN_STACK \
- (VEC_SIZE > DL_STACK_ALIGNMENT \
- && VEC_SIZE > DL_RUNTIME_UNALIGNED_VEC_SIZE)
-
-/* Align vector register save area to 16 bytes. */
-#define REGISTER_SAVE_VEC_OFF 0
+ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \
+ || 16 > DL_STACK_ALIGNMENT)
/* Area on stack to save and restore registers used for parameter
passing when calling _dl_fixup. */
#ifdef __ILP32__
-# define REGISTER_SAVE_RAX (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8)
# define PRESERVE_BND_REGS_PREFIX
#else
-/* Align bound register save area to 16 bytes. */
-# define REGISTER_SAVE_BND0 (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8)
-# define REGISTER_SAVE_BND1 (REGISTER_SAVE_BND0 + 16)
-# define REGISTER_SAVE_BND2 (REGISTER_SAVE_BND1 + 16)
-# define REGISTER_SAVE_BND3 (REGISTER_SAVE_BND2 + 16)
-# define REGISTER_SAVE_RAX (REGISTER_SAVE_BND3 + 16)
# ifdef HAVE_MPX_SUPPORT
# define PRESERVE_BND_REGS_PREFIX bnd
# else
# define PRESERVE_BND_REGS_PREFIX .byte 0xf2
# endif
#endif
+#define REGISTER_SAVE_RAX 0
#define REGISTER_SAVE_RCX (REGISTER_SAVE_RAX + 8)
#define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8)
#define REGISTER_SAVE_RSI (REGISTER_SAVE_RDX + 8)
@@ -80,68 +63,56 @@
#define VEC_SIZE 64
#define VMOVA vmovdqa64
-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT
-# define VMOV vmovdqa64
-#else
-# define VMOV vmovdqu64
-#endif
#define VEC(i) zmm##i
-#define _dl_runtime_resolve _dl_runtime_resolve_avx512
#define _dl_runtime_profile _dl_runtime_profile_avx512
#include "dl-trampoline.h"
-#undef _dl_runtime_resolve
#undef _dl_runtime_profile
#undef VEC
-#undef VMOV
#undef VMOVA
#undef VEC_SIZE
#define VEC_SIZE 32
#define VMOVA vmovdqa
-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT
-# define VMOV vmovdqa
-#else
-# define VMOV vmovdqu
-#endif
#define VEC(i) ymm##i
-#define _dl_runtime_resolve _dl_runtime_resolve_avx
-#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx_opt
#define _dl_runtime_profile _dl_runtime_profile_avx
#include "dl-trampoline.h"
-#undef _dl_runtime_resolve
-#undef _dl_runtime_resolve_opt
#undef _dl_runtime_profile
#undef VEC
-#undef VMOV
#undef VMOVA
#undef VEC_SIZE
/* movaps/movups is 1-byte shorter. */
#define VEC_SIZE 16
#define VMOVA movaps
-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT
-# define VMOV movaps
-#else
-# define VMOV movups
-#endif
#define VEC(i) xmm##i
-#define _dl_runtime_resolve _dl_runtime_resolve_sse
#define _dl_runtime_profile _dl_runtime_profile_sse
#undef RESTORE_AVX
#include "dl-trampoline.h"
-#undef _dl_runtime_resolve
#undef _dl_runtime_profile
-#undef VMOV
+#undef VEC
#undef VMOVA
+#undef VEC_SIZE
-/* Used by _dl_runtime_resolve_avx_opt/_dl_runtime_resolve_avx512_opt
- to preserve the full vector registers with zero upper bits. */
-#define VMOVA vmovdqa
-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT
-# define VMOV vmovdqa
-#else
-# define VMOV vmovdqu
-#endif
-#define _dl_runtime_resolve _dl_runtime_resolve_sse_vex
-#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx512_opt
+#define USE_FXSAVE
+#define STATE_SAVE_ALIGNMENT 16
+#define _dl_runtime_resolve _dl_runtime_resolve_fxsave
+#include "dl-trampoline.h"
+#undef _dl_runtime_resolve
+#undef USE_FXSAVE
+#undef STATE_SAVE_ALIGNMENT
+
+#define USE_XSAVE
+#define STATE_SAVE_ALIGNMENT 64
+#define _dl_runtime_resolve _dl_runtime_resolve_xsave
+#include "dl-trampoline.h"
+#undef _dl_runtime_resolve
+#undef USE_XSAVE
+#undef STATE_SAVE_ALIGNMENT
+
+#define USE_XSAVEC
+#define STATE_SAVE_ALIGNMENT 64
+#define _dl_runtime_resolve _dl_runtime_resolve_xsavec
#include "dl-trampoline.h"
+#undef _dl_runtime_resolve
+#undef USE_XSAVEC
+#undef STATE_SAVE_ALIGNMENT
diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h
index 8db24c16ac..9ddaafee17 100644
--- a/sysdeps/x86_64/dl-trampoline.h
+++ b/sysdeps/x86_64/dl-trampoline.h
@@ -16,140 +16,47 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#undef REGISTER_SAVE_AREA_RAW
-#ifdef __ILP32__
-/* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as VEC0 to
- VEC7. */
-# define REGISTER_SAVE_AREA_RAW (8 * 7 + VEC_SIZE * 8)
-#else
-/* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as
- BND0, BND1, BND2, BND3 and VEC0 to VEC7. */
-# define REGISTER_SAVE_AREA_RAW (8 * 7 + 16 * 4 + VEC_SIZE * 8)
-#endif
+ .text
+#ifdef _dl_runtime_resolve
-#undef REGISTER_SAVE_AREA
-#undef LOCAL_STORAGE_AREA
-#undef BASE
-#if DL_RUNTIME_RESOLVE_REALIGN_STACK
-# define REGISTER_SAVE_AREA (REGISTER_SAVE_AREA_RAW + 8)
-/* Local stack area before jumping to function address: RBX. */
-# define LOCAL_STORAGE_AREA 8
-# define BASE rbx
-# if (REGISTER_SAVE_AREA % VEC_SIZE) != 0
-# error REGISTER_SAVE_AREA must be multples of VEC_SIZE
-# endif
-#else
-# define REGISTER_SAVE_AREA REGISTER_SAVE_AREA_RAW
-/* Local stack area before jumping to function address: All saved
- registers. */
-# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA
-# define BASE rsp
-# if (REGISTER_SAVE_AREA % 16) != 8
-# error REGISTER_SAVE_AREA must be odd multples of 8
+# undef REGISTER_SAVE_AREA
+# undef LOCAL_STORAGE_AREA
+# undef BASE
+
+# if (STATE_SAVE_ALIGNMENT % 16) != 0
+# error STATE_SAVE_ALIGNMENT must be multples of 16
# endif
-#endif
- .text
-#ifdef _dl_runtime_resolve_opt
-/* Use the smallest vector registers to preserve the full YMM/ZMM
- registers to avoid SSE transition penalty. */
-
-# if VEC_SIZE == 32
-/* Check if the upper 128 bits in %ymm0 - %ymm7 registers are non-zero
- and preserve %xmm0 - %xmm7 registers with the zero upper bits. Since
- there is no SSE transition penalty on AVX512 processors which don't
- support XGETBV with ECX == 1, _dl_runtime_resolve_avx512_slow isn't
- provided. */
- .globl _dl_runtime_resolve_avx_slow
- .hidden _dl_runtime_resolve_avx_slow
- .type _dl_runtime_resolve_avx_slow, @function
- .align 16
-_dl_runtime_resolve_avx_slow:
- cfi_startproc
- cfi_adjust_cfa_offset(16) # Incorporate PLT
- vorpd %ymm0, %ymm1, %ymm8
- vorpd %ymm2, %ymm3, %ymm9
- vorpd %ymm4, %ymm5, %ymm10
- vorpd %ymm6, %ymm7, %ymm11
- vorpd %ymm8, %ymm9, %ymm9
- vorpd %ymm10, %ymm11, %ymm10
- vpcmpeqd %xmm8, %xmm8, %xmm8
- vorpd %ymm9, %ymm10, %ymm10
- vptest %ymm10, %ymm8
- # Preserve %ymm0 - %ymm7 registers if the upper 128 bits of any
- # %ymm0 - %ymm7 registers aren't zero.
- PRESERVE_BND_REGS_PREFIX
- jnc _dl_runtime_resolve_avx
- # Use vzeroupper to avoid SSE transition penalty.
- vzeroupper
- # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits
- # when the upper 128 bits of %ymm0 - %ymm7 registers are zero.
- PRESERVE_BND_REGS_PREFIX
- jmp _dl_runtime_resolve_sse_vex
- cfi_adjust_cfa_offset(-16) # Restore PLT adjustment
- cfi_endproc
- .size _dl_runtime_resolve_avx_slow, .-_dl_runtime_resolve_avx_slow
+# if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0
+# error STATE_SAVE_OFFSET must be multples of STATE_SAVE_ALIGNMENT
# endif
-/* Use XGETBV with ECX == 1 to check which bits in vector registers are
- non-zero and only preserve the non-zero lower bits with zero upper
- bits. */
- .globl _dl_runtime_resolve_opt
- .hidden _dl_runtime_resolve_opt
- .type _dl_runtime_resolve_opt, @function
- .align 16
-_dl_runtime_resolve_opt:
- cfi_startproc
- cfi_adjust_cfa_offset(16) # Incorporate PLT
- pushq %rax
- cfi_adjust_cfa_offset(8)
- cfi_rel_offset(%rax, 0)
- pushq %rcx
- cfi_adjust_cfa_offset(8)
- cfi_rel_offset(%rcx, 0)
- pushq %rdx
- cfi_adjust_cfa_offset(8)
- cfi_rel_offset(%rdx, 0)
- movl $1, %ecx
- xgetbv
- movl %eax, %r11d
- popq %rdx
- cfi_adjust_cfa_offset(-8)
- cfi_restore (%rdx)
- popq %rcx
- cfi_adjust_cfa_offset(-8)
- cfi_restore (%rcx)
- popq %rax
- cfi_adjust_cfa_offset(-8)
- cfi_restore (%rax)
-# if VEC_SIZE == 32
- # For YMM registers, check if YMM state is in use.
- andl $bit_YMM_state, %r11d
- # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits if
- # YMM state isn't in use.
- PRESERVE_BND_REGS_PREFIX
- jz _dl_runtime_resolve_sse_vex
-# elif VEC_SIZE == 16
- # For ZMM registers, check if YMM state and ZMM state are in
- # use.
- andl $(bit_YMM_state | bit_ZMM0_15_state), %r11d
- cmpl $bit_YMM_state, %r11d
- # Preserve %zmm0 - %zmm7 registers if ZMM state is in use.
- PRESERVE_BND_REGS_PREFIX
- jg _dl_runtime_resolve_avx512
- # Preserve %ymm0 - %ymm7 registers with the zero upper 256 bits if
- # ZMM state isn't in use.
- PRESERVE_BND_REGS_PREFIX
- je _dl_runtime_resolve_avx
- # Preserve %xmm0 - %xmm7 registers with the zero upper 384 bits if
- # neither YMM state nor ZMM state are in use.
+# if DL_RUNTIME_RESOLVE_REALIGN_STACK
+/* Local stack area before jumping to function address: RBX. */
+# define LOCAL_STORAGE_AREA 8
+# define BASE rbx
+# ifdef USE_FXSAVE
+/* Use fxsave to save XMM registers. */
+# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET)
+# if (REGISTER_SAVE_AREA % 16) != 0
+# error REGISTER_SAVE_AREA must be multples of 16
+# endif
+# endif
# else
-# error Unsupported VEC_SIZE!
+# ifndef USE_FXSAVE
+# error USE_FXSAVE must be defined
+# endif
+/* Use fxsave to save XMM registers. */
+# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8)
+/* Local stack area before jumping to function address: All saved
+ registers. */
+# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA
+# define BASE rsp
+# if (REGISTER_SAVE_AREA % 16) != 8
+# error REGISTER_SAVE_AREA must be odd multples of 8
+# endif
# endif
- cfi_adjust_cfa_offset(-16) # Restore PLT adjustment
- cfi_endproc
- .size _dl_runtime_resolve_opt, .-_dl_runtime_resolve_opt
-#endif
+
.globl _dl_runtime_resolve
.hidden _dl_runtime_resolve
.type _dl_runtime_resolve, @function
@@ -157,21 +64,30 @@ _dl_runtime_resolve_opt:
cfi_startproc
_dl_runtime_resolve:
cfi_adjust_cfa_offset(16) # Incorporate PLT
-#if DL_RUNTIME_RESOLVE_REALIGN_STACK
-# if LOCAL_STORAGE_AREA != 8
-# error LOCAL_STORAGE_AREA must be 8
-# endif
+# if DL_RUNTIME_RESOLVE_REALIGN_STACK
+# if LOCAL_STORAGE_AREA != 8
+# error LOCAL_STORAGE_AREA must be 8
+# endif
pushq %rbx # push subtracts stack by 8.
cfi_adjust_cfa_offset(8)
cfi_rel_offset(%rbx, 0)
mov %RSP_LP, %RBX_LP
cfi_def_cfa_register(%rbx)
- and $-VEC_SIZE, %RSP_LP
-#endif
+ and $-STATE_SAVE_ALIGNMENT, %RSP_LP
+# endif
+# ifdef REGISTER_SAVE_AREA
sub $REGISTER_SAVE_AREA, %RSP_LP
-#if !DL_RUNTIME_RESOLVE_REALIGN_STACK
+# if !DL_RUNTIME_RESOLVE_REALIGN_STACK
cfi_adjust_cfa_offset(REGISTER_SAVE_AREA)
-#endif
+# endif
+# else
+ # Allocate stack space of the required size to save the state.
+# if IS_IN (rtld)
+ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP
+# else
+ sub _dl_x86_cpu_features+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP
+# endif
+# endif
# Preserve registers otherwise clobbered.
movq %rax, REGISTER_SAVE_RAX(%rsp)
movq %rcx, REGISTER_SAVE_RCX(%rsp)
@@ -180,59 +96,42 @@ _dl_runtime_resolve:
movq %rdi, REGISTER_SAVE_RDI(%rsp)
movq %r8, REGISTER_SAVE_R8(%rsp)
movq %r9, REGISTER_SAVE_R9(%rsp)
- VMOV %VEC(0), (REGISTER_SAVE_VEC_OFF)(%rsp)
- VMOV %VEC(1), (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp)
- VMOV %VEC(2), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp)
- VMOV %VEC(3), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp)
- VMOV %VEC(4), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp)
- VMOV %VEC(5), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp)
- VMOV %VEC(6), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp)
- VMOV %VEC(7), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp)
-#ifndef __ILP32__
- # We also have to preserve bound registers. These are nops if
- # Intel MPX isn't available or disabled.
-# ifdef HAVE_MPX_SUPPORT
- bndmov %bnd0, REGISTER_SAVE_BND0(%rsp)
- bndmov %bnd1, REGISTER_SAVE_BND1(%rsp)
- bndmov %bnd2, REGISTER_SAVE_BND2(%rsp)
- bndmov %bnd3, REGISTER_SAVE_BND3(%rsp)
+# ifdef USE_FXSAVE
+ fxsave STATE_SAVE_OFFSET(%rsp)
# else
-# if REGISTER_SAVE_BND0 == 0
- .byte 0x66,0x0f,0x1b,0x04,0x24
+ movl $STATE_SAVE_MASK, %eax
+ xorl %edx, %edx
+ # Clear the XSAVE Header.
+# ifdef USE_XSAVE
+ movq %rdx, (STATE_SAVE_OFFSET + 512)(%rsp)
+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8)(%rsp)
+# endif
+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 2)(%rsp)
+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 3)(%rsp)
+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 4)(%rsp)
+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 5)(%rsp)
+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 6)(%rsp)
+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 7)(%rsp)
+# ifdef USE_XSAVE
+ xsave STATE_SAVE_OFFSET(%rsp)
# else
- .byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0
+ xsavec STATE_SAVE_OFFSET(%rsp)
# endif
- .byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1
- .byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2
- .byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3
# endif
-#endif
# Copy args pushed by PLT in register.
# %rdi: link_map, %rsi: reloc_index
mov (LOCAL_STORAGE_AREA + 8)(%BASE), %RSI_LP
mov LOCAL_STORAGE_AREA(%BASE), %RDI_LP
call _dl_fixup # Call resolver.
mov %RAX_LP, %R11_LP # Save return value
-#ifndef __ILP32__
- # Restore bound registers. These are nops if Intel MPX isn't
- # avaiable or disabled.
-# ifdef HAVE_MPX_SUPPORT
- bndmov REGISTER_SAVE_BND3(%rsp), %bnd3
- bndmov REGISTER_SAVE_BND2(%rsp), %bnd2
- bndmov REGISTER_SAVE_BND1(%rsp), %bnd1
- bndmov REGISTER_SAVE_BND0(%rsp), %bnd0
+ # Get register content back.
+# ifdef USE_FXSAVE
+ fxrstor STATE_SAVE_OFFSET(%rsp)
# else
- .byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3
- .byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2
- .byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1
-# if REGISTER_SAVE_BND0 == 0
- .byte 0x66,0x0f,0x1a,0x04,0x24
-# else
- .byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0
-# endif
+ movl $STATE_SAVE_MASK, %eax
+ xorl %edx, %edx
+ xrstor STATE_SAVE_OFFSET(%rsp)
# endif
-#endif
- # Get register content back.
movq REGISTER_SAVE_R9(%rsp), %r9
movq REGISTER_SAVE_R8(%rsp), %r8
movq REGISTER_SAVE_RDI(%rsp), %rdi
@@ -240,20 +139,12 @@ _dl_runtime_resolve:
movq REGISTER_SAVE_RDX(%rsp), %rdx
movq REGISTER_SAVE_RCX(%rsp), %rcx
movq REGISTER_SAVE_RAX(%rsp), %rax
- VMOV (REGISTER_SAVE_VEC_OFF)(%rsp), %VEC(0)
- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp), %VEC(1)
- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp), %VEC(2)
- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp), %VEC(3)
- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp), %VEC(4)
- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp), %VEC(5)
- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp), %VEC(6)
- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp), %VEC(7)
-#if DL_RUNTIME_RESOLVE_REALIGN_STACK
+# if DL_RUNTIME_RESOLVE_REALIGN_STACK
mov %RBX_LP, %RSP_LP
cfi_def_cfa_register(%rsp)
movq (%rsp), %rbx
cfi_restore(%rbx)
-#endif
+# endif
# Adjust stack(PLT did 2 pushes)
add $(LOCAL_STORAGE_AREA + 16), %RSP_LP
cfi_adjust_cfa_offset(-(LOCAL_STORAGE_AREA + 16))
@@ -262,11 +153,9 @@ _dl_runtime_resolve:
jmp *%r11 # Jump to function address.
cfi_endproc
.size _dl_runtime_resolve, .-_dl_runtime_resolve
+#endif
-/* To preserve %xmm0 - %xmm7 registers, dl-trampoline.h is included
- twice, for _dl_runtime_resolve_sse and _dl_runtime_resolve_sse_vex.
- But we don't need another _dl_runtime_profile for XMM registers. */
#if !defined PROF && defined _dl_runtime_profile
# if (LR_VECTOR_OFFSET % VEC_SIZE) != 0
# error LR_VECTOR_OFFSET must be multples of VEC_SIZE
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index c347642044..e7ec433b7b 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -1305,7 +1305,7 @@ Function: "cos_vlen4_avx2":
double: 2
Function: "cos_vlen8":
-double: 1
+double: 2
float: 1
Function: "cos_vlen8_avx2":
@@ -1733,10 +1733,10 @@ ldouble: 3
Function: Imaginary part of "ctan_upward":
double: 2
-float: 1
+float: 2
float128: 5
idouble: 2
-ifloat: 1
+ifloat: 2
ifloat128: 5
ildouble: 3
ldouble: 3
@@ -2645,7 +2645,7 @@ Function: "sincos_vlen4_avx2":
double: 2
Function: "sincos_vlen8":
-double: 1
+double: 2
float: 1
Function: "sincos_vlen8_avx2":
diff --git a/sysdeps/x86_64/nptl/pthread-offsets.h b/sysdeps/x86_64/nptl/pthread-offsets.h
new file mode 100644
index 0000000000..16c6b0d9fd
--- /dev/null
+++ b/sysdeps/x86_64/nptl/pthread-offsets.h
@@ -0,0 +1,5 @@
+#define __PTHREAD_MUTEX_NUSERS_OFFSET 12
+#define __PTHREAD_MUTEX_KIND_OFFSET 16
+#define __PTHREAD_MUTEX_SPINS_OFFSET 20
+#define __PTHREAD_MUTEX_ELISION_OFFSET 22
+#define __PTHREAD_MUTEX_LIST_OFFSET 24
diff --git a/sysdeps/x86_64/tst-platform-1.c b/sysdeps/x86_64/tst-platform-1.c
new file mode 100644
index 0000000000..76a02e4b6d
--- /dev/null
+++ b/sysdeps/x86_64/tst-platform-1.c
@@ -0,0 +1,29 @@
+/* Test PRELOAD with $PLATFORM.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+
+extern int preload (void);
+
+static int
+do_test (void)
+{
+ return preload () == 0x1234 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/tst-platformmod-1.c b/sysdeps/x86_64/tst-platformmod-1.c
new file mode 100644
index 0000000000..9ef5e2b5be
--- /dev/null
+++ b/sysdeps/x86_64/tst-platformmod-1.c
@@ -0,0 +1,23 @@
+/* Test PRELOAD with $PLATFORM.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+int
+preload (void)
+{
+ return 0;
+}
diff --git a/sysdeps/x86_64/tst-platformmod-2.c b/sysdeps/x86_64/tst-platformmod-2.c
new file mode 100644
index 0000000000..d0e5103892
--- /dev/null
+++ b/sysdeps/x86_64/tst-platformmod-2.c
@@ -0,0 +1,23 @@
+/* Test PRELOAD with $PLATFORM.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+int
+preload (void)
+{
+ return 0x1234;
+}
diff --git a/sysdeps/x86_64/tst-x86_64-1.c b/sysdeps/x86_64/tst-x86_64-1.c
new file mode 100644
index 0000000000..ba1a55cdaf
--- /dev/null
+++ b/sysdeps/x86_64/tst-x86_64-1.c
@@ -0,0 +1,26 @@
+/* Test searching the "x86_64" directory for shared libraries.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+extern void foo (void);
+
+int
+main (void)
+{
+ foo ();
+ return 0;
+}
diff --git a/sysdeps/x86_64/tst-x86_64mod-1.c b/sysdeps/x86_64/tst-x86_64mod-1.c
new file mode 100644
index 0000000000..83dfafb5a8
--- /dev/null
+++ b/sysdeps/x86_64/tst-x86_64mod-1.c
@@ -0,0 +1,22 @@
+/* Test searching the "x86_64" directory for shared libraries.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+void
+foo (void)
+{
+}