about summary refs log tree commit diff
path: root/linuxthreads/sysdeps/unix
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-09-17 18:23:49 +0000
committerUlrich Drepper <drepper@redhat.com>2003-09-17 18:23:49 +0000
commit06f6ca9019897f5d1799c0ae8d7293ed249c0f97 (patch)
tree9a04e5058de47ce0898cf279205c8e58735efb96 /linuxthreads/sysdeps/unix
parent65af7e61427ce9bbbc0e43b2ad44e5b4678a37fc (diff)
downloadglibc-06f6ca9019897f5d1799c0ae8d7293ed249c0f97.tar.gz
glibc-06f6ca9019897f5d1799c0ae8d7293ed249c0f97.tar.xz
glibc-06f6ca9019897f5d1799c0ae8d7293ed249c0f97.zip
Update.
2003-09-17  Philip Blundell  <philb@gnu.org>

	* sysdeps/unix/sysv/linux/arm/vfork.S: Branch to fork if
	libpthread is loaded.  Elide backwards compatibility code when not
	required.
Diffstat (limited to 'linuxthreads/sysdeps/unix')
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S39
1 files changed, 31 insertions, 8 deletions
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
index 8d3338afd0..23687342d1 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
+++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
@@ -20,37 +20,60 @@
 #include <sysdep-cancel.h>
 #define _ERRNO_H	1
 #include <bits/errno.h>
+#include <kernel-features.h>
 
-/* Clone the calling process, but without copying the whole address
-pace.
+/* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
-   replaced by a call to `execve'.  Return -1 for errors, 0 to the new
-rocess,
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
    and the process ID of the new process to the old process.  */
 
 	PSEUDO_PROLOGUE
 
 ENTRY (__vfork)
 
-	SINGLE_THREAD_P
-	bne	HIDDEN_JUMPTARGET (__fork)
 #ifdef __NR_vfork
+
+#ifdef SHARED
+	ldr	ip, 1f
+	ldr	r0, 2f
+3:	add	ip, pc, ip
+	ldr	r0, [ip, r0]
+#else
+	ldr	r0, 1f
+#endif
+	movs	r0, r0
+	bne	HIDDEN_JUMPTARGET (__fork)
+		
 	swi	__NR_vfork
 	cmn	a1, #4096
 	RETINSTR(movcc, pc, lr)
 
+#ifndef __ASSUME_VFORK_SYSCALL
 	/* Check if vfork syscall is known at all.  */
-	ldr	a2, =-ENOSYS
-	teq	a1, a2
+	cmn	a1, #ENOSYS
 	bne	PLTJMP(C_SYMBOL_NAME(__syscall_error))
 #endif
 
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
 	/* If we don't have vfork, fork is close enough.  */
 	swi	__NR_fork
 	cmn	a1, #4096
 	RETINSTR(movcc, pc, lr)
+#elif !defined __NR_vfork
+# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
+#endif
     	b	PLTJMP(C_SYMBOL_NAME(__syscall_error))
 
+#ifdef SHARED
+1:	.word	_GLOBAL_OFFSET_TABLE_ - 3b - 8
+2:	.word	__libc_pthread_functions(GOTOFF)
+#else
+	.weak	pthread_create
+1:	.word	pthread_create
+#endif
+
 PSEUDO_END (__vfork)
 libc_hidden_def (__vfork)