about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386/clone.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/clone.S')
-rw-r--r--sysdeps/unix/sysv/linux/i386/clone.S36
1 files changed, 34 insertions, 2 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S
index 94c6a72548..acd43dfb0b 100644
--- a/sysdeps/unix/sysv/linux/i386/clone.S
+++ b/sysdeps/unix/sysv/linux/i386/clone.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996,1997,98,99,2000,02,03 Free Software Foundation, Inc.
+/* Copyright (C) 1996,1997,98,99,2000,02,03,04 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@tamu.edu)
 
@@ -42,6 +42,9 @@
 #define __NR_clone 120
 #define SYS_clone 120
 
+#define CLONE_VM	0x00000100
+#define CLONE_THREAD	0x00010000
+
         .text
 ENTRY (BP_SYM (__clone))
 	/* Sanity check arguments.  */
@@ -74,7 +77,9 @@ ENTRY (BP_SYM (__clone))
 	movl	%eax,8(%ecx)
 	/* Don't leak any information.  */
 	movl	$0,4(%ecx)
+#ifndef RESET_PID
 	movl	$0,(%ecx)
+#endif
 
 	/* Do the system call */
 	pushl	%ebx
@@ -85,6 +90,12 @@ ENTRY (BP_SYM (__clone))
 	movl	FLAGS+12(%esp),%ebx
 	movl	CTID+12(%esp),%edi
 	movl	$SYS_ify(clone),%eax
+
+#ifdef RESET_PID
+	/* Remember the flag value.  */
+	movl	%ebx, (%ecx)
+#endif
+
 	int	$0x80
 	popl	%edi
 	popl	%esi
@@ -98,7 +109,13 @@ L(pseudo_end):
 	ret
 
 L(thread_start):
-	subl	%ebp,%ebp	/* terminate the stack frame */
+	/* Note: %esi is zero.  */
+	movl	%esi,%ebp	/* terminate the stack frame */
+#ifdef RESET_PID
+	testl	$CLONE_THREAD, %edi
+	je	L(newpid)
+L(haspid):
+#endif
 	call	*%ebx
 #ifdef PIC
 	call	L(here)
@@ -110,6 +127,21 @@ L(here):
 	movl	$SYS_ify(exit), %eax
 	int	$0x80
 
+#ifdef RESET_PID
+	.subsection 2
+L(newpid):
+	testl	$CLONE_VM, %edi
+	movl	$-1, %eax
+	jne	L(nomoregetpid)
+	movl	$SYS_ify(getpid), %eax
+	ENTER_KERNEL
+L(nomoregetpid):
+	movl	%eax, %gs:PID
+	movl	%eax, %gs:TID
+	jmp	L(haspid)
+	.previous
+#endif
+
 PSEUDO_END (BP_SYM (__clone))
 
 weak_alias (BP_SYM (__clone), BP_SYM (clone))