catm.hex2 (6456B)
1 ## Copyright (C) 2019 Jeremiah Orians 2 ## Copyright (C) 2020 Sanne Wouda 3 ## This file is part of stage0. 4 ## 5 ## stage0 is free software: you can redistribute it and/or modify 6 ## it under the terms of the GNU General Public License as published by 7 ## the Free Software Foundation, either version 3 of the License, or 8 ## (at your option) any later version. 9 ## 10 ## stage0 is distributed in the hope that it will be useful, 11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 ## GNU General Public License for more details. 14 ## 15 ## You should have received a copy of the GNU General Public License 16 ## along with stage0. If not, see <http://www.gnu.org/licenses/>. 17 18 19 # Register usage: 20 # X15 => OUTPUT 21 # X14 => Buffer 22 # X13 => INPUT 23 24 25 ## ELF Header 26 27 :ELF_base 28 29 7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number 30 31 02 # e_ident[EI_CLASS] Indicating 64 bit 32 01 # e_ident[EI_DATA] Indicating little endianness 33 01 # e_ident[EI_VERSION] Indicating original elf 34 35 03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict 36 00 # e_ident[EI_ABIVERSION] See above 37 38 00 00 00 00 00 00 00 # e_ident[EI_PAD] 39 02 00 # e_type Indicating Executable 40 B7 00 # e_machine Indicating AArch64 41 01 00 00 00 # e_version Indicating original elf 42 43 &ELF_text 00 00 00 00 # e_entry Address of the entry point 44 %ELF_program_headers>ELF_base 00 00 00 00 # e_phoff Address of program header table 45 00 00 00 00 00 00 00 00 # e_shoff Address of section header table 46 47 00 00 00 00 # e_flags 48 40 00 # e_ehsize Indicating our 64 Byte header 49 50 38 00 # e_phentsize size of a program header table 51 01 00 # e_phnum number of entries in program table 52 53 00 00 # e_shentsize size of a section header table 54 00 00 # e_shnum number of entries in section table 55 56 00 00 # e_shstrndx index of the section names 57 58 :ELF_program_headers 59 :ELF_program_header__text 60 01 00 00 00 # ph_type: PT-LOAD = 1 61 07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7 62 00 00 00 00 00 00 00 00 # ph_offset 63 &ELF_base 00 00 00 00 # ph_vaddr 64 &ELF_base 00 00 00 00 # ph_physaddr 65 %ELF_end>ELF_base 00 00 00 00 # ph_filesz 66 %ELF_end>ELF_base 00 00 00 00 # ph_memsz 67 01 00 00 00 00 00 00 00 # ph_align 68 69 :ELF_text 70 71 # Where the ELF Header is going to hit 72 # Simply jump to _start 73 # Our main function 74 :_start 75 e10f41f8 ; LDR_X1_[SP,16]_WB # Get the actual output name 76 600c8092 ; SET_X0_TO_FCNTL_H_AT_FDCWD # AT_FDCWD, relative to current working directory 77 224880d2 ; SET_X2_TO_577 # Prepare file as O_WRONLY|O_CREAT|O_TRUNC 78 033080d2 ; SET_X3_TO_384 # Prepare file as RW for owner only (600 in octal) 79 080780d2 ; SET_X8_TO_SYS_OPENAT # The syscall number for openat(), aarch64 has no open() 80 010000d4 ; SYSCALL # Now open that file 81 ef0300aa ; SET_X15_FROM_X0 # Preserve the file pointer we were given 82 83 c81a80d2 ; SET_X8_TO_SYS_BRK # the Syscall # for SYS_BRK 84 000080d2 ; SET_X0_TO_0 # Get current brk 85 010000d4 ; SYSCALL # Let the kernel do the work 86 ee0300aa ; SET_X14_FROM_X0 # Set our malloc pointer 87 88 c81a80d2 ; SET_X8_TO_SYS_BRK # the Syscall # for SYS_BRK 89 e0030eaa ; SET_X0_FROM_X14 # Using current pointer 90 00004491 ; ADD_X0_X0_0x100000 # Allocate 1MB 91 010000d4 ; SYSCALL # Let the kernel do the work 92 93 e4030091 ; SET_X4_FROM_SP 94 :core 95 818c40f8 ; LDR_X1_[X4,8]_WB # Get the actual input name 96 3f0000f1 ; CMP_X1_TO_0 # Check for null string 97 41000054 ; SKIP_INST_NE # Hit null be done 98 ^~done 14 ; ^~done FBRANCH 99 100 600c8092 ; SET_X0_TO_FCNTL_H_AT_FDCWD # AT_FDCWD, relative to current working directory 101 020080d2 ; SET_X2_TO_0 # prepare read_only 102 030080d2 ; SET_X3_TO_0 # prevent any interactions 103 080780d2 ; SET_X8_TO_SYS_OPENAT # The syscall number for openat(), aarch64 has no open() 104 010000d4 ; SYSCALL # Open file! 105 ed0300aa ; SET_X13_FROM_X0 # Protect INPUT 106 :keep 107 0202a0d2 ; SET_X2_TO_0x100000 # set the size of chars we want 108 e1030eaa ; SET_X1_FROM_X14 # Where to put it 109 e0030daa ; SET_X0_FROM_X13 # Where are we reading from 110 e80780d2 ; SET_X8_TO_SYS_READ # the syscall number for read 111 010000d4 ; SYSCALL # call the Kernel 112 113 e20300aa ; SET_X2_FROM_X0 # Number of bytes to write 114 e1030eaa ; SET_X1_FROM_X14 # What we are writing 115 e0030faa ; SET_X0_FROM_X15 # Write to target file 116 080880d2 ; SET_X8_TO_SYS_WRITE # the syscall number for write 117 010000d4 ; SYSCALL # call the Kernel 118 119 1f0044f1 ; CMP_X0_TO_0x100000 # Check if buffer was fully used 120 41000054 ; SKIP_INST_NE # Keep looping if was full 121 ^~keep 17 ; ^~keep RBRANCH 122 ^~core 17 ; ^~core RBRANCH # Otherwise move to next file 123 124 :done 125 # program completed Successfully 126 000080d2 ; SET_X0_TO_0 # All is well 127 a80b80d2 ; SET_X8_TO_SYS_EXIT # put the exit syscall number in x8 128 010000d4 ; SYSCALL # Call it a good day 129 130 :ELF_data 131 :ELF_end 132 :ELF_sym 133 :ELF_str