Skip to content

Commit

Permalink
Elf tests (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbirddog authored Jun 16, 2024
1 parent 145c0db commit ea894ef
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 46 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/makefile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Default target
run: make
run: make

- name: Run tests
run: make tests
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
blue
a.out
*.out

elf_test
elf_test_hello_world
19 changes: 12 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MY_GROUP := $(shell id -g)
ME := $(MY_USER):$(MY_GROUP)

BLUE := blue
DEMO := demo
WHAT ?= $(BLUE)

DEV_CONTAINER ?= $(BLUE)-dev
DEV_DOCKER_FILE ?= dev.Dockerfile
Expand All @@ -27,18 +27,23 @@ dev-stop:
docker rm -f $(DEV_CONTAINER) || true

compile:
$(IN_DEV_CONTAINER) $(FASM) $(BLUE).asm $(BLUE)
$(IN_DEV_CONTAINER) $(FASM) $(WHAT).asm $(WHAT) && chmod +x $(WHAT)

start:
$(IN_DEV_CONTAINER) ./$(BLUE)
run:
$(IN_DEV_CONTAINER) ./$(WHAT)

dis:
$(DISASM) a.out

watch:
watch -d make compile start
watch -d make compile run

watch-tests:
watch -d make tests

.PHONY:
dev-env dev-start dev-stop \
compile start dis \
watch
compile run dis \
watch watch-tests

include test.mk
41 changes: 6 additions & 35 deletions blue.asm
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
format elf64 executable 3

include "linux.inc"
include "elf.inc"

;
; compiler entry point
;

segment readable writeable

;
Expand Down Expand Up @@ -38,16 +35,7 @@ output_file:
db "a.out"
db 0x00

SYS_WRITE = 1
SYS_OPEN = 2
SYS_CLOSE = 3
SYS_EXIT = 60

entry $
mov eax, program_code.entry_offset
mov ecx, program_code.length
call elf_binary_calculate_fields
entry $
;
; write the output to ./a.out
;
Expand All @@ -58,27 +46,10 @@ entry $
syscall

mov rdi, rax

mov rsi, elf_binary_headers
mov rdx, elf_binary_headers_length
mov eax, SYS_WRITE
syscall

mov rsi, program_code
mov rdx, program_code.length
mov eax, SYS_WRITE
syscall

mov rsi, shstrtab
mov rdx, shstrtab.length
mov eax, SYS_WRITE
syscall

mov rsi, elf_binary_section_headers
mov rdx, elf_binary_section_headers_length
mov eax, SYS_WRITE
syscall

mov eax, program_code.entry_offset
mov ecx, program_code.length
call elf_binary_write
mov eax, SYS_CLOSE
syscall

Expand Down
39 changes: 38 additions & 1 deletion elf.inc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ program_header:
dq elf_binary.base_address ; load position in virtual memory
dq elf_binary.base_address ; load position in physical memory
.sizes:
.size_in_file:
dq -0x01 ; size of the loaded section (file)
.size_in_memory:
dq -0x01 ; size of the loaded section (memory)
dq 0x200000 ; alignment boundary for sections

Expand Down Expand Up @@ -102,6 +104,7 @@ shstrtab_section_header:
elf_binary_length = $ - elf_binary
elf_binary_headers_length = elf_header.length + program_header.length
elf_binary_section_headers_length = elf_binary_length - elf_binary_section_headers
elf_binary_section_headers_offset = elf_binary_section_headers - elf_binary

segment readable executable

Expand Down Expand Up @@ -136,7 +139,41 @@ elf_binary_calculate_fields:
mov eax, shstrtab.length
stosq

add ecx, elf_header.length + program_header.length
add ecx, elf_binary_section_headers_offset
mov qword [elf_header.section_header_offset], rcx

ret
;
; expects
; - program code entry offset in eax
; - program code length in ecx
; - file descriptor in edi
;
elf_binary_write:
push rdi
call elf_binary_calculate_fields
pop rdi

mov rsi, elf_binary_headers
mov rdx, elf_binary_headers_length
mov eax, SYS_WRITE
syscall

mov rsi, program_code
mov rdx, program_code.length
mov eax, SYS_WRITE
syscall

mov rsi, shstrtab
mov rdx, shstrtab.length
mov eax, SYS_WRITE
syscall

mov rsi, elf_binary_section_headers
mov rdx, elf_binary_section_headers_length
mov eax, SYS_WRITE
syscall

ret

79 changes: 79 additions & 0 deletions elf_test.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
format elf64 executable 3

include "linux.inc"
include "elf.inc"

segment readable writeable

program_code:
.entry_offset = $ - program_code
db 0x48, 0xc7, 0xc0 ; mov rax, 1 - sys_write
dd 0x01
db 0x48, 0xc7, 0xc7 ; mov rdi, 1 - stdout fd
dd 0x01
db 0x48, 0xc7, 0xc6 ; mov rsi, 0x4000a2 - location of string
dd 0x4000a2
db 0x48, 0xc7, 0xc2 ; mov rdx, 13 - size of string
dd 0x0d
db 0x0f, 0x05 ; syscall
db 0x48, 0xc7, 0xc0 ; mov rax, 60 - sys_exit
dd 0x3c
db 0x48, 0x31, 0xff ; xor rdi, rdi
db 0x0f, 0x05 ; syscall

db "Hello, world"
db 0x0a, 0x00

.length = $ - program_code

segment readable executable

entry $
mov eax, program_code.entry_offset
mov ecx, program_code.length
call elf_binary_calculate_fields

mov edi, 1
cmp qword [elf_header.start_address], 0x400078
jne exit

mov edi, 2
cmp qword [elf_header.section_header_offset], 0xc0
jne exit

mov edi, 3
cmp qword [program_header.size_in_file], 0xb0
jne exit

mov edi, 4
cmp qword [program_header.size_in_memory], 0xb0
jne exit

mov edi, 5
cmp qword [program_code_section_header.address], 0x400078
jne exit

mov edi, 6
cmp qword [program_code_section_header.offset], 0x78
jne exit

mov edi, 7
cmp qword [program_code_section_header.size], 0x38
jne exit

mov edi, 8
cmp qword [shstrtab_section_header.offset], 0xb0
jne exit

mov edi, 9
cmp qword [shstrtab_section_header.size], 0x10
jne exit

;
; exit cleanly
;
xor edi, edi

exit:
mov eax, SYS_EXIT
syscall
58 changes: 58 additions & 0 deletions elf_test_hello_world.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
format elf64 executable 3

include "linux.inc"
include "elf.inc"

segment readable writeable

program_code:
.entry_offset = $ - program_code
db 0x48, 0xc7, 0xc0 ; mov rax, 1 - sys_write
dd 0x01
db 0x48, 0xc7, 0xc7 ; mov rdi, 1 - stdout fd
dd 0x01
db 0x48, 0xc7, 0xc6 ; mov rsi, 0x4000a2 - location of string
dd 0x4000a2
db 0x48, 0xc7, 0xc2 ; mov rdx, 13 - size of string
dd 0x0d
db 0x0f, 0x05 ; syscall
db 0x48, 0xc7, 0xc0 ; mov rax, 60 - sys_exit
dd 0x3c
db 0x48, 0x31, 0xff ; xor rdi, rdi
db 0x0f, 0x05 ; syscall

db "Hello, world"
db 0x0a, 0x00

.length = $ - program_code

segment readable executable

output_file:
db "elf_test_hello_world.out"
db 0x00

execve_args:
dq output_file
dq 0x0

entry $
mov rdi, output_file
mov esi, 0x01 or 0x40 or 0x200
mov edx, 0x1ed
mov eax, SYS_OPEN
syscall

mov rdi, rax
mov eax, program_code.entry_offset
mov ecx, program_code.length
call elf_binary_write
mov eax, SYS_CLOSE
syscall

mov rdi, output_file
mov rsi, execve_args
xor rdx, rdx
mov eax, SYS_EXECVE
syscall
6 changes: 6 additions & 0 deletions linux.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

SYS_WRITE = 1
SYS_OPEN = 2
SYS_CLOSE = 3
SYS_EXECVE = 59
SYS_EXIT = 60
12 changes: 12 additions & 0 deletions test.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

TESTS := \
elf_test \
elf_test_hello_world

$(TESTS):
echo "Testing $@... " && make WHAT=$@ compile run && echo ""

tests: $(TESTS)
@/bin/true

.PHONY: tests $(TESTS)

0 comments on commit ea894ef

Please sign in to comment.