feat(verify): ABI checks on arm64, riscv64 and loong64

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-08-30 11:27:54 +02:00
parent 6d7f10f13e
commit 8f84dac10b
19 changed files with 710 additions and 138 deletions
+54
View File
@@ -0,0 +1,54 @@
// 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 SP, so any corruption there is a bug.
const redZoneSize = 128
// redZoneFill is the byte pattern used to detect writes below SP.
const redZoneFill = 0xA5