]> git.feebdaed.xyz Git - 0xmirror/go.git/commitdiff
runtime, cmd/link: tighten search for stackObjectRecord
authorIan Lance Taylor <iant@golang.org>
Wed, 10 Dec 2025 02:56:45 +0000 (18:56 -0800)
committerGopher Robot <gobot@golang.org>
Fri, 12 Dec 2025 21:23:17 +0000 (13:23 -0800)
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>
src/cmd/link/internal/ld/symtab.go
src/runtime/stack.go
src/runtime/stkframe.go
src/runtime/symtab.go

index dd2d74895ad60cd79667554a90b6999a0c7bf468..67b1f11c60bdd860bee95f742a788d3e8a4c4cec 100644 (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
index d1c80276a5c46947bf81793ba3f6fce1c31ef262..6f89cc142c39f07c8a41d4b5ca0275cb1ead9330 100644 (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
                }
index 485af1e75fb889e252117fb9adfb440cd2892795..b63c0b4519337d515e73a03449e99f211166b5db 100644 (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
                }
index c1643c1b39615889648eed6715427ff91ac7338a..058165553023411764fb2e2ed49539e23ebb1441 100644 (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