1/*
2 * Copyright (C) 2005 Atmel Corporation
3 *
4 * This file is subject to the terms and conditions of the GNU Lesser General
5 * Public License.  See the file "COPYING.LIB" in the main directory of this
6 * archive for more details.
7 */
8
9/*
10 * Clone the process without copying the address space.  The
11 * calling process is suspended until the child either exits
12 * or calls execve.
13 *
14 * This all means that we cannot rely on the stack to store
15 * away registers, since they will be overwritten by the child
16 * as soon as it makes another function call (e.g. execve()).
17 * Fortunately, the Linux kernel preserves LR across system calls.
18 */
19
20#include <sys/syscall.h>
21
22	.global	__vfork
23	.hidden __vfork
24	.type	__vfork,@function
25	.align	1
26__vfork:
27	mov	r8, __NR_vfork
28	scall
29	cp.w	r12, -4096
30	retls	r12
31
32	/* vfork failed, so we may use the stack freely */
33	pushm	r4-r7,lr
34#ifdef __PIC__
35	lddpc	r6, .L_GOT
36	rsub	r4, r12, 0
37.L_RGOT:
38	rsub	r6, pc
39	mcall	r6[__errno_location@got]
40#else
41	rsub	r4, r12, 0
42	mcall	.L__errno_location
43#endif
44	st.w	r12[0], r4
45	popm	r4-r7,pc,r12=-1
46
47	.align	2
48#ifdef __PIC__
49.L_GOT:
50	.long	.L_RGOT - _GLOBAL_OFFSET_TABLE_
51#else
52.L__errno_location:
53	.long	__errno_location
54#endif
55	.size	__vfork, . - __vfork
56
57weak_alias(__vfork,vfork)
58libc_hidden_def(vfork)
59