boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

hex0.hex0 (9763B)


      1 ## Copyright (C) 2016 Jeremiah Orians
      2 ## Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
      3 ## Copyright (C) 2020 Sanne Wouda
      4 ## This file is part of stage0.
      5 ##
      6 ## stage0 is free software: you can redistribute it and/or modify
      7 ## it under the terms of the GNU General Public License as published by
      8 ## the Free Software Foundation, either version 3 of the License, or
      9 ## (at your option) any later version.
     10 ##
     11 ## stage0 is distributed in the hope that it will be useful,
     12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 ## GNU General Public License for more details.
     15 ##
     16 ## You should have received a copy of the GNU General Public License
     17 ## along with stage0.  If not, see <http://www.gnu.org/licenses/>.
     18 
     19 ## ELF Header
     20 
     21 #:ELF_base
     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 (Number of bytes this header is + Base Address)
     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             ## p_type
     54 07 00 00 00             ## Flags
     55 00 00 00 00 00 00 00 00 ## p_offset
     56 
     57 00 00 60 00 00 00 00 00 ## p_vaddr
     58 00 00 60 00 00 00 00 00 ## p_physaddr
     59 
     60 0E 02 00 00 00 00 00 00 ## p_filesz
     61 0E 02 00 00 00 00 00 00 ## p_memsz
     62 
     63 01 00 00 00 00 00 00 00 ## Required alignment
     64 
     65 #:ELF_text
     66 
     67 # Where the ELF Header is going to hit
     68 # Simply jump to _start
     69 # Our main function
     70 #:_start
     71     E10B40F9                    ; LDR_X1_[SP,16]              # Get the actual input name
     72     600C8092                    ; SET_X0_TO_FCNTL_H_AT_FDCWD  # AT_FDCWD, relative to current working directory
     73     020080D2                    ; SET_X2_TO_0                 # Prepare file as read only
     74     080780D2                    ; SET_X8_TO_SYS_OPENAT        # The syscall number for openat(), aarch64 has no open()
     75     010000d4                    ; SYSCALL                     # Open file!
     76     E90300AA                    ; SET_X9_FROM_X0              # Preserve the file pointer we were given
     77 
     78     E10F40F9                    ; LDR_X1_[SP,24]              # Get the output name
     79     600C8092                    ; SET_X0_TO_FCNTL_H_AT_FDCWD  # AT_FDCWD, relative to current working directory
     80     224880D2                    ; SET_X2_TO_577               # Prepare file as O_WRONLY|O_CREAT|O_TRUNC
     81     033880D2                    ; SET_X3_TO_448               # Prepare file as RWX for owner only (700 in octal)
     82     080780D2                    ; SET_X8_TO_SYS_OPENAT        # The syscall number for openat(), aarch64 has no open()
     83     010000D4                    ; SYSCALL                     # Open file!
     84     EA0300AA                    ; SET_X10_FROM_X0             # Preserve the file pointer we were given
     85 
     86     # Our flag for byte processing
     87     0F008092                    ; SET_X15_TO_MINUS_1
     88 
     89     # temp storage for the sum
     90     0E0080D2                    ; SET_X14_TO_0
     91 
     92 #:loop
     93     # Read a byte
     94     470000 94                   ; ^~Read_byte CALL
     95 
     96     # process byte
     97     120000 94                   ; ^~hex CALL
     98 
     99     # Deal with -1 values
    100     1F0000F1                    ; CMP_X0_TO_0
    101     4A000054                    ; SKIP_INST_GE
    102     FCFFFF 17                   ; ^~loop RBRANCH
    103 
    104     # deal with toggle
    105     FF0100F1                    ; CMP_X15_TO_0
    106     4B000054                    ; SKIP_INST_LT
    107     040000 14                   ; ^~print BRANCH
    108 
    109     # process first byte of pair
    110     EE0300AA                    ; SET_X14_FROM_X0
    111     0F0080D2                    ; SET_X15_TO_0
    112 
    113     F6FFFF 17                   ; ^~loop RBRANCH
    114 
    115 # process second byte of pair
    116 #:print
    117     # update the sum and store in output
    118     00100E8B                    ; ADD_X0_X0_X14_LSL4
    119     41000018                    ; LOAD_W1_AHEAD
    120     02000014                    ; SKIP_32_DATA
    121     0C02 6000                   ; $output DATA_OFFSET 40 00
    122     20000039                    ; STR_BYTE_W0_[X1]
    123 
    124     # flip the toggle
    125     0F008092                    ; SET_X15_TO_MINUS_1
    126 
    127     2E0000 94                   ; ^~write_byte CALL
    128 
    129     EEFFFF 17                   ; ^~loop RBRANCH
    130 
    131 #:hex
    132     # Purge Comment Lines (#)
    133     1F8C00F1                    ; CMP_X0_TO_35
    134     41000054                    ; SKIP_INST_NE
    135     170000 14                   ; ^~purge_comment BRANCH
    136 
    137     # Purge Comment Lines (;)
    138     1FEC00F1                    ; CMP_X0_TO_59
    139     41000054                    ; SKIP_INST_NE
    140     140000 14                   ; ^~purge_comment BRANCH
    141 
    142     # deal all ascii less than 0
    143     1FC000F1                    ; CMP_X0_TO_48
    144     4A000054                    ; SKIP_INST_GE
    145     1F0000 14                   ; ^~ascii_other BRANCH
    146 
    147     # deal with 0-9
    148     1FE800F1                    ; CMP_X0_TO_58
    149     4A000054                    ; SKIP_INST_GE
    150     160000 14                   ; ^~ascii_num BRANCH
    151 
    152     # deal with all ascii less than A
    153     1F0401F1                    ; CMP_X0_TO_65
    154     4A000054                    ; SKIP_INST_GE
    155     190000 14                   ; ^~ascii_other BRANCH
    156 
    157     # deal with A-F
    158     1F1C01F1                    ; CMP_X0_TO_71
    159     4A000054                    ; SKIP_INST_GE
    160     140000 14                   ; ^~ascii_high BRANCH
    161 
    162     # deal with all ascii less than a
    163     1F8401F1                    ; CMP_X0_TO_97
    164     4A000054                    ; SKIP_INST_GE
    165     130000 14                   ; ^~ascii_other BRANCH
    166 
    167     # deal with a-f
    168     1F9C01F1                    ; CMP_X0_TO_103
    169     4A000054                    ; SKIP_INST_GE
    170     0C0000 14                   ; ^~ascii_low BRANCH
    171 
    172     # The rest that remains needs to be ignored
    173     0F0000 14                   ; ^~ascii_other BRANCH
    174 
    175 #:purge_comment
    176     FE0F1FF8                    ; PUSH_LR                     # push lr
    177 
    178 #:purge_comment_loop
    179     # Read a byte
    180     1A0000 94                   ; ^~Read_byte CALL
    181 
    182     # Loop if not LF
    183     1F2800F1                    ; CMP_X0_TO_10
    184     40000054                    ; SKIP_INST_EQ
    185     FDFFFF 17                   ; ^~purge_comment_loop RBRANCH
    186 
    187     # Otherwise return -1
    188     00008092                    ; SET_X0_TO_MINUS_1
    189 
    190     FE0741F8                    ; POP_LR                      # pop lr
    191     C0035FD6                    ; RETURN
    192 
    193 #:ascii_num
    194     00C000D1                    ; SUB_X0_48
    195     C0035FD6                    ; RETURN
    196 
    197 #:ascii_low
    198     005C01D1                    ; SUB_X0_87
    199     C0035FD6                    ; RETURN
    200 
    201 #:ascii_high
    202     00DC00D1                    ; SUB_X0_55
    203     C0035FD6                    ; RETURN
    204 
    205 #:ascii_other
    206     00008092                    ; SET_X0_TO_MINUS_1
    207     C0035FD6                    ; RETURN
    208 
    209 #:Done
    210     # program completed Successfully
    211     000080D2                    ; SET_X0_TO_0                 # All is well
    212     A80B80D2                    ; SET_X8_TO_SYS_EXIT          # put the exit syscall number in x8
    213     010000d4                    ; SYSCALL
    214 
    215 #:write_byte
    216     # Print our Hex
    217     E0030AAA                    ; SET_X0_FROM_X10             # Where are we writing to
    218     41000018                    ; LOAD_W1_AHEAD               # What we are writing
    219     02000014                    ; SKIP_32_DATA
    220     0C02 6000                   ; $output DATA_OFFSET
    221     220080D2                    ; SET_X2_TO_1                 # set the size of chars we want
    222     080880D2                    ; SET_X8_TO_SYS_WRITE         # the syscall number for write
    223     010000d4                    ; SYSCALL                     # call the Kernel
    224     C0035FD6                    ; RETURN
    225 
    226 #:Read_byte
    227     # Attempt to read 1 byte from input file
    228     E00309AA                    ; SET_X0_FROM_X9              # Where are we reading from
    229     41000018                    ; LOAD_W1_AHEAD               # Where to put it
    230     02000014                    ; SKIP_32_DATA
    231     0D02 6000                   ; $input DATA_OFFSET
    232     220080D2                    ; SET_X2_TO_1                 # set the size of chars we want
    233     E80780D2                    ; SET_X8_TO_SYS_READ          # the syscall number for read
    234     010000D4                    ; SYSCALL                     # call the Kernel
    235 
    236     1F0000F1                    ; CMP_X0_TO_0                 # Got EOF call it done
    237     41000054                    ; SKIP_INST_NE
    238     ECFFFF 17                   ; ^~Done RBRANCH
    239 
    240     # load byte
    241     40000098                    ; LOAD_W0_AHEAD
    242     02000014                    ; SKIP_32_DATA
    243     0D02 6000                   ; $input DATA_OFFSET
    244     00004039                    ; LDR_BYTE_W0_[X0]            # load char, unsigned so zero-extended already
    245     C0035FD6                    ; RETURN
    246 
    247 #:ELF_data
    248 # Where we are putting our output
    249 #:output
    250     # Reserve a byte
    251     00
    252 
    253 # Where we get our input
    254 #:input
    255     # Reserve a byte
    256     00
    257 
    258 #:ELF_end