mirror of
https://github.com/golang/go
synced 2024-11-17 07:04:44 -07:00
cmd/link: build dynexp symbol list directly
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>
This commit is contained in:
parent
007e247af1
commit
48531da9e7
@ -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 {
|
if d.ctxt.Debugvlog > 1 {
|
||||||
d.ctxt.Logf("deadcode start names: %v\n", names)
|
d.ctxt.Logf("deadcode start names: %v\n", names)
|
||||||
}
|
}
|
||||||
@ -106,6 +98,14 @@ func (d *deadcodePass) init() {
|
|||||||
// Also mark any Go functions (internal ABI).
|
// Also mark any Go functions (internal ABI).
|
||||||
d.mark(d.ldr.Lookup(name, sym.SymVerABIInternal), 0)
|
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() {
|
func (d *deadcodePass) flood() {
|
||||||
|
@ -234,11 +234,19 @@ func setCgoAttr(ctxt *Link, file string, pkg string, directives [][]string, host
|
|||||||
// Mark exported symbols and also add them to
|
// Mark exported symbols and also add them to
|
||||||
// the lists used for roots in the deadcode pass.
|
// the lists used for roots in the deadcode pass.
|
||||||
if f[0] == "cgo_export_static" {
|
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)
|
l.SetAttrCgoExportStatic(s, true)
|
||||||
ctxt.cgo_export_static[local] = true
|
|
||||||
} else {
|
} 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)
|
l.SetAttrCgoExportDynamic(s, true)
|
||||||
ctxt.cgo_export_dynamic[local] = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
@ -422,9 +430,26 @@ func (ctxt *Link) addexport() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, exp := range ctxt.dynexp {
|
// Add dynamic symbols.
|
||||||
Adddynsym(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, exp)
|
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) {
|
for _, lib := range dedupLibraries(ctxt, dynlib) {
|
||||||
adddynlib(ctxt, lib)
|
adddynlib(ctxt, lib)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@ -508,9 +507,6 @@ func (ctxt *Link) loadlib() {
|
|||||||
return ctxt.loader.SymName(s)
|
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.
|
// ctxt.Library grows during the loop, so not a range loop.
|
||||||
i := 0
|
i := 0
|
||||||
for ; i < len(ctxt.Library); i++ {
|
for ; i < len(ctxt.Library); i++ {
|
||||||
@ -638,43 +634,6 @@ func (ctxt *Link) loadlib() {
|
|||||||
strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
|
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
|
// loadcgodirectives reads the previously discovered cgo directives, creating
|
||||||
// symbols in preparation for host object loading or use later in the link.
|
// symbols in preparation for host object loading or use later in the link.
|
||||||
func (ctxt *Link) loadcgodirectives() {
|
func (ctxt *Link) loadcgodirectives() {
|
||||||
|
@ -84,9 +84,6 @@ type Link struct {
|
|||||||
loader *loader.Loader
|
loader *loader.Loader
|
||||||
cgodata []cgodata // cgo directives to load, three strings are args for loadcgo
|
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
|
datap []loader.Sym
|
||||||
dynexp []loader.Sym
|
dynexp []loader.Sym
|
||||||
|
|
||||||
|
@ -294,7 +294,6 @@ func Main(arch *sys.Arch, theArch Arch) {
|
|||||||
bench.Start("textbuildid")
|
bench.Start("textbuildid")
|
||||||
ctxt.textbuildid()
|
ctxt.textbuildid()
|
||||||
bench.Start("addexport")
|
bench.Start("addexport")
|
||||||
setupdynexp(ctxt)
|
|
||||||
ctxt.setArchSyms()
|
ctxt.setArchSyms()
|
||||||
ctxt.addexport()
|
ctxt.addexport()
|
||||||
bench.Start("Gentext")
|
bench.Start("Gentext")
|
||||||
|
Loading…
Reference in New Issue
Block a user