|
@@ -1,75 +1,122 @@
|
|
|
-/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
|
|
+/* Copyright (C) 1996, 1997,98,99,2000,02 Free Software Foundation, Inc.
|
|
|
This file is part of the GNU C Library.
|
|
|
Contributed by Richard Henderson (rth@tamu.edu)
|
|
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
|
- modify it under the terms of the GNU Library General Public License as
|
|
|
- published by the Free Software Foundation; either version 2 of the
|
|
|
- License, or (at your option) any later version.
|
|
|
+ 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
|
|
|
- Library General Public License for more details.
|
|
|
+ Lesser General Public License for more details.
|
|
|
|
|
|
- You should have received a copy of the GNU Library General Public
|
|
|
- License along with the GNU C Library; see the file COPYING.LIB. If not,
|
|
|
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
- Boston, MA 02111-1307, USA. */
|
|
|
+ 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. */
|
|
|
|
|
|
/* clone() is even more special than fork() as it mucks with stacks
|
|
|
- and invokes a function in the right context after its all over. */
|
|
|
+ and invokes a function in the right context after its all over.
|
|
|
+
|
|
|
+ Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
|
|
|
+*/
|
|
|
|
|
|
+#define _ERRNO_H 1
|
|
|
#include <bits/errno.h>
|
|
|
#include <sys/syscall.h>
|
|
|
|
|
|
-.text
|
|
|
-.align 4
|
|
|
-.type __clone,@function
|
|
|
-.globl __clone;
|
|
|
+#define LINKAGE 4
|
|
|
+#define PTR_SIZE 4
|
|
|
+#define PARMS LINKAGE /* no space for saved regs */
|
|
|
+#define FUNC PARMS
|
|
|
+#define STACK FUNC+4
|
|
|
+#define FLAGS STACK+PTR_SIZE
|
|
|
+#define ARG FLAGS+4
|
|
|
+#define PTID ARG+PTR_SIZE
|
|
|
+#define TLS PTID+PTR_SIZE
|
|
|
+#define CTID TLS+PTR_SIZE
|
|
|
+
|
|
|
+
|
|
|
+ .text
|
|
|
+ .globl __clone;
|
|
|
+ .type __clone,@function;
|
|
|
+ .align 1<<4;
|
|
|
+
|
|
|
__clone:
|
|
|
/* Sanity check arguments. */
|
|
|
- movl 4(%esp),%ecx /* no NULL function pointers */
|
|
|
- jecxz CLONE_ERROR_LABEL
|
|
|
-
|
|
|
- movl 8(%esp),%ecx /* no NULL stack pointers */
|
|
|
- jecxz CLONE_ERROR_LABEL
|
|
|
+ movl $-EINVAL,%eax
|
|
|
+ movl FUNC(%esp),%ecx /* no NULL function pointers */
|
|
|
+#ifdef __PIC__
|
|
|
+ jecxz __syscall_error
|
|
|
+#else
|
|
|
+ testl %ecx,%ecx
|
|
|
+ jz __syscall_error
|
|
|
+#endif
|
|
|
+ movl STACK(%esp),%ecx /* no NULL stack pointers */
|
|
|
+#ifdef __PIC__
|
|
|
+ jecxz __syscall_error
|
|
|
+#else
|
|
|
+ testl %ecx,%ecx
|
|
|
+ jz __syscall_error
|
|
|
+#endif
|
|
|
|
|
|
/* Insert the argument onto the new stack. */
|
|
|
- subl $8,%ecx
|
|
|
- movl 16(%esp),%eax /* no negative argument counts */
|
|
|
- movl %eax,4(%ecx)
|
|
|
+ subl $16,%ecx
|
|
|
+ movl ARG(%esp),%eax /* no negative argument counts */
|
|
|
+ movl %eax,12(%ecx)
|
|
|
|
|
|
/* Save the function pointer as the zeroth argument.
|
|
|
It will be popped off in the child in the ebx frobbing below. */
|
|
|
- movl 4(%esp),%eax
|
|
|
- movl %eax,0(%ecx)
|
|
|
+ movl FUNC(%esp),%eax
|
|
|
+ movl %eax,8(%ecx)
|
|
|
+ /* Don't leak any information. */
|
|
|
+ movl $0,4(%ecx)
|
|
|
+ movl $0,(%ecx)
|
|
|
|
|
|
/* Do the system call */
|
|
|
pushl %ebx
|
|
|
- movl 16(%esp),%ebx
|
|
|
+ pushl %esi
|
|
|
+ pushl %edi
|
|
|
+ movl TLS+12(%esp),%esi
|
|
|
+ movl PTID+12(%esp),%edx
|
|
|
+ movl FLAGS+12(%esp),%ebx
|
|
|
+ movl CTID+12(%esp),%edi
|
|
|
movl $__NR_clone,%eax
|
|
|
int $0x80
|
|
|
+ popl %edi
|
|
|
+ popl %esi
|
|
|
popl %ebx
|
|
|
|
|
|
test %eax,%eax
|
|
|
- jl CLONE_ERROR_LABEL
|
|
|
- jne CLONE_RETURN_LABEL
|
|
|
+ jl __syscall_error
|
|
|
+ jz .Lthread_start
|
|
|
|
|
|
- /* Start thread */
|
|
|
+.Lpseudo_end:
|
|
|
+ ret
|
|
|
+
|
|
|
+.Lthread_start:
|
|
|
subl %ebp,%ebp /* terminate the stack frame */
|
|
|
call *%ebx
|
|
|
- pushl %eax
|
|
|
- call _exit
|
|
|
+#ifdef __PIC__
|
|
|
+ call .Lhere
|
|
|
+.Lhere:
|
|
|
+ popl %ebx
|
|
|
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.Lhere], %ebx
|
|
|
+#endif
|
|
|
+ movl %eax, %ebx
|
|
|
+ movl $__NR_exit, %eax
|
|
|
+ int $0x80
|
|
|
|
|
|
-CLONE_ERROR_LABEL:
|
|
|
+__syscall_error:
|
|
|
negl %eax
|
|
|
pushl %eax
|
|
|
#ifdef __PIC__
|
|
|
- call .Lhere
|
|
|
-.Lhere:
|
|
|
+ call .Lthere
|
|
|
+.Lthere:
|
|
|
popl %ebx
|
|
|
- addl $_GLOBAL_OFFSET_TABLE_+[.- .Lhere ], %ebx
|
|
|
+ addl $_GLOBAL_OFFSET_TABLE_+[.- .Lthere ], %ebx
|
|
|
call __errno_location@PLT
|
|
|
#else
|
|
|
call __errno_location
|
|
@@ -79,9 +126,7 @@ CLONE_ERROR_LABEL:
|
|
|
xorl %eax, %eax
|
|
|
decl %eax
|
|
|
|
|
|
-CLONE_RETURN_LABEL:
|
|
|
- ret
|
|
|
-
|
|
|
-.globl clone;
|
|
|
- clone = __clone
|
|
|
+.Lsize:
|
|
|
+ .size __clone,.Lsize-__clone
|
|
|
|
|
|
+.weak clone ; clone = __clone
|