]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: move setupdynexp before loadlibfull
authorThan McIntosh <thanm@google.com>
Fri, 20 Mar 2020 12:31:38 +0000 (08:31 -0400)
committerThan McIntosh <thanm@google.com>
Wed, 25 Mar 2020 12:47:14 +0000 (12:47 +0000)
Rewrite setupdynexp to work with loader.Sym, and move the call to it
before the body of loadlibfull. After loadlibfull is complete,
construct the old *sym.Symbol version of dynexp, since not all all
clients that access this list are converted to the loader APIs.

Change-Id: I347d24958e2f3e2332fbe33f2eb6ec25cc126bdb
Reviewed-on: https://go-review.googlesource.com/c/go/+/224382
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/loader/loader.go

index 468dca9272e270e769b0c07de868af88a601bde9..49af1c3b744695439fa5f02c8f2115b157f667bd 100644 (file)
@@ -572,31 +572,47 @@ func (ctxt *Link) loadlib() {
        strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
 }
 
-// Set up dynexp list.
+// genSymsForDynexp constructs a *sym.Symbol version of ctxt.dynexp,
+// writing to the global variable 'dynexp'.
+func genSymsForDynexp(ctxt *Link) {
+       dynexp = make([]*sym.Symbol, len(ctxt.dynexp2))
+       for i, s := range ctxt.dynexp2 {
+               dynexp[i] = ctxt.loader.Syms[s]
+       }
+}
+
+// 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
        }
-       dynexp = make([]*sym.Symbol, 0, len(dynexpMap))
+       d := make([]loader.Sym, 0, len(dynexpMap))
        for exp := range dynexpMap {
-               s := ctxt.Syms.Lookup(exp, 0)
-               dynexp = append(dynexp, s)
+               s := ctxt.loader.LookupOrCreateSym(exp, 0)
+               d = append(d, s)
+               // sanity check
+               if !ctxt.loader.AttrReachable(s) {
+                       panic("dynexp entry not reachable")
+               }
        }
-       sort.Sort(byName(dynexp))
+       sort.Slice(dynexp, 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 dynexp {
-               if s.Type != sym.SABIALIAS {
+       for i, s := range d {
+               if ctxt.loader.SymType(s) != sym.SABIALIAS {
                        continue
                }
-               t := resolveABIAlias(s)
-               t.Attr |= s.Attr
-               t.SetExtname(s.Extname())
-               dynexp[i] = t
+               t := ctxt.loader.ResolveABIAlias(s)
+               ctxt.loader.CopyAttributes(s, t)
+               ctxt.loader.SetSymExtname(t, ctxt.loader.SymExtname(s))
+               d[i] = t
        }
+       ctxt.dynexp2 = d
 
        ctxt.cgo_export_static = nil
        ctxt.cgo_export_dynamic = nil
@@ -2711,6 +2727,7 @@ func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library
 }
 
 func (ctxt *Link) loadlibfull() {
+
        // Load full symbol contents, resolve indexed references.
        ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms)
 
@@ -2724,7 +2741,8 @@ func (ctxt *Link) loadlibfull() {
        ctxt.loader.ExtractSymbols(ctxt.Syms, ctxt.Reachparent)
        ctxt.lookup = ctxt.Syms.ROLookup
 
-       setupdynexp(ctxt)
+       // Recreate dynexp using *sym.Symbol instead of loader.Sym
+       genSymsForDynexp(ctxt)
 
        // Drop the cgodata reference.
        ctxt.cgodata = nil
index 2777904ccab0b7f4cf8f1a2e9a5c9ca9666d4d69..b32b7c892dabee07899caef0540efc4c35fd1c61 100644 (file)
@@ -92,7 +92,8 @@ type Link struct {
        cgo_export_static  map[string]bool
        cgo_export_dynamic map[string]bool
 
-       datap []*sym.Symbol
+       datap   []*sym.Symbol
+       dynexp2 []loader.Sym
 }
 
 type cgodata struct {
index 2f3091fab223913af9d44bdbd50b2c14093cf950..23873166ae396794187dbf20758ef331bae63e35 100644 (file)
@@ -273,6 +273,7 @@ func Main(arch *sys.Arch, theArch Arch) {
                ctxt.dope()
        }
        bench.Start("loadlibfull")
+       setupdynexp(ctxt)
        ctxt.loadlibfull() // XXX do it here for now
        if ctxt.IsAIX() {
                bench.Start("doxcoff")
index 599408370d39332b96679a6dbc0a2d221c7566db..03c64839bedd7af89dcc3ab5d70fc0537161efb6 100644 (file)
@@ -797,6 +797,19 @@ func (l *Loader) AttrShared(i Sym) bool {
        return l.attrShared.Has(l.extIndex(i))
 }
 
+// SetAttrShared sets the "shared" property for an external
+// symbol (see AttrShared).
+func (l *Loader) SetAttrShared(i Sym, v bool) {
+       if !l.IsExternal(i) {
+               panic(fmt.Sprintf("tried to set shared attr on non-external symbol %d %s", i, l.SymName(i)))
+       }
+       if v {
+               l.attrShared.Set(l.extIndex(i))
+       } else {
+               l.attrShared.Unset(l.extIndex(i))
+       }
+}
+
 // AttrExternal returns true for function symbols loaded from host
 // object files.
 func (l *Loader) AttrExternal(i Sym) bool {
@@ -1868,6 +1881,21 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols) {
        }
 }
 
+// ResolveABIAlias given a symbol returns the ABI alias target of that
+// symbol. If the sym in question is not an alias, the sym itself is
+// returned.
+func (l *Loader) ResolveABIAlias(s Sym) Sym {
+       if l.SymType(s) != sym.SABIALIAS {
+               return s
+       }
+       relocs := l.Relocs(s)
+       target := relocs.At2(0).Sym()
+       if l.SymType(target) == sym.SABIALIAS {
+               panic(fmt.Sprintf("ABI alias %s references another ABI alias %s", l.SymName(s), l.SymName(target)))
+       }
+       return target
+}
+
 // PropagateSymbolChangesBackToLoader is a temporary shim function
 // that copies over a given sym.Symbol into the equivalent representation
 // in the loader world. The intent is to enable converting a given
@@ -2265,6 +2293,32 @@ func (l *Loader) CopySym(src, dst Sym) {
        // TODO: other attributes?
 }
 
+// CopyAttributes copies over all of the attributes of symbol 'src' to
+// symbol 'dst'.
+func (l *Loader) CopyAttributes(src Sym, dst Sym) {
+       l.SetAttrReachable(dst, l.AttrReachable(src))
+       l.SetAttrOnList(dst, l.AttrOnList(src))
+       l.SetAttrLocal(dst, l.AttrLocal(src))
+       l.SetAttrNotInSymbolTable(dst, l.AttrNotInSymbolTable(src))
+       if l.IsExternal(dst) {
+               l.SetAttrVisibilityHidden(dst, l.AttrVisibilityHidden(src))
+               l.SetAttrDuplicateOK(dst, l.AttrDuplicateOK(src))
+               l.SetAttrShared(dst, l.AttrShared(src))
+               l.SetAttrExternal(dst, l.AttrExternal(src))
+       } else {
+               // Some attributes are modifiable only for external symbols.
+               // In such cases, don't try to transfer over the attribute
+               // from the source even if there is a clash. This comes up
+               // when copying attributes from a dupOK ABI wrapper symbol to
+               // the real target symbol (which may not be marked dupOK).
+       }
+       l.SetAttrTopFrame(dst, l.AttrTopFrame(src))
+       l.SetAttrSpecial(dst, l.AttrSpecial(src))
+       l.SetAttrCgoExportDynamic(dst, l.AttrCgoExportDynamic(src))
+       l.SetAttrCgoExportStatic(dst, l.AttrCgoExportStatic(src))
+       l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
+}
+
 // migrateAttributes copies over all of the attributes of symbol 'src' to
 // sym.Symbol 'dst'.
 func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {