diff --git a/src/cmd/compile/internal/gc/compile.go b/src/cmd/compile/internal/gc/compile.go index 159fd29c48..496daacb42 100644 --- a/src/cmd/compile/internal/gc/compile.go +++ b/src/cmd/compile/internal/gc/compile.go @@ -58,8 +58,13 @@ func enqueueFunc(fn *ir.Func) { types.CalcSize(fn.Type()) a := ssagen.AbiForBodylessFuncStackMap(fn) abiInfo := a.ABIAnalyzeFuncType(fn.Type()) // abiInfo has spill/home locations for wrapper - liveness.WriteFuncMap(fn, abiInfo) if fn.ABI == obj.ABI0 { + // The current args_stackmap generation assumes the function + // is ABI0, and only ABI0 assembly function can have a FUNCDATA + // reference to args_stackmap (see cmd/internal/obj/plist.go:Flushplist). + // So avoid introducing an args_stackmap if the func is not ABI0. + liveness.WriteFuncMap(fn, abiInfo) + x := ssagen.EmitArgInfo(fn, abiInfo) objw.Global(x, int32(len(x.P)), obj.RODATA|obj.LOCAL) } diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go index 1a36035f46..708f0f2023 100644 --- a/src/cmd/compile/internal/liveness/plive.go +++ b/src/cmd/compile/internal/liveness/plive.go @@ -1536,7 +1536,7 @@ func isfat(t *types.Type) bool { // inputs and outputs as the value of symbol .args_stackmap. // If fn has outputs, two bitmaps are written, otherwise just one. func WriteFuncMap(fn *ir.Func, abiInfo *abi.ABIParamResultInfo) { - if ir.FuncName(fn) == "_" || fn.Sym().Linkname != "" { + if ir.FuncName(fn) == "_" { return } nptr := int(abiInfo.ArgWidth() / int64(types.PtrSize)) diff --git a/test/linknameasm.dir/a_amd64.s b/test/linknameasm.dir/a_amd64.s new file mode 100644 index 0000000000..2799609cd7 --- /dev/null +++ b/test/linknameasm.dir/a_amd64.s @@ -0,0 +1,7 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +TEXT ·asm(SB),0,$0-8 + CALL ·callback(SB) + RET diff --git a/test/linknameasm.dir/x.go b/test/linknameasm.dir/x.go new file mode 100644 index 0000000000..38bca6f7d7 --- /dev/null +++ b/test/linknameasm.dir/x.go @@ -0,0 +1,26 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that a linkname applied on an assembly declaration +// does not affect stack map generation. + +package main + +import ( + "runtime" + _ "unsafe" +) + +//go:linkname asm +func asm(*int) + +func main() { + x := new(int) + asm(x) +} + +// called from asm +func callback() { + runtime.GC() // scan stack +} diff --git a/test/linknameasm.go b/test/linknameasm.go new file mode 100644 index 0000000000..119f4bda42 --- /dev/null +++ b/test/linknameasm.go @@ -0,0 +1,9 @@ +// buildrundir + +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 + +package ignored