diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 51163c2..1dbfb00 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -1543,6 +1543,14 @@
etypes.SetType(sym.STYPE)
ldr.SetAttrSpecial(etypes.Sym(), false)
+ itabs := ldr.CreateSymForUpdate("runtime.itabs", 0)
+ itabs.SetType(sym.STYPE)
+ ldr.SetAttrSpecial(itabs.Sym(), false)
+
+ eitabs := ldr.CreateSymForUpdate("runtime.eitabs", 0)
+ eitabs.SetType(sym.STYPE)
+ ldr.SetAttrSpecial(eitabs.Sym(), false)
+
if ctxt.HeadType == objabi.Haix {
rodata := ldr.CreateSymForUpdate("runtime.rodata", 0)
rodata.SetType(sym.SSTRING)
@@ -2220,6 +2228,8 @@
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypedesc", 0), sect)
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
+ ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.itabs", 0), sect)
+ ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.eitabs", 0), sect)
sect = createRelroSect(".go.func", sym.SGOFUNC)
@@ -2322,7 +2332,7 @@
for k, s := range syms {
ss := ldr.SymSize(s)
sl[k] = symNameSize{sz: ss, sym: s}
- if !sortBySize {
+ if !sortBySize || symn == sym.STYPE {
sl[k].name = ldr.SymName(s)
}
ds := int64(len(ldr.Data(s)))
@@ -2344,7 +2354,7 @@
"runtime.noptrdata", "runtime.noptrbss":
head = s
continue
- case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes", "runtime.erodata",
+ case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.eitabs", "runtime.erodata",
"runtime.enoptrdata", "runtime.enoptrbss":
tail = s
continue
@@ -2399,6 +2409,7 @@
// Sort type descriptors with the typelink flag first,
// sorted by type string. The reflect package will use
// this to ensure that type descriptor pointers are unique.
+ // Sort itabs after type descriptors.
// Compute all the type strings we need once.
typelinkStrings := make(map[loader.Sym]string)
@@ -2408,6 +2419,10 @@
}
}
+ isType := func(name string) bool {
+ return strings.HasPrefix(name, "type:")
+ }
+
sort.Slice(sl, func(i, j int) bool {
si, sj := sl[i].sym, sl[j].sym
@@ -2416,23 +2431,32 @@
return ret
}
- iTypestr, iIsTypelink := typelinkStrings[si]
- jTypestr, jIsTypelink := typelinkStrings[sj]
+ iIsType := isType(sl[i].name)
+ jIsType := isType(sl[j].name)
+ if iIsType && jIsType {
+ iTypestr, iIsTypelink := typelinkStrings[si]
+ jTypestr, jIsTypelink := typelinkStrings[sj]
- if iIsTypelink {
- if jIsTypelink {
+ if iIsTypelink && jIsTypelink {
// typelink symbols sort by type string
return iTypestr < jTypestr
+ } else if iIsTypelink {
+ // typelink < non-typelink
+ return true
+ } else if jIsTypelink {
+ // non-typelink > typelink
+ return false
}
-
- // typelink < non-typelink
+ } else if iIsType {
+ // type < itab
return true
- } else if jIsTypelink {
- // non-typelink greater than typelink
+ } else if jIsType {
+ // itab > type
return false
}
- // non-typelink symbols sort by size as usual
+ // Otherwise, within non-typelink types and itabs,
+ // sort by size as usual.
return sortFn(i, j)
})
@@ -2441,7 +2465,8 @@
// createRelroSect in allocateDataSections.
// TODO: This wastes some space.
offset := int64(1)
- for i := range sl {
+ i := 0
+ for ; i < len(sl); i++ {
si := sl[i].sym
if _, isTypelink := typelinkStrings[si]; !isTypelink {
break
@@ -2452,6 +2477,21 @@
ldr.SetSymValue(ldr.LookupOrCreateSym("runtime.etypedesc", 0), offset)
+ // Find the end of the type descriptors.
+ for ; i < len(sl); i++ {
+ if !isType(sl[i].name) {
+ break
+ }
+ offset = Rnd(offset, int64(symalign(ldr, sl[i].sym)))
+ offset += sl[i].sz
+ }
+
+ ldr.SetSymValue(ldr.LookupOrCreateSym("runtime.etypes", 0), offset)
+ if i < len(sl) {
+ offset = Rnd(offset, int64(symalign(ldr, sl[i].sym)))
+ }
+ ldr.SetSymValue(ldr.LookupOrCreateSym("runtime.itabs", 0), offset)
+
default:
sort.Slice(sl, sortFn)
}
@@ -3098,10 +3138,15 @@
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.
+ // etypedesc, etypes, and itabs were 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.etypes", 0)
+ ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+uint64(ldr.SymValue(s))))
+ s = ldr.Lookup("runtime.itabs", 0)
+ ctxt.xdefine("runtime.itabs", sym.SRODATA, int64(types.Vaddr+uint64(ldr.SymValue(s))))
+ ctxt.xdefine("runtime.eitabs", sym.SRODATA, int64(types.Vaddr+types.Length))
s = ldr.Lookup("runtime.gcdata", 0)
ldr.SetAttrLocal(s, true)
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index b379d4a..87a4d4e 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -435,6 +435,8 @@
ctxt.xdefine("runtime.types", sym.SRODATA, 0)
ctxt.xdefine("runtime.etypedesc", sym.SRODATA, 0)
ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.itabs", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.eitabs", sym.SRODATA, 0)
ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATAEND, 0)
ctxt.xdefine("runtime.data", sym.SDATA, 0)
@@ -460,15 +462,12 @@
ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
// pseudo-symbols to mark locations of type, string, and go string data.
- var symtype loader.Sym
- if !ctxt.DynlinkingGo() {
- s = ldr.CreateSymForUpdate("type:*", 0)
- s.SetType(sym.STYPE)
- s.SetSize(0)
- s.SetAlign(int32(ctxt.Arch.PtrSize))
- symtype = s.Sym()
- setCarrierSym(sym.STYPE, symtype)
- }
+ s = ldr.CreateSymForUpdate("type:*", 0)
+ s.SetType(sym.STYPE)
+ s.SetSize(0)
+ s.SetAlign(int32(ctxt.Arch.PtrSize))
+ symtype := s.Sym()
+ setCarrierSym(sym.STYPE, symtype)
groupSym := func(name string, t sym.SymKind) loader.Sym {
s := ldr.CreateSymForUpdate(name, 0)
@@ -524,11 +523,13 @@
case strings.HasPrefix(name, "type:"):
if !ctxt.DynlinkingGo() {
ldr.SetAttrNotInSymbolTable(s, true)
- }
- symGroupType[s] = sym.STYPE
- if symtype != 0 {
ldr.SetCarrierSym(s, symtype)
}
+ symGroupType[s] = sym.STYPE
+
+ case ldr.IsItab(s):
+ ldr.SetCarrierSym(s, symtype)
+ symGroupType[s] = sym.STYPE
}
}