runtime, cmd/link: tighten search for stackObjectRecord

A stackObjectRecord should always be in funcdata, between gofunc
and the end of pclntab, except for the special case of
methodValueCallFrameObjs, which should always be in noptrbss.
Adjust the two loops that look for the moduledata corresponding
to a stackObjectRecord to search more precisely, rather than
relying on datap.end.

Closely based on a patch by Michael Stapelberg.

For #76038

Change-Id: I751801d8fd030af751825a67905b2a343280e7d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/728840
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Ian Lance Taylor 2025-12-09 18:56:45 -08:00 committed by Gopher Robot
parent 63fced531c
commit ee0275d15b
4 changed files with 10 additions and 2 deletions

View File

@ -656,6 +656,7 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etypes", 0))
moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.rodata", 0))
moduledata.AddAddr(ctxt.Arch, ldr.Lookup("go:func.*", 0))
moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.epclntab", 0))
if ctxt.IsAIX() && ctxt.IsExternal() {
// Add R_XCOFFREF relocation to prevent ld's garbage collection of

View File

@ -1357,7 +1357,13 @@ func (r *stackObjectRecord) gcdata() (uintptr, *byte) {
ptr := uintptr(unsafe.Pointer(r))
var mod *moduledata
for datap := &firstmoduledata; datap != nil; datap = datap.next {
if datap.gofunc <= ptr && ptr < datap.end {
// The normal case: stackObjectRecord is in funcdata.
if datap.gofunc <= ptr && ptr < datap.epclntab {
mod = datap
break
}
// A special case: methodValueCallFrameObjs.
if datap.noptrbss <= ptr && ptr < datap.enoptrbss {
mod = datap
break
}

View File

@ -269,7 +269,7 @@ func stkobjinit() {
ptr := uintptr(unsafe.Pointer(&methodValueCallFrameObjs[0]))
var mod *moduledata
for datap := &firstmoduledata; datap != nil; datap = datap.next {
if datap.gofunc <= ptr && ptr < datap.end {
if datap.noptrbss <= ptr && ptr < datap.enoptrbss {
mod = datap
break
}

View File

@ -422,6 +422,7 @@ type moduledata struct {
types, etypes uintptr
rodata uintptr
gofunc uintptr // go.func.*
epclntab uintptr
textsectmap []textsect
typelinks []int32 // offsets from types