runtime, cmd/link: store type descriptor length, not end

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>
This commit is contained in:
Ian Lance Taylor 2026-01-27 17:34:46 -08:00 committed by Cherry Mui
parent 2bd7f15dd7
commit 1172294145
5 changed files with 34 additions and 29 deletions

View 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))

View file

@ -96,6 +96,8 @@ type Link struct {
Textp []loader.Sym
Moduledata loader.Sym
moduledataTypeDescOffset int64
PackageFile map[string]string
PackageShlib map[string]string

View 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))

View 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

View 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)