1*2d913a7cSmatt/* $NetBSD: __clone.S,v 1.5 2013/07/16 23:00:15 matt Exp $ */ 2c45a0d87Sscw 3c45a0d87Sscw/*- 4c45a0d87Sscw * Copyright (c) 2001 The NetBSD Foundation, Inc. 5c45a0d87Sscw * All rights reserved. 6c45a0d87Sscw * 7c45a0d87Sscw * This code is derived from software contributed to The NetBSD Foundation 8c45a0d87Sscw * by Steve C. Woodford. 9c45a0d87Sscw * 10c45a0d87Sscw * Redistribution and use in source and binary forms, with or without 11c45a0d87Sscw * modification, are permitted provided that the following conditions 12c45a0d87Sscw * are met: 13c45a0d87Sscw * 1. Redistributions of source code must retain the above copyright 14c45a0d87Sscw * notice, this list of conditions and the following disclaimer. 15c45a0d87Sscw * 2. Redistributions in binary form must reproduce the above copyright 16c45a0d87Sscw * notice, this list of conditions and the following disclaimer in the 17c45a0d87Sscw * documentation and/or other materials provided with the distribution. 18c45a0d87Sscw * 19c45a0d87Sscw * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20c45a0d87Sscw * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21c45a0d87Sscw * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22c45a0d87Sscw * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23c45a0d87Sscw * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24c45a0d87Sscw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25c45a0d87Sscw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26c45a0d87Sscw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27c45a0d87Sscw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28c45a0d87Sscw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29c45a0d87Sscw * POSSIBILITY OF SUCH DAMAGE. 30c45a0d87Sscw */ 31c45a0d87Sscw 32c45a0d87Sscw#include <sys/errno.h> 33c45a0d87Sscw#include "SYS.h" 34c45a0d87Sscw 35c45a0d87Sscw#ifdef WEAK_ALIAS 36c45a0d87SscwWEAK_ALIAS(clone, __clone) 37c45a0d87Sscw#endif 38c45a0d87Sscw 39c45a0d87Sscw/* 40c45a0d87Sscw * int clone(int (*fn)(void *), void *stack, int flags, void *arg); 41c45a0d87Sscw */ 42c45a0d87SscwENTRY(__clone) 4307a0a325Smatt movl 4(%sp),%d0 /* NULL function pointer? */ 44c45a0d87Sscw jeq 2f /* Yup, bomb out */ 45c45a0d87Sscw movl %d0,%a1 4607a0a325Smatt movl 8(%sp),%d0 /* NULL stack? */ 47c45a0d87Sscw jeq 2f /* Yup, bomb out */ 48c45a0d87Sscw movl %d0,%a0 4907a0a325Smatt movl 16(%sp),-(%a0) /* Push clone's `arg' on its new stack */ 5007a0a325Smatt lea -12(%a0),%a0 /* Fake syscall args for the clone */ 5107a0a325Smatt movl %a0,-(%sp) /* Syscall arg: stack */ 5207a0a325Smatt movl 16(%sp),-(%sp) /* Syscall arg: flags */ 5307a0a325Smatt clrl -(%sp) /* Fake return address */ 5407a0a325Smatt SYSTRAP(__clone) /* Note: `fn' in (a1) is preserved */ 5507a0a325Smatt lea 12(%sp),%sp /* Zap syscall args */ 56c45a0d87Sscw jcs 3f /* Punt if syscall failed */ 57c45a0d87Sscw tstl %d0 58c45a0d87Sscw jne 1f /* We're the parent, just return. */ 5907a0a325Smatt jsr (%a1) /* We're the clone, call the function */ 6007a0a325Smatt movl %d0,-(%sp) /* If clone returns, invoke _exit(3) */ 61c45a0d87Sscw jbsr PIC_PLT(_C_LABEL(_exit)) 62c45a0d87Sscw /* NOTREACHED */ 63c45a0d87Sscw1: rts 64c45a0d87Sscw2: movl #EINVAL,%d0 65*2d913a7cSmatt3: jbra CERROR 66*2d913a7cSmattEND(__clone) 67