This commit is contained in:
janis 2026-06-05 00:09:02 +02:00
parent 6f76735710
commit 44d5e95970
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8

View file

@ -41,53 +41,52 @@ fasthash:
;; push the label pointed at by rdi with length rsi, and the current file offset onto the labels array. ;; push the label pointed at by rdi with length rsi, and the current file offset onto the labels array.
push_lbl: push_lbl:
mov rax, num_labels mov eax, dword [r15 + 0x6000]
cmp rax, 340 cmp eax, 340
jge panic jge panic
add rax, rax ; rax = num_labels * 2 lea edx, [rax + rax*2]
add rax, num_labels ; rax = num_labels * 3 shl rdx, 2
sal rax, 2 ; rax = num_labels * 12 (size of each label entry) push rdx
push rax
call fasthash call fasthash
pop rdx ; rdx = offset of label entry in labels array pop rdx ; rdx = offset of label entry in labels array
mov [labels + rdx], rax ; store hash in labels array lea rdi, [r15 + 0x5010]
mov eax, file_offset mov qword [rdi + rdx], rax ; store hash in labels array
mov [labels + rdx + 8], eax ; store file offset in labels array mov eax, dword [r15 + 0x500c] ; get current file offset
inc num_labels mov dword [rdi + rdx + 8], eax ; store file offset in labels array
inc dword ptr [r15 + 0x6000]
ret ret
;; searches for the offset of the label with the name pointed at by rdi with length rsi, and returns it in rax. If the label is not found, dies. ;; searches for the offset of the label with the name pointed at by rdi with length rsi, and returns it in rax. If the label is not found, dies.
.find_lbl_not_found: .find_lbl_not_found:
call panic call panic
.find_lbl_found: .find_lbl_found:
mov rax, [rdx + 8] ; get file offset of label mov eax, dword ptr [rdx + 8] ; get file offset of label
ret ret
find_lbl: find_lbl:
call fasthash call fasthash
mov rbx, num_labels lea rdx, [r15 + 0x5010] ; rdx = pointer to start of labels array
lea rdx, [labels] ; rdx = pointer to start of labels array mov ebx, dword ptr [r15 + 0x6000]
.find_lbl_loop: .find_lbl_loop:
test rbx, rbx test rbx, rbx
jz .find_lbl_not_found jz .find_lbl_not_found
dec rbx dec rbx
mov rcx, [rdx] ; get hash of label at rdx cmp qword [rdx], rax
cmp rcx, rax
je .find_lbl_found je .find_lbl_found
add rdx, 12 ; move to next label entry add rdx, 12 ; move to next label entry
jmp .find_lbl_loop jmp .find_lbl_loop
die_jmp_start: die_jmp_start:
sub rsp, 8 ;; @_start_lbl: 5F 73 74 61 72 74 00 00
mov qword ptr [rsp], '\0\0trats_' lea rdi, [@_start_lbl]
mov rdi, rsp
mov rsi, 6 mov rsi, 6
call find_lbl call find_lbl
neg eax add dword [r15 + 0x500c], 5 ; advance the file offset by 5
mov byte ptr [write_buf + write_cursor], 0xe9 ; write the opcode for jmp rel32 sub eax, dword [r15 + 0x500c] ; add current file offset
add write_cursor, 1 mov edi, dword [r15 + 0x5004] ; get current write cursor
mov dword ptr [write_buf + write_cursor], eax ; write the offset of the label reference lea rdi, [r15 + edi + 0x1000] ; rdi = pointer to write location in write_buf
add write_cursor, 4 mov byte ptr [rdi], 0xe9 ; write the opcode for jmp rel32
add offset 5 mov dword ptr [rdi + 1], eax ; write the offset of the label reference
add dword ptr [r15 + 0x5004], 5 ; advance the write cursor by 5
call die call die
;; reads up to 0x1000 bytes from stdin into buf, and sets read_end to the number of bytes read, and resets read_cursor to 0 ;; reads up to 0x1000 bytes from stdin into buf, and sets read_end to the number of bytes read, and resets read_cursor to 0
@ -95,33 +94,36 @@ die_jmp_start:
rd_stdin: rd_stdin:
mov rax, 0 ; syscall: read mov rax, 0 ; syscall: read
mov rdi, 0 ; fd: stdin mov rdi, 0 ; fd: stdin
mov rsi, buf ; buf: pointer to buffer mov rsi, r15
mov rdx, 0x1000 ; count: size of buffer mov rdx, 0x1000 ; count: size of buffer
syscall syscall
mov read_end, rax test eax, eax
mov read_cursor, 0 jle die_jmp_start
cmp read_end, 0 mov dword [r15 + 0x5008], eax ; store number of bytes read in read_end
je die_jmp_start mov dword [r15 + 0x5000], 0 ; reset read_cursor to 0
ret ret
;; write up to write_cursor to stdout, and then reset the write cursor to 0 ;; write up to write_cursor to stdout, and then reset the write cursor to 0
wrt_stdout: wrt_stdout:
mov rax, 1 ; syscall: write mov rax, 1 ; syscall: write
mov rdi, 1 ; fd: stdout mov rdi, 1 ; fd: stdout
mov rsi, write_buf ; buf: pointer to buffer lea rsi, [r15 + 0x1000] ; buf: pointer to write_buf
mov rdx, write_cursor ; count: number of bytes to write mov rdx, dword [r15 + 0x5004] ; count: write_cursor
syscall syscall
mov write_cursor, 0 mov dword ptr [r15 + 0x5004], 0
ret ret
;; return the next byte from the input, or 0 if we are at the end of the input ;; return the next byte from the input
;; automatically writes to stdout and reads from stdin if we are at the end of the buffer ;; automatically writes to stdout and reads from stdin if we are at the end of the buffer
.rd_buf_end: .rd_buf_end:
mov al, byte ptr [buf + read_cursor] ; get byte at read_cursor mov eax, dword ptr [r15 + 0x5000] ; get read_cursor
inc read_cursor xor rax, rax
mov al, byte ptr [r15 + rax] ; get next byte from buf
inc dword ptr [r15 + 0x5000] ; advance read_cursor
ret ret
rd_buf: rd_buf:
cmp read_cursor, read_end mov eax, dword ptr [r15 + 0x5000] ; get read_cursor
cmp eax, dword ptr [r15 + 0x5008] ; compare to read_end
jl .rd_buf_end jl .rd_buf_end
call wrt_stdout call wrt_stdout
call rd_stdin call rd_stdin
@ -171,11 +173,6 @@ skip_comment:
call skip_line call skip_line
ret ret
write_u32le:
mov dword ptr [write_buf + write_cursor], edi
add write_cursor, 4
ret
.get_next_token_skip: .get_next_token_skip:
call skip_whitespaces call skip_whitespaces
call skip_comment call skip_comment
@ -192,12 +189,12 @@ get_next_token:
;; read the label into scratch, call push_lbl ;; read the label into scratch, call push_lbl
.label_ret .label_ret
lea rdi, [r15 + 0x6004] lea rdi, [r15 + 0x6004] ; rdi = pointer to scratch
call push_lbl call push_lbl
ret ret
label: label:
lea rdi, [r15 + 0x6004] ; rdi = pointer to scratch lea rdi, [r15 + 0x6004] ; rdi = pointer to scratch
xor rsi, rsi xor rsi, rsi ; rsi = length of label
cmp al, ':' cmp al, ':'
je .label_ret je .label_ret
mov byte ptr [rdi + rsi], al mov byte ptr [rdi + rsi], al
@ -208,10 +205,11 @@ label:
.label_ref_ret: .label_ref_ret:
lea rdi, [r15 + 0x6004] lea rdi, [r15 + 0x6004]
call find_lbl call find_lbl
add file_offset, 4 add dword ptr [r15 + 0x500c], 4 ; advance the file offset by 4
sub eax, file_offset sub eax, dword ptr [r15 + 0x500c] ; add current file offset
mov dword ptr [write_buf + write_cursor], eax ; write the offset of the label reference mov edi, dword ptr [r15 + 0x5004] ; get current write cursor
add write_cursor, 4 mov dword ptr [r15 + 0x1000 + rdi], eax ; write the opcode for jmp rel32
add dword ptr [r15 + 0x5004], 4 ; advance the write cursor by 4
ret ret
label_ref: label_ref:
lea rdi, [r15 + 0x6004] ; rdi = pointer to scratch lea rdi, [r15 + 0x6004] ; rdi = pointer to scratch
@ -272,6 +270,7 @@ _start:
sub rsp, 0x8000 ; allocate space for our variables + some scratch space sub rsp, 0x8000 ; allocate space for our variables + some scratch space
mov r15, rsp ; r15 will point to the start of our variables mov r15, rsp ; r15 will point to the start of our variables
call rd_buf
.loop: .loop:
call get_next_token call get_next_token
cmp al, '@' cmp al, '@'