Files
gasm-sdk/verify/goobj_link_fold_test.go
T

63 lines
1.9 KiB
Go
Raw Normal View History

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
package verify
import (
"os"
"os/exec"
"testing"
)
// goobjFoldMainSrc is the Go side of the SSE regression. The kernel
// XOR-folds 16-byte blocks and sums the tail bytes through the amd64 SSE
// families; main derives the same value in Go and panics on any divergence
// before printing the deterministic line the baseline and the gasm-linked
// binaries must agree on.
const goobjFoldMainSrc = `package main
import "encoding/binary"
func fold(buf []byte, seed uint64) uint64
func main() {
buf := []byte("gasm link parity vector kernel! 0123456789abcdef tail")
low, high := uint64(0), uint64(0)
for i := 0; i+16 <= len(buf); i += 16 {
low ^= binary.LittleEndian.Uint64(buf[i:])
high ^= binary.LittleEndian.Uint64(buf[i+8:])
}
tail := uint64(0)
for _, b := range buf[len(buf)-len(buf)%16:] {
tail += uint64(b)
}
const k = 0x9e3779b97f4a7c15
want := (low + high + tail) * k ^ 0xabcdef
if got := fold(buf, 0xabcdef); got != want {
panic("fold")
}
println("ok", fold(buf, 0xabcdef))
}
`
// TestGOOBJLinkFoldKernel proves the amd64 SSE families are proven end to
// end: the kernel assembles by gasm into a GOOBJ object, substitutes
// byte-wise into a real go build archive, relinks with cmd/link and the
// linked binary computes the same fold as the toolchain-built one, run
// natively on amd64 hosts.
func TestGOOBJLinkFoldKernel(t *testing.T) {
if testing.Short() {
t.Skip("builds the gasm binary and links Go programs")
}
if os.Getenv("GASM_LINK_PARITY") == "" {
t.Skip("deliberate verification: set GASM_LINK_PARITY=1 (just link-parity)")
}
goBin, err := exec.LookPath("go")
if err != nil {
t.Skip("no Go toolchain available")
}
gasmBin := buildLinkParityGasm(t, goBin)
t.Run("amd64", func(t *testing.T) {
goobjLinkKernel(t, goBin, gasmBin, "amd64", "linkfold_amd64.s", goobjFoldMainSrc)
})
}