diff options
Diffstat (limited to 'libc/sysdeps')
-rw-r--r-- | libc/sysdeps/linux/i386/vfork.S | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/libc/sysdeps/linux/i386/vfork.S b/libc/sysdeps/linux/i386/vfork.S index e2d87053b..c7002f189 100644 --- a/libc/sysdeps/linux/i386/vfork.S +++ b/libc/sysdeps/linux/i386/vfork.S @@ -2,60 +2,62 @@ * June 27, 2001 Manuel Novoa III * * Modified to (hopefully) be PIC and REENTRANT safe. + * Modified again to better follow the glibc implementation. * */ + +#define _ERRNO_H 1 +#include <bits/errno.h> +#include <sys/syscall.h> + + .text + .globl __vfork; + .type __vfork,@function; + .align 1<<4; -.text - .align 4 -.globl vfork - .type vfork,@function -vfork: +__vfork: +#ifdef __NR_vfork popl %ecx - movl $190,%eax -#ifdef __PIC__ - pushl %ebx -#endif -#APP + movl $__NR_vfork,%eax int $0x80 -#NO_APP -#ifdef __PIC__ - popl %ebx -#endif + pushl %ecx cmpl $-4095,%eax jae .Lerror - jmp *%ecx - .p2align 4,,7 + ret + .Lerror: - pushl %ecx + cmpl $-ENOSYS,%eax + jne __syscall_error +#endif + /* Fall back on calling fork */ + movl $__NR_fork,%eax + int $0x80 + cmpl $-4095,%eax + jae __syscall_error + ret + +__syscall_error: + negl %eax + pushl %eax #ifdef __PIC__ - pushl %ebx - call .Lhere -.Lhere: - popl %ebx - addl $_GLOBAL_OFFSET_TABLE_+[.-.Lhere],%ebx - negl %eax - movl %eax,%ecx -#ifdef __UCLIBC_HAS_THREADS__ - call __errno_location@PLT -#else - movl errno@GOT(%ebx),%eax -#endif /* __UCLIBC_HAS_THREADS__ */ - movl %ecx,(%eax) - popl %ebx + call .Lthere +.Lthere: + popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.- .Lthere ], %ebx + call __errno_location@PLT #else - negl %eax -#ifdef __UCLIBC_HAS_THREADS__ - movl %eax,%ecx - call __errno_location - movl %ecx,(%eax) -#else - movl %eax,errno -#endif /* __UCLIBC_HAS_THREADS__ */ + call __errno_location +#endif + popl %ecx + movl %ecx, (%eax) + xorl %eax, %eax + decl %eax -#endif /* __PIC__ */ - - movl $-1,%eax - ret .Lsize: - .size vfork,.Lsize-vfork + .size __vfork,.Lsize-__vfork + + +.weak vfork ; vfork = __vfork + + |