summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/run.scm92
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)