From: Cherry Zhang Date: Sat, 21 Mar 2020 17:50:46 +0000 (-0400) Subject: [dev.link] cmd/link: convert mangleTypeSym to new style X-Git-Tag: go1.15beta1~679^2~42 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ed7a4919404e56a7e15b029fed12c88f6e02fb43;p=gostls13.git [dev.link] cmd/link: convert mangleTypeSym to new style 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 TryBot-Result: Gobot Gobot Reviewed-by: Than McIntosh --- diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 833ec25a58..2829b0cd5f 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -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) + } + } } } } diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index af1f6d763d..2f3091fab2 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -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() diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index b6734f69cc..97cbb5616e 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -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. diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 0eaf401f30..b06e92214e 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -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) {