aboutsummaryrefslogtreecommitdiff
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
init commit
-rw-r--r--.envrc1
-rw-r--r--.gitignore3
-rw-r--r--Makefile6
-rw-r--r--bfc.S159
-rw-r--r--flake.lock27
-rw-r--r--flake.nix23
6 files changed, 219 insertions, 0 deletions
diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..3550a30
--- /dev/null
+++ b/.envrc
@@ -0,0 +1 @@
+use flake
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e6a59e1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+bfc
+bfc.o
+.direnv
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..d48bf1f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,6 @@
+bfc: bfc.S
+ as -64 bfc.S -o bfc.o -g
+ ld bfc.o -o bfc
+
+clean:
+ rm bfc.o bfc
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
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..3601be1
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1734649271,
+ "narHash": "sha256-4EVBRhOjMDuGtMaofAIqzJbg4Ql7Ai0PSeuVZTHjyKQ=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "d70bd19e0a38ad4790d3913bf08fcbfc9eeca507",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..fc6a998
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,23 @@
+{
+ description = "A very basic flake";
+
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
+ };
+
+ outputs = { self, nixpkgs }:
+ let
+ pkgs = import nixpkgs { system = "x86_64-linux"; };
+ in
+ {
+ packages.x86_64-linux.default = pkgs.stdenv.mkDerivation {
+ buildInputs = [ pkgs.glibc.static ];
+ name = "bfc";
+ };
+
+ devShells.x86_64-linux.default = pkgs.stdenv.mkDerivation {
+ name = "bfc-dev-shell";
+ buildInputs = [ pkgs.gdb pkgs.ascii pkgs.man-pages pkgs.moreutils ];
+ };
+ };
+}