boot2

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

hex0.hex0 (6387B)


      1 # SPDX-FileCopyrightText: 2017 Jeremiah Orians <jeremiah@pdp10.guru>
      2 # SPDX-FileCopyrightText: 2023 Andrius Štikonas <andrius@stikonas.eu>
      3 #
      4 # SPDX-License-Identifier: GPL-3.0-or-later
      5 
      6 ## ELF Header
      7 #:ELF_base
      8 7F 45 4C 46        ## e_ident[EI_MAG0-3] ELF's magic number
      9 
     10 02                 ## e_ident[EI_CLASS] Indicating 64 bit
     11 01                 ## e_ident[EI_DATA] Indicating little endianness
     12 01                 ## e_ident[EI_VERSION] Indicating original elf
     13 
     14 03                 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
     15 00                 ## e_ident[EI_ABIVERSION] Set at 0 because none cares
     16 
     17 00 00 00 00 00 00 00 ## e_ident[EI_PAD]
     18 02 00              ## e_type Indicating Executable
     19 3E 00              ## e_machine Indicating AMD64
     20 01 00 00 00        ## e_version Indicating original elf
     21 
     22 78 00 60 00 00 00 00 00 ## e_entry Address of the entry point (Number of bytes this header is + Base Address)
     23 40 00 00 00 00 00 00 00 ## e_phoff Address of program header table
     24 00 00 00 00 00 00 00 00 ## e_shoff Address of section header table
     25 
     26 00 00 00 00        ## e_flags
     27 40 00              ## e_ehsize Indicating our 64 Byte header
     28 
     29 38 00              ## e_phentsize size of a program header table
     30 01 00              ## e_phnum number of entries in program table
     31 
     32 00 00              ## e_shentsize size of a section header table
     33 00 00              ## e_shnum number of entries in section table
     34 
     35 00 00              ## e_shstrndx index of the section names
     36 
     37 ## Program Header
     38 #:ELF_program_headers
     39 01 00 00 00             ## p_type
     40 01 00 00 00             ## p_flags: PF-X = 1
     41 00 00 00 00 00 00 00 00 ## p_offset
     42 
     43 00 00 60 00 00 00 00 00 ## p_vaddr
     44 00 00 60 00 00 00 00 00 ## p_physaddr
     45 
     46 E5 00 00 00 00 00 00 00 ## p_filesz
     47 E5 00 00 00 00 00 00 00 ## p_memsz
     48 
     49 01 00 00 00 00 00 00 00 ## Required alignment
     50 
     51 #:ELF_text
     52 
     53 # Where the ELF Header is going to hit
     54 # Simply jump to _start
     55 # Our main function
     56 #:_start (0x600078)
     57 	58                  ; pop_rax         # Get the number of arguments
     58 	5F                  ; pop_rdi         # Get the program name
     59 	5F                  ; pop_rdi         # Get the actual input name
     60 	31F6                ; xor_esi,esi     # prepare read_only, rsi = 0
     61 	6A 02               ; push !2         # prepare syscall number
     62 	58                  ; pop_rax         # the syscall number for open()
     63 	99                  ; cdq             # Extra sure, rdx = 0
     64 	0F05                ; syscall         # Now open that damn file
     65 	5F                  ; pop_rdi         # Get the actual output name
     66 	50                  ; push_rax        # Preserve the file pointer we were given
     67 	66BE 4102           ; mov_si, @577    # Prepare file as O_WRONLY|O_CREAT|O_TRUNC
     68 	66BA C001           ; mov_dx, @448    # Prepare file as RWX for owner only (700 in octal)
     69 	6A 02               ; push !2         # prepare syscall number
     70 	58                  ; pop_rax         # the syscall number for open()
     71 	0F05                ; syscall         # Now open that damn file
     72 	93                  ; xchg_ebx,eax    # Preserve the file pointer we were given
     73 	99                  ; cdq             # rdx = 0 since file descriptor is nonnegative
     74 	FFC2                ; inc_edx         # rdx = 1 (count for read/write)
     75 
     76 #:loop_reset_all (0x600096)
     77 	31ED                ; xor_ebp,ebp     # ebp = 0 (no prior hex val)
     78 
     79 # Comment tracking is done with ecx.
     80 # ecx is decremented if we hit a
     81 # comment (';' or '#') and reset
     82 # if we hit a new-line.
     83 #:loop_reset_comment (0x600098)
     84 	52                  ; push_rdx
     85 	59                  ; pop_rcx         # Set no current comment
     86 #:loop_add_comment (0x60009A)
     87 	FFC9                ; dec_ecx
     88 #:loop (0x60009C)
     89 
     90 	# Read a byte
     91 	5F                  ; pop_rdi         # Get infile
     92 	54                  ; push_rsp
     93 	5E                  ; pop_rsi         # Set buffer
     94 	# rdx is already set to 1.
     95 	31C0                ; xor_eax,eax     # Set read syscall in rax
     96 	51                  ; push_rcx        # Save comment tracking
     97 	0F05                ; syscall         # Do the actual read
     98 	59                  ; pop_rcx         # Restore comment tracking
     99 	57                  ; push_rdi        # Re-save infile
    100 	85C0                ; test_eax,eax    # Check what we got
    101 	75 06               ; jne !cont       # No EOF
    102 
    103 	# Exit successfully
    104 	B0 3C               ; mov_al, !60     # Set exit syscall in rax
    105 	31FF                ; xor_edi,edi     # Set return success (rdi = 0)
    106 	0F05                ; syscall         # Exit
    107 
    108 #:cont (0x6000B0)
    109 	8A06                ; mov_al,[rsi]    # Move prog byte in eax
    110 
    111 	# New line check
    112 	3C 0A               ; cmp_al, !10     # Check new-line
    113 	74 E2               ; je !loop_reset_comment # If new-line, end comment handling
    114 
    115 	# In comment check
    116 	85C9                ; test_ecx,ecx    # Skip byte if we are in a comment
    117 	75 E2               ; jne !loop
    118 
    119 	# Start comment check
    120 	3C 23               ; cmp_al, !35     # Start of '#' comment
    121 	74 DC               ; je !loop_add_comment
    122 
    123 	3C 3B               ; cmp_al, !59     # Start of ';' comment
    124 	74 D8               ; je !loop_add_comment
    125 
    126 	# Start of hex str to int
    127 	2C 30               ; sub_al, !48     # Subtract ascii '0' from al
    128 	2C 0A               ; sub_al, !10     # Check for value in '0'-'9'
    129 	72 08               ; jb !write       # We have hex value, write it
    130 
    131 	2C 07               ; sub_al, !7      # Subtract ('A'-'0') from al
    132 	24 DF               ; and_al, !0xDF   # Remove lower case bit
    133 	3C 07               ; cmp_al, !7      # Check for value 'A'-'F'
    134 	73 CC               ; jae !loop       # We have hex value, write it
    135 
    136 #:write (0x6000D0)
    137 	C1E5 04             ; shl_ebp, !4     # Shift up existing hex digit
    138 	04 0A               ; add_al, !10     # Finish converting ascii to raw value
    139 	01C5                ; add_ebp,eax     # Combine the hex digits
    140 
    141 	# Check if this is first digit in hex val
    142 	F7DB                ; neg_ebx         # Flip sign of r10 to indicate we got a digit
    143 	7C C1               ; jl !loop        # Negative -> first digit, get another one
    144 
    145 	# We have both digits in low byte of ebp, good to write
    146 	892E                ; mov_[rsi],ebp   # Move edge to buffer
    147 	89DF                ; mov_edi,ebx     # Move outfile to rdi
    148 	B0 01               ; mov_al, !1      # Set write syscall in rax
    149 	0F05                ; syscall         # Do the write
    150 	EB B1               ; jmp !loop_reset_all # Start a fresh byte
    151 
    152 #:ELF_end (0x6000E5)