| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 | /* * Copyright (C) 2005 Atmel Corporation * * This file is subject to the terms and conditions of the GNU Lesser General * Public License.  See the file "COPYING.LIB" in the main directory of this * archive for more details. *//* * Clone the process without copying the address space.  The * calling process is suspended until the child either exits * or calls execve. * * This all means that we cannot rely on the stack to store * away registers, since they will be overwritten by the child * as soon as it makes another function call (e.g. execve()). * Fortunately, the Linux kernel preserves LR across system calls. */#include <features.h>#include <sys/syscall.h>       .global __vfork       .type   __vfork,@function       .align  1__vfork:       mov     r8, __NR_vfork       scall       cp.w    r12, -4096       retls   r12       /* vfork failed, so we may use the stack freely */       pushm   r4-r7,lr#ifdef __PIC__       lddpc   r6, .L_GOT       rsub    r4, r12, 0.L_RGOT:       rsub    r6, pc       mcall   r6[__errno_location@got]#else       rsub    r4, r12, 0       mcall   .L__errno_location#endif       st.w    r12[0], r4       popm    r4-r7,pc,r12=-1       .align  2#ifdef __PIC__.L_GOT:       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_#else.L__errno_location:       .long   __errno_location#endif       .size   __vfork, . - __vforkweak_alias(__vfork,vfork)libc_hidden_weak(vfork)
 |