From e8e2384f2ed57515873b81914c2999735856b02e Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Wed, 14 Nov 2001 02:26:48 +0000 Subject: Fix the clone syscall so it actually works. --- libc/sysdeps/linux/i386/Makefile | 2 +- libc/sysdeps/linux/i386/clone.S | 59 ++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 30 deletions(-) (limited to 'libc') diff --git a/libc/sysdeps/linux/i386/Makefile b/libc/sysdeps/linux/i386/Makefile index 6dd7c5f26..f38bc37ec 100644 --- a/libc/sysdeps/linux/i386/Makefile +++ b/libc/sysdeps/linux/i386/Makefile @@ -35,7 +35,7 @@ CRT0_OBJ=$(patsubst %.S,%.o, $(CRT0)) endif -SSRC=__longjmp.S setjmp.S vfork.S #_start.S #clone.S +SSRC=__longjmp.S setjmp.S vfork.S clone.S ifeq ($(UNIFIED_SYSCALL),true) SSRC += __uClibc_syscall.S endif diff --git a/libc/sysdeps/linux/i386/clone.S b/libc/sysdeps/linux/i386/clone.S index e15116152..c52bb7fd8 100644 --- a/libc/sysdeps/linux/i386/clone.S +++ b/libc/sysdeps/linux/i386/clone.S @@ -20,32 +20,20 @@ /* clone() is even more special than fork() as it mucks with stacks and invokes a function in the right context after its all over. */ -#include +#include +#include - -/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ - - .text -.globl __clone; -.type __clone,@function -.align 4; \ +.text +.align 4 +.type __clone,@function +.globl __clone; __clone: /* Sanity check arguments. */ - movl $-EINVAL,%eax movl 4(%esp),%ecx /* no NULL function pointers */ -#ifdef PIC - jecxz SYSCALL_ERROR_LABEL -#else - testl %ecx,%ecx - jz SYSCALL_ERROR_LABEL -#endif + jecxz CLONE_ERROR_LABEL + movl 8(%esp),%ecx /* no NULL stack pointers */ -#ifdef PIC - jecxz SYSCALL_ERROR_LABEL -#else - testl %ecx,%ecx - jz SYSCALL_ERROR_LABEL -#endif + jecxz CLONE_ERROR_LABEL /* Insert the argument onto the new stack. */ subl $8,%ecx @@ -65,22 +53,35 @@ __clone: popl %ebx test %eax,%eax - jl SYSCALL_ERROR_LABEL - jz thread_start + jl CLONE_ERROR_LABEL + jne CLONE_RETURN_LABEL -L(pseudo_end): - ret - -thread_start: + /* Start thread */ subl %ebp,%ebp /* terminate the stack frame */ call *%ebx + pushl %eax + call _exit + +CLONE_ERROR_LABEL: + negl %eax + pushl %eax #ifdef PIC call L(here) L(here): popl %ebx addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebx + call __errno_location@PLT +#else + call __errno_location #endif - pushl %eax - call _exit + popl %ecx + movl %ecx, (%eax) + xorl %eax, %eax + decl %eax + +CLONE_RETURN_LABEL: + ret +.globl clone; + clone = __clone -- cgit v1.2.3