]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/compile, cmd/link: generate itablink at link time
authorCherry Zhang <cherryyz@google.com>
Thu, 30 Jul 2020 21:19:13 +0000 (17:19 -0400)
committerCherry Zhang <cherryyz@google.com>
Mon, 3 Aug 2020 21:13:25 +0000 (21:13 +0000)
Currently, at compile time, for each itab symbol, we create an
"itablink" symbol which holds solely the address of the itab
symbol. At link time, all the itablink symbols are grouped
together to form the itablinks slice.

This CL removes the itablink symbols, and directly generate the
itablinks slice in the linker. This removes a number of symbols,
which are dupOK and generally have long names. And also removes
a special handling of itablink symbols in the deadcode pass which
iterates through all symbols.

Change-Id: I475c3c8899e9fbeec9abc7647b1e4a69aa5c3c5a
Reviewed-on: https://go-review.googlesource.com/c/go/+/245901
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/compile/internal/gc/reflect.go
src/cmd/internal/goobj2/objfile.go
src/cmd/internal/obj/objfile2.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/deadcode.go
src/cmd/link/internal/ld/symtab.go
src/cmd/link/internal/ld/typelink.go
src/cmd/link/internal/ld/xcoff.go
src/cmd/link/internal/loader/loader.go

index ce4838ce801b153ad5d99ff3e12e8ff146df5769..59b00168e03e0905e22de9cf23941b563cea3001 100644 (file)
@@ -1560,9 +1560,6 @@ func dumptabs() {
                // Nothing writes static itabs, so they are read only.
                ggloblsym(i.lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
                i.lsym.Set(obj.AttrContentAddressable, true)
-               ilink := itablinkpkg.Lookup(i.t.ShortString() + "," + i.itype.ShortString()).Linksym()
-               dsymptr(ilink, 0, i.lsym, 0)
-               ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA))
        }
 
        // process ptabs
index c3d00122e7c1f6dee576e8003137756bcba058ec..6f0df86b066ca19a9cfe3edf6dd9b54e9baf2e5f 100644 (file)
@@ -292,6 +292,7 @@ const (
 // Sym.Flag2
 const (
        SymFlagUsedInIface = 1 << iota
+       SymFlagItab
 )
 
 // Returns the length of the name of the symbol.
@@ -321,6 +322,7 @@ func (s *Sym) ReflectMethod() bool { return s.Flag()&SymFlagReflectMethod != 0 }
 func (s *Sym) IsGoType() bool      { return s.Flag()&SymFlagGoType != 0 }
 func (s *Sym) TopFrame() bool      { return s.Flag()&SymFlagTopFrame != 0 }
 func (s *Sym) UsedInIface() bool   { return s.Flag2()&SymFlagUsedInIface != 0 }
+func (s *Sym) IsItab() bool        { return s.Flag2()&SymFlagItab != 0 }
 
 func (s *Sym) SetName(x string, w *Writer) {
        binary.LittleEndian.PutUint32(s[:], uint32(len(x)))
index 74f4fc63bae2997a521d77533c0478c69fed2035..17021d92943325efa1682e78985b5db4ddf54614 100644 (file)
@@ -300,6 +300,9 @@ func (w *writer) Sym(s *LSym) {
        if s.UsedInIface() {
                flag2 |= goobj2.SymFlagUsedInIface
        }
+       if strings.HasPrefix(s.Name, "go.itab.") && s.Type == objabi.SRODATA {
+               flag2 |= goobj2.SymFlagItab
+       }
        name := s.Name
        if strings.HasPrefix(name, "gofile..") {
                name = filepath.ToSlash(name)
index 9bc0f021b12675b2100d5e78f0573658e87b8b4f..39f65364b71bf7bfec931eca36ccb09c1b527d91 100644 (file)
@@ -1904,14 +1904,14 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
        sect.Length = uint64(state.datsize) - sect.Vaddr
 
        /* itablink */
-       sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".itablink"), sym.SITABLINK, sym.Sxxx, relroSecPerm)
-       ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.itablink", 0), sect)
-       ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.eitablink", 0), sect)
-       if ctxt.HeadType == objabi.Haix {
-               // Store .itablink size because its symbols are wrapped
-               // under an outer symbol: runtime.itablink.
-               xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SITABLINK)
-       }
+       sect = state.allocateNamedDataSection(seg, genrelrosecname(".itablink"), []sym.SymKind{sym.SITABLINK}, relroSecPerm)
+
+       itablink := ldr.CreateSymForUpdate("runtime.itablink", 0)
+       ldr.SetSymSect(itablink.Sym(), sect)
+       itablink.SetType(sym.SRODATA)
+       state.datsize += itablink.Size()
+       state.checkdatsize(sym.SITABLINK)
+       sect.Length = uint64(state.datsize) - sect.Vaddr
 
        /* gosymtab */
        sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gosymtab"), sym.SSYMTAB, sym.SRODATA, relroSecPerm)
@@ -2414,11 +2414,10 @@ func (ctxt *Link) address() []*sym.Segment {
 
        ldr := ctxt.loader
        var (
-               rodata   = ldr.SymSect(ldr.LookupOrCreateSym("runtime.rodata", 0))
-               itablink = ldr.SymSect(ldr.LookupOrCreateSym("runtime.itablink", 0))
-               symtab   = ldr.SymSect(ldr.LookupOrCreateSym("runtime.symtab", 0))
-               pclntab  = ldr.SymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0))
-               types    = ldr.SymSect(ldr.LookupOrCreateSym("runtime.types", 0))
+               rodata  = ldr.SymSect(ldr.LookupOrCreateSym("runtime.rodata", 0))
+               symtab  = ldr.SymSect(ldr.LookupOrCreateSym("runtime.symtab", 0))
+               pclntab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0))
+               types   = ldr.SymSect(ldr.LookupOrCreateSym("runtime.types", 0))
        )
 
        for _, s := range ctxt.datap {
@@ -2474,8 +2473,6 @@ func (ctxt *Link) address() []*sym.Segment {
        ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
        ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
        ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
-       ctxt.xdefine("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr))
-       ctxt.xdefine("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length))
 
        s := ldr.Lookup("runtime.gcdata", 0)
        ldr.SetAttrLocal(s, true)
index 53ab0db9d0cac1c1f1c1fc2648c6ddfe3334b8c7..a169772dde3cc3b9e64d9a45ad68a4aad70b8e1f 100644 (file)
@@ -306,22 +306,6 @@ func deadcode(ctxt *Link) {
                }
                d.flood()
        }
-
-       n := ldr.NSym()
-
-       if ctxt.BuildMode != BuildModeShared {
-               // Keep a itablink if the symbol it points at is being kept.
-               // (When BuildModeShared, always keep itablinks.)
-               for i := 1; i < n; i++ {
-                       s := loader.Sym(i)
-                       if ldr.IsItabLink(s) {
-                               relocs := ldr.Relocs(s)
-                               if relocs.Count() > 0 && ldr.AttrReachable(relocs.At(0).Sym()) {
-                                       ldr.SetAttrReachable(s, true)
-                               }
-                       }
-               }
-       }
 }
 
 // methodsig is a typed method signature (name + type).
index 8d2cbd81337040d580d4114d72f70301c6d0c9d4..97d7a22537e26dba6191c3e84248c1d8163bca5d 100644 (file)
@@ -416,8 +416,6 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
 
        // Define these so that they'll get put into the symbol table.
        // data.c:/^address will provide the actual values.
-       ctxt.xdefine("runtime.itablink", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0)
        ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
        ctxt.xdefine("runtime.erodata", sym.SRODATA, 0)
        ctxt.xdefine("runtime.types", sym.SRODATA, 0)
@@ -489,16 +487,11 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
                }
        }
 
-       symitablink := ldr.CreateSymForUpdate("runtime.itablink", 0)
-       symitablink.SetType(sym.SITABLINK)
-
        symt := ldr.CreateSymForUpdate("runtime.symtab", 0)
        symt.SetType(sym.SSYMTAB)
        symt.SetSize(0)
        symt.SetLocal(true)
 
-       nitablinks := 0
-
        // assign specific types so that they sort together.
        // within a type they sort by size, so the .* symbols
        // just defined above will be first.
@@ -536,12 +529,6 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
                        // names, as they can be referred to by a section offset.
                        symGroupType[s] = sym.STYPERELRO
 
-               case strings.HasPrefix(name, "go.itablink."):
-                       nitablinks++
-                       symGroupType[s] = sym.SITABLINK
-                       ldr.SetAttrNotInSymbolTable(s, true)
-                       ldr.SetCarrierSym(s, symitablink.Sym())
-
                case strings.HasPrefix(name, "go.string."):
                        symGroupType[s] = sym.SGOSTRING
                        ldr.SetAttrNotInSymbolTable(s, true)
@@ -672,7 +659,9 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
        moduledata.AddUint(ctxt.Arch, ntypelinks)
        moduledata.AddUint(ctxt.Arch, ntypelinks)
        // The itablinks slice
-       moduledata.AddAddr(ctxt.Arch, symitablink.Sym())
+       itablinkSym := ldr.Lookup("runtime.itablink", 0)
+       nitablinks := uint64(ldr.SymSize(itablinkSym)) / uint64(ctxt.Arch.PtrSize)
+       moduledata.AddAddr(ctxt.Arch, itablinkSym)
        moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
        moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
        // The ptab slice
index 2476efe75c64409faccab5cc68e5e54dc2cad4a4..5eca6e01817e185bdb870471cc8ef6857164db4f 100644 (file)
@@ -28,9 +28,15 @@ func (s byTypeStr) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 func (ctxt *Link) typelink() {
        ldr := ctxt.loader
        typelinks := byTypeStr{}
+       var itabs []loader.Sym
        for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
-               if ldr.AttrReachable(s) && ldr.IsTypelink(s) {
+               if !ldr.AttrReachable(s) {
+                       continue
+               }
+               if ldr.IsTypelink(s) {
                        typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ldr, ctxt.Arch, s), s})
+               } else if ldr.IsItab(s) {
+                       itabs = append(itabs, s)
                }
        }
        sort.Sort(typelinks)
@@ -48,4 +54,19 @@ func (ctxt *Link) typelink() {
                r.SetSiz(4)
                r.SetType(objabi.R_ADDROFF)
        }
+
+       ptrsize := ctxt.Arch.PtrSize
+       il := ldr.CreateSymForUpdate("runtime.itablink", 0)
+       il.SetType(sym.SITABLINK)
+       ldr.SetAttrLocal(il.Sym(), true)
+       il.SetSize(int64(ptrsize * len(itabs)))
+       il.Grow(il.Size())
+       relocs = il.AddRelocs(len(itabs))
+       for i, s := range itabs {
+               r := relocs.At(i)
+               r.SetSym(s)
+               r.SetOff(int32(i * ptrsize))
+               r.SetSiz(uint8(ptrsize))
+               r.SetType(objabi.R_ADDR)
+       }
 }
index cc299cfb6bece4a5b8e1418717730639f3ee4b0b..7eb7f94ca46b104a013d9961881177d26fca653d 100644 (file)
@@ -605,9 +605,6 @@ func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
                outerSymSize["go.funcrel.*"] = size
        case sym.SGCBITS:
                outerSymSize["runtime.gcbits.*"] = size
-       case sym.SITABLINK:
-               outerSymSize["runtime.itablink"] = size
-
        }
 }
 
index 4da77c6d32edecdf3ddff65aef0b9440ce855c5a..d56c748f9cadb9f021ea086520c84fd682a18d7f 100644 (file)
@@ -217,8 +217,7 @@ type Loader struct {
 
        align []uint8 // symbol 2^N alignment, indexed by global index
 
-       itablink         map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
-       deferReturnTramp map[Sym]bool     // whether the symbol is a trampoline of a deferreturn call
+       deferReturnTramp map[Sym]bool // whether the symbol is a trampoline of a deferreturn call
 
        objByPkg map[string]*oReader // map package path to its Go object reader
 
@@ -352,7 +351,6 @@ func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorRepor
                attrCgoExportDynamic: make(map[Sym]struct{}),
                attrCgoExportStatic:  make(map[Sym]struct{}),
                generatedSyms:        make(map[Sym]struct{}),
-               itablink:             make(map[Sym]struct{}),
                deferReturnTramp:     make(map[Sym]bool),
                extStaticSyms:        make(map[nameVer]Sym),
                builtinSyms:          make([]Sym, nbuiltin),
@@ -1163,12 +1161,13 @@ func (l *Loader) IsTypelink(i Sym) bool {
        return l.SymAttr(i)&goobj2.SymFlagTypelink != 0
 }
 
-// Returns whether this is a "go.itablink.*" symbol.
-func (l *Loader) IsItabLink(i Sym) bool {
-       if _, ok := l.itablink[i]; ok {
-               return true
+// Returns whether this symbol is an itab symbol.
+func (l *Loader) IsItab(i Sym) bool {
+       if l.IsExternal(i) {
+               return false
        }
-       return false
+       r, li := l.toLocal(i)
+       return r.Sym(li).IsItab()
 }
 
 // Return whether this is a trampoline of a deferreturn call.
@@ -2139,9 +2138,6 @@ func (st *loadState) preloadSyms(r *oReader, kind int) {
                if osym.UsedInIface() {
                        l.SetAttrUsedInIface(gi, true)
                }
-               if strings.HasPrefix(name, "go.itablink.") {
-                       l.itablink[gi] = struct{}{}
-               }
                if strings.HasPrefix(name, "runtime.") ||
                        (loadingRuntimePkg && strings.HasPrefix(name, "type.")) {
                        if bi := goobj2.BuiltinIdx(name, v); bi != -1 {