summaryrefslogtreecommitdiff
path: root/libc/sysdeps
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2009-05-22 20:28:34 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2009-05-22 20:28:34 +0000
commit6b946eeb50a57ee4ff8c50783d516bb03cf89b7a (patch)
tree19d7e79d38b73083f6786b448e2c148e04533b9a /libc/sysdeps
parent8394b52f4259c85b39e1114e6f239599f50fbcc2 (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')
-rw-r--r--libc/sysdeps/i386/__longjmp.S1
-rw-r--r--libc/sysdeps/ia64/configure54
-rw-r--r--libc/sysdeps/ia64/configure.in35
-rw-r--r--libc/sysdeps/ia64/memchr.S17
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c7
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c8
-rw-r--r--libc/sysdeps/powerpc/powerpc32/____longjmp_chk.S37
-rw-r--r--libc/sysdeps/powerpc/powerpc32/__longjmp-common.S12
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S10
-rw-r--r--libc/sysdeps/powerpc/powerpc64/____longjmp_chk.S39
-rw-r--r--libc/sysdeps/powerpc/powerpc64/__longjmp-common.S14
-rw-r--r--libc/sysdeps/sh/____longjmp_chk.S70
-rw-r--r--libc/sysdeps/sh/sh3/__longjmp.S9
-rw-r--r--libc/sysdeps/sh/sh4/__longjmp.S7
-rw-r--r--libc/sysdeps/unix/sysv/linux/Makefile4
-rw-r--r--libc/sysdeps/unix/sysv/linux/accept4.c49
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/accept4.S4
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S48
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S10
-rw-r--r--libc/sysdeps/unix/sysv/linux/internal_accept4.S14
-rw-r--r--libc/sysdeps/unix/sysv/linux/kernel-features.h2
-rw-r--r--libc/sysdeps/unix/sysv/linux/socketcall.h4
-rw-r--r--libc/sysdeps/x86_64/__longjmp.S3
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