@@ -1,5 +1,27 @@
2015-10-07 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+ * sysdeps/i386/nptl/tls.h (THREAD_ATOMIC_BIT_SET): Remove macro.
+ * sysdeps/unix/sysv/linux/i386/Makefile
+ [$(subdir) = elf] (sysdep-rtld_routines): Add libc-do-syscall object.
+ * sysdeps/unix/sysv/linux/i386/fcntl.c (NO_CANCELLATION): Replace
+ by IS_IN (rtld).
+ * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_wait_tid): Use
+ cancellable futex syscall macro.
+ * sysdeps/unix/sysv/linux/i386/syscall_cancel.S: New file.
+ * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (PSEUDO): Redefine to
+ call __syscall_cancel function for cancellable syscalls.
+ * sysdeps/unix/sysv/linux/i386/sysdep.h (SYSCALL_CANCEL_ERROR): New
+ define.
+ (SYSCALL_CANCEL_ERRNO): Likewise.
+ (INTERNAL_SYSCALL_MAIN_NCS_0): Likewise.
+ (INTERNAL_SYSCALL_MAIN_NCS_1): Likewise.
+ (INTERNAL_SYSCALL_MAIN_NCS_2): Likewise.
+ (INTERNAL_SYSCALL_MAIN_NCS_3): Likewise.
+ (INTERNAL_SYSCALL_MAIN_NCS_4): Likewise.
+ (INTERNAL_SYSCALL_MAIN_NCS_5): Likewise.
+ (INTERNAL_SYSCALL_MAIN_NCS_6): Likewise.
+ (INTERNAL_SYSCALL_NCS): Redefine to call it with 6-arguments.
+
* sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h (__syscall_arg_t):
Define type for x32.
(__SSC): Add platform specific macro.
@@ -395,17 +395,6 @@ tls_fill_user_desc (union user_desc_init *desc,
abort (); })
-/* Atomic set bit. */
-#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
- (void) ({ if (sizeof ((descr)->member) == 4) \
- asm volatile (LOCK_PREFIX "orl %1, %%gs:%P0" \
- :: "i" (offsetof (struct pthread, member)), \
- "ir" (1 << (bit))); \
- else \
- /* Not necessary for other sizes in the moment. */ \
- abort (); })
-
-
/* Call the user-provided thread function. */
#define CALL_THREAD_FCT(descr) \
({ void *__res; \
@@ -6,6 +6,7 @@ sysdep_routines += ioperm iopl vm86
endif
ifeq ($(subdir),elf)
+sysdep-rtld_routines += libc-do-syscall
sysdep-others += lddlibc4
install-bin += lddlibc4
endif
@@ -23,7 +23,7 @@
#include <sys/syscall.h>
-#ifndef NO_CANCELLATION
+#if !IS_IN (rtld)
int
__fcntl_nocancel (int fd, int cmd, ...)
{
@@ -36,7 +36,7 @@ __fcntl_nocancel (int fd, int cmd, ...)
return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
}
-#endif /* NO_CANCELLATION */
+#endif
int
@@ -283,7 +283,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count,
do { \
__typeof (tid) __tid; \
while ((__tid = (tid)) != 0) \
- lll_futex_wait (&(tid), __tid, LLL_SHARED);\
+ lll_futex_wait_cancel (&(tid), __tid, LLL_SHARED);\
} while (0)
extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
new file mode 100644
@@ -0,0 +1,105 @@
+/* Cancellable syscall wrapper - x86_64 version.
+ Copyright (C) 2015 Free Software 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>
+
+/* long int [eax] __syscall_cancel_arch (int *cancelhandling [SP],
+ long int nr [SP+4],
+ long int arg1 [SP+8],
+ long int arg2 [SP+12],
+ long int arg3 [SP+16],
+ long int arg4 [SP+20],
+ long int arg5 [SP+24],
+ long int arg6 [SP+28]) */
+
+ENTRY (__syscall_cancel_arch)
+ pushl %ebp
+ cfi_def_cfa_offset (8)
+ cfi_offset (ebp, -8)
+ pushl %edi
+ cfi_def_cfa_offset (12)
+ cfi_offset (edi, -12)
+ pushl %esi
+ cfi_def_cfa_offset (16)
+ cfi_offset (esi, -16)
+ pushl %ebx
+ cfi_def_cfa_offset (20)
+ cfi_offset (ebx, -20)
+
+ .globl __syscall_cancel_arch_start
+ .type __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+
+ /* if (*cancelhandling & CANCELED_BITMASK)
+ __syscall_do_cancel() */
+ testb $4, (%eax)
+ jne 1f
+
+ /* Issue a 6 argument syscall, the nr [%eax] being the syscall
+ number. */
+ movl 24(%esp), %eax
+ movl 28(%esp), %ebx
+ movl 32(%esp), %ecx
+ movl 36(%esp), %edx
+ movl 40(%esp), %esi
+ movl 44(%esp), %edi
+ movl 48(%esp), %ebp
+
+ /* It can not use the vDSO __kernel_vsyscall because the cancelable
+ checks in libc-cancelation.c requires to know if the cancellation
+ IP value that was trigger between the two
+ __syscall_cancel_arch_{start,end} marks. */
+ int $128
+
+ .globl __syscall_cancel_arch_end
+ .type __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+
+ popl %ebx
+ cfi_restore (ebx)
+ cfi_def_cfa_offset (16)
+ popl %esi
+ cfi_restore (esi)
+ cfi_def_cfa_offset (12)
+ popl %edi
+ cfi_restore (edi)
+ cfi_def_cfa_offset (8)
+ popl %ebp
+ cfi_restore (ebp)
+ cfi_def_cfa_offset (4)
+ ret
+
+1:
+ /* Although the __syscall_do_cancel do not return, we need to stack
+ being set correctly so exceptions work correctly. */
+ popl %ebx
+ cfi_restore (ebx)
+ cfi_def_cfa_offset (16)
+ popl %esi
+ cfi_restore (esi)
+ cfi_def_cfa_offset (12)
+ popl %edi
+ cfi_restore (edi)
+ cfi_def_cfa_offset (8)
+ popl %ebp
+ cfi_restore (ebp)
+ cfi_def_cfa_offset (4)
+ jmp __syscall_do_cancel
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
@@ -24,112 +24,66 @@
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
+# if IS_IN (libc)
+# define JMP_STARTFUNC \
+ subl $16, %esp
+# define JMP_SYSCALL_CANCEL \
+ HIDDEN_JUMPTARGET(__syscall_cancel)
+# define JMP_ENDFUNC \
+ addl $44, %esp; \
+ cfi_def_cfa_offset (4)
+# else
+# define JMP_STARTFUNC \
+ pushl %ebx; \
+ cfi_def_cfa_offset (8); \
+ cfi_offset (ebx, -8); \
+ SETUP_PIC_REG (bx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
+ subl $12, %esp
+# define JMP_SYSCALL_CANCEL \
+ __syscall_cancel@plt
+# define JMP_ENDFUNC \
+ addl $40, %esp; \
+ cfi_def_cfa_offset (8); \
+ popl %ebx; \
+ cfi_restore (ebx); \
+ cfi_def_cfa_offset (4)
+# endif
+
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \
jne L(pseudo_cancel); \
- .type __##syscall_name##_nocancel,@function; \
- .globl __##syscall_name##_nocancel; \
- __##syscall_name##_nocancel: \
DO_CALL (syscall_name, args); \
cmpl $-4095, %eax; \
jae SYSCALL_ERROR_LABEL; \
ret; \
- .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
L(pseudo_cancel): \
- CENABLE \
- SAVE_OLDTYPE_##args \
- PUSHCARGS_##args \
- DOCARGS_##args \
- movl $SYS_ify (syscall_name), %eax; \
- ENTER_KERNEL; \
- POPCARGS_##args; \
- POPSTATE_##args \
+ JMP_STARTFUNC; \
+ cfi_def_cfa_offset (20); \
+ pushl 40(%esp); \
+ cfi_def_cfa_offset (24); \
+ pushl 40(%esp); \
+ cfi_def_cfa_offset (28); \
+ pushl 40(%esp); \
+ cfi_def_cfa_offset (32); \
+ pushl 40(%esp); \
+ cfi_def_cfa_offset (36); \
+ pushl 40(%esp); \
+ cfi_def_cfa_offset (40); \
+ pushl 40(%esp); \
+ cfi_def_cfa_offset (44); \
+ pushl $SYS_ify (syscall_name); \
+ cfi_def_cfa_offset (48); \
+ call JMP_SYSCALL_CANCEL; \
+ JMP_ENDFUNC; \
cmpl $-4095, %eax; \
jae SYSCALL_ERROR_LABEL
-# define SAVE_OLDTYPE_0 movl %eax, %ecx;
-# define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
-# define SAVE_OLDTYPE_2 pushl %eax; cfi_adjust_cfa_offset (4);
-# define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2
-# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
-# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
-# define SAVE_OLDTYPE_6 SAVE_OLDTYPE_2
-
-# define PUSHCARGS_0 /* No arguments to push. */
-# define DOCARGS_0 /* No arguments to frob. */
-# define POPCARGS_0 /* No arguments to pop. */
-# define _PUSHCARGS_0 /* No arguments to push. */
-# define _POPCARGS_0 /* No arguments to pop. */
-
-# define PUSHCARGS_1 movl %ebx, %edx; cfi_register (ebx, edx); PUSHCARGS_0
-# define DOCARGS_1 _DOARGS_1 (4)
-# define POPCARGS_1 POPCARGS_0; movl %edx, %ebx; cfi_restore (ebx);
-# define _PUSHCARGS_1 pushl %ebx; cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (ebx, 0); _PUSHCARGS_0
-# define _POPCARGS_1 _POPCARGS_0; popl %ebx; \
- cfi_adjust_cfa_offset (-4); cfi_restore (ebx);
-
-# define PUSHCARGS_2 PUSHCARGS_1
-# define DOCARGS_2 _DOARGS_2 (12)
-# define POPCARGS_2 POPCARGS_1
-# define _PUSHCARGS_2 _PUSHCARGS_1
-# define _POPCARGS_2 _POPCARGS_1
-
-# define PUSHCARGS_3 _PUSHCARGS_2
-# define DOCARGS_3 _DOARGS_3 (20)
-# define POPCARGS_3 _POPCARGS_3
-# define _PUSHCARGS_3 _PUSHCARGS_2
-# define _POPCARGS_3 _POPCARGS_2
-
-# define PUSHCARGS_4 _PUSHCARGS_4
-# define DOCARGS_4 _DOARGS_4 (28)
-# define POPCARGS_4 _POPCARGS_4
-# define _PUSHCARGS_4 pushl %esi; cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (esi, 0); _PUSHCARGS_3
-# define _POPCARGS_4 _POPCARGS_3; popl %esi; \
- cfi_adjust_cfa_offset (-4); cfi_restore (esi);
-
-# define PUSHCARGS_5 _PUSHCARGS_5
-# define DOCARGS_5 _DOARGS_5 (36)
-# define POPCARGS_5 _POPCARGS_5
-# define _PUSHCARGS_5 pushl %edi; cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (edi, 0); _PUSHCARGS_4
-# define _POPCARGS_5 _POPCARGS_4; popl %edi; \
- cfi_adjust_cfa_offset (-4); cfi_restore (edi);
-
-# define PUSHCARGS_6 _PUSHCARGS_6
-# define DOCARGS_6 _DOARGS_6 (44)
-# define POPCARGS_6 _POPCARGS_6
-# define _PUSHCARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (ebp, 0); _PUSHCARGS_5
-# define _POPCARGS_6 _POPCARGS_5; popl %ebp; \
- cfi_adjust_cfa_offset (-4); cfi_restore (ebp);
-
-# if IS_IN (libpthread)
-# define CENABLE call __pthread_enable_asynccancel;
-# define CDISABLE call __pthread_disable_asynccancel
-# elif IS_IN (libc)
-# define CENABLE call __libc_enable_asynccancel;
-# define CDISABLE call __libc_disable_asynccancel
-# elif IS_IN (librt)
-# define CENABLE call __librt_enable_asynccancel;
-# define CDISABLE call __librt_disable_asynccancel
-# else
-# error Unsupported library
-# endif
-# define POPSTATE_0 \
- pushl %eax; cfi_adjust_cfa_offset (4); movl %ecx, %eax; \
- CDISABLE; popl %eax; cfi_adjust_cfa_offset (-4);
-# define POPSTATE_1 POPSTATE_0
-# define POPSTATE_2 xchgl (%esp), %eax; CDISABLE; popl %eax; \
- cfi_adjust_cfa_offset (-4);
-# define POPSTATE_3 POPSTATE_2
-# define POPSTATE_4 POPSTATE_3
-# define POPSTATE_5 POPSTATE_4
-# define POPSTATE_6 POPSTATE_5
+# undef PSEUDO_RET
+# define PSEUDO_RET
# ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \
@@ -150,4 +104,10 @@
# define RTLD_SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
+
+static inline
+long int __pthread_get_ip (const ucontext_t *uc)
+{
+ return (long int)uc->uc_mcontext.gregs[REG_EIP];
+}
#endif
@@ -373,6 +373,42 @@ struct libc_do_syscall_args
register unsigned int resultvar; \
INTERNAL_SYSCALL_MAIN_##nr (name, err, args); \
(int) resultvar; })
+
+/* Same as INTERNAL_SYSCALL, but for non-constant name argument. */
+#define INTERNAL_SYSCALL_MAIN_NCS_0(name, err, args...) \
+ INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 0, args)
+#define INTERNAL_SYSCALL_MAIN_NCS_1(name, err, args...) \
+ INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 1, args)
+#define INTERNAL_SYSCALL_MAIN_NCS_2(name, err, args...) \
+ INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 2, args)
+#define INTERNAL_SYSCALL_MAIN_NCS_3(name, err, args...) \
+ INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 3, args)
+#define INTERNAL_SYSCALL_MAIN_NCS_4(name, err, args...) \
+ INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 4, args)
+#define INTERNAL_SYSCALL_MAIN_NCS_5(name, err, args...) \
+ INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 5, args)
+/* The NCS version is different because it has a non-constant 'name' arg
+ and then requires a different asm constraint ("0" instead of "i"). */
+#define INTERNAL_SYSCALL_MAIN_NCS_6(name, err, arg1, arg2, arg3, \
+ arg4, arg5, arg6) \
+ struct libc_do_syscall_args _xv = \
+ { \
+ (int) (arg1), \
+ (int) (arg5), \
+ (int) (arg6) \
+ }; \
+ asm volatile ( \
+ "movl %1, %%eax\n\t" \
+ "call __libc_do_syscall" \
+ : "=a" (resultvar) \
+ : "0" (name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \
+ : "memory", "cc")
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ INTERNAL_SYSCALL_MAIN_NCS_##nr (name, err, args); \
+ (int) resultvar; })
+
#ifdef I386_USE_SYSENTER
# ifdef SHARED
# define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
@@ -385,9 +421,7 @@ struct libc_do_syscall_args
: "=a" (resultvar) \
: "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
- ({ \
- register unsigned int resultvar; \
+# define INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, nr, args...) \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
@@ -395,8 +429,7 @@ struct libc_do_syscall_args
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
- ASMFMT_##nr(args) : "memory", "cc"); \
- (int) resultvar; })
+ ASMFMT_##nr(args) : "memory", "cc")
# else
# define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
EXTRAVAR_##nr \
@@ -407,17 +440,14 @@ struct libc_do_syscall_args
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
- ({ \
- register unsigned int resultvar; \
+# define INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, nr, args...) \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"call *_dl_sysinfo\n\t" \
RESTOREARGS_##nr \
: "=a" (resultvar) \
- : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
- (int) resultvar; })
+ : "0" (name) ASMFMT_##nr(args) : "memory", "cc")
# endif
#else
# define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \
@@ -429,17 +459,14 @@ struct libc_do_syscall_args
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc")
-# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
- ({ \
- register unsigned int resultvar; \
+# define INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, nr, args...) \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"int $0x80\n\t" \
RESTOREARGS_##nr \
: "=a" (resultvar) \
- : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
- (int) resultvar; })
+ : "0" (name) ASMFMT_##nr(args) : "memory", "cc")
#endif
#undef INTERNAL_SYSCALL_DECL
@@ -452,6 +479,14 @@ struct libc_do_syscall_args
#undef INTERNAL_SYSCALL_ERRNO
#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+#undef SYSCALL_CANCEL_ERROR
+#define SYSCALL_CANCEL_ERROR(__val) \
+ ((unsigned int) (__val) >= 0xfffff001u)
+
+#undef SYSCALL_CANCEL_ERRNO
+#define SYSCALL_CANCEL_ERRNO(__val) \
+ (-(__val))
+
#define LOADARGS_0
#ifdef __PIC__
# if defined I386_USE_SYSENTER && defined SHARED
@@ -86,13 +86,35 @@
sc_ret; \
})
-#define SOCKETCALL_CANCEL(name, __a1, __a2, __a3, __a4, __a5, __a6) \
+
+#define __SOCKETCALL_CANCEL1(__name, __a1) \
+ SYSCALL_CANCEL_NCS (socketcall, __name, \
+ ((long int [1]) { (long int) __a1 }))
+#define __SOCKETCALL_CANCEL2(__name, __a1, __a2) \
+ SYSCALL_CANCEL_NCS (socketcall, __name, \
+ ((long int [2]) { (long int) __a1, (long int) __a2 }))
+#define __SOCKETCALL_CANCEL3(__name, __a1, __a2, __a3) \
+ SYSCALL_CANCEL_NCS (socketcall, __name, \
+ ((long int [3]) { (long int) __a1, (long int) __a2, (long int) __a3 }))
+#define __SOCKETCALL_CANCEL4(__name, __a1, __a2, __a3, __a4) \
+ SYSCALL_CANCEL_NCS (socketcall, __name, \
+ ((long int [4]) { (long int) __a1, (long int) __a2, (long int) __a3, \
+ (long int) __a4 }))
+#define __SOCKETCALL_CANCEL5(__name, __a1, __a2, __a3, __a4, __a5) \
+ SYSCALL_CANCEL_NCS (socketcall, __name, \
+ ((long int [5]) { (long int) __a1, (long int) __a2, (long int) __a3, \
+ (long int) __a4, (long int) __a5 }))
+#define __SOCKETCALL_CANCEL6(__name, __a1, __a2, __a3, __a4, __a5, __a6) \
+ SYSCALL_CANCEL_NCS (socketcall, __name, \
+ ((long int [6]) { (long int) __a1, (long int) __a2, (long int) __a3, \
+ (long int) __a4, (long int) __a5, (long int) __a6 }))
+
+#define __SOCKETCALL_CANCEL(...) __SOCKETCALL_DISP (__SOCKETCALL_CANCEL,\
+ __VA_ARGS__)
+
+#define SOCKETCALL_CANCEL(name, args...) \
({ \
- __syscall_arg_t __args[6] = { __SSC (__a1), __SSC (__a2), \
- __SSC (__a3), __SSC (__a4), \
- __SSC (__a5), __SSC (__a6) }; \
- long int sc_ret = SYSCALL_CANCEL_NCS (socketcall, SOCKOP_##name, \
- __args); \
+ long int sc_ret = __SOCKETCALL_CANCEL (SOCKOP_##name, args); \
if (SYSCALL_CANCEL_ERROR (sc_ret)) \
{ \
__set_errno (SYSCALL_CANCEL_ERRNO (sc_ret)); \
From: Adhemerval Zanella <adhemerval.zanella@linaro.org> This patch adds the i386 modifications required for the BZ#12683 fix. It basically removes the enable_asynccancel/disable_asynccancel function usage on code used on x86_64, provide a arch-specific symbol that contains global markers to be used in SIGCANCEL handler, and add cancellation entrypoints in the socketcall default header. Checked on i686. * sysdeps/i386/nptl/tls.h (THREAD_ATOMIC_BIT_SET): Remove macro. * sysdeps/unix/sysv/linux/i386/Makefile [$(subdir) = elf] (sysdep-rtld_routines): Add libc-do-syscall object. * sysdeps/unix/sysv/linux/i386/fcntl.c (NO_CANCELLATION): Replace by IS_IN (rtld). * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_wait_tid): Use cancellable futex syscall macro. * sysdeps/unix/sysv/linux/i386/syscall_cancel.S: New file. * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (PSEUDO): Redefine to call __syscall_cancel function for cancellable syscalls. * sysdeps/unix/sysv/linux/i386/sysdep.h (SYSCALL_CANCEL_ERROR): New define. (SYSCALL_CANCEL_ERRNO): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_0): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_1): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_2): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_3): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_4): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_5): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_6): Likewise. (INTERNAL_SYSCALL_NCS): Redefine to call it with 6-arguments. --- ChangeLog | 22 ++++ sysdeps/i386/nptl/tls.h | 11 -- sysdeps/unix/sysv/linux/i386/Makefile | 1 + sysdeps/unix/sysv/linux/i386/fcntl.c | 4 +- sysdeps/unix/sysv/linux/i386/lowlevellock.h | 2 +- sysdeps/unix/sysv/linux/i386/syscall_cancel.S | 105 +++++++++++++++++++ sysdeps/unix/sysv/linux/i386/sysdep-cancel.h | 144 ++++++++++---------------- sysdeps/unix/sysv/linux/i386/sysdep.h | 65 +++++++++--- sysdeps/unix/sysv/linux/socketcall.h | 34 ++++-- 9 files changed, 261 insertions(+), 127 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/i386/syscall_cancel.S