diff options
-rw-r--r-- | ChangeLog | 42 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/Makefile | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/clone.S | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/clone.S | 11 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/clone.S | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/hppa/clone.S | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/clone.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ia64/clone2.S | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/m68k/clone.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/mips/clone.S | 12 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/nios2/clone.S | 17 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S | 7 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S | 11 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sh/clone.S | 21 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc32/clone.S | 5 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/clone.S | 5 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/tile/clone.S | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/tst-clone3.c | 96 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/clone.S | 5 |
19 files changed, 171 insertions, 104 deletions
@@ -1,3 +1,45 @@ +2017-06-26 Adhemerval Zanella <adhemerval.zanella@linaro.org> + + [BZ #21512] + * sysdeps/unix/sysv/linux/aarch64/clone.S (__clone): Call exit + syscall instead of jump to _exit. + (CLONE_VM_BIT): Remove unused define. + (CLONE_VM): Likewise. + (CLONE_THREAD_BIT): Likewise. + (CLONE_THREAD): Likewise. + * sysdeps/unix/sysv/linux/alpha/clone.S (__clone): Likewise. + (CLONE_VM): Remove unused define. + * sysdeps/unix/sysv/linux/arm/clone.S (__clone): Likewise. + (CLONE_VM): Remove unused define. + (CLONE_THREAD): Likewise. + * sysdeps/unix/sysv/linux/i386/clone.S (CLONE_VM): Likewise. + * sysdeps/unix/sysv/linux/ia64/clone2.S (__clone2): Call exit + syscall instead of jump to _exit. + * sysdeps/unix/sysv/linux/hppa/clone.S (__clone): Likewise. + * sysdeps/unix/sysv/linux/mips/clone.S (__clone): Likewise. + (CLONE_VM): Remove unused define. + (CLONE_THREAD): Likewise. + * sysdeps/unix/sysv/linux/nios2/clone.S (__clone): Likewise. + (CLONE_VM): Remove unused define. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S (__clone): + Likewise. + (CLONE_VM): Remove unused define. + (CLONE_THREAD): Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S (__clone): + Likewise. + (CLONE_VM): Remove unused define. + (CLONE_THREAD): Likewise. + * sysdeps/unix/sysv/linux/sh/clone.S (__clone): Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S (__clone): Likewise. + (CLONE_VM): Remove unused define. + * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S (__clone): Likewise. + (CLONE_VM): Remove unused define. + * sysdeps/unix/sysv/linux/tile/clone.S (__clone): Likewise. + * sysdeps/unix/sysv/linux/x86_64/clone.S (__clone): Likewise. + (CLONE_VM): Remove unused define. + * sysdeps/unix/sysv/linux/Makefile (tests): Add tst-clone3. + * sysdeps/unix/sysv/linux/tst-clone3.c: New file. + 2017-06-26 Paul E. Murphy <murphyp@linux.vnet.ibm.com> Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 8b340d4988..9d6a2de870 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -49,8 +49,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ bits/mman-linux.h \ bits/siginfo-arch.h bits/siginfo-consts-arch.h -tests += tst-clone tst-clone2 tst-fanotify tst-personality tst-quota \ - tst-sync_file_range test-errno-linux +tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-quota tst-sync_file_range test-errno-linux # Generate the list of SYS_* macros for the system calls (__NR_* macros). diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S index 259ec073c5..905915a0f3 100644 --- a/sysdeps/unix/sysv/linux/aarch64/clone.S +++ b/sysdeps/unix/sysv/linux/aarch64/clone.S @@ -23,12 +23,6 @@ #define _ERRNO_H 1 #include <bits/errno.h> -#define CLONE_VM_BIT 8 -#define CLONE_VM (1 << CLONE_VM_BIT) - -#define CLONE_THREAD_BIT 16 -#define CLONE_THREAD (1 << CLONE_THREAD_BIT) - /* int clone(int (*fn)(void *arg), x0 void *child_stack, x1 int flags, x2 @@ -84,7 +78,8 @@ thread_start: blr x10 /* We are done, pass the return value through x0. */ - b HIDDEN_JUMPTARGET(_exit) + mov x8, #SYS_ify(exit) + svc 0x0 cfi_endproc .size thread_start, .-thread_start diff --git a/sysdeps/unix/sysv/linux/alpha/clone.S b/sysdeps/unix/sysv/linux/alpha/clone.S index 20ae361c6b..550461fb3b 100644 --- a/sysdeps/unix/sysv/linux/alpha/clone.S +++ b/sysdeps/unix/sysv/linux/alpha/clone.S @@ -23,8 +23,6 @@ #define _ERRNO_H 1 #include <bits/errno.h> -#define CLONE_VM 0x00000100 - /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, pid_t *ptid, void *tls, pid_t *ctid); @@ -100,13 +98,8 @@ thread_start: jsr ra, (pv) ldgp gp, 0(ra) - /* Call _exit rather than doing it inline for breakpoint purposes. */ - mov v0, a0 -#ifdef PIC - bsr ra, HIDDEN_JUMPTARGET(_exit) !samegp -#else - jsr ra, HIDDEN_JUMPTARGET(_exit) -#endif + ldiq v0, __NR_exit + call_pal PAL_callsys /* Die horribly. */ .align 4 diff --git a/sysdeps/unix/sysv/linux/arm/clone.S b/sysdeps/unix/sysv/linux/arm/clone.S index a309add895..055d1304d9 100644 --- a/sysdeps/unix/sysv/linux/arm/clone.S +++ b/sysdeps/unix/sysv/linux/arm/clone.S @@ -24,9 +24,6 @@ #define _ERRNO_H 1 #include <bits/errno.h> -#define CLONE_VM 0x00000100 -#define CLONE_THREAD 0x00010000 - /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, pid_t *ptid, struct user_desc *tls, pid_t *ctid); */ @@ -76,7 +73,8 @@ PSEUDO_END (__clone) BLX (ip) @ and we are done, passing the return value through r0 - b PLTJMP(HIDDEN_JUMPTARGET(_exit)) + ldr r7, =SYS_ify(exit) + swi 0x0 .fnend diff --git a/sysdeps/unix/sysv/linux/hppa/clone.S b/sysdeps/unix/sysv/linux/hppa/clone.S index d36b302199..8c43944c7a 100644 --- a/sysdeps/unix/sysv/linux/hppa/clone.S +++ b/sysdeps/unix/sysv/linux/hppa/clone.S @@ -148,10 +148,10 @@ ENTRY(__clone) copy %r4, %r19 #endif /* The call to _exit needs saved r19. */ - bl _exit, %rp - copy %ret0, %arg0 + ble 0x100(%sr2, %r0) + ldi __NR_exit, %r20 - /* We should not return from _exit. + /* We should not return from exit. We do not restore r4, or the stack state. */ iitlbp %r0, (%sr0, %r0) diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S index a4ba3e20ff..49c82d98b0 100644 --- a/sysdeps/unix/sysv/linux/i386/clone.S +++ b/sysdeps/unix/sysv/linux/i386/clone.S @@ -39,8 +39,6 @@ #define __NR_clone 120 #define SYS_clone 120 -#define CLONE_VM 0x00000100 - .text ENTRY (__clone) /* Sanity check arguments. */ diff --git a/sysdeps/unix/sysv/linux/ia64/clone2.S b/sysdeps/unix/sysv/linux/ia64/clone2.S index 9b59473c80..3157ce92d6 100644 --- a/sysdeps/unix/sysv/linux/ia64/clone2.S +++ b/sysdeps/unix/sysv/linux/ia64/clone2.S @@ -74,11 +74,11 @@ ENTRY(__clone2) mov b6=out1 br.call.dptk.many rp=b6 /* Call fn(arg) in the child */ ;; - mov out0=r8 /* Argument to _exit */ + mov out0=r8 /* Argument to exit */ mov gp=loc0 - .globl HIDDEN_JUMPTARGET(_exit) - br.call.dpnt.many rp=HIDDEN_JUMPTARGET(_exit) - /* call _exit with result from fn. */ + mov r15=SYS_ify (exit) + .save rp, r0 + break __BREAK_SYSCALL ret /* Not reached. */ PSEUDO_END(__clone2) diff --git a/sysdeps/unix/sysv/linux/m68k/clone.S b/sysdeps/unix/sysv/linux/m68k/clone.S index a680191765..0894b2a362 100644 --- a/sysdeps/unix/sysv/linux/m68k/clone.S +++ b/sysdeps/unix/sysv/linux/m68k/clone.S @@ -24,8 +24,6 @@ #include <bits/errno.h> #include <tls.h> -#define CLONE_VM 0x00000100 - /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, void *parent_tidptr, void *tls, void *child_tidptr) */ diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S index 8b79457b1f..57b6c5e5bb 100644 --- a/sysdeps/unix/sysv/linux/mips/clone.S +++ b/sysdeps/unix/sysv/linux/mips/clone.S @@ -25,9 +25,6 @@ #include <bits/errno.h> #include <tls.h> -#define CLONE_VM 0x00000100 -#define CLONE_THREAD 0x00010000 - /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, void *parent_tidptr, void *tls, void *child_tidptr) */ @@ -137,14 +134,9 @@ L(thread_start): /* Call the user's function. */ jal t9 - /* Call _exit rather than doing it inline for breakpoint purposes. */ move a0,v0 -#ifdef __PIC__ - PTR_LA t9,_exit - jalr t9 -#else - jal _exit -#endif + li v0,__NR_exit + syscall END(__thread_start) diff --git a/sysdeps/unix/sysv/linux/nios2/clone.S b/sysdeps/unix/sysv/linux/nios2/clone.S index 7929dfa48a..2ba825888c 100644 --- a/sysdeps/unix/sysv/linux/nios2/clone.S +++ b/sysdeps/unix/sysv/linux/nios2/clone.S @@ -25,8 +25,6 @@ #include <bits/errno.h> #include <tcb-offsets.h> -#define CLONE_VM 0x00000100 - /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, void *parent_tidptr, void *tls, void *child_tidptr) */ @@ -75,18 +73,9 @@ thread_start: /* Call the user's function. */ callr r5 - /* _exit with the result. */ - mov r4, r2 -#ifdef PIC - nextpc r22 -1: movhi r8, %hiadj(_gp_got - 1b) - addi r8, r8, %lo(_gp_got - 1b) - add r22, r22, r8 - ldw r8, %call(HIDDEN_JUMPTARGET(_exit))(r22) - jmp r8 -#else - jmpi _exit -#endif + /* exit with the result. */ + movi r2, SYS_ify (exit) + trap cfi_endproc cfi_startproc diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S index a07b7d3238..e48cc5f2f3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S @@ -20,10 +20,6 @@ #define _ERRNO_H 1 #include <bits/errno.h> -#define CLONE_VM 0x00000100 -#define CLONE_THREAD 0x00010000 - - /* This is the only really unusual system call in PPC linux, but not because of any weirdness in the system call itself; because of all the freaky stuff we have to do to make the call useful. */ @@ -80,8 +76,7 @@ ENTRY (__clone) mtctr r30 mr r3,r31 bctrl - /* Call _exit with result from procedure. */ - b HIDDEN_JUMPTARGET(_exit) + DO_CALL(SYS_ify(exit)) L(parent): /* Parent. Restore registers & return. */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S index 9e5bfd2d03..78c353a8c7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S @@ -20,9 +20,6 @@ #define _ERRNO_H 1 #include <bits/errno.h> -#define CLONE_VM 0x00000100 -#define CLONE_THREAD 0x00010000 - /* This is the only really unusual system call in PPC linux, but not because of any weirdness in the system call itself; because of all the freaky stuff we have to do to make the call useful. */ @@ -84,15 +81,11 @@ ENTRY (__clone) mr r3,r31 bctrl ld r2,FRAME_TOC_SAVE(r1) - /* Call _exit with result from procedure. */ -#ifdef SHARED - b JUMPTARGET(__GI__exit) -#else - bl JUMPTARGET(_exit) + + DO_CALL(SYS_ify(exit)) /* We won't ever get here but provide a nop so that the linker will insert a toc adjusting stub if necessary. */ nop -#endif L(badargs): cfi_startproc diff --git a/sysdeps/unix/sysv/linux/sh/clone.S b/sysdeps/unix/sysv/linux/sh/clone.S index 9063b21928..b13a64bb10 100644 --- a/sysdeps/unix/sysv/linux/sh/clone.S +++ b/sysdeps/unix/sysv/linux/sh/clone.S @@ -73,25 +73,8 @@ ENTRY(__clone) mov.l @(4,r15), r4 /* we are done, passing the return value through r0 */ - mov.l .L3, r1 -#ifdef SHARED - mov.l r12, @-r15 - sts.l pr, @-r15 - mov r0, r4 - mova .LG, r0 - mov.l .LG, r12 - add r0, r12 - mova .L3, r0 - add r0, r1 - jsr @r1 - nop - lds.l @r15+, pr - rts - mov.l @r15+, r12 -#else - jmp @r1 - mov r0, r4 -#endif + mov #+SYS_ify(exit), r3 + trapa #0x15 .align 2 .LG: .long _GLOBAL_OFFSET_TABLE_ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S index 6d2f5bd55f..1afa26e559 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S @@ -24,8 +24,6 @@ #include <tcb-offsets.h> #include <sysdep.h> -#define CLONE_VM 0x00000100 - /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, pid_t *ptid, void *tls, pid_t *ctid); */ @@ -81,7 +79,8 @@ __thread_start: mov %g0, %fp /* terminate backtrace */ call %g2 mov %g3,%o0 - call HIDDEN_JUMPTARGET(_exit),0 + set __NR_exit, %g1 + ta 0x10 nop .size __thread_start, .-__thread_start diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S index fc28539a59..785ccd1beb 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S @@ -24,8 +24,6 @@ #include <tcb-offsets.h> #include <sysdep.h> -#define CLONE_VM 0x00000100 - /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, pid_t *ptid, void *tls, pid_t *ctid); */ @@ -78,7 +76,8 @@ __thread_start: mov %g0, %fp /* terminate backtrace */ call %g2 mov %g3,%o0 - call HIDDEN_JUMPTARGET(_exit),0 + set __NR_exit, %g1 + ta 0x6d nop .size __thread_start, .-__thread_start diff --git a/sysdeps/unix/sysv/linux/tile/clone.S b/sysdeps/unix/sysv/linux/tile/clone.S index d7d2a3b968..9610acdd8d 100644 --- a/sysdeps/unix/sysv/linux/tile/clone.S +++ b/sysdeps/unix/sysv/linux/tile/clone.S @@ -168,10 +168,8 @@ ENTRY (__clone) move r0, r31 jalr r32 } - { - j HIDDEN_JUMPTARGET(_exit) - info INFO_OP_CANNOT_BACKTRACE /* Notify backtracer to stop. */ - } + moveli TREG_SYSCALL_NR_NAME, __NR_exit + swint1 PSEUDO_END (__clone) libc_hidden_def (__clone) diff --git a/sysdeps/unix/sysv/linux/tst-clone3.c b/sysdeps/unix/sysv/linux/tst-clone3.c new file mode 100644 index 0000000000..a742237cb3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-clone3.c @@ -0,0 +1,96 @@ +/* Check if clone (CLONE_THREAD) does not call exit_group (BZ #21512) + Copyright (C) 2017 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 <string.h> +#include <sched.h> +#include <signal.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <linux/futex.h> + +#include <stackinfo.h> /* For _STACK_GROWS_{UP,DOWN}. */ +#include <support/check.h> + +/* Test if clone call with CLONE_THREAD does not call exit_group. The 'f' + function returns '1', which will be used by clone thread to call the + 'exit' syscall directly. If _exit is used instead, exit_group will be + used and thus the thread group will finish with return value of '1' + (where '2' from main thread is expected. */ + +static int +f (void *a) +{ + return 1; +} + +/* Futex wait for TID argument, similar to pthread_join internal + implementation. */ +#define wait_tid(tid) \ + do { \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + futex_wait (&(tid), __tid); \ + } while (0) + +static inline int +futex_wait (int *futexp, int val) +{ + return syscall (__NR_futex, futexp, FUTEX_WAIT, val); +} + +static int +do_test (void) +{ + char st[1024] __attribute__ ((aligned)); + int clone_flags = CLONE_THREAD; + /* Minimum required flags to used along with CLONE_THREAD. */ + clone_flags |= CLONE_VM | CLONE_SIGHAND; + /* We will used ctid to call on futex to wait for thread exit. */ + clone_flags |= CLONE_CHILD_CLEARTID; + pid_t ctid, tid; + +#ifdef __ia64__ + extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base, + size_t __child_stack_size, int __flags, + void *__arg, ...); + tid = __clone2 (f, st, sizeof (st), clone_flags, NULL, /* ptid */ NULL, + /* tls */ NULL, &ctid); +#else +#if _STACK_GROWS_DOWN + tid = clone (f, st + sizeof (st), clone_flags, NULL, /* ptid */ NULL, + /* tls */ NULL, &ctid); +#elif _STACK_GROWS_UP + tid = clone (f, st, clone_flags, NULL, /* ptid */ NULL, /* tls */ NULL, + &ctid); +#else +#error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +#endif +#endif + if (tid == -1) + FAIL_EXIT1 ("clone failed: %m"); + + ctid = tid; + wait_tid (ctid); + + return 2; +} + +#define EXPECTED_STATUS 2 +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S index d5c2d07885..b10fc2999c 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clone.S +++ b/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -23,8 +23,6 @@ #include <bits/errno.h> #include <asm-syntax.h> -#define CLONE_VM 0x00000100 - /* The userland implementation is: int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg), the kernel entry is: @@ -97,7 +95,8 @@ L(thread_start): call *%rax /* Call exit with return value from function call. */ movq %rax, %rdi - call HIDDEN_JUMPTARGET (_exit) + movl $SYS_ify(exit), %eax + syscall cfi_endproc; cfi_startproc; |