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
}
}
// 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 {
// 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:] {
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))
}
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)
lib.Textp2 = libtextp2
}
}
+ return textp2
}
// For debugging.