// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause package verify import ( "bytes" "runtime" "testing" "unsafe" ) func loadBasic(t *testing.T) *Kernel { t.Helper() k, err := Load("../testdata/verify/basic_amd64.s") if err != nil { t.Fatalf("Load: %v", err) } t.Cleanup(k.Close) return k } func TestJITAdd(t *testing.T) { k := loadBasic(t) tests := []struct { a, b, want int64 }{ {0, 0, 0}, {1, 2, 3}, {-1, 1, 0}, {1 << 62, 1 << 62, -9223372036854775808}, // overflow wraps (MinInt64) {-100, -200, -300}, } for _, tt := range tests { args := make([]byte, 24) PutUint64(args, 0, uint64(tt.a)) PutUint64(args, 8, uint64(tt.b)) out, err := k.CallFunc("add", args) if err != nil { t.Fatalf("CallFunc(add, %d, %d): %v", tt.a, tt.b, err) } got := int64(GetUint64(out, 16)) if got != tt.want { t.Errorf("add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.want) } } } func TestJITSum(t *testing.T) { k := loadBasic(t) tests := []struct { data []int64 want int64 }{ {nil, 0}, {[]int64{1}, 1}, {[]int64{1, 2, 3, 4, 5}, 15}, {[]int64{-10, 20, -30, 40}, 20}, } for _, tt := range tests { args := make([]byte, 32) if len(tt.data) > 0 { PutPtr(args, 0, unsafe.Pointer(&tt.data[0])) } PutUint64(args, 8, uint64(len(tt.data))) PutUint64(args, 16, uint64(cap(tt.data))) out, err := k.CallFunc("sum", args) runtime.KeepAlive(tt.data) if err != nil { t.Fatalf("CallFunc(sum, %v): %v", tt.data, err) } got := int64(GetUint64(out, 24)) if got != tt.want { t.Errorf("sum(%v) = %d, want %d", tt.data, got, tt.want) } } } func TestJITWideCopy(t *testing.T) { k := loadBasic(t) tests := []struct { name string n int }{ {"empty", 0}, {"tiny", 7}, {"exact32", 32}, {"overlap_range", 48}, {"exact64", 64}, {"unaligned", 45}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { src := make([]byte, tt.n) for i := range src { src[i] = byte(i * 7) } dst := make([]byte, tt.n) args := make([]byte, 48) if tt.n > 0 { PutPtr(args, 0, unsafe.Pointer(&dst[0])) PutPtr(args, 24, unsafe.Pointer(&src[0])) } PutUint64(args, 8, uint64(tt.n)) // dst_len PutUint64(args, 16, uint64(tt.n)) // dst_cap PutUint64(args, 32, uint64(tt.n)) // src_len PutUint64(args, 40, uint64(tt.n)) // src_cap _, err := k.CallFunc("wideCopy", args) runtime.KeepAlive(dst) runtime.KeepAlive(src) if err != nil { t.Fatalf("CallFunc(wideCopy): %v", err) } if !bytes.Equal(dst, src) { t.Errorf("wideCopy: dst ≠ src\n got %x\n want %x", dst, src) } }) } } func TestKernelFuncNames(t *testing.T) { k := loadBasic(t) names := k.FuncNames() want := []string{"add", "sum", "wideCopy"} if len(names) != len(want) { t.Fatalf("FuncNames() = %v, want %v", names, want) } for i, n := range names { if n != want[i] { t.Errorf("FuncNames()[%d] = %q, want %q", i, n, want[i]) } } } func TestKernelFuncNotFound(t *testing.T) { k := loadBasic(t) _, err := k.CallFunc("nonexistent", make([]byte, 8)) if err == nil { t.Fatal("expected error for nonexistent function") } } func TestKernelArgTooSmall(t *testing.T) { k := loadBasic(t) _, err := k.CallFunc("add", make([]byte, 8)) // needs 24 if err == nil { t.Fatal("expected error for too-small arg block") } } func TestMapZeroLength(t *testing.T) { _, err := Map(nil) if err == nil { t.Fatal("expected error for zero-length code") } } func TestLoadSourceError(t *testing.T) { _, err := LoadSource("bad.s", "TEXT ·f(SB), NOSPLIT\n\tBADINSTRUCTION\n") // The parser may or may not error on unknown instructions (it's // error-tolerant), but the assembler will reject it. if err == nil { t.Log("LoadSource succeeded unexpectedly (parser is error-tolerant)") } } func TestLoadSourceParseError(t *testing.T) { // A completely invalid file that the parser rejects. _, err := LoadSource("empty.s", "") if err != nil { t.Logf("expected: %v", err) } } func TestFuncLookup(t *testing.T) { k := loadBasic(t) fl, err := k.Func("add") if err != nil { t.Fatalf("Func(add): %v", err) } if fl.Name != "add" { t.Errorf("Func(add).Name = %q, want %q", fl.Name, "add") } if fl.Args != 24 { t.Errorf("Func(add).Args = %d, want 24", fl.Args) } _, err = k.Func("nonexistent") if err == nil { t.Fatal("expected error for nonexistent function") } } func TestABIReportString(t *testing.T) { r := ABIReport{} if r.String() != "ABI clean" { t.Errorf("clean report = %q", r.String()) } r.BPClobbered = true if r.OK() { t.Error("expected not OK with BP clobbered") } s := r.String() if s == "ABI clean" { t.Error("expected violation string, got clean") } r.R14Clobbered = true r.RedZoneHit = true s = r.String() if s == "ABI clean" { t.Error("expected violation string for all flags") } }