96 lines
2.1 KiB
Go
96 lines
2.1 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package verify
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func loadABIKernel(t *testing.T) *Kernel {
|
|
t.Helper()
|
|
k, err := Load("../testdata/verify/abi_amd64.s")
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
t.Cleanup(k.Close)
|
|
return k
|
|
}
|
|
|
|
func TestABIClean(t *testing.T) {
|
|
k := loadABIKernel(t)
|
|
|
|
args := make([]byte, 24)
|
|
PutUint64(args, 0, 3)
|
|
PutUint64(args, 8, 4)
|
|
|
|
out, report, err := k.CallFuncChecked("cleanAdd", args)
|
|
if err != nil {
|
|
t.Fatalf("CallFuncChecked: %v", err)
|
|
}
|
|
if got := int64(GetUint64(out, 16)); got != 7 {
|
|
t.Errorf("cleanAdd(3, 4) = %d, want 7", got)
|
|
}
|
|
if !report.OK() {
|
|
t.Errorf("cleanAdd: %s", report)
|
|
}
|
|
}
|
|
|
|
func TestABIBPClobbered(t *testing.T) {
|
|
k := loadABIKernel(t)
|
|
|
|
args := make([]byte, 16)
|
|
PutUint64(args, 0, 42)
|
|
|
|
out, report, err := k.CallFuncChecked("dirtyBP", args)
|
|
if err != nil {
|
|
t.Fatalf("CallFuncChecked: %v", err)
|
|
}
|
|
if got := int64(GetUint64(out, 8)); got != 42 {
|
|
t.Errorf("dirtyBP(42) = %d, want 42", got)
|
|
}
|
|
if !report.BPClobbered {
|
|
t.Error("dirtyBP: expected BP clobbered, but report says clean")
|
|
}
|
|
if report.R14Clobbered {
|
|
t.Error("dirtyBP: R14 should not be clobbered")
|
|
}
|
|
}
|
|
|
|
func TestABIR14Clobbered(t *testing.T) {
|
|
k := loadABIKernel(t)
|
|
|
|
args := make([]byte, 16)
|
|
PutUint64(args, 0, 99)
|
|
|
|
out, report, err := k.CallFuncChecked("dirtyR14", args)
|
|
if err != nil {
|
|
t.Fatalf("CallFuncChecked: %v", err)
|
|
}
|
|
if got := int64(GetUint64(out, 8)); got != 99 {
|
|
t.Errorf("dirtyR14(99) = %d, want 99", got)
|
|
}
|
|
if !report.R14Clobbered {
|
|
t.Error("dirtyR14: expected R14 clobbered, but report says clean")
|
|
}
|
|
if report.BPClobbered {
|
|
t.Error("dirtyR14: BP should not be clobbered")
|
|
}
|
|
}
|
|
|
|
func TestCallFuncCheckedErrors(t *testing.T) {
|
|
k := loadABIKernel(t)
|
|
|
|
// Nonexistent function.
|
|
_, _, err := k.CallFuncChecked("nope", make([]byte, 8))
|
|
if err == nil {
|
|
t.Fatal("expected error for nonexistent function")
|
|
}
|
|
|
|
// Arg block too small.
|
|
_, _, err = k.CallFuncChecked("cleanAdd", make([]byte, 8))
|
|
if err == nil {
|
|
t.Fatal("expected error for too-small arg block")
|
|
}
|
|
}
|