1
0
mirror of https://github.com/golang/go synced 2024-11-17 15:44:40 -07:00

[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 <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2020-03-21 13:50:46 -04:00
parent b328ab1d1e
commit ed7a491940
4 changed files with 51 additions and 7 deletions

View 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)
}
}
}
}
}

View 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()

View 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.

View 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) {