]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: mangle ABI name for shared linkage
authorCherry Zhang <cherryyz@google.com>
Fri, 30 Apr 2021 21:21:22 +0000 (17:21 -0400)
committerCherry Zhang <cherryyz@google.com>
Sat, 1 May 2021 19:17:12 +0000 (19:17 +0000)
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 <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/macho.go
src/cmd/link/internal/ld/pe.go
src/cmd/link/internal/ld/symtab.go

index e9349a4b3ecdbe92ba38583b573189b62f681b6a..fd687df9efa39b8c91e26c9fa64bd7a2dd050797 100644 (file)
@@ -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
index ad53e45b388f7e4bd869339b0e29ef5e448cbcb0..000bb0b853f5108a1f2895d12860d40423c59bc3 100644 (file)
@@ -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 {
index b7d057ebdcd61e76f37d841f790a01000234a5f2..3540c07da104e5e257eaf26b15680f23baefba0d 100644 (file)
@@ -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() {
index 013f7b55b64dee4c79798295b64acecd422cbd8f..3b4fda0c89a4ab963bf05975e18d6a06dc82ee95 100644 (file)
@@ -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
 }