diff --git a/test/Makefile b/test/Makefile index fdc3eb3..06dd47e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,19 +1,25 @@ -CC=afl-cc -LD=afl-cc - BIN=../bin -.PHONY: all masm mld msim +ASM = $(shell find ./masm -type f -name "*.asm") +OBJ = $(patsubst ./masm/%.asm,./mld/%.o,$(ASM)) +ELF = $(patsubst ./mld/%.o,./msim/%,$(OBJ)) +TEST = $(patsubst ./msim/%,%,$(ELF)) -all: masm mld msim +.PHONY: build clean -masm: - make -C ../masm clean build CC=$(CC) LD=$(LD) - $(BIN)/masm/masm -o ./mld/test.o ./masm/test.asm +build: $(TEST) -mld: - make -C ../mld clean build CC=$(CC) LD=$(LD) - $(BIN)/mld/mld -o ./msim/test ./mld/test.o +clean: + rm -fr ./mld + rm -fr ./msim -msim: - make -C ../msim clean build CC=$(CC) LD=$(LD) +$(OBJ): ./mld/%.o : ./masm/%.asm + @mkdir -p $(@D) + $(BIN)/masm/masm -o $@ $< + +$(ELF): ./msim/% : ./mld/%.o ../lib/runtime.asm + @mkdir -p $(@D) + $(BIN)/mld/mld -o $@ $< + +$(TEST): % : ./msim/% + ../tools/test.sh $@ diff --git a/test/a.out b/test/a.out deleted file mode 100755 index 075ddb6..0000000 Binary files a/test/a.out and /dev/null differ diff --git a/test/masm/div.asm b/test/masm/div.asm new file mode 100644 index 0000000..b9b4f3f --- /dev/null +++ b/test/masm/div.asm @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Freya Murphy + +# file: div.asm +# test: should cause floting point exception + +.text +.align 2 +.globl main + +main: + # divide by zero + li $t0, 0 + div $t0, $t0, $t0 + + # return + li $v0, 0 + jr $ra diff --git a/test/masm/fault.asm b/test/masm/fault.asm new file mode 100644 index 0000000..df700cf --- /dev/null +++ b/test/masm/fault.asm @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Freya Murphy + +# file: div.asm +# test: should cause page fault + +.text +.align 2 +.globl main + +main: + lw $t0, 0($zero) + + # return + li $v0, 0 + jr $ra diff --git a/test/masm/fncall.asm b/test/masm/fncall.asm new file mode 100644 index 0000000..96d1ba2 --- /dev/null +++ b/test/masm/fncall.asm @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Freya Murphy + +# file: fncall.asm +# test: should return value from function call + +.text +.align 2 +.globl main + +result: + move $t0, $a0 + move $v0, $t0 + jr $ra + +main: + # save ra on stack + addi $sp, $sp, -4 + sw $ra, 0($sp) + + # set return to 17 + li $a0, 17 + jal result + + # pop ra from stack + lw $ra, 0($sp) + addi $sp, $sp, 4 + + # return result + jr $ra diff --git a/test/masm/hello.asm b/test/masm/hello.asm new file mode 100644 index 0000000..2d64ae5 --- /dev/null +++ b/test/masm/hello.asm @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Freya Murphy + +# file: div.asm +# test: should print hello world + +.data +.align 1 + +hw: + .asciiz "Hello, world!\n" + +.text +.align 2 +.globl main + +main: + # print hello world + li $v0, 1 + li $a0, 1 # stdout + la $a1, hw # load string + li $a2, 14 # load length + syscall + + # return 1 + li $v0, 0 + jr $ra diff --git a/test/masm/test.asm b/test/masm/test.asm deleted file mode 100644 index b099c2e..0000000 --- a/test/masm/test.asm +++ /dev/null @@ -1,242 +0,0 @@ -# Copyright (c) 2024 Freya Murphy - -.data -.align 2 - -heap_start: - .space 4 -heap_len: - .space 4 -heap_free: - .space 4 -heap_ptr: - .space 4 - -null: - .space 4 - -.text -.align 2 -.globl main - -# init the heap -heap_init: - # sbrk(0) - li $v0, 9 - li $a0, 0 - syscall - sw $v0, heap_start - sw $v1, heap_len - - # heap is empty, ptr at start - sw $v0, heap_ptr - # heap is empty, size = len - sw $v1, heap_free - - jr $ra - - - -# $a0 : amount of bytes to increase -heap_increase: - # t0 : OLD heap len + 1 - # t1 : heap ptr - # t2 : heap end - # t2 : heap free - # t3 : a0 - - # save current length - lw $t0, heap_len - - # save a0 - move $t3, $a0 - - # sbrk(amt) - li $v0, 9 - syscall - # sbrk(0) - li $v0, 9 - li $a0, 0 - syscall - sw $v0, heap_start - sw $v1, heap_len - - lw $t1, heap_ptr # heap ptr - add $t2, $v0, $v1 # heap end - sub $t3, $t2, $t1 # heap free - sw $t3, heap_free - - # set return code to 1 if fail to allocate - # i.e. $v1 = $t0 or ($v1 < $t0 + 1) - # i.e. heap size hasen't changed - addi $t0, $t0, 1 - slt $v0, $v1, $t0 - jr $ra - - - -# $a0 : amount of bytes to allocate -malloc: - # t0 : heap free + 1 - # t1 : if enough mem is free - # t2 : alloc size [(a0 align 4) + 4096 + 4] - # t3 : temp for heap_ptr - # t7 : alloc amt (a0 align 4) + 4 - # t8 : temp for modulo - - # save $a0 - move $t7, $a0 - addi $t7, $t7, 4 # add 4 bytes to save INTERAL ptr size - - # align $t7 by 4 - # allows us to use lw and sw in realloc - li $t8, 4 - div $t8, $t7, $t8 - mfhi $t8 - beq $t8, $zero, malloc_aligned - addi $t7, $t7, 4 - sub $t7, $t7, $t8 - -malloc_aligned: - # check if we have enough memory free - lw $t0, heap_free - addi $t0, $t0, 1 - slt $t1, $t7, $t0 - bne $t1, $zero, malloc_hasmem - - # set needed mem to alloc - # page size + alloc request - - # save $ra and $t7 - addi $sp, $sp, -8 - sw $ra, 0($sp) - sw $t7, 4($sp) - - li $t2, 4096 - add $t2, $t2, $t7 - move $a0, $t2 - jal heap_increase - - # pop $ra and $t7 - lw $ra, 0($sp) - lw $t7, 4($sp) - addi $sp, $sp, 8 - - # check heap_increase return code - beq $v0, $zero, malloc_hasmem - -malloc_error: - # failed to sbrk, return null - la $v0, null - jr $ra - -malloc_hasmem: - # set return value, and save ptr size in it - # add 4 to return ptr, since first 4 bytes are INTERNAL - addi $t3, $t7, -4 - lw $v0, heap_ptr - sw $t3, ($v0) - addi $v0, $v0, 4 - - lw $t3, heap_ptr - add $t3, $t3, $t7 # increase ptr by alloc size - sw $t3, heap_ptr - - jr $ra - - - -# $a0 : address of ptr -free: - # haha hehe hoho - jr $ra - - - -# $a0 : new size -# $a1 : old ptr -realloc: - # t0 : old ptr size - # t2 : new ptr addr - - # check if $a0 is zero, if so then just free - bne $a0, $zero, realloc_inner - move $a0, $a1 - la $v0, null - j free - - # save to stack - addi $sp, $sp, -12 - sw $ra, 0($sp) - sw $a0, 4($sp) - sw $a1, 8($sp) - - jal malloc - - # pop to stack - lw $ra, 0($sp) - lw $a0, 4($sp) - lw $a1, 8($sp) - addi $sp, $sp, 12 - -realloc_inner: - addi $a1, $a1, -4 - lw $t0, ($a1) - addi $a1, $a1, 4 - -realloc_loop: - # loop until $t0 or $t1 is zero - beq $t0, $zero, realloc_end - beq $a0, $zero, realloc_end - - addi $a1, $a1, 4 - addi $t0, $t0, -4 - addi $a0, $a0, -4 - #lw $t3, - - j realloc_loop - -realloc_end: - - -realloc_free: - jr $ra - - -main: - # push return address - addi $sp, $sp, -4 - sw $ra, ($sp) - - jal heap_init - - li $a0, 24 - jal malloc - - move $a0, $v0 - li $v0, 1 - syscall - - li $v0, 11 - li $a0, 10 - syscall - - li $a0, 24 - jal malloc - - move $a0, $v0 - li $v0, 1 - syscall - - li $v0, 11 - li $a0, 10 - syscall - - # pop return address - lw $ra, ($sp) - addi $sp, $sp, 4 - -exit: - # exit with code 0 - li $v0, 0 - jr $ra diff --git a/test/mld/test.o b/test/mld/div.o similarity index 63% rename from test/mld/test.o rename to test/mld/div.o index 28af663..0ec84f2 100644 Binary files a/test/mld/test.o and b/test/mld/div.o differ diff --git a/test/mld/fault.o b/test/mld/fault.o new file mode 100644 index 0000000..fb48c85 Binary files /dev/null and b/test/mld/fault.o differ diff --git a/test/mld/fncall.o b/test/mld/fncall.o new file mode 100644 index 0000000..76732db Binary files /dev/null and b/test/mld/fncall.o differ diff --git a/test/mld/hello.o b/test/mld/hello.o new file mode 100644 index 0000000..ed85643 Binary files /dev/null and b/test/mld/hello.o differ diff --git a/test/msim/div b/test/msim/div new file mode 100755 index 0000000..de72052 Binary files /dev/null and b/test/msim/div differ diff --git a/test/msim/fault b/test/msim/fault new file mode 100755 index 0000000..d1f5e0b Binary files /dev/null and b/test/msim/fault differ diff --git a/test/msim/fncall b/test/msim/fncall new file mode 100755 index 0000000..7060b14 Binary files /dev/null and b/test/msim/fncall differ diff --git a/test/msim/test b/test/msim/hello similarity index 91% rename from test/msim/test rename to test/msim/hello index f53e634..02a3aa9 100755 Binary files a/test/msim/test and b/test/msim/hello differ diff --git a/test/out/div b/test/out/div new file mode 100644 index 0000000..94b9ab8 --- /dev/null +++ b/test/out/div @@ -0,0 +1,15 @@ + + !!! An exception has occurred !!! + +error: floating point exception +pc: 0x00400004 +ins: 0x0108409a +registers: +$zero: 0x00000000 $t0: 0x00000000 $s0: 0x00000000 $t8: 0x00000000 +$at: 0x00000000 $t1: 0x00000000 $s1: 0x00000000 $t9: 0x00000000 +$v0: 0x00000000 $t2: 0x00000000 $s2: 0x00000000 $k0: 0x00000000 +$v1: 0x00000000 $t3: 0x00000000 $s3: 0x00000000 $k1: 0x00000000 +$a0: 0x00000000 $t4: 0x00000000 $s4: 0x00000000 $gp: 0x00000000 +$a1: 0x00000000 $t5: 0x00000000 $s5: 0x00000000 $sp: 0x10001000 +$a2: 0x00000000 $t6: 0x00000000 $s6: 0x00000000 $fp: 0x00000000 +$a3: 0x00000000 $t7: 0x00000000 $s7: 0x00000000 $ra: 0x0040001c diff --git a/test/out/div.status b/test/out/div.status new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/test/out/div.status @@ -0,0 +1 @@ +1 diff --git a/test/out/fault b/test/out/fault new file mode 100644 index 0000000..938bb46 --- /dev/null +++ b/test/out/fault @@ -0,0 +1,15 @@ + + !!! An exception has occurred !!! + +error: page fault at (nil): address not mapped to object +pc: 0x00400000 +ins: 0x8c080000 +registers: +$zero: 0x00000000 $t0: 0x00000000 $s0: 0x00000000 $t8: 0x00000000 +$at: 0x00000000 $t1: 0x00000000 $s1: 0x00000000 $t9: 0x00000000 +$v0: 0x00000000 $t2: 0x00000000 $s2: 0x00000000 $k0: 0x00000000 +$v1: 0x00000000 $t3: 0x00000000 $s3: 0x00000000 $k1: 0x00000000 +$a0: 0x00000000 $t4: 0x00000000 $s4: 0x00000000 $gp: 0x00000000 +$a1: 0x00000000 $t5: 0x00000000 $s5: 0x00000000 $sp: 0x10001000 +$a2: 0x00000000 $t6: 0x00000000 $s6: 0x00000000 $fp: 0x00000000 +$a3: 0x00000000 $t7: 0x00000000 $s7: 0x00000000 $ra: 0x00400018 diff --git a/test/out/fault.status b/test/out/fault.status new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/test/out/fault.status @@ -0,0 +1 @@ +1 diff --git a/test/out/fncall b/test/out/fncall new file mode 100644 index 0000000..e69de29 diff --git a/test/out/fncall.status b/test/out/fncall.status new file mode 100644 index 0000000..98d9bcb --- /dev/null +++ b/test/out/fncall.status @@ -0,0 +1 @@ +17 diff --git a/test/out/hello b/test/out/hello new file mode 100644 index 0000000..af5626b --- /dev/null +++ b/test/out/hello @@ -0,0 +1 @@ +Hello, world! diff --git a/test/out/hello.status b/test/out/hello.status new file mode 100644 index 0000000..573541a --- /dev/null +++ b/test/out/hello.status @@ -0,0 +1 @@ +0 diff --git a/tools/test.sh b/tools/test.sh new file mode 100755 index 0000000..2dcbf6a --- /dev/null +++ b/tools/test.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# +# tests a binary +# against a output and an exit code +# + +dir="$(dirname "$0")" + +msim="$dir/../bin/msim/msim" +bin="$dir/../test/msim/$1" + +out=$(cat "$dir/../test/out/$1") +status=$(cat "$dir/../test/out/$1.status") + +temp=$(mktemp) + +$msim $bin &> $temp + +rstatus="$?" +rout=$(cat $temp) +rm $temp + +res=0 + +if [ "$out" != "$rout" ]; then + res=1 +fi + +if [ "$status" != "$rstatus" ]; then + res=1 +fi + +if [ $res = 0 ]; then + printf "\033[32mPASSED\033[0m\n" +else + printf "\033[31mFAILED\033[0m\n" + diff <(echo $out) <(echo $rout) +fi + +exit $res