1/* $NetBSD: __clone.S,v 1.5 2004/08/21 11:29:51 rearnsha Exp $ */ 2 3/* 4 * Copyright (c) 2001 Christopher Gilbert 5 * All rights reserved. 6 * 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. The name of the company nor the name of the author may be used to 13 * endorse or promote products derived from this software without specific 14 * prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <machine/asm.h> 30#include <sys/errno.h> 31#include "SYS.h" 32 33#ifdef WEAK_ALIAS 34WEAK_ALIAS(clone, __clone) 35#endif 36 37/* 38 * int __clone(int (*fn)(void *), void *stack, int flags, void *arg); 39 */ 40ENTRY(__clone) 41 42 /* test stack and function are not null */ 43 teq r0, #0x00 44 teqne r1, #0x00 45 beq .Leinval 46 47 /* place the func and its arg onto the child's stack */ 48 stmfd r1!, {r0, r3} 49 50 /* syscall expects (flags, stack) */ 51 mov r0, r2 52 53 SYSTRAP(__clone) 54 bcs PIC_SYM(CERROR, PLT) 55 56 /* 57 * r1 and r0 are the same as from fork: 58 * r1 == 0 in parent process, r1 == 1 in child process. 59 * r0 == pid of child in parent, r0 == pid of parent in child. 60 */ 61 teq r1, #0x00 62 63 /* if this is the parent then just return the pid */ 64 RETc(eq) 65 /* 66 * This is the child 67 * load the function and arg off the stack 68 */ 69 ldmfd sp!, {r1, r2} 70 71 /* setup return address */ 72 add lr, pc, #.Lreturnhere - . - 8 73 74 /* place arg in r0 */ 75 mov r0, r2 76 77 /* call the function */ 78#ifdef _ARM_ARCH_4T 79 bx r1 80#else 81 mov pc, r1 82#endif 83 84.Lreturnhere: 85 /* call _exit with the returned value */ 86 b PIC_SYM(_C_LABEL(_exit), PLT) 87 88 /* NOTREACHED */ 89 90 /* error handler if func or stack is NULL */ 91.Leinval: 92 mov R0, #EINVAL 93 b PIC_SYM(CERROR, PLT) 94