Files

57 lines
1.7 KiB
Go
Raw Permalink Normal View History

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
package verify
// abiResult records register-clobber violations detected by the ABI-checking
// trampolines. Bit 0: frame pointer clobbered. Bit 1: goroutine pointer
// clobbered.
var abiResult uint64
// ABIReport describes the result of an ABI-checking call. The register
// fields are architecture-dependent:
//
// - FPClobbered: the frame pointer the Go runtime maintains
// (amd64 BP, arm64 R29). riscv64 and loong64 keep no hardware frame
// pointer, so the field is always false there.
// - GClobbered: the goroutine pointer (amd64 R14, arm64 R28,
// riscv64 X27, loong64 R22).
type ABIReport struct {
FPClobbered bool
GClobbered bool
RedZoneHit bool
}
// OK returns true when no violations were detected.
func (r ABIReport) OK() bool {
return !r.FPClobbered && !r.GClobbered && !r.RedZoneHit
}
// String returns a human-readable summary.
func (r ABIReport) String() string {
if r.OK() {
return "ABI clean"
}
s := "ABI violation:"
if r.FPClobbered {
s += " frame pointer clobbered"
}
if r.GClobbered {
s += " goroutine pointer clobbered"
}
if r.RedZoneHit {
s += " stack below SP written"
}
return s
}
// redZoneSize is the canary window below the prepared stack pointer. On
// amd64 it is the System V red zone; on every architecture a Go function
// must not write below its own declared frame, so the canary sits below
// the frame plus the call margin (see CallCheckedFrame) and any corruption
// there is a bug.
const redZoneSize = 128
// redZoneFill is the byte pattern used to detect writes below SP.
const redZoneFill = 0xA5