335 lines
5.7 KiB
PHP
335 lines
5.7 KiB
PHP
|
|
||
|
LINE_FEED = 0Ah
|
||
|
|
||
|
O_ACCMODE = 0003o
|
||
|
O_RDONLY = 0000o
|
||
|
O_WRONLY = 0001o
|
||
|
O_RDWR = 0002o
|
||
|
O_CREAT = 0100o
|
||
|
O_EXCL = 0200o
|
||
|
O_NOCTTY = 0400o
|
||
|
O_TRUNC = 1000o
|
||
|
O_APPEND = 2000o
|
||
|
O_NONBLOCK = 4000o
|
||
|
|
||
|
S_ISUID = 4000o
|
||
|
S_ISGID = 2000o
|
||
|
S_ISVTX = 1000o
|
||
|
S_IRUSR = 0400o
|
||
|
S_IWUSR = 0200o
|
||
|
S_IXUSR = 0100o
|
||
|
S_IRGRP = 0040o
|
||
|
S_IWGRP = 0020o
|
||
|
S_IXGRP = 0010o
|
||
|
S_IROTH = 0004o
|
||
|
S_IWOTH = 0002o
|
||
|
S_IXOTH = 0001o
|
||
|
|
||
|
system_init:
|
||
|
mov eax,201 ; sys_time
|
||
|
mov edi,timestamp
|
||
|
syscall
|
||
|
or [local_heap_available],1
|
||
|
retn
|
||
|
|
||
|
system_shutdown:
|
||
|
call mcheck
|
||
|
retn
|
||
|
|
||
|
open:
|
||
|
; in: edx - path to file
|
||
|
; out: ebx = file handle, cf set on error
|
||
|
; preserves: esi, edi
|
||
|
push rsi rdi
|
||
|
call adapt_path
|
||
|
mov eax,2 ; sys_open
|
||
|
mov esi,O_RDONLY
|
||
|
xor edx,edx
|
||
|
syscall
|
||
|
pop rdi rsi
|
||
|
test eax,eax
|
||
|
js interface_error
|
||
|
mov ebx,eax
|
||
|
clc
|
||
|
ret
|
||
|
interface_error:
|
||
|
stc
|
||
|
ret
|
||
|
adapt_path:
|
||
|
xor ecx,ecx
|
||
|
mov edi,path_buffer
|
||
|
copy_path:
|
||
|
mov al,[edx+ecx]
|
||
|
cmp al,'\'
|
||
|
jne path_char_ok
|
||
|
mov al,'/'
|
||
|
path_char_ok:
|
||
|
cmp ecx,1000h
|
||
|
jae out_of_memory
|
||
|
mov [edi+ecx],al
|
||
|
inc ecx
|
||
|
test al,al
|
||
|
jnz copy_path
|
||
|
retn
|
||
|
create:
|
||
|
; in: edx - path to file
|
||
|
; out: ebx = file handle, cf set on error
|
||
|
; preserves: esi, edi
|
||
|
push rsi rdi
|
||
|
call adapt_path
|
||
|
mov esi,O_CREAT+O_TRUNC+O_WRONLY
|
||
|
mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH
|
||
|
mov eax,2 ; sys_open
|
||
|
syscall
|
||
|
pop rdi rsi
|
||
|
test eax,eax
|
||
|
js interface_error
|
||
|
mov ebx,eax
|
||
|
clc
|
||
|
retn
|
||
|
write:
|
||
|
; in: ebx = file handle, edx - data, ecx = number of bytes
|
||
|
; out: cf set on error
|
||
|
; preserves: ebx, esi, edi
|
||
|
push rsi rdi
|
||
|
mov eax,1 ; sys_write
|
||
|
mov edi,ebx
|
||
|
mov esi,edx
|
||
|
mov edx,ecx
|
||
|
syscall
|
||
|
pop rdi rsi
|
||
|
test eax,eax
|
||
|
js interface_error
|
||
|
cmp eax,edx
|
||
|
jne interface_error
|
||
|
clc
|
||
|
ret
|
||
|
read:
|
||
|
; in: ebx = file handle, edx - buffer, ecx = number of bytes
|
||
|
; out: cf set on error
|
||
|
; preserves: ebx, esi, edi
|
||
|
push rsi rdi
|
||
|
mov eax,0 ; sys_read
|
||
|
mov edi,ebx
|
||
|
mov esi,edx
|
||
|
mov edx,ecx
|
||
|
syscall
|
||
|
pop rdi rsi
|
||
|
test eax,eax
|
||
|
js interface_error
|
||
|
cmp eax,edx
|
||
|
jne interface_error
|
||
|
clc
|
||
|
ret
|
||
|
close:
|
||
|
; in: ebx = file handle
|
||
|
; preserves: ebx, esi, edi
|
||
|
push rdi
|
||
|
mov edi,ebx
|
||
|
mov eax,3 ; sys_close
|
||
|
syscall
|
||
|
pop rdi
|
||
|
ret
|
||
|
lseek:
|
||
|
; in: ebx = file handle, cl = method, edx:eax = offset
|
||
|
; out: edx:eax = new offset from the beginning of file, cf set on error
|
||
|
; preserves: ebx, esi, edi
|
||
|
push rsi rdi
|
||
|
mov edi,ebx
|
||
|
mov esi,edx
|
||
|
mov eax,eax
|
||
|
shl rsi,32
|
||
|
or rsi,rax
|
||
|
xor edx,edx
|
||
|
mov dl,cl
|
||
|
mov eax,8 ; sys_lseek
|
||
|
syscall
|
||
|
pop rdi rsi
|
||
|
cmp rax,-1
|
||
|
je interface_error
|
||
|
mov rdx,rax
|
||
|
shr rdx,32
|
||
|
clc
|
||
|
ret
|
||
|
|
||
|
get_timestamp:
|
||
|
; out: edx:eax = timestamp
|
||
|
; preserves: ebx, ecx, esi, edi
|
||
|
; note: during the passes of a single assembly this function should always return the same value
|
||
|
mov eax,dword [timestamp]
|
||
|
mov edx,dword [timestamp+4]
|
||
|
retn
|
||
|
|
||
|
display_string:
|
||
|
; in:
|
||
|
; esi - string
|
||
|
; ecx = string length, zero for ASCIIZ string
|
||
|
; preserves: ebx, esi
|
||
|
push rbx rsi rbp
|
||
|
test ecx,ecx
|
||
|
jnz write_string_to_stdout
|
||
|
xor al,al
|
||
|
mov edi,esi
|
||
|
or ecx,-1
|
||
|
repne scasb
|
||
|
neg ecx
|
||
|
sub ecx,2
|
||
|
write_string_to_stdout:
|
||
|
mov eax,1 ; sys_write
|
||
|
mov edi,1
|
||
|
mov edx,ecx
|
||
|
syscall
|
||
|
pop rbp rsi rbx
|
||
|
retn
|
||
|
|
||
|
display_error_string:
|
||
|
; in:
|
||
|
; esi - string
|
||
|
; ecx = string length, zero for ASCIIZ string
|
||
|
; preserves: ebx, esi
|
||
|
push rbx rsi rbp
|
||
|
test ecx,ecx
|
||
|
jnz write_string_to_stderr
|
||
|
xor al,al
|
||
|
mov edi,esi
|
||
|
or ecx,-1
|
||
|
repne scasb
|
||
|
neg ecx
|
||
|
sub ecx,2
|
||
|
write_string_to_stderr:
|
||
|
mov eax,1 ; sys_write
|
||
|
mov edi,2
|
||
|
mov edx,ecx
|
||
|
syscall
|
||
|
pop rbp rsi rbx
|
||
|
retn
|
||
|
|
||
|
get_environment_variable:
|
||
|
; in:
|
||
|
; esi - name
|
||
|
; edi - buffer for value
|
||
|
; ecx = size of buffer
|
||
|
; out:
|
||
|
; eax = length of value
|
||
|
; preserves: ebx, esi, edi
|
||
|
push rbx rcx
|
||
|
mov rdx,[env]
|
||
|
scan_environment:
|
||
|
mov rbx,[rdx]
|
||
|
test rbx,rbx
|
||
|
jz no_environment_variable
|
||
|
xor ecx,ecx
|
||
|
compare_character:
|
||
|
mov al,[rbx+rcx]
|
||
|
mov ah,[esi+ecx]
|
||
|
inc ecx
|
||
|
cmp al,'='
|
||
|
je end_of_variable_name
|
||
|
test ah,ah
|
||
|
jz next_variable
|
||
|
sub ah,al
|
||
|
je compare_character
|
||
|
cmp ah,20h
|
||
|
jne next_variable
|
||
|
cmp al,'A'
|
||
|
jb next_variable
|
||
|
cmp al,'Z'
|
||
|
jna compare_character
|
||
|
next_variable:
|
||
|
add rdx,8
|
||
|
jmp scan_environment
|
||
|
end_of_variable_name:
|
||
|
test ah,ah
|
||
|
jnz next_variable
|
||
|
add rbx,rcx
|
||
|
pop rcx
|
||
|
xor eax,eax
|
||
|
copy_environment_variable:
|
||
|
mov dl,[rbx+rax]
|
||
|
cmp eax,ecx
|
||
|
jae next_environment_variable_character
|
||
|
mov [edi+eax],dl
|
||
|
next_environment_variable_character:
|
||
|
inc eax
|
||
|
test dl,dl
|
||
|
jnz copy_environment_variable
|
||
|
environment_variable_ok:
|
||
|
pop rbx
|
||
|
ret
|
||
|
no_environment_variable:
|
||
|
pop rcx
|
||
|
mov eax,1
|
||
|
jecxz environment_variable_ok
|
||
|
and byte [edi],0
|
||
|
pop rbx
|
||
|
ret
|
||
|
|
||
|
VALLOC_MINIMUM_SIZE = 100000h
|
||
|
|
||
|
valloc:
|
||
|
; in: ecx = requested minimum size
|
||
|
; out: eax - allocated block, ecx = allocated size, zero if failed
|
||
|
; preserves: ebx, esi, edi
|
||
|
cmp ecx,VALLOC_MINIMUM_SIZE
|
||
|
jbe valloc_size_minimum
|
||
|
dec ecx
|
||
|
and ecx,(-1) shl 12
|
||
|
add ecx,1 shl 12
|
||
|
jmp valloc_size_ready
|
||
|
valloc_size_minimum:
|
||
|
mov ecx,VALLOC_MINIMUM_SIZE
|
||
|
valloc_size_ready:
|
||
|
push rbx rsi rdi
|
||
|
cmp [local_heap_available],0
|
||
|
je valloc_mmap
|
||
|
cmp ecx,LOCAL_HEAP_SIZE
|
||
|
ja valloc_mmap
|
||
|
and [local_heap_available],0
|
||
|
mov eax,local_heap
|
||
|
mov ecx,LOCAL_HEAP_SIZE
|
||
|
jmp valloc_ok
|
||
|
valloc_mmap:
|
||
|
xor r9d,r9d
|
||
|
or r8,-1
|
||
|
mov r10d,62h ; MAP_PRIVATE + MAP_ANONYMOUS + MAP_32BIT
|
||
|
mov edx,3 ; PROT_READ + PROT_WRITE
|
||
|
mov esi,ecx
|
||
|
xor edi,edi
|
||
|
mov eax,9 ; sys_mmap
|
||
|
syscall
|
||
|
cmp eax,-1
|
||
|
je valloc_mmap_with_hint
|
||
|
mov ecx,eax
|
||
|
cmp rcx,rax
|
||
|
jne valloc_mmap_unusable
|
||
|
add ecx,esi
|
||
|
jnc mmap_ok
|
||
|
valloc_mmap_unusable:
|
||
|
mov rdi,rax
|
||
|
mov eax,11 ; sys_munmap
|
||
|
syscall
|
||
|
valloc_mmap_with_hint:
|
||
|
mov r10d,22h ; MAP_PRIVATE + MAP_ANONYMOUS
|
||
|
mov edx,3 ; PROT_READ + PROT_WRITE
|
||
|
mov edi,[mmap_hint]
|
||
|
mov eax,9 ; sys_mmap
|
||
|
syscall
|
||
|
cmp eax,-1
|
||
|
je valloc_failed
|
||
|
mov ecx,eax
|
||
|
cmp rcx,rax
|
||
|
jne valloc_failed
|
||
|
add ecx,esi
|
||
|
jc valloc_failed
|
||
|
mmap_ok:
|
||
|
sub ecx,eax
|
||
|
valloc_ok:
|
||
|
lea edx,[eax+ecx]
|
||
|
mov [mmap_hint],edx
|
||
|
pop rdi rsi rbx
|
||
|
retn
|
||
|
valloc_failed:
|
||
|
xor ecx,ecx
|
||
|
pop rdi rsi rbx
|
||
|
retn
|