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 }