1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
.file "clone.S"
#include <sys/syscall.h>
#include "DEFS.h"
#include "SYS.h"
#define KERNEL
#define _KERNEL
#include <sys/errno.h>
#undef _KERNEL
#undef KERNEL
#undef DEBUG
/*
* 8 12 16 20
* _clone (__fn, __childstack, __flags, __arg);
*
* I'm pretty shakey on assembly language, so someone else better
* check this! I don't even know what half this stuff means, its
* just copied from somewhere else (rf.S).
*
* It seems to work though.
*
* Here's the idea:
* __childstack is the TOS for the new rforked thread
* __flags are the rfork flags
* __fn is the userland function go be started for the new thread
* as in:
*
* int __fn (void * __arg)
*
*/
.stabs "clone.S",100,0,0,Ltext0
.text
Ltext0:
.type CNAME(_clone),@function
.stabd 68,0,1
ENTRY(_clone)
pushl %ebp
movl %esp, %ebp
pushl %esi
/*
* Push thread info onto the new thread's stack
*/
movl 12(%ebp), %esi / get stack addr
subl $4, %esi
movl 20(%ebp), %eax / get __arg
movl %eax, (%esi)
subl $4, %esi
movl 8(%ebp), %eax / get __fn
movl %eax, (%esi)
.stabd 68,0,2
/*
* Prepare and execute rfork
*/
pushl 16(%ebp)
pushl %esi
leal SYS_rfork, %eax
KERNCALL
jb 2f
.stabd 68,0,3
/*
* Check to see if we are in the parent or child
*/
cmpl $0, %edx
jnz 1f
addl $8, %esp
popl %esi
movl %ebp, %esp
popl %ebp
ret
.p2align 2
/*
* If we are in the child (new thread), then
* set-up the call to the internal subroutine. If it
* returns, then call _exit.
*/
.stabd 68,0,4
1:
movl %esi,%esp
#ifdef DEBUG
movl %esp, _stackaddr
movl (%esp), %eax
movl %eax, _stack
movl 4(%esp), %eax
movl %eax,_stack+4
movl 8(%esp), %eax
movl %eax,_stack+8
#endif
popl %eax
#ifdef DEBUG
movl %eax,_fcn
#endif
call %eax
addl $8, %esp
/*
* Exit system call
*/
call PIC_PLT(_exit)
.stabd 68,0,5
2: addl $8, %esp
popl %esi
movl %ebp, %esp
popl %ebp
jmp PIC_PLT(HIDENAME(cerror))
.stabs "_clone:f67",36,0,6,CNAME(_clone)
Lfe1:
.size CNAME(_clone),Lfe1-CNAME(_clone)
#ifdef DEBUG
.data
.globl _stack
_stack: .long 0
.long 0
.long 0
.long 0
.globl _stackaddr
_stackaddr: .long 0
.globl _fcn
_fcn: .long 0
#endif
|