fix(cmd): padding-aware ground-truth comparison
Assisted-by: GLM 5.3
This commit is contained in:
+32
-3
@@ -938,11 +938,40 @@ func compareGroundTruth(img *asm.Image, gt map[string][]byte) (matched, total, d
|
||||
goCmp[j] = 0
|
||||
}
|
||||
}
|
||||
if bytes.Equal(gasmCmp, goCmp) {
|
||||
// The toolchain pads text symbols to 16-byte boundaries with
|
||||
// zeros, so a function whose size is not a multiple of 16
|
||||
// carries trailing zeros in the ground truth that are not part
|
||||
// of the encoding. Compare up to the shorter side and require
|
||||
// the remainder of whichever is longer to be zero, so padding
|
||||
// never masks a real difference.
|
||||
cmpLen := min(len(gasmCmp), len(goCmp))
|
||||
equal := bytes.Equal(gasmCmp[:cmpLen], goCmp[:cmpLen])
|
||||
if equal {
|
||||
for _, b := range gasmCmp[cmpLen:] {
|
||||
if b != 0 {
|
||||
equal = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if equal {
|
||||
for _, b := range goCmp[cmpLen:] {
|
||||
if b != 0 {
|
||||
equal = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if equal {
|
||||
matched++
|
||||
if len(fn.Relocs) > 0 {
|
||||
switch {
|
||||
case len(fn.Relocs) > 0 && len(goCmp) > cmpLen:
|
||||
fmt.Printf(" %s: MATCH (%d bytes, %d relocs masked, %d padding)\n", fn.Name, fn.Size, len(fn.Relocs), len(goCmp)-cmpLen)
|
||||
case len(fn.Relocs) > 0:
|
||||
fmt.Printf(" %s: MATCH (%d bytes, %d relocs masked)\n", fn.Name, fn.Size, len(fn.Relocs))
|
||||
} else {
|
||||
case len(goCmp) > cmpLen:
|
||||
fmt.Printf(" %s: MATCH (%d bytes, %d padding)\n", fn.Name, fn.Size, len(goCmp)-cmpLen)
|
||||
default:
|
||||
fmt.Printf(" %s: MATCH (%d bytes)\n", fn.Name, fn.Size)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"sourcedock.dev/petrbalvin/gasm-devkit/arch"
|
||||
"sourcedock.dev/petrbalvin/gasm-devkit/asm"
|
||||
)
|
||||
|
||||
const clean = "#include \"textflag.h\"\n" +
|
||||
@@ -440,3 +441,22 @@ func TestRunCorpusAudit(t *testing.T) {
|
||||
t.Errorf("arm64 unencodable reasons = %d, want 1", r)
|
||||
}
|
||||
}
|
||||
|
||||
// TestCompareGroundTruthPadding pins the padding-aware ground-truth
|
||||
// comparison: the toolchain pads text symbols to 16-byte boundaries, so
|
||||
// trailing zeros in the reference must not read as a mismatch, while any
|
||||
// non-zero tail still must.
|
||||
func TestCompareGroundTruthPadding(t *testing.T) {
|
||||
code := []byte{0x48, 0x8b, 0x07, 0xc3} // 4 bytes, not a multiple of 16
|
||||
img := &asm.Image{Code: code, Funcs: []asm.FuncLayout{{Name: "f", Offset: 0, Size: len(code)}}}
|
||||
padded := append(append([]byte(nil), code...), 0, 0, 0)
|
||||
matched, total, diffs := compareGroundTruth(img, map[string][]byte{"f": padded})
|
||||
if matched != 1 || total != 1 || diffs != 0 {
|
||||
t.Fatalf("zero padding should match: matched=%d total=%d diffs=%d", matched, total, diffs)
|
||||
}
|
||||
dirty := append(append([]byte(nil), code...), 0, 0x90, 0)
|
||||
matched, _, diffs = compareGroundTruth(img, map[string][]byte{"f": dirty})
|
||||
if matched != 0 || diffs != 1 {
|
||||
t.Fatalf("non-zero padding must mismatch: matched=%d diffs=%d", matched, diffs)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user