commit 32d51f29db633b2948f81517bfbc1932264ee336
parent 12e4c5b931f4a7a0b6458aa5143fb476d828a5ef
Author: mehdi-norouzi <mehdeenoroozi@gmail.com>
Date: Tue, 5 Nov 2024 15:25:27 +0330
elfer: create hello world
Diffstat:
3 files changed, 291 insertions(+), 0 deletions(-)
diff --git a/elfer/build.sh b/elfer/build.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+mkdir -p ./bin
+as --64 -g -o ./bin/elf-struct.o ./elf-struct.s
+as --64 -g -o ./bin/elfer-hello.o ./elfer-hello.s &&
+ld -m elf_x86_64 ./bin/elfer-hello.o ./bin/elf-struct.o -o ./bin/elfer-hello.elf
+ctags -R .
diff --git a/elfer/elf-struct.s b/elfer/elf-struct.s
@@ -0,0 +1,109 @@
+# --------------------- CONSTANTS ------------------------- #
+
+ #---------- ELF header ------------ #
+.set elf_header_size, 0x40
+ .set eh_idx_ident, 0x0
+ .set eh_idx_type, 0x10
+ .set eh_idx_machine, 0x12
+ .set eh_idx_version, 0x14
+ .set eh_idx_entry, 0x18
+ .set eh_idx_phoff, 0x20
+ .set eh_idx_shoff, 0x28
+ .set eh_idx_flags, 0x30
+ .set eh_idx_ehsize, 0x34
+ .set eh_idx_phentsize, 0x36
+ .set eh_idx_phnum, 0x38
+ .set eh_idx_shentsize, 0x3A
+ .set eh_idx_shnum, 0x3C
+ .set eh_idx_shstrndx, 0x3E
+
+.set eh_idnet_size, 0x10
+ .set ei_idx_mag0, 0x0
+ .set ei_val_mag0, 0x7F
+ .set ei_idx_mag1, 0x1
+ .set ei_val_mag1, 'E'
+ .set ei_idx_mag2, 0x2
+ .set ei_val_mag2, 'L'
+ .set ei_idx_mag3, 0x3
+ .set ei_val_mag3, 'F'
+ .set ei_idx_class, 0x4
+ .set ei_val_class_none, 0x0
+ .set ei_val_class_32, 0x1
+ .set ei_val_class_64, 0x2
+ .set ei_idx_data, 0x5
+ .set ei_val_data_none, 0x0
+ .set ei_val_data_lsb, 0x1 # little endian
+ .set ei_val_data_msb, 0x2 # big endian
+ .set ei_idx_version, 0x6
+
+.set eh_type_size, 0x2
+ .set et_val_none, 0x0
+ .set et_val_rel, 0x1
+ .set et_val_exec, 0x2
+ .set et_val_dyn, 0x3
+ .set et_val_core, 0x4
+ .set et_val_loproc, 0xFF00
+ .set et_val_hiproc, 0xFFFF
+
+.set eh_machine_size, 0x2
+ .set em_val_none, 0x0
+ .set em_val_m32, 0x1
+ .set em_val_sparc, 0x2
+ .set em_val_386, 0x3
+ .set em_val_68k, 0x4
+ .set em_val_88k, 0x5
+ .set em_val_860, 0x7
+ .set em_val_mips, 0x8
+ .set em_val_mips_rs4_be, 0xA
+ .set em_val_x8664, 0x3E
+
+.set eh_version_size, 0x4
+ .set ev_val_none, 0x0
+ .set ev_val_current, 0x1
+
+.set eh_entry_size, 0x8
+.set eh_phoff_size, 0x8
+.set eh_shoff_size, 0x8
+.set eh_flags_size, 0x4
+.set eh_ehsize_size, 0x2
+.set eh_phentsize_size, 0x2
+.set eh_phnum_size, 0x2
+.set eh_shentsize_size, 0x2
+.set eh_shnum_size, 0x2
+.set eh_shstrndx_size, 0x2
+
+.set ei_mag0_idx, 0x0
+.set ei_mag1_idx, 0x1
+.set ei_mag2_idx, 0x2
+.set ei_mag3_idx, 0x3
+.set ei_class_idx, 0x4
+.set ei_data_idx, 0x5
+.set ei_version_idx, 0x6
+
+ #---------- Program header ------------ #
+.set p_header_size, 0x38
+ .set ph_idx_type, 0x0
+ .set pt_val_null, 0x0
+ .set pt_val_load, 0x1
+ .set pt_val_dynamic, 0x2
+ .set pt_val_interp, 0x3
+ .set pt_val_note, 0x4
+ .set pt_val_shlib, 0x5
+ .set pt_val_phdr, 0x6
+ .set pt_val_loproc, 0x70000000
+ .set pt_val_hiproc, 0x7fffffff
+ .set ph_idx_flags, 0x4
+ .set ph_idx_offset, 0x8
+ .set ph_idx_vaddr, 0x10
+ .set ph_idx_paddr, 0x18
+ .set ph_idx_filesz, 0x20
+ .set ph_idx_memsz, 0x28
+ .set ph_idx_align, 0x30
+
+.data
+.bss
+elf_header:
+ .space elf_header_size
+program_header:
+ .space p_header_size
+
diff --git a/elfer/elfer-hello.s b/elfer/elfer-hello.s
@@ -0,0 +1,176 @@
+# --------------------- CONSTANTS ------------------------- #
+
+.set SYSCALL_READ, 0
+.set SYSCALL_WRITE, 1
+.set SYSCALL_OPEN, 2
+.set SYSCALL_CLOSE, 3
+.set SYSCALL_EXIT, 60
+.set SYSCALL_GETRLIMIT, 97
+
+.set FLAG_O_CREAT_RDWR, 0x42 # O_RDWR | O_CREAT
+.set FILE_MODE, 0x1ED # rwxr-xr-x
+
+.set STDIN, 0
+.set STDOUT, 1
+.set STDERR, 2
+
+.include "./elf-struct.s"
+
+
+# --------------------- DATA ------------------------- #
+.data
+
+file_path:
+ .asciz "./bin/hello.elf"
+
+machine_code:
+ .byte 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00
+ .byte 0xc7, 0xc7, 0x01, 0x00, 0x00, 0x00
+ .byte 0xc7, 0xc6, 0xf0, 0x00, 0x60, 0x00
+ .byte 0xc7, 0xc2, 0x10, 0x00, 0x00, 0x00
+ .byte 0x0f, 0x05
+ .byte 0xc7, 0xc7, 0x00, 0x00, 0x00, 0x00
+ .byte 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00
+ .byte 0x0f, 0x05
+machine_code_sz = . - machine_code
+
+padding_8b:
+ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+msg:
+ .asciz "hello, world\n"
+msg_len = . - msg
+
+
+
+.bss
+ph_array:
+ .space 2*p_header_size
+
+# --------------------- CODE ------------------------- #
+ .global _start
+
+.text
+
+_start:
+
+ mov $file_path, %rdi
+ mov $FLAG_O_CREAT_RDWR, %rsi
+ mov $FILE_MODE, %rdx
+ mov $SYSCALL_OPEN, %rax
+ syscall
+
+ # -------------- ELF header ---------#
+ lea elf_header, %r8
+ lea eh_idx_ident(%r8), %r9
+ movb $0x7F, ei_idx_mag0(%r9)
+ movb $0x45, ei_idx_mag1(%r9)
+ movb $0x4C, ei_idx_mag2(%r9)
+ movb $0x46, ei_idx_mag3(%r9)
+ movb $ei_val_class_64, ei_idx_class(%r9)
+ movb $ei_val_data_lsb, ei_idx_data(%r9)
+ movb $ev_val_current, ei_idx_version(%r9)
+
+ lea eh_idx_type(%r8), %r9
+ movw $et_val_exec, (%r9)
+
+ lea eh_idx_machine(%r8), %r9
+ movw $em_val_x8664, (%r9)
+
+ lea eh_idx_version(%r8), %r9
+ movl $ev_val_current, (%r9)
+
+ lea eh_idx_entry(%r8), %r9
+ movq $0x4000B0, (%r9)
+
+ lea eh_idx_phoff(%r8), %r9
+ movq $0x40, (%r9)
+
+ lea eh_idx_ehsize(%r8), %r9
+ movw $0x40, (%r9)
+
+ lea eh_idx_phentsize(%r8), %r9
+ movw $0x38, (%r9)
+
+ lea eh_idx_phnum(%r8), %r9
+ movw $0x2, (%r9)
+
+ # -------- Program header 1: code -------#
+ lea ph_array, %r8
+ lea ph_idx_type(%r8), %r9
+ movl $pt_val_load, (%r9)
+
+ lea ph_idx_flags(%r8), %r9
+ movl $0x5, (%r9)
+
+ lea ph_idx_vaddr(%r8), %r9
+ movq $0x400000, (%r9)
+
+ lea ph_idx_filesz(%r8), %r9
+ movq $0xE8, (%r9)
+
+ lea ph_idx_memsz(%r8), %r9
+ movq $0xE8, (%r9)
+
+ lea ph_idx_align(%r8), %r9
+ movq $0x1000, (%r9)
+
+ # -------- Program header 2: read-only data -------#
+ lea ph_array + p_header_size, %r8
+ lea ph_idx_type(%r8), %r9
+ movl $pt_val_load, (%r9)
+
+ lea ph_idx_flags(%r8), %r9
+ movl $0x4, (%r9)
+
+ lea ph_idx_vaddr(%r8), %r9
+ movq $0x600000, (%r9)
+
+ lea ph_idx_filesz(%r8), %r9
+ movq $0x1000, (%r9)
+
+ lea ph_idx_memsz(%r8), %r9
+ movq $0x1000, (%r9)
+
+ lea ph_idx_align(%r8), %r9
+ movq $0x1000, (%r9)
+ # write elf_header to the file
+ mov %rax, %rdi
+ lea elf_header, %rsi
+ mov $elf_header_size, %rdx
+ mov $SYSCALL_WRITE, %rax
+ syscall
+
+ # write program header 1 to the file
+ lea ph_array, %rsi
+ mov $p_header_size, %rdx
+ mov $SYSCALL_WRITE, %rax
+ syscall
+
+ # write program header 2 to the file
+ lea ph_array+p_header_size, %rsi
+ mov $p_header_size, %rdx
+ mov $SYSCALL_WRITE, %rax
+ syscall
+
+ # write machine code to the file
+ lea machine_code, %rsi
+ mov $machine_code_sz, %rdx
+ mov $SYSCALL_WRITE, %rax
+ syscall
+
+ # write padding
+ lea padding_8b, %rsi
+ mov $8, %rdx
+ mov $SYSCALL_WRITE, %rax
+ syscall
+
+ # write msg string to the file
+ lea msg, %rsi
+ mov $msg_len, %rdx
+ mov $SYSCALL_WRITE, %rax
+ syscall
+
+ xor %rdi, %rdi
+ mov $SYSCALL_EXIT, %rax
+ syscall