diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/run.scm | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/tests/run.scm b/tests/run.scm new file mode 100644 index 0000000..fc7c3d6 --- /dev/null +++ b/tests/run.scm @@ -0,0 +1,92 @@ +(use test matchable) + +(include "../bpf-assembler.scm") + +(import bpf-assembler) + +(test-begin "BPF assembler") + +(test-group "single instruction assembly/disassembly invariance" + (for-each (lambda (expr) + (test (->string expr) + expr + (car (bpf-bytecode->exprs + (exprs->bpf-bytecode (list expr)))))) + `(;; load word into accumulator register + (ld len) (ld 1) (ld (mem 1)) (ld (pkt 1)) (ld (pkt x 1)) + ;; load byte/halfword into accumulator register + (ldb (pkt 1)) (ldb (pkt x 1)) (ldh (pkt 1)) (ldh (pkt x 1)) + ;; load index register + (ldx len) (ldx 1) (ldx (mem 1)) (ldx (pkt 4* 1)) + ;; store accumulator/index register + (st (mem 1)) (stx (mem 1)) + ;; jump unconditionally (sometimes called JA instead of JMP) + (jmp 1) + ;; Jump conditionally on comparison of acc w/ immediate or idx + (jeq 1 2 3) (jeq x 2 3) (jgt 1 2 3) (jgt x 2 3) + (jge 1 2 3) (jge x 2 3) + ;; Jump if bit # from immediate/index register is set in acc + (jset 1 2 3) (jset x 2 3) + ;; ALU instructions: operates on acc w/ immediate or index + (add 1) (add x) (sub 1) (sub x) (mul 1) (mul x) (div 1) (div x) + (or 1) (or x) (and 1) (and x) (lsh 1) (lsh x) (rsh 1) (rsh x) + ;; Negate accumulator (no operands) + (neg) + ;; Return # of bytes in acc or idx registers or immediate + (ret 1) (ret a) (ret x) + ;; Transfer value between accumulator and index + (tax) (txa)))) + +(test-group "Invalid opcode/addressing mode combinations" + (for-each (match-lambda + ((subgroup-name exprs ...) + (test-group subgroup-name + (for-each (lambda (expr) + (test-error + (->string expr) + (car (bpf-bytecode->exprs + (exprs->bpf-bytecode (list expr)))))) + exprs)))) + `(("load of word into accumulator from invalid types" + (ld x) (ld a) (ld (pkt 4* 1))) + ("load of halfword into accumulator from invalid types" + (ldh len) (ldh x) (ldh a) (ldh (pkt 4* 1))) + ("load of byte into accumulator from invalid types" + (ldb len) (ldb x) (ldb a) (ldb (pkt 4* 1))) + ("load of word into index from invalid types" + (ldx (pkt 1)) (ldx a) (ldx x) (ldx (pkt 1)) (ldx (pkt x 1))) + + ("store of accumulator into memory must be immediate memory index" + (st 1) (st len) (st a) (st x) (st (mem x 1)) + (st (pkt 1)) (st (pkt 4* 1))) + ("store of index into memory must be immediate memory index" + (stx 1) (stx len) (stx a) (stx x) (stx (mem x 1)) + (stx (pkt 1)) (stx (pkt 4* 1))) + + ("bogus jump types" + (jmp x) (jmp a) (jmp (mem 1)) (jmp len)) + + ("unconditional jumps can't work conditionally" + (jmp 1 2 3) (jmp x 2 3)) + + ("bogus unconditional jumps" + (jmp (mem 1) 2 3) (jmp len 2 3) (jmp a 2 3)) + + ("conditional jumps can't work unconditionally" + (jeq 1) (jeq x) (jgt 1) (jgt x) (jge 1) (jge x) (jset 1) (jset x)) + + ;; Only test add, the rest are defined identically + ("diadic ALU instructions with disallowed operands" + (add a) (add (mem 1)) (add (pkt 1)) (add (pkt x 1)) (add (pkt 4* 1))) + + ("monadic instructions with operands" + (neg 1) (neg x) (neg a) (neg (mem 1)) + ;; Only do txa, tax is defined identically + (txa 1) (txa x) (txa a) (txa (mem 1))) + + ("returning non-immediate, non-register values" + (ret (mem 1)) (ret (pkt 1)) (ret (pkt x 1)) (ret (pkt 4* 1)))))) + +(test-end "BPF assembler") + +(test-exit) |