From d7473fd9076a978352d3bb29c13464c3c17d46c3 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Fri, 30 Apr 2021 17:21:22 -0400 Subject: [PATCH] cmd/link: mangle ABI name for shared linkage Currently, when ABI wrappers are used, we don't use ABI aliases. One exception is shared linkage. When loading a shared library, if a symbol has only one ABI, and the name is not mangled, we don't know what ABI it is, so we have to use ABI aliases. This CL makes it always mangle ABIInternal function name in shared linkage, so we know what ABI to choose when loading a shared library. And we now can fully stop using ABI aliases when ABI wrappers are used. Change-Id: Id15d9cd72a59f391f54574710ebba7dc44cb6e23 Reviewed-on: https://go-review.googlesource.com/c/go/+/315869 Trust: Cherry Zhang Reviewed-by: Than McIntosh --- src/cmd/link/internal/ld/lib.go | 42 ++++-------------------------- src/cmd/link/internal/ld/macho.go | 2 +- src/cmd/link/internal/ld/pe.go | 2 +- src/cmd/link/internal/ld/symtab.go | 18 ++++++++++--- 4 files changed, 22 insertions(+), 42 deletions(-) diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index e9349a4b3e..fd687df9ef 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -503,10 +503,8 @@ func (ctxt *Link) loadlib() { default: log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups) } - if !buildcfg.Experiment.RegabiWrappers || ctxt.linkShared { + if !buildcfg.Experiment.RegabiWrappers { // Use ABI aliases if ABI wrappers are not used. - // TODO: for now we still use ABI aliases in shared linkage, even if - // the wrapper is enabled. flags |= loader.FlagUseABIAlias } elfsetstring1 := func(str string, off int) { elfsetstring(ctxt, 0, str, off) } @@ -2088,25 +2086,6 @@ func ldshlibsyms(ctxt *Link, shlib string) { return } - // collect text symbol ABI versions. - symabi := make(map[string]int) // map (unmangled) symbol name to version - if buildcfg.Experiment.RegabiWrappers { - for _, elfsym := range syms { - if elf.ST_TYPE(elfsym.Info) != elf.STT_FUNC { - continue - } - // Demangle the name. Keep in sync with symtab.go:putelfsym. - if strings.HasSuffix(elfsym.Name, ".abiinternal") { - // ABIInternal symbol has mangled name, so the primary symbol is ABI0. - symabi[strings.TrimSuffix(elfsym.Name, ".abiinternal")] = 0 - } - if strings.HasSuffix(elfsym.Name, ".abi0") { - // ABI0 symbol has mangled name, so the primary symbol is ABIInternal. - symabi[strings.TrimSuffix(elfsym.Name, ".abi0")] = sym.SymVerABIInternal - } - } - } - for _, elfsym := range syms { if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { continue @@ -2119,14 +2098,13 @@ func ldshlibsyms(ctxt *Link, shlib string) { if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") { ver = sym.SymVerABIInternal } else if buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC { + // Demangle the ABI name. Keep in sync with symtab.go:mangleABIName. if strings.HasSuffix(elfsym.Name, ".abiinternal") { ver = sym.SymVerABIInternal symname = strings.TrimSuffix(elfsym.Name, ".abiinternal") } else if strings.HasSuffix(elfsym.Name, ".abi0") { ver = 0 symname = strings.TrimSuffix(elfsym.Name, ".abi0") - } else if abi, ok := symabi[elfsym.Name]; ok { - ver = abi } } @@ -2160,19 +2138,9 @@ func ldshlibsyms(ctxt *Link, shlib string) { l.SetSymExtname(s, elfsym.Name) } - // For function symbols, we don't know what ABI is - // available, so alias it under both ABIs. - // - // TODO(austin): This is almost certainly wrong once - // the ABIs are actually different. We might have to - // mangle Go function names in the .so to include the - // ABI. - if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 { - if buildcfg.Experiment.RegabiWrappers { - if _, ok := symabi[symname]; ok { - continue // only use alias for functions w/o ABI wrappers - } - } + // For function symbols, if ABI wrappers are not used, we don't + // know what ABI is available, so alias it under both ABIs. + if !buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 { alias := ctxt.loader.LookupOrCreateSym(symname, sym.SymVerABIInternal) if l.SymType(alias) != 0 { continue diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index ad53e45b38..000bb0b853 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -1047,7 +1047,7 @@ func machosymtab(ctxt *Link) { // replace "·" as ".", because DTrace cannot handle it. name := strings.Replace(ldr.SymExtname(s), "·", ".", -1) - name = mangleABIName(ldr, s, name) + name = mangleABIName(ctxt, ldr, s, name) symstr.Addstring(name) if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT { diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index b7d057ebdc..3540c07da1 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go @@ -727,7 +727,7 @@ func (f *peFile) writeSymbols(ctxt *Link) { name = "_" + name } - name = mangleABIName(ldr, s, name) + name = mangleABIName(ctxt, ldr, s, name) var peSymType uint16 if ctxt.IsExternal() { diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index 013f7b55b6..3b4fda0c89 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -105,7 +105,7 @@ func putelfsym(ctxt *Link, x loader.Sym, typ elf.SymType, curbind elf.SymBind) { } sname := ldr.SymExtname(x) - sname = mangleABIName(ldr, x, sname) + sname = mangleABIName(ctxt, ldr, x, sname) // One pass for each binding: elf.STB_LOCAL, elf.STB_GLOBAL, // maybe one day elf.STB_WEAK. @@ -834,9 +834,9 @@ func isStaticTmp(name string) bool { } // Mangle function name with ABI information. -func mangleABIName(ldr *loader.Loader, x loader.Sym, name string) string { +func mangleABIName(ctxt *Link, ldr *loader.Loader, x loader.Sym, name string) string { // For functions with ABI wrappers, we have to make sure that we - // don't wind up with two elf symbol table entries with the same + // don't wind up with two symbol table entries with the same // name (since this will generated an error from the external // linker). If we have wrappers, keep the ABIInternal name // unmangled since we want cross-load-module calls to target @@ -854,5 +854,17 @@ func mangleABIName(ldr *loader.Loader, x loader.Sym, name string) string { name = fmt.Sprintf("%s.abi%d", name, ldr.SymVersion(x)) } } + + // When loading a shared library, if a symbol has only one ABI, + // and the name is not mangled, we don't know what ABI it is. + // So we always mangle ABIInternal function name in shared linkage, + // except symbols that are exported to C. Type symbols are always + // ABIInternal so they are not mangled. + if ctxt.IsShared() { + if ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type.") { + name = fmt.Sprintf("%s.abiinternal", name) + } + } + return name } -- 2.50.0