0,0 → 1,84 |
; Threads management. |
|
; int create_thread(int (*proc)(void *param), void *param, int stack_size) |
; Creates a thread that executes the given function proc(param). |
; Returns -1 on error, TID otherwise. |
; If proc(param) returns, the returned value is passed to exit_thread(). |
; If stack_size is zero, uses the value from PE header of the executable. |
proc create_thread stdcall uses ebx, thread_proc, param, stack_size |
; 1. Determine stack size. |
; Align stack_size up to page boundary; |
mov ecx, [stack_size] |
add ecx, 0xFFF |
and ecx, not 0xFFF |
jnz .stack_size_ok |
; if this results in zero, read the value from the header of main module. |
mov eax, [modules_list + MODULE.next] |
mov eax, [eax + MODULE.base] |
mov ecx, [eax+STRIPPED_PE_HEADER.SizeOfStackReserve] |
cmp byte [eax], 'M' |
jnz .stack_size_ok |
mov ecx, [eax+3Ch] |
mov ecx, [eax+ecx+IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackReserve] |
.stack_size_ok: |
mov [stack_size], ecx |
; 2. Allocate the stack. |
mov eax, 68 |
mov ebx, 12 |
call FS_SYSCALL_PTR |
test eax, eax |
jz .fail |
; 3. Copy parameters to the stack. |
lea edx, [eax+ecx-16] |
mov [edx], ecx |
mov ebx, FS_SYSCALL_PTR |
mov [edx+4], ebx |
mov ebx, [thread_proc] |
mov [edx+8], ebx |
mov ebx, [param] |
mov [edx+12], ebx |
; 4. Call the kernel to create the thread. |
mov eax, 51 |
mov ebx, 1 |
mov ecx, internal_thread_start |
call FS_SYSCALL_PTR |
cmp eax, -1 |
jz .fail_free |
ret |
.fail_free: |
mov eax, 68 |
mov ebx, 13 |
lea ecx, [edx+12] |
sub ecx, [stack_size] |
call FS_SYSCALL_PTR |
xor eax, eax |
.fail: |
dec eax |
ret |
endp |
|
; void exit_thread(int exit_code) |
; Terminates the current thread. |
; exit_code is reserved; currently ignored |
proc exit_thread stdcall, exit_code |
or eax, -1 |
call FS_SYSCALL_PTR |
endp |
|
; Real entry point of threads created by create_thread. |
; Provides user-space initialization of the thread, |
; calls user-provided thread routine, |
; passes the returned value to exit_thread. |
proc internal_thread_start |
pop eax ; stack_size |
lea ecx, [esp+12] |
mov FS_STACK_MAX, ecx |
sub ecx, eax |
mov FS_STACK_MIN, ecx |
pop FS_SYSCALL_PTR ; from caller's FS_SYSCALL_PTR |
pop eax ; thread_proc |
call eax ; param is still on the stack |
push eax ; exit_code |
push 0 ; no return address |
jmp exit_thread |
endp |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |