x64-httpd/main.s
2025-05-11 08:22:07 +00:00

206 lines
4 KiB
ArmAsm

global _start
; constants
SYS_READ equ 0
SYS_WRITE equ 1
SYS_CLOSE equ 3
SYS_POLL equ 7
SYS_SENDFILE equ 40
SYS_SOCKET equ 41
SYS_ACCEPT equ 43
SYS_SHUTDOWN equ 48
SYS_BIND equ 49
SYS_LISTEN equ 50
SYS_EXIT equ 60
SYS_FCNTL equ 72
SYS_UNLINK equ 87
STDOUT equ 1
AF_UNIX equ 1
SOCK_STREAM equ 1
F_GETFL equ 3
F_SETFL equ 4
O_NONBLOCK equ 2048
POLLIN equ 1
POLLOUT equ 4
SHUT_RDWR equ 2
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
pollfds_capacity equ 100
client_size equ 1 + 256 + 256 ; state, line buffer, uri
clients_capacity equ pollfds_capacity - 1
SECTION .data
server_path db "server.sock", 0x00
server_path_len equ $ - server_path
sockaddr_size equ 2 + 108 ; $ man 7 unix
goodbye db "goodbye", 0x0a
goodbye_len equ $ - goodbye
pollfds_len dq 0
clients_len dq 0
SECTION .bss
sockaddr resb sockaddr_size
pollfds resb pollfd_size * pollfds_capacity
clients resb (4 + client_size) * clients_capacity
SECTION .text
%include "server.s"
%include "readline.s"
_start:
call make_server
mov rbx, rax ; server fd
mov rdi, rax
mov rsi, POLLIN
call pollfds__append
poll:
mov rax, SYS_POLL
mov rdi, pollfds
mov rsi, [pollfds_len]
mov rdx, 5000
syscall
cmp rax, 0
je poll
jl exit ; TODO handle this gracefully
mov rdi, rbx
; rdi - server fd
pollfds__scan:
mov r15, 0
pollfds__scan__loop:
cmp r15, [pollfds_len]
jge poll
mov r10w, [pollfds + r15 * pollfd_size + 6]
cmp r10w, 0
jne pollfds__scan__found
add r15, 1
jmp pollfds__scan__loop
pollfds__scan__found:
mov r14, 0
mov r14d, [pollfds + r15 * pollfd_size]
cmp r14d, edi
je pollfds__scan__found__server
pollfds__scan__found__client:
; TODO check r10w, incl for POLLNVAL & POLLERR
push rdi
mov rdi, r14
call clients__append
mov r12, [clients_len]
add r12, -1
imul r12, client_size
add r12, clients
add r12, 4
mov rdi, r14
mov rsi, r12
mov rdx, 256
call readline
cmp rax, 0 ; TODO
jl exit
;push rax ; TODO
mov rdx, rax
mov rax, SYS_WRITE
mov rdi, r14
mov rsi, r12
syscall
cmp rax, 0
jl exit ; TODO handle this gracefully
mov rax, SYS_SHUTDOWN
mov rdi, 0
mov edi, r14d
mov rsi, SHUT_RDWR
syscall
mov rax, SYS_CLOSE
mov rdi, 0
mov edi, r14d
syscall
mov rdi, r15
call pollfds__remove
pop rdi
jmp pollfds__scan__loop
pollfds__scan__found__server:
; TODO check r10w, incl for POLLNVAL & POLLERR
push rdi
mov rax, SYS_ACCEPT
mov rsi, 0
mov rdx, 0
syscall
cmp rax, 0
jl exit ; TODO handle this gracefully
mov rdi, rax
mov si, POLLIN | POLLOUT
call pollfds__append
pop rdi
add r15, 1
jmp pollfds__scan__loop
; edi - fd
; si - events
pollfds__append:
; TODO check against pollfds_capacity
mov r10, [pollfds_len]
mov [pollfds + r10 * pollfd_size], edi
mov [pollfds + r10 * pollfd_size + 4], si
add r10, 1
mov [pollfds_len], r10
ret
; rdi - pollfds array index to remove
pollfds__remove:
mov r11, [pollfds_len]
cmp rdi, r10
jge return ; XXX index out of bounds, do some other error?
cmp r11, 1
jle pollfds__clear
mov r10, [pollfds + (r11 - 1) * pollfd_size]
mov [pollfds + rdi * pollfd_size], r10
sub r11, 1
mov [pollfds_len], r11
ret
pollfds__clear:
mov r10, 0
mov [pollfds_len], r10
ret
; esi - fd
clients__append:
; TODO check against client_capacity
mov r10, [clients_len]
imul r10, client_size
add r10, clients
mov [r10], esi
add r10, 4
mov r8b, 0
mov r11, 0
clients__append__init:
cmp r11, client_size
jge return
mov [r10 + r11], r8b
add r11, 1
jmp clients__append__init
return:
ret
exit:
mov rax, SYS_EXIT
mov rdi, 0
syscall