catm.hex2 (6231B)
1 ## Copyright (C) 2021 Andrius Štikonas 2 ## This file is part of stage0. 3 ## 4 ## stage0 is free software: you can redistribute it and/or modify 5 ## it under the terms of the GNU General Public License as published by 6 ## the Free Software Foundation, either version 3 of the License, or 7 ## (at your option) any later version. 8 ## 9 ## stage0 is distributed in the hope that it will be useful, 10 ## but WITHOUT ANY WARRANTY# without even the implied warranty of 11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 ## GNU General Public License for more details. 13 ## 14 ## You should have received a copy of the GNU General Public License 15 ## along with stage0. If not, see <http://www.gnu.org/licenses/>. 16 17 18 ## ELF Header 19 20 :ELF_base 21 7F 45 4C 46 ## e_ident[EI_MAG0-3] ELF's magic number 22 23 02 ## e_ident[EI_CLASS] Indicating 64 bit 24 01 ## e_ident[EI_DATA] Indicating little endianness 25 01 ## e_ident[EI_VERSION] Indicating original elf 26 27 03 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict 28 00 ## e_ident[EI_ABIVERSION] Set at 0 because none cares 29 30 00 00 00 00 00 00 00 ## e_ident[EI_PAD] 31 02 00 ## e_type Indicating Executable 32 F3 00 ## e_machine Indicating RISC-V 33 01 00 00 00 ## e_version Indicating original elf 34 35 &_start 00 00 00 00 ## e_entry Address of the entry point (Number of bytes this header is + Base Address) 36 %ELF_program_headers>ELF_base 00 00 00 00 ## e_phoff Address of program header table 37 00 00 00 00 00 00 00 00 ## e_shoff Address of section header table 38 39 00 00 00 00 ## e_flags 40 40 00 ## e_ehsize Indicating our 64 Byte header 41 42 38 00 ## e_phentsize size of a program header table 43 01 00 ## e_phnum number of entries in program table 44 45 00 00 ## e_shentsize size of a section header table 46 00 00 ## e_shnum number of entries in section table 47 48 00 00 ## e_shstrndx index of the section names 49 50 ## Program Header 51 :ELF_program_headers 52 01 00 00 00 ## p_type 53 07 00 00 00 ## ph_flags: PF-X|PF-W|PF-R = 7 54 00 00 00 00 00 00 00 00 ## p_offset 55 56 &ELF_base 00 00 00 00 ## p_vaddr 57 &ELF_base 00 00 00 00 ## p_physaddr 58 59 %ELF_end>ELF_base 00 00 00 00 ## p_filesz 60 %ELF_end>ELF_base 00 00 00 00 ## p_memsz 61 62 01 00 00 00 00 00 00 00 ## Required alignment 63 64 :ELF_text 65 66 ; Simply jump to _start 67 ; Our main function 68 :_start 69 70 # Register use: 71 # s1: output file descriptor 72 # s2: buffer 73 # s3: input file descriptor 74 # s4: number of bytes read 75 76 # Open output file and store the FD in s1 77 # rd_a7 !56 addi ; sys_openat 78 .80080000 .00008003 13000000 79 # rd_a0 !-100 addi ; AT_FDCWD 80 .00050000 .0000C0F9 13000000 81 # rd_sp rs1_sp !16 addi ; Prepare stack for reading output file 82 .00010000 .00000100 .00000001 13000000 83 # rd_a1 rs1_sp ld ; Output file (argument 1) 84 .80050000 .00000100 03300000 85 # rd_a2 !577 addi ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC 86 .00060000 .00001024 13000000 87 # rd_a3 !384 addi ; Prepare file as RW for owner only (600 in octal) 88 .80060000 .00000018 13000000 89 # ecall ; syscall 90 73000000 91 # rd_s1 rs1_a0 addi ; Save fd in for later 92 .80040000 .00000500 13000000 93 94 # Prepare heap memory 95 # rd_a7 !214 addi ; sys_brk 96 .80080000 .0000600D 13000000 97 # rd_a0 addi ; Get current brk 98 .00050000 13000000 99 # ecall ; syscall 100 73000000 101 # rd_s2 rs1_a0 addi ; Set our malloc pointer 102 .00090000 .00000500 13000000 103 104 # rd_a1 ~0x100000 lui ; a1=1MiB 105 .80050000 .00001000 37000000 106 # rd_a0 rs1_a0 rs2_a1 add ; Allocate 1MiB 107 .00050000 .00000500 .0000B000 33000000 108 # ecall ; syscall 109 73000000 110 111 :core 112 # rd_sp rs1_sp !8 addi ; Move stack pointer to next input file 113 .00010000 .00000100 .00008000 13000000 114 # rd_a1 rs1_sp ld ; Get the input file name 115 .80050000 .00000100 03300000 116 # rs1_a1 @Done beq ; This was the last file, we are done 117 .00800500 @Done 63000000 118 119 # rd_a7 !56 addi ; sys_openat 120 .80080000 .00008003 13000000 121 # rd_a0 !-100 addi ; AT_FDCWD 122 .00050000 .0000C0F9 13000000 123 # rd_a2 addi ; read only 124 .00060000 13000000 125 # ecall ; syscall 126 73000000 127 # rd_s3 rs1_a0 addi ; protect input fd 128 .80090000 .00000500 13000000 129 130 :keep 131 # rd_a7 !63 addi ; sys_read 132 .80080000 .0000F003 13000000 133 # rd_a0 rs1_s3 addi ; input fd 134 .00050000 .00800900 13000000 135 # rd_a1 rs1_s2 addi ; read into buffer 136 .80050000 .00000900 13000000 137 # rd_a2 ~0x100000 lui ; a2=1MiB 138 .00060000 .00001000 37000000 139 # ecall ; syscall 140 73000000 141 # rd_s4 rs1_a0 addi ; actual number of bytes read 142 .000A0000 .00000500 13000000 143 144 # rd_a7 !64 addi ; sys_write 145 .80080000 .00000004 13000000 146 # rd_a0 rs1_s1 addi ; output fd 147 .00050000 .00800400 13000000 148 # rd_a1 rs1_s2 addi ; write from buffer 149 .80050000 .00000900 13000000 150 # rd_a2 rs1_s4 addi ; number of bytes to write 151 .00060000 .00000A00 13000000 152 # ecall ; syscall 153 73000000 154 155 # rd_a2 ~0x100000 lui ; 1MiB 156 .00060000 .00001000 37000000 157 # rs1_s4 rs2_a2 @keep beq ; keep looping if buffer was full 158 .00000A00 .0000C000 @keep 63000000 159 # $core jal ; otherwise move to next file 160 $core 6F000000 161 162 :Done 163 # Terminate program with 0 return code 164 # rd_a7 !93 addi ; sys_exit 165 .80080000 .0000D005 13000000 166 # rd_a0 addi ; Return code 0 167 .00050000 13000000 168 # ecall ; exit(0) 169 73000000 170 171 :ELF_end