]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/unix/sysv/linux/i386/clone.S
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / clone.S
index 94c6a72548f64d1274c8f3f76021e9d184484533..c8dd2e4a372cd87626b6b300471277a1003eeafa 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996,1997,98,99,2000,02,03 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2014 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@tamu.edu)
 
@@ -13,9 +13,8 @@
    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.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 /* clone() is even more special than fork() as it mucks with stacks
    and invokes a function in the right context after its all over.  */
 #define _ERRNO_H       1
 #include <bits/errno.h>
 #include <asm-syntax.h>
-#include <bp-sym.h>
-#include <bp-asm.h>
 
 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
             pid_t *ptid, struct user_desc *tls, pid_t *ctid); */
 
-#define PARMS  LINKAGE         /* no space for saved regs */
+#define PARMS  4               /* no space for saved regs */
 #define FUNC   PARMS
 #define STACK  FUNC+4
-#define FLAGS  STACK+PTR_SIZE
+#define FLAGS  STACK+4
 #define ARG    FLAGS+4
-#define PTID   ARG+PTR_SIZE
-#define TLS    PTID+PTR_SIZE
-#define CTID   TLS+PTR_SIZE
+#define PTID   ARG+4
+#define TLS    PTID+4
+#define CTID   TLS+4
 
 #define __NR_clone 120
 #define SYS_clone 120
 
+#define CLONE_VM       0x00000100
+#define CLONE_THREAD   0x00010000
+
         .text
-ENTRY (BP_SYM (__clone))
+ENTRY (__clone)
        /* Sanity check arguments.  */
        movl    $-EINVAL,%eax
        movl    FUNC(%esp),%ecx         /* no NULL function pointers */
@@ -64,7 +64,7 @@ ENTRY (BP_SYM (__clone))
        /* Insert the argument onto the new stack.  Make sure the new
           thread is started with an alignment of (mod 16).  */
        andl    $0xfffffff0, %ecx
-       subl    $24,%ecx
+       subl    $28,%ecx
        movl    ARG(%esp),%eax          /* no negative argument counts */
        movl    %eax,12(%ecx)
 
@@ -74,17 +74,36 @@ 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
+       cfi_adjust_cfa_offset (4)
        pushl   %esi
+       cfi_adjust_cfa_offset (4)
        pushl   %edi
+       cfi_adjust_cfa_offset (4)
+
        movl    TLS+12(%esp),%esi
+       cfi_rel_offset (esi, 4)
        movl    PTID+12(%esp),%edx
        movl    FLAGS+12(%esp),%ebx
+       cfi_rel_offset (ebx, 8)
        movl    CTID+12(%esp),%edi
+       cfi_rel_offset (edi, 0)
        movl    $SYS_ify(clone),%eax
+
+#ifdef RESET_PID
+       /* Remember the flag value.  */
+       movl    %ebx, (%ecx)
+#endif
+
+       /* End FDE now, because in the child the unwind info will be
+          wrong.  */
+       cfi_endproc
+
        int     $0x80
        popl    %edi
        popl    %esi
@@ -94,11 +113,19 @@ ENTRY (BP_SYM (__clone))
        jl      SYSCALL_ERROR_LABEL
        jz      L(thread_start)
 
-L(pseudo_end):
        ret
 
 L(thread_start):
-       subl    %ebp,%ebp       /* terminate the stack frame */
+       cfi_startproc;
+       /* Clearing frame pointer is insufficient, use CFI.  */
+       cfi_undefined (eip);
+       /* 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)
@@ -108,8 +135,25 @@ L(here):
 #endif
        movl    %eax, %ebx
        movl    $SYS_ify(exit), %eax
-       int     $0x80
+       ENTER_KERNEL
+
+#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
+       cfi_endproc;
 
-PSEUDO_END (BP_SYM (__clone))
+       cfi_startproc
+PSEUDO_END (__clone)
 
-weak_alias (BP_SYM (__clone), BP_SYM (clone))
+weak_alias (__clone, clone)