hex1.hex0 (18971B)
1 ## Copyright (C) 2017 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 ## ELF Header 19 20 #:ELF_base 21 22 7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number 23 24 02 # e_ident[EI_CLASS] Indicating 64 bit 25 01 # e_ident[EI_DATA] Indicating little endianness 26 01 # e_ident[EI_VERSION] Indicating original elf 27 28 03 # e_ident[EI_OSABI] Set at 0 because none cares 29 00 # e_ident[EI_ABIVERSION] See above 30 31 00 00 00 00 00 00 00 # e_ident[EI_PAD] 32 02 00 # e_type Indicating Executable 33 B7 00 # e_machine Indicating AArch64 34 01 00 00 00 # e_version Indicating original elf 35 36 78 00 60 00 00 00 00 00 # e_entry Address of the entry point 37 40 00 00 00 00 00 00 00 # e_phoff Address of program header table 38 00 00 00 00 00 00 00 00 # e_shoff Address of section header table 39 40 00 00 00 00 # e_flags 41 40 00 # e_ehsize Indicating our 64 Byte header 42 43 38 00 # e_phentsize size of a program header table 44 01 00 # e_phnum number of entries in program table 45 46 00 00 # e_shentsize size of a section header table 47 00 00 # e_shnum number of entries in section table 48 49 00 00 # e_shstrndx index of the section names 50 51 ## Program Header 52 #:ELF_program_headers 53 01 00 00 00 # ph_type: PT-LOAD = 1 54 07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7 55 00 00 00 00 00 00 00 00 # ph_offset 56 00 00 60 00 00 00 00 00 # ph_vaddr 57 00 00 60 00 00 00 00 00 # ph_physaddr 58 3D 04 00 00 00 00 00 00 # ph_filesz 59 3D 04 00 00 00 00 00 00 # ph_memsz 60 01 00 00 00 00 00 00 00 # ph_align 61 62 #:ELF_text 63 64 # Where the ELF Header is going to hit 65 # Simply jump to _start 66 # Our main function 67 #:_start 68 E10B40F9 ; LDR_X1_[SP,16] # Get the actual input name 69 600C8092 ; SET_X0_TO_FCNTL_H_AT_FDCWD # AT_FDCWD, relative to current working directory 70 020080D2 ; SET_X2_TO_0 # Prepare file as read only 71 080780D2 ; SET_X8_TO_SYS_OPENAT # The syscall number for openat(), aarch64 has no open() 72 010000D4 ; SYSCALL # Open file! 73 E90300AA ; SET_X9_FROM_X0 # Preserve the file pointer we were given 74 75 E10F40F9 ; LDR_X1_[SP,24] # Get the 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 033880D2 ; SET_X3_TO_448 # Prepare file as RWX for owner only (700 in octal) 79 080780D2 ; SET_X8_TO_SYS_OPENAT # The syscall number for openat(), aarch64 has no open() 80 010000D4 ; SYSCALL # Open file! 81 EA0300AA ; SET_X10_FROM_X0 # Preserve the file pointer we were given 82 83 0F008092 ; SET_X15_TO_MINUS_1 # Our flag for byte processing 84 0E0080D2 ; SET_X14_TO_0 # temp storage for the sum 85 0D0CA0D2 ; SET_X13_TO_0x600000 # Our starting IP 86 0D0000 94 ; ^~First_pass CALL # Process it 87 88 # rewind input file 89 E00309AA ; SET_X0_FROM_X9 # Using our input file 90 010080D2 ; SET_X1_TO_0 # Offset 91 020080D2 ; SET_X2_TO_0 # Whence SEEK_SET 92 C80780D2 ; SET_X8_TO_SYS_LSEEK # lseek 93 010000D4 ; SYSCALL 94 95 0F008092 ; SET_X15_TO_MINUS_1 # Our flag for byte processing 96 0E0080D2 ; SET_X14_TO_0 # temp storage for the sum 97 0D0CA0D2 ; SET_X13_TO_0x600000 # Our starting IP 98 2E0000 94 ; ^~Second_pass CALL # Process it 99 100 # program competed Successfully 101 000080D2 ; SET_X0_TO_0 # All is well 102 A80B80D2 ; SET_X8_TO_SYS_EXIT # put the exit syscall number in x8 103 010000D4 ; SYSCALL 104 105 #:First_pass 106 FE0F1FF8 ; PUSH_LR # push lr 107 108 #:First_pass_loop 109 880000 94 ; ^~Read_byte CALL 110 111 # Deal with EOF 112 1F1000B1 ; CMP_X0_TO_MINUS_4 113 41000054 ; SKIP_INST_NE 114 240000 14 ; ^~First_pass_done BRANCH 115 116 # Check for : 117 1FE800F1 ; CMP_X0_TO_58 118 40000054 ; SKIP_INST_EQ 119 020000 14 ; ^~First_pass_0 BRANCH 120 121 # Deal with label 122 A10000 94 ; ^~StoreLabel CALL 123 124 #:First_pass_0 125 # Check for $ 126 1F9000F1 ; CMP_X0_TO_36 127 41000054 ; SKIP_INST_NE 128 140000 14 ; ^~First_pass_abs16pointer BRANCH 129 130 # Check for ~ 131 1FF801F1 ; CMP_X0_TO_126 132 41000054 ; SKIP_INST_NE 133 140000 14 ; ^~First_pass_rel24pointer BRANCH 134 135 # Check for & 136 1F9800F1 ; CMP_X0_TO_38 137 41000054 ; SKIP_INST_NE 138 140000 14 ; ^~First_pass_abs32pointer BRANCH 139 140 # Deal with everything else 141 4A0000 94 ; ^~hex CALL # Process our char 142 143 # Deal with EOF 144 1F1000B1 ; CMP_X0_TO_MINUS_4 145 41000054 ; SKIP_INST_NE 146 130000 14 ; ^~First_pass_done BRANCH 147 148 # deal with -1 values 149 1F0000F1 ; CMP_X0_TO_0 150 4A000054 ; SKIP_INST_GE 151 E9FFFF 17 ; ^~First_pass_loop RBRANCH 152 153 # deal with toggle 154 FF0100F1 ; CMP_X15_TO_0 155 41000054 ; SKIP_INST_NE 156 020000 14 ; ^~First_pass_1 BRANCH 157 AD050091 ; ADD_X13_1 # Increment IP 158 159 #:First_pass_1 160 EF032FAA ; NOT_X15 # Flip toggle 161 E3FFFF 17 ; ^~First_pass_loop RBRANCH 162 163 #:First_pass_abs16pointer 164 # Deal with 16-bit Pointer to label 165 6A0000 94 ; ^~Read_byte CALL # Drop the char 166 AD090091 ; ADD_X13_2 # Increment IP 167 E0FFFF 17 ; ^~First_pass_loop RBRANCH # Loop again 168 169 #:First_pass_rel24pointer 170 # Deal with 24-bit Pointer to label 171 670000 94 ; ^~Read_byte CALL # Drop the char 172 AD0D0091 ; ADD_X13_3 # Increment IP 173 DDFFFF 17 ; ^~First_pass_loop RBRANCH # Loop again 174 175 #:First_pass_abs32pointer 176 # Deal with 32-bit Pointer to label 177 640000 94 ; ^~Read_byte CALL # Drop the char 178 AD110091 ; ADD_X13_4 # Increment IP 179 DAFFFF17 ; ^~First_pass_loop RBRANCH # Loop again 180 181 #:First_pass_done 182 FE0741F8 ; POP_LR 183 C0035FD6 ; RETURN 184 185 #:Second_pass 186 FE0F1FF8 ; PUSH_LR # push lr 187 188 #:Second_pass_loop 189 5E0000 94 ; ^~Read_byte CALL 190 191 # Deal with EOF 192 1F1000B1 ; CMP_X0_TO_MINUS_4 193 41000054 ; SKIP_INST_NE 194 2C0000 14 ; ^~Second_pass_done BRANCH 195 196 # Simply drop the label 197 1FE800F1 ; CMP_X0_TO_58 198 40000054 ; SKIP_INST_EQ 199 030000 14 ; ^~Second_pass_0 BRANCH 200 570000 94 ; ^~Read_byte CALL 201 F8FFFF 17 ; ^~Second_pass_loop RBRANCH 202 203 #:Second_pass_0 204 # Check for $ 205 1F9000F1 ; CMP_X0_TO_36 206 41000054 ; SKIP_INST_NE 207 140000 14 ; ^~Second_pass_abs16pointer BRANCH 208 209 # Check for ~, assume preceded by ^ 210 1FF801F1 ; CMP_X0_TO_126 211 41000054 ; SKIP_INST_NE 212 130000 14 ; ^~Second_pass_rel24pointer BRANCH 213 214 # Check for $ 215 1F9800F1 ; CMP_X0_TO_38 216 41000054 ; SKIP_INST_NE 217 120000 14 ; ^~Second_pass_abs32pointer BRANCH 218 219 # Deal with everything else 220 1F0000 94 ; ^~hex CALL # Process our char 221 222 # Deal with EOF 223 1F1000B1 ; CMP_X0_TO_MINUS_4 224 41000054 ; SKIP_INST_NE 225 1A0000 14 ; ^~Second_pass_done BRANCH 226 227 # deal with -1 values 228 1F0000F1 ; CMP_X0_TO_0 229 4A000054 ; SKIP_INST_GE 230 E8FFFF 17 ; ^~Second_pass_loop RBRANCH 231 232 # deal with toggle 233 FF0100F1 ; CMP_X15_TO_0 234 41000054 ; SKIP_INST_NE 235 0A0000 14 ; ^~print BRANCH 236 237 # process first byte of pair 238 EE0300AA ; SET_X14_FROM_X0 239 0F0080D2 ; SET_X15_TO_0 240 E2FFFF 17 ; ^~Second_pass_loop RBRANCH 241 242 #:Second_pass_abs16pointer 243 640000 94 ; ^~StoreAbs16Pointer CALL 244 E0FFFF 17 ; ^~Second_pass_loop RBRANCH 245 246 #:Second_pass_rel24pointer 247 6E0000 94 ; ^~StoreRel24Pointer CALL 248 DEFFFF 17 ; ^~Second_pass_loop RBRANCH 249 250 #:Second_pass_abs32pointer 251 7A0000 94 ; ^~StoreAbs32Pointer CALL 252 DCFFFF 17 ; ^~Second_pass_loop RBRANCH 253 254 # process second byte of pair 255 #:print 256 # update the sum and store in output 257 00100E8B ; ADD_X0_X0_X14_LSL_4 258 41000018 ; LOAD_W1_AHEAD 259 02000014 ; SKIP_32_DATA 260 3C04 6000 ; &table 261 20000039 ; STR_BYTE_W0_[X1] 262 263 # flip the toggle 264 0F008092 ; SET_X15_TO_MINUS_1 265 266 # print our first Hex 267 220080D2 ; SET_X2_TO_1 # set the size of chars we want 268 430000 94 ; ^~print_chars CALL 269 270 AD050091 ; ADD_X13_1 # Increment IP 271 D2FFFF 17 ; ^~Second_pass_loop RBRANCH 272 273 #:Second_pass_done 274 FE0741F8 ; POP_LR # pop lr 275 C0035FD6 ; RETURN 276 277 #:hex 278 # deal with EOF 279 1F1000B1 ; CMP_X0_TO_MINUS_4 280 41000054 ; SKIP_INST_NE 281 2A0000 14 ; ^~EOF BRANCH 282 283 # Purge Comment Lines (#) 284 1F8C00F1 ; CMP_X0_TO_35 285 41000054 ; SKIP_INST_NE 286 170000 14 ; ^~purge_comment BRANCH 287 288 # Purge Comment Lines (;) 289 1FEC00F1 ; CMP_X0_TO_59 290 41000054 ; SKIP_INST_NE 291 140000 14 ; ^~purge_comment BRANCH 292 293 # deal all ascii less than 0 294 1FC000F1 ; CMP_X0_TO_48 295 4A000054 ; SKIP_INST_GE 296 1F0000 14 ; ^~ascii_other BRANCH 297 298 # deal with 0-9 299 1FE800F1 ; CMP_X0_TO_58 300 4A000054 ; SKIP_INST_GE 301 160000 14 ; ^~ascii_num BRANCH 302 303 # deal with all ascii less than A 304 1F0401F1 ; CMP_X0_TO_65 305 4A000054 ; SKIP_INST_GE 306 190000 14 ; ^~ascii_other BRANCH 307 308 # deal with A-F 309 1F1C01F1 ; CMP_X0_TO_71 310 4A000054 ; SKIP_INST_GE 311 140000 14 ; ^~ascii_high BRANCH 312 313 # deal with all ascii less than a 314 1F8401F1 ; CMP_X0_TO_97 315 4A000054 ; SKIP_INST_GE 316 130000 14 ; ^~ascii_other BRANCH 317 318 # deal with a-f 319 1F9C01F1 ; CMP_X0_TO_103 320 4A000054 ; SKIP_INST_GE 321 0C0000 14 ; ^~ascii_low BRANCH 322 323 # The rest that remains needs to be ignored 324 0F0000 14 ; ^~ascii_other BRANCH 325 326 #:purge_comment 327 FE0F1FF8 ; PUSH_LR # push lr 328 329 #:loop0 330 # Read a byte 331 100000 94 ; ^~Read_byte CALL 332 333 # Loop if not LF 334 1F2800F1 ; CMP_X0_TO_10 335 40000054 ; SKIP_INST_EQ 336 FDFFFF 17 ; ^~loop0 RBRANCH 337 338 # Otherwise return -1 339 00008092 ; SET_X0_TO_MINUS_1 340 341 FE0741F8 ; POP_LR # pop lr 342 C0035FD6 ; RETURN 343 344 #:ascii_num 345 00C000D1 ; SUB_X0_48 346 C0035FD6 ; RETURN 347 348 #:ascii_low 349 005C01D1 ; SUB_X0_87 350 C0035FD6 ; RETURN 351 352 #:ascii_high 353 00DC00D1 ; SUB_X0_55 354 C0035FD6 ; RETURN 355 356 #:ascii_other 357 00008092 ; SET_X0_TO_MINUS_1 358 C0035FD6 ; RETURN 359 360 #:EOF 361 C0035FD6 ; RETURN 362 363 #:Read_byte 364 # Attempt to read 1 byte from input file 365 E00309AA ; SET_X0_FROM_X9 # Where are we reading from 366 41000018 ; LOAD_W1_AHEAD # Where to put it 367 02000014 ; SKIP_32_DATA 368 3C04 6000 ; &table 369 220080D2 ; SET_X2_TO_1 # set the size of chars we want 370 E80780D2 ; SET_X8_TO_SYS_READ # the syscall number for read 371 010000D4 ; SYSCALL # call the Kernel 372 373 1F0000F1 ; CMP_X0_TO_0 374 41000054 ; SKIP_INST_NE 375 060000 14 ; ^~Read_byte_1 BRANCH 376 377 # load byte 378 40000098 ; LOAD_W0_AHEAD 379 02000014 ; SKIP_32_DATA 380 3C04 6000 ; &table 381 00004039 ; LDR_BYTE_W0_[X0] # load char, unsigned so zero-extended already 382 C0035FD6 ; RETURN 383 384 # Deal with EOF 385 #:Read_byte_1 386 60008092 ; SET_X0_TO_MINUS_4 # Put EOF in x0 387 C0035FD6 ; RETURN 388 389 #:print_chars 390 E0030AAA ; SET_X0_FROM_X10 # Write to target file 391 41000018 ; LOAD_W1_AHEAD # What we are writing 392 02000014 ; SKIP_32_DATA 393 3C04 6000 ; &table 394 080880D2 ; SET_X8_TO_SYS_WRITE # the syscall number for write 395 010000D4 ; SYSCALL # call the Kernel 396 C0035FD6 ; RETURN 397 398 #:Get_table_target 399 FE0F1FF8 ; PUSH_LR # push lr 400 E7FFFF 97 ; ^~Read_byte RCALL # Get single char label 401 41000018 ; LOAD_W1_AHEAD 402 02000014 ; SKIP_32_DATA 403 3C04 6000 ; &table 404 200C008B ; ADD_X0_X1_X0_LSL_3 # Each label in table takes 8 bytes to store 405 FE0741F8 ; POP_LR # pop lr 406 C0035FD6 ; RETURN 407 408 #:StoreLabel 409 FE0F1FF8 ; PUSH_LR 410 F7FFFF 97 ; ^~Get_table_target RCALL 411 0D0000F9 ; STR_X13_[X0] 412 FE0741F8 ; POP_LR 413 C0035FD6 ; RETURN 414 415 #:StoreAbs16Pointer 416 FE0F1FF8 ; PUSH_LR # push lr 417 F2FFFF 97 ; ^~Get_table_target RCALL # Get address of pointer 418 000040F9 ; DEREF_X0 # Get pointer 419 41000018 ; LOAD_W1_AHEAD 420 02000014 ; SKIP_32_DATA 421 3C04 6000 ; &table 422 200000F9 ; STR_X0_[X1] # put value in output 423 AD090091 ; ADD_X13_2 # Increment IP 424 420080D2 ; SET_X2_TO_2 # set the size of chars we want 425 E3FFFF 97 ; ^~print_chars RCALL 426 FE0741F8 ; POP_LR # pop lr 427 C0035FD6 ; RETURN 428 429 #:StoreRel24Pointer 430 FE0F1FF8 ; PUSH_LR # push lr 431 E6FFFF 97 ; ^~Get_table_target RCALL # Get address of pointer 432 000040F9 ; DEREF_X0 # Get pointer 433 00000DCB ; SUB_X0_X0_X13 # target - ip 434 00FC4293 ; ASR_X0_X0_2 # rel24 pointer is 4-byte aligned 435 41000018 ; LOAD_W1_AHEAD 436 02000014 ; SKIP_32_DATA 437 3C04 6000 ; &table 438 200000F9 ; STR_X0_[X1] # put value in output 439 AD0D0091 ; ADD_X13_3 # Increment IP 440 620080D2 ; SET_X2_TO_3 # set the size of chars we want 441 D5FFFF 97 ; ^~print_chars RCALL 442 FE0741F8 ; POP_LR # pop lr 443 C0035FD6 ; RETURN 444 445 #:StoreAbs32Pointer 446 FE0F1FF8 ; PUSH_LR # push lr 447 D8FFFF 97 ; ^~Get_table_target RCALL # Get address of pointer 448 000040F9 ; DEREF_X0 # Get pointer 449 41000018 ; LOAD_W1_AHEAD 450 02000014 ; SKIP_32_DATA 451 3C04 6000 ; &table 452 200000F9 ; STR_X0_[X1] # put value in output 453 AD110091 ; ADD_X13_4 # Increment IP 454 820080D2 ; SET_X2_TO_4 # set the size of chars we want 455 C9FFFF 97 ; ^~print_chars RCALL 456 FE0741F8 ; POP_LR # pop lr 457 C0035FD6 ; RETURN 458 459 460 #:ELF_data 461 #:table 462 00 ; NULL8 463 464 #:ELF_end