fix: staticcheck and deadcode findings repo-wide, modernize counting loops
This commit is contained in:
+16
-5
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user