]> Cypherpunks repositories - gostls13.git/commitdiff
runtime, cmd/link: store type descriptor length, not end
authorIan Lance Taylor <iant@golang.org>
Wed, 28 Jan 2026 01:34:46 +0000 (17:34 -0800)
committerCherry Mui <cherryyz@google.com>
Thu, 29 Jan 2026 16:14:53 +0000 (08:14 -0800)
Storing the type descriptor length lets us save a relocation.
It also avoids a problem for Darwin dynamic linking.

For #6853
Fixes #77350

Change-Id: If5c94330fe10d75690325f3d0b0658060ef3eb2d
Reviewed-on: https://go-review.googlesource.com/c/go/+/739681
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/symtab.go
src/runtime/symtab.go
src/runtime/type.go

index 51163c2c8b73e875866a1ed02883c920f718d61b..682ae267bf453d0af0766893c11c9a39ee460080 100644 (file)
@@ -1535,10 +1535,6 @@ func fixZeroSizedSymbols(ctxt *Link) {
        types.SetSize(8)
        ldr.SetAttrSpecial(types.Sym(), false)
 
-       etypedesc := ldr.CreateSymForUpdate("runtime.etypedesc", 0)
-       etypedesc.SetType(sym.STYPE)
-       ldr.SetAttrSpecial(etypedesc.Sym(), false)
-
        etypes := ldr.CreateSymForUpdate("runtime.etypes", 0)
        etypes.SetType(sym.STYPE)
        ldr.SetAttrSpecial(etypes.Sym(), false)
@@ -2218,7 +2214,6 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
 
        sect = createRelroSect(".go.type", sym.STYPE)
        ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
-       ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypedesc", 0), sect)
        ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
 
        sect = createRelroSect(".go.func", sym.SGOFUNC)
@@ -2437,20 +2432,30 @@ func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader
                })
 
                // Find the end of the typelink descriptors.
-               // The offset starts at 1 to match the increment in
+               // The size starts at 1 to match the increment in
                // createRelroSect in allocateDataSections.
                // TODO: This wastes some space.
-               offset := int64(1)
+               typeLinkSize := int64(1)
                for i := range sl {
                        si := sl[i].sym
+                       if si == head {
+                               continue
+                       }
                        if _, isTypelink := typelinkStrings[si]; !isTypelink {
                                break
                        }
-                       offset = Rnd(offset, int64(symalign(ldr, si)))
-                       offset += sl[i].sz
+                       typeLinkSize = Rnd(typeLinkSize, int64(symalign(ldr, si)))
+                       typeLinkSize += sl[i].sz
                }
 
-               ldr.SetSymValue(ldr.LookupOrCreateSym("runtime.etypedesc", 0), offset)
+               // Store the length of the typelink descriptors
+               // in the typedesclen field of moduledata.
+               if ctxt.moduledataTypeDescOffset == 0 {
+                       Errorf("internal error: phase error: moduledataTypeDescOffset not set in dodataSect")
+               } else {
+                       su := ldr.MakeSymbolUpdater(ctxt.Moduledata)
+                       su.SetUint(ctxt.Arch, ctxt.moduledataTypeDescOffset, uint64(typeLinkSize))
+               }
 
        default:
                sort.Slice(sl, sortFn)
@@ -3098,12 +3103,9 @@ func (ctxt *Link) address() []*sym.Segment {
        ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
        ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
        ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
-       // etypedesc was set to the offset from the symbol start in dodataSect.
-       s := ldr.Lookup("runtime.etypedesc", 0)
-       ctxt.xdefine("runtime.etypedesc", sym.SRODATA, int64(types.Vaddr+uint64(ldr.SymValue(s))))
        ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
 
-       s = ldr.Lookup("runtime.gcdata", 0)
+       s := ldr.Lookup("runtime.gcdata", 0)
        ldr.SetAttrLocal(s, true)
        ctxt.xdefine("runtime.egcdata", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
        ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcdata", 0), ldr.SymSect(s))
index 2276d39d8885dd313eb0e9e784587d7b9f191078..aa4f655cc93730f39cd7bab4cfb0ddf79c7d346d 100644 (file)
@@ -96,6 +96,8 @@ type Link struct {
        Textp        []loader.Sym
        Moduledata   loader.Sym
 
+       moduledataTypeDescOffset int64
+
        PackageFile  map[string]string
        PackageShlib map[string]string
 
index d63a96d12b502037b62786dc699b65347d2d8e2c..142fb15785d7fde680ac729c8947f6093ffe3615 100644 (file)
@@ -433,7 +433,6 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
        ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
        ctxt.xdefine("runtime.erodata", sym.SRODATAEND, 0)
        ctxt.xdefine("runtime.types", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.etypedesc", sym.SRODATA, 0)
        ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
        ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
        ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATAEND, 0)
@@ -619,7 +618,8 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
        moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcdata", 0))
        moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcbss", 0))
        moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.types", 0))
-       moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etypedesc", 0))
+       ctxt.moduledataTypeDescOffset = moduledata.Size()
+       moduledata.AddUint(ctxt.Arch, 0) // filled in by dodataSect
        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))
index 5dbf7a9d31c056c92144122d266ff4ba48d77c3c..1bd9a0c1887d6767f75be27f51323d2235194d9f 100644 (file)
@@ -412,17 +412,17 @@ type moduledata struct {
        findfunctab  uintptr
        minpc, maxpc uintptr
 
-       text, etext              uintptr
-       noptrdata, enoptrdata    uintptr
-       data, edata              uintptr
-       bss, ebss                uintptr
-       noptrbss, enoptrbss      uintptr
-       covctrs, ecovctrs        uintptr
-       end, gcdata, gcbss       uintptr
-       types, etypedesc, etypes uintptr
-       rodata                   uintptr
-       gofunc                   uintptr // go.func.*
-       epclntab                 uintptr
+       text, etext                uintptr
+       noptrdata, enoptrdata      uintptr
+       data, edata                uintptr
+       bss, ebss                  uintptr
+       noptrbss, enoptrbss        uintptr
+       covctrs, ecovctrs          uintptr
+       end, gcdata, gcbss         uintptr
+       types, typedesclen, etypes uintptr
+       rodata                     uintptr
+       gofunc                     uintptr // go.func.*
+       epclntab                   uintptr
 
        textsectmap []textsect
        itablinks   []*itab
index 893c79404ea0e181d8f84531d2d8c4862139d343..c5262ccd0fef80ca832a3d73a49195c863e90f23 100644 (file)
@@ -514,7 +514,7 @@ func moduleTypelinks(md *moduledata) []*_type {
        }
 
        // Allocate a very rough estimate of the number of types.
-       ret := make([]*_type, 0, (md.etypedesc-md.types)/(2*unsafe.Sizeof(_type{})))
+       ret := make([]*_type, 0, md.typedesclen/(2*unsafe.Sizeof(_type{})))
 
        td := md.types
 
@@ -522,7 +522,8 @@ func moduleTypelinks(md *moduledata) []*_type {
        // cmd/link/internal/data.go createRelroSect in allocateDataSections.
        td++
 
-       for td < md.etypedesc {
+       etypedesc := md.types + md.typedesclen
+       for td < etypedesc {
                // TODO: The fact that type descriptors are aligned to
                // 0x20 does not make sense.
                td = alignUp(td, 0x20)