kolibrios-gitea/data/common/fasmdep/linux_sys.inc

187 lines
4.8 KiB
PHP
Raw Normal View History

; Platform-specific procedures for Linux.
; Reallocate memory at pointer [start.buf] and size [start.allocated],
; new size is in eax.
realloc:
push ebx esi edi
mov ecx, eax
push ebp
kercall __NR_mmap2, 0, , PROT_READ+PROT_WRITE, MAP_PRIVATE+MAP_ANONYMOUS, -1, 0
pop ebp
cmp eax, 0xFFFFF000
ja nomemory
add [start.free], ecx
xchg ecx, [start.allocated]
sub [start.free], ecx
mov edi, eax
xchg eax, [start.buf]
shr ecx, 2
jz .nothing
push ecx
mov esi, eax
rep movsd
pop ecx
shl ecx, 2
call free_eax_ecx
.nothing:
pop edi esi ebx
ret
; Read the next portion of input data to [start.buf].
read:
mov ecx, [start.buf]
add ecx, [start.allocated]
mov edx, [start.free]
sub ecx, edx
kercall __NR_read, [start.in], ,
test eax, eax
js readerr
ret
; Write output data: eax=pointer, edi=size.
write:
mov ecx, eax
kercall __NR_write, [start.out], , edi
cmp eax, edi
jnz writeerr
ret
; Parse command line, open input and output files.
get_params:
; 1. Initialize default streams: 0 for stdin, 1 for stdout.
inc [start.out]
; 2. Prepare for scanning, skipping argv[0].
mov ebx, [start.argc]
cmp ebx, 1
jbe .noargs
dec ebx
lea esi, [start.argv+4] ; skip argv[0]
xor edi, edi ; no args parsed yet
; 3. Parse loop.
.parse:
; 3a. Get the next argument.
lodsd
; 3b. Check whether it is a known option.
cmp word [eax], '-e'
jnz @f
cmp byte [eax+2], 0
jnz @f
; 3c. If it is, modify flags and continue the loop.
mov [start.flags], 1 ; '-e' is given
jmp .nextarg
@@:
; 3d. Otherwise, it is a name of input or output file.
; edi keeps the count of names encountered before;
; edi = 0 means this is input file, edi = 1 - output file,
; otherwise this is third arg, which is an error
cmp edi, 1
ja information
; 3e. Some parameters of __NR_open differ for input and output. Setup them.
mov ecx, O_WRONLY+O_CREAT+O_TRUNC
mov edx, 0644o
jz @f
mov ecx, O_RDONLY
@@:
; 3f. Open/create the file, save the handle.
push ebx
mov ebx, eax
kercall __NR_open
pop ebx
test eax, eax
js .fileerr
mov [start.in+edi*4], eax
inc edi
.nextarg:
dec ebx
jnz .parse
.noargs:
; 4. End of command line reached. Return.
ret
.fileerr:
test edi, edi
jz in_openerr
jmp out_openerr
; Exit, return code is in al.
exit:
movzx ebx, al
push ebx
mov eax, [start.buf]
test eax, eax
jz @f
mov ecx, [start.allocated]
call free_eax_ecx
@@:
kercall __NR_close, [start.in]
kercall __NR_close, [start.out]
pop ebx
kercall __NR_exit
; Helper procedure for realloc and exit.
free_eax_ecx:
mov ebx, eax
kercall __NR_munmap
ret
; Output the message given in esi to stderr.
sayerr:
movzx edx, byte [esi-1]
kercall __NR_write, 2, esi,
ret
; Get environment variable esi (ebx-relative pointer) to the buffer,
; expanding it if needed.
get_environment_variable:
mov ecx, [start.argc]
lea ecx, [start.argv+ecx*4+4]
.findvar:
mov edx, [ecx]
add ecx, 4
test edx, edx
jz .notfound
push esi
add esi, ebx
.comparename:
lodsb
cmp al, [edx]
jnz @f
inc edx
jmp .comparename
@@:
pop esi
test al, al
jnz .findvar
cmp byte [edx], '='
jnz .findvar
inc edx
xor eax, eax
@@:
inc eax
cmp byte [edx+eax-1], 0
jnz @b
stdcall alloc_in_buf, eax
@@:
mov al, [edx]
inc edx
mov [edi+ebx], al
inc edi
test al, al
jnz @b
ret
.notfound:
stdcall alloc_in_buf, 1
mov byte [edi+ebx], 0
inc edi
ret
; Test whether a file with name [.testname] exists.
; Returns eax<0 if not, nonzero otherwise.
test_file_exists:
push ebx
add ebx, [start.testname]
sub esp, 800h
kercall __NR_stat, , esp
add esp, 800h
pop ebx
ret