]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: build dynexp symbol list directly
authorAustin Clements <austin@google.com>
Mon, 12 Apr 2021 17:21:55 +0000 (13:21 -0400)
committerAustin Clements <austin@google.com>
Tue, 13 Apr 2021 20:07:46 +0000 (20:07 +0000)
Currently, setCgoAttr populates the cgo_export_{static,dynamic} maps
with symbol names of exported symbols, which are then re-looked-up by
deadcode and setupdynexp, which in turn puts the re-looked-up symbols
in ctxt.dynexp. setCgoAttr already looked up the Syms, so simplify all
of this by making setCgoAttr populate ctxt.dynexp directly and
eliminating the cgo_export_{static,dynamic} maps. Recording Syms
directly also sets us up to use correct symbol versions for these
exports, rather than just assuming version 0 for all lookups.

Since setupdynexp doesn't really do any "setting up" of dynexp any
more with this change, we fold the remaining logic from setupdynexp
directly into addexport, where it has better context anyway. This also
eliminates a sorting step, since we no longer do a non-deterministic
map iteration to build the dynexp slice.

For #40724.

Change-Id: I3e1a65165268da8c2bf50d7485f2624133433260
Reviewed-on: https://go-review.googlesource.com/c/go/+/309340
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/deadcode.go
src/cmd/link/internal/ld/go.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/main.go

index 9b04e2cddc144648a610c9447cb292e426937c6a..741a72cad844b24f03b2294255c2e8ffb851f8d3 100644 (file)
@@ -88,14 +88,6 @@ func (d *deadcodePass) init() {
                }
        }
 
-       dynexpMap := d.ctxt.cgo_export_dynamic
-       if d.ctxt.LinkMode == LinkExternal {
-               dynexpMap = d.ctxt.cgo_export_static
-       }
-       for exp := range dynexpMap {
-               names = append(names, exp)
-       }
-
        if d.ctxt.Debugvlog > 1 {
                d.ctxt.Logf("deadcode start names: %v\n", names)
        }
@@ -106,6 +98,14 @@ func (d *deadcodePass) init() {
                // Also mark any Go functions (internal ABI).
                d.mark(d.ldr.Lookup(name, sym.SymVerABIInternal), 0)
        }
+
+       // All dynamic exports are roots.
+       for _, s := range d.ctxt.dynexp {
+               if d.ctxt.Debugvlog > 1 {
+                       d.ctxt.Logf("deadcode start dynexp: %s<%d>\n", d.ldr.SymName(s), d.ldr.SymVersion(s))
+               }
+               d.mark(s, 0)
+       }
 }
 
 func (d *deadcodePass) flood() {
index ec6ceb82ce731b26f5a1551d7e8206603a9a97be..5dbf6c71537ddb062f17681ff2f6da68e833854f 100644 (file)
@@ -234,11 +234,19 @@ func setCgoAttr(ctxt *Link, file string, pkg string, directives [][]string, host
                        // Mark exported symbols and also add them to
                        // the lists used for roots in the deadcode pass.
                        if f[0] == "cgo_export_static" {
+                               if ctxt.LinkMode == LinkExternal && !l.AttrCgoExportStatic(s) {
+                                       // Static cgo exports appear
+                                       // in the exported symbol table.
+                                       ctxt.dynexp = append(ctxt.dynexp, s)
+                               }
                                l.SetAttrCgoExportStatic(s, true)
-                               ctxt.cgo_export_static[local] = true
                        } else {
+                               if ctxt.LinkMode == LinkInternal && !l.AttrCgoExportDynamic(s) {
+                                       // Dynamic cgo exports appear
+                                       // in the exported symbol table.
+                                       ctxt.dynexp = append(ctxt.dynexp, s)
+                               }
                                l.SetAttrCgoExportDynamic(s, true)
-                               ctxt.cgo_export_dynamic[local] = true
                        }
 
                        continue
@@ -422,9 +430,26 @@ func (ctxt *Link) addexport() {
                return
        }
 
-       for _, exp := range ctxt.dynexp {
-               Adddynsym(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, exp)
+       // Add dynamic symbols.
+       for _, s := range ctxt.dynexp {
+               // Consistency check.
+               if !ctxt.loader.AttrReachable(s) {
+                       panic("dynexp entry not reachable")
+               }
+
+               // Resolve ABI aliases in the list of cgo-exported functions.
+               // This is necessary because we load the ABI0 symbol for all
+               // cgo exports.
+               if ctxt.loader.SymType(s) == sym.SABIALIAS {
+                       t := ctxt.loader.ResolveABIAlias(s)
+                       ctxt.loader.CopyAttributes(s, t)
+                       ctxt.loader.SetSymExtname(t, ctxt.loader.SymExtname(s))
+                       s = t
+               }
+
+               Adddynsym(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, s)
        }
+
        for _, lib := range dedupLibraries(ctxt, dynlib) {
                adddynlib(ctxt, lib)
        }
index 520d57a72e7cefbcfb60db209d82c62f735f4d98..b709569103320a42c9fd2b44e366f1d49a0c8aed 100644 (file)
@@ -56,7 +56,6 @@ import (
        "os"
        "path/filepath"
        "runtime"
-       "sort"
        "strings"
        "sync"
 )
@@ -508,9 +507,6 @@ func (ctxt *Link) loadlib() {
                return ctxt.loader.SymName(s)
        }
 
-       ctxt.cgo_export_static = make(map[string]bool)
-       ctxt.cgo_export_dynamic = make(map[string]bool)
-
        // ctxt.Library grows during the loop, so not a range loop.
        i := 0
        for ; i < len(ctxt.Library); i++ {
@@ -638,43 +634,6 @@ func (ctxt *Link) loadlib() {
        strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
 }
 
-// setupdynexp constructs ctxt.dynexp, a list of loader.Sym.
-func setupdynexp(ctxt *Link) {
-       dynexpMap := ctxt.cgo_export_dynamic
-       if ctxt.LinkMode == LinkExternal {
-               dynexpMap = ctxt.cgo_export_static
-       }
-       d := make([]loader.Sym, 0, len(dynexpMap))
-       for exp := range dynexpMap {
-               s := ctxt.loader.LookupOrCreateSym(exp, 0)
-               d = append(d, s)
-               // sanity check
-               if !ctxt.loader.AttrReachable(s) {
-                       panic("dynexp entry not reachable")
-               }
-       }
-       sort.Slice(d, func(i, j int) bool {
-               return ctxt.loader.SymName(d[i]) < ctxt.loader.SymName(d[j])
-       })
-
-       // Resolve ABI aliases in the list of cgo-exported functions.
-       // This is necessary because we load the ABI0 symbol for all
-       // cgo exports.
-       for i, s := range d {
-               if ctxt.loader.SymType(s) != sym.SABIALIAS {
-                       continue
-               }
-               t := ctxt.loader.ResolveABIAlias(s)
-               ctxt.loader.CopyAttributes(s, t)
-               ctxt.loader.SetSymExtname(t, ctxt.loader.SymExtname(s))
-               d[i] = t
-       }
-       ctxt.dynexp = d
-
-       ctxt.cgo_export_static = nil
-       ctxt.cgo_export_dynamic = nil
-}
-
 // loadcgodirectives reads the previously discovered cgo directives, creating
 // symbols in preparation for host object loading or use later in the link.
 func (ctxt *Link) loadcgodirectives() {
index f26d051a491bbc3671cdb3c81a2a94f6000e6966..13618beff977a5a5aef902edd354bf6a644d7660 100644 (file)
@@ -84,9 +84,6 @@ type Link struct {
        loader  *loader.Loader
        cgodata []cgodata // cgo directives to load, three strings are args for loadcgo
 
-       cgo_export_static  map[string]bool
-       cgo_export_dynamic map[string]bool
-
        datap  []loader.Sym
        dynexp []loader.Sym
 
index 8631cf2939601537892d1cd249ed81da698560e8..1e3c3bdff7817880aec6a316d0a062ea02fb2b31 100644 (file)
@@ -294,7 +294,6 @@ func Main(arch *sys.Arch, theArch Arch) {
        bench.Start("textbuildid")
        ctxt.textbuildid()
        bench.Start("addexport")
-       setupdynexp(ctxt)
        ctxt.setArchSyms()
        ctxt.addexport()
        bench.Start("Gentext")