mirror of
https://github.com/golang/go
synced 2024-11-23 10:30:03 -07:00
[dev.regabi] cmd/link: resolve symbol ABI in shared linkage
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>
This commit is contained in:
parent
8fa84772ba
commit
a21de9ec73
@ -2091,6 +2091,26 @@ func ldshlibsyms(ctxt *Link, shlib string) {
|
|||||||
Errorf(nil, "cannot read symbols from shared library: %s", libpath)
|
Errorf(nil, "cannot read symbols from shared library: %s", libpath)
|
||||||
return
|
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 {
|
for _, elfsym := range syms {
|
||||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
|
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
|
||||||
continue
|
continue
|
||||||
@ -2099,12 +2119,23 @@ func ldshlibsyms(ctxt *Link, shlib string) {
|
|||||||
// Symbols whose names start with "type." are compiler
|
// Symbols whose names start with "type." are compiler
|
||||||
// generated, so make functions with that prefix internal.
|
// generated, so make functions with that prefix internal.
|
||||||
ver := 0
|
ver := 0
|
||||||
|
symname := elfsym.Name // (unmangled) symbol name
|
||||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
|
if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
|
||||||
ver = sym.SymVerABIInternal
|
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
|
l := ctxt.loader
|
||||||
s := l.LookupOrCreateSym(elfsym.Name, ver)
|
s := l.LookupOrCreateSym(symname, ver)
|
||||||
|
|
||||||
// Because loadlib above loads all .a files before loading
|
// Because loadlib above loads all .a files before loading
|
||||||
// any shared libraries, any non-dynimport symbols we find
|
// 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
|
// For function symbols, we don't know what ABI is
|
||||||
// available, so alias it under both ABIs.
|
// 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
|
// mangle Go function names in the .so to include the
|
||||||
// ABI.
|
// ABI.
|
||||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
|
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 {
|
if l.SymType(alias) != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user