diff options
Diffstat (limited to 'libc/sysdeps')
84 files changed, 2085 insertions, 854 deletions
diff --git a/libc/sysdeps/generic/ldsodefs.h b/libc/sysdeps/generic/ldsodefs.h index f6458627d..16bcfd10c 100644 --- a/libc/sysdeps/generic/ldsodefs.h +++ b/libc/sysdeps/generic/ldsodefs.h @@ -725,7 +725,11 @@ rtld_hidden_proto (_dl_make_stack_executable) might use the variable which results in copy relocations on some platforms. But this does not matter, ld.so can always use the local copy. */ -extern void *__libc_stack_end attribute_relro; +extern void *__libc_stack_end +#ifndef LIBC_STACK_END_NOT_RELRO + attribute_relro +#endif + ; rtld_hidden_proto (__libc_stack_end) /* Parameters passed to the dynamic linker. */ diff --git a/libc/sysdeps/generic/paths.h b/libc/sysdeps/generic/paths.h index 439992fe7..f85e88cb9 100644 --- a/libc/sysdeps/generic/paths.h +++ b/libc/sysdeps/generic/paths.h @@ -46,15 +46,15 @@ #define _PATH_DRUM "/dev/drum" #define _PATH_GSHADOW "/etc/gshadow" #define _PATH_KMEM "/dev/kmem" -#define _PATH_MAILDIR "/var/mail" #define _PATH_LASTLOG "/var/log/lastlog" -#define _PATH_MAN "/usr/man" +#define _PATH_MAILDIR "/var/mail" +#define _PATH_MAN "/usr/share/man" #define _PATH_MEM "/dev/mem" #define _PATH_MNTTAB "/etc/fstab" #define _PATH_MOUNTED "/var/run/mtab" #define _PATH_NOLOGIN "/etc/nologin" -#define _PATH_PRESERVE "/var/preserve" -#define _PATH_RWHODIR "/var/rwho" +#define _PATH_PRESERVE "/var/lib" +#define _PATH_RWHODIR "/var/spool/rwho" #define _PATH_SENDMAIL "/usr/sbin/sendmail" #define _PATH_SHADOW "/etc/shadow" #define _PATH_SHELLS "/etc/shells" diff --git a/libc/sysdeps/gnu/configure b/libc/sysdeps/gnu/configure new file mode 100644 index 000000000..634e1d0cc --- /dev/null +++ b/libc/sysdeps/gnu/configure @@ -0,0 +1,36 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + +# Local configure fragment for sysdeps/gnu. + +# The Filesystem Hierarchy Standard prescribes where to place "essential" +# files. I.e., when the installation prefix is "/usr" we have to place +# shared library objects and the configuration files on the root partition +# in /lib and /etc. +case "$prefix" in +/usr | /usr/) + # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib. + # Allow earlier configure scripts to handle libc_cv_slibdir, libdir, + # and libc_cv_localedir. + test -n "$libc_cv_slibdir" || \ + case $machine in + sparc/sparc64 | x86_64* | powerpc/powerpc64 | s390/s390-64) + libc_cv_slibdir=/lib64 + if test "$libdir" = '${exec_prefix}/lib'; then + libdir='${exec_prefix}/lib64'; + # Locale data can be shared between 32bit and 64bit libraries + libc_cv_localedir='${exec_prefix}/lib/locale' + fi + ;; + *) + libc_cv_slibdir=/lib + ;; + esac + # Allow the user to override the path with --sysconfdir + if test "$sysconfdir" = '${prefix}/etc'; then + libc_cv_sysconfdir=/etc + else + libc_cv_sysconfdir=$sysconfdir + fi + libc_cv_rootsbindir=/sbin + ;; +esac diff --git a/libc/sysdeps/gnu/configure.in b/libc/sysdeps/gnu/configure.in new file mode 100644 index 000000000..3422007ff --- /dev/null +++ b/libc/sysdeps/gnu/configure.in @@ -0,0 +1,36 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +# Local configure fragment for sysdeps/gnu. + +# The Filesystem Hierarchy Standard prescribes where to place "essential" +# files. I.e., when the installation prefix is "/usr" we have to place +# shared library objects and the configuration files on the root partition +# in /lib and /etc. +case "$prefix" in +/usr | /usr/) + # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib. + # Allow earlier configure scripts to handle libc_cv_slibdir, libdir, + # and libc_cv_localedir. + test -n "$libc_cv_slibdir" || \ + case $machine in + sparc/sparc64 | x86_64* | powerpc/powerpc64 | s390/s390-64) + libc_cv_slibdir=/lib64 + if test "$libdir" = '${exec_prefix}/lib'; then + libdir='${exec_prefix}/lib64'; + # Locale data can be shared between 32bit and 64bit libraries + libc_cv_localedir='${exec_prefix}/lib/locale' + fi + ;; + *) + libc_cv_slibdir=/lib + ;; + esac + # Allow the user to override the path with --sysconfdir + if test "$sysconfdir" = '${prefix}/etc'; then + libc_cv_sysconfdir=/etc + else + libc_cv_sysconfdir=$sysconfdir + fi + libc_cv_rootsbindir=/sbin + ;; +esac diff --git a/libc/sysdeps/i386/fpu/e_exp10l.S b/libc/sysdeps/i386/fpu/e_exp10l.S index 04ec8001d..d843e2b5e 100644 --- a/libc/sysdeps/i386/fpu/e_exp10l.S +++ b/libc/sysdeps/i386/fpu/e_exp10l.S @@ -1,39 +1,2 @@ -/* - * Written by Ulrich Drepper <drepper@cygnus.com>. - */ - -#include <machine/asm.h> - -/* 10^x = 2^(x * log2l(10)) */ -ENTRY(__ieee754_exp10l) - fldt 4(%esp) -/* I added the following ugly construct because expl(+-Inf) resulted - in NaN. The ugliness results from the bright minds at Intel. - For the i686 the code can be written better. - -- drepper@cygnus.com. */ - fxam /* Is NaN or +-Inf? */ - fstsw %ax - movb $0x45, %dh - andb %ah, %dh - cmpb $0x05, %dh - je 1f /* Is +-Inf, jump. */ - fldl2t - fmulp /* x * log2(10) */ - fld %st - frndint /* int(x * log2(10)) */ - fsubr %st,%st(1) /* fract(x * log2(10)) */ - fxch - f2xm1 /* 2^(fract(x * log2(10))) - 1 */ - fld1 - faddp /* 2^(fract(x * log2(10))) */ - fscale /* e^x */ - fstp %st(1) - ret - -1: testl $0x200, %eax /* Test sign. */ - jz 2f /* If positive, jump. */ - fstp %st - fldz /* Set result to 0. */ -2: ret -END (__ieee754_exp10l) -strong_alias (__ieee754_exp10l, __exp10l_finite) +#define USE_AS_EXP10L +#include <e_expl.S> diff --git a/libc/sysdeps/i386/fpu/e_expl.S b/libc/sysdeps/i386/fpu/e_expl.S index 45c4d0753..bab0a081b 100644 --- a/libc/sysdeps/i386/fpu/e_expl.S +++ b/libc/sysdeps/i386/fpu/e_expl.S @@ -24,9 +24,33 @@ #include <machine/asm.h> +#ifdef USE_AS_EXP10L +# define IEEE754_EXPL __ieee754_exp10l +# define EXPL_FINITE __exp10l_finite +# define FLDLOG fldl2t +#elif defined USE_AS_EXPM1L +# define IEEE754_EXPL __expm1l +# undef EXPL_FINITE +# define FLDLOG fldl2e +#else +# define IEEE754_EXPL __ieee754_expl +# define EXPL_FINITE __expl_finite +# define FLDLOG fldl2e +#endif + .section .rodata.cst16,"aM",@progbits,16 .p2align 4 +#ifdef USE_AS_EXP10L + ASM_TYPE_DIRECTIVE(c0,@object) +c0: .byte 0, 0, 0, 0, 0, 0, 0x9a, 0xd4, 0x00, 0x40 + .byte 0, 0, 0, 0, 0, 0 + ASM_SIZE_DIRECTIVE(c0) + ASM_TYPE_DIRECTIVE(c1,@object) +c1: .byte 0x58, 0x92, 0xfc, 0x15, 0x37, 0x9a, 0x97, 0xf0, 0xef, 0x3f + .byte 0, 0, 0, 0, 0, 0 + ASM_SIZE_DIRECTIVE(c1) +#else ASM_TYPE_DIRECTIVE(c0,@object) c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f .byte 0, 0, 0, 0, 0, 0 @@ -35,6 +59,7 @@ c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f c1: .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f .byte 0, 0, 0, 0, 0, 0 ASM_SIZE_DIRECTIVE(c1) +#endif ASM_TYPE_DIRECTIVE(csat,@object) csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40 .byte 0, 0, 0, 0, 0, 0 @@ -47,7 +72,13 @@ csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40 #endif .text -ENTRY(__ieee754_expl) +ENTRY(IEEE754_EXPL) +#ifdef USE_AS_EXPM1L + movzwl 4+8(%esp), %eax + xorb $0x80, %ah // invert sign bit (now 1 is "positive") + cmpl $0xc006, %eax // is num positive and exp >= 6 (number is >= 128.0)? + jae HIDDEN_JUMPTARGET (__expl) // (if num is denormal, it is at least >= 64.0) +#endif fldt 4(%esp) /* I added the following ugly construct because expl(+-Inf) resulted in NaN. The ugliness results from the bright minds at Intel. @@ -57,7 +88,9 @@ ENTRY(__ieee754_expl) #ifdef PIC LOAD_PIC_REG (cx) #endif +#ifndef USE_AS_EXPM1L movzwl 4+8(%esp), %eax +#endif andl $0x7fff, %eax cmpl $0x400d, %eax jle 3f @@ -75,8 +108,17 @@ ENTRY(__ieee754_expl) andb $2, %ah jz 3f fchs -3: fldl2e /* 1 log2(e) */ - fmul %st(1), %st /* 1 x log2(e) */ +3: +#ifdef USE_AS_EXPM1L + /* Test for +-0 as argument. */ + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x40, %dh + je 2f +#endif + FLDLOG /* 1 log2(base) */ + fmul %st(1), %st /* 1 x log2(base) */ frndint /* 1 i */ fld %st(1) /* 2 x */ frndint /* 2 xi */ @@ -92,18 +134,40 @@ ENTRY(__ieee754_expl) fldt MO(c1) /* 4 */ fmul %st(4), %st /* 4 c1 * x */ faddp %st, %st(1) /* 3 f = f + c1 * x */ - f2xm1 /* 3 2^(fract(x * log2(e))) - 1 */ + f2xm1 /* 3 2^(fract(x * log2(base))) - 1 */ +#ifdef USE_AS_EXPM1L + fstp %st(1) /* 2 */ + fscale /* 2 scale factor is st(1); base^x - 2^i */ + fxch /* 2 i */ + fld1 /* 3 1.0 */ + fscale /* 3 2^i */ + fld1 /* 4 1.0 */ + fsubrp %st, %st(1) /* 3 2^i - 1.0 */ + fstp %st(1) /* 2 */ + faddp %st, %st(1) /* 1 base^x - 1.0 */ +#else fld1 /* 4 1.0 */ - faddp /* 3 2^(fract(x * log2(e))) */ + faddp /* 3 2^(fract(x * log2(base))) */ fstp %st(1) /* 2 */ - fscale /* 2 scale factor is st(1); e^x */ + fscale /* 2 scale factor is st(1); base^x */ fstp %st(1) /* 1 */ +#endif fstp %st(1) /* 0 */ jmp 2f 1: testl $0x200, %eax /* Test sign. */ jz 2f /* If positive, jump. */ fstp %st +#ifdef USE_AS_EXPM1L + fld1 + fchs +#else fldz /* Set result to 0. */ +#endif 2: ret -END(__ieee754_expl) -strong_alias (__ieee754_expl, __expl_finite) +END(IEEE754_EXPL) +#ifdef USE_AS_EXPM1L +libm_hidden_def (__expm1l) +weak_alias (__expm1l, expm1l) +#else +strong_alias (IEEE754_EXPL, EXPL_FINITE) +#endif diff --git a/libc/sysdeps/i386/fpu/libm-test-ulps b/libc/sysdeps/i386/fpu/libm-test-ulps index 63235537e..cdc26a0c6 100644 --- a/libc/sysdeps/i386/fpu/libm-test-ulps +++ b/libc/sysdeps/i386/fpu/libm-test-ulps @@ -1008,10 +1008,6 @@ Test "cos_upward (9) == -0.9111302618846769883682947111811653112463": ildouble: 1 ldouble: 1 -# cosh -Test "cosh (0.75) == 1.29468328467684468784170818539018176": -ildouble: 1 - # cosh_downward Test "cosh_downward (22) == 1792456423.065795780980053377632656584997": double: 1 @@ -1899,29 +1895,20 @@ double: 1 float: 1 idouble: 1 ifloat: 1 -ildouble: 4 -ldouble: 4 +ildouble: 2 +ldouble: 2 Test "sinh_downward (23) == 4872401723.124451299966006944252978187305": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "sinh_downward (24) == 13244561064.92173614705070540368454568168": float: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 - -# sinh_tonearest -Test "sinh_tonearest (22) == 1792456423.065795780701106568345764104225": -ildouble: 3 -ldouble: 3 -Test "sinh_tonearest (23) == 4872401723.124451299966006944252978187305": -ildouble: 1 -ldouble: 1 -Test "sinh_tonearest (24) == 13244561064.92173614705070540368454568168": -ildouble: 6 -ldouble: 6 +ildouble: 2 +ldouble: 2 # sinh_towardzero Test "sinh_towardzero (22) == 1792456423.065795780701106568345764104225": @@ -1929,31 +1916,31 @@ double: 1 float: 1 idouble: 1 ifloat: 1 -ildouble: 4 -ldouble: 4 +ildouble: 2 +ldouble: 2 Test "sinh_towardzero (23) == 4872401723.124451299966006944252978187305": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "sinh_towardzero (24) == 13244561064.92173614705070540368454568168": float: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 +ildouble: 2 +ldouble: 2 # sinh_upward Test "sinh_upward (22) == 1792456423.065795780701106568345764104225": -ildouble: 16 -ldouble: 16 +ildouble: 1 +ldouble: 1 Test "sinh_upward (23) == 4872401723.124451299966006944252978187305": -ildouble: 27 -ldouble: 27 +ildouble: 1 +ldouble: 1 Test "sinh_upward (24) == 13244561064.92173614705070540368454568168": double: 1 idouble: 1 -ildouble: 7 -ldouble: 7 # tan Test "tan (0x1p16383) == 0.422722393732022337800504160054440141575": @@ -2587,9 +2574,6 @@ ifloat: 1 ildouble: 1 ldouble: 1 -Function: "cosh": -ildouble: 1 - Function: "cosh_downward": double: 1 float: 1 @@ -2862,26 +2846,22 @@ double: 1 float: 1 idouble: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 - -Function: "sinh_tonearest": -ildouble: 6 -ldouble: 6 +ildouble: 2 +ldouble: 2 Function: "sinh_towardzero": double: 1 float: 1 idouble: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 +ildouble: 2 +ldouble: 2 Function: "sinh_upward": double: 1 idouble: 1 -ildouble: 27 -ldouble: 27 +ildouble: 1 +ldouble: 1 Function: "tan": double: 1 diff --git a/libc/sysdeps/i386/fpu/s_expm1l.S b/libc/sysdeps/i386/fpu/s_expm1l.S index e91f18b69..7fbd99b0d 100644 --- a/libc/sysdeps/i386/fpu/s_expm1l.S +++ b/libc/sysdeps/i386/fpu/s_expm1l.S @@ -1,89 +1,2 @@ -/* ix87 specific implementation of exp(x)-1. - Copyright (C) 1996-1997, 2002, 2005, 2008, 2012 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. - Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>. - Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - - /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */ - -#include <sysdep.h> -#include <machine/asm.h> - - .section .rodata - - .align ALIGNARG(4) - ASM_TYPE_DIRECTIVE(minus1,@object) -minus1: .double -1.0 - ASM_SIZE_DIRECTIVE(minus1) - ASM_TYPE_DIRECTIVE(one,@object) -one: .double 1.0 - ASM_SIZE_DIRECTIVE(one) - ASM_TYPE_DIRECTIVE(l2e,@object) -l2e: .tfloat 1.442695040888963407359924681002 - ASM_SIZE_DIRECTIVE(l2e) - -#ifdef PIC -#define MO(op) op##@GOTOFF(%edx) -#else -#define MO(op) op -#endif - - .text -ENTRY(__expm1l) - movzwl 4+8(%esp), %eax // load sign bit and 15-bit exponent - xorb $0x80, %ah // invert sign bit (now 1 is "positive") - cmpl $0xc006, %eax // is num positive and exp >= 6 (number is >= 128.0)? - jae HIDDEN_JUMPTARGET (__expl) // (if num is denormal, it is at least >= 64.0) - - fldt 4(%esp) // x - fxam // Is NaN or +-Inf? - fstsw %ax - movb $0x45, %ch - andb %ah, %ch - cmpb $0x40, %ch - je 3f // If +-0, jump. -#ifdef PIC - LOAD_PIC_REG (dx) -#endif - cmpb $0x05, %ch - je 2f // If +-Inf, jump. - - fldt MO(l2e) // log2(e) : x - fmulp // log2(e)*x - fld %st // log2(e)*x : log2(e)*x - frndint // int(log2(e)*x) : log2(e)*x - fsubr %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x) - fxch // fract(log2(e)*x) : int(log2(e)*x) - f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x) - fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x) - fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fscale // 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fsubrl MO(one) // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fstp %st(1) // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fsubrp %st, %st(1) // 2^(log2(e)*x) - ret - -2: testl $0x200, %eax // Test sign. - jz 3f // If positive, jump. - fstp %st - fldl MO(minus1) // Set result to -1.0. -3: ret -END(__expm1l) -libm_hidden_def (__expm1l) -weak_alias (__expm1l, expm1l) +#define USE_AS_EXPM1L +#include <e_expl.S> diff --git a/libc/sysdeps/ieee754/dbl-64/e_exp10.c b/libc/sysdeps/ieee754/dbl-64/e_exp10.c new file mode 100644 index 000000000..eeb63a698 --- /dev/null +++ b/libc/sysdeps/ieee754/dbl-64/e_exp10.c @@ -0,0 +1,48 @@ +/* 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> + +static const double log10_high = 0x2.4d7637p0; +static const double log10_low = 0x7.6aaa2b05ba95cp-28; + +double +__ieee754_exp10 (double arg) +{ + int32_t lx; + double arg_high, arg_low; + double exp_high, exp_low; + + if (!__finite (arg)) + return __ieee754_exp (arg); + if (arg < DBL_MIN_10_EXP - DBL_DIG - 10) + return DBL_MIN * DBL_MIN; + else if (arg > DBL_MAX_10_EXP + 1) + return DBL_MAX * DBL_MAX; + + GET_LOW_WORD (lx, arg); + lx &= 0xf8000000; + arg_high = arg; + SET_LOW_WORD (arg_high, lx); + arg_low = arg - arg_high; + exp_high = arg_high * log10_high; + exp_low = arg_high * log10_low + arg_low * M_LN10; + return __ieee754_exp (exp_high) * __ieee754_exp (exp_low); +} +strong_alias (__ieee754_exp10, __exp10_finite) diff --git a/libc/sysdeps/ieee754/dbl-64/s_logb.c b/libc/sysdeps/ieee754/dbl-64/s_logb.c index 2382fbb41..baa35e14d 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_logb.c +++ b/libc/sysdeps/ieee754/dbl-64/s_logb.c @@ -10,10 +10,6 @@ * ==================================================== */ -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: s_logb.c,v 1.8 1995/05/10 20:47:50 jtc Exp $"; -#endif - /* * double logb(x) * IEEE 754 logb. Included to pass IEEE test suite. Not recommend. @@ -23,20 +19,29 @@ static char rcsid[] = "$NetBSD: s_logb.c,v 1.8 1995/05/10 20:47:50 jtc Exp $"; #include <math.h> #include <math_private.h> -double __logb(double x) +double +__logb (double x) { - int32_t lx,ix; - EXTRACT_WORDS(ix,lx,x); - ix &= 0x7fffffff; /* high |x| */ - if((ix|lx)==0) return -1.0/fabs(x); - if(ix>=0x7ff00000) return x*x; - if((ix>>=20)==0) /* IEEE 754 logb */ - return -1022.0; - else - return (double) (ix-1023); + int32_t lx, ix, rix; + + EXTRACT_WORDS (ix, lx, x); + ix &= 0x7fffffff; /* high |x| */ + if ((ix | lx) == 0) + return -1.0 / fabs (x); + if (ix >= 0x7ff00000) + return x * x; + if (__builtin_expect ((rix = ix >> 20) == 0, 0)) + { + /* POSIX specifies that denormal number is treated as + though it were normalized. */ + int m1 = (ix == 0) ? 0 : __builtin_clz (ix); + int m2 = (lx == 0) ? 0 : __builtin_clz (lx); + int ma = (m1 == 0) ? m2 + 32 : m1; + return -1022.0 + (double)(11 - ma); + } + return (double) (rix - 1023); } weak_alias (__logb, logb) #ifdef NO_LONG_DOUBLE -strong_alias (__logb, __logbl) -weak_alias (__logb, logbl) +strong_alias (__logb, __logbl) weak_alias (__logb, logbl) #endif diff --git a/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_logb.c b/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_logb.c index 2ad6c7ddb..474eeef36 100644 --- a/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_logb.c +++ b/libc/sysdeps/ieee754/dbl-64/wordsize-64/s_logb.c @@ -1,5 +1,5 @@ /* Compute radix independent exponent. - Copyright (C) 2011 Free Software Foundation, Inc. + Copyright (C) 2011, 2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@gmail.com>, 2011. @@ -25,16 +25,21 @@ double __logb (double x) { - int64_t ix; + int64_t ix, ex; EXTRACT_WORDS64 (ix, x); ix &= UINT64_C(0x7fffffffffffffff); if (ix == 0) return -1.0 / fabs (x); - unsigned int ex = ix >> 52; + ex = ix >> 52; if (ex == 0x7ff) return x * x; - return ex == 0 ? -1022.0 : (double) (ex - 1023); + if (__builtin_expect (ex == 0, 0)) + { + int m = (ix == 0) ? 0 : __builtin_clzl (ix); + return -1022.0 + (double)(11 -m); + } + return (double) (ex - 1023); } weak_alias (__logb, logb) #ifdef NO_LONG_DOUBLE diff --git a/libc/sysdeps/ieee754/flt-32/s_logbf.c b/libc/sysdeps/ieee754/flt-32/s_logbf.c index b6aa0f057..025c70de7 100644 --- a/libc/sysdeps/ieee754/flt-32/s_logbf.c +++ b/libc/sysdeps/ieee754/flt-32/s_logbf.c @@ -13,23 +13,27 @@ * ==================================================== */ -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: s_logbf.c,v 1.4 1995/05/10 20:47:51 jtc Exp $"; -#endif - #include <math.h> #include <math_private.h> -float __logbf(float x) +float +__logbf (float x) { - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; /* high |x| */ - if(ix==0) return (float)-1.0/fabsf(x); - if(ix>=0x7f800000) return x*x; - if((ix>>=23)==0) /* IEEE 754 logb */ - return -126.0; - else - return (float) (ix-127); + int32_t ix, rix; + + GET_FLOAT_WORD (ix, x); + ix &= 0x7fffffff; /* high |x| */ + if (ix == 0) + return (float) -1.0 / fabsf (x); + if (ix >= 0x7f800000) + return x * x; + if (__builtin_expect ((rix = ix >> 23) == 0, 0)) + { + /* POSIX specifies that denormal number is treated as + though it were normalized. */ + int m = (ix == 0) ? 0 : __builtin_clz (ix); + return -126.0 + (float)(8 - m); + } + return (float) (rix - 127); } weak_alias (__logbf, logbf) diff --git a/libc/sysdeps/ieee754/ldbl-128/e_exp10l.c b/libc/sysdeps/ieee754/ldbl-128/e_exp10l.c new file mode 100644 index 000000000..503c1de3e --- /dev/null +++ b/libc/sysdeps/ieee754/ldbl-128/e_exp10l.c @@ -0,0 +1,47 @@ +/* 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> + +static const long double log10_high = 0x2.4d763776aaa2bp0L; +static const long double log10_low = 0x5.ba95b58ae0b4c28a38a3fb3e7698p-60L; + +long double +__ieee754_exp10l (long double arg) +{ + ieee854_long_double_shape_type u; + long double arg_high, arg_low; + long double exp_high, exp_low; + + if (!__finitel (arg)) + return __ieee754_expl (arg); + if (arg < LDBL_MIN_10_EXP - LDBL_DIG - 10) + return LDBL_MIN * LDBL_MIN; + else if (arg > LDBL_MAX_10_EXP + 1) + return LDBL_MAX * LDBL_MAX; + + u.value = arg; + u.parts64.lsw &= 0xfe00000000000000LL; + arg_high = u.value; + arg_low = arg - arg_high; + exp_high = arg_high * log10_high; + exp_low = arg_high * log10_low + arg_low * M_LN10l; + return __ieee754_expl (exp_high) * __ieee754_expl (exp_low); +} +strong_alias (__ieee754_exp10l, __exp10l_finite) diff --git a/libc/sysdeps/ieee754/ldbl-128/s_logbl.c b/libc/sysdeps/ieee754/ldbl-128/s_logbl.c index 0b09b289c..cf6003e05 100644 --- a/libc/sysdeps/ieee754/ldbl-128/s_logbl.c +++ b/libc/sysdeps/ieee754/ldbl-128/s_logbl.c @@ -26,16 +26,27 @@ static char rcsid[] = "$NetBSD: $"; #include <math.h> #include <math_private.h> -long double __logbl(long double x) +long double +__logbl (long double x) { - int64_t lx,hx; - GET_LDOUBLE_WORDS64(hx,lx,x); - hx &= 0x7fffffffffffffffLL; /* high |x| */ - if((hx|lx)==0) return -1.0/fabs(x); - if(hx>=0x7fff000000000000LL) return x*x; - if((hx>>=48)==0) /* IEEE 754 logb */ - return -16382.0; - else - return (long double) (hx-0x3fff); + int64_t lx, hx, ex; + + GET_LDOUBLE_WORDS64 (hx, lx, x); + hx &= 0x7fffffffffffffffLL; /* high |x| */ + if ((hx | lx) == 0) + return -1.0 / fabs (x); + if (hx >= 0x7fff000000000000LL) + return x * x; + if ((ex = hx >> 48) == 0) /* IEEE 754 logb */ + { + /* POSIX specifies that denormal number is treated as + though it were normalized. */ + int m1 = (hx == 0) ? 0 : __builtin_clzll (hx); + int m2 = (lx == 0) ? 0 : __builtin_clzll (lx); + int ma = (m1 == 0) ? m2 + 64 : m1; + return -16382.0 + (long double)(15 - ma); + } + return (long double) (ex - 16383); } + weak_alias (__logbl, logbl) diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c new file mode 100644 index 000000000..b19e6c7f0 --- /dev/null +++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c @@ -0,0 +1,46 @@ +/* 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> + +static const long double log10_high = 0x2.4d763776aaa2cp0L; +static const long double log10_low = -0xf.a456a4a751f4b3d75c75c04c18p-56L; + +long double +__ieee754_exp10l (long double arg) +{ + union ibm_extended_long_double u; + long double arg_high, arg_low; + long double exp_high, exp_low; + + if (!__finitel (arg)) + return __ieee754_expl (arg); + if (arg < LDBL_MIN_10_EXP - LDBL_DIG - 10) + return LDBL_MIN * LDBL_MIN; + else if (arg > LDBL_MAX_10_EXP + 1) + return LDBL_MAX * LDBL_MAX; + + u.d = arg; + arg_high = u.dd[0]; + arg_low = u.dd[1]; + exp_high = arg_high * log10_high; + exp_low = arg_high * log10_low + arg_low * M_LN10l; + return __ieee754_expl (exp_high) * __ieee754_expl (exp_low); +} +strong_alias (__ieee754_exp10l, __exp10l_finite) diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c index f38b12997..678b6cad5 100644 --- a/libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c +++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c @@ -13,10 +13,6 @@ * ==================================================== */ -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - /* * long double logbl(x) * IEEE 754 logb. Included to pass IEEE test suite. Not recommend. @@ -27,16 +23,27 @@ static char rcsid[] = "$NetBSD: $"; #include <math_private.h> #include <math_ldbl_opt.h> -long double __logbl(long double x) +long double +__logbl (long double x) { - int64_t lx,hx; - GET_LDOUBLE_WORDS64(hx,lx,x); - hx &= 0x7fffffffffffffffLL; /* high |x| */ - if((hx|(lx&0x7fffffffffffffffLL))==0) return -1.0/fabs(x); - if(hx>=0x7ff0000000000000LL) return x*x; - if((hx>>=52)==0) /* IEEE 754 logb */ - return -1022.0; - else - return (long double) (hx-0x3ff); + int64_t lx, hx, rhx; + + GET_LDOUBLE_WORDS64 (hx, lx, x); + hx &= 0x7fffffffffffffffLL; /* high |x| */ + if ((hx | (lx & 0x7fffffffffffffffLL)) == 0) + return -1.0 / fabs (x); + if (hx >= 0x7ff0000000000000LL) + return x * x; + if (__builtin_expect ((rhx = hx >> 52) == 0, 0)) + { + /* POSIX specifies that denormal number is treated as + though it were normalized. */ + int m1 = (hx == 0) ? 0 : __builtin_clzll (hx); + int m2 = (lx == 0) ? 0 : __builtin_clzll (lx); + int ma = (m1 == 0) ? m2 + 64 : m1; + return -1022.0 + (long double)(11 - ma); + } + return (long double) (rhx - 1023); } + long_double_symbol (libm, __logbl, logbl); diff --git a/libc/sysdeps/ieee754/ldbl-96/s_logbl.c b/libc/sysdeps/ieee754/ldbl-96/s_logbl.c index 95b644c03..d8ad4bcfc 100644 --- a/libc/sysdeps/ieee754/ldbl-96/s_logbl.c +++ b/libc/sysdeps/ieee754/ldbl-96/s_logbl.c @@ -14,10 +14,6 @@ * ==================================================== */ -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - /* * long double logbl(x) * IEEE 754 logb. Included to pass IEEE test suite. Not recommend. @@ -27,16 +23,27 @@ static char rcsid[] = "$NetBSD: $"; #include <math.h> #include <math_private.h> -long double __logbl(long double x) +long double +__logbl (long double x) { - int32_t es,lx,ix; - GET_LDOUBLE_WORDS(es,ix,lx,x); - es &= 0x7fff; /* exponent */ - if((es|ix|lx)==0) return -1.0/fabs(x); - if(es==0x7fff) return x*x; - if(es==0) /* IEEE 754 logb */ - return -16382.0; - else - return (long double) (es-0x3fff); + int32_t es, lx, ix; + + GET_LDOUBLE_WORDS (es, ix, lx, x); + es &= 0x7fff; /* exponent */ + if ((es | ix | lx) == 0) + return -1.0 / fabs (x); + if (es == 0x7fff) + return x * x; + if (es == 0) /* IEEE 754 logb */ + { + /* POSIX specifies that denormal number is treated as + though it were normalized. */ + int m1 = (ix == 0) ? 0 : __builtin_clz (ix); + int m2 = (lx == 0) ? 0 : __builtin_clz (lx); + int ma = (m1 == 0) ? m2 + 32 : m1; + return -16382.0 - (long double)(ma); + } + return (long double) (es - 16383); } + weak_alias (__logbl, logbl) diff --git a/libc/sysdeps/mach/bits/libc-lock.h b/libc/sysdeps/mach/bits/libc-lock.h index 0a627e75f..110e25e96 100644 --- a/libc/sysdeps/mach/bits/libc-lock.h +++ b/libc/sysdeps/mach/bits/libc-lock.h @@ -1,5 +1,5 @@ /* libc-internal interface for mutex locks. Mach cthreads version. - Copyright (C) 1996,97,98,2000,01, 2002 Free Software Foundation, Inc. + Copyright (C) 1996-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 @@ -115,6 +115,9 @@ struct __libc_once __libc_lock_unlock (ONCE_CONTROL.lock); \ } while (0) +/* Get once control variable. */ +#define __libc_once_get(ONCE_CONTROL) ((ONCE_CONTROL).done != 0) + #ifdef _LIBC /* We need portable names for some functions. E.g., when they are used as argument to __libc_cleanup_region_start. */ diff --git a/libc/sysdeps/mach/hurd/Makefile b/libc/sysdeps/mach/hurd/Makefile index 80749c257..107eaafb0 100644 --- a/libc/sysdeps/mach/hurd/Makefile +++ b/libc/sysdeps/mach/hurd/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1993-2004,2009,2011,2012 Free Software Foundation, Inc. +# Copyright (C) 1993-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 @@ -133,6 +133,7 @@ rpcuserlibs := $(common-objpfx)mach/libmachuser.so \ $(common-objpfx)hurd/libhurduser.so link-rpcuserlibs := $(rpcuserlibs:%user.so=%user-link.so) $(common-objpfx)libc.so: $(link-rpcuserlibs) +$(common-objpfx)linkobj/libc.so: $(link-rpcuserlibs) rpath-dirs += mach hurd # Make sure the `lib' pass builds the dummy shared objects so diff --git a/libc/sysdeps/mach/hurd/accept.c b/libc/sysdeps/mach/hurd/accept.c index 78b5c67d8..52dfdf8ba 100644 --- a/libc/sysdeps/mach/hurd/accept.c +++ b/libc/sysdeps/mach/hurd/accept.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1992,1993,1994,1997,1999,2002 Free Software Foundation, Inc. +/* Copyright (C) 1992-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,72 +16,16 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <fcntl.h> -#include <string.h> #include <sys/socket.h> -#include <hurd.h> -#include <hurd/fd.h> -#include <hurd/socket.h> /* Await a connection on socket FD. When a connection arrives, open a new socket to communicate with it, - set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting + set *ADDRARG (which is *ADDR_LEN bytes long) to the address of the connecting peer and *ADDR_LEN to the address's actual length, and return the new socket's descriptor, or -1 for errors. */ int -accept (fd, addrarg, addr_len) - int fd; - __SOCKADDR_ARG addrarg; - socklen_t *addr_len; +accept (int fd, __SOCKADDR_ARG addrarg, socklen_t *addr_len) { - error_t err; - socket_t new; - addr_port_t aport; - struct sockaddr *addr = addrarg.__sockaddr__; - char *buf = (char *) addr; - mach_msg_type_number_t buflen; - int type; - - if (err = HURD_DPORT_USE (fd, __socket_accept (port, &new, &aport))) - return __hurd_dfail (fd, err); - - if (addr != NULL) - { - buflen = *addr_len; - err = __socket_whatis_address (aport, &type, &buf, &buflen); - if (err == EOPNOTSUPP) - /* If the protocol server can't tell us the address, just return a - zero-length one. */ - { - buf = (char *)addr; - buflen = 0; - err = 0; - } - } - __mach_port_deallocate (__mach_task_self (), aport); - - if (err) - { - __mach_port_deallocate (__mach_task_self (), new); - return __hurd_dfail (fd, err); - } - - if (addr != NULL) - { - if (*addr_len > buflen) - *addr_len = buflen; - - if (buf != (char *) addr) - { - memcpy (addr, buf, *addr_len); - __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); - } - - if (buflen > 0) - addr->sa_family = type; - } - - return _hurd_intern_fd (new, O_IGNORE_CTTY, 1); + return __libc_accept4 (fd, addrarg, addr_len, 0); } libc_hidden_def (accept) diff --git a/libc/sysdeps/mach/hurd/accept4.c b/libc/sysdeps/mach/hurd/accept4.c new file mode 100644 index 000000000..eb4f95c9f --- /dev/null +++ b/libc/sysdeps/mach/hurd/accept4.c @@ -0,0 +1,99 @@ +/* Copyright (C) 1992-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; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <fcntl-internal.h> +#include <string.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/socket.h> + +/* Await a connection on socket FD. + When a connection arrives, open a new socket to communicate with it, + set *ADDRARG (which is *ADDR_LEN bytes long) to the address of the connecting + peer and *ADDR_LEN to the address's actual length, and return the + new socket's descriptor, or -1 for errors. The operation can be influenced + by the FLAGS parameter. */ +int +__libc_accept4 (int fd, __SOCKADDR_ARG addrarg, socklen_t *addr_len, int flags) +{ + error_t err; + socket_t new; + addr_port_t aport; + struct sockaddr *addr = addrarg.__sockaddr__; + char *buf = (char *) addr; + mach_msg_type_number_t buflen; + int type; + + flags = sock_to_o_flags (flags); + + if (flags & ~(O_CLOEXEC | O_NONBLOCK)) + return __hurd_fail (EINVAL); + + if (err = HURD_DPORT_USE (fd, __socket_accept (port, &new, &aport))) + return __hurd_dfail (fd, err); + + if (addr != NULL) + { + buflen = *addr_len; + err = __socket_whatis_address (aport, &type, &buf, &buflen); + if (err == EOPNOTSUPP) + /* If the protocol server can't tell us the address, just return a + zero-length one. */ + { + buf = (char *)addr; + buflen = 0; + err = 0; + } + } + __mach_port_deallocate (__mach_task_self (), aport); + + if (! err) + { + if (flags & O_NONBLOCK) + err = __io_set_some_openmodes (new, O_NONBLOCK); + /* TODO: do we need special ERR massaging after the previous call? */ + } + + if (err) + { + __mach_port_deallocate (__mach_task_self (), new); + return __hurd_dfail (fd, err); + } + + if (addr != NULL) + { + if (*addr_len > buflen) + *addr_len = buflen; + + if (buf != (char *) addr) + { + memcpy (addr, buf, *addr_len); + __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); + } + + if (buflen > 0) + addr->sa_family = type; + } + + return _hurd_intern_fd (new, O_IGNORE_CTTY | flags, 1); +} +libc_hidden_def (__libc_accept4) +weak_alias (__libc_accept4, accept4) diff --git a/libc/sysdeps/mach/hurd/bits/fcntl.h b/libc/sysdeps/mach/hurd/bits/fcntl.h index 4224bf18f..1d24c7399 100644 --- a/libc/sysdeps/mach/hurd/bits/fcntl.h +++ b/libc/sysdeps/mach/hurd/bits/fcntl.h @@ -1,6 +1,5 @@ /* O_*, F_*, FD_* bit values for GNU. - Copyright (C) 1993,1994,1996,1997,1998,1999,2000,2001,2004,2007 - Free Software Foundation, Inc. + Copyright (C) 1993-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,7 +53,9 @@ #ifdef __USE_GNU # define O_NOLINK 0x0040 /* No name mappings on final component. */ # define O_NOTRANS 0x0080 /* No translator on final component. */ +#endif +#ifdef __USE_XOPEN2K8 # define O_NOFOLLOW 0x00100000 /* Produce ENOENT if file is a symlink. */ # define O_DIRECTORY 0x00200000 /* Produce ENOTDIR if not a directory. */ #endif @@ -118,7 +119,7 @@ once the file has been opened. */ #define O_TRUNC 0x00010000 /* Truncate file to zero length. */ -#ifdef __USE_GNU +#ifdef __USE_XOPEN2K8 # define O_CLOEXEC 0x00400000 /* Set FD_CLOEXEC. */ #endif @@ -158,7 +159,7 @@ #define F_SETFD 2 /* Set file descriptor flags. */ #define F_GETFL 3 /* Get file status flags. */ #define F_SETFL 4 /* Set file status flags. */ -#if defined __USE_BSD || defined __USE_UNIX98 +#if defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K8 # define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ # define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ #endif @@ -166,7 +167,7 @@ #define F_SETLK 8 /* Set record locking info (non-blocking). */ #define F_SETLKW 9 /* Set record locking info (blocking). */ -#ifdef __USE_GNU +#ifdef __USE_XOPEN2K8 # define F_DUPFD_CLOEXEC 1030 /* Duplicate, set FD_CLOEXEC on new one. */ #endif diff --git a/libc/sysdeps/mach/hurd/bits/ioctls.h b/libc/sysdeps/mach/hurd/bits/ioctls.h index 65f2ec1dd..c4cfce65a 100644 --- a/libc/sysdeps/mach/hurd/bits/ioctls.h +++ b/libc/sysdeps/mach/hurd/bits/ioctls.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1992,93,96,97,98,99,2001,2007 Free Software Foundation, Inc. +/* Copyright (C) 1992-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 @@ -157,6 +157,7 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 }; _IOT_foobar is defined either in this file, or where struct foobar is defined. */ #define _IO(g, n) _IOC (IOC_VOID, (g), (n), 0) +#define _IOIW(g, n, t) _IOC (IOC_VOID, (g), (n), _IOC_ENCODE_TYPE (t)) #define _IOR(g, n, t) _IOC (IOC_OUT, (g), (n), _IOC_ENCODE_TYPE (t)) #define _IOW(g, n, t) _IOC (IOC_IN, (g), (n), _IOC_ENCODE_TYPE (t)) #define _IOWR(g, n, t) _IOC (IOC_INOUT, (g), (n), _IOC_ENCODE_TYPE (t)) diff --git a/libc/sysdeps/mach/hurd/bits/libc-lock.h b/libc/sysdeps/mach/hurd/bits/libc-lock.h index af531da54..d18a10c45 100644 --- a/libc/sysdeps/mach/hurd/bits/libc-lock.h +++ b/libc/sysdeps/mach/hurd/bits/libc-lock.h @@ -1,5 +1,5 @@ /* libc-internal interface for mutex locks. Hurd version using Mach cthreads. - Copyright (C) 1996,97,98,2000,01, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1996-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 @@ -187,6 +187,9 @@ struct __libc_once __libc_lock_unlock (ONCE_CONTROL.lock); \ } while (0) +/* Get once control variable. */ +#define __libc_once_get(ONCE_CONTROL) ((ONCE_CONTROL).done != 0) + #ifdef _LIBC /* We need portable names for some functions. E.g., when they are used as argument to __libc_cleanup_region_start. */ diff --git a/libc/sysdeps/mach/hurd/bits/posix_opt.h b/libc/sysdeps/mach/hurd/bits/posix_opt.h index 23d32ce76..3c0830710 100644 --- a/libc/sysdeps/mach/hurd/bits/posix_opt.h +++ b/libc/sysdeps/mach/hurd/bits/posix_opt.h @@ -1,5 +1,5 @@ /* Define POSIX options for GNU/Hurd. - Copyright (C) 1998,2000,2001,2002,2006,2009 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 @@ -30,6 +30,9 @@ /* Processes have a saved set-user-ID and a saved set-group-ID. */ #define _POSIX_SAVED_IDS 1 +/* Priority scheduling is not supported. */ +#undef _POSIX_PRIORITY_SCHEDULING + /* Synchronizing file data is supported, but msync is missing. */ #undef _POSIX_SYNCHRONIZED_IO @@ -59,6 +62,14 @@ #undef _POSIX_NO_TRUNC /* Overlong file names get error? */ #undef _POSIX_SYNC_IO /* File supports O_SYNC et al? */ +/* X/Open realtime support is not supported. */ +#undef _XOPEN_REALTIME + +/* X/Open thread realtime support is not supported. */ +#undef _XOPEN_REALTIME_THREADS + +/* XPG4.2 shared memory is not supported. */ +#undef _XOPEN_SHM /* We do not have the POSIX threads interface. */ #define _POSIX_THREADS -1 @@ -71,6 +82,12 @@ #define _POSIX_THREAD_PRIORITY_SCHEDULING -1 #define _POSIX_THREAD_ATTR_STACKSIZE -1 #define _POSIX_THREAD_ATTR_STACKADDR -1 +#define _POSIX_THREAD_PRIO_INHERIT -1 +#define _POSIX_THREAD_PRIO_PROTECT -1 +#ifdef __USE_XOPEN2K8 +# define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1 +# define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1 +#endif #define _POSIX_SEMAPHORES -1 /* Real-time signals are not yet supported. */ @@ -78,8 +95,11 @@ /* Asynchronous I/O might supported with the existing ABI. */ #define _POSIX_ASYNCHRONOUS_IO 0 +#undef _POSIX_ASYNC_IO /* Alternative name for Unix98. */ #define _LFS_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO +/* Support for prioritization is not available. */ +#undef _POSIX_PRIORITIZED_IO /* The LFS support in asynchronous I/O is also available. */ #define _LFS64_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO @@ -110,6 +130,9 @@ /* We cannot support the Timeouts option without _POSIX_THREADS. */ #define _POSIX_TIMEOUTS -1 +/* We do not support spinlocks. */ +#define _POSIX_SPIN_LOCKS -1 + /* The `spawn' function family is supported. */ #define _POSIX_SPAWN 200809L @@ -156,9 +179,4 @@ /* Typed memory objects are not available. */ #define _POSIX_TYPED_MEMORY_OBJECTS -1 -/* No support for priority inheritance or protection so far. */ -#define _POSIX_THREAD_PRIO_INHERIT -1 -#define _POSIX_THREAD_PRIO_PROTECT -1 - - #endif /* bits/posix_opt.h */ diff --git a/libc/sysdeps/mach/hurd/bits/socket.h b/libc/sysdeps/mach/hurd/bits/socket.h new file mode 100644 index 000000000..6d53599b3 --- /dev/null +++ b/libc/sysdeps/mach/hurd/bits/socket.h @@ -0,0 +1,362 @@ +/* System-specific socket constants and types. Hurd 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 + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef __BITS_SOCKET_H +#define __BITS_SOCKET_H 1 + +#ifndef _SYS_SOCKET_H +# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead." +#endif + +#define __need_size_t +#define __need_NULL +#include <stddef.h> + +#include <limits.h> /* XXX Is this allowed? */ +#include <bits/types.h> + +/* Type for length arguments in socket calls. */ +#ifndef __socklen_t_defined +typedef __socklen_t socklen_t; +# define __socklen_t_defined +#endif + + +/* Types of sockets. */ +enum __socket_type +{ + SOCK_STREAM = 1, /* Sequenced, reliable, connection-based + byte streams. */ +#define SOCK_STREAM SOCK_STREAM + SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams + of fixed maximum length. */ +#define SOCK_DGRAM SOCK_DGRAM + SOCK_RAW = 3, /* Raw protocol interface. */ +#define SOCK_RAW SOCK_RAW + SOCK_RDM = 4, /* Reliably-delivered messages. */ +#define SOCK_RDM SOCK_RDM + SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, + datagrams of fixed maximum length. */ +#define SOCK_SEQPACKET SOCK_SEQPACKET + +#define SOCK_MAX (SOCK_SEQPACKET + 1) + /* Mask which covers at least up to SOCK_MASK-1. The + remaining bits are used as flags. */ +#define SOCK_TYPE_MASK 0xf + + /* Flags to be ORed into the type parameter of socket and socketpair and + used for the flags parameter of accept4. */ + + SOCK_CLOEXEC = 0x00400000, /* Atomically set close-on-exec flag for the + new descriptor(s). */ +#define SOCK_CLOEXEC SOCK_CLOEXEC + + /* Changed from the O_NONBLOCK value (0x8, which is unusable for us as it is + conflicting with the original SOCK_* flags' values) to the Linux value + (04000). TODO: is there a ``better'' value? */ + SOCK_NONBLOCK = 0x0800 /* Atomically mark descriptor(s) as + non-blocking. */ +#define SOCK_NONBLOCK SOCK_NONBLOCK +}; + +/* Protocol families. */ +#define PF_UNSPEC 0 /* Unspecified. */ +#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */ +#define PF_UNIX PF_LOCAL /* Old BSD name for PF_LOCAL. */ +#define PF_FILE PF_LOCAL /* POSIX name for PF_LOCAL. */ +#define PF_INET 2 /* IP protocol family. */ +#define PF_IMPLINK 3 /* ARPAnet IMP protocol. */ +#define PF_PUP 4 /* PUP protocols. */ +#define PF_CHAOS 5 /* MIT Chaos protocols. */ +#define PF_NS 6 /* Xerox NS protocols. */ +#define PF_ISO 7 /* ISO protocols. */ +#define PF_OSI PF_ISO +#define PF_ECMA 8 /* ECMA protocols. */ +#define PF_DATAKIT 9 /* AT&T Datakit protocols. */ +#define PF_CCITT 10 /* CCITT protocols (X.25 et al). */ +#define PF_SNA 11 /* IBM SNA protocol. */ +#define PF_DECnet 12 /* DECnet protocols. */ +#define PF_DLI 13 /* Direct data link interface. */ +#define PF_LAT 14 /* DEC Local Area Transport protocol. */ +#define PF_HYLINK 15 /* NSC Hyperchannel protocol. */ +#define PF_APPLETALK 16 /* Don't use this. */ +#define PF_ROUTE 17 /* Internal Routing Protocol. */ +#define PF_LINK 18 /* Link layer interface. */ +#define PF_XTP 19 /* eXpress Transfer Protocol (no AF). */ +#define PF_COIP 20 /* Connection-oriented IP, aka ST II. */ +#define PF_CNT 21 /* Computer Network Technology. */ +#define PF_RTIP 22 /* Help Identify RTIP packets. **/ +#define PF_IPX 23 /* Novell Internet Protocol. */ +#define PF_SIP 24 /* Simple Internet Protocol. */ +#define PF_PIP 25 /* Help Identify PIP packets. */ +#define PF_INET6 26 /* IP version 6. */ +#define PF_MAX 27 + +/* Address families. */ +#define AF_UNSPEC PF_UNSPEC +#define AF_LOCAL PF_LOCAL +#define AF_UNIX PF_UNIX +#define AF_FILE PF_FILE +#define AF_INET PF_INET +#define AF_IMPLINK PF_IMPLINK +#define AF_PUP PF_PUP +#define AF_CHAOS PF_CHAOS +#define AF_NS PF_NS +#define AF_ISO PF_ISO +#define AF_OSI PF_OSI +#define AF_ECMA PF_ECMA +#define AF_DATAKIT PF_DATAKIT +#define AF_CCITT PF_CCITT +#define AF_SNA PF_SNA +#define AF_DECnet PF_DECnet +#define AF_DLI PF_DLI +#define AF_LAT PF_LAT +#define AF_HYLINK PF_HYLINK +#define AF_APPLETALK PF_APPLETALK +#define AF_ROUTE PF_ROUTE +#define AF_LINK PF_LINK +#define pseudo_AF_XTP PF_XTP +#define AF_COIP PF_COIP +#define AF_CNT PF_CNT +#define pseudo_AF_RTIP PF_RTIP +#define AF_IPX PF_IPX +#define AF_SIP PF_SIP +#define pseudo_AF_PIP PF_PIP +#define AF_INET6 PF_INET6 +#define AF_MAX PF_MAX + +/* Maximum queue length specifiable by listen. */ +#define SOMAXCONN 128 /* 5 on the origional 4.4 BSD. */ + +/* Get the definition of the macro to define the common sockaddr members. */ +#include <bits/sockaddr.h> + +/* Structure describing a generic socket address. */ +struct sockaddr + { + __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ + char sa_data[14]; /* Address data. */ + }; + + +/* Structure large enough to hold any socket address (with the historical + exception of AF_UNIX). We reserve 128 bytes. */ +#if ULONG_MAX > 0xffffffff +# define __ss_aligntype __uint64_t +#else +# define __ss_aligntype __uint32_t +#endif +#define _SS_SIZE 128 +#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype))) + +struct sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ + __ss_aligntype __ss_align; /* Force desired alignment. */ + char __ss_padding[_SS_PADSIZE]; + }; + + +/* Bits in the FLAGS argument to `send', `recv', et al. */ +enum + { + MSG_OOB = 0x01, /* Process out-of-band data. */ +#define MSG_OOB MSG_OOB + MSG_PEEK = 0x02, /* Peek at incoming messages. */ +#define MSG_PEEK MSG_PEEK + MSG_DONTROUTE = 0x04, /* Don't use local routing. */ +#define MSG_DONTROUTE MSG_DONTROUTE + MSG_EOR = 0x08, /* Data completes record. */ +#define MSG_EOR MSG_EOR + MSG_TRUNC = 0x10, /* Data discarded before delivery. */ +#define MSG_TRUNC MSG_TRUNC + MSG_CTRUNC = 0x20, /* Control data lost before delivery. */ +#define MSG_CTRUNC MSG_CTRUNC + MSG_WAITALL = 0x40, /* Wait for full request or error. */ +#define MSG_WAITALL MSG_WAITALL + MSG_DONTWAIT = 0x80, /* This message should be nonblocking. */ +#define MSG_DONTWAIT MSG_DONTWAIT + MSG_NOSIGNAL = 0x0400 /* Do not generate SIGPIPE on EPIPE. */ +#define MSG_NOSIGNAL MSG_NOSIGNAL + }; + + +/* Structure describing messages sent by + `sendmsg' and received by `recvmsg'. */ +struct msghdr + { + void *msg_name; /* Address to send to/receive from. */ + socklen_t msg_namelen; /* Length of address data. */ + + struct iovec *msg_iov; /* Vector of data to send/receive into. */ + int msg_iovlen; /* Number of elements in the vector. */ + + void *msg_control; /* Ancillary data (eg BSD filedesc passing). */ + socklen_t msg_controllen; /* Ancillary data buffer length. */ + + int msg_flags; /* Flags in received message. */ + }; + +/* Structure used for storage of ancillary data object information. */ +struct cmsghdr + { + socklen_t cmsg_len; /* Length of data in cmsg_data plus length + of cmsghdr structure. */ + int cmsg_level; /* Originating protocol. */ + int cmsg_type; /* Protocol specific type. */ +#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L + __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data. */ +#endif + }; + +/* Ancillary data object manipulation macros. */ +#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L +# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data) +#else +# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1)) +#endif + +#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg) + +#define CMSG_FIRSTHDR(mhdr) \ + ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \ + ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL) + +#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \ + & (size_t) ~(sizeof (size_t) - 1)) +#define CMSG_SPACE(len) (CMSG_ALIGN (len) \ + + CMSG_ALIGN (sizeof (struct cmsghdr))) +#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) + +extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, + struct cmsghdr *__cmsg) __THROW; +#ifdef __USE_EXTERN_INLINES +# ifndef _EXTERN_INLINE +# define _EXTERN_INLINE __extern_inline +# endif +_EXTERN_INLINE struct cmsghdr * +__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) +{ + if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) + /* The kernel header does this so there may be a reason. */ + return NULL; + + __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg + + CMSG_ALIGN (__cmsg->cmsg_len)); + if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control + + __mhdr->msg_controllen) + || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) + > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) + /* No more entries. */ + return NULL; + return __cmsg; +} +#endif /* Use `extern inline'. */ + +/* Socket level message types. */ +enum + { + SCM_RIGHTS = 0x01, /* Access rights (array of int). */ +#define SCM_RIGHTS SCM_RIGHTS + SCM_TIMESTAMP = 0x02, /* Timestamp (struct timeval). */ +#define SCM_TIMESTAMP SCM_TIMESTAMP + SCM_CREDS = 0x03 /* Process creds (struct cmsgcred). */ +#define SCM_CREDS SCM_CREDS + }; + +/* Unfortunately, BSD practice dictates this structure be of fixed size. + If there are more than CMGROUP_MAX groups, the list is truncated. + (On GNU systems, the `cmcred_euid' field is just the first in the + list of effective UIDs.) */ +#define CMGROUP_MAX 16 + +/* Structure delivered by SCM_CREDS. This describes the identity of the + sender of the data simultaneously received on the socket. By BSD + convention, this is included only when a sender on a AF_LOCAL socket + sends cmsg data of this type and size; the sender's structure is + ignored, and the system fills in the various IDs of the sender process. */ +struct cmsgcred + { + __pid_t cmcred_pid; + __uid_t cmcred_uid; + __uid_t cmcred_euid; + __gid_t cmcred_gid; + int cmcred_ngroups; + __gid_t cmcred_groups[CMGROUP_MAX]; + }; + +/* Protocol number used to manipulate socket-level options + with `getsockopt' and `setsockopt'. */ +#define SOL_SOCKET 0xffff + +/* Socket-level options for `getsockopt' and `setsockopt'. */ +enum + { + SO_DEBUG = 0x0001, /* Record debugging information. */ +#define SO_DEBUG SO_DEBUG + SO_ACCEPTCONN = 0x0002, /* Accept connections on socket. */ +#define SO_ACCEPTCONN SO_ACCEPTCONN + SO_REUSEADDR = 0x0004, /* Allow reuse of local addresses. */ +#define SO_REUSEADDR SO_REUSEADDR + SO_KEEPALIVE = 0x0008, /* Keep connections alive and send + SIGPIPE when they die. */ +#define SO_KEEPALIVE SO_KEEPALIVE + SO_DONTROUTE = 0x0010, /* Don't do local routing. */ +#define SO_DONTROUTE SO_DONTROUTE + SO_BROADCAST = 0x0020, /* Allow transmission of + broadcast messages. */ +#define SO_BROADCAST SO_BROADCAST + SO_USELOOPBACK = 0x0040, /* Use the software loopback to avoid + hardware use when possible. */ +#define SO_USELOOPBACK SO_USELOOPBACK + SO_LINGER = 0x0080, /* Block on close of a reliable + socket to transmit pending data. */ +#define SO_LINGER SO_LINGER + SO_OOBINLINE = 0x0100, /* Receive out-of-band data in-band. */ +#define SO_OOBINLINE SO_OOBINLINE + SO_REUSEPORT = 0x0200, /* Allow local address and port reuse. */ +#define SO_REUSEPORT SO_REUSEPORT + SO_SNDBUF = 0x1001, /* Send buffer size. */ +#define SO_SNDBUF SO_SNDBUF + SO_RCVBUF = 0x1002, /* Receive buffer. */ +#define SO_RCVBUF SO_RCVBUF + SO_SNDLOWAT = 0x1003, /* Send low-water mark. */ +#define SO_SNDLOWAT SO_SNDLOWAT + SO_RCVLOWAT = 0x1004, /* Receive low-water mark. */ +#define SO_RCVLOWAT SO_RCVLOWAT + SO_SNDTIMEO = 0x1005, /* Send timeout. */ +#define SO_SNDTIMEO SO_SNDTIMEO + SO_RCVTIMEO = 0x1006, /* Receive timeout. */ +#define SO_RCVTIMEO SO_RCVTIMEO + SO_ERROR = 0x1007, /* Get and clear error status. */ +#define SO_ERROR SO_ERROR + SO_STYLE = 0x1008, /* Get socket connection style. */ +#define SO_STYLE SO_STYLE + SO_TYPE = SO_STYLE /* Compatible name for SO_STYLE. */ +#define SO_TYPE SO_TYPE + }; + +/* Structure used to manipulate the SO_LINGER option. */ +struct linger + { + int l_onoff; /* Nonzero to linger on close. */ + int l_linger; /* Time to linger. */ + }; + +#endif /* bits/socket.h */ diff --git a/libc/sysdeps/mach/hurd/bits/stat.h b/libc/sysdeps/mach/hurd/bits/stat.h index 15fcda117..e6ffda892 100644 --- a/libc/sysdeps/mach/hurd/bits/stat.h +++ b/libc/sysdeps/mach/hurd/bits/stat.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1992-1994,1996,1997,1999,2000,2005,2010 - Free Software Foundation, Inc. +/* Copyright (C) 1992-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 @@ -58,12 +57,27 @@ struct stat __off64_t st_size; /* Size in bytes. */ #endif - __time_t st_atime; /* Access time, seconds */ - unsigned long int st_atime_usec; /* and microseconds. */ - __time_t st_mtime; /* Modification time, seconds */ - unsigned long int st_mtime_usec; /* and microseconds. */ - __time_t st_ctime; /* Status change time, seconds */ - unsigned long int st_ctime_usec; /* and microseconds. */ +#if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the + identifier 'timespec' to appear in the <sys/stat.h> header. + Therefore we have to handle the use of this header in strictly + standard-compliant sources special. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +# define st_atime st_atim.tv_sec /* Backward compatibility. */ +# define st_mtime st_mtim.tv_sec +# define st_ctime st_ctim.tv_sec +#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +#endif __blksize_t st_blksize; /* Optimal size for I/O. */ @@ -107,12 +121,24 @@ struct stat64 __off64_t st_size; /* Size in bytes. */ - __time_t st_atime; /* Access time, seconds */ - unsigned long int st_atime_usec; /* and microseconds. */ - __time_t st_mtime; /* Modification time, seconds */ - unsigned long int st_mtime_usec; /* and microseconds. */ - __time_t st_ctime; /* Status change time, seconds */ - unsigned long int st_ctime_usec; /* and microseconds. */ +#if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the + identifier 'timespec' to appear in the <sys/stat.h> header. + Therefore we have to handle the use of this header in strictly + standard-compliant sources special. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +#endif __blksize_t st_blksize; /* Optimal size for I/O. */ @@ -130,7 +156,10 @@ struct stat64 }; #endif -#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ +/* Tell code we have these members. */ +#define _STATBUF_ST_BLKSIZE +/* Nanosecond resolution time values are supported. */ +#define _STATBUF_ST_NSEC /* Encoding of the file mode. */ diff --git a/libc/sysdeps/mach/hurd/brk.c b/libc/sysdeps/mach/hurd/brk.c index 275d7bea3..1900277d1 100644 --- a/libc/sysdeps/mach/hurd/brk.c +++ b/libc/sysdeps/mach/hurd/brk.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,99,2000 Free Software Foundation, Inc. +/* 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 @@ -63,7 +63,7 @@ weak_alias (__brk, brk) int _hurd_set_brk (vm_address_t addr) { - error_t err; + error_t err = 0; vm_address_t pagend = round_page (addr); vm_address_t pagebrk = round_page (_hurd_brk); long int rlimit; @@ -100,8 +100,22 @@ _hurd_set_brk (vm_address_t addr) if (pagend > _hurd_data_end) { + vm_address_t alloc_start = _hurd_data_end; + /* We didn't allocate enough space! Hopefully we can get some more! */ - err = __vm_allocate (__mach_task_self (), &pagebrk, pagend - pagebrk, 0); + + if (_hurd_data_end > pagebrk) + /* First finish allocation. */ + err = __vm_protect (__mach_task_self (), pagebrk, + alloc_start - pagebrk, 0, + VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); + if (! err) + _hurd_brk = alloc_start; + + if (! err) + err = __vm_allocate (__mach_task_self (), &alloc_start, + pagend - alloc_start, 0); + if (! err) _hurd_data_end = pagend; } diff --git a/libc/sysdeps/mach/hurd/chroot.c b/libc/sysdeps/mach/hurd/chroot.c index 1a6b1e44d..95bee3317 100644 --- a/libc/sysdeps/mach/hurd/chroot.c +++ b/libc/sysdeps/mach/hurd/chroot.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,93,94,95,97,99,2001 Free Software Foundation, Inc. +/* 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 @@ -37,6 +37,9 @@ chroot (const char *path) len = strlen (path); if (len >= 2 && path[len - 2] == '/' && path[len - 1] == '.') lookup = path; + else if (len == 0) + /* Special-case empty file name according to POSIX. */ + return __hurd_fail (ENOENT); else { char *n = alloca (len + 3); diff --git a/libc/sysdeps/mach/hurd/configure b/libc/sysdeps/mach/hurd/configure index 37ac6771a..3c90a665a 100755 --- a/libc/sysdeps/mach/hurd/configure +++ b/libc/sysdeps/mach/hurd/configure @@ -130,11 +130,6 @@ $as_echo "#define NO_HIDDEN 1" >>confdefs.h # existing system library, because we are the only system library. inhibit_glue=yes -if test "x$prefix" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --prefix= (empty) is required for GNU/Hurd to work normally" >&5 -$as_echo "$as_me: WARNING: --prefix= (empty) is required for GNU/Hurd to work normally" >&2;} -fi - case "$machine" in i386*) # The default oldest ABI is 2.2.6. diff --git a/libc/sysdeps/mach/hurd/configure.in b/libc/sysdeps/mach/hurd/configure.in index 87c07c11d..622014226 100644 --- a/libc/sysdeps/mach/hurd/configure.in +++ b/libc/sysdeps/mach/hurd/configure.in @@ -10,10 +10,6 @@ AC_DEFINE([NO_HIDDEN]) # existing system library, because we are the only system library. inhibit_glue=yes -if test "x$prefix" != x; then - AC_MSG_WARN([--prefix= (empty) is required for GNU/Hurd to work normally]) -fi - case "$machine" in i386*) # The default oldest ABI is 2.2.6. diff --git a/libc/sysdeps/mach/hurd/dirfd.c b/libc/sysdeps/mach/hurd/dirfd.c index 587ae7b2f..42dbc7883 100644 --- a/libc/sysdeps/mach/hurd/dirfd.c +++ b/libc/sysdeps/mach/hurd/dirfd.c @@ -1,5 +1,5 @@ /* dirfd -- Return the file descriptor used by a DIR stream. Hurd version. - Copyright (C) 1995, 1996 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 @@ -25,6 +25,8 @@ int dirfd (DIR *dirp) { int fd; + + HURD_CRITICAL_BEGIN; __mutex_lock (&_hurd_dtable_lock); for (fd = 0; fd < _hurd_dtablesize; ++fd) if (_hurd_dtable[fd] == dirp->__fd) @@ -35,6 +37,7 @@ dirfd (DIR *dirp) fd = -1; } __mutex_unlock (&_hurd_dtable_lock); + HURD_CRITICAL_END; return fd; } diff --git a/libc/sysdeps/mach/hurd/dl-sysdep.c b/libc/sysdeps/mach/hurd/dl-sysdep.c index d928cd247..13b001043 100644 --- a/libc/sysdeps/mach/hurd/dl-sysdep.c +++ b/libc/sysdeps/mach/hurd/dl-sysdep.c @@ -1,6 +1,5 @@ /* Operating system support for run-time dynamic linker. Hurd version. - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2010 - 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,10 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* In the static library, this is all handled by dl-support.c + or by the vanilla definitions in the rest of the C library. */ +#ifdef SHARED + #include <hurd.h> #include <link.h> #include <unistd.h> @@ -315,7 +318,7 @@ open_file (const char *file_name, int flags, return MACH_PORT_NULL; } - assert (!(flags & ~O_READ)); + assert (!(flags & ~(O_READ | O_CLOEXEC))); startdir = _dl_hurd_data->portarray[file_name[0] == '/' ? INIT_PORT_CRDIR : INIT_PORT_CWDIR]; @@ -668,3 +671,5 @@ _dl_init_first (int argc, ...) { /* This no-op definition only gets used if libc is not linked in. */ } + +#endif /* SHARED */ diff --git a/libc/sysdeps/mach/hurd/dl-sysdep.h b/libc/sysdeps/mach/hurd/dl-sysdep.h index 671b24183..c64a39d92 100644 --- a/libc/sysdeps/mach/hurd/dl-sysdep.h +++ b/libc/sysdeps/mach/hurd/dl-sysdep.h @@ -1,5 +1,5 @@ /* System-specific settings for dynamic linker code. Hurd version. - Copyright (C) 2002, 2005 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 @@ -24,7 +24,8 @@ #define RTLD_PRIVATE_ERRNO 0 #ifdef SHARED -/* _dl_argv cannot be attribute_relro, because the stack-switching +/* _dl_argv and __libc_stack_end cannot be attribute_relro, because the stack-switching libc initializer for using cthreads might write into it. */ # define DL_ARGV_NOT_RELRO 1 +# define LIBC_STACK_END_NOT_RELRO 1 #endif diff --git a/libc/sysdeps/mach/hurd/dup2.c b/libc/sysdeps/mach/hurd/dup2.c index d2329c936..b697a90ec 100644 --- a/libc/sysdeps/mach/hurd/dup2.c +++ b/libc/sysdeps/mach/hurd/dup2.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991, 92, 93, 94, 95, 97, 2002 Free Software Foundation, Inc. +/* 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,119 +16,20 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <fcntl.h> #include <unistd.h> -#include <hurd.h> -#include <hurd/fd.h> /* Duplicate FD to FD2, closing the old FD2 and making FD2 be open on the same file as FD is. Return FD2 or -1. */ int -__dup2 (fd, fd2) - int fd; - int fd2; +__dup2 (int fd, int fd2) { - struct hurd_fd *d; - - /* Extract the ports and flags from FD. */ - d = _hurd_fd_get (fd); - if (d == NULL) - { - errno = EBADF; - return -1; - } - - HURD_CRITICAL_BEGIN; - - __spin_lock (&d->port.lock); - if (d->port.port == MACH_PORT_NULL) - { - __spin_unlock (&d->port.lock); - errno = EBADF; - fd2 = -1; - } - else if (fd2 == fd) - /* FD is valid and FD2 is already the same; just return it. */ - __spin_unlock (&d->port.lock); - else - { - struct hurd_userlink ulink, ctty_ulink; - int flags = d->flags; - io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink); - io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D. */ - - if (fd2 < 0) - { - errno = EBADF; - fd2 = -1; - } - else - { - /* Get a hold of the destination descriptor. */ - struct hurd_fd *d2; - - if (fd2 >= _hurd_dtablesize) - { - /* The table is not large enough to hold the destination - descriptor. Enlarge it as necessary to allocate this - descriptor. */ - __mutex_unlock (&_hurd_dtable_lock); - /* We still hold FD1's lock, but this is safe because - _hurd_alloc_fd will only examine the cells starting - at FD2. */ - d2 = _hurd_alloc_fd (NULL, fd2); - if (d2) - __spin_unlock (&d2->port.lock); - __mutex_lock (&_hurd_dtable_lock); - } - else - { - d2 = _hurd_dtable[fd2]; - if (d2 == NULL) - { - /* Must allocate a new one. We don't initialize the port - cells with this call so that if it fails (out of - memory), we will not have already added user - references for the ports, which we would then have to - deallocate. */ - d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL, - MACH_PORT_NULL); - } - } - - if (d2 == NULL) - { - fd2 = -1; - if (errno == EINVAL) - errno = EBADF; /* POSIX.1-1990 6.2.1.2 ll 54-55. */ - } - else - { - /* Give the ports each a user ref for the new descriptor. */ - __mach_port_mod_refs (__mach_task_self (), port, - MACH_PORT_RIGHT_SEND, 1); - if (ctty != MACH_PORT_NULL) - __mach_port_mod_refs (__mach_task_self (), ctty, - MACH_PORT_RIGHT_SEND, 1); - - /* Install the ports and flags in the new descriptor slot. */ - __spin_lock (&d2->port.lock); - d2->flags = flags & ~FD_CLOEXEC; /* Dup clears FD_CLOEXEC. */ - _hurd_port_set (&d2->ctty, ctty); - _hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */ - } - } - __mutex_unlock (&_hurd_dtable_lock); - - _hurd_port_free (&d->port, &ulink, port); - if (ctty != MACH_PORT_NULL) - _hurd_port_free (&d->ctty, &ctty_ulink, port); - } + int flags = 0; - HURD_CRITICAL_END; + if (fd2 == fd) + /* See the comment in dup3. */ + flags = -1; - return fd2; + return __dup3 (fd, fd2, flags); } libc_hidden_def (__dup2) weak_alias (__dup2, dup2) diff --git a/libc/sysdeps/mach/hurd/dup3.c b/libc/sysdeps/mach/hurd/dup3.c new file mode 100644 index 000000000..22318705d --- /dev/null +++ b/libc/sysdeps/mach/hurd/dup3.c @@ -0,0 +1,139 @@ +/* Duplicate a file descriptor to a given number, with flags. Hurd 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Duplicate FD to FD2, closing the old FD2 and making FD2 be + open on the same file as FD is, and setting FD2's flags according to FLAGS. + Return FD2 or -1. */ +int +__dup3 (int fd, int fd2, int flags) +{ + struct hurd_fd *d; + + /* Both passing flags different from O_CLOEXEC and FD2 being the same as FD + are invalid. */ + if ((flags & ~O_CLOEXEC + || fd2 == fd) + /* ... with the exception in case that dup2 behavior is requested: if FD + is valid and FD2 is already the same then just return it. */ + && ! (flags == -1 + && fd2 == fd)) + return __hurd_fail (EINVAL); + + /* Extract the ports and flags from FD. */ + d = _hurd_fd_get (fd); + if (d == NULL) + return __hurd_fail (EBADF); + + HURD_CRITICAL_BEGIN; + + __spin_lock (&d->port.lock); + if (d->port.port == MACH_PORT_NULL) + { + __spin_unlock (&d->port.lock); + fd2 = __hurd_fail (EBADF); + } + else if (fd2 == fd) + __spin_unlock (&d->port.lock); + else + { + struct hurd_userlink ulink, ctty_ulink; + int d_flags = d->flags; + io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink); + io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D. */ + + if (fd2 < 0) + fd2 = __hurd_fail (EBADF); + else + { + /* Get a hold of the destination descriptor. */ + struct hurd_fd *d2; + + __mutex_lock (&_hurd_dtable_lock); + + if (fd2 >= _hurd_dtablesize) + { + /* The table is not large enough to hold the destination + descriptor. Enlarge it as necessary to allocate this + descriptor. */ + __mutex_unlock (&_hurd_dtable_lock); + d2 = _hurd_alloc_fd (NULL, fd2); + if (d2) + __spin_unlock (&d2->port.lock); + __mutex_lock (&_hurd_dtable_lock); + } + else + { + d2 = _hurd_dtable[fd2]; + if (d2 == NULL) + { + /* Must allocate a new one. We don't initialize the port + cells with this call so that if it fails (out of + memory), we will not have already added user + references for the ports, which we would then have to + deallocate. */ + d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL, + MACH_PORT_NULL); + } + } + __mutex_unlock (&_hurd_dtable_lock); + + if (d2 == NULL) + { + fd2 = -1; + if (errno == EINVAL) + errno = EBADF; /* POSIX.1-1990 6.2.1.2 ll 54-55. */ + } + else + { + /* Give the ports each a user ref for the new descriptor. */ + __mach_port_mod_refs (__mach_task_self (), port, + MACH_PORT_RIGHT_SEND, 1); + if (ctty != MACH_PORT_NULL) + __mach_port_mod_refs (__mach_task_self (), ctty, + MACH_PORT_RIGHT_SEND, 1); + + /* Install the ports and flags in the new descriptor slot. */ + __spin_lock (&d2->port.lock); + if (flags & O_CLOEXEC) + d2->flags = d_flags | FD_CLOEXEC; + else + /* dup clears FD_CLOEXEC. */ + d2->flags = d_flags & ~FD_CLOEXEC; + _hurd_port_set (&d2->ctty, ctty); + _hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */ + } + } + + _hurd_port_free (&d->port, &ulink, port); + if (ctty != MACH_PORT_NULL) + _hurd_port_free (&d->ctty, &ctty_ulink, port); + } + + HURD_CRITICAL_END; + + return fd2; +} +libc_hidden_def (__dup3) +weak_alias (__dup3, dup3) diff --git a/libc/sysdeps/mach/hurd/i386/Makefile b/libc/sysdeps/mach/hurd/i386/Makefile index 0eef17e8f..5f988097c 100644 --- a/libc/sysdeps/mach/hurd/i386/Makefile +++ b/libc/sysdeps/mach/hurd/i386/Makefile @@ -2,3 +2,7 @@ ifeq ($(subdir),misc) sysdep_routines += ioperm sysdep_headers += sys/io.h endif + +ifeq ($(subdir),debug) +gen-as-const-headers += signal-defines.sym +endif diff --git a/libc/sysdeps/mach/hurd/i386/____longjmp_chk.S b/libc/sysdeps/mach/hurd/i386/____longjmp_chk.S new file mode 100644 index 000000000..f499fbd1e --- /dev/null +++ b/libc/sysdeps/mach/hurd/i386/____longjmp_chk.S @@ -0,0 +1,107 @@ +/* Copyright (C) 2001-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> +#include <jmpbuf-offsets.h> +#include <asm-syntax.h> + +#include <signal-defines.h> +/* #include <signal.h> */ +#define SS_ONSTACK 1 + + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + + +#ifdef PIC +# define CALL_FAIL movl %ebx, %ecx; /* TODO: what's this mov good for? */ \ + cfi_register(%ebx,%ecx); \ + LOAD_PIC_REG (bx); \ + leal longjmp_msg@GOTOFF(%ebx), %eax; \ + call HIDDEN_JUMPTARGET(__fortify_fail) +#else +# define CALL_FAIL movl $longjmp_msg, %eax; \ + call HIDDEN_JUMPTARGET(__fortify_fail) +#endif + + + .text +ENTRY (____longjmp_chk) + movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ + + /* Save the return address now. */ + movl (JB_PC*4)(%ecx), %edx + /* Get the stack pointer. */ + movl (JB_SP*4)(%ecx), %edi + cfi_undefined(%edi) + PTR_DEMANGLE (%edx) + PTR_DEMANGLE (%edi) + + cmpl %edi, %esp + /* Jumping to a higher-address frame is always allowed. */ + jbe .Lok + + /* Passing here, we're either about to do something invalid, or we're + executing on an alternative signal stack. */ + + /* TODO: need locking? */ + /* struct hurd_sigstate * _hurd_self_sigstate (void) */ + call _hurd_self_sigstate + /* TODO: %eax and %eax->sigaltstack are always valid? */ + + testl $SS_ONSTACK, (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_FLAGS__OFFSET)(%eax) + /* Fail if SS_ONSTACK is not set. */ + jz .Lfail + + movl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SP__OFFSET)(%eax), %ebx + addl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx + subl %edi, %ebx + cmpl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx + /* TODO: comment this calculation. */ + jae .Lok + +.Lfail: CALL_FAIL + +.Lok: /* We add unwind information for the target here. */ + cfi_def_cfa(%ecx, 0) + cfi_register(%eip, %edx) + cfi_register(%esp, %edi) + cfi_offset(%ebx, JB_BX*4) + cfi_offset(%esi, JB_SI*4) + cfi_offset(%edi, JB_DI*4) + cfi_offset(%ebp, JB_BP*4) + + movl 8(%esp), %eax /* Second argument is return value. */ + movl %edi, %esp + + /* Restore registers. */ + movl (JB_BX*4)(%ecx), %ebx + movl (JB_SI*4)(%ecx), %esi + movl (JB_DI*4)(%ecx), %edi + movl (JB_BP*4)(%ecx), %ebp + cfi_restore(%ebx) + cfi_restore(%esi) + cfi_restore(%edi) + cfi_restore(%ebp) + + /* Jump to saved PC. */ + jmp *%edx +END (____longjmp_chk) diff --git a/libc/sysdeps/mach/hurd/i386/init-first.c b/libc/sysdeps/mach/hurd/i386/init-first.c index 4785e8dbe..fa4e3d9f6 100644 --- a/libc/sysdeps/mach/hurd/i386/init-first.c +++ b/libc/sysdeps/mach/hurd/i386/init-first.c @@ -122,7 +122,7 @@ init1 (int argc, char *arg0, ...) { #ifndef SHARED /* We may need to see our own phdrs, e.g. for TLS setup. - Try the usual kludge to find the headers without help from + Try the usual kludge to find the headers without help from the exec server. */ extern const void _start; const ElfW(Ehdr) *const ehdr = &_start; @@ -214,6 +214,8 @@ init (int *data) void switch_stacks (void); + __libc_stack_end = newsp; + /* Copy per-thread variables from that temporary area onto the new cthread stack. */ memcpy (__hurd_threadvar_location_from_sp (0, newsp), @@ -225,7 +227,7 @@ init (int *data) #ifdef SHARED /* And readjust the dynamic linker's idea of where the argument - vector lives. */ + vector lives. */ assert (_dl_argv == argv); _dl_argv = (void *) (newsp + 1); #endif @@ -244,9 +246,16 @@ init (int *data) /* Push the user code address on the top of the new stack. It will be the return address for `init1'; we will jump there with NEWSP as the stack pointer. */ - *--newsp = data[-1]; - ((void **) data)[-1] = switch_stacks; - /* Force NEWSP into %ecx and &init1 into %eax, which are not restored + /* The following expression would typically be written as + ``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't + recognize that this read operation may alias the following write + operation, and thus is free to reorder the two, clobbering the + original return address. */ + *--newsp = *((int *) __builtin_frame_address (0) + 1); + /* GCC 4.4.6 also wants us to force loading *NEWSP already here. */ + asm volatile ("# %0" : : "X" (*newsp)); + *((void **) __builtin_frame_address (0) + 1) = &switch_stacks; + /* Force NEWSP into %eax and &init1 into %ecx, which are not restored by function return. */ asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1)); } @@ -273,8 +282,15 @@ init (int *data) /* The argument data is just above the stack frame we will unwind by returning. Mutate our own return address to run the code below. */ - usercode = data[-1]; - data[-1] = (int) &call_init1; + /* The following expression would typically be written as + ``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't + recognize that this read operation may alias the following write + operation, and thus is free to reorder the two, clobbering the + original return address. */ + usercode = *((int *) __builtin_frame_address (0) + 1); + /* GCC 4.4.6 also wants us to force loading USERCODE already here. */ + asm volatile ("# %0" : : "X" (usercode)); + *((void **) __builtin_frame_address (0) + 1) = &call_init1; /* Force USERCODE into %eax and &init1 into %ecx, which are not restored by function return. */ asm volatile ("# a %0 c %1" : : "a" (usercode), "c" (&init1)); @@ -322,11 +338,12 @@ first_init (void) stack set up just as the user will see it, so it can switch stacks. */ void -_dl_init_first (void) +_dl_init_first (int argc, ...) { first_init (); - init ((int *) __builtin_frame_address (0) + 2); + /* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets confused. */ + init (&argc); } #endif @@ -360,15 +377,17 @@ _hurd_stack_setup (void) void doinit (intptr_t *data) { /* This function gets called with the argument data at TOS. */ - void doinit1 (void) + void doinit1 (int argc, ...) { - init ((int *) __builtin_frame_address (0) + 2); + /* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets + confused. */ + init ((int *) &argc); } /* Push the user return address after the argument data, and then - jump to `doinit1' (above), so it is as if __libc_init_first's - caller had called `doinit1' with the argument data already on the - stack. */ + jump to `doinit1' (above), so it is as if __libc_init_first's + caller had called `doinit1' with the argument data already on the + stack. */ *--data = caller; asm volatile ("movl %0, %%esp\n" /* Switch to new outermost stack. */ "movl $0, %%ebp\n" /* Clear outermost frame pointer. */ diff --git a/libc/sysdeps/mach/hurd/i386/signal-defines.sym b/libc/sysdeps/mach/hurd/i386/signal-defines.sym new file mode 100644 index 000000000..9521bd723 --- /dev/null +++ b/libc/sysdeps/mach/hurd/i386/signal-defines.sym @@ -0,0 +1,10 @@ +#include <hurd/signal.h> +#include <signal.h> + +-- + +HURD_SIGSTATE__SIGALTSTACK__OFFSET offsetof(struct hurd_sigstate, sigaltstack) + +SIGALTSTACK__SS_SP__OFFSET offsetof(struct sigaltstack, ss_sp) +SIGALTSTACK__SS_SIZE__OFFSET offsetof(struct sigaltstack, ss_size) +SIGALTSTACK__SS_FLAGS__OFFSET offsetof(struct sigaltstack, ss_flags) diff --git a/libc/sysdeps/mach/hurd/ioctl.c b/libc/sysdeps/mach/hurd/ioctl.c index beffe4365..543d437c1 100644 --- a/libc/sysdeps/mach/hurd/ioctl.c +++ b/libc/sysdeps/mach/hurd/ioctl.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1992,93,94,95,96,97,99,2000,2002,2005 - Free Software Foundation, Inc. +/* Copyright (C) 1992-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 @@ -88,7 +87,7 @@ __ioctl (int fd, unsigned long int request, ...) void *p; #endif - void *arg; + void *arg = NULL; error_t err; @@ -111,7 +110,7 @@ __ioctl (int fd, unsigned long int request, ...) if (_IOC_INOUT (request) & IOC_IN) { /* We don't want to advance ARG since it will be used to copy out - too if IOC_OUT is also set. */ + too if IOC_OUT is also set. */ void *argptr = arg; /* Pack an argument into the message buffer. */ @@ -139,7 +138,7 @@ __ioctl (int fd, unsigned long int request, ...) in (_IOT_COUNT1 (type), _IOT_TYPE1 (type)); in (_IOT_COUNT2 (type), _IOT_TYPE2 (type)); } - else if (_IOC_INOUT (request) == IOC_VOID) + else if (_IOC_INOUT (request) == IOC_VOID && _IOT_COUNT0 (type) != 0) { /* The RPC takes a single integer_t argument. Rather than pointing to the value, ARG is the value itself. */ @@ -208,11 +207,15 @@ __ioctl (int fd, unsigned long int request, ...) return msg.header.RetCode; } - va_list ap; + if (_IOT_COUNT0 (type) != 0) + { + /* Data need either be sent, received, or even both. */ + va_list ap; - va_start (ap, request); - arg = va_arg (ap, void *); - va_end (ap); + va_start (ap, request); + arg = va_arg (ap, void *); + va_end (ap); + } { /* Check for a registered handler for REQUEST. */ diff --git a/libc/sysdeps/mach/hurd/kernel-features.h b/libc/sysdeps/mach/hurd/kernel-features.h index 07caf31f2..96a0d568f 100644 --- a/libc/sysdeps/mach/hurd/kernel-features.h +++ b/libc/sysdeps/mach/hurd/kernel-features.h @@ -1,5 +1,5 @@ /* Set flags signalling availability of certain operating system features. - Copyright (C) 2007 Free Software Foundation, Inc. + 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 @@ -20,11 +20,6 @@ Almost none of these are used outside of sysdeps/unix/sysv/linux code. But those referring to POSIX-level features like O_* flags can be. */ -#include <fcntl.h> - -/* If a system defines the O_CLOEXEC constant but it is sometimes ignored, - it must override this file to define __ASSUME_O_CLOEXEC conditionally - (or not at all) to indicate when O_CLOEXEC actually works. */ -#ifdef O_CLOEXEC -# define __ASSUME_O_CLOEXEC 1 -#endif +#define __ASSUME_O_CLOEXEC 1 +#define __ASSUME_DUP3 1 +#define __ASSUME_ACCEPT4 1 diff --git a/libc/sysdeps/mach/hurd/mkdir.c b/libc/sysdeps/mach/hurd/mkdir.c index d3627ee5e..8ad648e0a 100644 --- a/libc/sysdeps/mach/hurd/mkdir.c +++ b/libc/sysdeps/mach/hurd/mkdir.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,93,94,95,96,97,2002 Free Software Foundation, Inc. +/* 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 @@ -19,6 +19,7 @@ #include <stddef.h> #include <sys/stat.h> #include <hurd.h> +#include <string.h> /* Create a directory named FILE_NAME with protections MODE. */ int @@ -28,7 +29,10 @@ __mkdir (file_name, mode) { error_t err; const char *name; - file_t parent = __directory_name_split (file_name, (char **) &name); + file_t parent; + if (!strcmp (file_name, "/")) + return __hurd_fail (EEXIST); + parent = __directory_name_split (file_name, (char **) &name); if (parent == MACH_PORT_NULL) return -1; err = __dir_mkdir (parent, name, mode & ~_hurd_umask); diff --git a/libc/sysdeps/mach/hurd/mkdirat.c b/libc/sysdeps/mach/hurd/mkdirat.c index 9201f7d35..d6d672ead 100644 --- a/libc/sysdeps/mach/hurd/mkdirat.c +++ b/libc/sysdeps/mach/hurd/mkdirat.c @@ -1,6 +1,5 @@ /* Create a directory named relative to another open directory. Hurd version. - Copyright (C) 1991,1993,1994,1995,1996,1997,2002,2006 - Free Software Foundation, Inc. + 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 @@ -22,6 +21,7 @@ #include <sys/stat.h> #include <hurd.h> #include <hurd/fd.h> +#include <string.h> int mkdirat (fd, path, mode) @@ -31,7 +31,10 @@ mkdirat (fd, path, mode) { error_t err; const char *name; - file_t parent = __directory_name_split_at (fd, path, (char **) &name); + file_t parent; + if (!strcmp (path, "/")) + return __hurd_fail (EEXIST); + parent = __directory_name_split_at (fd, path, (char **) &name); if (parent == MACH_PORT_NULL) return -1; err = __dir_mkdir (parent, name, mode & ~_hurd_umask); diff --git a/libc/sysdeps/mach/hurd/mlock.c b/libc/sysdeps/mach/hurd/mlock.c index 2cb3e5632..47bafaae1 100644 --- a/libc/sysdeps/mach/hurd/mlock.c +++ b/libc/sysdeps/mach/hurd/mlock.c @@ -1,5 +1,5 @@ /* mlock -- guarantee pages are resident in memory. Mach/Hurd version. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001-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 @@ -39,7 +39,7 @@ mlock (const void *addr, size_t len) page = trunc_page ((vm_address_t) addr); len = round_page ((vm_address_t) addr + len) - page; err = __vm_wire (hostpriv, __mach_task_self (), page, len, - VM_PROT_ALL); /* XXX ? */ + VM_PROT_READ); __mach_port_deallocate (__mach_task_self (), hostpriv); return err ? __hurd_fail (err) : 0; diff --git a/libc/sysdeps/mach/hurd/openat.c b/libc/sysdeps/mach/hurd/openat.c index 69d257c18..c6fcf49d8 100644 --- a/libc/sysdeps/mach/hurd/openat.c +++ b/libc/sysdeps/mach/hurd/openat.c @@ -1,5 +1,5 @@ /* openat -- Open a file named relative to an open directory. Hurd version. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-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 @@ -34,14 +34,14 @@ __openat (fd, file, oflag) const char *file; int oflag; { - int mode; + mode_t mode; io_t port; if (oflag & O_CREAT) { va_list arg; va_start (arg, oflag); - mode = va_arg (arg, int); + mode = va_arg (arg, mode_t); va_end (arg); } else diff --git a/libc/sysdeps/mach/hurd/opendir.c b/libc/sysdeps/mach/hurd/opendir.c index 217d4c85d..175944418 100644 --- a/libc/sysdeps/mach/hurd/opendir.c +++ b/libc/sysdeps/mach/hurd/opendir.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1993,1994,1995,1996,1997,1998,2001,2003,2005,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1993-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 @@ -29,6 +28,7 @@ #include <stdio.h> #include <hurd.h> #include <hurd/fd.h> +#include <not-cancel.h> #include "dirstream.h" @@ -50,9 +50,11 @@ _hurd_fd_opendir (struct hurd_fd *d) return NULL; /* Set the descriptor to close on exec. */ + HURD_CRITICAL_BEGIN; __spin_lock (&d->port.lock); d->flags |= FD_CLOEXEC; __spin_unlock (&d->port.lock); + HURD_CRITICAL_END; dirp->__fd = d; dirp->__data = dirp->__ptr = NULL; @@ -66,10 +68,45 @@ _hurd_fd_opendir (struct hurd_fd *d) } +DIR * +internal_function +__opendirat (int dfd, const char *name) +{ + if (name[0] == '\0') + { + /* POSIX.1-1990 says an empty name gets ENOENT; + but `open' might like it fine. */ + __set_errno (ENOENT); + return NULL; + } + + int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC; + int fd; +#ifdef IS_IN_rtld + assert (dfd == AT_FDCWD); + fd = open_not_cancel_2 (name, flags); +#else + fd = openat_not_cancel_3 (dfd, name, flags); +#endif + if (fd < 0) + return NULL; + + /* Extract the pointer to the descriptor structure. */ + DIR *dirp = _hurd_fd_opendir (_hurd_fd_get (fd)); + if (dirp == NULL) + __close (fd); + + return dirp; +} + + /* Open a directory stream on NAME. */ DIR * __opendir (const char *name) { +#if 0 /* TODO. */ + return __opendirat (AT_FDCWD, name); +#else if (name[0] == '\0') { /* POSIX.1-1990 says an empty name gets ENOENT; @@ -88,5 +125,6 @@ __opendir (const char *name) __close (fd); return dirp; +#endif } weak_alias (__opendir, opendir) diff --git a/libc/sysdeps/mach/hurd/readlinkat.c b/libc/sysdeps/mach/hurd/readlinkat.c new file mode 100644 index 000000000..c46522a48 --- /dev/null +++ b/libc/sysdeps/mach/hurd/readlinkat.c @@ -0,0 +1,63 @@ +/* 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <hurd.h> +#include <hurd/paths.h> +#include <hurd/fd.h> +#include <fcntl.h> +#include <string.h> + +/* Read the contents of the symbolic link FILE_NAME relative to FD into no more + than LEN bytes of BUF. The contents are not null-terminated. + Returns the number of characters read, or -1 for errors. */ +ssize_t +readlinkat (fd, file_name, buf, len) + int fd; + const char *file_name; + char *buf; + size_t len; +{ + error_t err; + file_t file; + struct stat64 st; + + file = __file_name_lookup_at (fd, 0, file_name, O_READ | O_NOLINK, 0); + if (file == MACH_PORT_NULL) + return -1; + + err = __io_stat (file, &st); + if (! err) + if (S_ISLNK (st.st_mode)) + { + char *rbuf = buf; + + err = __io_read (file, &rbuf, &len, 0, len); + if (!err && rbuf != buf) + { + memcpy (buf, rbuf, len); + __vm_deallocate (__mach_task_self (), (vm_address_t)rbuf, len); + } + } + else + err = EINVAL; + + __mach_port_deallocate (__mach_task_self (), file); + + return err ? __hurd_fail (err) : len; +} +libc_hidden_def (readlinkat) diff --git a/libc/sysdeps/mach/hurd/recvfrom.c b/libc/sysdeps/mach/hurd/recvfrom.c index f59133611..3a094aa0d 100644 --- a/libc/sysdeps/mach/hurd/recvfrom.c +++ b/libc/sysdeps/mach/hurd/recvfrom.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994, 1997, 1999, 2001, 2002 Free Software Foundation, Inc. +/* 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 @@ -54,7 +54,7 @@ __recvfrom (fd, buf, n, flags, addrarg, addr_len) return __hurd_sockfail (fd, flags, err); /* Get address data for the returned address port if requested. */ - if (addr != NULL) + if (addr != NULL && addrport != MACH_PORT_NULL) { char *buf = (char *) addr; mach_msg_type_number_t buflen = *addr_len; @@ -88,6 +88,8 @@ __recvfrom (fd, buf, n, flags, addrarg, addr_len) if (buflen > 0) addr->sa_family = type; } + else if (addr_len != NULL) + *addr_len = 0; __mach_port_deallocate (__mach_task_self (), addrport); diff --git a/libc/sysdeps/mach/hurd/setitimer.c b/libc/sysdeps/mach/hurd/setitimer.c index a7b2e29d1..00cd0cc44 100644 --- a/libc/sysdeps/mach/hurd/setitimer.c +++ b/libc/sysdeps/mach/hurd/setitimer.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1994,1995,1996,1997,2000,2001,2005 - Free Software Foundation, Inc. +/* 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 @@ -219,7 +218,7 @@ setitimer_locked (const struct itimerval *new, struct itimerval *old, /* Start up the itimer thread running `timer_thread' (below). */ if (err = __thread_create (__mach_task_self (), &_hurd_itimer_thread)) - return __hurd_fail (err); + goto out; _hurd_itimer_thread_stack_base = 0; /* Anywhere. */ _hurd_itimer_thread_stack_size = __vm_page_size; /* Small stack. */ if (err = __mach_setup_thread (__mach_task_self (), diff --git a/libc/sysdeps/mach/hurd/setresgid.c b/libc/sysdeps/mach/hurd/setresgid.c index 9d5885bed..eebd364fc 100644 --- a/libc/sysdeps/mach/hurd/setresgid.c +++ b/libc/sysdeps/mach/hurd/setresgid.c @@ -1,5 +1,5 @@ /* setresgid -- set real group ID, effective group ID, and saved-set group ID - Copyright (C) 2002, 2005, 2006 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 @@ -28,7 +28,6 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) { auth_t newauth; error_t err; - gid_t agids[2] = { rgid, sgid }; HURD_CRITICAL_BEGIN; __mutex_lock (&_hurd_id.lock); @@ -37,31 +36,78 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) if (!err) { /* Make a new auth handle which has EGID as the first element in the - list of effective gids. */ + list of effective gids. */ - if (_hurd_id.gen.ngids > 0) + uid_t *newgen, *newaux; + uid_t auxs[2] = { rgid, sgid }; + size_t ngen, naux; + + newgen = _hurd_id.gen.gids; + ngen = _hurd_id.gen.ngids; + if (egid != -1) + { + if (_hurd_id.gen.ngids == 0) + { + /* No effective gids now. The new set will be just UID. */ + newgen = &egid; + ngen = 1; + } + else + { + _hurd_id.gen.gids[0] = egid; + _hurd_id.valid = 0; + } + } + + newaux = _hurd_id.aux.gids; + naux = _hurd_id.aux.ngids; + if (rgid != -1) { - _hurd_id.gen.gids[0] = egid; - _hurd_id.valid = 0; + if (_hurd_id.aux.ngids == 0) + { + newaux = &rgid; + naux = 1; + } + else + { + _hurd_id.aux.gids[0] = rgid; + _hurd_id.valid = 0; + } } - if (_hurd_id.aux.ngids > 1) + + if (sgid != -1) { - _hurd_id.aux.gids[0] = rgid; - _hurd_id.aux.gids[1] = sgid; - _hurd_id.valid = 0; + if (rgid == -1) + { + if (_hurd_id.aux.ngids >= 1) + auxs[0] = _hurd_id.aux.gids[0]; + else if (_hurd_id.gen.ngids >= 1) + auxs[0] = _hurd_id.gen.gids[0]; + else + /* Not even an effective GID. + Fall back to the only GID we have. */ + auxs[0] = sgid; + } + if (_hurd_id.aux.ngids <= 1) + { + /* No saved gids now. The new set will be just UID. */ + newaux = auxs; + naux = 2; + } + else + { + _hurd_id.aux.gids[1] = sgid; + _hurd_id.valid = 0; + } } err = __USEPORT (AUTH, __auth_makeauth (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, _hurd_id.gen.uids, _hurd_id.gen.nuids, _hurd_id.aux.uids, _hurd_id.aux.nuids, - _hurd_id.gen.ngids ? _hurd_id.gen.gids : &egid, - _hurd_id.gen.ngids ?: 1, - _hurd_id.aux.ngids > 1 ? _hurd_id.aux.gids : agids, - _hurd_id.aux.ngids > 1 ? _hurd_id.aux.ngids : 2, + newgen, ngen, newaux, naux, &newauth)); } - __mutex_unlock (&_hurd_id.lock); HURD_CRITICAL_END; diff --git a/libc/sysdeps/mach/hurd/setresuid.c b/libc/sysdeps/mach/hurd/setresuid.c index 35aea8587..751763f5a 100644 --- a/libc/sysdeps/mach/hurd/setresuid.c +++ b/libc/sysdeps/mach/hurd/setresuid.c @@ -1,5 +1,5 @@ /* setresuid -- set real user ID, effective user ID, and saved-set user ID - Copyright (C) 2002, 2005, 2006 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 @@ -28,7 +28,6 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) { auth_t newauth; error_t err; - uid_t auids[2] = { ruid, suid }; HURD_CRITICAL_BEGIN; __mutex_lock (&_hurd_id.lock); @@ -37,26 +36,74 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) if (!err) { /* Make a new auth handle which has EUID as the first element in the - list of effective uids. */ + list of effective uids. */ - if (_hurd_id.gen.nuids > 0) + uid_t *newgen, *newaux; + uid_t auxs[2] = { ruid, suid }; + size_t ngen, naux; + + newgen = _hurd_id.gen.uids; + ngen = _hurd_id.gen.nuids; + if (euid != -1) { - _hurd_id.gen.uids[0] = euid; - _hurd_id.valid = 0; + if (_hurd_id.gen.nuids == 0) + { + /* No effective uids now. The new set will be just UID. */ + newgen = &euid; + ngen = 1; + } + else + { + _hurd_id.gen.uids[0] = euid; + _hurd_id.valid = 0; + } } - if (_hurd_id.aux.nuids > 1) + + newaux = _hurd_id.aux.uids; + naux = _hurd_id.aux.nuids; + if (ruid != -1) + { + if (_hurd_id.aux.nuids == 0) + { + newaux = &ruid; + naux = 1; + } + else + { + _hurd_id.aux.uids[0] = ruid; + _hurd_id.valid = 0; + } + } + + if (suid != -1) { - _hurd_id.aux.uids[0] = ruid; - _hurd_id.aux.uids[1] = suid; - _hurd_id.valid = 0; + if (ruid == -1) + { + if (_hurd_id.aux.nuids >= 1) + auxs[0] = _hurd_id.aux.uids[0]; + else if (_hurd_id.gen.nuids >= 1) + auxs[0] = _hurd_id.gen.uids[0]; + else + /* Not even an effective UID. + Fall back to the only UID we have. */ + auxs[0] = suid; + } + if (_hurd_id.aux.nuids <= 1) + { + /* No saved uids now. The new set will be just UID. */ + newaux = auxs; + naux = 2; + } + else + { + _hurd_id.aux.uids[1] = suid; + _hurd_id.valid = 0; + } } err = __USEPORT (AUTH, __auth_makeauth (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, - _hurd_id.gen.nuids ? _hurd_id.gen.uids : &euid, - _hurd_id.gen.nuids ?: 1, - _hurd_id.aux.nuids > 1 ? _hurd_id.aux.uids : auids, - _hurd_id.aux.nuids > 1 ? _hurd_id.aux.nuids : 2, + newgen, ngen, newaux, naux, _hurd_id.gen.gids, _hurd_id.gen.ngids, _hurd_id.aux.gids, _hurd_id.aux.ngids, &newauth)); diff --git a/libc/sysdeps/mach/hurd/xmknodat.c b/libc/sysdeps/mach/hurd/xmknodat.c index acd1a8c68..645f22280 100644 --- a/libc/sysdeps/mach/hurd/xmknodat.c +++ b/libc/sysdeps/mach/hurd/xmknodat.c @@ -1,6 +1,5 @@ /* Create a device file relative to an open directory. Hurd version. - Copyright (C) 1991,1992,1993,1994,1995,1996,1999,2002,2005,2006 - Free Software Foundation, Inc. + 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 @@ -34,7 +33,7 @@ int __xmknodat (int vers, int fd, const char *path, mode_t mode, dev_t *dev) { - error_t err; + error_t errnode, err; file_t dir, node; char *name; char buf[100], *bp; @@ -94,7 +93,7 @@ __xmknodat (int vers, int fd, const char *path, mode_t mode, dev_t *dev) return -1; /* Create a new, unlinked node in the target directory. */ - err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node); + errnode = err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node); if (! err && translator != NULL) /* Set the node's translator to make it a device. */ @@ -109,7 +108,8 @@ __xmknodat (int vers, int fd, const char *path, mode_t mode, dev_t *dev) err = __dir_link (dir, node, name, 1); __mach_port_deallocate (__mach_task_self (), dir); - __mach_port_deallocate (__mach_task_self (), node); + if (! errnode) + __mach_port_deallocate (__mach_task_self (), node); if (err) return __hurd_fail (err); diff --git a/libc/sysdeps/mach/hurd/xstatconv.c b/libc/sysdeps/mach/hurd/xstatconv.c index db704c6f3..ebe6471ac 100644 --- a/libc/sysdeps/mach/hurd/xstatconv.c +++ b/libc/sysdeps/mach/hurd/xstatconv.c @@ -1,5 +1,5 @@ /* Convert between `struct stat' format, and `struct stat64' format. - Copyright (C) 2000,01,02 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 @@ -41,12 +41,9 @@ xstat64_conv (struct stat *buf, const struct stat64 *buf64) buf->st_uid = buf64->st_uid; buf->st_gid = buf64->st_gid; buf->st_size = buf64->st_size; - buf->st_atime = buf64->st_atime; - buf->st_atime_usec = buf64->st_atime_usec; - buf->st_mtime = buf64->st_mtime; - buf->st_mtime_usec = buf64->st_mtime_usec; - buf->st_ctime = buf64->st_ctime; - buf->st_ctime_usec = buf64->st_ctime_usec; + buf->st_atim = buf64->st_atim; + buf->st_mtim = buf64->st_mtim; + buf->st_ctim = buf64->st_ctim; buf->st_blksize = buf64->st_blksize; buf->st_blocks = buf64->st_blocks; buf->st_author = buf64->st_author; diff --git a/libc/sysdeps/mach/nanosleep.c b/libc/sysdeps/mach/nanosleep.c index 0192ff0bd..a1ba19c17 100644 --- a/libc/sysdeps/mach/nanosleep.c +++ b/libc/sysdeps/mach/nanosleep.c @@ -1,5 +1,5 @@ /* nanosleep -- sleep for a period specified with a struct timespec - Copyright (C) 2002 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 @@ -27,6 +27,15 @@ __nanosleep (const struct timespec *requested_time, { mach_port_t recv; struct timeval before, after; + + if (requested_time->tv_sec < 0 + || requested_time->tv_nsec < 0 + || requested_time->tv_nsec >= 1000000000) + { + errno = EINVAL; + return -1; + } + const mach_msg_timeout_t ms = requested_time->tv_sec * 1000 + (requested_time->tv_nsec + 999999) / 1000000; @@ -35,16 +44,22 @@ __nanosleep (const struct timespec *requested_time, if (remaining && __gettimeofday (&before, NULL) < 0) return -1; - (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, - 0, 0, recv, ms, MACH_PORT_NULL); + error_t err = __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, + 0, 0, recv, ms, MACH_PORT_NULL); __mach_port_destroy (mach_task_self (), recv); - if (remaining && __gettimeofday (&after, NULL) < 0) - return -1; - - if (remaining) + if (err == EMACH_RCV_INTERRUPTED) { - timersub (&after, &before, &after); - TIMEVAL_TO_TIMESPEC (&after, remaining); + if (remaining && __gettimeofday (&after, NULL) >= 0) + { + struct timeval req_time, elapsed, rem; + TIMESPEC_TO_TIMEVAL (&req_time, requested_time); + timersub (&after, &before, &elapsed); + timersub (&req_time, &elapsed, &rem); + TIMEVAL_TO_TIMESPEC (&rem, remaining); + } + + errno = EINTR; + return -1; } return 0; diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c index 1a023f91f..2eca2ae0e 100644 --- a/libc/sysdeps/posix/getaddrinfo.c +++ b/libc/sysdeps/posix/getaddrinfo.c @@ -2604,7 +2604,7 @@ getaddrinfo (const char *name, const char *service, __libc_lock_define_initialized (static, lock); __libc_lock_lock (lock); - if (old_once && gaiconf_reload_flag) + if (__libc_once_get (old_once) && gaiconf_reload_flag) gaiconf_reload (); qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src); __libc_lock_unlock (lock); diff --git a/libc/sysdeps/posix/getcwd.c b/libc/sysdeps/posix/getcwd.c index 6c41977eb..1dc45e8ee 100644 --- a/libc/sysdeps/posix/getcwd.c +++ b/libc/sysdeps/posix/getcwd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-1999,2011-2012 Free Software Foundation, Inc. +/* 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 @@ -173,6 +173,7 @@ extern char *alloca (); #if defined _LIBC # include <not-cancel.h> +# include <kernel-features.h> #else # define openat64_not_cancel_3(dfd, name, mode) openat64 (dfd, name, mode) # define close_not_cancel_no_status(fd) close (fd) diff --git a/libc/sysdeps/powerpc/memmove.c b/libc/sysdeps/powerpc/memmove.c index 4887ae356..89182838e 100644 --- a/libc/sysdeps/powerpc/memmove.c +++ b/libc/sysdeps/powerpc/memmove.c @@ -15,9 +15,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #include <string.h> #include <memcopy.h> diff --git a/libc/sysdeps/sparc/fpu/bits/fenv.h b/libc/sysdeps/sparc/fpu/bits/fenv.h index 2168de582..0e2a9b9e6 100644 --- a/libc/sysdeps/sparc/fpu/bits/fenv.h +++ b/libc/sysdeps/sparc/fpu/bits/fenv.h @@ -76,9 +76,9 @@ typedef unsigned long int fenv_t; /* For internal use only: access the fp state register. */ #if __WORDSIZE == 64 -# define __fenv_stfsr(X) __asm__ ("stx %%fsr,%0" : "=m" (X)) +# define __fenv_stfsr(X) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (X)) # define __fenv_ldfsr(X) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (X)) #else -# define __fenv_stfsr(X) __asm__ ("st %%fsr,%0" : "=m" (X)) +# define __fenv_stfsr(X) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (X)) # define __fenv_ldfsr(X) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X)) #endif diff --git a/libc/sysdeps/sparc/fpu/fpu_control.h b/libc/sysdeps/sparc/fpu/fpu_control.h index c8bb50373..26c08e956 100644 --- a/libc/sysdeps/sparc/fpu/fpu_control.h +++ b/libc/sysdeps/sparc/fpu/fpu_control.h @@ -59,11 +59,11 @@ typedef unsigned long int fpu_control_t; #if __WORDSIZE == 64 -# define _FPU_GETCW(cw) __asm__ ("stx %%fsr,%0" : "=m" (*&cw)) -# define _FPU_SETCW(cw) __asm__ ("ldx %0,%%fsr" : : "m" (*&cw)) +# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw)) #else -# define _FPU_GETCW(cw) __asm__ ("st %%fsr,%0" : "=m" (*&cw)) -# define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : : "m" (*&cw)) +# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw)) #endif /* Default control word set at startup. */ diff --git a/libc/sysdeps/sparc/fpu/libm-test-ulps b/libc/sysdeps/sparc/fpu/libm-test-ulps index 080441e91..c9030879d 100644 --- a/libc/sysdeps/sparc/fpu/libm-test-ulps +++ b/libc/sysdeps/sparc/fpu/libm-test-ulps @@ -1,9 +1,18 @@ # Begin of automatic generation # acos_downward +Test "acos_downward (-0) == pi/2": +float: 1 +ifloat: 1 Test "acos_downward (-0.5) == M_PI_6l*4.0": double: 1 idouble: 1 +Test "acos_downward (-1) == pi": +float: 1 +ifloat: 1 +Test "acos_downward (0) == pi/2": +float: 1 +ifloat: 1 Test "acos_downward (0.5) == M_PI_6l*2.0": double: 1 float: 1 @@ -13,9 +22,18 @@ ildouble: 1 ldouble: 1 # acos_towardzero +Test "acos_towardzero (-0) == pi/2": +float: 1 +ifloat: 1 Test "acos_towardzero (-0.5) == M_PI_6l*4.0": double: 1 idouble: 1 +Test "acos_towardzero (-1) == pi": +float: 1 +ifloat: 1 +Test "acos_towardzero (0) == pi/2": +float: 1 +ifloat: 1 Test "acos_towardzero (0.5) == M_PI_6l*2.0": double: 1 float: 1 @@ -24,6 +42,17 @@ ifloat: 1 ildouble: 1 ldouble: 1 +# acos_upward +Test "acos_upward (-0) == pi/2": +ildouble: 1 +ldouble: 1 +Test "acos_upward (-1) == pi": +ildouble: 1 +ldouble: 1 +Test "acos_upward (0) == pi/2": +ildouble: 1 +ldouble: 1 + # asin_downward Test "asin_downward (-0.5) == -pi/6": double: 1 @@ -1224,6 +1253,14 @@ double: 2 float: 1 idouble: 2 ifloat: 1 +Test "exp10 (-305) == 1.0e-305": +double: 1 +idouble: 1 +Test "exp10 (-36) == 1.0e-36": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 Test "exp10 (0.75) == 5.62341325190349080394951039776481231": double: 1 float: 1 @@ -1236,6 +1273,12 @@ idouble: 6 ifloat: 2 ildouble: 1 ldouble: 1 +Test "exp10 (36) == 1.0e36": +double: 1 +idouble: 1 +Test "exp10 (4932) == 1.0e4932": +ildouble: 1 +ldouble: 1 # exp2 Test "exp2 (100.5) == 1.792728671193156477399422023278661496394e+30": @@ -1284,6 +1327,9 @@ idouble: 1 ifloat: 1 ildouble: 1 ldouble: 1 +Test "expm1 (500.0) == 1.4035922178528374107397703328409120821806e+217": +double: 1 +idouble: 1 # gamma Test "gamma (-0.5) == log(2*sqrt(pi))": @@ -2093,6 +2139,10 @@ ifloat: 1 ildouble: 1 ldouble: 1 +Function: "acos_upward": +ildouble: 1 +ldouble: 1 + Function: "asin_downward": double: 1 float: 1 diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floor-vis3.S b/libc/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floor-vis3.S index d7e5d24c1..dfaf55458 100644 --- a/libc/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floor-vis3.S +++ b/libc/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floor-vis3.S @@ -56,10 +56,9 @@ ENTRY (__floor_vis3) fnegd ZERO, SIGN_BIT - stx %o2, [%sp + 72] + movxtod %o2, %f16 fabsd %f0, %f14 - ldd [%sp + 72], %f16 fcmpd %fcc3, %f14, %f16 fmovduge %fcc3, ZERO, %f16 diff --git a/libc/sysdeps/sparc/sysdep.h b/libc/sysdeps/sparc/sysdep.h index 2702620be..bcffec94f 100644 --- a/libc/sysdeps/sparc/sysdep.h +++ b/libc/sysdeps/sparc/sysdep.h @@ -58,21 +58,34 @@ __sparc_get_pc_thunk.reg: \ .previous; \ .endif; -/* Even when v9 we use a call sequence instead of using "rd %pc" because +/* The "-4" and "+4" offsets against _GLOBAL_OFFSET_TABLE_ are + critical since they represent the offset from the thunk call to the + instruction containing the _GLOBAL_OFFSET_TABLE_ reference. + Therefore these instructions cannot be moved around without + appropriate adjustments to those offsets. + + Furthermore, these expressions are special in another regard. When + the assembler sees a reference to _GLOBAL_OFFSET_TABLE_ inside of + a %hi() or %lo(), it emits a PC-relative relocation. This causes + R_SPARC_HI22 to turn into R_SPARC_PC22, and R_SPARC_LO10 to turn into + R_SPARC_PC10, respectively. + + Even when v9 we use a call sequence instead of using "rd %pc" because RDPC is extremely expensive and incurs a full pipeline flush. */ -#define SETUP_PIC_REG(reg) \ - SPARC_PIC_THUNK(reg) \ +#define SPARC_PIC_THUNK_CALL(reg) \ sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %##reg; \ call __sparc_get_pc_thunk.reg; \ or %##reg, %lo(_GLOBAL_OFFSET_TABLE_+4), %##reg; +#define SETUP_PIC_REG(reg) \ + SPARC_PIC_THUNK(reg) \ + SPARC_PIC_THUNK_CALL(reg) + #define SETUP_PIC_REG_LEAF(reg, tmp) \ SPARC_PIC_THUNK(reg) \ - sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %##reg; \ mov %o7, %##tmp; \ - call __sparc_get_pc_thunk.reg; \ - or %##reg, %lo(_GLOBAL_OFFSET_TABLE_+4), %##reg; \ + SPARC_PIC_THUNK_CALL(reg); \ mov %##tmp, %o7; #undef ENTRY diff --git a/libc/sysdeps/unix/syscalls.list b/libc/sysdeps/unix/syscalls.list index 5c696b31c..39c40ed7f 100644 --- a/libc/sysdeps/unix/syscalls.list +++ b/libc/sysdeps/unix/syscalls.list @@ -10,7 +10,7 @@ chroot - chroot i:s chroot close - close Ci:i __libc_close __close close dup - dup i:i __dup dup dup2 - dup2 i:ii __dup2 dup2 -dup3 - dup3 i:iii dup3 +dup3 - dup3 i:iii __dup3 dup3 fchdir - fchdir i:i __fchdir fchdir fchmod - fchmod i:ii __fchmod fchmod fchown - fchown i:iii __fchown fchown diff --git a/libc/sysdeps/unix/sysv/linux/configure b/libc/sysdeps/unix/sysv/linux/configure index 31031613d..d571d0b62 100644 --- a/libc/sysdeps/unix/sysv/linux/configure +++ b/libc/sysdeps/unix/sysv/linux/configure @@ -382,38 +382,6 @@ fi if test -n "$sysheaders"; then CPPFLAGS=$OLD_CPPFLAGS fi -# The Linux filesystem standard prescribes where to place "essential" -# files. I.e., when the installation prefix is "/usr" we have to place -# shared library objects and the configuration files on the root partition -# in /lib and /etc. -case "$prefix" in -/usr | /usr/) - # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib. - # Allow earlier configure scripts to handle libc_cv_slibdir, libdir, - # and libc_cv_localedir. - test -n "$libc_cv_slibdir" || \ - case $machine in - sparc/sparc64 | x86_64* | powerpc/powerpc64 | s390/s390-64) - libc_cv_slibdir="/lib64" - if test "$libdir" = '${exec_prefix}/lib'; then - libdir='${exec_prefix}/lib64'; - # Locale data can be shared between 32bit and 64bit libraries - libc_cv_localedir='${exec_prefix}/lib/locale' - fi - ;; - *) - libc_cv_slibdir="/lib" - ;; - esac - # Allow the user to override the path with --sysconfdir - if test $sysconfdir = '${prefix}/etc'; then - libc_cv_sysconfdir=/etc - else - libc_cv_sysconfdir=$sysconfdir - fi - libc_cv_rootsbindir="/sbin" - ;; -esac # Under Linux the NPTL add-on should be available. case $add_ons in diff --git a/libc/sysdeps/unix/sysv/linux/configure.in b/libc/sysdeps/unix/sysv/linux/configure.in index 556ca8451..916d64a60 100644 --- a/libc/sysdeps/unix/sysv/linux/configure.in +++ b/libc/sysdeps/unix/sysv/linux/configure.in @@ -121,38 +121,6 @@ fi if test -n "$sysheaders"; then CPPFLAGS=$OLD_CPPFLAGS fi -# The Linux filesystem standard prescribes where to place "essential" -# files. I.e., when the installation prefix is "/usr" we have to place -# shared library objects and the configuration files on the root partition -# in /lib and /etc. -case "$prefix" in -/usr | /usr/) - # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib. - # Allow earlier configure scripts to handle libc_cv_slibdir, libdir, - # and libc_cv_localedir. - test -n "$libc_cv_slibdir" || \ - case $machine in - sparc/sparc64 | x86_64* | powerpc/powerpc64 | s390/s390-64) - libc_cv_slibdir="/lib64" - if test "$libdir" = '${exec_prefix}/lib'; then - libdir='${exec_prefix}/lib64'; - # Locale data can be shared between 32bit and 64bit libraries - libc_cv_localedir='${exec_prefix}/lib/locale' - fi - ;; - *) - libc_cv_slibdir="/lib" - ;; - esac - # Allow the user to override the path with --sysconfdir - if test $sysconfdir = '${prefix}/etc'; then - libc_cv_sysconfdir=/etc - else - libc_cv_sysconfdir=$sysconfdir - fi - libc_cv_rootsbindir="/sbin" - ;; -esac # Under Linux the NPTL add-on should be available. case $add_ons in diff --git a/libc/sysdeps/unix/sysv/linux/syscalls.list b/libc/sysdeps/unix/sysv/linux/syscalls.list index f6e6653d3..eef6d82b5 100644 --- a/libc/sysdeps/unix/sysv/linux/syscalls.list +++ b/libc/sysdeps/unix/sysv/linux/syscalls.list @@ -1,6 +1,7 @@ # File name Caller Syscall name Args Strong name Weak names adjtimex adjtime adjtimex i:p __adjtimex adjtimex ntp_adjtime __adjtimex_internal +alarm - alarm i:i alarm bdflush EXTRA bdflush i:ii bdflush capget EXTRA capget i:pp capget capset EXTRA capset i:pp capset @@ -71,12 +72,14 @@ setfsuid EXTRA setfsuid i:i setfsuid setpgid - setpgid i:ii __setpgid setpgid sigaltstack - sigaltstack i:PP __sigaltstack sigaltstack splice EXTRA splice Ci:iPiPii splice +stime - stime i:p stime sysinfo EXTRA sysinfo i:p sysinfo swapon - swapon i:si __swapon swapon swapoff - swapoff i:s __swapoff swapoff tee EXTRA tee Ci:iiii tee unshare EXTRA unshare i:i unshare uselib EXTRA uselib i:s uselib +utime - utime i:sP utime vmsplice EXTRA vmsplice Ci:iPii vmsplice wait4 - wait4 i:iWiP __wait4 wait4 diff --git a/libc/sysdeps/unix/sysv/syscalls.list b/libc/sysdeps/unix/sysv/syscalls.list deleted file mode 100644 index c508dd0ec..000000000 --- a/libc/sysdeps/unix/sysv/syscalls.list +++ /dev/null @@ -1,9 +0,0 @@ -# File name Caller Syscall name # args Strong name Weak names - -alarm - alarm i:i alarm -pause - pause Ci: pause -setrlimit - setrlimit i:ip __setrlimit setrlimit -settimeofday - settimeofday i:PP __settimeofday settimeofday -stime - stime i:p stime -ulimit - ulimit i:ii ulimit -utime - utime i:sP utime diff --git a/libc/sysdeps/x86_64/Makefile b/libc/sysdeps/x86_64/Makefile index b989f6a97..81c9128a9 100644 --- a/libc/sysdeps/x86_64/Makefile +++ b/libc/sysdeps/x86_64/Makefile @@ -21,6 +21,19 @@ sysdep-dl-routines += tlsdesc dl-tlsdesc sysdep_routines += tlsdesc dl-tlsdesc sysdep-rtld-routines += tlsdesc dl-tlsdesc +tests += tst-quad1 tst-quad2 +modules-names += tst-quadmod1 tst-quadmod2 + +$(objpfx)tst-quad1: $(objpfx)tst-quadmod1.so +$(objpfx)tst-quad2: $(objpfx)tst-quadmod2.so + +quad-pie-test += tst-quad1pie tst-quad2pie +tests += $(quad-pie-test) +tests-pie += $(quad-pie-test) + +$(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o +$(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o + tests: $(objpfx)tst-xmmymm.out $(objpfx)tst-xmmymm.out: ../sysdeps/x86_64/tst-xmmymm.sh $(objpfx)ld.so @echo "Checking ld.so for SSE register use. This will take a few seconds..." diff --git a/libc/sysdeps/x86_64/dl-machine.h b/libc/sysdeps/x86_64/dl-machine.h index 8ceb479de..32814b14f 100644 --- a/libc/sysdeps/x86_64/dl-machine.h +++ b/libc/sysdeps/x86_64/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. x86-64 version. - Copyright (C) 2001-2006, 2008-2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2001-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>. @@ -29,7 +29,7 @@ /* Return nonzero iff ELF header is compatible with the running host. */ static inline int __attribute__ ((unused)) -elf_machine_matches_host (const Elf64_Ehdr *ehdr) +elf_machine_matches_host (const ElfW(Ehdr) *ehdr) { return ehdr->e_machine == EM_X86_64; } @@ -38,24 +38,24 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr) /* Return the link-time address of _DYNAMIC. Conveniently, this is the first element of the GOT. This must be inlined in a function which uses global data. */ -static inline Elf64_Addr __attribute__ ((unused)) +static inline ElfW(Addr) __attribute__ ((unused)) elf_machine_dynamic (void) { - Elf64_Addr addr; + ElfW(Addr) addr; /* This works because we have our GOT address available in the small PIC model. */ - addr = (Elf64_Addr) &_DYNAMIC; + addr = (ElfW(Addr)) &_DYNAMIC; return addr; } /* Return the run-time load address of the shared object. */ -static inline Elf64_Addr __attribute__ ((unused)) +static inline ElfW(Addr) __attribute__ ((unused)) elf_machine_load_address (void) { - Elf64_Addr addr; + ElfW(Addr) addr; /* The easy way is just the same as on x86: leaq _dl_start, %0 @@ -89,8 +89,8 @@ static inline int __attribute__ ((unused, always_inline)) elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { Elf64_Addr *got; - extern void _dl_runtime_resolve (Elf64_Word) attribute_hidden; - extern void _dl_runtime_profile (Elf64_Word) attribute_hidden; + extern void _dl_runtime_resolve (ElfW(Word)) attribute_hidden; + extern void _dl_runtime_profile (ElfW(Word)) attribute_hidden; if (l->l_info[DT_JMPREL] && lazy) { @@ -105,9 +105,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) if (got[1]) { l->l_mach.plt = got[1] + l->l_addr; - l->l_mach.gotplt = (Elf64_Addr) &got[3]; + l->l_mach.gotplt = (ElfW(Addr)) &got[3]; } - got[1] = (Elf64_Addr) l; /* Identify this shared object. */ + /* Identify this shared object. */ + *(ElfW(Addr) *) (got + 1) = (ElfW(Addr)) l; /* The got[2] entry contains the address of a function which gets called to get the address of a so far unresolved function and @@ -117,7 +118,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) end in this function. */ if (__builtin_expect (profile, 0)) { - got[2] = (Elf64_Addr) &_dl_runtime_profile; + *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_profile; if (GLRO(dl_profile) != NULL && _dl_name_match_p (GLRO(dl_profile), l)) @@ -128,12 +129,12 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) else /* This function will get called to fix up the GOT entry indicated by the offset on the stack, and then jump to the resolved address. */ - got[2] = (Elf64_Addr) &_dl_runtime_resolve; + *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve; } if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy) - *(Elf64_Addr*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) + l->l_addr) - = (Elf64_Addr) &_dl_tlsdesc_resolve_rela; + *(ElfW(Addr)*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) + l->l_addr) + = (ElfW(Addr)) &_dl_tlsdesc_resolve_rela; return lazy; } @@ -210,7 +211,7 @@ _dl_start_user:\n\ // XXX This is a work-around for a broken linker. Remove! #define ELF_MACHINE_IRELATIVE R_X86_64_IRELATIVE -/* The x86-64 never uses Elf64_Rel relocations. */ +/* The x86-64 never uses Elf64_Rel/Elf32_Rel relocations. */ #define ELF_MACHINE_NO_REL 1 /* We define an initialization function. This is called very early in @@ -225,19 +226,19 @@ dl_platform_init (void) GLRO(dl_platform) = NULL; } -static inline Elf64_Addr +static inline ElfW(Addr) elf_machine_fixup_plt (struct link_map *map, lookup_t t, - const Elf64_Rela *reloc, - Elf64_Addr *reloc_addr, Elf64_Addr value) + const ElfW(Rela) *reloc, + ElfW(Addr) *reloc_addr, ElfW(Addr) value) { return *reloc_addr = value; } /* Return the final value of a PLT relocation. On x86-64 the JUMP_SLOT relocation ignores the addend. */ -static inline Elf64_Addr -elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, - Elf64_Addr value) +static inline ElfW(Addr) +elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc, + ElfW(Addr) value) { return value; } @@ -256,12 +257,12 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, auto inline void __attribute__ ((always_inline)) -elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, - const Elf64_Sym *sym, const struct r_found_version *version, +elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + const ElfW(Sym) *sym, const struct r_found_version *version, void *const reloc_addr_arg, int skip_ifunc) { - Elf64_Addr *const reloc_addr = reloc_addr_arg; - const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); + ElfW(Addr) *const reloc_addr = reloc_addr_arg; + const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); # if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC if (__builtin_expect (r_type == R_X86_64_RELATIVE, 0)) @@ -282,23 +283,30 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, } else # endif +# if !defined RTLD_BOOTSTRAP + /* l_addr + r_addend may be > 0xffffffff and R_X86_64_RELATIVE64 + relocation updates the whole 64-bit entry. */ + if (__builtin_expect (r_type == R_X86_64_RELATIVE64, 0)) + *(Elf64_Addr *) reloc_addr = (Elf64_Addr) map->l_addr + reloc->r_addend; + else +# endif if (__builtin_expect (r_type == R_X86_64_NONE, 0)) return; else { # ifndef RTLD_BOOTSTRAP - const Elf64_Sym *const refsym = sym; + const ElfW(Sym) *const refsym = sym; # endif struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); - Elf64_Addr value = (sym == NULL ? 0 - : (Elf64_Addr) sym_map->l_addr + sym->st_value); + ElfW(Addr) value = (sym == NULL ? 0 + : (ElfW(Addr)) sym_map->l_addr + sym->st_value); if (sym != NULL && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0) && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) && __builtin_expect (!skip_ifunc, 1)) - value = ((Elf64_Addr (*) (void)) value) (); + value = ((ElfW(Addr) (*) (void)) value) (); switch (r_type) { @@ -327,7 +335,19 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ if (sym != NULL) - *reloc_addr = sym->st_value + reloc->r_addend; + { + value = sym->st_value + reloc->r_addend; +# ifdef __ILP32__ + /* This relocation type computes a signed offset that is + usually negative. The symbol and addend values are 32 + bits but the GOT entry is 64 bits wide and the whole + 64-bit entry is used as a signed quantity, so we need + to sign-extend the computed value to 64 bits. */ + *(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value; +# else + *reloc_addr = value; +# endif + } # endif break; case R_X86_64_TLSDESC: @@ -377,15 +397,26 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, /* We know the offset of the object the symbol is contained in. It is a negative value which will be added to the thread pointer. */ - *reloc_addr = (sym->st_value + reloc->r_addend - - sym_map->l_tls_offset); + value = (sym->st_value + reloc->r_addend + - sym_map->l_tls_offset); +# ifdef __ILP32__ + /* The symbol and addend values are 32 bits but the GOT + entry is 64 bits wide and the whole 64-bit entry is used + as a signed quantity, so we need to sign-extend the + computed value to 64 bits. */ + *(Elf64_Sxword *) reloc_addr = (Elf64_Sxword) (Elf32_Sword) value; +# else + *reloc_addr = value; +# endif } break; # endif # ifndef RTLD_BOOTSTRAP case R_X86_64_64: - *reloc_addr = value + reloc->r_addend; + /* value + r_addend may be > 0xffffffff and R_X86_64_64 + relocation updates the whole 64-bit entry. */ + *(Elf64_Addr *) reloc_addr = (Elf64_Addr) value + reloc->r_addend; break; case R_X86_64_32: value += reloc->r_addend; @@ -411,7 +442,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, # ifndef RESOLVE_CONFLICT_FIND_MAP /* Not needed for dl-conflict.c. */ case R_X86_64_PC32: - value += reloc->r_addend - (Elf64_Addr) reloc_addr; + value += reloc->r_addend - (ElfW(Addr)) reloc_addr; *(unsigned int *) reloc_addr = value; if (__builtin_expect (value != (int) value, 0)) { @@ -439,7 +470,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, # endif case R_X86_64_IRELATIVE: value = map->l_addr + reloc->r_addend; - value = ((Elf64_Addr (*) (void)) value) (); + value = ((ElfW(Addr) (*) (void)) value) (); *reloc_addr = value; break; default: @@ -452,22 +483,31 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, auto inline void __attribute ((always_inline)) -elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, +elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr_arg) { - Elf64_Addr *const reloc_addr = reloc_addr_arg; - assert (ELF64_R_TYPE (reloc->r_info) == R_X86_64_RELATIVE); - *reloc_addr = l_addr + reloc->r_addend; + ElfW(Addr) *const reloc_addr = reloc_addr_arg; +#if !defined RTLD_BOOTSTRAP + /* l_addr + r_addend may be > 0xffffffff and R_X86_64_RELATIVE64 + relocation updates the whole 64-bit entry. */ + if (__builtin_expect (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE64, 0)) + *(Elf64_Addr *) reloc_addr = (Elf64_Addr) l_addr + reloc->r_addend; + else +#endif + { + assert (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE); + *reloc_addr = l_addr + reloc->r_addend; + } } auto inline void __attribute ((always_inline)) elf_machine_lazy_rel (struct link_map *map, - Elf64_Addr l_addr, const Elf64_Rela *reloc, + ElfW(Addr) l_addr, const ElfW(Rela) *reloc, int skip_ifunc) { - Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); - const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); + ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); /* Check for unexpected PLT reloc type. */ if (__builtin_expect (r_type == R_X86_64_JUMP_SLOT, 1)) @@ -477,7 +517,7 @@ elf_machine_lazy_rel (struct link_map *map, else *reloc_addr = map->l_mach.plt - + (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 2; + + (((ElfW(Addr)) reloc_addr) - map->l_mach.gotplt) * 2; } else if (__builtin_expect (r_type == R_X86_64_TLSDESC, 1)) { @@ -490,9 +530,9 @@ elf_machine_lazy_rel (struct link_map *map, } else if (__builtin_expect (r_type == R_X86_64_IRELATIVE, 0)) { - Elf64_Addr value = map->l_addr + reloc->r_addend; + ElfW(Addr) value = map->l_addr + reloc->r_addend; if (__builtin_expect (!skip_ifunc, 1)) - value = ((Elf64_Addr (*) (void)) value) (); + value = ((ElfW(Addr) (*) (void)) value) (); *reloc_addr = value; } else diff --git a/libc/sysdeps/x86_64/dl-trampoline.S b/libc/sysdeps/x86_64/dl-trampoline.S index 769166286..6185ba487 100644 --- a/libc/sysdeps/x86_64/dl-trampoline.S +++ b/libc/sysdeps/x86_64/dl-trampoline.S @@ -20,6 +20,10 @@ #include <sysdep.h> #include <link-defines.h> +#if (RTLD_SAVESPACE_SSE % 32) != 0 +# error RTLD_SAVESPACE_SSE must be aligned to 32 bytes +#endif + .text .globl _dl_runtime_resolve .type _dl_runtime_resolve, @function diff --git a/libc/sysdeps/x86_64/fpu/bits/mathinline.h b/libc/sysdeps/x86_64/fpu/bits/mathinline.h index c072f16a2..49a199b60 100644 --- a/libc/sysdeps/x86_64/fpu/bits/mathinline.h +++ b/libc/sysdeps/x86_64/fpu/bits/mathinline.h @@ -79,7 +79,11 @@ __MATH_INLINE long int __NTH (lrintf (float __x)) { long int __res; - __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x)); return __res; } # endif @@ -88,7 +92,11 @@ __MATH_INLINE long int __NTH (lrint (double __x)) { long int __res; - __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x)); return __res; } # endif @@ -97,14 +105,22 @@ __MATH_INLINE long long int __NTH (llrintf (float __x)) { long long int __res; - __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x)); return __res; } __MATH_INLINE long long int __NTH (llrint (double __x)) { long long int __res; - __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x)); return __res; } # endif @@ -176,14 +192,22 @@ __MATH_INLINE double __NTH (rint (double __x)) { double __res; - __asm ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x)); return __res; } __MATH_INLINE float __NTH (rintf (float __x)) { float __res; - __asm ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x)); return __res; } @@ -193,14 +217,22 @@ __MATH_INLINE double __NTH (nearbyint (double __x)) { double __res; - __asm ("roundsd $0xc, %1, %0" : "=x" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundsd $0xc, %1, %0" : "=x" (__res) : "xm" (__x)); return __res; } __MATH_INLINE float __NTH (nearbyintf (float __x)) { float __res; - __asm ("roundss $0xc, %1, %0" : "=x" (__res) : "xm" (__x)); + /* Mark as volatile since the result is dependend on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundss $0xc, %1, %0" : "=x" (__res) : "xm" (__x)); return __res; } # endif diff --git a/libc/sysdeps/x86_64/fpu/e_exp10l.S b/libc/sysdeps/x86_64/fpu/e_exp10l.S new file mode 100644 index 000000000..d843e2b5e --- /dev/null +++ b/libc/sysdeps/x86_64/fpu/e_exp10l.S @@ -0,0 +1,2 @@ +#define USE_AS_EXP10L +#include <e_expl.S> diff --git a/libc/sysdeps/x86_64/fpu/e_expl.S b/libc/sysdeps/x86_64/fpu/e_expl.S index d497b2897..e6b842bf2 100644 --- a/libc/sysdeps/x86_64/fpu/e_expl.S +++ b/libc/sysdeps/x86_64/fpu/e_expl.S @@ -24,9 +24,33 @@ #include <machine/asm.h> +#ifdef USE_AS_EXP10L +# define IEEE754_EXPL __ieee754_exp10l +# define EXPL_FINITE __exp10l_finite +# define FLDLOG fldl2t +#elif defined USE_AS_EXPM1L +# define IEEE754_EXPL __expm1l +# undef EXPL_FINITE +# define FLDLOG fldl2e +#else +# define IEEE754_EXPL __ieee754_expl +# define EXPL_FINITE __expl_finite +# define FLDLOG fldl2e +#endif + .section .rodata.cst16,"aM",@progbits,16 .p2align 4 +#ifdef USE_AS_EXP10L + ASM_TYPE_DIRECTIVE(c0,@object) +c0: .byte 0, 0, 0, 0, 0, 0, 0x9a, 0xd4, 0x00, 0x40 + .byte 0, 0, 0, 0, 0, 0 + ASM_SIZE_DIRECTIVE(c0) + ASM_TYPE_DIRECTIVE(c1,@object) +c1: .byte 0x58, 0x92, 0xfc, 0x15, 0x37, 0x9a, 0x97, 0xf0, 0xef, 0x3f + .byte 0, 0, 0, 0, 0, 0 + ASM_SIZE_DIRECTIVE(c1) +#else ASM_TYPE_DIRECTIVE(c0,@object) c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f .byte 0, 0, 0, 0, 0, 0 @@ -35,6 +59,7 @@ c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f c1: .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f .byte 0, 0, 0, 0, 0, 0 ASM_SIZE_DIRECTIVE(c1) +#endif ASM_TYPE_DIRECTIVE(csat,@object) csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40 .byte 0, 0, 0, 0, 0, 0 @@ -47,14 +72,22 @@ csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40 #endif .text -ENTRY(__ieee754_expl) +ENTRY(IEEE754_EXPL) +#ifdef USE_AS_EXPM1L + movzwl 8+8(%rsp), %eax + xorb $0x80, %ah // invert sign bit (now 1 is "positive") + cmpl $0xc006, %eax // is num positive and exp >= 6 (number is >= 128.0)? + jae HIDDEN_JUMPTARGET (__expl) // (if num is denormal, it is at least >= 64.0) +#endif fldt 8(%rsp) /* I added the following ugly construct because expl(+-Inf) resulted in NaN. The ugliness results from the bright minds at Intel. For the i686 the code can be written better. -- drepper@cygnus.com. */ fxam /* Is NaN or +-Inf? */ +#ifndef USE_AS_EXPM1L movzwl 8+8(%rsp), %eax +#endif andl $0x7fff, %eax cmpl $0x400d, %eax jle 3f @@ -72,8 +105,17 @@ ENTRY(__ieee754_expl) andb $2, %ah jz 3f fchs -3: fldl2e /* 1 log2(e) */ - fmul %st(1), %st /* 1 x log2(e) */ +3: +#ifdef USE_AS_EXPM1L + /* Test for +-0 as argument. */ + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x40, %dh + je 2f +#endif + FLDLOG /* 1 log2(base) */ + fmul %st(1), %st /* 1 x log2(base) */ frndint /* 1 i */ fld %st(1) /* 2 x */ frndint /* 2 xi */ @@ -89,18 +131,40 @@ ENTRY(__ieee754_expl) fldt MO(c1) /* 4 */ fmul %st(4), %st /* 4 c1 * x */ faddp %st, %st(1) /* 3 f = f + c1 * x */ - f2xm1 /* 3 2^(fract(x * log2(e))) - 1 */ + f2xm1 /* 3 2^(fract(x * log2(base))) - 1 */ +#ifdef USE_AS_EXPM1L + fstp %st(1) /* 2 */ + fscale /* 2 scale factor is st(1); base^x - 2^i */ + fxch /* 2 i */ + fld1 /* 3 1.0 */ + fscale /* 3 2^i */ + fld1 /* 4 1.0 */ + fsubrp %st, %st(1) /* 3 2^i - 1.0 */ + fstp %st(1) /* 2 */ + faddp %st, %st(1) /* 1 base^x - 1.0 */ +#else fld1 /* 4 1.0 */ - faddp /* 3 2^(fract(x * log2(e))) */ + faddp /* 3 2^(fract(x * log2(base))) */ fstp %st(1) /* 2 */ - fscale /* 2 scale factor is st(1); e^x */ + fscale /* 2 scale factor is st(1); base^x */ fstp %st(1) /* 1 */ +#endif fstp %st(1) /* 0 */ jmp 2f 1: testl $0x200, %eax /* Test sign. */ jz 2f /* If positive, jump. */ fstp %st +#ifdef USE_AS_EXPM1L + fld1 + fchs +#else fldz /* Set result to 0. */ +#endif 2: ret -END(__ieee754_expl) -strong_alias (__ieee754_expl, __expl_finite) +END(IEEE754_EXPL) +#ifdef USE_AS_EXPM1L +libm_hidden_def (__expm1l) +weak_alias (__expm1l, expm1l) +#else +strong_alias (IEEE754_EXPL, EXPL_FINITE) +#endif diff --git a/libc/sysdeps/x86_64/fpu/libm-test-ulps b/libc/sysdeps/x86_64/fpu/libm-test-ulps index 9a1e80ed8..9bb26d1fe 100644 --- a/libc/sysdeps/x86_64/fpu/libm-test-ulps +++ b/libc/sysdeps/x86_64/fpu/libm-test-ulps @@ -7,15 +7,21 @@ ldouble: 1 # acos_downward Test "acos_downward (-0) == pi/2": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "acos_downward (-0.5) == M_PI_6l*4.0": double: 1 idouble: 1 Test "acos_downward (-1) == pi": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "acos_downward (0) == pi/2": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "acos_downward (0.5) == M_PI_6l*2.0": @@ -26,15 +32,21 @@ ifloat: 1 # acos_towardzero Test "acos_towardzero (-0) == pi/2": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "acos_towardzero (-0.5) == M_PI_6l*4.0": double: 1 idouble: 1 Test "acos_towardzero (-1) == pi": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "acos_towardzero (0) == pi/2": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "acos_towardzero (0.5) == M_PI_6l*2.0": @@ -1275,6 +1287,12 @@ idouble: 2 ifloat: 1 ildouble: 1 ldouble: 1 +Test "exp10 (-305) == 1.0e-305": +double: 1 +idouble: 1 +Test "exp10 (-36) == 1.0e-36": +double: 1 +idouble: 1 Test "exp10 (0.75) == 5.62341325190349080394951039776481231": double: 1 float: 1 @@ -1289,6 +1307,9 @@ idouble: 6 ifloat: 2 ildouble: 8 ldouble: 8 +Test "exp10 (36) == 1.0e36": +double: 1 +idouble: 1 # exp_downward Test "exp_downward (1) == e": @@ -1337,6 +1358,9 @@ ifloat: 1 Test "expm1 (11356.25) == 9.05128237311923300051376115753226014206e+4931": ildouble: 1 ldouble: 1 +Test "expm1 (500.0) == 1.4035922178528374107397703328409120821806e+217": +double: 1 +idouble: 1 # gamma Test "gamma (-0.5) == log(2*sqrt(pi))": @@ -1810,62 +1834,47 @@ Test "sincos (pi/6, &sin_res, &cos_res) puts 0.866025403784438646763723170752936 float: 1 ifloat: 1 -# sinh -Test "sinh (0x8p-32) == 1.86264514923095703232705808926175479e-9": -ildouble: 1 -ldouble: 1 - # sinh_downward Test "sinh_downward (22) == 1792456423.065795780701106568345764104225": float: 1 ifloat: 1 -ildouble: 4 -ldouble: 4 +ildouble: 2 +ldouble: 2 Test "sinh_downward (23) == 4872401723.124451299966006944252978187305": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "sinh_downward (24) == 13244561064.92173614705070540368454568168": float: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 - -# sinh_tonearest -Test "sinh_tonearest (22) == 1792456423.065795780701106568345764104225": -ildouble: 3 -ldouble: 3 -Test "sinh_tonearest (23) == 4872401723.124451299966006944252978187305": -ildouble: 1 -ldouble: 1 -Test "sinh_tonearest (24) == 13244561064.92173614705070540368454568168": -ildouble: 6 -ldouble: 6 +ildouble: 2 +ldouble: 2 # sinh_towardzero Test "sinh_towardzero (22) == 1792456423.065795780701106568345764104225": float: 1 ifloat: 1 -ildouble: 4 -ldouble: 4 +ildouble: 2 +ldouble: 2 Test "sinh_towardzero (23) == 4872401723.124451299966006944252978187305": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "sinh_towardzero (24) == 13244561064.92173614705070540368454568168": float: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 +ildouble: 2 +ldouble: 2 # sinh_upward Test "sinh_upward (22) == 1792456423.065795780701106568345764104225": -ildouble: 16 -ldouble: 16 +ildouble: 1 +ldouble: 1 Test "sinh_upward (23) == 4872401723.124451299966006944252978187305": -ildouble: 27 -ldouble: 27 -Test "sinh_upward (24) == 13244561064.92173614705070540368454568168": -ildouble: 7 -ldouble: 7 +ildouble: 1 +ldouble: 1 # tan Test "tan (0x1p16383) == 0.422722393732022337800504160054440141575": @@ -2712,29 +2721,21 @@ ifloat: 1 ildouble: 1 ldouble: 1 -Function: "sinh": -ildouble: 1 -ldouble: 1 - Function: "sinh_downward": float: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 - -Function: "sinh_tonearest": -ildouble: 6 -ldouble: 6 +ildouble: 2 +ldouble: 2 Function: "sinh_towardzero": float: 1 ifloat: 1 -ildouble: 5 -ldouble: 5 +ildouble: 2 +ldouble: 2 Function: "sinh_upward": -ildouble: 27 -ldouble: 27 +ildouble: 1 +ldouble: 1 Function: "tan": double: 1 diff --git a/libc/sysdeps/x86_64/fpu/s_expm1l.S b/libc/sysdeps/x86_64/fpu/s_expm1l.S index 1380f34f0..7fbd99b0d 100644 --- a/libc/sysdeps/x86_64/fpu/s_expm1l.S +++ b/libc/sysdeps/x86_64/fpu/s_expm1l.S @@ -1,85 +1,2 @@ -/* ix87 specific implementation of exp(x)-1. - Copyright (C) 1996,1997,2001,2002,2008,2009,2012 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. - Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>. - Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - - /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */ - -#include <machine/asm.h> - - .section .rodata - - .align ALIGNARG(4) - ASM_TYPE_DIRECTIVE(minus1,@object) -minus1: .double -1.0 - ASM_SIZE_DIRECTIVE(minus1) - ASM_TYPE_DIRECTIVE(one,@object) -one: .double 1.0 - ASM_SIZE_DIRECTIVE(one) - ASM_TYPE_DIRECTIVE(l2e,@object) -l2e: .tfloat 1.442695040888963407359924681002 - ASM_SIZE_DIRECTIVE(l2e) - -#ifdef PIC -#define MO(op) op##(%rip) -#else -#define MO(op) op -#endif - - .text -ENTRY(__expm1l) - movzwl 8+8(%rsp), %eax // load sign bit and 15-bit exponent - xorb $0x80, %ah // invert sign bit (now 1 is "positive") - cmpl $0xc006, %eax // is num positive and exp >= 6 (number is >= 128.0)? - jae __expl // (if num is denormal, it is at least >= 64.0) - - fldt 8(%rsp) // x - fxam // Is NaN or +-Inf? - fstsw %ax - movb $0x45, %ch - andb %ah, %ch - cmpb $0x40, %ch - je 3f // If +-0, jump. - cmpb $0x05, %ch - je 2f // If +-Inf, jump. - - fldt MO(l2e) // log2(e) : x - fmulp // log2(e)*x - fld %st // log2(e)*x : log2(e)*x - frndint // int(log2(e)*x) : log2(e)*x - fsubr %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x) - fxch // fract(log2(e)*x) : int(log2(e)*x) - f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x) - fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x) - fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fscale // 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fsubrl MO(one) // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fstp %st(1) // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) - fsubrp %st, %st(1) // 2^(log2(e)*x)-1 - ret - -2: testl $0x200, %eax // Test sign. - jz 3f // If positive, jump. - fstp %st - fldl MO(minus1) // Set result to -1.0. -3: ret -END(__expm1l) -libm_hidden_def (__expm1l) -weak_alias (__expm1l, expm1l) +#define USE_AS_EXPM1L +#include <e_expl.S> diff --git a/libc/sysdeps/x86_64/tst-quad1.c b/libc/sysdeps/x86_64/tst-quad1.c new file mode 100644 index 000000000..a8567ea8a --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quad1.c @@ -0,0 +1,25 @@ +/* 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/>. */ + +extern void foo (void); + +int +main (void) +{ + foo (); + return 0; +} diff --git a/libc/sysdeps/x86_64/tst-quad1pie.c b/libc/sysdeps/x86_64/tst-quad1pie.c new file mode 100644 index 000000000..f5fd45f9b --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quad1pie.c @@ -0,0 +1 @@ +#include "tst-quad1.c" diff --git a/libc/sysdeps/x86_64/tst-quad2.c b/libc/sysdeps/x86_64/tst-quad2.c new file mode 100644 index 000000000..f5fd45f9b --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quad2.c @@ -0,0 +1 @@ +#include "tst-quad1.c" diff --git a/libc/sysdeps/x86_64/tst-quad2pie.c b/libc/sysdeps/x86_64/tst-quad2pie.c new file mode 100644 index 000000000..a15d8d36a --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quad2pie.c @@ -0,0 +1 @@ +#include "tst-quad2.c" diff --git a/libc/sysdeps/x86_64/tst-quadmod1.S b/libc/sysdeps/x86_64/tst-quadmod1.S new file mode 100644 index 000000000..0e691be80 --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quadmod1.S @@ -0,0 +1,44 @@ +/* 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 BIAS +# define BIAS 0x7fffffff +#endif + + .section .data.rel,"aw",@progbits + .align 8 +.Ljmp: + .quad func + BIAS + .text + .globl func + .type func, @function +func: + .cfi_startproc + xorl %edi, %edi + jmp exit@PLT + .cfi_endproc + .size func, .-func + .globl foo + .type foo, @function +foo: + .cfi_startproc + .cfi_def_cfa_register 6 + movq .Ljmp(%rip), %rax + subq $BIAS, %rax + jmp *%rax + .cfi_endproc + .size foo, .-foo diff --git a/libc/sysdeps/x86_64/tst-quadmod1pie.S b/libc/sysdeps/x86_64/tst-quadmod1pie.S new file mode 100644 index 000000000..c671d0cda --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quadmod1pie.S @@ -0,0 +1,2 @@ +#define BIAS 0x7fff0000 +#include "tst-quadmod1.S" diff --git a/libc/sysdeps/x86_64/tst-quadmod2.S b/libc/sysdeps/x86_64/tst-quadmod2.S new file mode 100644 index 000000000..38ab9598b --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quadmod2.S @@ -0,0 +1,43 @@ +/* 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 BIAS +# define BIAS 0x7fff0000 +#endif + + .section .data.rel.local,"aw",@progbits + .align 8 +.Ljmp: + .quad func + BIAS + .text + .type func, @function +func: + .cfi_startproc + xorl %edi, %edi + jmp exit@PLT + .cfi_endproc + .size func, .-func + .globl foo + .type foo, @function +foo: + .cfi_startproc + .cfi_def_cfa_register 6 + movq .Ljmp(%rip), %rax + subq $BIAS, %rax + jmp *%rax + .cfi_endproc + .size foo, .-foo diff --git a/libc/sysdeps/x86_64/tst-quadmod2pie.S b/libc/sysdeps/x86_64/tst-quadmod2pie.S new file mode 100644 index 000000000..609183fe5 --- /dev/null +++ b/libc/sysdeps/x86_64/tst-quadmod2pie.S @@ -0,0 +1 @@ +#include "tst-quadmod2.S" |