diff options
Diffstat (limited to 'src/cmd/link/internal/ld/deadcode.go')
| -rw-r--r-- | src/cmd/link/internal/ld/deadcode.go | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go index c880c0da01..cadb92b43c 100644 --- a/src/cmd/link/internal/ld/deadcode.go +++ b/src/cmd/link/internal/ld/deadcode.go @@ -118,22 +118,66 @@ func deadcode(ctxt *Link) { } } - for _, lib := range ctxt.Library { - lib.Textp = lib.Textp[:0] - } - // Remove dead text but keep file information (z symbols). - textp := make([]*sym.Symbol, 0, len(ctxt.Textp)) + textp := []*sym.Symbol{} for _, s := range ctxt.Textp { if s.Attr.Reachable() { - if s.Unit != nil { - s.Unit.Lib.Textp = append(s.Unit.Lib.Textp, s) - s.Unit.Textp = append(s.Unit.Textp, s) - } textp = append(textp, s) } } + + // Put reachable text symbols into Textp. + // do it in postorder so that packages are laid down in dependency order + // internal first, then everything else + ctxt.Library = postorder(ctxt.Library) + 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 _, 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) + } + } + ctxt.Textp = textp + } } // methodref holds the relocations from a receiver type symbol to its |
