summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2012-10-10 15:35:46 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2012-10-10 15:35:46 +0000
commit2d32c4f00084f68a390e8fa4291acb49e9c0df8e (patch)
tree00964019e9307917f730b8c6b817f0cb9496a167
parent7dfcd4332472afda13e2ea9c0eaba15a08d8351e (diff)
downloadeglibc2-2d32c4f00084f68a390e8fa4291acb49e9c0df8e.tar.gz
Merge changes between r20863 and r21108 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@21109 7b3dc134-2b1b-0410-93df-9e9f96275f8d
-rw-r--r--libc/ChangeLog553
-rw-r--r--libc/Makeconfig5
-rw-r--r--libc/Makefile.in2
-rw-r--r--libc/Makerules2
-rw-r--r--libc/NEWS14
-rw-r--r--libc/aclocal.m48
-rw-r--r--libc/bits/types.h1
-rw-r--r--libc/bits/typesizes.h1
-rw-r--r--libc/config.h.in3
-rwxr-xr-xlibc/configure4
-rw-r--r--libc/configure.in3
-rw-r--r--libc/csu/init-first.c89
-rw-r--r--libc/dlfcn/dlerror.c11
-rw-r--r--libc/elf/Makefile9
-rw-r--r--libc/elf/dl-hwcaps.c279
-rw-r--r--libc/elf/dl-load.c16
-rw-r--r--libc/elf/dl-open.c4
-rw-r--r--libc/elf/dl-runtime.c4
-rw-r--r--libc/elf/dl-support.c26
-rw-r--r--libc/elf/dl-sysdep.c261
-rw-r--r--libc/elf/dl-version.c5
-rw-r--r--libc/elf/do-rel.h8
-rw-r--r--libc/elf/dynamic-link.h149
-rw-r--r--libc/elf/get-dynamic-info.h161
-rw-r--r--libc/elf/rtld.c107
-rw-r--r--libc/elf/setup-vdso.h121
-rw-r--r--libc/include/sys/mman.h5
-rw-r--r--libc/io/open.c13
-rw-r--r--libc/io/openat.c9
-rw-r--r--libc/io/tst-mknodat.c28
-rw-r--r--libc/libidn/ChangeLog6
-rw-r--r--libc/libidn/configure14
-rw-r--r--libc/libidn/configure.in9
-rw-r--r--libc/libio/Makefile4
-rw-r--r--libc/libio/filedoalloc.c2
-rw-r--r--libc/libio/fileops.c29
-rw-r--r--libc/libio/libio.h2
-rw-r--r--libc/libio/oldfileops.c2
-rw-r--r--libc/libio/tst-fseek.c173
-rw-r--r--libc/libio/wfileops.c177
-rw-r--r--libc/malloc/arena.c2
-rw-r--r--libc/malloc/malloc.c5
-rw-r--r--libc/manual/platform.texi8
-rw-r--r--libc/math/Makefile2
-rwxr-xr-xlibc/math/gen-libm-test.pl4
-rw-r--r--libc/math/libm-test.inc570
-rw-r--r--libc/math/s_ccosh.c20
-rw-r--r--libc/math/s_ccoshf.c20
-rw-r--r--libc/math/s_ccoshl.c20
-rw-r--r--libc/math/s_cexp.c20
-rw-r--r--libc/math/s_cexpf.c20
-rw-r--r--libc/math/s_cexpl.c20
-rw-r--r--libc/math/s_clog.c13
-rw-r--r--libc/math/s_clog10.c13
-rw-r--r--libc/math/s_clog10f.c13
-rw-r--r--libc/math/s_clog10l.c13
-rw-r--r--libc/math/s_clogf.c13
-rw-r--r--libc/math/s_clogl.c13
-rw-r--r--libc/math/s_csin.c20
-rw-r--r--libc/math/s_csinf.c20
-rw-r--r--libc/math/s_csinh.c20
-rw-r--r--libc/math/s_csinhf.c20
-rw-r--r--libc/math/s_csinhl.c20
-rw-r--r--libc/math/s_csinl.c20
-rw-r--r--libc/math/s_ctan.c11
-rw-r--r--libc/math/s_ctanf.c10
-rw-r--r--libc/math/s_ctanh.c11
-rw-r--r--libc/math/s_ctanhf.c10
-rw-r--r--libc/math/s_ctanhl.c11
-rw-r--r--libc/math/s_ctanl.c11
-rw-r--r--libc/misc/Versions3
-rw-r--r--libc/misc/madvise.c9
-rw-r--r--libc/misc/sys/cdefs.h9
-rw-r--r--libc/nis/yp_xdr.c10
-rw-r--r--libc/nptl/ChangeLog81
-rw-r--r--libc/nptl/Makefile13
-rw-r--r--libc/nptl/pthread_create.c4
-rw-r--r--libc/nptl/sysdeps/i386/tls.h2
-rwxr-xr-xlibc/nptl/sysdeps/pthread/configure120
-rw-r--r--libc/nptl/sysdeps/sparc/tls.h4
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S50
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S129
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h2
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h2
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c21
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h2
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h2
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h2
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h2
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S51
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S121
-rw-r--r--libc/nptl/sysdeps/x86_64/configure82
-rw-r--r--libc/nptl/tst-cancel24-static.cc1
-rw-r--r--libc/nptl/tst-cond-except.c108
-rw-r--r--libc/nptl/tst-cond24.c249
-rw-r--r--libc/nptl/tst-cond8-static.c1
-rw-r--r--libc/nptl/tst-mutex8-static.c1
-rw-r--r--libc/nptl/tst-mutexpi8-static.c1
-rw-r--r--libc/nptl/tst-sem11-static.c1
-rw-r--r--libc/nptl/tst-sem12-static.c1
-rw-r--r--libc/nptl_db/ChangeLog6
-rw-r--r--libc/nptl_db/Makefile2
-rw-r--r--libc/nscd/Makefile42
-rw-r--r--libc/nss/Makefile2
-rw-r--r--libc/nss/nsswitch.c6
-rw-r--r--libc/ports/ChangeLog.alpha33
-rw-r--r--libc/ports/ChangeLog.am334
-rw-r--r--libc/ports/ChangeLog.arm19
-rw-r--r--libc/ports/ChangeLog.hppa5
-rw-r--r--libc/ports/ChangeLog.ia649
-rw-r--r--libc/ports/ChangeLog.linux-generic5
-rw-r--r--libc/ports/ChangeLog.m68k10
-rw-r--r--libc/ports/ChangeLog.mips22
-rw-r--r--libc/ports/ChangeLog.powerpc5
-rw-r--r--libc/ports/ChangeLog.tile5
-rw-r--r--libc/ports/sysdeps/alpha/configure1
-rw-r--r--libc/ports/sysdeps/arm/configure99
-rw-r--r--libc/ports/sysdeps/arm/dl-machine.h120
-rw-r--r--libc/ports/sysdeps/arm/dl-tlsdesc.h6
-rw-r--r--libc/ports/sysdeps/hppa/configure82
-rw-r--r--libc/ports/sysdeps/ia64/configure86
-rw-r--r--libc/ports/sysdeps/mips/dl-trampoline.c2
-rw-r--r--libc/ports/sysdeps/mips/ieee754/ieee754.h (renamed from libc/ports/sysdeps/mips/ieee754.h)0
-rw-r--r--libc/ports/sysdeps/mips/init-first.c65
-rw-r--r--libc/ports/sysdeps/mips/mips32/Implies1
-rw-r--r--libc/ports/sysdeps/mips/mips64/Implies1
-rw-r--r--libc/ports/sysdeps/mips/mips64/n32/Implies1
-rw-r--r--libc/ports/sysdeps/mips/mips64/n64/Implies1
-rw-r--r--libc/ports/sysdeps/unix/alpha/sysdep.h35
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S79
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h2
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h12
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S11
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h2
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h2
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h2
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c5
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h2
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h2
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h2
-rw-r--r--libc/posix/Makefile1
-rw-r--r--libc/posix/gai.conf16
-rw-r--r--libc/posix/glob.c10
-rw-r--r--libc/posix/tst-rfc3484.c5
-rw-r--r--libc/rt/tst-aio2.c3
-rw-r--r--libc/rt/tst-aio3.c3
-rwxr-xr-xlibc/scripts/check-local-headers.sh2
-rwxr-xr-xlibc/scripts/config.guess33
-rwxr-xr-xlibc/scripts/config.sub29
-rw-r--r--libc/stdio-common/Makefile1
-rw-r--r--libc/stdio-common/tst-sprintf.c13
-rw-r--r--libc/stdio-common/vfprintf.c40
-rw-r--r--libc/string/Makefile3
-rw-r--r--libc/string/bug-strchr1.c14
-rw-r--r--libc/string/bug-strstr1.c26
-rw-r--r--libc/string/str-two-way.h37
-rw-r--r--libc/string/strcasestr.c4
-rw-r--r--libc/string/strstr.c4
-rw-r--r--libc/string/test-strcasestr.c28
-rw-r--r--libc/string/test-strchr.c27
-rw-r--r--libc/string/test-strstr.c47
-rw-r--r--libc/sysdeps/generic/_G_config.h7
-rw-r--r--libc/sysdeps/generic/ldsodefs.h6
-rw-r--r--libc/sysdeps/generic/math_private.h7
-rwxr-xr-xlibc/sysdeps/i386/configure122
-rw-r--r--libc/sysdeps/i386/fpu/libm-test-ulps150
-rw-r--r--libc/sysdeps/i386/i686/fpu/multiarch/Makefile3
-rw-r--r--libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S586
-rw-r--r--libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c29
-rw-r--r--libc/sysdeps/i386/init-first.c78
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_fma.c10
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_fmaf.c7
-rw-r--r--libc/sysdeps/ieee754/dbl-64/x2y2m1.c111
-rw-r--r--libc/sysdeps/ieee754/dbl-64/x2y2m1f.c (renamed from libc/string/bug-strcasestr1.c)31
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_sincosf.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h50
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_fma.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_fmal.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/x2y2m1l.c111
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c128
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_fma.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_fmal.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/x2y2m1.c39
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/x2y2m1l.c111
-rwxr-xr-xlibc/sysdeps/ieee754/ldbl-opt/configure120
-rw-r--r--libc/sysdeps/mach/configure138
-rw-r--r--libc/sysdeps/mach/hurd/_G_config.h64
-rw-r--r--libc/sysdeps/mach/hurd/bits/typesizes.h1
-rwxr-xr-xlibc/sysdeps/mach/hurd/configure123
-rw-r--r--libc/sysdeps/mach/hurd/dl-sysdep.c20
-rw-r--r--libc/sysdeps/mach/hurd/malloc-machine.h5
-rw-r--r--libc/sysdeps/posix/getaddrinfo.c4
-rw-r--r--libc/sysdeps/posix/sleep.c100
-rw-r--r--libc/sysdeps/posix/sysconf.c1
-rwxr-xr-xlibc/sysdeps/powerpc/configure82
-rw-r--r--libc/sysdeps/powerpc/powerpc32/configure82
-rw-r--r--libc/sysdeps/powerpc/powerpc64/configure82
-rw-r--r--libc/sysdeps/powerpc/sys/platform/ppc.h1
-rw-r--r--libc/sysdeps/pthread/aio_fsync.c2
-rw-r--r--libc/sysdeps/s390/s390-32/configure1
-rw-r--r--libc/sysdeps/s390/s390-64/configure1
-rw-r--r--libc/sysdeps/sh/configure1
-rw-r--r--libc/sysdeps/sh/init-first.c78
-rw-r--r--libc/sysdeps/sparc/configure82
-rw-r--r--libc/sysdeps/sparc/fpu/libm-test-ulps177
-rw-r--r--libc/sysdeps/sparc/sparc32/dl-machine.h5
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile2
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S1
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S1
-rw-r--r--libc/sysdeps/sparc/sparc64/dl-machine.h14
-rw-r--r--libc/sysdeps/sparc/sparc64/multiarch/Makefile2
-rw-r--r--libc/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S332
-rw-r--r--libc/sysdeps/sparc/sparc64/multiarch/memcpy.S26
-rw-r--r--libc/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S124
-rw-r--r--libc/sysdeps/sparc/sparc64/multiarch/memset.S30
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h1
-rw-r--r--libc/sysdeps/unix/bsd/confstr.h1
-rw-r--r--libc/sysdeps/unix/syscalls.list2
-rw-r--r--libc/sysdeps/unix/sysv/linux/_G_config.h (renamed from libc/sysdeps/gnu/_G_config.h)2
-rw-r--r--libc/sysdeps/unix/sysv/linux/configure99
-rw-r--r--libc/sysdeps/unix/sysv/linux/init-first.c115
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/Makefile6
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h28
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h33
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/configure120
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c (renamed from libc/sysdeps/mach/hurd/dl-cache.c)17
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/init-first.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions3
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions3
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c62
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/init-first.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/syscalls.list2
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/init-first.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c5
-rw-r--r--libc/sysdeps/x86_64/configure124
-rw-r--r--libc/sysdeps/x86_64/dl-tlsdesc.h6
-rw-r--r--libc/sysdeps/x86_64/fpu/libm-test-ulps174
-rw-r--r--libc/sysdeps/x86_64/fpu/s_sincosf.S558
-rw-r--r--libc/sysdeps/x86_64/multiarch/init-arch.c3
-rw-r--r--libc/sysdeps/x86_64/multiarch/init-arch.h9
-rw-r--r--libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S10
249 files changed, 6713 insertions, 3543 deletions
diff --git a/libc/ChangeLog b/libc/ChangeLog
index cea98d16a..a3e846e34 100644
--- a/libc/ChangeLog
+++ b/libc/ChangeLog
@@ -1,3 +1,556 @@
+2012-10-09 Joseph Myers <joseph@codesourcery.com>
+
+ * math/gen-libm-test.pl (parse_args): Handle comparison macros as
+ type-generic.
+ * math/libm-test.inc: Update comment listing what functions and
+ macros are tested.
+ (isgreater_test): New function.
+ (isgreaterequal_test): Likewise.
+ (isless_test): Likewise.
+ (islessequal_test): Likewise.
+ (islessgreater_test): Likewise.
+ (isunordered_test): Likewise.
+ (main): Call the new functions.
+
+2012-10-09 Roland McGrath <roland@hack.frob.com>
+
+ * aclocal.m4 (GLIBC_PROVIDES): Provide _AS_BASENAME_PREPARE,
+ _AS_ME_PREPARE, _AS_VAR_ARITH_PREPARE, AS_SHELL_FN_as_fn_set_status,
+ AS_SHELL_FN_as_fn_exit, AS_SHELL_FN_ac_fn_c_try_compile.
+ * sysdeps/i386/configure: Regenerated.
+ * sysdeps/ieee754/ldbl-opt/configure: Regenerated.
+ * sysdeps/mach/configure: Regenerated.
+ * sysdeps/mach/hurd/configure: Regenerated.
+ * sysdeps/powerpc/configure: Regenerated.
+ * sysdeps/powerpc/powerpc32/configure: Regenerated.
+ * sysdeps/powerpc/powerpc64/configure: Regenerated.
+ * sysdeps/s390/s390-32/configure: Regenerated.
+ * sysdeps/s390/s390-64/configure: Regenerated.
+ * sysdeps/sh/configure: Regenerated.
+ * sysdeps/sparc/configure: Regenerated.
+ * sysdeps/unix/sysv/linux/configure: Regenerated.
+ * sysdeps/unix/sysv/linux/powerpc/configure: Regenerated.
+ * sysdeps/x86_64/configure: Regenerated.
+
+ * dlfcn/dlerror.c (check_free): Call _dl_addr only if SHARED is
+ defined. Don't check if MAP is NULL.
+
+2012-10-09 Joseph Myers <joseph@codesourcery.com>
+
+ * sysdeps/generic/_G_config.h (_G_off64_t): Remove.
+ (_G_stat64): Likewise.
+ * sysdeps/unix/sysv/linux/_G_config.h (_G_off64_t): Remove.
+ (_G_stat64): Likewise.
+ * libio/filedoalloc.c (_IO_file_doallocate): Use struct stat64
+ instead of struct _G_stat64.
+ * libio/fileops.c (mmap_remap_check): Likewise.
+ (decide_maybe_mmap): Likewise.
+ (_IO_new_file_seekoff): Likewise.
+ (_IO_file_stat): Likewise.
+ * libio/libio.h (_IO_off64_t): Define to __off64_t, not
+ _G_off64_t.
+ * libio/oldfileops.c (_IO_old_file_seekoff): Use struct stat64
+ instead of struct _G_stat64.
+ * libio/wfileops.c (_IO_wfile_seekoff): Likewise.
+
+2012-10-08 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ [BZ #14602]
+ * string/str-two-way.h (AVAILABLE1, AVAILABLE2, AVAILABLE1_USES_J):
+ Replace with ...
+ (CHECK_EOL): New macro.
+ (two_way_short_needle): Check beginning of haystack for EOL. Use
+ CHECK_EOL.
+ * string/strcasestr.c (AVAILABLE1, AVAILABLE2, AVAILABLE1_USES_J):
+ Replace with CHECK_EOL.
+ * string/strstr.c (AVAILABLE1, AVAILABLE2, AVAILABLE1_USES_J):
+ Replace with CHECK_EOL.
+
+2012-10-08 Joseph Myers <joseph@codesourcery.com>
+
+ * math/gen-libm-test.pl (parse_args): Handle isinf and isnan as
+ type-generic.
+ * math/libm-test.inc: Update comment listing what functions and
+ macros are tested.
+ (finite_test): New function.
+ (isinf_test): Likewise.
+ (isnan_test): Likewise.
+ (fpclassify_test): Test subnormal input.
+ (isfinite_test): Likewise.
+ (isnormal_test): Likewise.
+ (main): Call the new functions.
+
+2012-10-08 Jonathan Nieder <jrnieder@gmail.com>
+
+ [BZ #14660]
+ * Makerules (%.dynsym): Force C locale when running
+ $(OBJDUMP) --dynamic-syms.
+
+2012-10-08 Andreas Schwab <schwab@linux-m68k.org>
+
+ * sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: Include
+ <stdint.h>.
+
+2012-10-06 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S: On 32-bit, clear
+ upper 32-bits of the length value in %o2 since we use branch-on-register
+ tests which consider the entire 64-bit register.
+
+2012-10-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * string/test-strstr.c (check2): Add a test for page boundary.
+
+2012-10-05 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/sparc/sparc64/multiarch/memset-niagara4.S: New file.
+ * sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S: New
+ file.
+ * sysdeps/sparc/sparc64/multiarch/Makefile: Add to
+ sysdep_routines.
+ * sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile: Likewise.
+ * sysdeps/sparc/sparc64/multiarch/memset.S: Use Niagara-4 memset
+ and bzero when HWCAP_SPARC_CRYPTO is present.
+
+2012-10-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #14602]
+ * string/test-strstr.c (check2): New function.
+ (test_main): Call check2.
+
+ * string/Makefile (tests): Remove bug-strstr1, bug-strcasestr1
+ and bug-strchr1.
+ * string/bug-strcasestr1.c (do_test): Moved to ...
+ * string/test-strcasestr.c (check1): Here. New function.
+ (do_one_test): Break out result checking code into ...
+ (check_result): This. New function.
+ (do_one_test): Call check_result.
+ (test_main): Call check1.
+ * string/bug-strchr1.c (do_test): Moved to ...
+ * string/test-strchr.c (check1): Here. New function.
+ (do_one_test): Break out result checking code into ...
+ (check_result): This. New function.
+ (do_one_test): Call check_result.
+ (test_main): Call check1.
+ * string/bug-strstr1.c (main): Moved to ...
+ * string/test-strchr.c (check1): Here. New function.
+ (do_one_test): Break out result checking code into ...
+ (check_result): This. New function.
+ (do_one_test): Call check_result.
+ (test_main): Call check1.
+ * string/bug-strcasestr1.c: Removed.
+ * string/bug-strchr1.c: Likewise.
+ * string/bug-strstr1.c: Likewise.
+
+ * elf/Makefile (dl-routines): Add hwcaps.
+ * elf/dl-support.c (_dl_important_hwcaps): Removed.
+ * elf/dl-sysdep.c (_DL_FIRST_EXTRA): Likewise.
+ (_dl_important_hwcaps): Moved to ...
+ * elf/dl-hwcaps.c: Here. New file.
+ * sysdeps/mach/hurd/dl-sysdep.c (_dl_important_hwcaps): Removed.
+
+ [BZ #14557]
+ * elf/setup-vdso.h (setup_vdso): Set GL(dl_nns) to 1 for vDSO
+ if IS_IN_rtld isn't defined.
+
+ * elf/dl-support.c (_dl_sysinfo_map): New.
+ Include "get-dynamic-info.h" and "setup-vdso.h".
+ (_dl_non_dynamic_init): Call setup_vdso.
+ * elf/dynamic-link.h: Don't include <assert.h>.
+ (elf_get_dynamic_info): Moved to ...
+ * elf/get-dynamic-info.h: Here. New file.
+ * elf/dynamic-link.h: Include "get-dynamic-info.h".
+ * elf/rtld.c (dl_main): Break out vDSO setup code into ...
+ * elf/setup-vdso.h: Here. New file.
+ * elf/rtld.c: Include "setup-vdso.h".
+ (dl_main): Call setup_vdso.
+
+2012-10-05 Joseph Myers <joseph@codesourcery.com>
+
+ * math/libm-test.inc: List nexttoward, cimag, clog10, conf and
+ creal in comment listing functions tested. List finite, isinf,
+ isnan, isless, islessequal, isgreater, isgreaterequal,
+ islessgreater, isunordered, lgamma_r and pow10 as functions and
+ macros not tested. Mention which functions not tested are aliases
+ for other functions. Fix typo. Note that signs of NaNs are not
+ tested.
+
+ * scripts/config.guess: Update from config.git.
+ * scripts/config.sub: Likewise.
+
+2012-10-04 Roland McGrath <roland@hack.frob.com>
+
+ * misc/Versions (GLIBC_PRIVATE): New set, add __madvise.
+ * misc/madvise.c (madvise): Renamed to __madvise.
+ Make madvise a weak alias.
+ * include/sys/mman.h: Declare __madvise.
+ Replace libc_hidden_proto (madvise) with libc_hidden_proto (__madvise).
+ * sysdeps/unix/syscalls.list
+ (madvise): Make __madvise the strong name, and madvise a weak alias.
+ * sysdeps/unix/sysv/linux/syscalls.list
+ (madvise, mmap): Remove redundant entries.
+ * malloc/arena.c (shrink_heap): Use __madvise, not madvise.
+ * malloc/malloc.c (mtrim): Likewise.
+ * sysdeps/mach/hurd/malloc-machine.h (madvise): Renamed to __madvise.
+
+2012-10-03 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/mach/hurd/dl-cache.c: File removed.
+ * config.h.in (USE_LDCONFIG): New #undef.
+ * configure.in (use_ldconfig): If set, define USE_LDCONFIG.
+ * configure: Regenerated.
+ * elf/Makefile (dl-routines): Add dl-cache only under
+ [$(use-ldconfig) = yes].
+ * elf/dl-load.c (_dl_map_object): Conditionalize code consulting the
+ cache on [USE_LDCONFIG].
+ * elf/dl-open.c (_dl_open): Call _dl_unload_cache only under
+ [USE_LDCONFIG].
+ * elf/rtld.c (dl_main): Likewise.
+
+2012-10-03 Pino Toscano <toscano.pino@tiscali.it>
+
+ * sysdeps/posix/sysconf.c (__sysconf): Return 0 also for
+ _SC_LEVEL4_CACHE_LINESIZE.
+
+2012-10-03 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/unix/bsd/confstr.h: File removed.
+
+2012-10-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * scripts/check-local-headers.sh: Exclude sys/sdt.h and
+ sys/sdt-config.h.
+
+2012-10-02 Roland McGrath <roland@hack.frob.com>
+
+ * elf/dl-load.c (_dl_map_object_from_fd: struct loadcmd):
+ Make 'mapoff' field ElfW(Off) rather than off_t.
+
+2012-10-02 Dmitry V. Levin <ldv@altlinux.org>
+
+ * nscd/Makefile: Remove nscd-cflags and all its users.
+ (CPPFLAGS-nonlib): Add preprocessor flags for nscd modules.
+ (CFLAGS-nonlib): Add compiler flags for nscd modules.
+
+ [BZ #10631]
+ * malloc.c (malloc_printerr): Clarify error message.
+
+2012-10-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #14648]
+ * sysdeps/x86_64/multiarch/init-arch.c (__init_cpu_features):
+ Set bit_FMA_Usable if FMA is supported.
+ * sysdeps/x86_64/multiarch/init-arch.h (bit_FMA_Usable): New
+ macro.
+ (bit_FMA4_Usable): Updated.
+ (index_FMA_Usable): New macro.
+ (CPUID_FMA): Likewise
+ (HAS_FMA): Defined with bit_FMA_Usable.
+
+2012-10-01 Roland McGrath <roland@hack.frob.com>
+
+ * bits/types.h (__swblk_t): Type removed.
+ * bits/typesizes.h (__SWBLK_T_TYPE): Macro removed.
+ * sysdeps/mach/hurd/bits/typesizes.h (__SWBLK_T_TYPE): Likewise.
+ * sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h
+ (__SWBLK_T_TYPE): Likewise.
+ * sysdeps/unix/sysv/linux/x86/bits/typesizes.h
+ (__SWBLK_T_TYPE): Likewise.
+ * sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
+ (__SWBLK_T_TYPE): Likewise.
+ * sysdeps/unix/sysv/linux/s390/bits/typesizes.h
+ (__SWBLK_T_TYPE): Likewise.
+
+2012-10-01 Patsy Franklin <pfrankli@redhat.com>
+ Honza Horak <hhorak@redhat.com>
+
+ * nis/yp_xdr.c (xdr_domainname): Use YPMAXDOMAIN as maxsize.
+ (xdr_mapname): Use YPMAXMAP as maxsize.
+ (xdr_peername): Use YPMAXPEER as maxsize.
+ (xdr_keydat): Use YPAXRECORD as maxsize.
+ (xdr_valdat): Use YPMAXRECORD as maxsize.
+
+2012-10-01 Roland McGrath <roland@hack.frob.com>
+
+ * io/openat.c [!__ASSUME_ATFCTS] (__have_atfcts): New global variable.
+
+ * sysdeps/unix/sysv/linux/init-first.c: Moved to ...
+ * csu/init-first.c: ... here.
+ * sysdeps/unix/sysv/linux/powerpc/init-first.c: Update #include.
+ * sysdeps/unix/sysv/linux/s390/init-first.c: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/init-first.c: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/x32/init-first.c: Likewise.
+ * sysdeps/i386/init-first.c: File removed.
+ * sysdeps/sh/init-first.c: File removed.
+
+2012-10-01 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #14645]
+ * sysdeps/ieee754/dbl-64/s_fma.c (__fma): Compute result as x * y
+ if x * y might underflow to zero and z is zero.
+ * sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Likewise.
+ * sysdeps/ieee754/ldbl-96/s_fmal.c (__fmal): Likewise.
+ * math/libm-test.inc (min_subnorm_value): New variable.
+ (fma_test): Add more tests.
+ (fma_test_towardzero): Likewise.
+ (fma_test_downward): Likewise
+ (fma_test_upward): Likewise.
+ (initialize): Set min_subnorm_value.
+
+2012-09-29 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #14638]
+ * sysdeps/ieee754/dbl-64/s_fma.c (__fma): Use x * y + z for exact
+ 0 + 0.
+ * sysdeps/ieee754/dbl-64/s_fmaf.c (__fmaf): Use original rounding
+ mode for addition resulting in exact zero.
+ * sysdeps/ieee754/ldbl-128/s_fma.c (__fma): Likewise.
+ * sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Use x * y + z for
+ exact 0 + 0.
+ * sysdeps/ieee754/ldbl-96/s_fma.c (__fma): Likewise.
+ * sysdeps/ieee754/ldbl-96/s_fmal.c (__fmal): Likewise.
+ * math/libm-test.inc (fma_test): Add more tests.
+ (fma_test_towardzero): New function.
+ (fma_test_downward): Likewise.
+ (fma_test_upward): Likewise.
+ (main): Call the new functions.
+
+2012-09-28 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/sparc/fpu/libm-test-ulps: Fix garbage in file.
+
+2012-09-28 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/posix/sleep.c (__sleep): Rewritten using __nanosleep
+ instead of SIGALRM.
+
+ * sysdeps/gnu/_G_config.h: Moved to ...
+ * sysdeps/unix/sysv/linux/_G_config.h: ... here.
+ * sysdeps/mach/hurd/_G_config.h: Moved to ...
+ * sysdeps/generic/_G_config.h: ... here.
+
+ * io/open.c (__open): Renamed to __libc_open. Make __open an alias.
+
+ * posix/Makefile ($(objpfx)config-name.h): Do $(make-target-directory).
+
+ * nss/Makefile ($(objpfx)/libnss_test1.so$(libnss_test1.so-version)):
+ Conditionalize target on [libnss_test1.so-version].
+
+ * elf/dl-sysdep.c: Conditionalize whole contents on [SHARED].
+
+ * Makeconfig (nssobjdir, resolvobjdir): Remove variables.
+ (elfobjdir): Move out of conditionals.
+
+ * nss/nsswitch.c (nss_new_service): Conditionalize definition and
+ declaration on [!DO_STATIC_NSS || SHARED], matching its only caller.
+ (__nss_lookup_function): Conditionalize label remove_from_tree on
+ [!DO_STATIC_NSS || SHARED], matching its only use.
+
+2012-09-28 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S: New file.
+ * sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S: New
+ file.
+ * sysdeps/sparc/sparc64/multiarch/Makefile: Add to
+ sysdep_routines.
+ * sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile: Likewise.
+ * sysdeps/sparc/sparc64/multiarch/memcpy.S: Use Niagara-4 memcpy
+ when HWCAP_SPARC_CRYPTO is present.
+
+2012-09-28 Pino Toscano <toscano.pino@tiscali.it>
+
+ * io/tst-mknodat.c: Create a FIFO instead of a socket.
+
+2012-09-28 Andreas Schwab <schwab@linux-m68k.org>
+
+ [BZ #6530]
+ * stdio-common/vfprintf.c (process_string_arg): Revert
+ 2000-07-22 change.
+
+2011-09-28 Jonathan Nieder <jrnieder@gmail.com>
+
+ * stdio-common/Makefile (tst-sprintf-ENV): Set environment
+ for testcase.
+ * stdio-common/tst-sprintf.c: Include <locale.h>
+ (main): Test sprintf's handling of incomplete multibyte
+ characters.
+
+2012-09-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf/dl-runtime.c (VERSYMIDX): Removed.
+ * elf/dl-version.c (VERSYMIDX): Likewise.
+ * elf/do-rel.h (VERSYMIDX): Likewise.
+ (VALIDX): Likewise.
+ * elf/dynamic-link.h (VERSYMIDX): Likewise.
+ * elf/rtld.c (VALIDX): Likewise.
+ (ADDRIDX): Likewise.
+ * sysdeps/sparc/sparc32/dl-machine.h (VALIDX): Likewise.
+ * sysdeps/sparc/sparc64/dl-machine.h (VALIDX): Likewise.
+ * sysdeps/x86_64/dl-tlsdesc.h (ADDRIDX): Likewise.
+ * sysdeps/generic/ldsodefs.h (VERSYMIDX): New macro.
+ (VALIDX): Likewise.
+ (ADDRIDX): Likewise.
+
+2012-09-28 Pino Toscano <toscano.pino@tiscali.it>
+
+ * sysdeps/pthread/aio_fsync.c: Fix the file mode checking.
+
+2012-09-28 Dmitry V. Levin <ldv@altlinux.org>
+
+ [BZ #11438]
+ * sysdeps/posix/getaddrinfo.c (default_scopes): Map RFC 1918 addresses
+ to global scope.
+ * posix/tst-rfc3484.c: Verify 10/8, 172.16/12 and 196.128/16
+ addresses are in the same scope as 192.0.2/24.
+ * posix/gai.conf: Document new scope table defaults.
+
+2012-09-28 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ [BZ #5298]
+ * libio/fileops.c (_IO_new_file_seekoff): Don't flush buffer
+ for ftell. Compute offsets from write pointers instead.
+ * libio/wfileops.c (_IO_wfile_seekoff): Likewise.
+
+2012-09-28 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ [BZ #14543]
+ * libio/Makefile (tests): New test case tst-fseek.
+ * libio/tst-fseek.c: New test case to verify that fseek/ftell
+ combination works in wide mode.
+ * libio/wfileops.c (_IO_wfile_seekoff): Adjust internal buffer
+ state when the external buffer state changes.
+
+2012-09-27 David S. Miller <davem@davemloft.net>
+
+ [BZ #14376]
+ * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Do not
+ pass reloc->r_addend in as the 'high' argument to
+ sparc64_fixup_plt when handling R_SPARC_JMP_IREL relocations.
+
+ * sysdeps/sparc/fpu/libm-test-ulps: Update.
+
+2012-09-28 Pino Toscano <toscano.pino@tiscali.it>
+
+ * rt/tst-aio2.c: Include <pthread.h>.
+ * rt/tst-aio3.c: Likewise.
+
+2012-09-27 Steve Ellcey <sellcey@mips.com>
+
+ * sysdeps/ieee754/ldbl-128/bits/huge_vall.h: Remove.
+
+2012-09-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * sysdeps/x86_64/multiarch/strncmp-ssse3.S: Conditionalize
+ contents on [SHARED].
+
+2012-09-26 Marek Polacek <polacek@redhat.com>
+
+ [BZ #14530]
+ [BZ #13741]
+ * misc/sys/cdefs.h: Define __extern_inline and __extern_always_inline
+ for C++ and GCC <4.3 as well as for non GCC compilers.
+
+2012-09-26 Markus Trippelsdorf <markus@trippelsdorf.de>
+
+ * sysdeps/x86_64/fpu/libm-test-ulps: Update.
+
+2012-09-25 Roland McGrath <roland@hack.frob.com>
+
+ * Makefile.in (all, install): Declare with .PHONY.
+ Reported by Michael Hope <michael.hope@linaro.org>.
+
+2012-09-25 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
+
+ * manual/platform.texi (PowerPC): Document __ppc_get_timebase_freq.
+ * sysdeps/powerpc/sys/platform/ppc.h: Include the operating
+ system header.
+ * sysdeps/unix/sysv/linux/powerpc/Makefile (sysdep_headers):
+ Likewise.
+ (sydep_routines): Add the new and the internal functions.
+ * sysdeps/unix/sysv/linux/powerpc/bits/ppc.h: New file.
+ * sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
+ (GLIBC_2.17): Add the new function.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
+ (GLIBC_2.17): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
+ (GLIBC_2.17): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
+ (GLIBC_2.17): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c: New file.
+
+2012-09-25 Alan Modra <amodra@gmail.com>
+
+ * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once):
+ Add release barrier before setting once_control to say
+ initialisation is done. Add hints on lwarx. Use macro in
+ place of isync.
+ (clear_once_control): Add release barrier.
+
+2012-09-25 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #13629]
+ * math/s_clog.c (__clog): Handle more values close to |z| = 1
+ specially.
+ * math/s_clog10.c (__clog10): Likewise.
+ * math/s_clog10f.c (__clog10f): Likewise.
+ * math/s_clog10l.c (__clog10l): Likewise.
+ * math/s_clogf.c (__clogf): Likewise.
+ * math/s_clogl.c (__clogl): Likewise.
+ * math/Makefile (libm-calls): Add x2y2m1.
+ * sysdeps/generic/math_private.h (__x2y2m1f): Declare.
+ (__x2y2m1): Likewise.
+ (__x2y2m1l): Likewise.
+ * sysdeps/ieee754/dbl-64/x2y2m1.c: New file.
+ * sysdeps/ieee754/dbl-64/x2y2m1f.c: Likewise.
+ * sysdeps/ieee754/ldbl-128/x2y2m1l.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c: Likewise.
+ * sysdeps/ieee754/ldbl-96/x2y2m1.c: Likewise.
+ * sysdeps/ieee754/ldbl-96/x2y2m1l.c: Likewise.
+ * math/libm-test.inc (clog_test, clog10_test): Add more tests.
+ * sysdeps/i386/fpu/libm-test-ulps: Update.
+ * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
+ [BZ #14621]
+ * posix/glob.c (next_brace_sub): Use size_t instead of unsigned
+ int as type of variable DEPTH.
+ (glob): Use size_t instead of int as type of variables NEWCOUNT
+ and OLD_PATHC.
+
+2012-09-25 Liubov Dmitrieva <liubov.dmitrieva@gmail.com>
+
+ * sysdeps/i386/i686/fpu/multiarch/Makefile (sysdep_routines):
+ Add s_sincosf-sse2.
+ * sysdeps/i386/i686/fpu/multiarch/s_sincosf.c: New file.
+ * sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S: New file.
+ * sysdeps/ieee754/flt-32/s_sincosf.c (SINCOSF, SINCOSF_FUNC): Add
+ macros for using routine as __sincosf_ia32.
+ Use macro for function declaration and weak_alias.
+ * sysdeps/i386/fpu/libm-test-ulps: Update.
+
+ * sysdeps/x86_64/fpu/s_sincosf.S: New file.
+ * sysdeps/x86_64/fpu/libm-test-ulps: Update.
+
+ * math/s_ccoshf.c (__ccoshf): Fix wrong usage of sincos for
+ subnormal argument.
+ * math/s_cexpf.c (__cexpf): Likewise.
+ * math/s_csinf.c (__csinf): Likewise.
+ * math/s_csinhf.c (__csinhf): Likewise.
+ * math/s_ctanf.c (__ctanf): Likewise.
+ * math/s_ctanhf.c (__ctanhf): Likewise.
+ * math/s_ccosh.c (__ccoshf): Likewise.
+ * math/s_cexp.c (__cexpl): Likewise.
+ * math/s_csin.c (__csin): Likewise.
+ * math/s_csinh.c (__csinh): Likewise.
+ * math/s_ctan.c (__ctan): Likewise.
+ * math/s_ctanh.c (ctanh): Likewise.
+ * math/s_ccoshl.c (__ccoshl): Likewise.
+ * math/s_cexpl.c (__cexpl): Likewise.
+ * math/s_csinl.c (__csinl): Likewise.
+ * math/s_csinhl.c (__csinhl): Likewise.
+ * math/s_ctanl.c (__ctanl): Likewise.
+ * math/s_ctanhl.c (__ctanhl): Likewise.
+
2012-09-25 Joseph Myers <joseph@codesourcery.com>
* libio/libio.h (_IO_size_t): Define to size_t, not _G_size_t.
diff --git a/libc/Makeconfig b/libc/Makeconfig
index d3b2cffe6..f380bb653 100644
--- a/libc/Makeconfig
+++ b/libc/Makeconfig
@@ -494,15 +494,14 @@ link-libc-tests = $(link-libc-before-gnulib) $(gnulib-tests)
rpath-dirs = math elf dlfcn nss nis rt resolv crypt
rpath-link = \
$(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
-elfobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)elf)
else
-nssobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)nss)
-resolvobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)resolv)
link-libc = $(common-objpfx)libc.a $(otherlibs) $(gnulib) $(common-objpfx)libc.a $(gnulib)
link-libc-tests = $(common-objpfx)libc.a $(otherlibs) $(gnulib-tests) $(common-objpfx)libc.a $(gnulib-tests)
endif
endif
+elfobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)elf)
+
# Differences in the linkers on the various platforms.
LDFLAGS-rpath-ORIGIN = -Wl,-rpath,'$$ORIGIN'
LDFLAGS-soname-fname = -Wl,-soname,$(@F)
diff --git a/libc/Makefile.in b/libc/Makefile.in
index 1f5dc1cd7..d73a78f8e 100644
--- a/libc/Makefile.in
+++ b/libc/Makefile.in
@@ -3,6 +3,8 @@ srcdir = @srcdir@
# Uncomment the line below if you want to do parallel build.
# PARALLELMFLAGS = -j 4
+.PHONY: all install
+
all .DEFAULT:
$(MAKE) -r PARALLELMFLAGS="$(PARALLELMFLAGS)" -C $(srcdir) objdir=`pwd` $@
diff --git a/libc/Makerules b/libc/Makerules
index 009e736aa..16db52461 100644
--- a/libc/Makerules
+++ b/libc/Makerules
@@ -1216,7 +1216,7 @@ ifeq ($(versioning),yes)
mv -f $@T $@
%.dynsym: %.so
- $(OBJDUMP) --dynamic-syms $< > $@T
+ LC_ALL=C $(OBJDUMP) --dynamic-syms $< > $@T
mv -f $@T $@
vpath %.abilist $(+sysdep_dirs)
diff --git a/libc/NEWS b/libc/NEWS
index 0933b30a7..1b13ac134 100644
--- a/libc/NEWS
+++ b/libc/NEWS
@@ -9,12 +9,14 @@ Version 2.17
* The following bugs are resolved with this release:
- 1349, 3479, 5044, 5400, 6778, 6808, 9685, 9914, 10014, 10038, 11607,
- 13412, 13542, 13679, 13717, 13696, 13939, 13966, 14042, 14090, 14166,
- 14150, 14151, 14154, 14157, 14166, 14173, 14195, 14237, 14252, 14283,
- 14298, 14303, 14307, 14328, 14331, 14336, 14337, 14347, 14349, 14459,
- 14476, 14505, 14510, 14516, 14518, 14519, 14532, 14538, 14544, 14545,
- 14562, 14576, 14579, 14583, 14587.
+ 1349, 3479, 5044, 5298, 5400, 6530, 6778, 6808, 9685, 9914, 10014, 10038,
+ 10631, 11438, 11607, 13412, 13542, 13629, 13679, 13696, 13717, 13741,
+ 13939, 13966, 14042, 14090, 14150, 14151, 14154, 14157, 14166, 14173,
+ 14195, 14237, 14251, 14252, 14283, 14298, 14303, 14307, 14328, 14331,
+ 14336, 14337, 14347, 14349, 14376, 14417, 14459, 14476, 14477, 14505,
+ 14510, 14516, 14518, 14519, 14530, 14532, 14538, 14543, 14544, 14545,
+ 14557, 14562, 14568, 14576, 14579, 14583, 14587, 14621, 14638, 14645,
+ 14648, 14660, 14661.
* Support for STT_GNU_IFUNC symbols added for s390 and s390x.
Optimized versions of memcpy, memset, and memcmp added for System z10 and
diff --git a/libc/aclocal.m4 b/libc/aclocal.m4
index 626e4369b..7ecdd6ba6 100644
--- a/libc/aclocal.m4
+++ b/libc/aclocal.m4
@@ -10,11 +10,19 @@ AC_PROVIDE([_AS_ECHO_N_PREPARE])dnl
AC_PROVIDE([_AS_ECHO_PREPARE])dnl
AC_PROVIDE([_AS_CR_PREPARE])dnl
AC_PROVIDE([_AS_TR_SH_PREPARE])dnl
+AC_PROVIDE([_AS_VAR_ARITH_PREPARE])dnl
AC_PROVIDE([AC_PROG_INSTALL])dnl
AC_PROVIDE([AC_PROG_CC])dnl
AC_PROVIDE([AC_PROG_CPP])dnl
AC_PROVIDE([_AS_PATH_SEPARATOR_PREPARE])dnl
AC_PROVIDE([_AS_TEST_PREPARE])dnl
+AC_PROVIDE([_AS_BASENAME_PREPARE])dnl
+AC_PROVIDE([_AS_ME_PREPARE])dnl
+AC_PROVIDE([_AS_LINENO_PREPARE])dnl
+AC_PROVIDE([AS_SHELL_FN_as_fn_set_status])dnl
+AC_PROVIDE([AS_SHELL_FN_as_fn_exit])dnl
+AC_PROVIDE([AS_SHELL_FN_as_fn_arith])dnl
+AC_PROVIDE([AS_SHELL_FN_ac_fn_c_try_compile])dnl
define([AS_MESSAGE_LOG_FD],5)dnl
define([AS_MESSAGE_FD],6)dnl
dnl Ripped out of AS_INIT, which does more cruft we do not want.
diff --git a/libc/bits/types.h b/libc/bits/types.h
index 041ace631..51ef89b7a 100644
--- a/libc/bits/types.h
+++ b/libc/bits/types.h
@@ -150,7 +150,6 @@ __STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */
__STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */
__STD_TYPE __DADDR_T_TYPE __daddr_t; /* The type of a disk address. */
-__STD_TYPE __SWBLK_T_TYPE __swblk_t; /* Type of a swap block maybe? */
__STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */
/* Clock ID used in clock and timer functions. */
diff --git a/libc/bits/typesizes.h b/libc/bits/typesizes.h
index c3debd0dd..ac18c8199 100644
--- a/libc/bits/typesizes.h
+++ b/libc/bits/typesizes.h
@@ -51,7 +51,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE void *
diff --git a/libc/config.h.in b/libc/config.h.in
index 68b399927..7d824eee6 100644
--- a/libc/config.h.in
+++ b/libc/config.h.in
@@ -183,6 +183,9 @@
/* Define if library functions should try to contact the nscd daemon. */
#undef USE_NSCD
+/* Define if the dynamic linker should consult an ld.so.cache file. */
+#undef USE_LDCONFIG
+
/*
*/
diff --git a/libc/configure b/libc/configure
index 6e30b1701..09a82e016 100755
--- a/libc/configure
+++ b/libc/configure
@@ -7588,6 +7588,10 @@ fi
+if test x$use_ldconfig = xyes; then
+ $as_echo "#define USE_LDCONFIG 1" >>confdefs.h
+
+fi
diff --git a/libc/configure.in b/libc/configure.in
index bf2cb5412..f9f908ad6 100644
--- a/libc/configure.in
+++ b/libc/configure.in
@@ -2189,6 +2189,9 @@ AC_SUBST(libc_cv_cc_nofma)
AC_SUBST(libc_cv_as_i686)
AC_SUBST(libc_cv_sparc_as_vis3)
+if test x$use_ldconfig = xyes; then
+ AC_DEFINE(USE_LDCONFIG)
+fi
AC_SUBST(use_ldconfig)
AC_SUBST(ldd_rewrite_script)
diff --git a/libc/csu/init-first.c b/libc/csu/init-first.c
index 050959dcb..0cfabbce2 100644
--- a/libc/csu/init-first.c
+++ b/libc/csu/init-first.c
@@ -1,4 +1,4 @@
-/* Initialization code run first thing by the ELF startup code. Stub version.
+/* Initialization code run first thing by the ELF startup code. Common version
Copyright (C) 1995-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -17,40 +17,76 @@
<http://www.gnu.org/licenses/>. */
#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
#include <unistd.h>
+#include <sysdep.h>
+#include <fpu_control.h>
+#include <sys/param.h>
#include <sys/types.h>
+#include <libc-internal.h>
+
+#include <ldsodefs.h>
/* Set nonzero if we have to be prepared for more then one libc being
used in the process. Safe assumption if initializer never runs. */
int __libc_multiple_libcs attribute_hidden = 1;
-extern void __libc_init (int, char **, char **);
-#ifdef USE_NONOPTION_FLAGS
-extern void __getopt_clean_environment (char **);
-#endif
+/* Remember the command line argument and enviroment contents for
+ later calls of initializers for dynamic libraries. */
+int __libc_argc attribute_hidden;
+char **__libc_argv attribute_hidden;
+
-#ifdef SHARED
void
-__libc_init_first (void)
+__libc_init_first (int argc, char **argv, char **envp)
{
+#ifdef SHARED
+ /* For DSOs we do not need __libc_init_first but instead _init. */
}
+
+void
+attribute_hidden
+_init (int argc, char **argv, char **envp)
+{
+#endif
+#ifdef USE_NONOPTION_FLAGS
+ extern void __getopt_clean_environment (char **);
#endif
+ __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
+
+ /* Make sure we don't initialize twice. */
+ if (!__libc_multiple_libcs)
+ {
+ /* Set the FPU control word to the proper default value if the
+ kernel would use a different value. (In a static program we
+ don't have this information.) */
#ifdef SHARED
-/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
- pointer in the dynamic section based solely on that. It is convention
- for this function to be in the `.init' section, but the symbol name is
- the only thing that really matters!! */
-void _init
-#else
-void __libc_init_first
+ if (__fpu_control != GLRO(dl_fpu_control))
#endif
-(int argc, char *arg0, ...)
-{
- char **argv = &arg0, **envp = &argv[argc + 1];
+ __setfpucw (__fpu_control);
+ }
+ /* Save the command-line arguments. */
+ __libc_argc = argc;
+ __libc_argv = argv;
__environ = envp;
- __libc_init (argc, argv, envp);
+
+#ifndef SHARED
+ __libc_init_secure ();
+
+ /* First the initialization which normally would be done by the
+ dynamic linker. */
+ _dl_non_dynamic_init ();
+#endif
+
+#ifdef VDSO_SETUP
+ VDSO_SETUP ();
+#endif
+
+ __init_misc (argc, argv, envp);
#ifdef USE_NONOPTION_FLAGS
/* This is a hack to make the special getopt in GNU libc working. */
@@ -59,4 +95,21 @@ void __libc_init_first
/* Initialize ctype data. */
__ctype_init ();
+
+#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
+ __libc_global_ctors ();
+#endif
+}
+
+/* This function is defined here so that if this file ever gets into
+ ld.so we will get a link error. Having this file silently included
+ in ld.so causes disaster, because the _init definition above will
+ cause ld.so to gain an init function, which is not a cool thing. */
+
+extern void _dl_start (void) __attribute__ ((noreturn));
+
+void
+_dl_start (void)
+{
+ abort ();
}
diff --git a/libc/dlfcn/dlerror.c b/libc/dlfcn/dlerror.c
index 8138cc278..c30b4f1d3 100644
--- a/libc/dlfcn/dlerror.c
+++ b/libc/dlfcn/dlerror.c
@@ -1,5 +1,5 @@
/* Return error detail for failing <dlfcn.h> functions.
- Copyright (C) 1995-2000,2002,2003,2004,2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -190,11 +190,14 @@ check_free (struct dl_action_result *rec)
{
/* We can free the string only if the allocation happened in the
C library used by the dynamic linker. This means, it is
- always the C library in the base namespave. */
+ always the C library in the base namespace. When we're statically
+ linked, the dynamic linker is part of the program and so always
+ uses the same C library we use here. */
+#ifdef SHARED
struct link_map *map = NULL;
Dl_info info;
- if (_dl_addr (check_free, &info, &map, NULL) != 0
- && map != NULL && map->l_ns == 0)
+ if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
+#endif
free ((char *) rec->errstring);
}
}
diff --git a/libc/elf/Makefile b/libc/elf/Makefile
index b3b950be4..276581812 100644
--- a/libc/elf/Makefile
+++ b/libc/elf/Makefile
@@ -19,6 +19,8 @@
subdir := elf
+include ../Makeconfig
+
headers = elf.h bits/elfclass.h link.h bits/link.h
routines = $(dl-routines) dl-support dl-iteratephdr \
dl-addr enbl-secure dl-profstub \
@@ -26,10 +28,13 @@ routines = $(dl-routines) dl-support dl-iteratephdr \
# The core dynamic linking functions are in libc for the static and
# profiled libraries.
-dl-routines = $(addprefix dl-,load cache lookup object reloc deps \
+dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \
runtime error init fini debug misc \
version profile conflict tls origin scope \
execstack caller open close trampoline)
+ifeq (yes,$(use-ldconfig))
+dl-routines += dl-cache
+endif
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
# But they are absent from the shared libc, because that code is in ld.so.
elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
@@ -45,8 +50,6 @@ CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-dl-iterate-phdr.c = $(uses-callbacks)
-include ../Makeconfig
-
ifeq ($(unwind-find-fde),yes)
routines += unwind-dw2-fde-glibc
shared-only-routines += unwind-dw2-fde-glibc
diff --git a/libc/elf/dl-hwcaps.c b/libc/elf/dl-hwcaps.c
new file mode 100644
index 000000000..d911548f2
--- /dev/null
+++ b/libc/elf/dl-hwcaps.c
@@ -0,0 +1,279 @@
+/* Hardware capability support for run-time dynamic loader.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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>
+#include <elf.h>
+#include <errno.h>
+#include <libintl.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+
+#include <dl-procinfo.h>
+
+#ifdef _DL_FIRST_PLATFORM
+# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
+#else
+# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
+#endif
+
+/* Return an array of useful/necessary hardware capability names. */
+const struct r_strlenpair *
+internal_function
+_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
+ size_t *max_capstrlen)
+{
+ /* Determine how many important bits are set. */
+ uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask);
+ size_t cnt = platform != NULL;
+ size_t n, m;
+ size_t total;
+ struct r_strlenpair *temp;
+ struct r_strlenpair *result;
+ struct r_strlenpair *rp;
+ char *cp;
+
+ /* Count the number of bits set in the masked value. */
+ for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n)
+ if ((masked & (1ULL << n)) != 0)
+ ++cnt;
+
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ /* The system-supplied DSO can contain a note of type 2, vendor "GNU".
+ This gives us a list of names to treat as fake hwcap bits. */
+
+ const char *dsocaps = NULL;
+ size_t dsocapslen = 0;
+ if (GLRO(dl_sysinfo_map) != NULL)
+ {
+ const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
+ const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdr[i].p_type == PT_NOTE)
+ {
+ const ElfW(Addr) start = (phdr[i].p_vaddr
+ + GLRO(dl_sysinfo_map)->l_addr);
+ const struct
+ {
+ ElfW(Word) vendorlen;
+ ElfW(Word) datalen;
+ ElfW(Word) type;
+ } *note = (const void *) start;
+ while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
+ {
+#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+ if (note->type == NT_GNU_HWCAP
+ && note->vendorlen == sizeof "GNU"
+ && !memcmp ((note + 1), "GNU", sizeof "GNU")
+ && note->datalen > 2 * sizeof (ElfW(Word)) + 2)
+ {
+ const ElfW(Word) *p = ((const void *) (note + 1)
+ + ROUND (sizeof "GNU"));
+ cnt += *p++;
+ ++p; /* Skip mask word. */
+ dsocaps = (const char *) p;
+ dsocapslen = note->datalen - sizeof *p * 2;
+ break;
+ }
+ note = ((const void *) (note + 1)
+ + ROUND (note->vendorlen) + ROUND (note->datalen));
+#undef ROUND
+ }
+ if (dsocaps != NULL)
+ break;
+ }
+ }
+#endif
+
+ /* For TLS enabled builds always add 'tls'. */
+ ++cnt;
+
+ /* Create temporary data structure to generate result table. */
+ temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
+ m = 0;
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ if (dsocaps != NULL)
+ {
+ const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
+ GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
+ /* Note that we add the dsocaps to the set already chosen by the
+ LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT).
+ So there is no way to request ignoring an OS-supplied dsocap
+ string and bit like you can ignore an OS-supplied HWCAP bit. */
+ GLRO(dl_hwcap_mask) |= (uint64_t) mask << _DL_FIRST_EXTRA;
+ size_t len;
+ for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
+ {
+ uint_fast8_t bit = *p++;
+ len = strlen (p);
+
+ /* Skip entries that are not enabled in the mask word. */
+ if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1))
+ {
+ temp[m].str = p;
+ temp[m].len = len;
+ ++m;
+ }
+ else
+ --cnt;
+ }
+ }
+#endif
+ for (n = 0; masked != 0; ++n)
+ if ((masked & (1ULL << n)) != 0)
+ {
+ temp[m].str = _dl_hwcap_string (n);
+ temp[m].len = strlen (temp[m].str);
+ masked ^= 1ULL << n;
+ ++m;
+ }
+ if (platform != NULL)
+ {
+ temp[m].str = platform;
+ temp[m].len = platform_len;
+ ++m;
+ }
+
+ temp[m].str = "tls";
+ temp[m].len = 3;
+ ++m;
+
+ assert (m == cnt);
+
+ /* Determine the total size of all strings together. */
+ if (cnt == 1)
+ total = temp[0].len + 1;
+ else
+ {
+ total = temp[0].len + temp[cnt - 1].len + 2;
+ if (cnt > 2)
+ {
+ total <<= 1;
+ for (n = 1; n + 1 < cnt; ++n)
+ total += temp[n].len + 1;
+ if (cnt > 3
+ && (cnt >= sizeof (size_t) * 8
+ || total + (sizeof (*result) << 3)
+ >= (1UL << (sizeof (size_t) * 8 - cnt + 3))))
+ _dl_signal_error (ENOMEM, NULL, NULL,
+ N_("cannot create capability list"));
+
+ total <<= cnt - 3;
+ }
+ }
+
+ /* The result structure: we use a very compressed way to store the
+ various combinations of capability names. */
+ *sz = 1 << cnt;
+ result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
+ if (result == NULL)
+ _dl_signal_error (ENOMEM, NULL, NULL,
+ N_("cannot create capability list"));
+
+ if (cnt == 1)
+ {
+ result[0].str = (char *) (result + *sz);
+ result[0].len = temp[0].len + 1;
+ result[1].str = (char *) (result + *sz);
+ result[1].len = 0;
+ cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
+ *cp = '/';
+ *sz = 2;
+ *max_capstrlen = result[0].len;
+
+ return result;
+ }
+
+ /* Fill in the information. This follows the following scheme
+ (indeces from TEMP for four strings):
+ entry #0: 0, 1, 2, 3 binary: 1111
+ #1: 0, 1, 3 1101
+ #2: 0, 2, 3 1011
+ #3: 0, 3 1001
+ This allows the representation of all possible combinations of
+ capability names in the string. First generate the strings. */
+ result[1].str = result[0].str = cp = (char *) (result + *sz);
+#define add(idx) \
+ cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
+ if (cnt == 2)
+ {
+ add (1);
+ add (0);
+ }
+ else
+ {
+ n = 1 << (cnt - 1);
+ do
+ {
+ n -= 2;
+
+ /* We always add the last string. */
+ add (cnt - 1);
+
+ /* Add the strings which have the bit set in N. */
+ for (m = cnt - 2; m > 0; --m)
+ if ((n & (1 << m)) != 0)
+ add (m);
+
+ /* Always add the first string. */
+ add (0);
+ }
+ while (n != 0);
+ }
+#undef add
+
+ /* Now we are ready to install the string pointers and length. */
+ for (n = 0; n < (1UL << cnt); ++n)
+ result[n].len = 0;
+ n = cnt;
+ do
+ {
+ size_t mask = 1 << --n;
+
+ rp = result;
+ for (m = 1 << cnt; m > 0; ++rp)
+ if ((--m & mask) != 0)
+ rp->len += temp[n].len + 1;
+ }
+ while (n != 0);
+
+ /* The first half of the strings all include the first string. */
+ n = (1 << cnt) - 2;
+ rp = &result[2];
+ while (n != (1UL << (cnt - 1)))
+ {
+ if ((--n & 1) != 0)
+ rp[0].str = rp[-2].str + rp[-2].len;
+ else
+ rp[0].str = rp[-1].str;
+ ++rp;
+ }
+
+ /* The second half starts right after the first part of the string of
+ the corresponding entry in the first half. */
+ do
+ {
+ rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1;
+ ++rp;
+ }
+ while (--n != 0);
+
+ /* The maximum string length. */
+ *max_capstrlen = result[0].len;
+
+ return result;
+}
diff --git a/libc/elf/dl-load.c b/libc/elf/dl-load.c
index 4d708bc5d..524e7369e 100644
--- a/libc/elf/dl-load.c
+++ b/libc/elf/dl-load.c
@@ -1090,7 +1090,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
struct loadcmd
{
ElfW(Addr) mapstart, mapend, dataend, allocend;
- off_t mapoff;
+ ElfW(Off) mapoff;
int prot;
} loadcmds[l->l_phnum], *c;
size_t nloadcmds = 0;
@@ -1347,7 +1347,7 @@ cannot allocate TLS data structures for initial thread");
l->l_text_end = l->l_addr + c->mapend;
if (l->l_phdr == 0
- && (ElfW(Off)) c->mapoff <= header->e_phoff
+ && c->mapoff <= header->e_phoff
&& ((size_t) (c->mapend - c->mapstart + c->mapoff)
>= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr))))
/* Found the program header in this segment. */
@@ -2201,6 +2201,7 @@ _dl_map_object (struct link_map *loader, const char *name,
&loader->l_runpath_dirs, &realname, &fb, loader,
LA_SER_RUNPATH, &found_other_class);
+#ifdef USE_LDCONFIG
if (fd == -1
&& (__builtin_expect (! (mode & __RTLD_SECURE), 1)
|| ! INTUSE(__libc_enable_secure))
@@ -2212,22 +2213,22 @@ _dl_map_object (struct link_map *loader, const char *name,
if (cached != NULL)
{
-#ifdef SHARED
+# ifdef SHARED
// XXX Correct to unconditionally default to namespace 0?
l = (loader
?: GL(dl_ns)[LM_ID_BASE]._ns_loaded
?: &GL(dl_rtld_map));
-#else
+# else
l = loader;
-#endif
+# endif
/* If the loader has the DF_1_NODEFLIB flag set we must not
use a cache entry from any of these directories. */
if (
-#ifndef SHARED
+# ifndef SHARED
/* 'l' is always != NULL for dynamically linked objects. */
l != NULL &&
-#endif
+# endif
__builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0))
{
const char *dirp = system_dirs;
@@ -2265,6 +2266,7 @@ _dl_map_object (struct link_map *loader, const char *name,
}
}
}
+#endif
/* Finally, try the default path. */
if (fd == -1
diff --git a/libc/elf/dl-open.c b/libc/elf/dl-open.c
index 903bdf13f..703218b0c 100644
--- a/libc/elf/dl-open.c
+++ b/libc/elf/dl-open.c
@@ -654,8 +654,8 @@ no more namespaces available for dlmopen()"));
int errcode = _dl_catch_error (&objname, &errstring, &malloced,
dl_open_worker, &args);
-#ifndef MAP_COPY
- /* We must munmap() the cache file. */
+#if defined USE_LDCONFIG && !defined MAP_COPY
+ /* We must unmap the cache file. */
_dl_unload_cache ();
#endif
diff --git a/libc/elf/dl-runtime.c b/libc/elf/dl-runtime.c
index fdaa364c6..2e02a218e 100644
--- a/libc/elf/dl-runtime.c
+++ b/libc/elf/dl-runtime.c
@@ -36,10 +36,6 @@
# define PLTREL ElfW(Rel)
#endif
-#ifndef VERSYMIDX
-# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
-#endif
-
/* The fixup functions might have need special attributes. If none
are provided define the macro as empty. */
#ifndef ARCH_FIXUP_ATTRIBUTE
diff --git a/libc/elf/dl-support.c b/libc/elf/dl-support.c
index dff9aa074..a74cf636d 100644
--- a/libc/elf/dl-support.c
+++ b/libc/elf/dl-support.c
@@ -164,6 +164,11 @@ uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
/* Address of the ELF headers in the vsyscall page. */
const ElfW(Ehdr) *_dl_sysinfo_dso;
+
+struct link_map *_dl_sysinfo_map;
+
+# include "get-dynamic-info.h"
+# include "setup-vdso.h"
#endif
/* During the program run we must not modify the global data of
@@ -269,6 +274,10 @@ _dl_non_dynamic_init (void)
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
+ /* Set up the data structures for the system-supplied DSO early,
+ so they can influence _dl_init_paths. */
+ setup_vdso (NULL, NULL);
+
/* Initialize the data structures for the search paths for shared
objects. */
_dl_init_paths (getenv ("LD_LIBRARY_PATH"));
@@ -329,23 +338,6 @@ _dl_non_dynamic_init (void)
}
}
-
-const struct r_strlenpair *
-internal_function
-_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
- size_t *max_capstrlen)
-{
- static struct r_strlenpair result;
- static char buf[1];
-
- result.str = buf; /* Does not really matter. */
- result.len = 0;
-
- *sz = 1;
- return &result;
-}
-
-
#ifdef DL_SYSINFO_IMPLEMENTATION
DL_SYSINFO_IMPLEMENTATION
#endif
diff --git a/libc/elf/dl-sysdep.c b/libc/elf/dl-sysdep.c
index 7d2283910..65a90469c 100644
--- a/libc/elf/dl-sysdep.c
+++ b/libc/elf/dl-sysdep.c
@@ -1,6 +1,5 @@
/* Operating system support for run-time dynamic linker. Generic Unix version.
- Copyright (C) 1995-1998,2000-2010,2012
- Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,6 +16,12 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+/* We conditionalize the whole of this file rather than simply eliding it
+ from the static build, because other sysdeps/ versions of this file
+ might define things needed by a static build. */
+
+#ifdef SHARED
+
#include <assert.h>
#include <elf.h>
#include <errno.h>
@@ -39,12 +44,6 @@
#include <hp-timing.h>
#include <tls.h>
-#ifdef _DL_FIRST_PLATFORM
-# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
-#else
-# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
-#endif
-
extern char **_environ attribute_hidden;
extern char _end[] attribute_hidden;
@@ -345,250 +344,4 @@ _dl_show_auxv (void)
}
}
-
-/* Return an array of useful/necessary hardware capability names. */
-const struct r_strlenpair *
-internal_function
-_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
- size_t *max_capstrlen)
-{
- /* Determine how many important bits are set. */
- uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask);
- size_t cnt = platform != NULL;
- size_t n, m;
- size_t total;
- struct r_strlenpair *temp;
- struct r_strlenpair *result;
- struct r_strlenpair *rp;
- char *cp;
-
- /* Count the number of bits set in the masked value. */
- for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n)
- if ((masked & (1ULL << n)) != 0)
- ++cnt;
-
-#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED
- /* The system-supplied DSO can contain a note of type 2, vendor "GNU".
- This gives us a list of names to treat as fake hwcap bits. */
-
- const char *dsocaps = NULL;
- size_t dsocapslen = 0;
- if (GLRO(dl_sysinfo_map) != NULL)
- {
- const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
- const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdr[i].p_type == PT_NOTE)
- {
- const ElfW(Addr) start = (phdr[i].p_vaddr
- + GLRO(dl_sysinfo_map)->l_addr);
- const struct
- {
- ElfW(Word) vendorlen;
- ElfW(Word) datalen;
- ElfW(Word) type;
- } *note = (const void *) start;
- while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
- {
-#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
- if (note->type == NT_GNU_HWCAP
- && note->vendorlen == sizeof "GNU"
- && !memcmp ((note + 1), "GNU", sizeof "GNU")
- && note->datalen > 2 * sizeof (ElfW(Word)) + 2)
- {
- const ElfW(Word) *p = ((const void *) (note + 1)
- + ROUND (sizeof "GNU"));
- cnt += *p++;
- ++p; /* Skip mask word. */
- dsocaps = (const char *) p;
- dsocapslen = note->datalen - sizeof *p * 2;
- break;
- }
- note = ((const void *) (note + 1)
- + ROUND (note->vendorlen) + ROUND (note->datalen));
-#undef ROUND
- }
- if (dsocaps != NULL)
- break;
- }
- }
-#endif
-
- /* For TLS enabled builds always add 'tls'. */
- ++cnt;
-
- /* Create temporary data structure to generate result table. */
- temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
- m = 0;
-#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED
- if (dsocaps != NULL)
- {
- const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
- GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
- /* Note that we add the dsocaps to the set already chosen by the
- LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT).
- So there is no way to request ignoring an OS-supplied dsocap
- string and bit like you can ignore an OS-supplied HWCAP bit. */
- GLRO(dl_hwcap_mask) |= (uint64_t) mask << _DL_FIRST_EXTRA;
- size_t len;
- for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
- {
- uint_fast8_t bit = *p++;
- len = strlen (p);
-
- /* Skip entries that are not enabled in the mask word. */
- if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1))
- {
- temp[m].str = p;
- temp[m].len = len;
- ++m;
- }
- else
- --cnt;
- }
- }
#endif
- for (n = 0; masked != 0; ++n)
- if ((masked & (1ULL << n)) != 0)
- {
- temp[m].str = _dl_hwcap_string (n);
- temp[m].len = strlen (temp[m].str);
- masked ^= 1ULL << n;
- ++m;
- }
- if (platform != NULL)
- {
- temp[m].str = platform;
- temp[m].len = platform_len;
- ++m;
- }
-
- temp[m].str = "tls";
- temp[m].len = 3;
- ++m;
-
- assert (m == cnt);
-
- /* Determine the total size of all strings together. */
- if (cnt == 1)
- total = temp[0].len + 1;
- else
- {
- total = temp[0].len + temp[cnt - 1].len + 2;
- if (cnt > 2)
- {
- total <<= 1;
- for (n = 1; n + 1 < cnt; ++n)
- total += temp[n].len + 1;
- if (cnt > 3
- && (cnt >= sizeof (size_t) * 8
- || total + (sizeof (*result) << 3)
- >= (1UL << (sizeof (size_t) * 8 - cnt + 3))))
- _dl_signal_error (ENOMEM, NULL, NULL,
- N_("cannot create capability list"));
-
- total <<= cnt - 3;
- }
- }
-
- /* The result structure: we use a very compressed way to store the
- various combinations of capability names. */
- *sz = 1 << cnt;
- result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
- if (result == NULL)
- _dl_signal_error (ENOMEM, NULL, NULL,
- N_("cannot create capability list"));
-
- if (cnt == 1)
- {
- result[0].str = (char *) (result + *sz);
- result[0].len = temp[0].len + 1;
- result[1].str = (char *) (result + *sz);
- result[1].len = 0;
- cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
- *cp = '/';
- *sz = 2;
- *max_capstrlen = result[0].len;
-
- return result;
- }
-
- /* Fill in the information. This follows the following scheme
- (indeces from TEMP for four strings):
- entry #0: 0, 1, 2, 3 binary: 1111
- #1: 0, 1, 3 1101
- #2: 0, 2, 3 1011
- #3: 0, 3 1001
- This allows the representation of all possible combinations of
- capability names in the string. First generate the strings. */
- result[1].str = result[0].str = cp = (char *) (result + *sz);
-#define add(idx) \
- cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
- if (cnt == 2)
- {
- add (1);
- add (0);
- }
- else
- {
- n = 1 << (cnt - 1);
- do
- {
- n -= 2;
-
- /* We always add the last string. */
- add (cnt - 1);
-
- /* Add the strings which have the bit set in N. */
- for (m = cnt - 2; m > 0; --m)
- if ((n & (1 << m)) != 0)
- add (m);
-
- /* Always add the first string. */
- add (0);
- }
- while (n != 0);
- }
-#undef add
-
- /* Now we are ready to install the string pointers and length. */
- for (n = 0; n < (1UL << cnt); ++n)
- result[n].len = 0;
- n = cnt;
- do
- {
- size_t mask = 1 << --n;
-
- rp = result;
- for (m = 1 << cnt; m > 0; ++rp)
- if ((--m & mask) != 0)
- rp->len += temp[n].len + 1;
- }
- while (n != 0);
-
- /* The first half of the strings all include the first string. */
- n = (1 << cnt) - 2;
- rp = &result[2];
- while (n != (1UL << (cnt - 1)))
- {
- if ((--n & 1) != 0)
- rp[0].str = rp[-2].str + rp[-2].len;
- else
- rp[0].str = rp[-1].str;
- ++rp;
- }
-
- /* The second half starts right after the first part of the string of
- the corresponding entry in the first half. */
- do
- {
- rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1;
- ++rp;
- }
- while (--n != 0);
-
- /* The maximum string length. */
- *max_capstrlen = result[0].len;
-
- return result;
-}
diff --git a/libc/elf/dl-version.c b/libc/elf/dl-version.c
index 047db2f82..269c0aadf 100644
--- a/libc/elf/dl-version.c
+++ b/libc/elf/dl-version.c
@@ -28,11 +28,6 @@
#include <assert.h>
-#ifndef VERSYMIDX
-# define VERSYMIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
-#endif
-
-
#define make_string(string, rest...) \
({ \
const char *all[] = { string, ## rest }; \
diff --git a/libc/elf/do-rel.h b/libc/elf/do-rel.h
index 1138ca4bd..cfb9a512f 100644
--- a/libc/elf/do-rel.h
+++ b/libc/elf/do-rel.h
@@ -32,14 +32,6 @@
(void *) (l_addr + relative->r_offset))
#endif
-#ifndef VERSYMIDX
-# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
-#endif
-#ifndef VALIDX
-# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRANUM + DT_VALTAGIDX (tag))
-#endif
-
/* Perform the relocations in MAP on the running program image as specified
by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT
relocations; they should be set up to call _dl_runtime_resolve, rather
diff --git a/libc/elf/dynamic-link.h b/libc/elf/dynamic-link.h
index 44f53b3c7..ad30d23a7 100644
--- a/libc/elf/dynamic-link.h
+++ b/libc/elf/dynamic-link.h
@@ -42,7 +42,6 @@
int internal_function _dl_try_allocate_static_tls (struct link_map *map);
#include <elf.h>
-#include <assert.h>
#ifdef RESOLVE_MAP
/* We pass reloc_addr as a pointer to void, as opposed to a pointer to
@@ -88,153 +87,7 @@ elf_machine_lazy_rel (struct link_map *map,
#include <dl-machine.h>
-#ifndef VERSYMIDX
-# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
-#endif
-
-
-/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
-#ifndef RESOLVE_MAP
-static
-#else
-auto
-#endif
-inline void __attribute__ ((unused, always_inline))
-elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
-{
- ElfW(Dyn) *dyn = l->l_ld;
- ElfW(Dyn) **info;
-#if __ELF_NATIVE_CLASS == 32
- typedef Elf32_Word d_tag_utype;
-#elif __ELF_NATIVE_CLASS == 64
- typedef Elf64_Xword d_tag_utype;
-#endif
-
-#ifndef RTLD_BOOTSTRAP
- if (dyn == NULL)
- return;
-#endif
-
- info = l->l_info;
-
- while (dyn->d_tag != DT_NULL)
- {
- if ((d_tag_utype) dyn->d_tag < DT_NUM)
- info[dyn->d_tag] = dyn;
- else if (dyn->d_tag >= DT_LOPROC &&
- dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
- info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
- else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
- info[VERSYMIDX (dyn->d_tag)] = dyn;
- else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
- info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM] = dyn;
- else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
- info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn;
- else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
- info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
- ++dyn;
- }
-
-#define DL_RO_DYN_TEMP_CNT 8
-
-#ifndef DL_RO_DYN_SECTION
- /* Don't adjust .dynamic unnecessarily. */
- if (l->l_addr != 0)
- {
- ElfW(Addr) l_addr = l->l_addr;
- int cnt = 0;
-
-# define ADJUST_DYN_INFO(tag) \
- do \
- if (info[tag] != NULL) \
- { \
- if (temp) \
- { \
- temp[cnt].d_tag = info[tag]->d_tag; \
- temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \
- info[tag] = temp + cnt++; \
- } \
- else \
- info[tag]->d_un.d_ptr += l_addr; \
- } \
- while (0)
-
- ADJUST_DYN_INFO (DT_HASH);
- ADJUST_DYN_INFO (DT_PLTGOT);
- ADJUST_DYN_INFO (DT_STRTAB);
- ADJUST_DYN_INFO (DT_SYMTAB);
-# if ! ELF_MACHINE_NO_RELA
- ADJUST_DYN_INFO (DT_RELA);
-# endif
-# if ! ELF_MACHINE_NO_REL
- ADJUST_DYN_INFO (DT_REL);
-# endif
- ADJUST_DYN_INFO (DT_JMPREL);
- ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
- ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
-# undef ADJUST_DYN_INFO
- assert (cnt <= DL_RO_DYN_TEMP_CNT);
- }
-#endif
- if (info[DT_PLTREL] != NULL)
- {
-#if ELF_MACHINE_NO_RELA
- assert (info[DT_PLTREL]->d_un.d_val == DT_REL);
-#elif ELF_MACHINE_NO_REL
- assert (info[DT_PLTREL]->d_un.d_val == DT_RELA);
-#else
- assert (info[DT_PLTREL]->d_un.d_val == DT_REL
- || info[DT_PLTREL]->d_un.d_val == DT_RELA);
-#endif
- }
-#if ! ELF_MACHINE_NO_RELA
- if (info[DT_RELA] != NULL)
- assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
-# endif
-# if ! ELF_MACHINE_NO_REL
- if (info[DT_REL] != NULL)
- assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
-#endif
-#ifdef RTLD_BOOTSTRAP
- /* Only the bind now flags are allowed. */
- assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
- || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
- assert (info[DT_FLAGS] == NULL
- || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
- /* Flags must not be set for ld.so. */
- assert (info[DT_RUNPATH] == NULL);
- assert (info[DT_RPATH] == NULL);
-#else
- if (info[DT_FLAGS] != NULL)
- {
- /* Flags are used. Translate to the old form where available.
- Since these l_info entries are only tested for NULL pointers it
- is ok if they point to the DT_FLAGS entry. */
- l->l_flags = info[DT_FLAGS]->d_un.d_val;
-
- if (l->l_flags & DF_SYMBOLIC)
- info[DT_SYMBOLIC] = info[DT_FLAGS];
- if (l->l_flags & DF_TEXTREL)
- info[DT_TEXTREL] = info[DT_FLAGS];
- if (l->l_flags & DF_BIND_NOW)
- info[DT_BIND_NOW] = info[DT_FLAGS];
- }
- if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
- {
- l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
-
- if (l->l_flags_1 & DF_1_NOW)
- info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
- }
- if (info[DT_RUNPATH] != NULL)
- /* If both RUNPATH and RPATH are given, the latter is ignored. */
- info[DT_RPATH] = NULL;
-#endif
-}
+#include "get-dynamic-info.h"
#ifdef RESOLVE_MAP
diff --git a/libc/elf/get-dynamic-info.h b/libc/elf/get-dynamic-info.h
new file mode 100644
index 000000000..ffac75f63
--- /dev/null
+++ b/libc/elf/get-dynamic-info.h
@@ -0,0 +1,161 @@
+/* Read the dynamic section at DYN and fill in INFO with indices DT_*.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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>
+
+#ifndef RESOLVE_MAP
+static
+#else
+auto
+#endif
+inline void __attribute__ ((unused, always_inline))
+elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
+{
+ ElfW(Dyn) *dyn = l->l_ld;
+ ElfW(Dyn) **info;
+#if __ELF_NATIVE_CLASS == 32
+ typedef Elf32_Word d_tag_utype;
+#elif __ELF_NATIVE_CLASS == 64
+ typedef Elf64_Xword d_tag_utype;
+#endif
+
+#ifndef RTLD_BOOTSTRAP
+ if (dyn == NULL)
+ return;
+#endif
+
+ info = l->l_info;
+
+ while (dyn->d_tag != DT_NULL)
+ {
+ if ((d_tag_utype) dyn->d_tag < DT_NUM)
+ info[dyn->d_tag] = dyn;
+ else if (dyn->d_tag >= DT_LOPROC &&
+ dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
+ info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
+ else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
+ info[VERSYMIDX (dyn->d_tag)] = dyn;
+ else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
+ info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM] = dyn;
+ else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
+ info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn;
+ else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
+ info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
+ ++dyn;
+ }
+
+#define DL_RO_DYN_TEMP_CNT 8
+
+#ifndef DL_RO_DYN_SECTION
+ /* Don't adjust .dynamic unnecessarily. */
+ if (l->l_addr != 0)
+ {
+ ElfW(Addr) l_addr = l->l_addr;
+ int cnt = 0;
+
+# define ADJUST_DYN_INFO(tag) \
+ do \
+ if (info[tag] != NULL) \
+ { \
+ if (temp) \
+ { \
+ temp[cnt].d_tag = info[tag]->d_tag; \
+ temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \
+ info[tag] = temp + cnt++; \
+ } \
+ else \
+ info[tag]->d_un.d_ptr += l_addr; \
+ } \
+ while (0)
+
+ ADJUST_DYN_INFO (DT_HASH);
+ ADJUST_DYN_INFO (DT_PLTGOT);
+ ADJUST_DYN_INFO (DT_STRTAB);
+ ADJUST_DYN_INFO (DT_SYMTAB);
+# if ! ELF_MACHINE_NO_RELA
+ ADJUST_DYN_INFO (DT_RELA);
+# endif
+# if ! ELF_MACHINE_NO_REL
+ ADJUST_DYN_INFO (DT_REL);
+# endif
+ ADJUST_DYN_INFO (DT_JMPREL);
+ ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
+ ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
+# undef ADJUST_DYN_INFO
+ assert (cnt <= DL_RO_DYN_TEMP_CNT);
+ }
+#endif
+ if (info[DT_PLTREL] != NULL)
+ {
+#if ELF_MACHINE_NO_RELA
+ assert (info[DT_PLTREL]->d_un.d_val == DT_REL);
+#elif ELF_MACHINE_NO_REL
+ assert (info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#else
+ assert (info[DT_PLTREL]->d_un.d_val == DT_REL
+ || info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#endif
+ }
+#if ! ELF_MACHINE_NO_RELA
+ if (info[DT_RELA] != NULL)
+ assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
+# endif
+# if ! ELF_MACHINE_NO_REL
+ if (info[DT_REL] != NULL)
+ assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
+#endif
+#ifdef RTLD_BOOTSTRAP
+ /* Only the bind now flags are allowed. */
+ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
+ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
+ assert (info[DT_FLAGS] == NULL
+ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
+ /* Flags must not be set for ld.so. */
+ assert (info[DT_RUNPATH] == NULL);
+ assert (info[DT_RPATH] == NULL);
+#else
+ if (info[DT_FLAGS] != NULL)
+ {
+ /* Flags are used. Translate to the old form where available.
+ Since these l_info entries are only tested for NULL pointers it
+ is ok if they point to the DT_FLAGS entry. */
+ l->l_flags = info[DT_FLAGS]->d_un.d_val;
+
+ if (l->l_flags & DF_SYMBOLIC)
+ info[DT_SYMBOLIC] = info[DT_FLAGS];
+ if (l->l_flags & DF_TEXTREL)
+ info[DT_TEXTREL] = info[DT_FLAGS];
+ if (l->l_flags & DF_BIND_NOW)
+ info[DT_BIND_NOW] = info[DT_FLAGS];
+ }
+ if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
+ {
+ l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
+
+ if (l->l_flags_1 & DF_1_NOW)
+ info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
+ }
+ if (info[DT_RUNPATH] != NULL)
+ /* If both RUNPATH and RPATH are given, the latter is ignored. */
+ info[DT_RPATH] = NULL;
+#endif
+}
diff --git a/libc/elf/rtld.c b/libc/elf/rtld.c
index 1ba35321b..0c5aebefa 100644
--- a/libc/elf/rtld.c
+++ b/libc/elf/rtld.c
@@ -255,15 +255,6 @@ RTLD_START
# error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
#endif
-#ifndef VALIDX
-# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRANUM + DT_VALTAGIDX (tag))
-#endif
-#ifndef ADDRIDX
-# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
-#endif
-
/* This is the second half of _dl_start (below). It can be inlined safely
under DONT_USE_BOOTSTRAP_MAP, where it is careful not to make any GOT
references. When the tools don't permit us to avoid using a GOT entry
@@ -883,6 +874,7 @@ security_init (void)
_dl_random = NULL;
}
+#include "setup-vdso.h"
/* The library search path. */
static const char *library_path attribute_relro;
@@ -1339,102 +1331,9 @@ of this helper program; chances are you did not intend to run this program.\n\
}
struct link_map **first_preload = &GL(dl_rtld_map).l_next;
-#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
/* Set up the data structures for the system-supplied DSO early,
so they can influence _dl_init_paths. */
- if (GLRO(dl_sysinfo_dso) != NULL)
- {
- /* Do an abridged version of the work _dl_map_object_from_fd would do
- to map in the object. It's already mapped and prelinked (and
- better be, since it's read-only and so we couldn't relocate it).
- We just want our data structures to describe it as if we had just
- mapped and relocated it normally. */
- struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
- 0, LM_ID_BASE);
- if (__builtin_expect (l != NULL, 1))
- {
- static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
-
- l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
- + GLRO(dl_sysinfo_dso)->e_phoff);
- l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
- for (uint_fast16_t i = 0; i < l->l_phnum; ++i)
- {
- const ElfW(Phdr) *const ph = &l->l_phdr[i];
- if (ph->p_type == PT_DYNAMIC)
- {
- l->l_ld = (void *) ph->p_vaddr;
- l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
- }
- else if (ph->p_type == PT_LOAD)
- {
- if (! l->l_addr)
- l->l_addr = ph->p_vaddr;
- if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
- l->l_map_end = ph->p_vaddr + ph->p_memsz;
- if ((ph->p_flags & PF_X)
- && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
- l->l_text_end = ph->p_vaddr + ph->p_memsz;
- }
- else
- /* There must be no TLS segment. */
- assert (ph->p_type != PT_TLS);
- }
- l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
- l->l_addr = l->l_map_start - l->l_addr;
- l->l_map_end += l->l_addr;
- l->l_text_end += l->l_addr;
- l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
- elf_get_dynamic_info (l, dyn_temp);
- _dl_setup_hash (l);
- l->l_relocated = 1;
-
- /* The vDSO is always used. */
- l->l_used = 1;
-
- /* Initialize l_local_scope to contain just this map. This allows
- the use of dl_lookup_symbol_x to resolve symbols within the vdso.
- So we create a single entry list pointing to l_real as its only
- element */
- l->l_local_scope[0]->r_nlist = 1;
- l->l_local_scope[0]->r_list = &l->l_real;
-
- /* Now that we have the info handy, use the DSO image's soname
- so this object can be looked up by name. Note that we do not
- set l_name here. That field gives the file name of the DSO,
- and this DSO is not associated with any file. */
- if (l->l_info[DT_SONAME] != NULL)
- {
- /* Work around a kernel problem. The kernel cannot handle
- addresses in the vsyscall DSO pages in writev() calls. */
- const char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
- + l->l_info[DT_SONAME]->d_un.d_val);
- size_t len = strlen (dsoname);
- char *copy = malloc (len);
- if (copy == NULL)
- _dl_fatal_printf ("out of memory\n");
- l->l_libname->name = l->l_name = memcpy (copy, dsoname, len);
- }
-
- /* Add the vDSO to the object list. */
- _dl_add_to_namespace_list (l, LM_ID_BASE);
-
- /* Rearrange the list so this DSO appears after rtld_map. */
- assert (l->l_next == NULL);
- assert (l->l_prev == main_map);
- GL(dl_rtld_map).l_next = l;
- l->l_prev = &GL(dl_rtld_map);
- first_preload = &l->l_next;
-
- /* We have a prelinked DSO preloaded by the system. */
- GLRO(dl_sysinfo_map) = l;
-# ifdef NEED_DL_SYSINFO
- if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT)
- GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr;
-# endif
- }
- }
-#endif
+ setup_vdso (main_map, &first_preload);
#ifdef DL_SYSDEP_OSCHECK
DL_SYSDEP_OSCHECK (_dl_fatal_printf);
@@ -2410,7 +2309,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
_dl_debug_state ();
LIBC_PROBE (init_complete, 2, LM_ID_BASE, r);
-#ifndef MAP_COPY
+#if defined USE_LDCONFIG && !defined MAP_COPY
/* We must munmap() the cache file. */
_dl_unload_cache ();
#endif
diff --git a/libc/elf/setup-vdso.h b/libc/elf/setup-vdso.h
new file mode 100644
index 000000000..f8f348a5f
--- /dev/null
+++ b/libc/elf/setup-vdso.h
@@ -0,0 +1,121 @@
+/* Set up the data structures for the system-supplied DSO.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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/>. */
+
+static inline void __attribute__ ((always_inline))
+setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+ struct link_map ***first_preload __attribute__ ((unused)))
+{
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ if (GLRO(dl_sysinfo_dso) == NULL)
+ return;
+
+ /* Do an abridged version of the work _dl_map_object_from_fd would do
+ to map in the object. It's already mapped and prelinked (and
+ better be, since it's read-only and so we couldn't relocate it).
+ We just want our data structures to describe it as if we had just
+ mapped and relocated it normally. */
+ struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
+ 0, LM_ID_BASE);
+ if (__builtin_expect (l != NULL, 1))
+ {
+ static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
+
+ l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
+ + GLRO(dl_sysinfo_dso)->e_phoff);
+ l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
+ for (uint_fast16_t i = 0; i < l->l_phnum; ++i)
+ {
+ const ElfW(Phdr) *const ph = &l->l_phdr[i];
+ if (ph->p_type == PT_DYNAMIC)
+ {
+ l->l_ld = (void *) ph->p_vaddr;
+ l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
+ }
+ else if (ph->p_type == PT_LOAD)
+ {
+ if (! l->l_addr)
+ l->l_addr = ph->p_vaddr;
+ if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
+ l->l_map_end = ph->p_vaddr + ph->p_memsz;
+ if ((ph->p_flags & PF_X)
+ && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
+ l->l_text_end = ph->p_vaddr + ph->p_memsz;
+ }
+ else
+ /* There must be no TLS segment. */
+ assert (ph->p_type != PT_TLS);
+ }
+ l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
+ l->l_addr = l->l_map_start - l->l_addr;
+ l->l_map_end += l->l_addr;
+ l->l_text_end += l->l_addr;
+ l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
+ elf_get_dynamic_info (l, dyn_temp);
+ _dl_setup_hash (l);
+ l->l_relocated = 1;
+
+ /* The vDSO is always used. */
+ l->l_used = 1;
+
+ /* Initialize l_local_scope to contain just this map. This allows
+ the use of dl_lookup_symbol_x to resolve symbols within the vdso.
+ So we create a single entry list pointing to l_real as its only
+ element */
+ l->l_local_scope[0]->r_nlist = 1;
+ l->l_local_scope[0]->r_list = &l->l_real;
+
+ /* Now that we have the info handy, use the DSO image's soname
+ so this object can be looked up by name. Note that we do not
+ set l_name here. That field gives the file name of the DSO,
+ and this DSO is not associated with any file. */
+ if (l->l_info[DT_SONAME] != NULL)
+ {
+ /* Work around a kernel problem. The kernel cannot handle
+ addresses in the vsyscall DSO pages in writev() calls. */
+ const char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
+ + l->l_info[DT_SONAME]->d_un.d_val);
+ size_t len = strlen (dsoname);
+ char *copy = malloc (len);
+ if (copy == NULL)
+ _dl_fatal_printf ("out of memory\n");
+ l->l_libname->name = l->l_name = memcpy (copy, dsoname, len);
+ }
+
+ /* Add the vDSO to the object list. */
+ _dl_add_to_namespace_list (l, LM_ID_BASE);
+
+# ifdef IS_IN_rtld
+ /* Rearrange the list so this DSO appears after rtld_map. */
+ assert (l->l_next == NULL);
+ assert (l->l_prev == main_map);
+ GL(dl_rtld_map).l_next = l;
+ l->l_prev = &GL(dl_rtld_map);
+ *first_preload = &l->l_next;
+# else
+ GL(dl_nns) = 1;
+# endif
+
+ /* We have a prelinked DSO preloaded by the system. */
+ GLRO(dl_sysinfo_map) = l;
+# ifdef NEED_DL_SYSINFO
+ if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT)
+ GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr;
+# endif
+ }
+#endif
+}
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 0a0e4a653..fd125ecb9 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -10,11 +10,12 @@ extern void *__mmap64 (void *__addr, size_t __len, int __prot,
extern int __munmap (void *__addr, size_t __len);
extern int __mprotect (void *__addr, size_t __len, int __prot);
+extern int __madvise (void *__addr, size_t __len, int __advice);
+libc_hidden_proto (__madvise)
+
/* This one is Linux specific. */
extern void *__mremap (void *__addr, size_t __old_len,
size_t __new_len, int __flags, ...);
-
-libc_hidden_proto (madvise);
#endif
#endif
diff --git a/libc/io/open.c b/libc/io/open.c
index 0916b1e01..b6911206a 100644
--- a/libc/io/open.c
+++ b/libc/io/open.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1995,1996,1997,2002,2007 Free Software Foundation, Inc.
+/* Open a file by name. Stub version.
+ Copyright (C) 1991-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -26,7 +27,7 @@ extern char **__libc_argv attribute_hidden;
/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
a third argument is the file protection. */
int
-__open (file, oflag)
+__libc_open (file, oflag)
const char *file;
int oflag;
{
@@ -49,10 +50,12 @@ __open (file, oflag)
__set_errno (ENOSYS);
return -1;
}
-libc_hidden_def (__open)
-stub_warning (open)
+libc_hidden_def (__libc_open)
+weak_alias (__libc_open, __open)
+libc_hidden_weak (__open)
+weak_alias (__libc_open, open)
-weak_alias (__open, open)
+stub_warning (open)
int
diff --git a/libc/io/openat.c b/libc/io/openat.c
index 92a5769e9..b49653936 100644
--- a/libc/io/openat.c
+++ b/libc/io/openat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2012 Free Software 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,13 @@
#include <stddef.h>
#include <stdio.h>
#include <sys/stat.h>
+#include <kernel-features.h>
+
+/* Some mostly-generic code (e.g. sysdeps/posix/getcwd.c) uses this variable
+ if __ASSUME_ATFCTS is not defined. */
+#ifndef __ASSUME_ATFCTS
+int __have_atfcts;
+#endif
/* Open FILE with access OFLAG. Interpret relative paths relative to
the directory associated with FD. If OFLAG includes O_CREAT, a
diff --git a/libc/io/tst-mknodat.c b/libc/io/tst-mknodat.c
index 9158c0dfd..cba4dffad 100644
--- a/libc/io/tst-mknodat.c
+++ b/libc/io/tst-mknodat.c
@@ -80,8 +80,8 @@ do_test (void)
}
closedir (dir);
- /* Create a new directory. */
- int e = mknodat (dir_fd, "some-sock", 0777 | S_IFSOCK, 0);
+ /* Create a new fifo. */
+ int e = mknodat (dir_fd, "some-fifo", 0777 | S_IFIFO, 0);
if (e == -1)
{
if (errno == ENOSYS)
@@ -90,19 +90,19 @@ do_test (void)
return 0;
}
- puts ("socket creation failed");
+ puts ("fifo creation failed");
return 1;
}
struct stat64 st1;
- if (fstatat64 (dir_fd, "some-sock", &st1, 0) != 0)
+ if (fstatat64 (dir_fd, "some-fifo", &st1, 0) != 0)
{
puts ("fstat64 failed");
return 1;
}
- if (!S_ISSOCK (st1.st_mode))
+ if (!S_ISFIFO (st1.st_mode))
{
- puts ("mknodat did not create a Unix domain socket");
+ puts ("mknodat did not create a fifo");
return 1;
}
@@ -124,15 +124,15 @@ do_test (void)
puts ("2nd fdopendir failed");
return 1;
}
- bool has_some_sock = false;
+ bool has_some_fifo = false;
while ((d = readdir64 (dir)) != NULL)
- if (strcmp (d->d_name, "some-sock") == 0)
+ if (strcmp (d->d_name, "some-fifo") == 0)
{
- has_some_sock = true;
+ has_some_fifo = true;
#ifdef _DIRENT_HAVE_D_TYPE
- if (d->d_type != DT_UNKNOWN && d->d_type != DT_SOCK)
+ if (d->d_type != DT_UNKNOWN && d->d_type != DT_FIFO)
{
- puts ("d_type for some-sock wrong");
+ puts ("d_type for some-fifo wrong");
return 1;
}
#endif
@@ -144,13 +144,13 @@ do_test (void)
}
closedir (dir);
- if (!has_some_sock)
+ if (!has_some_fifo)
{
- puts ("some-sock not in directory list");
+ puts ("some-fifo not in directory list");
return 1;
}
- if (unlinkat (dir_fd, "some-sock", 0) != 0)
+ if (unlinkat (dir_fd, "some-fifo", 0) != 0)
{
puts ("unlinkat failed");
return 1;
diff --git a/libc/libidn/ChangeLog b/libc/libidn/ChangeLog
index 58a95b1b9..07af658b2 100644
--- a/libc/libidn/ChangeLog
+++ b/libc/libidn/ChangeLog
@@ -1,3 +1,9 @@
+2012-10-09 Roland McGrath <roland@hack.frob.com>
+
+ * configure.in: If $shared != yes, just disable the add-on entirely
+ and issue a warning.
+ * configure: Regenerated.
+
2012-03-07 Ulrich Drepper <drepper@gmail.com>
* Makefile (distribute): Remove variable.
diff --git a/libc/libidn/configure b/libc/libidn/configure
index c6ba2eebc..39ed16352 100644
--- a/libc/libidn/configure
+++ b/libc/libidn/configure
@@ -1,8 +1,16 @@
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
libc_add_on_canonical=
-libc_add_on_subdirs=.
-# Get this defined in config.h for main source code to test.
-$as_echo "#define HAVE_LIBIDN 1" >>confdefs.h
+if test "$shared" = yes; then :
+ libc_add_on_subdirs=.
+
+ # Get this defined in config.h for main source code to test.
+ $as_echo "#define HAVE_LIBIDN 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libidn add-on ignored with --disable-shared" >&5
+$as_echo "$as_me: WARNING: libidn add-on ignored with --disable-shared" >&2;}
+fi
diff --git a/libc/libidn/configure.in b/libc/libidn/configure.in
index 38b9ad7fa..16740ffb9 100644
--- a/libc/libidn/configure.in
+++ b/libc/libidn/configure.in
@@ -2,7 +2,10 @@ dnl glibc configure fragment for libidn add-on
GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
libc_add_on_canonical=
-libc_add_on_subdirs=.
-# Get this defined in config.h for main source code to test.
-AC_DEFINE([HAVE_LIBIDN])
+AS_IF([test "$shared" = yes], [
+ libc_add_on_subdirs=.
+
+ # Get this defined in config.h for main source code to test.
+ AC_DEFINE([HAVE_LIBIDN])
+], [AC_MSG_WARN([libidn add-on ignored with --disable-shared])])
diff --git a/libc/libio/Makefile b/libc/libio/Makefile
index d66e090e6..ae1621fbd 100644
--- a/libc/libio/Makefile
+++ b/libc/libio/Makefile
@@ -77,7 +77,8 @@ tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
+= bug-rewind bug-rewind2 bug-ungetwc1 \
bug-wfflush bug-wmemstream1 tst-fopenloc2 \
tst_getwc \
- tst_putwc tst_wprintf tst_wprintf2 tst_wscanf tst-fgetwc bug-wsetpos
+ tst_putwc tst_wprintf tst_wprintf2 tst_wscanf \
+ tst-fgetwc bug-wsetpos tst-fseek
tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
+= tst_swprintf tst_swscanf \
tst-sscanf \
@@ -180,6 +181,7 @@ bug-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
tst-swscanf-ENV = LOCPATH=$(common-objpfx)localedata
bug-ftell-ENV = LOCPATH=$(common-objpfx)localedata
tst-fgetwc-ENV = LOCPATH=$(common-objpfx)localedata
+tst-fseek-ENV = LOCPATH=$(common-objpfx)localedata
generated = tst-fopenloc.mtrace tst-fopenloc.check
diff --git a/libc/libio/filedoalloc.c b/libc/libio/filedoalloc.c
index b7733c7f8..c9b0f0172 100644
--- a/libc/libio/filedoalloc.c
+++ b/libc/libio/filedoalloc.c
@@ -96,7 +96,7 @@ _IO_file_doallocate (fp)
{
_IO_size_t size;
char *p;
- struct _G_stat64 st;
+ struct stat64 st;
#ifndef _LIBC
/* If _IO_cleanup_registration_needed is non-zero, we should call the
diff --git a/libc/libio/fileops.c b/libc/libio/fileops.c
index a65f0afbc..7033dd165 100644
--- a/libc/libio/fileops.c
+++ b/libc/libio/fileops.c
@@ -643,7 +643,7 @@ libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow)
static int
mmap_remap_check (_IO_FILE *fp)
{
- struct _G_stat64 st;
+ struct stat64 st;
if (_IO_SYSSTAT (fp, &st) == 0
&& S_ISREG (st.st_mode) && st.st_size != 0
@@ -771,7 +771,7 @@ decide_maybe_mmap (_IO_FILE *fp)
file descriptors are for mmap-able objects and on 32-bit
machines we don't want to map files which are too large since
this would require too much virtual memory. */
- struct _G_stat64 st;
+ struct stat64 st;
if (_IO_SYSSTAT (fp, &st) == 0
&& S_ISREG (st.st_mode) && st.st_size != 0
@@ -986,6 +986,9 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
&& fp->_IO_write_base == fp->_IO_write_ptr);
+ bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
+ || _IO_in_put_mode (fp));
+
if (mode == 0)
dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
@@ -996,10 +999,8 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
which assumes file_ptr() is eGptr. Anyway, since we probably
end up flushing when we close(), it doesn't make much difference.)
FIXME: simulate mem-mapped files. */
-
- if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
- if (_IO_switch_to_get_mode (fp))
- return EOF;
+ else if (was_writing && _IO_switch_to_get_mode (fp))
+ return EOF;
if (fp->_IO_buf_base == NULL)
{
@@ -1018,7 +1019,17 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
{
case _IO_seek_cur:
/* Adjust for read-ahead (bytes is buffer). */
- offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ if (mode != 0 || !was_writing)
+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ else
+ {
+ /* _IO_read_end coincides with fp._offset, so the actual file position
+ is fp._offset - (_IO_read_end - new_write_ptr). This is fine
+ even if fp._offset is not set, since fp->_IO_read_end is then at
+ _IO_buf_base and this adjustment is for unbuffered output. */
+ offset -= fp->_IO_read_end - fp->_IO_write_ptr;
+ }
+
if (fp->_offset == _IO_pos_BAD)
{
if (mode != 0)
@@ -1046,7 +1057,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
break;
case _IO_seek_end:
{
- struct _G_stat64 st;
+ struct stat64 st;
if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
{
offset += st.st_size;
@@ -1247,7 +1258,7 @@ _IO_file_stat (fp, st)
void *st;
{
#ifdef _G_FSTAT64
- return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
+ return _G_FSTAT64 (fp->_fileno, (struct stat64 *) st);
#else
return fstat (fp->_fileno, (struct stat *) st);
#endif
diff --git a/libc/libio/libio.h b/libc/libio/libio.h
index f093a93e9..45f4707e6 100644
--- a/libc/libio/libio.h
+++ b/libc/libio/libio.h
@@ -37,7 +37,7 @@
#define _IO_size_t size_t
#define _IO_ssize_t __ssize_t
#define _IO_off_t __off_t
-#define _IO_off64_t _G_off64_t
+#define _IO_off64_t __off64_t
#define _IO_pid_t __pid_t
#define _IO_uid_t __uid_t
#define _IO_iconv_t _G_iconv_t
diff --git a/libc/libio/oldfileops.c b/libc/libio/oldfileops.c
index 8fda0484a..aa4e3f5f9 100644
--- a/libc/libio/oldfileops.c
+++ b/libc/libio/oldfileops.c
@@ -530,7 +530,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode)
break;
case _IO_seek_end:
{
- struct _G_stat64 st;
+ struct stat64 st;
if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
{
offset += st.st_size;
diff --git a/libc/libio/tst-fseek.c b/libc/libio/tst-fseek.c
new file mode 100644
index 000000000..457a08778
--- /dev/null
+++ b/libc/libio/tst-fseek.c
@@ -0,0 +1,173 @@
+/* Verify that fseek/ftell combination works for wide chars.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 <stdlib.h>
+#include <locale.h>
+#include <errno.h>
+#include <wchar.h>
+#include <unistd.h>
+#include <string.h>
+
+/* Defined in test-skeleton.c. */
+static int create_temp_file (const char *base, char **filename);
+
+
+static int
+do_seek_end (FILE *fp)
+{
+ long save;
+
+ if (fputws (L"abc\n", fp) == -1)
+ {
+ printf ("do_seek_end: fputws: %s\n", strerror (errno));
+ return 1;
+ }
+
+ save = ftell (fp);
+ rewind (fp);
+
+ if (fseek (fp, 0, SEEK_END) == -1)
+ {
+ printf ("do_seek_end: fseek: %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (save != ftell (fp))
+ {
+ printf ("save = %ld, ftell = %ld\n", save, ftell (fp));
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+do_seek_set (FILE *fp)
+{
+ long save1, save2;
+
+ if (fputws (L"ゅう\n", fp) == -1)
+ {
+ printf ("seek_set: fputws(1): %s\n", strerror (errno));
+ return 1;
+ }
+
+ save1 = ftell (fp);
+
+ if (fputws (L"ゅう\n", fp) == -1)
+ {
+ printf ("seek_set: fputws(2): %s\n", strerror (errno));
+ return 1;
+ }
+
+ save2 = ftell (fp);
+
+ if (fputws (L"ゅう\n", fp) == -1)
+ {
+ printf ("seek_set: fputws(3): %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (fseek (fp, save1, SEEK_SET) == -1)
+ {
+ printf ("seek_set: fseek(1): %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (save1 != ftell (fp))
+ {
+ printf ("save1 = %ld, ftell = %ld\n", save1, ftell (fp));
+ return 1;
+ }
+
+ if (fseek (fp, save2, SEEK_SET) == -1)
+ {
+ printf ("seek_set: fseek(2): %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (save2 != ftell (fp))
+ {
+ printf ("save2 = %ld, ftell = %ld\n", save2, ftell (fp));
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ if (setlocale (LC_ALL, "ja_JP.UTF-8") == NULL)
+ {
+ printf ("Cannot set ja_JP.UTF-8 locale.\n");
+ exit (1);
+ }
+
+ /* Retain messages in English. */
+ if (setlocale (LC_MESSAGES, "en_US.ISO-8859-1") == NULL)
+ {
+ printf ("Cannot set LC_MESSAGES to en_US.ISO-8859-1 locale.\n");
+ exit (1);
+ }
+
+ int ret = 0;
+ char *filename;
+ int fd = create_temp_file ("tst-fseek.out", &filename);
+
+ if (fd == -1)
+ return 1;
+
+ FILE *fp = fdopen (fd, "w+");
+ if (fp == NULL)
+ {
+ printf ("seek_set: fopen: %s\n", strerror (errno));
+ close (fd);
+ return 1;
+ }
+
+ if (do_seek_set (fp))
+ {
+ printf ("SEEK_SET test failed\n");
+ ret = 1;
+ }
+
+ /* Reopen the file. */
+ fclose (fp);
+ fp = fopen (filename, "w+");
+ if (fp == NULL)
+ {
+ printf ("seek_end: fopen: %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (do_seek_end (fp))
+ {
+ printf ("SEEK_END test failed\n");
+ ret = 1;
+ }
+
+ fclose (fp);
+
+ return ret;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libc/libio/wfileops.c b/libc/libio/wfileops.c
index b790029ff..44b1236c0 100644
--- a/libc/libio/wfileops.c
+++ b/libc/libio/wfileops.c
@@ -545,6 +545,57 @@ _IO_wfile_sync (fp)
}
libc_hidden_def (_IO_wfile_sync)
+/* Adjust the internal buffer pointers to reflect the state in the external
+ buffer. The content between fp->_IO_read_base and fp->_IO_read_ptr is
+ assumed to be converted and available in the range
+ fp->_wide_data->_IO_read_base and fp->_wide_data->_IO_read_end.
+
+ Returns 0 on success and -1 on error with the _IO_ERR_SEEN flag set. */
+static inline int
+adjust_wide_data (_IO_FILE *fp, bool do_convert)
+{
+ struct _IO_codecvt *cv = fp->_codecvt;
+
+ int clen = (*cv->__codecvt_do_encoding) (cv);
+
+ /* Take the easy way out for constant length encodings if we don't need to
+ convert. */
+ if (!do_convert && clen > 0)
+ {
+ fp->_wide_data->_IO_read_end += ((fp->_IO_read_ptr - fp->_IO_read_base)
+ / clen);
+ goto done;
+ }
+
+ enum __codecvt_result status;
+ const char *read_stop = (const char *) fp->_IO_read_base;
+ do
+ {
+
+ fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+ status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state,
+ fp->_IO_read_base, fp->_IO_read_ptr,
+ &read_stop,
+ fp->_wide_data->_IO_read_base,
+ fp->_wide_data->_IO_buf_end,
+ &fp->_wide_data->_IO_read_end);
+
+ /* Should we return EILSEQ? */
+ if (__builtin_expect (status == __codecvt_error, 0))
+ {
+ fp->_flags |= _IO_ERR_SEEN;
+ return -1;
+ }
+ }
+ while (__builtin_expect (status == __codecvt_partial, 0));
+
+done:
+ /* Now seek to _IO_read_end to behave as if we have read it all in. */
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
+
+ return 0;
+}
+
_IO_off64_t
_IO_wfile_seekoff (fp, offset, dir, mode)
_IO_FILE *fp;
@@ -562,6 +613,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
&& (fp->_wide_data->_IO_write_base
== fp->_wide_data->_IO_write_ptr));
+ bool was_writing = ((fp->_wide_data->_IO_write_ptr
+ > fp->_wide_data->_IO_write_base)
+ || _IO_in_put_mode (fp));
+
if (mode == 0)
{
/* XXX For wide stream with backup store it is not very
@@ -593,11 +648,8 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
which assumes file_ptr() is eGptr. Anyway, since we probably
end up flushing when we close(), it doesn't make much difference.)
FIXME: simulate mem-mapped files. */
-
- if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
- || _IO_in_put_mode (fp))
- if (_IO_switch_to_wget_mode (fp))
- return WEOF;
+ else if (was_writing && _IO_switch_to_wget_mode (fp))
+ return WEOF;
if (fp->_wide_data->_IO_buf_base == NULL)
{
@@ -628,29 +680,104 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
cv = fp->_codecvt;
clen = (*cv->__codecvt_do_encoding) (cv);
- if (clen > 0)
+ if (mode != 0 || !was_writing)
{
- offset -= (fp->_wide_data->_IO_read_end
- - fp->_wide_data->_IO_read_ptr) * clen;
- /* Adjust by readahead in external buffer. */
- offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ if (clen > 0)
+ {
+ offset -= (fp->_wide_data->_IO_read_end
+ - fp->_wide_data->_IO_read_ptr) * clen;
+ /* Adjust by readahead in external buffer. */
+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ }
+ else
+ {
+ int nread;
+
+ flushed:
+ delta = (fp->_wide_data->_IO_read_ptr
+ - fp->_wide_data->_IO_read_base);
+ fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
+ nread = (*cv->__codecvt_do_length) (cv,
+ &fp->_wide_data->_IO_state,
+ fp->_IO_read_base,
+ fp->_IO_read_end, delta);
+ fp->_IO_read_ptr = fp->_IO_read_base + nread;
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
+ offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
+ }
}
else
{
- int nread;
+ char *new_write_ptr = fp->_IO_write_ptr;
- delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base;
- fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
- nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
- fp->_IO_read_base,
- fp->_IO_read_end, delta);
- fp->_IO_read_ptr = fp->_IO_read_base + nread;
- fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
- offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
+ if (clen > 0)
+ offset += (fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base) / clen;
+ else
+ {
+ enum __codecvt_result status;
+ delta = (fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base);
+ const wchar_t *write_base = fp->_wide_data->_IO_write_base;
+
+ /* FIXME: This actually ends up in two iterations of conversion,
+ one here and the next when the buffer actually gets flushed.
+ It may be possible to optimize this in future so that
+ wdo_write identifies already converted content and does not
+ redo it. In any case, this is much better than having to
+ flush buffers for every ftell. */
+ do
+ {
+ /* Ugh, no point trying to avoid the flush. Just do it
+ and go back to how it was with the read mode. */
+ if (delta > 0 && new_write_ptr == fp->_IO_buf_end)
+ {
+ if (_IO_switch_to_wget_mode (fp))
+ return WEOF;
+ goto flushed;
+ }
+
+ const wchar_t *new_wbase = fp->_wide_data->_IO_write_base;
+ fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
+ status = (*cv->__codecvt_do_out) (cv,
+ &fp->_wide_data->_IO_state,
+ write_base,
+ write_base + delta,
+ &new_wbase,
+ new_write_ptr,
+ fp->_IO_buf_end,
+ &new_write_ptr);
+
+ delta -= new_wbase - write_base;
+
+ /* If there was an error, then return WEOF.
+ TODO: set buffer state. */
+ if (__builtin_expect (status == __codecvt_error, 0))
+ return WEOF;
+ }
+ while (delta > 0);
+ }
+
+ /* _IO_read_end coincides with fp._offset, so the actual file position
+ is fp._offset - (_IO_read_end - new_write_ptr). This is fine
+ even if fp._offset is not set, since fp->_IO_read_end is then at
+ _IO_buf_base and this adjustment is for unbuffered output. */
+ offset -= fp->_IO_read_end - new_write_ptr;
}
if (fp->_offset == _IO_pos_BAD)
- goto dumb;
+ {
+ if (mode != 0)
+ goto dumb;
+ else
+ {
+ result = _IO_SYSSEEK (fp, 0, dir);
+ if (result == EOF)
+ return result;
+ fp->_offset = result;
+ }
+ }
+
/* Make offset absolute, assuming current pointer is file_ptr(). */
offset += fp->_offset;
@@ -660,7 +787,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
break;
case _IO_seek_end:
{
- struct _G_stat64 st;
+ struct stat64 st;
if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
{
offset += st.st_size;
@@ -693,6 +820,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
fp->_wide_data->_IO_buf_base);
_IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
fp->_wide_data->_IO_buf_base);
+
+ if (adjust_wide_data (fp, false))
+ goto dumb;
+
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
goto resync;
}
@@ -733,6 +864,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
_IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
_IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
+
+ if (adjust_wide_data (fp, true))
+ goto dumb;
+
fp->_offset = result + count;
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
return offset;
diff --git a/libc/malloc/arena.c b/libc/malloc/arena.c
index b209e3b7c..eb9180eb9 100644
--- a/libc/malloc/arena.c
+++ b/libc/malloc/arena.c
@@ -634,7 +634,7 @@ shrink_heap(heap_info *h, long diff)
h->mprotect_size = new_size;
}
else
- madvise ((char *)h + new_size, diff, MADV_DONTNEED);
+ __madvise ((char *)h + new_size, diff, MADV_DONTNEED);
/*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/
h->size = new_size;
diff --git a/libc/malloc/malloc.c b/libc/malloc/malloc.c
index ca1d73f87..3f0b6b1cd 100644
--- a/libc/malloc/malloc.c
+++ b/libc/malloc/malloc.c
@@ -4450,7 +4450,7 @@ static int mtrim(mstate av, size_t pad)
content. */
memset (paligned_mem, 0x89, size & ~psm1);
#endif
- madvise (paligned_mem, size & ~psm1, MADV_DONTNEED);
+ __madvise (paligned_mem, size & ~psm1, MADV_DONTNEED);
result = 1;
}
@@ -4899,8 +4899,7 @@ malloc_printerr(int action, const char *str, void *ptr)
while (cp > buf)
*--cp = '0';
- __libc_message (action & 2,
- "*** glibc detected *** %s: %s: 0x%s ***\n",
+ __libc_message (action & 2, "*** Error in `%s': %s: 0x%s ***\n",
__libc_argv[0] ?: "<unknown>", str, cp);
}
else if (action & 2)
diff --git a/libc/manual/platform.texi b/libc/manual/platform.texi
index 02b5c554a..e387ff4cc 100644
--- a/libc/manual/platform.texi
+++ b/libc/manual/platform.texi
@@ -26,3 +26,11 @@ different from the processor frequency. More information is available in
without requiring assistance from the operating system, so it is very
efficient.
@end deftypefun
+
+@deftypefun {uint64_t} __ppc_get_timebase_freq (void)
+Read the current frequency at which the Time Base Register is updated.
+
+This frequency is not related to the processor clock or the bus clock.
+It is also possible that this frequency is not constant. More information is
+available in @cite{Power ISA 2.06b - Book II - Section 5.2}.
+@end deftypefun
diff --git a/libc/math/Makefile b/libc/math/Makefile
index c390d5511..5491c5b83 100644
--- a/libc/math/Makefile
+++ b/libc/math/Makefile
@@ -60,7 +60,7 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod \
s_catan s_casin s_ccos s_csin s_ctan s_ctanh s_cacos \
s_casinh s_cacosh s_catanh s_csqrt s_cpow s_cproj s_clog10 \
s_fma s_lrint s_llrint s_lround s_llround e_exp10 w_log2 \
- s_isinf_ns $(calls:s_%=m_%)
+ s_isinf_ns $(calls:s_%=m_%) x2y2m1
include ../Makeconfig
diff --git a/libc/math/gen-libm-test.pl b/libc/math/gen-libm-test.pl
index c2c22a5b1..5d9b2ea4b 100755
--- a/libc/math/gen-libm-test.pl
+++ b/libc/math/gen-libm-test.pl
@@ -323,7 +323,9 @@ sub parse_args {
}
# Special handling for some macros:
$cline .= " (\"$str\", ";
- if ($args[0] =~ /fpclassify|isnormal|isfinite|signbit/) {
+ if ($args[0] =~ /fpclassify|isnormal|isfinite|isinf|isnan|signbit
+ |isgreater|isgreaterequal|isless|islessequal
+ |islessgreater|isunordered/x) {
$c_call = "$args[0] (";
} else {
$c_call = " FUNC($args[0]) (";
diff --git a/libc/math/libm-test.inc b/libc/math/libm-test.inc
index 83d58998f..df860ebe2 100644
--- a/libc/math/libm-test.inc
+++ b/libc/math/libm-test.inc
@@ -40,13 +40,13 @@
/* This testsuite has currently tests for:
acos, acosh, asin, asinh, atan, atan2, atanh,
cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp10, exp2, expm1,
- fabs, fdim, floor, fma, fmax, fmin, fmod, fpclassify,
+ fabs, fdim, finite, floor, fma, fmax, fmin, fmod, fpclassify,
frexp, gamma, hypot,
ilogb, isfinite, isinf, isnan, isnormal,
isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered,
j0, j1, jn,
ldexp, lgamma, log, log10, log1p, log2, logb,
- modf, nearbyint, nextafter,
+ modf, nearbyint, nextafter, nexttoward,
pow, remainder, remquo, rint, lrint, llrint,
round, lround, llround,
scalb, scalbn, scalbln, signbit, sin, sincos, sinh, sqrt, tan, tanh, tgamma, trunc,
@@ -54,10 +54,14 @@
and for the following complex math functions:
cabs, cacos, cacosh, carg, casin, casinh, catan, catanh,
- ccos, ccosh, cexp, clog, cpow, cproj, csin, csinh, csqrt, ctan, ctanh.
+ ccos, ccosh, cexp, cimag, clog, clog10, conj, cpow, cproj, creal,
+ csin, csinh, csqrt, ctan, ctanh.
- At the moment the following functions aren't tested:
- drem, nan
+ At the moment the following functions and macros aren't tested:
+ drem (alias for remainder),
+ lgamma_r,
+ nan,
+ pow10 (alias for exp10).
Parameter handling is primitive in the moment:
--verbose=[0..3] for different levels of output:
@@ -83,8 +87,9 @@
aren't checked at the moment.
NaN values: There exist signalling and quiet NaNs. This implementation
- only uses quiet NaN as parameter but does not differenciate
- between the two kinds of NaNs as result.
+ only uses quiet NaN as parameter but does not differentiate
+ between the two kinds of NaNs as result. Where the sign of a NaN is
+ significant, this is not tested.
Inline functions: Inlining functions should give an improvement in
speed - but not in precission. The inlined functions return
@@ -215,6 +220,7 @@ static int ignore_max_ulp; /* Should we ignore max_ulp? */
static FLOAT minus_zero, plus_zero;
static FLOAT plus_infty, minus_infty, nan_value, max_value, min_value;
+static FLOAT min_subnorm_value;
static FLOAT max_error, real_max_error, imag_max_error;
@@ -2503,6 +2509,66 @@ clog_test (void)
TEST_c_c (clog, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 9.868649107778739752403260515979017248596e-19L, 1.061846605795612822522063052130030717368e-301L);
#endif
+ TEST_c_c (clog, 0x0.ffffffp0L, 0x0.ffffffp-100L, -5.960464655174753498633255797994360530379e-8L, 7.888609052210118054117285652827862296732e-31L);
+#ifndef TEST_FLOAT
+ TEST_c_c (clog, 0x0.fffffffffffff8p0L, 0x0.fffffffffffff8p-1000L, -1.110223024625156602053389888482372171810e-16L, 9.332636185032188789900895447238171696171e-302L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
+ TEST_c_c (clog, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp-15000L, -5.421010862427522170184200798202494495630e-20L, 3.548665303440282824232502561095699343814e-4516L);
+#endif
+
+ TEST_c_c (clog, 0x1a6p-10L, 0x3a5p-10L, -1.4305135209763571252847059962654228661815e-06L, 1.1460277178115757370775644871674016684074L);
+ TEST_c_c (clog, 0xf2p-10L, 0x3e3p-10L, 6.1988446308070710970664736815277450078106e-06L, 1.3322126499153926210226335249558203898460L);
+ TEST_c_c (clog, 0x4d4ep-15L, 0x6605p-15L, -1.6298145321400412054744424587143483169412e-08L, 0.9223574537155056772124552172295398141249L);
+ TEST_c_c (clog, 0x2818p-15L, 0x798fp-15L, 1.5366822245016167178749091974664853785194e-08L, 1.2522014929038946066987318471922169174157L);
+ TEST_c_c (clog, 0x9b57bp-20L, 0xcb7b4p-20L, -3.9563019528687610863490232935890272740908e-11L, 0.9187593477446338910857133065497364950682L);
+ TEST_c_c (clog, 0x2731p-20L, 0xfffd0p-20L, 4.4110493034041283943115971658295280288115e-11L, 1.5612279663766352262688735061954290528838L);
+ TEST_c_c (clog, 0x2ede88p-23L, 0x771c3fp-23L, -4.4764192352906350039050902870893173560494e-13L, 1.1959106857549200806818600493552847793381L);
+ TEST_c_c (clog, 0x11682p-23L, 0x7ffed1p-23L, 1.1723955140027907954461000991619077811832e-12L, 1.5622968405332756349813737986164832897108L);
+ TEST_c_c (clog, 0xa1f2c1p-24L, 0xc643aep-24L, -1.0480505352462576151523512837107080269981e-13L, 0.8858771987699967480545613322309315260313L);
+ TEST_c_c (clog, 0x659feap-24L, 0xeaf6f9p-24L, 3.7303493627403868207597214252239749960738e-14L, 1.1625816408046866464773042283673653469061L);
+#ifndef TEST_FLOAT
+ TEST_c_c (clog, 0x4447d7175p-35L, 0x6c445e00ap-35L, -1.4823076576950255933915367361099865652625e-20L, 1.0081311552703893116404606212158840190615L);
+ TEST_c_c (clog, 0x2dd46725bp-35L, 0x7783a1284p-35L, 4.4469229730850767799109418892826021157328e-20L, 1.2046235979300843056806465045930070146351L);
+ TEST_c_c (clog, 0x164c74eea876p-45L, 0x16f393482f77p-45L, -3.0292258760486853327810377824479932031744e-26L, 0.7998237934177411746093524982030330293980L);
+ TEST_c_c (clog, 0xfe961079616p-45L, 0x1bc37e09e6d1p-45L, 5.3718272201930019901317065495843842735179e-26L, 1.0503831592447830576186444373011142397404L);
+ TEST_c_c (clog, 0xa4722f19346cp-51L, 0x7f9631c5e7f07p-51L, -6.2122796286154679676173624516405339768606e-30L, 1.4904138780720095276446375492434049214172L);
+ TEST_c_c (clog, 0x10673dd0f2481p-51L, 0x7ef1d17cefbd2p-51L, 3.2047474274603604594851472963586149973093e-29L, 1.4422922682185099608731642353544207976604L);
+ TEST_c_c (clog, 0x8ecbf810c4ae6p-52L, 0xd479468b09a37p-52L, -9.7375017988218644730510244778042114638107e-30L, 0.9790637929494922564724108399524154766631L);
+ TEST_c_c (clog, 0x5b06b680ea2ccp-52L, 0xef452b965da9fp-52L, 8.3076914081087805757422664530653247447136e-30L, 1.2072712126771536614482822173033535043206L);
+ TEST_c_c (clog, 0x659b70ab7971bp-53L, 0x1f5d111e08abecp-53L, -2.5083311595699359750201056724289010648701e-30L, 1.3710185432462268491534742969536240564640L);
+ TEST_c_c (clog, 0x15cfbd1990d1ffp-53L, 0x176a3973e09a9ap-53L, 1.0168910106364605304135563536838075568606e-30L, 0.8208373755522359859870890246475340086663L);
+ TEST_c_c (clog, 0x1367a310575591p-54L, 0x3cfcc0a0541f60p-54L, 5.0844550531823026520677817684239496041087e-32L, 1.2627468605458094918919206628466016525397L);
+ TEST_c_c (clog, 0x55cb6d0c83af5p-55L, 0x7fe33c0c7c4e90p-55L, -5.2000108498455368032511404449795741611813e-32L, 1.5288921536982513453421343495466824420259L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+ TEST_c_c (clog, 0x298c62cb546588a7p-63L, 0x7911b1dfcc4ecdaep-63L, -1.1931267660846218205882675852805793644095e-36L, 1.2402109774337032400594953899784058127412L);
+ TEST_c_c (clog, 0x4d9c37e2b5cb4533p-63L, 0x65c98be2385a042ep-63L, 6.4064442119814669184296141278612389400075e-37L, 0.9193591364645830864185131402313014890145L);
+ TEST_c_c (clog, 0x602fd5037c4792efp-64L, 0xed3e2086dcca80b8p-64L, -2.3362950222592964220878638677292132852104e-37L, 1.1856121127236268105413184264288408265852L);
+ TEST_c_c (clog, 0x6b10b4f3520217b6p-64L, 0xe8893cbb449253a1p-64L, 2.4244570985709679851855191080208817099132e-37L, 1.1393074519572050614551047548718495655972L);
+ TEST_c_c (clog, 0x81b7efa81fc35ad1p-65L, 0x1ef4b835f1c79d812p-65L, -9.9182335850630508484862145328126979066934e-39L, 1.3146479888794807046338799047003947008804L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+ TEST_c_c (clog, 0x3f96469050f650869c2p-75L, 0x6f16b2c9c8b05988335p-75L, -1.0509738482436128031927971874674370984602e-45L, 1.0509191467640012308402149909370784281448L);
+ TEST_c_c (clog, 0x3157fc1d73233e580c8p-75L, 0x761b52ccd435d7c7f5fp-75L, 1.3487497719126364307640897239165442763573e-43L, 1.1750493008528425228929764149024375035382L);
+ TEST_c_c (clog, 0x155f8afc4c48685bf63610p-85L, 0x17d0cf2652cdbeb1294e19p-85L, -4.7775669192897997174762089350332738583822e-50L, 0.8393953487996880419413728440067635213372L);
+ TEST_c_c (clog, 0x13836d58a13448d750b4b9p-85L, 0x195ca7bc3ab4f9161edbe6p-85L, 2.8398125044729578740243199963484494962411e-50L, 0.9149964976334130461795060758257083099706L);
+ TEST_c_c (clog, 0x1df515eb171a808b9e400266p-95L, 0x7c71eb0cd4688dfe98581c77p-95L, -3.5048022044913950094635368750889659723004e-57L, 1.3345633256521815205858155673950177421079L);
+ TEST_c_c (clog, 0xe33f66c9542ca25cc43c867p-95L, 0x7f35a68ebd3704a43c465864p-95L, 4.1101771307217268747345114262406964584250e-56L, 1.4596065864518742494094402406719567059585L);
+ TEST_c_c (clog, 0x6771f22c64ed551b857c128b4cp-105L, 0x1f570e7a13cc3cf2f44fd793ea1p-105L, -1.4281333889622737316199756373421183559948e-62L, 1.3673546561165378090903506783353927980633L);
+ TEST_c_c (clog, 0x15d8ab6ed05ca514086ac3a1e84p-105L, 0x1761e480aa094c0b10b34b09ce9p-105L, 1.0027319539522347477331743836657426754857e-62L, 0.8193464073721167323313606647411269414759L);
+ TEST_c_c (clog, 0x187190c1a334497bdbde5a95f48p-106L, 0x3b25f08062d0a095c4cfbbc338dp-106L, -1.7471844652198029695350765775994001163767e-63L, 1.1789110097072986038243729592318526094314L);
+ TEST_c_c (clog, 0x6241ef0da53f539f02fad67dabp-106L, 0x3fb46641182f7efd9caa769dac0p-106L, 4.3299788920664682288477984749202524623248e-63L, 1.4746938237585656250866370987773473745867L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+ TEST_c_c (clog, 0x3e1d0a105ac4ebeacd9c6952d34cp-112L, 0xf859b3d1b06d005dcbb5516d5479p-112L, -1.1683999374665377365054966073875064467108e-66L, 1.3257197596350832748781065387304444940172L);
+ TEST_c_c (clog, 0x47017a2e36807acb1e5214b209dep-112L, 0xf5f4a550c9d75e3bb1839d865f0dp-112L, 1.5077923002544367932999503838191154621839e-65L, 1.2897445708311412721399861948957141824914L);
+ TEST_c_c (clog, 0x148f818cb7a9258fca942ade2a0cap-113L, 0x18854a34780b8333ec53310ad7001p-113L, -7.1865869169568789348552370692485515571497e-67L, 0.8730167479365994646287897223471819363668L);
+ TEST_c_c (clog, 0xfd95243681c055c2632286921092p-113L, 0x1bccabcd29ca2152860ec29e34ef7p-113L, 6.6255694866654064502633121109394710807528e-66L, 1.0526409614996288387567810726095850312049L);
+ TEST_c_c (clog, 0xdb85c467ee2aadd5f425fe0f4b8dp-114L, 0x3e83162a0f95f1dcbf97dddf410eap-114L, 4.6017338806965821566734340588575402712716e-67L, 1.3547418904611758959096647942223384691728L);
+ TEST_c_c (clog, 0x1415bcaf2105940d49a636e98ae59p-115L, 0x7e6a150adfcd1b0921d44b31f40f4p-115L, 2.5993421227864195179698176012564317527271e-67L, 1.4132318089683022770487383611430906982461L);
+#endif
+
END (clog, complex);
}
@@ -2663,6 +2729,66 @@ clog10_test (void)
TEST_c_c (clog10, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 4.285899851347756186652871946325962330640e-19L, 4.611541215247321502041995872887317363241e-302L);
#endif
+ TEST_c_c (clog10, 0x0.ffffffp0L, 0x0.ffffffp-100L, -2.588596909321764128428416045209904492216e-8L, 3.425979381266895667295625489912064603415e-31L);
+#ifndef TEST_FLOAT
+ TEST_c_c (clog10, 0x0.fffffffffffff8p0L, 0x0.fffffffffffff8p-1000L, -4.821637332766435821255375046554377090472e-17L, 4.053112396770095089737411317782466262176e-302L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
+ TEST_c_c (clog10, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp-15000L, -2.354315103889861110220423157644627849164e-20L, 1.541165759405643564697852372112893034397e-4516L);
+#endif
+
+ TEST_c_c (clog10, 0x1a6p-10L, 0x3a5p-10L, -6.2126412844802358329771948751248003038444e-07L, 0.4977135139537443711784513409096950995985L);
+ TEST_c_c (clog10, 0xf2p-10L, 0x3e3p-10L, 2.6921240173351112953324592659528481616879e-06L, 0.5785726025799636431142862788413361783862L);
+ TEST_c_c (clog10, 0x4d4ep-15L, 0x6605p-15L, -7.0781945783414996953799915941870192015212e-09L, 0.4005747524909781155537088181659175147564L);
+ TEST_c_c (clog10, 0x2818p-15L, 0x798fp-15L, 6.6737261053986614395049481326819059203910e-09L, 0.5438241985991753781478398141908629586460L);
+ TEST_c_c (clog10, 0x9b57bp-20L, 0xcb7b4p-20L, -1.7182001068739620267773842120965071561416e-11L, 0.3990121149225253562859800593935899629087L);
+ TEST_c_c (clog10, 0x2731p-20L, 0xfffd0p-20L, 1.9156943718715958194239364991329064049438e-11L, 0.6780326907904082601285090019969008967595L);
+ TEST_c_c (clog10, 0x2ede88p-23L, 0x771c3fp-23L, -1.9440841725722970687903291200493082253766e-13L, 0.5193774116724956222518530053006822210323L);
+ TEST_c_c (clog10, 0x11682p-23L, 0x7ffed1p-23L, 5.0916490233953865181284669870035717560498e-13L, 0.6784968969384861816694467029319146542069L);
+ TEST_c_c (clog10, 0xa1f2c1p-24L, 0xc643aep-24L, -4.5516256421319921959681423447271490869664e-14L, 0.3847315790697197749315054516562206543710L);
+ TEST_c_c (clog10, 0x659feap-24L, 0xeaf6f9p-24L, 1.6200701438094619117335617123525612051457e-14L, 0.5049027913635038013499728086604870749732L);
+#ifndef TEST_FLOAT
+ TEST_c_c (clog10, 0x4447d7175p-35L, 0x6c445e00ap-35L, -6.4375803621988389731799033530075237868110e-21L, 0.4378257977686804492768642780897650927167L);
+ TEST_c_c (clog10, 0x2dd46725bp-35L, 0x7783a1284p-35L, 1.9312741086596516918394613098872836703188e-20L, 0.5231613813514771042838490538484014771862L);
+ TEST_c_c (clog10, 0x164c74eea876p-45L, 0x16f393482f77p-45L, -1.3155760824064879362415202279780039150764e-26L, 0.3473590599762514228227328130640352044313L);
+ TEST_c_c (clog10, 0xfe961079616p-45L, 0x1bc37e09e6d1p-45L, 2.3329549194675052736016290082882121135546e-26L, 0.4561756099441139182878993697611751382976L);
+ TEST_c_c (clog10, 0xa4722f19346cp-51L, 0x7f9631c5e7f07p-51L, -2.6979587627476803379953050733225113494503e-30L, 0.6472785229986997177606324374555347813105L);
+ TEST_c_c (clog10, 0x10673dd0f2481p-51L, 0x7ef1d17cefbd2p-51L, 1.3918041236396763648388478552321724382899e-29L, 0.6263795733790237053262025311642907438291L);
+ TEST_c_c (clog10, 0x8ecbf810c4ae6p-52L, 0xd479468b09a37p-52L, -4.2289432987513243393180377141513840878196e-30L, 0.4252020027092323591068799049905597805296L);
+ TEST_c_c (clog10, 0x5b06b680ea2ccp-52L, 0xef452b965da9fp-52L, 3.6079845358966994996207055940336690133424e-30L, 0.5243112258263349992771652393178033846555L);
+ TEST_c_c (clog10, 0x659b70ab7971bp-53L, 0x1f5d111e08abecp-53L, -1.0893543813872082317104059174982092534059e-30L, 0.5954257879188711495921161433751775633232L);
+ TEST_c_c (clog10, 0x15cfbd1990d1ffp-53L, 0x176a3973e09a9ap-53L, 4.4163015461643576961232672330852798804976e-31L, 0.3564851427422832755956993418877523303529L);
+ TEST_c_c (clog10, 0x1367a310575591p-54L, 0x3cfcc0a0541f60p-54L, 2.2081507730821788480616336165447731164865e-32L, 0.5484039935757001196548030312819898864760L);
+ TEST_c_c (clog10, 0x55cb6d0c83af5p-55L, 0x7fe33c0c7c4e90p-55L, -2.2583360179249556400630343805573865814771e-32L, 0.6639894257763289307423302343317622430835L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+ TEST_c_c (clog10, 0x298c62cb546588a7p-63L, 0x7911b1dfcc4ecdaep-63L, -5.1816837072162316773907242302011632570857e-37L, 0.5386167838952956925896424154370364458140L);
+ TEST_c_c (clog10, 0x4d9c37e2b5cb4533p-63L, 0x65c98be2385a042ep-63L, 2.7822833698845776001753149807484078521508e-37L, 0.3992725998539071066769046272515417679815L);
+ TEST_c_c (clog10, 0x602fd5037c4792efp-64L, 0xed3e2086dcca80b8p-64L, -1.0146400362652473358437501879334790111898e-37L, 0.5149047982335273098246594109614460842099L);
+ TEST_c_c (clog10, 0x6b10b4f3520217b6p-64L, 0xe8893cbb449253a1p-64L, 1.0529283395205396881397407610630442563938e-37L, 0.4947949395762683446121140513971996916447L);
+ TEST_c_c (clog10, 0x81b7efa81fc35ad1p-65L, 0x1ef4b835f1c79d812p-65L, -4.3074341162203896332989394770760901408798e-39L, 0.5709443672155660428417571212549720987784L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+ TEST_c_c (clog10, 0x3f96469050f650869c2p-75L, 0x6f16b2c9c8b05988335p-75L, -4.5643214291682663316715446865040356750881e-46L, 0.4564083863660793840592614609053162690362L);
+ TEST_c_c (clog10, 0x3157fc1d73233e580c8p-75L, 0x761b52ccd435d7c7f5fp-75L, 5.8575458340992751256451490143468457830297e-44L, 0.5103174273246635294300470585396890237265L);
+ TEST_c_c (clog10, 0x155f8afc4c48685bf63610p-85L, 0x17d0cf2652cdbeb1294e19p-85L, -2.0748709499710785084693619097712106753591e-50L, 0.3645447681189598740620098186365764884771L);
+ TEST_c_c (clog10, 0x13836d58a13448d750b4b9p-85L, 0x195ca7bc3ab4f9161edbe6p-85L, 1.2333149003324592532859843519619084433953e-50L, 0.3973779298829931059309198145608711073016L);
+ TEST_c_c (clog10, 0x1df515eb171a808b9e400266p-95L, 0x7c71eb0cd4688dfe98581c77p-95L, -1.5221162575729652613635150540947625639689e-57L, 0.5795934880811949230121092882659698986043L);
+ TEST_c_c (clog10, 0xe33f66c9542ca25cc43c867p-95L, 0x7f35a68ebd3704a43c465864p-95L, 1.7850272475173865337808494725293124613817e-56L, 0.6338990862456906754888183278564382516852L);
+ TEST_c_c (clog10, 0x6771f22c64ed551b857c128b4cp-105L, 0x1f570e7a13cc3cf2f44fd793ea1p-105L, -6.2023045024810589256360494043570293518879e-63L, 0.5938345819561308555003145899438513900776L);
+ TEST_c_c (clog10, 0x15d8ab6ed05ca514086ac3a1e84p-105L, 0x1761e480aa094c0b10b34b09ce9p-105L, 4.3548095442952115860848857519953610343042e-63L, 0.3558376234889641500775150477035448866763L);
+ TEST_c_c (clog10, 0x187190c1a334497bdbde5a95f48p-106L, 0x3b25f08062d0a095c4cfbbc338dp-106L, -7.5879257211204444302994221436282805900756e-64L, 0.5119945461708707332160859198685423099187L);
+ TEST_c_c (clog10, 0x6241ef0da53f539f02fad67dabp-106L, 0x3fb46641182f7efd9caa769dac0p-106L, 1.8804859395820231849002915747252695375405e-63L, 0.6404513901551516189871978418046651877394L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+ TEST_c_c (clog10, 0x3e1d0a105ac4ebeacd9c6952d34cp-112L, 0xf859b3d1b06d005dcbb5516d5479p-112L, -5.0742964549782184008668435276046798273476e-67L, 0.5757527761596220360985719127090110408283L);
+ TEST_c_c (clog10, 0x47017a2e36807acb1e5214b209dep-112L, 0xf5f4a550c9d75e3bb1839d865f0dp-112L, 6.5482587585671294601662599808612773010057e-66L, 0.5601289501766423782280643144987875760229L);
+ TEST_c_c (clog10, 0x148f818cb7a9258fca942ade2a0cap-113L, 0x18854a34780b8333ec53310ad7001p-113L, -3.1210950417524756037077807411854181477733e-67L, 0.3791463562379872585396164879981280044658L);
+ TEST_c_c (clog10, 0xfd95243681c055c2632286921092p-113L, 0x1bccabcd29ca2152860ec29e34ef7p-113L, 2.8774482675253468630312378575186855052697e-66L, 0.4571561610046221605554903008571429975493L);
+ TEST_c_c (clog10, 0xdb85c467ee2aadd5f425fe0f4b8dp-114L, 0x3e83162a0f95f1dcbf97dddf410eap-114L, 1.9985076315737626043096596036300177494613e-67L, 0.5883569274304683249184005177865521205198L);
+ TEST_c_c (clog10, 0x1415bcaf2105940d49a636e98ae59p-115L, 0x7e6a150adfcd1b0921d44b31f40f4p-115L, 1.1288799405048268615023706955013387413519e-67L, 0.6137587762850841972073301550420510507903L);
+#endif
+
END (clog10, complex);
}
@@ -4299,6 +4425,23 @@ fdim_test (void)
static void
+finite_test (void)
+{
+ START (finite);
+
+ TEST_f_b (finite, 0, 1);
+ TEST_f_b (finite, minus_zero, 1);
+ TEST_f_b (finite, 10, 1);
+ TEST_f_b (finite, min_subnorm_value, 1);
+ TEST_f_b (finite, plus_infty, 0);
+ TEST_f_b (finite, minus_infty, 0);
+ TEST_f_b (finite, nan_value, 0);
+
+ END (finite);
+}
+
+
+static void
floor_test (void)
{
START (floor);
@@ -4439,6 +4582,45 @@ fma_test (void)
TEST_fff_f (fma, minus_infty, minus_infty, plus_infty, plus_infty);
TEST_fff_f (fma, plus_infty, minus_infty, minus_infty, minus_infty);
+ TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero);
+
+ TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero);
+ TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero);
+ TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero);
+ TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero);
+
+ TEST_fff_f (fma, min_value, min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+
#if defined (TEST_FLOAT) && FLT_MANT_DIG == 24
TEST_fff_f (fma, 0x1.7ff8p+13, 0x1.000002p+0, 0x1.ffffp-24, 0x1.7ff802p+13);
TEST_fff_f (fma, 0x1.fffp+0, 0x1.00001p+0, -0x1.fffp+0, 0x1.fffp-20);
@@ -4501,6 +4683,174 @@ fma_test (void)
static void
+fma_test_towardzero (void)
+{
+ int save_round_mode;
+ START (fma_towardzero);
+
+ save_round_mode = fegetround ();
+
+ if (!fesetround (FE_TOWARDZERO))
+ {
+ TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero);
+
+ TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero);
+ TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero);
+ TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero);
+ TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero);
+
+ TEST_fff_f (fma, min_value, min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ }
+
+ fesetround (save_round_mode);
+
+ END (fma_towardzero);
+}
+
+
+static void
+fma_test_downward (void)
+{
+ int save_round_mode;
+ START (fma_downward);
+
+ save_round_mode = fegetround ();
+
+ if (!fesetround (FE_DOWNWARD))
+ {
+ TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, minus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, plus_zero, minus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, plus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, plus_zero, minus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, plus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, minus_zero, minus_zero);
+
+ TEST_fff_f (fma, 1.0, 1.0, -1.0, minus_zero);
+ TEST_fff_f (fma, 1.0, -1.0, 1.0, minus_zero);
+ TEST_fff_f (fma, -1.0, 1.0, 1.0, minus_zero);
+ TEST_fff_f (fma, -1.0, -1.0, -1.0, minus_zero);
+
+ TEST_fff_f (fma, min_value, min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, plus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, minus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, plus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, minus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION);
+ }
+
+ fesetround (save_round_mode);
+
+ END (fma_downward);
+}
+
+
+static void
+fma_test_upward (void)
+{
+ int save_round_mode;
+ START (fma_upward);
+
+ save_round_mode = fegetround ();
+
+ if (!fesetround (FE_UPWARD))
+ {
+ TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+ TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+ TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero);
+
+ TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero);
+ TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero);
+ TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero);
+ TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero);
+
+ TEST_fff_f (fma, min_value, min_value, plus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, min_value, minus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, min_value, -min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, plus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION);
+ TEST_fff_f (fma, -min_value, -min_value, minus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION);
+ }
+
+ fesetround (save_round_mode);
+
+ END (fma_upward);
+}
+
+
+static void
fmax_test (void)
{
START (fmax);
@@ -4642,6 +4992,7 @@ fpclassify_test (void)
TEST_f_i (fpclassify, plus_zero, FP_ZERO);
TEST_f_i (fpclassify, minus_zero, FP_ZERO);
TEST_f_i (fpclassify, 1000, FP_NORMAL);
+ TEST_f_i (fpclassify, min_subnorm_value, FP_SUBNORMAL);
END (fpclassify);
}
@@ -4791,6 +5142,7 @@ isfinite_test (void)
TEST_f_b (isfinite, 0, 1);
TEST_f_b (isfinite, minus_zero, 1);
TEST_f_b (isfinite, 10, 1);
+ TEST_f_b (isfinite, min_subnorm_value, 1);
TEST_f_b (isfinite, plus_infty, 0);
TEST_f_b (isfinite, minus_infty, 0);
TEST_f_b (isfinite, nan_value, 0);
@@ -4799,6 +5151,163 @@ isfinite_test (void)
}
static void
+isgreater_test (void)
+{
+ START (isgreater);
+
+ TEST_ff_i (isgreater, minus_zero, minus_zero, 0);
+ TEST_ff_i (isgreater, minus_zero, plus_zero, 0);
+ TEST_ff_i (isgreater, minus_zero, (FLOAT) 1, 0);
+ TEST_ff_i (isgreater, minus_zero, nan_value, 0);
+ TEST_ff_i (isgreater, plus_zero, minus_zero, 0);
+ TEST_ff_i (isgreater, plus_zero, plus_zero, 0);
+ TEST_ff_i (isgreater, plus_zero, (FLOAT) 1, 0);
+ TEST_ff_i (isgreater, plus_zero, nan_value, 0);
+ TEST_ff_i (isgreater, (FLOAT) 1, minus_zero, 1);
+ TEST_ff_i (isgreater, (FLOAT) 1, plus_zero, 1);
+ TEST_ff_i (isgreater, (FLOAT) 1, (FLOAT) 1, 0);
+ TEST_ff_i (isgreater, (FLOAT) 1, nan_value, 0);
+ TEST_ff_i (isgreater, nan_value, minus_zero, 0);
+ TEST_ff_i (isgreater, nan_value, plus_zero, 0);
+ TEST_ff_i (isgreater, nan_value, (FLOAT) 1, 0);
+ TEST_ff_i (isgreater, nan_value, nan_value, 0);
+
+ END (isgreater);
+}
+
+static void
+isgreaterequal_test (void)
+{
+ START (isgreaterequal);
+
+ TEST_ff_i (isgreaterequal, minus_zero, minus_zero, 1);
+ TEST_ff_i (isgreaterequal, minus_zero, plus_zero, 1);
+ TEST_ff_i (isgreaterequal, minus_zero, (FLOAT) 1, 0);
+ TEST_ff_i (isgreaterequal, minus_zero, nan_value, 0);
+ TEST_ff_i (isgreaterequal, plus_zero, minus_zero, 1);
+ TEST_ff_i (isgreaterequal, plus_zero, plus_zero, 1);
+ TEST_ff_i (isgreaterequal, plus_zero, (FLOAT) 1, 0);
+ TEST_ff_i (isgreaterequal, plus_zero, nan_value, 0);
+ TEST_ff_i (isgreaterequal, (FLOAT) 1, minus_zero, 1);
+ TEST_ff_i (isgreaterequal, (FLOAT) 1, plus_zero, 1);
+ TEST_ff_i (isgreaterequal, (FLOAT) 1, (FLOAT) 1, 1);
+ TEST_ff_i (isgreaterequal, (FLOAT) 1, nan_value, 0);
+ TEST_ff_i (isgreaterequal, nan_value, minus_zero, 0);
+ TEST_ff_i (isgreaterequal, nan_value, plus_zero, 0);
+ TEST_ff_i (isgreaterequal, nan_value, (FLOAT) 1, 0);
+ TEST_ff_i (isgreaterequal, nan_value, nan_value, 0);
+
+ END (isgreaterequal);
+}
+
+static void
+isinf_test (void)
+{
+ START (isinf);
+
+ TEST_f_b (isinf, 0, 0);
+ TEST_f_b (isinf, minus_zero, 0);
+ TEST_f_b (isinf, 10, 0);
+ TEST_f_b (isinf, min_subnorm_value, 0);
+ TEST_f_b (isinf, plus_infty, 1);
+ TEST_f_b (isinf, minus_infty, 1);
+ TEST_f_b (isinf, nan_value, 0);
+
+ END (isinf);
+}
+
+static void
+isless_test (void)
+{
+ START (isless);
+
+ TEST_ff_i (isless, minus_zero, minus_zero, 0);
+ TEST_ff_i (isless, minus_zero, plus_zero, 0);
+ TEST_ff_i (isless, minus_zero, (FLOAT) 1, 1);
+ TEST_ff_i (isless, minus_zero, nan_value, 0);
+ TEST_ff_i (isless, plus_zero, minus_zero, 0);
+ TEST_ff_i (isless, plus_zero, plus_zero, 0);
+ TEST_ff_i (isless, plus_zero, (FLOAT) 1, 1);
+ TEST_ff_i (isless, plus_zero, nan_value, 0);
+ TEST_ff_i (isless, (FLOAT) 1, minus_zero, 0);
+ TEST_ff_i (isless, (FLOAT) 1, plus_zero, 0);
+ TEST_ff_i (isless, (FLOAT) 1, (FLOAT) 1, 0);
+ TEST_ff_i (isless, (FLOAT) 1, nan_value, 0);
+ TEST_ff_i (isless, nan_value, minus_zero, 0);
+ TEST_ff_i (isless, nan_value, plus_zero, 0);
+ TEST_ff_i (isless, nan_value, (FLOAT) 1, 0);
+ TEST_ff_i (isless, nan_value, nan_value, 0);
+
+ END (isless);
+}
+
+static void
+islessequal_test (void)
+{
+ START (islessequal);
+
+ TEST_ff_i (islessequal, minus_zero, minus_zero, 1);
+ TEST_ff_i (islessequal, minus_zero, plus_zero, 1);
+ TEST_ff_i (islessequal, minus_zero, (FLOAT) 1, 1);
+ TEST_ff_i (islessequal, minus_zero, nan_value, 0);
+ TEST_ff_i (islessequal, plus_zero, minus_zero, 1);
+ TEST_ff_i (islessequal, plus_zero, plus_zero, 1);
+ TEST_ff_i (islessequal, plus_zero, (FLOAT) 1, 1);
+ TEST_ff_i (islessequal, plus_zero, nan_value, 0);
+ TEST_ff_i (islessequal, (FLOAT) 1, minus_zero, 0);
+ TEST_ff_i (islessequal, (FLOAT) 1, plus_zero, 0);
+ TEST_ff_i (islessequal, (FLOAT) 1, (FLOAT) 1, 1);
+ TEST_ff_i (islessequal, (FLOAT) 1, nan_value, 0);
+ TEST_ff_i (islessequal, nan_value, minus_zero, 0);
+ TEST_ff_i (islessequal, nan_value, plus_zero, 0);
+ TEST_ff_i (islessequal, nan_value, (FLOAT) 1, 0);
+ TEST_ff_i (islessequal, nan_value, nan_value, 0);
+
+ END (islessequal);
+}
+
+static void
+islessgreater_test (void)
+{
+ START (islessgreater);
+
+ TEST_ff_i (islessgreater, minus_zero, minus_zero, 0);
+ TEST_ff_i (islessgreater, minus_zero, plus_zero, 0);
+ TEST_ff_i (islessgreater, minus_zero, (FLOAT) 1, 1);
+ TEST_ff_i (islessgreater, minus_zero, nan_value, 0);
+ TEST_ff_i (islessgreater, plus_zero, minus_zero, 0);
+ TEST_ff_i (islessgreater, plus_zero, plus_zero, 0);
+ TEST_ff_i (islessgreater, plus_zero, (FLOAT) 1, 1);
+ TEST_ff_i (islessgreater, plus_zero, nan_value, 0);
+ TEST_ff_i (islessgreater, (FLOAT) 1, minus_zero, 1);
+ TEST_ff_i (islessgreater, (FLOAT) 1, plus_zero, 1);
+ TEST_ff_i (islessgreater, (FLOAT) 1, (FLOAT) 1, 0);
+ TEST_ff_i (islessgreater, (FLOAT) 1, nan_value, 0);
+ TEST_ff_i (islessgreater, nan_value, minus_zero, 0);
+ TEST_ff_i (islessgreater, nan_value, plus_zero, 0);
+ TEST_ff_i (islessgreater, nan_value, (FLOAT) 1, 0);
+ TEST_ff_i (islessgreater, nan_value, nan_value, 0);
+
+ END (islessgreater);
+}
+
+static void
+isnan_test (void)
+{
+ START (isnan);
+
+ TEST_f_b (isnan, 0, 0);
+ TEST_f_b (isnan, minus_zero, 0);
+ TEST_f_b (isnan, 10, 0);
+ TEST_f_b (isnan, min_subnorm_value, 0);
+ TEST_f_b (isnan, plus_infty, 0);
+ TEST_f_b (isnan, minus_infty, 0);
+ TEST_f_b (isnan, nan_value, 1);
+
+ END (isnan);
+}
+
+static void
isnormal_test (void)
{
START (isnormal);
@@ -4806,6 +5315,7 @@ isnormal_test (void)
TEST_f_b (isnormal, 0, 0);
TEST_f_b (isnormal, minus_zero, 0);
TEST_f_b (isnormal, 10, 1);
+ TEST_f_b (isnormal, min_subnorm_value, 0);
TEST_f_b (isnormal, plus_infty, 0);
TEST_f_b (isnormal, minus_infty, 0);
TEST_f_b (isnormal, nan_value, 0);
@@ -4814,6 +5324,31 @@ isnormal_test (void)
}
static void
+isunordered_test (void)
+{
+ START (isunordered);
+
+ TEST_ff_i (isunordered, minus_zero, minus_zero, 0);
+ TEST_ff_i (isunordered, minus_zero, plus_zero, 0);
+ TEST_ff_i (isunordered, minus_zero, (FLOAT) 1, 0);
+ TEST_ff_i (isunordered, minus_zero, nan_value, 1);
+ TEST_ff_i (isunordered, plus_zero, minus_zero, 0);
+ TEST_ff_i (isunordered, plus_zero, plus_zero, 0);
+ TEST_ff_i (isunordered, plus_zero, (FLOAT) 1, 0);
+ TEST_ff_i (isunordered, plus_zero, nan_value, 1);
+ TEST_ff_i (isunordered, (FLOAT) 1, minus_zero, 0);
+ TEST_ff_i (isunordered, (FLOAT) 1, plus_zero, 0);
+ TEST_ff_i (isunordered, (FLOAT) 1, (FLOAT) 1, 0);
+ TEST_ff_i (isunordered, (FLOAT) 1, nan_value, 1);
+ TEST_ff_i (isunordered, nan_value, minus_zero, 1);
+ TEST_ff_i (isunordered, nan_value, plus_zero, 1);
+ TEST_ff_i (isunordered, nan_value, (FLOAT) 1, 1);
+ TEST_ff_i (isunordered, nan_value, nan_value, 1);
+
+ END (isunordered);
+}
+
+static void
j0_test (void)
{
FLOAT s, c;
@@ -9153,6 +9688,12 @@ initialize (void)
LDBL_MAX, DBL_MAX, FLT_MAX);
min_value = CHOOSE (LDBL_MIN, DBL_MIN, FLT_MIN,
LDBL_MIN, DBL_MIN, FLT_MIN);
+ min_subnorm_value = CHOOSE (__LDBL_DENORM_MIN__,
+ __DBL_DENORM_MIN__,
+ __FLT_DENORM_MIN__,
+ __LDBL_DENORM_MIN__,
+ __DBL_DENORM_MIN__,
+ __FLT_DENORM_MIN__);
(void) &plus_zero;
(void) &nan_value;
@@ -9161,6 +9702,7 @@ initialize (void)
(void) &minus_infty;
(void) &max_value;
(void) &min_value;
+ (void) &min_subnorm_value;
/* Clear all exceptions. From now on we must not get random exceptions. */
feclearexcept (FE_ALL_EXCEPT);
@@ -9298,8 +9840,11 @@ main (int argc, char **argv)
/* Keep the tests a wee bit ordered (according to ISO C99). */
/* Classification macros: */
+ finite_test ();
fpclassify_test ();
isfinite_test ();
+ isinf_test ();
+ isnan_test ();
isnormal_test ();
signbit_test ();
@@ -9432,6 +9977,17 @@ main (int argc, char **argv)
/* Multiply and add: */
fma_test ();
+ fma_test_towardzero ();
+ fma_test_downward ();
+ fma_test_upward ();
+
+ /* Comparison macros: */
+ isgreater_test ();
+ isgreaterequal_test ();
+ isless_test ();
+ islessequal_test ();
+ islessgreater_test ();
+ isunordered_test ();
/* Complex functions: */
cabs_test ();
diff --git a/libc/math/s_ccosh.c b/libc/math/s_ccosh.c
index 44c994446..91477ee2d 100644
--- a/libc/math/s_ccosh.c
+++ b/libc/math/s_ccosh.c
@@ -39,7 +39,15 @@ __ccosh (__complex__ double x)
const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
double sinix, cosix;
- __sincos (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (fabs (__real__ x) > t)
{
@@ -92,7 +100,15 @@ __ccosh (__complex__ double x)
/* Imaginary part is finite. */
double sinix, cosix;
- __sincos (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysign (HUGE_VAL, cosix);
__imag__ retval = (__copysign (HUGE_VAL, sinix)
diff --git a/libc/math/s_ccoshf.c b/libc/math/s_ccoshf.c
index d6f811049..9ca57b25b 100644
--- a/libc/math/s_ccoshf.c
+++ b/libc/math/s_ccoshf.c
@@ -39,7 +39,15 @@ __ccoshf (__complex__ float x)
const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2);
float sinix, cosix;
- __sincosf (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0f;
+ }
if (fabsf (__real__ x) > t)
{
@@ -92,7 +100,15 @@ __ccoshf (__complex__ float x)
/* Imaginary part is finite. */
float sinix, cosix;
- __sincosf (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0f;
+ }
__real__ retval = __copysignf (HUGE_VALF, cosix);
__imag__ retval = (__copysignf (HUGE_VALF, sinix)
diff --git a/libc/math/s_ccoshl.c b/libc/math/s_ccoshl.c
index 77a9ae386..1d561b4e3 100644
--- a/libc/math/s_ccoshl.c
+++ b/libc/math/s_ccoshl.c
@@ -39,7 +39,15 @@ __ccoshl (__complex__ long double x)
const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
long double sinix, cosix;
- __sincosl (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (fabsl (__real__ x) > t)
{
@@ -92,7 +100,15 @@ __ccoshl (__complex__ long double x)
/* Imaginary part is finite. */
long double sinix, cosix;
- __sincosl (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysignl (HUGE_VALL, cosix);
__imag__ retval = (__copysignl (HUGE_VALL, sinix)
diff --git a/libc/math/s_cexp.c b/libc/math/s_cexp.c
index 1d7a5a2c4..d0a95ba79 100644
--- a/libc/math/s_cexp.c
+++ b/libc/math/s_cexp.c
@@ -39,7 +39,15 @@ __cexp (__complex__ double x)
const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
double sinix, cosix;
- __sincos (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (__real__ x > t)
{
@@ -95,7 +103,15 @@ __cexp (__complex__ double x)
{
double sinix, cosix;
- __sincos (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysign (value, cosix);
__imag__ retval = __copysign (value, sinix);
diff --git a/libc/math/s_cexpf.c b/libc/math/s_cexpf.c
index 4aa976581..41fcea51d 100644
--- a/libc/math/s_cexpf.c
+++ b/libc/math/s_cexpf.c
@@ -39,7 +39,15 @@ __cexpf (__complex__ float x)
const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2);
float sinix, cosix;
- __sincosf (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0f;
+ }
if (__real__ x > t)
{
@@ -95,7 +103,15 @@ __cexpf (__complex__ float x)
{
float sinix, cosix;
- __sincosf (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0f;
+ }
__real__ retval = __copysignf (value, cosix);
__imag__ retval = __copysignf (value, sinix);
diff --git a/libc/math/s_cexpl.c b/libc/math/s_cexpl.c
index 256824924..d67cc5e5e 100644
--- a/libc/math/s_cexpl.c
+++ b/libc/math/s_cexpl.c
@@ -39,7 +39,15 @@ __cexpl (__complex__ long double x)
const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
long double sinix, cosix;
- __sincosl (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (__real__ x > t)
{
@@ -95,7 +103,15 @@ __cexpl (__complex__ long double x)
{
long double sinix, cosix;
- __sincosl (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysignl (value, cosix);
__imag__ retval = __copysignl (value, sinix);
diff --git a/libc/math/s_clog.c b/libc/math/s_clog.c
index 259306600..79b1f375d 100644
--- a/libc/math/s_clog.c
+++ b/libc/math/s_clog.c
@@ -85,6 +85,19 @@ __clog (__complex__ double x)
d2m1 += absy * absy;
__real__ result = __log1p (d2m1) / 2.0;
}
+ else if (absx < 1.0
+ && absx >= 0.75
+ && absy < DBL_EPSILON / 2.0
+ && scale == 0)
+ {
+ double d2m1 = (absx - 1.0) * (absx + 1.0);
+ __real__ result = __log1p (d2m1) / 2.0;
+ }
+ else if (absx < 1.0 && (absx >= 0.75 || absy >= 0.5) && scale == 0)
+ {
+ double d2m1 = __x2y2m1 (absx, absy);
+ __real__ result = __log1p (d2m1) / 2.0;
+ }
else
{
double d = __ieee754_hypot (absx, absy);
diff --git a/libc/math/s_clog10.c b/libc/math/s_clog10.c
index ef997ee76..4ccb5bcaa 100644
--- a/libc/math/s_clog10.c
+++ b/libc/math/s_clog10.c
@@ -88,6 +88,19 @@ __clog10 (__complex__ double x)
d2m1 += absy * absy;
__real__ result = __log1p (d2m1) * (M_LOG10E / 2.0);
}
+ else if (absx < 1.0
+ && absx >= 0.75
+ && absy < DBL_EPSILON / 2.0
+ && scale == 0)
+ {
+ double d2m1 = (absx - 1.0) * (absx + 1.0);
+ __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0);
+ }
+ else if (absx < 1.0 && (absx >= 0.75 || absy >= 0.5) && scale == 0)
+ {
+ double d2m1 = __x2y2m1 (absx, absy);
+ __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0);
+ }
else
{
double d = __ieee754_hypot (absx, absy);
diff --git a/libc/math/s_clog10f.c b/libc/math/s_clog10f.c
index c61e8af8c..1789f1aed 100644
--- a/libc/math/s_clog10f.c
+++ b/libc/math/s_clog10f.c
@@ -90,6 +90,19 @@ __clog10f (__complex__ float x)
d2m1 += absy * absy;
__real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
}
+ else if (absx < 1.0f
+ && absx >= 0.75f
+ && absy < FLT_EPSILON / 2.0f
+ && scale == 0)
+ {
+ float d2m1 = (absx - 1.0f) * (absx + 1.0f);
+ __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
+ }
+ else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0)
+ {
+ float d2m1 = __x2y2m1f (absx, absy);
+ __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
+ }
else
{
float d = __ieee754_hypotf (absx, absy);
diff --git a/libc/math/s_clog10l.c b/libc/math/s_clog10l.c
index d50f61657..958f74abd 100644
--- a/libc/math/s_clog10l.c
+++ b/libc/math/s_clog10l.c
@@ -89,6 +89,19 @@ __clog10l (__complex__ long double x)
d2m1 += absy * absy;
__real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
}
+ else if (absx < 1.0L
+ && absx >= 0.75L
+ && absy < LDBL_EPSILON / 2.0L
+ && scale == 0)
+ {
+ long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
+ __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
+ }
+ else if (absx < 1.0L && (absx >= 0.75L || absy >= 0.5L) && scale == 0)
+ {
+ long double d2m1 = __x2y2m1l (absx, absy);
+ __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
+ }
else
{
long double d = __ieee754_hypotl (absx, absy);
diff --git a/libc/math/s_clogf.c b/libc/math/s_clogf.c
index 92f782c47..2b9038b41 100644
--- a/libc/math/s_clogf.c
+++ b/libc/math/s_clogf.c
@@ -85,6 +85,19 @@ __clogf (__complex__ float x)
d2m1 += absy * absy;
__real__ result = __log1pf (d2m1) / 2.0f;
}
+ else if (absx < 1.0f
+ && absx >= 0.75f
+ && absy < FLT_EPSILON / 2.0f
+ && scale == 0)
+ {
+ float d2m1 = (absx - 1.0f) * (absx + 1.0f);
+ __real__ result = __log1pf (d2m1) / 2.0f;
+ }
+ else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0)
+ {
+ float d2m1 = __x2y2m1f (absx, absy);
+ __real__ result = __log1pf (d2m1) / 2.0f;
+ }
else
{
float d = __ieee754_hypotf (absx, absy);
diff --git a/libc/math/s_clogl.c b/libc/math/s_clogl.c
index eaba572ce..af3ed9971 100644
--- a/libc/math/s_clogl.c
+++ b/libc/math/s_clogl.c
@@ -85,6 +85,19 @@ __clogl (__complex__ long double x)
d2m1 += absy * absy;
__real__ result = __log1pl (d2m1) / 2.0L;
}
+ else if (absx < 1.0L
+ && absx >= 0.75L
+ && absy < LDBL_EPSILON / 2.0L
+ && scale == 0)
+ {
+ long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
+ __real__ result = __log1pl (d2m1) / 2.0L;
+ }
+ else if (absx < 1.0L && (absx >= 0.75L || absy >= 0.5L) && scale == 0)
+ {
+ long double d2m1 = __x2y2m1l (absx, absy);
+ __real__ result = __log1pl (d2m1) / 2.0L;
+ }
else
{
long double d = __ieee754_hypotl (absx, absy);
diff --git a/libc/math/s_csin.c b/libc/math/s_csin.c
index 602c14e53..725989c9c 100644
--- a/libc/math/s_csin.c
+++ b/libc/math/s_csin.c
@@ -42,7 +42,15 @@ __csin (__complex__ double x)
const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
double sinix, cosix;
- __sincos (__real__ x, &sinix, &cosix);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__real__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __real__ x;
+ cosix = 1.0;
+ }
if (fabs (__imag__ x) > t)
{
@@ -115,7 +123,15 @@ __csin (__complex__ double x)
/* Real part is finite. */
double sinix, cosix;
- __sincos (__real__ x, &sinix, &cosix);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__real__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __real__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysign (HUGE_VAL, sinix);
__imag__ retval = __copysign (HUGE_VAL, cosix);
diff --git a/libc/math/s_csinf.c b/libc/math/s_csinf.c
index c1d6a4f28..d53f943fa 100644
--- a/libc/math/s_csinf.c
+++ b/libc/math/s_csinf.c
@@ -42,7 +42,15 @@ __csinf (__complex__ float x)
const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2);
float sinix, cosix;
- __sincosf (__real__ x, &sinix, &cosix);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__real__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __real__ x;
+ cosix = 1.0f;
+ }
if (fabsf (__imag__ x) > t)
{
@@ -115,7 +123,15 @@ __csinf (__complex__ float x)
/* Real part is finite. */
float sinix, cosix;
- __sincosf (__real__ x, &sinix, &cosix);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__real__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __real__ x;
+ cosix = 1.0f;
+ }
__real__ retval = __copysignf (HUGE_VALF, sinix);
__imag__ retval = __copysignf (HUGE_VALF, cosix);
diff --git a/libc/math/s_csinh.c b/libc/math/s_csinh.c
index 56bb25623..20edbd13f 100644
--- a/libc/math/s_csinh.c
+++ b/libc/math/s_csinh.c
@@ -42,7 +42,15 @@ __csinh (__complex__ double x)
const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
double sinix, cosix;
- __sincos (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (fabs (__real__ x) > t)
{
@@ -109,7 +117,15 @@ __csinh (__complex__ double x)
/* Imaginary part is finite. */
double sinix, cosix;
- __sincos (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysign (HUGE_VAL, cosix);
__imag__ retval = __copysign (HUGE_VAL, sinix);
diff --git a/libc/math/s_csinhf.c b/libc/math/s_csinhf.c
index ba85e79b8..4b019a0ed 100644
--- a/libc/math/s_csinhf.c
+++ b/libc/math/s_csinhf.c
@@ -42,7 +42,15 @@ __csinhf (__complex__ float x)
const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2);
float sinix, cosix;
- __sincosf (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0f;
+ }
if (fabsf (__real__ x) > t)
{
@@ -109,7 +117,15 @@ __csinhf (__complex__ float x)
/* Imaginary part is finite. */
float sinix, cosix;
- __sincosf (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0f;
+ }
__real__ retval = __copysignf (HUGE_VALF, cosix);
__imag__ retval = __copysignf (HUGE_VALF, sinix);
diff --git a/libc/math/s_csinhl.c b/libc/math/s_csinhl.c
index e482e3a62..d9a928a40 100644
--- a/libc/math/s_csinhl.c
+++ b/libc/math/s_csinhl.c
@@ -42,7 +42,15 @@ __csinhl (__complex__ long double x)
const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
long double sinix, cosix;
- __sincosl (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (fabsl (__real__ x) > t)
{
@@ -109,7 +117,15 @@ __csinhl (__complex__ long double x)
/* Imaginary part is finite. */
long double sinix, cosix;
- __sincosl (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysignl (HUGE_VALL, cosix);
__imag__ retval = __copysignl (HUGE_VALL, sinix);
diff --git a/libc/math/s_csinl.c b/libc/math/s_csinl.c
index ff43256e5..9812bddd5 100644
--- a/libc/math/s_csinl.c
+++ b/libc/math/s_csinl.c
@@ -42,7 +42,15 @@ __csinl (__complex__ long double x)
const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
long double sinix, cosix;
- __sincosl (__real__ x, &sinix, &cosix);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__real__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __real__ x;
+ cosix = 1.0;
+ }
if (fabsl (__imag__ x) > t)
{
@@ -115,7 +123,15 @@ __csinl (__complex__ long double x)
/* Real part is finite. */
long double sinix, cosix;
- __sincosl (__real__ x, &sinix, &cosix);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__real__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __real__ x;
+ cosix = 1.0;
+ }
__real__ retval = __copysignl (HUGE_VALL, sinix);
__imag__ retval = __copysignl (HUGE_VALL, cosix);
diff --git a/libc/math/s_ctan.c b/libc/math/s_ctan.c
index 89c0fef91..fdba84744 100644
--- a/libc/math/s_ctan.c
+++ b/libc/math/s_ctan.c
@@ -53,11 +53,20 @@ __ctan (__complex__ double x)
double sinrx, cosrx;
double den;
const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2 / 2);
+ int rcls = fpclassify (__real__ x);
/* tan(x+iy) = (sin(2x) + i*sinh(2y))/(cos(2x) + cosh(2y))
= (sin(x)*cos(x) + i*sinh(y)*cosh(y)/(cos(x)^2 + sinh(y)^2). */
- __sincos (__real__ x, &sinrx, &cosrx);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__real__ x, &sinrx, &cosrx);
+ }
+ else
+ {
+ sinrx = __real__ x;
+ cosrx = 1.0;
+ }
if (fabs (__imag__ x) > t)
{
diff --git a/libc/math/s_ctanf.c b/libc/math/s_ctanf.c
index 2559f83f8..fd2b79788 100644
--- a/libc/math/s_ctanf.c
+++ b/libc/math/s_ctanf.c
@@ -57,7 +57,15 @@ __ctanf (__complex__ float x)
/* tan(x+iy) = (sin(2x) + i*sinh(2y))/(cos(2x) + cosh(2y))
= (sin(x)*cos(x) + i*sinh(y)*cosh(y)/(cos(x)^2 + sinh(y)^2). */
- __sincosf (__real__ x, &sinrx, &cosrx);
+ if (__builtin_expect (fpclassify(__real__ x) != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__real__ x, &sinrx, &cosrx);
+ }
+ else
+ {
+ sinrx = __real__ x;
+ cosrx = 1.0f;
+ }
if (fabsf (__imag__ x) > t)
{
diff --git a/libc/math/s_ctanh.c b/libc/math/s_ctanh.c
index d288b7d16..fee191055 100644
--- a/libc/math/s_ctanh.c
+++ b/libc/math/s_ctanh.c
@@ -53,11 +53,20 @@ __ctanh (__complex__ double x)
double sinix, cosix;
double den;
const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2 / 2);
+ int icls = fpclassify (__imag__ x);
/* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y))
= (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2). */
- __sincos (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincos (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (fabs (__real__ x) > t)
{
diff --git a/libc/math/s_ctanhf.c b/libc/math/s_ctanhf.c
index ca36a83bf..862845f8c 100644
--- a/libc/math/s_ctanhf.c
+++ b/libc/math/s_ctanhf.c
@@ -57,7 +57,15 @@ __ctanhf (__complex__ float x)
/* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y))
= (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2). */
- __sincosf (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (fpclassify(__imag__ x) != FP_SUBNORMAL, 1))
+ {
+ __sincosf (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0f;
+ }
if (fabsf (__real__ x) > t)
{
diff --git a/libc/math/s_ctanhl.c b/libc/math/s_ctanhl.c
index dbf161270..c4fc1d3d0 100644
--- a/libc/math/s_ctanhl.c
+++ b/libc/math/s_ctanhl.c
@@ -53,11 +53,20 @@ __ctanhl (__complex__ long double x)
long double sinix, cosix;
long double den;
const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l / 2);
+ int icls = fpclassify (__imag__ x);
/* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y))
= (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2). */
- __sincosl (__imag__ x, &sinix, &cosix);
+ if (__builtin_expect (icls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__imag__ x, &sinix, &cosix);
+ }
+ else
+ {
+ sinix = __imag__ x;
+ cosix = 1.0;
+ }
if (fabsl (__real__ x) > t)
{
diff --git a/libc/math/s_ctanl.c b/libc/math/s_ctanl.c
index 4fe26119c..0affe9321 100644
--- a/libc/math/s_ctanl.c
+++ b/libc/math/s_ctanl.c
@@ -53,11 +53,20 @@ __ctanl (__complex__ long double x)
long double sinrx, cosrx;
long double den;
const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l / 2);
+ int rcls = fpclassify (__real__ x);
/* tan(x+iy) = (sin(2x) + i*sinh(2y))/(cos(2x) + cosh(2y))
= (sin(x)*cos(x) + i*sinh(y)*cosh(y)/(cos(x)^2 + sinh(y)^2). */
- __sincosl (__real__ x, &sinrx, &cosrx);
+ if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
+ {
+ __sincosl (__real__ x, &sinrx, &cosrx);
+ }
+ else
+ {
+ sinrx = __real__ x;
+ cosrx = 1.0;
+ }
if (fabsl (__imag__ x) > t)
{
diff --git a/libc/misc/Versions b/libc/misc/Versions
index 7f525eaf5..b2a91473d 100644
--- a/libc/misc/Versions
+++ b/libc/misc/Versions
@@ -149,4 +149,7 @@ libc {
GLIBC_2.16 {
__getauxval; getauxval;
}
+ GLIBC_PRIVATE {
+ __madvise;
+ }
}
diff --git a/libc/misc/madvise.c b/libc/misc/madvise.c
index 8f1c873c0..4e9681a52 100644
--- a/libc/misc/madvise.c
+++ b/libc/misc/madvise.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1994,1995,1996,1997,2000,2007 Free Software Foundation, Inc.
+/* Advise system about intentions for a memory region. Stub version.
+ Copyright (C) 1994-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -23,11 +24,13 @@
for the region starting at ADDR and extending LEN bytes. */
int
-madvise (__ptr_t addr, size_t len, int advice)
+__madvise (void *addr, size_t len, int advice)
{
__set_errno (ENOSYS);
return -1;
}
-libc_hidden_def (madvise)
+libc_hidden_def (__madvise)
+weak_alias (__madvise, madvise)
+
stub_warning (madvise)
#include <stub-tag.h>
diff --git a/libc/misc/sys/cdefs.h b/libc/misc/sys/cdefs.h
index b94147efe..fb6c959d9 100644
--- a/libc/misc/sys/cdefs.h
+++ b/libc/misc/sys/cdefs.h
@@ -320,7 +320,7 @@
/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
inline semantics, unless -fgnu89-inline is used. */
-#if !defined __cplusplus || __GNUC_PREREQ (4,3)
+#if (!defined __cplusplus || __GNUC_PREREQ (4,3)) && defined __GNUC__
# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
# define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
# define __extern_always_inline \
@@ -329,6 +329,13 @@
# define __extern_inline extern __inline
# define __extern_always_inline extern __always_inline
# endif
+#elif defined __GNUC__ /* C++ and GCC <4.3. */
+# define __extern_inline extern __inline
+# define __extern_always_inline \
+ extern __always_inline
+#else /* Not GCC. */
+# define __extern_inline /* Ignore */
+# define __extern_always_inline /* Ignore */
#endif
/* GCC 4.3 and above allow passing all anonymous arguments of an
diff --git a/libc/nis/yp_xdr.c b/libc/nis/yp_xdr.c
index 76e0f2f21..418850643 100644
--- a/libc/nis/yp_xdr.c
+++ b/libc/nis/yp_xdr.c
@@ -49,21 +49,21 @@ libnsl_hidden_def (xdr_ypxfrstat)
bool_t
xdr_domainname (XDR *xdrs, domainname *objp)
{
- return xdr_string (xdrs, objp, ~0);
+ return xdr_string (xdrs, objp, YPMAXDOMAIN);
}
libnsl_hidden_def (xdr_domainname)
bool_t
xdr_mapname (XDR *xdrs, mapname *objp)
{
- return xdr_string (xdrs, objp, ~0);
+ return xdr_string (xdrs, objp, YPMAXMAP);
}
libnsl_hidden_def (xdr_mapname)
bool_t
xdr_peername (XDR *xdrs, peername *objp)
{
- return xdr_string (xdrs, objp, ~0);
+ return xdr_string (xdrs, objp, YPMAXPEER);
}
libnsl_hidden_def (xdr_peername)
@@ -71,7 +71,7 @@ bool_t
xdr_keydat (XDR *xdrs, keydat *objp)
{
return xdr_bytes (xdrs, (char **) &objp->keydat_val,
- (u_int *) &objp->keydat_len, ~0);
+ (u_int *) &objp->keydat_len, YPMAXRECORD);
}
libnsl_hidden_def (xdr_keydat)
@@ -79,7 +79,7 @@ bool_t
xdr_valdat (XDR *xdrs, valdat *objp)
{
return xdr_bytes (xdrs, (char **) &objp->valdat_val,
- (u_int *) &objp->valdat_len, ~0);
+ (u_int *) &objp->valdat_len, YPMAXRECORD);
}
libnsl_hidden_def (xdr_valdat)
diff --git a/libc/nptl/ChangeLog b/libc/nptl/ChangeLog
index 217693250..9eeeeb1bd 100644
--- a/libc/nptl/ChangeLog
+++ b/libc/nptl/ChangeLog
@@ -1,3 +1,84 @@
+2012-10-09 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/pthread/configure: Regenerated.
+ * sysdeps/x86_64/configure: Regenerated.
+
+2012-10-05 David S. Miller <davem@davemloft.net>
+
+ [BZ #14568]
+ * sysdeps/sparc/tls.h (DB_THREAD_SELF_INCLUDE): Delete.
+ (DB_THREAD_SELF): Use constants for the register offsets. Correct
+ the case of a 64-bit debugger with a 32-bit inferior.
+
+2012-10-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #14557]
+ * Makefile (tests-static): Add tst-cancel24-static,
+ tst-cond8-static tst-mutex8-static, tst-mutexpi8-static,
+ tst-sem11-static and tst-sem12-static.
+ (tests): Likewise.
+ (LDLIBS-tst-cancel24-static): New macro.
+ * tst-cancel24-static.cc: New file.
+ * tst-cond8-static.c: Likewise.
+ * tst-mutex8-static.c: Likewise.
+ * tst-mutexpi8-static.c: Likewise.
+ * tst-sem11-static.c: Likewise.
+ * tst-sem12-static.c: Likewise.
+
+2012-10-05 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ [BZ #14417]
+ * Makefile (tests): New test case tst-cond24.
+ (LDFLAGS-tst-cond24): Link tst-cond24 against librt.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait): Unlock mutex before going back to
+ wait in PI case.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+ (__pthread_cond_wait): Likewise. Revert handling of EAGAIN
+ return from futex_wait.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait): Unlock mutex before going back to
+ wait in PI case. Set requeue_pi flag only if wait returned 0.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+ (__pthread_cond_wait): Likewise. Revert handling of EAGAIN
+ return from futex_wait.
+ * tst-cond24.c: New test case.
+
+2012-10-04 Roland McGrath <roland@hack.frob.com>
+
+ * pthread_create.c (start_thread): Use __madvise, not madvise.
+
+2012-10-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * sysdeps/i386/tls.h: Update copyright years.
+
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * pthread_create.c (start_thread): Fix clone flag name in
+ comment to CLONE_CHILD_CLEARTID.
+ * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+
+2012-10-01 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ [BZ #14477]
+ * Makefile (tests): Add tst-cond-except.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait): Mark instructions where %ebx is
+ incremented in PI case.
+ (.gcc_except_table): Add entry to jump to __condvar_tw_cleanup2
+ for the marked PI case instructions.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+ (__pthread_cond_wait): Mark instructions where %ebx is
+ incremented in PI case.
+ (.gcc_except_table): Add entry to jump to __condvar_w_cleanup2
+ for the marked PI case instructions.
+ * tst-cond-except.c: New test case.
+
2012-09-24 Dmitry V. Levin <ldv@altlinux.org>
* tst-tls6.sh: Add "set -e".
diff --git a/libc/nptl/Makefile b/libc/nptl/Makefile
index 5d781e206..47752f090 100644
--- a/libc/nptl/Makefile
+++ b/libc/nptl/Makefile
@@ -210,7 +210,8 @@ tests = tst-typesizes \
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
- tst-cond20 tst-cond21 tst-cond22 tst-cond23 \
+ tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 \
+ tst-cond-except \
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
@@ -288,6 +289,7 @@ gen-as-const-headers = pthread-errnos.sym
LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
+LDFLAGS-tst-cond24 = -lrt
include ../Makeconfig
@@ -368,8 +370,12 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
$(common-objpfx)libc.a
tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \
- tst-cancel21-static
-tests += tst-stackguard1-static tst-cancel21-static
+ tst-cancel21-static tst-cancel24-static tst-cond8-static \
+ tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
+ tst-sem12-static
+tests += tst-stackguard1-static tst-cancel21-static tst-cancel24-static \
+ tst-cond8-static tst-mutex8-static tst-mutexpi8-static \
+ tst-sem11-static tst-sem12-static
xtests-static += tst-setuid1-static
# These tests are linked with libc before libpthread
@@ -528,6 +534,7 @@ $(objpfx)tst-rwlock14: $(common-objpfx)rt/librt.a
endif
LDLIBS-tst-cancel24 = $(no-as-needed) -lstdc++
+LDLIBS-tst-cancel24-static = $(LDLIBS-tst-cancel24)
extra-B-pthread.so = -B$(common-objpfx)nptl/
$(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs))
diff --git a/libc/nptl/pthread_create.c b/libc/nptl/pthread_create.c
index 96ca51f4e..44181ea39 100644
--- a/libc/nptl/pthread_create.c
+++ b/libc/nptl/pthread_create.c
@@ -404,7 +404,7 @@ start_thread (void *arg)
#endif
assert (freesize < pd->stackblock_size);
if (freesize > PTHREAD_STACK_MIN)
- madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
+ __madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
/* If the thread is detached free the TCB. */
if (IS_DETACHED (pd))
@@ -425,7 +425,7 @@ start_thread (void *arg)
/* We cannot call '_exit' here. '_exit' will terminate the process.
The 'exit' implementation in the kernel will signal when the
- process is really dead since 'clone' got passed the CLONE_CLEARTID
+ process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID
flag. The 'tid' field in the TCB will be set to zero.
The exit code is zero since in case all threads exit by calling
diff --git a/libc/nptl/sysdeps/i386/tls.h b/libc/nptl/sysdeps/i386/tls.h
index 65497cf92..eb1ca312f 100644
--- a/libc/nptl/sysdeps/i386/tls.h
+++ b/libc/nptl/sysdeps/i386/tls.h
@@ -1,5 +1,5 @@
/* Definition for thread-local data handling. nptl/i386 version.
- Copyright (C) 2002-2007, 2009, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2002-2012 Free Software 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/libc/nptl/sysdeps/pthread/configure b/libc/nptl/sysdeps/pthread/configure
index 221ce9bbb..7962ed6fc 100755
--- a/libc/nptl/sysdeps/pthread/configure
+++ b/libc/nptl/sysdeps/pthread/configure
@@ -1,123 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
if test "x$libc_cv_gcc___thread" != xyes; then
diff --git a/libc/nptl/sysdeps/sparc/tls.h b/libc/nptl/sysdeps/sparc/tls.h
index 61cb09f29..cfc9d96c6 100644
--- a/libc/nptl/sysdeps/sparc/tls.h
+++ b/libc/nptl/sysdeps/sparc/tls.h
@@ -117,9 +117,9 @@ register struct pthread *__thread_self __asm__("%g7");
#define THREAD_SELF __thread_self
/* Magic for libthread_db to know how to do THREAD_SELF. */
-# define DB_THREAD_SELF_INCLUDE <sys/ucontext.h>
# define DB_THREAD_SELF \
- REGISTER (32, 32, REG_G7 * 4, 0) REGISTER (64, 64, REG_G7 * 8, 0)
+ REGISTER (32, 32, 10 * 4, 0) \
+ REGISTER (64, __WORDSIZE, (6 * 8) + (__WORDSIZE==64?0:4), 0)
/* Access to data in the thread descriptor is easy. */
#define THREAD_GETMEM(descr, member) \
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index 5f1fd5ddc..6761c136e 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -200,9 +200,11 @@ __pthread_cond_timedwait:
42: leal (%ebp), %esi
movl 28(%esp), %edx
addl $cond_futex, %ebx
+.Ladd_cond_futex_pi:
movl $SYS_futex, %eax
ENTER_KERNEL
subl $cond_futex, %ebx
+.Lsub_cond_futex_pi:
movl %eax, %esi
/* Set the pi-requeued flag only if the kernel has returned 0. The
kernel does not hold the mutex on ETIMEDOUT or any other error. */
@@ -210,8 +212,23 @@ __pthread_cond_timedwait:
sete 24(%esp)
je 41f
- /* Normal and PI futexes dont mix. Use normal futex functions only
- if the kernel does not support the PI futex functions. */
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (24(%esp)) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN (barring
+ the ETIMEOUT of course, for the timeout case in futex) since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
cmpl $-ENOSYS, %eax
jne 41f
xorl %ecx, %ecx
@@ -271,9 +288,24 @@ __pthread_cond_timedwait:
jne 9f
15: cmpl $-ETIMEDOUT, %esi
- jne 8b
+ je 28f
+
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+ movl 24(%esp), %edx
+ test %edx, %edx
+ jz 8b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the mutex
+ correctly. */
+ movl dep_mutex(%ebx), %eax
+ call __pthread_mutex_cond_lock_adjust
+ xorl %edx, %edx
+ call __pthread_mutex_unlock_usercnt
+ jmp 8b
- addl $1, wakeup_seq(%ebx)
+28: addl $1, wakeup_seq(%ebx)
adcl $0, wakeup_seq+4(%ebx)
addl $1, cond_futex(%ebx)
movl $ETIMEDOUT, %esi
@@ -638,7 +670,15 @@ __condvar_tw_cleanup:
.uleb128 .Lcstend-.Lcstbegin
.Lcstbegin:
.long .LcleanupSTART-.LSTARTCODE
- .long .Ladd_cond_futex-.LcleanupSTART
+ .long .Ladd_cond_futex_pi-.LcleanupSTART
+ .long __condvar_tw_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .Ladd_cond_futex_pi-.LSTARTCODE
+ .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
+ .long __condvar_tw_cleanup2-.LSTARTCODE
+ .uleb128 0
+ .long .Lsub_cond_futex_pi-.LSTARTCODE
+ .long .Ladd_cond_futex-.Lsub_cond_futex_pi
.long __condvar_tw_cleanup-.LSTARTCODE
.uleb128 0
.long .Ladd_cond_futex-.LSTARTCODE
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index 2ae7af261..0af06acad 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -136,25 +136,37 @@ __pthread_cond_wait:
cmpl $PI_BIT, %eax
jne 18f
-90:
movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
movl %ebp, %edx
xorl %esi, %esi
addl $cond_futex, %ebx
+.Ladd_cond_futex_pi:
movl $SYS_futex, %eax
ENTER_KERNEL
subl $cond_futex, %ebx
+.Lsub_cond_futex_pi:
/* Set the pi-requeued flag only if the kernel has returned 0. The
kernel does not hold the mutex on error. */
cmpl $0, %eax
sete 16(%esp)
je 19f
- cmpl $-EAGAIN, %eax
- je 91f
-
- /* Normal and PI futexes dont mix. Use normal futex functions only
- if the kernel does not support the PI futex functions. */
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (16(%esp)) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
cmpl $-ENOSYS, %eax
jne 19f
xorl %ecx, %ecx
@@ -204,12 +216,12 @@ __pthread_cond_wait:
cmpl 8(%esp), %edx
jne 7f
cmpl 4(%esp), %edi
- je 8b
+ je 22f
7: cmpl %ecx, %edx
jne 9f
cmp %eax, %edi
- je 8b
+ je 22f
9: addl $1, woken_seq(%ebx)
adcl $0, woken_seq+4(%ebx)
@@ -285,6 +297,22 @@ __pthread_cond_wait:
jmp 20b
cfi_adjust_cfa_offset(-FRAME_SIZE);
+
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+22: movl 16(%esp), %edx
+ test %edx, %edx
+ jz 8b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the mutex
+ correctly. */
+ movl dep_mutex(%ebx), %eax
+ call __pthread_mutex_cond_lock_adjust
+ xorl %edx, %edx
+ call __pthread_mutex_unlock_usercnt
+ jmp 8b
+
/* Initial locking failed. */
1:
#if cond_lock == 0
@@ -398,77 +426,6 @@ __pthread_cond_wait:
call __lll_unlock_wake
jmp 11b
-91:
-.LcleanupSTART2:
- /* FUTEX_WAIT_REQUEUE_PI returned EAGAIN. We need to
- call it again. */
-
- /* Get internal lock. */
- movl $1, %edx
- xorl %eax, %eax
- LOCK
-#if cond_lock == 0
- cmpxchgl %edx, (%ebx)
-#else
- cmpxchgl %edx, cond_lock(%ebx)
-#endif
- jz 92f
-
-#if cond_lock == 0
- movl %ebx, %edx
-#else
- leal cond_lock(%ebx), %edx
-#endif
-#if (LLL_SHARED-LLL_PRIVATE) > 255
- xorl %ecx, %ecx
-#endif
- cmpl $-1, dep_mutex(%ebx)
- setne %cl
- subl $1, %ecx
- andl $(LLL_SHARED-LLL_PRIVATE), %ecx
-#if LLL_PRIVATE != 0
- addl $LLL_PRIVATE, %ecx
-#endif
- call __lll_lock_wait
-
-92:
- /* Increment the cond_futex value again, so it can be used as a new
- expected value. */
- addl $1, cond_futex(%ebx)
- movl cond_futex(%ebx), %ebp
-
- /* Unlock. */
- LOCK
-#if cond_lock == 0
- subl $1, (%ebx)
-#else
- subl $1, cond_lock(%ebx)
-#endif
- je 93f
-#if cond_lock == 0
- movl %ebx, %eax
-#else
- leal cond_lock(%ebx), %eax
-#endif
-#if (LLL_SHARED-LLL_PRIVATE) > 255
- xorl %ecx, %ecx
-#endif
- cmpl $-1, dep_mutex(%ebx)
- setne %cl
- subl $1, %ecx
- andl $(LLL_SHARED-LLL_PRIVATE), %ecx
-#if LLL_PRIVATE != 0
- addl $LLL_PRIVATE, %ecx
-#endif
- call __lll_unlock_wake
-
-93:
- /* Set the rest of SYS_futex args for FUTEX_WAIT_REQUEUE_PI. */
- xorl %ecx, %ecx
- movl dep_mutex(%ebx), %edi
- jmp 90b
-.LcleanupEND2:
-
.size __pthread_cond_wait, .-__pthread_cond_wait
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
GLIBC_2_3_2)
@@ -630,7 +587,15 @@ __condvar_w_cleanup:
.uleb128 .Lcstend-.Lcstbegin
.Lcstbegin:
.long .LcleanupSTART-.LSTARTCODE
- .long .Ladd_cond_futex-.LcleanupSTART
+ .long .Ladd_cond_futex_pi-.LcleanupSTART
+ .long __condvar_w_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .Ladd_cond_futex_pi-.LSTARTCODE
+ .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
+ .long __condvar_w_cleanup2-.LSTARTCODE
+ .uleb128 0
+ .long .Lsub_cond_futex_pi-.LSTARTCODE
+ .long .Ladd_cond_futex-.Lsub_cond_futex_pi
.long __condvar_w_cleanup-.LSTARTCODE
.uleb128 0
.long .Ladd_cond_futex-.LSTARTCODE
@@ -641,10 +606,6 @@ __condvar_w_cleanup:
.long .LcleanupEND-.Lsub_cond_futex
.long __condvar_w_cleanup-.LSTARTCODE
.uleb128 0
- .long .LcleanupSTART2-.LSTARTCODE
- .long .LcleanupEND2-.LcleanupSTART2
- .long __condvar_w_cleanup-.LSTARTCODE
- .uleb128 0
.long .LcallUR-.LSTARTCODE
.long .LENDCODE-.LcallUR
.long 0
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
index 3d805ff43..7b576ca00 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
@@ -544,7 +544,7 @@ LLL_STUB_UNWIND_INFO_END
#define lll_islocked(futex) \
(futex != LLL_LOCK_INITIALIZER)
-/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards.
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
index 234e04234..406c290d7 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+++ b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
@@ -288,7 +288,7 @@ extern int __lll_robust_timedlock_wait
1 - taken by one user
>1 - taken by more users */
-/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
index 4e3d7bd49..52ab53f0a 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
+++ b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
@@ -28,6 +28,7 @@ clear_once_control (void *arg)
{
pthread_once_t *once_control = (pthread_once_t *) arg;
+ __asm __volatile (__lll_rel_instr);
*once_control = 0;
lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
}
@@ -47,15 +48,15 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
oldval = *once_control;
if ((oldval & 2) == 0)
*once_control = newval;
- Do this atomically.
+ Do this atomically with an acquire barrier.
*/
newval = __fork_generation | 1;
- __asm __volatile ("1: lwarx %0,0,%3\n"
+ __asm __volatile ("1: lwarx %0,0,%3" MUTEX_HINT_ACQ "\n"
" andi. %1,%0,2\n"
" bne 2f\n"
" stwcx. %4,0,%3\n"
" bne 1b\n"
- "2: isync"
+ "2: " __lll_acq_instr
: "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
: "r" (once_control), "r" (newval), "m" (*once_control)
: "cr0");
@@ -87,8 +88,18 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
pthread_cleanup_pop (0);
- /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */
- atomic_increment (once_control);
+ /* Add one to *once_control to take the bottom 2 bits from 01 to 10.
+ A release barrier is needed to ensure memory written by init_routine
+ is seen in other threads before *once_control changes. */
+ int tmp;
+ __asm __volatile (__lll_rel_instr "\n"
+ "1: lwarx %0,0,%2" MUTEX_HINT_REL "\n"
+ " addi %0,%0,1\n"
+ " stwcx. %0,0,%2\n"
+ " bne- 1b"
+ : "=&b" (tmp), "=m" (*once_control)
+ : "r" (once_control), "m" (*once_control)
+ : "cr0");
/* Wake up all other threads. */
lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index eeb7a72e2..97092823d 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+++ b/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
@@ -329,7 +329,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime,
#define LLL_LOCK_INITIALIZER (0)
#define LLL_LOCK_INITIALIZER_LOCKED (1)
-/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index f3ef3883a..cfd8d0cec 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -389,7 +389,7 @@ extern int __lll_unlock_wake (int *__futex, int private) attribute_hidden;
#define lll_islocked(futex) \
(futex != LLL_LOCK_INITIALIZER)
-/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 73c3327c0..fafb0873f 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -268,7 +268,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime,
#define LLL_LOCK_INITIALIZER (0)
#define LLL_LOCK_INITIALIZER_LOCKED (1)
-/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 3686970f0..5a80ddd8e 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -560,7 +560,7 @@ LLL_STUB_UNWIND_INFO_END
(futex != LLL_LOCK_INITIALIZER)
-/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards.
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index a1c8ca87b..b669abb57 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -103,7 +103,7 @@ __pthread_cond_timedwait:
mov %RSI_LP, dep_mutex(%rdi)
22:
- xorl %r15d, %r15d
+ xorb %r15b, %r15b
#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
# ifdef PIC
@@ -190,18 +190,39 @@ __pthread_cond_timedwait:
movl $SYS_futex, %eax
syscall
- movl $1, %r15d
+ cmpl $0, %eax
+ sete %r15b
+
#ifdef __ASSUME_REQUEUE_PI
jmp 62f
#else
- cmpq $-4095, %rax
- jnae 62f
+ je 62f
+
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (%r15b) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN (barring
+ the ETIMEOUT of course, for the timeout case in futex) since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
+ cmpl $-ENOSYS, %eax
+ jne 62f
subq $cond_futex, %rdi
#endif
61: movl $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi
-60: xorl %r15d, %r15d
+60: xorb %r15b, %r15b
xorl %eax, %eax
/* The following only works like this because we only support
two clocks, represented using a single bit. */
@@ -248,7 +269,23 @@ __pthread_cond_timedwait:
ja 39f
45: cmpq $-ETIMEDOUT, %r14
- jne 38b
+ je 99f
+
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+ test %r15b, %r15b
+ jz 38b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the
+ mutex correctly. */
+ movq %r8, %rdi
+ callq __pthread_mutex_cond_lock_adjust
+ xorl %esi, %esi
+ callq __pthread_mutex_unlock_usercnt
+ /* Reload cond_var. */
+ movq 8(%rsp), %rdi
+ jmp 38b
99: incq wakeup_seq(%rdi)
incl cond_futex(%rdi)
@@ -298,7 +335,7 @@ __pthread_cond_timedwait:
/* If requeue_pi is used the kernel performs the locking of the
mutex. */
41: movq 16(%rsp), %rdi
- testl %r15d, %r15d
+ testb %r15b, %r15b
jnz 64f
callq __pthread_mutex_cond_lock
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index 61948523a..ec403cd9b 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -136,19 +136,36 @@ __pthread_cond_wait:
cmpl $PI_BIT, %eax
jne 61f
-90:
movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
movl $SYS_futex, %eax
syscall
- movl $1, %r8d
- cmpq $-EAGAIN, %rax
- je 91f
+ cmpl $0, %eax
+ sete %r8b
+
#ifdef __ASSUME_REQUEUE_PI
jmp 62f
#else
- cmpq $-4095, %rax
- jnae 62f
+ je 62f
+
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (%r8b) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
+ cmpl $-ENOSYS, %eax
+ jne 62f
# ifndef __ASSUME_PRIVATE_FUTEX
movl $FUTEX_WAIT, %esi
@@ -161,7 +178,7 @@ __pthread_cond_wait:
#else
orl %fs:PRIVATE_FUTEX, %esi
#endif
-60: xorl %r8d, %r8d
+60: xorb %r8b, %r8b
movl $SYS_futex, %eax
syscall
@@ -191,10 +208,10 @@ __pthread_cond_wait:
jne 16f
cmpq 24(%rsp), %r9
- jbe 8b
+ jbe 19f
cmpq %rax, %r9
- jna 8b
+ jna 19f
incq woken_seq(%rdi)
@@ -236,7 +253,7 @@ __pthread_cond_wait:
/* If requeue_pi is used the kernel performs the locking of the
mutex. */
11: movq 16(%rsp), %rdi
- testl %r8d, %r8d
+ testb %r8b, %r8b
jnz 18f
callq __pthread_mutex_cond_lock
@@ -253,6 +270,23 @@ __pthread_cond_wait:
xorl %eax, %eax
jmp 14b
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+19: testb %r8b, %r8b
+ jz 8b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the mutex
+ correctly. */
+ movq 16(%rsp), %rdi
+ callq __pthread_mutex_cond_lock_adjust
+ movq %rdi, %r8
+ xorl %esi, %esi
+ callq __pthread_mutex_unlock_usercnt
+ /* Reload cond_var. */
+ movq 8(%rsp), %rdi
+ jmp 8b
+
/* Initial locking failed. */
1:
#if cond_lock != 0
@@ -331,69 +365,6 @@ __pthread_cond_wait:
13: movq %r10, %rax
jmp 14b
-91:
-.LcleanupSTART2:
- /* FUTEX_WAIT_REQUEUE_PI returned EAGAIN. We need to
- call it again. */
- movq 8(%rsp), %rdi
-
- /* Get internal lock. */
- movl $1, %esi
- xorl %eax, %eax
- LOCK
-#if cond_lock == 0
- cmpxchgl %esi, (%rdi)
-#else
- cmpxchgl %esi, cond_lock(%rdi)
-#endif
- jz 92f
-
-#if cond_lock != 0
- addq $cond_lock, %rdi
-#endif
- LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
- movl $LLL_PRIVATE, %eax
- movl $LLL_SHARED, %esi
- cmovne %eax, %esi
- callq __lll_lock_wait
-#if cond_lock != 0
- subq $cond_lock, %rdi
-#endif
-92:
- /* Increment the cond_futex value again, so it can be used as a new
- expected value. */
- incl cond_futex(%rdi)
- movl cond_futex(%rdi), %edx
-
- /* Release internal lock. */
- LOCK
-#if cond_lock == 0
- decl (%rdi)
-#else
- decl cond_lock(%rdi)
-#endif
- jz 93f
-
-#if cond_lock != 0
- addq $cond_lock, %rdi
-#endif
- LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
- movl $LLL_PRIVATE, %eax
- movl $LLL_SHARED, %esi
- cmovne %eax, %esi
- /* The call preserves %rdx. */
- callq __lll_unlock_wake
-#if cond_lock != 0
- subq $cond_lock, %rdi
-#endif
-93:
- /* Set the rest of SYS_futex args for FUTEX_WAIT_REQUEUE_PI. */
- xorq %r10, %r10
- mov dep_mutex(%rdi), %R8_LP
- leaq cond_futex(%rdi), %rdi
- jmp 90b
-.LcleanupEND2:
-
.size __pthread_cond_wait, .-__pthread_cond_wait
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
GLIBC_2_3_2)
@@ -547,10 +518,6 @@ __condvar_cleanup1:
.uleb128 .LcleanupEND-.LcleanupSTART
.uleb128 __condvar_cleanup1-.LSTARTCODE
.uleb128 0
- .uleb128 .LcleanupSTART2-.LSTARTCODE
- .uleb128 .LcleanupEND2-.LcleanupSTART2
- .uleb128 __condvar_cleanup1-.LSTARTCODE
- .uleb128 0
.uleb128 .LcallUR-.LSTARTCODE
.uleb128 .LENDCODE-.LcallUR
.uleb128 0
diff --git a/libc/nptl/sysdeps/x86_64/configure b/libc/nptl/sysdeps/x86_64/configure
index ee047153c..8e5bcacaf 100644
--- a/libc/nptl/sysdeps/x86_64/configure
+++ b/libc/nptl/sysdeps/x86_64/configure
@@ -1,85 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/i386.
diff --git a/libc/nptl/tst-cancel24-static.cc b/libc/nptl/tst-cancel24-static.cc
new file mode 100644
index 000000000..3f97de5d5
--- /dev/null
+++ b/libc/nptl/tst-cancel24-static.cc
@@ -0,0 +1 @@
+#include "tst-cancel24.cc"
diff --git a/libc/nptl/tst-cond-except.c b/libc/nptl/tst-cond-except.c
new file mode 100644
index 000000000..b9871ba86
--- /dev/null
+++ b/libc/nptl/tst-cond-except.c
@@ -0,0 +1,108 @@
+/* Verify that exception table for pthread_cond_wait is correct.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+pthread_mutex_t mutex;
+pthread_cond_t cond;
+
+#define CHECK_RETURN_VAL_OR_FAIL(ret,str) \
+ ({ if ((ret) != 0) \
+ { \
+ printf ("%s failed: %s\n", (str), strerror (ret)); \
+ ret = 1; \
+ goto out; \
+ } \
+ })
+
+
+void
+clean (void *arg)
+{
+ puts ("clean: Unlocking mutex...");
+ pthread_mutex_unlock ((pthread_mutex_t *) arg);
+ puts ("clean: Mutex unlocked...");
+}
+
+void *
+thr (void *arg)
+{
+ int ret = 0;
+ pthread_mutexattr_t mutexAttr;
+ ret = pthread_mutexattr_init (&mutexAttr);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_init");
+
+ ret = pthread_mutexattr_setprotocol (&mutexAttr, PTHREAD_PRIO_INHERIT);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_setprotocol");
+
+ ret = pthread_mutex_init (&mutex, &mutexAttr);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_init");
+
+ ret = pthread_cond_init (&cond, 0);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_init");
+
+ puts ("th: Init done, entering wait...");
+
+ pthread_cleanup_push (clean, (void *) &mutex);
+ ret = pthread_mutex_lock (&mutex);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_lock");
+ while (1)
+ {
+ ret = pthread_cond_wait (&cond, &mutex);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_wait");
+ }
+ pthread_cleanup_pop (1);
+
+out:
+ return (void *)ret;
+}
+
+int
+do_test ()
+{
+ pthread_t thread;
+ int ret = 0;
+ void *thr_ret = 0;
+ ret = pthread_create (&thread, 0, thr, &thr_ret);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_create");
+
+ puts ("main: Thread created, waiting a bit...");
+ sleep (2);
+
+ puts ("main: Cancelling thread...");
+ ret = pthread_cancel (thread);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cancel");
+
+ puts ("main: Joining th...");
+ ret = pthread_join (thread, NULL);
+ CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_join");
+
+ if (thr_ret != NULL)
+ return 1;
+
+ puts ("main: Joined thread, done!");
+
+out:
+ return ret;
+}
+
+#define TIMEOUT 5
+#include "../test-skeleton.c"
diff --git a/libc/nptl/tst-cond24.c b/libc/nptl/tst-cond24.c
new file mode 100644
index 000000000..2eb2df1a3
--- /dev/null
+++ b/libc/nptl/tst-cond24.c
@@ -0,0 +1,249 @@
+/* Verify that condition variables synchronized by PI mutexes don't hang.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define THREADS_NUM 5
+#define MAXITER 50000
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mutex_attr;
+static pthread_cond_t cond;
+static pthread_t threads[THREADS_NUM];
+static int pending = 0;
+
+typedef void * (*threadfunc) (void *);
+
+void *
+thread_fun_timed (void *arg)
+{
+ int *ret = arg;
+ int rv, i;
+
+ printf ("Started thread_fun_timed[%d]\n", *ret);
+
+ for (i = 0; i < MAXITER / THREADS_NUM; i++)
+ {
+ rv = pthread_mutex_lock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+
+ while (!pending)
+ {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += 20;
+ rv = pthread_cond_timedwait (&cond, &mutex, &ts);
+
+ /* There should be no timeout either. */
+ if (rv)
+ {
+ printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ pending--;
+
+ rv = pthread_mutex_unlock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ *ret = 0;
+
+out:
+ return ret;
+}
+
+void *
+thread_fun (void *arg)
+{
+ int *ret = arg;
+ int rv, i;
+
+ printf ("Started thread_fun[%d]\n", *ret);
+
+ for (i = 0; i < MAXITER / THREADS_NUM; i++)
+ {
+ rv = pthread_mutex_lock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+
+ while (!pending)
+ {
+ rv = pthread_cond_wait (&cond, &mutex);
+
+ if (rv)
+ {
+ printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ pending--;
+
+ rv = pthread_mutex_unlock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ *ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+do_test_wait (threadfunc f)
+{
+ int i;
+ int rv;
+ int counter = 0;
+ int retval[THREADS_NUM];
+
+ puts ("Starting test");
+
+ rv = pthread_mutexattr_init (&mutex_attr);
+ if (rv)
+ {
+ printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT);
+ if (rv)
+ {
+ printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_mutex_init (&mutex, &mutex_attr);
+ if (rv)
+ {
+ printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_cond_init (&cond, NULL);
+ if (rv)
+ {
+ printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ for (i = 0; i < THREADS_NUM; i++)
+ {
+ retval[i] = i;
+ rv = pthread_create (&threads[i], NULL, f, &retval[i]);
+ if (rv)
+ {
+ printf ("pthread_create: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+ }
+
+ for (; counter < MAXITER; counter++)
+ {
+ rv = pthread_mutex_lock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ if (!(counter % 100))
+ printf ("counter: %d\n", counter);
+ pending += 1;
+
+ rv = pthread_cond_signal (&cond);
+ if (rv)
+ {
+ printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_mutex_unlock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+ }
+
+ for (i = 0; i < THREADS_NUM; i++)
+ {
+ void *ret;
+ rv = pthread_join (threads[i], &ret);
+ if (rv)
+ {
+ printf ("pthread_join: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+ if (ret && *(int *)ret)
+ {
+ printf ("Thread %d returned with an error\n", i);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ puts ("Testing pthread_cond_wait");
+ int ret = do_test_wait (thread_fun);
+ if (ret)
+ return ret;
+
+ puts ("Testing pthread_cond_timedwait");
+ return do_test_wait (thread_fun_timed);
+}
+
+#define TIMEOUT 10
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libc/nptl/tst-cond8-static.c b/libc/nptl/tst-cond8-static.c
new file mode 100644
index 000000000..fed35db60
--- /dev/null
+++ b/libc/nptl/tst-cond8-static.c
@@ -0,0 +1 @@
+#include "tst-cond8.c"
diff --git a/libc/nptl/tst-mutex8-static.c b/libc/nptl/tst-mutex8-static.c
new file mode 100644
index 000000000..d69ed49ad
--- /dev/null
+++ b/libc/nptl/tst-mutex8-static.c
@@ -0,0 +1 @@
+#include "tst-mutex8.c"
diff --git a/libc/nptl/tst-mutexpi8-static.c b/libc/nptl/tst-mutexpi8-static.c
new file mode 100644
index 000000000..869e6df95
--- /dev/null
+++ b/libc/nptl/tst-mutexpi8-static.c
@@ -0,0 +1 @@
+#include "tst-mutexpi8.c"
diff --git a/libc/nptl/tst-sem11-static.c b/libc/nptl/tst-sem11-static.c
new file mode 100644
index 000000000..09b769807
--- /dev/null
+++ b/libc/nptl/tst-sem11-static.c
@@ -0,0 +1 @@
+#include "tst-sem11.c"
diff --git a/libc/nptl/tst-sem12-static.c b/libc/nptl/tst-sem12-static.c
new file mode 100644
index 000000000..c06349f2b
--- /dev/null
+++ b/libc/nptl/tst-sem12-static.c
@@ -0,0 +1 @@
+#include "tst-sem12.c"
diff --git a/libc/nptl_db/ChangeLog b/libc/nptl_db/ChangeLog
index fe1778ee9..417514978 100644
--- a/libc/nptl_db/ChangeLog
+++ b/libc/nptl_db/ChangeLog
@@ -1,3 +1,9 @@
+2012-10-08 Jonathan Nieder <jrnieder@gmail.com>
+
+ [BZ #14661]
+ * Makefile ($(objpfx)db-symbols.out): Force C locale when running
+ readelf -s.
+
2012-03-07 Ulrich Drepper <drepper@gmail.com>
* Makefile (distribute): Remove variable.
diff --git a/libc/nptl_db/Makefile b/libc/nptl_db/Makefile
index d15fb9e81..6ccb3d0cc 100644
--- a/libc/nptl_db/Makefile
+++ b/libc/nptl_db/Makefile
@@ -60,6 +60,6 @@ $(objpfx)libthread_db.so: $(common-objpfx)libc.so \
tests: $(objpfx)db-symbols.out
$(objpfx)db-symbols.out: $(objpfx)db-symbols.v.i \
$(common-objpfx)nptl/libpthread.so
- readelf -W -s $(filter %.so,$^) | $(AWK) -f $< > $@
+ LC_ALL=C readelf -W -s $(filter %.so,$^) | $(AWK) -f $< > $@
$(objpfx)db-symbols.v.i: db-symbols.awk
diff --git a/libc/nscd/Makefile b/libc/nscd/Makefile
index bc2f94530..e4714ba6d 100644
--- a/libc/nscd/Makefile
+++ b/libc/nscd/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,2000,2002-2009,2011,2012 Free Software Foundation, Inc.
+# Copyright (C) 1998-2012 Free Software 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,49 +86,21 @@ CFLAGS-nscd_gethst_r.c = -fexceptions
CFLAGS-nscd_getai.c = -fexceptions
CFLAGS-nscd_initgroups.c = -fexceptions
-nscd-cflags = -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2
+CPPFLAGS-nonlib += -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2
+
ifeq (yesyes,$(have-fpie)$(build-shared))
-nscd-cflags += $(pie-ccflag)
+CFLAGS-nonlib += $(pie-ccflag)
endif
ifeq (yes,$(have-ssp))
-nscd-cflags += -fstack-protector
+CFLAGS-nonlib += -fstack-protector
endif
-CFLAGS-nscd.c += $(nscd-cflags)
-CFLAGS-connections.c += $(nscd-cflags)
-CFLAGS-pwdcache.c += $(nscd-cflags)
-CFLAGS-getpwnam_r.c += $(nscd-cflags)
-CFLAGS-getpwuid_r.c += $(nscd-cflags)
-CFLAGS-grpcache.c += $(nscd-cflags)
-CFLAGS-getgrnam_r.c += $(nscd-cflags)
-CFLAGS-getgrgid_r.c += $(nscd-cflags)
-CFLAGS-hstcache.c += $(nscd-cflags)
-CFLAGS-gethstbyad_r.c += $(nscd-cflags)
-CFLAGS-gethstbynm3_r.c += $(nscd-cflags)
-CFLAGS-dbg_log.c += $(nscd-cflags)
-CFLAGS-nscd_conf.c += $(nscd-cflags)
-CFLAGS-nscd_stat.c += $(nscd-cflags)
-CFLAGS-cache.c += $(nscd-cflags)
-CFLAGS-xmalloc.c += $(nscd-cflags)
-CFLAGS-xstrdup.c += $(nscd-cflags)
-CFLAGS-mem.c += $(nscd-cflags)
-CFLAGS-nscd_setup_thread.c += $(nscd-cflags)
-CFLAGS-aicache.c += $(nscd-cflags)
-CFLAGS-selinux.c += $(nscd-cflags)
-CFLAGS-initgrcache.c += $(nscd-cflags)
-CFLAGS-gai.c += $(nscd-cflags)
-CFLAGS-servicescache.c += $(nscd-cflags)
-CFLAGS-getsrvbynm_r.c += $(nscd-cflags)
-CFLAGS-getsrvbypt_r.c += $(nscd-cflags)
-CFLAGS-res_hconf.c += $(nscd-cflags)
-CFLAGS-nis_hash.c += $(nscd-cflags)
-CFLAGS-netgroupcache.c += $(nscd-cflags)
-
ifeq (yesyes,$(have-fpie)$(build-shared))
LDFLAGS-nscd = -Wl,-z,now
endif
-# This makes sure -DNOT_IN_libc is passed for all these modules.
+# This makes sure CPPFLAGS-nonlib and CFLAGS-nonlib are passed
+# for all these modules.
cpp-srcs-left := $(nscd-modules:=.c)
lib := nonlib
include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
diff --git a/libc/nss/Makefile b/libc/nss/Makefile
index dad1c9106..8fab79dd0 100644
--- a/libc/nss/Makefile
+++ b/libc/nss/Makefile
@@ -157,6 +157,8 @@ CFLAGS-nss_test1.c = -DNOT_IN_libc=1
$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(common-objpfx)libc.so \
$(common-objpfx)libc_nonshared.a
$(build-module)
+ifdef libnss_test1.so-version
$(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
$(make-link)
+endif
$(objpfx)tst-nss-test1.out: $(objpfx)/libnss_test1.so$(libnss_test1.so-version)
diff --git a/libc/nss/nsswitch.c b/libc/nss/nsswitch.c
index 929df5422..480110d5e 100644
--- a/libc/nss/nsswitch.c
+++ b/libc/nss/nsswitch.c
@@ -56,8 +56,10 @@ static name_database *nss_parse_file (const char *fname) internal_function;
static name_database_entry *nss_getline (char *line) internal_function;
static service_user *nss_parse_service_list (const char *line)
internal_function;
+#if !defined DO_STATIC_NSS || defined SHARED
static service_library *nss_new_service (name_database *database,
const char *name) internal_function;
+#endif
/* Declare external database variables. */
@@ -474,7 +476,9 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
known_function *known = malloc (sizeof *known);
if (! known)
{
+#if !defined DO_STATIC_NSS || defined SHARED
remove_from_tree:
+#endif
/* Oops. We can't instantiate this node properly.
Remove it from the tree. */
__tdelete (&fct_name, &ni->known.tree, &known_compare);
@@ -860,6 +864,7 @@ nss_getline (char *line)
}
+#if !defined DO_STATIC_NSS || defined SHARED
static service_library *
internal_function
nss_new_service (name_database *database, const char *name)
@@ -884,6 +889,7 @@ nss_new_service (name_database *database, const char *name)
return *currentp;
}
+#endif
#endif /* __OPTION_EGLIBC_NSSWITCH */
diff --git a/libc/ports/ChangeLog.alpha b/libc/ports/ChangeLog.alpha
index ab807f7d4..8cddb777e 100644
--- a/libc/ports/ChangeLog.alpha
+++ b/libc/ports/ChangeLog.alpha
@@ -1,4 +1,35 @@
-2012-12-13 Richard Henderson <rth@redhat.com>
+2012-10-09 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/alpha/configure: Regenerated.
+
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h: Fix clone
+ flag name in comment to CLONE_CHILD_CLEARTID.
+
+2012-10-01 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
+ (__SWBLK_T_TYPE): Macro removed.
+
+2012-09-28 Richard Henderson <rth@redhat.com>
+
+ * sysdeps/unix/alpha/sysdep.h (PSEUDO_END): Merge versions and
+ move $syscall_error label...
+ (SYSCALL_ERROR_HANDLER): ... here.
+ (SYSCALL_ERROR_FALLTHRU): New.
+ (PSEUDO_PROF): Split out of ...
+ (PSEUDO_PROLOGUE): ... here.
+ * sysdeps/unix/sysv/linux/alpha/syscall.S (__syscall): Use
+ SYSCALL_ERROR_LABEL and PSEUDO_END.
+ * sysdeps/unix/sysv/linux/alpha/clone.S (__clone): Likewise.
+ Use USEPV_PROF and cfi markup.
+ (thread_start): Use cfi markup and cfi_undefined on ra.
+ * sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
+ (PSEUDO_PROF): Remove.
+ (PSEUDO): Use SYSCALL_ERROR_FALLTHRU.
+
+2012-09-13 Richard Henderson <rth@redhat.com>
* sysdeps/unix/sysv/linux/alpha/setfpucw.c (__setfpucw): Rewrite
with the assumption of being used at program startup only.
diff --git a/libc/ports/ChangeLog.am33 b/libc/ports/ChangeLog.am33
index 7e644caae..e8243c532 100644
--- a/libc/ports/ChangeLog.am33
+++ b/libc/ports/ChangeLog.am33
@@ -1,3 +1,7 @@
+2012-10-09 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/unix/sysv/linux/am33/configure: Regenerated.
+
2012-08-07 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/am33/configure.in (arch_minimum_kernel):
diff --git a/libc/ports/ChangeLog.arm b/libc/ports/ChangeLog.arm
index b6c022516..a45063082 100644
--- a/libc/ports/ChangeLog.arm
+++ b/libc/ports/ChangeLog.arm
@@ -1,3 +1,22 @@
+2012-10-09 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/arm/configure: Regenerated.
+
+2012-10-05 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/arm/dl-machine.h (fix_bad_pc24): Rewritten, replaced with ...
+ (relocate_pc24): ... this new function.
+ (elf_machine_rel, elf_machine_rela): Update callers.
+
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h: Fix clone
+ flag name in comment to CLONE_CHILD_CLEARTID.
+
+2012-09-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * sysdeps/arm/dl-tlsdesc.h (ADDRIDX): Removed.
+
2012-09-21 Joseph Myers <joseph@codesourcery.com>
* sysdeps/arm/bits/atomic.h [!__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4]
diff --git a/libc/ports/ChangeLog.hppa b/libc/ports/ChangeLog.hppa
index d34d9c2d2..5b16146e4 100644
--- a/libc/ports/ChangeLog.hppa
+++ b/libc/ports/ChangeLog.hppa
@@ -1,3 +1,8 @@
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h: Fix clone
+ flag name in comment to CLONE_CHILD_CLEARTID.
+
2012-09-20 Carlos O'Donell <carlos@systemhalted.org>
* sysdeps/unix/sysv/linux/hppa/syscalls.list: Use __prlimit64 as
diff --git a/libc/ports/ChangeLog.ia64 b/libc/ports/ChangeLog.ia64
index 39ec5ffe7..641033b29 100644
--- a/libc/ports/ChangeLog.ia64
+++ b/libc/ports/ChangeLog.ia64
@@ -1,3 +1,12 @@
+2012-10-09 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/ia64/configure: Regenerated.
+
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h: Fix clone
+ flag name in comment to CLONE_CHILD_CLEARTID.
+
2012-09-24 Mike Frysinger <vapier@gentoo.org>
* ports/sysdeps/ia64/fpu/fegetround.c (fegetround): Move contents
diff --git a/libc/ports/ChangeLog.linux-generic b/libc/ports/ChangeLog.linux-generic
index b5774de5f..efbf3992a 100644
--- a/libc/ports/ChangeLog.linux-generic
+++ b/libc/ports/ChangeLog.linux-generic
@@ -1,3 +1,8 @@
+2012-10-01 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/unix/sysv/linux/generic/bits/typesizes.h
+ (__SWBLK_T_TYPE): Macro removed.
+
2012-08-02 Roland McGrath <roland@hack.frob.com>
* sysdeps/unix/sysv/linux/generic/bits/typesizes.h
diff --git a/libc/ports/ChangeLog.m68k b/libc/ports/ChangeLog.m68k
index 5163cf3f7..e9b4f3689 100644
--- a/libc/ports/ChangeLog.m68k
+++ b/libc/ports/ChangeLog.m68k
@@ -1,3 +1,13 @@
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h: Fix clone
+ flag name in comment to CLONE_CHILD_CLEARTID.
+
+2012-09-28 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/unix/sysv/linux/m68k/init-first.c: Include main file from
+ csu/ rather than sysdeps/unix/sysv/linux/.
+
2012-08-27 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/m68k/kernel-features.h
diff --git a/libc/ports/ChangeLog.mips b/libc/ports/ChangeLog.mips
index 8c41753e5..add9c2dd3 100644
--- a/libc/ports/ChangeLog.mips
+++ b/libc/ports/ChangeLog.mips
@@ -1,3 +1,25 @@
+2012-10-03 Steve Ellcey <sellcey@mips.com>
+
+ * sysdeps/mips/ieee754.h: Move to...
+ * sysdeps/mips/ieee754/ieee754.h: Here.
+ * sysdeps/mips/mips32/Implies: Add mips/ieee754.
+ * sysdeps/mips/mips64/Implies: Ditto.
+ * sysdeps/mips/mips64/n32/Implies: Ditto.
+ * sysdeps/mips/mips64/n64/Implies: Ditto.
+
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h: Fix clone
+ flag name in comment to CLONE_CHILD_CLEARTID.
+
+2012-09-28 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/mips/init-first.c: File removed.
+
+2012-09-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * sysdeps/mips/dl-trampoline.c (VERSYMIDX): Removed.
+
2012-08-27 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/mips/kernel-features.h
diff --git a/libc/ports/ChangeLog.powerpc b/libc/ports/ChangeLog.powerpc
index af98f828e..aa5595602 100644
--- a/libc/ports/ChangeLog.powerpc
+++ b/libc/ports/ChangeLog.powerpc
@@ -1,3 +1,8 @@
+2012-09-26 Joseph Myers <joseph@codesourcery.com>
+
+ * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist:
+ Add __ppc_get_timebase_freq.
+
2012-09-12 Joseph Myers <joseph@codesourcery.com>
* sysdeps/powerpc/nofpu/get-rounding-mode.h: New file.
diff --git a/libc/ports/ChangeLog.tile b/libc/ports/ChangeLog.tile
index e1d4c3c76..2d19358e7 100644
--- a/libc/ports/ChangeLog.tile
+++ b/libc/ports/ChangeLog.tile
@@ -1,3 +1,8 @@
+2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h: Fix clone
+ flag name in comment to CLONE_CHILD_CLEARTID.
+
2012-09-17 Chris Metcalf <cmetcalf@tilera.com>
* sysdeps/tile/libm-test-ulps: Account for new tests.
diff --git a/libc/ports/sysdeps/alpha/configure b/libc/ports/sysdeps/alpha/configure
index d906524bd..9c03229df 100644
--- a/libc/ports/sysdeps/alpha/configure
+++ b/libc/ports/sysdeps/alpha/configure
@@ -4,3 +4,4 @@
# With required gcc+binutils, we can always access static and hidden
# symbols in a position independent way.
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
diff --git a/libc/ports/sysdeps/arm/configure b/libc/ports/sysdeps/arm/configure
index 51fd72557..385f29590 100644
--- a/libc/ports/sysdeps/arm/configure
+++ b/libc/ports/sysdeps/arm/configure
@@ -1,102 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/arm.
diff --git a/libc/ports/sysdeps/arm/dl-machine.h b/libc/ports/sysdeps/arm/dl-machine.h
index 343a83e98..3b25e0f0f 100644
--- a/libc/ports/sysdeps/arm/dl-machine.h
+++ b/libc/ports/sysdeps/arm/dl-machine.h
@@ -302,36 +302,56 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
#define ARCH_LA_PLTEXIT arm_gnu_pltexit
#ifdef RESOLVE_MAP
-
-/* Deal with an out-of-range PC24 reloc. */
-auto Elf32_Addr
-fix_bad_pc24 (Elf32_Addr *const reloc_addr, Elf32_Addr value)
+/* Handle a PC24 reloc, including the out-of-range case. */
+auto void
+relocate_pc24 (struct link_map *map, Elf32_Addr value,
+ Elf32_Addr *const reloc_addr, Elf32_Sword addend)
{
- static void *fix_page;
- static unsigned int fix_offset;
- static size_t pagesize;
- Elf32_Word *fix_address;
+ Elf32_Addr new_value;
+
+ /* Set NEW_VALUE based on V, and return true iff it overflows 24 bits. */
+ inline bool set_new_value (Elf32_Addr v)
+ {
+ new_value = v + addend - (Elf32_Addr) reloc_addr;
+ Elf32_Addr topbits = new_value & 0xfe000000;
+ return topbits != 0xfe000000 && topbits != 0x00000000;
+ }
- if (! fix_page)
+ if (set_new_value (value))
{
- if (! pagesize)
- pagesize = getpagesize ();
- fix_page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (! fix_page)
- assert (! "could not map page for fixup");
- fix_offset = 0;
+ /* The PC-relative address doesn't fit in 24 bits! */
+
+ static void *fix_page;
+ static size_t fix_offset;
+ if (fix_page == NULL)
+ {
+ void *new_page = __mmap (NULL, GLRO(dl_pagesize),
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (new_page == MAP_FAILED)
+ _dl_signal_error (0, map->l_name, NULL,
+ "could not map page for fixup");
+ fix_page = new_page;
+ assert (fix_offset == 0);
+ }
+
+ Elf32_Word *fix_address = fix_page + fix_offset;
+ fix_address[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */
+ fix_address[1] = value;
+
+ fix_offset += sizeof fix_address[0] * 2;
+ if (fix_offset >= GLRO(dl_pagesize))
+ {
+ fix_page = NULL;
+ fix_offset = 0;
+ }
+
+ if (set_new_value ((Elf32_Addr) fix_address))
+ _dl_signal_error (0, map->l_name, NULL,
+ "R_ARM_PC24 relocation out of range");
}
- fix_address = (Elf32_Word *)(fix_page + fix_offset);
- fix_address[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */
- fix_address[1] = value;
-
- fix_offset += 8;
- if (fix_offset >= pagesize)
- fix_page = NULL;
-
- return (Elf32_Addr)fix_address;
+ *reloc_addr = (*reloc_addr & 0xff000000) | ((new_value >> 2) & 0x00ffffff);
}
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
@@ -473,30 +493,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
}
break;
case R_ARM_PC24:
- {
- Elf32_Sword addend;
- Elf32_Addr newvalue, topbits;
-
- addend = *reloc_addr & 0x00ffffff;
- if (addend & 0x00800000) addend |= 0xff000000;
-
- newvalue = value - (Elf32_Addr)reloc_addr + (addend << 2);
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- newvalue = fix_bad_pc24(reloc_addr, value)
- - (Elf32_Addr)reloc_addr + (addend << 2);
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- _dl_signal_error (0, map->l_name, NULL,
- "R_ARM_PC24 relocation out of range");
- }
- }
- newvalue >>= 2;
- value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
- *reloc_addr = value;
- }
+ relocate_pc24 (map, value, reloc_addr,
+ /* Sign-extend the 24-bit addend in the
+ instruction (which counts instructions), and
+ then shift it up two so as to count bytes. */
+ (((Elf32_Sword) *reloc_addr << 8) >> 8) << 2);
break;
#if !defined RTLD_BOOTSTRAP
case R_ARM_TLS_DTPMOD32:
@@ -589,26 +590,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
*reloc_addr = value + reloc->r_addend;
break;
case R_ARM_PC24:
- {
- Elf32_Addr newvalue, topbits;
-
- newvalue = value + reloc->r_addend - (Elf32_Addr)reloc_addr;
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- newvalue = fix_bad_pc24(reloc_addr, value)
- - (Elf32_Addr)reloc_addr + (reloc->r_addend << 2);
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- _dl_signal_error (0, map->l_name, NULL,
- "R_ARM_PC24 relocation out of range");
- }
- }
- newvalue >>= 2;
- value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
- *reloc_addr = value;
- }
+ relocate_pc24 (map, value, reloc_addr, reloc->r_addend);
break;
#if !defined RTLD_BOOTSTRAP
case R_ARM_TLS_DTPMOD32:
diff --git a/libc/ports/sysdeps/arm/dl-tlsdesc.h b/libc/ports/sysdeps/arm/dl-tlsdesc.h
index 2b1131c55..97951c0da 100644
--- a/libc/ports/sysdeps/arm/dl-tlsdesc.h
+++ b/libc/ports/sysdeps/arm/dl-tlsdesc.h
@@ -20,12 +20,6 @@
#ifndef _ARM_DL_TLSDESC_H
# define _ARM_DL_TLSDESC_H 1
-/* Use this to access DT_TLSDESC_PLT and DT_TLSDESC_GOT. */
-#ifndef ADDRIDX
-# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
-#endif
-
/* Type used to represent a TLS descriptor in the GOT. */
struct tlsdesc
{
diff --git a/libc/ports/sysdeps/hppa/configure b/libc/ports/sysdeps/hppa/configure
index c47fb6d0a..762b668f4 100644
--- a/libc/ports/sysdeps/hppa/configure
+++ b/libc/ports/sysdeps/hppa/configure
@@ -1,85 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler line separator" >&5
diff --git a/libc/ports/sysdeps/ia64/configure b/libc/ports/sysdeps/ia64/configure
index d73346006..e1fe62d8c 100644
--- a/libc/ports/sysdeps/ia64/configure
+++ b/libc/ports/sysdeps/ia64/configure
@@ -1,89 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
- # already done that, so ensure we don't try to do so again and fall
- # in an infinite loop. This has already happened in practice.
- _as_can_reexec=no; export _as_can_reexec
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/ia64.
diff --git a/libc/ports/sysdeps/mips/dl-trampoline.c b/libc/ports/sysdeps/mips/dl-trampoline.c
index 3454eb306..e4886cc9b 100644
--- a/libc/ports/sysdeps/mips/dl-trampoline.c
+++ b/libc/ports/sysdeps/mips/dl-trampoline.c
@@ -112,8 +112,6 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
generated by the gnu linker. */
int _dl_mips_gnu_objects = 1;
-#define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
-
/* This is called from assembly stubs below which the compiler can't see. */
static ElfW(Addr)
__dl_runtime_resolve (ElfW(Word), ElfW(Word), ElfW(Addr), ElfW(Addr))
diff --git a/libc/ports/sysdeps/mips/ieee754.h b/libc/ports/sysdeps/mips/ieee754/ieee754.h
index 87dbf658e..87dbf658e 100644
--- a/libc/ports/sysdeps/mips/ieee754.h
+++ b/libc/ports/sysdeps/mips/ieee754/ieee754.h
diff --git a/libc/ports/sysdeps/mips/init-first.c b/libc/ports/sysdeps/mips/init-first.c
deleted file mode 100644
index 6a5e7caf0..000000000
--- a/libc/ports/sysdeps/mips/init-first.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Initialization code run first thing by the ELF startup code. For mips/Unix.
- Copyright (C) 1996, 1997, 2010 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for 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 <unistd.h>
-
-extern void __libc_init (int, char **, char **);
-extern void __libc_global_ctors (void);
-
-
-static void
-init (int *data)
-{
- int argc = *data;
- char **argv = (void *) (data + 1);
- char **envp = &argv[argc + 1];
-
- __environ = envp;
- __libc_init (argc, argv, envp);
-}
-
-#ifdef SHARED
-/* This function is called to initialize the shared C library.
- It is called just before the user _start code from mips/elf/start.S,
- with the stack set up as that code gets it. */
-
-/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
- pointer in the dynamic section based solely on that. It is convention
- for this function to be in the `.init' section, but the symbol name is
- the only thing that really matters!! */
-/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/
-
-void
-_init (int argc, ...)
-{
- init (&argc);
-
-#ifndef NO_CTORS_DTORS_SECTIONS
- __libc_global_ctors ();
-#endif
-}
-#endif
-
-
-void
-__libc_init_first (int argc __attribute__ ((unused)), ...)
-{
-#ifndef SHARED
- init (&argc);
-#endif
-}
diff --git a/libc/ports/sysdeps/mips/mips32/Implies b/libc/ports/sysdeps/mips/mips32/Implies
index fab98d731..6473f2517 100644
--- a/libc/ports/sysdeps/mips/mips32/Implies
+++ b/libc/ports/sysdeps/mips/mips32/Implies
@@ -1,2 +1,3 @@
+mips/ieee754
mips
wordsize-32
diff --git a/libc/ports/sysdeps/mips/mips64/Implies b/libc/ports/sysdeps/mips/mips64/Implies
index 8c18cb303..826ff1541 100644
--- a/libc/ports/sysdeps/mips/mips64/Implies
+++ b/libc/ports/sysdeps/mips/mips64/Implies
@@ -1,3 +1,4 @@
# MIPS uses IEEE 754 floating point.
+mips/ieee754
ieee754/flt-32
ieee754/dbl-64
diff --git a/libc/ports/sysdeps/mips/mips64/n32/Implies b/libc/ports/sysdeps/mips/mips64/n32/Implies
index bed8f14c3..9ab2f3261 100644
--- a/libc/ports/sysdeps/mips/mips64/n32/Implies
+++ b/libc/ports/sysdeps/mips/mips64/n32/Implies
@@ -1,3 +1,4 @@
+mips/ieee754
ieee754/ldbl-128
mips/mips64/soft-fp
mips/mips64
diff --git a/libc/ports/sysdeps/mips/mips64/n64/Implies b/libc/ports/sysdeps/mips/mips64/n64/Implies
index 214b85c77..de23ed1c3 100644
--- a/libc/ports/sysdeps/mips/mips64/n64/Implies
+++ b/libc/ports/sysdeps/mips/mips64/n64/Implies
@@ -1,3 +1,4 @@
+mips/ieee754
ieee754/ldbl-128
mips/mips64/soft-fp
mips/mips64
diff --git a/libc/ports/sysdeps/unix/alpha/sysdep.h b/libc/ports/sysdeps/unix/alpha/sysdep.h
index 4ee0746ac..75c06c9cf 100644
--- a/libc/ports/sysdeps/unix/alpha/sysdep.h
+++ b/libc/ports/sysdeps/unix/alpha/sysdep.h
@@ -52,13 +52,20 @@
#define END(sym) .end sym
#ifdef PROF
+# define PSEUDO_PROF \
+ .set noat; \
+ lda AT, _mcount; \
+ jsr AT, (AT), _mcount; \
+ .set at
+#else
+# define PSEUDO_PROF
+#endif
+
+#ifdef PROF
# define PSEUDO_PROLOGUE \
.frame sp, 0, ra; \
ldgp gp,0(pv); \
- .set noat; \
- lda AT,_mcount; \
- jsr AT,(AT),_mcount; \
- .set at; \
+ PSEUDO_PROF; \
.prologue 1
#elif defined PIC
# define PSEUDO_PROLOGUE \
@@ -80,16 +87,21 @@
#if RTLD_PRIVATE_ERRNO
# define SYSCALL_ERROR_LABEL $syscall_error
# define SYSCALL_ERROR_HANDLER \
+$syscall_error: \
stl v0, rtld_errno(gp) !gprel; \
lda v0, -1; \
ret
+# define SYSCALL_ERROR_FALLTHRU
#elif defined(PIC)
-# define SYSCALL_ERROR_LABEL __syscall_error !samegp
+# define SYSCALL_ERROR_LABEL __syscall_error !samegp
# define SYSCALL_ERROR_HANDLER
+# define SYSCALL_ERROR_FALLTHRU br SYSCALL_ERROR_LABEL
#else
-# define SYSCALL_ERROR_LABEL $syscall_error
-# define SYSCALL_ERROR_HANDLER \
- jmp $31, __syscall_error
+# define SYSCALL_ERROR_LABEL $syscall_error
+# define SYSCALL_ERROR_HANDLER \
+$syscall_error: \
+ jmp $31, __syscall_error
+# define SYSCALL_ERROR_FALLTHRU
#endif /* RTLD_PRIVATE_ERRNO */
/* Overridden by specific syscalls. */
@@ -108,14 +120,9 @@ __LABEL(name) \
bne a3, SYSCALL_ERROR_LABEL
#undef PSEUDO_END
-#if defined(PIC) && !RTLD_PRIVATE_ERRNO
-# define PSEUDO_END(sym) END(sym)
-#else
-# define PSEUDO_END(sym) \
-$syscall_error: \
+#define PSEUDO_END(sym) \
SYSCALL_ERROR_HANDLER; \
END(sym)
-#endif
#define PSEUDO_NOERRNO(name, syscall_name, args) \
.globl name; \
diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
index 31258e420..5ab9ac43a 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
@@ -50,7 +50,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __S64_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE void *
diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S b/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S
index 1c6c8d6b7..b92b6c2e7 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S
@@ -35,89 +35,84 @@
we don't bother checking FLAGS. */
.text
-ENTRY(__clone)
+ .align 4
+ .globl __clone
+ .ent __clone
+ .usepv __clone, USEPV_PROF
+
+ cfi_startproc
+__clone:
#ifdef PROF
ldgp gp,0(pv)
- .set noat
lda AT, _mcount
jsr AT, (AT), _mcount
- .set at
- .prologue 1
-#else
- .prologue 0
#endif
/* Sanity check arguments. */
- ldiq v0,EINVAL
- beq a0,$error /* no NULL function pointers */
- beq a1,$error /* no NULL stack pointers */
+ ldiq v0, EINVAL
+ beq a0, SYSCALL_ERROR_LABEL /* no NULL function pointers */
+ beq a1, SYSCALL_ERROR_LABEL /* no NULL stack pointers */
/* Save the fn ptr and arg on the new stack. */
- subq a1,32,a1
- stq a0,0(a1)
- stq a3,8(a1)
+ subq a1, 32, a1
+ stq a0, 0(a1)
+ stq a3, 8(a1)
#ifdef RESET_PID
- stq a2,16(a1)
+ stq a2, 16(a1)
#endif
/* The syscall is of the form clone(flags, usp, ptid, ctid, tls).
Shift the flags, ptid, ctid, tls arguments into place; the
child_stack argument is already correct. */
- mov a2,a0
- mov a4,a2
- ldq a3,0(sp)
- mov a5,a4
+ mov a2, a0
+ mov a4, a2
+ ldq a3, 0(sp)
+ mov a5, a4
/* Do the system call. */
- ldiq v0,__NR_clone
+ ldiq v0, __NR_clone
call_pal PAL_callsys
- bne a3,$error
- beq v0,thread_start
+ bne a3, SYSCALL_ERROR_LABEL
+ beq v0, thread_start
/* Successful return from the parent. */
ret
- /* Something bad happened -- no child created. */
-$error:
-#ifndef PROF
- br gp,1f
-1: ldgp gp,0(gp)
-#endif
- SYSCALL_ERROR_HANDLER
-
- END(__clone)
+PSEUDO_END(__clone)
+ cfi_endproc
/* Load up the arguments to the function. Put this block of code in
its own function so that we can terminate the stack trace with our
debug info. */
.ent thread_start
+ cfi_startproc
thread_start:
- .frame fp,0,fp,0
mov 0, fp
- .prologue 0
+ cfi_def_cfa_register(fp)
+ cfi_undefined(ra)
#ifdef RESET_PID
/* Check and see if we need to reset the PID. */
- ldq t0,16(sp)
- lda t1,CLONE_THREAD
- and t0,t1,t2
- beq t2,2f
+ ldq t0, 16(sp)
+ lda t1, CLONE_THREAD
+ and t0, t1, t2
+ beq t2, 2f
1:
#endif
/* Load up the arguments. */
- ldq pv,0(sp)
- ldq a0,8(sp)
- addq sp,32,sp
+ ldq pv, 0(sp)
+ ldq a0, 8(sp)
+ addq sp, 32, sp
/* Call the user's function. */
- jsr ra,(pv)
- ldgp gp,0(ra)
+ jsr ra, (pv)
+ ldgp gp, 0(ra)
/* Call _exit rather than doing it inline for breakpoint purposes. */
- mov v0,a0
+ mov v0, a0
#ifdef PIC
bsr ra, HIDDEN_JUMPTARGET(_exit) !samegp
#else
@@ -142,7 +137,7 @@ thread_start:
stl v0, TID_OFFSET(s0)
br 1b
#endif
-
+ cfi_endproc
.end thread_start
weak_alias (__clone, clone)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h
index ac364dae1..0ef2e7fd3 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h
@@ -259,7 +259,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime,
#define LLL_LOCK_INITIALIZER_LOCKED (1)
-/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
index 04c7af472..e6795d98f 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
@@ -23,16 +23,6 @@
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
-# ifdef PROF
-# define PSEUDO_PROF \
- .set noat; \
- lda AT, _mcount; \
- jsr AT, (AT), _mcount; \
- .set at
-# else
-# define PSEUDO_PROF
-# endif
-
/* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
besides "ret". */
@@ -88,7 +78,7 @@ __LABEL($multi_error) \
addq sp, 64, sp; \
cfi_restore(ra); \
cfi_def_cfa_offset(0); \
-__LABEL($syscall_error) \
+ SYSCALL_ERROR_FALLTHRU; \
SYSCALL_ERROR_HANDLER; \
cfi_endproc; \
.previous
diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S b/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S
index 830b10acb..5cec3800e 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S
@@ -62,16 +62,9 @@ LEAF(__syscall, 0)
ldq a5,0(sp) /* arg6 -> a5 */
call_pal PAL_callsys /* Invoke system call */
- bne a3, $error
+ bne a3, SYSCALL_ERROR_LABEL
ret
-$error:
-#ifndef PROF
- br gp, 2f
-2: ldgp gp, 0(gp)
-#endif
- SYSCALL_ERROR_HANDLER
-
-END(__syscall)
+PSEUDO_END(__syscall)
weak_alias (__syscall, syscall)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
index b9fa69ce3..5811361e3 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
@@ -256,7 +256,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
1 - taken by one user
>1 - taken by more users */
-/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h b/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h
index d7d2a5c10..d5799d185 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h
@@ -52,7 +52,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE void *
diff --git a/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
index 6d4b13517..ad601c683 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
@@ -319,7 +319,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime,
extern int lll_unlock_wake_cb (lll_lock_t *__futex) attribute_hidden;
-/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h
index 24ed47e22..e36ff2653 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h
@@ -267,7 +267,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
#define LLL_LOCK_INITIALIZER (0)
#define LLL_LOCK_INITIALIZER_LOCKED (1)
-/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c b/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c
index ec311ec42..713ab86b1 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c
+++ b/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2010 Free Software Foundation, Inc.
+/* Initialization code run first thing by the ELF startup code. Linux/m68k.
+ Copyright (C) 2010-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
@@ -70,4 +71,4 @@ _libc_vdso_platform_setup (void)
#endif /* SHARED */
-#include <sysdeps/unix/sysv/linux/init-first.c>
+#include <csu/init-first.c>
diff --git a/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h
index fed152ae3..4dbed8d37 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h
@@ -254,7 +254,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
1 - taken by one user
>1 - taken by more users */
-/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h
index d368ae1b6..9c1701167 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h
@@ -268,7 +268,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime,
1 - taken by one user
>1 - taken by more users */
-/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist b/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
index 11ad6a525..481162e99 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
+++ b/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
@@ -1775,6 +1775,7 @@ GLIBC_2.16
GLIBC_2.17
GLIBC_2.17 A
secure_getenv F
+ __ppc_get_timebase_freq F
GLIBC_2.2
GLIBC_2.2 A
_IO_adjust_wcolumn F
diff --git a/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h
index 8690c7be4..0e0d48ed0 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h
@@ -255,7 +255,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime,
#define LLL_LOCK_INITIALIZER_LOCKED (1)
-/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
diff --git a/libc/posix/Makefile b/libc/posix/Makefile
index 89f86bacf..e88f0ce22 100644
--- a/libc/posix/Makefile
+++ b/libc/posix/Makefile
@@ -159,6 +159,7 @@ endif
# it will say by examining the system, and write the results in config-name.h.
uname.c: $(objpfx)config-name.h
$(objpfx)config-name.h: $(..)scripts/config-uname.sh $(common-objpfx)config.make
+ $(make-target-directory)
$< '$(config-os)' '$(config-release)' \
'$(config-machine)-$(config-vendor)' > $@.new
mv -f $@.new $@
diff --git a/libc/posix/gai.conf b/libc/posix/gai.conf
index 195287e1c..4616ed005 100644
--- a/libc/posix/gai.conf
+++ b/libc/posix/gai.conf
@@ -55,23 +55,11 @@
#
# scopev4 <mask> <value>
-# Add another rule to the RFC 3484 scope table for IPv4 addresses.
-# By default the scope IDs described in section 3.2 in RFC 3484 are
+# Add another rule to the RFC 6724 scope table for IPv4 addresses.
+# By default the scope IDs described in section 3.2 in RFC 6724 are
# used. Changing these defaults should hardly ever be necessary.
# The defaults are equivalent to:
#
#scopev4 ::ffff:169.254.0.0/112 2
#scopev4 ::ffff:127.0.0.0/104 2
-#scopev4 ::ffff:10.0.0.0/104 5
-#scopev4 ::ffff:172.16.0.0/108 5
-#scopev4 ::ffff:192.168.0.0/112 5
-#scopev4 ::ffff:0.0.0.0/96 14
-#
-# For sites which use site-local IPv4 addresses behind NAT there is
-# the problem that even if IPv4 addresses are preferred they do not
-# have the same scope and are therefore not sorted first. To change
-# this use only these rules:
-#
-#scopev4 ::ffff:169.254.0.0/112 2
-#scopev4 ::ffff:127.0.0.0/104 2
#scopev4 ::ffff:0.0.0.0/96 14
diff --git a/libc/posix/glob.c b/libc/posix/glob.c
index b90943543..b82ba77e1 100644
--- a/libc/posix/glob.c
+++ b/libc/posix/glob.c
@@ -220,7 +220,7 @@ static int collated_compare (const void *, const void *) __THROW;
static const char *
next_brace_sub (const char *cp, int flags)
{
- unsigned int depth = 0;
+ size_t depth = 0;
while (*cp != '\0')
if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
{
@@ -965,7 +965,7 @@ glob (pattern, flags, errfunc, pglob)
&& S_ISDIR (st.st_mode))
: (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode)))))
{
- int newcount = pglob->gl_pathc + pglob->gl_offs;
+ size_t newcount = pglob->gl_pathc + pglob->gl_offs;
char **new_gl_pathv;
if (newcount > UINTPTR_MAX - (1 + 1)
@@ -1064,7 +1064,7 @@ glob (pattern, flags, errfunc, pglob)
appending the results to PGLOB. */
for (i = 0; i < dirs.gl_pathc; ++i)
{
- int old_pathc;
+ size_t old_pathc;
#ifdef SHELL
{
@@ -1119,7 +1119,7 @@ glob (pattern, flags, errfunc, pglob)
/* No matches. */
if (flags & GLOB_NOCHECK)
{
- int newcount = pglob->gl_pathc + pglob->gl_offs;
+ size_t newcount = pglob->gl_pathc + pglob->gl_offs;
char **new_gl_pathv;
if (newcount > UINTPTR_MAX - 2
@@ -1163,7 +1163,7 @@ glob (pattern, flags, errfunc, pglob)
}
else
{
- int old_pathc = pglob->gl_pathc;
+ size_t old_pathc = pglob->gl_pathc;
int orig_flags = flags;
if (meta & 2)
diff --git a/libc/posix/tst-rfc3484.c b/libc/posix/tst-rfc3484.c
index 29e1461e1..db3ae1b7b 100644
--- a/libc/posix/tst-rfc3484.c
+++ b/libc/posix/tst-rfc3484.c
@@ -71,6 +71,9 @@ service_user *__nss_hosts_database attribute_hidden;
struct sockaddr_in addrs[] =
{
+ { .sin_family = AF_INET, .sin_addr = { h (0x0aa85f19) } },
+ { .sin_family = AF_INET, .sin_addr = { h (0xac105f19) } },
+ { .sin_family = AF_INET, .sin_addr = { h (0xc0000219) } },
{ .sin_family = AF_INET, .sin_addr = { h (0xc0a86d1d) } },
{ .sin_family = AF_INET, .sin_addr = { h (0xc0a85d03) } },
{ .sin_family = AF_INET, .sin_addr = { h (0xc0a82c3d) } },
@@ -86,7 +89,7 @@ static size_t order[naddrs];
static int expected[naddrs] =
{
- 6, 1, 0, 3, 2, 4, 5
+ 9, 4, 3, 6, 5, 7, 8, 2, 0, 1
};
diff --git a/libc/rt/tst-aio2.c b/libc/rt/tst-aio2.c
index 897d37d8b..01a94fe27 100644
--- a/libc/rt/tst-aio2.c
+++ b/libc/rt/tst-aio2.c
@@ -1,5 +1,5 @@
/* Test for notification mechanism in lio_listio.
- Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2000-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
+#include <pthread.h>
static pthread_barrier_t b;
diff --git a/libc/rt/tst-aio3.c b/libc/rt/tst-aio3.c
index 4d1fe8e97..133e386cd 100644
--- a/libc/rt/tst-aio3.c
+++ b/libc/rt/tst-aio3.c
@@ -1,5 +1,5 @@
/* Test for notification mechanism in lio_listio.
- Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2000-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
+#include <pthread.h>
static pthread_barrier_t b;
diff --git a/libc/scripts/check-local-headers.sh b/libc/scripts/check-local-headers.sh
index cacb842de..7fafcbf4d 100755
--- a/libc/scripts/check-local-headers.sh
+++ b/libc/scripts/check-local-headers.sh
@@ -31,7 +31,7 @@ exec ${AWK} -v includedir="$includedir" '
BEGIN {
status = 0
exclude = "^" includedir \
- "/(.*-.*-.*/|)(asm[-/]|linux/|selinux/|gd|nss3/|sys/capability\\.h|libaudit\\.h)"
+ "/(.*-.*-.*/|)(asm[-/]|linux/|selinux/|gd|nss3/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)"
}
/^[^ ]/ && $1 ~ /.*:/ { obj = $1 }
{
diff --git a/libc/scripts/config.guess b/libc/scripts/config.guess
index 49ba16f15..872b96a16 100755
--- a/libc/scripts/config.guess
+++ b/libc/scripts/config.guess
@@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
-timestamp='2012-01-01'
+timestamp='2012-09-25'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -17,9 +17,7 @@ timestamp='2012-01-01'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -202,6 +200,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -304,7 +306,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -803,6 +805,9 @@ EOF
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
@@ -863,6 +868,13 @@ EOF
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@@ -1196,6 +1208,9 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1251,7 +1266,7 @@ EOF
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
+ NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1320,11 +1335,11 @@ EOF
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
esac
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
diff --git a/libc/scripts/config.sub b/libc/scripts/config.sub
index b6f695a83..bdda9e4a3 100755
--- a/libc/scripts/config.sub
+++ b/libc/scripts/config.sub
@@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
-timestamp='2012-01-28'
+timestamp='2012-08-18'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -21,9 +21,7 @@ timestamp='2012-01-28'
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -125,7 +123,7 @@ esac
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
@@ -227,6 +225,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
@@ -251,6 +255,7 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
@@ -362,6 +367,7 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
@@ -785,6 +791,10 @@ case $basic_machine in
microblaze)
basic_machine=microblaze-xilinx
;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
mingw32)
basic_machine=i386-pc
os=-mingw32
@@ -1346,15 +1356,15 @@ case $os in
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-uclibc* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1537,6 +1547,9 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
+ hexagon-*)
+ os=-elf
+ ;;
tic54x-*)
os=-coff
;;
diff --git a/libc/stdio-common/Makefile b/libc/stdio-common/Makefile
index 1e2c2b1cc..881eb9b2e 100644
--- a/libc/stdio-common/Makefile
+++ b/libc/stdio-common/Makefile
@@ -129,6 +129,7 @@ CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
# We know the test has a format string problem.
CFLAGS-tst-sprintf.c = -Wno-format
+tst-sprintf-ENV = LOCPATH=$(common-objpfx)localedata
tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata
test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata
diff --git a/libc/stdio-common/tst-sprintf.c b/libc/stdio-common/tst-sprintf.c
index bfa79c9cc..42159a26f 100644
--- a/libc/stdio-common/tst-sprintf.c
+++ b/libc/stdio-common/tst-sprintf.c
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
+#include <locale.h>
#include <string.h>
#include <gnu/option-groups.h>
@@ -61,5 +62,17 @@ main (void)
result = 1;
}
+ if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
+ {
+ puts ("cannot set locale");
+ result = 1;
+ }
+ else if (sprintf (buf, "%.8s\n", "Foo: \277") != 7
+ || strcmp (buf, "Foo: \277\n") != 0)
+ {
+ printf ("sprintf (buf, \"%%.8s\\n\", \"Foo: \\277\") produced '%s' output\n", buf);
+ result = 1;
+ }
+
return result;
}
diff --git a/libc/stdio-common/vfprintf.c b/libc/stdio-common/vfprintf.c
index a76b03acf..0a48ce2b5 100644
--- a/libc/stdio-common/vfprintf.c
+++ b/libc/stdio-common/vfprintf.c
@@ -1185,43 +1185,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
else if (!is_long && spec != L_('S')) \
{ \
if (prec != -1) \
- { \
- /* Search for the end of the string, but don't search past \
- the length (in bytes) specified by the precision. Also \
- don't use incomplete characters. */ \
- if (! LOCALE_SUPPORT \
- ||_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX) == 1) \
- len = __strnlen (string, prec); \
- else \
- { \
- /* In case we have a multibyte character set the \
- situation is more complicated. We must not copy \
- bytes at the end which form an incomplete character. */\
- size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\
- wchar_t ignore[ignore_size]; \
- const char *str2 = string; \
- const char *strend = string + prec; \
- if (strend < string) \
- strend = (const char *) UINTPTR_MAX; \
- \
- mbstate_t ps; \
- memset (&ps, '\0', sizeof (ps)); \
- \
- while (str2 != NULL && str2 < strend) \
- if (__mbsnrtowcs (ignore, &str2, strend - str2, \
- ignore_size, &ps) == (size_t) -1) \
- { \
- /* Conversion function has set errno. */ \
- done = -1; \
- goto all_done; \
- } \
- \
- if (str2 == NULL) \
- len = strlen (string); \
- else \
- len = str2 - string - (ps.__count & 7); \
- } \
- } \
+ /* Search for the end of the string, but don't search past \
+ the length (in bytes) specified by the precision. */ \
+ len = __strnlen (string, prec); \
else \
len = strlen (string); \
} \
diff --git a/libc/string/Makefile b/libc/string/Makefile
index 096147dcc..de3ce2734 100644
--- a/libc/string/Makefile
+++ b/libc/string/Makefile
@@ -59,8 +59,7 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \
bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
tst-strtok tst-strfry \
bug-strtok1 $(addprefix test-,$(strop-tests)) \
- tst-strxfrm2 tst-endian tst-svc2 bug-strstr1 \
- bug-strcasestr1 bug-strchr1 tst-strtok_r
+ tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r
tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1
tests-$(OPTION_EGLIBC_LOCALE_CODE) \
+= tst-strxfrm bug-strcoll1
diff --git a/libc/string/bug-strchr1.c b/libc/string/bug-strchr1.c
deleted file mode 100644
index 21155d8a7..000000000
--- a/libc/string/bug-strchr1.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-static int
-do_test (void)
-{
- char s[] __attribute__((aligned(16))) = "\xff";
- char *p = strchr (s, '\xfe');
- printf ("%p\n", p);
- return p != NULL;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/libc/string/bug-strstr1.c b/libc/string/bug-strstr1.c
deleted file mode 100644
index 889de1295..000000000
--- a/libc/string/bug-strstr1.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-int main (int argc, char** argv)
-{
- const char haystack[] =
- "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD";
-
- const char needle[] =
- "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
-
- const char* sub = strstr (haystack, needle);
-
- if (sub != NULL)
- {
- int j;
-
- fprintf (stderr, "BUG: expected NULL, got:\n%s\n%s\n", sub, needle);
- for (j = 0; needle[j] != '\0'; ++j)
- putchar (needle[j] == sub[j] ? ' ' : '^');
- puts ("");
- return 1;
- }
-
- return 0;
-}
diff --git a/libc/string/str-two-way.h b/libc/string/str-two-way.h
index 59609b868..d2572da40 100644
--- a/libc/string/str-two-way.h
+++ b/libc/string/str-two-way.h
@@ -75,18 +75,17 @@
# define CMP_FUNC memcmp
#endif
-#ifndef AVAILABLE1
-# define AVAILABLE1(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l)
-#endif
-#ifndef AVAILABLE2
-# define AVAILABLE2(h, h_l, j, n_l) (1)
+/* Check for end-of-line in strstr and strcasestr routines.
+ We piggy-back matching procedure for detecting EOL where possible,
+ and use AVAILABLE macro otherwise. */
+#ifndef CHECK_EOL
+# define CHECK_EOL (0)
#endif
+
+/* Return NULL if argument is '\0'. */
#ifndef RET0_IF_0
# define RET0_IF_0(a) /* nothing */
#endif
-#ifndef AVAILABLE1_USES_J
-# define AVAILABLE1_USES_J (1)
-#endif
/* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN.
Return the index of the first byte in the right half, and set
@@ -283,11 +282,23 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
and use an optimized first-character loop. */
unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]);
+#if CHECK_EOL
+ /* We start matching from the SUFFIX'th element, so make sure we
+ don't hit '\0' before that. */
+ if (haystack_len < suffix + 1
+ && !AVAILABLE (haystack, haystack_len, 0, suffix + 1))
+ return NULL;
+#endif
+
/* The two halves of needle are distinct; no extra memory is
required, and any mismatch results in a maximal shift. */
period = MAX (suffix, needle_len - suffix) + 1;
j = 0;
- while (AVAILABLE1 (haystack, haystack_len, j, needle_len))
+ while (1
+#if !CHECK_EOL
+ && AVAILABLE (haystack, haystack_len, j, needle_len)
+#endif
+ )
{
unsigned char haystack_char;
const unsigned char *pneedle;
@@ -298,13 +309,13 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
!= (haystack_char = CANON_ELEMENT (*phaystack++)))
{
RET0_IF_0 (haystack_char);
-#if AVAILABLE1_USES_J
+#if CHECK_EOL
++j;
#endif
continue;
}
-#if !AVAILABLE1_USES_J
+#if !CHECK_EOL
/* Calculate J if it wasn't kept up-to-date in the first-character
loop. */
j = phaystack - &haystack[suffix] - 1;
@@ -346,8 +357,10 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
else
j += i - suffix + 1;
- if (!AVAILABLE2 (haystack, haystack_len, j, needle_len))
+#if CHECK_EOL
+ if (!AVAILABLE (haystack, haystack_len, j, needle_len))
break;
+#endif
phaystack = &haystack[suffix + j];
}
diff --git a/libc/string/strcasestr.c b/libc/string/strcasestr.c
index 9467b7a75..6aaf45f3a 100644
--- a/libc/string/strcasestr.c
+++ b/libc/string/strcasestr.c
@@ -43,10 +43,8 @@
#define AVAILABLE(h, h_l, j, n_l) \
(!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
&& ((h_l) = (j) + (n_l)))
-#define AVAILABLE1(h, h_l, j, n_l) (true)
-#define AVAILABLE2(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l)
+#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
-#define AVAILABLE1_USES_J (0)
#define CANON_ELEMENT(c) TOLOWER (c)
#define CMP_FUNC(p1, p2, l) \
__strncasecmp ((const char *) (p1), (const char *) (p2), l)
diff --git a/libc/string/strstr.c b/libc/string/strstr.c
index cfed77119..d74cb4697 100644
--- a/libc/string/strstr.c
+++ b/libc/string/strstr.c
@@ -35,10 +35,8 @@
#define AVAILABLE(h, h_l, j, n_l) \
(!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
&& ((h_l) = (j) + (n_l)))
-#define AVAILABLE1(h, h_l, j, n_l) (true)
-#define AVAILABLE2(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l)
+#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
-#define AVAILABLE1_USES_J (0)
#include "str-two-way.h"
#undef strstr
diff --git a/libc/string/test-strcasestr.c b/libc/string/test-strcasestr.c
index 6c1a87861..fc0185863 100644
--- a/libc/string/test-strcasestr.c
+++ b/libc/string/test-strcasestr.c
@@ -57,8 +57,9 @@ IMPL (simple_strcasestr, 0)
IMPL (strcasestr, 1)
-static void
-do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+static int
+check_result (impl_t *impl, const char *s1, const char *s2,
+ char *exp_result)
{
char *result = CALL (impl, s1, s2);
if (result != exp_result)
@@ -66,8 +67,16 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
error (0, 0, "Wrong result in function %s %s %s", impl->name,
result, exp_result);
ret = 1;
- return;
+ return -1;
}
+ return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+ if (check_result (impl, s1, s2, exp_result) < 0)
+ return;
if (HP_TIMING_AVAIL)
{
@@ -136,12 +145,25 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2,
putchar ('\n');
}
+static void
+check1 (void)
+{
+ const char s1[] = "AOKB";
+ const char s2[] = "OK";
+ char *exp_result;
+
+ exp_result = stupid_strcasestr (s1, s2);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s1, s2, exp_result);
+}
static int
test_main (void)
{
test_init ();
+ check1 ();
+
printf ("%23s", "");
FOR_EACH_IMPL (impl, 0)
printf ("\t%s", impl->name);
diff --git a/libc/string/test-strchr.c b/libc/string/test-strchr.c
index e544aa715..161ac458c 100644
--- a/libc/string/test-strchr.c
+++ b/libc/string/test-strchr.c
@@ -79,8 +79,8 @@ IMPL (stupid_STRCHR, 0)
IMPL (simple_STRCHR, 0)
IMPL (STRCHR, 1)
-static void
-do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
+static int
+check_result (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
{
CHAR *res = CALL (impl, s, c);
if (res != exp_res)
@@ -88,8 +88,16 @@ do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
error (0, 0, "Wrong result in function %s %#x %p %p", impl->name,
c, res, exp_res);
ret = 1;
- return;
+ return -1;
}
+ return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
+{
+ if (check_result (impl, s, c, exp_res) < 0)
+ return;
if (HP_TIMING_AVAIL)
{
@@ -224,6 +232,17 @@ do_random_tests (void)
}
}
+static void
+check1 (void)
+{
+ char s[] __attribute__((aligned(16))) = "\xff";
+ char c = '\xfe';
+ char *exp_result = stupid_STRCHR (s, c);
+
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s, c, exp_result);
+}
+
int
test_main (void)
{
@@ -231,6 +250,8 @@ test_main (void)
test_init ();
+ check1 ();
+
printf ("%20s", "");
FOR_EACH_IMPL (impl, 0)
printf ("\t%s", impl->name);
diff --git a/libc/string/test-strstr.c b/libc/string/test-strstr.c
index 6be460168..d4c0efc5b 100644
--- a/libc/string/test-strstr.c
+++ b/libc/string/test-strstr.c
@@ -55,8 +55,9 @@ IMPL (simple_strstr, 0)
IMPL (strstr, 1)
-static void
-do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+static int
+check_result (impl_t *impl, const char *s1, const char *s2,
+ char *exp_result)
{
char *result = CALL (impl, s1, s2);
if (result != exp_result)
@@ -64,9 +65,18 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
error (0, 0, "Wrong result in function %s %s %s", impl->name,
result, exp_result);
ret = 1;
- return;
+ return -1;
}
+ return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+ if (check_result (impl, s1, s2, exp_result) < 0)
+ return;
+
if (HP_TIMING_AVAIL)
{
hp_timing_t start __attribute ((unused));
@@ -133,12 +143,43 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2,
putchar ('\n');
}
+static void
+check1 (void)
+{
+ const char s1[] =
+ "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD";
+ const char s2[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
+ char *exp_result;
+
+ exp_result = stupid_strstr (s1, s2);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s1, s2, exp_result);
+}
+
+static void
+check2 (void)
+{
+ const char s1[] = ", enable_static, \0, enable_shared, ";
+ char *exp_result;
+ char *s2 = (void *) buf1 + page_size - 18;
+
+ strcpy (s2, s1);
+ exp_result = stupid_strstr (s1, s1 + 18);
+ FOR_EACH_IMPL (impl, 0)
+ {
+ check_result (impl, s1, s1 + 18, exp_result);
+ check_result (impl, s2, s1 + 18, exp_result);
+ }
+}
static int
test_main (void)
{
test_init ();
+ check1 ();
+ check2 ();
+
printf ("%23s", "");
FOR_EACH_IMPL (impl, 0)
printf ("\t%s", impl->name);
diff --git a/libc/sysdeps/generic/_G_config.h b/libc/sysdeps/generic/_G_config.h
index fc83565b9..e4f276731 100644
--- a/libc/sysdeps/generic/_G_config.h
+++ b/libc/sysdeps/generic/_G_config.h
@@ -28,8 +28,6 @@ typedef struct
__off64_t __pos;
__mbstate_t __state;
} _G_fpos64_t;
-#define _G_off64_t __off_t
-#define _G_stat64 stat
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
# include <gconv.h>
typedef union
@@ -51,6 +49,11 @@ typedef union
#define _G_IO_IO_FILE_VERSION 0x20001
+#define _G_OPEN64 __open64
+#define _G_LSEEK64 __lseek64
+#define _G_MMAP64 __mmap64
+#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf)
+
/* This is defined by <bits/stat.h> if `st_blksize' exists. */
#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE)
diff --git a/libc/sysdeps/generic/ldsodefs.h b/libc/sysdeps/generic/ldsodefs.h
index 8d73212bb..9813d9bc2 100644
--- a/libc/sysdeps/generic/ldsodefs.h
+++ b/libc/sysdeps/generic/ldsodefs.h
@@ -41,6 +41,12 @@
__BEGIN_DECLS
+#define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
+#define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+ + DT_EXTRANUM + DT_VALTAGIDX (tag))
+#define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+ + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
+
/* We use this macro to refer to ELF types independent of the native wordsize.
`ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type)
diff --git a/libc/sysdeps/generic/math_private.h b/libc/sysdeps/generic/math_private.h
index 5267ec327..b375bc0c5 100644
--- a/libc/sysdeps/generic/math_private.h
+++ b/libc/sysdeps/generic/math_private.h
@@ -364,6 +364,13 @@ extern double __slowexp (double __x);
extern double __slowpow (double __x, double __y, double __z);
extern void __docos (double __x, double __dx, double __v[]);
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+ It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+ 0.75 or Y >= 0.5. */
+extern float __x2y2m1f (float x, float y);
+extern double __x2y2m1 (double x, double y);
+extern long double __x2y2m1l (long double x, long double y);
+
#ifndef math_opt_barrier
# define math_opt_barrier(x) \
({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; })
diff --git a/libc/sysdeps/i386/configure b/libc/sysdeps/i386/configure
index 608ff29bc..7b3683f60 100755
--- a/libc/sysdeps/i386/configure
+++ b/libc/sysdeps/i386/configure
@@ -1,124 +1,4 @@
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists and can be compiled using the include files in
@@ -162,6 +42,7 @@ else
fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSE4 support" >&5
$as_echo_n "checking for SSE4 support... " >&6; }
if ${libc_cv_cc_sse4+:} false; then :
@@ -299,3 +180,4 @@ fi
$as_echo "$libc_cv_cc_novzeroupper" >&6; }
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
diff --git a/libc/sysdeps/i386/fpu/libm-test-ulps b/libc/sysdeps/i386/fpu/libm-test-ulps
index d35635ce0..239da44a7 100644
--- a/libc/sysdeps/i386/fpu/libm-test-ulps
+++ b/libc/sysdeps/i386/fpu/libm-test-ulps
@@ -880,6 +880,12 @@ float: 1
ifloat: 1
ildouble: 1
ldouble: 1
+Test "Real part of: clog (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -5.421010862427522170184200798202494495630e-20 + 3.548665303440282824232502561095699343814e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i":
+float: 1
+ifloat: 1
Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i":
ildouble: 1
ldouble: 1
@@ -904,6 +910,9 @@ ldouble: 1
Test "Real part of: clog (0x1.fp+16383 - 0x1p-16445 i) == 11356.49165759582936919077408168801636572 - 0 i":
ildouble: 1
ldouble: 1
+Test "Imaginary part of: clog (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 5.0844550531823026520677817684239496041087e-32 + 1.2627468605458094918919206628466016525397 i":
+ildouble: 1
+ldouble: 1
Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i":
ildouble: 1
ldouble: 1
@@ -922,6 +931,9 @@ ldouble: 1
Test "Real part of: clog (0x1p-16445 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i":
ildouble: 1
ldouble: 1
+Test "Real part of: clog (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 4.4469229730850767799109418892826021157328e-20 + 1.2046235979300843056806465045930070146351 i":
+ildouble: 1
+ldouble: 1
Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i":
float: 1
ifloat: 1
@@ -1068,6 +1080,17 @@ idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -2.354315103889861110220423157644627849164e-20 + 1.541165759405643564697852372112893034397e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
Test "Real part of: clog10 (0x1.000566p0 + 0x1.234p-10 i) == 3.604093470239754109961125085078190708674e-5 + 4.824745078422174667425851670822596859720e-4 i":
ildouble: 1
ldouble: 1
@@ -1119,6 +1142,29 @@ ldouble: 1
Test "Real part of: clog10 (0x1.fp+16383 - 0x1p-16445 i) == 4932.061660674182269085496060792589701158 - 0 i":
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x11682p-23 + 0x7ffed1p-23 i) == 5.0916490233953865181284669870035717560498e-13 + 0.6784968969384861816694467029319146542069 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+double: 1
+idouble: 1
Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i":
double: 1
idouble: 1
@@ -1199,6 +1245,73 @@ ifloat: 1
Test "Real part of: clog10 (0x1p-8190 + 1.0 i) == 2.920285685286322365786846845062520925172e-4932 + 6.821881769209206737428918127156778851051e-1 i":
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659b70ab7971bp-53 + 0x1f5d111e08abecp-53 i) == -1.0893543813872082317104059174982092534059e-30 + 0.5954257879188711495921161433751775633232 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x81b7efa81fc35ad1p-65 + 0x1ef4b835f1c79d812p-65 i) == -4.3074341162203896332989394770760901408798e-39 + 0.5709443672155660428417571212549720987784 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -4.2289432987513243393180377141513840878196e-30 + 0.4252020027092323591068799049905597805296 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i":
+double: 1
+idouble: 1
Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i":
double: 1
idouble: 1
@@ -1490,9 +1603,9 @@ float: 1
ifloat: 1
Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
double: 2
-float: 3
+float: 4
idouble: 2
-ifloat: 3
+ifloat: 4
ildouble: 3
ldouble: 3
Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
@@ -1704,6 +1817,8 @@ ldouble: 1
# ctan
Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+float: 1
+ifloat: 1
double: 1
idouble: 1
ildouble: 1
@@ -1797,6 +1912,8 @@ Test "Imaginary part of: ctan_towardzero (0x1.921fb54442d18p+0 + 0x1p-1074 i) ==
ildouble: 1
ldouble: 1
Test "Real part of: ctan_towardzero (0x1.921fb6p+0 + 0x1p-149 i) == -2.287733242885645987394874673945769518150e7 + 7.334008549954377778731880988481078535821e-31 i":
+float: 1
+ifloat: 1
ildouble: 1
ldouble: 1
Test "Imaginary part of: ctan_towardzero (0x1.921fb6p+0 + 0x1p-149 i) == -2.287733242885645987394874673945769518150e7 + 7.334008549954377778731880988481078535821e-31 i":
@@ -1827,9 +1944,9 @@ ildouble: 2
ldouble: 2
Test "Imaginary part of: ctan_upward (0x1.921fb6p+0 + 0x1p-149 i) == -2.287733242885645987394874673945769518150e7 + 7.334008549954377778731880988481078535821e-31 i":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 1
ldouble: 1
@@ -1940,6 +2057,8 @@ ifloat: 3
ildouble: 4
ldouble: 4
Test "Imaginary part of: ctanh_towardzero (0x1p-149 + 0x1.921fb6p+0 i) == 7.334008549954377778731880988481078535821e-31 - 2.287733242885645987394874673945769518150e7 i":
+float: 1
+ifloat: 1
ildouble: 1
ldouble: 1
@@ -1954,9 +2073,9 @@ ildouble: 1
ldouble: 1
Test "Real part of: ctanh_upward (0x1p-149 + 0x1.921fb6p+0 i) == 7.334008549954377778731880988481078535821e-31 - 2.287733242885645987394874673945769518150e7 i":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 1
ldouble: 1
Test "Imaginary part of: ctanh_upward (0x1p-149 + 0x1.921fb6p+0 i) == 7.334008549954377778731880988481078535821e-31 - 2.287733242885645987394874673945769518150e7 i":
@@ -2564,9 +2683,6 @@ Test "sincos (0x1.fffff8p+127, &sin_res, &cos_res) puts 4.8578606313048733970111
float: 1
Test "sincos (0x1p+127, &sin_res, &cos_res) puts 6.23385512955870240370428801097126489001833e-01 in sin_res":
float: 1
-Test "sincos (0x1p+50, &sin_res, &cos_res) puts 8.68095904660550604334592502063501320395739e-01 in cos_res":
-float: 1
-ifloat: 1
Test "sincos (0x1p65, &sin_res, &cos_res) puts -0.047183876212354673805106149805700013943218 in sin_res":
float: 1
ifloat: 1
@@ -3268,6 +3384,10 @@ ifloat: 1
ildouble: 1
ldouble: 1
+Function: Imaginary part of "clog":
+ildouble: 1
+ldouble: 1
+
Function: Real part of "clog10":
double: 1
float: 1
@@ -3442,6 +3562,8 @@ ildouble: 1
ldouble: 1
Function: Real part of "ctan_towardzero":
+float: 1
+ifloat: 1
double: 1
idouble: 1
ildouble: 1
@@ -3461,9 +3583,9 @@ ldouble: 2
Function: Imaginary part of "ctan_upward":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 4
ldouble: 4
@@ -3514,6 +3636,8 @@ ildouble: 4
ldouble: 4
Function: Imaginary part of "ctanh_towardzero":
+float: 1
+ifloat: 1
double: 1
idouble: 1
ildouble: 1
@@ -3521,9 +3645,9 @@ ldouble: 1
Function: Real part of "ctanh_upward":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 4
ldouble: 4
diff --git a/libc/sysdeps/i386/i686/fpu/multiarch/Makefile b/libc/sysdeps/i386/i686/fpu/multiarch/Makefile
index aa28f7284..7d9089232 100644
--- a/libc/sysdeps/i386/i686/fpu/multiarch/Makefile
+++ b/libc/sysdeps/i386/i686/fpu/multiarch/Makefile
@@ -1,3 +1,4 @@
ifeq ($(subdir),math)
-libm-sysdep_routines += e_expf-sse2 e_expf-ia32 s_sinf-sse2 s_cosf-sse2
+libm-sysdep_routines += e_expf-sse2 e_expf-ia32 s_sinf-sse2 s_cosf-sse2 \
+ s_sincosf-sse2
endif
diff --git a/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S
new file mode 100644
index 000000000..622f07ac8
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S
@@ -0,0 +1,586 @@
+/* Optimized with sse2 version of sincosf
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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>
+#define __need_Emath
+#include <bits/errno.h>
+
+/* Short algorithm description:
+ *
+ * 1) if |x|==0: sin(x)=x,
+ * cos(x)=1.
+ * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed,
+ * cos(x)=1-|x|.
+ * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1,
+ * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1
+ * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))),
+ * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))).
+ * 5) if |x| < 9*Pi/4:
+ * 5.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4.
+ * 5.2) Reconstruction:
+ * sign_sin = sign(x) * (-1.0)^(( n >>2)&1)
+ * sign_cos = (-1.0)^(((n+2)>>2)&1)
+ * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t
+ * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s
+ * if(n&2 != 0) {
+ * using cos(t) and sin(t) polynomials for |t|<Pi/4, results are
+ * cos(x) = poly_sin * sign_cos
+ * sin(x) = poly_cos * sign_sin
+ * } else {
+ * sin(x) = poly_sin * sign_sin
+ * cos(x) = poly_cos * sign_cos
+ * }
+ * 6) if |x| < 2^23, large args:
+ * 6.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4
+ * 6.2) Reconstruction same as (5.2).
+ * 7) if |x| >= 2^23, very large args:
+ * 7.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4.
+ * 7.2) Reconstruction same as (5.2).
+ * 8) if x is Inf, return x-x, and set errno=EDOM.
+ * 9) if x is NaN, return x-x.
+ *
+ * Special cases:
+ * sin/cos(+-0) = +-0/1 not raising inexact/underflow,
+ * sin/cos(subnormal) raises inexact/underflow,
+ * sin/cos(min_normalized) raises inexact/underflow,
+ * sin/cos(normalized) raises inexact,
+ * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM,
+ * sin/cos(NaN) = NaN.
+ */
+
+#ifdef PIC
+# define MO1(symbol) L(symbol)##@GOTOFF(%ebx)
+# define MO2(symbol,reg2,_scale) L(symbol)##@GOTOFF(%ebx,reg2,_scale)
+# define CFI_PUSH(REG) cfi_adjust_cfa_offset(4); cfi_rel_offset(REG,0)
+# define CFI_POP(REG) cfi_adjust_cfa_offset(-4); cfi_restore(REG)
+# define PUSH(REG) pushl REG; CFI_PUSH(REG)
+# define POP(REG) popl REG; CFI_POP(REG)
+# define ENTRANCE PUSH(%ebx); LOAD_PIC_REG(bx)
+# define RETURN POP(%ebx); ret; CFI_PUSH(%ebx)
+# define ARG_X 8(%esp)
+# define ARG_SIN_PTR 12(%esp)
+# define ARG_COS_PTR 16(%esp)
+#else
+# define MO1(symbol) L(symbol)
+# define MO2(symbol,reg2,_scale) L(symbol)(,reg2,_scale)
+# define ENTRANCE
+# define RETURN ret
+# define ARG_X 4(%esp)
+# define ARG_SIN_PTR 8(%esp)
+# define ARG_COS_PTR 12(%esp)
+#endif
+
+ .text
+ENTRY(__sincosf_sse2)
+ /* Input: single precision x on stack at address ARG_X */
+ /* pointer to sin result on stack at address ARG_SIN_PTR */
+ /* pointer to cos result on stack at address ARG_COS_PTR */
+
+ ENTRANCE
+ movl ARG_X, %eax /* Bits of x */
+ cvtss2sd ARG_X, %xmm0 /* DP x */
+ andl $0x7fffffff, %eax /* |x| */
+
+ cmpl $0x3f490fdb, %eax /* |x|<Pi/4 ? */
+ jb L(arg_less_pio4)
+
+ /* Here if |x|>=Pi/4 */
+ movd %eax, %xmm3 /* SP |x| */
+ andpd MO1(DP_ABS_MASK),%xmm0 /* DP |x| */
+ movss MO1(SP_INVPIO4), %xmm2 /* SP 1/(Pi/4) */
+
+ cmpl $0x40e231d6, %eax /* |x|<9*Pi/4 ? */
+ jae L(large_args)
+
+ /* Here if Pi/4<=|x|<9*Pi/4 */
+ mulss %xmm3, %xmm2 /* SP |x|/(Pi/4) */
+ movl ARG_X, %ecx /* Load x */
+ cvttss2si %xmm2, %eax /* k, number of Pi/4 in x */
+ shrl $29, %ecx /* (sign of x) << 2 */
+ addl $1, %eax /* k+1 */
+ movl $0x0e, %edx
+ andl %eax, %edx /* j = (k+1)&0x0e */
+ subsd MO2(PIO4J,%edx,8), %xmm0/* t = |x| - j * Pi/4 */
+
+L(reconstruction):
+ /* Input: %eax=n, %xmm0=t, %ecx=sign(x) */
+
+ movaps %xmm0, %xmm4 /* t */
+ movhpd MO1(DP_ONES), %xmm4 /* 1|t */
+ mulsd %xmm0, %xmm0 /* y=t^2 */
+ movl $2, %edx
+ unpcklpd %xmm0, %xmm0 /* y|y */
+ addl %eax, %edx /* k+2 */
+ movaps %xmm0, %xmm1 /* y|y */
+ mulpd %xmm0, %xmm0 /* z=t^4|z=t^4 */
+
+ movaps MO1(DP_SC4), %xmm2 /* S4 */
+ mulpd %xmm0, %xmm2 /* z*S4 */
+ movaps MO1(DP_SC3), %xmm3 /* S3 */
+ mulpd %xmm0, %xmm3 /* z*S3 */
+ xorl %eax, %ecx /* (sign_x ^ (k>>2))<<2 */
+ addpd MO1(DP_SC2), %xmm2 /* S2+z*S4 */
+ mulpd %xmm0, %xmm2 /* z*(S2+z*S4) */
+ shrl $2, %edx /* (k+2)>>2 */
+ addpd MO1(DP_SC1), %xmm3 /* S1+z*S3 */
+ mulpd %xmm0, %xmm3 /* z*(S1+z*S3) */
+ shrl $2, %ecx /* sign_x ^ k>>2 */
+ addpd MO1(DP_SC0), %xmm2 /* S0+z*(S2+z*S4) */
+ andl $1, %edx /* sign_cos = ((k+2)>>2)&1 */
+ mulpd %xmm1, %xmm2 /* y*(S0+z*(S2+z*S4)) */
+ andl $1, %ecx /* sign_sin = sign_x ^ ((k>>2)&1) */
+ addpd %xmm2, %xmm3 /* y*(S0+y*(S1+y*(S2+y*(S3+y*S4)))) */
+ mulpd %xmm4, %xmm3 /*t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/
+ testl $2, %eax /* n&2 != 0 ? */
+ addpd %xmm4, %xmm3 /*t+t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/
+ jnz L(sin_result_sin_poly)
+
+/*L(sin_result_cos_poly):*/
+ /*
+ * Here if
+ * cos(x) = poly_sin * sign_cos
+ * sin(x) = poly_cos * sign_sin
+ */
+ movsd MO2(DP_ONES,%ecx,8), %xmm4/* 0|sign_sin */
+ movhpd MO2(DP_ONES,%edx,8), %xmm4/* sign_cos|sign_sin */
+ mulpd %xmm4, %xmm3 /* result_cos|result_sin */
+ movl ARG_SIN_PTR, %eax
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movl ARG_COS_PTR, %ecx
+ movss %xmm0, (%eax) /* store sin(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */
+ movss %xmm0, (%ecx) /* store cos(x) */
+ RETURN
+
+ .p2align 4
+L(sin_result_sin_poly):
+ /*
+ * Here if
+ * sin(x) = poly_sin * sign_sin
+ * cos(x) = poly_cos * sign_cos
+ */
+ movsd MO2(DP_ONES,%edx,8), %xmm4/* 0|sign_cos */
+ movhpd MO2(DP_ONES,%ecx,8), %xmm4/* sign_sin|sign_cos */
+ mulpd %xmm4, %xmm3 /* result_sin|result_cos */
+ movl ARG_SIN_PTR, %eax
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movl ARG_COS_PTR, %ecx
+ movss %xmm0, (%ecx) /* store cos(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move sin(x) to xmm0[0] */
+ movss %xmm0, (%eax) /* store sin(x) */
+ RETURN
+
+ .p2align 4
+L(large_args):
+ /* Here if |x|>=9*Pi/4 */
+ cmpl $0x7f800000, %eax /* x is Inf or NaN ? */
+ jae L(arg_inf_or_nan)
+
+ /* Here if finite |x|>=9*Pi/4 */
+ cmpl $0x4b000000, %eax /* |x|<2^23 ? */
+ jae L(very_large_args)
+
+ /* Here if 9*Pi/4<=|x|<2^23 */
+ movsd MO1(DP_INVPIO4), %xmm1 /* 1/(Pi/4) */
+ mulsd %xmm0, %xmm1 /* |x|/(Pi/4) */
+ cvttsd2si %xmm1, %eax /* k=trunc(|x|/(Pi/4)) */
+ addl $1, %eax /* k+1 */
+ movl %eax, %edx
+ andl $0xfffffffe, %edx /* j=(k+1)&0xfffffffe */
+ cvtsi2sdl %edx, %xmm4 /* DP j */
+ movl ARG_X, %ecx /* Load x */
+ movsd MO1(DP_PIO4HI), %xmm2 /* -PIO4HI = high part of -Pi/4 */
+ shrl $29, %ecx /* (sign of x) << 2 */
+ mulsd %xmm4, %xmm2 /* -j*PIO4HI */
+ movsd MO1(DP_PIO4LO), %xmm3 /* -PIO4LO = low part of -Pi/4 */
+ addsd %xmm2, %xmm0 /* |x| - j*PIO4HI */
+ mulsd %xmm3, %xmm4 /* j*PIO4LO */
+ addsd %xmm4, %xmm0 /* t = |x| - j*PIO4HI - j*PIO4LO */
+ jmp L(reconstruction)
+
+ .p2align 4
+L(very_large_args):
+ /* Here if finite |x|>=2^23 */
+
+ /* bitpos = (ix>>23) - BIAS_32 + 59; */
+ shrl $23, %eax /* eb = biased exponent of x */
+ subl $68, %eax /* bitpos=eb-0x7f+59, where 0x7f */
+ /*is exponent bias */
+ movl $28, %ecx /* %cl=28 */
+ movl %eax, %edx /* bitpos copy */
+
+ /* j = bitpos/28; */
+ div %cl /* j in register %al=%ax/%cl */
+ movapd %xmm0, %xmm3 /* |x| */
+ andl $0xff, %eax /* clear unneeded remainder from %ah*/
+
+ imull $28, %eax, %ecx /* j*28 */
+ movsd MO1(DP_HI_MASK), %xmm4 /* DP_HI_MASK */
+ movapd %xmm0, %xmm5 /* |x| */
+ mulsd -2*8+MO2(_FPI,%eax,8), %xmm3/* tmp3 = FPI[j-2]*|x| */
+ movapd %xmm0, %xmm1 /* |x| */
+ mulsd -1*8+MO2(_FPI,%eax,8), %xmm5/* tmp2 = FPI[j-1]*|x| */
+ mulsd 0*8+MO2(_FPI,%eax,8), %xmm0/* tmp0 = FPI[j]*|x| */
+ addl $19, %ecx /* j*28+19 */
+ mulsd 1*8+MO2(_FPI,%eax,8), %xmm1/* tmp1 = FPI[j+1]*|x| */
+ cmpl %ecx, %edx /* bitpos>=j*28+19 ? */
+ jl L(very_large_skip1)
+
+ /* Here if bitpos>=j*28+19 */
+ andpd %xmm3, %xmm4 /* HI(tmp3) */
+ subsd %xmm4, %xmm3 /* tmp3 = tmp3 - HI(tmp3) */
+L(very_large_skip1):
+
+ movsd MO1(DP_2POW52), %xmm6
+ movapd %xmm5, %xmm2 /* tmp2 copy */
+ addsd %xmm3, %xmm5 /* tmp5 = tmp3 + tmp2 */
+ movl $1, %edx
+ addsd %xmm5, %xmm6 /* tmp6 = tmp5 + 2^52 */
+ movsd 8+MO1(DP_2POW52), %xmm4
+ movd %xmm6, %eax /* k = I64_LO(tmp6); */
+ addsd %xmm6, %xmm4 /* tmp4 = tmp6 - 2^52 */
+ movl ARG_X, %ecx /* Load x */
+ comisd %xmm5, %xmm4 /* tmp4 > tmp5 ? */
+ jbe L(very_large_skip2)
+
+ /* Here if tmp4 > tmp5 */
+ subl $1, %eax /* k-- */
+ addsd 8+MO1(DP_ONES), %xmm4 /* tmp4 -= 1.0 */
+L(very_large_skip2):
+
+ andl %eax, %edx /* k&1 */
+ subsd %xmm4, %xmm3 /* tmp3 -= tmp4 */
+ addsd MO2(DP_ZERONE,%edx,8), %xmm3/* t = DP_ZERONE[k&1] + tmp3 */
+ addsd %xmm2, %xmm3 /* t += tmp2 */
+ shrl $29, %ecx /* (sign of x) << 2 */
+ addsd %xmm3, %xmm0 /* t += tmp0 */
+ addl $1, %eax /* n=k+1 */
+ addsd %xmm1, %xmm0 /* t += tmp1 */
+ mulsd MO1(DP_PIO4), %xmm0 /* t *= PI04 */
+
+ jmp L(reconstruction) /* end of very_large_args peth */
+
+ .p2align 4
+L(arg_less_pio4):
+ /* Here if |x|<Pi/4 */
+ cmpl $0x3d000000, %eax /* |x|<2^-5 ? */
+ jl L(arg_less_2pn5)
+
+ /* Here if 2^-5<=|x|<Pi/4 */
+ movaps %xmm0, %xmm3 /* DP x */
+ movhpd MO1(DP_ONES), %xmm3 /* DP 1|x */
+ mulsd %xmm0, %xmm0 /* DP y=x^2 */
+ unpcklpd %xmm0, %xmm0 /* DP y|y */
+ movaps %xmm0, %xmm1 /* y|y */
+ mulpd %xmm0, %xmm0 /* z=x^4|z=x^4 */
+
+ movapd MO1(DP_SC4), %xmm4 /* S4 */
+ mulpd %xmm0, %xmm4 /* z*S4 */
+ movapd MO1(DP_SC3), %xmm5 /* S3 */
+ mulpd %xmm0, %xmm5 /* z*S3 */
+ addpd MO1(DP_SC2), %xmm4 /* S2+z*S4 */
+ mulpd %xmm0, %xmm4 /* z*(S2+z*S4) */
+ addpd MO1(DP_SC1), %xmm5 /* S1+z*S3 */
+ mulpd %xmm0, %xmm5 /* z*(S1+z*S3) */
+ addpd MO1(DP_SC0), %xmm4 /* S0+z*(S2+z*S4) */
+ mulpd %xmm1, %xmm4 /* y*(S0+z*(S2+z*S4)) */
+ mulpd %xmm3, %xmm5 /* x*z*(S1+z*S3) */
+ mulpd %xmm3, %xmm4 /* x*y*(S0+z*(S2+z*S4)) */
+ addpd %xmm5, %xmm4 /*x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/
+ movl ARG_SIN_PTR, %eax
+ addpd %xmm4, %xmm3 /*x+x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/
+ movl ARG_COS_PTR, %ecx
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movss %xmm0, (%eax) /* store sin(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */
+ movss %xmm0, (%ecx) /* store cos(x) */
+ RETURN
+
+ .p2align 4
+L(arg_less_2pn5):
+ /* Here if |x|<2^-5 */
+ cmpl $0x32000000, %eax /* |x|<2^-27 ? */
+ jl L(arg_less_2pn27)
+
+ /* Here if 2^-27<=|x|<2^-5 */
+ movaps %xmm0, %xmm1 /* DP x */
+ movhpd MO1(DP_ONES), %xmm1 /* DP 1|x */
+ mulsd %xmm0, %xmm0 /* DP x^2 */
+ unpcklpd %xmm0, %xmm0 /* DP x^2|x^2 */
+
+ movaps MO1(DP_SINCOS2_1), %xmm3/* DP DP_SIN2_1 */
+ mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_1 */
+ addpd MO1(DP_SINCOS2_0), %xmm3/* DP DP_SIN2_0+x^2*DP_SIN2_1 */
+ mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_0+x^4*DP_SIN2_1 */
+ mulpd %xmm1, %xmm3 /* DP x^3*DP_SIN2_0+x^5*DP_SIN2_1 */
+ addpd %xmm1, %xmm3 /* DP x+x^3*DP_SIN2_0+x^5*DP_SIN2_1 */
+ movl ARG_SIN_PTR, %eax
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movl ARG_COS_PTR, %ecx
+ movss %xmm0, (%eax) /* store sin(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */
+ movss %xmm0, (%ecx) /* store cos(x) */
+ RETURN
+
+ .p2align 4
+L(arg_less_2pn27):
+ movss ARG_X, %xmm7 /* SP x */
+ cmpl $0, %eax /* x=0 ? */
+ je L(arg_zero) /* in case x=0 return sin(+-0)==+-0 */
+ /* Here if |x|<2^-27 */
+ /*
+ * Special cases here:
+ * sin(subnormal) raises inexact/underflow
+ * sin(min_normalized) raises inexact/underflow
+ * sin(normalized) raises inexact
+ * cos(here)=1-|x| (raising inexact)
+ */
+ movaps %xmm0, %xmm3 /* DP x */
+ mulsd MO1(DP_SMALL), %xmm0 /* DP x*DP_SMALL */
+ subsd %xmm0, %xmm3 /* DP sin result is x-x*DP_SMALL */
+ andps MO1(SP_ABS_MASK), %xmm7 /* SP |x| */
+ cvtsd2ss %xmm3, %xmm0 /* sin(x) */
+ movl ARG_SIN_PTR, %eax
+ movss MO1(SP_ONE), %xmm1 /* SP 1.0 */
+ movss %xmm0, (%eax) /* sin(x) store */
+ movl ARG_COS_PTR, %ecx
+ subss %xmm7, %xmm1 /* cos(x) */
+ movss %xmm1, (%ecx) /* cos(x) store */
+ RETURN
+
+ .p2align 4
+L(arg_zero):
+ movss MO1(SP_ONE), %xmm0 /* 1.0 */
+ movl ARG_SIN_PTR, %eax
+ movl ARG_COS_PTR, %ecx
+ movss %xmm7, (%eax) /* sin(+-0)==x */
+ movss %xmm0, (%ecx) /* cos(+-0)==1 */
+ RETURN
+
+ .p2align 4
+L(arg_inf_or_nan):
+ movss ARG_X, %xmm7 /* SP x */
+ /* Here if |x| is Inf or NAN */
+ jne L(skip_errno_setting) /* in case of x is NaN */
+
+ /* Here if x is Inf. Set errno to EDOM. */
+ call JUMPTARGET(__errno_location)
+ movl $EDOM, (%eax)
+
+ .p2align 4
+L(skip_errno_setting):
+ /* Here if |x| is Inf or NAN. Continued. */
+ subss %xmm7, %xmm7 /* x-x, result is NaN */
+ movl ARG_SIN_PTR, %eax
+ movl ARG_COS_PTR, %ecx
+ movss %xmm7, (%eax)
+ movss %xmm7, (%ecx)
+ RETURN
+END(__sincosf_sse2)
+
+ .section .rodata, "a"
+ .p2align 3
+L(PIO4J): /* Table of j*Pi/4, for j=0,1,..,10 */
+ .long 0x00000000,0x00000000
+ .long 0x54442d18,0x3fe921fb
+ .long 0x54442d18,0x3ff921fb
+ .long 0x7f3321d2,0x4002d97c
+ .long 0x54442d18,0x400921fb
+ .long 0x2955385e,0x400f6a7a
+ .long 0x7f3321d2,0x4012d97c
+ .long 0xe9bba775,0x4015fdbb
+ .long 0x54442d18,0x401921fb
+ .long 0xbeccb2bb,0x401c463a
+ .long 0x2955385e,0x401f6a7a
+ .type L(PIO4J), @object
+ ASM_SIZE_DIRECTIVE(L(PIO4J))
+
+ .p2align 3
+L(_FPI): /* 4/Pi broken into sum of positive DP values */
+ .long 0x00000000,0x00000000
+ .long 0x6c000000,0x3ff45f30
+ .long 0x2a000000,0x3e3c9c88
+ .long 0xa8000000,0x3c54fe13
+ .long 0xd0000000,0x3aaf47d4
+ .long 0x6c000000,0x38fbb81b
+ .long 0xe0000000,0x3714acc9
+ .long 0x7c000000,0x3560e410
+ .long 0x56000000,0x33bca2c7
+ .long 0xac000000,0x31fbd778
+ .long 0xe0000000,0x300b7246
+ .long 0xe8000000,0x2e5d2126
+ .long 0x48000000,0x2c970032
+ .long 0xe8000000,0x2ad77504
+ .long 0xe0000000,0x290921cf
+ .long 0xb0000000,0x274deb1c
+ .long 0xe0000000,0x25829a73
+ .long 0xbe000000,0x23fd1046
+ .long 0x10000000,0x2224baed
+ .long 0x8e000000,0x20709d33
+ .long 0x80000000,0x1e535a2f
+ .long 0x64000000,0x1cef904e
+ .long 0x30000000,0x1b0d6398
+ .long 0x24000000,0x1964ce7d
+ .long 0x16000000,0x17b908bf
+ .type L(_FPI), @object
+ ASM_SIZE_DIRECTIVE(L(_FPI))
+
+/* Coefficients of polynomials for */
+/* sin(x)~=x+x*x^2*(DP_SIN2_0+x^2*DP_SIN2_1) in low DP part, */
+/* cos(x)~=1+1*x^2*(DP_COS2_0+x^2*DP_COS2_1) in high DP part, */
+/* for |x|<2^-5. */
+ .p2align 4
+L(DP_SINCOS2_0):
+ .long 0x5543d49d,0xbfc55555
+ .long 0xff5cc6fd,0xbfdfffff
+ .type L(DP_SINCOS2_0), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_0))
+
+ .p2align 4
+L(DP_SINCOS2_1):
+ .long 0x75cec8c5,0x3f8110f4
+ .long 0xb178dac5,0x3fa55514
+ .type L(DP_SINCOS2_1), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_1))
+
+ .p2align 3
+L(DP_ZERONE):
+ .long 0x00000000,0x00000000 /* 0.0 */
+ .long 0x00000000,0xbff00000 /* 1.0 */
+ .type L(DP_ZERONE), @object
+ ASM_SIZE_DIRECTIVE(L(DP_ZERONE))
+
+ .p2align 3
+L(DP_ONES):
+ .long 0x00000000,0x3ff00000 /* +1.0 */
+ .long 0x00000000,0xbff00000 /* -1.0 */
+ .type L(DP_ONES), @object
+ ASM_SIZE_DIRECTIVE(L(DP_ONES))
+
+/* Coefficients of polynomials for */
+/* sin(t)~=t+t*t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4)))) in low DP part, */
+/* cos(t)~=1+1*t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4)))) in high DP part, */
+/* for |t|<Pi/4. */
+ .p2align 4
+L(DP_SC4):
+ .long 0x1674b58a,0xbe5a947e
+ .long 0xdd8844d7,0xbe923c97
+ .type L(DP_SC4), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC4))
+
+ .p2align 4
+L(DP_SC3):
+ .long 0x64e6b5b4,0x3ec71d72
+ .long 0x9ac43cc0,0x3efa00eb
+ .type L(DP_SC3), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC3))
+
+ .p2align 4
+L(DP_SC2):
+ .long 0x8b4bd1f9,0xbf2a019f
+ .long 0x348b6874,0xbf56c16b
+ .type L(DP_SC2), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC2))
+
+ .p2align 4
+L(DP_SC1):
+ .long 0x10c2688b,0x3f811111
+ .long 0x545c50c7,0x3fa55555
+ .type L(DP_SC1), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC1))
+
+ .p2align 4
+L(DP_SC0):
+ .long 0x55551cd9,0xbfc55555
+ .long 0xfffe98ae,0xbfdfffff
+ .type L(DP_SC0), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC0))
+
+ .p2align 3
+L(DP_SMALL):
+ .long 0x00000000,0x3cd00000 /* 2^(-50) */
+ .type L(DP_SMALL), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SMALL))
+
+ .p2align 3
+L(DP_PIO4):
+ .long 0x54442d18,0x3fe921fb /* Pi/4 */
+ .type L(DP_PIO4), @object
+ ASM_SIZE_DIRECTIVE(L(DP_PIO4))
+
+ .p2align 3
+L(DP_2POW52):
+ .long 0x00000000,0x43300000 /* +2^52 */
+ .long 0x00000000,0xc3300000 /* -2^52 */
+ .type L(DP_2POW52), @object
+ ASM_SIZE_DIRECTIVE(L(DP_2POW52))
+
+ .p2align 3
+L(DP_INVPIO4):
+ .long 0x6dc9c883,0x3ff45f30 /* 4/Pi */
+ .type L(DP_INVPIO4), @object
+ ASM_SIZE_DIRECTIVE(L(DP_INVPIO4))
+
+ .p2align 3
+L(DP_PIO4HI):
+ .long 0x54000000,0xbfe921fb /* High part of Pi/4 */
+ .type L(DP_PIO4HI), @object
+ ASM_SIZE_DIRECTIVE(L(DP_PIO4HI))
+
+ .p2align 3
+L(DP_PIO4LO):
+ .long 0x11A62633,0xbe010b46 /* Low part of Pi/4 */
+ .type L(DP_PIO4LO), @object
+ ASM_SIZE_DIRECTIVE(L(DP_PIO4LO))
+
+ .p2align 2
+L(SP_INVPIO4):
+ .long 0x3fa2f983 /* 4/Pi */
+ .type L(SP_INVPIO4), @object
+ ASM_SIZE_DIRECTIVE(L(SP_INVPIO4))
+
+ .p2align 4
+L(DP_ABS_MASK): /* Mask for getting DP absolute value */
+ .long 0xffffffff,0x7fffffff
+ .long 0xffffffff,0x7fffffff
+ .type L(DP_ABS_MASK), @object
+ ASM_SIZE_DIRECTIVE(L(DP_ABS_MASK))
+
+ .p2align 3
+L(DP_HI_MASK): /* Mask for getting high 21 bits of DP value */
+ .long 0x00000000,0xffffffff
+ .type L(DP_HI_MASK), @object
+ ASM_SIZE_DIRECTIVE(L(DP_HI_MASK))
+
+ .p2align 4
+L(SP_ABS_MASK): /* Mask for getting SP absolute value */
+ .long 0x7fffffff,0x7fffffff
+ .long 0x7fffffff,0x7fffffff
+ .type L(SP_ABS_MASK), @object
+ ASM_SIZE_DIRECTIVE(L(SP_ABS_MASK))
+
+ .p2align 2
+L(SP_ONE):
+ .long 0x3f800000 /* 1.0 */
+ .type L(SP_ONE), @object
+ ASM_SIZE_DIRECTIVE(L(SP_ONE))
+
+weak_alias(__sincosf, sincosf)
diff --git a/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c
new file mode 100644
index 000000000..c5e856a21
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c
@@ -0,0 +1,29 @@
+/* Multiple versions of sincosf
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 <init-arch.h>
+
+extern void __sincosf_sse2 (float, float *, float *);
+extern void __sincosf_ia32 (float, float *, float *);
+void __sincosf (float, float *, float *);
+
+libm_ifunc (__sincosf, HAS_SSE2 ? __sincosf_sse2 : __sincosf_ia32);
+weak_alias (__sincosf, sincosf);
+
+#define SINCOSF __sincosf_ia32
+#include <sysdeps/ieee754/flt-32/s_sincosf.c>
diff --git a/libc/sysdeps/i386/init-first.c b/libc/sysdeps/i386/init-first.c
deleted file mode 100644
index edea7f269..000000000
--- a/libc/sysdeps/i386/init-first.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Initialization code run first thing by the ELF startup code. For i386/Unix.
- Copyright (C) 1995-2012 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for 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 <ctype.h>
-#include <unistd.h>
-
-extern void __libc_init (int, char **, char **);
-#ifdef USE_NONOPTION_FLAGS
-extern void __getopt_clean_environment (char **);
-#endif
-extern void __libc_global_ctors (void);
-
-int __libc_multiple_libcs attribute_hidden = 1;
-
-static void
-init (int *data)
-{
- int argc = *data;
- char **argv = (void *) (data + 1);
- char **envp = &argv[argc + 1];
-
- __environ = envp;
- __libc_init (argc, argv, envp);
-
-#ifdef USE_NONOPTION_FLAGS
- /* This is a hack to make the special getopt in GNU libc working. */
- __getopt_clean_environment (envp);
-#endif
-
- /* Initialize ctype data. */
- __ctype_init ();
-}
-
-#ifdef SHARED
-/* This function is called to initialize the shared C library.
- It is called just before the user _start code from i386/start.S,
- with the stack set up as that code gets it. */
-
-/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
- pointer in the dynamic section based solely on that. It is convention
- for this function to be in the `.init' section, but the symbol name is
- the only thing that really matters!! */
-/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/
-
-void
-_init (int argc, ...)
-{
- init (&argc);
-
-#ifndef NO_CTORS_DTORS_SECTIONS
- __libc_global_ctors ();
-#endif
-}
-#endif
-
-
-void
-__libc_init_first (int argc __attribute__ ((unused)), ...)
-{
-#ifndef SHARED
- init (&argc);
-#endif
-}
diff --git a/libc/sysdeps/ieee754/dbl-64/s_fma.c b/libc/sysdeps/ieee754/dbl-64/s_fma.c
index ce3bd36fa..5e21461a4 100644
--- a/libc/sysdeps/ieee754/dbl-64/s_fma.c
+++ b/libc/sysdeps/ieee754/dbl-64/s_fma.c
@@ -49,6 +49,11 @@ __fma (double x, double y, double z)
&& u.ieee.exponent != 0x7ff
&& v.ieee.exponent != 0x7ff)
return (z + x) + y;
+ /* If z is zero and x are y are nonzero, compute the result
+ as x * y to avoid the wrong sign of a zero result if x * y
+ underflows to 0. */
+ if (z == 0 && x != 0 && y != 0)
+ return x * y;
/* If x or y or z is Inf/NaN, or if fma will certainly overflow,
or if x * y is less than half of DBL_DENORM_MIN,
compute as x * y + z. */
@@ -128,6 +133,11 @@ __fma (double x, double y, double z)
y = v.d;
z = w.d;
}
+
+ /* Ensure correct sign of exact 0 + 0. */
+ if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+ return x * y + z;
+
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
#define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
double x1 = x * C;
diff --git a/libc/sysdeps/ieee754/dbl-64/s_fmaf.c b/libc/sysdeps/ieee754/dbl-64/s_fmaf.c
index e7a0650f0..a4f12d9f7 100644
--- a/libc/sysdeps/ieee754/dbl-64/s_fmaf.c
+++ b/libc/sysdeps/ieee754/dbl-64/s_fmaf.c
@@ -32,8 +32,15 @@ float
__fmaf (float x, float y, float z)
{
fenv_t env;
+
/* Multiplication is always exact. */
double temp = (double) x * (double) y;
+
+ /* Ensure correct sign of an exact zero result by performing the
+ addition in the original rounding mode in that case. */
+ if (temp == -z)
+ return (float) temp + z;
+
union ieee754_double u;
libc_feholdexcept_setround (&env, FE_TOWARDZERO);
diff --git a/libc/sysdeps/ieee754/dbl-64/x2y2m1.c b/libc/sysdeps/ieee754/dbl-64/x2y2m1.c
new file mode 100644
index 000000000..4badde3be
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/x2y2m1.c
@@ -0,0 +1,111 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 <math.h>
+#include <math_private.h>
+#include <float.h>
+#include <stdlib.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO. It is
+ given that |X| >= |Y| and the values are small enough that no
+ overflow occurs. */
+
+static inline void
+add_split (double *hi, double *lo, double x, double y)
+{
+ /* Apply Dekker's algorithm. */
+ *hi = x + y;
+ *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO. It is
+ given that the values are small enough that no overflow occurs and
+ large enough (or zero) that no underflow occurs. */
+
+static inline void
+mul_split (double *hi, double *lo, double x, double y)
+{
+#ifdef __FP_FAST_FMA
+ /* Fast built-in fused multiply-add. */
+ *hi = x * y;
+ *lo = __builtin_fma (x, y, -*hi);
+#elif defined FP_FAST_FMA
+ /* Fast library fused multiply-add, compiler before GCC 4.6. */
+ *hi = x * y;
+ *lo = __fma (x, y, -*hi);
+#else
+ /* Apply Dekker's algorithm. */
+ *hi = x * y;
+# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
+ double x1 = x * C;
+ double y1 = y * C;
+# undef C
+ x1 = (x - x1) + x1;
+ y1 = (y - y1) + y1;
+ double x2 = x - x1;
+ double y2 = y - y1;
+ *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+ and Q for qsort. */
+
+static int
+compare (const void *p, const void *q)
+{
+ double pd = fabs (*(const double *) p);
+ double qd = fabs (*(const double *) q);
+ if (pd < qd)
+ return -1;
+ else if (pd == qd)
+ return 0;
+ else
+ return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+ It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+ 0.75 or Y >= 0.5. */
+
+double
+__x2y2m1 (double x, double y)
+{
+ double vals[4];
+ SET_RESTORE_ROUND (FE_TONEAREST);
+ mul_split (&vals[1], &vals[0], x, x);
+ mul_split (&vals[3], &vals[2], y, y);
+ if (x >= 0.75)
+ vals[1] -= 1.0;
+ else
+ {
+ vals[1] -= 0.5;
+ vals[3] -= 0.5;
+ }
+ qsort (vals, 4, sizeof (double), compare);
+ /* Add up the values so that each element of VALS has absolute value
+ at most equal to the last set bit of the next nonzero
+ element. */
+ for (size_t i = 0; i <= 2; i++)
+ {
+ add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+ qsort (vals + i + 1, 3 - i, sizeof (double), compare);
+ }
+ /* Now any error from this addition will be small. */
+ return vals[3] + vals[2] + vals[1] + vals[0];
+}
diff --git a/libc/string/bug-strcasestr1.c b/libc/sysdeps/ieee754/dbl-64/x2y2m1f.c
index e8334d709..fcaa70851 100644
--- a/libc/string/bug-strcasestr1.c
+++ b/libc/sysdeps/ieee754/dbl-64/x2y2m1f.c
@@ -1,4 +1,4 @@
-/* Test for non-submitted strcasestr bug.
+/* Compute x^2 + y^2 - 1, without large cancellation error.
Copyright (C) 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,24 +16,17 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <stdio.h>
-#include <string.h>
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
-#define TEST_FUNCTION do_test ()
-static int
-do_test (void)
-{
- const char haystack[] = "AOKB";
- const char needle[] = "OK";
- const char *sub = strcasestr (haystack, needle);
-
- if (sub == NULL)
- {
- fprintf (stderr, "BUG: didn't find \"%s\" in \"%s\"\n", needle, haystack);
- return 1;
- }
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+ It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+ 0.75 or Y >= 0.5. */
- return 0;
+float
+__x2y2m1f (float x, float y)
+{
+ double dx = x, dy = y;
+ return (float) ((dx - 1) * (dx + 1) + dy * dy);
}
-
-#include "../test-skeleton.c"
diff --git a/libc/sysdeps/ieee754/flt-32/s_sincosf.c b/libc/sysdeps/ieee754/flt-32/s_sincosf.c
index 1b4d000e1..c3bd998ab 100644
--- a/libc/sysdeps/ieee754/flt-32/s_sincosf.c
+++ b/libc/sysdeps/ieee754/flt-32/s_sincosf.c
@@ -21,9 +21,14 @@
#include <math_private.h>
+#ifndef SINCOSF
+# define SINCOSF_FUNC __sincosf
+#else
+# define SINCOSF_FUNC SINCOSF
+#endif
void
-__sincosf (float x, float *sinx, float *cosx)
+SINCOSF_FUNC (float x, float *sinx, float *cosx)
{
int32_t ix;
@@ -70,4 +75,7 @@ __sincosf (float x, float *sinx, float *cosx)
}
}
}
+
+#ifndef SINCOSF
weak_alias (__sincosf, sincosf)
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h b/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h
deleted file mode 100644
index 89b207331..000000000
--- a/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* `HUGE_VALL' constant for IEEE 754 machines (where it is infinity).
- Used by <stdlib.h> and <math.h> functions for overflow.
- Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for 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 _MATH_H
-# error "Never use <bits/huge_vall.h> directly; include <math.h> instead."
-#endif
-
-/* IEEE positive infinity (-HUGE_VAL is negative infinity). */
-
-#if __GNUC_PREREQ(3,3)
-# define HUGE_VALL (__builtin_huge_vall())
-#elif __GNUC_PREREQ(2,96)
-# define HUGE_VALL (__extension__ 0x1.0p32767L)
-#else
-# include <endian.h>
-
-typedef union { unsigned char __c[16]; long double __ld; } __huge_vall_t;
-
-# if __BYTE_ORDER == __BIG_ENDIAN
-# define __HUGE_VALL_bytes { 0x7f, 0xff, 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
-# endif
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define __HUGE_VALL_bytes { 0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0xff, 0x7f }
-# endif
-
-# ifdef __GNUC__
-# define HUGE_VALL (__extension__ \
- ((__huge_vall_t) { __c : __HUGE_VALL_bytes }).__ld)
-# else
-static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
-# define HUGE_VALL (__huge_vall.__ld)
-# endif
-#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_fma.c b/libc/sysdeps/ieee754/ldbl-128/s_fma.c
index 355b60ebb..b08ff29c0 100644
--- a/libc/sysdeps/ieee754/ldbl-128/s_fma.c
+++ b/libc/sysdeps/ieee754/ldbl-128/s_fma.c
@@ -1,5 +1,5 @@
/* Compute x * y + z as ternary operation.
- Copyright (C) 2010 Free Software Foundation, Inc.
+ Copyright (C) 2010-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
@@ -33,6 +33,12 @@ __fma (double x, double y, double z)
fenv_t env;
/* Multiplication is always exact. */
long double temp = (long double) x * (long double) y;
+
+ /* Ensure correct sign of an exact zero result by performing the
+ addition in the original rounding mode in that case. */
+ if (temp == -z)
+ return (double) temp + z;
+
union ieee854_long_double u;
feholdexcept (&env);
fesetround (FE_TOWARDZERO);
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_fmal.c b/libc/sysdeps/ieee754/ldbl-128/s_fmal.c
index 963bbd734..46b3d81ce 100644
--- a/libc/sysdeps/ieee754/ldbl-128/s_fmal.c
+++ b/libc/sysdeps/ieee754/ldbl-128/s_fmal.c
@@ -50,6 +50,11 @@ __fmal (long double x, long double y, long double z)
&& u.ieee.exponent != 0x7fff
&& v.ieee.exponent != 0x7fff)
return (z + x) + y;
+ /* If z is zero and x are y are nonzero, compute the result
+ as x * y to avoid the wrong sign of a zero result if x * y
+ underflows to 0. */
+ if (z == 0 && x != 0 && y != 0)
+ return x * y;
/* If x or y or z is Inf/NaN, or if fma will certainly overflow,
or if x * y is less than half of LDBL_DENORM_MIN,
compute as x * y + z. */
@@ -129,6 +134,11 @@ __fmal (long double x, long double y, long double z)
y = v.d;
z = w.d;
}
+
+ /* Ensure correct sign of exact 0 + 0. */
+ if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+ return x * y + z;
+
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
#define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
long double x1 = x * C;
diff --git a/libc/sysdeps/ieee754/ldbl-128/x2y2m1l.c b/libc/sysdeps/ieee754/ldbl-128/x2y2m1l.c
new file mode 100644
index 000000000..a249cd347
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/x2y2m1l.c
@@ -0,0 +1,111 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 <math.h>
+#include <math_private.h>
+#include <float.h>
+#include <stdlib.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO. It is
+ given that |X| >= |Y| and the values are small enough that no
+ overflow occurs. */
+
+static inline void
+add_split (long double *hi, long double *lo, long double x, long double y)
+{
+ /* Apply Dekker's algorithm. */
+ *hi = x + y;
+ *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO. It is
+ given that the values are small enough that no overflow occurs and
+ large enough (or zero) that no underflow occurs. */
+
+static inline void
+mul_split (long double *hi, long double *lo, long double x, long double y)
+{
+#ifdef __FP_FAST_FMAL
+ /* Fast built-in fused multiply-add. */
+ *hi = x * y;
+ *lo = __builtin_fmal (x, y, -*hi);
+#elif defined FP_FAST_FMAL
+ /* Fast library fused multiply-add, compiler before GCC 4.6. */
+ *hi = x * y;
+ *lo = __fmal (x, y, -*hi);
+#else
+ /* Apply Dekker's algorithm. */
+ *hi = x * y;
+# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
+ long double x1 = x * C;
+ long double y1 = y * C;
+# undef C
+ x1 = (x - x1) + x1;
+ y1 = (y - y1) + y1;
+ long double x2 = x - x1;
+ long double y2 = y - y1;
+ *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+ and Q for qsort. */
+
+static int
+compare (const void *p, const void *q)
+{
+ long double pld = fabsl (*(const long double *) p);
+ long double qld = fabsl (*(const long double *) q);
+ if (pld < qld)
+ return -1;
+ else if (pld == qld)
+ return 0;
+ else
+ return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+ It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+ 0.75 or Y >= 0.5. */
+
+long double
+__x2y2m1l (long double x, long double y)
+{
+ long double vals[4];
+ SET_RESTORE_ROUNDL (FE_TONEAREST);
+ mul_split (&vals[1], &vals[0], x, x);
+ mul_split (&vals[3], &vals[2], y, y);
+ if (x >= 0.75L)
+ vals[1] -= 1.0L;
+ else
+ {
+ vals[1] -= 0.5L;
+ vals[3] -= 0.5L;
+ }
+ qsort (vals, 4, sizeof (long double), compare);
+ /* Add up the values so that each element of VALS has absolute value
+ at most equal to the last set bit of the next nonzero
+ element. */
+ for (size_t i = 0; i <= 2; i++)
+ {
+ add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+ qsort (vals + i + 1, 3 - i, sizeof (long double), compare);
+ }
+ /* Now any error from this addition will be small. */
+ return vals[3] + vals[2] + vals[1] + vals[0];
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c b/libc/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c
new file mode 100644
index 000000000..4379b68c3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c
@@ -0,0 +1,128 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 <math.h>
+#include <math_private.h>
+#include <float.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO. It is
+ given that |X| >= |Y| and the values are small enough that no
+ overflow occurs. */
+
+static inline void
+add_split (double *hi, double *lo, double x, double y)
+{
+ /* Apply Dekker's algorithm. */
+ *hi = x + y;
+ *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO. It is
+ given that the values are small enough that no overflow occurs and
+ large enough (or zero) that no underflow occurs. */
+
+static inline void
+mul_split (double *hi, double *lo, double x, double y)
+{
+#ifdef __FP_FAST_FMA
+ /* Fast built-in fused multiply-add. */
+ *hi = x * y;
+ *lo = __builtin_fma (x, y, -*hi);
+#elif defined FP_FAST_FMA
+ /* Fast library fused multiply-add, compiler before GCC 4.6. */
+ *hi = x * y;
+ *lo = __fma (x, y, -*hi);
+#else
+ /* Apply Dekker's algorithm. */
+ *hi = x * y;
+# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
+ double x1 = x * C;
+ double y1 = y * C;
+# undef C
+ x1 = (x - x1) + x1;
+ y1 = (y - y1) + y1;
+ double x2 = x - x1;
+ double y2 = y - y1;
+ *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+ and Q for qsort. */
+
+static int
+compare (const void *p, const void *q)
+{
+ double pd = fabs (*(const double *) p);
+ double qd = fabs (*(const double *) q);
+ if (pd < qd)
+ return -1;
+ else if (pd == qd)
+ return 0;
+ else
+ return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+ It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+ 0.75 or Y >= 0.5. */
+
+long double
+__x2y2m1l (long double x, long double y)
+{
+ double vals[12];
+ SET_RESTORE_ROUND (FE_TONEAREST);
+ union ibm_extended_long_double xu, yu;
+ xu.d = x;
+ yu.d = y;
+ if (fabs (xu.dd[1]) < 0x1p-500)
+ xu.dd[1] = 0.0;
+ if (fabs (yu.dd[1]) < 0x1p-500)
+ yu.dd[1] = 0.0;
+ mul_split (&vals[1], &vals[0], xu.dd[0], xu.dd[0]);
+ mul_split (&vals[3], &vals[2], xu.dd[0], xu.dd[1]);
+ vals[2] *= 2.0;
+ vals[3] *= 2.0;
+ mul_split (&vals[5], &vals[4], xu.dd[1], xu.dd[1]);
+ mul_split (&vals[7], &vals[6], yu.dd[0], yu.dd[0]);
+ mul_split (&vals[9], &vals[8], yu.dd[0], yu.dd[1]);
+ vals[8] *= 2.0;
+ vals[9] *= 2.0;
+ mul_split (&vals[11], &vals[10], yu.dd[1], yu.dd[1]);
+ if (xu.dd[0] >= 0.75)
+ vals[1] -= 1.0;
+ else
+ {
+ vals[1] -= 0.5;
+ vals[7] -= 0.5;
+ }
+ qsort (vals, 12, sizeof (double), compare);
+ /* Add up the values so that each element of VALS has absolute value
+ at most equal to the last set bit of the next nonzero
+ element. */
+ for (size_t i = 0; i <= 10; i++)
+ {
+ add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+ qsort (vals + i + 1, 11 - i, sizeof (double), compare);
+ }
+ /* Now any error from this addition will be small. */
+ long double retval = (long double) vals[11];
+ for (size_t i = 10; i != (size_t) -1; i--)
+ retval += (long double) vals[i];
+ return retval;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_fma.c b/libc/sysdeps/ieee754/ldbl-96/s_fma.c
index 78c0b0db1..001d8063d 100644
--- a/libc/sysdeps/ieee754/ldbl-96/s_fma.c
+++ b/libc/sysdeps/ieee754/ldbl-96/s_fma.c
@@ -1,5 +1,5 @@
/* Compute x * y + z as ternary operation.
- Copyright (C) 2010 Free Software Foundation, Inc.
+ Copyright (C) 2010-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
@@ -38,6 +38,10 @@ __fma (double x, double y, double z)
return (x * y) + z;
}
+ /* Ensure correct sign of exact 0 + 0. */
+ if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+ return x * y + z;
+
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
#define C ((1ULL << (LDBL_MANT_DIG + 1) / 2) + 1)
long double x1 = (long double) x * C;
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_fmal.c b/libc/sysdeps/ieee754/ldbl-96/s_fmal.c
index ca1e0905a..d12512428 100644
--- a/libc/sysdeps/ieee754/ldbl-96/s_fmal.c
+++ b/libc/sysdeps/ieee754/ldbl-96/s_fmal.c
@@ -50,6 +50,11 @@ __fmal (long double x, long double y, long double z)
&& u.ieee.exponent != 0x7fff
&& v.ieee.exponent != 0x7fff)
return (z + x) + y;
+ /* If z is zero and x are y are nonzero, compute the result
+ as x * y to avoid the wrong sign of a zero result if x * y
+ underflows to 0. */
+ if (z == 0 && x != 0 && y != 0)
+ return x * y;
/* If x or y or z is Inf/NaN, or if fma will certainly overflow,
or if x * y is less than half of LDBL_DENORM_MIN,
compute as x * y + z. */
@@ -129,6 +134,11 @@ __fmal (long double x, long double y, long double z)
y = v.d;
z = w.d;
}
+
+ /* Ensure correct sign of exact 0 + 0. */
+ if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+ return x * y + z;
+
/* Multiplication m1 + m2 = x * y using Dekker's algorithm. */
#define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
long double x1 = x * C;
diff --git a/libc/sysdeps/ieee754/ldbl-96/x2y2m1.c b/libc/sysdeps/ieee754/ldbl-96/x2y2m1.c
new file mode 100644
index 000000000..3086fa2c8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/x2y2m1.c
@@ -0,0 +1,39 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 <math.h>
+#include <math_private.h>
+#include <float.h>
+
+#if FLT_EVAL_METHOD == 0
+
+# include <sysdeps/ieee754/dbl-64/x2y2m1.c>
+
+#else
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+ It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+ 0.75 or Y >= 0.5. */
+
+double
+__x2y2m1 (double x, double y)
+{
+ return (double) __x2y2m1l (x, y);
+}
+
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-96/x2y2m1l.c b/libc/sysdeps/ieee754/ldbl-96/x2y2m1l.c
new file mode 100644
index 000000000..a249cd347
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/x2y2m1l.c
@@ -0,0 +1,111 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 <math.h>
+#include <math_private.h>
+#include <float.h>
+#include <stdlib.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO. It is
+ given that |X| >= |Y| and the values are small enough that no
+ overflow occurs. */
+
+static inline void
+add_split (long double *hi, long double *lo, long double x, long double y)
+{
+ /* Apply Dekker's algorithm. */
+ *hi = x + y;
+ *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO. It is
+ given that the values are small enough that no overflow occurs and
+ large enough (or zero) that no underflow occurs. */
+
+static inline void
+mul_split (long double *hi, long double *lo, long double x, long double y)
+{
+#ifdef __FP_FAST_FMAL
+ /* Fast built-in fused multiply-add. */
+ *hi = x * y;
+ *lo = __builtin_fmal (x, y, -*hi);
+#elif defined FP_FAST_FMAL
+ /* Fast library fused multiply-add, compiler before GCC 4.6. */
+ *hi = x * y;
+ *lo = __fmal (x, y, -*hi);
+#else
+ /* Apply Dekker's algorithm. */
+ *hi = x * y;
+# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
+ long double x1 = x * C;
+ long double y1 = y * C;
+# undef C
+ x1 = (x - x1) + x1;
+ y1 = (y - y1) + y1;
+ long double x2 = x - x1;
+ long double y2 = y - y1;
+ *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+ and Q for qsort. */
+
+static int
+compare (const void *p, const void *q)
+{
+ long double pld = fabsl (*(const long double *) p);
+ long double qld = fabsl (*(const long double *) q);
+ if (pld < qld)
+ return -1;
+ else if (pld == qld)
+ return 0;
+ else
+ return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+ It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+ 0.75 or Y >= 0.5. */
+
+long double
+__x2y2m1l (long double x, long double y)
+{
+ long double vals[4];
+ SET_RESTORE_ROUNDL (FE_TONEAREST);
+ mul_split (&vals[1], &vals[0], x, x);
+ mul_split (&vals[3], &vals[2], y, y);
+ if (x >= 0.75L)
+ vals[1] -= 1.0L;
+ else
+ {
+ vals[1] -= 0.5L;
+ vals[3] -= 0.5L;
+ }
+ qsort (vals, 4, sizeof (long double), compare);
+ /* Add up the values so that each element of VALS has absolute value
+ at most equal to the last set bit of the next nonzero
+ element. */
+ for (size_t i = 0; i <= 2; i++)
+ {
+ add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+ qsort (vals + i + 1, 3 - i, sizeof (long double), compare);
+ }
+ /* Now any error from this addition will be small. */
+ return vals[3] + vals[2] + vals[1] + vals[0];
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/configure b/libc/sysdeps/ieee754/ldbl-opt/configure
index d1f3177cf..6e69038b9 100755
--- a/libc/sysdeps/ieee754/ldbl-opt/configure
+++ b/libc/sysdeps/ieee754/ldbl-opt/configure
@@ -1,123 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/ieee754/ldbl-opt/.
diff --git a/libc/sysdeps/mach/configure b/libc/sysdeps/mach/configure
index b41449e80..33cf09bd7 100644
--- a/libc/sysdeps/mach/configure
+++ b/libc/sysdeps/mach/configure
@@ -1,102 +1,4 @@
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# ac_fn_c_try_cpp LINENO
# ----------------------
@@ -288,45 +190,7 @@ $as_echo_n "checking for task_t in mach/mach_types.h... " >&6; }
if ${libc_cv_mach_task_t+:} false; then :
$as_echo_n "(cached) " >&6
else
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <mach/mach_types.h>
int
diff --git a/libc/sysdeps/mach/hurd/_G_config.h b/libc/sysdeps/mach/hurd/_G_config.h
deleted file mode 100644
index b3a7db72a..000000000
--- a/libc/sysdeps/mach/hurd/_G_config.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This file is needed by libio to define various configuration parameters.
- These are always the same in the GNU C library. */
-
-#ifndef _G_config_h
-#define _G_config_h 1
-
-/* Define types for libio in terms of the standard internal type names. */
-
-#include <bits/types.h>
-#define __need_size_t
-#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-# define __need_wchar_t
-#endif
-#define __need_NULL
-#include <stddef.h>
-#define __need_mbstate_t
-#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-# define __need_wint_t
-#endif
-#include <wchar.h>
-typedef struct
-{
- __off_t __pos;
- __mbstate_t __state;
-} _G_fpos_t;
-typedef struct
-{
- __off64_t __pos;
- __mbstate_t __state;
-} _G_fpos64_t;
-#define _G_off64_t __off64_t
-#define _G_stat64 stat64
-#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-# include <gconv.h>
-typedef union
-{
- struct __gconv_info __cd;
- struct
- {
- struct __gconv_info __cd;
- struct __gconv_step_data __data;
- } __combined;
-} _G_iconv_t;
-#endif
-
-
-/* These library features are always available in the GNU C library. */
-#define _G_va_list __gnuc_va_list
-
-#define _G_HAVE_MMAP 1
-
-#define _G_IO_IO_FILE_VERSION 0x20001
-
-#define _G_OPEN64 __open64
-#define _G_LSEEK64 __lseek64
-#define _G_MMAP64 __mmap64
-#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf)
-
-/* This is defined by <bits/stat.h> if `st_blksize' exists. */
-#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE)
-
-#define _G_BUFSIZ 8192
-
-#endif /* _G_config.h */
diff --git a/libc/sysdeps/mach/hurd/bits/typesizes.h b/libc/sysdeps/mach/hurd/bits/typesizes.h
index efc13143e..af132669f 100644
--- a/libc/sysdeps/mach/hurd/bits/typesizes.h
+++ b/libc/sysdeps/mach/hurd/bits/typesizes.h
@@ -51,7 +51,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE __S32_TYPE
diff --git a/libc/sysdeps/mach/hurd/configure b/libc/sysdeps/mach/hurd/configure
index 3c90a665a..84948a549 100755
--- a/libc/sysdeps/mach/hurd/configure
+++ b/libc/sysdeps/mach/hurd/configure
@@ -1,128 +1,5 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
-# GNU libc on the Hurd is always reentrant.
-DEFINES="$DEFINES -D_LIBC_REENTRANT"
-
$as_echo "#define NO_HIDDEN 1" >>confdefs.h
diff --git a/libc/sysdeps/mach/hurd/dl-sysdep.c b/libc/sysdeps/mach/hurd/dl-sysdep.c
index 13b001043..fad388b73 100644
--- a/libc/sysdeps/mach/hurd/dl-sysdep.c
+++ b/libc/sysdeps/mach/hurd/dl-sysdep.c
@@ -646,26 +646,6 @@ _dl_show_auxv (void)
}
-/* Return an array of useful/necessary hardware capability names. */
-const struct r_strlenpair *
-internal_function
-_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
- size_t *max_capstrlen)
-{
- struct r_strlenpair *result;
-
- /* Return an empty array. Hurd has no hardware capabilities. */
- result = (struct r_strlenpair *) malloc (sizeof (*result));
- if (result == NULL)
- _dl_signal_error (ENOMEM, NULL, NULL, "cannot create capability list");
-
- result[0].str = (char *) result; /* Does not really matter. */
- result[0].len = 0;
-
- *sz = 1;
- return result;
-}
-
void weak_function
_dl_init_first (int argc, ...)
{
diff --git a/libc/sysdeps/mach/hurd/malloc-machine.h b/libc/sysdeps/mach/hurd/malloc-machine.h
index 4a8bd16e6..16e054fe5 100644
--- a/libc/sysdeps/mach/hurd/malloc-machine.h
+++ b/libc/sysdeps/mach/hurd/malloc-machine.h
@@ -66,8 +66,9 @@ __libc_tsd_define (static, void *, MALLOC) /* declaration/common definition */
#include <sys/mman.h>
-#undef madvise
-#define madvise(addr, len, advice) ((void) (addr), (void) (len), (void) (advice))
+#undef __madvise
+#define __madvise(addr, len, advice) \
+ ((void) (addr), (void) (len), (void) (advice))
#include <sysdeps/generic/malloc-machine.h>
diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c
index 05883bd55..672571ef2 100644
--- a/libc/sysdeps/posix/getaddrinfo.c
+++ b/libc/sysdeps/posix/getaddrinfo.c
@@ -1369,10 +1369,6 @@ static const struct scopeentry
/* Link-local addresses: scope 2. */
{ { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
{ { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
- /* Site-local addresses: scope 5. */
- { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
- { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
- { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
/* Default: scope 14. */
{ { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
};
diff --git a/libc/sysdeps/posix/sleep.c b/libc/sysdeps/posix/sleep.c
index dfd7420ac..b3c9e27f1 100644
--- a/libc/sysdeps/posix/sleep.c
+++ b/libc/sysdeps/posix/sleep.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Sleep for a given number of seconds. POSIX.1 version.
+ Copyright (C) 1991-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -15,20 +16,12 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
+#include <sys/param.h>
-/* SIGALRM signal handler for `sleep'. This does nothing but return,
- but SIG_IGN isn't supposed to break `pause'. */
-static void
-sleep_handler (int sig)
-{
- return;
-}
-
/* Make the process sleep for SECONDS seconds, or until a signal arrives
and is not ignored. The function returns the number of seconds less
than SECONDS which it actually slept (zero if it slept the full time).
@@ -39,67 +32,44 @@ sleep_handler (int sig)
unsigned int
__sleep (unsigned int seconds)
{
- unsigned int remaining, slept;
- time_t before, after;
- sigset_t set, oset;
- struct sigaction act, oact;
- int save = errno;
-
- if (seconds == 0)
- return 0;
-
- /* Block SIGALRM signals while frobbing the handler. */
- if (sigemptyset (&set) < 0 ||
- sigaddset (&set, SIGALRM) < 0 ||
- sigprocmask (SIG_BLOCK, &set, &oset))
- return seconds;
-
- act.sa_handler = sleep_handler;
- act.sa_flags = 0;
- act.sa_mask = oset; /* execute handler with original mask */
- if (sigaction (SIGALRM, &act, &oact) < 0)
- return seconds;
-
- before = time ((time_t *) NULL);
- remaining = alarm (seconds);
-
- if (remaining > 0 && remaining < seconds)
+ /* This is not necessary but some buggy programs depend on it. */
+ if (__builtin_expect (seconds == 0, 0))
{
- /* The user's alarm will expire before our own would.
- Restore the user's signal action state and let his alarm happen. */
- (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL);
- alarm (remaining); /* Restore sooner alarm. */
- sigsuspend (&oset); /* Wait for it to go off. */
- after = time ((time_t *) NULL);
+#ifdef CANCELLATION_P
+ CANCELLATION_P (THREAD_SELF);
+#endif
+ return 0;
}
- else
- {
- /* Atomically restore the old signal mask
- (which had better not block SIGALRM),
- and wait for a signal to arrive. */
- sigsuspend (&oset);
- after = time ((time_t *) NULL);
+ int save_errno = errno;
- /* Restore the old signal action state. */
- (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL);
+ const unsigned int max
+ = (unsigned int) (((unsigned long int) (~((time_t) 0))) >> 1);
+ struct timespec ts = { 0, 0 };
+ do
+ {
+ if (sizeof (ts.tv_sec) <= sizeof (seconds))
+ {
+ /* Since SECONDS is unsigned assigning the value to .tv_sec can
+ overflow it. In this case we have to wait in steps. */
+ ts.tv_sec += MIN (seconds, max);
+ seconds -= (unsigned int) ts.tv_sec;
+ }
+ else
+ {
+ ts.tv_sec = (time_t) seconds;
+ seconds = 0;
+ }
+
+ if (__nanosleep (&ts, &ts) < 0)
+ /* We were interrupted.
+ Return the number of (whole) seconds we have not yet slept. */
+ return seconds + ts.tv_sec;
}
+ while (seconds > 0);
- /* Notice how long we actually slept. */
- slept = after - before;
-
- /* Restore the user's alarm if we have not already past it.
- If we have, be sure to turn off the alarm in case a signal
- other than SIGALRM was what woke us up. */
- (void) alarm (remaining > slept ? remaining - slept : 0);
-
- /* Restore the original signal mask. */
- (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
-
- /* Restore the `errno' value we started with.
- Some of the calls we made might have failed, but we didn't care. */
- __set_errno (save);
+ __set_errno (save_errno);
- return slept > seconds ? 0 : seconds - slept;
+ return 0;
}
weak_alias (__sleep, sleep)
diff --git a/libc/sysdeps/posix/sysconf.c b/libc/sysdeps/posix/sysconf.c
index d9b3c83ab..bfe28b47e 100644
--- a/libc/sysdeps/posix/sysconf.c
+++ b/libc/sysdeps/posix/sysconf.c
@@ -1227,6 +1227,7 @@ __sysconf (name)
case _SC_LEVEL3_CACHE_LINESIZE:
case _SC_LEVEL4_CACHE_SIZE:
case _SC_LEVEL4_CACHE_ASSOC:
+ case _SC_LEVEL4_CACHE_LINESIZE:
/* In general we cannot determine these values. Therefore we
return zero which indicates that no information is
available. */
diff --git a/libc/sysdeps/powerpc/configure b/libc/sysdeps/powerpc/configure
index c3ad67f01..4afbc29ab 100755
--- a/libc/sysdeps/powerpc/configure
+++ b/libc/sysdeps/powerpc/configure
@@ -1,85 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/powerpc.
diff --git a/libc/sysdeps/powerpc/powerpc32/configure b/libc/sysdeps/powerpc/powerpc32/configure
index 86ecfdcf4..31c571d9a 100644
--- a/libc/sysdeps/powerpc/powerpc32/configure
+++ b/libc/sysdeps/powerpc/powerpc32/configure
@@ -1,85 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/powerpc/powerpc32.
diff --git a/libc/sysdeps/powerpc/powerpc64/configure b/libc/sysdeps/powerpc/powerpc64/configure
index 7cff76141..5ddac5592 100644
--- a/libc/sysdeps/powerpc/powerpc64/configure
+++ b/libc/sysdeps/powerpc/powerpc64/configure
@@ -1,85 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/powerpc/powerpc64.
diff --git a/libc/sysdeps/powerpc/sys/platform/ppc.h b/libc/sysdeps/powerpc/sys/platform/ppc.h
index 165652c7c..3780f57ba 100644
--- a/libc/sysdeps/powerpc/sys/platform/ppc.h
+++ b/libc/sysdeps/powerpc/sys/platform/ppc.h
@@ -20,6 +20,7 @@
#define _SYS_PLATFORM_PPC_H 1
#include <stdint.h>
+#include <bits/ppc.h>
/* Read the Time Base Register. */
static inline uint64_t
diff --git a/libc/sysdeps/pthread/aio_fsync.c b/libc/sysdeps/pthread/aio_fsync.c
index 046e25c17..5b5d1863e 100644
--- a/libc/sysdeps/pthread/aio_fsync.c
+++ b/libc/sysdeps/pthread/aio_fsync.c
@@ -46,7 +46,7 @@ aio_fsync (int op, struct aiocb *aiocbp)
flags = fcntl (aiocbp->aio_fildes, F_GETFL);
if (__builtin_expect (flags == -1, 0)
- || __builtin_expect ((flags & (O_RDWR | O_WRONLY)) == 0, 0))
+ || __builtin_expect ((flags & O_ACCMODE) == O_RDONLY, 0))
{
__set_errno (EBADF);
return -1;
diff --git a/libc/sysdeps/s390/s390-32/configure b/libc/sysdeps/s390/s390-32/configure
index e982e817f..669bb9be5 100644
--- a/libc/sysdeps/s390/s390-32/configure
+++ b/libc/sysdeps/s390/s390-32/configure
@@ -2,3 +2,4 @@
# Local configure fragment for sysdeps/s390.
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
diff --git a/libc/sysdeps/s390/s390-64/configure b/libc/sysdeps/s390/s390-64/configure
index e982e817f..669bb9be5 100644
--- a/libc/sysdeps/s390/s390-64/configure
+++ b/libc/sysdeps/s390/s390-64/configure
@@ -2,3 +2,4 @@
# Local configure fragment for sysdeps/s390.
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
diff --git a/libc/sysdeps/sh/configure b/libc/sysdeps/sh/configure
index 655668556..b0f3b2fa2 100644
--- a/libc/sysdeps/sh/configure
+++ b/libc/sysdeps/sh/configure
@@ -2,3 +2,4 @@
# Local configure fragment for sysdeps/sh.
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
diff --git a/libc/sysdeps/sh/init-first.c b/libc/sysdeps/sh/init-first.c
deleted file mode 100644
index f298724c1..000000000
--- a/libc/sysdeps/sh/init-first.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Initialization code run first thing by the ELF startup code. For SH.
- Copyright (C) 1995-2012 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for 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 <ctype.h>
-#include <unistd.h>
-
-extern void __libc_init (int, char **, char **);
-#ifdef USE_NONOPTION_FLAGS
-extern void __getopt_clean_environment (char **);
-#endif
-extern void __libc_global_ctors (void);
-
-int __libc_multiple_libcs attribute_hidden = 1;
-
-static void
-init (int *data)
-{
- int argc = *data;
- char **argv = (void *) (data + 1);
- char **envp = &argv[argc + 1];
-
- __environ = envp;
- __libc_init (argc, argv, envp);
-
-#ifdef USE_NONOPTION_FLAGS
- /* This is a hack to make the special getopt in GNU libc working. */
- __getopt_clean_environment (envp);
-#endif
-
- /* Initialize ctype data. */
- __ctype_init ();
-}
-
-#ifdef SHARED
-/* This function is called to initialize the shared C library.
- It is called just before the user _start code from sh/sh[34]/start.S,
- with the stack set up as that code gets it. */
-
-/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
- pointer in the dynamic section based solely on that. It is convention
- for this function to be in the `.init' section, but the symbol name is
- the only thing that really matters!! */
-/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/
-
-void
-_init (int argc, ...)
-{
- init (&argc);
-
-#ifndef NO_CTORS_DTORS_SECTIONS
- __libc_global_ctors ();
-#endif
-}
-#endif
-
-
-void
-__libc_init_first (int argc __attribute__ ((unused)), ...)
-{
-#ifndef SHARED
- init (&argc);
-#endif
-}
diff --git a/libc/sysdeps/sparc/configure b/libc/sysdeps/sparc/configure
index 72b4622af..3abba2750 100644
--- a/libc/sysdeps/sparc/configure
+++ b/libc/sysdeps/sparc/configure
@@ -1,85 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/sparc.
diff --git a/libc/sysdeps/sparc/fpu/libm-test-ulps b/libc/sysdeps/sparc/fpu/libm-test-ulps
index b7dc3b483..0f8179f6b 100644
--- a/libc/sysdeps/sparc/fpu/libm-test-ulps
+++ b/libc/sysdeps/sparc/fpu/libm-test-ulps
@@ -876,6 +876,9 @@ float: 1
ifloat: 1
ildouble: 1
ldouble: 1
+Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i":
+float: 1
+ifloat: 1
Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i":
float: 1
ifloat: 1
@@ -903,6 +906,9 @@ ldouble: 1
Test "Real part of: clog (0x1.fp+16383 - 0x1p-16494 i) == 11356.49165759582936919077408168801636572 - 0 i":
ildouble: 1
ldouble: 1
+Test "Imaginary part of: clog (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 3.2047474274603604594851472963586149973093e-29 + 1.4422922682185099608731642353544207976604 i":
+ildouble: 1
+ldouble: 1
Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i":
double: 1
idouble: 1
@@ -927,6 +933,50 @@ ldouble: 1
Test "Real part of: clog (0x1p-16494 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i":
ildouble: 1
ldouble: 1
+Test "Imaginary part of: clog (0x2818p-15 + 0x798fp-15 i) == 1.5366822245016167178749091974664853785194e-08 + 1.2522014929038946066987318471922169174157 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x298c62cb546588a7p-63 + 0x7911b1dfcc4ecdaep-63 i) == -1.1931267660846218205882675852805793644095e-36 + 1.2402109774337032400594953899784058127412 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x2ede88p-23 + 0x771c3fp-23 i) == -4.4764192352906350039050902870893173560494e-13 + 1.1959106857549200806818600493552847793381 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x3f96469050f650869c2p-75 + 0x6f16b2c9c8b05988335p-75 i) == -1.0509738482436128031927971874674370984602e-45 + 1.0509191467640012308402149909370784281448 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x55cb6d0c83af5p-55 + 0x7fe33c0c7c4e90p-55 i) == -5.2000108498455368032511404449795741611813e-32 + 1.5288921536982513453421343495466824420259 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 8.3076914081087805757422664530653247447136e-30 + 1.2072712126771536614482822173033535043206 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x659feap-24 + 0xeaf6f9p-24 i) == 3.7303493627403868207597214252239749960738e-14 + 1.1625816408046866464773042283673653469061 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x6771f22c64ed551b857c128b4cp-105 + 0x1f570e7a13cc3cf2f44fd793ea1p-105 i) == -1.4281333889622737316199756373421183559948e-62 + 1.3673546561165378090903506783353927980633 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 2.4244570985709679851855191080208817099132e-37 + 1.1393074519572050614551047548718495655972 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -9.7375017988218644730510244778042114638107e-30 + 0.9790637929494922564724108399524154766631 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0x9b57bp-20 + 0xcb7b4p-20 i) == -3.9563019528687610863490232935890272740908e-11 + 0.9187593477446338910857133065497364950682 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0xdb85c467ee2aadd5f425fe0f4b8dp-114 + 0x3e83162a0f95f1dcbf97dddf410eap-114 i) == 4.6017338806965821566734340588575402712716e-67 + 1.3547418904611758959096647942223384691728 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0xfd95243681c055c2632286921092p-113 + 0x1bccabcd29ca2152860ec29e34ef7p-113 i) == 6.6255694866654064502633121109394710807528e-66 + 1.0526409614996288387567810726095850312049 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 5.3718272201930019901317065495843842735179e-26 + 1.0503831592447830576186444373011142397404 i":
+ildouble: 1
+ldouble: 1
Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i":
float: 1
ifloat: 1
@@ -1046,6 +1096,16 @@ ifloat: 1
Test "Imaginary part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
Test "Real part of: clog10 (0x1.00000000000000123456789abcp0 + 0x1.23456789p-1000 i) == 4.285899851347756186652871946325962330640e-19 + 4.611541215247321502041995872887317363241e-302 i":
ildouble: 1
ldouble: 1
@@ -1103,6 +1163,37 @@ ldouble: 1
Test "Real part of: clog10 (0x1.fp+16383 + 0x1p+16383 i) == 4932.112944269463028900262609694408579449 + 0.2069271710841128115912940666587802677383 i":
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x1415bcaf2105940d49a636e98ae59p-115 + 0x7e6a150adfcd1b0921d44b31f40f4p-115 i) == 1.1288799405048268615023706955013387413519e-67 + 0.6137587762850841972073301550420510507903 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x15cfbd1990d1ffp-53 + 0x176a3973e09a9ap-53 i) == 4.4163015461643576961232672330852798804976e-31 + 0.3564851427422832755956993418877523303529 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x1df515eb171a808b9e400266p-95 + 0x7c71eb0cd4688dfe98581c77p-95 i) == -1.5221162575729652613635150540947625639689e-57 + 0.5795934880811949230121092882659698986043 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x1df515eb171a808b9e400266p-95 + 0x7c71eb0cd4688dfe98581c77p-95 i) == -1.5221162575729652613635150540947625639689e-57 + 0.5795934880811949230121092882659698986043 i":
+ildouble: 1
+ldouble: 1
Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i":
double: 1
idouble: 1
@@ -1162,6 +1253,88 @@ double: 1
float: 1
idouble: 1
ifloat: 1
+Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x3f96469050f650869c2p-75 + 0x6f16b2c9c8b05988335p-75 i) == -4.5643214291682663316715446865040356750881e-46 + 0.4564083863660793840592614609053162690362 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4d9c37e2b5cb4533p-63 + 0x65c98be2385a042ep-63 i) == 2.7822833698845776001753149807484078521508e-37 + 0.3992725998539071066769046272515417679815 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x55cb6d0c83af5p-55 + 0x7fe33c0c7c4e90p-55 i) == -2.2583360179249556400630343805573865814771e-32 + 0.6639894257763289307423302343317622430835 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x602fd5037c4792efp-64 + 0xed3e2086dcca80b8p-64 i) == -1.0146400362652473358437501879334790111898e-37 + 0.5149047982335273098246594109614460842099 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x6241ef0da53f539f02fad67dabp-106 + 0x3fb46641182f7efd9caa769dac0p-106 i) == 1.8804859395820231849002915747252695375405e-63 + 0.6404513901551516189871978418046651877394 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0xdb85c467ee2aadd5f425fe0f4b8dp-114 + 0x3e83162a0f95f1dcbf97dddf410eap-114 i) == 1.9985076315737626043096596036300177494613e-67 + 0.5883569274304683249184005177865521205198 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0xfd95243681c055c2632286921092p-113 + 0x1bccabcd29ca2152860ec29e34ef7p-113 i) == 2.8774482675253468630312378575186855052697e-66 + 0.4571561610046221605554903008571429975493 i":
+ldouble: 2
+ildouble: 2
+Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i":
double: 1
idouble: 1
@@ -3051,9 +3224,9 @@ ldouble: 1
Function: Real part of "clog10":
double: 2
-float: 1
+float: 2
idouble: 2
-ifloat: 1
+ifloat: 2
ildouble: 1
ldouble: 1
diff --git a/libc/sysdeps/sparc/sparc32/dl-machine.h b/libc/sysdeps/sparc/sparc32/dl-machine.h
index 2dfeeb27a..04ce7854a 100644
--- a/libc/sysdeps/sparc/sparc32/dl-machine.h
+++ b/libc/sysdeps/sparc/sparc32/dl-machine.h
@@ -29,11 +29,6 @@
#include <tls.h>
#include <dl-plt.h>
-#ifndef VALIDX
-# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRANUM + DT_VALTAGIDX (tag))
-#endif
-
/* Return nonzero iff ELF header is compatible with the running host. */
static inline int
elf_machine_matches_host (const Elf32_Ehdr *ehdr)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
index 4d45042a9..7358bdb16 100644
--- a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
@@ -1,4 +1,4 @@
ifeq ($(subdir),string)
sysdep_routines += memcpy-ultra3 memcpy-niagara1 memcpy-niagara2 \
- memset-niagara1
+ memset-niagara1 memcpy-niagara4 memset-niagara4
endif
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S
new file mode 100644
index 000000000..75ef9c017
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S
@@ -0,0 +1 @@
+#include <sparc64/multiarch/memcpy-niagara4.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S
new file mode 100644
index 000000000..6545019c4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S
@@ -0,0 +1 @@
+#include <sparc64/multiarch/memset-niagara4.S>
diff --git a/libc/sysdeps/sparc/sparc64/dl-machine.h b/libc/sysdeps/sparc/sparc64/dl-machine.h
index 35c24d155..dec2fa080 100644
--- a/libc/sysdeps/sparc/sparc64/dl-machine.h
+++ b/libc/sysdeps/sparc/sparc64/dl-machine.h
@@ -27,11 +27,6 @@
#include <sysdep.h>
#include <dl-plt.h>
-#ifndef VALIDX
-# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRANUM + DT_VALTAGIDX (tag))
-#endif
-
#define ELF64_R_TYPE_ID(info) ((info) & 0xff)
#define ELF64_R_TYPE_DATA(info) ((info) >> 8)
@@ -458,7 +453,14 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
break;
case R_SPARC_JMP_IREL:
value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap));
- /* Fall thru */
+ /* 'high' is always zero, for large PLT entries the linker
+ emits an R_SPARC_IRELATIVE. */
+#ifdef RESOLVE_CONFLICT_FIND_MAP
+ sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0);
+#else
+ sparc64_fixup_plt (map, reloc, reloc_addr, value, 0, 0);
+#endif
+ break;
case R_SPARC_JMP_SLOT:
#ifdef RESOLVE_CONFLICT_FIND_MAP
/* R_SPARC_JMP_SLOT conflicts against .plt[32768+]
diff --git a/libc/sysdeps/sparc/sparc64/multiarch/Makefile b/libc/sysdeps/sparc/sparc64/multiarch/Makefile
index 4d45042a9..7358bdb16 100644
--- a/libc/sysdeps/sparc/sparc64/multiarch/Makefile
+++ b/libc/sysdeps/sparc/sparc64/multiarch/Makefile
@@ -1,4 +1,4 @@
ifeq ($(subdir),string)
sysdep_routines += memcpy-ultra3 memcpy-niagara1 memcpy-niagara2 \
- memset-niagara1
+ memset-niagara1 memcpy-niagara4 memset-niagara4
endif
diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S b/libc/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S
new file mode 100644
index 000000000..3da98a87a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S
@@ -0,0 +1,332 @@
+/* Copy SIZE bytes from SRC to DEST. For SUN4V Niagara-4.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller (davem@davemloft.net)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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>
+
+#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
+
+#define FPRS_FEF 0x04
+
+/* On T4 it is very expensive to access ASRs like %fprs and
+ * %asi, avoiding a read or a write can save ~50 cycles.
+ */
+#define FPU_ENTER \
+ rd %fprs, %o5; \
+ andcc %o5, FPRS_FEF, %g0; \
+ be,a,pn %icc, 999f; \
+ wr %g0, FPRS_FEF, %fprs; \
+ 999:
+
+#define VISEntryHalf FPU_ENTER
+#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
+
+#define GLOBAL_SPARE %g5
+
+#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P
+#define EX_LD(x) x
+#define EX_ST(x) x
+#define EX_RETVAL(x) x
+#define LOAD(type,addr,dest) type [addr], dest
+#define STORE(type,src,addr) type src, [addr]
+#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI
+
+#if !defined NOT_IN_libc
+
+ .register %g2,#scratch
+ .register %g3,#scratch
+ .register %g6,#scratch
+
+ .text
+
+ENTRY(__mempcpy_niagara4)
+ ba,pt %icc, 101f
+ add %o0, %o2, %o3
+END(__mempcpy_niagara4)
+
+ .align 32
+ENTRY(__memcpy_niagara4)
+100: /* %o0=dst, %o1=src, %o2=len */
+ mov %o0, %o3
+101:
+#ifndef __arch64__
+ srl %o2, 0, %o2
+#endif
+ brz,pn %o2, .Lexit
+ cmp %o2, 3
+ ble,pn %icc, .Ltiny
+ cmp %o2, 19
+ ble,pn %icc, .Lsmall
+ or %o0, %o1, %g2
+ cmp %o2, 128
+ bl,pn %icc, .Lmedium
+ nop
+
+.Llarge:/* len >= 0x80 */
+ /* First get dest 8 byte aligned. */
+ sub %g0, %o0, %g1
+ and %g1, 0x7, %g1
+ brz,pt %g1, 51f
+ sub %o2, %g1, %o2
+
+1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2))
+ add %o1, 1, %o1
+ subcc %g1, 1, %g1
+ add %o0, 1, %o0
+ bne,pt %icc, 1b
+ EX_ST(STORE(stb, %g2, %o0 - 0x01))
+
+51: LOAD(prefetch, %o1 + 0x040, #n_reads_strong)
+ LOAD(prefetch, %o1 + 0x080, #n_reads_strong)
+ LOAD(prefetch, %o1 + 0x0c0, #n_reads_strong)
+ LOAD(prefetch, %o1 + 0x100, #n_reads_strong)
+ LOAD(prefetch, %o1 + 0x140, #n_reads_strong)
+ LOAD(prefetch, %o1 + 0x180, #n_reads_strong)
+ LOAD(prefetch, %o1 + 0x1c0, #n_reads_strong)
+ LOAD(prefetch, %o1 + 0x200, #n_reads_strong)
+
+ /* Check if we can use the straight fully aligned
+ * loop, or we require the alignaddr/faligndata variant.
+ */
+ andcc %o1, 0x7, %o5
+ bne,pn %icc, .Llarge_src_unaligned
+ sub %g0, %o0, %g1
+
+ /* Legitimize the use of initializing stores by getting dest
+ * to be 64-byte aligned.
+ */
+ and %g1, 0x3f, %g1
+ brz,pt %g1, .Llarge_aligned
+ sub %o2, %g1, %o2
+
+1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2))
+ add %o1, 8, %o1
+ subcc %g1, 8, %g1
+ add %o0, 8, %o0
+ bne,pt %icc, 1b
+ EX_ST(STORE(stx, %g2, %o0 - 0x08))
+
+.Llarge_aligned:
+ /* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */
+ andn %o2, 0x3f, %o4
+ sub %o2, %o4, %o2
+
+1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1))
+ add %o1, 0x40, %o1
+ EX_LD(LOAD(ldx, %o1 - 0x38, %g2))
+ subcc %o4, 0x40, %o4
+ EX_LD(LOAD(ldx, %o1 - 0x30, %g3))
+ EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE))
+ EX_LD(LOAD(ldx, %o1 - 0x20, %o5))
+ EX_ST(STORE_INIT(%g1, %o0))
+ add %o0, 0x08, %o0
+ EX_ST(STORE_INIT(%g2, %o0))
+ add %o0, 0x08, %o0
+ EX_LD(LOAD(ldx, %o1 - 0x18, %g2))
+ EX_ST(STORE_INIT(%g3, %o0))
+ add %o0, 0x08, %o0
+ EX_LD(LOAD(ldx, %o1 - 0x10, %g3))
+ EX_ST(STORE_INIT(GLOBAL_SPARE, %o0))
+ add %o0, 0x08, %o0
+ EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE))
+ EX_ST(STORE_INIT(%o5, %o0))
+ add %o0, 0x08, %o0
+ EX_ST(STORE_INIT(%g2, %o0))
+ add %o0, 0x08, %o0
+ EX_ST(STORE_INIT(%g3, %o0))
+ add %o0, 0x08, %o0
+ EX_ST(STORE_INIT(GLOBAL_SPARE, %o0))
+ add %o0, 0x08, %o0
+ bne,pt %icc, 1b
+ LOAD(prefetch, %o1 + 0x200, #n_reads_strong)
+
+ membar #StoreLoad | #StoreStore
+
+ brz,pn %o2, .Lexit
+ cmp %o2, 19
+ ble,pn %icc, .Lsmall_unaligned
+ nop
+ ba,a,pt %icc, .Lmedium_noprefetch
+
+.Lexit: retl
+ mov EX_RETVAL(%o3), %o0
+
+.Llarge_src_unaligned:
+ andn %o2, 0x3f, %o4
+ sub %o2, %o4, %o2
+ VISEntryHalf
+ alignaddr %o1, %g0, %g1
+ add %o1, %o4, %o1
+ EX_LD(LOAD(ldd, %g1 + 0x00, %f0))
+1: EX_LD(LOAD(ldd, %g1 + 0x08, %f2))
+ subcc %o4, 0x40, %o4
+ EX_LD(LOAD(ldd, %g1 + 0x10, %f4))
+ EX_LD(LOAD(ldd, %g1 + 0x18, %f6))
+ EX_LD(LOAD(ldd, %g1 + 0x20, %f8))
+ EX_LD(LOAD(ldd, %g1 + 0x28, %f10))
+ EX_LD(LOAD(ldd, %g1 + 0x30, %f12))
+ EX_LD(LOAD(ldd, %g1 + 0x38, %f14))
+ faligndata %f0, %f2, %f16
+ EX_LD(LOAD(ldd, %g1 + 0x40, %f0))
+ faligndata %f2, %f4, %f18
+ add %g1, 0x40, %g1
+ faligndata %f4, %f6, %f20
+ faligndata %f6, %f8, %f22
+ faligndata %f8, %f10, %f24
+ faligndata %f10, %f12, %f26
+ faligndata %f12, %f14, %f28
+ faligndata %f14, %f0, %f30
+ EX_ST(STORE(std, %f16, %o0 + 0x00))
+ EX_ST(STORE(std, %f18, %o0 + 0x08))
+ EX_ST(STORE(std, %f20, %o0 + 0x10))
+ EX_ST(STORE(std, %f22, %o0 + 0x18))
+ EX_ST(STORE(std, %f24, %o0 + 0x20))
+ EX_ST(STORE(std, %f26, %o0 + 0x28))
+ EX_ST(STORE(std, %f28, %o0 + 0x30))
+ EX_ST(STORE(std, %f30, %o0 + 0x38))
+ add %o0, 0x40, %o0
+ bne,pt %icc, 1b
+ LOAD(prefetch, %g1 + 0x200, #n_reads_strong)
+ VISExitHalf
+
+ brz,pn %o2, .Lexit
+ cmp %o2, 19
+ ble,pn %icc, .Lsmall_unaligned
+ nop
+ ba,a,pt %icc, .Lmedium_unaligned
+
+.Lmedium:
+ LOAD(prefetch, %o1 + 0x40, #n_reads_strong)
+ andcc %g2, 0x7, %g0
+ bne,pn %icc, .Lmedium_unaligned
+ nop
+.Lmedium_noprefetch:
+ andncc %o2, 0x20 - 1, %o5
+ be,pn %icc, 2f
+ sub %o2, %o5, %o2
+1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1))
+ EX_LD(LOAD(ldx, %o1 + 0x08, %g2))
+ EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE))
+ EX_LD(LOAD(ldx, %o1 + 0x18, %o4))
+ add %o1, 0x20, %o1
+ subcc %o5, 0x20, %o5
+ EX_ST(STORE(stx, %g1, %o0 + 0x00))
+ EX_ST(STORE(stx, %g2, %o0 + 0x08))
+ EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10))
+ EX_ST(STORE(stx, %o4, %o0 + 0x18))
+ bne,pt %icc, 1b
+ add %o0, 0x20, %o0
+2: andcc %o2, 0x18, %o5
+ be,pt %icc, 3f
+ sub %o2, %o5, %o2
+1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1))
+ add %o1, 0x08, %o1
+ add %o0, 0x08, %o0
+ subcc %o5, 0x08, %o5
+ bne,pt %icc, 1b
+ EX_ST(STORE(stx, %g1, %o0 - 0x08))
+3: brz,pt %o2, .Lexit
+ cmp %o2, 0x04
+ bl,pn %icc, .Ltiny
+ nop
+ EX_LD(LOAD(lduw, %o1 + 0x00, %g1))
+ add %o1, 0x04, %o1
+ add %o0, 0x04, %o0
+ subcc %o2, 0x04, %o2
+ bne,pn %icc, .Ltiny
+ EX_ST(STORE(stw, %g1, %o0 - 0x04))
+ ba,a,pt %icc, .Lexit
+.Lmedium_unaligned:
+ /* First get dest 8 byte aligned. */
+ sub %g0, %o0, %g1
+ and %g1, 0x7, %g1
+ brz,pt %g1, 2f
+ sub %o2, %g1, %o2
+
+1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2))
+ add %o1, 1, %o1
+ subcc %g1, 1, %g1
+ add %o0, 1, %o0
+ bne,pt %icc, 1b
+ EX_ST(STORE(stb, %g2, %o0 - 0x01))
+2:
+ and %o1, 0x7, %g1
+ brz,pn %g1, .Lmedium_noprefetch
+ sll %g1, 3, %g1
+ mov 64, %g2
+ sub %g2, %g1, %g2
+ andn %o1, 0x7, %o1
+ EX_LD(LOAD(ldx, %o1 + 0x00, %o4))
+ sllx %o4, %g1, %o4
+ andn %o2, 0x08 - 1, %o5
+ sub %o2, %o5, %o2
+1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3))
+ add %o1, 0x08, %o1
+ subcc %o5, 0x08, %o5
+ srlx %g3, %g2, GLOBAL_SPARE
+ or GLOBAL_SPARE, %o4, GLOBAL_SPARE
+ EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00))
+ add %o0, 0x08, %o0
+ bne,pt %icc, 1b
+ sllx %g3, %g1, %o4
+ srl %g1, 3, %g1
+ add %o1, %g1, %o1
+ brz,pn %o2, .Lexit
+ nop
+ ba,pt %icc, .Lsmall_unaligned
+
+.Ltiny:
+ EX_LD(LOAD(ldub, %o1 + 0x00, %g1))
+ subcc %o2, 1, %o2
+ be,pn %icc, .Lexit
+ EX_ST(STORE(stb, %g1, %o0 + 0x00))
+ EX_LD(LOAD(ldub, %o1 + 0x01, %g1))
+ subcc %o2, 1, %o2
+ be,pn %icc, .Lexit
+ EX_ST(STORE(stb, %g1, %o0 + 0x01))
+ EX_LD(LOAD(ldub, %o1 + 0x02, %g1))
+ ba,pt %icc, .Lexit
+ EX_ST(STORE(stb, %g1, %o0 + 0x02))
+
+.Lsmall:
+ andcc %g2, 0x3, %g0
+ bne,pn %icc, .Lsmall_unaligned
+ andn %o2, 0x4 - 1, %o5
+ sub %o2, %o5, %o2
+1:
+ EX_LD(LOAD(lduw, %o1 + 0x00, %g1))
+ add %o1, 0x04, %o1
+ subcc %o5, 0x04, %o5
+ add %o0, 0x04, %o0
+ bne,pt %icc, 1b
+ EX_ST(STORE(stw, %g1, %o0 - 0x04))
+ brz,pt %o2, .Lexit
+ nop
+ ba,a,pt %icc, .Ltiny
+
+.Lsmall_unaligned:
+1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1))
+ add %o1, 1, %o1
+ add %o0, 1, %o0
+ subcc %o2, 1, %o2
+ bne,pt %icc, 1b
+ EX_ST(STORE(stb, %g1, %o0 - 0x01))
+ ba,a,pt %icc, .Lexit
+END(__memcpy_niagara4)
+
+#endif
diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S b/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S
index 20c72d9bb..50a40883c 100644
--- a/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S
+++ b/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S
@@ -26,8 +26,19 @@ ENTRY(memcpy)
# ifdef SHARED
SETUP_PIC_REG_LEAF(o3, o5)
# endif
- andcc %o0, HWCAP_SPARC_N2, %g0
+ set HWCAP_SPARC_CRYPTO, %o1
+ andcc %o0, %o1, %g0
be 1f
+ andcc %o0, HWCAP_SPARC_N2, %g0
+# ifdef SHARED
+ sethi %gdop_hix22(__memcpy_niagara4), %o1
+ xor %o1, %gdop_lox10(__memcpy_niagara4), %o1
+# else
+ set __memcpy_niagara4, %o1
+# endif
+ ba 10f
+ nop
+1: be 1f
andcc %o0, HWCAP_SPARC_BLKINIT, %g0
# ifdef SHARED
sethi %gdop_hix22(__memcpy_niagara2), %o1
@@ -77,8 +88,19 @@ ENTRY(__mempcpy)
# ifdef SHARED
SETUP_PIC_REG_LEAF(o3, o5)
# endif
- andcc %o0, HWCAP_SPARC_N2, %g0
+ set HWCAP_SPARC_CRYPTO, %o1
+ andcc %o0, %o1, %g0
be 1f
+ andcc %o0, HWCAP_SPARC_N2, %g0
+# ifdef SHARED
+ sethi %gdop_hix22(__mempcpy_niagara4), %o1
+ xor %o1, %gdop_lox10(__mempcpy_niagara4), %o1
+# else
+ set __mempcpy_niagara4, %o1
+# endif
+ ba 10f
+ nop
+1: be 1f
andcc %o0, HWCAP_SPARC_BLKINIT, %g0
# ifdef SHARED
sethi %gdop_hix22(__mempcpy_niagara2), %o1
diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S b/libc/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S
new file mode 100644
index 000000000..c5a2f1bef
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S
@@ -0,0 +1,124 @@
+/* Set a block of memory to some byte value. For SUN4V Niagara-4.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller (davem@davemloft.net)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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>
+
+#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
+
+#if !defined NOT_IN_libc
+
+ .register %g2, #scratch
+ .register %g3, #scratch
+
+ .text
+ .align 32
+
+ENTRY(__memset_niagara4)
+ andcc %o1, 0xff, %o4
+ be,pt %icc, 1f
+ mov %o2, %o1
+ sllx %o4, 8, %g1
+ or %g1, %o4, %o2
+ sllx %o2, 16, %g1
+ or %g1, %o2, %o2
+ sllx %o2, 32, %g1
+ ba,pt %icc, 1f
+ or %g1, %o2, %o4
+END(__memset_niagara4)
+
+ .align 32
+ENTRY(__bzero_niagara4)
+ clr %o4
+1: cmp %o1, 16
+ ble %icc, .Ltiny
+ mov %o0, %o3
+ sub %g0, %o0, %g1
+ and %g1, 0x7, %g1
+ brz,pt %g1, .Laligned8
+ sub %o1, %g1, %o1
+1: stb %o4, [%o0 + 0x00]
+ subcc %g1, 1, %g1
+ bne,pt %icc, 1b
+ add %o0, 1, %o0
+.Laligned8:
+ cmp %o1, 64 + (64 - 8)
+ ble .Lmedium
+ sub %g0, %o0, %g1
+ andcc %g1, (64 - 1), %g1
+ brz,pn %g1, .Laligned64
+ sub %o1, %g1, %o1
+1: stx %o4, [%o0 + 0x00]
+ subcc %g1, 8, %g1
+ bne,pt %icc, 1b
+ add %o0, 0x8, %o0
+.Laligned64:
+ andn %o1, 64 - 1, %g1
+ sub %o1, %g1, %o1
+ brnz,pn %o4, .Lnon_bzero_loop
+ mov 0x20, %g2
+1: stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+ subcc %g1, 0x40, %g1
+ stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+ bne,pt %icc, 1b
+ add %o0, 0x40, %o0
+.Lpostloop:
+ cmp %o1, 8
+ bl,pn %icc, .Ltiny
+ membar #StoreStore|#StoreLoad
+.Lmedium:
+ andn %o1, 0x7, %g1
+ sub %o1, %g1, %o1
+1: stx %o4, [%o0 + 0x00]
+ subcc %g1, 0x8, %g1
+ bne,pt %icc, 1b
+ add %o0, 0x08, %o0
+ andcc %o1, 0x4, %g1
+ be,pt %icc, .Ltiny
+ sub %o1, %g1, %o1
+ stw %o4, [%o0 + 0x00]
+ add %o0, 0x4, %o0
+.Ltiny:
+ cmp %o1, 0
+ be,pn %icc, .Lexit
+1: subcc %o1, 1, %o1
+ stb %o4, [%o0 + 0x00]
+ bne,pt %icc, 1b
+ add %o0, 1, %o0
+.Lexit:
+ retl
+ mov %o3, %o0
+.Lnon_bzero_loop:
+ mov 0x08, %g3
+ mov 0x28, %o5
+1: stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+ subcc %g1, 0x40, %g1
+ stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P
+ add %o0, 0x10, %o0
+ stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P
+ bne,pt %icc, 1b
+ add %o0, 0x30, %o0
+ ba,a,pt %icc, .Lpostloop
+END(__bzero_niagara4)
+
+#endif
diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memset.S b/libc/sysdeps/sparc/sparc64/multiarch/memset.S
index 26cc669d6..8b3faee91 100644
--- a/libc/sysdeps/sparc/sparc64/multiarch/memset.S
+++ b/libc/sysdeps/sparc/sparc64/multiarch/memset.S
@@ -26,8 +26,19 @@ ENTRY(memset)
# ifdef SHARED
SETUP_PIC_REG_LEAF(o3, o5)
# endif
- andcc %o0, HWCAP_SPARC_BLKINIT, %g0
- be 9f
+ set HWCAP_SPARC_CRYPTO, %o1
+ andcc %o0, %o1, %g0
+ be 1f
+ andcc %o0, HWCAP_SPARC_BLKINIT, %g0
+# ifdef SHARED
+ sethi %gdop_hix22(__memset_niagara4), %o1
+ xor %o1, %gdop_lox10(__memset_niagara4), %o1
+# else
+ set __memset_niagara4, %o1
+# endif
+ ba 10f
+ nop
+1: be 9f
nop
# ifdef SHARED
sethi %gdop_hix22(__memset_niagara1), %o1
@@ -57,8 +68,19 @@ ENTRY(__bzero)
# ifdef SHARED
SETUP_PIC_REG_LEAF(o3, o5)
# endif
- andcc %o0, HWCAP_SPARC_BLKINIT, %g0
- be 9f
+ set HWCAP_SPARC_CRYPTO, %o1
+ andcc %o0, %o1, %g0
+ be 1f
+ andcc %o0, HWCAP_SPARC_BLKINIT, %g0
+# ifdef SHARED
+ sethi %gdop_hix22(__bzero_niagara4), %o1
+ xor %o1, %gdop_lox10(__bzero_niagara4), %o1
+# else
+ set __bzero_niagara4, %o1
+# endif
+ ba 10f
+ nop
+1: be 9f
nop
# ifdef SHARED
sethi %gdop_hix22(__bzero_niagara1), %o1
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h
index 67d82e6e7..0714ed02b 100644
--- a/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h
+++ b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h
@@ -51,7 +51,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __S32_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE __S32_TYPE
diff --git a/libc/sysdeps/unix/bsd/confstr.h b/libc/sysdeps/unix/bsd/confstr.h
deleted file mode 100644
index befefb652..000000000
--- a/libc/sysdeps/unix/bsd/confstr.h
+++ /dev/null
@@ -1 +0,0 @@
-#define CS_PATH "/usr/ucb:/bin:/usr/bin"
diff --git a/libc/sysdeps/unix/syscalls.list b/libc/sysdeps/unix/syscalls.list
index b38b03e19..46205825c 100644
--- a/libc/sysdeps/unix/syscalls.list
+++ b/libc/sysdeps/unix/syscalls.list
@@ -41,7 +41,7 @@ kill - kill i:ii __kill kill
link - link i:ss __link link
listen - listen i:ii __listen listen
lseek - lseek i:iii __libc_lseek __lseek lseek
-madvise - madvise i:pii madvise
+madvise - madvise i:pii __madvise madvise
mkdir - mkdir i:si __mkdir mkdir
mmap - mmap b:aniiii __mmap mmap
mprotect - mprotect i:aii __mprotect mprotect
diff --git a/libc/sysdeps/gnu/_G_config.h b/libc/sysdeps/unix/sysv/linux/_G_config.h
index 4d3ae36c4..ec2e33317 100644
--- a/libc/sysdeps/gnu/_G_config.h
+++ b/libc/sysdeps/unix/sysv/linux/_G_config.h
@@ -28,8 +28,6 @@ typedef struct
__off64_t __pos;
__mbstate_t __state;
} _G_fpos64_t;
-#define _G_off64_t __off64_t
-#define _G_stat64 stat64
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
# include <gconv.h>
typedef union
diff --git a/libc/sysdeps/unix/sysv/linux/configure b/libc/sysdeps/unix/sysv/linux/configure
index b04f7715f..76cfea1dc 100644
--- a/libc/sysdeps/unix/sysv/linux/configure
+++ b/libc/sysdeps/unix/sysv/linux/configure
@@ -1,102 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/unix/sysv/linux.
diff --git a/libc/sysdeps/unix/sysv/linux/init-first.c b/libc/sysdeps/unix/sysv/linux/init-first.c
deleted file mode 100644
index 00234e689..000000000
--- a/libc/sysdeps/unix/sysv/linux/init-first.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Initialization code run first thing by the ELF startup code. Linux version.
- Copyright (C) 1995-2004, 2005, 2007, 2011 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for 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 <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sysdep.h>
-#include <fpu_control.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <libc-internal.h>
-
-#include <ldsodefs.h>
-
-/* Set nonzero if we have to be prepared for more then one libc being
- used in the process. Safe assumption if initializer never runs. */
-int __libc_multiple_libcs attribute_hidden = 1;
-
-/* Remember the command line argument and enviroment contents for
- later calls of initializers for dynamic libraries. */
-int __libc_argc attribute_hidden;
-char **__libc_argv attribute_hidden;
-
-
-void
-__libc_init_first (int argc, char **argv, char **envp)
-{
-#ifdef SHARED
- /* For DSOs we do not need __libc_init_first but instead _init. */
-}
-
-void
-attribute_hidden
-_init (int argc, char **argv, char **envp)
-{
-#endif
-#ifdef USE_NONOPTION_FLAGS
- extern void __getopt_clean_environment (char **);
-#endif
-
- __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
-
- /* Make sure we don't initialize twice. */
- if (!__libc_multiple_libcs)
- {
- /* Set the FPU control word to the proper default value if the
- kernel would use a different value. (In a static program we
- don't have this information.) */
-#ifdef SHARED
- if (__fpu_control != GLRO(dl_fpu_control))
-#endif
- __setfpucw (__fpu_control);
- }
-
- /* Save the command-line arguments. */
- __libc_argc = argc;
- __libc_argv = argv;
- __environ = envp;
-
-#ifndef SHARED
- __libc_init_secure ();
-
- /* First the initialization which normally would be done by the
- dynamic linker. */
- _dl_non_dynamic_init ();
-#endif
-
-#ifdef VDSO_SETUP
- VDSO_SETUP ();
-#endif
-
- __init_misc (argc, argv, envp);
-
-#ifdef USE_NONOPTION_FLAGS
- /* This is a hack to make the special getopt in GNU libc working. */
- __getopt_clean_environment (envp);
-#endif
-
- /* Initialize ctype data. */
- __ctype_init ();
-
-#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
- __libc_global_ctors ();
-#endif
-}
-
-/* This function is defined here so that if this file ever gets into
- ld.so we will get a link error. Having this file silently included
- in ld.so causes disaster, because the _init definition above will
- cause ld.so to gain an init function, which is not a cool thing. */
-
-extern void _dl_start (void) __attribute__ ((noreturn));
-
-void
-_dl_start (void)
-{
- abort ();
-}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/Makefile b/libc/sysdeps/unix/sysv/linux/powerpc/Makefile
index f6dccd9a3..6bdf4dc7f 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -16,3 +16,9 @@ endif
ifeq ($(subdir),elf)
sysdep_routines += dl-vdso
endif
+
+ifeq ($(subdir),misc)
+sysdep_headers += bits/ppc.h
+sysdep_routines += get_clockfreq get_timebase_freq
+tests += test-gettimebasefreq
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
index c984e2bbb..91797b74c 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/PowerPC.
- Copyright (C) 1995-1998, 2000, 2003, 2004, 2006, 2007, 2009, 2010, 2011
+ Copyright (C) 1995-2012
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -232,6 +232,19 @@ struct f_owner_ex
we splice from/to). */
# define SPLICE_F_MORE 4 /* Expect more data. */
# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+
+
+/* File handle structure. */
+struct file_handle
+{
+ unsigned int handle_bytes;
+ int handle_type;
+ /* File identifier. */
+ unsigned char f_handle[0];
+};
+
+/* Maximum handle size (for now). */
+# define MAX_HANDLE_SZ 128
#endif
__BEGIN_DECLS
@@ -278,6 +291,19 @@ extern int fallocate64 (int __fd, int __mode, __off64_t __offset,
__off64_t __len);
# endif
+
+/* Map file name to file handle. */
+extern int name_to_handle_at (int __dfd, const char *__name,
+ struct file_handle *__handle, int *__mnt_id,
+ int __flags) __THROW;
+
+/* Open file using the file handle.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int open_by_handle_at (int __mountdirfd, struct file_handle *__handle,
+ int __flags);
+
#endif
__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h
new file mode 100644
index 000000000..76542d9d8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h
@@ -0,0 +1,33 @@
+/* Facilities specific to the PowerPC architecture on Linux
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 _BITS_PPC_H
+#define _BITS_PPC_H
+
+#ifndef _SYS_PLATFORM_PPC_H
+# error "Never include this file directly; use <sys/platform/ppc.h> instead."
+#endif
+
+__BEGIN_DECLS
+
+/* Read the time base frequency. */
+extern uint64_t __ppc_get_timebase_freq (void);
+
+__END_DECLS
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/configure b/libc/sysdeps/unix/sysv/linux/powerpc/configure
index 802b37160..7df7e481f 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/configure
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/configure
@@ -1,123 +1,3 @@
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/unix/sysv/linux/powerpc/.
diff --git a/libc/sysdeps/mach/hurd/dl-cache.c b/libc/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
index 5c01c3d6d..5559dd5c0 100644
--- a/libc/sysdeps/mach/hurd/dl-cache.c
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
@@ -1,5 +1,5 @@
-/* Stubby version of dl-cache; the Hurd doesn't support this "feature".
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Get the frequency of the time base.
+ Copyright (C) 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,13 +16,12 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-const char *
-_dl_load_cache_lookup (const char *name)
-{
- return 0;
-}
+#include <stdint.h>
+#include <libc-internal.h>
-void
-_dl_unload_cache (void)
+uint64_t
+__get_timebase_freq (void)
{
+ return (uint64_t) __get_clockfreq ();
}
+weak_alias (__get_timebase_freq, __ppc_get_timebase_freq)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c b/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c
index 57b36afc4..ba7ae294b 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2007 Free Software Foundation, Inc.
+/* Initialization code run first thing by the ELF startup code. Linux/PowerPC.
+ Copyright (C) 2007-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -45,4 +46,4 @@ _libc_vdso_platform_setup (void)
# define VDSO_SETUP _libc_vdso_platform_setup
#endif
-#include "../init-first.c"
+#include <csu/init-first.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
index 6fa0119e9..8d1c3a59d 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
@@ -30,4 +30,7 @@ libc {
GLIBC_2.11 {
fallocate64;
}
+ GLIBC_2.17 {
+ __ppc_get_timebase_freq;
+ }
}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
index 75123b9f3..ab96361d4 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
@@ -1775,6 +1775,7 @@ GLIBC_2.16
GLIBC_2.17
GLIBC_2.17 A
secure_getenv F
+ __ppc_get_timebase_freq F
GLIBC_2.2
GLIBC_2.2 A
_IO_adjust_wcolumn F
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
index 8334741ae..3ff01d1c1 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
@@ -19,4 +19,7 @@ libc {
setcontext;
swapcontext;
}
+ GLIBC_2.17 {
+ __ppc_get_timebase_freq;
+ }
}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
index e2484d3f2..a60b72ad1 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
@@ -81,6 +81,7 @@ GLIBC_2.16
GLIBC_2.17
GLIBC_2.17 A
secure_getenv F
+ __ppc_get_timebase_freq F
GLIBC_2.3
GLIBC_2.3 A
_Exit F
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c b/libc/sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c
new file mode 100644
index 000000000..a3f3bd6f5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c
@@ -0,0 +1,62 @@
+/* Check __ppc_get_timebase_freq() for architecture changes
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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 if __ppc_get_timebase_freq() works and is different from zero. A read
+ failure might indicate a Linux Kernel change.
+ This test also use the frequency to compute the real elapsed time. */
+
+#include <inttypes.h>
+#include <stdio.h>
+
+#include <sys/platform/ppc.h>
+
+/* Maximum value of the Time Base Register: 2^60 - 1. */
+#define MAX_TB 0xFFFFFFFFFFFFFFF
+
+static int
+do_test (void)
+{
+ uint64_t t1, t2, f, diff;
+
+ t1 = __ppc_get_timebase ();
+ printf ("t1 = %"PRIu64"\n", t1);
+
+ f = __ppc_get_timebase_freq ();
+ printf ("Time Base frequency = %"PRIu64" Hz\n", f);
+
+ if (f == 0) {
+ printf ("Fail: The time base frequency can't be zero.");
+ return 1;
+ }
+
+ t2 = __ppc_get_timebase ();
+ printf ("t2 = %"PRIu64"\n", t2);
+
+ if (t2 > t1) {
+ diff = t2 - t1;
+ } else {
+ diff = (MAX_TB - t2) + t1;
+ }
+
+ printf ("Elapsed time = %1.2f usecs\n", (double) diff * 1000000 / f );
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
index b63048840..ee7e22b63 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
@@ -51,7 +51,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE void *
diff --git a/libc/sysdeps/unix/sysv/linux/s390/init-first.c b/libc/sysdeps/unix/sysv/linux/s390/init-first.c
index c97138270..a066daefd 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/init-first.c
+++ b/libc/sysdeps/unix/sysv/linux/s390/init-first.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2008 Free Software Foundation, Inc.
+/* Initialization code run first thing by the ELF startup code. Linux/s390.
+ Copyright (C) 2008-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -46,4 +47,4 @@ _libc_vdso_platform_setup (void)
# define VDSO_SETUP _libc_vdso_platform_setup
#endif
-#include "../init-first.c"
+#include <csu/init-first.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
index e55d642e7..8be55a8d7 100644
--- a/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
@@ -51,7 +51,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __S32_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE void *
diff --git a/libc/sysdeps/unix/sysv/linux/syscalls.list b/libc/sysdeps/unix/sysv/linux/syscalls.list
index 63432725d..2e6cf9c60 100644
--- a/libc/sysdeps/unix/sysv/linux/syscalls.list
+++ b/libc/sysdeps/unix/sysv/linux/syscalls.list
@@ -36,11 +36,9 @@ ioperm - ioperm i:iii ioperm
iopl - iopl i:i iopl
klogctl EXTRA syslog i:isi klogctl
lchown - lchown i:sii __lchown lchown
-madvise - madvise i:pii madvise
mincore - mincore i:anV mincore
mlock - mlock i:bn mlock
mlockall - mlockall i:i mlockall
-mmap - mmap b:aniiii __mmap mmap
mount EXTRA mount i:sssip __mount mount
mremap EXTRA mremap b:ainip __mremap mremap
munlock - munlock i:ai munlock
diff --git a/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h
index 397e86724..ebb5bbb64 100644
--- a/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h
+++ b/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h
@@ -65,7 +65,6 @@
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SYSCALL_SLONG_TYPE
#define __DADDR_T_TYPE __S32_TYPE
-#define __SWBLK_T_TYPE __SYSCALL_SLONG_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE void *
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c b/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c
index e8b52eacb..dd41f0f7a 100644
--- a/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2007, 2011 Free Software Foundation, Inc.
+/* Initialization code run first thing by the ELF startup code. Linux/x86-64.
+ Copyright (C) 2007-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -54,4 +55,4 @@ _libc_vdso_platform_setup (void)
# define VDSO_SETUP _libc_vdso_platform_setup
#endif
-#include "../init-first.c"
+#include <csu/init-first.c>
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c b/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
index c2aea9d4e..5fe472ea2 100644
--- a/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2012 Free Software Foundation, Inc.
+/* Initialization code run first thing by the ELF startup code. Linux/x32.
+ Copyright (C) 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -37,4 +38,4 @@ _libc_vdso_platform_setup (void)
# define VDSO_SETUP _libc_vdso_platform_setup
#endif
-#include "../../init-first.c"
+#include <csu/init-first.c>
diff --git a/libc/sysdeps/x86_64/configure b/libc/sysdeps/x86_64/configure
index adbaeee32..0fa0e1ecf 100644
--- a/libc/sysdeps/x86_64/configure
+++ b/libc/sysdeps/x86_64/configure
@@ -1,128 +1,4 @@
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
- # already done that, so ensure we don't try to do so again and fall
- # in an infinite loop. This has already happened in practice.
- _as_can_reexec=no; export _as_can_reexec
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists and can be compiled using the include files in
diff --git a/libc/sysdeps/x86_64/dl-tlsdesc.h b/libc/sysdeps/x86_64/dl-tlsdesc.h
index 06ede0214..ec750904f 100644
--- a/libc/sysdeps/x86_64/dl-tlsdesc.h
+++ b/libc/sysdeps/x86_64/dl-tlsdesc.h
@@ -20,12 +20,6 @@
#ifndef _X86_64_DL_TLSDESC_H
# define _X86_64_DL_TLSDESC_H 1
-/* Use this to access DT_TLSDESC_PLT and DT_TLSDESC_GOT. */
-#ifndef ADDRIDX
-# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
- + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
-#endif
-
/* Type used to represent a TLS descriptor in the GOT. */
struct tlsdesc
{
diff --git a/libc/sysdeps/x86_64/fpu/libm-test-ulps b/libc/sysdeps/x86_64/fpu/libm-test-ulps
index b02b9e6ba..9c5157ff7 100644
--- a/libc/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/libc/sysdeps/x86_64/fpu/libm-test-ulps
@@ -812,6 +812,12 @@ float: 1
ifloat: 1
ildouble: 1
ldouble: 1
+Test "Real part of: clog (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -5.421010862427522170184200798202494495630e-20 + 3.548665303440282824232502561095699343814e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i":
+float: 1
+ifloat: 1
Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i":
float: 1
ifloat: 1
@@ -841,6 +847,9 @@ ldouble: 1
Test "Real part of: clog (0x1.fp+16383 - 0x1p-16445 i) == 11356.49165759582936919077408168801636572 - 0 i":
ildouble: 1
ldouble: 1
+Test "Imaginary part of: clog (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 5.0844550531823026520677817684239496041087e-32 + 1.2627468605458094918919206628466016525397 i":
+ildouble: 1
+ldouble: 1
Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i":
double: 1
idouble: 1
@@ -868,6 +877,12 @@ ldouble: 1
Test "Real part of: clog (0x1p-16445 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i":
ildouble: 1
ldouble: 1
+Test "Imaginary part of: clog (0x2818p-15 + 0x798fp-15 i) == 1.5366822245016167178749091974664853785194e-08 + 1.2522014929038946066987318471922169174157 i":
+float: 1
+ifloat: 1
+Test "Real part of: clog (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 4.4469229730850767799109418892826021157328e-20 + 1.2046235979300843056806465045930070146351 i":
+ildouble: 1
+ldouble: 1
Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i":
float: 1
ifloat: 1
@@ -1009,6 +1024,21 @@ idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -2.354315103889861110220423157644627849164e-20 + 1.541165759405643564697852372112893034397e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
Test "Real part of: clog10 (0x1.000566p0 + 0x1.234p-10 i) == 3.604093470239754109961125085078190708674e-5 + 4.824745078422174667425851670822596859720e-4 i":
float: 1
ifloat: 1
@@ -1068,6 +1098,29 @@ ldouble: 1
Test "Real part of: clog10 (0x1.fp+16383 - 0x1p-16445 i) == 4932.061660674182269085496060792589701158 - 0 i":
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x11682p-23 + 0x7ffed1p-23 i) == 5.0916490233953865181284669870035717560498e-13 + 0.6784968969384861816694467029319146542069 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+double: 1
+idouble: 1
Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i":
double: 1
idouble: 1
@@ -1151,6 +1204,75 @@ ifloat: 1
Test "Real part of: clog10 (0x1p-8190 + 1.0 i) == 2.920285685286322365786846845062520925172e-4932 + 6.821881769209206737428918127156778851051e-1 i":
ildouble: 1
ldouble: 1
+Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659b70ab7971bp-53 + 0x1f5d111e08abecp-53 i) == -1.0893543813872082317104059174982092534059e-30 + 0.5954257879188711495921161433751775633232 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x81b7efa81fc35ad1p-65 + 0x1ef4b835f1c79d812p-65 i) == -4.3074341162203896332989394770760901408798e-39 + 0.5709443672155660428417571212549720987784 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -4.2289432987513243393180377141513840878196e-30 + 0.4252020027092323591068799049905597805296 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i":
+double: 1
+idouble: 1
Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i":
double: 1
idouble: 1
@@ -1611,9 +1733,14 @@ ldouble: 1
Test "Imaginary part of: ctan (0x1p1023 + 1 i) == -0.2254627924997545057926782581695274244229 + 0.8786063118883068695462540226219865087189 i":
ildouble: 1
ldouble: 1
+Test "Real part of: ctan (0x1p127 + 1 i) == 0.2446359391192790896381501310437708987204 + 0.9101334047676183761532873794426475906201 i":
+float: 1
+ifloat: 1
Test "Imaginary part of: ctan (0x1p127 + 1 i) == 0.2446359391192790896381501310437708987204 + 0.9101334047676183761532873794426475906201 i":
double: 1
+float: 2
idouble: 1
+ifloat: 2
Test "Real part of: ctan (0x3.243f6cp-1 + 0 i) == -2.287733242885645987394874673945769518150e7 + 0.0 i":
float: 1
ifloat: 1
@@ -1758,7 +1885,12 @@ ildouble: 1
ldouble: 1
Test "Real part of: ctanh (1 + 0x1p127 i) == 0.9101334047676183761532873794426475906201 + 0.2446359391192790896381501310437708987204 i":
double: 1
+float: 2
idouble: 1
+ifloat: 2
+Test "Imaginary part of: ctanh (1 + 0x1p127 i) == 0.9101334047676183761532873794426475906201 + 0.2446359391192790896381501310437708987204 i":
+float: 1
+ifloat: 1
Test "Imaginary part of: ctanh (45 + 1 i) == 1.000000000000000000000000000000000000001 + 1.490158918874345552942703234806348520895e-39 i":
ildouble: 1
ldouble: 1
@@ -2399,8 +2531,8 @@ ifloat: 2
ildouble: 1
ldouble: 1
Test "sin_upward (3) == 0.1411200080598672221007448028081102798469":
-float: 1
-ifloat: 1
+float: 2
+ifloat: 2
ildouble: 1
ldouble: 1
Test "sin_upward (4) == -0.7568024953079282513726390945118290941359":
@@ -2430,12 +2562,6 @@ ifloat: 1
Test "sincos (0.80190127184058835, &sin_res, &cos_res) puts 0.69534156199418473 in cos_res":
double: 1
idouble: 1
-Test "sincos (0x1p+120, &sin_res, &cos_res) puts -9.25879022854837867303861764107414946730833e-01 in cos_res":
-float: 1
-ifloat: 1
-Test "sincos (0x1p+127, &sin_res, &cos_res) puts 7.81914638714960072263910298466369236613162e-01 in cos_res":
-float: 1
-ifloat: 1
Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
double: 1
float: 1
@@ -2706,7 +2832,9 @@ ildouble: 2
ldouble: 2
Test "y1 (0x1.27e204p+99) == -8.881610148467797208469612080785210013461e-16":
double: 1
+float: 1
idouble: 1
+ifloat: 1
ildouble: 1
ldouble: 1
Test "y1 (1.5) == -0.412308626973911295952829820633445323":
@@ -3041,20 +3169,22 @@ ldouble: 1
Function: Imaginary part of "clog":
float: 3
ifloat: 3
+ildouble: 1
+ldouble: 1
Function: Real part of "clog10":
double: 2
-float: 1
+float: 2
idouble: 2
-ifloat: 1
+ifloat: 2
ildouble: 1
ldouble: 1
Function: Imaginary part of "clog10":
double: 1
-float: 5
+float: 1
idouble: 1
-ifloat: 5
+ifloat: 1
ildouble: 1
ldouble: 1
@@ -3085,8 +3215,8 @@ ildouble: 1
ldouble: 1
Function: "cos_upward":
-float: 1
-ifloat: 1
+float: 2
+ifloat: 2
ildouble: 1
ldouble: 1
@@ -3174,17 +3304,17 @@ ldouble: 1
Function: Real part of "ctan":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 2
ldouble: 2
Function: Imaginary part of "ctan":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 1
ldouble: 1
@@ -3242,9 +3372,9 @@ ldouble: 4
Function: Real part of "ctanh":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
ildouble: 1
ldouble: 1
@@ -3445,8 +3575,8 @@ ildouble: 1
ldouble: 1
Function: "sin_upward":
-float: 1
-ifloat: 1
+float: 2
+ifloat: 2
ildouble: 1
ldouble: 1
diff --git a/libc/sysdeps/x86_64/fpu/s_sincosf.S b/libc/sysdeps/x86_64/fpu/s_sincosf.S
new file mode 100644
index 000000000..3334a3a78
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_sincosf.S
@@ -0,0 +1,558 @@
+/* Optimized sincosf function.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for 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>
+#define __need_Emath
+#include <bits/errno.h>
+
+/* Short algorithm description:
+ *
+ * 1) if |x|==0: sin(x)=x,
+ * cos(x)=1.
+ * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed,
+ * cos(x)=1-|x|.
+ * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1,
+ * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1
+ * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))),
+ * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))).
+ * 5) if |x| < 9*Pi/4:
+ * 5.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4.
+ * 5.2) Reconstruction:
+ * sign_sin = sign(x) * (-1.0)^(( n >>2)&1)
+ * sign_cos = (-1.0)^(((n+2)>>2)&1)
+ * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t
+ * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s
+ * if(n&2 != 0) {
+ * using cos(t) and sin(t) polynomials for |t|<Pi/4, results are
+ * cos(x) = poly_sin * sign_cos
+ * sin(x) = poly_cos * sign_sin
+ * } else {
+ * sin(x) = poly_sin * sign_sin
+ * cos(x) = poly_cos * sign_cos
+ * }
+ * 6) if |x| < 2^23, large args:
+ * 6.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4
+ * 6.2) Reconstruction same as (5.2).
+ * 7) if |x| >= 2^23, very large args:
+ * 7.1) Range reduction:
+ * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4.
+ * 7.2) Reconstruction same as (5.2).
+ * 8) if x is Inf, return x-x, and set errno=EDOM.
+ * 9) if x is NaN, return x-x.
+ *
+ * Special cases:
+ * sin/cos(+-0) = +-0/1 not raising inexact/underflow,
+ * sin/cos(subnormal) raises inexact/underflow,
+ * sin/cos(min_normalized) raises inexact/underflow,
+ * sin/cos(normalized) raises inexact,
+ * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM,
+ * sin/cos(NaN) = NaN.
+ */
+
+# define ARG_SIN_PTR %rdi
+# define ARG_COS_PTR %rsi
+
+ .text
+ENTRY(__sincosf)
+ /* Input: %xmm0 contains single precision argument x */
+ /* %rdi points to sin result */
+ /* %rsi points to cos result */
+
+ movd %xmm0, %eax /* Bits of x */
+ movaps %xmm0, %xmm7 /* Copy of x */
+ cvtss2sd %xmm0, %xmm0 /* DP x */
+ movss L(SP_ABS_MASK)(%rip), %xmm3
+ movl %eax, %r8d /* Copy of x bits */
+ andl $0x7fffffff, %eax /* |x| */
+
+ cmpl $0x3f490fdb, %eax /* |x|<Pi/4 ? */
+ jb L(arg_less_pio4)
+
+ /* Here if |x|>=Pi/4 */
+ andps %xmm7, %xmm3 /* SP |x| */
+ andpd L(DP_ABS_MASK)(%rip),%xmm0 /* DP |x| */
+ movss L(SP_INVPIO4)(%rip), %xmm2 /* SP 1/(Pi/4) */
+
+ cmpl $0x40e231d6, %eax /* |x|<9*Pi/4 ? */
+ jae L(large_args)
+
+ /* Here if Pi/4<=|x|<9*Pi/4 */
+ mulss %xmm3, %xmm2 /* SP |x|/(Pi/4) */
+ movl %r8d, %ecx /* Load x */
+ cvttss2si %xmm2, %eax /* k, number of Pi/4 in x */
+ lea L(PIO4J)(%rip), %r9
+ shrl $29, %ecx /* (sign of x) << 2 */
+ addl $1, %eax /* k+1 */
+ movl $0x0e, %edx
+ andl %eax, %edx /* j = (k+1)&0x0e */
+ subsd (%r9,%rdx,8), %xmm0 /* t = |x| - j * Pi/4 */
+
+L(reconstruction):
+ /* Input: %eax=n, %xmm0=t, %ecx=sign(x) */
+
+ movaps %xmm0, %xmm4 /* t */
+ movhpd L(DP_ONES)(%rip), %xmm4 /* 1|t */
+ mulsd %xmm0, %xmm0 /* y=t^2 */
+ movl $2, %edx
+ unpcklpd %xmm0, %xmm0 /* y|y */
+ addl %eax, %edx /* k+2 */
+ movaps %xmm0, %xmm1 /* y|y */
+ mulpd %xmm0, %xmm0 /* z=t^4|z=t^4 */
+
+ movaps L(DP_SC4)(%rip), %xmm2 /* S4 */
+ mulpd %xmm0, %xmm2 /* z*S4 */
+ movaps L(DP_SC3)(%rip), %xmm3 /* S3 */
+ mulpd %xmm0, %xmm3 /* z*S3 */
+ xorl %eax, %ecx /* (sign_x ^ (k>>2))<<2 */
+ addpd L(DP_SC2)(%rip), %xmm2 /* S2+z*S4 */
+ mulpd %xmm0, %xmm2 /* z*(S2+z*S4) */
+ shrl $2, %edx /* (k+2)>>2 */
+ addpd L(DP_SC1)(%rip), %xmm3 /* S1+z*S3 */
+ mulpd %xmm0, %xmm3 /* z*(S1+z*S3) */
+ shrl $2, %ecx /* sign_x ^ k>>2 */
+ addpd L(DP_SC0)(%rip), %xmm2 /* S0+z*(S2+z*S4) */
+ andl $1, %edx /* sign_cos = ((k+2)>>2)&1 */
+ mulpd %xmm1, %xmm2 /* y*(S0+z*(S2+z*S4)) */
+ andl $1, %ecx /* sign_sin = sign_x ^ ((k>>2)&1) */
+ addpd %xmm2, %xmm3 /* y*(S0+y*(S1+y*(S2+y*(S3+y*S4)))) */
+ lea L(DP_ONES)(%rip), %r9
+ mulpd %xmm4, %xmm3 /*t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/
+ testl $2, %eax /* n&2 != 0 ? */
+ addpd %xmm4, %xmm3 /*t+t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/
+ jnz L(sin_result_sin_poly)
+
+/*L(sin_result_cos_poly):*/
+ /*
+ * Here if
+ * cos(x) = poly_sin * sign_cos
+ * sin(x) = poly_cos * sign_sin
+ */
+ movsd (%r9,%rcx,8), %xmm4 /* 0|sign_sin */
+ movhpd (%r9,%rdx,8), %xmm4 /* sign_cos|sign_sin */
+ mulpd %xmm4, %xmm3 /* result_cos|result_sin */
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movss %xmm0, (ARG_SIN_PTR) /* store sin(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */
+ movss %xmm0, (ARG_COS_PTR) /* store cos(x) */
+ ret
+
+ .p2align 4
+L(sin_result_sin_poly):
+ /*
+ * Here if
+ * sin(x) = poly_sin * sign_sin
+ * cos(x) = poly_cos * sign_cos
+ */
+ movsd (%r9,%rdx,8), %xmm4 /* 0|sign_cos */
+ movhpd (%r9,%rcx,8), %xmm4 /* sign_sin|sign_cos */
+ mulpd %xmm4, %xmm3 /* result_sin|result_cos */
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movss %xmm0, (ARG_COS_PTR) /* store cos(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move sin(x) to xmm0[0] */
+ movss %xmm0, (ARG_SIN_PTR) /* store sin(x) */
+ ret
+
+ .p2align 4
+L(large_args):
+ /* Here if |x|>=9*Pi/4 */
+ cmpl $0x7f800000, %eax /* x is Inf or NaN ? */
+ jae L(arg_inf_or_nan)
+
+ /* Here if finite |x|>=9*Pi/4 */
+ cmpl $0x4b000000, %eax /* |x|<2^23 ? */
+ jae L(very_large_args)
+
+ /* Here if 9*Pi/4<=|x|<2^23 */
+ movsd L(DP_INVPIO4)(%rip), %xmm1 /* 1/(Pi/4) */
+ mulsd %xmm0, %xmm1 /* |x|/(Pi/4) */
+ cvttsd2si %xmm1, %eax /* k=trunc(|x|/(Pi/4)) */
+ addl $1, %eax /* k+1 */
+ movl %eax, %edx
+ andl $0xfffffffe, %edx /* j=(k+1)&0xfffffffe */
+ cvtsi2sdl %edx, %xmm4 /* DP j */
+ movl %r8d, %ecx /* Load x */
+ movsd L(DP_PIO4HI)(%rip), %xmm2 /* -PIO4HI = high part of -Pi/4 */
+ shrl $29, %ecx /* (sign of x) << 2 */
+ mulsd %xmm4, %xmm2 /* -j*PIO4HI */
+ movsd L(DP_PIO4LO)(%rip), %xmm3 /* -PIO4LO = low part of -Pi/4 */
+ addsd %xmm2, %xmm0 /* |x| - j*PIO4HI */
+ mulsd %xmm3, %xmm4 /* j*PIO4LO */
+ addsd %xmm4, %xmm0 /* t = |x| - j*PIO4HI - j*PIO4LO */
+ jmp L(reconstruction)
+
+ .p2align 4
+L(very_large_args):
+ /* Here if finite |x|>=2^23 */
+
+ /* bitpos = (ix>>23) - BIAS_32 + 59; */
+ shrl $23, %eax /* eb = biased exponent of x */
+ subl $68, %eax /* bitpos=eb-0x7f+59, where 0x7f */
+ /*is exponent bias */
+ movl $28, %ecx /* %cl=28 */
+ movl %eax, %edx /* bitpos copy */
+
+ /* j = bitpos/28; */
+ div %cl /* j in register %al=%ax/%cl */
+ movapd %xmm0, %xmm3 /* |x| */
+ andl $0xff, %eax /* clear unneeded remainder from %ah*/
+
+ imull $28, %eax, %ecx /* j*28 */
+ lea L(_FPI)(%rip), %r9
+ movsd L(DP_HI_MASK)(%rip), %xmm4 /* DP_HI_MASK */
+ movapd %xmm0, %xmm5 /* |x| */
+ mulsd -16(%r9,%rax,8), %xmm3 /* tmp3 = FPI[j-2]*|x| */
+ movapd %xmm0, %xmm1 /* |x| */
+ mulsd -8(%r9,%rax,8), %xmm5 /* tmp2 = FPI[j-1]*|x| */
+ mulsd (%r9,%rax,8), %xmm0 /* tmp0 = FPI[j]*|x| */
+ addl $19, %ecx /* j*28+19 */
+ mulsd 8(%r9,%rax,8), %xmm1 /* tmp1 = FPI[j+1]*|x| */
+ cmpl %ecx, %edx /* bitpos>=j*28+19 ? */
+ jl L(very_large_skip1)
+
+ /* Here if bitpos>=j*28+19 */
+ andpd %xmm3, %xmm4 /* HI(tmp3) */
+ subsd %xmm4, %xmm3 /* tmp3 = tmp3 - HI(tmp3) */
+L(very_large_skip1):
+
+ movsd L(DP_2POW52)(%rip), %xmm6
+ movapd %xmm5, %xmm2 /* tmp2 copy */
+ addsd %xmm3, %xmm5 /* tmp5 = tmp3 + tmp2 */
+ movl $1, %edx
+ addsd %xmm5, %xmm6 /* tmp6 = tmp5 + 2^52 */
+ movsd 8+L(DP_2POW52)(%rip), %xmm4
+ movd %xmm6, %eax /* k = I64_LO(tmp6); */
+ addsd %xmm6, %xmm4 /* tmp4 = tmp6 - 2^52 */
+ movl %r8d, %ecx /* Load x */
+ comisd %xmm5, %xmm4 /* tmp4 > tmp5 ? */
+ jbe L(very_large_skip2)
+
+ /* Here if tmp4 > tmp5 */
+ subl $1, %eax /* k-- */
+ addsd 8+L(DP_ONES)(%rip), %xmm4 /* tmp4 -= 1.0 */
+L(very_large_skip2):
+
+ andl %eax, %edx /* k&1 */
+ lea L(DP_ZERONE)(%rip), %r9
+ subsd %xmm4, %xmm3 /* tmp3 -= tmp4 */
+ addsd (%r9,%rdx,8), %xmm3 /* t = DP_ZERONE[k&1] + tmp3 */
+ addsd %xmm2, %xmm3 /* t += tmp2 */
+ shrl $29, %ecx /* (sign of x) << 2 */
+ addsd %xmm3, %xmm0 /* t += tmp0 */
+ addl $1, %eax /* n=k+1 */
+ addsd %xmm1, %xmm0 /* t += tmp1 */
+ mulsd L(DP_PIO4)(%rip), %xmm0 /* t *= PI04 */
+
+ jmp L(reconstruction) /* end of very_large_args peth */
+
+ .p2align 4
+L(arg_less_pio4):
+ /* Here if |x|<Pi/4 */
+ cmpl $0x3d000000, %eax /* |x|<2^-5 ? */
+ jl L(arg_less_2pn5)
+
+ /* Here if 2^-5<=|x|<Pi/4 */
+ movaps %xmm0, %xmm3 /* DP x */
+ movhpd L(DP_ONES)(%rip), %xmm3 /* DP 1|x */
+ mulsd %xmm0, %xmm0 /* DP y=x^2 */
+ unpcklpd %xmm0, %xmm0 /* DP y|y */
+ movaps %xmm0, %xmm1 /* y|y */
+ mulpd %xmm0, %xmm0 /* z=x^4|z=x^4 */
+
+ movapd L(DP_SC4)(%rip), %xmm4 /* S4 */
+ mulpd %xmm0, %xmm4 /* z*S4 */
+ movapd L(DP_SC3)(%rip), %xmm5 /* S3 */
+ mulpd %xmm0, %xmm5 /* z*S3 */
+ addpd L(DP_SC2)(%rip), %xmm4 /* S2+z*S4 */
+ mulpd %xmm0, %xmm4 /* z*(S2+z*S4) */
+ addpd L(DP_SC1)(%rip), %xmm5 /* S1+z*S3 */
+ mulpd %xmm0, %xmm5 /* z*(S1+z*S3) */
+ addpd L(DP_SC0)(%rip), %xmm4 /* S0+z*(S2+z*S4) */
+ mulpd %xmm1, %xmm4 /* y*(S0+z*(S2+z*S4)) */
+ mulpd %xmm3, %xmm5 /* x*z*(S1+z*S3) */
+ mulpd %xmm3, %xmm4 /* x*y*(S0+z*(S2+z*S4)) */
+ addpd %xmm5, %xmm4 /*x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/
+ addpd %xmm4, %xmm3 /*x+x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movss %xmm0, (ARG_SIN_PTR) /* store sin(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */
+ movss %xmm0, (ARG_COS_PTR) /* store cos(x) */
+ ret
+
+ .p2align 4
+L(arg_less_2pn5):
+ /* Here if |x|<2^-5 */
+ cmpl $0x32000000, %eax /* |x|<2^-27 ? */
+ jl L(arg_less_2pn27)
+
+ /* Here if 2^-27<=|x|<2^-5 */
+ movaps %xmm0, %xmm1 /* DP x */
+ movhpd L(DP_ONES)(%rip), %xmm1 /* DP 1|x */
+ mulsd %xmm0, %xmm0 /* DP x^2 */
+ unpcklpd %xmm0, %xmm0 /* DP x^2|x^2 */
+
+ movaps L(DP_SINCOS2_1)(%rip), %xmm3 /* DP DP_SIN2_1 */
+ mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_1 */
+ addpd L(DP_SINCOS2_0)(%rip), %xmm3 /* DP DP_SIN2_0+x^2*DP_SIN2_1 */
+ mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_0+x^4*DP_SIN2_1 */
+ mulpd %xmm1, %xmm3 /* DP x^3*DP_SIN2_0+x^5*DP_SIN2_1 */
+ addpd %xmm1, %xmm3 /* DP x+x^3*DP_SIN2_0+x^5*DP_SIN2_1 */
+ cvtpd2ps %xmm3, %xmm0 /* SP results */
+ movss %xmm0, (ARG_SIN_PTR) /* store sin(x) from xmm0[0] */
+ shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */
+ movss %xmm0, (ARG_COS_PTR) /* store cos(x) */
+ ret
+
+ .p2align 4
+L(arg_less_2pn27):
+ cmpl $0, %eax /* x=0 ? */
+ je L(arg_zero) /* in case x=0 return sin(+-0)==+-0 */
+ /* Here if |x|<2^-27 */
+ /*
+ * Special cases here:
+ * sin(subnormal) raises inexact/underflow
+ * sin(min_normalized) raises inexact/underflow
+ * sin(normalized) raises inexact
+ * cos(here)=1-|x| (raising inexact)
+ */
+ movaps %xmm0, %xmm3 /* DP x */
+ mulsd L(DP_SMALL)(%rip), %xmm0/* DP x*DP_SMALL */
+ subsd %xmm0, %xmm3 /* DP sin result is x-x*DP_SMALL */
+ andps L(SP_ABS_MASK)(%rip), %xmm7/* SP |x| */
+ cvtsd2ss %xmm3, %xmm0 /* sin(x) */
+ movss L(SP_ONE)(%rip), %xmm1 /* SP 1.0 */
+ movss %xmm0, (ARG_SIN_PTR) /* sin(x) store */
+ subss %xmm7, %xmm1 /* cos(x) */
+ movss %xmm1, (ARG_COS_PTR) /* cos(x) store */
+ ret
+
+ .p2align 4
+L(arg_zero):
+ movss L(SP_ONE)(%rip), %xmm0 /* 1.0 */
+ movss %xmm7, (ARG_SIN_PTR) /* sin(+-0)==x */
+ movss %xmm0, (ARG_COS_PTR) /* cos(+-0)==1 */
+ ret
+
+ .p2align 4
+L(arg_inf_or_nan):
+ /* Here if |x| is Inf or NAN */
+ jne L(skip_errno_setting) /* in case of x is NaN */
+
+ /* Here if x is Inf. Set errno to EDOM. */
+ call JUMPTARGET(__errno_location)
+ movl $EDOM, (%rax)
+
+ .p2align 4
+L(skip_errno_setting):
+ /* Here if |x| is Inf or NAN. Continued. */
+ subss %xmm7, %xmm7 /* x-x, result is NaN */
+ movss %xmm7, (ARG_SIN_PTR)
+ movss %xmm7, (ARG_COS_PTR)
+ ret
+END(__sincosf)
+
+ .section .rodata, "a"
+ .p2align 3
+L(PIO4J): /* Table of j*Pi/4, for j=0,1,..,10 */
+ .long 0x00000000,0x00000000
+ .long 0x54442d18,0x3fe921fb
+ .long 0x54442d18,0x3ff921fb
+ .long 0x7f3321d2,0x4002d97c
+ .long 0x54442d18,0x400921fb
+ .long 0x2955385e,0x400f6a7a
+ .long 0x7f3321d2,0x4012d97c
+ .long 0xe9bba775,0x4015fdbb
+ .long 0x54442d18,0x401921fb
+ .long 0xbeccb2bb,0x401c463a
+ .long 0x2955385e,0x401f6a7a
+ .type L(PIO4J), @object
+ ASM_SIZE_DIRECTIVE(L(PIO4J))
+
+ .p2align 3
+L(_FPI): /* 4/Pi broken into sum of positive DP values */
+ .long 0x00000000,0x00000000
+ .long 0x6c000000,0x3ff45f30
+ .long 0x2a000000,0x3e3c9c88
+ .long 0xa8000000,0x3c54fe13
+ .long 0xd0000000,0x3aaf47d4
+ .long 0x6c000000,0x38fbb81b
+ .long 0xe0000000,0x3714acc9
+ .long 0x7c000000,0x3560e410
+ .long 0x56000000,0x33bca2c7
+ .long 0xac000000,0x31fbd778
+ .long 0xe0000000,0x300b7246
+ .long 0xe8000000,0x2e5d2126
+ .long 0x48000000,0x2c970032
+ .long 0xe8000000,0x2ad77504
+ .long 0xe0000000,0x290921cf
+ .long 0xb0000000,0x274deb1c
+ .long 0xe0000000,0x25829a73
+ .long 0xbe000000,0x23fd1046
+ .long 0x10000000,0x2224baed
+ .long 0x8e000000,0x20709d33
+ .long 0x80000000,0x1e535a2f
+ .long 0x64000000,0x1cef904e
+ .long 0x30000000,0x1b0d6398
+ .long 0x24000000,0x1964ce7d
+ .long 0x16000000,0x17b908bf
+ .type L(_FPI), @object
+ ASM_SIZE_DIRECTIVE(L(_FPI))
+
+/* Coefficients of polynomials for */
+/* sin(x)~=x+x*x^2*(DP_SIN2_0+x^2*DP_SIN2_1) in low DP part, */
+/* cos(x)~=1+1*x^2*(DP_COS2_0+x^2*DP_COS2_1) in high DP part, */
+/* for |x|<2^-5. */
+ .p2align 4
+L(DP_SINCOS2_0):
+ .long 0x5543d49d,0xbfc55555
+ .long 0xff5cc6fd,0xbfdfffff
+ .type L(DP_SINCOS2_0), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_0))
+
+ .p2align 4
+L(DP_SINCOS2_1):
+ .long 0x75cec8c5,0x3f8110f4
+ .long 0xb178dac5,0x3fa55514
+ .type L(DP_SINCOS2_1), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_1))
+
+
+ .p2align 3
+L(DP_ZERONE):
+ .long 0x00000000,0x00000000 /* 0.0 */
+ .long 0x00000000,0xbff00000 /* 1.0 */
+ .type L(DP_ZERONE), @object
+ ASM_SIZE_DIRECTIVE(L(DP_ZERONE))
+
+ .p2align 3
+L(DP_ONES):
+ .long 0x00000000,0x3ff00000 /* +1.0 */
+ .long 0x00000000,0xbff00000 /* -1.0 */
+ .type L(DP_ONES), @object
+ ASM_SIZE_DIRECTIVE(L(DP_ONES))
+
+/* Coefficients of polynomials for */
+/* sin(t)~=t+t*t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4)))) in low DP part, */
+/* cos(t)~=1+1*t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4)))) in high DP part, */
+/* for |t|<Pi/4. */
+ .p2align 4
+L(DP_SC4):
+ .long 0x1674b58a,0xbe5a947e
+ .long 0xdd8844d7,0xbe923c97
+ .type L(DP_SC4), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC4))
+
+ .p2align 4
+L(DP_SC3):
+ .long 0x64e6b5b4,0x3ec71d72
+ .long 0x9ac43cc0,0x3efa00eb
+ .type L(DP_SC3), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC3))
+
+ .p2align 4
+L(DP_SC2):
+ .long 0x8b4bd1f9,0xbf2a019f
+ .long 0x348b6874,0xbf56c16b
+ .type L(DP_SC2), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC2))
+
+ .p2align 4
+L(DP_SC1):
+ .long 0x10c2688b,0x3f811111
+ .long 0x545c50c7,0x3fa55555
+ .type L(DP_SC1), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC1))
+
+ .p2align 4
+L(DP_SC0):
+ .long 0x55551cd9,0xbfc55555
+ .long 0xfffe98ae,0xbfdfffff
+ .type L(DP_SC0), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SC0))
+
+ .p2align 3
+L(DP_SMALL):
+ .long 0x00000000,0x3cd00000 /* 2^(-50) */
+ .type L(DP_SMALL), @object
+ ASM_SIZE_DIRECTIVE(L(DP_SMALL))
+
+ .p2align 3
+L(DP_PIO4):
+ .long 0x54442d18,0x3fe921fb /* Pi/4 */
+ .type L(DP_PIO4), @object
+ ASM_SIZE_DIRECTIVE(L(DP_PIO4))
+
+ .p2align 3
+L(DP_2POW52):
+ .long 0x00000000,0x43300000 /* +2^52 */
+ .long 0x00000000,0xc3300000 /* -2^52 */
+ .type L(DP_2POW52), @object
+ ASM_SIZE_DIRECTIVE(L(DP_2POW52))
+
+ .p2align 3
+L(DP_INVPIO4):
+ .long 0x6dc9c883,0x3ff45f30 /* 4/Pi */
+ .type L(DP_INVPIO4), @object
+ ASM_SIZE_DIRECTIVE(L(DP_INVPIO4))
+
+ .p2align 3
+L(DP_PIO4HI):
+ .long 0x54000000,0xbfe921fb /* High part of Pi/4 */
+ .type L(DP_PIO4HI), @object
+ ASM_SIZE_DIRECTIVE(L(DP_PIO4HI))
+
+ .p2align 3
+L(DP_PIO4LO):
+ .long 0x11A62633,0xbe010b46 /* Low part of Pi/4 */
+ .type L(DP_PIO4LO), @object
+ ASM_SIZE_DIRECTIVE(L(DP_PIO4LO))
+
+ .p2align 2
+L(SP_INVPIO4):
+ .long 0x3fa2f983 /* 4/Pi */
+ .type L(SP_INVPIO4), @object
+ ASM_SIZE_DIRECTIVE(L(SP_INVPIO4))
+
+ .p2align 4
+L(DP_ABS_MASK): /* Mask for getting DP absolute value */
+ .long 0xffffffff,0x7fffffff
+ .long 0xffffffff,0x7fffffff
+ .type L(DP_ABS_MASK), @object
+ ASM_SIZE_DIRECTIVE(L(DP_ABS_MASK))
+
+ .p2align 3
+L(DP_HI_MASK): /* Mask for getting high 21 bits of DP value */
+ .long 0x00000000,0xffffffff
+ .type L(DP_HI_MASK), @object
+ ASM_SIZE_DIRECTIVE(L(DP_HI_MASK))
+
+ .p2align 4
+L(SP_ABS_MASK): /* Mask for getting SP absolute value */
+ .long 0x7fffffff,0x7fffffff
+ .long 0x7fffffff,0x7fffffff
+ .type L(SP_ABS_MASK), @object
+ ASM_SIZE_DIRECTIVE(L(SP_ABS_MASK))
+
+ .p2align 2
+L(SP_ONE):
+ .long 0x3f800000 /* 1.0 */
+ .type L(SP_ONE), @object
+ ASM_SIZE_DIRECTIVE(L(SP_ONE))
+
+weak_alias(__sincosf, sincosf)
diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.c b/libc/sysdeps/x86_64/multiarch/init-arch.c
index fb44dcfcf..fed5ab898 100644
--- a/libc/sysdeps/x86_64/multiarch/init-arch.c
+++ b/libc/sysdeps/x86_64/multiarch/init-arch.c
@@ -156,6 +156,9 @@ __init_cpu_features (void)
/* Determine if AVX is usable. */
if (CPUID_AVX)
__cpu_features.feature[index_AVX_Usable] |= bit_AVX_Usable;
+ /* Determine if FMA is usable. */
+ if (CPUID_FMA)
+ __cpu_features.feature[index_FMA_Usable] |= bit_FMA_Usable;
/* Determine if FMA4 is usable. */
if (CPUID_FMA4)
__cpu_features.feature[index_FMA4_Usable] |= bit_FMA4_Usable;
diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.h b/libc/sysdeps/x86_64/multiarch/init-arch.h
index 45e265167..f33f1c81e 100644
--- a/libc/sysdeps/x86_64/multiarch/init-arch.h
+++ b/libc/sysdeps/x86_64/multiarch/init-arch.h
@@ -22,7 +22,8 @@
#define bit_Fast_Unaligned_Load (1 << 4)
#define bit_Prefer_PMINUB_for_stringop (1 << 5)
#define bit_AVX_Usable (1 << 6)
-#define bit_FMA4_Usable (1 << 7)
+#define bit_FMA_Usable (1 << 7)
+#define bit_FMA4_Usable (1 << 8)
/* CPUID Feature flags. */
#define bit_SSE2 (1 << 26)
@@ -56,6 +57,7 @@
# define index_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE
# define index_Prefer_PMINUB_for_stringop FEATURE_INDEX_1*FEATURE_SIZE
# define index_AVX_Usable FEATURE_INDEX_1*FEATURE_SIZE
+# define index_FMA_Usable FEATURE_INDEX_1*FEATURE_SIZE
# define index_FMA4_Usable FEATURE_INDEX_1*FEATURE_SIZE
#else /* __ASSEMBLER__ */
@@ -131,6 +133,8 @@ extern const struct cpu_features *__get_cpu_features (void)
HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_OSXSAVE)
# define CPUID_AVX \
HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_AVX)
+# define CPUID_FMA \
+ HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_FMA)
# define CPUID_FMA4 \
HAS_CPUID_FLAG (COMMON_CPUID_INDEX_80000001, ecx, bit_FMA4)
@@ -140,7 +144,6 @@ extern const struct cpu_features *__get_cpu_features (void)
# define HAS_SSSE3 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSSE3)
# define HAS_SSE4_1 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_1)
# define HAS_SSE4_2 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_2)
-# define HAS_FMA HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_FMA)
# define index_Fast_Rep_String FEATURE_INDEX_1
# define index_Fast_Copy_Backward FEATURE_INDEX_1
@@ -148,6 +151,7 @@ extern const struct cpu_features *__get_cpu_features (void)
# define index_Prefer_SSE_for_memop FEATURE_INDEX_1
# define index_Fast_Unaligned_Load FEATURE_INDEX_1
# define index_AVX_Usable FEATURE_INDEX_1
+# define index_FMA_Usable FEATURE_INDEX_1
# define index_FMA4_Usable FEATURE_INDEX_1
# define HAS_ARCH_FEATURE(name) \
@@ -159,6 +163,7 @@ extern const struct cpu_features *__get_cpu_features (void)
# define HAS_PREFER_SSE_FOR_MEMOP HAS_ARCH_FEATURE (Prefer_SSE_for_memop)
# define HAS_FAST_UNALIGNED_LOAD HAS_ARCH_FEATURE (Fast_Unaligned_Load)
# define HAS_AVX HAS_ARCH_FEATURE (AVX_Usable)
+# define HAS_FMA HAS_ARCH_FEATURE (FMA_Usable)
# define HAS_FMA4 HAS_ARCH_FEATURE (FMA4_Usable)
#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S b/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S
index a320a3e94..96380a46b 100644
--- a/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S
+++ b/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S
@@ -1,4 +1,6 @@
-#define USE_SSSE3 1
-#define STRCMP __strncmp_ssse3
-#define USE_AS_STRNCMP
-#include "../strcmp.S"
+#ifdef SHARED
+# define USE_SSSE3 1
+# define STRCMP __strncmp_ssse3
+# define USE_AS_STRNCMP
+# include "../strcmp.S"
+#endif