xref: /freebsd/lib/libsys/i386/pdrfork_thread.S (revision 74a2bf1b7a7ff0c872499cb94df24713f61c872c)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright 2000 Peter Wemm <peter@FreeBSD.org>
5 * Copyright 2026 The FreeBSD Foundation
6 * All rights reserved.
7 *
8 * Portions of this software were developed by
9 * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
10 * the FreeBSD Foundation.
11 */
12
13#include <machine/asm.h>
14/*
15 * With thanks to John Dyson for the original version of this.
16 */
17
18#include <SYS.h>
19
20/*
21 *              8    12      16       20          24         28
22 * rfork_thread(fdp, pdflags rfflags, stack_addr, start_fnc, start_arg);
23 *
24 * fdp			Pointer for the resulting fd location
25 * pdflags		Flags as to pdfork.
26 * rfflags:		Flags as to rfork.
27 * stack_addr:		Top of stack for thread.
28 * start_fnc:		Address of thread function to call in child.
29 * start_arg:		Argument to pass to the thread function in child.
30 */
31
32ENTRY(pdrfork_thread)
33	pushl	%ebp
34	movl	%esp, %ebp
35	pushl	%esi
36
37	/*
38	 * Push thread info onto the new thread's stack
39	 */
40	movl	20(%ebp), %esi	# get stack addr
41
42	subl	$4, %esi
43	movl	28(%ebp), %eax	# get start argument
44	movl	%eax, (%esi)
45
46	subl	$4, %esi
47	movl	24(%ebp), %eax	# get start thread address
48	movl	%eax, (%esi)
49
50	/*
51	 * Prepare and execute the thread creation syscall
52	 */
53	pushl	16(%ebp)
54	pushl	12(%ebp)
55	pushl	8(%ebp)
56	pushl	$0
57	_SYSCALL(pdrfork)
58	jb 	2f
59
60	/*
61	 * Check to see if we are in the parent or child
62	 */
63	cmpl	$0, %edx
64	jnz	1f
65	addl	$16, %esp
66	popl	%esi
67	movl	%ebp, %esp
68	popl	%ebp
69	ret
70	.p2align 2
71
72	/*
73	 * If we are in the child (new thread), then
74	 * set-up the call to the internal subroutine.  If it
75	 * returns, then call __exit.
76	 */
771:
78	movl	%esi,%esp
79	popl	%eax
80	call	*%eax
81	addl	$4, %esp
82
83	/*
84	 * Exit system call
85	 */
86	pushl	%eax
87	pushl	$0
88	_SYSCALL(exit)
89
90	/*
91	 * Branch here if the thread creation fails:
92	 */
932:
94	addl	$16, %esp
95	popl	%esi
96	movl	%ebp, %esp
97	popl	%ebp
98	jmp	HIDENAME(cerror)
99END(pdrfork_thread)
100
101	.section .note.GNU-stack,"",%progbits
102