aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog42
-rw-r--r--sysdeps/unix/sysv/linux/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/clone.S9
-rw-r--r--sysdeps/unix/sysv/linux/alpha/clone.S11
-rw-r--r--sysdeps/unix/sysv/linux/arm/clone.S6
-rw-r--r--sysdeps/unix/sysv/linux/hppa/clone.S6
-rw-r--r--sysdeps/unix/sysv/linux/i386/clone.S2
-rw-r--r--sysdeps/unix/sysv/linux/ia64/clone2.S8
-rw-r--r--sysdeps/unix/sysv/linux/m68k/clone.S2
-rw-r--r--sysdeps/unix/sysv/linux/mips/clone.S12
-rw-r--r--sysdeps/unix/sysv/linux/nios2/clone.S17
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S7
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S11
-rw-r--r--sysdeps/unix/sysv/linux/sh/clone.S21
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/clone.S5
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/clone.S5
-rw-r--r--sysdeps/unix/sysv/linux/tile/clone.S6
-rw-r--r--sysdeps/unix/sysv/linux/tst-clone3.c96
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/clone.S5
19 files changed, 171 insertions, 104 deletions
diff --git a/ChangeLog b/ChangeLog
index 4fada927c5..c530cae057 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;