test(asm): pair the same-named GOROOT functions in definition order

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-07 21:34:30 +02:00
1 parent c27ba30862
commit df7a5091e0
1 file changed
+23 -18
+23 -18
View File
@@ -57,15 +57,9 @@ var gorootARM64Packages = []string{
var gorootARM64GapFiles = map[string]string{ var gorootARM64GapFiles = map[string]string{
"runtime/asm_arm64.s": "the unparenthesised NOSPLIT|NOFRAME flag list is not recognised, so the prologue and guard shapes diverge", "runtime/asm_arm64.s": "the unparenthesised NOSPLIT|NOFRAME flag list is not recognised, so the prologue and guard shapes diverge",
"runtime/sys_linux_arm64.s": "the unparenthesised NOSPLIT|NOFRAME flag list is not recognised, so the prologue and guard shapes diverge (cgoSigtramp, clone)", "runtime/sys_linux_arm64.s": "the unparenthesised NOSPLIT|NOFRAME flag list is not recognised, so the prologue and guard shapes diverge (cgoSigtramp, clone)",
"runtime/tls_arm64.s": "a branch distance diverges: an earlier statement's expansion is sized differently", "runtime/preempt_arm64.s": "the unparenthesised NOSPLIT|NOFRAME flag list is not recognised, so the prologue and guard shapes diverge (asyncPreempt)",
"crypto/internal/fips140/aes/aes_arm64.s": "a tested immediate bit in a TBZ diverges", "runtime/race_arm64.s": "the unparenthesised NOSPLIT|NOFRAME flag list is not recognised, so the prologue shape diverges (racecallbackthunk)",
"crypto/internal/fips140/aes/gcm/gcm_arm64.s": "an ADD immediate's value diverges mid-function",
"crypto/internal/fips140/nistec/p256_asm_arm64.s": "a branch distance and a logical-immediate lowering diverge",
"runtime/memclr_arm64.s": "a branch distance diverges: an earlier statement's expansion is sized differently",
"runtime/preempt_arm64.s": "the prologue shape for the function's frame diverges at the first word",
"runtime/race_arm64.s": "the flag list and prologue shape diverge at the first words",
"runtime/rt0_linux_arm64.s": "the #ifdef GOOS selection diverges: gasm keeps a word the toolchain drops", "runtime/rt0_linux_arm64.s": "the #ifdef GOOS selection diverges: gasm keeps a word the toolchain drops",
"internal/runtime/syscall/linux/asm_linux_arm64.s": "a branch distance diverges: an earlier statement's expansion is sized differently",
} }
// gorootOtherGOOS matches the file names of the ports the linux build never // gorootOtherGOOS matches the file names of the ports the linux build never
@@ -152,22 +146,30 @@ func TestGOROOTARM64Parity(t *testing.T) {
if oout, err := cmd.CombinedOutput(); err != nil { if oout, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("go tool asm %s: %v\n%s", base, err, oout) t.Fatalf("go tool asm %s: %v\n%s", base, err, oout)
} }
gt := oracleFuncText(t, mustRead(t, objPath)) byLocal := oracleFuncText(t, mustRead(t, objPath))
byLocal := gt
// The object's symdef order is the source order, gasm's
// function list too, so same-named functions pair up in
// definition order: a file-local kernel beside its
// package-level twin (runtime·racefuncenter and
// racefuncenter<>) carries the plain name twice in the
// object and the reader cannot see the locality.
seen := map[string]int{}
for _, fn := range img.Funcs { for _, fn := range img.Funcs {
gasmCode := maskCode(append([]byte(nil), img.Code[fn.Offset:fn.Offset+fn.Size]...), fn.Relocs) gasmCode := maskCode(append([]byte(nil), img.Code[fn.Offset:fn.Offset+fn.Size]...), fn.Relocs)
goCode, ok := byLocal[fn.Name] bodies := byLocal[fn.Name]
if !ok { idx := seen[fn.Name]
seen[fn.Name] = idx + 1
if idx >= len(bodies) {
keys := make([]string, 0, len(byLocal)) keys := make([]string, 0, len(byLocal))
for name := range byLocal { for name := range byLocal {
keys = append(keys, name) keys = append(keys, name)
} }
t.Errorf("%s: not in the oracle output (%d functions: %s)", t.Errorf("%s: not in the oracle output (%d functions: %s)",
fn.Name, len(gt), strings.Join(keys, ", ")) fn.Name, len(byLocal), strings.Join(keys, ", "))
continue continue
} }
goCode = maskCode(append([]byte(nil), goCode...), fn.Relocs) goCode := maskCode(append([]byte(nil), bodies[idx]...), fn.Relocs)
cmpLen := min(len(goCode), len(gasmCode)) cmpLen := min(len(goCode), len(gasmCode))
if !bytes.Equal(gasmCode[:cmpLen], goCode[:cmpLen]) { if !bytes.Equal(gasmCode[:cmpLen], goCode[:cmpLen]) {
for w := 0; w < cmpLen/4; w++ { for w := 0; w < cmpLen/4; w++ {
@@ -202,13 +204,16 @@ func TestGOROOTARM64Parity(t *testing.T) {
// non-package and the hashed (file-local) definitions both, keyed by the // non-package and the hashed (file-local) definitions both, keyed by the
// local name: GOROOT keeps several kernels file-local (cmpbody<>, // local name: GOROOT keeps several kernels file-local (cmpbody<>,
// encryptBlockAsm<>), and those ride the hashed definition blocks the // encryptBlockAsm<>), and those ride the hashed definition blocks the
// non-package reader never sees. // non-package reader never sees. The value is the functions' bodies in
func oracleFuncText(t *testing.T, obj []byte) map[string][]byte { // symdef order: a file-local kernel beside its package-level twin carries
// the same plain name twice (the object reader cannot see the locality),
// and the encoder pairs them up in definition order.
func oracleFuncText(t *testing.T, obj []byte) map[string][][]byte {
t.Helper() t.Helper()
v := openGoobj(t, obj) v := openGoobj(t, obj)
data := v.blk(blkData) data := v.blk(blkData)
didx := v.blk(blkDataIdx) didx := v.blk(blkDataIdx)
out := make(map[string][]byte) out := make(map[string][][]byte)
di := 0 di := 0
for _, bi := range []int{blkSymdef, blkHashed64def, blkHasheddef, blkNonpkgdef} { for _, bi := range []int{blkSymdef, blkHashed64def, blkHasheddef, blkNonpkgdef} {
for _, s := range v.syms(bi) { for _, s := range v.syms(bi) {
@@ -221,7 +226,7 @@ func oracleFuncText(t *testing.T, obj []byte) map[string][]byte {
if _, after, ok := strings.Cut(name, "."); ok { if _, after, ok := strings.Cut(name, "."); ok {
name = after name = after
} }
out[name] = data[off : int(off)+int(s.size)] out[name] = append(out[name], data[off:int(off)+int(s.size)])
} }
} }
di++ di++