aboutsummaryrefslogtreecommitdiff
path: root/bfc.S
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-12-26 16:15:22 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2024-12-26 16:15:22 +0100
commitd89df1906d0805a1465e052ae80339c38f25db1b (patch)
treedae1e24243aaf074eec0f30a72abbd88e2bb359e /bfc.S
init commit
Diffstat (limited to 'bfc.S')
-rw-r--r--bfc.S159
1 files changed, 159 insertions, 0 deletions
diff --git a/bfc.S b/bfc.S
new file mode 100644
index 0000000..44ee7ec
--- /dev/null
+++ b/bfc.S
@@ -0,0 +1,159 @@
+.global _start
+
+.data
+
+v_elf_header:
+ .byte 0x7f # Magic Number
+ .ascii "ELF" #
+ .byte 0x2 # 64-Bit
+ .byte 0x1 # little-endian
+ .byte 0x1 # ELFv1
+ .byte 0x0 # System V ABI
+ .quad 0x0 #
+ .hword 0x02 # Executable
+ .hword 0x3e # AMD x86-64
+ .int 0x1 # ELFv1
+ .quad 0x401000 # Entry
+ .quad 0x40 # Program Header Offset
+ .quad 0x100 # TODO: Section Header Offset
+ .int 0x0 #
+ .hword 0x40 # ELF Header Size
+ .hword 0x38 # Program Header Table Entry Size
+ .hword 0x3 # TODO: Number Of Entries in Program Header Table
+ .hword 0x40 # Section Header Table Entry Size
+ .hword 0x3 # TODO: Number Of Entries in Section Header Table
+ .hword 0x2 # TODO: Index of Section Header Table Entry containing section names
+
+v_usage_message:
+ .asciz "bfc [input file] [output file]\n"
+
+v_input_fd:
+ .int 0x0
+
+v_output_fd:
+ .int 0x0
+
+v_buffer_start:
+ .quad 0x0
+
+v_buffer_end:
+ .quad 0x0
+
+v_buffer_cursor:
+ .quad 0x0
+
+
+.text
+_start:
+ mov %rsp, %rbp
+ call f_check_args
+ call f_open_files
+ call f_init_buffer
+
+ mov $v_buffer_cursor, %rbx
+ mov (%rbx), %rsi
+ add $0x300, %rsi
+ mov %rsi, (%rbx)
+ call f_check_buffer
+
+ mov $v_buffer_cursor, %rsi
+ mov (%rbx), %rsi
+ add $0x300, %rsi
+ mov %rsi, (%rbx)
+ call f_check_buffer
+
+ # ----
+
+ mov $1, %rax
+ mov %rcx, %rdi
+ mov $v_elf_header, %rsi
+ mov $0x40, %rdx
+ syscall
+
+ # ----
+
+ call f_close_files
+ mov $0, %rdi
+ jmp f_exit
+
+f_exit:
+ mov $60, %rax
+ syscall
+
+f_check_args:
+ mov (%rbp), %rax
+ cmp $3, %rax
+ je l_check_args_success
+
+ mov $1, %rax
+ mov $2, %rdi
+ mov $v_usage_message, %rsi
+ mov $32, %rdx
+ syscall
+
+ mov $-1, %rdi
+ jmp f_exit
+
+l_check_args_success:
+ ret
+
+f_open_files:
+ mov $2, %rax
+ mov 16(%rbp), %rdi
+ mov $0, %rsi
+ mov $0, %rdx
+ syscall
+ mov $v_input_fd, %rbx
+ mov %eax, (%rbx)
+
+ mov $2, %rax
+ mov 24(%rbp), %rdi
+ mov $0x41, %rsi
+ mov $0744, %rdx
+ syscall
+ mov $v_output_fd, %rbx
+ mov %eax, (%rbx)
+ ret
+
+f_close_files:
+ mov $3, %rax
+ mov %rbx, %rsi
+ syscall
+
+ mov $3, %rax
+ mov %rcx, %rsi
+ syscall
+ ret
+
+f_init_buffer:
+ mov $12, %rax
+ mov $0, %rdi
+ syscall
+ mov $v_buffer_start, %rbx
+ mov %rax, (%rbx)
+ mov $v_buffer_end, %rbx
+ mov %rax, (%rbx)
+ mov $v_buffer_cursor, %rbx
+ mov %rax, (%rbx)
+ /*
+ * We directly skip to f_resize_buffer
+ * since we want to resize it to a usable amount
+ */
+f_resize_buffer:
+ mov $12, %rax
+ mov $v_buffer_end, %rbx
+ mov (%rbx), %rdi
+ add $0x400, %rdi
+ syscall
+ mov %rax, (%rbx)
+ ret
+
+/* %rsi = needed end */
+f_check_buffer:
+ mov $v_buffer_end, %rbx
+ mov (%rbx), %rax
+ cmp %rax, %rsi
+ jl l_check_buffer_large_enough
+ call f_resize_buffer
+l_check_buffer_large_enough:
+ ret