diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2009-05-22 20:28:34 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2009-05-22 20:28:34 +0000 |
commit | 6b946eeb50a57ee4ff8c50783d516bb03cf89b7a (patch) | |
tree | 19d7e79d38b73083f6786b448e2c148e04533b9a /libc/sysdeps | |
parent | 8394b52f4259c85b39e1114e6f239599f50fbcc2 (diff) |
Merge changes between r8463 and r8486 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@8487 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps')
25 files changed, 446 insertions, 26 deletions
diff --git a/libc/sysdeps/i386/__longjmp.S b/libc/sysdeps/i386/__longjmp.S index 15c9e55ec..8b0732056 100644 --- a/libc/sysdeps/i386/__longjmp.S +++ b/libc/sysdeps/i386/__longjmp.S @@ -28,6 +28,7 @@ #define JBUF PARMS #define VAL JBUF+PTR_SIZE + .text ENTRY (BP_SYM (__longjmp)) ENTER diff --git a/libc/sysdeps/ia64/configure b/libc/sysdeps/ia64/configure new file mode 100644 index 000000000..88caca538 --- /dev/null +++ b/libc/sysdeps/ia64/configure @@ -0,0 +1,54 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/ia64. + +echo "$as_me:$LINENO: checking if -g produces usable source locations for assembler-with-cpp" >&5 +echo $ECHO_N "checking if -g produces usable source locations for assembler-with-cpp... $ECHO_C" >&6 +if test "${libc_cv_cpp_asm_debuginfo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.S <<EOF +#include "confdefs.h" + +/* comment on + two lines */ + ${libc_cv_dot_text} + ${libc_cv_asm_global_directive} foo +foo: + /* Unfortunately this test only works for a real instruction, + not for any of the machine-independent pseudo-ops. + So we just have to assume everybody has a "nop". */ + nop.b 0;; + /* comment */ + nop.b 0;; + /* comment */ + nop.b 0;; +EOF +if { ac_try='${CC-cc} $CPPFLAGS $ASFLAGS -g -c conftest.S 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && { + ac_pattern='conftest\.S' + { ac_try='readelf --debug-dump=line conftest.o | + grep $ac_pattern 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } + }; then + libc_cv_cpp_asm_debuginfo=yes +else + libc_cv_cpp_asm_debuginfo=no +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_cpp_asm_debuginfo" >&5 +echo "${ECHO_T}$libc_cv_cpp_asm_debuginfo" >&6 +if test $libc_cv_cpp_asm_debuginfo = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_CPP_ASM_DEBUGINFO 1 +_ACEOF + +fi diff --git a/libc/sysdeps/ia64/configure.in b/libc/sysdeps/ia64/configure.in new file mode 100644 index 000000000..887b4cb2e --- /dev/null +++ b/libc/sysdeps/ia64/configure.in @@ -0,0 +1,35 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/ia64. + +AC_CACHE_CHECK(if -g produces usable source locations for assembler-with-cpp, + libc_cv_cpp_asm_debuginfo, [dnl +cat > conftest.S <<EOF +#include "confdefs.h" + +/* comment on + two lines */ + ${libc_cv_dot_text} + ${libc_cv_asm_global_directive} foo +foo: + /* Unfortunately this test only works for a real instruction, + not for any of the machine-independent pseudo-ops. + So we just have to assume everybody has a "nop". */ + nop.b 0;; + /* comment */ + nop.b 0;; + /* comment */ + nop.b 0;; +EOF +if AC_TRY_COMMAND([${CC-cc} $CPPFLAGS $ASFLAGS -g -c conftest.S 1>&AS_MESSAGE_LOG_FD]) && { + ac_pattern='conftest\.S' + AC_TRY_COMMAND([readelf --debug-dump=line conftest.o | + grep $ac_pattern 1>&AS_MESSAGE_LOG_FD]) + }; then + libc_cv_cpp_asm_debuginfo=yes +else + libc_cv_cpp_asm_debuginfo=no +fi +rm -f conftest*])AC_SUBST(libc_cv_cpp_asm_debuginfo) +if test $libc_cv_cpp_asm_debuginfo = yes; then + AC_DEFINE(HAVE_CPP_ASM_DEBUGINFO) +fi diff --git a/libc/sysdeps/ia64/memchr.S b/libc/sysdeps/ia64/memchr.S index e9a7ba823..cd062b2dd 100644 --- a/libc/sysdeps/ia64/memchr.S +++ b/libc/sysdeps/ia64/memchr.S @@ -96,7 +96,8 @@ ENTRY(__memchr) mov pr.rot = 1 << 16 ;; .l2: (p[0]) mov addr[0] = ret0 -(p[0]) ld8 value[0] = [ret0], 8 +(p[0]) ld8.s value[0] = [ret0], 8 // speculative load +(p[MEMLAT]) chk.s value[MEMLAT], .recovery // check and recovery (p[MEMLAT]) xor aux[0] = value[MEMLAT], chrx8 (p[MEMLAT+1]) czx1.r poschr[0] = aux[1] (p[MEMLAT+2]) cmp.ne p7, p0 = 8, poschr[1] @@ -124,6 +125,20 @@ ENTRY(__memchr) mov ar.lc = saved_lc br.ret.sptk.many b0 +.recovery: + adds ret0 = -((MEMLAT + 1) * 8), ret0;; +(p[MEMLAT+1]) add ret0 = -8, ret0;; +(p[MEMLAT+2]) add ret0 = -8, ret0;; +.l4: + mov addr[MEMLAT+2] = ret0 + ld8 tmp = [ret0];; // load the first unchecked 8byte + xor aux[1] = tmp, chrx8;; + czx1.r poschr[1] = aux[1];; + cmp.ne p7, p0 = 8, poschr[1] +(p7) br.cond.spnt .foundit;; + adds ret0 = 8, ret0 // load the next unchecked 8byte + br.sptk .l4;; + END(__memchr) weak_alias (__memchr, memchr) diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c index 59a819670..8470850fc 100644 --- a/libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c +++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c @@ -44,6 +44,7 @@ * TRIG(x) returns trig(x) nearly rounded */ +#include <errno.h> #include "math.h" #include "math_private.h" #include <math_ldbl_opt.h> @@ -67,9 +68,11 @@ return __kernel_cosl(x,z); /* cos(Inf or NaN) is NaN */ - else if (ix>=0x7ff0000000000000LL) + else if (ix>=0x7ff0000000000000LL) { + if (ix == 0x7ff0000000000000LL) + __set_errno (EDOM); return x-x; - + } /* argument reduction needed */ else { n = __ieee754_rem_pio2l(x,y); diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c index 735006575..f631eddf5 100644 --- a/libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c +++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c @@ -51,6 +51,7 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <errno.h> #include "math.h" #include "math_private.h" #include <math_ldbl_opt.h> @@ -120,7 +121,10 @@ __expm1l (long double x) /* Overflow. */ if (x > maxlog) - return (big * big); + { + __set_errno (ERANGE); + return (big * big); + } /* Minimum value. */ if (x < minarg) diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c index 8cc592c61..bd72225e1 100644 --- a/libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c +++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c @@ -44,6 +44,7 @@ * TRIG(x) returns trig(x) nearly rounded */ +#include <errno.h> #include "math.h" #include "math_private.h" #include <math_ldbl_opt.h> @@ -67,8 +68,11 @@ return __kernel_sinl(x,z,0); /* sin(Inf or NaN) is NaN */ - else if (ix>=0x7ff0000000000000LL) return x-x; - + else if (ix>=0x7ff0000000000000LL) { + if (ix == 0x7ff0000000000000LL) + __set_errno (EDOM); + return x-x; + } /* argument reduction needed */ else { n = __ieee754_rem_pio2l(x,y); diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c index ea5a7f0ff..913f38f24 100644 --- a/libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c +++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c @@ -44,6 +44,7 @@ * TRIG(x) returns trig(x) nearly rounded */ +#include <errno.h> #include "math.h" #include "math_private.h" #include <math_ldbl_opt.h> @@ -66,8 +67,11 @@ if(ix <= 0x3fe921fb54442d10LL) return __kernel_tanl(x,z,1); /* tanl(Inf or NaN) is NaN */ - else if (ix>=0x7ff0000000000000LL) return x-x; /* NaN */ - + else if (ix>=0x7ff0000000000000LL) { + if (ix == 0x7ff0000000000000LL) + __set_errno (EDOM); + return x-x; /* NaN */ + } /* argument reduction needed */ else { n = __ieee754_rem_pio2l(x,y); diff --git a/libc/sysdeps/powerpc/powerpc32/____longjmp_chk.S b/libc/sysdeps/powerpc/powerpc32/____longjmp_chk.S new file mode 100644 index 000000000..5c1f64866 --- /dev/null +++ b/libc/sysdeps/powerpc/powerpc32/____longjmp_chk.S @@ -0,0 +1,37 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License 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. */ + +#include <sysdep.h> +#include <rtld-global-offsets.h> + + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "longjmp causes uninitialized stack frame" + .text + +#define __longjmp ____longjmp_chk + +#define CHECK_SP(reg) \ + cmplw reg, r1; \ + bge+ .Lok; \ + lis r3,.LC0@ha; \ + la r3,.LC0@l(r3); \ + bl HIDDEN_JUMPTARGET (__fortify_fail); \ +.Lok: + +#include <__longjmp-common.S> diff --git a/libc/sysdeps/powerpc/powerpc32/__longjmp-common.S b/libc/sysdeps/powerpc/powerpc32/__longjmp-common.S index 2093b7e33..7b1c01783 100644 --- a/libc/sysdeps/powerpc/powerpc32/__longjmp-common.S +++ b/libc/sysdeps/powerpc/powerpc32/__longjmp-common.S @@ -1,5 +1,5 @@ /* longjmp for PowerPC. - Copyright (C) 1995-1997, 1999-2001, 2003, 2004, 2005, 2006 + Copyright (C) 1995-1997, 1999-2001, 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -31,7 +31,7 @@ ENTRY (BP_SYM (__longjmp)) CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) -#ifdef PTR_DEMANGLE +#if defined PTR_DEMANGLE || defined CHECK_SP lwz r24,(JB_GPR1*4)(r3) #else lwz r1,(JB_GPR1*4)(r3) @@ -45,9 +45,17 @@ ENTRY (BP_SYM (__longjmp)) lwz r19,((JB_GPRS+5)*4)(r3) lwz r20,((JB_GPRS+6)*4)(r3) #ifdef PTR_DEMANGLE +# ifdef CHECK_SP + PTR_DEMANGLE3 (r24, r24, r25) +# else PTR_DEMANGLE3 (r1, r24, r25) +# endif PTR_DEMANGLE2 (r0, r25) #endif +#ifdef CHECK_SP + CHECK_SP (r24) + mr r1,r24 +#endif mtlr r0 lwz r21,((JB_GPRS+7)*4)(r3) lwz r22,((JB_GPRS+8)*4)(r3) diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S index f9f010fca..f105815b9 100644 --- a/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S +++ b/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S @@ -114,7 +114,7 @@ L(aligned_restore_vmx): lvx v31,0,r6 L(no_vmx): #endif -#ifdef PTR_DEMANGLE +#if defined PTR_DEMANGLE || defined CHECK_SP lwz r24,(JB_GPR1*4)(r3) #else lwz r1,(JB_GPR1*4)(r3) @@ -135,9 +135,17 @@ L(no_vmx): lwz r20,((JB_GPRS+6)*4)(r3) lfd fp20,((JB_FPRS+6*2)*4)(r3) #ifdef PTR_DEMANGLE +# ifdef CHECK_SP + PTR_DEMANGLE3 (r24, r24, r25) +# else PTR_DEMANGLE3 (r1, r24, r25) +# endif PTR_DEMANGLE2 (r0, r25) #endif +#ifdef CHECK_SP + CHECK_SP (r24) + mr r1,r24 +#endif mtlr r0 lwz r21,((JB_GPRS+7)*4)(r3) lfd fp21,((JB_FPRS+7*2)*4)(r3) diff --git a/libc/sysdeps/powerpc/powerpc64/____longjmp_chk.S b/libc/sysdeps/powerpc/powerpc64/____longjmp_chk.S new file mode 100644 index 000000000..56549021a --- /dev/null +++ b/libc/sysdeps/powerpc/powerpc64/____longjmp_chk.S @@ -0,0 +1,39 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License 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. */ + +#include <sysdep.h> +#include <rtld-global-offsets.h> + + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "longjmp causes uninitialized stack frame" + .section .toc,"aw" +.LC1: + .tc .LC0[TC],.LC0 + .text + +#define __longjmp ____longjmp_chk + +#define CHECK_SP(reg) \ + cmpld reg, r1; \ + bge+ .Lok; \ + ld r3,.LC1@toc(2); \ + bl HIDDEN_JUMPTARGET (__fortify_fail); \ +.Lok: + +#include <__longjmp-common.S> diff --git a/libc/sysdeps/powerpc/powerpc64/__longjmp-common.S b/libc/sysdeps/powerpc/powerpc64/__longjmp-common.S index 19b2849c0..1be1f8f3b 100644 --- a/libc/sysdeps/powerpc/powerpc64/__longjmp-common.S +++ b/libc/sysdeps/powerpc/powerpc64/__longjmp-common.S @@ -107,12 +107,22 @@ L(aligned_restore_vmx): lvx v31,0,r6 L(no_vmx): #endif -#ifdef PTR_DEMANGLE +#if defined PTR_DEMANGLE || defined CHECK_SP ld r22,(JB_GPR1*8)(r3) - PTR_DEMANGLE3 (r1, r22, r25) #else ld r1,(JB_GPR1*8)(r3) #endif +#ifdef PTR_DEMANGLE +# ifdef CHECK_SP + PTR_DEMANGLE3 (r22, r22, r25) +# else + PTR_DEMANGLE3 (r1, r22, r25) +# endif +#endif +#ifdef CHECK_SP + CHECK_SP (r22) + mr r1,r22 +#endif ld r2,(JB_GPR2*8)(r3) ld r0,(JB_LR*8)(r3) ld r14,((JB_GPRS+0)*8)(r3) diff --git a/libc/sysdeps/sh/____longjmp_chk.S b/libc/sysdeps/sh/____longjmp_chk.S new file mode 100644 index 000000000..2ff4f586e --- /dev/null +++ b/libc/sysdeps/sh/____longjmp_chk.S @@ -0,0 +1,70 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License 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. */ + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + .text + +#define __longjmp ____longjmp_chk + +#ifdef PIC +# define CALL_FAIL \ + mov.l .Lfail, r1; \ + mov.l .Lstr, r4; \ + mova .Lgot, r0; \ + mov.l .Lgot, r12; \ + add r0, r12; \ + bsrf r1; \ + add r12, r4; \ +.Lfail0: \ + bra 0f; \ + nop; \ + .align 2; \ +.Lgot: \ + .long _GLOBAL_OFFSET_TABLE_; \ +.Lstr: \ + .long longjmp_msg@GOTOFF; \ +.Lfail: \ + .long __GI___fortify_fail@PLT-(.Lfail0-.); \ +0: +#else +# define CALL_FAIL \ + mov.l .Lfail, r1; \ + mov.l .Lstr, r4; \ + jsr @r1; \ + nop; \ + bra 0f; \ + nop; \ + .align 2; \ +.Lstr: \ + .long longjmp_msg; \ +.Lfail: \ + .long __fortify_fail; \ +0: +#endif + +#define CHECK_SP(reg) \ + cmp/hs r15, reg; \ + bt .Lok; \ + CALL_FAIL \ +.Lok: + +#include <__longjmp.S> diff --git a/libc/sysdeps/sh/sh3/__longjmp.S b/libc/sysdeps/sh/sh3/__longjmp.S index c6d8a3214..8c84aff9b 100644 --- a/libc/sysdeps/sh/sh3/__longjmp.S +++ b/libc/sysdeps/sh/sh3/__longjmp.S @@ -1,5 +1,5 @@ /* longjmp for SH. - Copyright (C) 1999, 2000, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2005, 2006, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -42,6 +42,9 @@ ENTRY (__longjmp) mov r2, r14 mov.l @r4+, r2 PTR_DEMANGLE2 (r2, r1) +# ifdef CHECK_SP + CHECK_SP (r2) +# endif mov r2, r15 mov.l @r4+, r2 PTR_DEMANGLE2 (r2, r1) @@ -49,6 +52,10 @@ ENTRY (__longjmp) mov #0, r1 #else mov.l @r4+, r14 +# ifdef CHECK_SP + mov.l @r4, r2 + CHECK_SP (r2) +# endif mov.l @r4+, r15 lds.l @r4+, pr #endif diff --git a/libc/sysdeps/sh/sh4/__longjmp.S b/libc/sysdeps/sh/sh4/__longjmp.S index 2fd137bcb..f2e4b7535 100644 --- a/libc/sysdeps/sh/sh4/__longjmp.S +++ b/libc/sysdeps/sh/sh4/__longjmp.S @@ -42,6 +42,9 @@ ENTRY (__longjmp) mov r2, r14 mov.l @r4+, r2 PTR_DEMANGLE2 (r2, r1) +# ifdef CHECK_SP + CHECK_SP (r2) +# endif mov r2, r15 mov.l @r4+, r2 PTR_DEMANGLE2 (r2, r1) @@ -49,6 +52,10 @@ ENTRY (__longjmp) mov #0, r1 #else mov.l @r4+, r14 +# ifdef CHECK_SP + mov.l @r4, r2 + CHECK_SP (r2) +# endif mov.l @r4+, r15 lds.l @r4+, pr #endif diff --git a/libc/sysdeps/unix/sysv/linux/Makefile b/libc/sysdeps/unix/sysv/linux/Makefile index 0c1dcee0c..a41624e37 100644 --- a/libc/sysdeps/unix/sysv/linux/Makefile +++ b/libc/sysdeps/unix/sysv/linux/Makefile @@ -11,6 +11,10 @@ ifeq ($(subdir),malloc) CFLAGS-malloc.c += -DMORECORE_CLEARS=2 endif +ifeq ($(subdir),socket) +sysdep_routines += internal_accept4 +endif + ifeq ($(subdir),misc) sysdep_routines += sysctl clone llseek umount umount2 readahead \ setfsuid setfsgid makedev epoll_pwait signalfd \ diff --git a/libc/sysdeps/unix/sysv/linux/accept4.c b/libc/sysdeps/unix/sysv/linux/accept4.c index 97f7b8ce6..9ef9f479b 100644 --- a/libc/sysdeps/unix/sysv/linux/accept4.c +++ b/libc/sysdeps/unix/sysv/linux/accept4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 Free Software Foundation, Inc. +/* Copyright (C) 2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2008. @@ -23,8 +23,7 @@ #include <sysdep-cancel.h> #include <sys/syscall.h> - -#define __NR_accept4 288 +#include <kernel-features.h> #ifdef __NR_accept4 @@ -43,6 +42,50 @@ accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags) return result; } +#elif defined __NR_socketcall +# ifndef __ASSUME_ACCEPT4 +extern int __internal_accept4 (int fd, __SOCKADDR_ARG addr, + socklen_t *addr_len, int flags) + attribute_hidden; + +static int have_accept4; + +int +accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags) +{ + if (__builtin_expect (have_accept4 >= 0, 1)) + { + int ret = __internal_accept4 (fd, addr, addr_len, flags); + /* The kernel returns -EINVAL for unknown socket operations. + We need to convert that error to an ENOSYS error. */ + if (__builtin_expect (ret < 0, 0) + && have_accept4 == 0 + && errno == EINVAL) + { + /* Try another call, this time with the FLAGS parameter + cleared and an invalid file descriptor. This call will not + cause any harm and it will return immediately. */ + ret = __internal_accept4 (-1, addr, addr_len, 0); + if (errno == EINVAL) + { + have_accept4 = -1; + __set_errno (ENOSYS); + } + else + { + have_accept4 = 1; + __set_errno (EINVAL); + } + return -1; + } + return ret; + } + __set_errno (ENOSYS); + return -1; +} +# else +/* When __ASSUME_ACCEPT4 accept4 is defined in internal_accept4.S. */ +# endif #else int accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags) diff --git a/libc/sysdeps/unix/sysv/linux/i386/accept4.S b/libc/sysdeps/unix/sysv/linux/i386/accept4.S index 087ccc456..1d05eff7f 100644 --- a/libc/sysdeps/unix/sysv/linux/i386/accept4.S +++ b/libc/sysdeps/unix/sysv/linux/i386/accept4.S @@ -24,10 +24,6 @@ #define EINVAL 22 #define ENOSYS 38 -#ifndef SOCKOP_accept4 -# define SOCKOP_accept4 18 -#endif - #ifdef __ASSUME_ACCEPT4 # define errlabel SYSCALL_ERROR_LABEL #else diff --git a/libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S b/libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S new file mode 100644 index 000000000..e097c2288 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S @@ -0,0 +1,48 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License 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. */ + + .section .rodata.str1.8,"aMS",@progbits,1 + .align 8 +.LC0: + .string "longjmp causes uninitialized stack frame" + + .section .sdata,"aws",@progbits + .align 8 + .type longjmp_msg,@object +longjmp_msg: + data8 .LC0 + .size longjmp_msg, .-longjmp_msg + +#define __longjmp ____longjmp_chk + +#ifdef PIC +# define CALL_FAIL __GI___fortify_fail +#else +# define CALL_FAIL __fortify_fail +#endif + +#define CHECK_RSP(reg) \ + cmp.ltu p0, p8 = reg, r12; \ +(p8) br.cond.dpnt .Lok;; \ + addl r28 = @ltoffx(longjmp_msg#), r1;; \ + ld8.mov r28 = [r28], longjmp_msg#;; \ + ld8 out0 = [r28]; \ + br.call.sptk.many b0 = CALL_FAIL#;; \ +.Lok: + +#include "__longjmp.S" diff --git a/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S b/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S index aa18fadf9..2e7490438 100644 --- a/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S +++ b/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S @@ -42,7 +42,11 @@ /* __longjmp(__jmp_buf buf, int val) */ LEAF(__longjmp) +#ifdef CHECK_RSP + alloc r8=ar.pfs,2,1,1,0 +#else alloc r8=ar.pfs,2,1,0,0 +#endif mov r27=ar.rsc add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr ;; @@ -70,14 +74,18 @@ LEAF(__longjmp) add r3=8,in0 // r3 <- &jmpbuf.r1 shl r9=r25,r17 ;; + ld8.fill.nta r28=[r2],16 // r28 <- jmpbuf.sp or r25=r8,r9 ;; mov r26=ar.rnat mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12) ;; - ld8.fill.nta sp=[r2],16 // r12 (sp) +#ifdef CHECK_RSP + CHECK_RSP (r28) +#endif ld8.fill.nta gp=[r3],16 // r1 (gp) dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp) + mov sp=r28 // r12 (sp) ;; ld8.nta r16=[r2],16 // caller's unat ld8.nta r17=[r3],16 // fpsr diff --git a/libc/sysdeps/unix/sysv/linux/internal_accept4.S b/libc/sysdeps/unix/sysv/linux/internal_accept4.S new file mode 100644 index 000000000..ffc553624 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/internal_accept4.S @@ -0,0 +1,14 @@ +#include <kernel-features.h> +#include <sys/syscall.h> +#if !defined __NR_accept4 && defined __NR_socketcall +# define socket accept4 +# ifdef __ASSUME_ACCEPT4 +# define __socket accept4 +# else +# define __socket __internal_accept4 +# endif +# define NARGS 4 +# define NEED_CANCELLATION +# define NO_WEAK_ALIAS +# include <socket.S> +#endif diff --git a/libc/sysdeps/unix/sysv/linux/kernel-features.h b/libc/sysdeps/unix/sysv/linux/kernel-features.h index 473360a13..456251579 100644 --- a/libc/sysdeps/unix/sysv/linux/kernel-features.h +++ b/libc/sysdeps/unix/sysv/linux/kernel-features.h @@ -521,7 +521,7 @@ /* Support for the accept4 syscall was added in 2.6.28. */ #if __LINUX_KERNEL_VERSION >= 0x02061c \ && (defined __i386__ || defined __x86_64__ || defined __powerpc__ \ - || defined __ia64__ || defined __sparc__ || defined __s390__) + || defined __sparc__ || defined __s390__) # define __ASSUME_ACCEPT4 1 #endif diff --git a/libc/sysdeps/unix/sysv/linux/socketcall.h b/libc/sysdeps/unix/sysv/linux/socketcall.h index 24ec9ee2a..adf01b6e1 100644 --- a/libc/sysdeps/unix/sysv/linux/socketcall.h +++ b/libc/sysdeps/unix/sysv/linux/socketcall.h @@ -1,5 +1,5 @@ /* ID for functions called via socketcall system call. - Copyright (C) 1995, 1996, 2008 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -43,6 +43,6 @@ #define SOCKOP_getsockopt 15 #define SOCKOP_sendmsg 16 #define SOCKOP_recvmsg 17 -#define SOCKOP_paccept 18 +#define SOCKOP_accept4 18 #endif /* sys/socketcall.h */ diff --git a/libc/sysdeps/x86_64/__longjmp.S b/libc/sysdeps/x86_64/__longjmp.S index 7649e9924..24552ece3 100644 --- a/libc/sysdeps/x86_64/__longjmp.S +++ b/libc/sysdeps/x86_64/__longjmp.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2001,2004,2005,2006 Free Software Foundation, Inc. +/* Copyright (C) 2001,2004,2005,2006,2009 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -23,6 +23,7 @@ /* Jump to the position specified by ENV, causing the setjmp call there to return VAL, or 1 if VAL is 0. void __longjmp (__jmp_buf env, int val). */ + .text ENTRY(__longjmp) /* Restore registers. */ movq (JB_RSP*8)(%rdi),%r8 |