]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: convert mangleTypeSym to new style
authorCherry Zhang <cherryyz@google.com>
Sat, 21 Mar 2020 17:50:46 +0000 (13:50 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 24 Mar 2020 16:43:18 +0000 (16:43 +0000)
Use symbol's Extname, instead of symbol renaming, for the mangled
names.

The old symbol Rename has an interesting logic of "merging"
symbols, when a symbol is renamed to the name of an existing
symbol. It turns out that this is needed for linking against
shared libraries, where the Go object has a reference to a symbol
with the original name, and the shared libary provides a symbol
under the mangled name. Implement this logic with the loader.

Change-Id: Ib95d7a9c93a52f8e02f4a51ac67240d6ebfc1c6a
Reviewed-on: https://go-review.googlesource.com/c/go/+/224939
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/ld/symtab.go
src/cmd/link/internal/loader/loader.go

index 833ec25a5803da465f56d0354fddce2226a17be0..2829b0cd5feb53f8fc62f6b2bc456f19dbbeb90c 100644 (file)
@@ -794,10 +794,29 @@ func (ctxt *Link) mangleTypeSym() {
                return
        }
 
-       for _, s := range ctxt.Syms.Allsym {
-               newName := typeSymbolMangle(s.Name)
-               if newName != s.Name {
-                       ctxt.Syms.Rename(s.Name, newName, int(s.Version))
+       ldr := ctxt.loader
+       for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+               if !ldr.AttrReachable(s) {
+                       continue
+               }
+               name := ldr.SymName(s)
+               newName := typeSymbolMangle(name)
+               if newName != name {
+                       ldr.SetSymExtname(s, newName)
+
+                       // When linking against a shared library, the Go object file may
+                       // have reference to the original symbol name whereas the shared
+                       // library provides a symbol with the mangled name. We need to
+                       // copy the payload of mangled to original.
+                       // XXX maybe there is a better way to do this.
+                       dup := ldr.Lookup(newName, ldr.SymVersion(s))
+                       if dup != 0 {
+                               st := ldr.SymType(s)
+                               dt := ldr.SymType(dup)
+                               if st == sym.Sxxx && dt != sym.Sxxx {
+                                       ldr.CopySym(dup, s)
+                               }
+                       }
                }
        }
 }
index af1f6d763d961947eb272b5dbfdb5a7a3902ad45..2f3091fab223913af9d44bdbd50b2c14093cf950 100644 (file)
@@ -257,6 +257,9 @@ func Main(arch *sys.Arch, theArch Arch) {
        bench.Start("dostkcheck")
        ctxt.dostkcheck()
 
+       bench.Start("mangleTypeSym")
+       ctxt.mangleTypeSym()
+
        if ctxt.IsELF {
                bench.Start("doelf")
                ctxt.doelf()
@@ -280,9 +283,6 @@ func Main(arch *sys.Arch, theArch Arch) {
                ctxt.windynrelocsyms()
        }
 
-       bench.Start("mangleTypeSym")
-       ctxt.mangleTypeSym()
-
        ctxt.setArchSyms()
        bench.Start("addexport")
        ctxt.addexport()
index b6734f69cceae43cdc3799fa6c0ef0e2f4b1780d..97cbb5616e508553e3ba1d9ea3479fad5896dfed 100644 (file)
@@ -163,6 +163,13 @@ func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go
                other |= 3 << 5
        }
 
+       if s == x.Name {
+               // We should use Extname for ELF symbol table.
+               // TODO: maybe genasmsym should have done this. That function is too
+               // overloaded and I would rather not change it for now.
+               s = x.Extname()
+       }
+
        // When dynamically linking, we create Symbols by reading the names from
        // the symbol tables of the shared libraries and so the names need to
        // match exactly. Tools like DTrace will have to wait for now.
index 0eaf401f30ec33c93d0985a413f22db4509c96a6..b06e92214eb07a671186f01457c05a01dfb8a73f 100644 (file)
@@ -2261,6 +2261,24 @@ func (l *Loader) cloneToExternal(symIdx Sym) {
        l.extReader.syms = append(l.extReader.syms, symIdx)
 }
 
+// Copy the payload of symbol src to dst. Both src and dst must be external
+// symbols.
+// The intended use case is that when building/linking against a shared library,
+// where we do symbol name mangling, the Go object file may have reference to
+// the original symbol name whereas the shared library provides a symbol with
+// the mangled name. When we do mangling, we copy payload of mangled to original.
+func (l *Loader) CopySym(src, dst Sym) {
+       if !l.IsExternal(dst) {
+               panic("dst is not external") //l.newExtSym(l.SymName(dst), l.SymVersion(dst))
+       }
+       if !l.IsExternal(src) {
+               panic("src is not external") //l.cloneToExternal(src)
+       }
+       l.payloads[l.extIndex(dst)] = l.payloads[l.extIndex(src)]
+       l.SetSymFile(dst, l.SymFile(src))
+       // TODO: other attributes?
+}
+
 // migrateAttributes copies over all of the attributes of symbol 'src' to
 // sym.Symbol 'dst'.
 func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {