diff --git a/stages/hex0/Makefile b/stages/hex0/Makefile new file mode 100644 index 0000000..7219cf5 --- /dev/null +++ b/stages/hex0/Makefile @@ -0,0 +1,15 @@ +BUILD = ../build + +all: $(BUILD)/stage0 + +stage0: $(BUILD)/stage0 + +stage0-bootstrap: $(BUILD)/stage0-bootstrap + +$(BUILD)/stage0-bootstrap: hex0.in + for x in `sed '/^#/d;s/#.*//;s/ *//' hex0.in`; do printf \\x$$x; done > $@ + chmod +x $@ + +$(BUILD)/stage0: $(BUILD)/stage0-bootstrap + $< < hex0.in > $@ + chmod +x $@ diff --git a/stages/hex0/hex0.in b/stages/hex0/hex0.in new file mode 100644 index 0000000..6cce7a4 --- /dev/null +++ b/stages/hex0/hex0.in @@ -0,0 +1,205 @@ +# ELF header +# e_ident: u128 +# Magic number: 0x7f454c46 = "\x7fELF" +7f 45 4c 46 +02 # EI_CLASS: u8 = ELFCLASS64 +01 # EI_DATA: u8 = ELFDATA2LSB +01 # EI_VERSION: u8 = EV_CURRENT +00 # EI_OSABI: u8 = ELFOSABI_NONE +00 # EI_ABIVERSION: u8 = 0 +00 00 00 00 00 00 00 # EI_PAD: [u8; 7] +# e_type: u16 = E_EXEC +02 00 +# e_machine: u16 = EM_X86_64 +3e 00 +# e_version: u32 = EV_CURRENT +01 00 00 00 +# e_entry: u64 = 0x400000 +00 00 40 00 00 00 00 00 +# e_phoff: u64 = 0x40 +40 00 00 00 00 00 00 00 +# e_shoff: u64 = 0x0 +00 00 00 00 00 00 00 00 +# e_flags: u32 = 0 +00 00 00 00 +# e_ehsize: u16 = 64 +40 00 +# e_phentsize: u16 = 56 +38 00 +# e_phnum: u16 = 1 +01 00 +# e_shentsize: u16 = 0 +00 00 +# e_shnum: u16 = 0 +00 00 +# e_shstrndx: u16 = 0 +00 00 +# End of ELF header +# +# Program header +# p_type: u32 = PT_LOAD +01 00 00 00 +# p_flags: u32 = PF_R | PF_X +05 00 00 00 +# p_offset: u64 = 0 +00 00 00 00 00 00 00 00 +# p_vaddr: u64 = 0x400000 +00 00 40 00 00 00 00 00 +# p_paddr: u64 = 0x0 +00 00 00 00 00 00 00 00 +# p_filesz: u64 = 0x164 +64 01 00 00 00 00 00 00 +# p_memsz: u64 = 0x1000 +00 10 00 00 00 00 00 00 +# p_align: u64 = 0x1000 +00 10 00 00 00 00 00 00 +# End of program header +# +# Code segment (offset 0x40, virtual address 0x400000) +# +# _start: +# ; alloca 0x1000 bytes on the stack +# mov rbp, rsp +48 89 e5 +# sub rsp, 0x1000 +48 81 ec 00 10 00 00 +# ; read 0x800 bytes from stdin into the stack +# .READ: (_start+10) +# xor rax, rax +48 31 c0 +# mov edi, 0 (stdin) +48 c7 c7 00 00 00 00 +# mov rsi, rsp +48 89 e6 +# mov rdx, 0x800 +48 c7 c2 00 08 00 00 +# syscall (sys_read) +0f 05 +# cmp rax, 0 +48 83 f8 00 +# jle die +0f 8e a1 00 00 00 # 203 - 42 = 161 = 0xa1 +## (_start+42) +# ; end = r8 +# mov r8, rax +49 89 c0 +# add r8, rsp +49 01 e0 +# ; pos = r9 +# mov r9, rsp +49 89 e1 +# ; dst = r10 +# mov r10, rsp +49 89 e2 +# add r10, 0x800 +49 81 c2 00 08 00 00 +# ; while (pos < end) { +# ; .L0: (_start+61) +# cmp r9, r8 +4d 39 c1 +# jge .L3 +0f 8d 60 00 00 00 ; 166 - 70 = 96 = 0x60 +# (_start+70) +# +# ; if (*pos == '#') { +# mov al , byte [r9] +41 8a 41 00 +# cmp al, '#' +3c 23 +# jne .L1 ; 100 - 82 = 18 = 0x12 +0f 85 12 00 00 00 +# (_start+82) +# ; while (*pos != '\n') pos++; +# ; .L2: (_start+82) +# inc r9 +49 ff c1 +# cmp byte [r9], '\n' +41 80 39 0a +# jne .L2 ; 82 - 95 = -13 = 0xfffffffffffffff3 = 0xf3 +0f 85 f3 ff ff ff +# (_start+95) +# jmp .L0 ; 61 - 100 = -39 = 0xfffffffffffffd89 = 0xfd89 +e9 89 fd ff ff +# (_start+100) +# ; .L1: (_start+100) +# ; convert *pos to high word +# mov bl, al +88 c3 +# sub bl, 'a' +80 eb 61 +# add bl, 10 +80 c3 0a +# sub al, '0' +2c 30 +# cmp al, 10 +3c 0a +# cmovge eax, ebx +0f 43 c3 +# shl al, 4 +c0 e0 04 +# ; pos++ +# inc r9 +49 ff c1 +# ; convert *pos to low word +# mov bl, byte [r9] +41 8a 19 +# mov cl, bl +88 d9 +# sub cl, 'a' +80 e9 61 +# add cl, 10 +80 c1 0a +# sub bl, '0' +80 eb 30 +# cmp bl, 10 +80 fb 0a +# cmovge ebx, ecx +0f 4d d9 +# ; combine high and low word +# or al, bl +08 d8 +# ; write the byte to dst +# mov byte [r10], al +41 88 02 +# inc r10 +41 ff c2 +# ; if (*pos != '\n') pos++; +# cmp byte [r9], '\n' +41 80 39 0a +# inc r9 +49 ff c1 +# je .L0 ; 61 - 161 = -100 = 0xffffffffffffff9c = 0x9c +0f 84 9c ff ff ff +## (_start+161) +# jmp .L1 ; 100 - 166 = -66 = 0xffffffffffffffbe = 0xbe +e9 be ff ff ff +## (_start+166) +# ; } +# .L3: (_start+166) +# ; write the decoded bytes to stdout +# mov rax, 1 (sys_write) +48 c7 c0 01 00 00 00 +# mov rdi, 1 (stdout) +48 c7 c7 01 00 00 00 +# mov rsi, rsp +48 89 e6 +# add rsi, 0x800 +48 81 c6 00 08 00 00 +# mov rdx, r10 +4c 89 d2 +# sub rdx, rsi +48 29 f2 +# syscall +0f 05 +# jmp .READ ; 10 - 203 = -193 = 0xffffffffffffff3f = 0x3f +e9 3f ff ff ff +## (_start+203) +# +# die: (_start+203) +# mov rax, 60 (sys_exit) +48 c7 c0 3c 00 00 00 +# xor rdi, rdi +48 31 ff +# syscall +0f 05 +# _start+215