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
| | .text
.global __clone
.type __clone,@function
/* args: 8 - fn
12 - stack
16 - flags
20 - td ptr
24 - TID ptr
28 - thread pointer
32 - TID ptr (again?)
*/
__clone:
push %ebp /* function intro */
mov %esp,%ebp
push %ebx
push %esi
push %edi
xor %eax,%eax
push $0x51 /* 0x51 */
mov %gs,%ax
push $0xfffff /* 0x51 : 0xfffff */
shr $3,%eax
push 28(%ebp) /* 0x51 : 0xfffff : thread pointer */
push %eax /* 0x51 : 0xfffff : thread pointer : current gs index */
mov $120,%al /* __NR_clone */
mov 12(%ebp),%ecx /* ecx = stack */
mov 16(%ebp),%ebx /* ebx = flags */
and $-16,%ecx
sub $16,%ecx /* align stack */
mov 20(%ebp),%edi /* edi = td pointer */
mov %edi,(%ecx) /* push td pointer to new stack */
mov 24(%ebp),%edx /* edx = TID pointer */
mov %esp,%esi /* esi = esp */
mov 32(%ebp),%edi /* edi = TID pointer */
mov 8(%ebp),%ebp /* ebp = start function (for safe-keeping) */
int $128 /* clone(flags, stack, TID pointer, {.index = current gs index, .base = thread pointer, .limit=0xfffff, .seg32_bit, .limit_in_pages, .usable}, td pointer) */
test %eax,%eax
jnz 1f /* if that's not 0, just return the return value */
mov %ebp,%eax /* in child: zero out ebp, then call function */
xor %ebp,%ebp
call *%eax
mov %eax,%ebx /* exit(rv from function) */
xor %eax,%eax
inc %eax
int $128
hlt /* exit didn't exit? Crash! */
1: add $16,%esp
pop %edi
pop %esi
pop %ebx
pop %ebp
ret
|