From: Than McIntosh Date: Tue, 25 Feb 2020 14:07:39 +0000 (-0500) Subject: [dev.link] cmd/link: fix up ctxt.Textp2 handling in AssignTextSymbolOrder X-Git-Tag: go1.15beta1~679^2~101 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=85d62a91ee51e5cd46561ae132c151258cfe3e0d;p=gostls13.git [dev.link] cmd/link: fix up ctxt.Textp2 handling in AssignTextSymbolOrder 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 TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang Reviewed-by: Jeremy Faller --- diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go index e725a1eab4..13ddcdac24 100644 --- a/src/cmd/link/internal/ld/deadcode.go +++ b/src/cmd/link/internal/ld/deadcode.go @@ -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 } } diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 35c6d1c5a1..9a2df58cb9 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -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 { diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index da3bb8b7c8..d88eb1fd16 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -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 diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 058ef78f76..ed7e889bf5 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -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.