fix: staticcheck and deadcode findings repo-wide, modernize counting loops

This commit is contained in:
2026-08-29 15:25:15 +02:00
parent 9a34733615
commit eacf33d0f7
33 changed files with 88 additions and 250 deletions
+16 -5
View File
@@ -17,7 +17,12 @@ import (
var abiResult uint64
// savedBP holds the caller's frame pointer across the ABI-checked JIT call.
// Referenced by enterJITChecked to satisfy go vet's save-before-clobber rule.
// Written and read by enterJITChecked/leaveJITChecked (abi_amd64.s); no Go
// code references it, which GoLand cannot see inside assembly.
//
// noinspection GoUnusedGlobalVariable
//
//lint:ignore U1000 written and read by the assembly
var savedBP uintptr
// leaveCheckedPtr is initialised by the linker from the GLOBL/DATA in
@@ -26,7 +31,10 @@ var savedBP uintptr
var leaveCheckedPtr uintptr
// enterJITChecked sets sentinels in BP and R14, switches to the prepared
// stack and jumps to fn.
// stack and jumps to fn. The body lives in abi_amd64.s and reads the
// parameters from the frame by name, which GoLand cannot see.
//
// noinspection GoUnusedParameter
//
//go:nosplit
func enterJITChecked(fn uintptr, stack uintptr)
@@ -37,6 +45,9 @@ func enterJITChecked(fn uintptr, stack uintptr)
// declaration would generate. The declaration exists solely to satisfy
// go vet's "missing Go declaration" check.
//
// noinspection GoUnusedFunction
//
//lint:ignore U1000 the assembly obtains this address through leaveCheckedPtr
//go:nosplit
func leaveJITCheckedRaw()
@@ -95,10 +106,10 @@ func CallChecked(fnAddr uintptr, args []byte) ([]byte, ABIReport, error) {
if err != nil {
return nil, report, fmt.Errorf("verify: stack mmap: %w", err)
}
defer syscall.Munmap(stackMem)
defer func() { _ = syscall.Munmap(stackMem) }()
// Fill the red zone with the canary pattern.
for i := 0; i < redZoneSize; i++ {
for i := range redZoneSize {
stackMem[i] = redZoneFill
}
@@ -116,7 +127,7 @@ func CallChecked(fnAddr uintptr, args []byte) ([]byte, ABIReport, error) {
report.R14Clobbered = res&2 != 0
// Check the red zone.
for i := 0; i < redZoneSize; i++ {
for i := range redZoneSize {
if stackMem[i] != redZoneFill {
report.RedZoneHit = true
break
+6 -1
View File
@@ -14,7 +14,12 @@ import (
)
// savedSP holds the Go stack pointer while a JIT call is in flight.
// Referenced by the assembly trampoline (trampoline_amd64.s).
// Written and read by the assembly trampoline (trampoline_amd64.s); no Go
// code references it, which staticcheck and GoLand cannot see.
//
// noinspection GoUnusedGlobalVariable
//
//lint:ignore U1000 written and read by the assembly
var savedSP uintptr
// enterJIT switches to the prepared stack and jumps to fn.
-46
View File
@@ -55,49 +55,3 @@ func (k *Kernel) BlockCount(name string) (int, error) {
}
return len(blocks), nil
}
// PathFingerprint is the observable output of one function execution: the
// values written back into the result slots of the argument block. Two
// executions that produce the same fingerprint took observationally
// equivalent paths (though they may differ internally).
type PathFingerprint struct {
Results []uint64 // the result words from the arg block
}
// ProfilePaths runs the function with each of the given argument blocks and
// collects the distinct output fingerprints. This measures path diversity:
// how many observationally different execution paths the input corpus
// exercises. Combined with Blocks (the static block count), it gives a
// lower bound on code coverage.
func (k *Kernel) ProfilePaths(name string, argSets [][]byte, resultOffsets []int) ([]PathFingerprint, error) {
idx, ok := k.funcs[name]
if !ok {
return nil, fmt.Errorf("verify: function %q not found", name)
}
fl := k.img.Funcs[idx]
seen := map[string]bool{}
var paths []PathFingerprint
for _, args := range argSets {
if len(args) < fl.Args {
return nil, fmt.Errorf("verify: %s: arg block too small", name)
}
out, err := k.CallFunc(name, args)
if err != nil {
return nil, err
}
fp := PathFingerprint{}
key := ""
for _, off := range resultOffsets {
v := GetUint64(out, off)
fp.Results = append(fp.Results, v)
key += fmt.Sprintf("%016x", v)
}
if !seen[key] {
seen[key] = true
paths = append(paths, fp)
}
}
return paths, nil
}
+1 -1
View File
@@ -177,7 +177,7 @@ func (k *Kernel) FuzzFunc(name string, sig funcSig, goCode []byte, iterations in
return result
}
for i := 0; i < iterations; i++ {
for i := range iterations {
// Generate inputs and build TWO independent arg blocks (one per
// version) so that functions which write to their arguments
// (e.g. histogram increments) don't corrupt the other's input.
+15 -1
View File
@@ -38,6 +38,17 @@ func GroundTruthLOONG64(path string) (map[string][]byte, error) {
return groundTruthArch(path, "loong64")
}
// goRoot locates the GOROOT of the `go` binary on PATH: the build-time
// runtime.GOROOT is meaningless for a relocated binary, so the toolchain is
// asked directly.
func goRoot() (string, error) {
out, err := exec.Command("go", "env", "GOROOT").Output()
if err != nil {
return "", fmt.Errorf("verify: go env GOROOT: %w", err)
}
return strings.TrimSpace(string(out)), nil
}
// GroundTruthARM64 assembles the given .s file with the Go toolchain in
// AArch64 cross-assembly mode (GOARCH=arm64).
func GroundTruthARM64(path string) (map[string][]byte, error) {
@@ -45,7 +56,10 @@ func GroundTruthARM64(path string) (map[string][]byte, error) {
}
func groundTruthArch(path, goarch string) (map[string][]byte, error) {
goroot := runtime.GOROOT()
goroot, err := goRoot()
if err != nil {
return nil, err
}
asmBin := filepath.Join(goroot, "pkg", "tool", runtime.GOOS+"_"+runtime.GOARCH, "asm")
if _, err := os.Stat(asmBin); err != nil {
return nil, fmt.Errorf("verify: go tool asm not found at %s: %w", asmBin, err)
+1 -1
View File
@@ -144,7 +144,7 @@ func (k *Kernel) FuzzFuncChecked(name string, sig funcSig, iterations int, seed
}
violations := 0
for i := 0; i < iterations; i++ {
for i := range iterations {
gasmArgs, _, bufs := genDualArgs(rng, sig, fl.Args)
result.CrashInput = gasmArgs