xref: /netbsd-src/lib/libc/arch/m68k/sys/__clone.S (revision 2d913a7c7db7947ee27532721a4a2937d7092aeb)
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