]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/link: resolve symbol ABI in shared linkage
authorCherry Zhang <cherryyz@google.com>
Wed, 3 Feb 2021 20:07:33 +0000 (15:07 -0500)
committerCherry Zhang <cherryyz@google.com>
Mon, 8 Feb 2021 15:50:35 +0000 (15:50 +0000)
In shared build mode and linkage, currently we assume all
function symbols are ABI0 (except for generated type algorithm
functions), and alias them to ABIInternal. When the two ABIs
actually differ (as it is now), this is not actually correct.
This CL resolves symbol ABI based on their mangled names.
If the symbol's name has a ".abi0" or ".abiinternal" suffix, it
is of the corresponding ABI. The symbol without the suffix is
the other ABI. For functions without ABI wrapper generated,
only one ABI exists but we don't know what it is, so we still
use alias (for now).

Change-Id: I2165f149bc83d513e81eb1eb4ee95464335b0e75
Reviewed-on: https://go-review.googlesource.com/c/go/+/289289
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/lib.go

index 17d5040827c0e4b03f708b719bf7752c486f3cf6..71cef0b774ff8d4a2bcda88f4b692ae2f57be29d 100644 (file)
@@ -2091,6 +2091,26 @@ func ldshlibsyms(ctxt *Link, shlib string) {
                Errorf(nil, "cannot read symbols from shared library: %s", libpath)
                return
        }
+
+       // collect text symbol ABI versions.
+       symabi := make(map[string]int) // map (unmangled) symbol name to version
+       if *flagAbiWrap {
+               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
@@ -2099,12 +2119,23 @@ func ldshlibsyms(ctxt *Link, shlib string) {
                // Symbols whose names start with "type." are compiler
                // generated, so make functions with that prefix internal.
                ver := 0
+               symname := elfsym.Name // (unmangled) symbol name
                if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
                        ver = sym.SymVerABIInternal
+               } else if *flagAbiWrap && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
+                       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
+                       }
                }
 
                l := ctxt.loader
-               s := l.LookupOrCreateSym(elfsym.Name, ver)
+               s := l.LookupOrCreateSym(symname, ver)
 
                // Because loadlib above loads all .a files before loading
                // any shared libraries, any non-dynimport symbols we find
@@ -2129,6 +2160,10 @@ func ldshlibsyms(ctxt *Link, shlib string) {
                        }
                }
 
+               if symname != elfsym.Name {
+                       l.SetSymExtname(s, elfsym.Name)
+               }
+
                // For function symbols, we don't know what ABI is
                // available, so alias it under both ABIs.
                //
@@ -2137,7 +2172,12 @@ func ldshlibsyms(ctxt *Link, shlib string) {
                // mangle Go function names in the .so to include the
                // ABI.
                if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
-                       alias := ctxt.loader.LookupOrCreateSym(elfsym.Name, sym.SymVerABIInternal)
+                       if *flagAbiWrap {
+                               if _, ok := symabi[symname]; ok {
+                                       continue // only use alias for functions w/o ABI wrappers
+                               }
+                       }
+                       alias := ctxt.loader.LookupOrCreateSym(symname, sym.SymVerABIInternal)
                        if l.SymType(alias) != 0 {
                                continue
                        }