]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: fix up ctxt.Textp2 handling in AssignTextSymbolOrder
authorThan McIntosh <thanm@google.com>
Tue, 25 Feb 2020 14:07:39 +0000 (09:07 -0500)
committerThan McIntosh <thanm@google.com>
Thu, 5 Mar 2020 16:20:42 +0000 (16:20 +0000)
Change the loader method AssignTextSymbolOrder to return a slice of
all reachable textp symbols, since it will be needed in second-phase
DWARF gen.

Change-Id: Iaf16ee9cf0d5266aeb0d3df596e8117263b35d8e
Reviewed-on: https://go-review.googlesource.com/c/go/+/220985
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/link/internal/ld/deadcode.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/loader/loader.go

index e725a1eab46d81a259e74f5034b44b951f3cf260..13ddcdac24c4f482f6a1c08c98561d9d636283c9 100644 (file)
@@ -45,80 +45,56 @@ func deadcode(ctxt *Link) {
        deadcode2(ctxt)
 }
 
+// addToTextp populates the context Textp slice (needed in various places
+// in the linker) and also the unit Textp slices (needed by the "old"
+// phase 2 DWARF generation).
 func addToTextp(ctxt *Link) {
-       // Remove dead text but keep file information (z symbols).
-       textp := []*sym.Symbol{}
-       for _, s := range ctxt.Textp {
-               if s.Attr.Reachable() {
-                       textp = append(textp, s)
-               }
-       }
 
-       // Append the sym.Symbol's that correspond to the reachable
-       // loader.Sym's created by the new host object loader.
-       // FIXME: is this the right way to do this? Or should there be
-       // some way to associated a given host object symbol with the Go
-       // package that refers to it?
-       for _, s := range ctxt.Textp2 {
-               if !ctxt.loader.AttrReachable(s) {
+       // First set up ctxt.Textp, based on ctxt.Textp2.
+       textp := make([]*sym.Symbol, 0, len(ctxt.Textp2))
+       haveshlibs := len(ctxt.Shlibs) > 0
+       for _, tsym := range ctxt.Textp2 {
+               sp := ctxt.loader.Syms[tsym]
+               if sp == nil || !ctxt.loader.AttrReachable(tsym) {
+                       panic("should never happen")
+               }
+               if haveshlibs && sp.Type == sym.SDYNIMPORT {
                        continue
                }
-               textp = append(textp, ctxt.loader.Syms[s])
+               textp = append(textp, sp)
        }
+       ctxt.Textp = textp
 
-       // Put reachable text symbols into Textp.
-       // do it in postorder so that packages are laid down in dependency order
-       // internal first, then everything else. This also populates lib and
-       // unit Textp slices, which are needed for DWARF
-       // FIXME: once DWARF is completely converted to using loader.Sym,
-       // we can remove the *sym.Symbol Textp slices.
-       ctxt.Library = postorder(ctxt.Library)
+       // Dupok symbols may be defined in multiple packages; the
+       // associated package for a dupok sym is chosen sort of
+       // arbitrarily (the first containing package that the linker
+       // loads). The loop below canonicalizes the File to the package
+       // with which it will be laid down in text. Assumes that
+       // ctxt.Library is already in postorder.
        for _, doInternal := range [2]bool{true, false} {
                for _, lib := range ctxt.Library {
                        if isRuntimeDepPkg(lib.Pkg) != doInternal {
                                continue
                        }
-                       libtextp := lib.Textp[:0]
-                       for _, s := range lib.Textp {
-                               if s.Attr.Reachable() {
-                                       textp = append(textp, s)
-                                       libtextp = append(libtextp, s)
-                                       if s.Unit != nil {
-                                               s.Unit.Textp = append(s.Unit.Textp, s)
-                                       }
+                       for _, dsym := range lib.DupTextSyms2 {
+                               tsp := ctxt.loader.Syms[dsym]
+                               if !tsp.Attr.OnList() {
+                                       tsp.Attr |= sym.AttrOnList
+                                       tsp.File = objabi.PathToPrefix(lib.Pkg)
                                }
                        }
-                       for _, s := range lib.DupTextSyms {
-                               if s.Attr.Reachable() && !s.Attr.OnList() {
-                                       textp = append(textp, s)
-                                       libtextp = append(libtextp, s)
-                                       if s.Unit != nil {
-                                               s.Unit.Textp = append(s.Unit.Textp, s)
-                                       }
-                                       s.Attr |= sym.AttrOnList
-                                       // dupok symbols may be defined in multiple packages. its
-                                       // associated package is chosen sort of arbitrarily (the
-                                       // first containing package that the linker loads). canonicalize
-                                       // it here to the package with which it will be laid down
-                                       // in text.
-                                       s.File = objabi.PathToPrefix(lib.Pkg)
-                               }
-                       }
-                       lib.Textp = libtextp
                }
        }
-       ctxt.Textp = textp
 
-       if len(ctxt.Shlibs) > 0 {
-               // We might have overwritten some functions above (this tends to happen for the
-               // autogenerated type equality/hashing functions) and we don't want to generated
-               // pcln table entries for these any more so remove them from Textp.
-               textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
-               for _, s := range ctxt.Textp {
-                       if s.Type != sym.SDYNIMPORT {
-                               textp = append(textp, s)
+       // Finally, set up compilation unit Textp slices. Can be removed
+       // once loader-Sym DWARF-gen phase 2 is always enabled.
+       for _, lib := range ctxt.Library {
+               for _, unit := range lib.Units {
+                       for _, usym := range unit.Textp2 {
+                               usp := ctxt.loader.Syms[usym]
+                               usp.Attr |= sym.AttrOnList
+                               unit.Textp = append(unit.Textp, usp)
                        }
                }
-               ctxt.Textp = textp
        }
 }
index 35c6d1c5a139cc0cda60b3bb13768d041aa27897..9a2df58cb9da21e36c92ce6b2afef8dbbcc138c2 100644 (file)
@@ -1214,19 +1214,6 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
                return
        }
 
-       // DWARF-gen requires that the unit Textp2 slices be populated,
-       // so that it can walk the functions in each unit. Call into
-       // the loader to do this (requires that we collect the set of
-       // internal libraries first). NB: might be simpler if we moved
-       // isRuntimeDepPkg to cmd/internal and then did the test
-       // in loader.AssignTextSymbolOrder.
-       ctxt.Library = postorder(ctxt.Library)
-       intlibs := []bool{}
-       for _, lib := range ctxt.Library {
-               intlibs = append(intlibs, isRuntimeDepPkg(lib.Pkg))
-       }
-       ctxt.loader.AssignTextSymbolOrder(ctxt.Library, intlibs)
-
        d := newdwctxt2(ctxt, true)
 
        if ctxt.HeadType == objabi.Haix {
index da3bb8b7c868600aef0a313fad9ca30b11478780..d88eb1fd169324bf01aca4cd9ec70cfea437a52e 100644 (file)
@@ -734,6 +734,19 @@ func (ctxt *Link) linksetup() {
                        ctxt.loader.SetAttrReachable(got, true)
                }
        }
+
+       // DWARF-gen and other phases require that the unit Textp2 slices
+       // be populated, so that it can walk the functions in each unit.
+       // Call into the loader to do this (requires that we collect the
+       // set of internal libraries first). NB: might be simpler if we
+       // moved isRuntimeDepPkg to cmd/internal and then did the test in
+       // loader.AssignTextSymbolOrder.
+       ctxt.Library = postorder(ctxt.Library)
+       intlibs := []bool{}
+       for _, lib := range ctxt.Library {
+               intlibs = append(intlibs, isRuntimeDepPkg(lib.Pkg))
+       }
+       ctxt.Textp2 = ctxt.loader.AssignTextSymbolOrder(ctxt.Library, intlibs, ctxt.Textp2)
 }
 
 // mangleTypeSym shortens the names of symbols that represent Go types
index 058ef78f761f1f59c2bcc9b9bd084ae9373354b4..ed7e889bf549ff98eb4235bce060075493908566 100644 (file)
@@ -2459,8 +2459,9 @@ func (l *Loader) UndefinedRelocTargets(limit int) []Sym {
 
 // AssignTextSymbolOrder populates the Textp2 slices within each
 // library and compilation unit, insuring that packages are laid down
-// in dependency order (internal first, then everything else).
-func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool) {
+// in dependency order (internal first, then everything else). Return value
+// is a slice of all text syms.
+func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, extsyms []Sym) []Sym {
 
        // Library Textp2 lists should be empty at this point.
        for _, lib := range libs {
@@ -2479,6 +2480,15 @@ func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool) {
        // call the regular addToTextp.
        assignedToUnit := MakeBitmap(l.NSym() + 1)
 
+       // Start off textp2 with reachable external syms.
+       textp2 := []Sym{}
+       for _, sym := range extsyms {
+               if !l.attrReachable.Has(sym) {
+                       continue
+               }
+               textp2 = append(textp2, sym)
+       }
+
        // Walk through all text symbols from Go object files and append
        // them to their corresponding library's textp2 list.
        for _, o := range l.objs[1:] {
@@ -2486,23 +2496,27 @@ func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool) {
                lib := r.unit.Lib
                for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
                        gi := l.toGlobal(r, i)
+                       if !l.attrReachable.Has(gi) {
+                               continue
+                       }
                        osym := goobj2.Sym{}
                        osym.ReadWithoutName(r.Reader, r.SymOff(i))
                        st := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)]
                        if st != sym.STEXT {
                                continue
                        }
-                       // check for dupok
+                       dupok := osym.Dupok()
                        if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
-                               if l.attrReachable.Has(gi) {
-                                       // A dupok symbol is resolved to another package.
-                                       // We still need to record its presence in the
-                                       // current package, as the trampoline pass expects
-                                       // packages are laid out in dependency order.
-                                       lib.DupTextSyms2 = append(lib.DupTextSyms2, sym.LoaderSym(gi))
-                               }
+                               // A dupok text symbol is resolved to another package.
+                               // We still need to record its presence in the current
+                               // package, as the trampoline pass expects packages
+                               // are laid out in dependency order.
+                               lib.DupTextSyms2 = append(lib.DupTextSyms2, sym.LoaderSym(gi))
                                continue // symbol in different object
                        }
+                       if dupok {
+                               lib.DupTextSyms2 = append(lib.DupTextSyms2, sym.LoaderSym(gi))
+                       }
 
                        lib.Textp2 = append(lib.Textp2, sym.LoaderSym(gi))
                }
@@ -2515,12 +2529,13 @@ func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool) {
                                continue
                        }
                        libtextp2 := []sym.LoaderSym{}
-                       tpls := [2][]sym.LoaderSym{lib.Textp2, lib.DupTextSyms2}
-                       for _, textp2 := range tpls {
-                               for _, s := range textp2 {
+                       lists := [2][]sym.LoaderSym{lib.Textp2, lib.DupTextSyms2}
+                       for _, list := range lists {
+                               for _, s := range list {
                                        sym := Sym(s)
                                        if l.attrReachable.Has(sym) && !assignedToUnit.Has(sym) {
                                                libtextp2 = append(libtextp2, s)
+                                               textp2 = append(textp2, sym)
                                                unit := l.SymUnit(sym)
                                                if unit != nil {
                                                        unit.Textp2 = append(unit.Textp2, s)
@@ -2532,6 +2547,7 @@ func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool) {
                        lib.Textp2 = libtextp2
                }
        }
+       return textp2
 }
 
 // For debugging.