1/*
2 * vfork for uClibc
3 * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5 */
6
7#include <features.h>
8#include <bits/arm_asm.h>
9#include <bits/arm_bx.h>
10
11#define _ERRNO_H
12#include <bits/errno.h>
13#include <sys/syscall.h>
14
15#ifdef __NR_fork
16.text
17.global	__vfork
18.hidden	__vfork
19.type	__vfork,%function
20.align 4
21
22#if defined(__thumb__) && !defined(__thumb2__)
23.thumb_func
24__vfork:
25#ifdef __NR_vfork
26	DO_CALL (vfork)
27	ldr		r1, =0xfffff000
28	cmp		r0, r1
29	bcs		1f
30	bx		lr
311:
32
33	/* Check if vfork even exists.  */
34	ldr		r1, =-ENOSYS
35	cmp		r0, r1
36	bne		__error
37
38	/* If we don't have vfork, use fork.  */
39	DO_CALL (fork)
40	ldr		r1, =0xfffff000
41	cmp		r0, r1
42
43	/* Syscall worked.  Return to child/parent */
44	bcs		1f
45	bx		lr
461:
47
48__error:
49	push	{r3, lr}
50	bl	__syscall_error
51	POP_RET
52.pool
53
54#endif
55
56#else
57__vfork:
58
59#ifdef __NR_vfork
60	DO_CALL (vfork)
61	cmn	r0, #4096
62	IT(t, cc)
63	BXC(cc, lr)
64
65	/* Check if vfork even exists.  */
66	ldr     r1, =-ENOSYS
67	teq     r0, r1
68	bne     __error
69#endif
70
71	/* If we don't have vfork, use fork.  */
72	DO_CALL (fork)
73	cmn     r0, #4096
74
75	/* Syscall worked.  Return to child/parent */
76	IT(t, cc)
77	BXC(cc, lr)
78
79__error:
80	b	__syscall_error
81#endif
82
83.size __vfork,.-__vfork
84
85weak_alias(__vfork,vfork)
86libc_hidden_def(vfork)
87#endif
88